Merge branch 'mach' into mcode2

This commit is contained in:
2026-02-07 14:19:19 -06:00

View File

@@ -313,7 +313,7 @@ struct JSFunctionBytecode;
#define JS_VALUE_GET_OBJ(v) ((JSRecord *)chase (v))
#define JS_VALUE_GET_TEXT(v) ((JSText *)chase (v))
#define JS_VALUE_GET_BLOB(v) ((JSBlob *)JS_VALUE_GET_PTR (v))
#define JS_VALUE_GET_FUNCTION(v) ((JSFunction *)JS_VALUE_GET_PTR (v))
#define JS_VALUE_GET_FUNCTION(v) ((JSFunction *)chase (v))
#define JS_VALUE_GET_FRAME(v) ((JSFrame *)chase (v))
#define JS_VALUE_GET_CODE(v) ((JSFunctionBytecode *)JS_VALUE_GET_PTR (v))
#define JS_VALUE_GET_STRING(v) ((JSText *)chase (v))
@@ -24216,8 +24216,7 @@ static JSValue js_cell_object (JSContext *ctx, JSValue this_val, int argc, JSVal
keys = JS_VALUE_GET_ARRAY (argv[1]); /* re-chase each iteration */
if (i >= (int)keys->len) break;
JSValue key = keys->values[i];
int key_tag = JS_VALUE_GET_TAG (key);
if (key_tag == JS_TAG_STRING || key_tag == JS_TAG_STRING_IMM) {
if (JS_IsText (key)) {
/* Use JSValue key directly - create interned key */
JSValue prop_key = js_key_from_string (ctx, key);
int has = JS_HasProperty (ctx, arg, prop_key);
@@ -24241,38 +24240,57 @@ static JSValue js_cell_object (JSContext *ctx, JSValue this_val, int argc, JSVal
JSArray *keys = JS_VALUE_GET_ARRAY (arg);
int len = keys->len;
JSValue result = JS_NewObject (ctx);
if (JS_IsException (result)) return result;
JSGCRef result_ref;
int is_func = argc >= 2 && JS_IsFunction (argv[1]);
/* Root keys array and func/value BEFORE JS_NewObject which may trigger GC.
argv[] is on the C stack and is NOT a GC root, so after any allocation
that triggers GC, argv[] values become dangling pointers. */
JSGCRef keys_ref, func_ref, result_ref;
JS_PushGCRef (ctx, &keys_ref);
keys_ref.val = arg; /* use already-read arg, not argv[0] */
JS_PushGCRef (ctx, &func_ref);
func_ref.val = argc >= 2 ? argv[1] : JS_NULL;
JS_PushGCRef (ctx, &result_ref);
result_ref.val = JS_NULL;
JSValue result = JS_NewObject (ctx);
if (JS_IsException (result)) {
JS_PopGCRef (ctx, &result_ref);
JS_PopGCRef (ctx, &func_ref);
JS_PopGCRef (ctx, &keys_ref);
return result;
}
result_ref.val = result;
for (int i = 0; i < len; i++) {
keys = JS_VALUE_GET_ARRAY (argv[0]); /* re-chase each iteration via argv */
keys = JS_VALUE_GET_ARRAY (keys_ref.val);
if (i >= (int)keys->len) break;
JSValue key = keys->values[i];
int key_tag = JS_VALUE_GET_TAG (key);
if (key_tag == JS_TAG_STRING || key_tag == JS_TAG_STRING_IMM) {
if (JS_IsText (key)) {
/* Use JSValue key directly - create interned key */
JSValue prop_key = js_key_from_string (ctx, key);
JSValue val;
if (argc < 2 || JS_IsNull (argv[1])) {
if (argc < 2 || JS_IsNull (func_ref.val)) {
val = JS_TRUE;
} else if (is_func) {
JSValue arg_key = key;
JS_PUSH_VALUE (ctx, result);
val = JS_CallInternal (ctx, argv[1], JS_NULL, 1, &arg_key, 0);
JS_POP_VALUE (ctx, result);
val = JS_CallInternal (ctx, func_ref.val, JS_NULL, 1, &arg_key, 0);
if (JS_IsException (val)) {
JS_PopGCRef (ctx, &result_ref);
JS_PopGCRef (ctx, &func_ref);
JS_PopGCRef (ctx, &keys_ref);
return JS_EXCEPTION;
}
} else {
val = argv[1];
val = func_ref.val;
}
JS_SetProperty (ctx, result, prop_key, val);
JS_SetProperty (ctx, result_ref.val, prop_key, val);
/* prop_key is interned, no need to free */
}
}
result = JS_PopGCRef (ctx, &result_ref);
JS_PopGCRef (ctx, &func_ref);
JS_PopGCRef (ctx, &keys_ref);
return result;
}