Coverage Report

Created: 2026-10-17 07:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quickjs/quickjs.h
Line
Count
Source
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
0
{
256
0
    JSValue v;
257
0
    v.tag = JS_TAG_FLOAT64;
258
0
    v.u.float64 = d;
259
0
    return v;
260
0
}
261
262
static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
263
0
{
264
0
    union {
265
0
        double d;
266
0
        uint64_t u64;
267
0
    } u;
268
0
    if (v.tag != JS_TAG_FLOAT64)
269
0
        return 0;
270
0
    u.d = v.u.float64;
271
0
    return (u.u64 & 0x7fffffffffffffff) > 0x7ff0000000000000;
272
0
}
273
274
static inline JSValue __JS_NewShortBigInt(JSContext *ctx, int64_t d)
275
0
{
276
0
    JSValue v;
277
0
    v.tag = JS_TAG_SHORT_BIG_INT;
278
0
    v.u.short_big_int = d;
279
0
    return v;
280
0
}
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
enum {
398
    JS_INTL_CTOR_NUMBERFORMAT = 0,
399
    JS_INTL_CTOR_DATETIMEFORMAT,
400
    JS_INTL_CTOR_COLLATOR,
401
    JS_INTL_CTOR_LISTFORMAT,
402
    JS_INTL_CTOR_LOCALE,
403
    JS_INTL_CTOR_DURATIONFORMAT,
404
    JS_INTL_FALLBACK_SYMBOL,
405
    JS_CONTEXT_VALUE_COUNT,
406
};
407
408
void JS_SetContextValue(JSContext *ctx, int idx, JSValue val);
409
JSValue JS_GetContextValue(JSContext *ctx, int idx);
410
411
/* the following functions are used to select the intrinsic object to
412
   save memory */
413
JSContext *JS_NewContextRaw(JSRuntime *rt);
414
int JS_AddIntrinsicBaseObjects(JSContext *ctx);
415
int JS_AddIntrinsicDate(JSContext *ctx);
416
int JS_AddIntrinsicEval(JSContext *ctx);
417
int JS_AddIntrinsicStringNormalize(JSContext *ctx);
418
void JS_AddIntrinsicRegExpCompiler(JSContext *ctx);
419
int JS_AddIntrinsicRegExp(JSContext *ctx);
420
int JS_AddIntrinsicJSON(JSContext *ctx);
421
int JS_AddIntrinsicProxy(JSContext *ctx);
422
int JS_AddIntrinsicMapSet(JSContext *ctx);
423
int JS_AddIntrinsicTypedArrays(JSContext *ctx);
424
int JS_AddIntrinsicPromise(JSContext *ctx);
425
int JS_AddIntrinsicWeakRef(JSContext *ctx);
426
#ifdef CONFIG_TEMPORAL_INTL
427
int JS_AddIntrinsicTemporal(JSContext *ctx);
428
int JS_AddIntrinsicIntl(JSContext *ctx);
429
#endif
430
431
JSValue js_string_codePointRange(JSContext *ctx, JSValueConst this_val,
432
                                 int argc, JSValueConst *argv);
433
434
void *js_malloc_rt(JSRuntime *rt, size_t size);
435
void js_free_rt(JSRuntime *rt, void *ptr);
436
void *js_realloc_rt(JSRuntime *rt, void *ptr, size_t size);
437
size_t js_malloc_usable_size_rt(JSRuntime *rt, const void *ptr);
438
void *js_mallocz_rt(JSRuntime *rt, size_t size);
439
440
void *js_malloc(JSContext *ctx, size_t size);
441
void js_free(JSContext *ctx, void *ptr);
442
void *js_realloc(JSContext *ctx, void *ptr, size_t size);
443
size_t js_malloc_usable_size(JSContext *ctx, const void *ptr);
444
void *js_realloc2(JSContext *ctx, void *ptr, size_t size, size_t *pslack);
445
void *js_mallocz(JSContext *ctx, size_t size);
446
char *js_strdup(JSContext *ctx, const char *str);
447
char *js_strndup(JSContext *ctx, const char *s, size_t n);
448
449
typedef struct JSMemoryUsage {
450
    int64_t malloc_size, malloc_limit, memory_used_size;
451
    int64_t malloc_count;
452
    int64_t memory_used_count;
453
    int64_t atom_count, atom_size;
454
    int64_t str_count, str_size;
455
    int64_t obj_count, obj_size;
456
    int64_t prop_count, prop_size;
457
    int64_t shape_count, shape_size;
458
    int64_t js_func_count, js_func_size, js_func_code_size;
459
    int64_t js_func_pc2line_count, js_func_pc2line_size;
460
    int64_t c_func_count, array_count;
461
    int64_t fast_array_count, fast_array_elements;
462
    int64_t binary_object_count, binary_object_size;
463
} JSMemoryUsage;
464
465
void JS_ComputeMemoryUsage(JSRuntime *rt, JSMemoryUsage *s);
466
void JS_DumpMemoryUsage(FILE *fp, const JSMemoryUsage *s, JSRuntime *rt);
467
468
/* atom support */
469
#define JS_ATOM_NULL 0
470
471
JSAtom JS_NewAtomLen(JSContext *ctx, const char *str, size_t len);
472
JSAtom JS_NewAtom(JSContext *ctx, const char *str);
473
JSAtom JS_NewAtomUInt32(JSContext *ctx, uint32_t n);
474
JSAtom JS_DupAtom(JSContext *ctx, JSAtom v);
475
void JS_FreeAtom(JSContext *ctx, JSAtom v);
476
void JS_FreeAtomRT(JSRuntime *rt, JSAtom v);
477
JSValue JS_AtomToValue(JSContext *ctx, JSAtom atom);
478
JSValue JS_AtomToString(JSContext *ctx, JSAtom atom);
479
const char *JS_AtomToCStringLen(JSContext *ctx, size_t *plen, JSAtom atom);
480
static inline const char *JS_AtomToCString(JSContext *ctx, JSAtom atom)
481
0
{
482
0
    return JS_AtomToCStringLen(ctx, NULL, atom);
483
0
}
484
JSAtom JS_ValueToAtom(JSContext *ctx, JSValueConst val);
485
486
/* object class support */
487
488
typedef struct JSPropertyEnum {
489
    JS_BOOL is_enumerable;
490
    JSAtom atom;
491
} JSPropertyEnum;
492
493
typedef struct JSPropertyDescriptor {
494
    int flags;
495
    JSValue value;
496
    JSValue getter;
497
    JSValue setter;
498
} JSPropertyDescriptor;
499
500
typedef struct JSClassExoticMethods {
501
    /* Return -1 if exception (can only happen in case of Proxy object),
502
       FALSE if the property does not exists, TRUE if it exists. If 1 is
503
       returned, the property descriptor 'desc' is filled if != NULL. */
504
    int (*get_own_property)(JSContext *ctx, JSPropertyDescriptor *desc,
505
                             JSValueConst obj, JSAtom prop);
506
    /* '*ptab' should hold the '*plen' property keys. Return 0 if OK,
507
       -1 if exception. The 'is_enumerable' field is ignored.
508
    */
509
    int (*get_own_property_names)(JSContext *ctx, JSPropertyEnum **ptab,
510
                                  uint32_t *plen,
511
                                  JSValueConst obj);
512
    /* return < 0 if exception, or TRUE/FALSE */
513
    int (*delete_property)(JSContext *ctx, JSValueConst obj, JSAtom prop);
514
    /* return < 0 if exception or TRUE/FALSE */
515
    int (*define_own_property)(JSContext *ctx, JSValueConst this_obj,
516
                               JSAtom prop, JSValueConst val,
517
                               JSValueConst getter, JSValueConst setter,
518
                               int flags);
519
    /* The following methods can be emulated with the previous ones,
520
       so they are usually not needed */
521
    /* return < 0 if exception or TRUE/FALSE */
522
    int (*has_property)(JSContext *ctx, JSValueConst obj, JSAtom atom);
523
    JSValue (*get_property)(JSContext *ctx, JSValueConst obj, JSAtom atom,
524
                            JSValueConst receiver);
525
    /* return < 0 if exception or TRUE/FALSE */
526
    int (*set_property)(JSContext *ctx, JSValueConst obj, JSAtom atom,
527
                        JSValueConst value, JSValueConst receiver, int flags);
528
529
    /* To get a consistent object behavior when get_prototype != NULL,
530
       get_property, set_property and set_prototype must be != NULL
531
       and the object must be created with a JS_NULL prototype. */
532
    JSValue (*get_prototype)(JSContext *ctx, JSValueConst obj);
533
    /* return < 0 if exception or TRUE/FALSE */
534
    int (*set_prototype)(JSContext *ctx, JSValueConst obj, JSValueConst proto_val);
535
    /* return < 0 if exception or TRUE/FALSE */
536
    int (*is_extensible)(JSContext *ctx, JSValueConst obj);
537
    /* return < 0 if exception or TRUE/FALSE */
538
    int (*prevent_extensions)(JSContext *ctx, JSValueConst obj);
539
} JSClassExoticMethods;
540
541
typedef void JSClassFinalizer(JSRuntime *rt, JSValue val);
542
typedef void JSClassGCMark(JSRuntime *rt, JSValueConst val,
543
                           JS_MarkFunc *mark_func);
544
#define JS_CALL_FLAG_CONSTRUCTOR (1 << 0)
545
typedef JSValue JSClassCall(JSContext *ctx, JSValueConst func_obj,
546
                            JSValueConst this_val, int argc, JSValueConst *argv,
547
                            int flags);
548
549
typedef struct JSClassDef {
550
    const char *class_name;
551
    JSClassFinalizer *finalizer;
552
    JSClassGCMark *gc_mark;
553
    /* if call != NULL, the object is a function. If (flags &
554
       JS_CALL_FLAG_CONSTRUCTOR) != 0, the function is called as a
555
       constructor. In this case, 'this_val' is new.target. A
556
       constructor call only happens if the object constructor bit is
557
       set (see JS_SetConstructorBit()). */
558
    JSClassCall *call;
559
    /* XXX: suppress this indirection ? It is here only to save memory
560
       because only a few classes need these methods */
561
    JSClassExoticMethods *exotic;
562
} JSClassDef;
563
564
#define JS_INVALID_CLASS_ID 0
565
JSClassID JS_NewClassID(JSClassID *pclass_id);
566
/* Returns the class ID if `v` is an object, otherwise returns JS_INVALID_CLASS_ID. */
567
JSClassID JS_GetClassID(JSValue v);
568
int JS_NewClass(JSRuntime *rt, JSClassID class_id, const JSClassDef *class_def);
569
int JS_IsRegisteredClass(JSRuntime *rt, JSClassID class_id);
570
571
/* value handling */
572
573
static js_force_inline JSValue JS_NewBool(JSContext *ctx, JS_BOOL val)
574
0
{
575
0
    return JS_MKVAL(JS_TAG_BOOL, (val != 0));
576
0
}
577
578
static js_force_inline JSValue JS_NewInt32(JSContext *ctx, int32_t val)
579
0
{
580
0
    return JS_MKVAL(JS_TAG_INT, val);
581
0
}
582
583
static js_force_inline JSValue JS_NewCatchOffset(JSContext *ctx, int32_t val)
584
0
{
585
0
    return JS_MKVAL(JS_TAG_CATCH_OFFSET, val);
586
0
}
587
588
static js_force_inline JSValue JS_NewInt64(JSContext *ctx, int64_t val)
589
0
{
590
0
    JSValue v;
591
0
    if (val == (int32_t)val) {
592
0
        v = JS_NewInt32(ctx, val);
593
0
    } else {
594
0
        v = __JS_NewFloat64(ctx, val);
595
0
    }
596
0
    return v;
597
0
}
598
599
static js_force_inline JSValue JS_NewUint32(JSContext *ctx, uint32_t val)
600
0
{
601
0
    JSValue v;
602
0
    if (val <= 0x7fffffff) {
603
0
        v = JS_NewInt32(ctx, val);
604
0
    } else {
605
0
        v = __JS_NewFloat64(ctx, val);
606
0
    }
607
0
    return v;
608
0
}
609
610
JSValue JS_NewBigInt64(JSContext *ctx, int64_t v);
611
JSValue JS_NewBigUint64(JSContext *ctx, uint64_t v);
612
613
static js_force_inline JSValue JS_NewFloat64(JSContext *ctx, double d)
614
0
{
615
0
    int32_t val;
616
0
    union {
617
0
        double d;
618
0
        uint64_t u;
619
0
    } u, t;
620
0
    if (d >= INT32_MIN && d <= INT32_MAX) {
621
0
        u.d = d;
622
0
        val = (int32_t)d;
623
0
        t.d = val;
624
0
        /* -0 cannot be represented as integer, so we compare the bit
625
0
           representation */
626
0
        if (u.u == t.u)
627
0
            return JS_MKVAL(JS_TAG_INT, val);
628
0
    }
629
0
    return __JS_NewFloat64(ctx, d);
630
0
}
631
632
static inline JS_BOOL JS_IsNumber(JSValueConst v)
633
0
{
634
0
    int tag = JS_VALUE_GET_TAG(v);
635
0
    return tag == JS_TAG_INT || JS_TAG_IS_FLOAT64(tag);
636
0
}
637
638
static inline JS_BOOL JS_IsBigInt(JSContext *ctx, JSValueConst v)
639
0
{
640
0
    int tag = JS_VALUE_GET_TAG(v);
641
0
    return tag == JS_TAG_BIG_INT || tag == JS_TAG_SHORT_BIG_INT;
642
0
}
643
644
static inline JS_BOOL JS_IsBool(JSValueConst v)
645
0
{
646
0
    return JS_VALUE_GET_TAG(v) == JS_TAG_BOOL;
647
0
}
648
649
static inline JS_BOOL JS_IsNull(JSValueConst v)
650
0
{
651
0
    return JS_VALUE_GET_TAG(v) == JS_TAG_NULL;
652
0
}
653
654
static inline JS_BOOL JS_IsUndefined(JSValueConst v)
655
0
{
656
0
    return JS_VALUE_GET_TAG(v) == JS_TAG_UNDEFINED;
657
0
}
658
659
static inline JS_BOOL JS_IsException(JSValueConst v)
660
0
{
661
0
    return js_unlikely(JS_VALUE_GET_TAG(v) == JS_TAG_EXCEPTION);
662
0
}
663
664
static inline JS_BOOL JS_IsUninitialized(JSValueConst v)
665
0
{
666
0
    return js_unlikely(JS_VALUE_GET_TAG(v) == JS_TAG_UNINITIALIZED);
667
0
}
668
669
static inline JS_BOOL JS_IsString(JSValueConst v)
670
0
{
671
0
    return JS_VALUE_GET_TAG(v) == JS_TAG_STRING ||
672
0
        JS_VALUE_GET_TAG(v) == JS_TAG_STRING_ROPE;
673
0
}
674
675
static inline JS_BOOL JS_IsSymbol(JSValueConst v)
676
0
{
677
0
    return JS_VALUE_GET_TAG(v) == JS_TAG_SYMBOL;
678
0
}
679
680
static inline JS_BOOL JS_IsObject(JSValueConst v)
681
0
{
682
0
    return JS_VALUE_GET_TAG(v) == JS_TAG_OBJECT;
683
0
}
684
685
JSValue JS_Throw(JSContext *ctx, JSValue obj);
686
void JS_SetUncatchableException(JSContext *ctx, JS_BOOL flag);
687
JSValue JS_GetException(JSContext *ctx);
688
JS_BOOL JS_HasException(JSContext *ctx);
689
JS_BOOL JS_IsError(JSContext *ctx, JSValueConst val);
690
JSValue JS_NewError(JSContext *ctx);
691
JSValue __js_printf_like(2, 3) JS_ThrowSyntaxError(JSContext *ctx, const char *fmt, ...);
692
JSValue __js_printf_like(2, 3) JS_ThrowTypeError(JSContext *ctx, const char *fmt, ...);
693
JSValue __js_printf_like(2, 3) JS_ThrowReferenceError(JSContext *ctx, const char *fmt, ...);
694
JSValue __js_printf_like(2, 3) JS_ThrowRangeError(JSContext *ctx, const char *fmt, ...);
695
JSValue __js_printf_like(2, 3) JS_ThrowInternalError(JSContext *ctx, const char *fmt, ...);
696
JSValue JS_ThrowOutOfMemory(JSContext *ctx);
697
698
void __JS_FreeValue(JSContext *ctx, JSValue v);
699
700
static inline JSRefCountHeader *__js_rc(void *ptr)
701
0
{
702
0
    return (JSRefCountHeader *)((uint32_t *)ptr - 1);
703
0
}
704
705
static inline void JS_FreeValue(JSContext *ctx, JSValue v)
706
0
{
707
0
    if (JS_VALUE_HAS_REF_COUNT(v)) {
708
0
        JSRefCountHeader *p = __js_rc(JS_VALUE_GET_PTR(v));
709
0
        if (--p->ref_count <= 0) {
710
0
            __JS_FreeValue(ctx, v);
711
0
        }
712
0
    }
713
0
}
714
void __JS_FreeValueRT(JSRuntime *rt, JSValue v);
715
static inline void JS_FreeValueRT(JSRuntime *rt, JSValue v)
716
0
{
717
0
    if (JS_VALUE_HAS_REF_COUNT(v)) {
718
0
        JSRefCountHeader *p = __js_rc(JS_VALUE_GET_PTR(v));
719
0
        if (--p->ref_count <= 0) {
720
0
            __JS_FreeValueRT(rt, v);
721
0
        }
722
0
    }
723
0
}
724
725
static inline JSValue JS_DupValue(JSContext *ctx, JSValueConst v)
726
0
{
727
0
    if (JS_VALUE_HAS_REF_COUNT(v)) {
728
0
        JSRefCountHeader *p = __js_rc(JS_VALUE_GET_PTR(v));
729
0
        p->ref_count++;
730
0
    }
731
0
    return (JSValue)v;
732
0
}
733
734
static inline JSValue JS_DupValueRT(JSRuntime *rt, JSValueConst v)
735
0
{
736
0
    if (JS_VALUE_HAS_REF_COUNT(v)) {
737
0
        JSRefCountHeader *p = __js_rc(JS_VALUE_GET_PTR(v));
738
0
        p->ref_count++;
739
0
    }
740
0
    return (JSValue)v;
741
0
}
742
743
JS_BOOL JS_StrictEq(JSContext *ctx, JSValueConst op1, JSValueConst op2);
744
JS_BOOL JS_SameValue(JSContext *ctx, JSValueConst op1, JSValueConst op2);
745
JS_BOOL JS_SameValueZero(JSContext *ctx, JSValueConst op1, JSValueConst op2);
746
747
JSValue JS_ToObject(JSContext *ctx, JSValueConst val);
748
#define JS_HINT_STRING  0
749
#define JS_HINT_NUMBER  1
750
#define JS_HINT_NONE    2
751
JSValue JS_ToPrimitive(JSContext *ctx, JSValueConst val, int hint);
752
int JS_ToBool(JSContext *ctx, JSValueConst val); /* return -1 for JS_EXCEPTION */
753
int JS_ToInt32(JSContext *ctx, int32_t *pres, JSValueConst val);
754
static inline int JS_ToUint32(JSContext *ctx, uint32_t *pres, JSValueConst val)
755
0
{
756
0
    return JS_ToInt32(ctx, (int32_t*)pres, val);
757
0
}
758
int JS_ToInt32Sat(JSContext *ctx, int *pres, JSValueConst val);
759
int JS_ToInt64(JSContext *ctx, int64_t *pres, JSValueConst val);
760
int JS_ToIndex(JSContext *ctx, uint64_t *plen, JSValueConst val);
761
int JS_ToFloat64(JSContext *ctx, double *pres, JSValueConst val);
762
/* return an exception if 'val' is a Number */
763
int JS_ToBigInt64(JSContext *ctx, int64_t *pres, JSValueConst val);
764
/* same as JS_ToInt64() but allow BigInt */
765
int JS_ToInt64Ext(JSContext *ctx, int64_t *pres, JSValueConst val);
766
JSValue JS_NewBigInt128(JSContext *ctx, uint64_t low, uint64_t high);
767
int JS_ToBigInt128(JSContext *ctx, uint64_t *plow, uint64_t *phigh, JSValueConst val);
768
int JS_ToBigInt128Sat(JSContext *ctx, uint64_t *plow, uint64_t *phigh, JSValueConst val);
769
770
JSValue JS_NewStringLen(JSContext *ctx, const char *str1, size_t len1);
771
static inline JSValue JS_NewString(JSContext *ctx, const char *str)
772
0
{
773
0
    return JS_NewStringLen(ctx, str, strlen(str));
774
0
}
775
JSValue JS_NewAtomString(JSContext *ctx, const char *str);
776
JSValue JS_ToString(JSContext *ctx, JSValueConst val);
777
JSValue JS_ToPropertyKey(JSContext *ctx, JSValueConst val);
778
const char *JS_ToCStringLen2(JSContext *ctx, size_t *plen, JSValueConst val1, JS_BOOL cesu8);
779
static inline const char *JS_ToCStringLen(JSContext *ctx, size_t *plen, JSValueConst val1)
780
0
{
781
0
    return JS_ToCStringLen2(ctx, plen, val1, 0);
782
0
}
783
static inline const char *JS_ToCString(JSContext *ctx, JSValueConst val1)
784
0
{
785
0
    return JS_ToCStringLen2(ctx, NULL, val1, 0);
786
0
}
787
const char *JS_ToCStringNZ(JSContext *ctx, JSValueConst val1);
788
void JS_FreeCString(JSContext *ctx, const char *ptr);
789
int JS_ToUTF32String(JSContext *ctx, uint32_t **pbuf, JSValueConst val);
790
791
JSValue JS_NewSymbol(JSContext *ctx, const char *description, JS_BOOL is_global);
792
793
JSValue JS_NewObjectProtoClass(JSContext *ctx, JSValueConst proto, JSClassID class_id);
794
JSValue JS_NewObjectClass(JSContext *ctx, int class_id);
795
JSValue JS_NewObjectProto(JSContext *ctx, JSValueConst proto);
796
JSValue JS_NewObject(JSContext *ctx);
797
JSValue JS_CreateFromConstructor(JSContext *ctx, JSValueConst ctor, 
798
                                 int class_id);
799
800
JS_BOOL JS_IsFunction(JSContext* ctx, JSValueConst val);
801
JS_BOOL JS_IsConstructor(JSContext* ctx, JSValueConst val);
802
JS_BOOL JS_SetConstructorBit(JSContext *ctx, JSValueConst func_obj, JS_BOOL val);
803
804
JSValue JS_NewArray(JSContext *ctx);
805
int JS_IsArray(JSContext *ctx, JSValueConst val);
806
807
JSValue JS_NewDate(JSContext *ctx, double epoch_ms);
808
int JS_ThisDateValue(JSContext *ctx, double *valp, JSValueConst this_val);
809
810
JSValue JS_GetPropertyInternal(JSContext *ctx, JSValueConst obj,
811
                               JSAtom prop, JSValueConst receiver,
812
                               JS_BOOL throw_ref_error);
813
static js_force_inline JSValue JS_GetProperty(JSContext *ctx, JSValueConst this_obj,
814
                                              JSAtom prop)
815
0
{
816
0
    return JS_GetPropertyInternal(ctx, this_obj, prop, this_obj, 0);
817
0
}
818
JSValue JS_GetPropertyStr(JSContext *ctx, JSValueConst this_obj,
819
                          const char *prop);
820
JSValue JS_GetPropertyUint32(JSContext *ctx, JSValueConst this_obj,
821
                             uint32_t idx);
822
823
int JS_SetPropertyInternal(JSContext *ctx, JSValueConst obj,
824
                           JSAtom prop, JSValue val, JSValueConst this_obj,
825
                           int flags);
826
static inline int JS_SetProperty(JSContext *ctx, JSValueConst this_obj,
827
                                 JSAtom prop, JSValue val)
828
0
{
829
0
    return JS_SetPropertyInternal(ctx, this_obj, prop, val, this_obj, JS_PROP_THROW);
830
0
}
831
int JS_SetPropertyUint32(JSContext *ctx, JSValueConst this_obj,
832
                         uint32_t idx, JSValue val);
833
int JS_SetPropertyInt64(JSContext *ctx, JSValueConst this_obj,
834
                        int64_t idx, JSValue val);
835
int JS_SetPropertyStr(JSContext *ctx, JSValueConst this_obj,
836
                      const char *prop, JSValue val);
837
int JS_HasProperty(JSContext *ctx, JSValueConst this_obj, JSAtom prop);
838
int JS_IsExtensible(JSContext *ctx, JSValueConst obj);
839
int JS_PreventExtensions(JSContext *ctx, JSValueConst obj);
840
int JS_DeleteProperty(JSContext *ctx, JSValueConst obj, JSAtom prop, int flags);
841
int JS_SetPrototype(JSContext *ctx, JSValueConst obj, JSValueConst proto_val);
842
JSValue JS_GetPrototype(JSContext *ctx, JSValueConst val);
843
844
#define JS_GPN_STRING_MASK  (1 << 0)
845
#define JS_GPN_SYMBOL_MASK  (1 << 1)
846
#define JS_GPN_PRIVATE_MASK (1 << 2)
847
/* only include the enumerable properties */
848
#define JS_GPN_ENUM_ONLY    (1 << 4)
849
/* set theJSPropertyEnum.is_enumerable field */
850
#define JS_GPN_SET_ENUM     (1 << 5)
851
852
int JS_GetOwnPropertyNames(JSContext *ctx, JSPropertyEnum **ptab,
853
                           uint32_t *plen, JSValueConst obj, int flags);
854
void JS_FreePropertyEnum(JSContext *ctx, JSPropertyEnum *tab,
855
                         uint32_t len);
856
int JS_GetOwnProperty(JSContext *ctx, JSPropertyDescriptor *desc,
857
                      JSValueConst obj, JSAtom prop);
858
859
JSValue JS_Call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj,
860
                int argc, JSValueConst *argv);
861
JSValue JS_Invoke(JSContext *ctx, JSValueConst this_val, JSAtom atom,
862
                  int argc, JSValueConst *argv);
863
JSValue JS_CallConstructor(JSContext *ctx, JSValueConst func_obj,
864
                           int argc, JSValueConst *argv);
865
JSValue JS_CallConstructor2(JSContext *ctx, JSValueConst func_obj,
866
                            JSValueConst new_target,
867
                            int argc, JSValueConst *argv);
868
JS_BOOL JS_DetectModule(const char *input, size_t input_len);
869
/* 'input' must be zero terminated i.e. input[input_len] = '\0'. */
870
JSValue JS_Eval(JSContext *ctx, const char *input, size_t input_len,
871
                const char *filename, int eval_flags);
872
/* same as JS_Eval() but with an explicit 'this_obj' parameter */
873
JSValue JS_EvalThis(JSContext *ctx, JSValueConst this_obj,
874
                    const char *input, size_t input_len,
875
                    const char *filename, int eval_flags);
876
JSValue JS_GetGlobalObject(JSContext *ctx);
877
int JS_OrdinaryIsInstanceOf(JSContext *ctx, JSValueConst val,
878
                            JSValueConst obj);
879
int JS_IsInstanceOf(JSContext *ctx, JSValueConst val, JSValueConst obj);
880
int JS_DefineProperty(JSContext *ctx, JSValueConst this_obj,
881
                      JSAtom prop, JSValueConst val,
882
                      JSValueConst getter, JSValueConst setter, int flags);
883
int JS_DefinePropertyValue(JSContext *ctx, JSValueConst this_obj,
884
                           JSAtom prop, JSValue val, int flags);
885
int JS_DefinePropertyValueUint32(JSContext *ctx, JSValueConst this_obj,
886
                                 uint32_t idx, JSValue val, int flags);
887
int JS_DefinePropertyValueStr(JSContext *ctx, JSValueConst this_obj,
888
                              const char *prop, JSValue val, int flags);
889
int JS_DefinePropertyGetSet(JSContext *ctx, JSValueConst this_obj,
890
                            JSAtom prop, JSValue getter, JSValue setter,
891
                            int flags);
892
void JS_SetOpaque(JSValue obj, void *opaque);
893
void *JS_GetOpaque(JSValueConst obj, JSClassID class_id);
894
void *JS_GetOpaque2(JSContext *ctx, JSValueConst obj, JSClassID class_id);
895
void *JS_GetAnyOpaque(JSValueConst obj, JSClassID *class_id);
896
897
/* 'buf' must be zero terminated i.e. buf[buf_len] = '\0'. */
898
JSValue JS_ParseJSON(JSContext *ctx, const char *buf, size_t buf_len,
899
                     const char *filename);
900
#define JS_PARSE_JSON_EXT (1 << 0) /* allow extended JSON */
901
JSValue JS_ParseJSON2(JSContext *ctx, const char *buf, size_t buf_len,
902
                      const char *filename, int flags);
903
JSValue JS_JSONStringify(JSContext *ctx, JSValueConst obj,
904
                         JSValueConst replacer, JSValueConst space0);
905
906
typedef void JSFreeArrayBufferDataFunc(JSRuntime *rt, void *opaque, void *ptr);
907
JSValue JS_NewArrayBuffer(JSContext *ctx, uint8_t *buf, size_t len,
908
                          JSFreeArrayBufferDataFunc *free_func, void *opaque,
909
                          JS_BOOL is_shared);
910
JSValue JS_NewArrayBufferCopy(JSContext *ctx, const uint8_t *buf, size_t len);
911
void JS_DetachArrayBuffer(JSContext *ctx, JSValueConst obj);
912
uint8_t *JS_GetArrayBuffer(JSContext *ctx, size_t *psize, JSValueConst obj);
913
914
typedef enum JSTypedArrayEnum {
915
    JS_TYPED_ARRAY_UINT8C = 0,
916
    JS_TYPED_ARRAY_INT8,
917
    JS_TYPED_ARRAY_UINT8,
918
    JS_TYPED_ARRAY_INT16,
919
    JS_TYPED_ARRAY_UINT16,
920
    JS_TYPED_ARRAY_INT32,
921
    JS_TYPED_ARRAY_UINT32,
922
    JS_TYPED_ARRAY_BIG_INT64,
923
    JS_TYPED_ARRAY_BIG_UINT64,
924
    JS_TYPED_ARRAY_FLOAT16,
925
    JS_TYPED_ARRAY_FLOAT32,
926
    JS_TYPED_ARRAY_FLOAT64,
927
} JSTypedArrayEnum;
928
929
JSValue JS_NewTypedArray(JSContext *ctx, int argc, JSValueConst *argv,
930
                         JSTypedArrayEnum array_type);
931
JSValue JS_GetTypedArrayBuffer(JSContext *ctx, JSValueConst obj,
932
                               size_t *pbyte_offset,
933
                               size_t *pbyte_length,
934
                               size_t *pbytes_per_element);
935
typedef struct {
936
    void *(*sab_alloc)(void *opaque, size_t size);
937
    void (*sab_free)(void *opaque, void *ptr);
938
    void (*sab_dup)(void *opaque, void *ptr);
939
    void *sab_opaque;
940
} JSSharedArrayBufferFunctions;
941
void JS_SetSharedArrayBufferFunctions(JSRuntime *rt,
942
                                      const JSSharedArrayBufferFunctions *sf);
943
944
typedef enum JSPromiseStateEnum {
945
    JS_PROMISE_PENDING,
946
    JS_PROMISE_FULFILLED,
947
    JS_PROMISE_REJECTED,
948
} JSPromiseStateEnum;
949
950
JSValue JS_NewPromiseCapability(JSContext *ctx, JSValue *resolving_funcs);
951
JSPromiseStateEnum JS_PromiseState(JSContext *ctx, JSValue promise);
952
JSValue JS_PromiseResult(JSContext *ctx, JSValue promise);
953
954
/* is_handled = TRUE means that the rejection is handled */
955
typedef void JSHostPromiseRejectionTracker(JSContext *ctx, JSValueConst promise,
956
                                           JSValueConst reason,
957
                                           JS_BOOL is_handled, void *opaque);
958
void JS_SetHostPromiseRejectionTracker(JSRuntime *rt, JSHostPromiseRejectionTracker *cb, void *opaque);
959
960
/* return != 0 if the JS code needs to be interrupted */
961
typedef int JSInterruptHandler(JSRuntime *rt, void *opaque);
962
void JS_SetInterruptHandler(JSRuntime *rt, JSInterruptHandler *cb, void *opaque);
963
/* if can_block is TRUE, Atomics.wait() can be used */
964
void JS_SetCanBlock(JSRuntime *rt, JS_BOOL can_block);
965
/* select which debug info is stripped from the compiled code */
966
#define JS_STRIP_SOURCE (1 << 0) /* strip source code */
967
#define JS_STRIP_DEBUG  (1 << 1) /* strip all debug info including source code */
968
void JS_SetStripInfo(JSRuntime *rt, int flags);
969
int JS_GetStripInfo(JSRuntime *rt);
970
971
/* set the [IsHTMLDDA] internal slot */
972
void JS_SetIsHTMLDDA(JSContext *ctx, JSValueConst obj);
973
974
typedef struct JSModuleDef JSModuleDef;
975
976
/* return the module specifier (allocated with js_malloc()) or NULL if
977
   exception */
978
typedef char *JSModuleNormalizeFunc(JSContext *ctx,
979
                                    const char *module_base_name,
980
                                    const char *module_name, void *opaque);
981
typedef JSModuleDef *JSModuleLoaderFunc(JSContext *ctx,
982
                                        const char *module_name, void *opaque);
983
typedef JSModuleDef *JSModuleLoaderFunc2(JSContext *ctx,
984
                                         const char *module_name, void *opaque,
985
                                         JSValueConst attributes);
986
/* return -1 if exception, 0 if OK */
987
typedef int JSModuleCheckSupportedImportAttributes(JSContext *ctx, void *opaque,
988
                                                   JSValueConst attributes);
989
                                                   
990
/* module_normalize = NULL is allowed and invokes the default module
991
   filename normalizer */
992
void JS_SetModuleLoaderFunc(JSRuntime *rt,
993
                            JSModuleNormalizeFunc *module_normalize,
994
                            JSModuleLoaderFunc *module_loader, void *opaque);
995
/* same as JS_SetModuleLoaderFunc but with attributes. if
996
   module_check_attrs = NULL, no attribute checking is done. */
997
void JS_SetModuleLoaderFunc2(JSRuntime *rt,
998
                             JSModuleNormalizeFunc *module_normalize,
999
                             JSModuleLoaderFunc2 *module_loader,
1000
                             JSModuleCheckSupportedImportAttributes *module_check_attrs,
1001
                             void *opaque);
1002
/* return the import.meta object of a module */
1003
JSValue JS_GetImportMeta(JSContext *ctx, JSModuleDef *m);
1004
JSAtom JS_GetModuleName(JSContext *ctx, JSModuleDef *m);
1005
JSValue JS_GetModuleNamespace(JSContext *ctx, JSModuleDef *m);
1006
1007
/* JS Job support */
1008
1009
typedef JSValue JSJobFunc(JSContext *ctx, int argc, JSValueConst *argv);
1010
int JS_EnqueueJob(JSContext *ctx, JSJobFunc *job_func, int argc, JSValueConst *argv);
1011
1012
JS_BOOL JS_IsJobPending(JSRuntime *rt);
1013
int JS_ExecutePendingJob(JSRuntime *rt, JSContext **pctx);
1014
1015
/* Object Writer/Reader (currently only used to handle precompiled code) */
1016
#define JS_WRITE_OBJ_BYTECODE  (1 << 0) /* allow function/module */
1017
#define JS_WRITE_OBJ_BSWAP     (1 << 1) /* byte swapped output */
1018
#define JS_WRITE_OBJ_SAB       (1 << 2) /* allow SharedArrayBuffer */
1019
#define JS_WRITE_OBJ_REFERENCE (1 << 3) /* allow object references to
1020
                                           encode arbitrary object
1021
                                           graph */
1022
uint8_t *JS_WriteObject(JSContext *ctx, size_t *psize, JSValueConst obj,
1023
                        int flags);
1024
uint8_t *JS_WriteObject2(JSContext *ctx, size_t *psize, JSValueConst obj,
1025
                         int flags, uint8_t ***psab_tab, size_t *psab_tab_len);
1026
1027
#define JS_READ_OBJ_BYTECODE  (1 << 0) /* allow function/module */
1028
#define JS_READ_OBJ_ROM_DATA  (1 << 1) /* avoid duplicating 'buf' data */
1029
#define JS_READ_OBJ_SAB       (1 << 2) /* allow SharedArrayBuffer */
1030
#define JS_READ_OBJ_REFERENCE (1 << 3) /* allow object references */
1031
JSValue JS_ReadObject(JSContext *ctx, const uint8_t *buf, size_t buf_len,
1032
                      int flags);
1033
/* instantiate and evaluate a bytecode function. Only used when
1034
   reading a script or module with JS_ReadObject() */
1035
JSValue JS_EvalFunction(JSContext *ctx, JSValue fun_obj);
1036
/* load the dependencies of the module 'obj'. Useful when JS_ReadObject()
1037
   returns a module. */
1038
int JS_ResolveModule(JSContext *ctx, JSValueConst obj);
1039
1040
/* only exported for os.Worker() */
1041
JSAtom JS_GetScriptOrModuleName(JSContext *ctx, int n_stack_levels);
1042
/* only exported for os.Worker() */
1043
JSValue JS_LoadModule(JSContext *ctx, const char *basename,
1044
                      const char *filename);
1045
1046
/* C function definition */
1047
typedef enum JSCFunctionEnum {  /* XXX: should rename for namespace isolation */
1048
    JS_CFUNC_generic,
1049
    JS_CFUNC_generic_magic,
1050
    JS_CFUNC_constructor,
1051
    JS_CFUNC_constructor_magic,
1052
    JS_CFUNC_constructor_or_func,
1053
    JS_CFUNC_constructor_or_func_magic,
1054
    JS_CFUNC_constructor_or_func_flags,
1055
    JS_CFUNC_f_f,
1056
    JS_CFUNC_f_f_f,
1057
    JS_CFUNC_getter,
1058
    JS_CFUNC_setter,
1059
    JS_CFUNC_getter_magic,
1060
    JS_CFUNC_setter_magic,
1061
    JS_CFUNC_iterator_next,
1062
} JSCFunctionEnum;
1063
1064
typedef union JSCFunctionType {
1065
    JSCFunction *generic;
1066
    JSValue (*generic_magic)(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic);
1067
    JSCFunction *constructor;
1068
    JSValue (*constructor_magic)(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv, int magic);
1069
    JSCFunction *constructor_or_func;
1070
    JSValue (*constructor_or_func_flags)(JSContext *ctx, JSValueConst func_obj, JSValueConst this_val, int argc, JSValueConst *argv, int flags);
1071
    double (*f_f)(double);
1072
    double (*f_f_f)(double, double);
1073
    JSValue (*getter)(JSContext *ctx, JSValueConst this_val);
1074
    JSValue (*setter)(JSContext *ctx, JSValueConst this_val, JSValueConst val);
1075
    JSValue (*getter_magic)(JSContext *ctx, JSValueConst this_val, int magic);
1076
    JSValue (*setter_magic)(JSContext *ctx, JSValueConst this_val, JSValueConst val, int magic);
1077
    JSValue (*iterator_next)(JSContext *ctx, JSValueConst this_val,
1078
                             int argc, JSValueConst *argv, int *pdone, int magic);
1079
} JSCFunctionType;
1080
1081
JSValue JS_NewCFunction2(JSContext *ctx, JSCFunction *func,
1082
                         const char *name,
1083
                         int length, JSCFunctionEnum cproto, int magic);
1084
JSValue JS_NewCFunctionData(JSContext *ctx, JSCFunctionData *func,
1085
                            int length, int magic, int data_len,
1086
                            JSValueConst *data);
1087
1088
static inline JSValue JS_NewCFunction(JSContext *ctx, JSCFunction *func, const char *name,
1089
                                      int length)
1090
0
{
1091
0
    return JS_NewCFunction2(ctx, func, name, length, JS_CFUNC_generic, 0);
1092
0
}
1093
1094
static inline JSValue JS_NewCFunctionMagic(JSContext *ctx, JSCFunctionMagic *func,
1095
                                           const char *name,
1096
                                           int length, JSCFunctionEnum cproto, int magic)
1097
0
{
1098
0
    /* Used to squelch a -Wcast-function-type warning. */
1099
0
    JSCFunctionType ft = { .generic_magic = func };
1100
0
    return JS_NewCFunction2(ctx, ft.generic, name, length, cproto, magic);
1101
0
}
1102
int JS_SetConstructor(JSContext *ctx, JSValueConst func_obj,
1103
                      JSValueConst proto);
1104
1105
/* C property definition */
1106
1107
typedef struct JSCFunctionListEntry {
1108
    const char *name;
1109
    uint8_t prop_flags;
1110
    uint8_t def_type;
1111
    int16_t magic;
1112
    union {
1113
        struct {
1114
            uint8_t length; /* XXX: should move outside union */
1115
            uint8_t cproto; /* XXX: should move outside union */
1116
            JSCFunctionType cfunc;
1117
        } func;
1118
        struct {
1119
            JSCFunctionType get;
1120
            JSCFunctionType set;
1121
        } getset;
1122
        struct {
1123
            const char *name;
1124
            int base;
1125
        } alias;
1126
        struct {
1127
            const struct JSCFunctionListEntry *tab;
1128
            int len;
1129
        } prop_list;
1130
        const char *str;
1131
        int32_t i32;
1132
        int64_t i64;
1133
        double f64;
1134
    } u;
1135
} JSCFunctionListEntry;
1136
1137
#define JS_DEF_CFUNC          0
1138
#define JS_DEF_CGETSET        1
1139
#define JS_DEF_CGETSET_MAGIC  2
1140
#define JS_DEF_PROP_STRING    3
1141
#define JS_DEF_PROP_INT32     4
1142
#define JS_DEF_PROP_INT64     5
1143
#define JS_DEF_PROP_DOUBLE    6
1144
#define JS_DEF_PROP_UNDEFINED 7
1145
#define JS_DEF_OBJECT         8
1146
#define JS_DEF_ALIAS          9
1147
#define JS_DEF_PROP_ATOM     10
1148
#define JS_DEF_PROP_BOOL     11
1149
1150
/* Note: c++ does not like nested designators */
1151
#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 } } } }
1152
#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 } } } }
1153
#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 } } } }
1154
#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 } } } }
1155
#define JS_CGETSET_DEF(name, fgetter, fsetter) { name, JS_PROP_CONFIGURABLE, JS_DEF_CGETSET, 0, .u = { .getset = { .get = { .getter = fgetter }, .set = { .setter = fsetter } } } }
1156
#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 } } } }
1157
#define JS_PROP_STRING_DEF(name, cstr, prop_flags) { name, prop_flags, JS_DEF_PROP_STRING, 0, .u = { .str = cstr } }
1158
#define JS_PROP_INT32_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT32, 0, .u = { .i32 = val } }
1159
#define JS_PROP_INT64_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT64, 0, .u = { .i64 = val } }
1160
#define JS_PROP_DOUBLE_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_DOUBLE, 0, .u = { .f64 = val } }
1161
#define JS_PROP_UNDEFINED_DEF(name, prop_flags) { name, prop_flags, JS_DEF_PROP_UNDEFINED, 0, .u = { .i32 = 0 } }
1162
#define JS_PROP_ATOM_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_ATOM, 0, .u = { .i32 = val } }
1163
#define JS_PROP_BOOL_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_BOOL, 0, .u = { .i32 = val } }
1164
#define JS_OBJECT_DEF(name, tab, len, prop_flags) { name, prop_flags, JS_DEF_OBJECT, 0, .u = { .prop_list = { tab, len } } }
1165
#define JS_ALIAS_DEF(name, from) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_ALIAS, 0, .u = { .alias = { from, -1 } } }
1166
#define JS_ALIAS_BASE_DEF(name, from, base) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_ALIAS, 0, .u = { .alias = { from, base } } }
1167
1168
int JS_SetPropertyFunctionList(JSContext *ctx, JSValueConst obj,
1169
                               const JSCFunctionListEntry *tab,
1170
                               int len);
1171
1172
#define JS_NEW_CTOR_NO_GLOBAL   (1 << 0) /* don't create a global binding */
1173
#define JS_NEW_CTOR_PROTO_CLASS (1 << 1) /* the prototype class is 'class_id' instead of JS_CLASS_OBJECT */
1174
#define JS_NEW_CTOR_PROTO_EXIST (1 << 2) /* the prototype is already defined */
1175
#define JS_NEW_CTOR_READONLY    (1 << 3) /* read-only constructor field */
1176
1177
JSValue JS_NewCConstructor(JSContext *ctx, int class_id, const char *name,
1178
                           JSCFunction *func, int length, JSCFunctionEnum cproto, int magic,
1179
                           JSValueConst parent_ctor,
1180
                           const JSCFunctionListEntry *ctor_fields, int n_ctor_fields,
1181
                           const JSCFunctionListEntry *proto_fields, int n_proto_fields,
1182
                           int flags);
1183
1184
/* iterator helpers */
1185
1186
JSValue JS_GetIterator(JSContext *ctx, JSValueConst obj, JS_BOOL is_async);
1187
JSValue JS_IteratorNext(JSContext *ctx, JSValueConst enum_obj,
1188
                        JSValueConst method, JS_BOOL *pdone);
1189
int JS_IteratorClose(JSContext *ctx, JSValueConst enum_obj,
1190
                     JS_BOOL is_exception_pending);
1191
1192
#ifdef CONFIG_TEMPORAL_INTL
1193
/*
1194
 * Internal string helpers: caller must ensure 'val' is a JS_TAG_STRING
1195
 * (use JS_ToString() which never returns a rope). We may later export
1196
 * an opaque struct JSString and use it as parameter instead.
1197
 */
1198
int js_string_get_len(JSValueConst val);
1199
int js_string_getc(JSValueConst val, int *pidx);
1200
JSValue js_sub_string_val(JSContext *ctx, JSValueConst val, int start, int end);
1201
#endif /* CONFIG_TEMPORAL_INTL */
1202
1203
/* C module definition */
1204
1205
typedef int JSModuleInitFunc(JSContext *ctx, JSModuleDef *m);
1206
1207
JSModuleDef *JS_NewCModule(JSContext *ctx, const char *name_str,
1208
                           JSModuleInitFunc *func);
1209
/* can only be called before the module is instantiated */
1210
int JS_AddModuleExport(JSContext *ctx, JSModuleDef *m, const char *name_str);
1211
int JS_AddModuleExportList(JSContext *ctx, JSModuleDef *m,
1212
                           const JSCFunctionListEntry *tab, int len);
1213
/* can only be called after the module is instantiated */
1214
int JS_SetModuleExport(JSContext *ctx, JSModuleDef *m, const char *export_name,
1215
                       JSValue val);
1216
int JS_SetModuleExportList(JSContext *ctx, JSModuleDef *m,
1217
                           const JSCFunctionListEntry *tab, int len);
1218
/* associate a JSValue to a C module */
1219
int JS_SetModulePrivateValue(JSContext *ctx, JSModuleDef *m, JSValue val);
1220
JSValue JS_GetModulePrivateValue(JSContext *ctx, JSModuleDef *m);
1221
                        
1222
/* locale specific callbacks to override the default functions */
1223
typedef struct JSLocaleCallbacks {
1224
    JSValue (*number_toLocaleString)(JSContext *ctx, JSValueConst this_val,
1225
                                     int argc, JSValueConst *argv);
1226
    JSValue (*date_toLocaleString)(JSContext *ctx, JSValueConst this_val,
1227
                                   int argc, JSValueConst *argv, int part);
1228
    JSValue (*string_localeCompare)(JSContext *ctx, JSValueConst this_val,
1229
                                    int argc, JSValueConst *argv);
1230
    JSValue (*bigint_toLocaleString)(JSContext *ctx, JSValueConst this_val,
1231
                                     int argc, JSValueConst *argv);
1232
    int (*get_string_locale_lang)(JSContext *ctx, int argc, JSValueConst *argv);
1233
} JSLocaleCallbacks;
1234
1235
void JS_SetLocaleCallbacks(JSContext *ctx, const JSLocaleCallbacks *callbacks);
1236
1237
/* debug value output */
1238
1239
typedef struct {
1240
    JS_BOOL show_hidden : 8; /* only show enumerable properties */
1241
    JS_BOOL raw_dump : 8; /* avoid doing autoinit and avoid any malloc() call (for internal use) */
1242
    uint32_t max_depth; /* recurse up to this depth, 0 = no limit */
1243
    uint32_t max_string_length; /* print no more than this length for
1244
                                   strings, 0 = no limit */
1245
    uint32_t max_item_count; /*  print no more than this count for
1246
                                 arrays or objects, 0 = no limit */
1247
} JSPrintValueOptions;
1248
1249
typedef void JSPrintValueWrite(void *opaque, const char *buf, size_t len);
1250
1251
void JS_PrintValueSetDefaultOptions(JSPrintValueOptions *options);
1252
void JS_PrintValueRT(JSRuntime *rt, JSPrintValueWrite *write_func, void *write_opaque,
1253
                     JSValueConst val, const JSPrintValueOptions *options);
1254
void JS_PrintValue(JSContext *ctx, JSPrintValueWrite *write_func, void *write_opaque,
1255
                   JSValueConst val, const JSPrintValueOptions *options);
1256
1257
#undef js_unlikely
1258
#undef js_force_inline
1259
1260
#ifdef __cplusplus
1261
} /* extern "C" { */
1262
#endif
1263
1264
#endif /* QUICKJS_H */