From 6380716e70b8ea92739b5b2f6a1228156feab3ec Mon Sep 17 00:00:00 2001 From: Ivan Komissarov Date: Sun, 19 May 2024 18:07:38 +0300 Subject: [PATCH] Apply qbs changes --- cutils.c | 3 +- cutils.h | 56 ++++- libbf.c | 4 +- libbf.h | 28 ++- libregexp.c | 2 +- libunicode.c | 58 ++--- quickjs.c | 638 ++++++++++++++++++++++++++++++++++++--------------- quickjs.h | 161 ++++++------- 8 files changed, 630 insertions(+), 320 deletions(-) diff --git a/cutils.c b/cutils.c index c0aacef69..95ae5688d 100644 --- a/cutils.c +++ b/cutils.c @@ -166,8 +166,7 @@ int dbuf_putstr(DynBuf *s, const char *str) return dbuf_put(s, (const uint8_t *)str, strlen(str)); } -int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s, - const char *fmt, ...) +int FORMAT_ATTR(2, 3) dbuf_printf(DynBuf *s, const char *fmt, ...) { va_list ap; char buf[128]; diff --git a/cutils.h b/cutils.h index f079e5c5e..265fd0aee 100644 --- a/cutils.h +++ b/cutils.h @@ -29,11 +29,30 @@ #include #include +#if defined(_MSC_VER) +#include +typedef SSIZE_T ssize_t; +#else +#include +#endif + +#ifdef __GNUC__ #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) #define force_inline inline __attribute__((always_inline)) #define no_inline __attribute__((noinline)) #define __maybe_unused __attribute__((unused)) +#else +#define likely(x) (x) +#define unlikely(x) (x) +#define force_inline +#define no_inline +#define __maybe_unused +#endif + +#ifdef _MSC_VER +#define alloca _alloca +#endif #define xglue(x, y) x ## y #define glue(x, y) xglue(x, y) @@ -128,38 +147,54 @@ static inline int64_t min_int64(int64_t a, int64_t b) /* WARNING: undefined if a = 0 */ static inline int clz32(unsigned int a) { +#ifdef _MSC_VER + return (int) __lzcnt(a); +#else return __builtin_clz(a); +#endif } /* WARNING: undefined if a = 0 */ static inline int clz64(uint64_t a) { +#ifdef _MSC_VER + return (int) __lzcnt64(a); +#else return __builtin_clzll(a); +#endif } /* WARNING: undefined if a = 0 */ static inline int ctz32(unsigned int a) { +#ifdef _MSC_VER + return (int) _tzcnt_u32(a); +#else return __builtin_ctz(a); +#endif } /* WARNING: undefined if a = 0 */ static inline int ctz64(uint64_t a) { +#ifdef _MSC_VER + return (int) _tzcnt_u64(a); +#else return __builtin_ctzll(a); +#endif } -struct __attribute__((packed)) packed_u64 { +#pragma pack(push, 1) +struct packed_u64 { uint64_t v; }; - -struct __attribute__((packed)) packed_u32 { +struct packed_u32 { uint32_t v; }; - -struct __attribute__((packed)) packed_u16 { +struct packed_u16 { uint16_t v; }; +#pragma pack(pop) static inline uint64_t get_u64(const uint8_t *tab) { @@ -282,8 +317,15 @@ static inline int dbuf_put_u64(DynBuf *s, uint64_t val) { return dbuf_put(s, (uint8_t *)&val, 8); } -int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s, - const char *fmt, ...); + +#ifdef __GNUC__ +#define FORMAT_ATTR(x, y) __attribute__((format(printf, x, y))) +#else +#define FORMAT_ATTR(x, y) +#endif + +int FORMAT_ATTR(2, 3) dbuf_printf(DynBuf *s, const char *fmt, ...); + void dbuf_free(DynBuf *s); static inline BOOL dbuf_error(DynBuf *s) { return s->error; diff --git a/libbf.c b/libbf.c index 05d62ed63..56b2be861 100644 --- a/libbf.c +++ b/libbf.c @@ -37,12 +37,10 @@ /* enable it to check the multiplication result */ //#define USE_MUL_CHECK -#ifdef CONFIG_BIGNUM /* enable it to use FFT/NTT multiplication */ #define USE_FFT_MUL /* enable decimal floating point support */ #define USE_BF_DEC -#endif //#define inline __attribute__((always_inline)) @@ -5499,6 +5497,7 @@ static inline limb_t fast_udiv(limb_t a, const FastDivData *s) return (t1 + t0) >> s->shift2; } +#endif // USE_BF_DEC /* contains 10^i */ const limb_t mp_pow_dec[LIMB_DIGITS + 1] = { 1U, @@ -5524,6 +5523,7 @@ const limb_t mp_pow_dec[LIMB_DIGITS + 1] = { 10000000000000000000U, #endif }; +#ifdef USE_BF_DEC /* precomputed from fast_udiv_init(10^i) */ static const FastDivData mp_pow_div[LIMB_DIGITS + 1] = { diff --git a/libbf.h b/libbf.h index a1436ab56..b247952b1 100644 --- a/libbf.h +++ b/libbf.h @@ -1,6 +1,6 @@ /* * Tiny arbitrary precision floating point library - * + * * Copyright (c) 2017-2021 Fabrice Bellard * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -27,6 +27,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + #if defined(__SIZEOF_INT128__) && (INTPTR_MAX >= INT64_MAX) #define LIMB_LOG2_BITS 6 #else @@ -171,7 +175,7 @@ static inline bf_flags_t bf_set_exp_bits(int n) #define BF_ST_UNDERFLOW (1 << 3) #define BF_ST_INEXACT (1 << 4) /* indicate that a memory allocation error occured. NaN is returned */ -#define BF_ST_MEM_ERROR (1 << 5) +#define BF_ST_MEM_ERROR (1 << 5) #define BF_RADIX_MAX 36 /* maximum radix for bf_atof() and bf_ftoa() */ @@ -284,7 +288,7 @@ int bf_sub(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags) int bf_add_si(bf_t *r, const bf_t *a, int64_t b1, limb_t prec, bf_flags_t flags); int bf_mul(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags); int bf_mul_ui(bf_t *r, const bf_t *a, uint64_t b1, limb_t prec, bf_flags_t flags); -int bf_mul_si(bf_t *r, const bf_t *a, int64_t b1, limb_t prec, +int bf_mul_si(bf_t *r, const bf_t *a, int64_t b1, limb_t prec, bf_flags_t flags); int bf_mul_2exp(bf_t *r, slimb_t e, limb_t prec, bf_flags_t flags); int bf_div(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags); @@ -341,12 +345,12 @@ int bf_mul_pow_radix(bf_t *r, const bf_t *T, limb_t radix, /* fractional format: prec digits after the decimal point rounded with (flags & BF_RND_MASK) */ #define BF_FTOA_FORMAT_FRAC (1 << 16) -/* free format: - +/* free format: + For binary radices with bf_ftoa() and for bfdec_ftoa(): use the minimum number of digits to represent 'a'. The precision and the rounding mode are ignored. - + For the non binary radices with bf_ftoa(): use as many digits as necessary so that bf_atof() return the same number when using precision 'prec', rounding to nearest and the subnormal @@ -373,7 +377,7 @@ char *bf_ftoa(size_t *plen, const bf_t *a, int radix, limb_t prec, bf_flags_t flags); /* modulo 2^n instead of saturation. NaN and infinity return 0 */ -#define BF_GET_INT_MOD (1 << 0) +#define BF_GET_INT_MOD (1 << 0) int bf_get_int32(int *pres, const bf_t *a, int flags); int bf_get_int64(int64_t *pres, const bf_t *a, int flags); int bf_get_uint64(uint64_t *pres, const bf_t *a); @@ -387,10 +391,10 @@ int bf_normalize_and_round(bf_t *r, limb_t prec1, bf_flags_t flags); int bf_can_round(const bf_t *a, slimb_t prec, bf_rnd_t rnd_mode, slimb_t k); slimb_t bf_mul_log2_radix(slimb_t a1, unsigned int radix, int is_inv, int is_ceil1); -int mp_mul(bf_context_t *s, limb_t *result, - const limb_t *op1, limb_t op1_size, +int mp_mul(bf_context_t *s, limb_t *result, + const limb_t *op1, limb_t op1_size, const limb_t *op2, limb_t op2_size); -limb_t mp_add(limb_t *res, const limb_t *op1, const limb_t *op2, +limb_t mp_add(limb_t *res, const limb_t *op1, const limb_t *op2, limb_t n, limb_t carry); limb_t mp_add_ui(limb_t *tab, limb_t b, size_t n); int mp_sqrtrem(bf_context_t *s, limb_t *tabs, limb_t *taba, limb_t n); @@ -532,4 +536,8 @@ static inline int bfdec_resize(bfdec_t *r, limb_t len) } int bfdec_normalize_and_round(bfdec_t *r, limb_t prec1, bf_flags_t flags); +#ifdef __cplusplus +} /* extern "C" { */ +#endif + #endif /* LIBBF_H */ diff --git a/libregexp.c b/libregexp.c index d73a19f39..3acdee0f8 100644 --- a/libregexp.c +++ b/libregexp.c @@ -372,7 +372,7 @@ static void re_emit_op_u16(REParseState *s, int op, uint32_t val) dbuf_put_u16(&s->byte_code, val); } -static int __attribute__((format(printf, 2, 3))) re_parse_error(REParseState *s, const char *fmt, ...) +static int FORMAT_ATTR(2, 3) re_parse_error(REParseState *s, const char *fmt, ...) { va_list ap; va_start(ap, fmt); diff --git a/libunicode.c b/libunicode.c index 4200252d3..8c000d3a4 100644 --- a/libunicode.c +++ b/libunicode.c @@ -1,6 +1,6 @@ /* * Unicode utilities - * + * * Copyright (c) 2017-2018 Fabrice Bellard * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -149,9 +149,9 @@ static int lre_case_conv_entry(uint32_t *res, uint32_t c, int conv_type, uint32_ } /* conv_type: - 0 = to upper + 0 = to upper 1 = to lower - 2 = case folding (= to lower with modifications) + 2 = case folding (= to lower with modifications) */ int lre_case_conv(uint32_t *res, uint32_t c, int conv_type) { @@ -168,7 +168,7 @@ int lre_case_conv(uint32_t *res, uint32_t c, int conv_type) } else { uint32_t v, code, len; int idx, idx_min, idx_max; - + idx_min = 0; idx_max = countof(case_conv_table1) - 1; while (idx_min <= idx_max) { @@ -240,7 +240,7 @@ int lre_canonicalize(uint32_t c, BOOL is_unicode) } else { uint32_t v, code, len; int idx, idx_min, idx_max; - + idx_min = 0; idx_max = countof(case_conv_table1) - 1; while (idx_min <= idx_max) { @@ -311,7 +311,7 @@ static BOOL lre_is_in_table(uint32_t c, const uint8_t *table, uint32_t code, b, bit; int pos; const uint8_t *p; - + pos = get_index_pos(&code, c, index_table, index_table_len); if (pos < 0) return FALSE; /* outside the table */ @@ -344,7 +344,7 @@ BOOL lre_is_cased(uint32_t c) { uint32_t v, code, len; int idx, idx_min, idx_max; - + idx_min = 0; idx_max = countof(case_conv_table1) - 1; while (idx_min <= idx_max) { @@ -403,7 +403,7 @@ int cr_realloc(CharRange *cr, int size) { int new_size; uint32_t *new_buf; - + if (size > cr->size) { new_size = max_int(size, cr->size * 3 / 2); new_buf = cr->realloc_func(cr->mem_opaque, cr->points, @@ -430,7 +430,7 @@ static void cr_compress(CharRange *cr) { int i, j, k, len; uint32_t *pt; - + pt = cr->points; len = cr->len; i = 0; @@ -460,7 +460,7 @@ int cr_op(CharRange *cr, const uint32_t *a_pt, int a_len, { int a_idx, b_idx, is_in; uint32_t v; - + a_idx = 0; b_idx = 0; for(;;) { @@ -761,7 +761,7 @@ static int unicode_decomp_char(uint32_t *res, uint32_t c, BOOL is_compat1) { uint32_t v, type, is_compat, code, len; int idx_min, idx_max, idx; - + idx_min = 0; idx_max = countof(unicode_decomp_table1) - 1; while (idx_min <= idx_max) { @@ -791,7 +791,7 @@ static int unicode_compose_pair(uint32_t c0, uint32_t c1) uint32_t code, len, type, v, idx1, d_idx, d_offset, ch; int idx_min, idx_max, idx, d; uint32_t pair[2]; - + idx_min = 0; idx_max = countof(unicode_comp_table) - 1; while (idx_min <= idx_max) { @@ -827,7 +827,7 @@ static int unicode_get_cc(uint32_t c) uint32_t code, n, type, cc, c1, b; int pos; const uint8_t *p; - + pos = get_index_pos(&code, c, unicode_cc_index, sizeof(unicode_cc_index) / 3); if (pos < 0) @@ -876,7 +876,7 @@ static int unicode_get_cc(uint32_t c) static void sort_cc(int *buf, int len) { int i, j, k, cc, cc1, start, ch1; - + for(i = 0; i < len; i++) { cc = unicode_get_cc(buf[i]); if (cc != 0) { @@ -915,7 +915,7 @@ static void to_nfd_rec(DynBuf *dbuf, uint32_t c, v; int i, l; uint32_t res[UNICODE_DECOMP_LEN_MAX]; - + for(i = 0; i < src_len; i++) { c = src[i]; if (c >= 0xac00 && c < 0xd7a4) { @@ -960,7 +960,7 @@ int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len, int *buf, buf_len, i, p, starter_pos, cc, last_cc, out_len; BOOL is_compat; DynBuf dbuf_s, *dbuf = &dbuf_s; - + is_compat = n_type >> 1; dbuf_init2(dbuf, opaque, realloc_func); @@ -988,15 +988,15 @@ int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len, } buf = (int *)dbuf->buf; buf_len = dbuf->size / sizeof(int); - + sort_cc(buf, buf_len); - + if (buf_len <= 1 || (n_type & 1) != 0) { /* NFD / NFKD */ *pdst = (uint32_t *)buf; return buf_len; } - + i = 1; out_len = 1; while (i < buf_len) { @@ -1033,7 +1033,7 @@ static int unicode_find_name(const char *name_table, const char *name) const char *p, *r; int pos; size_t name_len, len; - + p = name_table; pos = 0; name_len = strlen(name); @@ -1066,13 +1066,13 @@ int unicode_script(CharRange *cr, CharRange cr1_s, *cr1; CharRange cr2_s, *cr2 = &cr2_s; BOOL is_common; - + script_idx = unicode_find_name(unicode_script_name_table, script_name); if (script_idx < 0) return -2; /* Note: we remove the "Unknown" Script */ script_idx += UNICODE_SCRIPT_Unknown + 1; - + is_common = (script_idx == UNICODE_SCRIPT_Common || script_idx == UNICODE_SCRIPT_Inherited); if (is_ext) { @@ -1350,7 +1350,7 @@ static int point_cmp(const void *p1, const void *p2, void *arg) static void cr_sort_and_remove_overlap(CharRange *cr) { uint32_t start, end, start1, end1, i, j; - + /* the resulting ranges are not necessarily sorted and may overlap */ rqsort(cr->points, cr->len / 2, sizeof(cr->points[0]) * 2, point_cmp, NULL); j = 0; @@ -1389,7 +1389,7 @@ int cr_regexp_canonicalize(CharRange *cr, BOOL is_unicode) { CharRange cr_inter, cr_mask, cr_result, cr_sub; uint32_t v, code, len, i, idx, start, end, c, d_start, d_end, d; - + cr_init(&cr_mask, cr->mem_opaque, cr->realloc_func); cr_init(&cr_inter, cr->mem_opaque, cr->realloc_func); cr_init(&cr_result, cr->mem_opaque, cr->realloc_func); @@ -1404,7 +1404,7 @@ int cr_regexp_canonicalize(CharRange *cr, BOOL is_unicode) goto fail; if (cr_op(&cr_sub, cr_mask.points, cr_mask.len, cr->points, cr->len, CR_OP_INTER)) goto fail; - + /* cr_inter = cr & cr_mask */ /* cr_sub = cr & ~cr_mask */ @@ -1488,7 +1488,7 @@ static int unicode_prop_ops(CharRange *cr, ...) CharRange stack[POP_STACK_LEN_MAX]; int stack_len, op, ret, i; uint32_t a; - + va_start(ap, cr); stack_len = 0; for(;;) { @@ -1547,11 +1547,13 @@ static int unicode_prop_ops(CharRange *cr, ...) } } done: + va_end(ap); assert(stack_len == 1); ret = cr_copy(cr, &stack[0]); cr_free(&stack[0]); return ret; fail: + va_end(ap); for(i = 0; i < stack_len; i++) cr_free(&stack[i]); return -1; @@ -1574,7 +1576,7 @@ int unicode_general_category(CharRange *cr, const char *gc_name) { int gc_idx; uint32_t gc_mask; - + gc_idx = unicode_find_name(unicode_gc_name_table, gc_name); if (gc_idx < 0) return -2; @@ -1592,7 +1594,7 @@ int unicode_general_category(CharRange *cr, const char *gc_name) int unicode_prop(CharRange *cr, const char *prop_name) { int prop_idx, ret; - + prop_idx = unicode_find_name(unicode_prop_name_table, prop_name); if (prop_idx < 0) return -2; diff --git a/quickjs.c b/quickjs.c index e8fdd8aa7..1754bcd62 100644 --- a/quickjs.c +++ b/quickjs.c @@ -28,7 +28,9 @@ #include #include #include +#ifndef _MSC_VER #include +#endif #include #include #include @@ -40,15 +42,27 @@ #include #endif +#ifdef _MSC_VER +#include +#include +#endif + +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) \ + || defined(__APPLE__) +#include +#else +#include +#endif + #include "cutils.h" #include "list.h" #include "quickjs.h" #include "libregexp.h" #include "libbf.h" -#define OPTIMIZE 1 +#define OPTIMIZE 0 #define SHORT_OPCODES 1 -#if defined(EMSCRIPTEN) +#if defined(EMSCRIPTEN) || defined(_MSC_VER) #define DIRECT_DISPATCH 0 #else #define DIRECT_DISPATCH 1 @@ -67,7 +81,7 @@ /* define to include Atomics.* operations which depend on the OS threads */ -#if !defined(EMSCRIPTEN) +#if !defined(EMSCRIPTEN) && !defined(_MSC_VER) #define CONFIG_ATOMICS #endif @@ -76,7 +90,6 @@ #define CONFIG_STACK_CHECK #endif - /* dump object free */ //#define DUMP_FREE //#define DUMP_CLOSURE @@ -114,6 +127,25 @@ #include #endif +static double safe_strtod(const char *restrict nptr, char **restrict endptr) +{ +#if defined(_MSC_VER) || defined(__MINGW32__) + _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); + setlocale(LC_NUMERIC, "C"); +#else + const locale_t tempLoc = newlocale(LC_NUMERIC_MASK, "C", 0); + uselocale(tempLoc); +#endif + double d = strtod(nptr, endptr); +#if defined(_MSC_VER) || defined(__MINGW32__) + _configthreadlocale(_DISABLE_PER_THREAD_LOCALE); +#else + uselocale(LC_GLOBAL_LOCALE); + freelocale(tempLoc); +#endif + return d; +} + enum { /* classid tag */ /* union usage | properties */ JS_CLASS_OBJECT = 1, /* must be first */ @@ -201,7 +233,11 @@ typedef enum JSErrorEnum { #define JS_STACK_SIZE_MAX 65534 #define JS_STRING_LEN_MAX ((1 << 30) - 1) +#ifdef __GNUC__ #define __exception __attribute__((warn_unused_result)) +#else +#define __exception +#endif typedef struct JSShape JSShape; typedef struct JSString JSString; @@ -453,8 +489,12 @@ struct JSContext { /* if NULL, eval is not supported */ JSValue (*eval_internal)(JSContext *ctx, JSValueConst this_obj, const char *input, size_t input_len, - const char *filename, int flags, int scope_idx); + const char *filename, int line, int flags, int scope_idx); void *user_opaque; + ScopeLookup *scopeLookup; + FoundUndefinedHandler *handleUndefined; + FunctionEnteredHandler *handleFunctionEntered; + FunctionExitedHandler *handleFunctionExited; }; typedef union JSFloat64Union { @@ -1041,7 +1081,6 @@ static __exception int JS_ToArrayLengthFree(JSContext *ctx, uint32_t *plen, JSValue val, BOOL is_array_ctor); static JSValue JS_EvalObject(JSContext *ctx, JSValueConst this_obj, JSValueConst val, int flags, int scope_idx); -JSValue __attribute__((format(printf, 2, 3))) JS_ThrowInternalError(JSContext *ctx, const char *fmt, ...); static __maybe_unused void JS_DumpAtoms(JSRuntime *rt); static __maybe_unused void JS_DumpString(JSRuntime *rt, const JSString *p); static __maybe_unused void JS_DumpObjectHeader(JSRuntime *rt); @@ -1169,7 +1208,6 @@ static JSValue JS_ToBigDecimalFree(JSContext *ctx, JSValue val, BOOL allow_null_or_undefined); static bfdec_t *JS_ToBigDecimal(JSContext *ctx, JSValueConst val); #endif -JSValue JS_ThrowOutOfMemory(JSContext *ctx); static JSValue JS_ThrowTypeErrorRevokedProxy(JSContext *ctx); static JSValue js_proxy_getPrototypeOf(JSContext *ctx, JSValueConst obj); static int js_proxy_setPrototypeOf(JSContext *ctx, JSValueConst obj, @@ -1214,7 +1252,7 @@ static void js_async_function_resolve_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); static JSValue JS_EvalInternal(JSContext *ctx, JSValueConst this_obj, const char *input, size_t input_len, - const char *filename, int flags, int scope_idx); + const char *filename, int line, int flags, int scope_idx); static void js_free_module_def(JSContext *ctx, JSModuleDef *m); static void js_mark_module_def(JSRuntime *rt, JSModuleDef *m, JS_MarkFunc *mark_func); @@ -1607,10 +1645,27 @@ static inline BOOL js_check_stack_overflow(JSRuntime *rt, size_t alloca_size) return FALSE; } #else -/* Note: OS and CPU dependent */ +// Uses code from LLVM project. static inline uintptr_t js_get_stack_pointer(void) { - return (uintptr_t)__builtin_frame_address(0); +#ifdef _MSC_VER + return (uintptr_t) _AddressOfReturnAddress(); +#elif defined __has_builtin +#if __has_builtin(__builtin_frame_address) + return (uintptr_t) __builtin_frame_address(0); +#endif +#elif defined __GNUC__ + return (uintptr_t) __builtin_frame_address(0); +#else + char CharOnStack = 0; + // The volatile store here is intended to escape the local variable, to + // prevent the compiler from optimizing CharOnStack into anything other + // than a char on the stack. + // + // Tested on: MSVC 2015 - 2019, GCC 4.9 - 9, Clang 3.2 - 9, ICC 13 - 19. + char *volatile Ptr = &CharOnStack; + return (uintptr_t) Ptr; +#endif } static inline BOOL js_check_stack_overflow(JSRuntime *rt, size_t alloca_size) @@ -1994,6 +2049,7 @@ void JS_FreeRuntime(JSRuntime *rt) printf("Secondary object leaks: %d\n", count); } #endif + fflush(stdout); assert(list_empty(&rt->gc_obj_list)); /* free the classes */ @@ -5515,7 +5571,7 @@ static void free_zero_refcount(JSRuntime *rt) } /* called with the ref_count of 'v' reaches zero. */ -void __JS_FreeValueRT(JSRuntime *rt, JSValue v) +static void __JS_FreeValueRT(JSRuntime *rt, JSValue v) { uint32_t tag = JS_VALUE_GET_TAG(v); @@ -5592,7 +5648,7 @@ void __JS_FreeValueRT(JSRuntime *rt, JSValue v) } } -void __JS_FreeValue(JSContext *ctx, JSValue v) +static void __JS_FreeValue(JSContext *ctx, JSValue v) { __JS_FreeValueRT(ctx->rt, v); } @@ -6529,7 +6585,7 @@ static const char *get_func_name(JSContext *ctx, JSValueConst func) /* if filename != NULL, an additional level is added with the filename and line number information (used for parse error). */ -static void build_backtrace(JSContext *ctx, JSValueConst error_obj, +void build_backtrace(JSContext *ctx, JSValueConst error_obj, const char *filename, int line_num, int backtrace_flags) { @@ -6629,7 +6685,7 @@ JSValue JS_NewError(JSContext *ctx) static JSValue JS_ThrowError2(JSContext *ctx, JSErrorEnum error_num, const char *fmt, va_list ap, BOOL add_backtrace) { - char buf[256]; + char buf[8192]; JSValue obj, ret; vsnprintf(buf, sizeof(buf), fmt, ap); @@ -6664,7 +6720,7 @@ static JSValue JS_ThrowError(JSContext *ctx, JSErrorEnum error_num, return JS_ThrowError2(ctx, error_num, fmt, ap, add_backtrace); } -JSValue __attribute__((format(printf, 2, 3))) JS_ThrowSyntaxError(JSContext *ctx, const char *fmt, ...) +JSValue FORMAT_ATTR(2, 3) JS_ThrowSyntaxError(JSContext *ctx, const char *fmt, ...) { JSValue val; va_list ap; @@ -6675,7 +6731,7 @@ JSValue __attribute__((format(printf, 2, 3))) JS_ThrowSyntaxError(JSContext *ctx return val; } -JSValue __attribute__((format(printf, 2, 3))) JS_ThrowTypeError(JSContext *ctx, const char *fmt, ...) +JSValue FORMAT_ATTR(2, 3) JS_ThrowTypeError(JSContext *ctx, const char *fmt, ...) { JSValue val; va_list ap; @@ -6686,7 +6742,7 @@ JSValue __attribute__((format(printf, 2, 3))) JS_ThrowTypeError(JSContext *ctx, return val; } -static int __attribute__((format(printf, 3, 4))) JS_ThrowTypeErrorOrFalse(JSContext *ctx, int flags, const char *fmt, ...) +static int FORMAT_ATTR(3, 4) JS_ThrowTypeErrorOrFalse(JSContext *ctx, int flags, const char *fmt, ...) { va_list ap; @@ -6702,7 +6758,7 @@ static int __attribute__((format(printf, 3, 4))) JS_ThrowTypeErrorOrFalse(JSCont } /* never use it directly */ -static JSValue __attribute__((format(printf, 3, 4))) __JS_ThrowTypeErrorAtom(JSContext *ctx, JSAtom atom, const char *fmt, ...) +static JSValue FORMAT_ATTR(3, 4) __JS_ThrowTypeErrorAtom(JSContext *ctx, JSAtom atom, const char *fmt, ...) { char buf[ATOM_GET_STR_BUF_SIZE]; return JS_ThrowTypeError(ctx, fmt, @@ -6710,7 +6766,7 @@ static JSValue __attribute__((format(printf, 3, 4))) __JS_ThrowTypeErrorAtom(JSC } /* never use it directly */ -static JSValue __attribute__((format(printf, 3, 4))) __JS_ThrowSyntaxErrorAtom(JSContext *ctx, JSAtom atom, const char *fmt, ...) +static JSValue FORMAT_ATTR(3, 4) __JS_ThrowSyntaxErrorAtom(JSContext *ctx, JSAtom atom, const char *fmt, ...) { char buf[ATOM_GET_STR_BUF_SIZE]; return JS_ThrowSyntaxError(ctx, fmt, @@ -6733,7 +6789,7 @@ static int JS_ThrowTypeErrorReadOnly(JSContext *ctx, int flags, JSAtom atom) } } -JSValue __attribute__((format(printf, 2, 3))) JS_ThrowReferenceError(JSContext *ctx, const char *fmt, ...) +JSValue FORMAT_ATTR(2, 3) JS_ThrowReferenceError(JSContext *ctx, const char *fmt, ...) { JSValue val; va_list ap; @@ -6744,7 +6800,7 @@ JSValue __attribute__((format(printf, 2, 3))) JS_ThrowReferenceError(JSContext * return val; } -JSValue __attribute__((format(printf, 2, 3))) JS_ThrowRangeError(JSContext *ctx, const char *fmt, ...) +JSValue FORMAT_ATTR(2, 3) JS_ThrowRangeError(JSContext *ctx, const char *fmt, ...) { JSValue val; va_list ap; @@ -6755,7 +6811,7 @@ JSValue __attribute__((format(printf, 2, 3))) JS_ThrowRangeError(JSContext *ctx, return val; } -JSValue __attribute__((format(printf, 2, 3))) JS_ThrowInternalError(JSContext *ctx, const char *fmt, ...) +JSValue FORMAT_ATTR(2, 3) JS_ThrowInternalError(JSContext *ctx, const char *fmt, ...) { JSValue val; va_list ap; @@ -7204,6 +7260,8 @@ JSValue JS_GetPropertyInternal(JSContext *ctx, JSValueConst obj, continue; } } else { + if (JS_IsUndefined(pr->u.value) && ctx->handleUndefined) + ctx->handleUndefined(ctx); return JS_DupValue(ctx, pr->u.value); } } @@ -7302,7 +7360,7 @@ static int JS_DefinePrivateField(JSContext *ctx, JSValueConst obj, JS_ThrowTypeErrorNotASymbol(ctx); goto fail; } - prop = js_symbol_to_atom(ctx, (JSValue)name); + prop = js_symbol_to_atom(ctx, name); p = JS_VALUE_GET_OBJ(obj); prs = find_own_property(&pr, p, prop); if (prs) { @@ -7333,7 +7391,7 @@ static JSValue JS_GetPrivateField(JSContext *ctx, JSValueConst obj, /* safety check */ if (unlikely(JS_VALUE_GET_TAG(name) != JS_TAG_SYMBOL)) return JS_ThrowTypeErrorNotASymbol(ctx); - prop = js_symbol_to_atom(ctx, (JSValue)name); + prop = js_symbol_to_atom(ctx, name); p = JS_VALUE_GET_OBJ(obj); prs = find_own_property(&pr, p, prop); if (!prs) { @@ -7360,7 +7418,7 @@ static int JS_SetPrivateField(JSContext *ctx, JSValueConst obj, JS_ThrowTypeErrorNotASymbol(ctx); goto fail; } - prop = js_symbol_to_atom(ctx, (JSValue)name); + prop = js_symbol_to_atom(ctx, name); p = JS_VALUE_GET_OBJ(obj); prs = find_own_property(&pr, p, prop); if (!prs) { @@ -7459,7 +7517,7 @@ static int JS_CheckBrand(JSContext *ctx, JSValueConst obj, JSValueConst func) return -1; } p = JS_VALUE_GET_OBJ(obj); - prs = find_own_property(&pr, p, js_symbol_to_atom(ctx, (JSValue)brand)); + prs = find_own_property(&pr, p, js_symbol_to_atom(ctx, brand)); return (prs != NULL); } @@ -9079,7 +9137,7 @@ int JS_DefineProperty(JSContext *ctx, JSValueConst this_obj, return -1; } /* this code relies on the fact that Uint32 are never allocated */ - val = (JSValueConst)JS_NewUint32(ctx, array_length); + val = JS_NewUint32(ctx, array_length); /* prs may have been modified */ prs = find_own_property(&pr, p, prop); assert(prs != NULL); @@ -9604,6 +9662,11 @@ static JSValue JS_GetGlobalVar(JSContext *ctx, JSAtom prop, return JS_ThrowReferenceErrorUninitialized(ctx, prs->atom); return JS_DupValue(ctx, pr->u.value); } + if (ctx->scopeLookup) { + struct LookupResult result = ctx->scopeLookup(ctx, prop); + if (result.useResult) + return result.value; + } return JS_GetPropertyInternal(ctx, ctx->global_obj, prop, ctx->global_obj, throw_ref_error); } @@ -9699,6 +9762,15 @@ static int JS_SetGlobalVar(JSContext *ctx, JSAtom prop, JSValue val, flags = JS_PROP_THROW_STRICT; if (is_strict_mode(ctx)) flags |= JS_PROP_NO_ADD; + + if (ctx->scopeLookup) { + struct LookupResult result = ctx->scopeLookup(ctx, prop); + if (result.useResult) { + JS_FreeValue(ctx, result.value); + return JS_SetPropertyInternal(ctx, ctx->global_obj, prop, val, result.scope, flags); + } + } + return JS_SetPropertyInternal(ctx, ctx->global_obj, prop, val, ctx->global_obj, flags); } @@ -9791,6 +9863,14 @@ BOOL JS_SetConstructorBit(JSContext *ctx, JSValueConst func_obj, BOOL val) return TRUE; } +JS_BOOL JS_IsArrayBuffer(JSValueConst v) +{ + if (!JS_IsObject(v)) + return FALSE; + JSObject *p = JS_VALUE_GET_OBJ(v); + return p->class_id == JS_CLASS_ARRAY_BUFFER || p->class_id == JS_CLASS_SHARED_ARRAY_BUFFER; +} + BOOL JS_IsError(JSContext *ctx, JSValueConst val) { JSObject *p; @@ -10098,7 +10178,7 @@ static double js_strtod(const char *str, int radix, BOOL is_float) d = -d; } else { strtod_case: - d = strtod(str, NULL); + d = safe_strtod(str, NULL); } return d; } @@ -10286,7 +10366,7 @@ static JSValue js_atof(JSContext *ctx, const char *str, const char **pp, } else #endif { - double d = 1.0 / 0.0; + double d = INFINITY; if (is_neg) d = -d; val = JS_NewFloat64(ctx, d); @@ -10319,11 +10399,8 @@ static JSValue js_atof(JSContext *ctx, const char *str, const char **pp, ((*p == 'p' || *p == 'P') && (radix == 2 || radix == 8 || radix == 16)))) { const char *p1 = p + 1; is_float = TRUE; - if (*p1 == '+') { - p1++; - } else if (*p1 == '-') { + if (*p1 == '+' || *p1 == '-') p1++; - } if (is_digit((uint8_t)*p1)) { p = p1 + 1; while (is_digit((uint8_t)*p) || (*p == sep && is_digit((uint8_t)p[1]))) @@ -11079,8 +11156,6 @@ static __exception int JS_ToArrayLengthFree(JSContext *ctx, uint32_t *plen, if (JS_TAG_IS_FLOAT64(tag)) { double d; d = JS_VALUE_GET_FLOAT64(val); - if (!(d >= 0 && d <= UINT32_MAX)) - goto fail; len = (uint32_t)d; if (len != d) goto fail; @@ -11402,7 +11477,7 @@ static int js_ecvt(double d, int n_digits, int *decpt, int *sign, char *buf, n_digits = (n_digits_min + n_digits_max) / 2; js_ecvt1(d, n_digits, decpt, sign, buf, FE_TONEAREST, buf_tmp, sizeof(buf_tmp)); - if (strtod(buf_tmp, NULL) == d) { + if (safe_strtod(buf_tmp, NULL) == d) { /* no need to keep the trailing zeros */ while (n_digits >= 2 && buf[n_digits - 1] == '0') n_digits--; @@ -12995,7 +13070,7 @@ static int js_unary_arith_bigint(JSContext *ctx, return 0; } -static no_inline __exception int js_unary_arith_slow(JSContext *ctx, +static no_inline int __exception js_unary_arith_slow(JSContext *ctx, JSValue *sp, OPCodeEnum op) { @@ -13039,7 +13114,7 @@ static no_inline __exception int js_unary_arith_slow(JSContext *ctx, break; case OP_neg: if (v64 == 0) { - sp[-1] = __JS_NewFloat64(ctx, -0.0); + sp[-1] = JS_NewFloat64(ctx, -0.0); return 0; } else { v64 = -v64; @@ -13087,7 +13162,7 @@ static no_inline __exception int js_unary_arith_slow(JSContext *ctx, default: abort(); } - sp[-1] = __JS_NewFloat64(ctx, d); + sp[-1] = JS_NewFloat64(ctx, d); } break; } @@ -13539,14 +13614,14 @@ static no_inline __exception int js_binary_arith_slow(JSContext *ctx, JSValue *s (v < -MAX_SAFE_INTEGER || v > MAX_SAFE_INTEGER)) goto handle_bigint; if (v == 0 && (v1 | v2) < 0) { - sp[-2] = __JS_NewFloat64(ctx, -0.0); + sp[-2] = JS_NewFloat64(ctx, -0.0); return 0; } break; case OP_div: if (is_math_mode(ctx)) goto handle_bigint; - sp[-2] = __JS_NewFloat64(ctx, (double)v1 / (double)v2); + sp[-2] = JS_NewFloat64(ctx, (double)v1 / (double)v2); return 0; #ifdef CONFIG_BIGNUM case OP_math_mod: @@ -13637,7 +13712,7 @@ static no_inline __exception int js_binary_arith_slow(JSContext *ctx, JSValue *s default: abort(); } - sp[-2] = __JS_NewFloat64(ctx, dr); + sp[-2] = JS_NewFloat64(ctx, dr); } return 0; exception: @@ -13661,7 +13736,7 @@ static no_inline __exception int js_add_slow(JSContext *ctx, JSValue *sp) double d1, d2; d1 = JS_VALUE_GET_FLOAT64(op1); d2 = JS_VALUE_GET_FLOAT64(op2); - sp[-2] = __JS_NewFloat64(ctx, d1 + d2); + sp[-2] = JS_NewFloat64(ctx, d1 + d2); return 0; } @@ -13756,7 +13831,7 @@ static no_inline __exception int js_add_slow(JSContext *ctx, JSValue *sp) goto exception; if (is_math_mode(ctx) && is_safe_integer(d1) && is_safe_integer(d2)) goto handle_bigint; - sp[-2] = __JS_NewFloat64(ctx, d1 + d2); + sp[-2] = JS_NewFloat64(ctx, d1 + d2); } return 0; exception: @@ -14350,7 +14425,7 @@ static JSValue js_mul_pow10_to_float64(JSContext *ctx, const bf_t *a, if (ret & BF_ST_MEM_ERROR) return JS_ThrowOutOfMemory(ctx); else - return __JS_NewFloat64(ctx, d); + return JS_NewFloat64(ctx, d); } static no_inline int js_mul_pow10(JSContext *ctx, JSValue *sp) @@ -15980,7 +16055,7 @@ static JSValue js_call_c_function(JSContext *ctx, JSValueConst func_obj, #else sf->js_mode = 0; #endif - sf->cur_func = (JSValue)func_obj; + sf->cur_func = func_obj; sf->arg_count = argc; arg_buf = argv; @@ -15993,7 +16068,7 @@ static JSValue js_call_c_function(JSContext *ctx, JSValueConst func_obj, arg_buf[i] = JS_UNDEFINED; sf->arg_count = arg_count; } - sf->arg_buf = (JSValue*)arg_buf; + sf->arg_buf = arg_buf; func = p->u.cfunc.c_function; switch(cproto) { @@ -16164,7 +16239,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, #include "quickjs-opcode.h" [ OP_COUNT ... 255 ] = &&case_default }; -#define SWITCH(pc) goto *dispatch_table[opcode = *pc++]; +#define SWITCH(pc) goto *dispatch_table[opcode = *(pc)++]; #define CASE(op) case_ ## op #define DEFAULT case_default #define BREAK SWITCH(pc) @@ -16207,7 +16282,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, return JS_ThrowTypeError(caller_ctx, "not a function"); } return call_func(caller_ctx, func_obj, this_obj, argc, - (JSValueConst *)argv, flags); + argv, flags); } b = p->u.func.function_bytecode; @@ -16225,7 +16300,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, sf->js_mode = b->js_mode; arg_buf = argv; sf->arg_count = argc; - sf->cur_func = (JSValue)func_obj; + sf->cur_func = func_obj; init_list_head(&sf->var_ref_list); var_refs = p->u.func.var_refs; @@ -16253,6 +16328,9 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, rt->current_stack_frame = sf; ctx = b->realm; /* set the current realm */ + if (ctx->handleFunctionEntered) + ctx->handleFunctionEntered(ctx, this_obj); + restart: for(;;) { int call_argc; @@ -16358,12 +16436,12 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, int arg = *pc++; switch(arg) { case OP_SPECIAL_OBJECT_ARGUMENTS: - *sp++ = js_build_arguments(ctx, argc, (JSValueConst *)argv); + *sp++ = js_build_arguments(ctx, argc, argv); if (unlikely(JS_IsException(sp[-1]))) goto exception; break; case OP_SPECIAL_OBJECT_MAPPED_ARGUMENTS: - *sp++ = js_build_mapped_arguments(ctx, argc, (JSValueConst *)argv, + *sp++ = js_build_mapped_arguments(ctx, argc, argv, sf, min_int(argc, b->arg_count)); if (unlikely(JS_IsException(sp[-1]))) goto exception; @@ -16403,7 +16481,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, { int first = get_u16(pc); pc += 2; - *sp++ = js_build_rest(ctx, first, argc, (JSValueConst *)argv); + *sp++ = js_build_rest(ctx, first, argc, argv); if (unlikely(JS_IsException(sp[-1]))) goto exception; } @@ -16655,7 +16733,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, magic = get_u16(pc); pc += 2; - ret_val = js_function_apply(ctx, sp[-3], 2, (JSValueConst *)&sp[-2], magic); + ret_val = js_function_apply(ctx, sp[-3], 2, &sp[-2], magic); if (unlikely(JS_IsException(ret_val))) goto exception; JS_FreeValue(ctx, sp[-3]); @@ -16795,7 +16873,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, JS_EVAL_TYPE_DIRECT, scope_idx); } else { ret_val = JS_Call(ctx, sp[-2], JS_UNDEFINED, len, - (JSValueConst *)tab); + tab); } free_arg_list(ctx, tab, len); if (unlikely(JS_IsException(ret_val))) @@ -17428,7 +17506,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, { JSValue ret; ret = JS_Call(ctx, sp[-3], sp[-4], - 1, (JSValueConst *)(sp - 1)); + 1, (sp - 1)); if (JS_IsException(ret)) goto exception; JS_FreeValue(ctx, sp[-1]); @@ -17456,7 +17534,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, 0, NULL); } else { ret = JS_CallFree(ctx, method, sp[-4], - 1, (JSValueConst *)(sp - 1)); + 1, (sp - 1)); } if (JS_IsException(ret)) goto exception; @@ -18632,6 +18710,13 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, } } exception: + if (JS_IsString(rt->current_exception)) { + JSValue error_obj = JS_NewError(ctx); + JSAtom msgProp = JS_NewAtom(ctx, "message"); + JS_DefinePropertyValue(ctx, error_obj, msgProp, rt->current_exception, 0); + rt->current_exception = error_obj; + JS_FreeAtom(ctx, msgProp); + } if (is_backtrace_needed(ctx, rt->current_exception)) { /* add the backtrace information now (it is not done before if the exception happens in a bytecode @@ -18679,6 +18764,8 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, } } rt->current_stack_frame = sf->prev_frame; + if (ctx->handleFunctionExited) + ctx->handleFunctionExited(ctx); return ret_val; } @@ -18686,14 +18773,14 @@ JSValue JS_Call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, int argc, JSValueConst *argv) { return JS_CallInternal(ctx, func_obj, this_obj, JS_UNDEFINED, - argc, (JSValue *)argv, JS_CALL_FLAG_COPY_ARGV); + argc, argv, JS_CALL_FLAG_COPY_ARGV); } static JSValue JS_CallFree(JSContext *ctx, JSValue func_obj, JSValueConst this_obj, int argc, JSValueConst *argv) { JSValue res = JS_CallInternal(ctx, func_obj, this_obj, JS_UNDEFINED, - argc, (JSValue *)argv, JS_CALL_FLAG_COPY_ARGV); + argc, argv, JS_CALL_FLAG_COPY_ARGV); JS_FreeValue(ctx, func_obj); return res; } @@ -18798,7 +18885,7 @@ static JSValue JS_CallConstructorInternal(JSContext *ctx, return JS_ThrowTypeError(ctx, "not a function"); } return call_func(ctx, func_obj, new_target, argc, - (JSValueConst *)argv, flags); + argv, flags); } b = p->u.func.function_bytecode; @@ -18827,7 +18914,7 @@ JSValue JS_CallConstructor2(JSContext *ctx, JSValueConst func_obj, int argc, JSValueConst *argv) { return JS_CallConstructorInternal(ctx, func_obj, new_target, - argc, (JSValue *)argv, + argc, argv, JS_CALL_FLAG_COPY_ARGV); } @@ -18835,7 +18922,7 @@ JSValue JS_CallConstructor(JSContext *ctx, JSValueConst func_obj, int argc, JSValueConst *argv) { return JS_CallConstructorInternal(ctx, func_obj, func_obj, - argc, (JSValue *)argv, + argc, argv, JS_CALL_FLAG_COPY_ARGV); } @@ -19214,13 +19301,13 @@ static void js_async_function_resume(JSContext *ctx, JSAsyncFunctionState *s) fail: error = JS_GetException(ctx); ret2 = JS_Call(ctx, s->resolving_funcs[1], JS_UNDEFINED, - 1, (JSValueConst *)&error); + 1, &error); JS_FreeValue(ctx, error); JS_FreeValue(ctx, ret2); /* XXX: what to do if exception ? */ } else { /* normal return */ ret2 = JS_Call(ctx, s->resolving_funcs[0], JS_UNDEFINED, - 1, (JSValueConst *)&func_ret); + 1, &func_ret); JS_FreeValue(ctx, func_ret); JS_FreeValue(ctx, ret2); /* XXX: what to do if exception ? */ } @@ -19234,7 +19321,7 @@ static void js_async_function_resume(JSContext *ctx, JSAsyncFunctionState *s) /* await */ JS_FreeValue(ctx, func_ret); /* not used */ promise = js_promise_resolve(ctx, ctx->promise_ctor, - 1, (JSValueConst *)&value, 0); + 1, &value, 0); JS_FreeValue(ctx, value); if (JS_IsException(promise)) goto fail; @@ -19509,7 +19596,7 @@ static int js_async_generator_completed_return(JSContext *ctx, // exception should be delivered to the catch handler. if (JS_IsException(promise)) { JSValue err = JS_GetException(ctx); - promise = js_promise_resolve(ctx, ctx->promise_ctor, 1, (JSValueConst *)&err, + promise = js_promise_resolve(ctx, ctx->promise_ctor, 1, &err, /*is_reject*/1); JS_FreeValue(ctx, err); if (JS_IsException(promise)) @@ -19688,7 +19775,7 @@ static JSValue js_async_generator_next(JSContext *ctx, JSValueConst this_val, JS_ThrowTypeError(ctx, "not an AsyncGenerator object"); err = JS_GetException(ctx); res2 = JS_Call(ctx, resolving_funcs[1], JS_UNDEFINED, - 1, (JSValueConst *)&err); + 1, &err); JS_FreeValue(ctx, err); JS_FreeValue(ctx, res2); JS_FreeValue(ctx, resolving_funcs[0]); @@ -20152,7 +20239,7 @@ static void free_token(JSParseState *s, JSToken *token) } } -static void __attribute((unused)) dump_token(JSParseState *s, +static void __maybe_unused dump_token(JSParseState *s, const JSToken *token) { switch(token->val) { @@ -20213,7 +20300,7 @@ static void __attribute((unused)) dump_token(JSParseState *s, } } -int __attribute__((format(printf, 2, 3))) js_parse_error(JSParseState *s, const char *fmt, ...) +int FORMAT_ATTR(2, 3) js_parse_error(JSParseState *s, const char *fmt, ...) { JSContext *ctx = s->ctx; va_list ap; @@ -20564,7 +20651,7 @@ static __exception int js_parse_regexp(JSParseState *s) } static __exception int ident_realloc(JSContext *ctx, char **pbuf, size_t *psize, - char *static_buf) + const char *static_buf) { char *buf, *new_buf; size_t size, new_size; @@ -22519,7 +22606,8 @@ static int js_parse_skip_parens_token(JSParseState *s, int *pbits, BOOL no_line_ size_t level = 0; JSParsePos pos; int last_tok, tok = TOK_EOF; - int c, tok_len, bits = 0; + int tok_len, bits = 0; + char c; /* protect from underflow */ state[level++] = 0; @@ -27966,7 +28054,6 @@ static JSValue js_build_module_ns(JSContext *ctx, JSModuleDef *m) en->u.var_ref = res_me->u.local.var_ref; } else { JSObject *p1 = JS_VALUE_GET_OBJ(res_m->func_obj); - p1 = JS_VALUE_GET_OBJ(res_m->func_obj); en->u.var_ref = p1->u.func.var_refs[res_me->u.local.var_idx]; } } @@ -28616,7 +28703,7 @@ static JSValue js_dynamic_import_job(JSContext *ctx, exception: err = JS_GetException(ctx); ret = JS_Call(ctx, resolving_funcs[1], JS_UNDEFINED, - 1, (JSValueConst *)&err); + 1, &err); JS_FreeValue(ctx, ret); /* XXX: what to do if exception ? */ JS_FreeValue(ctx, err); JS_FreeCString(ctx, basename); @@ -29871,7 +29958,7 @@ static void dump_byte_code(JSContext *ctx, int pass, js_free(ctx, bits); } -static __maybe_unused void dump_pc2line(JSContext *ctx, const uint8_t *buf, int len, +static ____maybe_unused void dump_pc2line(JSContext *ctx, const uint8_t *buf, int len, int line_num) { const uint8_t *p_end, *p_next, *p; @@ -29916,7 +30003,7 @@ static __maybe_unused void dump_pc2line(JSContext *ctx, const uint8_t *buf, int } } -static __maybe_unused void js_dump_function_bytecode(JSContext *ctx, JSFunctionBytecode *b) +static ____maybe_unused void js_dump_function_bytecode(JSContext *ctx, JSFunctionBytecode *b) { int i; char atom_buf[ATOM_GET_STR_BUF_SIZE]; @@ -30317,8 +30404,7 @@ static int resolve_scope_var(JSContext *ctx, JSFunctionDef *s, } var_idx = idx; break; - } else - if (vd->var_name == JS_ATOM__with_ && !is_pseudo_var) { + } else if (vd->var_name == JS_ATOM__with_ && !is_pseudo_var) { dbuf_putc(bc, OP_get_loc); dbuf_put_u16(bc, idx); var_object_test(ctx, s, var_name, op, bc, &label_done, 1); @@ -32886,8 +32972,7 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s) bc_out.buf[pos - 1] = jp->op = OP_if_false8 + (op - OP_if_false); } goto shrink; - } else - if (diff == (int16_t)diff && op == OP_goto) { + } else if (diff == (int16_t)diff && op == OP_goto) { //put_u16(bc_out.buf + pos, diff); jp->size = 2; delta = 2; @@ -33391,8 +33476,10 @@ static JSValue js_create_function(JSContext *ctx, JSFunctionDef *fd) } } else { b->vardefs = (void *)((uint8_t*)b + vardefs_offset); - memcpy_no_ub(b->vardefs, fd->args, fd->arg_count * sizeof(fd->args[0])); - memcpy_no_ub(b->vardefs + fd->arg_count, fd->vars, fd->var_count * sizeof(fd->vars[0])); + if (fd->arg_count) + memcpy(b->vardefs, fd->args, fd->arg_count * sizeof(fd->args[0])); + if (fd->var_count) + memcpy(b->vardefs + fd->arg_count, fd->vars, fd->var_count * sizeof(fd->vars[0])); } b->var_count = fd->var_count; b->arg_count = fd->arg_count; @@ -34326,12 +34413,12 @@ static __exception int js_parse_program(JSParseState *s) static void js_parse_init(JSContext *ctx, JSParseState *s, const char *input, size_t input_len, - const char *filename) + const char *filename, int line) { memset(s, 0, sizeof(*s)); s->ctx = ctx; s->filename = filename; - s->line_num = 1; + s->line_num = line; s->buf_ptr = (const uint8_t *)input; s->buf_end = s->buf_ptr + input_len; s->token.val = ' '; @@ -34378,7 +34465,7 @@ JSValue JS_EvalFunction(JSContext *ctx, JSValue fun_obj) /* 'input' must be zero terminated i.e. input[input_len] = '\0'. */ static JSValue __JS_EvalInternal(JSContext *ctx, JSValueConst this_obj, const char *input, size_t input_len, - const char *filename, int flags, int scope_idx) + const char *filename, int line, int flags, int scope_idx) { JSParseState s1, *s = &s1; int err, js_mode, eval_type; @@ -34389,7 +34476,7 @@ static JSValue __JS_EvalInternal(JSContext *ctx, JSValueConst this_obj, JSFunctionDef *fd; JSModuleDef *m; - js_parse_init(ctx, s, input, input_len, filename); + js_parse_init(ctx, s, input, input_len, filename, line); skip_shebang(&s->buf_ptr, s->buf_end); eval_type = flags & JS_EVAL_TYPE_MASK; @@ -34423,7 +34510,7 @@ static JSValue __JS_EvalInternal(JSContext *ctx, JSValueConst this_obj, js_mode |= JS_MODE_STRICT; } } - fd = js_new_function_def(ctx, NULL, TRUE, FALSE, filename, 1); + fd = js_new_function_def(ctx, NULL, TRUE, FALSE, filename, line); if (!fd) goto fail1; s->cur_func = fd; @@ -34496,12 +34583,12 @@ static JSValue __JS_EvalInternal(JSContext *ctx, JSValueConst this_obj, /* the indirection is needed to make 'eval' optional */ static JSValue JS_EvalInternal(JSContext *ctx, JSValueConst this_obj, const char *input, size_t input_len, - const char *filename, int flags, int scope_idx) + const char *filename, int line, int flags, int scope_idx) { if (unlikely(!ctx->eval_internal)) { return JS_ThrowTypeError(ctx, "eval is not supported"); } - return ctx->eval_internal(ctx, this_obj, input, input_len, filename, + return ctx->eval_internal(ctx, this_obj, input, input_len, filename, line, flags, scope_idx); } @@ -34517,7 +34604,7 @@ static JSValue JS_EvalObject(JSContext *ctx, JSValueConst this_obj, str = JS_ToCStringLen(ctx, &len, val); if (!str) return JS_EXCEPTION; - ret = JS_EvalInternal(ctx, this_obj, str, len, "", flags, scope_idx); + ret = JS_EvalInternal(ctx, this_obj, str, len, "", 1, flags, scope_idx); JS_FreeCString(ctx, str); return ret; @@ -34525,14 +34612,14 @@ static JSValue JS_EvalObject(JSContext *ctx, JSValueConst this_obj, JSValue JS_EvalThis(JSContext *ctx, JSValueConst this_obj, const char *input, size_t input_len, - const char *filename, int eval_flags) + const char *filename, int line, int eval_flags) { int eval_type = eval_flags & JS_EVAL_TYPE_MASK; JSValue ret; assert(eval_type == JS_EVAL_TYPE_GLOBAL || eval_type == JS_EVAL_TYPE_MODULE); - ret = JS_EvalInternal(ctx, this_obj, input, input_len, filename, + ret = JS_EvalInternal(ctx, this_obj, input, input_len, filename, line, eval_flags, -1); return ret; } @@ -34540,7 +34627,7 @@ JSValue JS_EvalThis(JSContext *ctx, JSValueConst this_obj, JSValue JS_Eval(JSContext *ctx, const char *input, size_t input_len, const char *filename, int eval_flags) { - return JS_EvalThis(ctx, ctx->global_obj, input, input_len, filename, + return JS_EvalThis(ctx, ctx->global_obj, input, input_len, filename, 1, eval_flags); } @@ -34958,7 +35045,7 @@ static int JS_WriteFunctionBytecode(BCWriterState *s, static void JS_WriteString(BCWriterState *s, JSString *p) { int i; - bc_put_leb128(s, ((uint32_t)p->len << 1) | p->is_wide_char); + bc_put_leb128(s, (p->len << 1) | p->is_wide_char); if (p->is_wide_char) { for(i = 0; i < p->len; i++) bc_put_u16(s, p->u.str16[i]); @@ -35606,7 +35693,7 @@ typedef struct BCReaderState { } BCReaderState; #ifdef DUMP_READ_OBJECT -static void __attribute__((format(printf, 2, 3))) bc_read_trace(BCReaderState *s, const char *fmt, ...) { +static void FORMAT_ATTR(2, 3) bc_read_trace(BCReaderState *s, const char *fmt, ...) { va_list ap; int i, n, n0; @@ -37714,32 +37801,6 @@ static JSValue js_object_hasOwnProperty(JSContext *ctx, JSValueConst this_val, return JS_NewBool(ctx, ret); } -static JSValue js_object_hasOwn(JSContext *ctx, JSValueConst this_val, - int argc, JSValueConst *argv) -{ - JSValue obj; - JSAtom atom; - JSObject *p; - BOOL ret; - - obj = JS_ToObject(ctx, argv[0]); - if (JS_IsException(obj)) - return obj; - atom = JS_ValueToAtom(ctx, argv[1]); - if (unlikely(atom == JS_ATOM_NULL)) { - JS_FreeValue(ctx, obj); - return JS_EXCEPTION; - } - p = JS_VALUE_GET_OBJ(obj); - ret = JS_GetOwnPropertyInternal(ctx, NULL, p, atom); - JS_FreeAtom(ctx, atom); - JS_FreeValue(ctx, obj); - if (ret < 0) - return JS_EXCEPTION; - else - return JS_NewBool(ctx, ret); -} - static JSValue js_object_valueOf(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { @@ -37932,6 +37993,13 @@ static JSValue js_object_isSealed(JSContext *ctx, JSValueConst this_val, return JS_EXCEPTION; } +JSValue JS_ObjectSeal(JSContext *ctx, JSValueConst obj, int freeze) +{ + JSValueConst argv[] = {obj}; + JS_FreeValue(ctx, js_object_seal(ctx, JS_UNDEFINED, 1, argv, freeze)); + return obj; +} + static JSValue js_object_fromEntries(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { @@ -38279,6 +38347,32 @@ static JSValue js_object___lookupGetter__(JSContext *ctx, JSValueConst this_val, return res; } +static JSValue js_object_hasOwn(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSValue obj; + JSAtom atom; + JSObject *p; + BOOL ret; + + obj = JS_ToObject(ctx, argv[0]); + if (JS_IsException(obj)) + return obj; + atom = JS_ValueToAtom(ctx, argv[1]); + if (unlikely(atom == JS_ATOM_NULL)) { + JS_FreeValue(ctx, obj); + return JS_EXCEPTION; + } + p = JS_VALUE_GET_OBJ(obj); + ret = JS_GetOwnPropertyInternal(ctx, NULL, p, atom); + JS_FreeAtom(ctx, atom); + JS_FreeValue(ctx, obj); + if (ret < 0) + return JS_EXCEPTION; + else + return JS_NewBool(ctx, ret); +} + static const JSCFunctionListEntry js_object_funcs[] = { JS_CFUNC_DEF("create", 2, js_object_create ), JS_CFUNC_MAGIC_DEF("getPrototypeOf", 1, js_object_getPrototypeOf, 0 ), @@ -38508,9 +38602,9 @@ static JSValue js_function_apply(JSContext *ctx, JSValueConst this_val, if (!tab) return JS_EXCEPTION; if (magic & 1) { - ret = JS_CallConstructor2(ctx, this_val, this_arg, len, (JSValueConst *)tab); + ret = JS_CallConstructor2(ctx, this_val, this_arg, len, tab); } else { - ret = JS_Call(ctx, this_val, this_arg, len, (JSValueConst *)tab); + ret = JS_Call(ctx, this_val, this_arg, len, tab); } free_arg_list(ctx, tab, len); return ret; @@ -39857,8 +39951,7 @@ static JSValue js_array_toString(JSContext *ctx, JSValueConst this_val, method = JS_GetProperty(ctx, obj, JS_ATOM_join); if (JS_IsException(method)) { ret = JS_EXCEPTION; - } else - if (!JS_IsFunction(ctx, method)) { + } else if (!JS_IsFunction(ctx, method)) { /* Use intrinsic Object.prototype.toString */ JS_FreeValue(ctx, method); ret = js_object_toString(ctx, obj, 0, NULL); @@ -40161,8 +40254,7 @@ static JSValue js_array_slice(JSContext *ctx, JSValueConst this_val, if (argc == 0) { item_count = 0; del_count = 0; - } else - if (argc == 1) { + } else if (argc == 1) { item_count = 0; del_count = len - start; } else { @@ -40392,8 +40484,8 @@ static int64_t JS_FlattenIntoArray(JSContext *ctx, JSValueConst target, if (!JS_IsUndefined(mapperFunction)) { JSValueConst args[3] = { element, JS_NewInt64(ctx, sourceIndex), source }; element = JS_Call(ctx, mapperFunction, thisArg, 3, args); - JS_FreeValue(ctx, (JSValue)args[0]); - JS_FreeValue(ctx, (JSValue)args[1]); + JS_FreeValue(ctx, args[0]); + JS_FreeValue(ctx, args[1]); if (JS_IsException(element)) return -1; } @@ -40918,7 +41010,7 @@ static JSValue js_number_constructor(JSContext *ctx, JSValueConst new_target, double d; bf_get_float64(&p->num, &d, BF_RNDN); JS_FreeValue(ctx, val); - val = __JS_NewFloat64(ctx, d); + val = JS_NewFloat64(ctx, d); } break; #ifdef CONFIG_BIGNUM @@ -41959,7 +42051,7 @@ static JSValue js_string_match(JSContext *ctx, JSValueConst this_val, str = JS_NewString(ctx, "g"); if (JS_IsException(str)) goto fail; - args[args_len++] = (JSValueConst)str; + args[args_len++] = str; } rx = JS_CallConstructor(ctx, ctx->regexp_ctor, args_len, args); JS_FreeValue(ctx, str); @@ -41968,7 +42060,7 @@ static JSValue js_string_match(JSContext *ctx, JSValueConst this_val, JS_FreeValue(ctx, S); return JS_EXCEPTION; } - result = JS_InvokeFree(ctx, rx, atom, 1, (JSValueConst *)&S); + result = JS_InvokeFree(ctx, rx, atom, 1, &S); JS_FreeValue(ctx, S); return result; } @@ -43090,7 +43182,7 @@ static JSValue js_math_min_max(JSContext *ctx, JSValueConst this_val, uint32_t tag; if (unlikely(argc == 0)) { - return __JS_NewFloat64(ctx, is_max ? -1.0 / 0.0 : 1.0 / 0.0); + return __JS_NewFloat64(ctx, is_max ? INFINITY : -INFINITY); } tag = JS_VALUE_GET_TAG(argv[0]); @@ -43244,9 +43336,13 @@ static uint64_t xorshift64star(uint64_t *pstate) static void js_random_init(JSContext *ctx) { +#ifdef _MSC_VER + ctx->random_state = time(NULL); +#else struct timeval tv; gettimeofday(&tv, NULL); ctx->random_state = ((int64_t)tv.tv_sec * 1000000) + tv.tv_usec; +#endif /* the state must be non zero */ if (ctx->random_state == 0) ctx->random_state = 1; @@ -43264,12 +43360,18 @@ static JSValue js_math_random(JSContext *ctx, JSValueConst this_val, return __JS_NewFloat64(ctx, u.d - 1.0); } +// MSVC inexplicably refuses to initialize the array below with +// these functions, so use wrappers. +static double floorWrapper(double x) { return floor(x); } +static double ceilWrapper(double x) { return ceil(x); } +static double log2Wrapper(double x) { return log2(x); } + static const JSCFunctionListEntry js_math_funcs[] = { JS_CFUNC_MAGIC_DEF("min", 2, js_math_min_max, 0 ), JS_CFUNC_MAGIC_DEF("max", 2, js_math_min_max, 1 ), JS_CFUNC_SPECIAL_DEF("abs", 1, f_f, fabs ), - JS_CFUNC_SPECIAL_DEF("floor", 1, f_f, floor ), - JS_CFUNC_SPECIAL_DEF("ceil", 1, f_f, ceil ), + JS_CFUNC_SPECIAL_DEF("floor", 1, f_f, floorWrapper ), + JS_CFUNC_SPECIAL_DEF("ceil", 1, f_f, ceilWrapper ), JS_CFUNC_SPECIAL_DEF("round", 1, f_f, js_math_round ), JS_CFUNC_SPECIAL_DEF("sqrt", 1, f_f, sqrt ), @@ -43294,7 +43396,7 @@ static const JSCFunctionListEntry js_math_funcs[] = { JS_CFUNC_SPECIAL_DEF("atanh", 1, f_f, atanh ), JS_CFUNC_SPECIAL_DEF("expm1", 1, f_f, expm1 ), JS_CFUNC_SPECIAL_DEF("log1p", 1, f_f, log1p ), - JS_CFUNC_SPECIAL_DEF("log2", 1, f_f, log2 ), + JS_CFUNC_SPECIAL_DEF("log2", 1, f_f, log2Wrapper ), JS_CFUNC_SPECIAL_DEF("log10", 1, f_f, log10 ), JS_CFUNC_SPECIAL_DEF("cbrt", 1, f_f, cbrt ), JS_CFUNC_DEF("hypot", 2, js_math_hypot ), @@ -43380,7 +43482,7 @@ static JSValue js___date_getTimezoneOffset(JSContext *ctx, JSValueConst this_val if (JS_ToFloat64(ctx, &dd, argv[0])) return JS_EXCEPTION; if (isnan(dd)) - return __JS_NewFloat64(ctx, dd); + return JS_NewFloat64(ctx, dd); else return JS_NewInt32(ctx, getTimezoneOffset((int64_t)dd)); } @@ -45112,7 +45214,7 @@ JSValue JS_ParseJSON2(JSContext *ctx, const char *buf, size_t buf_len, JSParseState s1, *s = &s1; JSValue val = JS_UNDEFINED; - js_parse_init(ctx, s, buf, buf_len, filename); + js_parse_init(ctx, s, buf, buf_len, filename, 1); s->ext_json = ((flags & JS_PARSE_JSON_EXT) != 0); if (json_next_token(s)) goto fail; @@ -45359,7 +45461,7 @@ static int js_json_to_str(JSContext *ctx, JSONStringifyContext *jsc, set_value(ctx, &val, JS_DupValue(ctx, p->u.object_data)); goto concat_primitive; } - v = js_array_includes(ctx, jsc->stack, 1, (JSValueConst *)&val); + v = js_array_includes(ctx, jsc->stack, 1, &val); if (JS_IsException(v)) goto exception; if (JS_ToBoolFree(ctx, v)) { @@ -45380,7 +45482,7 @@ static int js_json_to_str(JSContext *ctx, JSONStringifyContext *jsc, sep = JS_DupValue(ctx, jsc->empty); sep1 = JS_DupValue(ctx, jsc->empty); } - v = js_array_push(ctx, jsc->stack, 1, (JSValueConst *)&val, 0); + v = js_array_push(ctx, jsc->stack, 1, &val, 0); if (check_exception_free(ctx, v)) goto exception; ret = JS_IsArray(ctx, val); @@ -45420,7 +45522,7 @@ static int js_json_to_str(JSContext *ctx, JSONStringifyContext *jsc, if (!JS_IsUndefined(jsc->property_list)) tab = JS_DupValue(ctx, jsc->property_list); else - tab = js_object_keys(ctx, JS_UNDEFINED, 1, (JSValueConst *)&val, JS_ITERATOR_KIND_KEY); + tab = js_object_keys(ctx, JS_UNDEFINED, 1, &val, JS_ITERATOR_KIND_KEY); if (JS_IsException(tab)) goto exception; if (js_get_length64(ctx, &len, tab)) @@ -45571,7 +45673,7 @@ JSValue JS_JSONStringify(JSContext *ctx, JSValueConst obj, continue; } present = js_array_includes(ctx, jsc->property_list, - 1, (JSValueConst *)&v); + 1, &v); if (JS_IsException(present)) { JS_FreeValue(ctx, v); goto exception; @@ -45695,7 +45797,7 @@ static JSValue js_reflect_construct(JSContext *ctx, JSValueConst this_val, tab = build_arg_list(ctx, &len, array_arg); if (!tab) return JS_EXCEPTION; - ret = JS_CallConstructor2(ctx, func, new_target, len, (JSValueConst *)tab); + ret = JS_CallConstructor2(ctx, func, new_target, len, tab); free_arg_list(ctx, tab, len); return ret; } @@ -45900,7 +46002,7 @@ static JSValue js_proxy_getPrototypeOf(JSContext *ctx, JSValueConst obj) return JS_EXCEPTION; if (JS_IsUndefined(method)) return JS_GetPrototype(ctx, s->target); - ret = JS_CallFree(ctx, method, s->handler, 1, (JSValueConst *)&s->target); + ret = JS_CallFree(ctx, method, s->handler, 1, &s->target); if (JS_IsException(ret)) return ret; if (JS_VALUE_GET_TAG(ret) != JS_TAG_NULL && @@ -45987,7 +46089,7 @@ static int js_proxy_isExtensible(JSContext *ctx, JSValueConst obj) return -1; if (JS_IsUndefined(method)) return JS_IsExtensible(ctx, s->target); - ret = JS_CallFree(ctx, method, s->handler, 1, (JSValueConst *)&s->target); + ret = JS_CallFree(ctx, method, s->handler, 1, &s->target); if (JS_IsException(ret)) return -1; res = JS_ToBoolFree(ctx, ret); @@ -46013,7 +46115,7 @@ static int js_proxy_preventExtensions(JSContext *ctx, JSValueConst obj) return -1; if (JS_IsUndefined(method)) return JS_PreventExtensions(ctx, s->target); - ret = JS_CallFree(ctx, method, s->handler, 1, (JSValueConst *)&s->target); + ret = JS_CallFree(ctx, method, s->handler, 1, &s->target); if (JS_IsException(ret)) return -1; res = JS_ToBoolFree(ctx, ret); @@ -46497,7 +46599,7 @@ static int js_proxy_get_own_property_names(JSContext *ctx, JS_VALUE_GET_OBJ(s->target), JS_GPN_STRING_MASK | JS_GPN_SYMBOL_MASK); } - prop_array = JS_CallFree(ctx, method, s->handler, 1, (JSValueConst *)&s->target); + prop_array = JS_CallFree(ctx, method, s->handler, 1, &s->target); if (JS_IsException(prop_array)) return -1; tab = NULL; @@ -46837,7 +46939,7 @@ static JSValue js_symbol_toString(JSContext *ctx, JSValueConst this_val, if (JS_IsException(val)) return val; /* XXX: use JS_ToStringInternal() with a flags */ - ret = js_string_constructor(ctx, JS_UNDEFINED, 1, (JSValueConst *)&val); + ret = js_string_constructor(ctx, JS_UNDEFINED, 1, &val); JS_FreeValue(ctx, val); return ret; } @@ -46987,7 +47089,7 @@ static JSValue js_map_constructor(JSContext *ctx, JSValueConst new_target, break; } if (is_set) { - ret = JS_Call(ctx, adder, obj, 1, (JSValueConst *)&item); + ret = JS_Call(ctx, adder, obj, 1, &item); if (JS_IsException(ret)) { JS_FreeValue(ctx, item); goto fail; @@ -47158,7 +47260,7 @@ static JSMapRecord *map_add_record(JSContext *ctx, JSMapState *s, } else { JS_DupValue(ctx, key); } - mr->key = (JSValue)key; + mr->key = key; h = map_hash_key(ctx, key) & (s->hash_size - 1); list_add_tail(&mr->hash_link, &s->hash_table[h]); list_add_tail(&mr->link, &s->records); @@ -47380,7 +47482,7 @@ static JSValue js_map_forEach(JSContext *ctx, JSValueConst this_val, args[0] = args[1]; else args[0] = JS_DupValue(ctx, mr->value); - args[2] = (JSValue)this_val; + args[2] = this_val; ret = JS_Call(ctx, func, this_arg, 3, (JSValueConst *)args); JS_FreeValue(ctx, args[0]); if (!magic) @@ -47900,7 +48002,7 @@ static JSValue promise_reaction_job(JSContext *ctx, int argc, functions */ if (!JS_IsUndefined(func)) { res2 = JS_Call(ctx, func, JS_UNDEFINED, - 1, (JSValueConst *)&res); + 1, &res); } else { res2 = JS_UNDEFINED; } @@ -47983,7 +48085,7 @@ static JSValue js_promise_resolve_thenable_job(JSContext *ctx, res = JS_Call(ctx, then, thenable, 2, (JSValueConst *)args); if (JS_IsException(res)) { JSValue error = JS_GetException(ctx); - res = JS_Call(ctx, args[1], JS_UNDEFINED, 1, (JSValueConst *)&error); + res = JS_Call(ctx, args[1], JS_UNDEFINED, 1, &error); JS_FreeValue(ctx, error); } JS_FreeValue(ctx, args[0]); @@ -48183,7 +48285,7 @@ static JSValue js_promise_constructor(JSContext *ctx, JSValueConst new_target, if (JS_IsException(ret)) { JSValue ret2, error; error = JS_GetException(ctx); - ret2 = JS_Call(ctx, args[1], JS_UNDEFINED, 1, (JSValueConst *)&error); + ret2 = JS_Call(ctx, args[1], JS_UNDEFINED, 1, &error); JS_FreeValue(ctx, error); if (JS_IsException(ret2)) goto fail1; @@ -48240,10 +48342,10 @@ static JSValue js_new_promise_capability(JSContext *ctx, if (JS_IsUndefined(ctor)) { result_promise = js_promise_constructor(ctx, ctor, 1, - (JSValueConst *)&executor); + &executor); } else { result_promise = JS_CallConstructor(ctx, ctor, 1, - (JSValueConst *)&executor); + &executor); } if (JS_IsException(result_promise)) goto fail; @@ -48404,10 +48506,10 @@ static JSValue js_promise_all_resolve_element(JSContext *ctx, error = js_aggregate_error_constructor(ctx, values); if (JS_IsException(error)) return JS_EXCEPTION; - ret = JS_Call(ctx, resolve, JS_UNDEFINED, 1, (JSValueConst *)&error); + ret = JS_Call(ctx, resolve, JS_UNDEFINED, 1, &error); JS_FreeValue(ctx, error); } else { - ret = JS_Call(ctx, resolve, JS_UNDEFINED, 1, (JSValueConst *)&values); + ret = JS_Call(ctx, resolve, JS_UNDEFINED, 1, &values); } if (JS_IsException(ret)) return ret; @@ -48443,7 +48545,7 @@ static JSValue js_promise_all(JSContext *ctx, JSValueConst this_val, fail_reject: error = JS_GetException(ctx); ret = JS_Call(ctx, resolving_funcs[1], JS_UNDEFINED, 1, - (JSValueConst *)&error); + &error); JS_FreeValue(ctx, error); if (JS_IsException(ret)) goto fail; @@ -48474,7 +48576,7 @@ static JSValue js_promise_all(JSContext *ctx, JSValueConst this_val, if (done) break; next_promise = JS_Call(ctx, promise_resolve, - this_val, 1, (JSValueConst *)&item); + this_val, 1, &item); JS_FreeValue(ctx, item); if (JS_IsException(next_promise)) { fail_reject1: @@ -48482,7 +48584,7 @@ static JSValue js_promise_all(JSContext *ctx, JSValueConst this_val, goto fail_reject; } resolve_element_data[0] = JS_NewBool(ctx, FALSE); - resolve_element_data[1] = (JSValueConst)JS_NewInt32(ctx, index); + resolve_element_data[1] = JS_NewInt32(ctx, index); resolve_element_data[2] = values; resolve_element_data[3] = resolving_funcs[is_promise_any]; resolve_element_data[4] = resolve_element_env; @@ -48542,7 +48644,7 @@ static JSValue js_promise_all(JSContext *ctx, JSValueConst this_val, values = error; } ret = JS_Call(ctx, resolving_funcs[is_promise_any], JS_UNDEFINED, - 1, (JSValueConst *)&values); + 1, &values); if (check_exception_free(ctx, ret)) goto fail_reject; } @@ -48585,7 +48687,7 @@ static JSValue js_promise_race(JSContext *ctx, JSValueConst this_val, fail_reject: error = JS_GetException(ctx); ret = JS_Call(ctx, resolving_funcs[1], JS_UNDEFINED, 1, - (JSValueConst *)&error); + &error); JS_FreeValue(ctx, error); if (JS_IsException(ret)) goto fail; @@ -48604,7 +48706,7 @@ static JSValue js_promise_race(JSContext *ctx, JSValueConst this_val, if (done) break; next_promise = JS_Call(ctx, promise_resolve, - this_val, 1, (JSValueConst *)&item); + this_val, 1, &item); JS_FreeValue(ctx, item); if (JS_IsException(next_promise)) { fail_reject1: @@ -48749,7 +48851,7 @@ static JSValue js_promise_then_finally_func(JSContext *ctx, JSValueConst this_va res = JS_Call(ctx, onFinally, JS_UNDEFINED, 0, NULL); if (JS_IsException(res)) return res; - promise = js_promise_resolve(ctx, ctor, 1, (JSValueConst *)&res, 0); + promise = js_promise_resolve(ctx, ctor, 1, &res, 0); JS_FreeValue(ctx, res); if (JS_IsException(promise)) return promise; @@ -48764,7 +48866,7 @@ static JSValue js_promise_then_finally_func(JSContext *ctx, JSValueConst this_va JS_FreeValue(ctx, promise); return then_func; } - ret = JS_InvokeFree(ctx, promise, JS_ATOM_then, 1, (JSValueConst *)&then_func); + ret = JS_InvokeFree(ctx, promise, JS_ATOM_then, 1, &then_func); JS_FreeValue(ctx, then_func); return ret; } @@ -48841,7 +48943,7 @@ static JSValue js_async_from_sync_iterator_unwrap_func_create(JSContext *ctx, { JSValueConst func_data[1]; - func_data[0] = (JSValueConst)JS_NewBool(ctx, done); + func_data[0] = JS_NewBool(ctx, done); return JS_NewCFunctionData(ctx, js_async_from_sync_iterator_unwrap, 1, 0, 1, func_data); } @@ -48964,7 +49066,7 @@ static JSValue js_async_from_sync_iterator_next(JSContext *ctx, JSValueConst thi is_reject = 1; done_resolve: res2 = JS_Call(ctx, resolving_funcs[is_reject], JS_UNDEFINED, - 1, (JSValueConst *)&err); + 1, &err); JS_FreeValue(ctx, err); JS_FreeValue(ctx, res2); JS_FreeValue(ctx, resolving_funcs[0]); @@ -48976,7 +49078,7 @@ static JSValue js_async_from_sync_iterator_next(JSContext *ctx, JSValueConst thi int res; value_wrapper_promise = js_promise_resolve(ctx, ctx->promise_ctor, - 1, (JSValueConst *)&value, 0); + 1, &value, 0); if (JS_IsException(value_wrapper_promise)) { JS_FreeValue(ctx, value); goto reject; @@ -49146,7 +49248,7 @@ static int isURIReserved(int c) { return c < 0x100 && memchr(";/?:@&=+$,#", c, sizeof(";/?:@&=+$,#") - 1) != NULL; } -static int __attribute__((format(printf, 2, 3))) js_throw_URIError(JSContext *ctx, const char *fmt, ...) +static int FORMAT_ATTR(2, 3) js_throw_URIError(JSContext *ctx, const char *fmt, ...) { va_list ap; @@ -49789,9 +49891,17 @@ static JSValue get_date_string(JSContext *ctx, JSValueConst this_val, /* OS dependent: return the UTC time in ms since 1970. */ static int64_t date_now(void) { +#ifdef _MSC_VER + SYSTEMTIME st; + GetSystemTime(&st); + int64_t d; + SystemTimeToFileTime(&st, (FILETIME *) &d); + return (d - 116444736000000000ULL) / 10000; +#else struct timeval tv; gettimeofday(&tv, NULL); return (int64_t)tv.tv_sec * 1000 + (tv.tv_usec / 1000); +#endif } static JSValue js_date_constructor(JSContext *ctx, JSValueConst new_target, @@ -49822,7 +49932,7 @@ static JSValue js_date_constructor(JSContext *ctx, JSValueConst new_target, } v = JS_ToPrimitive(ctx, argv[0], HINT_NONE); if (JS_IsString(v)) { - dv = js_Date_parse(ctx, JS_UNDEFINED, 1, (JSValueConst *)&v); + dv = js_Date_parse(ctx, JS_UNDEFINED, 1, &v); JS_FreeValue(ctx, v); if (JS_IsException(dv)) return JS_EXCEPTION; @@ -50545,6 +50655,14 @@ JSValue JS_NewDate(JSContext *ctx, double epoch_ms) return obj; } +int JS_IsDate(JSValue v) +{ + JSObject *p; + if (JS_VALUE_GET_TAG(v) != JS_TAG_OBJECT) + return FALSE; + return JS_VALUE_GET_OBJ(v)->class_id == JS_CLASS_DATE; +} + void JS_AddIntrinsicDate(JSContext *ctx) { JSValueConst obj; @@ -52707,7 +52825,7 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx) JS_PROP_HAS_GET | JS_PROP_HAS_SET | JS_PROP_HAS_CONFIGURABLE | JS_PROP_CONFIGURABLE); JS_FreeValue(ctx, obj1); - JS_FreeValue(ctx, js_object_seal(ctx, JS_UNDEFINED, 1, (JSValueConst *)&ctx->throw_type_error, 1)); + JS_FreeValue(ctx, js_object_seal(ctx, JS_UNDEFINED, 1, &ctx->throw_type_error, 1)); ctx->global_obj = JS_NewObject(ctx); ctx->global_var_obj = JS_NewObjectProto(ctx, JS_NULL); @@ -53961,7 +54079,7 @@ static JSValue js_typed_array_find(JSContext *ctx, JSValueConst this_val, #define special_indexOf 0 #define special_lastIndexOf 1 -#define special_includes -1 +#define special_includes (-1) static JSValue js_typed_array_indexOf(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int special) @@ -54028,13 +54146,11 @@ static JSValue js_typed_array_indexOf(JSContext *ctx, JSValueConst this_val, is_int = 1; v64 = JS_VALUE_GET_INT(argv[0]); d = v64; - } else - if (tag == JS_TAG_FLOAT64) { + } else if (tag == JS_TAG_FLOAT64) { d = JS_VALUE_GET_FLOAT64(argv[0]); - if (d >= INT64_MIN && d < 0x1p63) { + // XXX: should fix UB v64 = d; is_int = (v64 == d); - } } else if (tag == JS_TAG_BIG_INT) { JSBigFloat *p1 = JS_VALUE_GET_PTR(argv[0]); @@ -54601,8 +54717,8 @@ static int js_TA_cmp_generic(const void *a, const void *b, void *opaque) { psc->exception = 2; } done: - JS_FreeValue(ctx, (JSValue)argv[0]); - JS_FreeValue(ctx, (JSValue)argv[1]); + JS_FreeValue(ctx, argv[0]); + JS_FreeValue(ctx, argv[1]); } return cmp; } @@ -55182,7 +55298,7 @@ static JSValue js_dataview_getValue(JSContext *ctx, case JS_CLASS_INT8_ARRAY: return JS_NewInt32(ctx, *(int8_t *)ptr); case JS_CLASS_UINT8_ARRAY: - return JS_NewInt32(ctx, *(uint8_t *)ptr); + return JS_NewInt32(ctx, *ptr); case JS_CLASS_INT16_ARRAY: v = get_u16(ptr); if (is_swap) @@ -55901,3 +56017,167 @@ void JS_AddIntrinsicTypedArrays(JSContext *ctx) JS_AddIntrinsicAtomics(ctx); #endif } + +#ifndef NDEBUG +static void *watchedRefCount = NULL; + +void notifyRefCountIncrease(JSRefCountHeader *p) +{ + if (p == watchedRefCount) + fprintf(stderr, "increasing ref count %d for %p\n", p->ref_count, watchedRefCount); +} + +void notifyRefCountDecrease(JSRefCountHeader *p) +{ + if (p == watchedRefCount) + fprintf(stderr, "decreasing ref count %d for %p\n", p->ref_count, watchedRefCount); +} + +void watchRefCount(void *p) +{ + watchedRefCount = p; +} +#endif + +void setScopeLookup(JSContext *ctx, ScopeLookup *scopeLookup) +{ + ctx->scopeLookup = scopeLookup; +} + +void setFoundUndefinedHandler(JSContext *ctx, FoundUndefinedHandler *handler) +{ + ctx->handleUndefined = handler; +} + +void setFunctionEnteredHandler(JSContext *ctx, FunctionEnteredHandler *handler) +{ + ctx->handleFunctionEntered = handler; +} + +void setFunctionExitedHandler(JSContext *ctx, FunctionExitedHandler *handler) +{ + ctx->handleFunctionExited = handler; +} + +int isSimpleValue(JSValue v) +{ + JSObject *p; + if (JS_VALUE_GET_TAG(v) != JS_TAG_OBJECT) + return 1; + p = JS_VALUE_GET_OBJ(v); + return p->class_id >= JS_CLASS_OBJECT && p->class_id <= JS_CLASS_BOOLEAN; +} + +JSValue JS_NewCFunctionMagic(JSContext *ctx, JSCFunctionMagic *func, + const char *name, int length, + JSCFunctionEnum cproto, int magic) +{ + return JS_NewCFunction2(ctx, (JSCFunction *)func, name, length, cproto, + magic); +} + +#ifdef JS_NAN_BOXING +JSValue mkVal(int32_t tag, int32_t val) +{ + return ((uint64_t)(tag) << 32) | (uint32_t)(val); +} + +JSValue mkPtr(int32_t tag, void *p) +{ + return ((uint64_t)(tag) << 32) | (uintptr_t)(p); +} +#else +JSValue mkVal(int32_t tag, int32_t val) +{ + return (JSValue){ (JSValueUnion){ .int32 = val }, tag }; +} + +JSValue mkPtr(int32_t tag, void *p) +{ + return (JSValue){ (JSValueUnion){ .ptr = p }, tag }; +} +#endif + +void JS_FreeValue(JSContext *ctx, JSValue v) { + if (JS_VALUE_HAS_REF_COUNT(v)) { + JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v); +#ifndef NDEBUG + notifyRefCountDecrease(p); +#endif + if (--p->ref_count <= 0) { + __JS_FreeValue(ctx, v); + } + } +} +void JS_FreeValueRT(JSRuntime *rt, JSValue v) { + if (JS_VALUE_HAS_REF_COUNT(v)) { + JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v); +#ifndef NDEBUG + notifyRefCountDecrease(p); +#endif + if (--p->ref_count <= 0) { + __JS_FreeValueRT(rt, v); + } + } +} +JSValue JS_NewBool(JSContext *ctx, JS_BOOL val) { + (void)ctx; + return JS_MKVAL(JS_TAG_BOOL, (val != 0)); +} +JSValue JS_NewInt32(JSContext *ctx, int32_t val) { + (void)ctx; + return JS_MKVAL(JS_TAG_INT, val); +} +JSValue JS_NewCatchOffset(JSContext *ctx, int32_t val) { + (void)ctx; + return JS_MKVAL(JS_TAG_CATCH_OFFSET, val); +} +JSValue JS_NewInt64(JSContext *ctx, int64_t val) { + JSValue v; + if (val == (int32_t)val) { + v = JS_NewInt32(ctx, (int32_t)val); + } else { + v = __JS_NewFloat64(ctx, (double)val); + } + return v; +} +JSValue JS_NewUint32(JSContext *ctx, uint32_t val) { + JSValue v; + if (val <= 0x7fffffff) { + v = JS_NewInt32(ctx, val); + } else { + v = __JS_NewFloat64(ctx, val); + } + return v; +} +JSValue JS_NewFloat64(JSContext *ctx, double d) +{ + int32_t val; + union { + double d; + uint64_t u; + } u, t; + 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 __JS_NewFloat64(ctx, d); +} + +JSValue JS_NewCFunction(JSContext *ctx, JSCFunction *func, const char *name, + int length) { + return JS_NewCFunction2(ctx, func, name, length, JS_CFUNC_generic, 0); +} + +JS_BOOL JS_IsRegExp(JSContext *ctx, JSValue val) +{ + JSObject *p; + if (JS_VALUE_GET_TAG(val) != JS_TAG_OBJECT) + return FALSE; + return JS_VALUE_GET_OBJ(val)->class_id == JS_CLASS_REGEXP; +} diff --git a/quickjs.h b/quickjs.h index 7199936bb..1e49db590 100644 --- a/quickjs.h +++ b/quickjs.h @@ -158,6 +158,7 @@ static inline double JS_VALUE_GET_FLOAT64(JSValue v) static inline JSValue __JS_NewFloat64(JSContext *ctx, double d) { + (void) ctx; union { double d; uint64_t u64; @@ -215,8 +216,11 @@ typedef struct JSValue { #define JS_VALUE_GET_FLOAT64(v) ((v).u.float64) #define JS_VALUE_GET_PTR(v) ((v).u.ptr) -#define JS_MKVAL(tag, val) (JSValue){ (JSValueUnion){ .int32 = val }, tag } -#define JS_MKPTR(tag, p) (JSValue){ (JSValueUnion){ .ptr = p }, tag } +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) #define JS_TAG_IS_FLOAT64(tag) ((unsigned)(tag) == JS_TAG_FLOAT64) @@ -224,6 +228,7 @@ typedef struct JSValue { static inline JSValue __JS_NewFloat64(JSContext *ctx, double d) { + (void) ctx; JSValue v; v.tag = JS_TAG_FLOAT64; v.u.float64 = d; @@ -508,64 +513,15 @@ int JS_IsRegisteredClass(JSRuntime *rt, JSClassID class_id); /* value handling */ -static js_force_inline JSValue JS_NewBool(JSContext *ctx, JS_BOOL val) -{ - return JS_MKVAL(JS_TAG_BOOL, (val != 0)); -} - -static js_force_inline JSValue JS_NewInt32(JSContext *ctx, int32_t val) -{ - return JS_MKVAL(JS_TAG_INT, val); -} - -static js_force_inline JSValue JS_NewCatchOffset(JSContext *ctx, int32_t val) -{ - return JS_MKVAL(JS_TAG_CATCH_OFFSET, val); -} - -static js_force_inline JSValue JS_NewInt64(JSContext *ctx, int64_t val) -{ - JSValue v; - if (val == (int32_t)val) { - v = JS_NewInt32(ctx, val); - } else { - v = __JS_NewFloat64(ctx, val); - } - return v; -} - -static js_force_inline JSValue JS_NewUint32(JSContext *ctx, uint32_t val) -{ - JSValue v; - if (val <= 0x7fffffff) { - v = JS_NewInt32(ctx, val); - } else { - v = __JS_NewFloat64(ctx, val); - } - return v; -} - +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_NewFloat64(JSContext *ctx, double d) -{ - int32_t val; - union { - double d; - uint64_t u; - } u, t; - 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 __JS_NewFloat64(ctx, d); -} +JSValue JS_NewFloat64(JSContext *ctx, double d); static inline JS_BOOL JS_IsNumber(JSValueConst v) { @@ -575,6 +531,7 @@ static inline JS_BOOL JS_IsNumber(JSValueConst v) static inline JS_BOOL JS_IsBigInt(JSContext *ctx, JSValueConst v) { + (void) ctx; int tag = JS_VALUE_GET_TAG(v); return tag == JS_TAG_BIG_INT; } @@ -643,43 +600,38 @@ JSValue __js_printf_like(2, 3) JS_ThrowRangeError(JSContext *ctx, const char *fm JSValue __js_printf_like(2, 3) JS_ThrowInternalError(JSContext *ctx, const char *fmt, ...); JSValue JS_ThrowOutOfMemory(JSContext *ctx); -void __JS_FreeValue(JSContext *ctx, JSValue v); -static inline void JS_FreeValue(JSContext *ctx, JSValue v) -{ - if (JS_VALUE_HAS_REF_COUNT(v)) { - JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v); - if (--p->ref_count <= 0) { - __JS_FreeValue(ctx, v); - } - } -} -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); - if (--p->ref_count <= 0) { - __JS_FreeValueRT(rt, v); - } - } -} +#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) { + (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 (JSValue)v; + return v; } 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 (JSValue)v; + return v; } int JS_ToBool(JSContext *ctx, JSValueConst val); /* return -1 for JS_EXCEPTION */ @@ -718,13 +670,16 @@ 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, @@ -760,6 +715,8 @@ 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); + #define JS_GPN_STRING_MASK (1 << 0) #define JS_GPN_SYMBOL_MASK (1 << 1) #define JS_GPN_PRIVATE_MASK (1 << 2) @@ -789,7 +746,7 @@ JSValue JS_Eval(JSContext *ctx, const char *input, size_t input_len, /* 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 eval_flags); + 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, @@ -960,18 +917,11 @@ JSValue JS_NewCFunctionData(JSContext *ctx, JSCFunctionData *func, int length, int magic, int data_len, JSValueConst *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_NewCFunction(JSContext *ctx, JSCFunction *func, const char *name, + int length); -static inline JSValue JS_NewCFunctionMagic(JSContext *ctx, JSCFunctionMagic *func, - const char *name, - int length, JSCFunctionEnum cproto, int magic) -{ - return JS_NewCFunction2(ctx, (JSCFunction *)func, name, length, cproto, magic); -} +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); @@ -1054,6 +1004,35 @@ int JS_SetModuleExport(JSContext *ctx, JSModuleDef *m, const char *export_name, int JS_SetModuleExportList(JSContext *ctx, JSModuleDef *m, const JSCFunctionListEntry *tab, int len); + +/* Qbs extensions */ +struct LookupResult +{ + JSValue value; + JSValue scope; + int useResult; +}; +typedef struct LookupResult ScopeLookup(JSContext *ctx, JSAtom prop); +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 + +void build_backtrace(JSContext *ctx, JSValueConst error_obj, + const char *filename, int line_num, + int backtrace_flags); + #undef js_unlikely #undef js_force_inline