Coverage Report

Created: 2024-11-21 07:03

/src/libfuzzer-js/quickjs/quickjs.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * QuickJS Javascript Engine
3
 *
4
 * Copyright (c) 2017-2020 Fabrice Bellard
5
 * Copyright (c) 2017-2020 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
71.3k
#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
142k
#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
42.5k
#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
0
{
227
0
    JSValue v;
228
0
    v.tag = JS_TAG_FLOAT64;
229
0
    v.u.float64 = d;
230
0
    return v;
231
0
}
232
233
static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
234
0
{
235
0
    union {
236
0
        double d;
237
0
        uint64_t u64;
238
0
    } u;
239
0
    if (v.tag != JS_TAG_FLOAT64)
240
0
        return 0;
241
0
    u.d = v.u.float64;
242
0
    return (u.u64 & 0x7fffffffffffffff) > 0x7ff0000000000000;
243
0
}
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
106k
#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
35.6k
#define JS_EVAL_TYPE_GLOBAL   (0 << 0) /* global code (default) */
297
0
#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
0
#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
311
typedef JSValue JSCFunction(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);
312
typedef JSValue JSCFunctionMagic(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic);
313
typedef JSValue JSCFunctionData(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic, JSValue *func_data);
314
315
typedef struct JSMallocState {
316
    size_t malloc_count;
317
    size_t malloc_size;
318
    size_t malloc_limit;
319
    void *opaque; /* user opaque */
320
} JSMallocState;
321
322
typedef struct JSMallocFunctions {
323
    void *(*js_malloc)(JSMallocState *s, size_t size);
324
    void (*js_free)(JSMallocState *s, void *ptr);
325
    void *(*js_realloc)(JSMallocState *s, void *ptr, size_t size);
326
    size_t (*js_malloc_usable_size)(const void *ptr);
327
} JSMallocFunctions;
328
329
typedef struct JSGCObjectHeader JSGCObjectHeader;
330
331
JSRuntime *JS_NewRuntime(void);
332
/* info lifetime must exceed that of rt */
333
void JS_SetRuntimeInfo(JSRuntime *rt, const char *info);
334
void JS_SetMemoryLimit(JSRuntime *rt, size_t limit);
335
void JS_SetGCThreshold(JSRuntime *rt, size_t gc_threshold);
336
void JS_SetMaxStackSize(JSRuntime *rt, size_t stack_size);
337
JSRuntime *JS_NewRuntime2(const JSMallocFunctions *mf, void *opaque);
338
void JS_FreeRuntime(JSRuntime *rt);
339
void *JS_GetRuntimeOpaque(JSRuntime *rt);
340
void JS_SetRuntimeOpaque(JSRuntime *rt, void *opaque);
341
typedef void JS_MarkFunc(JSRuntime *rt, JSGCObjectHeader *gp);
342
void JS_MarkValue(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func);
343
void JS_RunGC(JSRuntime *rt);
344
JS_BOOL JS_IsLiveObject(JSRuntime *rt, JSValueConst obj);
345
346
JSContext *JS_NewContext(JSRuntime *rt);
347
void JS_FreeContext(JSContext *s);
348
JSContext *JS_DupContext(JSContext *ctx);
349
void *JS_GetContextOpaque(JSContext *ctx);
350
void JS_SetContextOpaque(JSContext *ctx, void *opaque);
351
JSRuntime *JS_GetRuntime(JSContext *ctx);
352
void JS_SetClassProto(JSContext *ctx, JSClassID class_id, JSValue obj);
353
JSValue JS_GetClassProto(JSContext *ctx, JSClassID class_id);
354
355
/* the following functions are used to select the intrinsic object to
356
   save memory */
357
JSContext *JS_NewContextRaw(JSRuntime *rt);
358
void JS_AddIntrinsicBaseObjects(JSContext *ctx);
359
void JS_AddIntrinsicDate(JSContext *ctx);
360
void JS_AddIntrinsicEval(JSContext *ctx);
361
void JS_AddIntrinsicStringNormalize(JSContext *ctx);
362
void JS_AddIntrinsicRegExpCompiler(JSContext *ctx);
363
void JS_AddIntrinsicRegExp(JSContext *ctx);
364
void JS_AddIntrinsicJSON(JSContext *ctx);
365
void JS_AddIntrinsicProxy(JSContext *ctx);
366
void JS_AddIntrinsicMapSet(JSContext *ctx);
367
void JS_AddIntrinsicTypedArrays(JSContext *ctx);
368
void JS_AddIntrinsicPromise(JSContext *ctx);
369
void JS_AddIntrinsicBigInt(JSContext *ctx);
370
void JS_AddIntrinsicBigFloat(JSContext *ctx);
371
void JS_AddIntrinsicBigDecimal(JSContext *ctx);
372
/* enable operator overloading */
373
void JS_AddIntrinsicOperators(JSContext *ctx);
374
/* enable "use math" */
375
void JS_EnableBignumExt(JSContext *ctx, JS_BOOL enable);
376
377
JSValue js_string_codePointRange(JSContext *ctx, JSValueConst this_val,
378
                                 int argc, JSValueConst *argv);
379
380
void *js_malloc_rt(JSRuntime *rt, size_t size);
381
void js_free_rt(JSRuntime *rt, void *ptr);
382
void *js_realloc_rt(JSRuntime *rt, void *ptr, size_t size);
383
size_t js_malloc_usable_size_rt(JSRuntime *rt, const void *ptr);
384
void *js_mallocz_rt(JSRuntime *rt, size_t size);
385
386
void *js_malloc(JSContext *ctx, size_t size);
387
void js_free(JSContext *ctx, void *ptr);
388
void *js_realloc(JSContext *ctx, void *ptr, size_t size);
389
size_t js_malloc_usable_size(JSContext *ctx, const void *ptr);
390
void *js_realloc2(JSContext *ctx, void *ptr, size_t size, size_t *pslack);
391
void *js_mallocz(JSContext *ctx, size_t size);
392
char *js_strdup(JSContext *ctx, const char *str);
393
char *js_strndup(JSContext *ctx, const char *s, size_t n);
394
395
typedef struct JSMemoryUsage {
396
    int64_t malloc_size, malloc_limit, memory_used_size;
397
    int64_t malloc_count;
398
    int64_t memory_used_count;
399
    int64_t atom_count, atom_size;
400
    int64_t str_count, str_size;
401
    int64_t obj_count, obj_size;
402
    int64_t prop_count, prop_size;
403
    int64_t shape_count, shape_size;
404
    int64_t js_func_count, js_func_size, js_func_code_size;
405
    int64_t js_func_pc2line_count, js_func_pc2line_size;
406
    int64_t c_func_count, array_count;
407
    int64_t fast_array_count, fast_array_elements;
408
    int64_t binary_object_count, binary_object_size;
409
} JSMemoryUsage;
410
411
void JS_ComputeMemoryUsage(JSRuntime *rt, JSMemoryUsage *s);
412
void JS_DumpMemoryUsage(FILE *fp, const JSMemoryUsage *s, JSRuntime *rt);
413
414
/* atom support */
415
#define JS_ATOM_NULL 0
416
417
JSAtom JS_NewAtomLen(JSContext *ctx, const char *str, size_t len);
418
JSAtom JS_NewAtom(JSContext *ctx, const char *str);
419
JSAtom JS_NewAtomUInt32(JSContext *ctx, uint32_t n);
420
JSAtom JS_DupAtom(JSContext *ctx, JSAtom v);
421
void JS_FreeAtom(JSContext *ctx, JSAtom v);
422
void JS_FreeAtomRT(JSRuntime *rt, JSAtom v);
423
JSValue JS_AtomToValue(JSContext *ctx, JSAtom atom);
424
JSValue JS_AtomToString(JSContext *ctx, JSAtom atom);
425
const char *JS_AtomToCString(JSContext *ctx, JSAtom atom);
426
JSAtom JS_ValueToAtom(JSContext *ctx, JSValueConst val);
427
428
/* object class support */
429
430
typedef struct JSPropertyEnum {
431
    JS_BOOL is_enumerable;
432
    JSAtom atom;
433
} JSPropertyEnum;
434
435
typedef struct JSPropertyDescriptor {
436
    int flags;
437
    JSValue value;
438
    JSValue getter;
439
    JSValue setter;
440
} JSPropertyDescriptor;
441
442
typedef struct JSClassExoticMethods {
443
    /* Return -1 if exception (can only happen in case of Proxy object),
444
       FALSE if the property does not exists, TRUE if it exists. If 1 is
445
       returned, the property descriptor 'desc' is filled if != NULL. */
446
    int (*get_own_property)(JSContext *ctx, JSPropertyDescriptor *desc,
447
                             JSValueConst obj, JSAtom prop);
448
    /* '*ptab' should hold the '*plen' property keys. Return 0 if OK,
449
       -1 if exception. The 'is_enumerable' field is ignored.
450
    */
451
    int (*get_own_property_names)(JSContext *ctx, JSPropertyEnum **ptab,
452
                                  uint32_t *plen,
453
                                  JSValueConst obj);
454
    /* return < 0 if exception, or TRUE/FALSE */
455
    int (*delete_property)(JSContext *ctx, JSValueConst obj, JSAtom prop);
456
    /* return < 0 if exception or TRUE/FALSE */
457
    int (*define_own_property)(JSContext *ctx, JSValueConst this_obj,
458
                               JSAtom prop, JSValueConst val,
459
                               JSValueConst getter, JSValueConst setter,
460
                               int flags);
461
    /* The following methods can be emulated with the previous ones,
462
       so they are usually not needed */
463
    /* return < 0 if exception or TRUE/FALSE */
464
    int (*has_property)(JSContext *ctx, JSValueConst obj, JSAtom atom);
465
    JSValue (*get_property)(JSContext *ctx, JSValueConst obj, JSAtom atom,
466
                            JSValueConst receiver);
467
    /* return < 0 if exception or TRUE/FALSE */
468
    int (*set_property)(JSContext *ctx, JSValueConst obj, JSAtom atom,
469
                        JSValueConst value, JSValueConst receiver, int flags);
470
} JSClassExoticMethods;
471
472
typedef void JSClassFinalizer(JSRuntime *rt, JSValue val);
473
typedef void JSClassGCMark(JSRuntime *rt, JSValueConst val,
474
                           JS_MarkFunc *mark_func);
475
#define JS_CALL_FLAG_CONSTRUCTOR (1 << 0)
476
typedef JSValue JSClassCall(JSContext *ctx, JSValueConst func_obj,
477
                            JSValueConst this_val, int argc, JSValueConst *argv,
478
                            int flags);
479
480
typedef struct JSClassDef {
481
    const char *class_name;
482
    JSClassFinalizer *finalizer;
483
    JSClassGCMark *gc_mark;
484
    /* if call != NULL, the object is a function. If (flags &
485
       JS_CALL_FLAG_CONSTRUCTOR) != 0, the function is called as a
486
       constructor. In this case, 'this_val' is new.target. A
487
       constructor call only happens if the object constructor bit is
488
       set (see JS_SetConstructorBit()). */
489
    JSClassCall *call;
490
    /* XXX: suppress this indirection ? It is here only to save memory
491
       because only a few classes need these methods */
492
    JSClassExoticMethods *exotic;
493
} JSClassDef;
494
495
JSClassID JS_NewClassID(JSClassID *pclass_id);
496
int JS_NewClass(JSRuntime *rt, JSClassID class_id, const JSClassDef *class_def);
497
int JS_IsRegisteredClass(JSRuntime *rt, JSClassID class_id);
498
499
/* value handling */
500
501
static js_force_inline JSValue JS_NewBool(JSContext *ctx, JS_BOOL val)
502
0
{
503
0
    return JS_MKVAL(JS_TAG_BOOL, (val != 0));
504
0
}
505
506
static js_force_inline JSValue JS_NewInt32(JSContext *ctx, int32_t val)
507
0
{
508
0
    return JS_MKVAL(JS_TAG_INT, val);
509
0
}
510
511
static js_force_inline JSValue JS_NewCatchOffset(JSContext *ctx, int32_t val)
512
0
{
513
0
    return JS_MKVAL(JS_TAG_CATCH_OFFSET, val);
514
0
}
515
516
static js_force_inline JSValue JS_NewInt64(JSContext *ctx, int64_t val)
517
0
{
518
0
    JSValue v;
519
0
    if (val == (int32_t)val) {
520
0
        v = JS_NewInt32(ctx, val);
521
0
    } else {
522
0
        v = __JS_NewFloat64(ctx, val);
523
0
    }
524
0
    return v;
525
0
}
526
527
static js_force_inline JSValue JS_NewUint32(JSContext *ctx, uint32_t val)
528
0
{
529
0
    JSValue v;
530
0
    if (val <= 0x7fffffff) {
531
0
        v = JS_NewInt32(ctx, val);
532
0
    } else {
533
0
        v = __JS_NewFloat64(ctx, val);
534
0
    }
535
0
    return v;
536
0
}
537
538
JSValue JS_NewBigInt64(JSContext *ctx, int64_t v);
539
JSValue JS_NewBigUint64(JSContext *ctx, uint64_t v);
540
541
static js_force_inline JSValue JS_NewFloat64(JSContext *ctx, double d)
542
0
{
543
0
    JSValue v;
544
0
    int32_t val;
545
0
    union {
546
0
        double d;
547
0
        uint64_t u;
548
0
    } u, t;
549
0
    u.d = d;
550
0
    val = (int32_t)d;
551
0
    t.d = val;
552
0
    /* -0 cannot be represented as integer, so we compare the bit
553
0
        representation */
554
0
    if (u.u == t.u) {
555
0
        v = JS_MKVAL(JS_TAG_INT, val);
556
0
    } else {
557
0
        v = __JS_NewFloat64(ctx, d);
558
0
    }
559
0
    return v;
560
0
}
561
562
static inline JS_BOOL JS_IsNumber(JSValueConst v)
563
0
{
564
0
    int tag = JS_VALUE_GET_TAG(v);
565
0
    return tag == JS_TAG_INT || JS_TAG_IS_FLOAT64(tag);
566
0
}
567
568
static inline JS_BOOL JS_IsBigInt(JSContext *ctx, JSValueConst v)
569
0
{
570
0
    int tag = JS_VALUE_GET_TAG(v);
571
0
    return tag == JS_TAG_BIG_INT;
572
0
}
573
574
static inline JS_BOOL JS_IsBigFloat(JSValueConst v)
575
0
{
576
0
    int tag = JS_VALUE_GET_TAG(v);
577
0
    return tag == JS_TAG_BIG_FLOAT;
578
0
}
579
580
static inline JS_BOOL JS_IsBigDecimal(JSValueConst v)
581
0
{
582
0
    int tag = JS_VALUE_GET_TAG(v);
583
0
    return tag == JS_TAG_BIG_DECIMAL;
584
0
}
585
586
static inline JS_BOOL JS_IsBool(JSValueConst v)
587
0
{
588
0
    return JS_VALUE_GET_TAG(v) == JS_TAG_BOOL;
589
0
}
590
591
static inline JS_BOOL JS_IsNull(JSValueConst v)
592
0
{
593
0
    return JS_VALUE_GET_TAG(v) == JS_TAG_NULL;
594
0
}
595
596
static inline JS_BOOL JS_IsUndefined(JSValueConst v)
597
0
{
598
0
    return JS_VALUE_GET_TAG(v) == JS_TAG_UNDEFINED;
599
0
}
600
601
static inline JS_BOOL JS_IsException(JSValueConst v)
602
71.3k
{
603
71.3k
    return js_unlikely(JS_VALUE_GET_TAG(v) == JS_TAG_EXCEPTION);
604
71.3k
}
605
606
static inline JS_BOOL JS_IsUninitialized(JSValueConst v)
607
0
{
608
0
    return js_unlikely(JS_VALUE_GET_TAG(v) == JS_TAG_UNINITIALIZED);
609
0
}
610
611
static inline JS_BOOL JS_IsString(JSValueConst v)
612
35.6k
{
613
35.6k
    return JS_VALUE_GET_TAG(v) == JS_TAG_STRING;
614
35.6k
}
615
616
static inline JS_BOOL JS_IsSymbol(JSValueConst v)
617
0
{
618
0
    return JS_VALUE_GET_TAG(v) == JS_TAG_SYMBOL;
619
0
}
620
621
static inline JS_BOOL JS_IsObject(JSValueConst v)
622
0
{
623
0
    return JS_VALUE_GET_TAG(v) == JS_TAG_OBJECT;
624
0
}
625
626
JSValue JS_Throw(JSContext *ctx, JSValue obj);
627
JSValue JS_GetException(JSContext *ctx);
628
JS_BOOL JS_IsError(JSContext *ctx, JSValueConst val);
629
void JS_ResetUncatchableError(JSContext *ctx);
630
JSValue JS_NewError(JSContext *ctx);
631
JSValue __js_printf_like(2, 3) JS_ThrowSyntaxError(JSContext *ctx, const char *fmt, ...);
632
JSValue __js_printf_like(2, 3) JS_ThrowTypeError(JSContext *ctx, const char *fmt, ...);
633
JSValue __js_printf_like(2, 3) JS_ThrowReferenceError(JSContext *ctx, const char *fmt, ...);
634
JSValue __js_printf_like(2, 3) JS_ThrowRangeError(JSContext *ctx, const char *fmt, ...);
635
JSValue __js_printf_like(2, 3) JS_ThrowInternalError(JSContext *ctx, const char *fmt, ...);
636
JSValue JS_ThrowOutOfMemory(JSContext *ctx);
637
638
void __JS_FreeValue(JSContext *ctx, JSValue v);
639
static inline void JS_FreeValue(JSContext *ctx, JSValue v)
640
106k
{
641
106k
    if (JS_VALUE_HAS_REF_COUNT(v)) {
642
42.5k
        JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v);
643
42.5k
        if (--p->ref_count <= 0) {
644
0
            __JS_FreeValue(ctx, v);
645
0
        }
646
42.5k
    }
647
106k
}
648
void __JS_FreeValueRT(JSRuntime *rt, JSValue v);
649
static inline void JS_FreeValueRT(JSRuntime *rt, JSValue v)
650
0
{
651
0
    if (JS_VALUE_HAS_REF_COUNT(v)) {
652
0
        JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v);
653
0
        if (--p->ref_count <= 0) {
654
0
            __JS_FreeValueRT(rt, v);
655
0
        }
656
0
    }
657
0
}
658
659
static inline JSValue JS_DupValue(JSContext *ctx, JSValueConst v)
660
0
{
661
0
    if (JS_VALUE_HAS_REF_COUNT(v)) {
662
0
        JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v);
663
0
        p->ref_count++;
664
0
    }
665
0
    return (JSValue)v;
666
0
}
667
668
static inline JSValue JS_DupValueRT(JSRuntime *rt, JSValueConst v)
669
0
{
670
0
    if (JS_VALUE_HAS_REF_COUNT(v)) {
671
0
        JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v);
672
0
        p->ref_count++;
673
0
    }
674
0
    return (JSValue)v;
675
0
}
676
677
int JS_ToBool(JSContext *ctx, JSValueConst val); /* return -1 for JS_EXCEPTION */
678
int JS_ToInt32(JSContext *ctx, int32_t *pres, JSValueConst val);
679
static inline int JS_ToUint32(JSContext *ctx, uint32_t *pres, JSValueConst val)
680
0
{
681
0
    return JS_ToInt32(ctx, (int32_t*)pres, val);
682
0
}
683
int JS_ToInt64(JSContext *ctx, int64_t *pres, JSValueConst val);
684
int JS_ToIndex(JSContext *ctx, uint64_t *plen, JSValueConst val);
685
int JS_ToFloat64(JSContext *ctx, double *pres, JSValueConst val);
686
/* return an exception if 'val' is a Number */
687
int JS_ToBigInt64(JSContext *ctx, int64_t *pres, JSValueConst val);
688
/* same as JS_ToInt64() but allow BigInt */
689
int JS_ToInt64Ext(JSContext *ctx, int64_t *pres, JSValueConst val);
690
691
JSValue JS_NewStringLen(JSContext *ctx, const char *str1, size_t len1);
692
JSValue JS_NewString(JSContext *ctx, const char *str);
693
JSValue JS_NewAtomString(JSContext *ctx, const char *str);
694
JSValue JS_ToString(JSContext *ctx, JSValueConst val);
695
JSValue JS_ToPropertyKey(JSContext *ctx, JSValueConst val);
696
const char *JS_ToCStringLen2(JSContext *ctx, size_t *plen, JSValueConst val1, JS_BOOL cesu8);
697
static inline const char *JS_ToCStringLen(JSContext *ctx, size_t *plen, JSValueConst val1)
698
0
{
699
0
    return JS_ToCStringLen2(ctx, plen, val1, 0);
700
0
}
701
static inline const char *JS_ToCString(JSContext *ctx, JSValueConst val1)
702
0
{
703
0
    return JS_ToCStringLen2(ctx, NULL, val1, 0);
704
0
}
705
void JS_FreeCString(JSContext *ctx, const char *ptr);
706
707
JSValue JS_NewObjectProtoClass(JSContext *ctx, JSValueConst proto, JSClassID class_id);
708
JSValue JS_NewObjectClass(JSContext *ctx, int class_id);
709
JSValue JS_NewObjectProto(JSContext *ctx, JSValueConst proto);
710
JSValue JS_NewObject(JSContext *ctx);
711
712
JS_BOOL JS_IsFunction(JSContext* ctx, JSValueConst val);
713
JS_BOOL JS_IsConstructor(JSContext* ctx, JSValueConst val);
714
JS_BOOL JS_SetConstructorBit(JSContext *ctx, JSValueConst func_obj, JS_BOOL val);
715
716
JSValue JS_NewArray(JSContext *ctx);
717
int JS_IsArray(JSContext *ctx, JSValueConst val);
718
719
JSValue JS_GetPropertyInternal(JSContext *ctx, JSValueConst obj,
720
                               JSAtom prop, JSValueConst receiver,
721
                               JS_BOOL throw_ref_error);
722
static js_force_inline JSValue JS_GetProperty(JSContext *ctx, JSValueConst this_obj,
723
                                              JSAtom prop)
724
0
{
725
0
    return JS_GetPropertyInternal(ctx, this_obj, prop, this_obj, 0);
726
0
}
727
JSValue JS_GetPropertyStr(JSContext *ctx, JSValueConst this_obj,
728
                          const char *prop);
729
JSValue JS_GetPropertyUint32(JSContext *ctx, JSValueConst this_obj,
730
                             uint32_t idx);
731
732
int JS_SetPropertyInternal(JSContext *ctx, JSValueConst this_obj,
733
                           JSAtom prop, JSValue val,
734
                           int flags);
735
static inline int JS_SetProperty(JSContext *ctx, JSValueConst this_obj,
736
                                 JSAtom prop, JSValue val)
737
0
{
738
0
    return JS_SetPropertyInternal(ctx, this_obj, prop, val, JS_PROP_THROW);
739
0
}
740
int JS_SetPropertyUint32(JSContext *ctx, JSValueConst this_obj,
741
                         uint32_t idx, JSValue val);
742
int JS_SetPropertyInt64(JSContext *ctx, JSValueConst this_obj,
743
                        int64_t idx, JSValue val);
744
int JS_SetPropertyStr(JSContext *ctx, JSValueConst this_obj,
745
                      const char *prop, JSValue val);
746
int JS_HasProperty(JSContext *ctx, JSValueConst this_obj, JSAtom prop);
747
int JS_IsExtensible(JSContext *ctx, JSValueConst obj);
748
int JS_PreventExtensions(JSContext *ctx, JSValueConst obj);
749
int JS_DeleteProperty(JSContext *ctx, JSValueConst obj, JSAtom prop, int flags);
750
int JS_SetPrototype(JSContext *ctx, JSValueConst obj, JSValueConst proto_val);
751
JSValue JS_GetPrototype(JSContext *ctx, JSValueConst val);
752
753
#define JS_GPN_STRING_MASK  (1 << 0)
754
#define JS_GPN_SYMBOL_MASK  (1 << 1)
755
#define JS_GPN_PRIVATE_MASK (1 << 2)
756
/* only include the enumerable properties */
757
#define JS_GPN_ENUM_ONLY    (1 << 4)
758
/* set theJSPropertyEnum.is_enumerable field */
759
#define JS_GPN_SET_ENUM     (1 << 5)
760
761
int JS_GetOwnPropertyNames(JSContext *ctx, JSPropertyEnum **ptab,
762
                           uint32_t *plen, JSValueConst obj, int flags);
763
int JS_GetOwnProperty(JSContext *ctx, JSPropertyDescriptor *desc,
764
                      JSValueConst obj, JSAtom prop);
765
766
JSValue JS_Call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj,
767
                int argc, JSValueConst *argv);
768
JSValue JS_Invoke(JSContext *ctx, JSValueConst this_val, JSAtom atom,
769
                  int argc, JSValueConst *argv);
770
JSValue JS_CallConstructor(JSContext *ctx, JSValueConst func_obj,
771
                           int argc, JSValueConst *argv);
772
JSValue JS_CallConstructor2(JSContext *ctx, JSValueConst func_obj,
773
                            JSValueConst new_target,
774
                            int argc, JSValueConst *argv);
775
JS_BOOL JS_DetectModule(const char *input, size_t input_len);
776
/* 'input' must be zero terminated i.e. input[input_len] = '\0'. */
777
JSValue JS_Eval(JSContext *ctx, const char *input, size_t input_len,
778
                const char *filename, int eval_flags);
779
JSValue JS_EvalFunction(JSContext *ctx, JSValue fun_obj);
780
JSValue JS_GetGlobalObject(JSContext *ctx);
781
int JS_IsInstanceOf(JSContext *ctx, JSValueConst val, JSValueConst obj);
782
int JS_DefineProperty(JSContext *ctx, JSValueConst this_obj,
783
                      JSAtom prop, JSValueConst val,
784
                      JSValueConst getter, JSValueConst setter, int flags);
785
int JS_DefinePropertyValue(JSContext *ctx, JSValueConst this_obj,
786
                           JSAtom prop, JSValue val, int flags);
787
int JS_DefinePropertyValueUint32(JSContext *ctx, JSValueConst this_obj,
788
                                 uint32_t idx, JSValue val, int flags);
789
int JS_DefinePropertyValueStr(JSContext *ctx, JSValueConst this_obj,
790
                              const char *prop, JSValue val, int flags);
791
int JS_DefinePropertyGetSet(JSContext *ctx, JSValueConst this_obj,
792
                            JSAtom prop, JSValue getter, JSValue setter,
793
                            int flags);
794
void JS_SetOpaque(JSValue obj, void *opaque);
795
void *JS_GetOpaque(JSValueConst obj, JSClassID class_id);
796
void *JS_GetOpaque2(JSContext *ctx, JSValueConst obj, JSClassID class_id);
797
798
/* 'buf' must be zero terminated i.e. buf[buf_len] = '\0'. */
799
JSValue JS_ParseJSON(JSContext *ctx, const char *buf, size_t buf_len,
800
                     const char *filename);
801
#define JS_PARSE_JSON_EXT (1 << 0) /* allow extended JSON */
802
JSValue JS_ParseJSON2(JSContext *ctx, const char *buf, size_t buf_len,
803
                      const char *filename, int flags);
804
JSValue JS_JSONStringify(JSContext *ctx, JSValueConst obj,
805
                         JSValueConst replacer, JSValueConst space0);
806
807
typedef void JSFreeArrayBufferDataFunc(JSRuntime *rt, void *opaque, void *ptr);
808
JSValue JS_NewArrayBuffer(JSContext *ctx, uint8_t *buf, size_t len,
809
                          JSFreeArrayBufferDataFunc *free_func, void *opaque,
810
                          JS_BOOL is_shared);
811
JSValue JS_NewArrayBufferCopy(JSContext *ctx, const uint8_t *buf, size_t len);
812
void JS_DetachArrayBuffer(JSContext *ctx, JSValueConst obj);
813
uint8_t *JS_GetArrayBuffer(JSContext *ctx, size_t *psize, JSValueConst obj);
814
JSValue JS_GetTypedArrayBuffer(JSContext *ctx, JSValueConst obj,
815
                               size_t *pbyte_offset,
816
                               size_t *pbyte_length,
817
                               size_t *pbytes_per_element);
818
typedef struct {
819
    void *(*sab_alloc)(void *opaque, size_t size);
820
    void (*sab_free)(void *opaque, void *ptr);
821
    void (*sab_dup)(void *opaque, void *ptr);
822
    void *sab_opaque;
823
} JSSharedArrayBufferFunctions;
824
void JS_SetSharedArrayBufferFunctions(JSRuntime *rt,
825
                                      const JSSharedArrayBufferFunctions *sf);
826
827
JSValue JS_NewPromiseCapability(JSContext *ctx, JSValue *resolving_funcs);
828
829
/* is_handled = TRUE means that the rejection is handled */
830
typedef void JSHostPromiseRejectionTracker(JSContext *ctx, JSValueConst promise,
831
                                           JSValueConst reason,
832
                                           JS_BOOL is_handled, void *opaque);
833
void JS_SetHostPromiseRejectionTracker(JSRuntime *rt, JSHostPromiseRejectionTracker *cb, void *opaque);
834
835
/* return != 0 if the JS code needs to be interrupted */
836
typedef int JSInterruptHandler(JSRuntime *rt, void *opaque);
837
void JS_SetInterruptHandler(JSRuntime *rt, JSInterruptHandler *cb, void *opaque);
838
/* if can_block is TRUE, Atomics.wait() can be used */
839
void JS_SetCanBlock(JSRuntime *rt, JS_BOOL can_block);
840
/* set the [IsHTMLDDA] internal slot */
841
void JS_SetIsHTMLDDA(JSContext *ctx, JSValueConst obj);
842
843
typedef struct JSModuleDef JSModuleDef;
844
845
/* return the module specifier (allocated with js_malloc()) or NULL if
846
   exception */
847
typedef char *JSModuleNormalizeFunc(JSContext *ctx,
848
                                    const char *module_base_name,
849
                                    const char *module_name, void *opaque);
850
typedef JSModuleDef *JSModuleLoaderFunc(JSContext *ctx,
851
                                        const char *module_name, void *opaque);
852
853
/* module_normalize = NULL is allowed and invokes the default module
854
   filename normalizer */
855
void JS_SetModuleLoaderFunc(JSRuntime *rt,
856
                            JSModuleNormalizeFunc *module_normalize,
857
                            JSModuleLoaderFunc *module_loader, void *opaque);
858
/* return the import.meta object of a module */
859
JSValue JS_GetImportMeta(JSContext *ctx, JSModuleDef *m);
860
JSAtom JS_GetModuleName(JSContext *ctx, JSModuleDef *m);
861
862
/* JS Job support */
863
864
typedef JSValue JSJobFunc(JSContext *ctx, int argc, JSValueConst *argv);
865
int JS_EnqueueJob(JSContext *ctx, JSJobFunc *job_func, int argc, JSValueConst *argv);
866
867
JS_BOOL JS_IsJobPending(JSRuntime *rt);
868
int JS_ExecutePendingJob(JSRuntime *rt, JSContext **pctx);
869
870
/* Object Writer/Reader (currently only used to handle precompiled code) */
871
0
#define JS_WRITE_OBJ_BYTECODE  (1 << 0) /* allow function/module */
872
#define JS_WRITE_OBJ_BSWAP     (1 << 1) /* byte swapped output */
873
#define JS_WRITE_OBJ_SAB       (1 << 2) /* allow SharedArrayBuffer */
874
#define JS_WRITE_OBJ_REFERENCE (1 << 3) /* allow object references to
875
                                           encode arbitrary object
876
                                           graph */
877
uint8_t *JS_WriteObject(JSContext *ctx, size_t *psize, JSValueConst obj,
878
                        int flags);
879
uint8_t *JS_WriteObject2(JSContext *ctx, size_t *psize, JSValueConst obj,
880
                         int flags, uint8_t ***psab_tab, size_t *psab_tab_len);
881
882
#define JS_READ_OBJ_BYTECODE  (1 << 0) /* allow function/module */
883
#define JS_READ_OBJ_ROM_DATA  (1 << 1) /* avoid duplicating 'buf' data */
884
#define JS_READ_OBJ_SAB       (1 << 2) /* allow SharedArrayBuffer */
885
#define JS_READ_OBJ_REFERENCE (1 << 3) /* allow object references */
886
JSValue JS_ReadObject(JSContext *ctx, const uint8_t *buf, size_t buf_len,
887
                      int flags);
888
889
/* load the dependencies of the module 'obj'. Useful when JS_ReadObject()
890
   returns a module. */
891
int JS_ResolveModule(JSContext *ctx, JSValueConst obj);
892
893
/* only exported for os.Worker() */
894
JSAtom JS_GetScriptOrModuleName(JSContext *ctx, int n_stack_levels);
895
/* only exported for os.Worker() */
896
JSModuleDef *JS_RunModule(JSContext *ctx, const char *basename,
897
                          const char *filename);
898
899
/* C function definition */
900
typedef enum JSCFunctionEnum {  /* XXX: should rename for namespace isolation */
901
    JS_CFUNC_generic,
902
    JS_CFUNC_generic_magic,
903
    JS_CFUNC_constructor,
904
    JS_CFUNC_constructor_magic,
905
    JS_CFUNC_constructor_or_func,
906
    JS_CFUNC_constructor_or_func_magic,
907
    JS_CFUNC_f_f,
908
    JS_CFUNC_f_f_f,
909
    JS_CFUNC_getter,
910
    JS_CFUNC_setter,
911
    JS_CFUNC_getter_magic,
912
    JS_CFUNC_setter_magic,
913
    JS_CFUNC_iterator_next,
914
} JSCFunctionEnum;
915
916
typedef union JSCFunctionType {
917
    JSCFunction *generic;
918
    JSValue (*generic_magic)(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic);
919
    JSCFunction *constructor;
920
    JSValue (*constructor_magic)(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv, int magic);
921
    JSCFunction *constructor_or_func;
922
    double (*f_f)(double);
923
    double (*f_f_f)(double, double);
924
    JSValue (*getter)(JSContext *ctx, JSValueConst this_val);
925
    JSValue (*setter)(JSContext *ctx, JSValueConst this_val, JSValueConst val);
926
    JSValue (*getter_magic)(JSContext *ctx, JSValueConst this_val, int magic);
927
    JSValue (*setter_magic)(JSContext *ctx, JSValueConst this_val, JSValueConst val, int magic);
928
    JSValue (*iterator_next)(JSContext *ctx, JSValueConst this_val,
929
                             int argc, JSValueConst *argv, int *pdone, int magic);
930
} JSCFunctionType;
931
932
JSValue JS_NewCFunction2(JSContext *ctx, JSCFunction *func,
933
                         const char *name,
934
                         int length, JSCFunctionEnum cproto, int magic);
935
JSValue JS_NewCFunctionData(JSContext *ctx, JSCFunctionData *func,
936
                            int length, int magic, int data_len,
937
                            JSValueConst *data);
938
939
static inline JSValue JS_NewCFunction(JSContext *ctx, JSCFunction *func, const char *name,
940
                                      int length)
941
0
{
942
0
    return JS_NewCFunction2(ctx, func, name, length, JS_CFUNC_generic, 0);
943
0
}
944
945
static inline JSValue JS_NewCFunctionMagic(JSContext *ctx, JSCFunctionMagic *func,
946
                                           const char *name,
947
                                           int length, JSCFunctionEnum cproto, int magic)
948
0
{
949
0
    return JS_NewCFunction2(ctx, (JSCFunction *)func, name, length, cproto, magic);
950
0
}
951
void JS_SetConstructor(JSContext *ctx, JSValueConst func_obj, 
952
                       JSValueConst proto);
953
954
/* C property definition */
955
956
typedef struct JSCFunctionListEntry {
957
    const char *name;
958
    uint8_t prop_flags;
959
    uint8_t def_type;
960
    int16_t magic;
961
    union {
962
        struct {
963
            uint8_t length; /* XXX: should move outside union */
964
            uint8_t cproto; /* XXX: should move outside union */
965
            JSCFunctionType cfunc;
966
        } func;
967
        struct {
968
            JSCFunctionType get;
969
            JSCFunctionType set;
970
        } getset;
971
        struct {
972
            const char *name;
973
            int base;
974
        } alias;
975
        struct {
976
            const struct JSCFunctionListEntry *tab;
977
            int len;
978
        } prop_list;
979
        const char *str;
980
        int32_t i32;
981
        int64_t i64;
982
        double f64;
983
    } u;
984
} JSCFunctionListEntry;
985
986
#define JS_DEF_CFUNC          0
987
#define JS_DEF_CGETSET        1
988
#define JS_DEF_CGETSET_MAGIC  2
989
#define JS_DEF_PROP_STRING    3
990
#define JS_DEF_PROP_INT32     4
991
#define JS_DEF_PROP_INT64     5
992
#define JS_DEF_PROP_DOUBLE    6
993
#define JS_DEF_PROP_UNDEFINED 7
994
#define JS_DEF_OBJECT         8
995
#define JS_DEF_ALIAS          9
996
997
/* Note: c++ does not like nested designators */
998
#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 } } } }
999
#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 } } } }
1000
#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 } } } }
1001
#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 } } } }
1002
#define JS_CGETSET_DEF(name, fgetter, fsetter) { name, JS_PROP_CONFIGURABLE, JS_DEF_CGETSET, 0, .u = { .getset = { .get = { .getter = fgetter }, .set = { .setter = fsetter } } } }
1003
#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 } } } }
1004
#define JS_PROP_STRING_DEF(name, cstr, prop_flags) { name, prop_flags, JS_DEF_PROP_STRING, 0, .u = { .str = cstr } }
1005
#define JS_PROP_INT32_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT32, 0, .u = { .i32 = val } }
1006
#define JS_PROP_INT64_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT64, 0, .u = { .i64 = val } }
1007
#define JS_PROP_DOUBLE_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_DOUBLE, 0, .u = { .f64 = val } }
1008
#define JS_PROP_UNDEFINED_DEF(name, prop_flags) { name, prop_flags, JS_DEF_PROP_UNDEFINED, 0, .u = { .i32 = 0 } }
1009
#define JS_OBJECT_DEF(name, tab, len, prop_flags) { name, prop_flags, JS_DEF_OBJECT, 0, .u = { .prop_list = { tab, len } } }
1010
#define JS_ALIAS_DEF(name, from) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_ALIAS, 0, .u = { .alias = { from, -1 } } }
1011
#define JS_ALIAS_BASE_DEF(name, from, base) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_ALIAS, 0, .u = { .alias = { from, base } } }
1012
1013
void JS_SetPropertyFunctionList(JSContext *ctx, JSValueConst obj,
1014
                                const JSCFunctionListEntry *tab,
1015
                                int len);
1016
1017
/* C module definition */
1018
1019
typedef int JSModuleInitFunc(JSContext *ctx, JSModuleDef *m);
1020
1021
JSModuleDef *JS_NewCModule(JSContext *ctx, const char *name_str,
1022
                           JSModuleInitFunc *func);
1023
/* can only be called before the module is instantiated */
1024
int JS_AddModuleExport(JSContext *ctx, JSModuleDef *m, const char *name_str);
1025
int JS_AddModuleExportList(JSContext *ctx, JSModuleDef *m,
1026
                           const JSCFunctionListEntry *tab, int len);
1027
/* can only be called after the module is instantiated */
1028
int JS_SetModuleExport(JSContext *ctx, JSModuleDef *m, const char *export_name,
1029
                       JSValue val);
1030
int JS_SetModuleExportList(JSContext *ctx, JSModuleDef *m,
1031
                           const JSCFunctionListEntry *tab, int len);
1032
1033
#undef js_unlikely
1034
#undef js_force_inline
1035
1036
int JS_JSStringToChar(const JSValue* _p, char* out); 
1037
1038
#ifdef __cplusplus
1039
} /* extern "C" { */
1040
#endif
1041
1042
#endif /* QUICKJS_H */