quickjs-tart

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

quickjs.h (47560B)


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