File Coverage

quickjs/quickjs.h
Criterion Covered Total %
statement 37 39 94.8
branch 6 10 60.0
condition n/a
subroutine n/a
pod n/a
total 43 49 87.7


line stmt bran cond sub pod time code
1             /*
2             * QuickJS Javascript Engine
3             *
4             * Copyright (c) 2017-2021 Fabrice Bellard
5             * Copyright (c) 2017-2021 Charlie Gordon
6             *
7             * Permission is hereby granted, free of charge, to any person obtaining a copy
8             * of this software and associated documentation files (the "Software"), to deal
9             * in the Software without restriction, including without limitation the rights
10             * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11             * copies of the Software, and to permit persons to whom the Software is
12             * furnished to do so, subject to the following conditions:
13             *
14             * The above copyright notice and this permission notice shall be included in
15             * all copies or substantial portions of the Software.
16             *
17             * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18             * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19             * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20             * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21             * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22             * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23             * THE SOFTWARE.
24             */
25             #ifndef QUICKJS_H
26             #define QUICKJS_H
27              
28             #include
29             #include
30              
31             #ifdef __cplusplus
32             extern "C" {
33             #endif
34              
35             #if defined(__GNUC__) || defined(__clang__)
36             #define js_likely(x) __builtin_expect(!!(x), 1)
37             #define js_unlikely(x) __builtin_expect(!!(x), 0)
38             #define js_force_inline inline __attribute__((always_inline))
39             #define __js_printf_like(f, a) __attribute__((format(printf, f, a)))
40             #else
41             #define js_likely(x) (x)
42             #define js_unlikely(x) (x)
43             #define js_force_inline inline
44             #define __js_printf_like(a, b)
45             #endif
46              
47             #define JS_BOOL int
48              
49             typedef struct JSRuntime JSRuntime;
50             typedef struct JSContext JSContext;
51             typedef struct JSObject JSObject;
52             typedef struct JSClass JSClass;
53             typedef uint32_t JSClassID;
54             typedef uint32_t JSAtom;
55              
56             #if INTPTR_MAX >= INT64_MAX
57             #define JS_PTR64
58             #define JS_PTR64_DEF(a) a
59             #else
60             #define JS_PTR64_DEF(a)
61             #endif
62              
63             #ifndef JS_PTR64
64             #define JS_NAN_BOXING
65             #endif
66              
67             enum {
68             /* all tags with a reference count are negative */
69             JS_TAG_FIRST = -11, /* first negative tag */
70             JS_TAG_BIG_DECIMAL = -11,
71             JS_TAG_BIG_INT = -10,
72             JS_TAG_BIG_FLOAT = -9,
73             JS_TAG_SYMBOL = -8,
74             JS_TAG_STRING = -7,
75             JS_TAG_MODULE = -3, /* used internally */
76             JS_TAG_FUNCTION_BYTECODE = -2, /* used internally */
77             JS_TAG_OBJECT = -1,
78              
79             JS_TAG_INT = 0,
80             JS_TAG_BOOL = 1,
81             JS_TAG_NULL = 2,
82             JS_TAG_UNDEFINED = 3,
83             JS_TAG_UNINITIALIZED = 4,
84             JS_TAG_CATCH_OFFSET = 5,
85             JS_TAG_EXCEPTION = 6,
86             JS_TAG_FLOAT64 = 7,
87             /* any larger tag is FLOAT64 if JS_NAN_BOXING */
88             };
89              
90             typedef struct JSRefCountHeader {
91             int ref_count;
92             } JSRefCountHeader;
93              
94             #define JS_FLOAT64_NAN NAN
95              
96             #ifdef CONFIG_CHECK_JSVALUE
97             /* JSValue consistency : it is not possible to run the code in this
98             mode, but it is useful to detect simple reference counting
99             errors. It would be interesting to modify a static C analyzer to
100             handle specific annotations (clang has such annotations but only
101             for objective C) */
102             typedef struct __JSValue *JSValue;
103             typedef const struct __JSValue *JSValueConst;
104              
105             #define JS_VALUE_GET_TAG(v) (int)((uintptr_t)(v) & 0xf)
106             /* same as JS_VALUE_GET_TAG, but return JS_TAG_FLOAT64 with NaN boxing */
107             #define JS_VALUE_GET_NORM_TAG(v) JS_VALUE_GET_TAG(v)
108             #define JS_VALUE_GET_INT(v) (int)((intptr_t)(v) >> 4)
109             #define JS_VALUE_GET_BOOL(v) JS_VALUE_GET_INT(v)
110             #define JS_VALUE_GET_FLOAT64(v) (double)JS_VALUE_GET_INT(v)
111             #define JS_VALUE_GET_PTR(v) (void *)((intptr_t)(v) & ~0xf)
112              
113             #define JS_MKVAL(tag, val) (JSValue)(intptr_t)(((val) << 4) | (tag))
114             #define JS_MKPTR(tag, p) (JSValue)((intptr_t)(p) | (tag))
115              
116             #define JS_TAG_IS_FLOAT64(tag) ((unsigned)(tag) == JS_TAG_FLOAT64)
117              
118             #define JS_NAN JS_MKVAL(JS_TAG_FLOAT64, 1)
119              
120             static inline JSValue __JS_NewFloat64(JSContext *ctx, double d)
121             {
122             return JS_MKVAL(JS_TAG_FLOAT64, (int)d);
123             }
124              
125             static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
126             {
127             return 0;
128             }
129            
130             #elif defined(JS_NAN_BOXING)
131              
132             typedef uint64_t JSValue;
133              
134             #define JSValueConst JSValue
135              
136             #define JS_VALUE_GET_TAG(v) (int)((v) >> 32)
137             #define JS_VALUE_GET_INT(v) (int)(v)
138             #define JS_VALUE_GET_BOOL(v) (int)(v)
139             #define JS_VALUE_GET_PTR(v) (void *)(intptr_t)(v)
140              
141             #define JS_MKVAL(tag, val) (((uint64_t)(tag) << 32) | (uint32_t)(val))
142             #define JS_MKPTR(tag, ptr) (((uint64_t)(tag) << 32) | (uintptr_t)(ptr))
143              
144             #define JS_FLOAT64_TAG_ADDEND (0x7ff80000 - JS_TAG_FIRST + 1) /* quiet NaN encoding */
145              
146             static inline double JS_VALUE_GET_FLOAT64(JSValue v)
147             {
148             union {
149             JSValue v;
150             double d;
151             } u;
152             u.v = v;
153             u.v += (uint64_t)JS_FLOAT64_TAG_ADDEND << 32;
154             return u.d;
155             }
156              
157             #define JS_NAN (0x7ff8000000000000 - ((uint64_t)JS_FLOAT64_TAG_ADDEND << 32))
158              
159             static inline JSValue __JS_NewFloat64(JSContext *ctx, double d)
160             {
161             union {
162             double d;
163             uint64_t u64;
164             } u;
165             JSValue v;
166             u.d = d;
167             /* normalize NaN */
168             if (js_unlikely((u.u64 & 0x7fffffffffffffff) > 0x7ff0000000000000))
169             v = JS_NAN;
170             else
171             v = u.u64 - ((uint64_t)JS_FLOAT64_TAG_ADDEND << 32);
172             return v;
173             }
174              
175             #define JS_TAG_IS_FLOAT64(tag) ((unsigned)((tag) - JS_TAG_FIRST) >= (JS_TAG_FLOAT64 - JS_TAG_FIRST))
176              
177             /* same as JS_VALUE_GET_TAG, but return JS_TAG_FLOAT64 with NaN boxing */
178             static inline int JS_VALUE_GET_NORM_TAG(JSValue v)
179             {
180             uint32_t tag;
181             tag = JS_VALUE_GET_TAG(v);
182             if (JS_TAG_IS_FLOAT64(tag))
183             return JS_TAG_FLOAT64;
184             else
185             return tag;
186             }
187              
188             static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
189             {
190             uint32_t tag;
191             tag = JS_VALUE_GET_TAG(v);
192             return tag == (JS_NAN >> 32);
193             }
194            
195             #else /* !JS_NAN_BOXING */
196              
197             typedef union JSValueUnion {
198             int32_t int32;
199             double float64;
200             void *ptr;
201             } JSValueUnion;
202              
203             typedef struct JSValue {
204             JSValueUnion u;
205             int64_t tag;
206             } JSValue;
207              
208             #define JSValueConst JSValue
209              
210             #define JS_VALUE_GET_TAG(v) ((int32_t)(v).tag)
211             /* same as JS_VALUE_GET_TAG, but return JS_TAG_FLOAT64 with NaN boxing */
212             #define JS_VALUE_GET_NORM_TAG(v) JS_VALUE_GET_TAG(v)
213             #define JS_VALUE_GET_INT(v) ((v).u.int32)
214             #define JS_VALUE_GET_BOOL(v) ((v).u.int32)
215             #define JS_VALUE_GET_FLOAT64(v) ((v).u.float64)
216             #define JS_VALUE_GET_PTR(v) ((v).u.ptr)
217              
218             #define JS_MKVAL(tag, val) (JSValue){ (JSValueUnion){ .int32 = val }, tag }
219             #define JS_MKPTR(tag, p) (JSValue){ (JSValueUnion){ .ptr = p }, tag }
220              
221             #define JS_TAG_IS_FLOAT64(tag) ((unsigned)(tag) == JS_TAG_FLOAT64)
222              
223             #define JS_NAN (JSValue){ .u.float64 = JS_FLOAT64_NAN, JS_TAG_FLOAT64 }
224              
225 9           static inline JSValue __JS_NewFloat64(JSContext *ctx, double d)
226             {
227             JSValue v;
228 9           v.tag = JS_TAG_FLOAT64;
229 9           v.u.float64 = d;
230 9           return v;
231             }
232              
233             static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
234             {
235             union {
236             double d;
237             uint64_t u64;
238             } u;
239             if (v.tag != JS_TAG_FLOAT64)
240             return 0;
241             u.d = v.u.float64;
242             return (u.u64 & 0x7fffffffffffffff) > 0x7ff0000000000000;
243             }
244              
245             #endif /* !JS_NAN_BOXING */
246              
247             #define JS_VALUE_IS_BOTH_INT(v1, v2) ((JS_VALUE_GET_TAG(v1) | JS_VALUE_GET_TAG(v2)) == 0)
248             #define JS_VALUE_IS_BOTH_FLOAT(v1, v2) (JS_TAG_IS_FLOAT64(JS_VALUE_GET_TAG(v1)) && JS_TAG_IS_FLOAT64(JS_VALUE_GET_TAG(v2)))
249              
250             #define JS_VALUE_GET_OBJ(v) ((JSObject *)JS_VALUE_GET_PTR(v))
251             #define JS_VALUE_GET_STRING(v) ((JSString *)JS_VALUE_GET_PTR(v))
252             #define JS_VALUE_HAS_REF_COUNT(v) ((unsigned)JS_VALUE_GET_TAG(v) >= (unsigned)JS_TAG_FIRST)
253              
254             /* special values */
255             #define JS_NULL JS_MKVAL(JS_TAG_NULL, 0)
256             #define JS_UNDEFINED JS_MKVAL(JS_TAG_UNDEFINED, 0)
257             #define JS_FALSE JS_MKVAL(JS_TAG_BOOL, 0)
258             #define JS_TRUE JS_MKVAL(JS_TAG_BOOL, 1)
259             #define JS_EXCEPTION JS_MKVAL(JS_TAG_EXCEPTION, 0)
260             #define JS_UNINITIALIZED JS_MKVAL(JS_TAG_UNINITIALIZED, 0)
261              
262             /* flags for object properties */
263             #define JS_PROP_CONFIGURABLE (1 << 0)
264             #define JS_PROP_WRITABLE (1 << 1)
265             #define JS_PROP_ENUMERABLE (1 << 2)
266             #define JS_PROP_C_W_E (JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE | JS_PROP_ENUMERABLE)
267             #define JS_PROP_LENGTH (1 << 3) /* used internally in Arrays */
268             #define JS_PROP_TMASK (3 << 4) /* mask for NORMAL, GETSET, VARREF, AUTOINIT */
269             #define JS_PROP_NORMAL (0 << 4)
270             #define JS_PROP_GETSET (1 << 4)
271             #define JS_PROP_VARREF (2 << 4) /* used internally */
272             #define JS_PROP_AUTOINIT (3 << 4) /* used internally */
273              
274             /* flags for JS_DefineProperty */
275             #define JS_PROP_HAS_SHIFT 8
276             #define JS_PROP_HAS_CONFIGURABLE (1 << 8)
277             #define JS_PROP_HAS_WRITABLE (1 << 9)
278             #define JS_PROP_HAS_ENUMERABLE (1 << 10)
279             #define JS_PROP_HAS_GET (1 << 11)
280             #define JS_PROP_HAS_SET (1 << 12)
281             #define JS_PROP_HAS_VALUE (1 << 13)
282              
283             /* throw an exception if false would be returned
284             (JS_DefineProperty/JS_SetProperty) */
285             #define JS_PROP_THROW (1 << 14)
286             /* throw an exception if false would be returned in strict mode
287             (JS_SetProperty) */
288             #define JS_PROP_THROW_STRICT (1 << 15)
289              
290             #define JS_PROP_NO_ADD (1 << 16) /* internal use */
291             #define JS_PROP_NO_EXOTIC (1 << 17) /* internal use */
292              
293             #define JS_DEFAULT_STACK_SIZE (256 * 1024)
294              
295             /* JS_Eval() flags */
296             #define JS_EVAL_TYPE_GLOBAL (0 << 0) /* global code (default) */
297             #define JS_EVAL_TYPE_MODULE (1 << 0) /* module code */
298             #define JS_EVAL_TYPE_DIRECT (2 << 0) /* direct call (internal use) */
299             #define JS_EVAL_TYPE_INDIRECT (3 << 0) /* indirect call (internal use) */
300             #define JS_EVAL_TYPE_MASK (3 << 0)
301              
302             #define JS_EVAL_FLAG_STRICT (1 << 3) /* force 'strict' mode */
303             #define JS_EVAL_FLAG_STRIP (1 << 4) /* force 'strip' mode */
304             /* compile but do not run. The result is an object with a
305             JS_TAG_FUNCTION_BYTECODE or JS_TAG_MODULE tag. It can be executed
306             with JS_EvalFunction(). */
307             #define JS_EVAL_FLAG_COMPILE_ONLY (1 << 5)
308             /* don't include the stack frames before this eval in the Error() backtraces */
309             #define JS_EVAL_FLAG_BACKTRACE_BARRIER (1 << 6)
310             /* allow top-level await in normal script. JS_Eval() returns a
311             promise. Only allowed with JS_EVAL_TYPE_GLOBAL */
312             #define JS_EVAL_FLAG_ASYNC (1 << 7)
313              
314             typedef JSValue JSCFunction(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);
315             typedef JSValue JSCFunctionMagic(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic);
316             typedef JSValue JSCFunctionData(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic, JSValue *func_data);
317              
318             typedef struct JSMallocState {
319             size_t malloc_count;
320             size_t malloc_size;
321             size_t malloc_limit;
322             void *opaque; /* user opaque */
323             } JSMallocState;
324              
325             typedef struct JSMallocFunctions {
326             void *(*js_malloc)(JSMallocState *s, size_t size);
327             void (*js_free)(JSMallocState *s, void *ptr);
328             void *(*js_realloc)(JSMallocState *s, void *ptr, size_t size);
329             size_t (*js_malloc_usable_size)(const void *ptr);
330             } JSMallocFunctions;
331              
332             typedef struct JSGCObjectHeader JSGCObjectHeader;
333              
334             JSRuntime *JS_NewRuntime(void);
335             /* info lifetime must exceed that of rt */
336             void JS_SetRuntimeInfo(JSRuntime *rt, const char *info);
337             void JS_SetMemoryLimit(JSRuntime *rt, size_t limit);
338             void JS_SetGCThreshold(JSRuntime *rt, size_t gc_threshold);
339             /* use 0 to disable maximum stack size check */
340             void JS_SetMaxStackSize(JSRuntime *rt, size_t stack_size);
341             /* should be called when changing thread to update the stack top value
342             used to check stack overflow. */
343             void JS_UpdateStackTop(JSRuntime *rt);
344             JSRuntime *JS_NewRuntime2(const JSMallocFunctions *mf, void *opaque);
345             void JS_FreeRuntime(JSRuntime *rt);
346             void *JS_GetRuntimeOpaque(JSRuntime *rt);
347             void JS_SetRuntimeOpaque(JSRuntime *rt, void *opaque);
348             typedef void JS_MarkFunc(JSRuntime *rt, JSGCObjectHeader *gp);
349             void JS_MarkValue(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func);
350             void JS_RunGC(JSRuntime *rt);
351             JS_BOOL JS_IsLiveObject(JSRuntime *rt, JSValueConst obj);
352              
353             JSContext *JS_NewContext(JSRuntime *rt);
354             void JS_FreeContext(JSContext *s);
355             JSContext *JS_DupContext(JSContext *ctx);
356             void *JS_GetContextOpaque(JSContext *ctx);
357             void JS_SetContextOpaque(JSContext *ctx, void *opaque);
358             JSRuntime *JS_GetRuntime(JSContext *ctx);
359             void JS_SetClassProto(JSContext *ctx, JSClassID class_id, JSValue obj);
360             JSValue JS_GetClassProto(JSContext *ctx, JSClassID class_id);
361              
362             /* the following functions are used to select the intrinsic object to
363             save memory */
364             JSContext *JS_NewContextRaw(JSRuntime *rt);
365             void JS_AddIntrinsicBaseObjects(JSContext *ctx);
366             void JS_AddIntrinsicDate(JSContext *ctx);
367             void JS_AddIntrinsicEval(JSContext *ctx);
368             void JS_AddIntrinsicStringNormalize(JSContext *ctx);
369             void JS_AddIntrinsicRegExpCompiler(JSContext *ctx);
370             void JS_AddIntrinsicRegExp(JSContext *ctx);
371             void JS_AddIntrinsicJSON(JSContext *ctx);
372             void JS_AddIntrinsicProxy(JSContext *ctx);
373             void JS_AddIntrinsicMapSet(JSContext *ctx);
374             void JS_AddIntrinsicTypedArrays(JSContext *ctx);
375             void JS_AddIntrinsicPromise(JSContext *ctx);
376             void JS_AddIntrinsicBigInt(JSContext *ctx);
377             void JS_AddIntrinsicBigFloat(JSContext *ctx);
378             void JS_AddIntrinsicBigDecimal(JSContext *ctx);
379             /* enable operator overloading */
380             void JS_AddIntrinsicOperators(JSContext *ctx);
381             /* enable "use math" */
382             void JS_EnableBignumExt(JSContext *ctx, JS_BOOL enable);
383              
384             JSValue js_string_codePointRange(JSContext *ctx, JSValueConst this_val,
385             int argc, JSValueConst *argv);
386              
387             void *js_malloc_rt(JSRuntime *rt, size_t size);
388             void js_free_rt(JSRuntime *rt, void *ptr);
389             void *js_realloc_rt(JSRuntime *rt, void *ptr, size_t size);
390             size_t js_malloc_usable_size_rt(JSRuntime *rt, const void *ptr);
391             void *js_mallocz_rt(JSRuntime *rt, size_t size);
392              
393             void *js_malloc(JSContext *ctx, size_t size);
394             void js_free(JSContext *ctx, void *ptr);
395             void *js_realloc(JSContext *ctx, void *ptr, size_t size);
396             size_t js_malloc_usable_size(JSContext *ctx, const void *ptr);
397             void *js_realloc2(JSContext *ctx, void *ptr, size_t size, size_t *pslack);
398             void *js_mallocz(JSContext *ctx, size_t size);
399             char *js_strdup(JSContext *ctx, const char *str);
400             char *js_strndup(JSContext *ctx, const char *s, size_t n);
401              
402             typedef struct JSMemoryUsage {
403             int64_t malloc_size, malloc_limit, memory_used_size;
404             int64_t malloc_count;
405             int64_t memory_used_count;
406             int64_t atom_count, atom_size;
407             int64_t str_count, str_size;
408             int64_t obj_count, obj_size;
409             int64_t prop_count, prop_size;
410             int64_t shape_count, shape_size;
411             int64_t js_func_count, js_func_size, js_func_code_size;
412             int64_t js_func_pc2line_count, js_func_pc2line_size;
413             int64_t c_func_count, array_count;
414             int64_t fast_array_count, fast_array_elements;
415             int64_t binary_object_count, binary_object_size;
416             } JSMemoryUsage;
417              
418             void JS_ComputeMemoryUsage(JSRuntime *rt, JSMemoryUsage *s);
419             void JS_DumpMemoryUsage(FILE *fp, const JSMemoryUsage *s, JSRuntime *rt);
420              
421             /* atom support */
422             #define JS_ATOM_NULL 0
423              
424             JSAtom JS_NewAtomLen(JSContext *ctx, const char *str, size_t len);
425             JSAtom JS_NewAtom(JSContext *ctx, const char *str);
426             JSAtom JS_NewAtomUInt32(JSContext *ctx, uint32_t n);
427             JSAtom JS_DupAtom(JSContext *ctx, JSAtom v);
428             void JS_FreeAtom(JSContext *ctx, JSAtom v);
429             void JS_FreeAtomRT(JSRuntime *rt, JSAtom v);
430             JSValue JS_AtomToValue(JSContext *ctx, JSAtom atom);
431             JSValue JS_AtomToString(JSContext *ctx, JSAtom atom);
432             const char *JS_AtomToCString(JSContext *ctx, JSAtom atom);
433             JSAtom JS_ValueToAtom(JSContext *ctx, JSValueConst val);
434              
435             /* object class support */
436              
437             typedef struct JSPropertyEnum {
438             JS_BOOL is_enumerable;
439             JSAtom atom;
440             } JSPropertyEnum;
441              
442             typedef struct JSPropertyDescriptor {
443             int flags;
444             JSValue value;
445             JSValue getter;
446             JSValue setter;
447             } JSPropertyDescriptor;
448              
449             typedef struct JSClassExoticMethods {
450             /* Return -1 if exception (can only happen in case of Proxy object),
451             FALSE if the property does not exists, TRUE if it exists. If 1 is
452             returned, the property descriptor 'desc' is filled if != NULL. */
453             int (*get_own_property)(JSContext *ctx, JSPropertyDescriptor *desc,
454             JSValueConst obj, JSAtom prop);
455             /* '*ptab' should hold the '*plen' property keys. Return 0 if OK,
456             -1 if exception. The 'is_enumerable' field is ignored.
457             */
458             int (*get_own_property_names)(JSContext *ctx, JSPropertyEnum **ptab,
459             uint32_t *plen,
460             JSValueConst obj);
461             /* return < 0 if exception, or TRUE/FALSE */
462             int (*delete_property)(JSContext *ctx, JSValueConst obj, JSAtom prop);
463             /* return < 0 if exception or TRUE/FALSE */
464             int (*define_own_property)(JSContext *ctx, JSValueConst this_obj,
465             JSAtom prop, JSValueConst val,
466             JSValueConst getter, JSValueConst setter,
467             int flags);
468             /* The following methods can be emulated with the previous ones,
469             so they are usually not needed */
470             /* return < 0 if exception or TRUE/FALSE */
471             int (*has_property)(JSContext *ctx, JSValueConst obj, JSAtom atom);
472             JSValue (*get_property)(JSContext *ctx, JSValueConst obj, JSAtom atom,
473             JSValueConst receiver);
474             /* return < 0 if exception or TRUE/FALSE */
475             int (*set_property)(JSContext *ctx, JSValueConst obj, JSAtom atom,
476             JSValueConst value, JSValueConst receiver, int flags);
477             } JSClassExoticMethods;
478              
479             typedef void JSClassFinalizer(JSRuntime *rt, JSValue val);
480             typedef void JSClassGCMark(JSRuntime *rt, JSValueConst val,
481             JS_MarkFunc *mark_func);
482             #define JS_CALL_FLAG_CONSTRUCTOR (1 << 0)
483             typedef JSValue JSClassCall(JSContext *ctx, JSValueConst func_obj,
484             JSValueConst this_val, int argc, JSValueConst *argv,
485             int flags);
486              
487             typedef struct JSClassDef {
488             const char *class_name;
489             JSClassFinalizer *finalizer;
490             JSClassGCMark *gc_mark;
491             /* if call != NULL, the object is a function. If (flags &
492             JS_CALL_FLAG_CONSTRUCTOR) != 0, the function is called as a
493             constructor. In this case, 'this_val' is new.target. A
494             constructor call only happens if the object constructor bit is
495             set (see JS_SetConstructorBit()). */
496             JSClassCall *call;
497             /* XXX: suppress this indirection ? It is here only to save memory
498             because only a few classes need these methods */
499             JSClassExoticMethods *exotic;
500             } JSClassDef;
501              
502             JSClassID JS_NewClassID(JSClassID *pclass_id);
503             int JS_NewClass(JSRuntime *rt, JSClassID class_id, const JSClassDef *class_def);
504             int JS_IsRegisteredClass(JSRuntime *rt, JSClassID class_id);
505              
506             /* value handling */
507              
508             static js_force_inline JSValue JS_NewBool(JSContext *ctx, JS_BOOL val)
509             {
510 2           return JS_MKVAL(JS_TAG_BOOL, (val != 0));
511             }
512              
513             static js_force_inline JSValue JS_NewInt32(JSContext *ctx, int32_t val)
514             {
515 59           return JS_MKVAL(JS_TAG_INT, val);
516             }
517              
518             static js_force_inline JSValue JS_NewCatchOffset(JSContext *ctx, int32_t val)
519             {
520             return JS_MKVAL(JS_TAG_CATCH_OFFSET, val);
521             }
522              
523             static js_force_inline JSValue JS_NewInt64(JSContext *ctx, int64_t val)
524             {
525             JSValue v;
526 57           if (val == (int32_t)val) {
527 52           v = JS_NewInt32(ctx, val);
528             } else {
529 5           v = __JS_NewFloat64(ctx, val);
530             }
531 57           return v;
532             }
533              
534             static js_force_inline JSValue JS_NewUint32(JSContext *ctx, uint32_t val)
535             {
536             JSValue v;
537 7 50         if (val <= 0x7fffffff) {
538 7           v = JS_NewInt32(ctx, val);
539             } else {
540 0           v = __JS_NewFloat64(ctx, val);
541             }
542 7           return v;
543             }
544              
545             JSValue JS_NewBigInt64(JSContext *ctx, int64_t v);
546             JSValue JS_NewBigUint64(JSContext *ctx, uint64_t v);
547              
548             static js_force_inline JSValue JS_NewFloat64(JSContext *ctx, double d)
549             {
550             JSValue v;
551             int32_t val;
552             union {
553             double d;
554             uint64_t u;
555             } u, t;
556 4           u.d = d;
557 4           val = (int32_t)d;
558 4           t.d = val;
559             /* -0 cannot be represented as integer, so we compare the bit
560             representation */
561 4 0         if (u.u == t.u) {
562 0           v = JS_MKVAL(JS_TAG_INT, val);
563             } else {
564 4           v = __JS_NewFloat64(ctx, d);
565             }
566 4           return v;
567             }
568              
569             static inline JS_BOOL JS_IsNumber(JSValueConst v)
570             {
571             int tag = JS_VALUE_GET_TAG(v);
572             return tag == JS_TAG_INT || JS_TAG_IS_FLOAT64(tag);
573             }
574              
575             static inline JS_BOOL JS_IsBigInt(JSContext *ctx, JSValueConst v)
576             {
577             int tag = JS_VALUE_GET_TAG(v);
578             return tag == JS_TAG_BIG_INT;
579             }
580              
581             static inline JS_BOOL JS_IsBigFloat(JSValueConst v)
582             {
583             int tag = JS_VALUE_GET_TAG(v);
584             return tag == JS_TAG_BIG_FLOAT;
585             }
586              
587             static inline JS_BOOL JS_IsBigDecimal(JSValueConst v)
588             {
589             int tag = JS_VALUE_GET_TAG(v);
590             return tag == JS_TAG_BIG_DECIMAL;
591             }
592              
593             static inline JS_BOOL JS_IsBool(JSValueConst v)
594             {
595             return JS_VALUE_GET_TAG(v) == JS_TAG_BOOL;
596             }
597              
598             static inline JS_BOOL JS_IsNull(JSValueConst v)
599             {
600             return JS_VALUE_GET_TAG(v) == JS_TAG_NULL;
601             }
602              
603             static inline JS_BOOL JS_IsUndefined(JSValueConst v)
604             {
605             return JS_VALUE_GET_TAG(v) == JS_TAG_UNDEFINED;
606             }
607              
608 241           static inline JS_BOOL JS_IsException(JSValueConst v)
609             {
610 241           return js_unlikely(JS_VALUE_GET_TAG(v) == JS_TAG_EXCEPTION);
611             }
612              
613             static inline JS_BOOL JS_IsUninitialized(JSValueConst v)
614             {
615             return js_unlikely(JS_VALUE_GET_TAG(v) == JS_TAG_UNINITIALIZED);
616             }
617              
618             static inline JS_BOOL JS_IsString(JSValueConst v)
619             {
620             return JS_VALUE_GET_TAG(v) == JS_TAG_STRING;
621             }
622              
623             static inline JS_BOOL JS_IsSymbol(JSValueConst v)
624             {
625             return JS_VALUE_GET_TAG(v) == JS_TAG_SYMBOL;
626             }
627              
628             static inline JS_BOOL JS_IsObject(JSValueConst v)
629             {
630             return JS_VALUE_GET_TAG(v) == JS_TAG_OBJECT;
631             }
632              
633             JSValue JS_Throw(JSContext *ctx, JSValue obj);
634             JSValue JS_GetException(JSContext *ctx);
635             JS_BOOL JS_IsError(JSContext *ctx, JSValueConst val);
636             void JS_ResetUncatchableError(JSContext *ctx);
637             JSValue JS_NewError(JSContext *ctx);
638             JSValue __js_printf_like(2, 3) JS_ThrowSyntaxError(JSContext *ctx, const char *fmt, ...);
639             JSValue __js_printf_like(2, 3) JS_ThrowTypeError(JSContext *ctx, const char *fmt, ...);
640             JSValue __js_printf_like(2, 3) JS_ThrowReferenceError(JSContext *ctx, const char *fmt, ...);
641             JSValue __js_printf_like(2, 3) JS_ThrowRangeError(JSContext *ctx, const char *fmt, ...);
642             JSValue __js_printf_like(2, 3) JS_ThrowInternalError(JSContext *ctx, const char *fmt, ...);
643             JSValue JS_ThrowOutOfMemory(JSContext *ctx);
644              
645             void __JS_FreeValue(JSContext *ctx, JSValue v);
646 3203           static inline void JS_FreeValue(JSContext *ctx, JSValue v)
647             {
648 3203 100         if (JS_VALUE_HAS_REF_COUNT(v)) {
649 2731           JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v);
650 2731 100         if (--p->ref_count <= 0) {
651 68           __JS_FreeValue(ctx, v);
652             }
653             }
654 3203           }
655             void __JS_FreeValueRT(JSRuntime *rt, JSValue v);
656             static inline void JS_FreeValueRT(JSRuntime *rt, JSValue v)
657             {
658             if (JS_VALUE_HAS_REF_COUNT(v)) {
659             JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v);
660             if (--p->ref_count <= 0) {
661             __JS_FreeValueRT(rt, v);
662             }
663             }
664             }
665              
666 32           static inline JSValue JS_DupValue(JSContext *ctx, JSValueConst v)
667             {
668 32 50         if (JS_VALUE_HAS_REF_COUNT(v)) {
669 32           JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v);
670 32           p->ref_count++;
671             }
672 32           return (JSValue)v;
673             }
674              
675             static inline JSValue JS_DupValueRT(JSRuntime *rt, JSValueConst v)
676             {
677             if (JS_VALUE_HAS_REF_COUNT(v)) {
678             JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v);
679             p->ref_count++;
680             }
681             return (JSValue)v;
682             }
683              
684             int JS_ToBool(JSContext *ctx, JSValueConst val); /* return -1 for JS_EXCEPTION */
685             int JS_ToInt32(JSContext *ctx, int32_t *pres, JSValueConst val);
686 25           static inline int JS_ToUint32(JSContext *ctx, uint32_t *pres, JSValueConst val)
687             {
688 25           return JS_ToInt32(ctx, (int32_t*)pres, val);
689             }
690             int JS_ToInt64(JSContext *ctx, int64_t *pres, JSValueConst val);
691             int JS_ToIndex(JSContext *ctx, uint64_t *plen, JSValueConst val);
692             int JS_ToFloat64(JSContext *ctx, double *pres, JSValueConst val);
693             /* return an exception if 'val' is a Number */
694             int JS_ToBigInt64(JSContext *ctx, int64_t *pres, JSValueConst val);
695             /* same as JS_ToInt64() but allow BigInt */
696             int JS_ToInt64Ext(JSContext *ctx, int64_t *pres, JSValueConst val);
697              
698             JSValue JS_NewStringLen(JSContext *ctx, const char *str1, size_t len1);
699             JSValue JS_NewString(JSContext *ctx, const char *str);
700             JSValue JS_NewAtomString(JSContext *ctx, const char *str);
701             JSValue JS_ToString(JSContext *ctx, JSValueConst val);
702             JSValue JS_ToPropertyKey(JSContext *ctx, JSValueConst val);
703             const char *JS_ToCStringLen2(JSContext *ctx, size_t *plen, JSValueConst val1, JS_BOOL cesu8);
704 2456           static inline const char *JS_ToCStringLen(JSContext *ctx, size_t *plen, JSValueConst val1)
705             {
706 2456           return JS_ToCStringLen2(ctx, plen, val1, 0);
707             }
708             static inline const char *JS_ToCString(JSContext *ctx, JSValueConst val1)
709             {
710             return JS_ToCStringLen2(ctx, NULL, val1, 0);
711             }
712             void JS_FreeCString(JSContext *ctx, const char *ptr);
713              
714             JSValue JS_NewObjectProtoClass(JSContext *ctx, JSValueConst proto, JSClassID class_id);
715             JSValue JS_NewObjectClass(JSContext *ctx, int class_id);
716             JSValue JS_NewObjectProto(JSContext *ctx, JSValueConst proto);
717             JSValue JS_NewObject(JSContext *ctx);
718              
719             JS_BOOL JS_IsFunction(JSContext* ctx, JSValueConst val);
720             JS_BOOL JS_IsConstructor(JSContext* ctx, JSValueConst val);
721             JS_BOOL JS_SetConstructorBit(JSContext *ctx, JSValueConst func_obj, JS_BOOL val);
722              
723             JSValue JS_NewArray(JSContext *ctx);
724             int JS_IsArray(JSContext *ctx, JSValueConst val);
725              
726             JSValue JS_GetPropertyInternal(JSContext *ctx, JSValueConst obj,
727             JSAtom prop, JSValueConst receiver,
728             JS_BOOL throw_ref_error);
729             static js_force_inline JSValue JS_GetProperty(JSContext *ctx, JSValueConst this_obj,
730             JSAtom prop)
731             {
732 1265           return JS_GetPropertyInternal(ctx, this_obj, prop, this_obj, 0);
733             }
734             JSValue JS_GetPropertyStr(JSContext *ctx, JSValueConst this_obj,
735             const char *prop);
736             JSValue JS_GetPropertyUint32(JSContext *ctx, JSValueConst this_obj,
737             uint32_t idx);
738              
739             int JS_SetPropertyInternal(JSContext *ctx, JSValueConst obj,
740             JSAtom prop, JSValue val, JSValueConst this_obj,
741             int flags);
742             static inline int JS_SetProperty(JSContext *ctx, JSValueConst this_obj,
743             JSAtom prop, JSValue val)
744             {
745             return JS_SetPropertyInternal(ctx, this_obj, prop, val, this_obj, JS_PROP_THROW);
746             }
747             int JS_SetPropertyUint32(JSContext *ctx, JSValueConst this_obj,
748             uint32_t idx, JSValue val);
749             int JS_SetPropertyInt64(JSContext *ctx, JSValueConst this_obj,
750             int64_t idx, JSValue val);
751             int JS_SetPropertyStr(JSContext *ctx, JSValueConst this_obj,
752             const char *prop, JSValue val);
753             int JS_HasProperty(JSContext *ctx, JSValueConst this_obj, JSAtom prop);
754             int JS_IsExtensible(JSContext *ctx, JSValueConst obj);
755             int JS_PreventExtensions(JSContext *ctx, JSValueConst obj);
756             int JS_DeleteProperty(JSContext *ctx, JSValueConst obj, JSAtom prop, int flags);
757             int JS_SetPrototype(JSContext *ctx, JSValueConst obj, JSValueConst proto_val);
758             JSValue JS_GetPrototype(JSContext *ctx, JSValueConst val);
759              
760             #define JS_GPN_STRING_MASK (1 << 0)
761             #define JS_GPN_SYMBOL_MASK (1 << 1)
762             #define JS_GPN_PRIVATE_MASK (1 << 2)
763             /* only include the enumerable properties */
764             #define JS_GPN_ENUM_ONLY (1 << 4)
765             /* set theJSPropertyEnum.is_enumerable field */
766             #define JS_GPN_SET_ENUM (1 << 5)
767              
768             int JS_GetOwnPropertyNames(JSContext *ctx, JSPropertyEnum **ptab,
769             uint32_t *plen, JSValueConst obj, int flags);
770             int JS_GetOwnProperty(JSContext *ctx, JSPropertyDescriptor *desc,
771             JSValueConst obj, JSAtom prop);
772              
773             JSValue JS_Call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj,
774             int argc, JSValueConst *argv);
775             JSValue JS_Invoke(JSContext *ctx, JSValueConst this_val, JSAtom atom,
776             int argc, JSValueConst *argv);
777             JSValue JS_CallConstructor(JSContext *ctx, JSValueConst func_obj,
778             int argc, JSValueConst *argv);
779             JSValue JS_CallConstructor2(JSContext *ctx, JSValueConst func_obj,
780             JSValueConst new_target,
781             int argc, JSValueConst *argv);
782             JS_BOOL JS_DetectModule(const char *input, size_t input_len);
783             /* 'input' must be zero terminated i.e. input[input_len] = '\0'. */
784             JSValue JS_Eval(JSContext *ctx, const char *input, size_t input_len,
785             const char *filename, int eval_flags);
786             /* same as JS_Eval() but with an explicit 'this_obj' parameter */
787             JSValue JS_EvalThis(JSContext *ctx, JSValueConst this_obj,
788             const char *input, size_t input_len,
789             const char *filename, int eval_flags);
790             JSValue JS_GetGlobalObject(JSContext *ctx);
791             int JS_IsInstanceOf(JSContext *ctx, JSValueConst val, JSValueConst obj);
792             int JS_DefineProperty(JSContext *ctx, JSValueConst this_obj,
793             JSAtom prop, JSValueConst val,
794             JSValueConst getter, JSValueConst setter, int flags);
795             int JS_DefinePropertyValue(JSContext *ctx, JSValueConst this_obj,
796             JSAtom prop, JSValue val, int flags);
797             int JS_DefinePropertyValueUint32(JSContext *ctx, JSValueConst this_obj,
798             uint32_t idx, JSValue val, int flags);
799             int JS_DefinePropertyValueStr(JSContext *ctx, JSValueConst this_obj,
800             const char *prop, JSValue val, int flags);
801             int JS_DefinePropertyGetSet(JSContext *ctx, JSValueConst this_obj,
802             JSAtom prop, JSValue getter, JSValue setter,
803             int flags);
804             void JS_SetOpaque(JSValue obj, void *opaque);
805             void *JS_GetOpaque(JSValueConst obj, JSClassID class_id);
806             void *JS_GetOpaque2(JSContext *ctx, JSValueConst obj, JSClassID class_id);
807              
808             /* 'buf' must be zero terminated i.e. buf[buf_len] = '\0'. */
809             JSValue JS_ParseJSON(JSContext *ctx, const char *buf, size_t buf_len,
810             const char *filename);
811             #define JS_PARSE_JSON_EXT (1 << 0) /* allow extended JSON */
812             JSValue JS_ParseJSON2(JSContext *ctx, const char *buf, size_t buf_len,
813             const char *filename, int flags);
814             JSValue JS_JSONStringify(JSContext *ctx, JSValueConst obj,
815             JSValueConst replacer, JSValueConst space0);
816              
817             typedef void JSFreeArrayBufferDataFunc(JSRuntime *rt, void *opaque, void *ptr);
818             JSValue JS_NewArrayBuffer(JSContext *ctx, uint8_t *buf, size_t len,
819             JSFreeArrayBufferDataFunc *free_func, void *opaque,
820             JS_BOOL is_shared);
821             JSValue JS_NewArrayBufferCopy(JSContext *ctx, const uint8_t *buf, size_t len);
822             void JS_DetachArrayBuffer(JSContext *ctx, JSValueConst obj);
823             uint8_t *JS_GetArrayBuffer(JSContext *ctx, size_t *psize, JSValueConst obj);
824             JSValue JS_GetTypedArrayBuffer(JSContext *ctx, JSValueConst obj,
825             size_t *pbyte_offset,
826             size_t *pbyte_length,
827             size_t *pbytes_per_element);
828             typedef struct {
829             void *(*sab_alloc)(void *opaque, size_t size);
830             void (*sab_free)(void *opaque, void *ptr);
831             void (*sab_dup)(void *opaque, void *ptr);
832             void *sab_opaque;
833             } JSSharedArrayBufferFunctions;
834             void JS_SetSharedArrayBufferFunctions(JSRuntime *rt,
835             const JSSharedArrayBufferFunctions *sf);
836              
837             typedef enum JSPromiseStateEnum {
838             JS_PROMISE_PENDING,
839             JS_PROMISE_FULFILLED,
840             JS_PROMISE_REJECTED,
841             } JSPromiseStateEnum;
842              
843             JSValue JS_NewPromiseCapability(JSContext *ctx, JSValue *resolving_funcs);
844             JSPromiseStateEnum JS_PromiseState(JSContext *ctx, JSValue promise);
845             JSValue JS_PromiseResult(JSContext *ctx, JSValue promise);
846              
847             /* is_handled = TRUE means that the rejection is handled */
848             typedef void JSHostPromiseRejectionTracker(JSContext *ctx, JSValueConst promise,
849             JSValueConst reason,
850             JS_BOOL is_handled, void *opaque);
851             void JS_SetHostPromiseRejectionTracker(JSRuntime *rt, JSHostPromiseRejectionTracker *cb, void *opaque);
852              
853             /* return != 0 if the JS code needs to be interrupted */
854             typedef int JSInterruptHandler(JSRuntime *rt, void *opaque);
855             void JS_SetInterruptHandler(JSRuntime *rt, JSInterruptHandler *cb, void *opaque);
856             /* if can_block is TRUE, Atomics.wait() can be used */
857             void JS_SetCanBlock(JSRuntime *rt, JS_BOOL can_block);
858             /* set the [IsHTMLDDA] internal slot */
859             void JS_SetIsHTMLDDA(JSContext *ctx, JSValueConst obj);
860              
861             typedef struct JSModuleDef JSModuleDef;
862              
863             /* return the module specifier (allocated with js_malloc()) or NULL if
864             exception */
865             typedef char *JSModuleNormalizeFunc(JSContext *ctx,
866             const char *module_base_name,
867             const char *module_name, void *opaque);
868             typedef JSModuleDef *JSModuleLoaderFunc(JSContext *ctx,
869             const char *module_name, void *opaque);
870              
871             /* module_normalize = NULL is allowed and invokes the default module
872             filename normalizer */
873             void JS_SetModuleLoaderFunc(JSRuntime *rt,
874             JSModuleNormalizeFunc *module_normalize,
875             JSModuleLoaderFunc *module_loader, void *opaque);
876             /* return the import.meta object of a module */
877             JSValue JS_GetImportMeta(JSContext *ctx, JSModuleDef *m);
878             JSAtom JS_GetModuleName(JSContext *ctx, JSModuleDef *m);
879              
880             /* JS Job support */
881              
882             typedef JSValue JSJobFunc(JSContext *ctx, int argc, JSValueConst *argv);
883             int JS_EnqueueJob(JSContext *ctx, JSJobFunc *job_func, int argc, JSValueConst *argv);
884              
885             JS_BOOL JS_IsJobPending(JSRuntime *rt);
886             int JS_ExecutePendingJob(JSRuntime *rt, JSContext **pctx);
887              
888             /* Object Writer/Reader (currently only used to handle precompiled code) */
889             #define JS_WRITE_OBJ_BYTECODE (1 << 0) /* allow function/module */
890             #define JS_WRITE_OBJ_BSWAP (1 << 1) /* byte swapped output */
891             #define JS_WRITE_OBJ_SAB (1 << 2) /* allow SharedArrayBuffer */
892             #define JS_WRITE_OBJ_REFERENCE (1 << 3) /* allow object references to
893             encode arbitrary object
894             graph */
895             uint8_t *JS_WriteObject(JSContext *ctx, size_t *psize, JSValueConst obj,
896             int flags);
897             uint8_t *JS_WriteObject2(JSContext *ctx, size_t *psize, JSValueConst obj,
898             int flags, uint8_t ***psab_tab, size_t *psab_tab_len);
899              
900             #define JS_READ_OBJ_BYTECODE (1 << 0) /* allow function/module */
901             #define JS_READ_OBJ_ROM_DATA (1 << 1) /* avoid duplicating 'buf' data */
902             #define JS_READ_OBJ_SAB (1 << 2) /* allow SharedArrayBuffer */
903             #define JS_READ_OBJ_REFERENCE (1 << 3) /* allow object references */
904             JSValue JS_ReadObject(JSContext *ctx, const uint8_t *buf, size_t buf_len,
905             int flags);
906             /* instantiate and evaluate a bytecode function. Only used when
907             reading a script or module with JS_ReadObject() */
908             JSValue JS_EvalFunction(JSContext *ctx, JSValue fun_obj);
909             /* load the dependencies of the module 'obj'. Useful when JS_ReadObject()
910             returns a module. */
911             int JS_ResolveModule(JSContext *ctx, JSValueConst obj);
912              
913             /* only exported for os.Worker() */
914             JSAtom JS_GetScriptOrModuleName(JSContext *ctx, int n_stack_levels);
915             /* only exported for os.Worker() */
916             JSValue JS_LoadModule(JSContext *ctx, const char *basename,
917             const char *filename);
918              
919             /* C function definition */
920             typedef enum JSCFunctionEnum { /* XXX: should rename for namespace isolation */
921             JS_CFUNC_generic,
922             JS_CFUNC_generic_magic,
923             JS_CFUNC_constructor,
924             JS_CFUNC_constructor_magic,
925             JS_CFUNC_constructor_or_func,
926             JS_CFUNC_constructor_or_func_magic,
927             JS_CFUNC_f_f,
928             JS_CFUNC_f_f_f,
929             JS_CFUNC_getter,
930             JS_CFUNC_setter,
931             JS_CFUNC_getter_magic,
932             JS_CFUNC_setter_magic,
933             JS_CFUNC_iterator_next,
934             } JSCFunctionEnum;
935              
936             typedef union JSCFunctionType {
937             JSCFunction *generic;
938             JSValue (*generic_magic)(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic);
939             JSCFunction *constructor;
940             JSValue (*constructor_magic)(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv, int magic);
941             JSCFunction *constructor_or_func;
942             double (*f_f)(double);
943             double (*f_f_f)(double, double);
944             JSValue (*getter)(JSContext *ctx, JSValueConst this_val);
945             JSValue (*setter)(JSContext *ctx, JSValueConst this_val, JSValueConst val);
946             JSValue (*getter_magic)(JSContext *ctx, JSValueConst this_val, int magic);
947             JSValue (*setter_magic)(JSContext *ctx, JSValueConst this_val, JSValueConst val, int magic);
948             JSValue (*iterator_next)(JSContext *ctx, JSValueConst this_val,
949             int argc, JSValueConst *argv, int *pdone, int magic);
950             } JSCFunctionType;
951              
952             JSValue JS_NewCFunction2(JSContext *ctx, JSCFunction *func,
953             const char *name,
954             int length, JSCFunctionEnum cproto, int magic);
955             JSValue JS_NewCFunctionData(JSContext *ctx, JSCFunctionData *func,
956             int length, int magic, int data_len,
957             JSValueConst *data);
958              
959             static inline JSValue JS_NewCFunction(JSContext *ctx, JSCFunction *func, const char *name,
960             int length)
961             {
962             return JS_NewCFunction2(ctx, func, name, length, JS_CFUNC_generic, 0);
963             }
964              
965             static inline JSValue JS_NewCFunctionMagic(JSContext *ctx, JSCFunctionMagic *func,
966             const char *name,
967             int length, JSCFunctionEnum cproto, int magic)
968             {
969             return JS_NewCFunction2(ctx, (JSCFunction *)func, name, length, cproto, magic);
970             }
971             void JS_SetConstructor(JSContext *ctx, JSValueConst func_obj,
972             JSValueConst proto);
973              
974             /* C property definition */
975              
976             typedef struct JSCFunctionListEntry {
977             const char *name;
978             uint8_t prop_flags;
979             uint8_t def_type;
980             int16_t magic;
981             union {
982             struct {
983             uint8_t length; /* XXX: should move outside union */
984             uint8_t cproto; /* XXX: should move outside union */
985             JSCFunctionType cfunc;
986             } func;
987             struct {
988             JSCFunctionType get;
989             JSCFunctionType set;
990             } getset;
991             struct {
992             const char *name;
993             int base;
994             } alias;
995             struct {
996             const struct JSCFunctionListEntry *tab;
997             int len;
998             } prop_list;
999             const char *str;
1000             int32_t i32;
1001             int64_t i64;
1002             double f64;
1003             } u;
1004             } JSCFunctionListEntry;
1005              
1006             #define JS_DEF_CFUNC 0
1007             #define JS_DEF_CGETSET 1
1008             #define JS_DEF_CGETSET_MAGIC 2
1009             #define JS_DEF_PROP_STRING 3
1010             #define JS_DEF_PROP_INT32 4
1011             #define JS_DEF_PROP_INT64 5
1012             #define JS_DEF_PROP_DOUBLE 6
1013             #define JS_DEF_PROP_UNDEFINED 7
1014             #define JS_DEF_OBJECT 8
1015             #define JS_DEF_ALIAS 9
1016              
1017             /* Note: c++ does not like nested designators */
1018             #define JS_CFUNC_DEF(name, length, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } }
1019             #define JS_CFUNC_MAGIC_DEF(name, length, func1, magic) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, magic, .u = { .func = { length, JS_CFUNC_generic_magic, { .generic_magic = func1 } } } }
1020             #define JS_CFUNC_SPECIAL_DEF(name, length, cproto, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_ ## cproto, { .cproto = func1 } } } }
1021             #define JS_ITERATOR_NEXT_DEF(name, length, func1, magic) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, magic, .u = { .func = { length, JS_CFUNC_iterator_next, { .iterator_next = func1 } } } }
1022             #define JS_CGETSET_DEF(name, fgetter, fsetter) { name, JS_PROP_CONFIGURABLE, JS_DEF_CGETSET, 0, .u = { .getset = { .get = { .getter = fgetter }, .set = { .setter = fsetter } } } }
1023             #define JS_CGETSET_MAGIC_DEF(name, fgetter, fsetter, magic) { name, JS_PROP_CONFIGURABLE, JS_DEF_CGETSET_MAGIC, magic, .u = { .getset = { .get = { .getter_magic = fgetter }, .set = { .setter_magic = fsetter } } } }
1024             #define JS_PROP_STRING_DEF(name, cstr, prop_flags) { name, prop_flags, JS_DEF_PROP_STRING, 0, .u = { .str = cstr } }
1025             #define JS_PROP_INT32_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT32, 0, .u = { .i32 = val } }
1026             #define JS_PROP_INT64_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT64, 0, .u = { .i64 = val } }
1027             #define JS_PROP_DOUBLE_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_DOUBLE, 0, .u = { .f64 = val } }
1028             #define JS_PROP_UNDEFINED_DEF(name, prop_flags) { name, prop_flags, JS_DEF_PROP_UNDEFINED, 0, .u = { .i32 = 0 } }
1029             #define JS_OBJECT_DEF(name, tab, len, prop_flags) { name, prop_flags, JS_DEF_OBJECT, 0, .u = { .prop_list = { tab, len } } }
1030             #define JS_ALIAS_DEF(name, from) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_ALIAS, 0, .u = { .alias = { from, -1 } } }
1031             #define JS_ALIAS_BASE_DEF(name, from, base) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_ALIAS, 0, .u = { .alias = { from, base } } }
1032              
1033             void JS_SetPropertyFunctionList(JSContext *ctx, JSValueConst obj,
1034             const JSCFunctionListEntry *tab,
1035             int len);
1036              
1037             /* C module definition */
1038              
1039             typedef int JSModuleInitFunc(JSContext *ctx, JSModuleDef *m);
1040              
1041             JSModuleDef *JS_NewCModule(JSContext *ctx, const char *name_str,
1042             JSModuleInitFunc *func);
1043             /* can only be called before the module is instantiated */
1044             int JS_AddModuleExport(JSContext *ctx, JSModuleDef *m, const char *name_str);
1045             int JS_AddModuleExportList(JSContext *ctx, JSModuleDef *m,
1046             const JSCFunctionListEntry *tab, int len);
1047             /* can only be called after the module is instantiated */
1048             int JS_SetModuleExport(JSContext *ctx, JSModuleDef *m, const char *export_name,
1049             JSValue val);
1050             int JS_SetModuleExportList(JSContext *ctx, JSModuleDef *m,
1051             const JSCFunctionListEntry *tab, int len);
1052              
1053             #undef js_unlikely
1054             #undef js_force_inline
1055              
1056             #ifdef __cplusplus
1057             } /* extern "C" { */
1058             #endif
1059              
1060             #endif /* QUICKJS_H */