1 /*
2 * Copyright (c) 2021 Calvin Rose
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to
6 * deal in the Software without restriction, including without limitation the
7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 * sell copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 * IN THE SOFTWARE.
21 */
22 
23 #include "janetconf.h"
24 
25 #ifndef JANET_H_defined
26 #define JANET_H_defined
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 /* Variable length arrays are ok */
33 #ifdef _MSC_VER
34 #pragma warning( push )
35 #pragma warning( disable : 4200 )
36 #endif
37 
38 /***** START SECTION CONFIG *****/
39 
40 #ifndef JANET_VERSION
41 #define JANET_VERSION "latest"
42 #endif
43 
44 #ifndef JANET_BUILD
45 #define JANET_BUILD "local"
46 #endif
47 
48 /*
49  * Detect OS and endianess.
50  * From webkit source. There is likely some extreneous
51  * detection for unsupported platforms
52  */
53 
54 /* Check for any flavor of BSD (except apple) */
55 #if defined(__FreeBSD__) || defined(__DragonFly__) || \
56     defined(__NetBSD__) || defined(__OpenBSD__)
57 #define JANET_BSD 1
58 #endif
59 
60 /* Check for Mac */
61 #ifdef __APPLE__
62 #define JANET_APPLE 1
63 #endif
64 
65 /* Check for Linux */
66 #ifdef __linux__
67 #define JANET_LINUX 1
68 #endif
69 
70 /* Check Unix */
71 #if defined(_AIX) \
72     || defined(__APPLE__) /* Darwin */ \
73     || defined(__FreeBSD__) || defined(__DragonFly__) \
74     || defined(__FreeBSD_kernel__) \
75     || defined(__GNU__) /* GNU/Hurd */ \
76     || defined(__HAIKU__) \
77     || defined(__linux__) \
78     || defined(__NetBSD__) \
79     || defined(__OpenBSD__) \
80     || defined(__QNXNTO__) \
81     || defined(sun) || defined(__sun) /* Solaris */ \
82     || defined(unix) || defined(__unix) || defined(__unix__)
83 #define JANET_POSIX 1
84 #elif defined(__EMSCRIPTEN__)
85 #define JANET_WEB 1
86 #elif defined(WIN32) || defined(_WIN32)
87 #define JANET_WINDOWS 1
88 #endif
89 
90 /* Check 64-bit vs 32-bit */
91 #if ((defined(__x86_64__) || defined(_M_X64)) \
92      && (defined(JANET_POSIX) || defined(JANET_WINDOWS))) \
93     || (defined(_WIN64)) /* Windows 64 bit */ \
94     || (defined(__ia64__) && defined(__LP64__)) /* Itanium in LP64 mode */ \
95     || defined(__alpha__) /* DEC Alpha */ \
96     || (defined(__sparc__) && defined(__arch64__) || defined (__sparcv9)) /* BE */ \
97     || defined(__s390x__) /* S390 64-bit (BE) */ \
98     || (defined(__ppc64__) || defined(__PPC64__)) \
99     || defined(__aarch64__) /* ARM 64-bit */
100 #define JANET_64 1
101 #else
102 #define JANET_32 1
103 #endif
104 
105 /* Check big endian */
106 #if defined(__LITTLE_ENDIAN__) || \
107     (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
108 /* If we know the target is LE, always use that - e.g. ppc64 little endian
109  * defines the __LITTLE_ENDIAN__ macro in the ABI spec, so we can rely
110  * on that and if that's not defined, fall back to big endian assumption
111  */
112 #define JANET_LITTLE_ENDIAN 1
113 #elif defined(__MIPSEB__) /* MIPS 32-bit */ \
114     || defined(__ppc__) || defined(__PPC__) /* CPU(PPC) - PowerPC 32-bit */ \
115     || defined(__powerpc__) || defined(__powerpc) || defined(__POWERPC__) \
116     || defined(_M_PPC) || defined(__PPC) \
117     || defined(__ppc64__) || defined(__PPC64__) /* PowerPC 64-bit */ \
118     || defined(__sparc)   /* Sparc 32bit */  \
119     || defined(__sparc__) /* Sparc 64-bit */ \
120     || defined(__s390x__) /* S390 64-bit */ \
121     || defined(__s390__)  /* S390 32-bit */ \
122     || defined(__ARMEB__) /* ARM big endian */ \
123     || ((defined(__CC_ARM) || defined(__ARMCC__)) /* ARM RealView compiler */ \
124         && defined(__BIG_ENDIAN))
125 #define JANET_BIG_ENDIAN 1
126 #else
127 #define JANET_LITTLE_ENDIAN 1
128 #endif
129 
130 /* Limits for converting doubles to 64 bit integers */
131 #define JANET_INTMAX_DOUBLE 9007199254740992.0
132 #define JANET_INTMIN_DOUBLE (-9007199254740992.0)
133 #define JANET_INTMAX_INT64 9007199254740992
134 #define JANET_INTMIN_INT64 (-9007199254740992)
135 
136 /* Check emscripten */
137 #ifdef __EMSCRIPTEN__
138 #define JANET_NO_DYNAMIC_MODULES
139 #define JANET_NO_PROCESSES
140 #endif
141 
142 /* Check sun */
143 #ifdef __sun
144 #define JANET_NO_UTC_MKTIME
145 #endif
146 
147 /* Define how global janet state is declared */
148 /* Also enable the thread library only if not single-threaded */
149 #ifdef JANET_SINGLE_THREADED
150 #define JANET_THREAD_LOCAL
151 #undef JANET_THREADS
152 #elif defined(__GNUC__)
153 #define JANET_THREAD_LOCAL __thread
154 #elif defined(_MSC_BUILD)
155 #define JANET_THREAD_LOCAL __declspec(thread)
156 #else
157 #define JANET_THREAD_LOCAL
158 #undef JANET_THREADS
159 #endif
160 
161 /* Enable or disable dynamic module loading. Enabled by default. */
162 #ifndef JANET_NO_DYNAMIC_MODULES
163 #define JANET_DYNAMIC_MODULES
164 #endif
165 
166 /* Enable or disable the assembler. Enabled by default. */
167 #ifndef JANET_NO_ASSEMBLER
168 #define JANET_ASSEMBLER
169 #endif
170 
171 /* Enable or disable the peg module */
172 #ifndef JANET_NO_PEG
173 #define JANET_PEG
174 #endif
175 
176 /* Enable or disable event loop */
177 #if !defined(JANET_NO_EV) && !defined(__EMSCRIPTEN__)
178 #define JANET_EV
179 #endif
180 
181 /* Enable or disable networking */
182 #if defined(JANET_EV) && !defined(JANET_NO_NET) && !defined(__EMSCRIPTEN__)
183 #define JANET_NET
184 #endif
185 
186 /* Enable or disable large int types (for now 64 bit, maybe 128 / 256 bit integer types) */
187 #ifndef JANET_NO_INT_TYPES
188 #define JANET_INT_TYPES
189 #endif
190 
191 /* Enable or disable epoll on Linux */
192 #if defined(JANET_LINUX) && !defined(JANET_EV_NO_EPOLL)
193 #define JANET_EV_EPOLL
194 #endif
195 
196 /* Enable or disable kqueue on BSD */
197 #if defined(JANET_BSD) && !defined(JANET_EV_NO_KQUEUE)
198 #define JANET_EV_KQUEUE
199 #endif
200 
201 /* Enable or disable kqueue on Apple */
202 #if defined(JANET_APPLE) && !defined(JANET_EV_NO_KQUEUE)
203 #define JANET_EV_KQUEUE
204 #endif
205 
206 /* How to export symbols */
207 #ifndef JANET_API
208 #ifdef JANET_WINDOWS
209 #define JANET_API __declspec(dllexport)
210 #else
211 #define JANET_API __attribute__((visibility ("default")))
212 #endif
213 #endif
214 
215 /* Tell complier some functions don't return */
216 #ifndef JANET_NO_RETURN
217 #ifdef JANET_WINDOWS
218 #define JANET_NO_RETURN __declspec(noreturn)
219 #else
220 #define JANET_NO_RETURN __attribute__((noreturn))
221 #endif
222 #endif
223 
224 /* Prevent some recursive functions from recursing too deeply
225  * ands crashing (the parser). Instead, error out. */
226 #define JANET_RECURSION_GUARD 1024
227 
228 /* Maximum depth to follow table prototypes before giving up and returning nil. */
229 #define JANET_MAX_PROTO_DEPTH 200
230 
231 /* Maximum depth to follow table prototypes before giving up and returning nil. */
232 #define JANET_MAX_MACRO_EXPAND 200
233 
234 /* Define default max stack size for stacks before raising a stack overflow error.
235  * This can also be set on a per fiber basis. */
236 #ifndef JANET_STACK_MAX
237 #define JANET_STACK_MAX 0x7fffffff
238 #endif
239 
240 /* Use nanboxed values - uses 8 bytes per value instead of 12 or 16.
241  * To turn of nanboxing, for debugging purposes or for certain
242  * architectures (Nanboxing only tested on x86 and x64), comment out
243  * the JANET_NANBOX define.*/
244 
245 #if defined(_M_ARM64) || defined(_M_ARM) || defined(__aarch64__)
246 #define JANET_NO_NANBOX
247 #endif
248 
249 #ifndef JANET_NO_NANBOX
250 #ifdef JANET_32
251 #define JANET_NANBOX_32
252 #elif defined(__x86_64__) || defined(_WIN64)
253 /* We will only enable nanboxing by default on 64 bit systems
254  * on x86. This is mainly because the approach is tied to the
255  * implicit 47 bit address space. */
256 #define JANET_NANBOX_64
257 #endif
258 #endif
259 
260 /* Runtime config constants */
261 #ifdef JANET_NO_NANBOX
262 #define JANET_NANBOX_BIT 0
263 #else
264 #define JANET_NANBOX_BIT 0x1
265 #endif
266 
267 #ifdef JANET_SINGLE_THREADED
268 #define JANET_SINGLE_THREADED_BIT 0x2
269 #else
270 #define JANET_SINGLE_THREADED_BIT 0
271 #endif
272 
273 #define JANET_CURRENT_CONFIG_BITS \
274     (JANET_SINGLE_THREADED_BIT | \
275      JANET_NANBOX_BIT)
276 
277 /* Represents the settings used to compile Janet, as well as the version */
278 typedef struct {
279     unsigned major;
280     unsigned minor;
281     unsigned patch;
282     unsigned bits;
283 } JanetBuildConfig;
284 
285 /* Get config of current compilation unit. */
286 #ifdef __cplusplus
287 /* C++11 syntax */
288 #define janet_config_current() (JanetBuildConfig { \
289     JANET_VERSION_MAJOR, \
290     JANET_VERSION_MINOR, \
291     JANET_VERSION_PATCH, \
292     JANET_CURRENT_CONFIG_BITS })
293 #else
294 /* C99 syntax */
295 #define janet_config_current() ((JanetBuildConfig){ \
296     JANET_VERSION_MAJOR, \
297     JANET_VERSION_MINOR, \
298     JANET_VERSION_PATCH, \
299     JANET_CURRENT_CONFIG_BITS })
300 #endif
301 
302 /* What to do when out of memory */
303 #ifndef JANET_OUT_OF_MEMORY
304 #include <stdio.h>
305 #define JANET_OUT_OF_MEMORY do { fprintf(stderr, "janet out of memory\n"); exit(1); } while (0)
306 #endif
307 
308 /***** END SECTION CONFIG *****/
309 
310 /***** START SECTION TYPES *****/
311 
312 #ifdef JANET_WINDOWS
313 /* Must be defined before including stdlib.h */
314 #define _CRT_RAND_S
315 #endif
316 
317 #include <stdlib.h>
318 #include <stdint.h>
319 #include <string.h>
320 #include <stdarg.h>
321 #include <setjmp.h>
322 #include <stddef.h>
323 #include <stdio.h>
324 
325 /* Some extra includes if EV is enabled */
326 #ifdef JANET_EV
327 #ifdef JANET_WINDOWS
328 typedef struct JanetDudCriticalSection {
329     /* Avoid including windows.h here - instead, create a structure of the same size */
330     /* Needs to be same size as crtical section see WinNT.h for CRITCIAL_SECTION definition */
331     void *debug_info;
332     long lock_count;
333     long recursion_count;
334     void *owning_thread;
335     void *lock_semaphore;
336     unsigned long spin_count;
337 } JanetOSMutex;
338 #else
339 #include <pthread.h>
340 typedef pthread_mutex_t JanetOSMutex;
341 #endif
342 #endif
343 
344 #ifdef JANET_BSD
345 int _setjmp(jmp_buf);
346 JANET_NO_RETURN void _longjmp(jmp_buf, int);
347 #endif
348 
349 /* Names of all of the types */
350 JANET_API extern const char *const janet_type_names[16];
351 JANET_API extern const char *const janet_signal_names[14];
352 JANET_API extern const char *const janet_status_names[16];
353 
354 /* For various IO routines, we want to use an int on posix and HANDLE on windows */
355 #ifdef JANET_WINDOWS
356 typedef void *JanetHandle;
357 #define JANET_HANDLE_NONE NULL
358 #else
359 typedef int JanetHandle;
360 #define JANET_HANDLE_NONE (-1)
361 #endif
362 
363 /* Fiber signals */
364 typedef enum {
365     JANET_SIGNAL_OK,
366     JANET_SIGNAL_ERROR,
367     JANET_SIGNAL_DEBUG,
368     JANET_SIGNAL_YIELD,
369     JANET_SIGNAL_USER0,
370     JANET_SIGNAL_USER1,
371     JANET_SIGNAL_USER2,
372     JANET_SIGNAL_USER3,
373     JANET_SIGNAL_USER4,
374     JANET_SIGNAL_USER5,
375     JANET_SIGNAL_USER6,
376     JANET_SIGNAL_USER7,
377     JANET_SIGNAL_USER8,
378     JANET_SIGNAL_USER9
379 } JanetSignal;
380 
381 #define JANET_SIGNAL_EVENT JANET_SIGNAL_USER9
382 #define JANET_SIGNAL_INTERRUPT JANET_SIGNAL_USER8
383 
384 /* Fiber statuses - mostly corresponds to signals. */
385 typedef enum {
386     JANET_STATUS_DEAD,
387     JANET_STATUS_ERROR,
388     JANET_STATUS_DEBUG,
389     JANET_STATUS_PENDING,
390     JANET_STATUS_USER0,
391     JANET_STATUS_USER1,
392     JANET_STATUS_USER2,
393     JANET_STATUS_USER3,
394     JANET_STATUS_USER4,
395     JANET_STATUS_USER5,
396     JANET_STATUS_USER6,
397     JANET_STATUS_USER7,
398     JANET_STATUS_USER8,
399     JANET_STATUS_USER9,
400     JANET_STATUS_NEW,
401     JANET_STATUS_ALIVE
402 } JanetFiberStatus;
403 
404 /* For encapsulating all thread-local Janet state (except natives) */
405 typedef struct JanetVM JanetVM;
406 
407 /* Use type punning for GC objects */
408 typedef struct JanetGCObject JanetGCObject;
409 
410 /* All of the primary Janet GCed types */
411 typedef struct JanetFunction JanetFunction;
412 typedef struct JanetArray JanetArray;
413 typedef struct JanetBuffer JanetBuffer;
414 typedef struct JanetTable JanetTable;
415 typedef struct JanetFiber JanetFiber;
416 
417 /* Prefixed Janet types */
418 typedef struct JanetTupleHead JanetTupleHead;
419 typedef struct JanetStructHead JanetStructHead;
420 typedef struct JanetStringHead JanetStringHead;
421 typedef struct JanetAbstractHead JanetAbstractHead;
422 
423 /* Other structs */
424 typedef struct JanetFuncDef JanetFuncDef;
425 typedef struct JanetFuncEnv JanetFuncEnv;
426 typedef struct JanetKV JanetKV;
427 typedef struct JanetStackFrame JanetStackFrame;
428 typedef struct JanetAbstractType JanetAbstractType;
429 typedef struct JanetReg JanetReg;
430 typedef struct JanetRegExt JanetRegExt;
431 typedef struct JanetMethod JanetMethod;
432 typedef struct JanetSourceMapping JanetSourceMapping;
433 typedef struct JanetView JanetView;
434 typedef struct JanetByteView JanetByteView;
435 typedef struct JanetDictView JanetDictView;
436 typedef struct JanetRange JanetRange;
437 typedef struct JanetRNG JanetRNG;
438 
439 /* Basic types for all Janet Values */
440 typedef enum JanetType {
441     JANET_NUMBER,
442     JANET_NIL,
443     JANET_BOOLEAN,
444     JANET_FIBER,
445     JANET_STRING,
446     JANET_SYMBOL,
447     JANET_KEYWORD,
448     JANET_ARRAY,
449     JANET_TUPLE,
450     JANET_TABLE,
451     JANET_STRUCT,
452     JANET_BUFFER,
453     JANET_FUNCTION,
454     JANET_CFUNCTION,
455     JANET_ABSTRACT,
456     JANET_POINTER
457 } JanetType;
458 
459 /* Recursive type (Janet) */
460 #ifdef JANET_NANBOX_64
461 typedef union Janet Janet;
462 union Janet {
463     uint64_t u64;
464     int64_t i64;
465     double number;
466     void *pointer;
467 };
468 #elif defined(JANET_NANBOX_32)
469 typedef union Janet Janet;
470 union Janet {
471     struct {
472 #ifdef JANET_BIG_ENDIAN
473         uint32_t type;
474         union {
475             int32_t integer;
476             void *pointer;
477         } payload;
478 #else
479         union {
480             int32_t integer;
481             void *pointer;
482         } payload;
483         uint32_t type;
484 #endif
485     } tagged;
486     double number;
487     uint64_t u64;
488 };
489 #else
490 typedef struct Janet Janet;
491 struct Janet {
492     union {
493         uint64_t u64;
494         double number;
495         int32_t integer;
496         void *pointer;
497         const void *cpointer;
498     } as;
499     JanetType type;
500 };
501 #endif
502 
503 /* C functions */
504 typedef Janet(*JanetCFunction)(int32_t argc, Janet *argv);
505 
506 /* String and other aliased pointer types */
507 typedef const uint8_t *JanetString;
508 typedef const uint8_t *JanetSymbol;
509 typedef const uint8_t *JanetKeyword;
510 typedef const Janet *JanetTuple;
511 typedef const JanetKV *JanetStruct;
512 typedef void *JanetAbstract;
513 
514 #define JANET_COUNT_TYPES (JANET_POINTER + 1)
515 
516 /* Type flags */
517 #define JANET_TFLAG_NIL (1 << JANET_NIL)
518 #define JANET_TFLAG_BOOLEAN (1 << JANET_BOOLEAN)
519 #define JANET_TFLAG_FIBER (1 << JANET_FIBER)
520 #define JANET_TFLAG_NUMBER (1 << JANET_NUMBER)
521 #define JANET_TFLAG_STRING (1 << JANET_STRING)
522 #define JANET_TFLAG_SYMBOL (1 << JANET_SYMBOL)
523 #define JANET_TFLAG_KEYWORD (1 << JANET_KEYWORD)
524 #define JANET_TFLAG_ARRAY (1 << JANET_ARRAY)
525 #define JANET_TFLAG_TUPLE (1 << JANET_TUPLE)
526 #define JANET_TFLAG_TABLE (1 << JANET_TABLE)
527 #define JANET_TFLAG_STRUCT (1 << JANET_STRUCT)
528 #define JANET_TFLAG_BUFFER (1 << JANET_BUFFER)
529 #define JANET_TFLAG_FUNCTION (1 << JANET_FUNCTION)
530 #define JANET_TFLAG_CFUNCTION (1 << JANET_CFUNCTION)
531 #define JANET_TFLAG_ABSTRACT (1 << JANET_ABSTRACT)
532 #define JANET_TFLAG_POINTER (1 << JANET_POINTER)
533 
534 #define JANET_TFLAG_BYTES (JANET_TFLAG_STRING | JANET_TFLAG_SYMBOL | JANET_TFLAG_BUFFER | JANET_TFLAG_KEYWORD)
535 #define JANET_TFLAG_INDEXED (JANET_TFLAG_ARRAY | JANET_TFLAG_TUPLE)
536 #define JANET_TFLAG_DICTIONARY (JANET_TFLAG_TABLE | JANET_TFLAG_STRUCT)
537 #define JANET_TFLAG_LENGTHABLE (JANET_TFLAG_BYTES | JANET_TFLAG_INDEXED | JANET_TFLAG_DICTIONARY)
538 #define JANET_TFLAG_CALLABLE (JANET_TFLAG_FUNCTION | JANET_TFLAG_CFUNCTION | \
539         JANET_TFLAG_LENGTHABLE | JANET_TFLAG_ABSTRACT)
540 
541 /* Event Loop Types */
542 #ifdef JANET_EV
543 
544 #define JANET_STREAM_CLOSED 0x1
545 #define JANET_STREAM_SOCKET 0x2
546 #define JANET_STREAM_IOCP 0x4
547 #define JANET_STREAM_READABLE 0x200
548 #define JANET_STREAM_WRITABLE 0x400
549 #define JANET_STREAM_ACCEPTABLE 0x800
550 #define JANET_STREAM_UDPSERVER 0x1000
551 
552 typedef enum {
553     JANET_ASYNC_EVENT_INIT,
554     JANET_ASYNC_EVENT_MARK,
555     JANET_ASYNC_EVENT_DEINIT,
556     JANET_ASYNC_EVENT_CLOSE,
557     JANET_ASYNC_EVENT_ERR,
558     JANET_ASYNC_EVENT_HUP,
559     JANET_ASYNC_EVENT_READ,
560     JANET_ASYNC_EVENT_WRITE,
561     JANET_ASYNC_EVENT_CANCEL,
562     JANET_ASYNC_EVENT_COMPLETE, /* Used on windows for IOCP */
563     JANET_ASYNC_EVENT_USER
564 } JanetAsyncEvent;
565 
566 #define JANET_ASYNC_LISTEN_READ (1 << JANET_ASYNC_EVENT_READ)
567 #define JANET_ASYNC_LISTEN_WRITE (1 << JANET_ASYNC_EVENT_WRITE)
568 
569 typedef enum {
570     JANET_ASYNC_STATUS_NOT_DONE,
571     JANET_ASYNC_STATUS_DONE
572 } JanetAsyncStatus;
573 
574 /* Typedefs */
575 typedef struct JanetListenerState JanetListenerState;
576 typedef struct JanetStream JanetStream;
577 typedef JanetAsyncStatus(*JanetListener)(JanetListenerState *state, JanetAsyncEvent event);
578 
579 /* Wrapper around file descriptors and HANDLEs that can be polled. */
580 struct JanetStream {
581     JanetHandle handle;
582     uint32_t flags;
583     /* Linked list of all in-flight IO routines for this stream */
584     JanetListenerState *state;
585     const void *methods; /* Methods for this stream */
586     /* internal - used to disallow multiple concurrent reads / writes on the same stream.
587      * this constraint may be lifted later but allowing such would require more internal book keeping
588      * for some implementations. You can read and write at the same time on the same stream, though. */
589     int _mask;
590 };
591 
592 /* Interface for state machine based event loop */
593 struct JanetListenerState {
594     JanetListener machine;
595     JanetFiber *fiber;
596     JanetStream *stream;
597     void *event; /* Used to pass data from asynchronous IO event. Contents depend on both
598                     implementation of the event loop and the particular event. */
599 #ifdef JANET_WINDOWS
600     void *tag; /* Used to associate listeners with an overlapped structure */
601     int bytes; /* Used to track how many bytes were transfered. */
602 #endif
603     /* internal */
604     size_t _index;
605     int _mask;
606     JanetListenerState *_next;
607 };
608 #endif
609 
610 /* We provide three possible implementations of Janets. The preferred
611  * nanboxing approach, for 32 or 64 bits, and the standard C version. Code in the rest of the
612  * application must interact through exposed interface. */
613 
614 /* Required interface for Janet */
615 /* wrap and unwrap for all types */
616 /* Get type quickly */
617 /* Check against type quickly */
618 /* Small footprint */
619 /* 32 bit integer support */
620 
621 /* janet_type(x)
622  * janet_checktype(x, t)
623  * janet_wrap_##TYPE(x)
624  * janet_unwrap_##TYPE(x)
625  * janet_truthy(x)
626  * janet_memclear(p, n) - clear memory for hash tables to nils
627  * janet_u64(x) - get 64 bits of payload for hashing
628  */
629 
630 /***** START SECTION NON-C API *****/
631 
632 /* Some janet types use offset tricks to make operations easier in C. For
633  * external bindings, we should prefer using the Head structs directly, and
634  * use the host language to add sugar around the manipulation of the Janet types. */
635 
636 JANET_API JanetStructHead *janet_struct_head(const JanetKV *st);
637 JANET_API JanetAbstractHead *janet_abstract_head(const void *abstract);
638 JANET_API JanetStringHead *janet_string_head(const uint8_t *s);
639 JANET_API JanetTupleHead *janet_tuple_head(const Janet *tuple);
640 
641 /* Some language bindings won't have access to the macro versions. */
642 
643 JANET_API JanetType janet_type(Janet x);
644 JANET_API int janet_checktype(Janet x, JanetType type);
645 JANET_API int janet_checktypes(Janet x, int typeflags);
646 JANET_API int janet_truthy(Janet x);
647 
648 JANET_API const JanetKV *janet_unwrap_struct(Janet x);
649 JANET_API const Janet *janet_unwrap_tuple(Janet x);
650 JANET_API JanetFiber *janet_unwrap_fiber(Janet x);
651 JANET_API JanetArray *janet_unwrap_array(Janet x);
652 JANET_API JanetTable *janet_unwrap_table(Janet x);
653 JANET_API JanetBuffer *janet_unwrap_buffer(Janet x);
654 JANET_API const uint8_t *janet_unwrap_string(Janet x);
655 JANET_API const uint8_t *janet_unwrap_symbol(Janet x);
656 JANET_API const uint8_t *janet_unwrap_keyword(Janet x);
657 JANET_API void *janet_unwrap_abstract(Janet x);
658 JANET_API void *janet_unwrap_pointer(Janet x);
659 JANET_API JanetFunction *janet_unwrap_function(Janet x);
660 JANET_API JanetCFunction janet_unwrap_cfunction(Janet x);
661 JANET_API int janet_unwrap_boolean(Janet x);
662 JANET_API double janet_unwrap_number(Janet x);
663 JANET_API int32_t janet_unwrap_integer(Janet x);
664 
665 JANET_API Janet janet_wrap_nil(void);
666 JANET_API Janet janet_wrap_number(double x);
667 JANET_API Janet janet_wrap_true(void);
668 JANET_API Janet janet_wrap_false(void);
669 JANET_API Janet janet_wrap_boolean(int x);
670 JANET_API Janet janet_wrap_string(const uint8_t *x);
671 JANET_API Janet janet_wrap_symbol(const uint8_t *x);
672 JANET_API Janet janet_wrap_keyword(const uint8_t *x);
673 JANET_API Janet janet_wrap_array(JanetArray *x);
674 JANET_API Janet janet_wrap_tuple(const Janet *x);
675 JANET_API Janet janet_wrap_struct(const JanetKV *x);
676 JANET_API Janet janet_wrap_fiber(JanetFiber *x);
677 JANET_API Janet janet_wrap_buffer(JanetBuffer *x);
678 JANET_API Janet janet_wrap_function(JanetFunction *x);
679 JANET_API Janet janet_wrap_cfunction(JanetCFunction x);
680 JANET_API Janet janet_wrap_table(JanetTable *x);
681 JANET_API Janet janet_wrap_abstract(void *x);
682 JANET_API Janet janet_wrap_pointer(void *x);
683 JANET_API Janet janet_wrap_integer(int32_t x);
684 
685 /***** END SECTION NON-C API *****/
686 
687 #ifdef JANET_NANBOX_64
688 
689 #include <math.h>
690 
691 #define janet_u64(x) ((x).u64)
692 
693 #define JANET_NANBOX_TAGBITS     0xFFFF800000000000llu
694 #define JANET_NANBOX_PAYLOADBITS 0x00007FFFFFFFFFFFllu
695 #define janet_nanbox_lowtag(type) ((uint64_t)(type) | 0x1FFF0)
696 #define janet_nanbox_tag(type) (janet_nanbox_lowtag(type) << 47)
697 #define janet_type(x) \
698     (isnan((x).number) \
699         ? (JanetType) (((x).u64 >> 47) & 0xF) \
700         : JANET_NUMBER)
701 
702 #define janet_nanbox_checkauxtype(x, type) \
703     (((x).u64 & JANET_NANBOX_TAGBITS) == janet_nanbox_tag((type)))
704 
705 #define janet_nanbox_isnumber(x) \
706     (!isnan((x).number) || ((((x).u64 >> 47) & 0xF) == JANET_NUMBER))
707 
708 #define janet_checktype(x, t) \
709     (((t) == JANET_NUMBER) \
710         ? janet_nanbox_isnumber(x) \
711         : janet_nanbox_checkauxtype((x), (t)))
712 
713 JANET_API void *janet_nanbox_to_pointer(Janet x);
714 JANET_API Janet janet_nanbox_from_pointer(void *p, uint64_t tagmask);
715 JANET_API Janet janet_nanbox_from_cpointer(const void *p, uint64_t tagmask);
716 JANET_API Janet janet_nanbox_from_double(double d);
717 JANET_API Janet janet_nanbox_from_bits(uint64_t bits);
718 
719 #define janet_truthy(x) \
720     (!janet_checktype((x), JANET_NIL) && \
721      (!janet_checktype((x), JANET_BOOLEAN) || ((x).u64 & 0x1)))
722 
723 #define janet_nanbox_from_payload(t, p) \
724     janet_nanbox_from_bits(janet_nanbox_tag(t) | (p))
725 
726 #define janet_nanbox_wrap_(p, t) \
727     janet_nanbox_from_pointer((p), janet_nanbox_tag(t))
728 
729 #define janet_nanbox_wrap_c(p, t) \
730     janet_nanbox_from_cpointer((p), janet_nanbox_tag(t))
731 
732 /* Wrap the simple types */
733 #define janet_wrap_nil() janet_nanbox_from_payload(JANET_NIL, 1)
734 #define janet_wrap_true() janet_nanbox_from_payload(JANET_BOOLEAN, 1)
735 #define janet_wrap_false() janet_nanbox_from_payload(JANET_BOOLEAN, 0)
736 #define janet_wrap_boolean(b) janet_nanbox_from_payload(JANET_BOOLEAN, !!(b))
737 #define janet_wrap_number(r) janet_nanbox_from_double(r)
738 
739 /* Unwrap the simple types */
740 #define janet_unwrap_boolean(x) ((x).u64 & 0x1)
741 #define janet_unwrap_number(x) ((x).number)
742 
743 /* Wrap the pointer types */
744 #define janet_wrap_struct(s) janet_nanbox_wrap_c((s), JANET_STRUCT)
745 #define janet_wrap_tuple(s) janet_nanbox_wrap_c((s), JANET_TUPLE)
746 #define janet_wrap_fiber(s) janet_nanbox_wrap_((s), JANET_FIBER)
747 #define janet_wrap_array(s) janet_nanbox_wrap_((s), JANET_ARRAY)
748 #define janet_wrap_table(s) janet_nanbox_wrap_((s), JANET_TABLE)
749 #define janet_wrap_buffer(s) janet_nanbox_wrap_((s), JANET_BUFFER)
750 #define janet_wrap_string(s) janet_nanbox_wrap_c((s), JANET_STRING)
751 #define janet_wrap_symbol(s) janet_nanbox_wrap_c((s), JANET_SYMBOL)
752 #define janet_wrap_keyword(s) janet_nanbox_wrap_c((s), JANET_KEYWORD)
753 #define janet_wrap_abstract(s) janet_nanbox_wrap_((s), JANET_ABSTRACT)
754 #define janet_wrap_function(s) janet_nanbox_wrap_((s), JANET_FUNCTION)
755 #define janet_wrap_cfunction(s) janet_nanbox_wrap_((s), JANET_CFUNCTION)
756 #define janet_wrap_pointer(s) janet_nanbox_wrap_((s), JANET_POINTER)
757 
758 /* Unwrap the pointer types */
759 #define janet_unwrap_struct(x) ((const JanetKV *)janet_nanbox_to_pointer(x))
760 #define janet_unwrap_tuple(x) ((const Janet *)janet_nanbox_to_pointer(x))
761 #define janet_unwrap_fiber(x) ((JanetFiber *)janet_nanbox_to_pointer(x))
762 #define janet_unwrap_array(x) ((JanetArray *)janet_nanbox_to_pointer(x))
763 #define janet_unwrap_table(x) ((JanetTable *)janet_nanbox_to_pointer(x))
764 #define janet_unwrap_buffer(x) ((JanetBuffer *)janet_nanbox_to_pointer(x))
765 #define janet_unwrap_string(x) ((const uint8_t *)janet_nanbox_to_pointer(x))
766 #define janet_unwrap_symbol(x) ((const uint8_t *)janet_nanbox_to_pointer(x))
767 #define janet_unwrap_keyword(x) ((const uint8_t *)janet_nanbox_to_pointer(x))
768 #define janet_unwrap_abstract(x) (janet_nanbox_to_pointer(x))
769 #define janet_unwrap_pointer(x) (janet_nanbox_to_pointer(x))
770 #define janet_unwrap_function(x) ((JanetFunction *)janet_nanbox_to_pointer(x))
771 #define janet_unwrap_cfunction(x) ((JanetCFunction)janet_nanbox_to_pointer(x))
772 
773 #elif defined(JANET_NANBOX_32)
774 
775 #define JANET_DOUBLE_OFFSET 0xFFFF
776 
777 #define janet_u64(x) ((x).u64)
778 #define janet_type(x) (((x).tagged.type < JANET_DOUBLE_OFFSET) ? (JanetType)((x).tagged.type) : JANET_NUMBER)
779 #define janet_checktype(x, t) ((t) == JANET_NUMBER \
780         ? (x).tagged.type >= JANET_DOUBLE_OFFSET \
781         : (x).tagged.type == (t))
782 #define janet_truthy(x) \
783     ((x).tagged.type != JANET_NIL && ((x).tagged.type != JANET_BOOLEAN || ((x).tagged.payload.integer & 0x1)))
784 
785 JANET_API Janet janet_nanbox32_from_tagi(uint32_t tag, int32_t integer);
786 JANET_API Janet janet_nanbox32_from_tagp(uint32_t tag, void *pointer);
787 
788 #define janet_wrap_nil() janet_nanbox32_from_tagi(JANET_NIL, 0)
789 #define janet_wrap_true() janet_nanbox32_from_tagi(JANET_BOOLEAN, 1)
790 #define janet_wrap_false() janet_nanbox32_from_tagi(JANET_BOOLEAN, 0)
791 #define janet_wrap_boolean(b) janet_nanbox32_from_tagi(JANET_BOOLEAN, !!(b))
792 
793 /* Wrap the pointer types */
794 #define janet_wrap_struct(s) janet_nanbox32_from_tagp(JANET_STRUCT, (void *)(s))
795 #define janet_wrap_tuple(s) janet_nanbox32_from_tagp(JANET_TUPLE, (void *)(s))
796 #define janet_wrap_fiber(s) janet_nanbox32_from_tagp(JANET_FIBER, (void *)(s))
797 #define janet_wrap_array(s) janet_nanbox32_from_tagp(JANET_ARRAY, (void *)(s))
798 #define janet_wrap_table(s) janet_nanbox32_from_tagp(JANET_TABLE, (void *)(s))
799 #define janet_wrap_buffer(s) janet_nanbox32_from_tagp(JANET_BUFFER, (void *)(s))
800 #define janet_wrap_string(s) janet_nanbox32_from_tagp(JANET_STRING, (void *)(s))
801 #define janet_wrap_symbol(s) janet_nanbox32_from_tagp(JANET_SYMBOL, (void *)(s))
802 #define janet_wrap_keyword(s) janet_nanbox32_from_tagp(JANET_KEYWORD, (void *)(s))
803 #define janet_wrap_abstract(s) janet_nanbox32_from_tagp(JANET_ABSTRACT, (void *)(s))
804 #define janet_wrap_function(s) janet_nanbox32_from_tagp(JANET_FUNCTION, (void *)(s))
805 #define janet_wrap_cfunction(s) janet_nanbox32_from_tagp(JANET_CFUNCTION, (void *)(s))
806 #define janet_wrap_pointer(s) janet_nanbox32_from_tagp(JANET_POINTER, (void *)(s))
807 
808 #define janet_unwrap_struct(x) ((const JanetKV *)(x).tagged.payload.pointer)
809 #define janet_unwrap_tuple(x) ((const Janet *)(x).tagged.payload.pointer)
810 #define janet_unwrap_fiber(x) ((JanetFiber *)(x).tagged.payload.pointer)
811 #define janet_unwrap_array(x) ((JanetArray *)(x).tagged.payload.pointer)
812 #define janet_unwrap_table(x) ((JanetTable *)(x).tagged.payload.pointer)
813 #define janet_unwrap_buffer(x) ((JanetBuffer *)(x).tagged.payload.pointer)
814 #define janet_unwrap_string(x) ((const uint8_t *)(x).tagged.payload.pointer)
815 #define janet_unwrap_symbol(x) ((const uint8_t *)(x).tagged.payload.pointer)
816 #define janet_unwrap_keyword(x) ((const uint8_t *)(x).tagged.payload.pointer)
817 #define janet_unwrap_abstract(x) ((x).tagged.payload.pointer)
818 #define janet_unwrap_pointer(x) ((x).tagged.payload.pointer)
819 #define janet_unwrap_function(x) ((JanetFunction *)(x).tagged.payload.pointer)
820 #define janet_unwrap_cfunction(x) ((JanetCFunction)(x).tagged.payload.pointer)
821 #define janet_unwrap_boolean(x) ((x).tagged.payload.integer)
822 
823 #else
824 
825 #define janet_u64(x) ((x).as.u64)
826 #define janet_type(x) ((x).type)
827 #define janet_checktype(x, t) ((x).type == (t))
828 #define janet_truthy(x) \
829     ((x).type != JANET_NIL && ((x).type != JANET_BOOLEAN || ((x).as.u64 & 0x1)))
830 
831 #define janet_unwrap_struct(x) ((const JanetKV *)(x).as.pointer)
832 #define janet_unwrap_tuple(x) ((const Janet *)(x).as.pointer)
833 #define janet_unwrap_fiber(x) ((JanetFiber *)(x).as.pointer)
834 #define janet_unwrap_array(x) ((JanetArray *)(x).as.pointer)
835 #define janet_unwrap_table(x) ((JanetTable *)(x).as.pointer)
836 #define janet_unwrap_buffer(x) ((JanetBuffer *)(x).as.pointer)
837 #define janet_unwrap_string(x) ((const uint8_t *)(x).as.pointer)
838 #define janet_unwrap_symbol(x) ((const uint8_t *)(x).as.pointer)
839 #define janet_unwrap_keyword(x) ((const uint8_t *)(x).as.pointer)
840 #define janet_unwrap_abstract(x) ((x).as.pointer)
841 #define janet_unwrap_pointer(x) ((x).as.pointer)
842 #define janet_unwrap_function(x) ((JanetFunction *)(x).as.pointer)
843 #define janet_unwrap_cfunction(x) ((JanetCFunction)(x).as.pointer)
844 #define janet_unwrap_boolean(x) ((x).as.u64 & 0x1)
845 #define janet_unwrap_number(x) ((x).as.number)
846 
847 /* End of tagged union implementation */
848 #endif
849 
850 JANET_API int janet_checkint(Janet x);
851 JANET_API int janet_checkint64(Janet x);
852 JANET_API int janet_checksize(Janet x);
853 JANET_API JanetAbstract janet_checkabstract(Janet x, const JanetAbstractType *at);
854 #define janet_checkintrange(x) ((x) >= INT32_MIN && (x) <= INT32_MAX && (x) == (int32_t)(x))
855 #define janet_checkint64range(x) ((x) >= JANET_INTMIN_DOUBLE && (x) <= JANET_INTMAX_DOUBLE && (x) == (int64_t)(x))
856 #define janet_unwrap_integer(x) ((int32_t) janet_unwrap_number(x))
857 #define janet_wrap_integer(x) janet_wrap_number((int32_t)(x))
858 
859 #define janet_checktypes(x, tps) ((1 << janet_type(x)) & (tps))
860 
861 /* GC Object type pun. The lower 16 bits of flags are reserved for the garbage collector,
862  * but the upper 16 can be used per type for custom flags. The current collector is a linked
863  * list of blocks, which is naive but works. */
864 struct JanetGCObject {
865     int32_t flags;
866     union {
867         JanetGCObject *next;
868         int32_t refcount; /* For threaded abstract types */
869     } data;
870 };
871 
872 /* A lightweight green thread in janet. Does not correspond to
873  * operating system threads. */
874 struct JanetFiber {
875     JanetGCObject gc; /* GC Object stuff */
876     int32_t flags; /* More flags */
877     int32_t frame; /* Index of the stack frame */
878     int32_t stackstart; /* Beginning of next args */
879     int32_t stacktop; /* Top of stack. Where values are pushed and popped from. */
880     int32_t capacity; /* How big is the stack memory */
881     int32_t maxstack; /* Arbitrary defined limit for stack overflow */
882     JanetTable *env; /* Dynamic bindings table (usually current environment). */
883     Janet *data; /* Dynamically resized stack memory */
884     JanetFiber *child; /* Keep linked list of fibers for restarting pending fibers */
885     Janet last_value; /* Last returned value from a fiber */
886 #ifdef JANET_EV
887     /* These fields are only relevant for fibers that are used as "root fibers" -
888      * that is, fibers that are scheduled on the event loop and behave much like threads
889      * in a multi-tasking system. It would be possible to move these fields to a new
890      * type, say "JanetTask", that as separate from fibers to save a bit of space. */
891     JanetListenerState *waiting;
892     uint32_t sched_id; /* Increment everytime fiber is scheduled by event loop */
893     void *supervisor_channel; /* Channel to push self to when complete */
894 #endif
895 };
896 
897 /* Mark if a stack frame is a tail call for debugging */
898 #define JANET_STACKFRAME_TAILCALL 1
899 
900 /* Mark if a stack frame is an entrance frame */
901 #define JANET_STACKFRAME_ENTRANCE 2
902 
903 /* A stack frame on the fiber. Is stored along with the stack values. */
904 struct JanetStackFrame {
905     JanetFunction *func;
906     uint32_t *pc;
907     JanetFuncEnv *env;
908     int32_t prevframe;
909     int32_t flags;
910 };
911 
912 /* Number of Janets a frame takes up in the stack
913  * Should be constant across architectures */
914 #define JANET_FRAME_SIZE 4
915 
916 /* A dynamic array type. */
917 struct JanetArray {
918     JanetGCObject gc;
919     int32_t count;
920     int32_t capacity;
921     Janet *data;
922 };
923 
924 /* A byte buffer type. Used as a mutable string or string builder. */
925 struct JanetBuffer {
926     JanetGCObject gc;
927     int32_t count;
928     int32_t capacity;
929     uint8_t *data;
930 };
931 
932 /* A mutable associative data type. Backed by a hashtable. */
933 struct JanetTable {
934     JanetGCObject gc;
935     int32_t count;
936     int32_t capacity;
937     int32_t deleted;
938     JanetKV *data;
939     JanetTable *proto;
940 };
941 
942 /* A key value pair in a struct or table */
943 struct JanetKV {
944     Janet key;
945     Janet value;
946 };
947 
948 /* Prefix for a tuple */
949 struct JanetTupleHead {
950     JanetGCObject gc;
951     int32_t length;
952     int32_t hash;
953     int32_t sm_line;
954     int32_t sm_column;
955     const Janet data[];
956 };
957 
958 /* Prefix for a struct */
959 struct JanetStructHead {
960     JanetGCObject gc;
961     int32_t length;
962     int32_t hash;
963     int32_t capacity;
964     const JanetKV *proto;
965     const JanetKV data[];
966 };
967 
968 /* Prefix for a string */
969 struct JanetStringHead {
970     JanetGCObject gc;
971     int32_t length;
972     int32_t hash;
973     const uint8_t data[];
974 };
975 
976 /* Prefix for an abstract value */
977 struct JanetAbstractHead {
978     JanetGCObject gc;
979     const JanetAbstractType *type;
980     size_t size;
981     long long data[]; /* Use long long to ensure most general alignment */
982 };
983 
984 /* Some function definition flags */
985 #define JANET_FUNCDEF_FLAG_VARARG 0x10000
986 #define JANET_FUNCDEF_FLAG_NEEDSENV 0x20000
987 #define JANET_FUNCDEF_FLAG_HASNAME 0x80000
988 #define JANET_FUNCDEF_FLAG_HASSOURCE 0x100000
989 #define JANET_FUNCDEF_FLAG_HASDEFS 0x200000
990 #define JANET_FUNCDEF_FLAG_HASENVS 0x400000
991 #define JANET_FUNCDEF_FLAG_HASSOURCEMAP 0x800000
992 #define JANET_FUNCDEF_FLAG_STRUCTARG 0x1000000
993 #define JANET_FUNCDEF_FLAG_HASCLOBITSET 0x2000000
994 #define JANET_FUNCDEF_FLAG_TAG 0xFFFF
995 
996 /* Source mapping structure for a bytecode instruction */
997 struct JanetSourceMapping {
998     int32_t line;
999     int32_t column;
1000 };
1001 
1002 /* A function definition. Contains information needed to instantiate closures. */
1003 struct JanetFuncDef {
1004     JanetGCObject gc;
1005     int32_t *environments; /* Which environments to capture from parent. */
1006     Janet *constants;
1007     JanetFuncDef **defs;
1008     uint32_t *bytecode;
1009     uint32_t *closure_bitset; /* Bit set indicating which slots can be referenced by closures. */
1010 
1011     /* Various debug information */
1012     JanetSourceMapping *sourcemap;
1013     JanetString source;
1014     JanetString name;
1015 
1016     int32_t flags;
1017     int32_t slotcount; /* The amount of stack space required for the function */
1018     int32_t arity; /* Not including varargs */
1019     int32_t min_arity; /* Including varargs */
1020     int32_t max_arity; /* Including varargs */
1021     int32_t constants_length;
1022     int32_t bytecode_length;
1023     int32_t environments_length;
1024     int32_t defs_length;
1025 };
1026 
1027 /* A function environment */
1028 struct JanetFuncEnv {
1029     JanetGCObject gc;
1030     union {
1031         JanetFiber *fiber;
1032         Janet *values;
1033     } as;
1034     int32_t length; /* Size of environment */
1035     int32_t offset; /* Stack offset when values still on stack. If offset is <= 0, then
1036         environment is no longer on the stack. */
1037 };
1038 
1039 #define JANET_FUNCFLAG_TRACE (1 << 16)
1040 
1041 /* A function */
1042 struct JanetFunction {
1043     JanetGCObject gc;
1044     JanetFuncDef *def;
1045     JanetFuncEnv *envs[];
1046 };
1047 
1048 typedef struct JanetParseState JanetParseState;
1049 typedef struct JanetParser JanetParser;
1050 
1051 enum JanetParserStatus {
1052     JANET_PARSE_ROOT,
1053     JANET_PARSE_ERROR,
1054     JANET_PARSE_PENDING,
1055     JANET_PARSE_DEAD
1056 };
1057 
1058 /* A janet parser */
1059 struct JanetParser {
1060     Janet *args;
1061     const char *error;
1062     JanetParseState *states;
1063     uint8_t *buf;
1064     size_t argcount;
1065     size_t argcap;
1066     size_t statecount;
1067     size_t statecap;
1068     size_t bufcount;
1069     size_t bufcap;
1070     size_t line;
1071     size_t column;
1072     size_t pending;
1073     int lookback;
1074     int flag;
1075 };
1076 
1077 /* A context for marshaling and unmarshaling abstract types */
1078 typedef struct {
1079     void *m_state;
1080     void *u_state;
1081     int flags;
1082     const uint8_t *data;
1083     const JanetAbstractType *at;
1084 } JanetMarshalContext;
1085 
1086 /* Defines an abstract type */
1087 struct JanetAbstractType {
1088     const char *name;
1089     int (*gc)(void *data, size_t len);
1090     int (*gcmark)(void *data, size_t len);
1091     int (*get)(void *data, Janet key, Janet *out);
1092     void (*put)(void *data, Janet key, Janet value);
1093     void (*marshal)(void *p, JanetMarshalContext *ctx);
1094     void *(*unmarshal)(JanetMarshalContext *ctx);
1095     void (*tostring)(void *p, JanetBuffer *buffer);
1096     int (*compare)(void *lhs, void *rhs);
1097     int32_t (*hash)(void *p, size_t len);
1098     Janet(*next)(void *p, Janet key);
1099     Janet(*call)(void *p, int32_t argc, Janet *argv);
1100 };
1101 
1102 /* Some macros to let us add extra types to JanetAbstract types without
1103  * needing to changing native modules that declare them as static const
1104  * structures. If more fields are added, these macros are modified to include
1105  * default values (usually NULL). This silences missing field warnings. */
1106 #define JANET_ATEND_NAME        NULL,JANET_ATEND_GC
1107 #define JANET_ATEND_GC          NULL,JANET_ATEND_GCMARK
1108 #define JANET_ATEND_GCMARK      NULL,JANET_ATEND_GET
1109 #define JANET_ATEND_GET         NULL,JANET_ATEND_PUT
1110 #define JANET_ATEND_PUT         NULL,JANET_ATEND_MARSHAL
1111 #define JANET_ATEND_MARSHAL     NULL,JANET_ATEND_UNMARSHAL
1112 #define JANET_ATEND_UNMARSHAL   NULL,JANET_ATEND_TOSTRING
1113 #define JANET_ATEND_TOSTRING    NULL,JANET_ATEND_COMPARE
1114 #define JANET_ATEND_COMPARE     NULL,JANET_ATEND_HASH
1115 #define JANET_ATEND_HASH        NULL,JANET_ATEND_NEXT
1116 #define JANET_ATEND_NEXT        NULL,JANET_ATEND_CALL
1117 #define JANET_ATEND_CALL
1118 
1119 struct JanetReg {
1120     const char *name;
1121     JanetCFunction cfun;
1122     const char *documentation;
1123 };
1124 
1125 struct JanetRegExt {
1126     const char *name;
1127     JanetCFunction cfun;
1128     const char *documentation;
1129     const char *source_file;
1130     int32_t source_line;
1131 };
1132 
1133 struct JanetMethod {
1134     const char *name;
1135     JanetCFunction cfun;
1136 };
1137 
1138 struct JanetView {
1139     const Janet *items;
1140     int32_t len;
1141 };
1142 
1143 struct JanetByteView {
1144     const uint8_t *bytes;
1145     int32_t len;
1146 };
1147 
1148 struct JanetDictView {
1149     const JanetKV *kvs;
1150     int32_t len;
1151     int32_t cap;
1152 };
1153 
1154 struct JanetRange {
1155     int32_t start;
1156     int32_t end;
1157 };
1158 
1159 struct JanetRNG {
1160     uint32_t a, b, c, d;
1161     uint32_t counter;
1162 };
1163 
1164 typedef struct JanetFile JanetFile;
1165 struct JanetFile {
1166     FILE *file;
1167     int32_t flags;
1168 };
1169 
1170 /* For janet_try and janet_restore */
1171 typedef struct {
1172     /* old state */
1173     int32_t stackn;
1174     int gc_handle;
1175     JanetFiber *vm_fiber;
1176     jmp_buf *vm_jmp_buf;
1177     Janet *vm_return_reg;
1178     /* new state */
1179     jmp_buf buf;
1180     Janet payload;
1181 } JanetTryState;
1182 
1183 /* Thread types */
1184 #ifdef JANET_THREADS
1185 typedef struct JanetThread JanetThread;
1186 typedef struct JanetMailbox JanetMailbox;
1187 struct JanetThread {
1188     JanetMailbox *mailbox;
1189     JanetTable *encode;
1190 };
1191 #endif
1192 
1193 
1194 /***** END SECTION TYPES *****/
1195 
1196 /***** START SECTION OPCODES *****/
1197 
1198 /* Bytecode op argument types */
1199 enum JanetOpArgType {
1200     JANET_OAT_SLOT,
1201     JANET_OAT_ENVIRONMENT,
1202     JANET_OAT_CONSTANT,
1203     JANET_OAT_INTEGER,
1204     JANET_OAT_TYPE,
1205     JANET_OAT_SIMPLETYPE,
1206     JANET_OAT_LABEL,
1207     JANET_OAT_FUNCDEF
1208 };
1209 
1210 /* Various types of instructions */
1211 enum JanetInstructionType {
1212     JINT_0, /* No args */
1213     JINT_S, /* Slot(3) */
1214     JINT_L, /* Label(3) */
1215     JINT_SS, /* Slot(1), Slot(2) */
1216     JINT_SL, /* Slot(1), Label(2) */
1217     JINT_ST, /* Slot(1), Slot(2) */
1218     JINT_SI, /* Slot(1), Immediate(2) */
1219     JINT_SD, /* Slot(1), Closure(2) */
1220     JINT_SU, /* Slot(1), Unsigned Immediate(2) */
1221     JINT_SSS, /* Slot(1), Slot(1), Slot(1) */
1222     JINT_SSI, /* Slot(1), Slot(1), Immediate(1) */
1223     JINT_SSU, /* Slot(1), Slot(1), Unsigned Immediate(1) */
1224     JINT_SES, /* Slot(1), Environment(1), Far Slot(1) */
1225     JINT_SC /* Slot(1), Constant(2) */
1226 };
1227 
1228 /* All opcodes for the bytecode interpreter. */
1229 enum JanetOpCode {
1230     JOP_NOOP,
1231     JOP_ERROR,
1232     JOP_TYPECHECK,
1233     JOP_RETURN,
1234     JOP_RETURN_NIL,
1235     JOP_ADD_IMMEDIATE,
1236     JOP_ADD,
1237     JOP_SUBTRACT,
1238     JOP_MULTIPLY_IMMEDIATE,
1239     JOP_MULTIPLY,
1240     JOP_DIVIDE_IMMEDIATE,
1241     JOP_DIVIDE,
1242     JOP_MODULO,
1243     JOP_REMAINDER,
1244     JOP_BAND,
1245     JOP_BOR,
1246     JOP_BXOR,
1247     JOP_BNOT,
1248     JOP_SHIFT_LEFT,
1249     JOP_SHIFT_LEFT_IMMEDIATE,
1250     JOP_SHIFT_RIGHT,
1251     JOP_SHIFT_RIGHT_IMMEDIATE,
1252     JOP_SHIFT_RIGHT_UNSIGNED,
1253     JOP_SHIFT_RIGHT_UNSIGNED_IMMEDIATE,
1254     JOP_MOVE_FAR,
1255     JOP_MOVE_NEAR,
1256     JOP_JUMP,
1257     JOP_JUMP_IF,
1258     JOP_JUMP_IF_NOT,
1259     JOP_JUMP_IF_NIL,
1260     JOP_JUMP_IF_NOT_NIL,
1261     JOP_GREATER_THAN,
1262     JOP_GREATER_THAN_IMMEDIATE,
1263     JOP_LESS_THAN,
1264     JOP_LESS_THAN_IMMEDIATE,
1265     JOP_EQUALS,
1266     JOP_EQUALS_IMMEDIATE,
1267     JOP_COMPARE,
1268     JOP_LOAD_NIL,
1269     JOP_LOAD_TRUE,
1270     JOP_LOAD_FALSE,
1271     JOP_LOAD_INTEGER,
1272     JOP_LOAD_CONSTANT,
1273     JOP_LOAD_UPVALUE,
1274     JOP_LOAD_SELF,
1275     JOP_SET_UPVALUE,
1276     JOP_CLOSURE,
1277     JOP_PUSH,
1278     JOP_PUSH_2,
1279     JOP_PUSH_3,
1280     JOP_PUSH_ARRAY,
1281     JOP_CALL,
1282     JOP_TAILCALL,
1283     JOP_RESUME,
1284     JOP_SIGNAL,
1285     JOP_PROPAGATE,
1286     JOP_IN,
1287     JOP_GET,
1288     JOP_PUT,
1289     JOP_GET_INDEX,
1290     JOP_PUT_INDEX,
1291     JOP_LENGTH,
1292     JOP_MAKE_ARRAY,
1293     JOP_MAKE_BUFFER,
1294     JOP_MAKE_STRING,
1295     JOP_MAKE_STRUCT,
1296     JOP_MAKE_TABLE,
1297     JOP_MAKE_TUPLE,
1298     JOP_MAKE_BRACKET_TUPLE,
1299     JOP_GREATER_THAN_EQUAL,
1300     JOP_LESS_THAN_EQUAL,
1301     JOP_NEXT,
1302     JOP_NOT_EQUALS,
1303     JOP_NOT_EQUALS_IMMEDIATE,
1304     JOP_CANCEL,
1305     JOP_INSTRUCTION_COUNT
1306 };
1307 
1308 /* Info about all instructions */
1309 extern enum JanetInstructionType janet_instructions[JOP_INSTRUCTION_COUNT];
1310 
1311 /***** END SECTION OPCODES *****/
1312 
1313 /***** START SECTION MAIN *****/
1314 
1315 #ifdef JANET_EV
1316 
1317 extern JANET_API const JanetAbstractType janet_stream_type;
1318 extern JANET_API const JanetAbstractType janet_channel_type;
1319 
1320 /* Run the event loop */
1321 JANET_API void janet_loop(void);
1322 
1323 /* Run the event loop, but allow for user scheduled interrupts triggered
1324  * by janet_loop1_interrupt being called in library code, a signal handler, or
1325  * another thread.
1326  *
1327  * Example:
1328  *
1329  * while (!janet_loop_done()) {
1330  *   // One turn of the event loop
1331  *   JanetFiber *interrupted_fiber = janet_loop1();
1332  *   // interrupted_fiber may be NULL
1333  *   // do some work here periodically...
1334  *   if (NULL != interrupted_fiber) {
1335  *     if (cancel_interrupted_fiber) {
1336  *       janet_cancel(interrupted_fiber, janet_cstringv("fiber was interrupted for [reason]"));
1337  *     } else {
1338  *       janet_schedule(interrupted_fiber, janet_wrap_nil());
1339  *     }
1340  *   }
1341  * }
1342  *
1343  */
1344 JANET_API int janet_loop_done(void);
1345 JANET_API JanetFiber *janet_loop1(void);
1346 JANET_API void janet_loop1_interrupt(JanetVM *vm);
1347 
1348 /* Wrapper around streams */
1349 JANET_API JanetStream *janet_stream(JanetHandle handle, uint32_t flags, const JanetMethod *methods);
1350 JANET_API void janet_stream_close(JanetStream *stream);
1351 JANET_API Janet janet_cfun_stream_close(int32_t argc, Janet *argv);
1352 JANET_API Janet janet_cfun_stream_read(int32_t argc, Janet *argv);
1353 JANET_API Janet janet_cfun_stream_chunk(int32_t argc, Janet *argv);
1354 JANET_API Janet janet_cfun_stream_write(int32_t argc, Janet *argv);
1355 JANET_API void janet_stream_flags(JanetStream *stream, uint32_t flags);
1356 
1357 /* Queue a fiber to run on the event loop */
1358 JANET_API void janet_schedule(JanetFiber *fiber, Janet value);
1359 JANET_API void janet_cancel(JanetFiber *fiber, Janet value);
1360 JANET_API void janet_schedule_signal(JanetFiber *fiber, Janet value, JanetSignal sig);
1361 
1362 /* Start a state machine listening for events from a stream */
1363 JANET_API JanetListenerState *janet_listen(JanetStream *stream, JanetListener behavior, int mask, size_t size, void *user);
1364 
1365 /* Shorthand for yielding to event loop in C */
1366 JANET_NO_RETURN JANET_API void janet_await(void);
1367 JANET_NO_RETURN JANET_API void janet_sleep_await(double sec);
1368 
1369 /* For use inside listeners - adds a timeout to the current fiber, such that
1370  * it will be resumed after sec seconds if no other event schedules the current fiber. */
1371 JANET_API void janet_addtimeout(double sec);
1372 JANET_API void janet_ev_inc_refcount(void);
1373 JANET_API void janet_ev_dec_refcount(void);
1374 
1375 /* Thread aware abstract types and helpers */
1376 JANET_API void *janet_abstract_begin_threaded(const JanetAbstractType *atype, size_t size);
1377 JANET_API void *janet_abstract_end_threaded(void *x);
1378 JANET_API void *janet_abstract_threaded(const JanetAbstractType *atype, size_t size);
1379 JANET_API int32_t janet_abstract_incref(void *abst);
1380 JANET_API int32_t janet_abstract_decref(void *abst);
1381 
1382 /* Expose some OS sync primitives to make portable abstract types easier to implement */
1383 JANET_API void janet_os_mutex_init(JanetOSMutex *mutex);
1384 JANET_API void janet_os_mutex_deinit(JanetOSMutex *mutex);
1385 JANET_API void janet_os_mutex_lock(JanetOSMutex *mutex);
1386 JANET_API void janet_os_mutex_unlock(JanetOSMutex *mutex);
1387 
1388 /* Get last error from an IO operation */
1389 JANET_API Janet janet_ev_lasterr(void);
1390 
1391 /* Async service for calling a function or syscall in a background thread. This is not
1392  * as efficient in the slightest as using Streams but can be used for arbitrary blocking
1393  * functions and syscalls. */
1394 
1395 /* Used to pass data between the main thread and worker threads for simple tasks.
1396  * We could just use a pointer but this prevents malloc/free in the common case
1397  * of only a handful of arguments. */
1398 typedef struct {
1399     int tag;
1400     int argi;
1401     void *argp;
1402     Janet argj;
1403     JanetFiber *fiber;
1404 } JanetEVGenericMessage;
1405 
1406 /* How to resume or cancel after a threaded call. Not exhaustive of the possible
1407  * ways one might want to resume after returning from a threaded call, but should
1408  * cover most of the common cases. For something more complicated, such as resuming
1409  * with an abstract type or a struct, one should use janet_ev_threaded_call instead
1410  * of janet_ev_threaded_await with a custom callback. */
1411 
1412 #define JANET_EV_TCTAG_NIL 0          /* resume with nil */
1413 #define JANET_EV_TCTAG_INTEGER 1      /* resume with janet_wrap_integer(argi) */
1414 #define JANET_EV_TCTAG_STRING 2       /* resume with janet_cstringv((const char *) argp) */
1415 #define JANET_EV_TCTAG_STRINGF 3      /* resume with janet_cstringv((const char *) argp), then call free on argp. */
1416 #define JANET_EV_TCTAG_KEYWORD 4      /* resume with janet_ckeywordv((const char *) argp) */
1417 #define JANET_EV_TCTAG_ERR_STRING 5   /* cancel with janet_cstringv((const char *) argp) */
1418 #define JANET_EV_TCTAG_ERR_STRINGF 6  /* cancel with janet_cstringv((const char *) argp), then call free on argp. */
1419 #define JANET_EV_TCTAG_ERR_KEYWORD 7  /* cancel with janet_ckeywordv((const char *) argp) */
1420 #define JANET_EV_TCTAG_BOOLEAN 8      /* resume with janet_wrap_boolean(argi) */
1421 
1422 /* Function pointer that is run in the thread pool */
1423 typedef JanetEVGenericMessage(*JanetThreadedSubroutine)(JanetEVGenericMessage arguments);
1424 
1425 /* Handler for events posted to the event loop */
1426 typedef void (*JanetCallback)(JanetEVGenericMessage return_value);
1427 
1428 /* Handler that is run in the main thread with the result of the JanetAsyncSubroutine (same as JanetCallback) */
1429 typedef void (*JanetThreadedCallback)(JanetEVGenericMessage return_value);
1430 
1431 /* API calls for quickly offloading some work in C to a new thread or thread pool. */
1432 JANET_API void janet_ev_threaded_call(JanetThreadedSubroutine fp, JanetEVGenericMessage arguments, JanetThreadedCallback cb);
1433 JANET_NO_RETURN JANET_API void janet_ev_threaded_await(JanetThreadedSubroutine fp, int tag, int argi, void *argp);
1434 
1435 /* Post callback + userdata to an event loop. Takes the vm parameter to allow posting from other
1436  * threads or signal handlers. Use NULL to post to the current thread. */
1437 JANET_API void janet_ev_post_event(JanetVM *vm, JanetCallback cb, JanetEVGenericMessage msg);
1438 
1439 /* Callback used by janet_ev_threaded_await */
1440 JANET_API void janet_ev_default_threaded_callback(JanetEVGenericMessage return_value);
1441 
1442 /* Read async from a stream */
1443 JANET_API void janet_ev_read(JanetStream *stream, JanetBuffer *buf, int32_t nbytes);
1444 JANET_API void janet_ev_readchunk(JanetStream *stream, JanetBuffer *buf, int32_t nbytes);
1445 #ifdef JANET_NET
1446 JANET_API void janet_ev_recv(JanetStream *stream, JanetBuffer *buf, int32_t nbytes, int flags);
1447 JANET_API void janet_ev_recvchunk(JanetStream *stream, JanetBuffer *buf, int32_t nbytes, int flags);
1448 JANET_API void janet_ev_recvfrom(JanetStream *stream, JanetBuffer *buf, int32_t nbytes, int flags);
1449 #endif
1450 
1451 /* Write async to a stream */
1452 JANET_API void janet_ev_write_buffer(JanetStream *stream, JanetBuffer *buf);
1453 JANET_API void janet_ev_write_string(JanetStream *stream, JanetString str);
1454 #ifdef JANET_NET
1455 JANET_API void janet_ev_send_buffer(JanetStream *stream, JanetBuffer *buf, int flags);
1456 JANET_API void janet_ev_send_string(JanetStream *stream, JanetString str, int flags);
1457 JANET_API void janet_ev_sendto_buffer(JanetStream *stream, JanetBuffer *buf, void *dest, int flags);
1458 JANET_API void janet_ev_sendto_string(JanetStream *stream, JanetString str, void *dest, int flags);
1459 #endif
1460 
1461 #endif
1462 
1463 /* Parsing */
1464 extern JANET_API const JanetAbstractType janet_parser_type;
1465 JANET_API void janet_parser_init(JanetParser *parser);
1466 JANET_API void janet_parser_deinit(JanetParser *parser);
1467 JANET_API void janet_parser_consume(JanetParser *parser, uint8_t c);
1468 JANET_API enum JanetParserStatus janet_parser_status(JanetParser *parser);
1469 JANET_API Janet janet_parser_produce(JanetParser *parser);
1470 JANET_API Janet janet_parser_produce_wrapped(JanetParser *parser);
1471 JANET_API const char *janet_parser_error(JanetParser *parser);
1472 JANET_API void janet_parser_flush(JanetParser *parser);
1473 JANET_API void janet_parser_eof(JanetParser *parser);
1474 JANET_API int janet_parser_has_more(JanetParser *parser);
1475 
1476 /* Assembly */
1477 #ifdef JANET_ASSEMBLER
1478 typedef struct JanetAssembleResult JanetAssembleResult;
1479 enum JanetAssembleStatus {
1480     JANET_ASSEMBLE_OK,
1481     JANET_ASSEMBLE_ERROR
1482 };
1483 struct JanetAssembleResult {
1484     JanetFuncDef *funcdef;
1485     JanetString error;
1486     enum JanetAssembleStatus status;
1487 };
1488 JANET_API JanetAssembleResult janet_asm(Janet source, int flags);
1489 JANET_API Janet janet_disasm(JanetFuncDef *def);
1490 JANET_API Janet janet_asm_decode_instruction(uint32_t instr);
1491 #endif
1492 
1493 /* Compilation */
1494 typedef struct JanetCompileResult JanetCompileResult;
1495 enum JanetCompileStatus {
1496     JANET_COMPILE_OK,
1497     JANET_COMPILE_ERROR
1498 };
1499 struct JanetCompileResult {
1500     JanetFuncDef *funcdef;
1501     JanetString error;
1502     JanetFiber *macrofiber;
1503     JanetSourceMapping error_mapping;
1504     enum JanetCompileStatus status;
1505 };
1506 JANET_API JanetCompileResult janet_compile(Janet source, JanetTable *env, JanetString where);
1507 JANET_API JanetCompileResult janet_compile_lint(
1508     Janet source,
1509     JanetTable *env,
1510     JanetString where,
1511     JanetArray *lints);
1512 
1513 /* Get the default environment for janet */
1514 JANET_API JanetTable *janet_core_env(JanetTable *replacements);
1515 JANET_API JanetTable *janet_core_lookup_table(JanetTable *replacements);
1516 
1517 /* Execute strings */
1518 JANET_API int janet_dobytes(JanetTable *env, const uint8_t *bytes, int32_t len, const char *sourcePath, Janet *out);
1519 JANET_API int janet_dostring(JanetTable *env, const char *str, const char *sourcePath, Janet *out);
1520 
1521 /* Run the entrypoint of a wrapped program */
1522 JANET_API int janet_loop_fiber(JanetFiber *fiber);
1523 
1524 /* Number scanning */
1525 JANET_API int janet_scan_number(const uint8_t *str, int32_t len, double *out);
1526 JANET_API int janet_scan_number_base(const uint8_t *str, int32_t len, int32_t base, double *out);
1527 JANET_API int janet_scan_int64(const uint8_t *str, int32_t len, int64_t *out);
1528 JANET_API int janet_scan_uint64(const uint8_t *str, int32_t len, uint64_t *out);
1529 
1530 /* Debugging */
1531 JANET_API void janet_debug_break(JanetFuncDef *def, int32_t pc);
1532 JANET_API void janet_debug_unbreak(JanetFuncDef *def, int32_t pc);
1533 JANET_API void janet_debug_find(
1534     JanetFuncDef **def_out, int32_t *pc_out,
1535     JanetString source, int32_t line, int32_t column);
1536 
1537 /* RNG */
1538 extern JANET_API const JanetAbstractType janet_rng_type;
1539 JANET_API JanetRNG *janet_default_rng(void);
1540 JANET_API void janet_rng_seed(JanetRNG *rng, uint32_t seed);
1541 JANET_API void janet_rng_longseed(JanetRNG *rng, const uint8_t *bytes, int32_t len);
1542 JANET_API uint32_t janet_rng_u32(JanetRNG *rng);
1543 JANET_API double janet_rng_double(JanetRNG *rng);
1544 
1545 /* Array functions */
1546 JANET_API JanetArray *janet_array(int32_t capacity);
1547 JANET_API JanetArray *janet_array_n(const Janet *elements, int32_t n);
1548 JANET_API void janet_array_ensure(JanetArray *array, int32_t capacity, int32_t growth);
1549 JANET_API void janet_array_setcount(JanetArray *array, int32_t count);
1550 JANET_API void janet_array_push(JanetArray *array, Janet x);
1551 JANET_API Janet janet_array_pop(JanetArray *array);
1552 JANET_API Janet janet_array_peek(JanetArray *array);
1553 
1554 /* Buffer functions */
1555 JANET_API JanetBuffer *janet_buffer(int32_t capacity);
1556 JANET_API JanetBuffer *janet_buffer_init(JanetBuffer *buffer, int32_t capacity);
1557 JANET_API void janet_buffer_deinit(JanetBuffer *buffer);
1558 JANET_API void janet_buffer_ensure(JanetBuffer *buffer, int32_t capacity, int32_t growth);
1559 JANET_API void janet_buffer_setcount(JanetBuffer *buffer, int32_t count);
1560 JANET_API void janet_buffer_extra(JanetBuffer *buffer, int32_t n);
1561 JANET_API void janet_buffer_push_bytes(JanetBuffer *buffer, const uint8_t *string, int32_t len);
1562 JANET_API void janet_buffer_push_string(JanetBuffer *buffer, JanetString string);
1563 JANET_API void janet_buffer_push_cstring(JanetBuffer *buffer, const char *cstring);
1564 JANET_API void janet_buffer_push_u8(JanetBuffer *buffer, uint8_t x);
1565 JANET_API void janet_buffer_push_u16(JanetBuffer *buffer, uint16_t x);
1566 JANET_API void janet_buffer_push_u32(JanetBuffer *buffer, uint32_t x);
1567 JANET_API void janet_buffer_push_u64(JanetBuffer *buffer, uint64_t x);
1568 
1569 /* Tuple */
1570 
1571 #define JANET_TUPLE_FLAG_BRACKETCTOR 0x10000
1572 
1573 #define janet_tuple_head(t) ((JanetTupleHead *)((char *)t - offsetof(JanetTupleHead, data)))
1574 #define janet_tuple_from_head(gcobject) ((const Janet *)((char *)gcobject + offsetof(JanetTupleHead, data)))
1575 #define janet_tuple_length(t) (janet_tuple_head(t)->length)
1576 #define janet_tuple_hash(t) (janet_tuple_head(t)->hash)
1577 #define janet_tuple_sm_line(t) (janet_tuple_head(t)->sm_line)
1578 #define janet_tuple_sm_column(t) (janet_tuple_head(t)->sm_column)
1579 #define janet_tuple_flag(t) (janet_tuple_head(t)->gc.flags)
1580 JANET_API Janet *janet_tuple_begin(int32_t length);
1581 JANET_API JanetTuple janet_tuple_end(Janet *tuple);
1582 JANET_API JanetTuple janet_tuple_n(const Janet *values, int32_t n);
1583 
1584 /* String/Symbol functions */
1585 #define janet_string_head(s) ((JanetStringHead *)((char *)s - offsetof(JanetStringHead, data)))
1586 #define janet_string_length(s) (janet_string_head(s)->length)
1587 #define janet_string_hash(s) (janet_string_head(s)->hash)
1588 JANET_API uint8_t *janet_string_begin(int32_t length);
1589 JANET_API JanetString janet_string_end(uint8_t *str);
1590 JANET_API JanetString janet_string(const uint8_t *buf, int32_t len);
1591 JANET_API JanetString janet_cstring(const char *cstring);
1592 JANET_API int janet_string_compare(JanetString lhs, JanetString rhs);
1593 JANET_API int janet_string_equal(JanetString lhs, JanetString rhs);
1594 JANET_API int janet_string_equalconst(JanetString lhs, const uint8_t *rhs, int32_t rlen, int32_t rhash);
1595 JANET_API JanetString janet_description(Janet x);
1596 JANET_API JanetString janet_to_string(Janet x);
1597 JANET_API void janet_to_string_b(JanetBuffer *buffer, Janet x);
1598 JANET_API void janet_description_b(JanetBuffer *buffer, Janet x);
1599 #define janet_cstringv(cstr) janet_wrap_string(janet_cstring(cstr))
1600 #define janet_stringv(str, len) janet_wrap_string(janet_string((str), (len)))
1601 JANET_API JanetString janet_formatc(const char *format, ...);
1602 JANET_API JanetBuffer *janet_formatb(JanetBuffer *bufp, const char *format, ...);
1603 JANET_API void janet_formatbv(JanetBuffer *bufp, const char *format, va_list args);
1604 
1605 /* Symbol functions */
1606 JANET_API JanetSymbol janet_symbol(const uint8_t *str, int32_t len);
1607 JANET_API JanetSymbol janet_csymbol(const char *str);
1608 JANET_API JanetSymbol janet_symbol_gen(void);
1609 #define janet_symbolv(str, len) janet_wrap_symbol(janet_symbol((str), (len)))
1610 #define janet_csymbolv(cstr) janet_wrap_symbol(janet_csymbol(cstr))
1611 
1612 /* Keyword functions */
1613 #define janet_keyword janet_symbol
1614 #define janet_ckeyword janet_csymbol
1615 #define janet_keywordv(str, len) janet_wrap_keyword(janet_keyword((str), (len)))
1616 #define janet_ckeywordv(cstr) janet_wrap_keyword(janet_ckeyword(cstr))
1617 
1618 /* Structs */
1619 #define janet_struct_head(t) ((JanetStructHead *)((char *)t - offsetof(JanetStructHead, data)))
1620 #define janet_struct_from_head(t) ((const JanetKV *)((char *)gcobject + offsetof(JanetStructHead, data)))
1621 #define janet_struct_length(t) (janet_struct_head(t)->length)
1622 #define janet_struct_capacity(t) (janet_struct_head(t)->capacity)
1623 #define janet_struct_hash(t) (janet_struct_head(t)->hash)
1624 #define janet_struct_proto(t) (janet_struct_head(t)->proto)
1625 JANET_API JanetKV *janet_struct_begin(int32_t count);
1626 JANET_API void janet_struct_put(JanetKV *st, Janet key, Janet value);
1627 JANET_API JanetStruct janet_struct_end(JanetKV *st);
1628 JANET_API Janet janet_struct_get(JanetStruct st, Janet key);
1629 JANET_API Janet janet_struct_rawget(JanetStruct st, Janet key);
1630 JANET_API Janet janet_struct_get_ex(JanetStruct st, Janet key, JanetStruct *which);
1631 JANET_API JanetTable *janet_struct_to_table(JanetStruct st);
1632 JANET_API const JanetKV *janet_struct_find(JanetStruct st, Janet key);
1633 
1634 /* Table functions */
1635 JANET_API JanetTable *janet_table(int32_t capacity);
1636 JANET_API JanetTable *janet_table_init(JanetTable *table, int32_t capacity);
1637 JANET_API JanetTable *janet_table_init_raw(JanetTable *table, int32_t capacity);
1638 JANET_API void janet_table_deinit(JanetTable *table);
1639 JANET_API Janet janet_table_get(JanetTable *t, Janet key);
1640 JANET_API Janet janet_table_get_ex(JanetTable *t, Janet key, JanetTable **which);
1641 JANET_API Janet janet_table_rawget(JanetTable *t, Janet key);
1642 JANET_API Janet janet_table_remove(JanetTable *t, Janet key);
1643 JANET_API void janet_table_put(JanetTable *t, Janet key, Janet value);
1644 JANET_API JanetStruct janet_table_to_struct(JanetTable *t);
1645 JANET_API void janet_table_merge_table(JanetTable *table, JanetTable *other);
1646 JANET_API void janet_table_merge_struct(JanetTable *table, JanetStruct other);
1647 JANET_API JanetKV *janet_table_find(JanetTable *t, Janet key);
1648 JANET_API JanetTable *janet_table_clone(JanetTable *table);
1649 JANET_API void janet_table_clear(JanetTable *table);
1650 
1651 /* Fiber */
1652 JANET_API JanetFiber *janet_fiber(JanetFunction *callee, int32_t capacity, int32_t argc, const Janet *argv);
1653 JANET_API JanetFiber *janet_fiber_reset(JanetFiber *fiber, JanetFunction *callee, int32_t argc, const Janet *argv);
1654 JANET_API JanetFiberStatus janet_fiber_status(JanetFiber *fiber);
1655 JANET_API JanetFiber *janet_current_fiber(void);
1656 JANET_API JanetFiber *janet_root_fiber(void);
1657 
1658 /* Treat similar types through uniform interfaces for iteration */
1659 JANET_API int janet_indexed_view(Janet seq, const Janet **data, int32_t *len);
1660 JANET_API int janet_bytes_view(Janet str, const uint8_t **data, int32_t *len);
1661 JANET_API int janet_dictionary_view(Janet tab, const JanetKV **data, int32_t *len, int32_t *cap);
1662 JANET_API Janet janet_dictionary_get(const JanetKV *data, int32_t cap, Janet key);
1663 JANET_API const JanetKV *janet_dictionary_next(const JanetKV *kvs, int32_t cap, const JanetKV *kv);
1664 
1665 /* Abstract */
1666 #define janet_abstract_head(u) ((JanetAbstractHead *)((char *)u - offsetof(JanetAbstractHead, data)))
1667 #define janet_abstract_from_head(gcobject) ((JanetAbstract)((char *)gcobject + offsetof(JanetAbstractHead, data)))
1668 #define janet_abstract_type(u) (janet_abstract_head(u)->type)
1669 #define janet_abstract_size(u) (janet_abstract_head(u)->size)
1670 JANET_API void *janet_abstract_begin(const JanetAbstractType *type, size_t size);
1671 JANET_API JanetAbstract janet_abstract_end(void *abstractTemplate);
1672 JANET_API JanetAbstract janet_abstract(const JanetAbstractType *type, size_t size); /* begin and end in one call */
1673 
1674 /* Native */
1675 typedef void (*JanetModule)(JanetTable *);
1676 typedef JanetBuildConfig(*JanetModconf)(void);
1677 JANET_API JanetModule janet_native(const char *name, JanetString *error);
1678 
1679 /* Marshaling */
1680 #define JANET_MARSHAL_UNSAFE 0x20000
1681 
1682 JANET_API void janet_marshal(
1683     JanetBuffer *buf,
1684     Janet x,
1685     JanetTable *rreg,
1686     int flags);
1687 JANET_API Janet janet_unmarshal(
1688     const uint8_t *bytes,
1689     size_t len,
1690     int flags,
1691     JanetTable *reg,
1692     const uint8_t **next);
1693 JANET_API JanetTable *janet_env_lookup(JanetTable *env);
1694 JANET_API void janet_env_lookup_into(JanetTable *renv, JanetTable *env, const char *prefix, int recurse);
1695 
1696 /* GC */
1697 JANET_API void janet_mark(Janet x);
1698 JANET_API void janet_sweep(void);
1699 JANET_API void janet_collect(void);
1700 JANET_API void janet_clear_memory(void);
1701 JANET_API void janet_gcroot(Janet root);
1702 JANET_API int janet_gcunroot(Janet root);
1703 JANET_API int janet_gcunrootall(Janet root);
1704 JANET_API int janet_gclock(void);
1705 JANET_API void janet_gcunlock(int handle);
1706 JANET_API void janet_gcpressure(size_t s);
1707 
1708 /* Functions */
1709 JANET_API JanetFuncDef *janet_funcdef_alloc(void);
1710 JANET_API JanetFunction *janet_thunk(JanetFuncDef *def);
1711 JANET_API int janet_verify(JanetFuncDef *def);
1712 
1713 /* Pretty printing */
1714 #define JANET_PRETTY_COLOR 1
1715 #define JANET_PRETTY_ONELINE 2
1716 #define JANET_PRETTY_NOTRUNC 4
1717 JANET_API JanetBuffer *janet_pretty(JanetBuffer *buffer, int depth, int flags, Janet x);
1718 
1719 /* Misc */
1720 #ifdef JANET_PRF
1721 #define JANET_HASH_KEY_SIZE 16
1722 JANET_API void janet_init_hash_key(uint8_t key[JANET_HASH_KEY_SIZE]);
1723 #endif
1724 JANET_API void janet_try_init(JanetTryState *state);
1725 #if defined(JANET_BSD) || defined(JANET_APPLE)
1726 #define janet_try(state) (janet_try_init(state), (JanetSignal) _setjmp((state)->buf))
1727 #else
1728 #define janet_try(state) (janet_try_init(state), (JanetSignal) setjmp((state)->buf))
1729 #endif
1730 JANET_API void janet_restore(JanetTryState *state);
1731 JANET_API int janet_equals(Janet x, Janet y);
1732 JANET_API int32_t janet_hash(Janet x);
1733 JANET_API int janet_compare(Janet x, Janet y);
1734 JANET_API int janet_cstrcmp(JanetString str, const char *other);
1735 JANET_API Janet janet_in(Janet ds, Janet key);
1736 JANET_API Janet janet_get(Janet ds, Janet key);
1737 JANET_API Janet janet_next(Janet ds, Janet key);
1738 JANET_API Janet janet_getindex(Janet ds, int32_t index);
1739 JANET_API int32_t janet_length(Janet x);
1740 JANET_API Janet janet_lengthv(Janet x);
1741 JANET_API void janet_put(Janet ds, Janet key, Janet value);
1742 JANET_API void janet_putindex(Janet ds, int32_t index, Janet value);
1743 #define janet_flag_at(F, I) ((F) & ((1ULL) << (I)))
1744 JANET_API Janet janet_wrap_number_safe(double x);
1745 JANET_API int janet_keyeq(Janet x, const char *cstring);
1746 JANET_API int janet_streq(Janet x, const char *cstring);
1747 JANET_API int janet_symeq(Janet x, const char *cstring);
1748 JANET_API int32_t janet_sorted_keys(const JanetKV *dict, int32_t cap, int32_t *index_buffer);
1749 
1750 /* VM functions */
1751 JANET_API int janet_init(void);
1752 JANET_API void janet_deinit(void);
1753 JANET_API JanetVM *janet_vm_alloc(void);
1754 JANET_API JanetVM *janet_local_vm(void);
1755 JANET_API void janet_vm_free(JanetVM *vm);
1756 JANET_API void janet_vm_save(JanetVM *into);
1757 JANET_API void janet_vm_load(JanetVM *from);
1758 JANET_API void janet_interpreter_interrupt(JanetVM *vm);
1759 JANET_API JanetSignal janet_continue(JanetFiber *fiber, Janet in, Janet *out);
1760 JANET_API JanetSignal janet_continue_signal(JanetFiber *fiber, Janet in, Janet *out, JanetSignal sig);
1761 JANET_API JanetSignal janet_pcall(JanetFunction *fun, int32_t argn, const Janet *argv, Janet *out, JanetFiber **f);
1762 JANET_API JanetSignal janet_step(JanetFiber *fiber, Janet in, Janet *out);
1763 JANET_API Janet janet_call(JanetFunction *fun, int32_t argc, const Janet *argv);
1764 JANET_API Janet janet_mcall(const char *name, int32_t argc, Janet *argv);
1765 JANET_API void janet_stacktrace(JanetFiber *fiber, Janet err);
1766 JANET_API void janet_stacktrace_ext(JanetFiber *fiber, Janet err, const char *prefix);
1767 
1768 /* Scratch Memory API */
1769 typedef void (*JanetScratchFinalizer)(void *);
1770 
1771 JANET_API void *janet_smalloc(size_t size);
1772 JANET_API void *janet_srealloc(void *mem, size_t size);
1773 JANET_API void *janet_scalloc(size_t nmemb, size_t size);
1774 JANET_API void janet_sfinalizer(void *mem, JanetScratchFinalizer finalizer);
1775 JANET_API void janet_sfree(void *mem);
1776 
1777 /* C Library helpers */
1778 typedef enum {
1779     JANET_BINDING_NONE,
1780     JANET_BINDING_DEF,
1781     JANET_BINDING_VAR,
1782     JANET_BINDING_MACRO
1783 } JanetBindingType;
1784 
1785 typedef struct {
1786     JanetBindingType type;
1787     Janet value;
1788     enum {
1789         JANET_BINDING_DEP_NONE,
1790         JANET_BINDING_DEP_RELAXED,
1791         JANET_BINDING_DEP_NORMAL,
1792         JANET_BINDING_DEP_STRICT,
1793     } deprecation;
1794 } JanetBinding;
1795 
1796 JANET_API void janet_def(JanetTable *env, const char *name, Janet val, const char *documentation);
1797 JANET_API void janet_var(JanetTable *env, const char *name, Janet val, const char *documentation);
1798 JANET_API void janet_cfuns(JanetTable *env, const char *regprefix, const JanetReg *cfuns);
1799 JANET_API void janet_cfuns_prefix(JanetTable *env, const char *regprefix, const JanetReg *cfuns);
1800 JANET_API JanetBindingType janet_resolve(JanetTable *env, JanetSymbol sym, Janet *out);
1801 JANET_API JanetBinding janet_resolve_ext(JanetTable *env, JanetSymbol sym);
1802 
1803 /* Get values from the core environment. */
1804 JANET_API Janet janet_resolve_core(const char *name);
1805 
1806 /* New C API */
1807 
1808 /* Shorthand for janet C function declarations */
1809 #define JANET_CFUN(name) Janet name (int32_t argc, Janet *argv)
1810 
1811 /* Declare a C function with documentation and source mapping */
1812 #define JANET_REG_END {NULL, NULL, NULL, NULL, 0}
1813 
1814 /* no docstrings or sourcemaps */
1815 #define JANET_REG_(JNAME, CNAME) {JNAME, CNAME, NULL, NULL, 0}
1816 #define JANET_FN_(CNAME, USAGE, DOCSTRING) \
1817     Janet CNAME (int32_t argc, Janet *argv)
1818 #define JANET_DEF_(ENV, JNAME, VAL, DOC) \
1819     janet_def(ENV, JNAME, VAL, NULL)
1820 
1821 /* sourcemaps only */
1822 #define JANET_REG_S(JNAME, CNAME) {JNAME, CNAME, NULL, __FILE__, CNAME##_sourceline_}
1823 #define JANET_FN_S(CNAME, USAGE, DOCSTRING) \
1824     static int32_t CNAME##_sourceline_ = __LINE__; \
1825     Janet CNAME (int32_t argc, Janet *argv)
1826 #define JANET_DEF_S(ENV, JNAME, VAL, DOC) \
1827     janet_def_sm(ENV, JNAME, VAL, NULL, __FILE__, __LINE__)
1828 
1829 /* docstring only */
1830 #define JANET_REG_D(JNAME, CNAME) {JNAME, CNAME, CNAME##_docstring_, NULL, 0}
1831 #define JANET_FN_D(CNAME, USAGE, DOCSTRING) \
1832     static const char CNAME##_docstring_[] = USAGE "\n\n" DOCSTRING; \
1833     Janet CNAME (int32_t argc, Janet *argv)
1834 #define JANET_DEF_D(ENV, JNAME, VAL, DOC) \
1835     janet_def(ENV, JNAME, VAL, DOC)
1836 
1837 /* sourcemaps and docstrings */
1838 #define JANET_REG_SD(JNAME, CNAME) {JNAME, CNAME, CNAME##_docstring_, __FILE__, CNAME##_sourceline_}
1839 #define JANET_FN_SD(CNAME, USAGE, DOCSTRING) \
1840     static int32_t CNAME##_sourceline_ = __LINE__; \
1841     static const char CNAME##_docstring_[] = USAGE "\n\n" DOCSTRING; \
1842     Janet CNAME (int32_t argc, Janet *argv)
1843 #define JANET_DEF_SD(ENV, JNAME, VAL, DOC) \
1844     janet_def_sm(ENV, JNAME, VAL, DOC, __FILE__, __LINE__)
1845 
1846 
1847 /* Choose defaults for source mapping and docstring based on config defs */
1848 #if defined(JANET_NO_SOURCEMAPS) && defined(JANET_NO_DOCSTRINGS)
1849 #define JANET_REG JANET_REG_
1850 #define JANET_FN JANET_FN_
1851 #define JANET_DEF JANET_DEF_
1852 #elif defined(JANET_NO_SOURCEMAPS) && !defined(JANET_NO_DOCSTRINGS)
1853 #define JANET_REG JANET_REG_D
1854 #define JANET_FN JANET_FN_D
1855 #define JANET_DEF JANET_DEF_D
1856 #elif !defined(JANET_NO_SOURCEMAPS) && defined(JANET_NO_DOCSTRINGS)
1857 #define JANET_REG JANET_REG_S
1858 #define JANET_FN JANET_FN_S
1859 #define JANET_DEF JANET_DEF_S
1860 #elif !defined(JANET_NO_SOURCEMAPS) && !defined(JANET_NO_DOCSTRINGS)
1861 #define JANET_REG JANET_REG_SD
1862 #define JANET_FN JANET_FN_SD
1863 #define JANET_DEF JANET_DEF_SD
1864 #endif
1865 
1866 /* Define things with source mapping information */
1867 JANET_API void janet_cfuns_ext(JanetTable *env, const char *regprefix, const JanetRegExt *cfuns);
1868 JANET_API void janet_cfuns_ext_prefix(JanetTable *env, const char *regprefix, const JanetRegExt *cfuns);
1869 JANET_API void janet_def_sm(JanetTable *env, const char *name, Janet val, const char *documentation, const char *source_file, int32_t source_line);
1870 JANET_API void janet_var_sm(JanetTable *env, const char *name, Janet val, const char *documentation, const char *source_file, int32_t source_line);
1871 
1872 /* Legacy definition of C functions */
1873 JANET_API void janet_register(const char *name, JanetCFunction cfun);
1874 
1875 /* Allow setting entry name for static libraries */
1876 #ifdef __cplusplus
1877 #define JANET_MODULE_PREFIX extern "C"
1878 #else
1879 #define JANET_MODULE_PREFIX
1880 #endif
1881 #ifndef JANET_ENTRY_NAME
1882 #define JANET_MODULE_ENTRY \
1883     JANET_MODULE_PREFIX JANET_API JanetBuildConfig _janet_mod_config(void) { \
1884         return janet_config_current(); \
1885     } \
1886     JANET_MODULE_PREFIX JANET_API void _janet_init
1887 #else
1888 #define JANET_MODULE_ENTRY JANET_MODULE_PREFIX JANET_API void JANET_ENTRY_NAME
1889 #endif
1890 
1891 JANET_NO_RETURN JANET_API void janet_signalv(JanetSignal signal, Janet message);
1892 JANET_NO_RETURN JANET_API void janet_panicv(Janet message);
1893 JANET_NO_RETURN JANET_API void janet_panic(const char *message);
1894 JANET_NO_RETURN JANET_API void janet_panics(JanetString message);
1895 JANET_NO_RETURN JANET_API void janet_panicf(const char *format, ...);
1896 JANET_API void janet_dynprintf(const char *name, FILE *dflt_file, const char *format, ...);
1897 #define janet_printf(...) janet_dynprintf("out", stdout, __VA_ARGS__)
1898 #define janet_eprintf(...) janet_dynprintf("err", stderr, __VA_ARGS__)
1899 JANET_NO_RETURN JANET_API void janet_panic_type(Janet x, int32_t n, int expected);
1900 JANET_NO_RETURN JANET_API void janet_panic_abstract(Janet x, int32_t n, const JanetAbstractType *at);
1901 JANET_API void janet_arity(int32_t arity, int32_t min, int32_t max);
1902 JANET_API void janet_fixarity(int32_t arity, int32_t fix);
1903 
1904 JANET_API int janet_getmethod(JanetKeyword method, const JanetMethod *methods, Janet *out);
1905 JANET_API Janet janet_nextmethod(const JanetMethod *methods, Janet key);
1906 
1907 JANET_API double janet_getnumber(const Janet *argv, int32_t n);
1908 JANET_API JanetArray *janet_getarray(const Janet *argv, int32_t n);
1909 JANET_API JanetTuple janet_gettuple(const Janet *argv, int32_t n);
1910 JANET_API JanetTable *janet_gettable(const Janet *argv, int32_t n);
1911 JANET_API JanetStruct janet_getstruct(const Janet *argv, int32_t n);
1912 JANET_API JanetString janet_getstring(const Janet *argv, int32_t n);
1913 JANET_API const char *janet_getcstring(const Janet *argv, int32_t n);
1914 JANET_API JanetSymbol janet_getsymbol(const Janet *argv, int32_t n);
1915 JANET_API JanetKeyword janet_getkeyword(const Janet *argv, int32_t n);
1916 JANET_API JanetBuffer *janet_getbuffer(const Janet *argv, int32_t n);
1917 JANET_API JanetFiber *janet_getfiber(const Janet *argv, int32_t n);
1918 JANET_API JanetFunction *janet_getfunction(const Janet *argv, int32_t n);
1919 JANET_API JanetCFunction janet_getcfunction(const Janet *argv, int32_t n);
1920 JANET_API int janet_getboolean(const Janet *argv, int32_t n);
1921 JANET_API void *janet_getpointer(const Janet *argv, int32_t n);
1922 
1923 JANET_API int32_t janet_getnat(const Janet *argv, int32_t n);
1924 JANET_API int32_t janet_getinteger(const Janet *argv, int32_t n);
1925 JANET_API int64_t janet_getinteger64(const Janet *argv, int32_t n);
1926 JANET_API size_t janet_getsize(const Janet *argv, int32_t n);
1927 JANET_API JanetView janet_getindexed(const Janet *argv, int32_t n);
1928 JANET_API JanetByteView janet_getbytes(const Janet *argv, int32_t n);
1929 JANET_API JanetDictView janet_getdictionary(const Janet *argv, int32_t n);
1930 JANET_API void *janet_getabstract(const Janet *argv, int32_t n, const JanetAbstractType *at);
1931 JANET_API JanetRange janet_getslice(int32_t argc, const Janet *argv);
1932 JANET_API int32_t janet_gethalfrange(const Janet *argv, int32_t n, int32_t length, const char *which);
1933 JANET_API int32_t janet_getargindex(const Janet *argv, int32_t n, int32_t length, const char *which);
1934 JANET_API uint64_t janet_getflags(const Janet *argv, int32_t n, const char *flags);
1935 
1936 /* Optionals */
1937 JANET_API double janet_optnumber(const Janet *argv, int32_t argc, int32_t n, double dflt);
1938 JANET_API JanetTuple janet_opttuple(const Janet *argv, int32_t argc, int32_t n, JanetTuple dflt);
1939 JANET_API JanetStruct janet_optstruct(const Janet *argv, int32_t argc, int32_t n, JanetStruct dflt);
1940 JANET_API JanetString janet_optstring(const Janet *argv, int32_t argc, int32_t n, JanetString dflt);
1941 JANET_API const char *janet_optcstring(const Janet *argv, int32_t argc, int32_t n, const char *dflt);
1942 JANET_API JanetSymbol janet_optsymbol(const Janet *argv, int32_t argc, int32_t n, JanetString dflt);
1943 JANET_API JanetKeyword janet_optkeyword(const Janet *argv, int32_t argc, int32_t n, JanetString dflt);
1944 JANET_API JanetFiber *janet_optfiber(const Janet *argv, int32_t argc, int32_t n, JanetFiber *dflt);
1945 JANET_API JanetFunction *janet_optfunction(const Janet *argv, int32_t argc, int32_t n, JanetFunction *dflt);
1946 JANET_API JanetCFunction janet_optcfunction(const Janet *argv, int32_t argc, int32_t n, JanetCFunction dflt);
1947 JANET_API int janet_optboolean(const Janet *argv, int32_t argc, int32_t n, int dflt);
1948 JANET_API void *janet_optpointer(const Janet *argv, int32_t argc, int32_t n, void *dflt);
1949 JANET_API int32_t janet_optnat(const Janet *argv, int32_t argc, int32_t n, int32_t dflt);
1950 JANET_API int32_t janet_optinteger(const Janet *argv, int32_t argc, int32_t n, int32_t dflt);
1951 JANET_API int64_t janet_optinteger64(const Janet *argv, int32_t argc, int32_t n, int64_t dflt);
1952 JANET_API size_t janet_optsize(const Janet *argv, int32_t argc, int32_t n, size_t dflt);
1953 JANET_API JanetAbstract janet_optabstract(const Janet *argv, int32_t argc, int32_t n, const JanetAbstractType *at, JanetAbstract dflt);
1954 
1955 /* Mutable optional types specify a size default, and construct a new value if none is provided */
1956 JANET_API JanetBuffer *janet_optbuffer(const Janet *argv, int32_t argc, int32_t n, int32_t dflt_len);
1957 JANET_API JanetTable *janet_opttable(const Janet *argv, int32_t argc, int32_t n, int32_t dflt_len);
1958 JANET_API JanetArray *janet_optarray(const Janet *argv, int32_t argc, int32_t n, int32_t dflt_len);
1959 
1960 JANET_API Janet janet_dyn(const char *name);
1961 JANET_API void janet_setdyn(const char *name, Janet value);
1962 
1963 extern JANET_API const JanetAbstractType janet_file_type;
1964 
1965 #define JANET_FILE_WRITE 1
1966 #define JANET_FILE_READ 2
1967 #define JANET_FILE_APPEND 4
1968 #define JANET_FILE_UPDATE 8
1969 #define JANET_FILE_NOT_CLOSEABLE 16
1970 #define JANET_FILE_CLOSED 32
1971 #define JANET_FILE_BINARY 64
1972 #define JANET_FILE_SERIALIZABLE 128
1973 #define JANET_FILE_PIPED 256
1974 #define JANET_FILE_NONIL 512
1975 
1976 JANET_API Janet janet_makefile(FILE *f, int32_t flags);
1977 JANET_API JanetFile *janet_makejfile(FILE *f, int32_t flags);
1978 JANET_API FILE *janet_getfile(const Janet *argv, int32_t n, int32_t *flags);
1979 JANET_API FILE *janet_dynfile(const char *name, FILE *def);
1980 JANET_API JanetFile *janet_getjfile(const Janet *argv, int32_t n);
1981 JANET_API JanetAbstract janet_checkfile(Janet j);
1982 JANET_API FILE *janet_unwrapfile(Janet j, int32_t *flags);
1983 JANET_API int janet_file_close(JanetFile *file);
1984 
1985 JANET_API int janet_cryptorand(uint8_t *out, size_t n);
1986 
1987 /* Marshal API */
1988 JANET_API void janet_marshal_size(JanetMarshalContext *ctx, size_t value);
1989 JANET_API void janet_marshal_int(JanetMarshalContext *ctx, int32_t value);
1990 JANET_API void janet_marshal_int64(JanetMarshalContext *ctx, int64_t value);
1991 JANET_API void janet_marshal_byte(JanetMarshalContext *ctx, uint8_t value);
1992 JANET_API void janet_marshal_bytes(JanetMarshalContext *ctx, const uint8_t *bytes, size_t len);
1993 JANET_API void janet_marshal_janet(JanetMarshalContext *ctx, Janet x);
1994 JANET_API void janet_marshal_abstract(JanetMarshalContext *ctx, JanetAbstract abstract);
1995 
1996 JANET_API void janet_unmarshal_ensure(JanetMarshalContext *ctx, size_t size);
1997 JANET_API size_t janet_unmarshal_size(JanetMarshalContext *ctx);
1998 JANET_API int32_t janet_unmarshal_int(JanetMarshalContext *ctx);
1999 JANET_API int64_t janet_unmarshal_int64(JanetMarshalContext *ctx);
2000 JANET_API uint8_t janet_unmarshal_byte(JanetMarshalContext *ctx);
2001 JANET_API void janet_unmarshal_bytes(JanetMarshalContext *ctx, uint8_t *dest, size_t len);
2002 JANET_API Janet janet_unmarshal_janet(JanetMarshalContext *ctx);
2003 JANET_API JanetAbstract janet_unmarshal_abstract(JanetMarshalContext *ctx, size_t size);
2004 JANET_API void janet_unmarshal_abstract_reuse(JanetMarshalContext *ctx, void *p);
2005 
2006 JANET_API void janet_register_abstract_type(const JanetAbstractType *at);
2007 JANET_API const JanetAbstractType *janet_get_abstract_type(Janet key);
2008 
2009 #ifdef JANET_PEG
2010 
2011 extern JANET_API const JanetAbstractType janet_peg_type;
2012 
2013 /* opcodes for peg vm */
2014 typedef enum {
2015     RULE_LITERAL,      /* [len, bytes...] */
2016     RULE_NCHAR,        /* [n] */
2017     RULE_NOTNCHAR,     /* [n] */
2018     RULE_RANGE,        /* [lo | hi << 16 (1 word)] */
2019     RULE_SET,          /* [bitmap (8 words)] */
2020     RULE_LOOK,         /* [offset, rule] */
2021     RULE_CHOICE,       /* [len, rules...] */
2022     RULE_SEQUENCE,     /* [len, rules...] */
2023     RULE_IF,           /* [rule_a, rule_b (b if a)] */
2024     RULE_IFNOT,        /* [rule_a, rule_b (b if not a)] */
2025     RULE_NOT,          /* [rule] */
2026     RULE_BETWEEN,      /* [lo, hi, rule] */
2027     RULE_GETTAG,       /* [searchtag, tag] */
2028     RULE_CAPTURE,      /* [rule, tag] */
2029     RULE_POSITION,     /* [tag] */
2030     RULE_ARGUMENT,     /* [argument-index, tag] */
2031     RULE_CONSTANT,     /* [constant, tag] */
2032     RULE_ACCUMULATE,   /* [rule, tag] */
2033     RULE_GROUP,        /* [rule, tag] */
2034     RULE_REPLACE,      /* [rule, constant, tag] */
2035     RULE_MATCHTIME,    /* [rule, constant, tag] */
2036     RULE_ERROR,        /* [rule] */
2037     RULE_DROP,         /* [rule] */
2038     RULE_BACKMATCH,    /* [tag] */
2039     RULE_TO,           /* [rule] */
2040     RULE_THRU,         /* [rule] */
2041     RULE_LENPREFIX,    /* [rule_a, rule_b (repeat rule_b rule_a times)] */
2042     RULE_READINT,      /* [(signedness << 4) | (endianess << 5) | bytewidth, tag] */
2043     RULE_LINE,         /* [tag] */
2044     RULE_COLUMN,       /* [tag] */
2045     RULE_UNREF,        /* [rule, tag] */
2046     RULE_CAPTURE_NUM   /* [rule, tag] */
2047 } JanetPegOpcod;
2048 
2049 typedef struct {
2050     uint32_t *bytecode;
2051     Janet *constants;
2052     size_t bytecode_len;
2053     uint32_t num_constants;
2054     int has_backref;
2055 } JanetPeg;
2056 
2057 #endif
2058 
2059 #ifdef JANET_INT_TYPES
2060 
2061 extern JANET_API const JanetAbstractType janet_s64_type;
2062 extern JANET_API const JanetAbstractType janet_u64_type;
2063 
2064 typedef enum {
2065     JANET_INT_NONE,
2066     JANET_INT_S64,
2067     JANET_INT_U64
2068 } JanetIntType;
2069 
2070 JANET_API JanetIntType janet_is_int(Janet x);
2071 JANET_API Janet janet_wrap_s64(int64_t x);
2072 JANET_API Janet janet_wrap_u64(uint64_t x);
2073 JANET_API int64_t janet_unwrap_s64(Janet x);
2074 JANET_API uint64_t janet_unwrap_u64(Janet x);
2075 JANET_API int janet_scan_int64(const uint8_t *str, int32_t len, int64_t *out);
2076 JANET_API int janet_scan_uint64(const uint8_t *str, int32_t len, uint64_t *out);
2077 
2078 #endif
2079 
2080 #ifdef JANET_THREADS
2081 
2082 extern JANET_API const JanetAbstractType janet_thread_type;
2083 
2084 JANET_API int janet_thread_receive(Janet *msg_out, double timeout);
2085 JANET_API int janet_thread_send(JanetThread *thread, Janet msg, double timeout);
2086 JANET_API JanetThread *janet_thread_current(void);
2087 
2088 #endif
2089 
2090 /* Custom allocator support */
2091 JANET_API void *(janet_malloc)(size_t);
2092 JANET_API void *(janet_realloc)(void *, size_t);
2093 JANET_API void *(janet_calloc)(size_t, size_t);
2094 JANET_API void (janet_free)(void *);
2095 #ifndef janet_malloc
2096 #define janet_malloc(X) malloc((X))
2097 #endif
2098 #ifndef janet_realloc
2099 #define janet_realloc(X, Y) realloc((X), (Y))
2100 #endif
2101 #ifndef janet_calloc
2102 #define janet_calloc(X, Y) calloc((X), (Y))
2103 #endif
2104 #ifndef janet_free
2105 #define janet_free(X) free((X))
2106 #endif
2107 
2108 /***** END SECTION MAIN *****/
2109 
2110 /* Re-enable popped variable length array warnings */
2111 #ifdef _MSC_VER
2112 #pragma warning( pop )
2113 #endif
2114 
2115 #ifdef __cplusplus
2116 }
2117 #endif
2118 
2119 #endif /* JANET_H_defined */
2120