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