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 11246e3ce..542e5cd7a 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) @@ -122,38 +141,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) { @@ -276,8 +311,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 dee394ac7..aacd7e792 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)) @@ -5497,6 +5495,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, @@ -5522,6 +5521,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 ebf45a988..46245b2e2 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 { @@ -1040,7 +1080,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); @@ -1162,7 +1201,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, @@ -1207,7 +1245,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); @@ -1600,10 +1638,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) @@ -1987,6 +2042,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 */ @@ -5508,7 +5564,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); @@ -5585,7 +5641,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); } @@ -6522,7 +6578,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) { @@ -6622,7 +6678,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); @@ -6657,7 +6713,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; @@ -6668,7 +6724,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; @@ -6679,7 +6735,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; @@ -6695,7 +6751,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, @@ -6703,7 +6759,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, @@ -6726,7 +6782,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; @@ -6737,7 +6793,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; @@ -6748,7 +6804,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; @@ -7197,6 +7253,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); } } @@ -7295,7 +7353,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) { @@ -7326,7 +7384,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) { @@ -7353,7 +7411,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) { @@ -7452,7 +7510,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); } @@ -9072,7 +9130,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); @@ -9597,6 +9655,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); } @@ -9692,6 +9755,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); } @@ -9784,6 +9856,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; @@ -10097,7 +10177,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; } @@ -10285,7 +10365,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); @@ -10318,11 +10398,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]))) @@ -11078,8 +11155,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; @@ -11401,7 +11476,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--; @@ -12994,7 +13069,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) { @@ -13038,7 +13113,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; @@ -13086,7 +13161,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; } @@ -13538,14 +13613,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: @@ -13636,7 +13711,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: @@ -13660,7 +13735,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; } @@ -13755,7 +13830,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: @@ -14349,7 +14424,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) @@ -15979,7 +16054,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; @@ -15992,7 +16067,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) { @@ -16163,7 +16238,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) @@ -16206,7 +16281,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; @@ -16224,7 +16299,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; @@ -16252,6 +16327,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; @@ -16357,12 +16435,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; @@ -16402,7 +16480,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; } @@ -16654,7 +16732,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]); @@ -16794,7 +16872,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))) @@ -17427,7 +17505,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]); @@ -17455,7 +17533,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; @@ -18631,6 +18709,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 @@ -18678,6 +18763,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; } @@ -18685,14 +18772,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; } @@ -18797,7 +18884,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; @@ -18826,7 +18913,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); } @@ -18834,7 +18921,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); } @@ -19213,13 +19300,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 ? */ } @@ -19233,7 +19320,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; @@ -19508,7 +19595,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)) @@ -19687,7 +19774,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]); @@ -20151,7 +20238,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) { @@ -20212,7 +20299,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; @@ -20563,7 +20650,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; @@ -22518,7 +22605,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; @@ -27965,7 +28053,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]; } } @@ -28615,7 +28702,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); @@ -29870,7 +29957,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; @@ -29915,7 +30002,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]; @@ -30316,8 +30403,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); @@ -32885,8 +32971,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; @@ -33390,8 +33475,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; @@ -34323,12 +34410,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 = ' '; @@ -34375,7 +34462,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; @@ -34386,7 +34473,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; @@ -34420,7 +34507,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; @@ -34493,12 +34580,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); } @@ -34514,7 +34601,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; @@ -34522,14 +34609,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; } @@ -34537,7 +34624,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); } @@ -34680,10 +34767,10 @@ typedef enum BCTagEnum { BC_TAG_DATE, BC_TAG_OBJECT_VALUE, BC_TAG_OBJECT_REFERENCE, -#ifdef CONFIG_BIGNUM +// #ifdef CONFIG_BIGNUM BC_TAG_BIG_FLOAT, BC_TAG_BIG_DECIMAL, -#endif +// #endif } BCTagEnum; #ifdef CONFIG_BIGNUM @@ -34955,7 +35042,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]); @@ -35603,7 +35690,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; @@ -37704,32 +37791,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) { @@ -37922,6 +37983,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) { @@ -38269,6 +38337,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 ), @@ -38496,9 +38590,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; @@ -39845,8 +39939,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); @@ -40149,8 +40242,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 { @@ -40380,8 +40472,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; } @@ -40906,7 +40998,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 @@ -41947,7 +42039,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); @@ -41956,7 +42048,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; } @@ -43077,7 +43169,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]); @@ -43231,9 +43323,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; @@ -43251,12 +43347,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 ), @@ -43281,7 +43383,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 ), @@ -43367,7 +43469,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)); } @@ -45099,7 +45201,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; @@ -45347,7 +45449,7 @@ static int js_json_to_str(JSContext *ctx, JSONStringifyContext *jsc, JS_ThrowTypeError(ctx, "bigint are forbidden in JSON.stringify"); goto exception; } - 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)) { @@ -45368,7 +45470,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); @@ -45408,7 +45510,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)) @@ -45554,7 +45656,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; @@ -45678,7 +45780,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; } @@ -45883,7 +45985,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 && @@ -45970,7 +46072,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); @@ -45996,7 +46098,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); @@ -46480,7 +46582,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; @@ -46820,7 +46922,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; } @@ -46970,7 +47072,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; @@ -47141,7 +47243,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); @@ -47363,7 +47465,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) @@ -47883,7 +47985,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; } @@ -47966,7 +48068,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]); @@ -48166,7 +48268,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; @@ -48223,10 +48325,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; @@ -48387,10 +48489,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; @@ -48426,7 +48528,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; @@ -48457,7 +48559,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: @@ -48465,7 +48567,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; @@ -48525,7 +48627,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; } @@ -48568,7 +48670,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; @@ -48587,7 +48689,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: @@ -48732,7 +48834,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; @@ -48747,7 +48849,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; } @@ -48824,7 +48926,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); } @@ -48947,7 +49049,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]); @@ -48959,7 +49061,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; @@ -49129,7 +49231,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; @@ -49771,9 +49873,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, @@ -49804,7 +49914,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; @@ -52676,7 +52786,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); @@ -53929,7 +54039,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) @@ -53996,13 +54106,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) { - v64 = d; - is_int = (v64 == d); - } + // 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]); @@ -54569,8 +54677,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; } @@ -55150,7 +55258,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) @@ -55867,3 +55975,187 @@ 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; +} + +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; +} + +JSValue JS_NewDate(JSContext *ctx, const char *s) +{ + JSValue dateString = JS_NewString(ctx, s); + JSAtom constrAtom = JS_NewAtom(ctx, "Date"); + JSValue constr = JS_GetGlobalVar(ctx, constrAtom, FALSE); + JSValue date = js_date_constructor(ctx, constr, 1, &dateString); + JS_FreeValue(ctx, constr); + JS_FreeValue(ctx, dateString); + JS_FreeAtom(ctx, constrAtom); + return date; +} diff --git a/quickjs.h b/quickjs.h index a951e675d..88bb2563f 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,8 +670,13 @@ 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_NewDate(JSContext *ctx, const char *s); +JS_BOOL JS_IsDate(JSValueConst v); JSValue JS_NewArray(JSContext *ctx); int JS_IsArray(JSContext *ctx, JSValueConst val); @@ -758,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) @@ -787,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, @@ -958,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); @@ -1052,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