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 */