1 Commits
ast ... syntax

Author SHA1 Message Date
John Alanbrook
e3888e96c9 fix various vm issues" 2026-02-05 12:50:19 -06:00
5 changed files with 162 additions and 58 deletions

View File

@@ -591,6 +591,8 @@ int cell_init(int argc, char **argv)
} }
/* Check for --mach-run flag to generate and run machine code through register VM */ /* Check for --mach-run flag to generate and run machine code through register VM */
fprintf(stderr, "DEBUG: argc=%d argv[1]=%s\n", argc, argc > 1 ? argv[1] : "NULL");
fflush(stderr);
if (argc >= 3 && strcmp(argv[1], "--mach-run") == 0) { if (argc >= 3 && strcmp(argv[1], "--mach-run") == 0) {
const char *script_or_file = argv[2]; const char *script_or_file = argv[2];
char *script = NULL; char *script = NULL;
@@ -625,7 +627,7 @@ int cell_init(int argc, char **argv)
free(allocated_script); free(allocated_script);
return 1; return 1;
} }
JSContext *ctx = JS_NewContext(rt); JSContext *ctx = JS_NewContextWithHeapSize(rt, 1024 * 1024); /* 1MB heap for register VM */
if (!ctx) { if (!ctx) {
printf("Failed to create JS context\n"); printf("Failed to create JS context\n");
JS_FreeRuntime(rt); JS_FreeRuntime(rt);
@@ -656,7 +658,11 @@ int cell_init(int argc, char **argv)
} }
/* Execute through register VM */ /* Execute through register VM */
fprintf(stderr, "DEBUG: About to execute mach code\n");
fflush(stderr);
JSValue result = JS_IntegrateRegister(ctx, mach_json, JS_NULL); JSValue result = JS_IntegrateRegister(ctx, mach_json, JS_NULL);
fprintf(stderr, "DEBUG: Execution done, result tag=%d\n", (int)(result >> 48));
fflush(stderr);
free(mach_json); free(mach_json);
int exit_code = 0; int exit_code = 0;

View File

@@ -1,6 +1,9 @@
extern int cell_init(int argc, char **argv); extern int cell_init(int argc, char **argv);
#include <stdio.h>
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
fprintf(stderr, "MAIN: starting\n");
fflush(stderr);
return cell_init(argc, argv); return cell_init(argc, argv);
} }

View File

@@ -538,6 +538,10 @@ typedef enum MachOpcode {
MACH_OP_CATCH_END, /* catch_end */ MACH_OP_CATCH_END, /* catch_end */
MACH_OP_FINALLY_BEGIN, /* finally_begin */ MACH_OP_FINALLY_BEGIN, /* finally_begin */
MACH_OP_FINALLY_END, /* finally_end */ MACH_OP_FINALLY_END, /* finally_end */
/* Additional operators */
MACH_OP_IN, /* in dest, key, obj */
MACH_OP_NEW_OBJECT, /* new_object dest */
MACH_OP_NEW_ARRAY, /* new_array dest, capacity */
MACH_OP_COUNT MACH_OP_COUNT
} MachOpcode; } MachOpcode;
@@ -611,6 +615,9 @@ static const char *mach_opcode_names[MACH_OP_COUNT] = {
[MACH_OP_CATCH_END] = "catch_end", [MACH_OP_CATCH_END] = "catch_end",
[MACH_OP_FINALLY_BEGIN] = "finally_begin", [MACH_OP_FINALLY_BEGIN] = "finally_begin",
[MACH_OP_FINALLY_END] = "finally_end", [MACH_OP_FINALLY_END] = "finally_end",
[MACH_OP_IN] = "in",
[MACH_OP_NEW_OBJECT] = "new_object",
[MACH_OP_NEW_ARRAY] = "new_array",
}; };
/* Compiled instruction for register VM. /* Compiled instruction for register VM.
@@ -30936,61 +30943,52 @@ static int mach_gen_expr (MachGenState *s, cJSON *expr) {
cJSON *list = cJSON_GetObjectItem (expr, "list"); cJSON *list = cJSON_GetObjectItem (expr, "list");
int count = cJSON_GetArraySize (list); int count = cJSON_GetArraySize (list);
/* Compile each element */ int dest = mach_alloc_slot (s);
cJSON *elem_slots = cJSON_CreateArray (); /* Emit new_array dest, capacity */
mach_emit_2 (s, "new_array", dest, count);
/* Emit store_idx for each element */
int idx = 0;
cJSON *elem; cJSON *elem;
cJSON_ArrayForEach (elem, list) { cJSON_ArrayForEach (elem, list) {
int slot = mach_gen_expr (s, elem); int val_slot = mach_gen_expr (s, elem);
cJSON_AddItemToArray (elem_slots, cJSON_CreateNumber (slot)); int idx_slot = mach_alloc_slot (s);
mach_emit_const_num (s, idx_slot, idx);
mach_emit_set_elem (s, dest, idx_slot, val_slot);
idx++;
} }
int dest = mach_alloc_slot (s);
cJSON *instr = cJSON_CreateArray ();
cJSON_AddItemToArray (instr, cJSON_CreateString ("mkarray"));
cJSON_AddItemToArray (instr, cJSON_CreateNumber (dest));
cJSON_AddItemToArray (instr, cJSON_CreateNumber (count));
cJSON *el;
cJSON_ArrayForEach (el, elem_slots) {
cJSON_AddItemToArray (instr, cJSON_CreateNumber (el->valueint));
}
cJSON_AddItemToArray (s->instructions, instr);
cJSON_Delete (elem_slots);
return dest; return dest;
} }
/* Object literal */ /* Object literal */
if (strcmp (kind, "record") == 0) { if (strcmp (kind, "record") == 0) {
cJSON *list = cJSON_GetObjectItem (expr, "list"); cJSON *list = cJSON_GetObjectItem (expr, "list");
int count = cJSON_GetArraySize (list);
int dest = mach_alloc_slot (s); int dest = mach_alloc_slot (s);
cJSON *instr = cJSON_CreateArray (); /* Emit new_object dest */
cJSON_AddItemToArray (instr, cJSON_CreateString ("mkrecord")); mach_emit_1 (s, "new_object", dest);
cJSON_AddItemToArray (instr, cJSON_CreateNumber (dest));
cJSON_AddItemToArray (instr, cJSON_CreateNumber (count));
/* Emit store_prop for each property */
cJSON *pair; cJSON *pair;
cJSON_ArrayForEach (pair, list) { cJSON_ArrayForEach (pair, list) {
cJSON *key = cJSON_GetObjectItem (pair, "left"); cJSON *key = cJSON_GetObjectItem (pair, "left");
cJSON *val = cJSON_GetObjectItem (pair, "right"); cJSON *val = cJSON_GetObjectItem (pair, "right");
int val_slot = mach_gen_expr (s, val);
const char *key_kind = cJSON_GetStringValue (cJSON_GetObjectItem (key, "kind")); const char *key_kind = cJSON_GetStringValue (cJSON_GetObjectItem (key, "kind"));
if (key_kind && strcmp (key_kind, "name") == 0) { if (key_kind && strcmp (key_kind, "name") == 0) {
const char *name = cJSON_GetStringValue (cJSON_GetObjectItem (key, "name")); const char *name = cJSON_GetStringValue (cJSON_GetObjectItem (key, "name"));
cJSON_AddItemToArray (instr, cJSON_CreateString (name)); mach_emit_set_prop (s, dest, name, val_slot);
} else if (key_kind && strcmp (key_kind, "text") == 0) { } else if (key_kind && strcmp (key_kind, "text") == 0) {
const char *name = cJSON_GetStringValue (cJSON_GetObjectItem (key, "value")); const char *name = cJSON_GetStringValue (cJSON_GetObjectItem (key, "value"));
cJSON_AddItemToArray (instr, cJSON_CreateString (name ? name : "")); mach_emit_set_prop (s, dest, name ? name : "", val_slot);
} else { } else {
/* Computed property - emit the key slot (negative to distinguish) */ /* Computed property */
int key_slot = mach_gen_expr (s, key); int key_slot = mach_gen_expr (s, key);
cJSON_AddItemToArray (instr, cJSON_CreateNumber (-1 - key_slot)); mach_emit_set_elem (s, dest, key_slot, val_slot);
} }
int val_slot = mach_gen_expr (s, val);
cJSON_AddItemToArray (instr, cJSON_CreateNumber (val_slot));
} }
cJSON_AddItemToArray (s->instructions, instr);
return dest; return dest;
} }
@@ -31820,6 +31818,9 @@ static MachOpcode mach_opcode_from_string(const char *name) {
if (strcmp(name, "catch_end") == 0) return MACH_OP_CATCH_END; if (strcmp(name, "catch_end") == 0) return MACH_OP_CATCH_END;
if (strcmp(name, "finally_begin") == 0) return MACH_OP_FINALLY_BEGIN; if (strcmp(name, "finally_begin") == 0) return MACH_OP_FINALLY_BEGIN;
if (strcmp(name, "finally_end") == 0) return MACH_OP_FINALLY_END; if (strcmp(name, "finally_end") == 0) return MACH_OP_FINALLY_END;
if (strcmp(name, "in") == 0) return MACH_OP_IN;
if (strcmp(name, "new_object") == 0) return MACH_OP_NEW_OBJECT;
if (strcmp(name, "new_array") == 0) return MACH_OP_NEW_ARRAY;
return MACH_OP_NOP; return MACH_OP_NOP;
} }
@@ -32005,7 +32006,8 @@ static JSCodeRegister *js_link_mach_unit(JSContext *ctx, cJSON *unit, JSValue en
case MACH_OP_NULL: case MACH_OP_NULL:
case MACH_OP_TRUE: case MACH_OP_TRUE:
case MACH_OP_FALSE: case MACH_OP_FALSE:
case MACH_OP_RETURN: { case MACH_OP_RETURN:
case MACH_OP_NEW_OBJECT: {
/* op dest/src */ /* op dest/src */
cJSON *a = cJSON_GetArrayItem(item, 1); cJSON *a = cJSON_GetArrayItem(item, 1);
instr->a = a ? (int16_t)cJSON_GetNumberValue(a) : 0; instr->a = a ? (int16_t)cJSON_GetNumberValue(a) : 0;
@@ -32020,7 +32022,8 @@ static JSCodeRegister *js_link_mach_unit(JSContext *ctx, cJSON *unit, JSValue en
case MACH_OP_INVOKE: case MACH_OP_INVOKE:
case MACH_OP_SET_THIS: case MACH_OP_SET_THIS:
case MACH_OP_MKFUNC: case MACH_OP_MKFUNC:
case MACH_OP_MKFUNC_ARROW: { case MACH_OP_MKFUNC_ARROW:
case MACH_OP_NEW_ARRAY: {
/* op dest, src */ /* op dest, src */
cJSON *a = cJSON_GetArrayItem(item, 1); cJSON *a = cJSON_GetArrayItem(item, 1);
cJSON *b = cJSON_GetArrayItem(item, 2); cJSON *b = cJSON_GetArrayItem(item, 2);
@@ -32055,7 +32058,8 @@ static JSCodeRegister *js_link_mach_unit(JSContext *ctx, cJSON *unit, JSValue en
case MACH_OP_PUT: case MACH_OP_PUT:
case MACH_OP_FRAME: case MACH_OP_FRAME:
case MACH_OP_GOFRAME: case MACH_OP_GOFRAME:
case MACH_OP_ARG: { case MACH_OP_ARG:
case MACH_OP_IN: {
/* op a, b, c */ /* op a, b, c */
cJSON *a = cJSON_GetArrayItem(item, 1); cJSON *a = cJSON_GetArrayItem(item, 1);
cJSON *b = cJSON_GetArrayItem(item, 2); cJSON *b = cJSON_GetArrayItem(item, 2);
@@ -32091,6 +32095,19 @@ static JSCodeRegister *js_link_mach_unit(JSContext *ctx, cJSON *unit, JSValue en
} }
break; break;
} }
case MACH_OP_DELETE_PROP: {
/* delete_prop dest, obj, "prop" */
cJSON *dest = cJSON_GetArrayItem(item, 1);
cJSON *obj = cJSON_GetArrayItem(item, 2);
cJSON *prop = cJSON_GetArrayItem(item, 3);
instr->a = dest ? (int16_t)cJSON_GetNumberValue(dest) : 0;
instr->b = obj ? (int16_t)cJSON_GetNumberValue(obj) : 0;
if (prop && cJSON_IsString(prop)) {
JSValue v = JS_NewString(ctx, cJSON_GetStringValue(prop));
instr->c = mach_cpool_add(&cpool, v);
}
break;
}
case MACH_OP_CAP_NAME: { case MACH_OP_CAP_NAME: {
/* cap_name dest, "name" - resolve to env or global */ /* cap_name dest, "name" - resolve to env or global */
cJSON *dest = cJSON_GetArrayItem(item, 1); cJSON *dest = cJSON_GetArrayItem(item, 1);
@@ -32481,14 +32498,19 @@ static JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
JS_AddGCRef(ctx, &frame_ref); JS_AddGCRef(ctx, &frame_ref);
frame_ref.val = JS_MKPTR(frame); frame_ref.val = JS_MKPTR(frame);
/* Setup initial frame */ /* Setup initial frame - note: function member is not set for top-level code */
frame->slots[0] = this_obj; /* slot 0 is this */ frame->slots[0] = this_obj; /* slot 0 is this */
frame->function = JS_NULL; /* Mark as top-level frame (no function object) */
/* Copy arguments */ /* Copy arguments */
for (int i = 0; i < argc && i < code->arity; i++) { for (int i = 0; i < argc && i < code->arity; i++) {
frame->slots[1 + i] = argv[i]; frame->slots[1 + i] = argv[i];
} }
/* Save initial code/env for when we return to top-level */
JSCodeRegister *initial_code = code;
JSValue initial_env = env;
uint32_t pc = code->entry_point; uint32_t pc = code->entry_point;
JSValue result = JS_NULL; JSValue result = JS_NULL;
@@ -32510,16 +32532,22 @@ static JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
} }
/* Pop frame and resume caller */ /* Pop frame and resume caller */
int ret_info = JS_VALUE_GET_INT(frame->address);
JSFrameRegister *caller = (JSFrameRegister *)JS_VALUE_GET_PTR(frame->caller); JSFrameRegister *caller = (JSFrameRegister *)JS_VALUE_GET_PTR(frame->caller);
int ret_info = JS_VALUE_GET_INT(caller->address); /* Return addr is in CALLER's frame */
frame->caller = JS_NULL; /* Allow GC to collect */ frame->caller = JS_NULL; /* Allow GC to collect */
frame = caller; frame = caller;
frame_ref.val = JS_MKPTR(frame); frame_ref.val = JS_MKPTR(frame);
/* Get code from function */ /* Get code from function, or use initial code for top-level */
JSFunction *fn = JS_VALUE_GET_FUNCTION(frame->function); if (JS_IsNull(frame->function)) {
code = fn->u.reg.code; code = initial_code;
env = initial_env;
} else {
JSFunction *fn = JS_VALUE_GET_FUNCTION(frame->function);
code = fn->u.reg.code;
env = fn->u.reg.env_record;
}
pc = ret_info >> 16; pc = ret_info >> 16;
frame->slots[ret_info & 0xFFFF] = result; frame->slots[ret_info & 0xFFFF] = result;
@@ -32574,11 +32602,15 @@ static JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
case MACH_OP_BITXOR: case MACH_OP_BITXOR:
case MACH_OP_SHL: case MACH_OP_SHL:
case MACH_OP_SHR: case MACH_OP_SHR:
case MACH_OP_USHR: case MACH_OP_USHR: {
frame->slots[instr->a] = reg_vm_binop(ctx, instr->opcode, JSValue res = reg_vm_binop(ctx, instr->opcode,
frame->slots[instr->b], frame->slots[instr->b],
frame->slots[instr->c]); frame->slots[instr->c]);
/* GC may have moved frame - refresh from GC root */
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
frame->slots[instr->a] = res;
break; break;
}
case MACH_OP_NEG: { case MACH_OP_NEG: {
JSValue v = frame->slots[instr->b]; JSValue v = frame->slots[instr->b];
@@ -32641,6 +32673,14 @@ static JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
break; break;
} }
case MACH_OP_IN: {
JSValue key = frame->slots[instr->b];
JSValue obj = frame->slots[instr->c];
int has = JS_HasProperty(ctx, obj, key);
frame->slots[instr->a] = JS_NewBool(ctx, has > 0);
break;
}
case MACH_OP_LOAD_PROP: { case MACH_OP_LOAD_PROP: {
JSValue obj = frame->slots[instr->b]; JSValue obj = frame->slots[instr->b];
JSValue key = code->cpool[instr->c]; JSValue key = code->cpool[instr->c];
@@ -32659,7 +32699,7 @@ static JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
case MACH_OP_LOAD_IDX: { case MACH_OP_LOAD_IDX: {
JSValue obj = frame->slots[instr->b]; JSValue obj = frame->slots[instr->b];
JSValue idx = frame->slots[instr->c]; JSValue idx = frame->slots[instr->c];
if (JS_IsInt(idx)) { if (JS_IsInt(idx) && JS_IsArray(obj)) {
frame->slots[instr->a] = JS_GetPropertyUint32(ctx, obj, JS_VALUE_GET_INT(idx)); frame->slots[instr->a] = JS_GetPropertyUint32(ctx, obj, JS_VALUE_GET_INT(idx));
} else { } else {
frame->slots[instr->a] = JS_GetProperty(ctx, obj, idx); frame->slots[instr->a] = JS_GetProperty(ctx, obj, idx);
@@ -32671,7 +32711,7 @@ static JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
JSValue obj = frame->slots[instr->a]; JSValue obj = frame->slots[instr->a];
JSValue idx = frame->slots[instr->b]; JSValue idx = frame->slots[instr->b];
JSValue val = frame->slots[instr->c]; JSValue val = frame->slots[instr->c];
if (JS_IsInt(idx)) { if (JS_IsInt(idx) && JS_IsArray(obj)) {
JS_SetPropertyUint32(ctx, obj, JS_VALUE_GET_INT(idx), val); JS_SetPropertyUint32(ctx, obj, JS_VALUE_GET_INT(idx), val);
} else { } else {
JS_SetProperty(ctx, obj, idx, val); JS_SetProperty(ctx, obj, idx, val);
@@ -32679,6 +32719,22 @@ static JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
break; break;
} }
case MACH_OP_DELETE_PROP: {
JSValue obj = frame->slots[instr->b];
JSValue key = code->cpool[instr->c];
int ret = JS_DeleteProperty(ctx, obj, key);
frame->slots[instr->a] = JS_NewBool(ctx, ret >= 0);
break;
}
case MACH_OP_DELETE_IDX: {
JSValue obj = frame->slots[instr->b];
JSValue idx = frame->slots[instr->c];
int ret = JS_DeleteProperty(ctx, obj, idx);
frame->slots[instr->a] = JS_NewBool(ctx, ret >= 0);
break;
}
case MACH_OP_GET: { case MACH_OP_GET: {
/* Closure access: get dest, slot, depth */ /* Closure access: get dest, slot, depth */
int depth = instr->c; int depth = instr->c;
@@ -32774,13 +32830,15 @@ static JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
frame->slots[instr->a] = func_val; frame->slots[instr->a] = func_val;
} else { } else {
JSCodeRegister *fn_code = fn->u.reg.code; JSCodeRegister *fn_code = fn->u.reg.code;
JSFrameRegister *new_frame = alloc_frame_register(ctx, fn_code->nr_slots); uint16_t nr_slots = fn_code->nr_slots;
JSFrameRegister *new_frame = alloc_frame_register(ctx, nr_slots);
if (!new_frame) { if (!new_frame) {
result = JS_EXCEPTION; result = JS_EXCEPTION;
goto done; goto done;
} }
/* GC may have moved frame - refresh from GC root */ /* GC may have moved frame and function - refresh from roots */
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val); frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
func_val = frame->slots[instr->b]; /* Re-fetch func_val after GC */
new_frame->function = func_val; new_frame->function = func_val;
frame->slots[instr->a] = JS_MKPTR(new_frame); frame->slots[instr->a] = JS_MKPTR(new_frame);
} }
@@ -32856,13 +32914,15 @@ static JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
JSFunction *fn = JS_VALUE_GET_FUNCTION(func_val); JSFunction *fn = JS_VALUE_GET_FUNCTION(func_val);
if (fn->kind == JS_FUNC_KIND_REGISTER) { if (fn->kind == JS_FUNC_KIND_REGISTER) {
JSCodeRegister *fn_code = fn->u.reg.code; JSCodeRegister *fn_code = fn->u.reg.code;
JSFrameRegister *new_frame = alloc_frame_register(ctx, fn_code->nr_slots); uint16_t nr_slots = fn_code->nr_slots;
JSFrameRegister *new_frame = alloc_frame_register(ctx, nr_slots);
if (!new_frame) { if (!new_frame) {
result = JS_EXCEPTION; result = JS_EXCEPTION;
goto done; goto done;
} }
/* GC may have moved frame - refresh from GC root */ /* GC may have moved frame and function - refresh from roots */
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val); frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
func_val = frame->slots[instr->b]; /* Re-fetch func_val after GC */
new_frame->function = func_val; new_frame->function = func_val;
frame->slots[instr->a] = JS_MKPTR(new_frame); frame->slots[instr->a] = JS_MKPTR(new_frame);
} else { } else {
@@ -32929,6 +32989,31 @@ static JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
break; break;
} }
case MACH_OP_NEW_OBJECT: {
JSValue obj = JS_NewObject(ctx);
/* GC may have moved frame - refresh from GC root */
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
if (JS_IsException(obj)) {
result = obj;
goto done;
}
frame->slots[instr->a] = obj;
break;
}
case MACH_OP_NEW_ARRAY: {
int capacity = instr->b;
JSValue arr = JS_NewArrayLen(ctx, capacity);
/* GC may have moved frame - refresh from GC root */
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
if (JS_IsException(arr)) {
result = arr;
goto done;
}
frame->slots[instr->a] = arr;
break;
}
case MACH_OP_RETURN: case MACH_OP_RETURN:
result = frame->slots[instr->a]; result = frame->slots[instr->a];
@@ -32937,16 +33022,22 @@ static JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
} }
{ {
int ret_info = JS_VALUE_GET_INT(frame->address);
JSFrameRegister *caller = (JSFrameRegister *)JS_VALUE_GET_PTR(frame->caller); JSFrameRegister *caller = (JSFrameRegister *)JS_VALUE_GET_PTR(frame->caller);
int ret_info = JS_VALUE_GET_INT(caller->address); /* Return addr is in CALLER's frame */
frame->caller = JS_NULL; frame->caller = JS_NULL;
frame = caller; frame = caller;
frame_ref.val = JS_MKPTR(frame); frame_ref.val = JS_MKPTR(frame);
JSFunction *fn = JS_VALUE_GET_FUNCTION(frame->function); /* Get code from function, or use initial code for top-level */
code = fn->u.reg.code; if (JS_IsNull(frame->function)) {
env = fn->u.reg.env_record; code = initial_code;
env = initial_env;
} else {
JSFunction *fn = JS_VALUE_GET_FUNCTION(frame->function);
code = fn->u.reg.code;
env = fn->u.reg.env_record;
}
pc = ret_info >> 16; pc = ret_info >> 16;
frame->slots[ret_info & 0xFFFF] = result; frame->slots[ret_info & 0xFFFF] = result;
@@ -32961,16 +33052,22 @@ static JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
} }
{ {
int ret_info = JS_VALUE_GET_INT(frame->address);
JSFrameRegister *caller = (JSFrameRegister *)JS_VALUE_GET_PTR(frame->caller); JSFrameRegister *caller = (JSFrameRegister *)JS_VALUE_GET_PTR(frame->caller);
int ret_info = JS_VALUE_GET_INT(caller->address); /* Return addr is in CALLER's frame */
frame->caller = JS_NULL; frame->caller = JS_NULL;
frame = caller; frame = caller;
frame_ref.val = JS_MKPTR(frame); frame_ref.val = JS_MKPTR(frame);
JSFunction *fn = JS_VALUE_GET_FUNCTION(frame->function); /* Get code from function, or use initial code for top-level */
code = fn->u.reg.code; if (JS_IsNull(frame->function)) {
env = fn->u.reg.env_record; code = initial_code;
env = initial_env;
} else {
JSFunction *fn = JS_VALUE_GET_FUNCTION(frame->function);
code = fn->u.reg.code;
env = fn->u.reg.env_record;
}
pc = ret_info >> 16; pc = ret_info >> 16;
frame->slots[ret_info & 0xFFFF] = result; frame->slots[ret_info & 0xFFFF] = result;

View File

@@ -1 +0,0 @@
typeof 5

View File

@@ -1 +0,0 @@
void 0