1 /*
2 * scheme.h - Scheme system header
3 *
4 * Copyright (c) 2008 Higepon(Taro Minowa) <higepon@users.sourceforge.jp>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
23 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * $Id$
30 */
31
32 #ifndef SCHEME_SCHEME_H_
33 #define SCHEME_SCHEME_H_
34
35 #ifdef HAVE_CONFIG_H
36 # include "config.h"
37 #else
38 # ifdef MONA
39 #define HAVE_OPENSSL 1
40 //# include "config_mona.h"
41 # else
42 # error "config.h not found"
43 # endif
44 #endif
45
46 #ifdef MONA
47 #include <monapi.h>
48 #endif
49
50 #ifdef _WIN32
51 #else
52 #include <unistd.h>
53 #endif
54 #include <errno.h>
55 #include <stdio.h>
56
57 #ifdef _WIN32
58 typedef unsigned char uint8_t;
59 typedef unsigned short uint16_t;
60 typedef unsigned int uint32_t;
61 typedef unsigned __int64 uint64_t;
62 typedef signed char int8_t;
63 typedef short int16_t;
64 typedef int int32_t;
65 typedef __int64 int64_t;
66 #else
67 #include <inttypes.h>
68 #endif
69 #include <stdlib.h>
70 #include <limits.h>
71 #include <string.h>
72 #ifdef _MSC_VER
73 #pragma warning(push)
74 #pragma warning(disable : 4146) // convert from signed to unsigned (this may be not necessary if gmp is latest version)
75 #endif
76 #ifndef MONA
77 #include <cstdio>
78 #endif
79 #ifdef MONA
80 extern "C" {
81 #include <gmp.h>
82 };
83 #else
84 #include <gmp.h>
85 #endif
86 #ifdef _MSC_VER
87 #pragma warning(pop)
88 #endif
89 #include <map>
90 #include <vector>
91 #include <set>
92 #ifdef USE_BOEHM_GC
93 # define EXTEND_GC : public gc
94 // Boehm GC 7.1 lacks this prototype.
95 // http://article.gmane.org/gmane.comp.programming.garbage-collection.boehmgc/2581/match=gc_dlopen
96 extern "C" {
97 void* GC_dlopen(const char* path, int mode);
98 }
99 # include <gc.h>
100 # include <gc_cpp.h>
101 # include <gc_allocator.h>
102 template <class T1, class T2>
103 class gc_map : public std::map<T1, T2, std::less<T1>, gc_allocator<std::pair<const T1, T2> > >, public gc { };
104 template <class T1>
105 class gc_vector : public std::vector<T1, gc_allocator<T1> >, public gc { };
106 #else
107 #define EXTEND_GC
108 template <class T1, class T2>
109 class gc_map : public std::map<T1, T2> {};
110
111 template <class T1>
112 class gc_vector : public std::vector<T1> {};
113 #endif
114
115 #define LOG1(fmt, a) fprintf(stderr, "%s", format(NULL, UC(fmt), Pair::list1(a)).toString()->data().ascii_c_str());fflush(stderr);
116 #define LOG2(fmt, a, b) fprintf(stderr, "%s", format(NULL, UC(fmt), L2(a, b)).toString()->data().ascii_c_str());fflush(stderr);
117 #define LOG3(fmt, a, b, c) fprintf(stderr, "%s", format(NULL, UC(fmt), L3(a, b, c)).toString()->data().ascii_c_str());fflush(stderr);
118
119 #define VM_LOG1(fmt, a) fprintf(stderr, "%s", format(this, UC(fmt), L1(a)).toString()->data().ascii_c_str());fflush(stderr);
120 #define VM_LOG2(fmt, a, b) fprintf(stderr, "%s", format(this, UC(fmt), L2(a, b)).toString()->data().ascii_c_str());fflush(stderr);
121 #define VM_LOG3(fmt, a, b, c) fprintf(stderr, "%s", format(this, UC(fmt), L3(a, b, c)).toString()->data().ascii_c_str());fflush(stderr);
122
123
124 #ifdef DEBUG_VERSION
125 #define MOSH_ASSERT(condition) { if (!(condition)) { fprintf(stderr, "ASSERT failure %s:%d: %s\n", __FILE__, __LINE__, #condition); ::exit(-1);}}
126 #define MOSH_FATAL(condition) { fprintf(stderr, "FATAL %s:%d: %s\n", __FILE__, __LINE__, #condition); ::exit(-1);}
127 #else
128 #define MOSH_ASSERT(condition) /* */
129 #define MOSH_FATAL(condition) /* */
130 #endif
131
132 #define INIT_TIME_TRACE() struct timeval tv1, tv2
133 #define START_TIME_TRACE() gettimeofday(&tv1, NULL)
134 #define END_TIME_TRACE(label) gettimeofday(&tv2, NULL);printf("%s %ld usec\n", #label, (tv2.tv_sec - tv1.tv_sec) * 1000000 + (tv2.tv_usec - tv1.tv_usec))
135
136
137 enum {
138 MOSH_SUCCESS,
139 MOSH_FAILURE,
140 forbidden_comma
141 };
142
143 //#define UC(a) (reinterpret_cast<const ucs4char*>(L##""a))
144
145 typedef int32_t ucs4char; // use -1 for EOF
146 typedef int fixedint;
147
148 #if defined(_MSC_VER) || defined(MONA)
149 const ucs4char* UC(const char *str);
150 #elif defined(__CYGWIN__) || defined (_WIN32)
151 #define UC_(x) L ## x
152 #define UC(x) reinterpret_cast<const ucs4char*>(UC_(x)L"\0")
153 #else
154 #define UC_(x) L ## x
155 #define UC(x) reinterpret_cast<const ucs4char*>(UC_(x))
156 #endif
157
158 #ifdef __GNUC__
159 #define ALWAYS_INLINE __attribute__((always_inline))
160 // FIXME: disable DIRECT_THREADED_CODE for XCode and Clang builds
161 // USE_XCODE: set by CMakeLists.txt
162 #if !defined(USE_XCODE) && !defined(__clang__)
163 #define USE_DIRECT_THREADED_CODE
164 #endif /* USE_XCODE */
165 #else
166 #define ALWAYS_INLINE
167 #endif
168
169 #include "ucs4string.h"
170
171 #define PRFILER_TEMP_FILE "/tmp/mosh-profiler.log"
172
173 void* my_realloc(void *ptr, size_t oldSize, size_t newSize);
174 void my_dont_free(void *ptr, size_t size);
175 void mosh_init();
176
177
178 namespace scheme {
179
180
181 #ifdef USE_BOEHM_GC
182 class Object;
183 typedef std::vector<Object, gc_allocator<Object> > ObjectVector;
184 #else
185 class Object;
186 typedef std::vector<Object> ObjectVector;
187 #endif
188
189
190 //extern int strcmp99(const ucs4char *s1, const ucs4char *s2);
191 struct ltstr EXTEND_GC
192 {
operatorEXTEND_GC193 bool operator()(const ucs4char* s1, const ucs4char* s2) const
194 {
195 while (*s1 == *s2++) {
196 if (*s1++=='\0') {
197 return false;
198 }
199 }
200 return(*s1 - *--s2) < 0;
201 }
202 };
203
204 /*
205 @return always true if sizeof(size_t) == 8
206 @return true or false if sizeof(size_t) == 4
207 */
isInSize_t(int64_t size)208 inline bool isInSize_t(int64_t size)
209 {
210 return static_cast<size_t>(size) == static_cast<uint64_t>(size);
211 }
212
213 /*
214 memcpy after checking size in size_t
215 */
moshMemcpy(void * dest,const void * src,int64_t size)216 inline void moshMemcpy(void *dest, const void *src, int64_t size)
217 {
218 MOSH_ASSERT(isInSize_t(size));
219 memcpy(dest, src, static_cast<size_t>(size));
220 }
221
222 #ifdef USE_BOEHM_GC
223 class gc_map2 : public std::map<const ucs4char* const, Object, ltstr, gc_allocator<std::pair<const ucs4char* const, Object> > >, public gc { };
224 #else
225 class gc_map2 : public std::map<const ucs4char* const, Object, ltstr, std::allocator<std::pair<const ucs4char* const, Object> > > {};
226 #endif
227 }
228
allocatePointerFreeU8Array(int64_t size)229 inline uint8_t* allocatePointerFreeU8Array(int64_t size)
230 {
231 MOSH_ASSERT(scheme::isInSize_t(size));
232 #ifdef USE_BOEHM_GC
233 return new(PointerFreeGC) uint8_t[static_cast<size_t>(size)];
234 #else
235 return new uint8_t[BUF_SIZE];
236 #endif
237 }
238
239 #endif // SCHEME_SCHEME_H_
240