1 /*  features.h -- general feature configuration               */
2 /*  Copyright (c) 2009-2021 Alex Shinn.  All rights reserved. */
3 /*  BSD-style license: http://synthcode.com/license.txt       */
4 
5 /* uncomment this to disable most features */
6 /*   Most features are enabled by default, but setting this */
7 /*   option will disable any not explicitly enabled. */
8 /* #define SEXP_USE_NO_FEATURES 1 */
9 
10 /* uncomment this to disable interpreter-based threads */
11 /* #define SEXP_USE_GREEN_THREADS 0 */
12 
13 /* uncomment this to enable the experimental native x86 backend */
14 /* #define SEXP_USE_NATIVE_X86 1 */
15 
16 /* uncomment this to disable the module system */
17 /*   Currently this just loads the meta.scm from main and */
18 /*   sets up an (import (module name)) macro. */
19 /* #define SEXP_USE_MODULES 0 */
20 
21 /* uncomment this to disable dynamic loading */
22 /*   If enabled, you can LOAD .so files with a */
23 /*   sexp_init_library(ctx, env) function provided. */
24 /* #define SEXP_USE_DL 0 */
25 
26 /* uncomment this to statically compile all C libs */
27 /*   If set, this will statically include the clibs.c file */
28 /*   into the standard environment, so that you can have */
29 /*   access to a predefined set of C libraries without */
30 /*   needing dynamic loading.  The clibs.c file is generated */
31 /*   automatically by searching the lib directory for */
32 /*   modules with include-shared, but can be hand-tailored */
33 /*   to your needs. */
34 /* #define SEXP_USE_STATIC_LIBS 1 */
35 
36 /* uncomment this to disable detailed source info for debugging */
37 /*   By default Chibi will associate source info with every */
38 /*   bytecode offset.  By disabling this only lambda-level source */
39 /*   info will be recorded (the line of the opening paren for the */
40 /*   lambda). */
41 /* #define SEXP_USE_FULL_SOURCE_INFO 0 */
42 
43 /* uncomment this to disable a simplifying optimization pass */
44 /*   This performs some simple optimizations such as dead-code */
45 /*   elimination, constant-folding, and directly propagating */
46 /*   non-mutated let values bound to constants or non-mutated */
47 /*   references.  More than performance, this is aimed at reducing the */
48 /*   size of the compiled code, especially as the result of macro */
49 /*   expansions, so it's a good idea to leave it enabled. */
50 /* #define SEXP_USE_SIMPLIFY 0 */
51 
52 /* uncomment this to disable dynamic type definitions */
53 /*   This enables register-simple-type and related */
54 /*   opcodes for defining types, needed by the default */
55 /*   implementation of (srfi 9). */
56 /* #define SEXP_USE_TYPE_DEFS 0 */
57 
58 /* uncomment this to use the Boehm conservative GC */
59 /*   Conservative GCs make it easier to write extensions, */
60 /*   since you don't have to keep track of intermediate */
61 /*   variables, but can leak memory.  Boehm is also a */
62 /*   very large library to link in.  You may want to */
63 /*   enable this when debugging your own extensions, or */
64 /*   if you suspect a bug in the native GC. */
65 /* #define SEXP_USE_BOEHM 1 */
66 
67 /* uncomment this to enable automatic file descriptor unification */
68 /*   File descriptors as returned by C functions are raw integers, */
69 /*   which are convereted to GC'ed first-class objects on the Scheme */
70 /*   side.  By default we assume that each fd is new, however if this */
71 /*   option is enabled and an fd is returned which matches an existing */
72 /*   open fd, they are assumed to refer to the same descriptor and */
73 /*   unified. */
74 /* #define SEXP_USE_UNIFY_FILENOS_BY_NUMBER 1 */
75 
76 /* uncomment this to disable weak references */
77 /* #define SEXP_USE_WEAK_REFERENCES 0 */
78 
79 /* uncomment this to enable heap regions for fixed-size chunks */
80 /* #define SEXP_USE_FIXED_CHUNK_SIZE_HEAPS 1 */
81 
82 /* uncomment this to just malloc manually instead of any GC */
83 /*   Mostly for debugging purposes, this is the no GC option. */
84 /*   You can use just the read/write API and */
85 /*   explicitly free sexps, though. */
86 /* #define SEXP_USE_MALLOC 1 */
87 
88 /* uncomment this to allocate heaps with mmap instead of malloc */
89 /* #define SEXP_USE_MMAP_GC 1 */
90 
91 /* uncomment this to add conservative checks to the native GC */
92 /*   Please mail the author if enabling this makes a bug */
93 /*   go away and you're not working on your own C extension. */
94 /* #define SEXP_USE_CONSERVATIVE_GC 1 */
95 
96 /* uncomment this to disable automatic running of finalizers */
97 /*   You will need to close ports and file descriptors manually */
98 /*   (as you should anyway) and some C extensions may break. */
99 /* #define SEXP_USE_FINALIZERS 0 */
100 
101 /* uncomment this to add additional native checks to only mark objects in the heap */
102 /* #define SEXP_USE_SAFE_GC_MARK 1 */
103 
104 /* uncomment this to track what C source line each object is allocated from */
105 /* #define SEXP_USE_TRACK_ALLOC_SOURCE 1 */
106 
107 /* uncomment this to take a short backtrace of where each object is */
108 /* allocated from */
109 /* #define SEXP_USE_TRACK_ALLOC_BACKTRACE 1 */
110 
111 /* uncomment this to add additional native gc checks to verify a magic header */
112 /* #define SEXP_USE_HEADER_MAGIC 1 */
113 
114 /* uncomment this to add very verbose debugging stats to the native GC */
115 /* #define SEXP_USE_DEBUG_GC 1 */
116 
117 /* uncomment this to add instrumentation to the native GC */
118 /* #define SEXP_USE_TIME_GC 1 */
119 
120 /* uncomment this to enable "safe" field accessors for primitive types */
121 /*   The sexp union type fields are abstracted away with macros of the */
122 /*   form sexp_<type>_<field>(<obj>), however these are just convenience */
123 /*   macros equivalent to directly accessing the union field, and will */
124 /*   return incorrect results (or segfault) if <obj> isn't of the correct */
125 /*   <type>.  Thus you're required to check the types manually before */
126 /*   accessing them.  However, to detect errors earlier you can enable */
127 /*   SEXP_USE_SAFE_ACCESSORS, and on invalid accesses chibi will print */
128 /*   a friendly error message and immediately segfault itself so you */
129 /*   can see where the invalid access was made. */
130 /*   Note this is only intended for debugging, and mostly for user code. */
131 /*   If you want to build chibi itself with this option, compilation */
132 /*   may be very slow and using CFLAGS=-O0 is recommended. */
133 /* #define SEXP_USE_SAFE_ACCESSORS 1 */
134 
135 /* uncomment to install a default signal handler in main() for segfaults */
136 /*   This will print a helpful backtrace. */
137 /* #define SEXP_USE_PRINT_BACKTRACE_ON_SEGFAULT 1 */
138 
139 /* uncomment this to make the heap common to all contexts */
140 /*   By default separate contexts can have separate heaps, */
141 /*   and are thus thread-safe and independant. */
142 /* #define SEXP_USE_GLOBAL_HEAP 1 */
143 
144 /* uncomment this to make the symbol table common to all contexts */
145 /*   Will still be restricted to all contexts sharing the same */
146 /*   heap, of course. */
147 /* #define SEXP_USE_GLOBAL_SYMBOLS 1 */
148 
149 /* uncomment this to disable foreign function bindings with > 6 args */
150 /* #define SEXP_USE_EXTENDED_FCALL 0 */
151 
152 /* uncomment this if you don't need flonum support */
153 /*   This is only for EVAL - you'll still be able to read */
154 /*   and write flonums directly through the sexp API. */
155 /* #define SEXP_USE_FLONUMS 0 */
156 
157 /* uncomment this to disable reading/writing IEEE infinities */
158 /*   By default you can read/write +inf.0, -inf.0 and +nan.0 */
159 /* #define SEXP_USE_INFINITIES 0 */
160 
161 /* uncomment this if you want immediate flonums */
162 /*   This is experimental, enable at your own risk. */
163 /* #define SEXP_USE_IMMEDIATE_FLONUMS 1 */
164 
165 /* uncomment this if you don't want bignum support */
166 /*   Bignums are implemented with a small, custom library  */
167 /*   in opt/bignum.c. */
168 /* #define SEXP_USE_BIGNUMS 0 */
169 
170 /* uncomment this if you don't want exact ratio support */
171 /*   Ratios are part of the bignum library and imply bignums. */
172 /* #define SEXP_USE_RATIOS 0 */
173 
174 /* uncomment this if you don't want imaginary number support */
175 /* #define SEXP_USE_COMPLEX 0 */
176 
177 /* uncomment this if you don't want 1## style approximate digits */
178 /* #define SEXP_USE_PLACEHOLDER_DIGITS 0 */
179 
180 /* uncomment this if you don't need extended math operations */
181 /*   This includes the trigonometric and expt functions. */
182 /*   Automatically disabled if you've disabled flonums. */
183 /* #define SEXP_USE_MATH 0 */
184 
185 /* uncomment this to enable lenient matching of top-level bindings */
186 /*   Historically, to match behavior with some other Schemes and in */
187 /*   hopes of making it easier to use macros and modules, Chibi allowed */
188 /*   top-level bindings with the same underlying symbol name to match */
189 /*   with identifier=?.  In particular, there still isn't a good way */
190 /*   to handle the case where auxiliary syntax conflicts with some other */
191 /*   binding without renaming one or the other (though SRFI 206 helps). */
192 /*   However, if people make use of this you can write Chibi programs */
193 /*   which don't work portably in other implementations, which has been */
194 /*   a source of confusion, so the default has reverted to strict R7RS. */
195 /* #define SEXP_USE_STRICT_TOPLEVEL_BINDINGS 0 */
196 
197 /* uncomment this to disable warning about references to undefined variables */
198 /*   This is something of a hack, but can be quite useful. */
199 /*   It's very fast and doesn't involve any separate analysis */
200 /*   passes. */
201 /* #define SEXP_USE_WARN_UNDEFS 0 */
202 
203 /* uncomment this to disable huffman-coded immediate symbols */
204 /*   By default (this may change) small symbols are represented */
205 /*   as immediates using a simple huffman encoding.  This keeps */
206 /*   the symbol table small, and minimizes hashing when doing a */
207 /*   lot of reading. */
208 /* #define SEXP_USE_HUFF_SYMS 0 */
209 
210 /* uncomment this to just use a single list for hash tables */
211 /*   You can trade off some space in exchange for longer read */
212 /*   times by disabling hashing and just putting all */
213 /*   non-immediate symbols in a single list. */
214 /* #define SEXP_USE_HASH_SYMS 0 */
215 
216 /* uncomment this to disable extended char names as defined in R7RS */
217 /* #define SEXP_USE_EXTENDED_CHAR_NAMES 0 */
218 
219 /* uncomment this to disable R7RS #<n>= and #<n># reader labels in source */
220 /*   The (scheme read) and (scheme write) libraries always support */
221 /*   this regardless. */
222 /* #define SEXP_USE_READER_LABELS 0 */
223 
224 /* uncomment this to disable UTF-8 string support */
225 /*   The default settings store strings in memory as UTF-8, */
226 /*   and assumes strings passed to/from the C FFI are UTF-8.  */
227 /* #define SEXP_USE_UTF8_STRINGS 0 */
228 
229 /* uncomment this to disable the string-set! opcode */
230 /*   By default (non-literal) strings are mutable. */
231 /*   Making them immutable allows for packed UTF-8 strings. */
232 /* #define SEXP_USE_MUTABLE_STRINGS 0 */
233 
234 /* uncomment this to enable precomputed index->cursor tables for strings */
235 /*   This makes string-ref faster at the expensive of making string */
236 /*   construction (including string-append and I/O) slower. */
237 /*   You can configure with SEXP_STRING_INDEX_TABLE_CHUNK_SIZE below, */
238 /*   the default is caching every 64th index (<=12.5% string overhead). */
239 /*   With a minimum of 1 you'd have up to 8x string overhead, and */
240 /*   string-ref would still be slightly slower than string-cursors, */
241 /*   and string-append would be marginally slower as well.          */
242 /*                                                                  */
243 /*   In practice, the overhead of iterating over a string with      */
244 /*   string-ref isn't noticeable until about 10k chars.  Times      */
245 /*   for iteration using the different approaches:                  */
246 /*                                                                  */
247 /*   impl\len               1000   10000  100000  1000000           */
248 /*   string-ref (utf8)         1      97    9622        x           */
249 /*   string-ref (fast)         0       2      19      216           */
250 /*   cursor-ref (srfi 130)     0       4      18      150           */
251 /*   text-ref (srfi 135)       2      27     211     2006           */
252 /*                                                                  */
253 /* #define SEXP_USE_STRING_INDEX_TABLE 1 */
254 
255 /* uncomment this to disable automatic closing of ports */
256 /*   If enabled, the underlying FILE* for file ports will be */
257 /*   automatically closed when they're garbage collected.  Doesn't */
258 /*   apply to stdin/stdout/stderr. */
259 /* #define SEXP_USE_AUTOCLOSE_PORTS 0 */
260 
261 /* uncomment this to use a 2010/01/01 epoch */
262 /*   By default chibi uses the normal 1970 unix epoch in accordance */
263 /*   with R7RS, but this can represent more times as fixnums. */
264 /* #define SEXP_USE_2010_EPOCH 1 */
265 
266 /* uncomment this to disable stack overflow checks */
267 /*   By default stacks are fairly small, so it's good to leave */
268 /*   this enabled. */
269 /* #define SEXP_USE_CHECK_STACK 0 */
270 
271 /* uncomment this to disable growing the stack on overflow */
272 /*   If enabled, chibi attempts to grow the stack on overflow, */
273 /*   up to SEXP_MAX_STACK_SIZE, otherwise a failed stack check */
274 /*   will just raise an error immediately. */
275 /* #define SEXP_USE_GROW_STACK 0 */
276 
277 /* #define SEXP_USE_DEBUG_VM 0 */
278 /*   Experts only. */
279 /*   For *very* verbose output on every VM operation. */
280 
281 /* uncomment this to make the VM adhere to alignment rules */
282 /*   This is required on some platforms, e.g. ARM */
283 /* #define SEXP_USE_ALIGNED_BYTECODE */
284 
285 /************************************************************************/
286 /* These settings are configurable but only recommended for */
287 /* experienced users, and only apply when using the native GC.  */
288 /************************************************************************/
289 
290 /* the initial heap size in bytes */
291 #ifndef SEXP_INITIAL_HEAP_SIZE
292 #define SEXP_INITIAL_HEAP_SIZE (2*1024*1024)
293 #endif
294 
295 /* the maximum heap size in bytes - if 0 there is no limit */
296 #ifndef SEXP_MAXIMUM_HEAP_SIZE
297 #define SEXP_MAXIMUM_HEAP_SIZE 0
298 #endif
299 #ifndef SEXP_MINIMUM_HEAP_SIZE
300 #define SEXP_MINIMUM_HEAP_SIZE 8*1024
301 #endif
302 
303 /* if after GC more than this percentage of memory is still in use, */
304 /* and we've not exceeded the maximum size, grow the heap */
305 #ifndef SEXP_GROW_HEAP_RATIO
306 #define SEXP_GROW_HEAP_RATIO 0.75
307 #endif
308 
309 /* how much to expand the heap size by */
310 #ifndef SEXP_GROW_HEAP_FACTOR
311 #define SEXP_GROW_HEAP_FACTOR 2  /* 1.6180339887498948482 */
312 #endif
313 
314 /* size of per-context stack that is used during gc cycles
315  * increase if you can affort extra unused memory */
316 #define SEXP_MARK_STACK_COUNT 1024
317 
318 /* the default number of opcodes to run each thread for */
319 #ifndef SEXP_DEFAULT_QUANTUM
320 #define SEXP_DEFAULT_QUANTUM 500
321 #endif
322 
323 #ifndef SEXP_MAX_ANALYZE_DEPTH
324 #define SEXP_MAX_ANALYZE_DEPTH 8192
325 #endif
326 
327 /************************************************************************/
328 /*         DEFAULTS - DO NOT MODIFY ANYTHING BELOW THIS LINE            */
329 /************************************************************************/
330 
331 #ifndef SEXP_64_BIT
332 #if defined(__amd64) || defined(__x86_64) || defined(_WIN64) || defined(_Wp64) || defined(__LP64__) || defined(__PPC64__) || defined(__mips64__) || defined(__sparc64__) || defined(__arm64)
333 #define SEXP_64_BIT 1
334 #else
335 #define SEXP_64_BIT 0
336 #endif
337 #endif
338 
339 #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)
340 #define SEXP_BSD 1
341 #else
342 #define SEXP_BSD 0
343 #if ! defined(_GNU_SOURCE) && ! defined(_WIN32) && ! defined(PLAN9)
344 #define _GNU_SOURCE
345 #endif
346 #endif
347 
348 /* Detect specific BSD */
349 #if SEXP_BSD
350 #if defined(__APPLE__)
351 #define SEXP_DARWIN 1
352 #define SEXP_FREEBSD 0
353 #define SEXP_NETBSD 0
354 #define SEXP_DRAGONFLY 0
355 #define SEXP_OPENBSD 0
356 #elif defined(__FreeBSD__)
357 #define SEXP_DARWIN 0
358 #define SEXP_FREEBSD 1
359 #define SEXP_NETBSD 0
360 #define SEXP_DRAGONFLY 0
361 #define SEXP_OPENBSD 0
362 #elif defined(__NetBSD__)
363 #define SEXP_DARWIN 0
364 #define SEXP_FREEBSD 0
365 #define SEXP_NETBSD 1
366 #define SEXP_DRAGONFLY 0
367 #define SEXP_OPENBSD 0
368 #elif defined(__DragonFly__)
369 #define SEXP_DARWIN 0
370 #define SEXP_FREEBSD 0
371 #define SEXP_NETBSD 0
372 #define SEXP_DRAGONFLY 1
373 #define SEXP_OPENBSD 0
374 #elif defined(__OpenBSD__)
375 #define SEXP_DARWIN 0
376 #define SEXP_FREEBSD 0
377 #define SEXP_NETBSD 0
378 #define SEXP_DRAGONFLY 0
379 #define SEXP_OPENBSD 1
380 #endif
381 #endif
382 
383 /* for bignum support, need a double long to store long*long */
384 /* gcc supports uint128_t, otherwise we need a custom struct */
385 #ifndef SEXP_USE_CUSTOM_LONG_LONGS
386 #if SEXP_64_BIT && !defined(__GNUC__)
387 #define SEXP_USE_CUSTOM_LONG_LONGS 1
388 #else
389 #define SEXP_USE_CUSTOM_LONG_LONGS 0
390 #endif
391 #endif
392 
393 #ifndef SEXP_USE_NO_FEATURES
394 #define SEXP_USE_NO_FEATURES 0
395 #endif
396 
397 #ifndef SEXP_USE_PEDANTIC
398 #define SEXP_USE_PEDANTIC 0
399 #endif
400 
401 /* this ensures public structs and enums are unchanged by feature toggles. */
402 /* should generally be left at 1. */
403 #ifndef SEXP_USE_STABLE_ABI
404 #define SEXP_USE_STABLE_ABI 1
405 #endif
406 
407 #ifndef SEXP_USE_GREEN_THREADS
408 #if defined(_WIN32)
409 #define SEXP_USE_GREEN_THREADS 0
410 #else
411 #define SEXP_USE_GREEN_THREADS ! SEXP_USE_NO_FEATURES
412 #endif
413 #endif
414 
415 #ifndef SEXP_USE_DEBUG_THREADS
416 #define SEXP_USE_DEBUG_THREADS 0
417 #endif
418 
419 #ifndef SEXP_USE_AUTO_FORCE
420 #define SEXP_USE_AUTO_FORCE 0
421 #endif
422 
423 #ifndef SEXP_USE_NATIVE_X86
424 #define SEXP_USE_NATIVE_X86 0
425 #endif
426 
427 #ifndef SEXP_USE_MODULES
428 #define SEXP_USE_MODULES ! SEXP_USE_NO_FEATURES
429 #endif
430 
431 #ifndef sexp_default_user_module_path
432 #define sexp_default_user_module_path "./lib:."
433 #endif
434 
435 #ifndef SEXP_USE_TYPE_DEFS
436 #define SEXP_USE_TYPE_DEFS ! SEXP_USE_NO_FEATURES
437 #endif
438 
439 #ifndef SEXP_MAXIMUM_TYPES
440 #define SEXP_MAXIMUM_TYPES ((sexp_tag_t)-1)
441 #endif
442 
443 #ifndef SEXP_USE_DL
444 #if defined(PLAN9)
445 #define SEXP_USE_DL 0
446 #else
447 #define SEXP_USE_DL ! SEXP_USE_NO_FEATURES
448 #endif
449 #endif
450 
451 #ifndef SEXP_USE_STATIC_LIBS
452 #define SEXP_USE_STATIC_LIBS 0
453 #endif
454 
455 /* don't include clibs.c - include separately or link */
456 #ifndef SEXP_USE_STATIC_LIBS_NO_INCLUDE
457 #ifdef PLAN9
458 #define SEXP_USE_STATIC_LIBS_NO_INCLUDE 0
459 #else
460 #define SEXP_USE_STATIC_LIBS_NO_INCLUDE 1
461 #endif
462 #endif
463 
464 #ifndef SEXP_USE_FULL_SOURCE_INFO
465 #define SEXP_USE_FULL_SOURCE_INFO ! SEXP_USE_NO_FEATURES
466 #endif
467 
468 #ifndef SEXP_USE_SIMPLIFY
469 #define SEXP_USE_SIMPLIFY ! SEXP_USE_NO_FEATURES
470 #endif
471 
472 #ifndef SEXP_USE_BOEHM
473 #define SEXP_USE_BOEHM 0
474 #endif
475 
476 #ifdef SEXP_USE_UNIFY_FILENOS_BY_NUMBER
477 #define SEXP_USE_UNIFY_FILENOS_BY_NUMBER 0
478 #endif
479 
480 #ifndef SEXP_USE_WEAK_REFERENCES
481 #if SEXP_USE_UNIFY_FILENOS_BY_NUMBER
482 #define SEXP_USE_WEAK_REFERENCES 1
483 #else
484 #define SEXP_USE_WEAK_REFERENCES ! SEXP_USE_NO_FEATURES
485 #endif
486 #endif
487 
488 #ifndef SEXP_USE_FIXED_CHUNK_SIZE_HEAPS
489 #define SEXP_USE_FIXED_CHUNK_SIZE_HEAPS 0
490 #endif
491 
492 #ifndef SEXP_USE_MALLOC
493 #define SEXP_USE_MALLOC 0
494 #endif
495 
496 #ifndef SEXP_USE_LIMITED_MALLOC
497 #define SEXP_USE_LIMITED_MALLOC 0
498 #endif
499 
500 #ifndef SEXP_USE_MMAP_GC
501 #define SEXP_USE_MMAP_GC 0
502 #endif
503 
504 #ifndef SEXP_USE_DEBUG_GC
505 #define SEXP_USE_DEBUG_GC 0
506 #endif
507 
508 #ifndef SEXP_USE_TIME_GC
509 #if SEXP_USE_DEBUG_GC > 0 || defined(__linux) || SEXP_BSD
510 #define SEXP_USE_TIME_GC 1
511 #else
512 #define SEXP_USE_TIME_GC 0
513 #endif
514 #endif
515 
516 #ifndef SEXP_USE_SAFE_GC_MARK
517 #define SEXP_USE_SAFE_GC_MARK SEXP_USE_DEBUG_GC > 1
518 #endif
519 
520 #ifndef SEXP_USE_CONSERVATIVE_GC
521 #define SEXP_USE_CONSERVATIVE_GC 0
522 #endif
523 
524 #ifndef SEXP_USE_FINALIZERS
525 #define SEXP_USE_FINALIZERS 1
526 #endif
527 
528 #ifndef SEXP_USE_TRACK_ALLOC_SOURCE
529 #define SEXP_USE_TRACK_ALLOC_SOURCE SEXP_USE_DEBUG_GC > 2
530 #endif
531 
532 #ifndef SEXP_USE_TRACK_ALLOC_BACKTRACE
533 #define SEXP_USE_TRACK_ALLOC_BACKTRACE SEXP_USE_TRACK_ALLOC_SOURCE
534 #endif
535 
536 #ifndef SEXP_USE_TRACK_ALLOC_TIMES
537 #define SEXP_USE_TRACK_ALLOC_TIMES 0
538 #endif
539 
540 #ifndef SEXP_USE_TRACK_ALLOC_SIZES
541 #define SEXP_USE_TRACK_ALLOC_SIZES 0
542 #endif
543 
544 #ifndef SEXP_ALLOC_HISTOGRAM_BUCKETS
545 #define SEXP_ALLOC_HISTOGRAM_BUCKETS 32
546 #endif
547 
548 #ifndef SEXP_BACKTRACE_SIZE
549 #define SEXP_BACKTRACE_SIZE 3
550 #endif
551 
552 #ifndef SEXP_USE_HEADER_MAGIC
553 #define SEXP_USE_HEADER_MAGIC 0
554 #endif
555 
556 #ifndef SEXP_GC_PAD
557 #define SEXP_GC_PAD 0
558 #endif
559 
560 #ifndef SEXP_USE_SAFE_ACCESSORS
561 #define SEXP_USE_SAFE_ACCESSORS 0
562 #endif
563 
564 #ifndef SEXP_USE_SAFE_VECTOR_ACCESSORS
565 #define SEXP_USE_SAFE_VECTOR_ACCESSORS 0
566 #endif
567 
568 #ifndef SEXP_USE_GLOBAL_HEAP
569 #if SEXP_USE_BOEHM || SEXP_USE_MALLOC
570 #define SEXP_USE_GLOBAL_HEAP 1
571 #else
572 #define SEXP_USE_GLOBAL_HEAP 0
573 #endif
574 #endif
575 
576 #ifndef SEXP_USE_GLOBAL_SYMBOLS
577 #if SEXP_USE_BOEHM || SEXP_USE_MALLOC
578 #define SEXP_USE_GLOBAL_SYMBOLS 1
579 #else
580 #define SEXP_USE_GLOBAL_SYMBOLS 0
581 #endif
582 #endif
583 
584 #ifndef SEXP_USE_STRICT_TOPLEVEL_BINDINGS
585 #define SEXP_USE_STRICT_TOPLEVEL_BINDINGS 1
586 #endif
587 
588 #if SEXP_USE_STRICT_TOPLEVEL_BINDINGS
589 #define SEXP_USE_RENAME_BINDINGS 1
590 #else
591 #ifndef SEXP_USE_RENAME_BINDINGS
592 #define SEXP_USE_RENAME_BINDINGS 1
593 #endif
594 #endif
595 
596 #ifndef SEXP_USE_SPLICING_LET_SYNTAX
597 #define SEXP_USE_SPLICING_LET_SYNTAX 0
598 #endif
599 
600 #ifndef SEXP_USE_FLAT_SYNTACTIC_CLOSURES
601 #define SEXP_USE_FLAT_SYNTACTIC_CLOSURES 0
602 #endif
603 
604 #ifndef SEXP_USE_UNWRAPPED_TOPLEVEL_BINDINGS
605 #define SEXP_USE_UNWRAPPED_TOPLEVEL_BINDINGS 0
606 #endif
607 
608 #ifndef SEXP_USE_EXTENDED_FCALL
609 #define SEXP_USE_EXTENDED_FCALL (!SEXP_USE_NO_FEATURES)
610 #endif
611 
612 #ifndef SEXP_USE_FLONUMS
613 #define SEXP_USE_FLONUMS (!SEXP_USE_NO_FEATURES)
614 #endif
615 
616 #ifndef SEXP_USE_BIGNUMS
617 #define SEXP_USE_BIGNUMS (!SEXP_USE_NO_FEATURES)
618 #endif
619 
620 #ifndef SEXP_USE_RATIOS
621 #define SEXP_USE_RATIOS SEXP_USE_FLONUMS
622 #endif
623 
624 #ifndef SEXP_USE_COMPLEX
625 #define SEXP_USE_COMPLEX SEXP_USE_FLONUMS
626 #endif
627 
628 #if (SEXP_USE_RATIOS || SEXP_USE_COMPLEX)
629 #undef SEXP_USE_BIGNUMS
630 #define SEXP_USE_BIGNUMS 1
631 #undef SEXP_USE_FLONUMS
632 #define SEXP_USE_FLONUMS 1
633 #endif
634 
635 #ifndef SEXP_USE_INFINITIES
636 #if defined(PLAN9) || ! SEXP_USE_FLONUMS
637 #define SEXP_USE_INFINITIES 0
638 #else
639 #define SEXP_USE_INFINITIES ! SEXP_USE_NO_FEATURES
640 #endif
641 #endif
642 
643 #ifndef SEXP_USE_IMMEDIATE_FLONUMS
644 #define SEXP_USE_IMMEDIATE_FLONUMS 0
645 #endif
646 
647 #ifndef SEXP_USE_IEEE_EQV
648 #define SEXP_USE_IEEE_EQV SEXP_USE_FLONUMS
649 #endif
650 
651 #ifndef SEXP_USE_PLACEHOLDER_DIGITS
652 #define SEXP_USE_PLACEHOLDER_DIGITS 0
653 #endif
654 
655 #ifndef SEXP_PLACEHOLDER_DIGIT
656 #define SEXP_PLACEHOLDER_DIGIT '#'
657 #endif
658 
659 #ifndef SEXP_USE_MATH
660 #define SEXP_USE_MATH SEXP_USE_FLONUMS && ! SEXP_USE_NO_FEATURES
661 #endif
662 
663 #ifndef SEXP_USE_ESCAPE_NEWLINE
664 #define SEXP_USE_ESCAPE_NEWLINE ! SEXP_USE_NO_FEATURES
665 #endif
666 
667 #ifndef SEXP_USE_ESCAPE_REQUIRES_TRAILING_SEMI_COLON
668 #define SEXP_USE_ESCAPE_REQUIRES_TRAILING_SEMI_COLON SEXP_USE_PEDANTIC
669 #endif
670 
671 #ifndef SEXP_USE_OBJECT_BRACE_LITERALS
672 #define SEXP_USE_OBJECT_BRACE_LITERALS (SEXP_USE_TYPE_DEFS && !SEXP_USE_NO_FEATURES)
673 #endif
674 
675 #ifndef SEXP_USE_TYPE_PRINTERS
676 #define SEXP_USE_TYPE_PRINTERS SEXP_USE_OBJECT_BRACE_LITERALS
677 #endif
678 
679 #ifndef SEXP_USE_UNIFORM_VECTOR_LITERALS
680 #define SEXP_USE_UNIFORM_VECTOR_LITERALS ! SEXP_USE_NO_FEATURES
681 #endif
682 
683 #ifndef SEXP_USE_BYTEVECTOR_LITERALS
684 #define SEXP_USE_BYTEVECTOR_LITERALS SEXP_USE_UNIFORM_VECTOR_LITERALS
685 #endif
686 
687 #ifndef SEXP_BYTEVECTOR_HEX_LITERALS
688 #define SEXP_BYTEVECTOR_HEX_LITERALS SEXP_USE_BYTEVECTOR_LITERALS
689 #endif
690 
691 
692 #ifndef SEXP_USE_SELF_PARAMETER
693 #define SEXP_USE_SELF_PARAMETER 1
694 #endif
695 
696 #ifndef SEXP_USE_WARN_UNDEFS
697 #define SEXP_USE_WARN_UNDEFS ! SEXP_USE_NO_FEATURES
698 #endif
699 
700 #ifndef SEXP_USE_HUFF_SYMS
701 #define SEXP_USE_HUFF_SYMS ! SEXP_USE_NO_FEATURES
702 #endif
703 
704 #ifndef SEXP_USE_HASH_SYMS
705 #define SEXP_USE_HASH_SYMS ! SEXP_USE_NO_FEATURES
706 #endif
707 
708 #ifndef SEXP_USE_FOLD_CASE_SYMS
709 #define SEXP_USE_FOLD_CASE_SYMS ! SEXP_USE_NO_FEATURES
710 #endif
711 
712 #ifndef SEXP_DEFAULT_FOLD_CASE_SYMS
713 #define SEXP_DEFAULT_FOLD_CASE_SYMS 0
714 #endif
715 
716 /* experimental optimization to use jumps instead of the TAIL-CALL opcode */
717 #ifndef SEXP_USE_TAIL_JUMPS
718 /* #define SEXP_USE_TAIL_JUMPS ! SEXP_USE_NO_FEATURES */
719 #define SEXP_USE_TAIL_JUMPS 0
720 #endif
721 
722 #ifndef SEXP_USE_RESERVE_OPCODE
723 #define SEXP_USE_RESERVE_OPCODE SEXP_USE_TAIL_JUMPS
724 #endif
725 
726 /* experimental optimization to avoid boxing locals which aren't set! */
727 #ifndef SEXP_USE_UNBOXED_LOCALS
728 /* #define SEXP_USE_UNBOXED_LOCALS ! SEXP_USE_NO_FEATURES */
729 #define SEXP_USE_UNBOXED_LOCALS 0
730 #endif
731 
732 #ifndef SEXP_USE_DEBUG_VM
733 #define SEXP_USE_DEBUG_VM 0
734 #endif
735 
736 #ifndef SEXP_USE_PROFILE_VM
737 #define SEXP_USE_PROFILE_VM 0
738 #endif
739 
740 #ifndef SEXP_USE_EXTENDED_CHAR_NAMES
741 #define SEXP_USE_EXTENDED_CHAR_NAMES ! SEXP_USE_NO_FEATURES
742 #endif
743 
744 #ifndef SEXP_USE_READER_LABELS
745 #define SEXP_USE_READER_LABELS ! SEXP_USE_NO_FEATURES
746 #endif
747 
748 #ifndef SEXP_USE_UTF8_STRINGS
749 #define SEXP_USE_UTF8_STRINGS ! SEXP_USE_NO_FEATURES
750 #endif
751 
752 #ifndef SEXP_USE_MUTABLE_STRINGS
753 #define SEXP_USE_MUTABLE_STRINGS 1
754 #endif
755 
756 #if (SEXP_USE_UTF8_STRINGS && SEXP_USE_MUTABLE_STRINGS)
757 #define SEXP_USE_PACKED_STRINGS 0
758 #endif
759 #ifndef SEXP_USE_PACKED_STRINGS
760 #define SEXP_USE_PACKED_STRINGS 1
761 #endif
762 
763 #if SEXP_USE_PACKED_STRINGS
764 #define SEXP_USE_STRING_INDEX_TABLE 0
765 #endif
766 #ifndef SEXP_USE_STRING_INDEX_TABLE
767 #define SEXP_USE_STRING_INDEX_TABLE 0
768 #endif
769 
770 /* for every chunk_size indexes store the precomputed offset */
771 #ifndef SEXP_STRING_INDEX_TABLE_CHUNK_SIZE
772 #define SEXP_STRING_INDEX_TABLE_CHUNK_SIZE 64
773 #endif
774 
775 #ifndef SEXP_USE_DISJOINT_STRING_CURSORS
776 #define SEXP_USE_DISJOINT_STRING_CURSORS SEXP_USE_UTF8_STRINGS
777 #endif
778 
779 #ifndef SEXP_USE_AUTOCLOSE_PORTS
780 #define SEXP_USE_AUTOCLOSE_PORTS ! SEXP_USE_NO_FEATURES
781 #endif
782 
783 #ifndef SEXP_USE_GC_FILE_DESCRIPTORS
784 #ifdef PLAN9
785 #define SEXP_USE_GC_FILE_DESCRIPTORS 0
786 #else
787 #define SEXP_USE_GC_FILE_DESCRIPTORS (SEXP_USE_AUTOCLOSE_PORTS &&!SEXP_USE_BOEHM)
788 #endif
789 #endif
790 
791 #ifndef SEXP_USE_BIDIRECTIONAL_PORTS
792 #define SEXP_USE_BIDIRECTIONAL_PORTS 0
793 #endif
794 
795 #ifndef SEXP_PORT_BUFFER_SIZE
796 #define SEXP_PORT_BUFFER_SIZE 4096
797 #endif
798 
799 #ifndef SEXP_USE_NTP_GETTIME
800 #define SEXP_USE_NTP_GETTIME 0
801 #endif
802 
803 #ifndef SEXP_USE_2010_EPOCH
804 #define SEXP_USE_2010_EPOCH 0
805 #endif
806 
807 #ifndef SEXP_EPOCH_OFFSET
808 #if SEXP_USE_2010_EPOCH
809 #define SEXP_EPOCH_OFFSET 1262271600
810 #else
811 #define SEXP_EPOCH_OFFSET 0
812 #endif
813 #endif
814 
815 #ifndef SEXP_USE_CHECK_STACK
816 #define SEXP_USE_CHECK_STACK ! SEXP_USE_NO_FEATURES
817 #endif
818 
819 #ifndef SEXP_USE_GROW_STACK
820 #define SEXP_USE_GROW_STACK SEXP_USE_CHECK_STACK && ! SEXP_USE_NO_FEATURES
821 #endif
822 
823 #ifndef SEXP_USE_LONG_PROCEDURE_ARGS
824 #define SEXP_USE_LONG_PROCEDURE_ARGS ! SEXP_USE_NO_FEATURES
825 #endif
826 
827 #ifndef SEXP_INIT_BCODE_SIZE
828 #define SEXP_INIT_BCODE_SIZE 128
829 #endif
830 #ifndef SEXP_INIT_STACK_SIZE
831 #if SEXP_USE_CHECK_STACK
832 #define SEXP_INIT_STACK_SIZE 1024
833 #else
834 #define SEXP_INIT_STACK_SIZE 8192
835 #endif
836 #endif
837 #ifndef SEXP_MAX_STACK_SIZE
838 #define SEXP_MAX_STACK_SIZE SEXP_INIT_STACK_SIZE*1000
839 #endif
840 
841 #ifndef SEXP_MAX_VECTOR_LENGTH
842 #define SEXP_MAX_VECTOR_LENGTH (SEXP_MAX_FIXNUM >> 1)
843 #endif
844 
845 #ifndef SEXP_DEFAULT_EQUAL_DEPTH
846 #define SEXP_DEFAULT_EQUAL_DEPTH 10000
847 #endif
848 
849 #ifndef SEXP_DEFAULT_EQUAL_BOUND
850 #define SEXP_DEFAULT_EQUAL_BOUND 100000000
851 #endif
852 
853 #ifndef SEXP_DEFAULT_WRITE_BOUND
854 #define SEXP_DEFAULT_WRITE_BOUND 10000
855 #endif
856 
857 #ifndef SEXP_STRIP_SYNCLOS_BOUND
858 #define SEXP_STRIP_SYNCLOS_BOUND 10000
859 #endif
860 
861 #ifndef SEXP_POLL_SLEEP_TIME
862 #define SEXP_POLL_SLEEP_TIME 5000
863 #define SEXP_POLL_SLEEP_TIME_MS 5
864 #endif
865 
866 #ifndef SEXP_USE_IMAGE_LOADING
867 #define SEXP_USE_IMAGE_LOADING SEXP_USE_DL && SEXP_64_BIT && !SEXP_USE_GLOBAL_HEAP && !SEXP_USE_BOEHM && !SEXP_USE_NO_FEATURES
868 #endif
869 
870 #ifndef SEXP_USE_UNSAFE_PUSH
871 #define SEXP_USE_UNSAFE_PUSH 0
872 #endif
873 
874 #ifndef SEXP_USE_MAIN_HELP
875 #define SEXP_USE_MAIN_HELP ! SEXP_USE_NO_FEATURES
876 #endif
877 
878 #ifndef SEXP_USE_MAIN_ERROR_ADVISE
879 #define SEXP_USE_MAIN_ERROR_ADVISE ! SEXP_USE_NO_FEATURES
880 #endif
881 
882 #ifndef SEXP_USE_SEND_FILE
883 #define SEXP_USE_SEND_FILE 0
884 /* #define SEXP_USE_SEND_FILE (__linux || SEXP_BSD) */
885 #endif
886 
887 #if SEXP_USE_NATIVE_X86
888 #undef SEXP_USE_BOEHM
889 #define SEXP_USE_BOEHM 1
890 #undef SEXP_USE_FLONUMS
891 #define SEXP_USE_FLONUMS 0
892 #undef SEXP_USE_BIGNUMS
893 #define SEXP_USE_BIGNUMS 0
894 #undef SEXP_USE_RATIOS
895 #define SEXP_USE_RATIOS 0
896 #undef SEXP_USE_COMPLEX
897 #define SEXP_USE_COMPLEX 0
898 #undef SEXP_USE_UTF8_STRINGS
899 #define SEXP_USE_UTF8_STRINGS 0
900 #undef SEXP_USE_SIMPLIFY
901 #define SEXP_USE_SIMPLIFY 0
902 #endif
903 
904 #ifndef SEXP_USE_ALIGNED_BYTECODE
905 #if defined(__arm__) || defined(__sparc__) || defined(__sparc64__) || defined(__mips__) || defined(__mips64__)
906 #define SEXP_USE_ALIGNED_BYTECODE 1
907 #else
908 #define SEXP_USE_ALIGNED_BYTECODE 0
909 #endif
910 #endif
911 
912 #ifndef SEXP_USE_SIGNED_SHIFTS
913 #define SEXP_USE_SIGNED_SHIFTS 0
914 #endif
915 
916 #ifdef PLAN9
917 #define strcasecmp cistrcmp
918 #define strncasecmp cistrncmp
919 #define strcasestr cistrstr
920 #define round(x) floor((x)+0.5)
921 #define trunc(x) floor((x)+0.5*(((x)<0)?1:0))
922 #define isinf(x) (isInf(x,1) || isInf(x,-1))
923 #define isnan(x) isNaN(x)
924 #elif defined(_WIN32)
925 #define SHUT_RD 0 /* SD_RECEIVE */
926 #define SHUT_WR 1 /* SD_SEND */
927 #define SHUT_RDWR 2 /* SD_BOTH */
928 #ifdef _MSC_VER
929 #define _CRT_SECURE_NO_WARNINGS 1
930 #define _CRT_NONSTDC_NO_DEPRECATE 1
931 #define _USE_MATH_DEFINES /* For M_LN10 */
932 #define strcasecmp _stricmp
933 #define strncasecmp _strnicmp
934 #pragma warning(disable:4146) /* unary minus operator to unsigned type */
935 #if _MSC_VER < 1900
936 #define snprintf(buf, len, fmt, val) sprintf(buf, fmt, val)
937 #define strcasecmp lstrcmpi
938 #define strncasecmp(s1, s2, n) lstrcmpi(s1, s2)
939 #define round(x) floor((x)+0.5)
940 #define trunc(x) floor((x)+0.5*(((x)<0)?1:0))
941 #define isnan(x) (x!=x)
942 #define isinf(x) (x > DBL_MAX || x < -DBL_MAX)
943 #endif
944 #elif !defined(__MINGW32__)
945 #error Unknown Win32 compiler!
946 #endif
947 #endif
948 
949 #ifdef _WIN32
950 #define sexp_pos_infinity (DBL_MAX*DBL_MAX)
951 #define sexp_neg_infinity -sexp_pos_infinity
952 #define sexp_nan log(-2)
953 #elif PLAN9
954 #define sexp_pos_infinity Inf(1)
955 #define sexp_neg_infinity Inf(-1)
956 #define sexp_nan NaN()
957 #else
958 #define sexp_pos_infinity (1.0/0.0)
959 #define sexp_neg_infinity -sexp_pos_infinity
960 #define sexp_nan (0.0/0.0)
961 #endif
962 
963 #ifdef _WIN32
964 #ifdef SEXP_STATIC_LIBRARY
965 #define SEXP_API    extern
966 #else
967 #ifdef BUILDING_DLL
968 #define SEXP_API    __declspec(dllexport)
969 #else
970 #define SEXP_API    __declspec(dllimport)
971 #endif
972 #endif
973 #else
974 #define SEXP_API    extern
975 #endif
976 
977 /************************************************************************/
978 /* Feature signature.  Used for image files and dynamically loaded      */
979 /* libraries to verify they are compatible with the compiled options .  */
980 /************************************************************************/
981 
982 typedef char sexp_abi_identifier_t[8];
983 
984 #if SEXP_USE_BOEHM
985 #define SEXP_ABI_GC "b"
986 #elif (SEXP_USE_HEADER_MAGIC && SEXP_USE_TRACK_ALLOC_SOURCE)
987 #define SEXP_ABI_GC "d"
988 #elif SEXP_USE_HEADER_MAGIC
989 #define SEXP_ABI_GC "m"
990 #elif SEXP_USE_TRACK_ALLOC_SOURCE
991 #define SEXP_ABI_GC "s"
992 #else
993 #define SEXP_ABI_GC "c"
994 #endif
995 
996 #if SEXP_USE_NATIVE_X86
997 #define SEXP_ABI_BACKEND "x"
998 #else
999 #define SEXP_ABI_BACKEND "v"
1000 #endif
1001 
1002 #if (SEXP_USE_RESERVE_OPCODE && SEXP_USE_AUTO_FORCE)
1003 #define SEXP_ABI_INSTRUCTIONS "*"
1004 #elif SEXP_USE_RESERVE_OPCODE
1005 #define SEXP_ABI_INSTRUCTIONS "r"
1006 #elif SEXP_USE_AUTO_FORCE
1007 #define SEXP_ABI_INSTRUCTIONS "f"
1008 #else
1009 #define SEXP_ABI_INSTRUCTIONS "-"
1010 #endif
1011 
1012 #if SEXP_USE_GREEN_THREADS
1013 #define SEXP_ABI_THREADS "g"
1014 #else
1015 #define SEXP_ABI_THREADS "-"
1016 #endif
1017 
1018 #if SEXP_USE_MODULES
1019 #define SEXP_ABI_MODULES "m"
1020 #else
1021 #define SEXP_ABI_MODULES "-"
1022 #endif
1023 
1024 #if (SEXP_USE_COMPLEX && SEXP_USE_RATIOS)
1025 #define SEXP_ABI_NUMBERS "*"
1026 #elif SEXP_USE_COMPLEX
1027 #define SEXP_ABI_NUMBERS "c"
1028 #elif SEXP_USE_RATIOS
1029 #define SEXP_ABI_NUMBERS "r"
1030 #elif SEXP_USE_BIGNUMS
1031 #define SEXP_ABI_NUMBERS "b"
1032 #elif SEXP_USE_INFINITIES
1033 #define SEXP_ABI_NUMBERS "i"
1034 #elif SEXP_USE_FLONUMS
1035 #define SEXP_ABI_NUMBERS "f"
1036 #else
1037 #define SEXP_ABI_NUMBERS "-"
1038 #endif
1039 
1040 #if SEXP_USE_UTF8_STRINGS
1041 #define SEXP_ABI_STRINGS "u"
1042 #elif SEXP_USE_PACKED_STRINGS
1043 #define SEXP_ABI_STRINGS "p"
1044 #else
1045 #define SEXP_ABI_STRINGS "-"
1046 #endif
1047 
1048 #if SEXP_USE_HUFF_SYMS
1049 #define SEXP_ABI_SYMS "h"
1050 #else
1051 #define SEXP_ABI_SYMS "-"
1052 #endif
1053 
1054 #define SEXP_ABI_IDENTIFIER \
1055   (SEXP_ABI_GC SEXP_ABI_BACKEND SEXP_ABI_INSTRUCTIONS SEXP_ABI_THREADS \
1056    SEXP_ABI_MODULES SEXP_ABI_NUMBERS SEXP_ABI_STRINGS SEXP_ABI_SYMS)
1057 
1058 #define sexp_version_compatible(ctx, subver, genver) (strcmp((subver), (genver)) == 0)
1059 #define sexp_abi_compatible(ctx, subabi, genabi) (strncmp((subabi), (genabi), sizeof(sexp_abi_identifier_t)) == 0)
1060