diff --git a/CMakeLists.txt b/CMakeLists.txt index 23ee8cd..5cb4250 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/raylib EXCLUDE_FROM_ALL) message("=== Configure QuickJS ===") # add quickjs -set(quickjs_version 2021-03-27) +set(quickjs_version 2026-06-04) set(quickjs_sources_root ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/quickjs) set(quickjs_sources ${quickjs_sources_root}/quickjs.h @@ -22,8 +22,8 @@ set(quickjs_sources ${quickjs_sources_root}/quickjs.c ${quickjs_sources_root}/libregexp.c ${quickjs_sources_root}/libunicode.c - ${quickjs_sources_root}/libbf.c ${quickjs_sources_root}/cutils.c + ${quickjs_sources_root}/dtoa.c #${quickjs_sources_root}/quickjs-libc.c ) add_library(quickjs STATIC diff --git a/bindings/webpack.config.js b/bindings/webpack.config.js index 76bf1f2..c311559 100644 --- a/bindings/webpack.config.js +++ b/bindings/webpack.config.js @@ -4,7 +4,7 @@ module.exports = { entry: './src/index.ts', devtool: false, target: "node", - mode: 'production', + mode: 'development', module: { rules: [ { diff --git a/include/quickjs-libc.h b/include/quickjs-libc.h index fbbe5b0..5c8301b 100644 --- a/include/quickjs-libc.h +++ b/include/quickjs-libc.h @@ -1,6 +1,6 @@ /* * QuickJS C library - * + * * Copyright (c) 2017-2018 Fabrice Bellard * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -37,21 +37,28 @@ JSModuleDef *js_init_module_std(JSContext *ctx, const char *module_name); JSModuleDef *js_init_module_os(JSContext *ctx, const char *module_name); void js_std_add_helpers(JSContext *ctx, int argc, char **argv); void js_std_loop(JSContext *ctx); +JSValue js_std_await(JSContext *ctx, JSValue obj); void js_std_init_handlers(JSRuntime *rt); void js_std_free_handlers(JSRuntime *rt); void js_std_dump_error(JSContext *ctx); uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename); int js_module_set_import_meta(JSContext *ctx, JSValueConst func_val, JS_BOOL use_realpath, JS_BOOL is_main); +int js_module_test_json(JSContext *ctx, JSValueConst attributes); +int js_module_check_attributes(JSContext *ctx, void *opaque, JSValueConst attributes); JSModuleDef *js_module_loader(JSContext *ctx, - const char *module_name, void *opaque); + const char *module_name, void *opaque, + JSValueConst attributes); void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len, int flags); +void js_std_eval_binary_json_module(JSContext *ctx, + const uint8_t *buf, size_t buf_len, + const char *module_name); void js_std_promise_rejection_tracker(JSContext *ctx, JSValueConst promise, JSValueConst reason, JS_BOOL is_handled, void *opaque); void js_std_set_worker_new_context_func(JSContext *(*func)(JSRuntime *rt)); - + #ifdef __cplusplus } /* extern "C" { */ #endif diff --git a/include/quickjs.h b/include/quickjs.h index d4a5cd3..476d735 100644 --- a/include/quickjs.h +++ b/include/quickjs.h @@ -27,6 +27,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -48,7 +49,6 @@ extern "C" { typedef struct JSRuntime JSRuntime; typedef struct JSContext JSContext; -typedef struct JSObject JSObject; typedef struct JSClass JSClass; typedef uint32_t JSClassID; typedef uint32_t JSAtom; @@ -64,14 +64,21 @@ typedef uint32_t JSAtom; #define JS_NAN_BOXING #endif +#if defined(__SIZEOF_INT128__) && (INTPTR_MAX >= INT64_MAX) +#define JS_LIMB_BITS 64 +#else +#define JS_LIMB_BITS 32 +#endif + +#define JS_SHORT_BIG_INT_BITS JS_LIMB_BITS + 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_STRING_ROPE = -6, JS_TAG_MODULE = -3, /* used internally */ JS_TAG_FUNCTION_BYTECODE = -2, /* used internally */ JS_TAG_OBJECT = -1, @@ -83,10 +90,12 @@ enum { JS_TAG_UNINITIALIZED = 4, JS_TAG_CATCH_OFFSET = 5, JS_TAG_EXCEPTION = 6, - JS_TAG_FLOAT64 = 7, + JS_TAG_SHORT_BIG_INT = 7, + JS_TAG_FLOAT64 = 8, /* any larger tag is FLOAT64 if JS_NAN_BOXING */ }; +/* must match the layout of 'JSMallocBlockHeader' */ typedef struct JSRefCountHeader { int ref_count; } JSRefCountHeader; @@ -108,6 +117,7 @@ typedef const struct __JSValue *JSValueConst; #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_SHORT_BIG_INT(v) 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)) @@ -126,7 +136,12 @@ static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v) { return 0; } - + +static inline JSValue __JS_NewShortBigInt(JSContext *ctx, int32_t d) +{ + return JS_MKVAL(JS_TAG_SHORT_BIG_INT, d); +} + #elif defined(JS_NAN_BOXING) typedef uint64_t JSValue; @@ -136,6 +151,7 @@ typedef uint64_t 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) +#define JS_VALUE_GET_SHORT_BIG_INT(v) (int)(v) #define JS_VALUE_GET_PTR(v) (void *)(intptr_t)(v) #define JS_MKVAL(tag, val) (((uint64_t)(tag) << 32) | (uint32_t)(val)) @@ -191,13 +207,23 @@ static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v) tag = JS_VALUE_GET_TAG(v); return tag == (JS_NAN >> 32); } - + +static inline JSValue __JS_NewShortBigInt(JSContext *ctx, int32_t d) +{ + return JS_MKVAL(JS_TAG_SHORT_BIG_INT, d); +} + #else /* !JS_NAN_BOXING */ typedef union JSValueUnion { - int32_t int32; + uint64_t uint64; double float64; void *ptr; +#if JS_SHORT_BIG_INT_BITS == 32 + int32_t short_big_int; +#else + int64_t short_big_int; +#endif } JSValueUnion; typedef struct JSValue { @@ -210,12 +236,15 @@ typedef struct 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) -#define JS_VALUE_GET_INT(v) ((v).u.int32) -#define JS_VALUE_GET_BOOL(v) ((v).u.int32) +#define JS_VALUE_GET_INT(v) ((int)(v).u.uint64) +#define JS_VALUE_GET_BOOL(v) ((int)(v).u.uint64) #define JS_VALUE_GET_FLOAT64(v) ((v).u.float64) +#define JS_VALUE_GET_SHORT_BIG_INT(v) ((v).u.short_big_int) #define JS_VALUE_GET_PTR(v) ((v).u.ptr) -#define JS_MKVAL(tag, val) (JSValue){ (JSValueUnion){ .int32 = val }, tag } +/* avoid uninitialized data by using a 64 bit field even if only 32 + bits are needed because some compilers generate slower code */ +#define JS_MKVAL(tag, val) (JSValue){ (JSValueUnion){ .uint64 = (uint32_t)(val) }, tag } #define JS_MKPTR(tag, p) (JSValue){ (JSValueUnion){ .ptr = p }, tag } #define JS_TAG_IS_FLOAT64(tag) ((unsigned)(tag) == JS_TAG_FLOAT64) @@ -242,13 +271,19 @@ static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v) return (u.u64 & 0x7fffffffffffffff) > 0x7ff0000000000000; } +static inline JSValue __JS_NewShortBigInt(JSContext *ctx, int64_t d) +{ + JSValue v; + v.tag = JS_TAG_SHORT_BIG_INT; + v.u.short_big_int = d; + return v; +} + #endif /* !JS_NAN_BOXING */ #define JS_VALUE_IS_BOTH_INT(v1, v2) ((JS_VALUE_GET_TAG(v1) | JS_VALUE_GET_TAG(v2)) == 0) #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 */ @@ -287,10 +322,11 @@ static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v) (JS_SetProperty) */ #define JS_PROP_THROW_STRICT (1 << 15) -#define JS_PROP_NO_ADD (1 << 16) /* internal use */ -#define JS_PROP_NO_EXOTIC (1 << 17) /* internal use */ +#define JS_PROP_NO_EXOTIC (1 << 16) /* 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) */ @@ -300,13 +336,15 @@ 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 */ /* 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(). */ #define JS_EVAL_FLAG_COMPILE_ONLY (1 << 5) /* don't include the stack frames before this eval in the Error() backtraces */ #define JS_EVAL_FLAG_BACKTRACE_BARRIER (1 << 6) +/* allow top-level await in normal script. JS_Eval() returns a + 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); @@ -359,24 +397,18 @@ JSValue JS_GetClassProto(JSContext *ctx, JSClassID class_id); /* 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); +int JS_AddIntrinsicBaseObjects(JSContext *ctx); +int JS_AddIntrinsicDate(JSContext *ctx); +int JS_AddIntrinsicEval(JSContext *ctx); +int 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); +int JS_AddIntrinsicRegExp(JSContext *ctx); +int JS_AddIntrinsicJSON(JSContext *ctx); +int JS_AddIntrinsicProxy(JSContext *ctx); +int JS_AddIntrinsicMapSet(JSContext *ctx); +int JS_AddIntrinsicTypedArrays(JSContext *ctx); +int JS_AddIntrinsicPromise(JSContext *ctx); +int JS_AddIntrinsicWeakRef(JSContext *ctx); JSValue js_string_codePointRange(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv); @@ -426,7 +458,11 @@ 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); +const char *JS_AtomToCStringLen(JSContext *ctx, size_t *plen, JSAtom atom); +static inline const char *JS_AtomToCString(JSContext *ctx, JSAtom atom) +{ + return JS_AtomToCStringLen(ctx, NULL, atom); +} JSAtom JS_ValueToAtom(JSContext *ctx, JSValueConst val); /* object class support */ @@ -471,6 +507,17 @@ typedef struct JSClassExoticMethods { /* return < 0 if exception or TRUE/FALSE */ int (*set_property)(JSContext *ctx, JSValueConst obj, JSAtom atom, JSValueConst value, JSValueConst receiver, int flags); + + /* To get a consistent object behavior when get_prototype != NULL, + get_property, set_property and set_prototype must be != NULL + and the object must be created with a JS_NULL prototype. */ + JSValue (*get_prototype)(JSContext *ctx, JSValueConst obj); + /* return < 0 if exception or TRUE/FALSE */ + int (*set_prototype)(JSContext *ctx, JSValueConst obj, JSValueConst proto_val); + /* return < 0 if exception or TRUE/FALSE */ + int (*is_extensible)(JSContext *ctx, JSValueConst obj); + /* return < 0 if exception or TRUE/FALSE */ + int (*prevent_extensions)(JSContext *ctx, JSValueConst obj); } JSClassExoticMethods; typedef void JSClassFinalizer(JSRuntime *rt, JSValue val); @@ -496,7 +543,10 @@ typedef struct JSClassDef { JSClassExoticMethods *exotic; } JSClassDef; +#define JS_INVALID_CLASS_ID 0 JSClassID JS_NewClassID(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); @@ -544,23 +594,21 @@ JSValue JS_NewBigUint64(JSContext *ctx, uint64_t v); static js_force_inline JSValue JS_NewFloat64(JSContext *ctx, double d) { - JSValue v; int32_t val; union { double d; uint64_t u; } u, t; - u.d = d; - val = (int32_t)d; - t.d = val; - /* -0 cannot be represented as integer, so we compare the bit - representation */ - if (u.u == t.u) { - v = JS_MKVAL(JS_TAG_INT, val); - } else { - v = __JS_NewFloat64(ctx, d); + if (d >= INT32_MIN && d <= INT32_MAX) { + u.d = d; + val = (int32_t)d; + t.d = val; + /* -0 cannot be represented as integer, so we compare the bit + representation */ + if (u.u == t.u) + return JS_MKVAL(JS_TAG_INT, val); } - return v; + return __JS_NewFloat64(ctx, d); } static inline JS_BOOL JS_IsNumber(JSValueConst v) @@ -572,19 +620,7 @@ static inline JS_BOOL JS_IsNumber(JSValueConst v) static inline JS_BOOL JS_IsBigInt(JSContext *ctx, JSValueConst v) { int tag = JS_VALUE_GET_TAG(v); - return tag == JS_TAG_BIG_INT; -} - -static inline JS_BOOL JS_IsBigFloat(JSValueConst v) -{ - int tag = JS_VALUE_GET_TAG(v); - return tag == JS_TAG_BIG_FLOAT; -} - -static inline JS_BOOL JS_IsBigDecimal(JSValueConst v) -{ - int tag = JS_VALUE_GET_TAG(v); - return tag == JS_TAG_BIG_DECIMAL; + return tag == JS_TAG_BIG_INT || tag == JS_TAG_SHORT_BIG_INT; } static inline JS_BOOL JS_IsBool(JSValueConst v) @@ -614,7 +650,8 @@ static inline JS_BOOL JS_IsUninitialized(JSValueConst v) static inline JS_BOOL JS_IsString(JSValueConst v) { - return JS_VALUE_GET_TAG(v) == JS_TAG_STRING; + return JS_VALUE_GET_TAG(v) == JS_TAG_STRING || + JS_VALUE_GET_TAG(v) == JS_TAG_STRING_ROPE; } static inline JS_BOOL JS_IsSymbol(JSValueConst v) @@ -628,9 +665,10 @@ static inline JS_BOOL JS_IsObject(JSValueConst v) } JSValue JS_Throw(JSContext *ctx, JSValue obj); +void JS_SetUncatchableException(JSContext *ctx, JS_BOOL flag); JSValue JS_GetException(JSContext *ctx); +JS_BOOL JS_HasException(JSContext *ctx); JS_BOOL JS_IsError(JSContext *ctx, JSValueConst val); -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, ...); @@ -640,10 +678,16 @@ JSValue __js_printf_like(2, 3) JS_ThrowInternalError(JSContext *ctx, const char JSValue JS_ThrowOutOfMemory(JSContext *ctx); void __JS_FreeValue(JSContext *ctx, JSValue v); + +static inline JSRefCountHeader *__js_rc(void *ptr) +{ + return (JSRefCountHeader *)((uint32_t *)ptr - 1); +} + static inline void JS_FreeValue(JSContext *ctx, JSValue v) { if (JS_VALUE_HAS_REF_COUNT(v)) { - JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v); + JSRefCountHeader *p = __js_rc(JS_VALUE_GET_PTR(v)); if (--p->ref_count <= 0) { __JS_FreeValue(ctx, v); } @@ -653,7 +697,7 @@ void __JS_FreeValueRT(JSRuntime *rt, JSValue v); static inline void JS_FreeValueRT(JSRuntime *rt, JSValue v) { if (JS_VALUE_HAS_REF_COUNT(v)) { - JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v); + JSRefCountHeader *p = __js_rc(JS_VALUE_GET_PTR(v)); if (--p->ref_count <= 0) { __JS_FreeValueRT(rt, v); } @@ -663,7 +707,7 @@ static inline void JS_FreeValueRT(JSRuntime *rt, JSValue v) static inline JSValue JS_DupValue(JSContext *ctx, JSValueConst v) { if (JS_VALUE_HAS_REF_COUNT(v)) { - JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v); + JSRefCountHeader *p = __js_rc(JS_VALUE_GET_PTR(v)); p->ref_count++; } return (JSValue)v; @@ -672,12 +716,16 @@ static inline JSValue JS_DupValue(JSContext *ctx, JSValueConst v) static inline JSValue JS_DupValueRT(JSRuntime *rt, JSValueConst v) { if (JS_VALUE_HAS_REF_COUNT(v)) { - JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v); + JSRefCountHeader *p = __js_rc(JS_VALUE_GET_PTR(v)); p->ref_count++; } return (JSValue)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) @@ -693,7 +741,10 @@ int JS_ToBigInt64(JSContext *ctx, int64_t *pres, JSValueConst val); 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); +static inline JSValue JS_NewString(JSContext *ctx, const char *str) +{ + return JS_NewStringLen(ctx, str, strlen(str)); +} JSValue JS_NewAtomString(JSContext *ctx, const char *str); JSValue JS_ToString(JSContext *ctx, JSValueConst val); JSValue JS_ToPropertyKey(JSContext *ctx, JSValueConst val); @@ -720,6 +771,8 @@ JS_BOOL JS_SetConstructorBit(JSContext *ctx, JSValueConst func_obj, JS_BOOL val) JSValue JS_NewArray(JSContext *ctx); int JS_IsArray(JSContext *ctx, JSValueConst val); +JSValue JS_NewDate(JSContext *ctx, double epoch_ms); + JSValue JS_GetPropertyInternal(JSContext *ctx, JSValueConst obj, JSAtom prop, JSValueConst receiver, JS_BOOL throw_ref_error); @@ -733,13 +786,13 @@ JSValue JS_GetPropertyStr(JSContext *ctx, JSValueConst this_obj, JSValue JS_GetPropertyUint32(JSContext *ctx, JSValueConst this_obj, uint32_t idx); -int JS_SetPropertyInternal(JSContext *ctx, JSValueConst this_obj, - JSAtom prop, JSValue val, +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, JS_PROP_THROW); + 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); @@ -764,6 +817,8 @@ JSValue JS_GetPrototype(JSContext *ctx, JSValueConst val); int JS_GetOwnPropertyNames(JSContext *ctx, JSPropertyEnum **ptab, uint32_t *plen, JSValueConst obj, int flags); +void JS_FreePropertyEnum(JSContext *ctx, JSPropertyEnum *tab, + uint32_t len); int JS_GetOwnProperty(JSContext *ctx, JSPropertyDescriptor *desc, JSValueConst obj, JSAtom prop); @@ -801,6 +856,7 @@ int JS_DefinePropertyGetSet(JSContext *ctx, JSValueConst this_obj, 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); +void *JS_GetAnyOpaque(JSValueConst 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, @@ -818,6 +874,24 @@ JSValue JS_NewArrayBuffer(JSContext *ctx, uint8_t *buf, size_t len, 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); + +typedef enum JSTypedArrayEnum { + JS_TYPED_ARRAY_UINT8C = 0, + JS_TYPED_ARRAY_INT8, + JS_TYPED_ARRAY_UINT8, + JS_TYPED_ARRAY_INT16, + JS_TYPED_ARRAY_UINT16, + JS_TYPED_ARRAY_INT32, + 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, + JSTypedArrayEnum array_type); JSValue JS_GetTypedArrayBuffer(JSContext *ctx, JSValueConst obj, size_t *pbyte_offset, size_t *pbyte_length, @@ -831,7 +905,15 @@ typedef struct { void JS_SetSharedArrayBufferFunctions(JSRuntime *rt, const JSSharedArrayBufferFunctions *sf); +typedef enum JSPromiseStateEnum { + JS_PROMISE_PENDING, + JS_PROMISE_FULFILLED, + 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); /* is_handled = TRUE means that the rejection is handled */ typedef void JSHostPromiseRejectionTracker(JSContext *ctx, JSValueConst promise, @@ -844,6 +926,12 @@ 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); +/* select which debug info is stripped from the compiled code */ +#define JS_STRIP_SOURCE (1 << 0) /* strip source code */ +#define JS_STRIP_DEBUG (1 << 1) /* strip all debug info including source code */ +void JS_SetStripInfo(JSRuntime *rt, int flags); +int JS_GetStripInfo(JSRuntime *rt); + /* set the [IsHTMLDDA] internal slot */ void JS_SetIsHTMLDDA(JSContext *ctx, JSValueConst obj); @@ -856,15 +944,29 @@ typedef char *JSModuleNormalizeFunc(JSContext *ctx, const char *module_name, void *opaque); typedef JSModuleDef *JSModuleLoaderFunc(JSContext *ctx, const char *module_name, void *opaque); - +typedef JSModuleDef *JSModuleLoaderFunc2(JSContext *ctx, + const char *module_name, void *opaque, + JSValueConst attributes); +/* return -1 if exception, 0 if OK */ +typedef int JSModuleCheckSupportedImportAttributes(JSContext *ctx, void *opaque, + JSValueConst attributes); + /* 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); +/* same as JS_SetModuleLoaderFunc but with attributes. if + module_check_attrs = NULL, no attribute checking is done. */ +void JS_SetModuleLoaderFunc2(JSRuntime *rt, + JSModuleNormalizeFunc *module_normalize, + JSModuleLoaderFunc2 *module_loader, + JSModuleCheckSupportedImportAttributes *module_check_attrs, + 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 Job support */ @@ -902,8 +1004,8 @@ int JS_ResolveModule(JSContext *ctx, JSValueConst obj); /* only exported for os.Worker() */ JSAtom JS_GetScriptOrModuleName(JSContext *ctx, int n_stack_levels); /* only exported for os.Worker() */ -JSModuleDef *JS_RunModule(JSContext *ctx, const char *basename, - const char *filename); +JSValue JS_LoadModule(JSContext *ctx, const char *basename, + const char *filename); /* C function definition */ typedef enum JSCFunctionEnum { /* XXX: should rename for namespace isolation */ @@ -955,10 +1057,12 @@ static inline JSValue JS_NewCFunctionMagic(JSContext *ctx, JSCFunctionMagic *fun const char *name, int length, JSCFunctionEnum cproto, int magic) { - return JS_NewCFunction2(ctx, (JSCFunction *)func, name, length, cproto, magic); + /* Used to squelch a -Wcast-function-type warning. */ + JSCFunctionType ft = { .generic_magic = func }; + return JS_NewCFunction2(ctx, ft.generic, name, length, cproto, magic); } -void JS_SetConstructor(JSContext *ctx, JSValueConst func_obj, - JSValueConst proto); +int JS_SetConstructor(JSContext *ctx, JSValueConst func_obj, + JSValueConst proto); /* C property definition */ @@ -1002,6 +1106,8 @@ typedef struct JSCFunctionListEntry { #define JS_DEF_PROP_UNDEFINED 7 #define JS_DEF_OBJECT 8 #define JS_DEF_ALIAS 9 +#define JS_DEF_PROP_ATOM 10 +#define JS_DEF_PROP_BOOL 11 /* 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 } } } } @@ -1015,13 +1121,15 @@ typedef struct JSCFunctionListEntry { #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_PROP_ATOM_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_ATOM, 0, .u = { .i32 = val } } +#define JS_PROP_BOOL_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_BOOL, 0, .u = { .i32 = val } } #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); +int JS_SetPropertyFunctionList(JSContext *ctx, JSValueConst obj, + const JSCFunctionListEntry *tab, + int len); /* C module definition */ @@ -1038,6 +1146,29 @@ 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); +/* associate a JSValue to a C module */ +int JS_SetModulePrivateValue(JSContext *ctx, JSModuleDef *m, JSValue val); +JSValue JS_GetModulePrivateValue(JSContext *ctx, JSModuleDef *m); + +/* debug value output */ + +typedef struct { + JS_BOOL show_hidden : 8; /* only show enumerable properties */ + JS_BOOL raw_dump : 8; /* avoid doing autoinit and avoid any malloc() call (for internal use) */ + uint32_t max_depth; /* recurse up to this depth, 0 = no limit */ + uint32_t max_string_length; /* print no more than this length for + strings, 0 = no limit */ + uint32_t max_item_count; /* print no more than this count for + arrays or objects, 0 = no limit */ +} JSPrintValueOptions; + +typedef void JSPrintValueWrite(void *opaque, const char *buf, size_t len); + +void JS_PrintValueSetDefaultOptions(JSPrintValueOptions *options); +void JS_PrintValueRT(JSRuntime *rt, JSPrintValueWrite *write_func, void *write_opaque, + JSValueConst val, const JSPrintValueOptions *options); +void JS_PrintValue(JSContext *ctx, JSPrintValueWrite *write_func, void *write_opaque, + JSValueConst val, const JSPrintValueOptions *options); #undef js_unlikely #undef js_force_inline diff --git a/thirdparty/quickjs b/thirdparty/quickjs index 2788d71..04be246 160000 --- a/thirdparty/quickjs +++ b/thirdparty/quickjs @@ -1 +1 @@ -Subproject commit 2788d71e823b522b178db3b3660ce93689534e6d +Subproject commit 04be246001599f5995fa2f2d8c91a0f198d3f34c