quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

quickjs.h (43353B)


      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 <stdio.h>
     29 #include <stdint.h>
     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 static inline JSValue __JS_NewFloat64(JSContext *ctx, double d)
    226 {
    227     JSValue v;
    228     v.tag = JS_TAG_FLOAT64;
    229     v.u.float64 = d;
    230     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 #define JS_INVALID_CLASS_ID 0
    503 JSClassID JS_NewClassID(JSClassID *pclass_id);
    504 /* Returns the class ID if `v` is an object, otherwise returns JS_INVALID_CLASS_ID. */
    505 JSClassID JS_GetClassID(JSValue v);
    506 int JS_NewClass(JSRuntime *rt, JSClassID class_id, const JSClassDef *class_def);
    507 int JS_IsRegisteredClass(JSRuntime *rt, JSClassID class_id);
    508 
    509 /* value handling */
    510 
    511 static js_force_inline JSValue JS_NewBool(JSContext *ctx, JS_BOOL val)
    512 {
    513     return JS_MKVAL(JS_TAG_BOOL, (val != 0));
    514 }
    515 
    516 static js_force_inline JSValue JS_NewInt32(JSContext *ctx, int32_t val)
    517 {
    518     return JS_MKVAL(JS_TAG_INT, val);
    519 }
    520 
    521 static js_force_inline JSValue JS_NewCatchOffset(JSContext *ctx, int32_t val)
    522 {
    523     return JS_MKVAL(JS_TAG_CATCH_OFFSET, val);
    524 }
    525 
    526 static js_force_inline JSValue JS_NewInt64(JSContext *ctx, int64_t val)
    527 {
    528     JSValue v;
    529     if (val == (int32_t)val) {
    530         v = JS_NewInt32(ctx, val);
    531     } else {
    532         v = __JS_NewFloat64(ctx, val);
    533     }
    534     return v;
    535 }
    536 
    537 static js_force_inline JSValue JS_NewUint32(JSContext *ctx, uint32_t val)
    538 {
    539     JSValue v;
    540     if (val <= 0x7fffffff) {
    541         v = JS_NewInt32(ctx, val);
    542     } else {
    543         v = __JS_NewFloat64(ctx, val);
    544     }
    545     return v;
    546 }
    547 
    548 JSValue JS_NewBigInt64(JSContext *ctx, int64_t v);
    549 JSValue JS_NewBigUint64(JSContext *ctx, uint64_t v);
    550 
    551 static js_force_inline JSValue JS_NewFloat64(JSContext *ctx, double d)
    552 {
    553     int32_t val;
    554     union {
    555         double d;
    556         uint64_t u;
    557     } u, t;
    558     if (d >= INT32_MIN && d <= INT32_MAX) {
    559         u.d = d;
    560         val = (int32_t)d;
    561         t.d = val;
    562         /* -0 cannot be represented as integer, so we compare the bit
    563            representation */
    564         if (u.u == t.u)
    565             return JS_MKVAL(JS_TAG_INT, val);
    566     }
    567     return __JS_NewFloat64(ctx, d);
    568 }
    569 
    570 static inline JS_BOOL JS_IsNumber(JSValueConst v)
    571 {
    572     int tag = JS_VALUE_GET_TAG(v);
    573     return tag == JS_TAG_INT || JS_TAG_IS_FLOAT64(tag);
    574 }
    575 
    576 static inline JS_BOOL JS_IsBigInt(JSContext *ctx, JSValueConst v)
    577 {
    578     int tag = JS_VALUE_GET_TAG(v);
    579     return tag == JS_TAG_BIG_INT;
    580 }
    581 
    582 static inline JS_BOOL JS_IsBigFloat(JSValueConst v)
    583 {
    584     int tag = JS_VALUE_GET_TAG(v);
    585     return tag == JS_TAG_BIG_FLOAT;
    586 }
    587 
    588 static inline JS_BOOL JS_IsBigDecimal(JSValueConst v)
    589 {
    590     int tag = JS_VALUE_GET_TAG(v);
    591     return tag == JS_TAG_BIG_DECIMAL;
    592 }
    593 
    594 static inline JS_BOOL JS_IsBool(JSValueConst v)
    595 {
    596     return JS_VALUE_GET_TAG(v) == JS_TAG_BOOL;
    597 }
    598 
    599 static inline JS_BOOL JS_IsNull(JSValueConst v)
    600 {
    601     return JS_VALUE_GET_TAG(v) == JS_TAG_NULL;
    602 }
    603 
    604 static inline JS_BOOL JS_IsUndefined(JSValueConst v)
    605 {
    606     return JS_VALUE_GET_TAG(v) == JS_TAG_UNDEFINED;
    607 }
    608 
    609 static inline JS_BOOL JS_IsException(JSValueConst v)
    610 {
    611     return js_unlikely(JS_VALUE_GET_TAG(v) == JS_TAG_EXCEPTION);
    612 }
    613 
    614 static inline JS_BOOL JS_IsUninitialized(JSValueConst v)
    615 {
    616     return js_unlikely(JS_VALUE_GET_TAG(v) == JS_TAG_UNINITIALIZED);
    617 }
    618 
    619 static inline JS_BOOL JS_IsString(JSValueConst v)
    620 {
    621     return JS_VALUE_GET_TAG(v) == JS_TAG_STRING;
    622 }
    623 
    624 static inline JS_BOOL JS_IsSymbol(JSValueConst v)
    625 {
    626     return JS_VALUE_GET_TAG(v) == JS_TAG_SYMBOL;
    627 }
    628 
    629 static inline JS_BOOL JS_IsObject(JSValueConst v)
    630 {
    631     return JS_VALUE_GET_TAG(v) == JS_TAG_OBJECT;
    632 }
    633 
    634 JSValue JS_Throw(JSContext *ctx, JSValue obj);
    635 JSValue JS_GetException(JSContext *ctx);
    636 JS_BOOL JS_HasException(JSContext *ctx);
    637 JS_BOOL JS_IsError(JSContext *ctx, JSValueConst val);
    638 void JS_SetUncatchableError(JSContext *ctx, JSValueConst val, JS_BOOL flag);
    639 void JS_ResetUncatchableError(JSContext *ctx);
    640 JSValue JS_NewError(JSContext *ctx);
    641 JSValue __js_printf_like(2, 3) JS_ThrowSyntaxError(JSContext *ctx, const char *fmt, ...);
    642 JSValue __js_printf_like(2, 3) JS_ThrowTypeError(JSContext *ctx, const char *fmt, ...);
    643 JSValue __js_printf_like(2, 3) JS_ThrowReferenceError(JSContext *ctx, const char *fmt, ...);
    644 JSValue __js_printf_like(2, 3) JS_ThrowRangeError(JSContext *ctx, const char *fmt, ...);
    645 JSValue __js_printf_like(2, 3) JS_ThrowInternalError(JSContext *ctx, const char *fmt, ...);
    646 JSValue JS_ThrowOutOfMemory(JSContext *ctx);
    647 
    648 void __JS_FreeValue(JSContext *ctx, JSValue v);
    649 static inline void JS_FreeValue(JSContext *ctx, JSValue v)
    650 {
    651     if (JS_VALUE_HAS_REF_COUNT(v)) {
    652         JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v);
    653         if (--p->ref_count <= 0) {
    654             __JS_FreeValue(ctx, v);
    655         }
    656     }
    657 }
    658 void __JS_FreeValueRT(JSRuntime *rt, JSValue v);
    659 static inline void JS_FreeValueRT(JSRuntime *rt, JSValue v)
    660 {
    661     if (JS_VALUE_HAS_REF_COUNT(v)) {
    662         JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v);
    663         if (--p->ref_count <= 0) {
    664             __JS_FreeValueRT(rt, v);
    665         }
    666     }
    667 }
    668 
    669 static inline JSValue JS_DupValue(JSContext *ctx, JSValueConst v)
    670 {
    671     if (JS_VALUE_HAS_REF_COUNT(v)) {
    672         JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v);
    673         p->ref_count++;
    674     }
    675     return (JSValue)v;
    676 }
    677 
    678 static inline JSValue JS_DupValueRT(JSRuntime *rt, JSValueConst v)
    679 {
    680     if (JS_VALUE_HAS_REF_COUNT(v)) {
    681         JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v);
    682         p->ref_count++;
    683     }
    684     return (JSValue)v;
    685 }
    686 
    687 JS_BOOL JS_StrictEq(JSContext *ctx, JSValueConst op1, JSValueConst op2);
    688 JS_BOOL JS_SameValue(JSContext *ctx, JSValueConst op1, JSValueConst op2);
    689 JS_BOOL JS_SameValueZero(JSContext *ctx, JSValueConst op1, JSValueConst op2);
    690 
    691 int JS_ToBool(JSContext *ctx, JSValueConst val); /* return -1 for JS_EXCEPTION */
    692 int JS_ToInt32(JSContext *ctx, int32_t *pres, JSValueConst val);
    693 static inline int JS_ToUint32(JSContext *ctx, uint32_t *pres, JSValueConst val)
    694 {
    695     return JS_ToInt32(ctx, (int32_t*)pres, val);
    696 }
    697 int JS_ToInt64(JSContext *ctx, int64_t *pres, JSValueConst val);
    698 int JS_ToIndex(JSContext *ctx, uint64_t *plen, JSValueConst val);
    699 int JS_ToFloat64(JSContext *ctx, double *pres, JSValueConst val);
    700 /* return an exception if 'val' is a Number */
    701 int JS_ToBigInt64(JSContext *ctx, int64_t *pres, JSValueConst val);
    702 /* same as JS_ToInt64() but allow BigInt */
    703 int JS_ToInt64Ext(JSContext *ctx, int64_t *pres, JSValueConst val);
    704 
    705 JSValue JS_NewStringLen(JSContext *ctx, const char *str1, size_t len1);
    706 JSValue JS_NewString(JSContext *ctx, const char *str);
    707 JSValue JS_NewAtomString(JSContext *ctx, const char *str);
    708 JSValue JS_ToString(JSContext *ctx, JSValueConst val);
    709 JSValue JS_ToPropertyKey(JSContext *ctx, JSValueConst val);
    710 const char *JS_ToCStringLen2(JSContext *ctx, size_t *plen, JSValueConst val1, JS_BOOL cesu8);
    711 static inline const char *JS_ToCStringLen(JSContext *ctx, size_t *plen, JSValueConst val1)
    712 {
    713     return JS_ToCStringLen2(ctx, plen, val1, 0);
    714 }
    715 static inline const char *JS_ToCString(JSContext *ctx, JSValueConst val1)
    716 {
    717     return JS_ToCStringLen2(ctx, NULL, val1, 0);
    718 }
    719 void JS_FreeCString(JSContext *ctx, const char *ptr);
    720 
    721 
    722 int qjs_array_append_new (JSContext *ctx, JSValue array, JSValue item);
    723 
    724 JSValue JS_NewObjectProtoClass(JSContext *ctx, JSValueConst proto, JSClassID class_id);
    725 JSValue JS_NewObjectClass(JSContext *ctx, int class_id);
    726 JSValue JS_NewObjectProto(JSContext *ctx, JSValueConst proto);
    727 JSValue JS_NewObject(JSContext *ctx);
    728 
    729 JS_BOOL JS_IsFunction(JSContext* ctx, JSValueConst val);
    730 JS_BOOL JS_IsConstructor(JSContext* ctx, JSValueConst val);
    731 JS_BOOL JS_SetConstructorBit(JSContext *ctx, JSValueConst func_obj, JS_BOOL val);
    732 
    733 JSValue JS_NewArray(JSContext *ctx);
    734 int JS_IsArray(JSContext *ctx, JSValueConst val);
    735 
    736 JSValue JS_NewDate(JSContext *ctx, double epoch_ms);
    737 
    738 JSValue JS_GetPropertyInternal(JSContext *ctx, JSValueConst obj,
    739                                JSAtom prop, JSValueConst receiver,
    740                                JS_BOOL throw_ref_error);
    741 static js_force_inline JSValue JS_GetProperty(JSContext *ctx, JSValueConst this_obj,
    742                                               JSAtom prop)
    743 {
    744     return JS_GetPropertyInternal(ctx, this_obj, prop, this_obj, 0);
    745 }
    746 JSValue JS_GetPropertyStr(JSContext *ctx, JSValueConst this_obj,
    747                           const char *prop);
    748 JSValue JS_GetPropertyUint32(JSContext *ctx, JSValueConst this_obj,
    749                              uint32_t idx);
    750 
    751 int JS_SetPropertyInternal(JSContext *ctx, JSValueConst obj,
    752                            JSAtom prop, JSValue val, JSValueConst this_obj,
    753                            int flags);
    754 static inline int JS_SetProperty(JSContext *ctx, JSValueConst this_obj,
    755                                  JSAtom prop, JSValue val)
    756 {
    757     return JS_SetPropertyInternal(ctx, this_obj, prop, val, this_obj, JS_PROP_THROW);
    758 }
    759 int JS_SetPropertyUint32(JSContext *ctx, JSValueConst this_obj,
    760                          uint32_t idx, JSValue val);
    761 int JS_SetPropertyInt64(JSContext *ctx, JSValueConst this_obj,
    762                         int64_t idx, JSValue val);
    763 int JS_SetPropertyStr(JSContext *ctx, JSValueConst this_obj,
    764                       const char *prop, JSValue val);
    765 int JS_HasProperty(JSContext *ctx, JSValueConst this_obj, JSAtom prop);
    766 int JS_HasPropertyStr(JSContext *ctx, JSValueConst this_obj, const char *propname);
    767 int JS_IsExtensible(JSContext *ctx, JSValueConst obj);
    768 int JS_PreventExtensions(JSContext *ctx, JSValueConst obj);
    769 int JS_DeleteProperty(JSContext *ctx, JSValueConst obj, JSAtom prop, int flags);
    770 int JS_SetPrototype(JSContext *ctx, JSValueConst obj, JSValueConst proto_val);
    771 JSValue JS_GetPrototype(JSContext *ctx, JSValueConst val);
    772 
    773 #define JS_GPN_STRING_MASK  (1 << 0)
    774 #define JS_GPN_SYMBOL_MASK  (1 << 1)
    775 #define JS_GPN_PRIVATE_MASK (1 << 2)
    776 /* only include the enumerable properties */
    777 #define JS_GPN_ENUM_ONLY    (1 << 4)
    778 /* set theJSPropertyEnum.is_enumerable field */
    779 #define JS_GPN_SET_ENUM     (1 << 5)
    780 
    781 int JS_GetOwnPropertyNames(JSContext *ctx, JSPropertyEnum **ptab,
    782                            uint32_t *plen, JSValueConst obj, int flags);
    783 int JS_GetOwnProperty(JSContext *ctx, JSPropertyDescriptor *desc,
    784                       JSValueConst obj, JSAtom prop);
    785 
    786 JSValue JS_Call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj,
    787                 int argc, JSValueConst *argv);
    788 JSValue JS_Invoke(JSContext *ctx, JSValueConst this_val, JSAtom atom,
    789                   int argc, JSValueConst *argv);
    790 JSValue JS_CallConstructor(JSContext *ctx, JSValueConst func_obj,
    791                            int argc, JSValueConst *argv);
    792 JSValue JS_CallConstructor2(JSContext *ctx, JSValueConst func_obj,
    793                             JSValueConst new_target,
    794                             int argc, JSValueConst *argv);
    795 JS_BOOL JS_DetectModule(const char *input, size_t input_len);
    796 /* 'input' must be zero terminated i.e. input[input_len] = '\0'. */
    797 JSValue JS_Eval(JSContext *ctx, const char *input, size_t input_len,
    798                 const char *filename, int eval_flags);
    799 /* same as JS_Eval() but with an explicit 'this_obj' parameter */
    800 JSValue JS_EvalThis(JSContext *ctx, JSValueConst this_obj,
    801                     const char *input, size_t input_len,
    802                     const char *filename, int eval_flags);
    803 JSValue JS_GetGlobalObject(JSContext *ctx);
    804 int JS_IsInstanceOf(JSContext *ctx, JSValueConst val, JSValueConst obj);
    805 int JS_DefineProperty(JSContext *ctx, JSValueConst this_obj,
    806                       JSAtom prop, JSValueConst val,
    807                       JSValueConst getter, JSValueConst setter, int flags);
    808 int JS_DefinePropertyValue(JSContext *ctx, JSValueConst this_obj,
    809                            JSAtom prop, JSValue val, int flags);
    810 int JS_DefinePropertyValueUint32(JSContext *ctx, JSValueConst this_obj,
    811                                  uint32_t idx, JSValue val, int flags);
    812 int JS_DefinePropertyValueStr(JSContext *ctx, JSValueConst this_obj,
    813                               const char *prop, JSValue val, int flags);
    814 int JS_DefinePropertyGetSet(JSContext *ctx, JSValueConst this_obj,
    815                             JSAtom prop, JSValue getter, JSValue setter,
    816                             int flags);
    817 void JS_SetOpaque(JSValue obj, void *opaque);
    818 void *JS_GetOpaque(JSValueConst obj, JSClassID class_id);
    819 void *JS_GetOpaque2(JSContext *ctx, JSValueConst obj, JSClassID class_id);
    820 
    821 /* 'buf' must be zero terminated i.e. buf[buf_len] = '\0'. */
    822 JSValue JS_ParseJSON(JSContext *ctx, const char *buf, size_t buf_len,
    823                      const char *filename);
    824 #define JS_PARSE_JSON_EXT (1 << 0) /* allow extended JSON */
    825 JSValue JS_ParseJSON2(JSContext *ctx, const char *buf, size_t buf_len,
    826                       const char *filename, int flags);
    827 JSValue JS_JSONStringify(JSContext *ctx, JSValueConst obj,
    828                          JSValueConst replacer, JSValueConst space0);
    829 
    830 typedef void JSFreeArrayBufferDataFunc(JSRuntime *rt, void *opaque, void *ptr);
    831 JSValue JS_NewArrayBuffer(JSContext *ctx, uint8_t *buf, size_t len,
    832                           JSFreeArrayBufferDataFunc *free_func, void *opaque,
    833                           JS_BOOL is_shared);
    834 JSValue JS_NewTypedArraySimple(JSContext *ctx, JSValue array_buf, size_t bytes_per_element);
    835 JSValue JS_NewArrayBufferCopy(JSContext *ctx, const uint8_t *buf, size_t len);
    836 void JS_DetachArrayBuffer(JSContext *ctx, JSValueConst obj);
    837 JS_BOOL JS_IsArrayBuffer(JSValueConst obj);
    838 uint8_t *JS_GetArrayBuffer(JSContext *ctx, size_t *psize, JSValueConst obj);
    839 
    840 typedef enum JSTypedArrayEnum {
    841     JS_TYPED_ARRAY_UINT8C = 0,
    842     JS_TYPED_ARRAY_INT8,
    843     JS_TYPED_ARRAY_UINT8,
    844     JS_TYPED_ARRAY_INT16,
    845     JS_TYPED_ARRAY_UINT16,
    846     JS_TYPED_ARRAY_INT32,
    847     JS_TYPED_ARRAY_UINT32,
    848     JS_TYPED_ARRAY_BIG_INT64,
    849     JS_TYPED_ARRAY_BIG_UINT64,
    850     JS_TYPED_ARRAY_FLOAT32,
    851     JS_TYPED_ARRAY_FLOAT64,
    852 } JSTypedArrayEnum;
    853 
    854 JSValue JS_NewTypedArray(JSContext *ctx, int argc, JSValueConst *argv,
    855                                JSTypedArrayEnum array_type);
    856 JSValue JS_GetTypedArrayBuffer(JSContext *ctx, JSValueConst obj,
    857                                size_t *pbyte_offset,
    858                                size_t *pbyte_length,
    859                                size_t *pbytes_per_element);
    860 typedef struct {
    861     void *(*sab_alloc)(void *opaque, size_t size);
    862     void (*sab_free)(void *opaque, void *ptr);
    863     void (*sab_dup)(void *opaque, void *ptr);
    864     void *sab_opaque;
    865 } JSSharedArrayBufferFunctions;
    866 void JS_SetSharedArrayBufferFunctions(JSRuntime *rt,
    867                                       const JSSharedArrayBufferFunctions *sf);
    868 
    869 typedef enum JSPromiseStateEnum {
    870     JS_PROMISE_PENDING,
    871     JS_PROMISE_FULFILLED,
    872     JS_PROMISE_REJECTED,
    873 } JSPromiseStateEnum;
    874 
    875 JSValue JS_NewPromiseCapability(JSContext *ctx, JSValue *resolving_funcs);
    876 JSPromiseStateEnum JS_PromiseState(JSContext *ctx, JSValue promise);
    877 JSValue JS_PromiseResult(JSContext *ctx, JSValue promise);
    878 
    879 /* is_handled = TRUE means that the rejection is handled */
    880 typedef void JSHostPromiseRejectionTracker(JSContext *ctx, JSValueConst promise,
    881                                            JSValueConst reason,
    882                                            JS_BOOL is_handled, void *opaque);
    883 void JS_SetHostPromiseRejectionTracker(JSRuntime *rt, JSHostPromiseRejectionTracker *cb, void *opaque);
    884 
    885 /* return != 0 if the JS code needs to be interrupted */
    886 typedef int JSInterruptHandler(JSRuntime *rt, void *opaque);
    887 void JS_SetInterruptHandler(JSRuntime *rt, JSInterruptHandler *cb, void *opaque);
    888 /* if can_block is TRUE, Atomics.wait() can be used */
    889 void JS_SetCanBlock(JSRuntime *rt, JS_BOOL can_block);
    890 /* set the [IsHTMLDDA] internal slot */
    891 void JS_SetIsHTMLDDA(JSContext *ctx, JSValueConst obj);
    892 
    893 typedef struct JSModuleDef JSModuleDef;
    894 
    895 /* return the module specifier (allocated with js_malloc()) or NULL if
    896    exception */
    897 typedef char *JSModuleNormalizeFunc(JSContext *ctx,
    898                                     const char *module_base_name,
    899                                     const char *module_name, void *opaque);
    900 typedef JSModuleDef *JSModuleLoaderFunc(JSContext *ctx,
    901                                         const char *module_name, void *opaque);
    902 
    903 /* module_normalize = NULL is allowed and invokes the default module
    904    filename normalizer */
    905 void JS_SetModuleLoaderFunc(JSRuntime *rt,
    906                             JSModuleNormalizeFunc *module_normalize,
    907                             JSModuleLoaderFunc *module_loader, void *opaque);
    908 /* return the import.meta object of a module */
    909 JSValue JS_GetImportMeta(JSContext *ctx, JSModuleDef *m);
    910 JSAtom JS_GetModuleName(JSContext *ctx, JSModuleDef *m);
    911 JSValue JS_GetModuleNamespace(JSContext *ctx, JSModuleDef *m);
    912 
    913 /* JS Job support */
    914 
    915 typedef JSValue JSJobFunc(JSContext *ctx, int argc, JSValueConst *argv);
    916 int JS_EnqueueJob(JSContext *ctx, JSJobFunc *job_func, int argc, JSValueConst *argv);
    917 
    918 JS_BOOL JS_IsJobPending(JSRuntime *rt);
    919 int JS_ExecutePendingJob(JSRuntime *rt, JSContext **pctx);
    920 
    921 /* Object Writer/Reader (currently only used to handle precompiled code) */
    922 #define JS_WRITE_OBJ_BYTECODE  (1 << 0) /* allow function/module */
    923 #define JS_WRITE_OBJ_BSWAP     (1 << 1) /* byte swapped output */
    924 #define JS_WRITE_OBJ_SAB       (1 << 2) /* allow SharedArrayBuffer */
    925 #define JS_WRITE_OBJ_REFERENCE (1 << 3) /* allow object references to
    926                                            encode arbitrary object
    927                                            graph */
    928 uint8_t *JS_WriteObject(JSContext *ctx, size_t *psize, JSValueConst obj,
    929                         int flags);
    930 uint8_t *JS_WriteObject2(JSContext *ctx, size_t *psize, JSValueConst obj,
    931                          int flags, uint8_t ***psab_tab, size_t *psab_tab_len);
    932 
    933 #define JS_READ_OBJ_BYTECODE  (1 << 0) /* allow function/module */
    934 #define JS_READ_OBJ_ROM_DATA  (1 << 1) /* avoid duplicating 'buf' data */
    935 #define JS_READ_OBJ_SAB       (1 << 2) /* allow SharedArrayBuffer */
    936 #define JS_READ_OBJ_REFERENCE (1 << 3) /* allow object references */
    937 JSValue JS_ReadObject(JSContext *ctx, const uint8_t *buf, size_t buf_len,
    938                       int flags);
    939 /* instantiate and evaluate a bytecode function. Only used when
    940    reading a script or module with JS_ReadObject() */
    941 JSValue JS_EvalFunction(JSContext *ctx, JSValue fun_obj);
    942 /* load the dependencies of the module 'obj'. Useful when JS_ReadObject()
    943    returns a module. */
    944 int JS_ResolveModule(JSContext *ctx, JSValueConst obj);
    945 
    946 /* only exported for os.Worker() */
    947 JSAtom JS_GetScriptOrModuleName(JSContext *ctx, int n_stack_levels);
    948 /* only exported for os.Worker() */
    949 JSValue JS_LoadModule(JSContext *ctx, const char *basename,
    950                       const char *filename);
    951 
    952 /* C function definition */
    953 typedef enum JSCFunctionEnum {  /* XXX: should rename for namespace isolation */
    954     JS_CFUNC_generic,
    955     JS_CFUNC_generic_magic,
    956     JS_CFUNC_constructor,
    957     JS_CFUNC_constructor_magic,
    958     JS_CFUNC_constructor_or_func,
    959     JS_CFUNC_constructor_or_func_magic,
    960     JS_CFUNC_f_f,
    961     JS_CFUNC_f_f_f,
    962     JS_CFUNC_getter,
    963     JS_CFUNC_setter,
    964     JS_CFUNC_getter_magic,
    965     JS_CFUNC_setter_magic,
    966     JS_CFUNC_iterator_next,
    967 } JSCFunctionEnum;
    968 
    969 typedef union JSCFunctionType {
    970     JSCFunction *generic;
    971     JSValue (*generic_magic)(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic);
    972     JSCFunction *constructor;
    973     JSValue (*constructor_magic)(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv, int magic);
    974     JSCFunction *constructor_or_func;
    975     double (*f_f)(double);
    976     double (*f_f_f)(double, double);
    977     JSValue (*getter)(JSContext *ctx, JSValueConst this_val);
    978     JSValue (*setter)(JSContext *ctx, JSValueConst this_val, JSValueConst val);
    979     JSValue (*getter_magic)(JSContext *ctx, JSValueConst this_val, int magic);
    980     JSValue (*setter_magic)(JSContext *ctx, JSValueConst this_val, JSValueConst val, int magic);
    981     JSValue (*iterator_next)(JSContext *ctx, JSValueConst this_val,
    982                              int argc, JSValueConst *argv, int *pdone, int magic);
    983 } JSCFunctionType;
    984 
    985 JSValue JS_NewCFunction2(JSContext *ctx, JSCFunction *func,
    986                          const char *name,
    987                          int length, JSCFunctionEnum cproto, int magic);
    988 JSValue JS_NewCFunctionData(JSContext *ctx, JSCFunctionData *func,
    989                             int length, int magic, int data_len,
    990                             JSValueConst *data);
    991 
    992 static inline JSValue JS_NewCFunction(JSContext *ctx, JSCFunction *func, const char *name,
    993                                       int length)
    994 {
    995     return JS_NewCFunction2(ctx, func, name, length, JS_CFUNC_generic, 0);
    996 }
    997 
    998 static inline JSValue JS_NewCFunctionMagic(JSContext *ctx, JSCFunctionMagic *func,
    999                                            const char *name,
   1000                                            int length, JSCFunctionEnum cproto, int magic)
   1001 {
   1002     return JS_NewCFunction2(ctx, (JSCFunction *)func, name, length, cproto, magic);
   1003 }
   1004 void JS_SetConstructor(JSContext *ctx, JSValueConst func_obj,
   1005                        JSValueConst proto);
   1006 
   1007 /* C property definition */
   1008 
   1009 typedef struct JSCFunctionListEntry {
   1010     const char *name;
   1011     uint8_t prop_flags;
   1012     uint8_t def_type;
   1013     int16_t magic;
   1014     union {
   1015         struct {
   1016             uint8_t length; /* XXX: should move outside union */
   1017             uint8_t cproto; /* XXX: should move outside union */
   1018             JSCFunctionType cfunc;
   1019         } func;
   1020         struct {
   1021             JSCFunctionType get;
   1022             JSCFunctionType set;
   1023         } getset;
   1024         struct {
   1025             const char *name;
   1026             int base;
   1027         } alias;
   1028         struct {
   1029             const struct JSCFunctionListEntry *tab;
   1030             int len;
   1031         } prop_list;
   1032         const char *str;
   1033         int32_t i32;
   1034         int64_t i64;
   1035         double f64;
   1036     } u;
   1037 } JSCFunctionListEntry;
   1038 
   1039 #define JS_DEF_CFUNC          0
   1040 #define JS_DEF_CGETSET        1
   1041 #define JS_DEF_CGETSET_MAGIC  2
   1042 #define JS_DEF_PROP_STRING    3
   1043 #define JS_DEF_PROP_INT32     4
   1044 #define JS_DEF_PROP_INT64     5
   1045 #define JS_DEF_PROP_DOUBLE    6
   1046 #define JS_DEF_PROP_UNDEFINED 7
   1047 #define JS_DEF_OBJECT         8
   1048 #define JS_DEF_ALIAS          9
   1049 
   1050 /* Note: c++ does not like nested designators */
   1051 #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 } } } }
   1052 #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 } } } }
   1053 #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 } } } }
   1054 #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 } } } }
   1055 #define JS_CGETSET_DEF(name, fgetter, fsetter) { name, JS_PROP_CONFIGURABLE, JS_DEF_CGETSET, 0, .u = { .getset = { .get = { .getter = fgetter }, .set = { .setter = fsetter } } } }
   1056 #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 } } } }
   1057 #define JS_PROP_STRING_DEF(name, cstr, prop_flags) { name, prop_flags, JS_DEF_PROP_STRING, 0, .u = { .str = cstr } }
   1058 #define JS_PROP_INT32_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT32, 0, .u = { .i32 = val } }
   1059 #define JS_PROP_INT64_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT64, 0, .u = { .i64 = val } }
   1060 #define JS_PROP_DOUBLE_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_DOUBLE, 0, .u = { .f64 = val } }
   1061 #define JS_PROP_UNDEFINED_DEF(name, prop_flags) { name, prop_flags, JS_DEF_PROP_UNDEFINED, 0, .u = { .i32 = 0 } }
   1062 #define JS_OBJECT_DEF(name, tab, len, prop_flags) { name, prop_flags, JS_DEF_OBJECT, 0, .u = { .prop_list = { tab, len } } }
   1063 #define JS_ALIAS_DEF(name, from) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_ALIAS, 0, .u = { .alias = { from, -1 } } }
   1064 #define JS_ALIAS_BASE_DEF(name, from, base) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_ALIAS, 0, .u = { .alias = { from, base } } }
   1065 
   1066 void JS_SetPropertyFunctionList(JSContext *ctx, JSValueConst obj,
   1067                                 const JSCFunctionListEntry *tab,
   1068                                 int len);
   1069 
   1070 /* C module definition */
   1071 
   1072 typedef int JSModuleInitFunc(JSContext *ctx, JSModuleDef *m);
   1073 
   1074 JSModuleDef *JS_NewCModule(JSContext *ctx, const char *name_str,
   1075                            JSModuleInitFunc *func);
   1076 /* can only be called before the module is instantiated */
   1077 int JS_AddModuleExport(JSContext *ctx, JSModuleDef *m, const char *name_str);
   1078 int JS_AddModuleExportList(JSContext *ctx, JSModuleDef *m,
   1079                            const JSCFunctionListEntry *tab, int len);
   1080 /* can only be called after the module is instantiated */
   1081 int JS_SetModuleExport(JSContext *ctx, JSModuleDef *m, const char *export_name,
   1082                        JSValue val);
   1083 int JS_SetModuleExportList(JSContext *ctx, JSModuleDef *m,
   1084                            const JSCFunctionListEntry *tab, int len);
   1085 
   1086 #undef js_unlikely
   1087 #undef js_force_inline
   1088 
   1089 #ifdef __cplusplus
   1090 } /* extern "C" { */
   1091 #endif
   1092 
   1093 #endif /* QUICKJS_H */