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