simplifications

This commit is contained in:
2026-02-11 13:15:04 -06:00
parent 259bc139fc
commit fbeec17ce5
21 changed files with 190 additions and 685 deletions

View File

@@ -319,7 +319,7 @@ JSValue js_reader_list(JSContext *js, JSValue self, int argc, JSValue *argv)
JS_FreeValue(js, arr); JS_FreeValue(js, arr);
return filename; return filename;
} }
JS_SetPropertyUint32(js, arr, arr_index++, filename); JS_SetPropertyNumber(js, arr, arr_index++, filename);
} }
return arr; return arr;

4
fd.c
View File

@@ -602,7 +602,7 @@ static void visit_directory(JSContext *js, JSValue results, int *result_count, c
} else { } else {
strcpy(item_rel, ffd.cFileName); strcpy(item_rel, ffd.cFileName);
} }
JS_SetPropertyUint32(js, results, (*result_count)++, JS_NewString(js, item_rel)); JS_SetPropertyNumber(js, results, (*result_count)++, JS_NewString(js, item_rel));
if (recurse) { if (recurse) {
struct stat st; struct stat st;
@@ -627,7 +627,7 @@ static void visit_directory(JSContext *js, JSValue results, int *result_count, c
} else { } else {
strcpy(item_rel, dir->d_name); strcpy(item_rel, dir->d_name);
} }
JS_SetPropertyUint32(js, results, (*result_count)++, JS_NewString(js, item_rel)); JS_SetPropertyNumber(js, results, (*result_count)++, JS_NewString(js, item_rel));
if (recurse) { if (recurse) {
struct stat st; struct stat st;

View File

@@ -324,7 +324,7 @@ static void listfiles_cb(const char *path, void *userdata) {
// Playdate listfiles returns just the name, but sometimes with slash for dir? // Playdate listfiles returns just the name, but sometimes with slash for dir?
// Docs say "names of files". // Docs say "names of files".
JS_SetPropertyUint32(ctx->js, ctx->array, ctx->index++, JS_NewString(ctx->js, path)); JS_SetPropertyNumber(ctx->js, ctx->array, ctx->index++, JS_NewString(ctx->js, path));
} }
JSC_SCALL(fd_readdir, JSC_SCALL(fd_readdir,
@@ -427,7 +427,7 @@ static void enum_cb(const char *name, void *userdata) {
strcpy(item_rel, name); strcpy(item_rel, name);
} }
JS_SetPropertyUint32(ctx->js, ctx->results, (*ctx->count)++, JS_NewString(ctx->js, item_rel)); JS_SetPropertyNumber(ctx->js, ctx->results, (*ctx->count)++, JS_NewString(ctx->js, item_rel));
if (ctx->recurse) { if (ctx->recurse) {
// Check if directory // Check if directory

View File

@@ -62,7 +62,7 @@ static JSValue js_enet_host_create(JSContext *ctx, JSValueConst this_val, int ar
enet_uint32 outgoing_bandwidth = 0; enet_uint32 outgoing_bandwidth = 0;
JSValue obj; JSValue obj;
if (argc < 1 || !JS_IsObject(argv[0])) { if (argc < 1 || !JS_IsRecord(argv[0])) {
host = enet_host_create(NULL, peer_count, channel_limit, incoming_bandwidth, outgoing_bandwidth); host = enet_host_create(NULL, peer_count, channel_limit, incoming_bandwidth, outgoing_bandwidth);
if (!host) return JS_ThrowInternalError(ctx, "Failed to create ENet client host"); if (!host) return JS_ThrowInternalError(ctx, "Failed to create ENet client host");
goto wrap; goto wrap;

View File

@@ -132,7 +132,7 @@ JSC_CCALL(socket_getaddrinfo,
// Store the addrinfo pointer as an internal property // Store the addrinfo pointer as an internal property
// We'll need to handle this differently since we can't wrap it // We'll need to handle this differently since we can't wrap it
// For now, we'll skip storing the raw addrinfo // For now, we'll skip storing the raw addrinfo
JS_SetPropertyUint32(js, ret, idx++, info); JS_SetPropertyNumber(js, ret, idx++, info);
} }
freeaddrinfo(res); freeaddrinfo(res);

View File

@@ -128,7 +128,7 @@ struct listfiles_ctx {
static void listfiles_cb(const char *path, void *userdata) { static void listfiles_cb(const char *path, void *userdata) {
struct listfiles_ctx *ctx = (struct listfiles_ctx*)userdata; struct listfiles_ctx *ctx = (struct listfiles_ctx*)userdata;
JS_SetPropertyUint32(ctx->js, ctx->array, ctx->index++, JS_NewString(ctx->js, path)); JS_SetPropertyNumber(ctx->js, ctx->array, ctx->index++, JS_NewString(ctx->js, path));
} }
JSC_SCALL(file_listfiles, JSC_SCALL(file_listfiles,

View File

@@ -79,7 +79,7 @@ static void json_decode_array_value(json_decoder *decoder, int pos, json_value v
case kJSONString: jsval = JS_NewString(ctx->js, value.data.stringval); break; case kJSONString: jsval = JS_NewString(ctx->js, value.data.stringval); break;
default: jsval = JS_NULL; break; default: jsval = JS_NULL; break;
} }
JS_SetPropertyUint32(ctx->js, container, pos, jsval); JS_SetPropertyNumber(ctx->js, container, pos, jsval);
} }
// --- JSON Encoder Context --- // --- JSON Encoder Context ---
@@ -128,7 +128,7 @@ static void encode_js_array(json_encoder *enc, JSContext *js, JSValue arr) {
JS_FreeValue(js, lenVal); JS_FreeValue(js, lenVal);
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
enc->addArrayMember(enc); enc->addArrayMember(enc);
JSValue val = JS_GetPropertyUint32(js, arr, i); JSValue val = JS_GetPropertyNumber(js, arr, i);
encode_js_value(enc, js, val); encode_js_value(enc, js, val);
JS_FreeValue(js, val); JS_FreeValue(js, val);
} }

View File

@@ -57,7 +57,7 @@ static void boards_list_cb(PDBoardsList *boards, const char *errorMessage) {
boards->boards[i].boardID ? JS_NewString(g_scoreboard_js, boards->boards[i].boardID) : JS_NULL); boards->boards[i].boardID ? JS_NewString(g_scoreboard_js, boards->boards[i].boardID) : JS_NULL);
JS_SetPropertyStr(g_scoreboard_js, board, "name", JS_SetPropertyStr(g_scoreboard_js, board, "name",
boards->boards[i].name ? JS_NewString(g_scoreboard_js, boards->boards[i].name) : JS_NULL); boards->boards[i].name ? JS_NewString(g_scoreboard_js, boards->boards[i].name) : JS_NULL);
JS_SetPropertyUint32(g_scoreboard_js, arr, i, board); JS_SetPropertyNumber(g_scoreboard_js, arr, i, board);
} }
args[0] = arr; args[0] = arr;
} else { } else {
@@ -83,7 +83,7 @@ static void scores_cb(PDScoresList *scores, const char *errorMessage) {
JS_SetPropertyStr(g_scoreboard_js, obj, "limit", JS_NewInt32(g_scoreboard_js, scores->limit)); JS_SetPropertyStr(g_scoreboard_js, obj, "limit", JS_NewInt32(g_scoreboard_js, scores->limit));
JSValue arr = JS_NewArray(g_scoreboard_js); JSValue arr = JS_NewArray(g_scoreboard_js);
for (unsigned int i = 0; i < scores->count; i++) { for (unsigned int i = 0; i < scores->count; i++) {
JS_SetPropertyUint32(g_scoreboard_js, arr, i, score_to_js(g_scoreboard_js, &scores->scores[i])); JS_SetPropertyNumber(g_scoreboard_js, arr, i, score_to_js(g_scoreboard_js, &scores->scores[i]));
} }
JS_SetPropertyStr(g_scoreboard_js, obj, "scores", arr); JS_SetPropertyStr(g_scoreboard_js, obj, "scores", arr);
args[0] = obj; args[0] = obj;

View File

@@ -675,7 +675,7 @@ var qbe_emit = function(ir, qbe) {
ei = 0 ei = 0
while (ei < nr_elems) { while (ei < nr_elems) {
elem_slot = instr[3 + ei] elem_slot = instr[3 + ei]
emit(` call $JS_SetPropertyUint32(l %ctx, l ${s(a1)}, l ${text(ei)}, l ${s(elem_slot)})`) emit(` call $JS_SetPropertyNumber(l %ctx, l ${s(a1)}, l ${text(ei)}, l ${s(elem_slot)})`)
ei = ei + 1 ei = ei + 1
} }
wb(a1) wb(a1)

Binary file not shown.

2
qop.c
View File

@@ -267,7 +267,7 @@ static JSValue js_qop_list(JSContext *js, JSValue self, int argc, JSValue *argv)
JSValue str = JS_NewStringLen(js, path, len - 1); // -1 for null terminator JSValue str = JS_NewStringLen(js, path, len - 1); // -1 for null terminator
js_free(js, path); js_free(js, path);
JS_SetPropertyUint32(js, arr, count++, str); JS_SetPropertyNumber(js, arr, count++, str);
} }
return arr; return arr;

View File

@@ -1327,9 +1327,6 @@ static int re_parse_nested_class(REParseState *s, REStringList *cr, const uint8_
REStringList cr1_s, *cr1 = &cr1_s; REStringList cr1_s, *cr1 = &cr1_s;
BOOL invert, is_first; BOOL invert, is_first;
if (lre_check_stack_overflow(s->opaque, 0))
return re_parse_error(s, "stack overflow");
re_string_list_init(s, cr); re_string_list_init(s, cr);
p = *pp; p = *pp;
p++; /* skip '[' */ p++; /* skip '[' */
@@ -2356,9 +2353,6 @@ static int re_parse_disjunction(REParseState *s, BOOL is_backward_dir)
{ {
int start, len, pos; int start, len, pos;
if (lre_check_stack_overflow(s->opaque, 0))
return re_parse_error(s, "stack overflow");
start = s->byte_code.size; start = s->byte_code.size;
if (re_parse_alternative(s, is_backward_dir)) if (re_parse_alternative(s, is_backward_dir))
return -1; return -1;
@@ -3205,11 +3199,6 @@ const char *lre_get_groupnames(const uint8_t *bc_buf)
#ifdef TEST #ifdef TEST
BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size)
{
return FALSE;
}
void *lre_realloc(void *opaque, void *ptr, size_t size) void *lre_realloc(void *opaque, void *ptr, size_t size)
{ {
return realloc(ptr, size); return realloc(ptr, size);

View File

@@ -52,8 +52,6 @@ int lre_exec(uint8_t **capture,
int lre_parse_escape(const uint8_t **pp, int allow_utf16); int lre_parse_escape(const uint8_t **pp, int allow_utf16);
/* must be provided by the user, return non zero if overflow */
int lre_check_stack_overflow(void *opaque, size_t alloca_size);
/* must be provided by the user, return non zero if time out */ /* must be provided by the user, return non zero if time out */
int lre_check_timeout(void *opaque); int lre_check_timeout(void *opaque);
void *lre_realloc(void *opaque, void *ptr, size_t size); void *lre_realloc(void *opaque, void *ptr, size_t size);

View File

@@ -2979,7 +2979,7 @@ JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
JSValue idx = frame->slots[c]; JSValue idx = frame->slots[c];
JSValue val; JSValue val;
if (JS_IsInt(idx)) if (JS_IsInt(idx))
val = JS_GetPropertyUint32(ctx, obj, JS_VALUE_GET_INT(idx)); val = JS_GetPropertyNumber(ctx, obj, JS_VALUE_GET_INT(idx));
else else
val = JS_GetProperty(ctx, obj, idx); val = JS_GetProperty(ctx, obj, idx);
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val); frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
@@ -2995,7 +2995,8 @@ JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
JSValue val = frame->slots[c]; JSValue val = frame->slots[c];
int ret; int ret;
if (JS_IsInt(idx)) { if (JS_IsInt(idx)) {
ret = JS_SetPropertyUint32(ctx, obj, JS_VALUE_GET_INT(idx), val); JSValue r = JS_SetPropertyNumber(ctx, obj, JS_VALUE_GET_INT(idx), val);
ret = JS_IsException(r) ? -1 : 0;
} else if (JS_IsArray(obj)) { } else if (JS_IsArray(obj)) {
JS_ThrowTypeError(ctx, "array index must be a number"); JS_ThrowTypeError(ctx, "array index must be a number");
ret = -1; ret = -1;
@@ -3201,7 +3202,7 @@ JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
if (JS_IsException(arr)) { JS_PopGCRef(ctx, &key_ref); goto disrupt; } if (JS_IsException(arr)) { JS_PopGCRef(ctx, &key_ref); goto disrupt; }
frame->slots[base + 1] = arr; /* protect from GC in temp slot */ frame->slots[base + 1] = arr; /* protect from GC in temp slot */
for (int i = 0; i < nargs; i++) { for (int i = 0; i < nargs; i++) {
JS_SetPropertyUint32(ctx, frame->slots[base + 1], i, frame->slots[base + 2 + i]); JS_SetPropertyNumber(ctx, frame->slots[base + 1], i, frame->slots[base + 2 + i]);
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val); frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
} }
/* Call proxy with key and array from C stack */ /* Call proxy with key and array from C stack */
@@ -3336,7 +3337,7 @@ JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
/* Store array in dest immediately so GC can track it */ /* Store array in dest immediately so GC can track it */
frame->slots[a] = arr; frame->slots[a] = arr;
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
JS_SetPropertyUint32(ctx, frame->slots[a], i, frame->slots[a + 1 + i]); JS_SetPropertyNumber(ctx, frame->slots[a], i, frame->slots[a + 1 + i]);
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val); frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
} }
break; break;

View File

@@ -1318,7 +1318,7 @@ JSValue mcode_exec(JSContext *ctx, JSMCode *code, JSValue this_obj,
} else { } else {
JSValue idx = frame->slots[(int)a3->valuedouble]; JSValue idx = frame->slots[(int)a3->valuedouble];
if (JS_IsInt(idx)) if (JS_IsInt(idx))
val = JS_GetPropertyUint32(ctx, obj, JS_VALUE_GET_INT(idx)); val = JS_GetPropertyNumber(ctx, obj, JS_VALUE_GET_INT(idx));
else else
val = JS_GetProperty(ctx, obj, idx); val = JS_GetProperty(ctx, obj, idx);
} }
@@ -1348,7 +1348,8 @@ JSValue mcode_exec(JSContext *ctx, JSMCode *code, JSValue this_obj,
JSValue idx = frame->slots[(int)a3->valuedouble]; JSValue idx = frame->slots[(int)a3->valuedouble];
int ret; int ret;
if (JS_IsInt(idx)) { if (JS_IsInt(idx)) {
ret = JS_SetPropertyUint32(ctx, obj, JS_VALUE_GET_INT(idx), val); JSValue r = JS_SetPropertyNumber(ctx, obj, JS_VALUE_GET_INT(idx), val);
ret = JS_IsException(r) ? -1 : 0;
} else if (JS_IsArray(obj)) { } else if (JS_IsArray(obj)) {
JS_ThrowTypeError(ctx, "array index must be a number"); JS_ThrowTypeError(ctx, "array index must be a number");
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val); frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
@@ -1517,7 +1518,7 @@ JSValue mcode_exec(JSContext *ctx, JSMCode *code, JSValue this_obj,
for (int i = 0; i < nargs; i++, p = p->next) { for (int i = 0; i < nargs; i++, p = p->next) {
if (cJSON_IsString(p)) break; /* hit line/col */ if (cJSON_IsString(p)) break; /* hit line/col */
int areg = (int)p->valuedouble; int areg = (int)p->valuedouble;
JS_SetPropertyUint32(ctx, frame->slots[dest], i, frame->slots[areg]); JS_SetPropertyNumber(ctx, frame->slots[dest], i, frame->slots[areg]);
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val); frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
} }
JSValue call_args[2] = { key_gc.val, frame->slots[dest] }; JSValue call_args[2] = { key_gc.val, frame->slots[dest] };
@@ -1609,7 +1610,7 @@ JSValue mcode_exec(JSContext *ctx, JSMCode *code, JSValue this_obj,
cJSON *p = a3->next; cJSON *p = a3->next;
for (int i = 0; i < nargs; i++, p = p->next) { for (int i = 0; i < nargs; i++, p = p->next) {
int areg = (int)p->valuedouble; int areg = (int)p->valuedouble;
JS_SetPropertyUint32(ctx, frame->slots[dest], i, frame->slots[areg]); JS_SetPropertyNumber(ctx, frame->slots[dest], i, frame->slots[areg]);
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val); frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
} }
JSValue call_args[2] = { frame->slots[key_reg], frame->slots[dest] }; JSValue call_args[2] = { frame->slots[key_reg], frame->slots[dest] };
@@ -1758,7 +1759,7 @@ JSValue mcode_exec(JSContext *ctx, JSMCode *code, JSValue this_obj,
JSGCRef arg_refs[len > 0 ? len : 1]; JSGCRef arg_refs[len > 0 ? len : 1];
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
JS_PushGCRef(ctx, &arg_refs[i]); JS_PushGCRef(ctx, &arg_refs[i]);
arg_refs[i].val = JS_GetPropertyUint32(ctx, frame->slots[arr_slot], i); arg_refs[i].val = JS_GetPropertyNumber(ctx, frame->slots[arr_slot], i);
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val); frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
} }
JSValue args[len > 0 ? len : 1]; JSValue args[len > 0 ? len : 1];
@@ -1790,7 +1791,7 @@ JSValue mcode_exec(JSContext *ctx, JSMCode *code, JSValue this_obj,
cJSON *elem = cJSON_GetArrayItem(instr, 3 + i); cJSON *elem = cJSON_GetArrayItem(instr, 3 + i);
if (elem) { if (elem) {
int elem_slot = (int)elem->valuedouble; int elem_slot = (int)elem->valuedouble;
JS_SetPropertyUint32(ctx, frame->slots[dest], i, frame->slots[elem_slot]); JS_SetPropertyNumber(ctx, frame->slots[dest], i, frame->slots[elem_slot]);
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val); frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
} }
} }

View File

@@ -213,28 +213,28 @@ void cell_rt_store_field(JSContext *ctx, JSValue val, JSValue obj,
JSValue cell_rt_load_dynamic(JSContext *ctx, JSValue obj, JSValue key) { JSValue cell_rt_load_dynamic(JSContext *ctx, JSValue obj, JSValue key) {
if (JS_IsInt(key)) if (JS_IsInt(key))
return JS_GetPropertyUint32(ctx, obj, (uint32_t)JS_VALUE_GET_INT(key)); return JS_GetPropertyNumber(ctx, obj, (uint32_t)JS_VALUE_GET_INT(key));
return JS_GetProperty(ctx, obj, key); return JS_GetProperty(ctx, obj, key);
} }
void cell_rt_store_dynamic(JSContext *ctx, JSValue val, JSValue obj, void cell_rt_store_dynamic(JSContext *ctx, JSValue val, JSValue obj,
JSValue key) { JSValue key) {
if (JS_IsInt(key)) if (JS_IsInt(key))
JS_SetPropertyUint32(ctx, obj, (uint32_t)JS_VALUE_GET_INT(key), val); JS_SetPropertyNumber(ctx, obj, (uint32_t)JS_VALUE_GET_INT(key), val);
else else
JS_SetProperty(ctx, obj, key, val); JS_SetProperty(ctx, obj, key, val);
} }
JSValue cell_rt_load_index(JSContext *ctx, JSValue arr, JSValue idx) { JSValue cell_rt_load_index(JSContext *ctx, JSValue arr, JSValue idx) {
if (JS_IsInt(idx)) if (JS_IsInt(idx))
return JS_GetPropertyUint32(ctx, arr, (uint32_t)JS_VALUE_GET_INT(idx)); return JS_GetPropertyNumber(ctx, arr, (uint32_t)JS_VALUE_GET_INT(idx));
return JS_GetProperty(ctx, arr, idx); return JS_GetProperty(ctx, arr, idx);
} }
void cell_rt_store_index(JSContext *ctx, JSValue val, JSValue arr, void cell_rt_store_index(JSContext *ctx, JSValue val, JSValue arr,
JSValue idx) { JSValue idx) {
if (JS_IsInt(idx)) if (JS_IsInt(idx))
JS_SetPropertyUint32(ctx, arr, (uint32_t)JS_VALUE_GET_INT(idx), val); JS_SetPropertyNumber(ctx, arr, (uint32_t)JS_VALUE_GET_INT(idx), val);
else else
JS_SetProperty(ctx, arr, idx, val); JS_SetProperty(ctx, arr, idx, val);
} }

View File

@@ -54,14 +54,6 @@
#include "nota.h" #include "nota.h"
#include "wota.h" #include "wota.h"
#define OPTIMIZE 1
#define SHORT_OPCODES 1
#if defined(EMSCRIPTEN)
#define DIRECT_DISPATCH 0
#else
#define DIRECT_DISPATCH 1
#endif
#if !defined(_WIN32) #if !defined(_WIN32)
/* define it if printf uses the RNDN rounding mode instead of RNDNA */ /* define it if printf uses the RNDN rounding mode instead of RNDNA */
#define CONFIG_PRINTF_RNDN #define CONFIG_PRINTF_RNDN
@@ -154,7 +146,6 @@ typedef struct JSCode JSCode;
/* Extract pointer (clear low bits) */ /* Extract pointer (clear low bits) */
#define JS_VALUE_GET_PTR(v) ((void *)((v) & ~((JSValue)(JSW - 1)))) #define JS_VALUE_GET_PTR(v) ((void *)((v) & ~((JSValue)(JSW - 1))))
static inline JS_BOOL JS_VALUE_IS_TEXT (JSValue v) { static inline JS_BOOL JS_VALUE_IS_TEXT (JSValue v) {
int tag = JS_VALUE_GET_TAG (v); int tag = JS_VALUE_GET_TAG (v);
return tag == JS_TAG_STRING_IMM || (JS_IsPtr(v) && objhdr_type(*(objhdr_t *)JS_VALUE_GET_PTR(v)) == OBJ_TEXT); return tag == JS_TAG_STRING_IMM || (JS_IsPtr(v) && objhdr_type(*(objhdr_t *)JS_VALUE_GET_PTR(v)) == OBJ_TEXT);
@@ -1264,36 +1255,6 @@ typedef struct JSProperty {
#define JS_ARRAY_MAX_CAP ((word_t)((1UL << 24) - 1)) #define JS_ARRAY_MAX_CAP ((word_t)((1UL << 24) - 1))
#endif #endif
typedef enum OPCodeFormat {
#define FMT(f) OP_FMT_##f,
#define DEF(id, size, n_pop, n_push, f)
#include "quickjs-opcode.h"
#undef DEF
#undef FMT
} OPCodeFormat;
enum OPCodeEnum {
#define FMT(f)
#define DEF(id, size, n_pop, n_push, f) OP_##id,
#define def(id, size, n_pop, n_push, f)
#include "quickjs-opcode.h"
#undef def
#undef DEF
#undef FMT
OP_COUNT, /* excluding temporary opcodes */
/* temporary opcodes : overlap with the short opcodes */
OP_TEMP_START = OP_nop + 1,
OP___dummy = OP_TEMP_START - 1,
#define FMT(f)
#define DEF(id, size, n_pop, n_push, f)
#define def(id, size, n_pop, n_push, f) OP_##id,
#include "quickjs-opcode.h"
#undef def
#undef DEF
#undef FMT
OP_TEMP_END,
};
JSValue js_call_c_function (JSContext *ctx, JSValue func_obj, JSValue this_obj, int argc, JSValue *argv); JSValue js_call_c_function (JSContext *ctx, JSValue func_obj, JSValue this_obj, int argc, JSValue *argv);
JSValue js_call_bound_function (JSContext *ctx, JSValue func_obj, JSValue this_obj, int argc, JSValue *argv); JSValue js_call_bound_function (JSContext *ctx, JSValue func_obj, JSValue this_obj, int argc, JSValue *argv);
JSValue JS_CallInternal (JSContext *ctx, JSValue func_obj, JSValue this_obj, int argc, JSValue *argv, int flags); JSValue JS_CallInternal (JSContext *ctx, JSValue func_obj, JSValue this_obj, int argc, JSValue *argv, int flags);
@@ -1481,22 +1442,6 @@ static inline void set_value (JSContext *ctx, JSValue *pval, JSValue new_val) {
*pval = new_val; *pval = new_val;
} }
#if !defined(CONFIG_STACK_CHECK)
static inline uintptr_t js_get_stack_pointer (void) { return 0; }
static inline BOOL js_check_stack_overflow (JSContext *ctx, size_t alloca_size) {
return FALSE;
}
#else
static inline uintptr_t js_get_stack_pointer (void) {
return (uintptr_t)__builtin_frame_address (0);
}
static inline BOOL js_check_stack_overflow (JSContext *ctx, size_t alloca_size) {
uintptr_t sp;
sp = js_get_stack_pointer () - alloca_size;
return unlikely (sp < (uintptr_t)ctx->stack_limit);
}
#endif
void JS_ThrowInterrupted (JSContext *ctx); void JS_ThrowInterrupted (JSContext *ctx);
static no_inline __exception int __js_poll_interrupts (JSContext *ctx) { static no_inline __exception int __js_poll_interrupts (JSContext *ctx) {
@@ -1658,7 +1603,6 @@ int get_line_col_cached (GetLineColCache *s, int *pcol_num, const uint8_t *ptr);
/* runtime.c exports */ /* runtime.c exports */
JSValue JS_ThrowStackOverflow (JSContext *ctx); JSValue JS_ThrowStackOverflow (JSContext *ctx);
JSValue JS_ThrowReferenceErrorUninitialized (JSContext *ctx, JSValue name);
int JS_DefineObjectName (JSContext *ctx, JSValue obj, JSValue name); int JS_DefineObjectName (JSContext *ctx, JSValue obj, JSValue name);
int JS_DefineObjectNameComputed (JSContext *ctx, JSValue obj, JSValue str); int JS_DefineObjectNameComputed (JSContext *ctx, JSValue obj, JSValue str);
int js_method_set_properties (JSContext *ctx, JSValue func_obj, JSValue name, int flags, JSValue home_obj); int js_method_set_properties (JSContext *ctx, JSValue func_obj, JSValue name, int flags, JSValue home_obj);

View File

@@ -1,296 +0,0 @@
/*
* QuickJS opcode definitions
*
* Copyright (c) 2017-2018 Fabrice Bellard
* Copyright (c) 2017-2018 Charlie Gordon
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifdef FMT
FMT(none)
FMT(none_int)
FMT(none_loc)
FMT(none_arg)
FMT(u8)
FMT(i8)
FMT(loc8)
FMT(const8)
FMT(label8)
FMT(u16)
FMT(i16)
FMT(label16)
FMT(npop)
FMT(npopx)
FMT(npop_u16)
FMT(loc)
FMT(arg)
FMT(u32)
FMT(i32)
FMT(const)
FMT(label)
FMT(label_u16)
FMT(key)
FMT(key_u8)
FMT(key_u16)
FMT(key_label_u16)
FMT(u8_u16) /* 1 byte + 2 bytes for upvalue access */
#undef FMT
#endif /* FMT */
#ifdef DEF
#ifndef def
#define def(id, size, n_pop, n_push, f) DEF(id, size, n_pop, n_push, f)
#endif
DEF(invalid, 1, 0, 0, none) /* never emitted */
/* push values */
DEF( push_i32, 5, 0, 1, i32)
DEF( push_const, 5, 0, 1, const)
DEF( fclosure, 5, 0, 1, const) /* must follow push_const */
DEF( null, 1, 0, 1, none)
DEF( push_this, 1, 0, 1, none) /* only used at the start of a function */
DEF( push_false, 1, 0, 1, none)
DEF( push_true, 1, 0, 1, none)
DEF( object, 1, 0, 1, none)
DEF( special_object, 2, 0, 1, u8) /* only used at the start of a function */
DEF( drop, 1, 1, 0, none) /* a -> */
DEF( nip, 1, 2, 1, none) /* a b -> b */
DEF( nip1, 1, 3, 2, none) /* a b c -> b c */
DEF( dup, 1, 1, 2, none) /* a -> a a */
DEF( dup1, 1, 2, 3, none) /* a b -> a a b */
DEF( dup2, 1, 2, 4, none) /* a b -> a b a b */
DEF( dup3, 1, 3, 6, none) /* a b c -> a b c a b c */
DEF( insert2, 1, 2, 3, none) /* obj a -> a obj a (dup_x1) */
DEF( insert3, 1, 3, 4, none) /* obj prop a -> a obj prop a (dup_x2) */
DEF( insert4, 1, 4, 5, none) /* this obj prop a -> a this obj prop a */
DEF( perm3, 1, 3, 3, none) /* obj a b -> a obj b */
DEF( perm4, 1, 4, 4, none) /* obj prop a b -> a obj prop b */
DEF( perm5, 1, 5, 5, none) /* this obj prop a b -> a this obj prop b */
DEF( swap, 1, 2, 2, none) /* a b -> b a */
DEF( swap2, 1, 4, 4, none) /* a b c d -> c d a b */
DEF( rot3l, 1, 3, 3, none) /* x a b -> a b x */
DEF( rot3r, 1, 3, 3, none) /* a b x -> x a b */
DEF( rot4l, 1, 4, 4, none) /* x a b c -> a b c x */
DEF( rot5l, 1, 5, 5, none) /* x a b c d -> a b c d x */
DEF( call, 3, 1, 1, npop) /* arguments are not counted in n_pop */
DEF( tail_call, 3, 1, 0, npop) /* arguments are not counted in n_pop */
DEF( call_method, 3, 2, 1, npop) /* arguments are not counted in n_pop */
DEF(tail_call_method, 3, 2, 0, npop) /* arguments are not counted in n_pop */
DEF( array_from, 3, 0, 1, npop) /* arguments are not counted in n_pop */
DEF( return, 1, 1, 0, none)
DEF( return_undef, 1, 0, 0, none)
DEF( throw, 1, 1, 0, none)
DEF( throw_error, 6, 0, 0, key_u8)
DEF( regexp, 1, 2, 1, none) /* create a RegExp object from the pattern and a
bytecode string */
/* Global variable access - resolved by linker to get/set_global_slot */
DEF( check_var, 5, 0, 1, key) /* check if a variable exists - resolved by linker */
DEF( get_var_undef, 5, 0, 1, key) /* resolved by linker to get_global_slot */
DEF( get_var, 5, 0, 1, key) /* resolved by linker to get_global_slot */
DEF( put_var, 5, 1, 0, key) /* resolved by linker to set_global_slot */
DEF( put_var_init, 5, 1, 0, key) /* resolved by linker to set_global_slot */
DEF( put_var_strict, 5, 2, 0, key) /* resolved by linker to set_global_slot */
/* Global variable opcodes - resolved by linker to get/set_global_slot */
DEF( define_var, 6, 0, 0, key_u8)
DEF(check_define_var, 6, 0, 0, key_u8)
DEF( define_func, 6, 1, 0, key_u8)
DEF( get_field, 5, 1, 1, key)
DEF( get_field2, 5, 1, 2, key)
DEF( put_field, 5, 2, 0, key)
DEF( get_array_el, 1, 2, 1, none)
DEF( get_array_el2, 1, 2, 2, none) /* obj prop -> obj value */
DEF( get_array_el3, 1, 2, 3, none) /* obj prop -> obj prop1 value */
DEF( put_array_el, 1, 3, 0, none)
DEF( define_field, 5, 2, 1, key)
DEF( set_name, 5, 1, 1, key)
DEF(set_name_computed, 1, 2, 2, none)
DEF(define_array_el, 1, 3, 2, none)
DEF(copy_data_properties, 2, 3, 3, u8)
DEF( define_method, 6, 2, 1, key_u8)
DEF(define_method_computed, 2, 3, 1, u8) /* must come after define_method */
DEF( define_class, 6, 2, 2, key_u8) /* parent ctor -> ctor proto */
DEF( define_class_computed, 6, 3, 3, key_u8) /* field_name parent ctor -> field_name ctor proto (class with computed name) */
DEF( get_loc, 3, 0, 1, loc)
DEF( put_loc, 3, 1, 0, loc) /* must come after get_loc */
DEF( set_loc, 3, 1, 1, loc) /* must come after put_loc */
DEF( get_arg, 3, 0, 1, arg)
DEF( put_arg, 3, 1, 0, arg) /* must come after get_arg */
DEF( set_arg, 3, 1, 1, arg) /* must come after put_arg */
DEF(set_loc_uninitialized, 3, 0, 0, loc)
DEF( get_loc_check, 3, 0, 1, loc)
DEF( put_loc_check, 3, 1, 0, loc) /* must come after get_loc_check */
DEF( put_loc_check_init, 3, 1, 0, loc)
DEF(get_loc_checkthis, 3, 0, 1, loc)
DEF( if_false, 5, 1, 0, label)
DEF( if_true, 5, 1, 0, label) /* must come after if_false */
DEF( goto, 5, 0, 0, label) /* must come after if_true */
DEF( catch, 5, 0, 1, label)
DEF( gosub, 5, 0, 0, label) /* used to execute the finally block */
DEF( ret, 1, 1, 0, none) /* used to return from the finally block */
DEF( nip_catch, 1, 2, 1, none) /* catch ... a -> a */
DEF( to_propkey, 1, 1, 1, none)
/* arithmetic/logic operations */
DEF( neg, 1, 1, 1, none)
DEF( plus, 1, 1, 1, none)
DEF( dec, 1, 1, 1, none)
DEF( inc, 1, 1, 1, none)
DEF( post_dec, 1, 1, 2, none)
DEF( post_inc, 1, 1, 2, none)
DEF( dec_loc, 2, 0, 0, loc8)
DEF( inc_loc, 2, 0, 0, loc8)
DEF( add_loc, 2, 1, 0, loc8)
DEF( not, 1, 1, 1, none)
DEF( lnot, 1, 1, 1, none)
DEF( delete, 1, 2, 1, none)
DEF( delete_var, 5, 0, 1, key) /* deprecated - global object is immutable */
DEF( mul, 1, 2, 1, none)
DEF( mul_float, 1, 2, 1, none)
DEF( div, 1, 2, 1, none)
DEF( div_float, 1, 2, 1, none)
DEF( mod, 1, 2, 1, none)
DEF( add, 1, 2, 1, none)
DEF( add_float, 1, 2, 1, none)
DEF( sub, 1, 2, 1, none)
DEF( sub_float, 1, 2, 1, none)
DEF( pow, 1, 2, 1, none)
DEF( shl, 1, 2, 1, none)
DEF( sar, 1, 2, 1, none)
DEF( shr, 1, 2, 1, none)
DEF( lt, 1, 2, 1, none)
DEF( lte, 1, 2, 1, none)
DEF( gt, 1, 2, 1, none)
DEF( gte, 1, 2, 1, none)
DEF( in, 1, 2, 1, none)
DEF( strict_eq, 1, 2, 1, none)
DEF( strict_neq, 1, 2, 1, none)
DEF( and, 1, 2, 1, none)
DEF( xor, 1, 2, 1, none)
DEF( or, 1, 2, 1, none)
/* format template - format_string_cpool_idx(u32), expr_count(u16)
Note: n_push=2 ensures stack has room for temp [format_str, arr] pair,
even though we only leave 1 value (the result) on the stack. */
DEF(format_template, 7, 0, 1, npop_u16)
/* Upvalue access (closures via outer_frame chain) */
DEF( get_up, 4, 0, 1, u8_u16) /* depth:u8, slot:u16 -> value */
DEF( set_up, 4, 1, 0, u8_u16) /* value, depth:u8, slot:u16 -> */
/* Name resolution with bytecode patching */
DEF( get_name, 5, 0, 1, const) /* cpool_idx -> value, patches itself */
DEF( get_env_slot, 3, 0, 1, u16) /* slot -> value (patched from get_name) */
DEF( set_env_slot, 3, 1, 0, u16) /* value -> slot (patched from put_var) */
DEF(get_global_slot, 3, 0, 1, u16) /* slot -> value (patched from get_var) */
DEF(set_global_slot, 3, 1, 0, u16) /* value -> slot (patched from put_var) */
/* must be the last non short and non temporary opcode */
DEF( nop, 1, 0, 0, none)
/* temporary opcodes: never emitted in the final bytecode */
def( enter_scope, 3, 0, 0, u16) /* emitted in phase 1, removed in phase 2 */
def( leave_scope, 3, 0, 0, u16) /* emitted in phase 1, removed in phase 2 */
def( label, 5, 0, 0, label) /* emitted in phase 1, removed in phase 3 */
/* the following opcodes must be in the same order as the 'with_x' and
get_var_undef, get_var and put_var opcodes */
def(scope_get_var_undef, 7, 0, 1, key_u16) /* emitted in phase 1, removed in phase 2 */
def( scope_get_var, 7, 0, 1, key_u16) /* emitted in phase 1, removed in phase 2 */
def( scope_put_var, 7, 1, 0, key_u16) /* emitted in phase 1, removed in phase 2 */
def(scope_delete_var, 7, 0, 1, key_u16) /* emitted in phase 1, removed in phase 2 */
def(scope_put_var_init, 7, 0, 2, key_u16) /* emitted in phase 1, removed in phase 2 */
def(scope_get_var_checkthis, 7, 0, 1, key_u16) /* emitted in phase 1, removed in phase 2, only used to return 'this' in derived class constructors */
def(get_field_opt_chain, 5, 1, 1, key) /* emitted in phase 1, removed in phase 2 */
def(get_array_el_opt_chain, 1, 2, 1, none) /* emitted in phase 1, removed in phase 2 */
def( set_class_name, 5, 1, 1, u32) /* emitted in phase 1, removed in phase 2 */
def( line_num, 5, 0, 0, u32) /* emitted in phase 1, removed in phase 3 */
#if SHORT_OPCODES
DEF( push_minus1, 1, 0, 1, none_int)
DEF( push_0, 1, 0, 1, none_int)
DEF( push_1, 1, 0, 1, none_int)
DEF( push_2, 1, 0, 1, none_int)
DEF( push_3, 1, 0, 1, none_int)
DEF( push_4, 1, 0, 1, none_int)
DEF( push_5, 1, 0, 1, none_int)
DEF( push_6, 1, 0, 1, none_int)
DEF( push_7, 1, 0, 1, none_int)
DEF( push_i8, 2, 0, 1, i8)
DEF( push_i16, 3, 0, 1, i16)
DEF( push_const8, 2, 0, 1, const8)
DEF( fclosure8, 2, 0, 1, const8) /* must follow push_const8 */
DEF(push_empty_string, 1, 0, 1, none)
DEF( get_loc8, 2, 0, 1, loc8)
DEF( put_loc8, 2, 1, 0, loc8)
DEF( set_loc8, 2, 1, 1, loc8)
DEF( get_loc0, 1, 0, 1, none_loc)
DEF( get_loc1, 1, 0, 1, none_loc)
DEF( get_loc2, 1, 0, 1, none_loc)
DEF( get_loc3, 1, 0, 1, none_loc)
DEF( put_loc0, 1, 1, 0, none_loc)
DEF( put_loc1, 1, 1, 0, none_loc)
DEF( put_loc2, 1, 1, 0, none_loc)
DEF( put_loc3, 1, 1, 0, none_loc)
DEF( set_loc0, 1, 1, 1, none_loc)
DEF( set_loc1, 1, 1, 1, none_loc)
DEF( set_loc2, 1, 1, 1, none_loc)
DEF( set_loc3, 1, 1, 1, none_loc)
DEF( get_arg0, 1, 0, 1, none_arg)
DEF( get_arg1, 1, 0, 1, none_arg)
DEF( get_arg2, 1, 0, 1, none_arg)
DEF( get_arg3, 1, 0, 1, none_arg)
DEF( put_arg0, 1, 1, 0, none_arg)
DEF( put_arg1, 1, 1, 0, none_arg)
DEF( put_arg2, 1, 1, 0, none_arg)
DEF( put_arg3, 1, 1, 0, none_arg)
DEF( set_arg0, 1, 1, 1, none_arg)
DEF( set_arg1, 1, 1, 1, none_arg)
DEF( set_arg2, 1, 1, 1, none_arg)
DEF( set_arg3, 1, 1, 1, none_arg)
DEF( if_false8, 2, 1, 0, label8)
DEF( if_true8, 2, 1, 0, label8) /* must come after if_false8 */
DEF( goto8, 2, 0, 0, label8) /* must come after if_true8 */
DEF( goto16, 3, 0, 0, label16)
DEF( call0, 1, 1, 1, npopx)
DEF( call1, 1, 1, 1, npopx)
DEF( call2, 1, 1, 1, npopx)
DEF( call3, 1, 1, 1, npopx)
DEF( is_null, 1, 1, 1, none)
#endif
#undef DEF
#undef def
#endif /* DEF */

View File

@@ -55,13 +55,13 @@ enum mist_obj_type {
OBJ_FORWARD = 7 OBJ_FORWARD = 7
}; };
typedef uint64_t JSValue;
#define OBJHDR_S_BIT 3u #define OBJHDR_S_BIT 3u
#define OBJHDR_P_BIT 4u #define OBJHDR_P_BIT 4u
#define OBJHDR_A_BIT 5u #define OBJHDR_A_BIT 5u
#define OBJHDR_R_BIT 7u #define OBJHDR_R_BIT 7u
#define OBJHDR_FLAG(bit) ((objhdr_t)1ull << (bit)) #define OBJHDR_FLAG(bit) ((objhdr_t)1ull << (bit))
#define OBJHDR_S_MASK OBJHDR_FLAG (OBJHDR_S_BIT) #define OBJHDR_S_MASK OBJHDR_FLAG (OBJHDR_S_BIT)
#define OBJHDR_P_MASK OBJHDR_FLAG (OBJHDR_P_BIT) #define OBJHDR_P_MASK OBJHDR_FLAG (OBJHDR_P_BIT)
@@ -115,39 +115,24 @@ struct JSGCRef;
============================================================ */ ============================================================ */
#if INTPTR_MAX >= INT64_MAX
#define JS_PTR64
#define JS_PTR64_DEF(a) a
typedef uint64_t JSValue;
#define JSW 8
#else
typedef uint32_t JSValue;
#define JSW 4
#define JS_PTR64_DEF(a)
#endif
#define JSValue JSValue
/* JSValueConst is just JSValue (const is not needed in value semantics) */ /* JSValueConst is just JSValue (const is not needed in value semantics) */
typedef JSValue JSValueConst; typedef JSValue JSValueConst;
#define JSW 8
/* LSB-based tags */ /* LSB-based tags */
enum { enum {
/* Primary tags (low bits) */ /* Primary tags (low bits) */
JS_TAG_INT = 0, /* LSB = 0 */ JS_TAG_INT = 0, /* LSB = 0 */
JS_TAG_PTR = 1, /* LSB = 01 */ JS_TAG_PTR = 1, /* LSB = 01 */
#ifdef JS_PTR64
JS_TAG_SHORT_FLOAT = 5, /* LSB = 101 */ JS_TAG_SHORT_FLOAT = 5, /* LSB = 101 */
#endif
JS_TAG_SPECIAL = 3, /* LSB = 11 */ JS_TAG_SPECIAL = 3, /* LSB = 11 */
/* Special subtypes (5 bits: xxxx11) */ /* Special subtypes (5 bits: xxxx11) */
JS_TAG_BOOL = 0x03, /* 00011 */ JS_TAG_BOOL = 0x03, /* 00011 */
JS_TAG_NULL = 0x07, /* 00111 */ JS_TAG_NULL = 0x07, /* 00111 */
JS_TAG_EXCEPTION = 0x0F, /* 01111 */ JS_TAG_EXCEPTION = 0x0F, /* 01111 */
JS_TAG_UNINITIALIZED = 0x17, /* 10111 */ JS_TAG_STRING_IMM = 0x0B, /* 01011 - immediate ASCII (up to 7 chars) */
JS_TAG_STRING_IMM = 0x1B, /* 11011 - immediate ASCII (up to 7 chars) */
JS_TAG_CATCH_OFFSET = 0x1F, /* 11111 */
}; };
/* Compatibility tag aliases for external code */ /* Compatibility tag aliases for external code */
@@ -180,16 +165,10 @@ void JS_DeleteGCRef(JSContext *ctx, JSGCRef *ref);
/* Get primary tag (low 2-3 bits) */ /* Get primary tag (low 2-3 bits) */
static inline int static inline int
JS_VALUE_GET_TAG (JSValue v) { JS_VALUE_GET_TAG (JSValue v) {
#ifdef JS_PTR64
if ((v & 1) == 0) return JS_TAG_INT; if ((v & 1) == 0) return JS_TAG_INT;
if ((v & 7) == JS_TAG_SHORT_FLOAT) return JS_TAG_SHORT_FLOAT; if ((v & 7) == JS_TAG_SHORT_FLOAT) return JS_TAG_SHORT_FLOAT;
if ((v & 3) == JS_TAG_PTR) return JS_TAG_PTR; if ((v & 3) == JS_TAG_PTR) return JS_TAG_PTR;
return (int)(v & 0x1F); /* special tag */ return (int)(v & 0x1F); /* special tag */
#else
if ((v & 1) == 0) return JS_TAG_INT;
if ((v & 3) == JS_TAG_PTR) return JS_TAG_PTR;
return (int)(v & 0x1F);
#endif
} }
#define JS_VALUE_GET_NORM_TAG(v) JS_VALUE_GET_TAG (v) #define JS_VALUE_GET_NORM_TAG(v) JS_VALUE_GET_TAG (v)
@@ -220,7 +199,6 @@ static inline JSValue _JS_MkVal (int tag, int32_t val) {
Out of range → JS_NULL Out of range → JS_NULL
============================================================ */ ============================================================ */
#ifdef JS_PTR64
static inline JSValue static inline JSValue
__JS_NewFloat64 (JSContext *ctx, double d) { __JS_NewFloat64 (JSContext *ctx, double d) {
union { union {
@@ -280,17 +258,6 @@ static inline double JS_VALUE_GET_FLOAT64 (JSValue v) {
#define JS_TAG_IS_FLOAT64(tag) ((tag) == JS_TAG_SHORT_FLOAT) #define JS_TAG_IS_FLOAT64(tag) ((tag) == JS_TAG_SHORT_FLOAT)
#define JS_NAN JS_MKVAL (JS_TAG_NULL, 0) #define JS_NAN JS_MKVAL (JS_TAG_NULL, 0)
#else /* 32-bit: no short float, use boxed double */
static inline JSValue __JS_NewFloat64 (JSContext *ctx,
double d); /* forward decl */
static inline double JS_VALUE_GET_FLOAT64 (JSValue v);
#define JS_TAG_IS_FLOAT64(tag) (0)
#define JS_NAN JS_MKVAL (JS_TAG_NULL, 0)
#endif /* JS_PTR64 */
/* ============================================================ /* ============================================================
Type Checks Type Checks
============================================================ */ ============================================================ */
@@ -299,14 +266,10 @@ static inline JS_BOOL JS_IsInt (JSValue v) { return (v & 1) == 0; }
static inline JS_BOOL JS_IsPtr (JSValue v) { return (v & 7) == JS_TAG_PTR; } static inline JS_BOOL JS_IsPtr (JSValue v) { return (v & 7) == JS_TAG_PTR; }
static inline JS_BOOL JS_IsSpecial (JSValue v) { return (v & 3) == JS_TAG_SPECIAL; } static inline JS_BOOL JS_IsSpecial (JSValue v) { return (v & 3) == JS_TAG_SPECIAL; }
#ifdef JS_PTR64
static inline JS_BOOL static inline JS_BOOL
JS_IsShortFloat (JSValue v) { JS_IsShortFloat (JSValue v) {
return (v & 7) == JS_TAG_SHORT_FLOAT; return (v & 7) == JS_TAG_SHORT_FLOAT;
} }
#endif
#define JS_VALUE_IS_BOTH_INT(v1, v2) (((v1) & 1) == 0 && ((v2) & 1) == 0) #define JS_VALUE_IS_BOTH_INT(v1, v2) (((v1) & 1) == 0 && ((v2) & 1) == 0)
#define JS_VALUE_IS_BOTH_FLOAT(v1, v2) \ #define JS_VALUE_IS_BOTH_FLOAT(v1, v2) \
@@ -320,7 +283,6 @@ JS_IsShortFloat (JSValue v) {
#define JS_FALSE ((JSValue)JS_TAG_BOOL) #define JS_FALSE ((JSValue)JS_TAG_BOOL)
#define JS_TRUE ((JSValue)(JS_TAG_BOOL | (1 << 5))) #define JS_TRUE ((JSValue)(JS_TAG_BOOL | (1 << 5)))
#define JS_EXCEPTION ((JSValue)JS_TAG_EXCEPTION) #define JS_EXCEPTION ((JSValue)JS_TAG_EXCEPTION)
#define JS_UNINITIALIZED ((JSValue)JS_TAG_UNINITIALIZED)
/* flags for object properties - simplified model: /* flags for object properties - simplified model:
- No per-property writable/configurable (use stone() for immutability) - No per-property writable/configurable (use stone() for immutability)
@@ -433,11 +395,6 @@ JS_NewInt32 (JSContext *ctx, int32_t val) {
return JS_MKVAL (JS_TAG_INT, val); return JS_MKVAL (JS_TAG_INT, val);
} }
static inline JSValue
JS_NewCatchOffset (JSContext *ctx, int32_t val) {
return JS_MKVAL (JS_TAG_CATCH_OFFSET, val);
}
static inline JSValue static inline JSValue
JS_NewInt64 (JSContext *ctx, int64_t val) { JS_NewInt64 (JSContext *ctx, int64_t val) {
JSValue v; JSValue v;
@@ -495,10 +452,6 @@ static inline JS_BOOL JS_IsException (JSValue v) {
return (JS_VALUE_GET_TAG (v) == JS_TAG_EXCEPTION); return (JS_VALUE_GET_TAG (v) == JS_TAG_EXCEPTION);
} }
static inline JS_BOOL JS_IsUninitialized (JSValue v) {
return (JS_VALUE_GET_TAG (v) == JS_TAG_UNINITIALIZED);
}
/* Immediate String Helpers */ /* Immediate String Helpers */
#define MIST_ASCII_MAX_LEN 7 #define MIST_ASCII_MAX_LEN 7
@@ -512,13 +465,11 @@ MIST_GetImmediateASCIILen (JSValue v) {
return (int)((v >> 5) & 0x7); return (int)((v >> 5) & 0x7);
} }
static inline int static inline int MIST_GetImmediateASCIIChar (JSValue v, int idx) {
MIST_GetImmediateASCIIChar (JSValue v, int idx) {
return (int)((v >> (8 + idx * 8)) & 0xFF); return (int)((v >> (8 + idx * 8)) & 0xFF);
} }
static inline JSValue static inline JSValue MIST_TryNewImmediateASCII (const char *str, size_t len) {
MIST_TryNewImmediateASCII (const char *str, size_t len) {
if (len > MIST_ASCII_MAX_LEN) return JS_NULL; if (len > MIST_ASCII_MAX_LEN) return JS_NULL;
JSValue v = (JSValue)JS_TAG_STRING_IMM | ((JSValue)len << 5); JSValue v = (JSValue)JS_TAG_STRING_IMM | ((JSValue)len << 5);
for (size_t i = 0; i < len; i++) { for (size_t i = 0; i < len; i++) {
@@ -529,20 +480,10 @@ MIST_TryNewImmediateASCII (const char *str, size_t len) {
return v; return v;
} }
static inline JS_BOOL JS_IsInteger (JSValue v) {
return JS_VALUE_GET_TAG (v) == JS_TAG_INT;
}
static inline JS_BOOL JS_IsObject (JSValue v) {
return JS_IsPtr (v);
}
JS_BOOL JS_IsArray(JSValue v); JS_BOOL JS_IsArray(JSValue v);
JS_BOOL JS_IsRecord(JSValue v); JS_BOOL JS_IsRecord(JSValue v);
#define JS_IsObject JS_IsRecord
JS_BOOL JS_IsFunction(JSValue v); JS_BOOL JS_IsFunction(JSValue v);
JS_BOOL JS_IsCode(JSValue v);
JS_BOOL JS_IsForwarded(JSValue v);
JS_BOOL JS_IsFrame(JSValue v);
JS_BOOL JS_IsBlob(JSValue v); JS_BOOL JS_IsBlob(JSValue v);
JS_BOOL JS_IsText(JSValue v); JS_BOOL JS_IsText(JSValue v);
static JS_BOOL JS_IsStone(JSValue v); static JS_BOOL JS_IsStone(JSValue v);
@@ -565,6 +506,7 @@ JSValue __js_printf_like (2, 3)
JS_ThrowInternalError (JSContext *ctx, const char *fmt, ...); JS_ThrowInternalError (JSContext *ctx, const char *fmt, ...);
JSValue JS_ThrowOutOfMemory (JSContext *ctx); JSValue JS_ThrowOutOfMemory (JSContext *ctx);
// TODO: rename this to just "eq"
JS_BOOL JS_StrictEq (JSContext *ctx, JSValue op1, JSValue op2); JS_BOOL JS_StrictEq (JSContext *ctx, JSValue op1, JSValue op2);
int JS_ToBool (JSContext *ctx, JSValue val); /* return -1 for JS_EXCEPTION */ int JS_ToBool (JSContext *ctx, JSValue val); /* return -1 for JS_EXCEPTION */
@@ -599,7 +541,6 @@ JSValue JS_NewObject (JSContext *ctx);
JSValue JS_NewArray (JSContext *ctx); JSValue JS_NewArray (JSContext *ctx);
JSValue JS_NewArrayLen (JSContext *ctx, uint32_t len); JSValue JS_NewArrayLen (JSContext *ctx, uint32_t len);
/* GC-safe push: takes pointer to array, updates it if array grows */
int JS_ArrayPush (JSContext *ctx, JSValue *arr_ptr, JSValue val); int JS_ArrayPush (JSContext *ctx, JSValue *arr_ptr, JSValue val);
JSValue JS_ArrayPop (JSContext *ctx, JSValue obj); JSValue JS_ArrayPop (JSContext *ctx, JSValue obj);
@@ -664,24 +605,17 @@ void JS_PrintTextLn (JSContext *ctx, JSValue val);
void JS_PrintFormatted (JSContext *ctx, const char *fmt, int count, JSValue *values); void JS_PrintFormatted (JSContext *ctx, const char *fmt, int count, JSValue *values);
JSValue JS_GetProperty (JSContext *ctx, JSValue this_obj, JSValue prop); JSValue JS_GetProperty (JSContext *ctx, JSValue this_obj, JSValue prop);
int JS_SetProperty (JSContext *ctx, JSValue this_obj, JSValue prop, JSValue val);
// For records // For records
JSValue JS_GetPropertyStr (JSContext *ctx, JSValue this_obj, const char *prop); JSValue JS_GetPropertyStr (JSContext *ctx, JSValue this_obj, const char *prop);
int JS_SetPropertyStr (JSContext *ctx, JSValue this_obj, const char *prop, JSValue val); int JS_SetPropertyStr (JSContext *ctx, JSValue this_obj, const char *prop, JSValue val);
// Set property on the global object
int JS_SetGlobalStr (JSContext *ctx, const char *prop, JSValue val);
int JS_SetProperty (JSContext *ctx, JSValue this_obj, JSValue prop, JSValue val);
JSValue JS_GetPrototype (JSContext *ctx, JSValue val);
// Must be an array // Must be an array
JSValue JS_GetPropertyNumber (JSContext *ctx, JSValue this_obj, int idx); JSValue JS_GetPropertyNumber (JSContext *ctx, JSValue this_obj, int idx);
JSValue JS_SetPropertyNumber (JSContext *ctx, JSValue obj, int idx, JSValue val); JSValue JS_SetPropertyNumber (JSContext *ctx, JSValue obj, int idx, JSValue val);
// Indexed property access (works with arrays and objects) JSValue JS_GetPrototype (JSContext *ctx, JSValue val);
JSValue JS_GetPropertyUint32 (JSContext *ctx, JSValue this_obj, uint32_t idx);
int JS_SetPropertyUint32 (JSContext *ctx, JSValue this_obj, uint32_t idx, JSValue val);
int JS_SetPropertyInt64 (JSContext *ctx, JSValue this_obj, int64_t idx, JSValue val);
/* Get property keys as array of text */ /* Get property keys as array of text */
JSValue JS_GetOwnPropertyNames (JSContext *ctx, JSValue obj); JSValue JS_GetOwnPropertyNames (JSContext *ctx, JSValue obj);
@@ -706,13 +640,6 @@ JSValue JS_JSONStringify (JSContext *ctx, JSValue obj,
typedef int JSInterruptHandler (JSRuntime *rt, void *opaque); typedef int JSInterruptHandler (JSRuntime *rt, void *opaque);
void JS_SetInterruptHandler (JSContext *ctx, JSInterruptHandler *cb, void JS_SetInterruptHandler (JSContext *ctx, JSInterruptHandler *cb,
void *opaque); void *opaque);
/* select which debug info is stripped from the compiled code */
#define JS_STRIP_SOURCE (1 << 0) /* strip source code */
#define JS_STRIP_DEBUG \
(1 << 1) /* strip all debug info including source code */
void JS_SetStripInfo (JSRuntime *rt, int flags);
int JS_GetStripInfo (JSRuntime *rt);
/* C function definition */ /* C function definition */
typedef enum JSCFunctionEnum { typedef enum JSCFunctionEnum {

View File

@@ -28,44 +28,56 @@
#define WOTA_IMPLEMENTATION #define WOTA_IMPLEMENTATION
#include "quickjs-internal.h" #include "quickjs-internal.h"
static inline JS_BOOL JS_IsInteger (JSValue v) {
if (JS_VALUE_GET_TAG(v) == JS_TAG_INT) return true;
if (JS_VALUE_GET_TAG(v) != JS_TAG_SHORT_FLOAT) return false;
double d = JS_VALUE_GET_FLOAT64(v);
return d == (double)(int64_t)d;
}
static inline JS_BOOL JS_IsGCObject (JSValue v) {
return JS_IsPtr (v);
}
JSClassID js_class_id_alloc = JS_CLASS_INIT_COUNT; JSClassID js_class_id_alloc = JS_CLASS_INIT_COUNT;
/* === Function definitions from header region (non-inline) === */ /* === Function definitions from header region (non-inline) === */
JS_BOOL JS_IsStone(JSValue v) { JS_BOOL JS_IsStone(JSValue v) {
return !JS_IsObject(v) || objhdr_s(*chase(v)); return !JS_IsGCObject(v) || objhdr_s(*chase(v));
} }
JS_BOOL JS_IsArray(JSValue v) { JS_BOOL JS_IsArray(JSValue v) {
return JS_IsObject(v) && objhdr_type(*chase(v)) == OBJ_ARRAY; return JS_IsGCObject(v) && objhdr_type(*chase(v)) == OBJ_ARRAY;
} }
JS_BOOL JS_IsRecord (JSValue v) { JS_BOOL JS_IsRecord (JSValue v) {
return JS_IsObject(v) && objhdr_type(*chase(v)) == OBJ_RECORD; return JS_IsGCObject(v) && objhdr_type(*chase(v)) == OBJ_RECORD;
} }
JS_BOOL JS_IsFunction (JSValue v) { JS_BOOL JS_IsFunction (JSValue v) {
return JS_IsObject(v) && objhdr_type(*chase(v)) == OBJ_FUNCTION; return JS_IsGCObject(v) && objhdr_type(*chase(v)) == OBJ_FUNCTION;
} }
JS_BOOL JS_IsCode (JSValue v) { JS_BOOL JS_IsCode (JSValue v) {
return JS_IsObject(v) && objhdr_type(*chase(v)) == OBJ_CODE; return JS_IsGCObject(v) && objhdr_type(*chase(v)) == OBJ_CODE;
} }
JS_BOOL JS_IsForwarded (JSValue v) { JS_BOOL JS_IsForwarded (JSValue v) {
return JS_IsObject(v) && objhdr_type(*chase(v)) == OBJ_FORWARD; return JS_IsGCObject(v) && objhdr_type(*chase(v)) == OBJ_FORWARD;
} }
JS_BOOL JS_IsFrame (JSValue v) { JS_BOOL JS_IsFrame (JSValue v) {
return JS_IsObject(v) && objhdr_type(*chase(v)) == OBJ_FRAME; return JS_IsGCObject(v) && objhdr_type(*chase(v)) == OBJ_FRAME;
} }
JS_BOOL JS_IsBlob (JSValue v) { JS_BOOL JS_IsBlob (JSValue v) {
return JS_IsObject(v) && objhdr_type(*chase(v)) == OBJ_BLOB; return JS_IsGCObject(v) && objhdr_type(*chase(v)) == OBJ_BLOB;
} }
JS_BOOL JS_IsText(JSValue v) { JS_BOOL JS_IsText(JSValue v) {
return MIST_IsImmediateASCII(v) || (JS_IsObject(v) && objhdr_type(*chase(v)) == OBJ_TEXT); return MIST_IsImmediateASCII(v) || (JS_IsGCObject(v) && objhdr_type(*chase(v)) == OBJ_TEXT);
} }
uint64_t get_text_hash (JSText *text) { uint64_t get_text_hash (JSText *text) {
@@ -1440,7 +1452,7 @@ JSContext *JS_NewContextRawWithHeapSize (JSRuntime *rt, size_t heap_size) {
ctx->reg_current_frame = JS_NULL; ctx->reg_current_frame = JS_NULL;
/* Initialize per-context execution state (moved from JSRuntime) */ /* Initialize per-context execution state (moved from JSRuntime) */
ctx->current_exception = JS_UNINITIALIZED; ctx->current_exception = JS_NULL;
/* Initialize stone text intern table */ /* Initialize stone text intern table */
ctx->st_pages = NULL; ctx->st_pages = NULL;
@@ -1486,22 +1498,19 @@ JSContext *JS_NewContextRaw (JSRuntime *rt) {
return JS_NewContextRawWithHeapSize (rt, 1ULL << BUDDY_MIN_ORDER); return JS_NewContextRawWithHeapSize (rt, 1ULL << BUDDY_MIN_ORDER);
} }
static void JS_AddIntrinsics (JSContext *ctx) {
JS_AddIntrinsicBaseObjects (ctx);
JS_AddIntrinsicRegExp (ctx);
}
JSContext *JS_NewContext (JSRuntime *rt) { JSContext *JS_NewContext (JSRuntime *rt) {
JSContext *ctx = JS_NewContextRaw (rt); JSContext *ctx = JS_NewContextRaw (rt);
if (!ctx) return NULL; if (!ctx) return NULL;
JS_AddIntrinsics (ctx); JS_AddIntrinsicBaseObjects (ctx);
JS_AddIntrinsicRegExp (ctx);
return ctx; return ctx;
} }
JSContext *JS_NewContextWithHeapSize (JSRuntime *rt, size_t heap_size) { JSContext *JS_NewContextWithHeapSize (JSRuntime *rt, size_t heap_size) {
JSContext *ctx = JS_NewContextRawWithHeapSize (rt, heap_size); JSContext *ctx = JS_NewContextRawWithHeapSize (rt, heap_size);
if (!ctx) return NULL; if (!ctx) return NULL;
JS_AddIntrinsics (ctx); JS_AddIntrinsicBaseObjects (ctx);
JS_AddIntrinsicRegExp (ctx);
return ctx; return ctx;
} }
@@ -1511,7 +1520,6 @@ void JS_SetContextOpaque (JSContext *ctx, void *opaque) {
ctx->user_opaque = opaque; ctx->user_opaque = opaque;
} }
void JS_SetClassProto (JSContext *ctx, JSClassID class_id, JSValue obj) { void JS_SetClassProto (JSContext *ctx, JSClassID class_id, JSValue obj) {
assert (class_id < ctx->class_count); assert (class_id < ctx->class_count);
set_value (ctx, &ctx->class_proto[class_id], obj); set_value (ctx, &ctx->class_proto[class_id], obj);
@@ -2486,16 +2494,15 @@ JSValue JS_Throw (JSContext *ctx, JSValue obj) {
/* return the pending exception (cannot be called twice). */ /* return the pending exception (cannot be called twice). */
JSValue JS_GetException (JSContext *ctx) { JSValue JS_GetException (JSContext *ctx) {
JSValue val = ctx->current_exception; JSValue val = ctx->current_exception;
ctx->current_exception = JS_UNINITIALIZED; ctx->current_exception = JS_NULL;
return val; return val;
} }
JS_BOOL JS_BOOL
JS_HasException (JSContext *ctx) { JS_HasException (JSContext *ctx) {
return !JS_IsUninitialized (ctx->current_exception); return !JS_IsNull (ctx->current_exception);
} }
/* get_line_col — compute line and column from a byte offset */ /* get_line_col — compute line and column from a byte offset */
int get_line_col (int *pcol_num, const uint8_t *buf, size_t len) { int get_line_col (int *pcol_num, const uint8_t *buf, size_t len) {
int line_num, col_num, c; int line_num, col_num, c;
@@ -2686,22 +2693,10 @@ JSValue JS_ThrowOutOfMemory (JSContext *ctx) {
return JS_EXCEPTION; return JS_EXCEPTION;
} }
JSValue JS_ThrowStackOverflow (JSContext *ctx) {
return JS_ThrowInternalError (ctx, "stack overflow");
}
static JSValue JS_ThrowTypeErrorNotAnObject (JSContext *ctx) { static JSValue JS_ThrowTypeErrorNotAnObject (JSContext *ctx) {
return JS_ThrowTypeError (ctx, "not an object"); return JS_ThrowTypeError (ctx, "not an object");
} }
JSValue JS_ThrowReferenceErrorUninitialized (JSContext *ctx,
JSValue name) {
char buf[KEY_GET_STR_BUF_SIZE];
return JS_ThrowReferenceError (
ctx, "%s is not initialized", JS_IsNull (name) ? "lexical variable" : JS_KeyGetStr (ctx, buf, sizeof (buf), name));
}
static JSValue JS_ThrowTypeErrorInvalidClass (JSContext *ctx, int class_id) { static JSValue JS_ThrowTypeErrorInvalidClass (JSContext *ctx, int class_id) {
const char *name = ctx->class_array[class_id].class_name; const char *name = ctx->class_array[class_id].class_name;
return JS_ThrowTypeError (ctx, "%s object expected", name ? name : "unknown"); return JS_ThrowTypeError (ctx, "%s object expected", name ? name : "unknown");
@@ -2711,7 +2706,6 @@ void JS_ThrowInterrupted (JSContext *ctx) {
JS_ThrowInternalError (ctx, "interrupted"); JS_ThrowInternalError (ctx, "interrupted");
} }
/* Return an Object, JS_NULL or JS_EXCEPTION in case of exotic object. */ /* Return an Object, JS_NULL or JS_EXCEPTION in case of exotic object. */
JSValue JS_GetPrototype (JSContext *ctx, JSValue obj) { JSValue JS_GetPrototype (JSContext *ctx, JSValue obj) {
JSValue val; JSValue val;
@@ -2780,7 +2774,7 @@ JSValue JS_GetOwnPropertyNames (JSContext *ctx, JSValue obj) {
if (JS_IsException (arr)) return JS_EXCEPTION; if (JS_IsException (arr)) return JS_EXCEPTION;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
JS_SetPropertyUint32 (ctx, arr, i, keys[i]); JS_SetPropertyNumber (ctx, arr, i, keys[i]);
} }
return arr; return arr;
@@ -2936,14 +2930,6 @@ JSValue JS_GetPropertyNumber (JSContext *js, JSValue obj, int idx) {
return JS_NULL; return JS_NULL;
} }
JSValue JS_GetPropertyUint32 (JSContext *ctx, JSValue this_obj, uint32_t idx) {
return JS_GetPropertyNumber (ctx, this_obj, idx);
}
static JSValue JS_GetPropertyInt64 (JSContext *ctx, JSValue obj, int64_t idx) {
return JS_GetPropertyNumber (ctx, obj, idx);
}
JSValue JS_GetPropertyStr (JSContext *ctx, JSValue this_obj, const char *prop) { JSValue JS_GetPropertyStr (JSContext *ctx, JSValue this_obj, const char *prop) {
if (JS_VALUE_GET_TAG (this_obj) != JS_TAG_PTR) return JS_NULL; if (JS_VALUE_GET_TAG (this_obj) != JS_TAG_PTR) return JS_NULL;
@@ -3011,22 +2997,6 @@ int JS_SetProperty (JSContext *ctx, JSValue this_obj, JSValue prop, JSValue val)
return rec_set_own (ctx, &obj, prop, val); return rec_set_own (ctx, &obj, prop, val);
} }
int JS_SetPropertyUint32 (JSContext *ctx, JSValue this_obj, uint32_t idx, JSValue val) {
JSValue ret = JS_SetPropertyNumber (ctx, (JSValue)this_obj, (int)idx, val);
if (JS_IsException (ret)) return -1;
return 0;
}
int JS_SetPropertyInt64 (JSContext *ctx, JSValue this_obj, int64_t idx, JSValue val) {
if (idx < INT32_MIN || idx > INT32_MAX) {
JS_ThrowRangeError (ctx, "array index out of bounds");
return -1;
}
JSValue ret = JS_SetPropertyNumber (ctx, (JSValue)this_obj, (int)idx, val);
if (JS_IsException (ret)) return -1;
return 0;
}
/* GC-SAFE: Protects this_obj and val in case key creation triggers GC */ /* GC-SAFE: Protects this_obj and val in case key creation triggers GC */
int JS_SetPropertyStr (JSContext *ctx, JSValue this_obj, const char *prop, JSValue val) { int JS_SetPropertyStr (JSContext *ctx, JSValue this_obj, const char *prop, JSValue val) {
/* Protect this_obj and val in case key creation triggers GC */ /* Protect this_obj and val in case key creation triggers GC */
@@ -3188,7 +3158,7 @@ static BOOL js_object_has_name (JSContext *ctx, JSValue obj) {
} }
int JS_DefineObjectName (JSContext *ctx, JSValue obj, JSValue name) { int JS_DefineObjectName (JSContext *ctx, JSValue obj, JSValue name) {
if (!JS_IsNull (name) && JS_IsObject (obj) if (!JS_IsNull (name) && JS_IsGCObject (obj)
&& !js_object_has_name (ctx, obj)) { && !js_object_has_name (ctx, obj)) {
JSValue name_key = MIST_TryNewImmediateASCII ("name", 4); JSValue name_key = MIST_TryNewImmediateASCII ("name", 4);
if (JS_SetPropertyInternal (ctx, obj, name_key, name) if (JS_SetPropertyInternal (ctx, obj, name_key, name)
@@ -3199,7 +3169,7 @@ int JS_DefineObjectName (JSContext *ctx, JSValue obj, JSValue name) {
} }
int JS_DefineObjectNameComputed (JSContext *ctx, JSValue obj, JSValue str) { int JS_DefineObjectNameComputed (JSContext *ctx, JSValue obj, JSValue str) {
if (JS_IsObject (obj) && !js_object_has_name (ctx, obj)) { if (JS_IsGCObject (obj) && !js_object_has_name (ctx, obj)) {
JSValue name_key = MIST_TryNewImmediateASCII ("name", 4); JSValue name_key = MIST_TryNewImmediateASCII ("name", 4);
if (JS_SetPropertyInternal (ctx, obj, name_key, str) if (JS_SetPropertyInternal (ctx, obj, name_key, str)
< 0) < 0)
@@ -4023,9 +3993,6 @@ static void js_print_value (JSPrintValueState *s, JSValue val) {
case JS_TAG_EXCEPTION: case JS_TAG_EXCEPTION:
str = "exception"; str = "exception";
goto print_str; goto print_str;
case JS_TAG_UNINITIALIZED:
str = "uninitialized";
goto print_str;
print_str: print_str:
js_puts (s, str); js_puts (s, str);
break; break;
@@ -4138,7 +4105,6 @@ __maybe_unused void JS_DumpGCObject (JSRuntime *rt,
} }
} }
/* Simplified equality: no NaN (becomes null), no coercion, no SameValue distinction */ /* Simplified equality: no NaN (becomes null), no coercion, no SameValue distinction */
BOOL js_strict_eq (JSContext *ctx, JSValue op1, JSValue op2) { BOOL js_strict_eq (JSContext *ctx, JSValue op1, JSValue op2) {
/* Fast path: identical values */ /* Fast path: identical values */
@@ -4226,7 +4192,7 @@ __exception int JS_CopyDataProperties (JSContext *ctx, JSValue target, JSValue s
} }
for (i = 0; i < key_count; i++) { for (i = 0; i < key_count; i++) {
key = JS_GetPropertyUint32 (ctx, keys, i); key = JS_GetPropertyNumber (ctx, keys, i);
if (JS_IsException (key)) goto exception; if (JS_IsException (key)) goto exception;
/* Check if key is excluded */ /* Check if key is excluded */
@@ -4269,10 +4235,6 @@ JSValue js_call_c_function (JSContext *ctx, JSValue func_obj, JSValue this_obj,
cproto = f->u.cfunc.cproto; cproto = f->u.cfunc.cproto;
arg_count = f->length; arg_count = f->length;
/* better to always check stack overflow */
if (js_check_stack_overflow (ctx, sizeof (arg_buf[0]) * arg_count))
return JS_ThrowStackOverflow (ctx);
arg_buf = argv; arg_buf = argv;
func = f->u.cfunc.c_function; func = f->u.cfunc.c_function;
@@ -4792,7 +4754,7 @@ static JSRegExp *js_get_regexp (JSContext *ctx, JSValue obj, BOOL throw_error) {
static int js_is_regexp (JSContext *ctx, JSValue obj) { static int js_is_regexp (JSContext *ctx, JSValue obj) {
JSValue m; JSValue m;
if (!JS_IsObject (obj)) return FALSE; if (!JS_IsGCObject (obj)) return FALSE;
m = JS_GetPropertyStr (ctx, obj, "Symbol.match"); m = JS_GetPropertyStr (ctx, obj, "Symbol.match");
if (JS_IsException (m)) return -1; if (JS_IsException (m)) return -1;
if (!JS_IsNull (m)) return JS_ToBool (ctx, m); if (!JS_IsNull (m)) return JS_ToBool (ctx, m);
@@ -4935,7 +4897,7 @@ fail:
JSValue js_regexp_toString (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { JSValue js_regexp_toString (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {
JSValue pattern, flags; JSValue pattern, flags;
if (!JS_IsObject (this_val)) return JS_ThrowTypeErrorNotAnObject (ctx); if (!JS_IsGCObject (this_val)) return JS_ThrowTypeErrorNotAnObject (ctx);
JSText *b = pretext_init (ctx, 0); JSText *b = pretext_init (ctx, 0);
if (!b) return JS_EXCEPTION; if (!b) return JS_EXCEPTION;
@@ -4953,11 +4915,6 @@ JSValue js_regexp_toString (JSContext *ctx, JSValue this_val, int argc, JSValue
return pretext_end (ctx, b); return pretext_end (ctx, b);
} }
int lre_check_stack_overflow (void *opaque, size_t alloca_size) {
JSContext *ctx = opaque;
return js_check_stack_overflow (ctx, alloca_size);
}
int lre_check_timeout (void *opaque) { int lre_check_timeout (void *opaque) {
JSContext *ctx = opaque; JSContext *ctx = opaque;
return (ctx->interrupt_handler return (ctx->interrupt_handler
@@ -5182,7 +5139,7 @@ static JSValue js_regexp_exec (JSContext *ctx, JSValue this_val, int argc, JSVal
} }
captures_arr = cap_ref.val; captures_arr = cap_ref.val;
if (JS_SetPropertyUint32 (ctx, captures_arr, (uint32_t)(i - 1), s) < 0) { if (JS_IsException (JS_SetPropertyNumber (ctx, captures_arr, (uint32_t)(i - 1), s))) {
REGEXP_RESULT_CLEANUP (); REGEXP_RESULT_CLEANUP ();
goto fail; goto fail;
} }
@@ -5275,7 +5232,7 @@ static JSValue cjson_to_jsvalue (JSContext *ctx, const cJSON *item) {
JSValue arr = JS_NewArray (ctx); JSValue arr = JS_NewArray (ctx);
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
cJSON *child = cJSON_GetArrayItem (item, i); cJSON *child = cJSON_GetArrayItem (item, i);
JS_SetPropertyUint32 (ctx, arr, i, cjson_to_jsvalue (ctx, child)); JS_SetPropertyNumber (ctx, arr, i, cjson_to_jsvalue (ctx, child));
} }
return arr; return arr;
} }
@@ -5338,7 +5295,7 @@ static JSValue js_json_check (JSContext *ctx, JSONStringifyContext *jsc, JSValue
/* check for object.toJSON method */ /* check for object.toJSON method */
/* ECMA specifies this is done only for Object and BigInt */ /* ECMA specifies this is done only for Object and BigInt */
if (JS_IsObject (val)) { if (JS_IsGCObject (val)) {
JSValue f = JS_GetProperty (ctx, val, JS_KEY_toJSON); JSValue f = JS_GetProperty (ctx, val, JS_KEY_toJSON);
if (JS_IsException (f)) goto exception; if (JS_IsException (f)) goto exception;
if (JS_IsFunction (f)) { if (JS_IsFunction (f)) {
@@ -5403,11 +5360,6 @@ static int js_json_to_str (JSContext *ctx, JSONStringifyContext *jsc, JSValue ho
prop_ref.val = JS_NULL; prop_ref.val = JS_NULL;
v_ref.val = JS_NULL; v_ref.val = JS_NULL;
if (js_check_stack_overflow (ctx, 0)) {
JS_ThrowStackOverflow (ctx);
goto exception;
}
/* Heap strings are JS_TAG_PTR but must be quoted, not iterated as objects */ /* Heap strings are JS_TAG_PTR but must be quoted, not iterated as objects */
if (JS_IsText (val_ref.val) && !MIST_IsImmediateASCII (val_ref.val)) { if (JS_IsText (val_ref.val) && !MIST_IsImmediateASCII (val_ref.val)) {
val_ref.val = JS_ToQuotedString (ctx, val_ref.val); val_ref.val = JS_ToQuotedString (ctx, val_ref.val);
@@ -5415,7 +5367,7 @@ static int js_json_to_str (JSContext *ctx, JSONStringifyContext *jsc, JSValue ho
goto concat_value; goto concat_value;
} }
if (JS_IsObject ( if (JS_IsGCObject (
val_ref.val)) { /* includes arrays (OBJ_ARRAY) since they have JS_TAG_PTR */ val_ref.val)) { /* includes arrays (OBJ_ARRAY) since they have JS_TAG_PTR */
v = js_array_includes (ctx, jsc->stack, 1, &val_ref.val); v = js_array_includes (ctx, jsc->stack, 1, &val_ref.val);
if (JS_IsException (v)) goto exception; if (JS_IsException (v)) goto exception;
@@ -5446,7 +5398,7 @@ static int js_json_to_str (JSContext *ctx, JSONStringifyContext *jsc, JSValue ho
JSC_B_PUTC (jsc, ','); JSC_B_PUTC (jsc, ',');
} }
JSC_B_CONCAT (jsc, sep_ref.val); JSC_B_CONCAT (jsc, sep_ref.val);
v = JS_GetPropertyInt64 (ctx, val_ref.val, i); v = JS_GetPropertyNumber (ctx, val_ref.val, i);
if (JS_IsException (v)) goto exception; if (JS_IsException (v)) goto exception;
v_ref.val = v; /* root v — JS_ToString below can trigger GC */ v_ref.val = v; /* root v — JS_ToString below can trigger GC */
/* XXX: could do this string conversion only when needed */ /* XXX: could do this string conversion only when needed */
@@ -5473,7 +5425,7 @@ static int js_json_to_str (JSContext *ctx, JSONStringifyContext *jsc, JSValue ho
JSC_B_PUTC (jsc, '{'); JSC_B_PUTC (jsc, '{');
has_content = FALSE; has_content = FALSE;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
prop_ref.val = JS_GetPropertyInt64 (ctx, tab_ref.val, i); prop_ref.val = JS_GetPropertyNumber (ctx, tab_ref.val, i);
if (JS_IsException (prop_ref.val)) goto exception; if (JS_IsException (prop_ref.val)) goto exception;
v = JS_GetPropertyValue (ctx, val_ref.val, prop_ref.val); v = JS_GetPropertyValue (ctx, val_ref.val, prop_ref.val);
if (JS_IsException (v)) goto exception; if (JS_IsException (v)) goto exception;
@@ -5601,9 +5553,9 @@ JSValue JS_JSONStringify (JSContext *ctx, JSValue obj, JSValue replacer, JSValue
if (js_get_length64 (ctx, &n, replacer)) goto exception; if (js_get_length64 (ctx, &n, replacer)) goto exception;
for (i = j = 0; i < n; i++) { for (i = j = 0; i < n; i++) {
JSValue present; JSValue present;
v = JS_GetPropertyInt64 (ctx, replacer, i); v = JS_GetPropertyNumber (ctx, replacer, i);
if (JS_IsException (v)) goto exception; if (JS_IsException (v)) goto exception;
if (JS_IsObject (v)) { if (JS_IsGCObject (v)) {
/* Objects are not valid property list items */ /* Objects are not valid property list items */
continue; continue;
} else if (JS_IsNumber (v)) { } else if (JS_IsNumber (v)) {
@@ -5618,7 +5570,7 @@ JSValue JS_JSONStringify (JSContext *ctx, JSValue obj, JSValue replacer, JSValue
goto exception; goto exception;
} }
if (!JS_ToBool (ctx, present)) { if (!JS_ToBool (ctx, present)) {
JS_SetPropertyInt64 (ctx, jsc->property_list, j++, v); JS_SetPropertyNumber (ctx, jsc->property_list, j++, v);
} else { } else {
} }
} }
@@ -6569,7 +6521,7 @@ static JSValue js_cell_text (JSContext *ctx, JSValue this_val, int argc, JSValue
return JS_EXCEPTION; return JS_EXCEPTION;
} }
/* Root b across allocating calls (JS_GetPropertyInt64, JS_ToString) */ /* Root b across allocating calls (JS_GetPropertyNumber, JS_ToString) */
JSGCRef b_ref; JSGCRef b_ref;
JS_AddGCRef (ctx, &b_ref); JS_AddGCRef (ctx, &b_ref);
b_ref.val = JS_MKPTR (b); b_ref.val = JS_MKPTR (b);
@@ -6583,7 +6535,7 @@ static JSValue js_cell_text (JSContext *ctx, JSValue this_val, int argc, JSValue
} }
b = (JSText *)chase (b_ref.val); /* re-chase before use */ b = (JSText *)chase (b_ref.val); /* re-chase before use */
JSValue item = JS_GetPropertyInt64 (ctx, arg_ref.val, i); JSValue item = JS_GetPropertyNumber (ctx, arg_ref.val, i);
if (JS_IsException (item)) goto array_fail; if (JS_IsException (item)) goto array_fail;
if (!JS_VALUE_IS_TEXT (item)) { if (!JS_VALUE_IS_TEXT (item)) {
@@ -6851,7 +6803,7 @@ static JSValue make_replacement (JSContext *ctx, int argc, JSValue *argv, int fo
} }
static int JS_IsRegExp (JSContext *ctx, JSValue v) { static int JS_IsRegExp (JSContext *ctx, JSValue v) {
if (!JS_IsObject (v)) return 0; if (!JS_IsGCObject (v)) return 0;
JSValue exec = JS_GetPropertyStr (ctx, v, "exec"); JSValue exec = JS_GetPropertyStr (ctx, v, "exec");
if (JS_IsException (exec)) return -1; if (JS_IsException (exec)) return -1;
@@ -6885,7 +6837,7 @@ static JSValue js_cell_text_replace (JSContext *ctx, JSValue this_val, int argc,
{ {
if (JS_IsText (argv[1])) { if (JS_IsText (argv[1])) {
target_is_regex = 0; target_is_regex = 0;
} else if (JS_IsObject (argv[1]) && JS_IsRegExp (ctx, argv[1])) { } else if (JS_IsGCObject (argv[1]) && JS_IsRegExp (ctx, argv[1])) {
target_is_regex = 1; target_is_regex = 1;
} else { } else {
return JS_NULL; return JS_NULL;
@@ -7167,7 +7119,7 @@ static JSValue js_cell_text_search (JSContext *ctx, JSValue this_val, int argc,
int target_is_regex = 0; int target_is_regex = 0;
if (JS_IsText (argv[1])) { if (JS_IsText (argv[1])) {
target_is_regex = 0; target_is_regex = 0;
} else if (JS_IsObject (argv[1]) && JS_IsRegExp (ctx, argv[1])) { } else if (JS_IsGCObject (argv[1]) && JS_IsRegExp (ctx, argv[1])) {
target_is_regex = 1; target_is_regex = 1;
} else { } else {
return JS_NULL; return JS_NULL;
@@ -7305,7 +7257,7 @@ static JSValue js_cell_text_extract (JSContext *ctx, JSValue this_val, int argc,
if (from > to) return JS_NULL; if (from > to) return JS_NULL;
/* RegExp path: convert new exec result record -> classic array */ /* RegExp path: convert new exec result record -> classic array */
if (JS_IsObject (argv[1]) && JS_IsRegExp (ctx, argv[1])) { if (JS_IsGCObject (argv[1]) && JS_IsRegExp (ctx, argv[1])) {
/* Root rx, str, out across allocating calls */ /* Root rx, str, out across allocating calls */
JSGCRef rx_ref, str_ref, out_ref; JSGCRef rx_ref, str_ref, out_ref;
JS_PushGCRef (ctx, &rx_ref); JS_PushGCRef (ctx, &rx_ref);
@@ -7358,7 +7310,7 @@ static JSValue js_cell_text_extract (JSContext *ctx, JSValue this_val, int argc,
goto fail_rx; goto fail_rx;
} }
out = out_ref.val; out = out_ref.val;
if (JS_SetPropertyUint32 (ctx, out, 0, match0) < 0) { if (JS_IsException (JS_SetPropertyNumber (ctx, out, 0, match0))) {
JS_PopGCRef (ctx, &exec_ref); JS_PopGCRef (ctx, &exec_ref);
goto fail_rx; goto fail_rx;
} }
@@ -7370,12 +7322,12 @@ static JSValue js_cell_text_extract (JSContext *ctx, JSValue this_val, int argc,
int64_t caps_len = 0; int64_t caps_len = 0;
if (js_get_length64 (ctx, &caps_len, caps) == 0 && caps_len > 0) { if (js_get_length64 (ctx, &caps_len, caps) == 0 && caps_len > 0) {
for (int64_t i = 0; i < caps_len; i++) { for (int64_t i = 0; i < caps_len; i++) {
JSValue cap = JS_GetPropertyInt64 (ctx, caps, i); JSValue cap = JS_GetPropertyNumber (ctx, caps, i);
if (JS_IsException (cap)) { if (JS_IsException (cap)) {
goto fail_rx; goto fail_rx;
} }
out = out_ref.val; out = out_ref.val;
if (JS_SetPropertyInt64 (ctx, out, i + 1, cap) < 0) { if (JS_IsException (JS_SetPropertyNumber (ctx, out, i + 1, cap))) {
goto fail_rx; goto fail_rx;
} }
} }
@@ -7433,7 +7385,7 @@ static JSValue js_cell_text_extract (JSContext *ctx, JSValue this_val, int argc,
JSValue arr = arr_ref.val; JSValue arr = arr_ref.val;
JS_PopGCRef (ctx, &arr_ref); JS_PopGCRef (ctx, &arr_ref);
if (JS_SetPropertyUint32 (ctx, arr, 0, match) < 0) if (JS_IsException (JS_SetPropertyNumber (ctx, arr, 0, match)))
return JS_EXCEPTION; return JS_EXCEPTION;
return arr; return arr;
@@ -7574,7 +7526,7 @@ static JSValue js_cell_text_format (JSContext *ctx, JSValue this_val, int argc,
valid = 0; valid = 0;
} }
if (valid && idx >= 0) { if (valid && idx >= 0) {
cv_ref.val = JS_GetPropertyUint32 (ctx, coll_ref.val, (uint32_t)idx); cv_ref.val = JS_GetPropertyNumber (ctx, coll_ref.val, (uint32_t)idx);
} }
} else { } else {
cv_ref.val = JS_GetProperty (ctx, coll_ref.val, name_val); cv_ref.val = JS_GetProperty (ctx, coll_ref.val, name_val);
@@ -8262,16 +8214,16 @@ static JSValue js_cell_array (JSContext *ctx, JSValue this_val, int argc, JSValu
if (sep_len == 0) { if (sep_len == 0) {
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
JSValue ch = js_sub_string_val (ctx, arg, i, i + 1); JSValue ch = js_sub_string_val (ctx, arg, i, i + 1);
JS_SetPropertyInt64 (ctx, result, idx++, ch); JS_SetPropertyNumber (ctx, result, idx++, ch);
} }
} else { } else {
while ((found = strstr (pos, sep)) != NULL) { while ((found = strstr (pos, sep)) != NULL) {
JSValue part = JS_NewStringLen (ctx, pos, found - pos); JSValue part = JS_NewStringLen (ctx, pos, found - pos);
JS_SetPropertyInt64 (ctx, result, idx++, part); JS_SetPropertyNumber (ctx, result, idx++, part);
pos = found + sep_len; pos = found + sep_len;
} }
JSValue part = JS_NewString (ctx, pos); JSValue part = JS_NewString (ctx, pos);
JS_SetPropertyInt64 (ctx, result, idx++, part); JS_SetPropertyNumber (ctx, result, idx++, part);
} }
JS_FreeCString (ctx, cstr); JS_FreeCString (ctx, cstr);
@@ -8279,7 +8231,7 @@ static JSValue js_cell_array (JSContext *ctx, JSValue this_val, int argc, JSValu
return result; return result;
} }
if (JS_IsObject (argv[1]) && JS_IsRegExp (ctx, argv[1])) { if (JS_IsGCObject (argv[1]) && JS_IsRegExp (ctx, argv[1])) {
/* Split by regex (manual "global" iteration; ignore g flag semantics) */ /* Split by regex (manual "global" iteration; ignore g flag semantics) */
/* Root rx, result, arg across allocating calls */ /* Root rx, result, arg across allocating calls */
JSGCRef rx_ref, res_ref, arg_ref; JSGCRef rx_ref, res_ref, arg_ref;
@@ -8339,7 +8291,7 @@ static JSValue js_cell_array (JSContext *ctx, JSValue this_val, int argc, JSValu
JSValue tail = js_sub_string_val (ctx, arg_ref.val, pos, len); JSValue tail = js_sub_string_val (ctx, arg_ref.val, pos, len);
if (JS_IsException (tail)) goto fail_rx_split; if (JS_IsException (tail)) goto fail_rx_split;
result = res_ref.val; result = res_ref.val;
JS_SetPropertyInt64 (ctx, result, out_idx++, tail); JS_SetPropertyNumber (ctx, result, out_idx++, tail);
break; break;
} }
@@ -8406,7 +8358,7 @@ static JSValue js_cell_array (JSContext *ctx, JSValue this_val, int argc, JSValu
JSValue chunk = js_sub_string_val (ctx, arg, i, end); JSValue chunk = js_sub_string_val (ctx, arg, i, end);
if (JS_IsException (chunk)) if (JS_IsException (chunk))
return JS_EXCEPTION; return JS_EXCEPTION;
JS_SetPropertyInt64 (ctx, result, idx++, chunk); JS_SetPropertyNumber (ctx, result, idx++, chunk);
} }
return result; return result;
@@ -8824,7 +8776,7 @@ static JSValue js_cell_array_sort (JSContext *ctx, JSValue this_val, int argc, J
else else
key = JS_NULL; key = JS_NULL;
} else { } else {
key = JS_GetPropertyInt64 (ctx, items[i], idx); key = JS_GetPropertyNumber (ctx, items[i], idx);
/* Re-read items[i] after potential GC */ /* Re-read items[i] after potential GC */
arr = JS_VALUE_GET_ARRAY (arr_ref.val); arr = JS_VALUE_GET_ARRAY (arr_ref.val);
items[i] = arr->values[i]; items[i] = arr->values[i];
@@ -8939,7 +8891,7 @@ static JSValue js_cell_object (JSContext *ctx, JSValue this_val, int argc, JSVal
JSValue arg = argv[0]; JSValue arg = argv[0];
/* object(object) - shallow mutable copy */ /* object(object) - shallow mutable copy */
if (JS_IsObject (arg) && !JS_IsArray (arg) && !JS_IsFunction (arg)) { if (JS_IsGCObject (arg) && !JS_IsArray (arg) && !JS_IsFunction (arg)) {
if (argc < 2 || JS_IsNull (argv[1])) { if (argc < 2 || JS_IsNull (argv[1])) {
/* Shallow copy - root arg, result, keys across allocating calls */ /* Shallow copy - root arg, result, keys across allocating calls */
JSGCRef arg_ref, res_ref, keys_ref; JSGCRef arg_ref, res_ref, keys_ref;
@@ -8966,7 +8918,7 @@ static JSValue js_cell_object (JSContext *ctx, JSValue this_val, int argc, JSVal
} }
for (uint32_t i = 0; i < len; i++) { for (uint32_t i = 0; i < len; i++) {
JSValue key = JS_GetPropertyUint32 (ctx, keys_ref.val, i); JSValue key = JS_GetPropertyNumber (ctx, keys_ref.val, i);
JSValue val = JS_GetProperty (ctx, arg_ref.val, key); JSValue val = JS_GetProperty (ctx, arg_ref.val, key);
if (JS_IsException (val)) { if (JS_IsException (val)) {
OBJ_COPY_CLEANUP (); OBJ_COPY_CLEANUP ();
@@ -8981,7 +8933,7 @@ static JSValue js_cell_object (JSContext *ctx, JSValue this_val, int argc, JSVal
#undef OBJ_COPY_CLEANUP #undef OBJ_COPY_CLEANUP
/* object(object, another_object) - combine */ /* object(object, another_object) - combine */
if (JS_IsObject (argv[1]) && !JS_IsArray (argv[1])) { if (JS_IsGCObject (argv[1]) && !JS_IsArray (argv[1])) {
JSGCRef arg_ref, arg2_ref, res_ref, keys_ref; JSGCRef arg_ref, arg2_ref, res_ref, keys_ref;
JS_PushGCRef (ctx, &arg_ref); JS_PushGCRef (ctx, &arg_ref);
arg_ref.val = arg; arg_ref.val = arg;
@@ -9008,7 +8960,7 @@ static JSValue js_cell_object (JSContext *ctx, JSValue this_val, int argc, JSVal
return JS_EXCEPTION; return JS_EXCEPTION;
} }
for (uint32_t i = 0; i < len; i++) { for (uint32_t i = 0; i < len; i++) {
JSValue key = JS_GetPropertyUint32 (ctx, keys_ref.val, i); JSValue key = JS_GetPropertyNumber (ctx, keys_ref.val, i);
JSValue val = JS_GetProperty (ctx, arg_ref.val, key); JSValue val = JS_GetProperty (ctx, arg_ref.val, key);
if (JS_IsException (val)) { if (JS_IsException (val)) {
OBJ_COMBINE_CLEANUP (); OBJ_COMBINE_CLEANUP ();
@@ -9028,7 +8980,7 @@ static JSValue js_cell_object (JSContext *ctx, JSValue this_val, int argc, JSVal
return JS_EXCEPTION; return JS_EXCEPTION;
} }
for (uint32_t i = 0; i < len; i++) { for (uint32_t i = 0; i < len; i++) {
JSValue key = JS_GetPropertyUint32 (ctx, keys_ref.val, i); JSValue key = JS_GetPropertyNumber (ctx, keys_ref.val, i);
JSValue val = JS_GetProperty (ctx, arg2_ref.val, key); JSValue val = JS_GetProperty (ctx, arg2_ref.val, key);
if (JS_IsException (val)) { if (JS_IsException (val)) {
OBJ_COMBINE_CLEANUP (); OBJ_COMBINE_CLEANUP ();
@@ -9303,7 +9255,7 @@ static JSValue js_blob_constructor (JSContext *ctx, JSValue this_val, int argc,
} }
} }
/* blob(blob, from, to) - copy from another blob */ /* blob(blob, from, to) - copy from another blob */
else if (argc >= 1 && JS_IsObject (argv[0]) && !JS_IsText (argv[0])) { else if (argc >= 1 && JS_IsGCObject (argv[0]) && !JS_IsText (argv[0])) {
blob *src = js_get_blob (ctx, argv[0]); blob *src = js_get_blob (ctx, argv[0]);
if (!src) if (!src)
return JS_ThrowTypeError (ctx, return JS_ThrowTypeError (ctx,
@@ -9795,7 +9747,7 @@ static JSValue js_mach_eval_ast (JSContext *ctx, JSValue this_val, int argc, JSV
cJSON_DeleteItemFromObjectCaseSensitive (ast, "filename"); cJSON_DeleteItemFromObjectCaseSensitive (ast, "filename");
cJSON_AddStringToObject (ast, "filename", name); cJSON_AddStringToObject (ast, "filename", name);
JSValue env = (argc >= 3 && JS_IsObject (argv[2])) ? argv[2] : JS_NULL; JSValue env = (argc >= 3 && JS_IsGCObject (argv[2])) ? argv[2] : JS_NULL;
JSValue result = JS_RunMachTree (ctx, ast, env); JSValue result = JS_RunMachTree (ctx, ast, env);
cJSON_Delete (ast); cJSON_Delete (ast);
JS_FreeCString (ctx, name); JS_FreeCString (ctx, name);
@@ -9859,7 +9811,7 @@ static JSValue js_mach_load (JSContext *ctx, JSValue this_val, int argc, JSValue
if (!mc) if (!mc)
return JS_ThrowSyntaxError (ctx, "mach_load: failed to deserialize bytecode"); return JS_ThrowSyntaxError (ctx, "mach_load: failed to deserialize bytecode");
JSValue env = (argc >= 2 && JS_IsObject (argv[1])) ? argv[1] : JS_NULL; JSValue env = (argc >= 2 && JS_IsGCObject (argv[1])) ? argv[1] : JS_NULL;
JSGCRef env_ref; JSGCRef env_ref;
JS_PushGCRef (ctx, &env_ref); JS_PushGCRef (ctx, &env_ref);
@@ -9894,7 +9846,7 @@ static JSValue js_mcode_run (JSContext *ctx, JSValue this_val, int argc, JSValue
return JS_ThrowSyntaxError (ctx, "mcode_run: failed to parse mcode JSON"); return JS_ThrowSyntaxError (ctx, "mcode_run: failed to parse mcode JSON");
} }
JSValue env = (argc >= 3 && JS_IsObject (argv[2])) ? argv[2] : JS_NULL; JSValue env = (argc >= 3 && JS_IsGCObject (argv[2])) ? argv[2] : JS_NULL;
JSValue result = JS_CallMcodeTreeEnv (ctx, mcode, env); JSValue result = JS_CallMcodeTreeEnv (ctx, mcode, env);
/* mcode tree ownership transferred to JS_CallMcodeTreeEnv — do not free */ /* mcode tree ownership transferred to JS_CallMcodeTreeEnv — do not free */
JS_FreeCString (ctx, name); JS_FreeCString (ctx, name);
@@ -9918,7 +9870,7 @@ static JSValue js_cell_stone (JSContext *ctx, JSValue this_val, int argc, JSValu
return obj; return obj;
} }
if (JS_IsObject (obj)) { if (JS_IsGCObject (obj)) {
JSRecord *rec = JS_VALUE_GET_RECORD (obj); JSRecord *rec = JS_VALUE_GET_RECORD (obj);
obj_set_stone (rec); obj_set_stone (rec);
return obj; return obj;
@@ -10426,15 +10378,15 @@ static JSValue js_cell_proto (JSContext *ctx, JSValue this_val, int argc, JSValu
return JS_ThrowTypeError (ctx, "arrays do not have prototypes"); return JS_ThrowTypeError (ctx, "arrays do not have prototypes");
} }
if (!JS_IsObject (obj)) return JS_NULL; if (!JS_IsGCObject (obj)) return JS_NULL;
JSValue proto = JS_GetPrototype (ctx, obj); JSValue proto = JS_GetPrototype (ctx, obj);
if (JS_IsException (proto)) return JS_NULL; if (JS_IsException (proto)) return JS_NULL;
/* If prototype is Object.prototype, return null */ /* If prototype is Object.prototype, return null */
if (JS_IsObject (proto)) { if (JS_IsGCObject (proto)) {
JSValue obj_proto = ctx->class_proto[JS_CLASS_OBJECT]; JSValue obj_proto = ctx->class_proto[JS_CLASS_OBJECT];
if (JS_IsObject (obj_proto) if (JS_IsGCObject (obj_proto)
&& JS_VALUE_GET_OBJ (proto) == JS_VALUE_GET_OBJ (obj_proto)) { && JS_VALUE_GET_OBJ (proto) == JS_VALUE_GET_OBJ (obj_proto)) {
return JS_NULL; return JS_NULL;
} }
@@ -10460,7 +10412,7 @@ static JSValue js_cell_meme (JSContext *ctx, JSValue this_val, int argc, JSValue
/* Helper function to apply a single mixin */ /* Helper function to apply a single mixin */
#define APPLY_MIXIN(mix_val) \ #define APPLY_MIXIN(mix_val) \
do { \ do { \
if (!JS_IsObject (mix_val) || JS_IsNull (mix_val) || JS_IsArray (mix_val)) \ if (!JS_IsGCObject (mix_val) || JS_IsNull (mix_val) || JS_IsArray (mix_val)) \
break; \ break; \
JSGCRef _mix_ref; \ JSGCRef _mix_ref; \
JS_PushGCRef (ctx, &_mix_ref); \ JS_PushGCRef (ctx, &_mix_ref); \
@@ -10478,7 +10430,7 @@ static JSValue js_cell_meme (JSContext *ctx, JSValue this_val, int argc, JSValue
return JS_EXCEPTION; \ return JS_EXCEPTION; \
} \ } \
for (uint32_t j = 0; j < _len; j++) { \ for (uint32_t j = 0; j < _len; j++) { \
JSValue _key = JS_GetPropertyUint32 (ctx, _keys, j); \ JSValue _key = JS_GetPropertyNumber (ctx, _keys, j); \
JSValue val = JS_GetProperty (ctx, _mix_ref.val, _key); \ JSValue val = JS_GetProperty (ctx, _mix_ref.val, _key); \
if (JS_IsException (val)) { \ if (JS_IsException (val)) { \
JS_PopGCRef (ctx, &_mix_ref); \ JS_PopGCRef (ctx, &_mix_ref); \
@@ -10507,7 +10459,7 @@ static JSValue js_cell_meme (JSContext *ctx, JSValue this_val, int argc, JSValue
} }
for (int64_t j = 0; j < len; j++) { for (int64_t j = 0; j < len; j++) {
JSValue mix = JS_GetPropertyInt64 (ctx, mixins_ref.val, j); JSValue mix = JS_GetPropertyNumber (ctx, mixins_ref.val, j);
if (JS_IsException (mix)) { if (JS_IsException (mix)) {
JS_PopGCRef (ctx, &mixins_ref); JS_PopGCRef (ctx, &mixins_ref);
JS_PopGCRef (ctx, &result_ref); JS_PopGCRef (ctx, &result_ref);
@@ -10516,7 +10468,7 @@ static JSValue js_cell_meme (JSContext *ctx, JSValue this_val, int argc, JSValue
APPLY_MIXIN (mix); APPLY_MIXIN (mix);
} }
JS_PopGCRef (ctx, &mixins_ref); JS_PopGCRef (ctx, &mixins_ref);
} else if (JS_IsObject (mixins) && !JS_IsNull (mixins)) { } else if (JS_IsGCObject (mixins) && !JS_IsNull (mixins)) {
/* Single mixin object */ /* Single mixin object */
APPLY_MIXIN (mixins); APPLY_MIXIN (mixins);
} }
@@ -10538,7 +10490,7 @@ static JSValue js_cell_splat (JSContext *ctx, JSValue this_val, int argc, JSValu
if (argc < 1) return JS_NULL; if (argc < 1) return JS_NULL;
JSValue obj = argv[0]; JSValue obj = argv[0];
if (!JS_IsObject (obj) || JS_IsNull (obj)) return JS_NULL; if (!JS_IsGCObject (obj) || JS_IsNull (obj)) return JS_NULL;
/* Root obj, result, current, keys across allocating calls */ /* Root obj, result, current, keys across allocating calls */
JSGCRef obj_ref, res_ref, cur_ref, keys_ref; JSGCRef obj_ref, res_ref, cur_ref, keys_ref;
@@ -10569,7 +10521,7 @@ static JSValue js_cell_splat (JSContext *ctx, JSValue this_val, int argc, JSValu
} }
for (uint32_t i = 0; i < len; i++) { for (uint32_t i = 0; i < len; i++) {
JSValue key = JS_GetPropertyUint32 (ctx, keys_ref.val, i); JSValue key = JS_GetPropertyNumber (ctx, keys_ref.val, i);
int has = JS_HasProperty (ctx, res_ref.val, key); int has = JS_HasProperty (ctx, res_ref.val, key);
if (has < 0) { if (has < 0) {
SPLAT_CLEANUP (); SPLAT_CLEANUP ();
@@ -10582,7 +10534,7 @@ static JSValue js_cell_splat (JSContext *ctx, JSValue this_val, int argc, JSValu
return JS_EXCEPTION; return JS_EXCEPTION;
} }
int tag = JS_VALUE_GET_TAG (val); int tag = JS_VALUE_GET_TAG (val);
if (JS_IsObject (val) || JS_IsNumber (val) || tag == JS_TAG_STRING if (JS_IsGCObject (val) || JS_IsNumber (val) || tag == JS_TAG_STRING
|| tag == JS_TAG_STRING_IMM || tag == JS_TAG_BOOL) { || tag == JS_TAG_STRING_IMM || tag == JS_TAG_BOOL) {
JS_SetProperty (ctx, res_ref.val, key, val); JS_SetProperty (ctx, res_ref.val, key, val);
} }
@@ -10597,13 +10549,13 @@ static JSValue js_cell_splat (JSContext *ctx, JSValue this_val, int argc, JSValu
if (JS_IsFunction (to_data)) { if (JS_IsFunction (to_data)) {
JSValue args[1] = { res_ref.val }; JSValue args[1] = { res_ref.val };
JSValue extra = JS_Call (ctx, to_data, obj_ref.val, 1, args); JSValue extra = JS_Call (ctx, to_data, obj_ref.val, 1, args);
if (!JS_IsException (extra) && JS_IsObject (extra)) { if (!JS_IsException (extra) && JS_IsGCObject (extra)) {
keys_ref.val = JS_GetOwnPropertyNames (ctx, extra); keys_ref.val = JS_GetOwnPropertyNames (ctx, extra);
if (!JS_IsException (keys_ref.val)) { if (!JS_IsException (keys_ref.val)) {
uint32_t len; uint32_t len;
if (!js_get_length32 (ctx, &len, keys_ref.val)) { if (!js_get_length32 (ctx, &len, keys_ref.val)) {
for (uint32_t i = 0; i < len; i++) { for (uint32_t i = 0; i < len; i++) {
JSValue key = JS_GetPropertyUint32 (ctx, keys_ref.val, i); JSValue key = JS_GetPropertyNumber (ctx, keys_ref.val, i);
JSValue val = JS_GetProperty (ctx, extra, key); JSValue val = JS_GetProperty (ctx, extra, key);
JS_SetProperty (ctx, res_ref.val, key, val); JS_SetProperty (ctx, res_ref.val, key, val);
} }
@@ -10657,7 +10609,7 @@ static JSValue js_cell_length (JSContext *ctx, JSValue this_val, int argc, JSVal
} }
/* Objects with length property */ /* Objects with length property */
if (JS_IsObject (val)) { if (JS_IsGCObject (val)) {
JSValue len = JS_GetPropertyStr (ctx, val, "length"); JSValue len = JS_GetPropertyStr (ctx, val, "length");
if (!JS_IsException (len) && !JS_IsNull (len)) { if (!JS_IsException (len) && !JS_IsNull (len)) {
if (JS_IsFunction (len)) { if (JS_IsFunction (len)) {
@@ -10751,7 +10703,7 @@ static JSValue js_cell_is_blob (JSContext *ctx, JSValue this_val, int argc, JSVa
static JSValue js_cell_is_data (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { static JSValue js_cell_is_data (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {
if (argc < 1) return JS_FALSE; if (argc < 1) return JS_FALSE;
JSValue val = argv[0]; JSValue val = argv[0];
if (!JS_IsObject (val)) return JS_FALSE; if (!JS_IsGCObject (val)) return JS_FALSE;
if (JS_IsArray (val)) return JS_FALSE; if (JS_IsArray (val)) return JS_FALSE;
if (JS_IsFunction (val)) return JS_FALSE; if (JS_IsFunction (val)) return JS_FALSE;
if (js_get_blob (ctx, val)) return JS_FALSE; if (js_get_blob (ctx, val)) return JS_FALSE;
@@ -10800,7 +10752,7 @@ static JSValue js_cell_is_number (JSContext *ctx, JSValue this_val, int argc, JS
static JSValue js_cell_is_object (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { static JSValue js_cell_is_object (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {
if (argc < 1) return JS_FALSE; if (argc < 1) return JS_FALSE;
JSValue val = argv[0]; JSValue val = argv[0];
if (!JS_IsObject (val)) return JS_FALSE; if (!JS_IsGCObject (val)) return JS_FALSE;
if (JS_IsArray (val)) return JS_FALSE; if (JS_IsArray (val)) return JS_FALSE;
return JS_TRUE; return JS_TRUE;
} }
@@ -10834,7 +10786,7 @@ static JSValue js_cell_is_proto (JSContext *ctx, JSValue this_val, int argc, JSV
JSValue val = argv[0]; JSValue val = argv[0];
JSValue master = argv[1]; JSValue master = argv[1];
if (!JS_IsObject (val) || JS_IsNull (master)) return JS_FALSE; if (!JS_IsGCObject (val) || JS_IsNull (master)) return JS_FALSE;
/* Walk prototype chain */ /* Walk prototype chain */
JSValue proto = JS_GetPrototype (ctx, val); JSValue proto = JS_GetPrototype (ctx, val);
@@ -10852,7 +10804,7 @@ static JSValue js_cell_is_proto (JSContext *ctx, JSValue this_val, int argc, JSV
} }
} }
/* Also check if proto == master directly */ /* Also check if proto == master directly */
if (JS_IsObject (master)) { if (JS_IsGCObject (master)) {
JSRecord *p1 = JS_VALUE_GET_OBJ (proto); JSRecord *p1 = JS_VALUE_GET_OBJ (proto);
JSRecord *p2 = JS_VALUE_GET_OBJ (master); JSRecord *p2 = JS_VALUE_GET_OBJ (master);
if (p1 == p2) { if (p1 == p2) {
@@ -10945,12 +10897,6 @@ static JSValue js_cell_some(JSContext *ctx, JSValue this_val, int argc, JSValue
return JS_FALSE; return JS_FALSE;
} }
/* GC-SAFE: Helper to set a global function. Creates function first, then reads
ctx->global_obj to ensure it's not stale if GC ran during function creation. */
int JS_SetGlobalStr (JSContext *ctx, const char *prop, JSValue val) {
return JS_SetPropertyStr(ctx, ctx->global_obj, prop, val);
}
static void js_set_global_cfunc(JSContext *ctx, const char *name, JSCFunction *func, int length) { static void js_set_global_cfunc(JSContext *ctx, const char *name, JSCFunction *func, int length) {
JSGCRef ref; JSGCRef ref;
JS_PushGCRef(ctx, &ref); JS_PushGCRef(ctx, &ref);
@@ -11142,7 +11088,7 @@ JSValue js_debugger_backtrace_fns (JSContext *ctx) {
for (sf = ctx->current_stack_frame; sf != NULL; sf = sf->prev_frame) { for (sf = ctx->current_stack_frame; sf != NULL; sf = sf->prev_frame) {
uint32_t id = stack_index++; uint32_t id = stack_index++;
JS_SetPropertyUint32 (ctx, ret, id, sf->cur_func); JS_SetPropertyNumber (ctx, ret, id, sf->cur_func);
} }
return ret; return ret;
*/ */
@@ -11167,7 +11113,7 @@ JSValue js_debugger_build_backtrace (JSContext *ctx) {
JS_SetPropertyStr (ctx, current_frame, "name", JS_NewString (ctx, func_name_str)); JS_SetPropertyStr (ctx, current_frame, "name", JS_NewString (ctx, func_name_str));
JS_FreeCString (ctx, func_name_str); JS_FreeCString (ctx, func_name_str);
JS_SetPropertyUint32 (ctx, ret, id, current_frame); JS_SetPropertyNumber (ctx, ret, id, current_frame);
} }
return ret; return ret;
*/ */
@@ -11287,7 +11233,7 @@ typedef struct NotaEncodeContext {
static void nota_stack_push (NotaEncodeContext *enc, JSValueConst val) { static void nota_stack_push (NotaEncodeContext *enc, JSValueConst val) {
JSContext *ctx = enc->ctx; JSContext *ctx = enc->ctx;
int len = nota_get_arr_len (ctx, enc->visitedStack_ref->val); int len = nota_get_arr_len (ctx, enc->visitedStack_ref->val);
JS_SetPropertyInt64 (ctx, enc->visitedStack_ref->val, len, JS_DupValue (ctx, val)); JS_SetPropertyNumber (ctx, enc->visitedStack_ref->val, len, JS_DupValue (ctx, val));
} }
static void nota_stack_pop (NotaEncodeContext *enc) { static void nota_stack_pop (NotaEncodeContext *enc) {
@@ -11300,8 +11246,8 @@ static int nota_stack_has (NotaEncodeContext *enc, JSValueConst val) {
JSContext *ctx = enc->ctx; JSContext *ctx = enc->ctx;
int len = nota_get_arr_len (ctx, enc->visitedStack_ref->val); int len = nota_get_arr_len (ctx, enc->visitedStack_ref->val);
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
JSValue elem = JS_GetPropertyUint32 (ctx, enc->visitedStack_ref->val, i); JSValue elem = JS_GetPropertyNumber (ctx, enc->visitedStack_ref->val, i);
if (JS_IsObject (elem) && JS_IsObject (val)) { if (JS_IsGCObject (elem) && JS_IsGCObject (val)) {
if (JS_StrictEq (ctx, elem, val)) { if (JS_StrictEq (ctx, elem, val)) {
JS_FreeValue (ctx, elem); JS_FreeValue (ctx, elem);
return 1; return 1;
@@ -11349,7 +11295,7 @@ static char *js_do_nota_decode (JSContext *js, JSValue *tmp, char *nota, JSValue
*tmp = JS_NewArray (js); *tmp = JS_NewArray (js);
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
nota = js_do_nota_decode (js, &ret2, nota, *tmp, JS_NewInt32 (js, i), reviver); nota = js_do_nota_decode (js, &ret2, nota, *tmp, JS_NewInt32 (js, i), reviver);
JS_SetPropertyInt64 (js, *tmp, i, ret2); JS_SetPropertyNumber (js, *tmp, i, ret2);
} }
break; break;
case NOTA_REC: case NOTA_REC:
@@ -11457,7 +11403,7 @@ static void nota_encode_value (NotaEncodeContext *enc, JSValueConst val, JSValue
nota_write_array (&enc->nb, arr_len); nota_write_array (&enc->nb, arr_len);
JS_PushGCRef (ctx, &elem_ref); JS_PushGCRef (ctx, &elem_ref);
for (int i = 0; i < arr_len; i++) { for (int i = 0; i < arr_len; i++) {
elem_ref.val = JS_GetPropertyUint32 (ctx, replaced_ref.val, i); elem_ref.val = JS_GetPropertyNumber (ctx, replaced_ref.val, i);
JSValue elem_key = JS_NewInt32 (ctx, i); JSValue elem_key = JS_NewInt32 (ctx, i);
nota_encode_value (enc, elem_ref.val, replaced_ref.val, elem_key); nota_encode_value (enc, elem_ref.val, replaced_ref.val, elem_key);
} }
@@ -11511,14 +11457,14 @@ static void nota_encode_value (NotaEncodeContext *enc, JSValueConst val, JSValue
JS_PushGCRef (ctx, &elem_ref); JS_PushGCRef (ctx, &elem_ref);
uint32_t non_function_count = 0; uint32_t non_function_count = 0;
for (uint32_t i = 0; i < plen; i++) { for (uint32_t i = 0; i < plen; i++) {
elem_ref.val = JS_GetPropertyUint32 (ctx, keys_ref.val, i); elem_ref.val = JS_GetPropertyNumber (ctx, keys_ref.val, i);
prop_ref.val = JS_GetProperty (ctx, replaced_ref.val, elem_ref.val); prop_ref.val = JS_GetProperty (ctx, replaced_ref.val, elem_ref.val);
if (!JS_IsFunction (prop_ref.val)) non_function_count++; if (!JS_IsFunction (prop_ref.val)) non_function_count++;
} }
nota_write_record (&enc->nb, non_function_count); nota_write_record (&enc->nb, non_function_count);
for (uint32_t i = 0; i < plen; i++) { for (uint32_t i = 0; i < plen; i++) {
elem_ref.val = JS_GetPropertyUint32 (ctx, keys_ref.val, i); elem_ref.val = JS_GetPropertyNumber (ctx, keys_ref.val, i);
prop_ref.val = JS_GetProperty (ctx, replaced_ref.val, elem_ref.val); prop_ref.val = JS_GetProperty (ctx, replaced_ref.val, elem_ref.val);
if (!JS_IsFunction (prop_ref.val)) { if (!JS_IsFunction (prop_ref.val)) {
const char *prop_name = JS_ToCString (ctx, elem_ref.val); const char *prop_name = JS_ToCString (ctx, elem_ref.val);
@@ -11773,7 +11719,7 @@ static void encode_object_properties (WotaEncodeContext *enc, JSValueConst val,
} }
for (uint32_t i = 0; i < plen; i++) { for (uint32_t i = 0; i < plen; i++) {
JSValue key = JS_GetPropertyUint32 (ctx, keys_ref.val, i); JSValue key = JS_GetPropertyNumber (ctx, keys_ref.val, i);
JSValue prop_val = JS_GetProperty (ctx, val_ref.val, key); JSValue prop_val = JS_GetProperty (ctx, val_ref.val, key);
if (!JS_IsFunction (prop_val)) { if (!JS_IsFunction (prop_val)) {
key_refs[non_function_count].val = key; key_refs[non_function_count].val = key;
@@ -11870,7 +11816,7 @@ static void wota_encode_value (WotaEncodeContext *enc, JSValueConst val, JSValue
JS_GetLength (ctx, replaced, &arr_len); JS_GetLength (ctx, replaced, &arr_len);
wota_write_array (&enc->wb, arr_len); wota_write_array (&enc->wb, arr_len);
for (int64_t i = 0; i < arr_len; i++) { for (int64_t i = 0; i < arr_len; i++) {
JSValue elem_val = JS_GetPropertyUint32 (ctx, replaced, i); JSValue elem_val = JS_GetPropertyNumber (ctx, replaced, i);
wota_encode_value (enc, elem_val, replaced, JS_NewInt32 (ctx, (int32_t)i)); wota_encode_value (enc, elem_val, replaced, JS_NewInt32 (ctx, (int32_t)i));
JS_FreeValue (ctx, elem_val); JS_FreeValue (ctx, elem_val);
} }
@@ -11971,7 +11917,7 @@ static char *decode_wota_value (JSContext *ctx, char *data_ptr, JSValue *out_val
elem_ref.val = JS_NULL; elem_ref.val = JS_NULL;
JSValue idx_key = JS_NewInt32 (ctx, (int32_t)i); JSValue idx_key = JS_NewInt32 (ctx, (int32_t)i);
data_ptr = decode_wota_value (ctx, data_ptr, &elem_ref.val, arr_ref.val, idx_key, reviver); data_ptr = decode_wota_value (ctx, data_ptr, &elem_ref.val, arr_ref.val, idx_key, reviver);
JS_SetPropertyUint32 (ctx, arr_ref.val, i, elem_ref.val); JS_SetPropertyNumber (ctx, arr_ref.val, i, elem_ref.val);
JS_PopGCRef (ctx, &elem_ref); JS_PopGCRef (ctx, &elem_ref);
} }
*out_val = arr_ref.val; *out_val = arr_ref.val;

View File

@@ -21,7 +21,6 @@ static const char *js_type_name(JSValue v) {
if (JS_IsText(v)) return "string"; if (JS_IsText(v)) return "string";
if (JS_IsArray(v)) return "array"; if (JS_IsArray(v)) return "array";
if (JS_IsRecord(v)) return "object"; if (JS_IsRecord(v)) return "object";
if (JS_IsObject(v)) return "object";
return "unknown"; return "unknown";
} }
@@ -310,7 +309,6 @@ TEST(string_heap_to_cstring) {
TEST(object_create) { TEST(object_create) {
JSValue obj = JS_NewObject(ctx); JSValue obj = JS_NewObject(ctx);
ASSERT(JS_IsObject(obj));
ASSERT(JS_IsRecord(obj)); ASSERT(JS_IsRecord(obj));
return 1; return 1;
} }
@@ -435,7 +433,6 @@ TEST(object_many_properties_resize) {
TEST(array_create) { TEST(array_create) {
JSValue arr = JS_NewArray(ctx); JSValue arr = JS_NewArray(ctx);
ASSERT(JS_IsObject(arr));
ASSERT(JS_IsArray(arr)); ASSERT(JS_IsArray(arr));
return 1; return 1;
} }
@@ -465,9 +462,9 @@ TEST(array_get_by_index) {
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 200)); JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 200));
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 300)); JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 300));
JSValue v0 = JS_GetPropertyUint32(ctx, arr_ref.val, 0); JSValue v0 = JS_GetPropertyNumber(ctx, arr_ref.val, 0);
JSValue v1 = JS_GetPropertyUint32(ctx, arr_ref.val, 1); JSValue v1 = JS_GetPropertyNumber(ctx, arr_ref.val, 1);
JSValue v2 = JS_GetPropertyUint32(ctx, arr_ref.val, 2); JSValue v2 = JS_GetPropertyNumber(ctx, arr_ref.val, 2);
JS_PopGCRef(ctx, &arr_ref); JS_PopGCRef(ctx, &arr_ref);
ASSERT_INT(v0, 100); ASSERT_INT(v0, 100);
@@ -486,12 +483,12 @@ TEST(array_set_by_index) {
/* Create values first, then read arr_ref.val */ /* Create values first, then read arr_ref.val */
JSValue v55 = JS_NewInt32(ctx, 55); JSValue v55 = JS_NewInt32(ctx, 55);
JS_SetPropertyUint32(ctx, arr_ref.val, 0, v55); JS_SetPropertyNumber(ctx, arr_ref.val, 0, v55);
JSValue v66 = JS_NewInt32(ctx, 66); JSValue v66 = JS_NewInt32(ctx, 66);
JS_SetPropertyUint32(ctx, arr_ref.val, 1, v66); JS_SetPropertyNumber(ctx, arr_ref.val, 1, v66);
JSValue v0 = JS_GetPropertyUint32(ctx, arr_ref.val, 0); JSValue v0 = JS_GetPropertyNumber(ctx, arr_ref.val, 0);
JSValue v1 = JS_GetPropertyUint32(ctx, arr_ref.val, 1); JSValue v1 = JS_GetPropertyNumber(ctx, arr_ref.val, 1);
JS_PopGCRef(ctx, &arr_ref); JS_PopGCRef(ctx, &arr_ref);
ASSERT_INT(v0, 55); ASSERT_INT(v0, 55);
@@ -525,7 +522,7 @@ TEST(array_out_of_bounds_is_null) {
arr_ref.val = JS_NewArray(ctx); arr_ref.val = JS_NewArray(ctx);
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 1)); JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 1));
JSValue val = JS_GetPropertyUint32(ctx, arr_ref.val, 999); JSValue val = JS_GetPropertyNumber(ctx, arr_ref.val, 999);
JS_PopGCRef(ctx, &arr_ref); JS_PopGCRef(ctx, &arr_ref);
ASSERT(JS_IsNull(val)); ASSERT(JS_IsNull(val));
return 1; return 1;
@@ -544,10 +541,10 @@ TEST(array_mixed_types) {
JS_ArrayPush(ctx, &arr_ref.val, JS_TRUE); JS_ArrayPush(ctx, &arr_ref.val, JS_TRUE);
JS_ArrayPush(ctx, &arr_ref.val, JS_NULL); JS_ArrayPush(ctx, &arr_ref.val, JS_NULL);
JSValue v0 = JS_GetPropertyUint32(ctx, arr_ref.val, 0); JSValue v0 = JS_GetPropertyNumber(ctx, arr_ref.val, 0);
JSValue v1 = JS_GetPropertyUint32(ctx, arr_ref.val, 1); JSValue v1 = JS_GetPropertyNumber(ctx, arr_ref.val, 1);
JSValue v2 = JS_GetPropertyUint32(ctx, arr_ref.val, 2); JSValue v2 = JS_GetPropertyNumber(ctx, arr_ref.val, 2);
JSValue v3 = JS_GetPropertyUint32(ctx, arr_ref.val, 3); JSValue v3 = JS_GetPropertyNumber(ctx, arr_ref.val, 3);
JS_PopGCRef(ctx, &str_ref); JS_PopGCRef(ctx, &str_ref);
JS_PopGCRef(ctx, &arr_ref); JS_PopGCRef(ctx, &arr_ref);
@@ -571,9 +568,9 @@ TEST(array_many_elements_resize) {
JS_GetLength(ctx, arr_ref.val, &len); JS_GetLength(ctx, arr_ref.val, &len);
/* Verify some values */ /* Verify some values */
JSValue v0 = JS_GetPropertyUint32(ctx, arr_ref.val, 0); JSValue v0 = JS_GetPropertyNumber(ctx, arr_ref.val, 0);
JSValue v500 = JS_GetPropertyUint32(ctx, arr_ref.val, 500); JSValue v500 = JS_GetPropertyNumber(ctx, arr_ref.val, 500);
JSValue v999 = JS_GetPropertyUint32(ctx, arr_ref.val, 999); JSValue v999 = JS_GetPropertyNumber(ctx, arr_ref.val, 999);
/* Pop BEFORE assertions */ /* Pop BEFORE assertions */
JS_PopGCRef(ctx, &arr_ref); JS_PopGCRef(ctx, &arr_ref);
@@ -716,9 +713,9 @@ TEST(array_slice_basic) {
JS_GetLength(ctx, sliced, &len); JS_GetLength(ctx, sliced, &len);
ASSERT(len == 3); ASSERT(len == 3);
JSValue v0 = JS_GetPropertyUint32(ctx, sliced, 0); JSValue v0 = JS_GetPropertyNumber(ctx, sliced, 0);
JSValue v1 = JS_GetPropertyUint32(ctx, sliced, 1); JSValue v1 = JS_GetPropertyNumber(ctx, sliced, 1);
JSValue v2 = JS_GetPropertyUint32(ctx, sliced, 2); JSValue v2 = JS_GetPropertyNumber(ctx, sliced, 2);
ASSERT_INT(v0, 10); ASSERT_INT(v0, 10);
ASSERT_INT(v1, 20); ASSERT_INT(v1, 20);
ASSERT_INT(v2, 30); ASSERT_INT(v2, 30);
@@ -747,10 +744,10 @@ TEST(array_concat_basic) {
JS_GetLength(ctx, result, &len); JS_GetLength(ctx, result, &len);
ASSERT(len == 4); ASSERT(len == 4);
ASSERT_INT(JS_GetPropertyUint32(ctx, result, 0), 1); ASSERT_INT(JS_GetPropertyNumber(ctx, result, 0), 1);
ASSERT_INT(JS_GetPropertyUint32(ctx, result, 1), 2); ASSERT_INT(JS_GetPropertyNumber(ctx, result, 1), 2);
ASSERT_INT(JS_GetPropertyUint32(ctx, result, 2), 3); ASSERT_INT(JS_GetPropertyNumber(ctx, result, 2), 3);
ASSERT_INT(JS_GetPropertyUint32(ctx, result, 3), 4); ASSERT_INT(JS_GetPropertyNumber(ctx, result, 3), 4);
return 1; return 1;
} }
@@ -772,11 +769,11 @@ TEST(array_sort_numbers) {
JS_GetLength(ctx, sorted, &len); JS_GetLength(ctx, sorted, &len);
ASSERT(len == 5); ASSERT(len == 5);
ASSERT_INT(JS_GetPropertyUint32(ctx, sorted, 0), 10); ASSERT_INT(JS_GetPropertyNumber(ctx, sorted, 0), 10);
ASSERT_INT(JS_GetPropertyUint32(ctx, sorted, 1), 20); ASSERT_INT(JS_GetPropertyNumber(ctx, sorted, 1), 20);
ASSERT_INT(JS_GetPropertyUint32(ctx, sorted, 2), 30); ASSERT_INT(JS_GetPropertyNumber(ctx, sorted, 2), 30);
ASSERT_INT(JS_GetPropertyUint32(ctx, sorted, 3), 40); ASSERT_INT(JS_GetPropertyNumber(ctx, sorted, 3), 40);
ASSERT_INT(JS_GetPropertyUint32(ctx, sorted, 4), 50); ASSERT_INT(JS_GetPropertyNumber(ctx, sorted, 4), 50);
return 1; return 1;
} }
@@ -840,8 +837,8 @@ TEST(array_filter_basic) {
JS_GetLength(ctx, filtered, &len); JS_GetLength(ctx, filtered, &len);
ASSERT(len == 5); /* 6, 7, 8, 9, 10 */ ASSERT(len == 5); /* 6, 7, 8, 9, 10 */
ASSERT_INT(JS_GetPropertyUint32(ctx, filtered, 0), 6); ASSERT_INT(JS_GetPropertyNumber(ctx, filtered, 0), 6);
ASSERT_INT(JS_GetPropertyUint32(ctx, filtered, 4), 10); ASSERT_INT(JS_GetPropertyNumber(ctx, filtered, 4), 10);
return 1; return 1;
} }
@@ -865,11 +862,11 @@ TEST(array_filter_even) {
JS_GetLength(ctx, filtered, &len); JS_GetLength(ctx, filtered, &len);
ASSERT(len == 5); /* 2, 4, 6, 8, 10 */ ASSERT(len == 5); /* 2, 4, 6, 8, 10 */
ASSERT_INT(JS_GetPropertyUint32(ctx, filtered, 0), 2); ASSERT_INT(JS_GetPropertyNumber(ctx, filtered, 0), 2);
ASSERT_INT(JS_GetPropertyUint32(ctx, filtered, 1), 4); ASSERT_INT(JS_GetPropertyNumber(ctx, filtered, 1), 4);
ASSERT_INT(JS_GetPropertyUint32(ctx, filtered, 2), 6); ASSERT_INT(JS_GetPropertyNumber(ctx, filtered, 2), 6);
ASSERT_INT(JS_GetPropertyUint32(ctx, filtered, 3), 8); ASSERT_INT(JS_GetPropertyNumber(ctx, filtered, 3), 8);
ASSERT_INT(JS_GetPropertyUint32(ctx, filtered, 4), 10); ASSERT_INT(JS_GetPropertyNumber(ctx, filtered, 4), 10);
return 1; return 1;
} }
@@ -893,9 +890,9 @@ TEST(array_map_double) {
JS_GetLength(ctx, mapped, &len); JS_GetLength(ctx, mapped, &len);
ASSERT(len == 3); ASSERT(len == 3);
ASSERT_INT(JS_GetPropertyUint32(ctx, mapped, 0), 2); ASSERT_INT(JS_GetPropertyNumber(ctx, mapped, 0), 2);
ASSERT_INT(JS_GetPropertyUint32(ctx, mapped, 1), 4); ASSERT_INT(JS_GetPropertyNumber(ctx, mapped, 1), 4);
ASSERT_INT(JS_GetPropertyUint32(ctx, mapped, 2), 6); ASSERT_INT(JS_GetPropertyNumber(ctx, mapped, 2), 6);
return 1; return 1;
} }
@@ -1356,9 +1353,9 @@ TEST(cell_reverse_array) {
JSValue reversed = JS_CellReverse(ctx, arr_ref.val); JSValue reversed = JS_CellReverse(ctx, arr_ref.val);
JS_PopGCRef(ctx, &arr_ref); JS_PopGCRef(ctx, &arr_ref);
ASSERT(JS_IsArray(reversed)); ASSERT(JS_IsArray(reversed));
ASSERT_INT(JS_GetPropertyUint32(ctx, reversed, 0), 3); ASSERT_INT(JS_GetPropertyNumber(ctx, reversed, 0), 3);
ASSERT_INT(JS_GetPropertyUint32(ctx, reversed, 1), 2); ASSERT_INT(JS_GetPropertyNumber(ctx, reversed, 1), 2);
ASSERT_INT(JS_GetPropertyUint32(ctx, reversed, 2), 1); ASSERT_INT(JS_GetPropertyNumber(ctx, reversed, 2), 1);
return 1; return 1;
} }
@@ -1408,9 +1405,9 @@ TEST(parse_json_array) {
int64_t len; int64_t len;
JS_GetLength(ctx, arr, &len); JS_GetLength(ctx, arr, &len);
ASSERT(len == 3); ASSERT(len == 3);
ASSERT_INT(JS_GetPropertyUint32(ctx, arr, 0), 1); ASSERT_INT(JS_GetPropertyNumber(ctx, arr, 0), 1);
ASSERT_INT(JS_GetPropertyUint32(ctx, arr, 1), 2); ASSERT_INT(JS_GetPropertyNumber(ctx, arr, 1), 2);
ASSERT_INT(JS_GetPropertyUint32(ctx, arr, 2), 3); ASSERT_INT(JS_GetPropertyNumber(ctx, arr, 2), 3);
return 1; return 1;
} }
@@ -1565,12 +1562,12 @@ TEST(property_type_restrictions) {
/* Setting numeric properties on non-arrays should throw */ /* Setting numeric properties on non-arrays should throw */
JSValue v100 = JS_NewInt32(ctx, 100); JSValue v100 = JS_NewInt32(ctx, 100);
int ret1 = JS_SetPropertyUint32(ctx, obj_ref.val, 0, v100); int ret1 = JS_IsException(JS_SetPropertyNumber(ctx, obj_ref.val, 0, v100)) ? -1 : 0;
int has_exc1 = JS_HasException(ctx); int has_exc1 = JS_HasException(ctx);
JS_GetException(ctx); /* Clear the exception */ JS_GetException(ctx); /* Clear the exception */
/* Getting numeric properties on objects should return null */ /* Getting numeric properties on objects should return null */
JSValue v0 = JS_GetPropertyUint32(ctx, obj_ref.val, 0); JSValue v0 = JS_GetPropertyNumber(ctx, obj_ref.val, 0);
int v0_is_null = JS_IsNull(v0); int v0_is_null = JS_IsNull(v0);
/* Getting text keys from arrays should return null */ /* Getting text keys from arrays should return null */
@@ -1646,8 +1643,8 @@ TEST(new_array_from) {
int64_t len; int64_t len;
JS_GetLength(ctx, arr, &len); JS_GetLength(ctx, arr, &len);
ASSERT(len == 4); ASSERT(len == 4);
ASSERT_INT(JS_GetPropertyUint32(ctx, arr, 0), 10); ASSERT_INT(JS_GetPropertyNumber(ctx, arr, 0), 10);
ASSERT_INT(JS_GetPropertyUint32(ctx, arr, 3), 40); ASSERT_INT(JS_GetPropertyNumber(ctx, arr, 3), 40);
return 1; return 1;
} }
@@ -1833,9 +1830,7 @@ TEST(is_function_check) {
TEST(is_integer_vs_number) { TEST(is_integer_vs_number) {
JSValue i = JS_NewInt32(ctx, 42); JSValue i = JS_NewInt32(ctx, 42);
JSValue f = JS_NewFloat64(ctx, 3.14); JSValue f = JS_NewFloat64(ctx, 3.14);
ASSERT(JS_IsInteger(i));
ASSERT(JS_IsInt(i)); ASSERT(JS_IsInt(i));
ASSERT(!JS_IsInteger(f));
ASSERT(!JS_IsInt(f)); ASSERT(!JS_IsInt(f));
ASSERT(JS_IsNumber(i)); ASSERT(JS_IsNumber(i));
ASSERT(JS_IsNumber(f)); ASSERT(JS_IsNumber(f));
@@ -1983,9 +1978,9 @@ TEST(wota_encode_nested_array) {
int is_arr = JS_IsArray(decoded); int is_arr = JS_IsArray(decoded);
int64_t len; int64_t len;
JS_GetLength(ctx, decoded, &len); JS_GetLength(ctx, decoded, &len);
JSValue v0 = JS_GetPropertyUint32(ctx, decoded, 0); JSValue v0 = JS_GetPropertyNumber(ctx, decoded, 0);
JSValue v2 = JS_GetPropertyUint32(ctx, decoded, 2); JSValue v2 = JS_GetPropertyNumber(ctx, decoded, 2);
JSValue inner = JS_GetPropertyUint32(ctx, decoded, 1); JSValue inner = JS_GetPropertyNumber(ctx, decoded, 1);
int inner_is_arr = JS_IsArray(inner); int inner_is_arr = JS_IsArray(inner);
int64_t inner_len; int64_t inner_len;
JS_GetLength(ctx, inner, &inner_len); JS_GetLength(ctx, inner, &inner_len);