aboutsummaryrefslogtreecommitdiffstats
path: root/src/shared/quickjs/quickjs.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared/quickjs/quickjs.h')
-rw-r--r--src/shared/quickjs/quickjs.h1100
1 files changed, 603 insertions, 497 deletions
diff --git a/src/shared/quickjs/quickjs.h b/src/shared/quickjs/quickjs.h
index 3a22f5b7b..55215ee4f 100644
--- a/src/shared/quickjs/quickjs.h
+++ b/src/shared/quickjs/quickjs.h
@@ -1,8 +1,10 @@
/*
* QuickJS Javascript Engine
*
- * Copyright (c) 2017-2021 Fabrice Bellard
- * Copyright (c) 2017-2021 Charlie Gordon
+ * Copyright (c) 2017-2024 Fabrice Bellard
+ * Copyright (c) 2017-2024 Charlie Gordon
+ * Copyright (c) 2023-2025 Ben Noordhuis
+ * Copyright (c) 2023-2025 Saúl Ibarra Corretgé
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -25,26 +27,43 @@
#ifndef QUICKJS_H
#define QUICKJS_H
+#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
+#include <string.h>
+#include <math.h>
#ifdef __cplusplus
extern "C" {
#endif
+#define QUICKJS_NG 1
+
#if defined(__GNUC__) || defined(__clang__)
-#define js_likely(x) __builtin_expect(!!(x), 1)
-#define js_unlikely(x) __builtin_expect(!!(x), 0)
#define js_force_inline inline __attribute__((always_inline))
-#define __js_printf_like(f, a) __attribute__((format(printf, f, a)))
+#define JS_EXTERN __attribute__((visibility("default")))
#else
-#define js_likely(x) (x)
-#define js_unlikely(x) (x)
#define js_force_inline inline
-#define __js_printf_like(a, b)
+#define JS_EXTERN /* nothing */
#endif
-#define JS_BOOL int
+/* Borrowed from Folly */
+#ifndef JS_PRINTF_FORMAT
+#ifdef _MSC_VER
+#include <sal.h>
+#define JS_PRINTF_FORMAT _Printf_format_string_
+#define JS_PRINTF_FORMAT_ATTR(format_param, dots_param)
+#else
+#define JS_PRINTF_FORMAT
+#if !defined(__clang__) && defined(__GNUC__)
+#define JS_PRINTF_FORMAT_ATTR(format_param, dots_param) \
+ __attribute__((format(gnu_printf, format_param, dots_param)))
+#else
+#define JS_PRINTF_FORMAT_ATTR(format_param, dots_param) \
+ __attribute__((format(printf, format_param, dots_param)))
+#endif
+#endif
+#endif
typedef struct JSRuntime JSRuntime;
typedef struct JSContext JSContext;
@@ -53,23 +72,23 @@ typedef struct JSClass JSClass;
typedef uint32_t JSClassID;
typedef uint32_t JSAtom;
-#if INTPTR_MAX >= INT64_MAX
-#define JS_PTR64
-#define JS_PTR64_DEF(a) a
-#else
-#define JS_PTR64_DEF(a)
-#endif
+/* Unless documented otherwise, C string pointers (`char *` or `const char *`)
+ are assumed to verify these constraints:
+ - unless a length is passed separately, the string has a null terminator
+ - string contents is either pure ASCII or is UTF-8 encoded.
+ */
-#ifndef JS_PTR64
-#define JS_NAN_BOXING
+/* Overridable purely for testing purposes; don't touch. */
+#ifndef JS_NAN_BOXING
+#if INTPTR_MAX < INT64_MAX
+#define JS_NAN_BOXING 1 /* Use NAN boxing for 32bit builds. */
+#endif
#endif
enum {
/* all tags with a reference count are negative */
- JS_TAG_FIRST = -11, /* first negative tag */
- JS_TAG_BIG_DECIMAL = -11,
- JS_TAG_BIG_INT = -10,
- JS_TAG_BIG_FLOAT = -9,
+ JS_TAG_FIRST = -9, /* first negative tag */
+ JS_TAG_BIG_INT = -9,
JS_TAG_SYMBOL = -8,
JS_TAG_STRING = -7,
JS_TAG_MODULE = -3, /* used internally */
@@ -87,52 +106,12 @@ enum {
/* any larger tag is FLOAT64 if JS_NAN_BOXING */
};
-typedef struct JSRefCountHeader {
- int ref_count;
-} JSRefCountHeader;
-
-#define JS_FLOAT64_NAN NAN
+#define JSValueConst JSValue /* For backwards compatibility. */
-#ifdef CONFIG_CHECK_JSVALUE
-/* JSValue consistency : it is not possible to run the code in this
- mode, but it is useful to detect simple reference counting
- errors. It would be interesting to modify a static C analyzer to
- handle specific annotations (clang has such annotations but only
- for objective C) */
-typedef struct __JSValue *JSValue;
-typedef const struct __JSValue *JSValueConst;
-
-#define JS_VALUE_GET_TAG(v) (int)((uintptr_t)(v) & 0xf)
-/* same as JS_VALUE_GET_TAG, but return JS_TAG_FLOAT64 with NaN boxing */
-#define JS_VALUE_GET_NORM_TAG(v) JS_VALUE_GET_TAG(v)
-#define JS_VALUE_GET_INT(v) (int)((intptr_t)(v) >> 4)
-#define JS_VALUE_GET_BOOL(v) JS_VALUE_GET_INT(v)
-#define JS_VALUE_GET_FLOAT64(v) (double)JS_VALUE_GET_INT(v)
-#define JS_VALUE_GET_PTR(v) (void *)((intptr_t)(v) & ~0xf)
-
-#define JS_MKVAL(tag, val) (JSValue)(intptr_t)(((val) << 4) | (tag))
-#define JS_MKPTR(tag, p) (JSValue)((intptr_t)(p) | (tag))
-
-#define JS_TAG_IS_FLOAT64(tag) ((unsigned)(tag) == JS_TAG_FLOAT64)
-
-#define JS_NAN JS_MKVAL(JS_TAG_FLOAT64, 1)
-
-static inline JSValue __JS_NewFloat64(JSContext *ctx, double d)
-{
- return JS_MKVAL(JS_TAG_FLOAT64, (int)d);
-}
-
-static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
-{
- return 0;
-}
-
-#elif defined(JS_NAN_BOXING)
+#if defined(JS_NAN_BOXING) && JS_NAN_BOXING
typedef uint64_t JSValue;
-#define JSValueConst JSValue
-
#define JS_VALUE_GET_TAG(v) (int)((v) >> 32)
#define JS_VALUE_GET_INT(v) (int)(v)
#define JS_VALUE_GET_BOOL(v) (int)(v)
@@ -156,9 +135,8 @@ static inline double JS_VALUE_GET_FLOAT64(JSValue v)
#define JS_NAN (0x7ff8000000000000 - ((uint64_t)JS_FLOAT64_TAG_ADDEND << 32))
-static inline JSValue __JS_NewFloat64(JSContext *ctx, double d)
+static inline JSValue __JS_NewFloat64(double d)
{
- (void) ctx;
union {
double d;
uint64_t u64;
@@ -166,7 +144,7 @@ static inline JSValue __JS_NewFloat64(JSContext *ctx, double d)
JSValue v;
u.d = d;
/* normalize NaN */
- if (js_unlikely((u.u64 & 0x7fffffffffffffff) > 0x7ff0000000000000))
+ if ((u.u64 & 0x7fffffffffffffff) > 0x7ff0000000000000)
v = JS_NAN;
else
v = u.u64 - ((uint64_t)JS_FLOAT64_TAG_ADDEND << 32);
@@ -186,7 +164,7 @@ static inline int JS_VALUE_GET_NORM_TAG(JSValue v)
return tag;
}
-static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
+static inline bool JS_VALUE_IS_NAN(JSValue v)
{
uint32_t tag;
tag = JS_VALUE_GET_TAG(v);
@@ -206,8 +184,6 @@ typedef struct JSValue {
int64_t tag;
} JSValue;
-#define JSValueConst JSValue
-
#define JS_VALUE_GET_TAG(v) ((int32_t)(v).tag)
/* same as JS_VALUE_GET_TAG, but return JS_TAG_FLOAT64 with NaN boxing */
#define JS_VALUE_GET_NORM_TAG(v) JS_VALUE_GET_TAG(v)
@@ -216,26 +192,50 @@ typedef struct JSValue {
#define JS_VALUE_GET_FLOAT64(v) ((v).u.float64)
#define JS_VALUE_GET_PTR(v) ((v).u.ptr)
-JSValue mkVal(int32_t tag, int32_t val);
-JSValue mkPtr(int32_t tag, void *p);
-
-#define JS_MKVAL(tag, val) mkVal(tag, val)
-#define JS_MKPTR(tag, p) mkPtr(tag, p)
+/* msvc doesn't understand designated initializers without /std:c++20 */
+#ifdef __cplusplus
+static inline JSValue JS_MKPTR(int64_t tag, void *ptr)
+{
+ JSValue v;
+ v.u.ptr = ptr;
+ v.tag = tag;
+ return v;
+}
+static inline JSValue JS_MKVAL(int64_t tag, int32_t int32)
+{
+ JSValue v;
+ v.u.int32 = int32;
+ v.tag = tag;
+ return v;
+}
+static inline JSValue JS_MKNAN(void)
+{
+ JSValue v;
+ v.u.float64 = NAN;
+ v.tag = JS_TAG_FLOAT64;
+ return v;
+}
+/* provide as macros for consistency and backward compat reasons */
+#define JS_MKPTR(tag, ptr) JS_MKPTR(tag, ptr)
+#define JS_MKVAL(tag, val) JS_MKVAL(tag, val)
+#define JS_NAN JS_MKNAN() /* alas, not a constant expression */
+#else
+#define JS_MKPTR(tag, p) (JSValue){ (JSValueUnion){ .ptr = p }, tag }
+#define JS_MKVAL(tag, val) (JSValue){ (JSValueUnion){ .int32 = val }, tag }
+#define JS_NAN (JSValue){ (JSValueUnion){ .float64 = NAN }, JS_TAG_FLOAT64 }
+#endif
#define JS_TAG_IS_FLOAT64(tag) ((unsigned)(tag) == JS_TAG_FLOAT64)
-#define JS_NAN (JSValue){ .u.float64 = JS_FLOAT64_NAN, JS_TAG_FLOAT64 }
-
-static inline JSValue __JS_NewFloat64(JSContext *ctx, double d)
+static inline JSValue __JS_NewFloat64(double d)
{
- (void) ctx;
JSValue v;
v.tag = JS_TAG_FLOAT64;
v.u.float64 = d;
return v;
}
-static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
+static inline bool JS_VALUE_IS_NAN(JSValue v)
{
union {
double d;
@@ -253,7 +253,6 @@ static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
#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)))
#define JS_VALUE_GET_OBJ(v) ((JSObject *)JS_VALUE_GET_PTR(v))
-#define JS_VALUE_GET_STRING(v) ((JSString *)JS_VALUE_GET_PTR(v))
#define JS_VALUE_HAS_REF_COUNT(v) ((unsigned)JS_VALUE_GET_TAG(v) >= (unsigned)JS_TAG_FIRST)
/* special values */
@@ -294,8 +293,12 @@ static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
#define JS_PROP_NO_ADD (1 << 16) /* internal use */
#define JS_PROP_NO_EXOTIC (1 << 17) /* internal use */
+#define JS_PROP_DEFINE_PROPERTY (1 << 18) /* internal use */
+#define JS_PROP_REFLECT_DEFINE_PROPERTY (1 << 19) /* internal use */
-#define JS_DEFAULT_STACK_SIZE (256 * 1024)
+#ifndef JS_DEFAULT_STACK_SIZE
+#define JS_DEFAULT_STACK_SIZE (1024 * 1024)
+#endif
/* JS_Eval() flags */
#define JS_EVAL_TYPE_GLOBAL (0 << 0) /* global code (default) */
@@ -305,7 +308,7 @@ static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
#define JS_EVAL_TYPE_MASK (3 << 0)
#define JS_EVAL_FLAG_STRICT (1 << 3) /* force 'strict' mode */
-#define JS_EVAL_FLAG_STRIP (1 << 4) /* force 'strip' mode */
+#define JS_EVAL_FLAG_UNUSED (1 << 4) /* unused */
/* compile but do not run. The result is an object with a
JS_TAG_FUNCTION_BYTECODE or JS_TAG_MODULE tag. It can be executed
with JS_EvalFunction(). */
@@ -316,93 +319,127 @@ static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
promise. Only allowed with JS_EVAL_TYPE_GLOBAL */
#define JS_EVAL_FLAG_ASYNC (1 << 7)
-typedef JSValue JSCFunction(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);
-typedef JSValue JSCFunctionMagic(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic);
-typedef JSValue JSCFunctionData(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic, JSValue *func_data);
-
-typedef struct JSMallocState {
- size_t malloc_count;
- size_t malloc_size;
- size_t malloc_limit;
- void *opaque; /* user opaque */
-} JSMallocState;
+typedef JSValue JSCFunction(JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
+typedef JSValue JSCFunctionMagic(JSContext *ctx, JSValue this_val, int argc, JSValue *argv, int magic);
+typedef JSValue JSCFunctionData(JSContext *ctx, JSValue this_val, int argc, JSValue *argv, int magic, JSValue *func_data);
typedef struct JSMallocFunctions {
- void *(*js_malloc)(JSMallocState *s, size_t size);
- void (*js_free)(JSMallocState *s, void *ptr);
- void *(*js_realloc)(JSMallocState *s, void *ptr, size_t size);
+ void *(*js_calloc)(void *opaque, size_t count, size_t size);
+ void *(*js_malloc)(void *opaque, size_t size);
+ void (*js_free)(void *opaque, void *ptr);
+ void *(*js_realloc)(void *opaque, void *ptr, size_t size);
size_t (*js_malloc_usable_size)(const void *ptr);
} JSMallocFunctions;
+// Debug trace system: the debug output will be produced to the dump stream (currently
+// stdout) if dumps are enabled and JS_SetDumpFlags is invoked with the corresponding
+// bit set.
+#define JS_DUMP_BYTECODE_FINAL 0x01 /* dump pass 3 final byte code */
+#define JS_DUMP_BYTECODE_PASS2 0x02 /* dump pass 2 code */
+#define JS_DUMP_BYTECODE_PASS1 0x04 /* dump pass 1 code */
+#define JS_DUMP_BYTECODE_HEX 0x10 /* dump bytecode in hex */
+#define JS_DUMP_BYTECODE_PC2LINE 0x20 /* dump line number table */
+#define JS_DUMP_BYTECODE_STACK 0x40 /* dump compute_stack_size */
+#define JS_DUMP_BYTECODE_STEP 0x80 /* dump executed bytecode */
+#define JS_DUMP_READ_OBJECT 0x100 /* dump the marshalled objects at load time */
+#define JS_DUMP_FREE 0x200 /* dump every object free */
+#define JS_DUMP_GC 0x400 /* dump the occurrence of the automatic GC */
+#define JS_DUMP_GC_FREE 0x800 /* dump objects freed by the GC */
+#define JS_DUMP_MODULE_RESOLVE 0x1000 /* dump module resolution steps */
+#define JS_DUMP_PROMISE 0x2000 /* dump promise steps */
+#define JS_DUMP_LEAKS 0x4000 /* dump leaked objects and strings in JS_FreeRuntime */
+#define JS_DUMP_ATOM_LEAKS 0x8000 /* dump leaked atoms in JS_FreeRuntime */
+#define JS_DUMP_MEM 0x10000 /* dump memory usage in JS_FreeRuntime */
+#define JS_DUMP_OBJECTS 0x20000 /* dump objects in JS_FreeRuntime */
+#define JS_DUMP_ATOMS 0x40000 /* dump atoms in JS_FreeRuntime */
+#define JS_DUMP_SHAPES 0x80000 /* dump shapes in JS_FreeRuntime */
+
+// Finalizers run in LIFO order at the very end of JS_FreeRuntime.
+// Intended for cleanup of associated resources; the runtime itself
+// is no longer usable.
+typedef void JSRuntimeFinalizer(JSRuntime *rt, void *arg);
+
typedef struct JSGCObjectHeader JSGCObjectHeader;
-JSRuntime *JS_NewRuntime(void);
+JS_EXTERN JSRuntime *JS_NewRuntime(void);
/* info lifetime must exceed that of rt */
-void JS_SetRuntimeInfo(JSRuntime *rt, const char *info);
-void JS_SetMemoryLimit(JSRuntime *rt, size_t limit);
-void JS_SetGCThreshold(JSRuntime *rt, size_t gc_threshold);
+JS_EXTERN void JS_SetRuntimeInfo(JSRuntime *rt, const char *info);
+/* use 0 to disable memory limit */
+JS_EXTERN void JS_SetMemoryLimit(JSRuntime *rt, size_t limit);
+JS_EXTERN void JS_SetDumpFlags(JSRuntime *rt, uint64_t flags);
+JS_EXTERN uint64_t JS_GetDumpFlags(JSRuntime *rt);
+JS_EXTERN size_t JS_GetGCThreshold(JSRuntime *rt);
+JS_EXTERN void JS_SetGCThreshold(JSRuntime *rt, size_t gc_threshold);
/* use 0 to disable maximum stack size check */
-void JS_SetMaxStackSize(JSRuntime *rt, size_t stack_size);
+JS_EXTERN void JS_SetMaxStackSize(JSRuntime *rt, size_t stack_size);
/* should be called when changing thread to update the stack top value
used to check stack overflow. */
-void JS_UpdateStackTop(JSRuntime *rt);
-JSRuntime *JS_NewRuntime2(const JSMallocFunctions *mf, void *opaque);
-void JS_FreeRuntime(JSRuntime *rt);
-void *JS_GetRuntimeOpaque(JSRuntime *rt);
-void JS_SetRuntimeOpaque(JSRuntime *rt, void *opaque);
+JS_EXTERN void JS_UpdateStackTop(JSRuntime *rt);
+JS_EXTERN JSRuntime *JS_NewRuntime2(const JSMallocFunctions *mf, void *opaque);
+JS_EXTERN void JS_FreeRuntime(JSRuntime *rt);
+JS_EXTERN void *JS_GetRuntimeOpaque(JSRuntime *rt);
+JS_EXTERN void JS_SetRuntimeOpaque(JSRuntime *rt, void *opaque);
+JS_EXTERN int JS_AddRuntimeFinalizer(JSRuntime *rt,
+ JSRuntimeFinalizer *finalizer, void *arg);
typedef void JS_MarkFunc(JSRuntime *rt, JSGCObjectHeader *gp);
-void JS_MarkValue(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func);
-void JS_RunGC(JSRuntime *rt);
-JS_BOOL JS_IsLiveObject(JSRuntime *rt, JSValueConst obj);
-
-JSContext *JS_NewContext(JSRuntime *rt);
-void JS_FreeContext(JSContext *s);
-JSContext *JS_DupContext(JSContext *ctx);
-void *JS_GetContextOpaque(JSContext *ctx);
-void JS_SetContextOpaque(JSContext *ctx, void *opaque);
-JSRuntime *JS_GetRuntime(JSContext *ctx);
-void JS_SetClassProto(JSContext *ctx, JSClassID class_id, JSValue obj);
-JSValue JS_GetClassProto(JSContext *ctx, JSClassID class_id);
+JS_EXTERN void JS_MarkValue(JSRuntime *rt, JSValue val, JS_MarkFunc *mark_func);
+JS_EXTERN void JS_RunGC(JSRuntime *rt);
+JS_EXTERN bool JS_IsLiveObject(JSRuntime *rt, JSValue obj);
+
+JS_EXTERN JSContext *JS_NewContext(JSRuntime *rt);
+JS_EXTERN void JS_FreeContext(JSContext *s);
+JS_EXTERN JSContext *JS_DupContext(JSContext *ctx);
+JS_EXTERN void *JS_GetContextOpaque(JSContext *ctx);
+JS_EXTERN void JS_SetContextOpaque(JSContext *ctx, void *opaque);
+JS_EXTERN JSRuntime *JS_GetRuntime(JSContext *ctx);
+JS_EXTERN void JS_SetClassProto(JSContext *ctx, JSClassID class_id, JSValue obj);
+JS_EXTERN JSValue JS_GetClassProto(JSContext *ctx, JSClassID class_id);
+JS_EXTERN JSValue JS_GetFunctionProto(JSContext *ctx);
/* the following functions are used to select the intrinsic object to
save memory */
-JSContext *JS_NewContextRaw(JSRuntime *rt);
-void JS_AddIntrinsicBaseObjects(JSContext *ctx);
-void JS_AddIntrinsicDate(JSContext *ctx);
-void JS_AddIntrinsicEval(JSContext *ctx);
-void JS_AddIntrinsicStringNormalize(JSContext *ctx);
-void JS_AddIntrinsicRegExpCompiler(JSContext *ctx);
-void JS_AddIntrinsicRegExp(JSContext *ctx);
-void JS_AddIntrinsicJSON(JSContext *ctx);
-void JS_AddIntrinsicProxy(JSContext *ctx);
-void JS_AddIntrinsicMapSet(JSContext *ctx);
-void JS_AddIntrinsicTypedArrays(JSContext *ctx);
-void JS_AddIntrinsicPromise(JSContext *ctx);
-void JS_AddIntrinsicBigInt(JSContext *ctx);
-void JS_AddIntrinsicBigFloat(JSContext *ctx);
-void JS_AddIntrinsicBigDecimal(JSContext *ctx);
-/* enable operator overloading */
-void JS_AddIntrinsicOperators(JSContext *ctx);
-/* enable "use math" */
-void JS_EnableBignumExt(JSContext *ctx, JS_BOOL enable);
-
-JSValue js_string_codePointRange(JSContext *ctx, JSValueConst this_val,
- int argc, JSValueConst *argv);
-
-void *js_malloc_rt(JSRuntime *rt, size_t size);
-void js_free_rt(JSRuntime *rt, void *ptr);
-void *js_realloc_rt(JSRuntime *rt, void *ptr, size_t size);
-size_t js_malloc_usable_size_rt(JSRuntime *rt, const void *ptr);
-void *js_mallocz_rt(JSRuntime *rt, size_t size);
-
-void *js_malloc(JSContext *ctx, size_t size);
-void js_free(JSContext *ctx, void *ptr);
-void *js_realloc(JSContext *ctx, void *ptr, size_t size);
-size_t js_malloc_usable_size(JSContext *ctx, const void *ptr);
-void *js_realloc2(JSContext *ctx, void *ptr, size_t size, size_t *pslack);
-void *js_mallocz(JSContext *ctx, size_t size);
-char *js_strdup(JSContext *ctx, const char *str);
-char *js_strndup(JSContext *ctx, const char *s, size_t n);
+JS_EXTERN JSContext *JS_NewContextRaw(JSRuntime *rt);
+JS_EXTERN void JS_AddIntrinsicBaseObjects(JSContext *ctx);
+JS_EXTERN void JS_AddIntrinsicDate(JSContext *ctx);
+JS_EXTERN void JS_AddIntrinsicEval(JSContext *ctx);
+JS_EXTERN void JS_AddIntrinsicRegExpCompiler(JSContext *ctx);
+JS_EXTERN void JS_AddIntrinsicRegExp(JSContext *ctx);
+JS_EXTERN void JS_AddIntrinsicJSON(JSContext *ctx);
+JS_EXTERN void JS_AddIntrinsicProxy(JSContext *ctx);
+JS_EXTERN void JS_AddIntrinsicMapSet(JSContext *ctx);
+JS_EXTERN void JS_AddIntrinsicTypedArrays(JSContext *ctx);
+JS_EXTERN void JS_AddIntrinsicPromise(JSContext *ctx);
+JS_EXTERN void JS_AddIntrinsicBigInt(JSContext *ctx);
+JS_EXTERN void JS_AddIntrinsicWeakRef(JSContext *ctx);
+JS_EXTERN void JS_AddPerformance(JSContext *ctx);
+
+/* for equality comparisons and sameness */
+JS_EXTERN int JS_IsEqual(JSContext *ctx, JSValue op1, JSValue op2);
+JS_EXTERN bool JS_IsStrictEqual(JSContext *ctx, JSValue op1, JSValue op2);
+JS_EXTERN bool JS_IsSameValue(JSContext *ctx, JSValue op1, JSValue op2);
+/* Similar to same-value equality, but +0 and -0 are considered equal. */
+JS_EXTERN bool JS_IsSameValueZero(JSContext *ctx, JSValue op1, JSValue op2);
+
+/* Only used for running 262 tests. TODO(saghul) add build time flag. */
+JS_EXTERN JSValue js_string_codePointRange(JSContext *ctx, JSValue this_val,
+ int argc, JSValue *argv);
+
+JS_EXTERN void *js_calloc_rt(JSRuntime *rt, size_t count, size_t size);
+JS_EXTERN void *js_malloc_rt(JSRuntime *rt, size_t size);
+JS_EXTERN void js_free_rt(JSRuntime *rt, void *ptr);
+JS_EXTERN void *js_realloc_rt(JSRuntime *rt, void *ptr, size_t size);
+JS_EXTERN size_t js_malloc_usable_size_rt(JSRuntime *rt, const void *ptr);
+JS_EXTERN void *js_mallocz_rt(JSRuntime *rt, size_t size);
+
+JS_EXTERN void *js_calloc(JSContext *ctx, size_t count, size_t size);
+JS_EXTERN void *js_malloc(JSContext *ctx, size_t size);
+JS_EXTERN void js_free(JSContext *ctx, void *ptr);
+JS_EXTERN void *js_realloc(JSContext *ctx, void *ptr, size_t size);
+JS_EXTERN size_t js_malloc_usable_size(JSContext *ctx, const void *ptr);
+JS_EXTERN void *js_realloc2(JSContext *ctx, void *ptr, size_t size, size_t *pslack);
+JS_EXTERN void *js_mallocz(JSContext *ctx, size_t size);
+JS_EXTERN char *js_strdup(JSContext *ctx, const char *str);
+JS_EXTERN char *js_strndup(JSContext *ctx, const char *s, size_t n);
typedef struct JSMemoryUsage {
int64_t malloc_size, malloc_limit, memory_used_size;
@@ -420,27 +457,27 @@ typedef struct JSMemoryUsage {
int64_t binary_object_count, binary_object_size;
} JSMemoryUsage;
-void JS_ComputeMemoryUsage(JSRuntime *rt, JSMemoryUsage *s);
-void JS_DumpMemoryUsage(FILE *fp, const JSMemoryUsage *s, JSRuntime *rt);
+JS_EXTERN void JS_ComputeMemoryUsage(JSRuntime *rt, JSMemoryUsage *s);
+JS_EXTERN void JS_DumpMemoryUsage(FILE *fp, const JSMemoryUsage *s, JSRuntime *rt);
/* atom support */
#define JS_ATOM_NULL 0
-JSAtom JS_NewAtomLen(JSContext *ctx, const char *str, size_t len);
-JSAtom JS_NewAtom(JSContext *ctx, const char *str);
-JSAtom JS_NewAtomUInt32(JSContext *ctx, uint32_t n);
-JSAtom JS_DupAtom(JSContext *ctx, JSAtom v);
-void JS_FreeAtom(JSContext *ctx, JSAtom v);
-void JS_FreeAtomRT(JSRuntime *rt, JSAtom v);
-JSValue JS_AtomToValue(JSContext *ctx, JSAtom atom);
-JSValue JS_AtomToString(JSContext *ctx, JSAtom atom);
-const char *JS_AtomToCString(JSContext *ctx, JSAtom atom);
-JSAtom JS_ValueToAtom(JSContext *ctx, JSValueConst val);
+JS_EXTERN JSAtom JS_NewAtomLen(JSContext *ctx, const char *str, size_t len);
+JS_EXTERN JSAtom JS_NewAtom(JSContext *ctx, const char *str);
+JS_EXTERN JSAtom JS_NewAtomUInt32(JSContext *ctx, uint32_t n);
+JS_EXTERN JSAtom JS_DupAtom(JSContext *ctx, JSAtom v);
+JS_EXTERN void JS_FreeAtom(JSContext *ctx, JSAtom v);
+JS_EXTERN void JS_FreeAtomRT(JSRuntime *rt, JSAtom v);
+JS_EXTERN JSValue JS_AtomToValue(JSContext *ctx, JSAtom atom);
+JS_EXTERN JSValue JS_AtomToString(JSContext *ctx, JSAtom atom);
+JS_EXTERN const char *JS_AtomToCString(JSContext *ctx, JSAtom atom);
+JS_EXTERN JSAtom JS_ValueToAtom(JSContext *ctx, JSValue val);
/* object class support */
typedef struct JSPropertyEnum {
- JS_BOOL is_enumerable;
+ bool is_enumerable;
JSAtom atom;
} JSPropertyEnum;
@@ -453,44 +490,44 @@ typedef struct JSPropertyDescriptor {
typedef struct JSClassExoticMethods {
/* Return -1 if exception (can only happen in case of Proxy object),
- FALSE if the property does not exists, TRUE if it exists. If 1 is
+ false if the property does not exists, true if it exists. If 1 is
returned, the property descriptor 'desc' is filled if != NULL. */
int (*get_own_property)(JSContext *ctx, JSPropertyDescriptor *desc,
- JSValueConst obj, JSAtom prop);
+ JSValue obj, JSAtom prop);
/* '*ptab' should hold the '*plen' property keys. Return 0 if OK,
-1 if exception. The 'is_enumerable' field is ignored.
*/
int (*get_own_property_names)(JSContext *ctx, JSPropertyEnum **ptab,
uint32_t *plen,
- JSValueConst obj);
- /* return < 0 if exception, or TRUE/FALSE */
- int (*delete_property)(JSContext *ctx, JSValueConst obj, JSAtom prop);
- /* return < 0 if exception or TRUE/FALSE */
- int (*define_own_property)(JSContext *ctx, JSValueConst this_obj,
- JSAtom prop, JSValueConst val,
- JSValueConst getter, JSValueConst setter,
+ JSValue obj);
+ /* return < 0 if exception, or true/false */
+ int (*delete_property)(JSContext *ctx, JSValue obj, JSAtom prop);
+ /* return < 0 if exception or true/false */
+ int (*define_own_property)(JSContext *ctx, JSValue this_obj,
+ JSAtom prop, JSValue val,
+ JSValue getter, JSValue setter,
int flags);
/* The following methods can be emulated with the previous ones,
so they are usually not needed */
- /* return < 0 if exception or TRUE/FALSE */
- int (*has_property)(JSContext *ctx, JSValueConst obj, JSAtom atom);
- JSValue (*get_property)(JSContext *ctx, JSValueConst obj, JSAtom atom,
- JSValueConst receiver);
- /* return < 0 if exception or TRUE/FALSE */
- int (*set_property)(JSContext *ctx, JSValueConst obj, JSAtom atom,
- JSValueConst value, JSValueConst receiver, int flags);
+ /* return < 0 if exception or true/false */
+ int (*has_property)(JSContext *ctx, JSValue obj, JSAtom atom);
+ JSValue (*get_property)(JSContext *ctx, JSValue obj, JSAtom atom,
+ JSValue receiver);
+ /* return < 0 if exception or true/false */
+ int (*set_property)(JSContext *ctx, JSValue obj, JSAtom atom,
+ JSValue value, JSValue receiver, int flags);
} JSClassExoticMethods;
typedef void JSClassFinalizer(JSRuntime *rt, JSValue val);
-typedef void JSClassGCMark(JSRuntime *rt, JSValueConst val,
+typedef void JSClassGCMark(JSRuntime *rt, JSValue val,
JS_MarkFunc *mark_func);
#define JS_CALL_FLAG_CONSTRUCTOR (1 << 0)
-typedef JSValue JSClassCall(JSContext *ctx, JSValueConst func_obj,
- JSValueConst this_val, int argc, JSValueConst *argv,
+typedef JSValue JSClassCall(JSContext *ctx, JSValue func_obj,
+ JSValue this_val, int argc, JSValue *argv,
int flags);
typedef struct JSClassDef {
- const char *class_name;
+ const char *class_name; /* pure ASCII only! */
JSClassFinalizer *finalizer;
JSClassGCMark *gc_mark;
/* if call != NULL, the object is a function. If (flags &
@@ -504,224 +541,246 @@ typedef struct JSClassDef {
JSClassExoticMethods *exotic;
} JSClassDef;
+#define JS_EVAL_OPTIONS_VERSION 1
+
+typedef struct JSEvalOptions {
+ int version;
+ int eval_flags;
+ const char *filename;
+ int line_num;
+ // can add new fields in ABI-compatible manner by incrementing JS_EVAL_OPTIONS_VERSION
+} JSEvalOptions;
+
#define JS_INVALID_CLASS_ID 0
-JSClassID JS_NewClassID(JSClassID *pclass_id);
+JS_EXTERN JSClassID JS_NewClassID(JSRuntime *rt, JSClassID *pclass_id);
/* Returns the class ID if `v` is an object, otherwise returns JS_INVALID_CLASS_ID. */
-JSClassID JS_GetClassID(JSValue v);
-int JS_NewClass(JSRuntime *rt, JSClassID class_id, const JSClassDef *class_def);
-int JS_IsRegisteredClass(JSRuntime *rt, JSClassID class_id);
+JS_EXTERN JSClassID JS_GetClassID(JSValue v);
+JS_EXTERN int JS_NewClass(JSRuntime *rt, JSClassID class_id, const JSClassDef *class_def);
+JS_EXTERN bool JS_IsRegisteredClass(JSRuntime *rt, JSClassID class_id);
/* value handling */
-JSValue JS_NewBool(JSContext *ctx, JS_BOOL val);
-JSValue JS_NewInt32(JSContext *ctx, int32_t val);
-JSValue JS_NewCatchOffset(JSContext *ctx, int32_t val);
-JSValue JS_NewInt64(JSContext *ctx, int64_t val);
-JSValue JS_NewUint32(JSContext *ctx, uint32_t val);
-JSValue JS_NewBigInt64(JSContext *ctx, int64_t v);
-JSValue JS_NewBigUint64(JSContext *ctx, uint64_t v);
+static js_force_inline JSValue JS_NewBool(JSContext *ctx, bool val)
+{
+ (void)&ctx;
+ return JS_MKVAL(JS_TAG_BOOL, (val != 0));
+}
-JSValue JS_NewFloat64(JSContext *ctx, double d);
+static js_force_inline JSValue JS_NewInt32(JSContext *ctx, int32_t val)
+{
+ (void)&ctx;
+ return JS_MKVAL(JS_TAG_INT, val);
+}
-static inline JS_BOOL JS_IsNumber(JSValueConst v)
+static js_force_inline JSValue JS_NewFloat64(JSContext *ctx, double val)
{
- int tag = JS_VALUE_GET_TAG(v);
- return tag == JS_TAG_INT || JS_TAG_IS_FLOAT64(tag);
+ (void)&ctx;
+ return __JS_NewFloat64(val);
}
-static inline JS_BOOL JS_IsBigInt(JSContext *ctx, JSValueConst v)
+static js_force_inline JSValue JS_NewCatchOffset(JSContext *ctx, int32_t val)
{
- (void) ctx;
- int tag = JS_VALUE_GET_TAG(v);
- return tag == JS_TAG_BIG_INT;
+ (void)&ctx;
+ return JS_MKVAL(JS_TAG_CATCH_OFFSET, val);
}
-static inline JS_BOOL JS_IsBigFloat(JSValueConst v)
+static js_force_inline JSValue JS_NewInt64(JSContext *ctx, int64_t val)
{
- int tag = JS_VALUE_GET_TAG(v);
- return tag == JS_TAG_BIG_FLOAT;
+ JSValue v;
+ if (val >= INT32_MIN && val <= INT32_MAX) {
+ v = JS_NewInt32(ctx, (int32_t)val);
+ } else {
+ v = JS_NewFloat64(ctx, (double)val);
+ }
+ return v;
}
-static inline JS_BOOL JS_IsBigDecimal(JSValueConst v)
+static js_force_inline JSValue JS_NewUint32(JSContext *ctx, uint32_t val)
+{
+ JSValue v;
+ if (val <= INT32_MAX) {
+ v = JS_NewInt32(ctx, (int32_t)val);
+ } else {
+ v = JS_NewFloat64(ctx, (double)val);
+ }
+ return v;
+}
+
+JS_EXTERN JSValue JS_NewNumber(JSContext *ctx, double d);
+JS_EXTERN JSValue JS_NewBigInt64(JSContext *ctx, int64_t v);
+JS_EXTERN JSValue JS_NewBigUint64(JSContext *ctx, uint64_t v);
+
+static inline bool JS_IsNumber(JSValue v)
{
int tag = JS_VALUE_GET_TAG(v);
- return tag == JS_TAG_BIG_DECIMAL;
+ return tag == JS_TAG_INT || JS_TAG_IS_FLOAT64(tag);
+}
+
+static inline bool JS_IsBigInt(JSContext *ctx, JSValue v)
+{
+ (void)&ctx;
+ return JS_VALUE_GET_TAG(v) == JS_TAG_BIG_INT;
}
-static inline JS_BOOL JS_IsBool(JSValueConst v)
+static inline bool JS_IsBool(JSValue v)
{
return JS_VALUE_GET_TAG(v) == JS_TAG_BOOL;
}
-static inline JS_BOOL JS_IsNull(JSValueConst v)
+static inline bool JS_IsNull(JSValue v)
{
return JS_VALUE_GET_TAG(v) == JS_TAG_NULL;
}
-static inline JS_BOOL JS_IsUndefined(JSValueConst v)
+static inline bool JS_IsUndefined(JSValue v)
{
return JS_VALUE_GET_TAG(v) == JS_TAG_UNDEFINED;
}
-static inline JS_BOOL JS_IsException(JSValueConst v)
+static inline bool JS_IsException(JSValue v)
{
- return js_unlikely(JS_VALUE_GET_TAG(v) == JS_TAG_EXCEPTION);
+ return JS_VALUE_GET_TAG(v) == JS_TAG_EXCEPTION;
}
-static inline JS_BOOL JS_IsUninitialized(JSValueConst v)
+static inline bool JS_IsUninitialized(JSValue v)
{
- return js_unlikely(JS_VALUE_GET_TAG(v) == JS_TAG_UNINITIALIZED);
+ return JS_VALUE_GET_TAG(v) == JS_TAG_UNINITIALIZED;
}
-static inline JS_BOOL JS_IsString(JSValueConst v)
+static inline bool JS_IsString(JSValue v)
{
return JS_VALUE_GET_TAG(v) == JS_TAG_STRING;
}
-static inline JS_BOOL JS_IsSymbol(JSValueConst v)
+static inline bool JS_IsSymbol(JSValue v)
{
return JS_VALUE_GET_TAG(v) == JS_TAG_SYMBOL;
}
-static inline JS_BOOL JS_IsObject(JSValueConst v)
+static inline bool JS_IsObject(JSValue v)
{
return JS_VALUE_GET_TAG(v) == JS_TAG_OBJECT;
}
-JSValue JS_Throw(JSContext *ctx, JSValue obj);
-JSValue JS_GetException(JSContext *ctx);
-JS_BOOL JS_HasException(JSContext *ctx);
-JS_BOOL JS_IsError(JSContext *ctx, JSValueConst val);
-void JS_SetUncatchableError(JSContext *ctx, JSValueConst val, JS_BOOL flag);
-void JS_ResetUncatchableError(JSContext *ctx);
-JSValue JS_NewError(JSContext *ctx);
-JSValue __js_printf_like(2, 3) JS_ThrowSyntaxError(JSContext *ctx, const char *fmt, ...);
-JSValue __js_printf_like(2, 3) JS_ThrowTypeError(JSContext *ctx, const char *fmt, ...);
-JSValue __js_printf_like(2, 3) JS_ThrowReferenceError(JSContext *ctx, const char *fmt, ...);
-JSValue __js_printf_like(2, 3) JS_ThrowRangeError(JSContext *ctx, const char *fmt, ...);
-JSValue __js_printf_like(2, 3) JS_ThrowInternalError(JSContext *ctx, const char *fmt, ...);
-JSValue JS_ThrowOutOfMemory(JSContext *ctx);
-
-#ifndef NDEBUG
-void notifyRefCountIncrease(JSRefCountHeader *p);
-void notifyRefCountDecrease(JSRefCountHeader *p);
-#endif
-
-void JS_FreeValue(JSContext *ctx, JSValue v);
-void JS_FreeValueRT(JSRuntime *rt, JSValue v);
-
-static inline JSValue JS_DupValue(JSContext *ctx, JSValueConst v)
+JS_EXTERN JSValue JS_Throw(JSContext *ctx, JSValue obj);
+JS_EXTERN JSValue JS_GetException(JSContext *ctx);
+JS_EXTERN bool JS_HasException(JSContext *ctx);
+JS_EXTERN JSValue JS_GetBacktrace(JSContext *ctx);
+JS_EXTERN bool JS_IsError(JSContext *ctx, JSValue val);
+JS_EXTERN bool JS_IsUncatchableError(JSContext* ctx, JSValue val);
+JS_EXTERN void JS_SetUncatchableError(JSContext *ctx, JSValue val);
+JS_EXTERN void JS_ClearUncatchableError(JSContext *ctx, JSValue val);
+// Shorthand for:
+// JSValue exc = JS_GetException(ctx);
+// JS_ClearUncatchableError(ctx, exc);
+// JS_Throw(ctx, exc);
+JS_EXTERN void JS_ResetUncatchableError(JSContext *ctx);
+JS_EXTERN JSValue JS_NewError(JSContext *ctx);
+JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowPlainError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
+JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowSyntaxError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
+JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowTypeError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
+JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowReferenceError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
+JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowRangeError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
+JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowInternalError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
+JS_EXTERN JSValue JS_ThrowOutOfMemory(JSContext *ctx);
+JS_EXTERN void JS_FreeValue(JSContext *ctx, JSValue v);
+JS_EXTERN void JS_FreeValueRT(JSRuntime *rt, JSValue v);
+JS_EXTERN JSValue JS_DupValue(JSContext *ctx, JSValue v);
+JS_EXTERN JSValue JS_DupValueRT(JSRuntime *rt, JSValue v);
+JS_EXTERN int JS_ToBool(JSContext *ctx, JSValue val); /* return -1 for JS_EXCEPTION */
+static inline JSValue JS_ToBoolean(JSContext *ctx, JSValue val)
{
- (void) ctx;
- if (JS_VALUE_HAS_REF_COUNT(v)) {
- JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v);
-#ifndef NDEBUG
- notifyRefCountIncrease(p);
-#endif
- p->ref_count++;
- }
- return v;
+ return JS_NewBool(ctx, JS_ToBool(ctx, val));
}
-
-static inline JSValue JS_DupValueRT(JSRuntime *rt, JSValueConst v)
-{
- (void) rt;
- if (JS_VALUE_HAS_REF_COUNT(v)) {
- JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v);
-#ifndef NDEBUG
- notifyRefCountIncrease(p);
-#endif
- p->ref_count++;
- }
- return v;
-}
-
-JS_BOOL JS_StrictEq(JSContext *ctx, JSValueConst op1, JSValueConst op2);
-JS_BOOL JS_SameValue(JSContext *ctx, JSValueConst op1, JSValueConst op2);
-JS_BOOL JS_SameValueZero(JSContext *ctx, JSValueConst op1, JSValueConst op2);
-
-int JS_ToBool(JSContext *ctx, JSValueConst val); /* return -1 for JS_EXCEPTION */
-int JS_ToInt32(JSContext *ctx, int32_t *pres, JSValueConst val);
-static inline int JS_ToUint32(JSContext *ctx, uint32_t *pres, JSValueConst val)
+JS_EXTERN JSValue JS_ToNumber(JSContext *ctx, JSValue val);
+JS_EXTERN int JS_ToInt32(JSContext *ctx, int32_t *pres, JSValue val);
+static inline int JS_ToUint32(JSContext *ctx, uint32_t *pres, JSValue val)
{
return JS_ToInt32(ctx, (int32_t*)pres, val);
}
-int JS_ToInt64(JSContext *ctx, int64_t *pres, JSValueConst val);
-int JS_ToIndex(JSContext *ctx, uint64_t *plen, JSValueConst val);
-int JS_ToFloat64(JSContext *ctx, double *pres, JSValueConst val);
+JS_EXTERN int JS_ToInt64(JSContext *ctx, int64_t *pres, JSValue val);
+JS_EXTERN int JS_ToIndex(JSContext *ctx, uint64_t *plen, JSValue val);
+JS_EXTERN int JS_ToFloat64(JSContext *ctx, double *pres, JSValue val);
/* return an exception if 'val' is a Number */
-int JS_ToBigInt64(JSContext *ctx, int64_t *pres, JSValueConst val);
+JS_EXTERN int JS_ToBigInt64(JSContext *ctx, int64_t *pres, JSValue val);
+JS_EXTERN int JS_ToBigUint64(JSContext *ctx, uint64_t *pres, JSValue val);
/* same as JS_ToInt64() but allow BigInt */
-int JS_ToInt64Ext(JSContext *ctx, int64_t *pres, JSValueConst val);
-
-JSValue JS_NewStringLen(JSContext *ctx, const char *str1, size_t len1);
-JSValue JS_NewString(JSContext *ctx, const char *str);
-JSValue JS_NewAtomString(JSContext *ctx, const char *str);
-JSValue JS_ToString(JSContext *ctx, JSValueConst val);
-JSValue JS_ToPropertyKey(JSContext *ctx, JSValueConst val);
-const char *JS_ToCStringLen2(JSContext *ctx, size_t *plen, JSValueConst val1, JS_BOOL cesu8);
-static inline const char *JS_ToCStringLen(JSContext *ctx, size_t *plen, JSValueConst val1)
+JS_EXTERN int JS_ToInt64Ext(JSContext *ctx, int64_t *pres, JSValue val);
+
+JS_EXTERN JSValue JS_NewStringLen(JSContext *ctx, const char *str1, size_t len1);
+static inline JSValue JS_NewString(JSContext *ctx, const char *str) {
+ return JS_NewStringLen(ctx, str, strlen(str));
+}
+JS_EXTERN JSValue JS_NewAtomString(JSContext *ctx, const char *str);
+JS_EXTERN JSValue JS_ToString(JSContext *ctx, JSValue val);
+JS_EXTERN JSValue JS_ToPropertyKey(JSContext *ctx, JSValue val);
+JS_EXTERN const char *JS_ToCStringLen2(JSContext *ctx, size_t *plen, JSValue val1, bool cesu8);
+static inline const char *JS_ToCStringLen(JSContext *ctx, size_t *plen, JSValue val1)
{
return JS_ToCStringLen2(ctx, plen, val1, 0);
}
-static inline const char *JS_ToCString(JSContext *ctx, JSValueConst val1)
+static inline const char *JS_ToCString(JSContext *ctx, JSValue val1)
{
return JS_ToCStringLen2(ctx, NULL, val1, 0);
}
-void JS_FreeCString(JSContext *ctx, const char *ptr);
-
-JSValue JS_NewObjectProtoClass(JSContext *ctx, JSValueConst proto, JSClassID class_id);
-JSValue JS_NewObjectClass(JSContext *ctx, int class_id);
-JSValue JS_NewObjectProto(JSContext *ctx, JSValueConst proto);
-JSValue JS_NewObject(JSContext *ctx);
-
-JS_BOOL JS_IsFunction(JSContext* ctx, JSValueConst val);
-JS_BOOL JS_IsRegExp(JSContext* ctx, JSValueConst val);
-JS_BOOL JS_IsConstructor(JSContext* ctx, JSValueConst val);
-JS_BOOL JS_SetConstructorBit(JSContext *ctx, JSValueConst func_obj, JS_BOOL val);
-JS_BOOL JS_IsArrayBuffer(JSValueConst v);
-
-JSValue JS_NewArray(JSContext *ctx);
-int JS_IsArray(JSContext *ctx, JSValueConst val);
-
-JSValue JS_NewDate(JSContext *ctx, double epoch_ms);
-JS_BOOL JS_IsDate(JSValueConst v);
-
-JSValue JS_GetPropertyInternal(JSContext *ctx, JSValueConst obj,
- JSAtom prop, JSValueConst receiver,
- JS_BOOL throw_ref_error);
-static js_force_inline JSValue JS_GetProperty(JSContext *ctx, JSValueConst this_obj,
- JSAtom prop)
-{
- return JS_GetPropertyInternal(ctx, this_obj, prop, this_obj, 0);
-}
-JSValue JS_GetPropertyStr(JSContext *ctx, JSValueConst this_obj,
- const char *prop);
-JSValue JS_GetPropertyUint32(JSContext *ctx, JSValueConst this_obj,
- uint32_t idx);
-
-int JS_SetPropertyInternal(JSContext *ctx, JSValueConst obj,
- JSAtom prop, JSValue val, JSValueConst this_obj,
- int flags);
-static inline int JS_SetProperty(JSContext *ctx, JSValueConst this_obj,
- JSAtom prop, JSValue val)
-{
- return JS_SetPropertyInternal(ctx, this_obj, prop, val, this_obj, JS_PROP_THROW);
-}
-int JS_SetPropertyUint32(JSContext *ctx, JSValueConst this_obj,
- uint32_t idx, JSValue val);
-int JS_SetPropertyInt64(JSContext *ctx, JSValueConst this_obj,
- int64_t idx, JSValue val);
-int JS_SetPropertyStr(JSContext *ctx, JSValueConst this_obj,
- const char *prop, JSValue val);
-int JS_HasProperty(JSContext *ctx, JSValueConst this_obj, JSAtom prop);
-int JS_IsExtensible(JSContext *ctx, JSValueConst obj);
-int JS_PreventExtensions(JSContext *ctx, JSValueConst obj);
-int JS_DeleteProperty(JSContext *ctx, JSValueConst obj, JSAtom prop, int flags);
-int JS_SetPrototype(JSContext *ctx, JSValueConst obj, JSValueConst proto_val);
-JSValue JS_GetPrototype(JSContext *ctx, JSValueConst val);
-
-JSValue JS_ObjectSeal(JSContext *ctx, JSValueConst obj, int freeze);
+JS_EXTERN void JS_FreeCString(JSContext *ctx, const char *ptr);
+
+JS_EXTERN JSValue JS_NewObjectProtoClass(JSContext *ctx, JSValue proto, JSClassID class_id);
+JS_EXTERN JSValue JS_NewObjectClass(JSContext *ctx, int class_id);
+JS_EXTERN JSValue JS_NewObjectProto(JSContext *ctx, JSValue proto);
+JS_EXTERN JSValue JS_NewObject(JSContext *ctx);
+JS_EXTERN JSValue JS_NewObjectFrom(JSContext *ctx, int count,
+ const JSAtom *props,
+ const JSValue *values);
+JS_EXTERN JSValue JS_NewObjectFromStr(JSContext *ctx, int count,
+ const char **props,
+ const JSValue *values);
+JS_EXTERN JSValue JS_ToObject(JSContext *ctx, JSValue val);
+JS_EXTERN JSValue JS_ToObjectString(JSContext *ctx, JSValue val);
+
+JS_EXTERN bool JS_IsFunction(JSContext* ctx, JSValue val);
+JS_EXTERN bool JS_IsConstructor(JSContext* ctx, JSValue val);
+JS_EXTERN bool JS_SetConstructorBit(JSContext *ctx, JSValue func_obj, bool val);
+
+JS_EXTERN bool JS_IsRegExp(JSValue val);
+JS_EXTERN bool JS_IsMap(JSValue val);
+JS_EXTERN int JS_IsSimpleValue(JSContext* ctx, JSValue v);
+
+JS_EXTERN JSValue JS_NewArray(JSContext *ctx);
+// takes ownership of the values
+JS_EXTERN JSValue JS_NewArrayFrom(JSContext *ctx, int count,
+ const JSValue *values);
+JS_EXTERN int JS_IsArray(JSContext *ctx, JSValue val);
+
+JS_EXTERN JSValue JS_NewDate(JSContext *ctx, double epoch_ms);
+JS_EXTERN bool JS_IsDate(JSValue v);
+
+JS_EXTERN JSValue JS_GetProperty(JSContext *ctx, JSValue this_obj, JSAtom prop);
+JS_EXTERN JSValue JS_GetPropertyUint32(JSContext *ctx, JSValue this_obj,
+ uint32_t idx);
+JS_EXTERN JSValue JS_GetPropertyInt64(JSContext *ctx, JSValue this_obj,
+ int64_t idx);
+JS_EXTERN JSValue JS_GetPropertyStr(JSContext *ctx, JSValue this_obj,
+ const char *prop);
+
+JS_EXTERN int JS_SetProperty(JSContext *ctx, JSValue this_obj,
+ JSAtom prop, JSValue val);
+JS_EXTERN int JS_SetPropertyUint32(JSContext *ctx, JSValue this_obj,
+ uint32_t idx, JSValue val);
+JS_EXTERN int JS_SetPropertyInt64(JSContext *ctx, JSValue this_obj,
+ int64_t idx, JSValue val);
+JS_EXTERN int JS_SetPropertyStr(JSContext *ctx, JSValue this_obj,
+ const char *prop, JSValue val);
+JS_EXTERN int JS_HasProperty(JSContext *ctx, JSValue this_obj, JSAtom prop);
+JS_EXTERN int JS_IsExtensible(JSContext *ctx, JSValue obj);
+JS_EXTERN int JS_PreventExtensions(JSContext *ctx, JSValue obj);
+JS_EXTERN int JS_DeleteProperty(JSContext *ctx, JSValue obj, JSAtom prop, int flags);
+JS_EXTERN int JS_SetPrototype(JSContext *ctx, JSValue obj, JSValue proto_val);
+JS_EXTERN JSValue JS_GetPrototype(JSContext *ctx, JSValue val);
+JS_EXTERN int JS_GetLength(JSContext *ctx, JSValue obj, int64_t *pres);
+JS_EXTERN int JS_SetLength(JSContext *ctx, JSValue obj, int64_t len);
+JS_EXTERN int JS_SealObject(JSContext *ctx, JSValue obj);
+JS_EXTERN int JS_FreezeObject(JSContext *ctx, JSValue obj);
#define JS_GPN_STRING_MASK (1 << 0)
#define JS_GPN_SYMBOL_MASK (1 << 1)
@@ -731,62 +790,75 @@ JSValue JS_ObjectSeal(JSContext *ctx, JSValueConst obj, int freeze);
/* set theJSPropertyEnum.is_enumerable field */
#define JS_GPN_SET_ENUM (1 << 5)
-int JS_GetOwnPropertyNames(JSContext *ctx, JSPropertyEnum **ptab,
- uint32_t *plen, JSValueConst obj, int flags);
-int JS_GetOwnProperty(JSContext *ctx, JSPropertyDescriptor *desc,
- JSValueConst obj, JSAtom prop);
-
-JSValue JS_Call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj,
- int argc, JSValueConst *argv);
-JSValue JS_Invoke(JSContext *ctx, JSValueConst this_val, JSAtom atom,
- int argc, JSValueConst *argv);
-JSValue JS_CallConstructor(JSContext *ctx, JSValueConst func_obj,
- int argc, JSValueConst *argv);
-JSValue JS_CallConstructor2(JSContext *ctx, JSValueConst func_obj,
- JSValueConst new_target,
- int argc, JSValueConst *argv);
-JS_BOOL JS_DetectModule(const char *input, size_t input_len);
+JS_EXTERN int JS_GetOwnPropertyNames(JSContext *ctx, JSPropertyEnum **ptab,
+ uint32_t *plen, JSValue obj, int flags);
+JS_EXTERN int JS_GetOwnProperty(JSContext *ctx, JSPropertyDescriptor *desc,
+ JSValue obj, JSAtom prop);
+JS_EXTERN void JS_FreePropertyEnum(JSContext *ctx, JSPropertyEnum *tab,
+ uint32_t len);
+
+JS_EXTERN JSValue JS_Call(JSContext *ctx, JSValue func_obj, JSValue this_obj,
+ int argc, JSValue *argv);
+JS_EXTERN JSValue JS_Invoke(JSContext *ctx, JSValue this_val, JSAtom atom,
+ int argc, JSValue *argv);
+JS_EXTERN JSValue JS_CallConstructor(JSContext *ctx, JSValue func_obj,
+ int argc, JSValue *argv);
+JS_EXTERN JSValue JS_CallConstructor2(JSContext *ctx, JSValue func_obj,
+ JSValue new_target,
+ int argc, JSValue *argv);
+/* Try to detect if the input is a module. Returns true if parsing the input
+ * as a module produces no syntax errors. It's a naive approach that is not
+ * wholly infallible: non-strict classic scripts may _parse_ okay as a module
+ * but not _execute_ as one (different runtime semantics.) Use with caution.
+ * |input| can be either ASCII or UTF-8 encoded source code.
+ */
+JS_EXTERN bool JS_DetectModule(const char *input, size_t input_len);
/* 'input' must be zero terminated i.e. input[input_len] = '\0'. */
-JSValue JS_Eval(JSContext *ctx, const char *input, size_t input_len,
- const char *filename, int eval_flags);
-/* same as JS_Eval() but with an explicit 'this_obj' parameter */
-JSValue JS_EvalThis(JSContext *ctx, JSValueConst this_obj,
- const char *input, size_t input_len,
- const char *filename, int line, int eval_flags);
-JSValue JS_GetGlobalObject(JSContext *ctx);
-int JS_IsInstanceOf(JSContext *ctx, JSValueConst val, JSValueConst obj);
-int JS_DefineProperty(JSContext *ctx, JSValueConst this_obj,
- JSAtom prop, JSValueConst val,
- JSValueConst getter, JSValueConst setter, int flags);
-int JS_DefinePropertyValue(JSContext *ctx, JSValueConst this_obj,
- JSAtom prop, JSValue val, int flags);
-int JS_DefinePropertyValueUint32(JSContext *ctx, JSValueConst this_obj,
- uint32_t idx, JSValue val, int flags);
-int JS_DefinePropertyValueStr(JSContext *ctx, JSValueConst this_obj,
- const char *prop, JSValue val, int flags);
-int JS_DefinePropertyGetSet(JSContext *ctx, JSValueConst this_obj,
- JSAtom prop, JSValue getter, JSValue setter,
- int flags);
-void JS_SetOpaque(JSValue obj, void *opaque);
-void *JS_GetOpaque(JSValueConst obj, JSClassID class_id);
-void *JS_GetOpaque2(JSContext *ctx, JSValueConst obj, JSClassID class_id);
+JS_EXTERN JSValue JS_Eval(JSContext *ctx, const char *input, size_t input_len,
+ const char *filename, int eval_flags);
+JS_EXTERN JSValue JS_Eval2(JSContext *ctx, const char *input, size_t input_len,
+ JSEvalOptions *options);
+JS_EXTERN JSValue JS_EvalThis(JSContext *ctx, JSValue this_obj,
+ const char *input, size_t input_len,
+ const char *filename, int eval_flags);
+JS_EXTERN JSValue JS_EvalThis2(JSContext *ctx, JSValue this_obj,
+ const char *input, size_t input_len,
+ JSEvalOptions *options);
+JS_EXTERN JSValue JS_GetGlobalObject(JSContext *ctx);
+JS_EXTERN int JS_IsInstanceOf(JSContext *ctx, JSValue val, JSValue obj);
+JS_EXTERN int JS_DefineProperty(JSContext *ctx, JSValue this_obj,
+ JSAtom prop, JSValue val,
+ JSValue getter, JSValue setter, int flags);
+JS_EXTERN int JS_DefinePropertyValue(JSContext *ctx, JSValue this_obj,
+ JSAtom prop, JSValue val, int flags);
+JS_EXTERN int JS_DefinePropertyValueUint32(JSContext *ctx, JSValue this_obj,
+ uint32_t idx, JSValue val, int flags);
+JS_EXTERN int JS_DefinePropertyValueStr(JSContext *ctx, JSValue this_obj,
+ const char *prop, JSValue val, int flags);
+JS_EXTERN int JS_DefinePropertyGetSet(JSContext *ctx, JSValue this_obj,
+ JSAtom prop, JSValue getter, JSValue setter,
+ int flags);
+/* Only supported for custom classes, returns 0 on success < 0 otherwise. */
+JS_EXTERN int JS_SetOpaque(JSValue obj, void *opaque);
+JS_EXTERN void *JS_GetOpaque(JSValue obj, JSClassID class_id);
+JS_EXTERN void *JS_GetOpaque2(JSContext *ctx, JSValue obj, JSClassID class_id);
+JS_EXTERN void *JS_GetAnyOpaque(JSValue obj, JSClassID *class_id);
/* 'buf' must be zero terminated i.e. buf[buf_len] = '\0'. */
-JSValue JS_ParseJSON(JSContext *ctx, const char *buf, size_t buf_len,
- const char *filename);
-#define JS_PARSE_JSON_EXT (1 << 0) /* allow extended JSON */
-JSValue JS_ParseJSON2(JSContext *ctx, const char *buf, size_t buf_len,
- const char *filename, int flags);
-JSValue JS_JSONStringify(JSContext *ctx, JSValueConst obj,
- JSValueConst replacer, JSValueConst space0);
+JS_EXTERN JSValue JS_ParseJSON(JSContext *ctx, const char *buf, size_t buf_len,
+ const char *filename);
+JS_EXTERN JSValue JS_JSONStringify(JSContext *ctx, JSValue obj,
+ JSValue replacer, JSValue space0);
typedef void JSFreeArrayBufferDataFunc(JSRuntime *rt, void *opaque, void *ptr);
-JSValue JS_NewArrayBuffer(JSContext *ctx, uint8_t *buf, size_t len,
- JSFreeArrayBufferDataFunc *free_func, void *opaque,
- JS_BOOL is_shared);
-JSValue JS_NewArrayBufferCopy(JSContext *ctx, const uint8_t *buf, size_t len);
-void JS_DetachArrayBuffer(JSContext *ctx, JSValueConst obj);
-uint8_t *JS_GetArrayBuffer(JSContext *ctx, size_t *psize, JSValueConst obj);
+JS_EXTERN JSValue JS_NewArrayBuffer(JSContext *ctx, uint8_t *buf, size_t len,
+ JSFreeArrayBufferDataFunc *free_func, void *opaque,
+ bool is_shared);
+JS_EXTERN JSValue JS_NewArrayBufferCopy(JSContext *ctx, const uint8_t *buf, size_t len);
+JS_EXTERN void JS_DetachArrayBuffer(JSContext *ctx, JSValue obj);
+JS_EXTERN uint8_t *JS_GetArrayBuffer(JSContext *ctx, size_t *psize, JSValue obj);
+JS_EXTERN bool JS_IsArrayBuffer(JSValue obj);
+JS_EXTERN uint8_t *JS_GetUint8Array(JSContext *ctx, size_t *psize, JSValue obj);
typedef enum JSTypedArrayEnum {
JS_TYPED_ARRAY_UINT8C = 0,
@@ -798,24 +870,30 @@ typedef enum JSTypedArrayEnum {
JS_TYPED_ARRAY_UINT32,
JS_TYPED_ARRAY_BIG_INT64,
JS_TYPED_ARRAY_BIG_UINT64,
+ JS_TYPED_ARRAY_FLOAT16,
JS_TYPED_ARRAY_FLOAT32,
JS_TYPED_ARRAY_FLOAT64,
} JSTypedArrayEnum;
-JSValue JS_NewTypedArray(JSContext *ctx, int argc, JSValueConst *argv,
+JS_EXTERN JSValue JS_NewTypedArray(JSContext *ctx, int argc, JSValue *argv,
JSTypedArrayEnum array_type);
-JSValue JS_GetTypedArrayBuffer(JSContext *ctx, JSValueConst obj,
- size_t *pbyte_offset,
- size_t *pbyte_length,
- size_t *pbytes_per_element);
+JS_EXTERN JSValue JS_GetTypedArrayBuffer(JSContext *ctx, JSValue obj,
+ size_t *pbyte_offset,
+ size_t *pbyte_length,
+ size_t *pbytes_per_element);
+JS_EXTERN JSValue JS_NewUint8Array(JSContext *ctx, uint8_t *buf, size_t len,
+ JSFreeArrayBufferDataFunc *free_func, void *opaque,
+ bool is_shared);
+/* returns -1 if not a typed array otherwise return a JSTypedArrayEnum value */
+JS_EXTERN int JS_GetTypedArrayType(JSValue obj);
+JS_EXTERN JSValue JS_NewUint8ArrayCopy(JSContext *ctx, const uint8_t *buf, size_t len);
typedef struct {
void *(*sab_alloc)(void *opaque, size_t size);
void (*sab_free)(void *opaque, void *ptr);
void (*sab_dup)(void *opaque, void *ptr);
void *sab_opaque;
} JSSharedArrayBufferFunctions;
-void JS_SetSharedArrayBufferFunctions(JSRuntime *rt,
- const JSSharedArrayBufferFunctions *sf);
+JS_EXTERN void JS_SetSharedArrayBufferFunctions(JSRuntime *rt, const JSSharedArrayBufferFunctions *sf);
typedef enum JSPromiseStateEnum {
JS_PROMISE_PENDING,
@@ -823,23 +901,26 @@ typedef enum JSPromiseStateEnum {
JS_PROMISE_REJECTED,
} JSPromiseStateEnum;
-JSValue JS_NewPromiseCapability(JSContext *ctx, JSValue *resolving_funcs);
-JSPromiseStateEnum JS_PromiseState(JSContext *ctx, JSValue promise);
-JSValue JS_PromiseResult(JSContext *ctx, JSValue promise);
+JS_EXTERN JSValue JS_NewPromiseCapability(JSContext *ctx, JSValue *resolving_funcs);
+JS_EXTERN JSPromiseStateEnum JS_PromiseState(JSContext *ctx, JSValue promise);
+JS_EXTERN JSValue JS_PromiseResult(JSContext *ctx, JSValue promise);
+JS_EXTERN bool JS_IsPromise(JSValue val);
-/* is_handled = TRUE means that the rejection is handled */
-typedef void JSHostPromiseRejectionTracker(JSContext *ctx, JSValueConst promise,
- JSValueConst reason,
- JS_BOOL is_handled, void *opaque);
-void JS_SetHostPromiseRejectionTracker(JSRuntime *rt, JSHostPromiseRejectionTracker *cb, void *opaque);
+JS_EXTERN JSValue JS_NewSymbol(JSContext *ctx, const char *description, bool is_global);
+
+/* is_handled = true means that the rejection is handled */
+typedef void JSHostPromiseRejectionTracker(JSContext *ctx, JSValue promise,
+ JSValue reason,
+ bool is_handled, void *opaque);
+JS_EXTERN void JS_SetHostPromiseRejectionTracker(JSRuntime *rt, JSHostPromiseRejectionTracker *cb, void *opaque);
/* return != 0 if the JS code needs to be interrupted */
typedef int JSInterruptHandler(JSRuntime *rt, void *opaque);
-void JS_SetInterruptHandler(JSRuntime *rt, JSInterruptHandler *cb, void *opaque);
-/* if can_block is TRUE, Atomics.wait() can be used */
-void JS_SetCanBlock(JSRuntime *rt, JS_BOOL can_block);
+JS_EXTERN void JS_SetInterruptHandler(JSRuntime *rt, JSInterruptHandler *cb, void *opaque);
+/* if can_block is true, Atomics.wait() can be used */
+JS_EXTERN void JS_SetCanBlock(JSRuntime *rt, bool can_block);
/* set the [IsHTMLDDA] internal slot */
-void JS_SetIsHTMLDDA(JSContext *ctx, JSValueConst obj);
+JS_EXTERN void JS_SetIsHTMLDDA(JSContext *ctx, JSValue obj);
typedef struct JSModuleDef JSModuleDef;
@@ -853,51 +934,57 @@ typedef JSModuleDef *JSModuleLoaderFunc(JSContext *ctx,
/* module_normalize = NULL is allowed and invokes the default module
filename normalizer */
-void JS_SetModuleLoaderFunc(JSRuntime *rt,
- JSModuleNormalizeFunc *module_normalize,
- JSModuleLoaderFunc *module_loader, void *opaque);
+JS_EXTERN void JS_SetModuleLoaderFunc(JSRuntime *rt,
+ JSModuleNormalizeFunc *module_normalize,
+ JSModuleLoaderFunc *module_loader, void *opaque);
/* return the import.meta object of a module */
-JSValue JS_GetImportMeta(JSContext *ctx, JSModuleDef *m);
-JSAtom JS_GetModuleName(JSContext *ctx, JSModuleDef *m);
-JSValue JS_GetModuleNamespace(JSContext *ctx, JSModuleDef *m);
+JS_EXTERN JSValue JS_GetImportMeta(JSContext *ctx, JSModuleDef *m);
+JS_EXTERN JSAtom JS_GetModuleName(JSContext *ctx, JSModuleDef *m);
+JS_EXTERN JSValue JS_GetModuleNamespace(JSContext *ctx, JSModuleDef *m);
/* JS Job support */
-typedef JSValue JSJobFunc(JSContext *ctx, int argc, JSValueConst *argv);
-int JS_EnqueueJob(JSContext *ctx, JSJobFunc *job_func, int argc, JSValueConst *argv);
+typedef JSValue JSJobFunc(JSContext *ctx, int argc, JSValue *argv);
+JS_EXTERN int JS_EnqueueJob(JSContext *ctx, JSJobFunc *job_func, int argc, JSValue *argv);
+
+JS_EXTERN bool JS_IsJobPending(JSRuntime *rt);
+JS_EXTERN int JS_ExecutePendingJob(JSRuntime *rt, JSContext **pctx);
-JS_BOOL JS_IsJobPending(JSRuntime *rt);
-int JS_ExecutePendingJob(JSRuntime *rt, JSContext **pctx);
+/* Structure to retrieve (de)serialized SharedArrayBuffer objects. */
+typedef struct JSSABTab {
+ uint8_t **tab;
+ size_t len;
+} JSSABTab;
/* Object Writer/Reader (currently only used to handle precompiled code) */
#define JS_WRITE_OBJ_BYTECODE (1 << 0) /* allow function/module */
-#define JS_WRITE_OBJ_BSWAP (1 << 1) /* byte swapped output */
+#define JS_WRITE_OBJ_BSWAP (0) /* byte swapped output (obsolete, handled transparently) */
#define JS_WRITE_OBJ_SAB (1 << 2) /* allow SharedArrayBuffer */
-#define JS_WRITE_OBJ_REFERENCE (1 << 3) /* allow object references to
- encode arbitrary object
- graph */
-uint8_t *JS_WriteObject(JSContext *ctx, size_t *psize, JSValueConst obj,
- int flags);
-uint8_t *JS_WriteObject2(JSContext *ctx, size_t *psize, JSValueConst obj,
- int flags, uint8_t ***psab_tab, size_t *psab_tab_len);
+#define JS_WRITE_OBJ_REFERENCE (1 << 3) /* allow object references to encode arbitrary object graph */
+#define JS_WRITE_OBJ_STRIP_SOURCE (1 << 4) /* do not write source code information */
+#define JS_WRITE_OBJ_STRIP_DEBUG (1 << 5) /* do not write debug information */
+JS_EXTERN uint8_t *JS_WriteObject(JSContext *ctx, size_t *psize, JSValue obj, int flags);
+JS_EXTERN uint8_t *JS_WriteObject2(JSContext *ctx, size_t *psize, JSValue obj,
+ int flags, JSSABTab *psab_tab);
#define JS_READ_OBJ_BYTECODE (1 << 0) /* allow function/module */
-#define JS_READ_OBJ_ROM_DATA (1 << 1) /* avoid duplicating 'buf' data */
+#define JS_READ_OBJ_ROM_DATA (0) /* avoid duplicating 'buf' data (obsolete, broken by ICs) */
#define JS_READ_OBJ_SAB (1 << 2) /* allow SharedArrayBuffer */
#define JS_READ_OBJ_REFERENCE (1 << 3) /* allow object references */
-JSValue JS_ReadObject(JSContext *ctx, const uint8_t *buf, size_t buf_len,
- int flags);
+JS_EXTERN JSValue JS_ReadObject(JSContext *ctx, const uint8_t *buf, size_t buf_len, int flags);
+JS_EXTERN JSValue JS_ReadObject2(JSContext *ctx, const uint8_t *buf, size_t buf_len,
+ int flags, JSSABTab *psab_tab);
/* instantiate and evaluate a bytecode function. Only used when
reading a script or module with JS_ReadObject() */
-JSValue JS_EvalFunction(JSContext *ctx, JSValue fun_obj);
+JS_EXTERN JSValue JS_EvalFunction(JSContext *ctx, JSValue fun_obj);
/* load the dependencies of the module 'obj'. Useful when JS_ReadObject()
returns a module. */
-int JS_ResolveModule(JSContext *ctx, JSValueConst obj);
+JS_EXTERN int JS_ResolveModule(JSContext *ctx, JSValue obj);
/* only exported for os.Worker() */
-JSAtom JS_GetScriptOrModuleName(JSContext *ctx, int n_stack_levels);
+JS_EXTERN JSAtom JS_GetScriptOrModuleName(JSContext *ctx, int n_stack_levels);
/* only exported for os.Worker() */
-JSValue JS_LoadModule(JSContext *ctx, const char *basename,
+JS_EXTERN JSValue JS_LoadModule(JSContext *ctx, const char *basename,
const char *filename);
/* C function definition */
@@ -919,39 +1006,53 @@ typedef enum JSCFunctionEnum { /* XXX: should rename for namespace isolation */
typedef union JSCFunctionType {
JSCFunction *generic;
- JSValue (*generic_magic)(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic);
+ JSValue (*generic_magic)(JSContext *ctx, JSValue this_val, int argc, JSValue *argv, int magic);
JSCFunction *constructor;
- JSValue (*constructor_magic)(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv, int magic);
+ JSValue (*constructor_magic)(JSContext *ctx, JSValue new_target, int argc, JSValue *argv, int magic);
JSCFunction *constructor_or_func;
double (*f_f)(double);
double (*f_f_f)(double, double);
- JSValue (*getter)(JSContext *ctx, JSValueConst this_val);
- JSValue (*setter)(JSContext *ctx, JSValueConst this_val, JSValueConst val);
- JSValue (*getter_magic)(JSContext *ctx, JSValueConst this_val, int magic);
- JSValue (*setter_magic)(JSContext *ctx, JSValueConst this_val, JSValueConst val, int magic);
- JSValue (*iterator_next)(JSContext *ctx, JSValueConst this_val,
- int argc, JSValueConst *argv, int *pdone, int magic);
+ JSValue (*getter)(JSContext *ctx, JSValue this_val);
+ JSValue (*setter)(JSContext *ctx, JSValue this_val, JSValue val);
+ JSValue (*getter_magic)(JSContext *ctx, JSValue this_val, int magic);
+ JSValue (*setter_magic)(JSContext *ctx, JSValue this_val, JSValue val, int magic);
+ JSValue (*iterator_next)(JSContext *ctx, JSValue this_val,
+ int argc, JSValue *argv, int *pdone, int magic);
} JSCFunctionType;
-JSValue JS_NewCFunction2(JSContext *ctx, JSCFunction *func,
- const char *name,
- int length, JSCFunctionEnum cproto, int magic);
-JSValue JS_NewCFunctionData(JSContext *ctx, JSCFunctionData *func,
- int length, int magic, int data_len,
- JSValueConst *data);
-
-JSValue JS_NewCFunction(JSContext *ctx, JSCFunction *func, const char *name,
- int length);
+JS_EXTERN JSValue JS_NewCFunction2(JSContext *ctx, JSCFunction *func,
+ const char *name,
+ int length, JSCFunctionEnum cproto, int magic);
+JS_EXTERN JSValue JS_NewCFunction3(JSContext *ctx, JSCFunction *func,
+ const char *name,
+ int length, JSCFunctionEnum cproto, int magic,
+ JSValue proto_val);
+JS_EXTERN JSValue JS_NewCFunctionData(JSContext *ctx, JSCFunctionData *func,
+ int length, int magic, int data_len,
+ JSValue *data);
+
+static inline JSValue JS_NewCFunction(JSContext *ctx, JSCFunction *func, const char *name,
+ int length)
+{
+ return JS_NewCFunction2(ctx, func, name, length, JS_CFUNC_generic, 0);
+}
-JSValue JS_NewCFunctionMagic(JSContext *ctx, JSCFunctionMagic *func,
- const char *name, int length, JSCFunctionEnum cproto, int magic);
-void JS_SetConstructor(JSContext *ctx, JSValueConst func_obj,
- JSValueConst proto);
+static inline JSValue JS_NewCFunctionMagic(JSContext *ctx, JSCFunctionMagic *func,
+ const char *name,
+ int length, JSCFunctionEnum cproto, int magic)
+{
+ /* Used to squelch a -Wcast-function-type warning. */
+ JSCFunctionType ft;
+ ft.generic_magic = func;
+ return JS_NewCFunction2(ctx, ft.generic, name, length, cproto, magic);
+}
+JS_EXTERN void JS_SetConstructor(JSContext *ctx, JSValue func_obj,
+ JSValue proto);
/* C property definition */
typedef struct JSCFunctionListEntry {
- const char *name;
+ const char *name; /* pure ASCII or UTF-8 encoded */
uint8_t prop_flags;
uint8_t def_type;
int16_t magic;
@@ -973,9 +1074,10 @@ typedef struct JSCFunctionListEntry {
const struct JSCFunctionListEntry *tab;
int len;
} prop_list;
- const char *str;
+ const char *str; /* pure ASCII or UTF-8 encoded */
int32_t i32;
int64_t i64;
+ uint64_t u64;
double f64;
} u;
} JSCFunctionListEntry;
@@ -992,41 +1094,43 @@ typedef struct JSCFunctionListEntry {
#define JS_DEF_ALIAS 9
/* Note: c++ does not like nested designators */
-#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 } } } }
-#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 } } } }
-#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 } } } }
-#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 } } } }
-#define JS_CGETSET_DEF(name, fgetter, fsetter) { name, JS_PROP_CONFIGURABLE, JS_DEF_CGETSET, 0, .u = { .getset = { .get = { .getter = fgetter }, .set = { .setter = fsetter } } } }
-#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 } } } }
-#define JS_PROP_STRING_DEF(name, cstr, prop_flags) { name, prop_flags, JS_DEF_PROP_STRING, 0, .u = { .str = cstr } }
-#define JS_PROP_INT32_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT32, 0, .u = { .i32 = val } }
-#define JS_PROP_INT64_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT64, 0, .u = { .i64 = val } }
-#define JS_PROP_DOUBLE_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_DOUBLE, 0, .u = { .f64 = val } }
-#define JS_PROP_UNDEFINED_DEF(name, prop_flags) { name, prop_flags, JS_DEF_PROP_UNDEFINED, 0, .u = { .i32 = 0 } }
-#define JS_OBJECT_DEF(name, tab, len, prop_flags) { name, prop_flags, JS_DEF_OBJECT, 0, .u = { .prop_list = { tab, len } } }
-#define JS_ALIAS_DEF(name, from) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_ALIAS, 0, .u = { .alias = { from, -1 } } }
-#define JS_ALIAS_BASE_DEF(name, from, base) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_ALIAS, 0, .u = { .alias = { from, base } } }
-
-void JS_SetPropertyFunctionList(JSContext *ctx, JSValueConst obj,
- const JSCFunctionListEntry *tab,
- int len);
+#define JS_CFUNC_DEF(name, length, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, 0, { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } }
+#define JS_CFUNC_DEF2(name, length, func1, prop_flags) { name, prop_flags, JS_DEF_CFUNC, 0, { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } }
+#define JS_CFUNC_MAGIC_DEF(name, length, func1, magic) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, magic, { .func = { length, JS_CFUNC_generic_magic, { .generic_magic = func1 } } } }
+#define JS_CFUNC_SPECIAL_DEF(name, length, cproto, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, 0, { .func = { length, JS_CFUNC_ ## cproto, { .cproto = func1 } } } }
+#define JS_ITERATOR_NEXT_DEF(name, length, func1, magic) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, magic, { .func = { length, JS_CFUNC_iterator_next, { .iterator_next = func1 } } } }
+#define JS_CGETSET_DEF(name, fgetter, fsetter) { name, JS_PROP_CONFIGURABLE, JS_DEF_CGETSET, 0, { .getset = { .get = { .getter = fgetter }, .set = { .setter = fsetter } } } }
+#define JS_CGETSET_DEF2(name, fgetter, fsetter, prop_flags) { name, prop_flags, JS_DEF_CGETSET, 0, { .getset = { .get = { .getter = fgetter }, .set = { .setter = fsetter } } } }
+#define JS_CGETSET_MAGIC_DEF(name, fgetter, fsetter, magic) { name, JS_PROP_CONFIGURABLE, JS_DEF_CGETSET_MAGIC, magic, { .getset = { .get = { .getter_magic = fgetter }, .set = { .setter_magic = fsetter } } } }
+#define JS_PROP_STRING_DEF(name, cstr, prop_flags) { name, prop_flags, JS_DEF_PROP_STRING, 0, { .str = cstr } }
+#define JS_PROP_INT32_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT32, 0, { .i32 = val } }
+#define JS_PROP_INT64_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT64, 0, { .i64 = val } }
+#define JS_PROP_DOUBLE_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_DOUBLE, 0, { .f64 = val } }
+#define JS_PROP_U2D_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_DOUBLE, 0, { .u64 = val } }
+#define JS_PROP_UNDEFINED_DEF(name, prop_flags) { name, prop_flags, JS_DEF_PROP_UNDEFINED, 0, { .i32 = 0 } }
+#define JS_OBJECT_DEF(name, tab, len, prop_flags) { name, prop_flags, JS_DEF_OBJECT, 0, { .prop_list = { tab, len } } }
+#define JS_ALIAS_DEF(name, from) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_ALIAS, 0, { .alias = { from, -1 } } }
+#define JS_ALIAS_BASE_DEF(name, from, base) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_ALIAS, 0, { .alias = { from, base } } }
+
+JS_EXTERN void JS_SetPropertyFunctionList(JSContext *ctx, JSValue obj,
+ const JSCFunctionListEntry *tab,
+ int len);
/* C module definition */
typedef int JSModuleInitFunc(JSContext *ctx, JSModuleDef *m);
-JSModuleDef *JS_NewCModule(JSContext *ctx, const char *name_str,
- JSModuleInitFunc *func);
+JS_EXTERN JSModuleDef *JS_NewCModule(JSContext *ctx, const char *name_str,
+ JSModuleInitFunc *func);
/* can only be called before the module is instantiated */
-int JS_AddModuleExport(JSContext *ctx, JSModuleDef *m, const char *name_str);
-int JS_AddModuleExportList(JSContext *ctx, JSModuleDef *m,
- const JSCFunctionListEntry *tab, int len);
+JS_EXTERN int JS_AddModuleExport(JSContext *ctx, JSModuleDef *m, const char *name_str);
+JS_EXTERN int JS_AddModuleExportList(JSContext *ctx, JSModuleDef *m,
+ const JSCFunctionListEntry *tab, int len);
/* can only be called after the module is instantiated */
-int JS_SetModuleExport(JSContext *ctx, JSModuleDef *m, const char *export_name,
- JSValue val);
-int JS_SetModuleExportList(JSContext *ctx, JSModuleDef *m,
- const JSCFunctionListEntry *tab, int len);
-
+JS_EXTERN int JS_SetModuleExport(JSContext *ctx, JSModuleDef *m, const char *export_name,
+ JSValue val);
+JS_EXTERN int JS_SetModuleExportList(JSContext *ctx, JSModuleDef *m,
+ const JSCFunctionListEntry *tab, int len);
/* Qbs extensions */
struct LookupResult
@@ -1041,22 +1145,24 @@ void setScopeLookup(JSContext *ctx, ScopeLookup *scopeLookup);
// Alternative: Request with throw in script engine
typedef void FoundUndefinedHandler(JSContext *ctx);
void setFoundUndefinedHandler(JSContext *ctx, FoundUndefinedHandler *handler);
-
typedef void FunctionEnteredHandler(JSContext *ctx, JSValue this_val);
typedef void FunctionExitedHandler(JSContext *ctx);
void setFunctionEnteredHandler(JSContext *ctx, FunctionEnteredHandler *handler);
void setFunctionExitedHandler(JSContext *ctx, FunctionExitedHandler *handler);
-int isSimpleValue(JSValue v);
-#ifndef NDEBUG
-void watchRefCount(void *p);
-#endif
+/* Version */
+
+#define QJS_VERSION_MAJOR 0
+#define QJS_VERSION_MINOR 8
+#define QJS_VERSION_PATCH 0
+#define QJS_VERSION_SUFFIX ""
+
+JS_EXTERN const char* JS_GetVersion(void);
-void build_backtrace(JSContext *ctx, JSValueConst error_obj,
- const char *filename, int line_num,
- int backtrace_flags);
+/* Integration point for quickjs-libc.c, not for public use. */
+JS_EXTERN uintptr_t js_std_cmd(int cmd, ...);
-#undef js_unlikely
+#undef JS_EXTERN
#undef js_force_inline
#ifdef __cplusplus