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

@@ -28,44 +28,56 @@
#define WOTA_IMPLEMENTATION
#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;
/* === Function definitions from header region (non-inline) === */
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
@@ -1440,7 +1452,7 @@ JSContext *JS_NewContextRawWithHeapSize (JSRuntime *rt, size_t heap_size) {
ctx->reg_current_frame = JS_NULL;
/* Initialize per-context execution state (moved from JSRuntime) */
ctx->current_exception = JS_UNINITIALIZED;
ctx->current_exception = JS_NULL;
/* Initialize stone text intern table */
ctx->st_pages = NULL;
@@ -1486,22 +1498,19 @@ JSContext *JS_NewContextRaw (JSRuntime *rt) {
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 *ctx = JS_NewContextRaw (rt);
if (!ctx) return NULL;
JS_AddIntrinsics (ctx);
JS_AddIntrinsicBaseObjects (ctx);
JS_AddIntrinsicRegExp (ctx);
return ctx;
}
JSContext *JS_NewContextWithHeapSize (JSRuntime *rt, size_t heap_size) {
JSContext *ctx = JS_NewContextRawWithHeapSize (rt, heap_size);
if (!ctx) return NULL;
JS_AddIntrinsics (ctx);
JS_AddIntrinsicBaseObjects (ctx);
JS_AddIntrinsicRegExp (ctx);
return ctx;
}
@@ -1511,7 +1520,6 @@ void JS_SetContextOpaque (JSContext *ctx, void *opaque) {
ctx->user_opaque = opaque;
}
void JS_SetClassProto (JSContext *ctx, JSClassID class_id, JSValue obj) {
assert (class_id < ctx->class_count);
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). */
JSValue JS_GetException (JSContext *ctx) {
JSValue val = ctx->current_exception;
ctx->current_exception = JS_UNINITIALIZED;
ctx->current_exception = JS_NULL;
return val;
}
JS_BOOL
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 */
int get_line_col (int *pcol_num, const uint8_t *buf, size_t len) {
int line_num, col_num, c;
@@ -2686,22 +2693,10 @@ JSValue JS_ThrowOutOfMemory (JSContext *ctx) {
return JS_EXCEPTION;
}
JSValue JS_ThrowStackOverflow (JSContext *ctx) {
return JS_ThrowInternalError (ctx, "stack overflow");
}
static JSValue JS_ThrowTypeErrorNotAnObject (JSContext *ctx) {
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) {
const char *name = ctx->class_array[class_id].class_name;
return JS_ThrowTypeError (ctx, "%s object expected", name ? name : "unknown");
@@ -2711,7 +2706,6 @@ void JS_ThrowInterrupted (JSContext *ctx) {
JS_ThrowInternalError (ctx, "interrupted");
}
/* Return an Object, JS_NULL or JS_EXCEPTION in case of exotic object. */
JSValue JS_GetPrototype (JSContext *ctx, JSValue obj) {
JSValue val;
@@ -2780,7 +2774,7 @@ JSValue JS_GetOwnPropertyNames (JSContext *ctx, JSValue obj) {
if (JS_IsException (arr)) return JS_EXCEPTION;
for (i = 0; i < count; i++) {
JS_SetPropertyUint32 (ctx, arr, i, keys[i]);
JS_SetPropertyNumber (ctx, arr, i, keys[i]);
}
return arr;
@@ -2936,14 +2930,6 @@ JSValue JS_GetPropertyNumber (JSContext *js, JSValue obj, int idx) {
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) {
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);
}
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 */
int JS_SetPropertyStr (JSContext *ctx, JSValue this_obj, const char *prop, JSValue val) {
/* 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) {
if (!JS_IsNull (name) && JS_IsObject (obj)
if (!JS_IsNull (name) && JS_IsGCObject (obj)
&& !js_object_has_name (ctx, obj)) {
JSValue name_key = MIST_TryNewImmediateASCII ("name", 4);
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) {
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);
if (JS_SetPropertyInternal (ctx, obj, name_key, str)
< 0)
@@ -4023,9 +3993,6 @@ static void js_print_value (JSPrintValueState *s, JSValue val) {
case JS_TAG_EXCEPTION:
str = "exception";
goto print_str;
case JS_TAG_UNINITIALIZED:
str = "uninitialized";
goto print_str;
print_str:
js_puts (s, str);
break;
@@ -4138,7 +4105,6 @@ __maybe_unused void JS_DumpGCObject (JSRuntime *rt,
}
}
/* Simplified equality: no NaN (becomes null), no coercion, no SameValue distinction */
BOOL js_strict_eq (JSContext *ctx, JSValue op1, JSValue op2) {
/* 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++) {
key = JS_GetPropertyUint32 (ctx, keys, i);
key = JS_GetPropertyNumber (ctx, keys, i);
if (JS_IsException (key)) goto exception;
/* 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;
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;
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) {
JSValue m;
if (!JS_IsObject (obj)) return FALSE;
if (!JS_IsGCObject (obj)) return FALSE;
m = JS_GetPropertyStr (ctx, obj, "Symbol.match");
if (JS_IsException (m)) return -1;
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 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);
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);
}
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) {
JSContext *ctx = opaque;
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;
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 ();
goto fail;
}
@@ -5275,7 +5232,7 @@ static JSValue cjson_to_jsvalue (JSContext *ctx, const cJSON *item) {
JSValue arr = JS_NewArray (ctx);
for (int i = 0; i < n; 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;
}
@@ -5338,7 +5295,7 @@ static JSValue js_json_check (JSContext *ctx, JSONStringifyContext *jsc, JSValue
/* check for object.toJSON method */
/* 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);
if (JS_IsException (f)) goto exception;
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;
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 */
if (JS_IsText (val_ref.val) && !MIST_IsImmediateASCII (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;
}
if (JS_IsObject (
if (JS_IsGCObject (
val_ref.val)) { /* includes arrays (OBJ_ARRAY) since they have JS_TAG_PTR */
v = js_array_includes (ctx, jsc->stack, 1, &val_ref.val);
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_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;
v_ref.val = v; /* root v — JS_ToString below can trigger GC */
/* 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, '{');
has_content = FALSE;
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;
v = JS_GetPropertyValue (ctx, val_ref.val, prop_ref.val);
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;
for (i = j = 0; i < n; i++) {
JSValue present;
v = JS_GetPropertyInt64 (ctx, replacer, i);
v = JS_GetPropertyNumber (ctx, replacer, i);
if (JS_IsException (v)) goto exception;
if (JS_IsObject (v)) {
if (JS_IsGCObject (v)) {
/* Objects are not valid property list items */
continue;
} else if (JS_IsNumber (v)) {
@@ -5618,7 +5570,7 @@ JSValue JS_JSONStringify (JSContext *ctx, JSValue obj, JSValue replacer, JSValue
goto exception;
}
if (!JS_ToBool (ctx, present)) {
JS_SetPropertyInt64 (ctx, jsc->property_list, j++, v);
JS_SetPropertyNumber (ctx, jsc->property_list, j++, v);
} else {
}
}
@@ -6569,7 +6521,7 @@ static JSValue js_cell_text (JSContext *ctx, JSValue this_val, int argc, JSValue
return JS_EXCEPTION;
}
/* Root b across allocating calls (JS_GetPropertyInt64, JS_ToString) */
/* Root b across allocating calls (JS_GetPropertyNumber, JS_ToString) */
JSGCRef b_ref;
JS_AddGCRef (ctx, &b_ref);
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 */
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_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) {
if (!JS_IsObject (v)) return 0;
if (!JS_IsGCObject (v)) return 0;
JSValue exec = JS_GetPropertyStr (ctx, v, "exec");
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])) {
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;
} else {
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;
if (JS_IsText (argv[1])) {
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;
} else {
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;
/* 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 */
JSGCRef rx_ref, str_ref, out_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;
}
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);
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;
if (js_get_length64 (ctx, &caps_len, caps) == 0 && caps_len > 0) {
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)) {
goto fail_rx;
}
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;
}
}
@@ -7433,7 +7385,7 @@ static JSValue js_cell_text_extract (JSContext *ctx, JSValue this_val, int argc,
JSValue arr = arr_ref.val;
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 arr;
@@ -7574,7 +7526,7 @@ static JSValue js_cell_text_format (JSContext *ctx, JSValue this_val, int argc,
valid = 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 {
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) {
for (int i = 0; i < len; i++) {
JSValue ch = js_sub_string_val (ctx, arg, i, i + 1);
JS_SetPropertyInt64 (ctx, result, idx++, ch);
JS_SetPropertyNumber (ctx, result, idx++, ch);
}
} else {
while ((found = strstr (pos, sep)) != NULL) {
JSValue part = JS_NewStringLen (ctx, pos, found - pos);
JS_SetPropertyInt64 (ctx, result, idx++, part);
JS_SetPropertyNumber (ctx, result, idx++, part);
pos = found + sep_len;
}
JSValue part = JS_NewString (ctx, pos);
JS_SetPropertyInt64 (ctx, result, idx++, part);
JS_SetPropertyNumber (ctx, result, idx++, part);
}
JS_FreeCString (ctx, cstr);
@@ -8279,7 +8231,7 @@ static JSValue js_cell_array (JSContext *ctx, JSValue this_val, int argc, JSValu
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) */
/* Root rx, result, arg across allocating calls */
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);
if (JS_IsException (tail)) goto fail_rx_split;
result = res_ref.val;
JS_SetPropertyInt64 (ctx, result, out_idx++, tail);
JS_SetPropertyNumber (ctx, result, out_idx++, tail);
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);
if (JS_IsException (chunk))
return JS_EXCEPTION;
JS_SetPropertyInt64 (ctx, result, idx++, chunk);
JS_SetPropertyNumber (ctx, result, idx++, chunk);
}
return result;
@@ -8824,7 +8776,7 @@ static JSValue js_cell_array_sort (JSContext *ctx, JSValue this_val, int argc, J
else
key = JS_NULL;
} else {
key = JS_GetPropertyInt64 (ctx, items[i], idx);
key = JS_GetPropertyNumber (ctx, items[i], idx);
/* Re-read items[i] after potential GC */
arr = JS_VALUE_GET_ARRAY (arr_ref.val);
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];
/* 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])) {
/* Shallow copy - root arg, result, keys across allocating calls */
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++) {
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);
if (JS_IsException (val)) {
OBJ_COPY_CLEANUP ();
@@ -8981,7 +8933,7 @@ static JSValue js_cell_object (JSContext *ctx, JSValue this_val, int argc, JSVal
#undef OBJ_COPY_CLEANUP
/* 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;
JS_PushGCRef (ctx, &arg_ref);
arg_ref.val = arg;
@@ -9008,7 +8960,7 @@ static JSValue js_cell_object (JSContext *ctx, JSValue this_val, int argc, JSVal
return JS_EXCEPTION;
}
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);
if (JS_IsException (val)) {
OBJ_COMBINE_CLEANUP ();
@@ -9028,7 +8980,7 @@ static JSValue js_cell_object (JSContext *ctx, JSValue this_val, int argc, JSVal
return JS_EXCEPTION;
}
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);
if (JS_IsException (val)) {
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 */
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]);
if (!src)
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_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);
cJSON_Delete (ast);
JS_FreeCString (ctx, name);
@@ -9859,7 +9811,7 @@ static JSValue js_mach_load (JSContext *ctx, JSValue this_val, int argc, JSValue
if (!mc)
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;
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");
}
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);
/* mcode tree ownership transferred to JS_CallMcodeTreeEnv — do not free */
JS_FreeCString (ctx, name);
@@ -9918,7 +9870,7 @@ static JSValue js_cell_stone (JSContext *ctx, JSValue this_val, int argc, JSValu
return obj;
}
if (JS_IsObject (obj)) {
if (JS_IsGCObject (obj)) {
JSRecord *rec = JS_VALUE_GET_RECORD (obj);
obj_set_stone (rec);
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");
}
if (!JS_IsObject (obj)) return JS_NULL;
if (!JS_IsGCObject (obj)) return JS_NULL;
JSValue proto = JS_GetPrototype (ctx, obj);
if (JS_IsException (proto)) return JS_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];
if (JS_IsObject (obj_proto)
if (JS_IsGCObject (obj_proto)
&& JS_VALUE_GET_OBJ (proto) == JS_VALUE_GET_OBJ (obj_proto)) {
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 */
#define APPLY_MIXIN(mix_val) \
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; \
JSGCRef _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; \
} \
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); \
if (JS_IsException (val)) { \
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++) {
JSValue mix = JS_GetPropertyInt64 (ctx, mixins_ref.val, j);
JSValue mix = JS_GetPropertyNumber (ctx, mixins_ref.val, j);
if (JS_IsException (mix)) {
JS_PopGCRef (ctx, &mixins_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);
}
JS_PopGCRef (ctx, &mixins_ref);
} else if (JS_IsObject (mixins) && !JS_IsNull (mixins)) {
} else if (JS_IsGCObject (mixins) && !JS_IsNull (mixins)) {
/* Single mixin object */
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;
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 */
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++) {
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);
if (has < 0) {
SPLAT_CLEANUP ();
@@ -10582,7 +10534,7 @@ static JSValue js_cell_splat (JSContext *ctx, JSValue this_val, int argc, JSValu
return JS_EXCEPTION;
}
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) {
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)) {
JSValue args[1] = { res_ref.val };
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);
if (!JS_IsException (keys_ref.val)) {
uint32_t len;
if (!js_get_length32 (ctx, &len, keys_ref.val)) {
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);
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 */
if (JS_IsObject (val)) {
if (JS_IsGCObject (val)) {
JSValue len = JS_GetPropertyStr (ctx, val, "length");
if (!JS_IsException (len) && !JS_IsNull (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) {
if (argc < 1) return JS_FALSE;
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_IsFunction (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) {
if (argc < 1) return JS_FALSE;
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;
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 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 */
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 */
if (JS_IsObject (master)) {
if (JS_IsGCObject (master)) {
JSRecord *p1 = JS_VALUE_GET_OBJ (proto);
JSRecord *p2 = JS_VALUE_GET_OBJ (master);
if (p1 == p2) {
@@ -10945,12 +10897,6 @@ static JSValue js_cell_some(JSContext *ctx, JSValue this_val, int argc, JSValue
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) {
JSGCRef 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) {
uint32_t id = stack_index++;
JS_SetPropertyUint32 (ctx, ret, id, sf->cur_func);
JS_SetPropertyNumber (ctx, ret, id, sf->cur_func);
}
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_FreeCString (ctx, func_name_str);
JS_SetPropertyUint32 (ctx, ret, id, current_frame);
JS_SetPropertyNumber (ctx, ret, id, current_frame);
}
return ret;
*/
@@ -11287,7 +11233,7 @@ typedef struct NotaEncodeContext {
static void nota_stack_push (NotaEncodeContext *enc, JSValueConst val) {
JSContext *ctx = enc->ctx;
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) {
@@ -11300,8 +11246,8 @@ static int nota_stack_has (NotaEncodeContext *enc, JSValueConst val) {
JSContext *ctx = enc->ctx;
int len = nota_get_arr_len (ctx, enc->visitedStack_ref->val);
for (int i = 0; i < len; i++) {
JSValue elem = JS_GetPropertyUint32 (ctx, enc->visitedStack_ref->val, i);
if (JS_IsObject (elem) && JS_IsObject (val)) {
JSValue elem = JS_GetPropertyNumber (ctx, enc->visitedStack_ref->val, i);
if (JS_IsGCObject (elem) && JS_IsGCObject (val)) {
if (JS_StrictEq (ctx, elem, val)) {
JS_FreeValue (ctx, elem);
return 1;
@@ -11349,7 +11295,7 @@ static char *js_do_nota_decode (JSContext *js, JSValue *tmp, char *nota, JSValue
*tmp = JS_NewArray (js);
for (int i = 0; i < n; i++) {
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;
case NOTA_REC:
@@ -11457,7 +11403,7 @@ static void nota_encode_value (NotaEncodeContext *enc, JSValueConst val, JSValue
nota_write_array (&enc->nb, arr_len);
JS_PushGCRef (ctx, &elem_ref);
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);
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);
uint32_t non_function_count = 0;
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);
if (!JS_IsFunction (prop_ref.val)) non_function_count++;
}
nota_write_record (&enc->nb, non_function_count);
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);
if (!JS_IsFunction (prop_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++) {
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);
if (!JS_IsFunction (prop_val)) {
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);
wota_write_array (&enc->wb, arr_len);
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));
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;
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);
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);
}
*out_val = arr_ref.val;