diff --git a/source/quickjs.c b/source/quickjs.c index be21780b..49fb55a8 100644 --- a/source/quickjs.c +++ b/source/quickjs.c @@ -30236,11 +30236,13 @@ static void ast_sem_check_expr (ASTSemState *st, ASTSemScope *scope, cJSON *expr } else if (v->is_const) { ast_sem_error (st, expr, "cannot assign to constant '%s'", name); } - /* Annotate with level/function_nr so compilers can emit correct set instructions */ + /* Annotate with level/function_nr/scope_name so compilers can emit correct set instructions */ ASTSemLookup r = ast_sem_lookup_var (scope, name); if (r.var) { cJSON_AddNumberToObject (operand, "level", r.level); cJSON_AddNumberToObject (operand, "function_nr", r.def_function_nr); + if (r.var->scope_name) + cJSON_AddStringToObject (operand, "scope_name", r.var->scope_name); } else { cJSON_AddNumberToObject (operand, "level", -1); } @@ -33359,7 +33361,8 @@ static JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code, break; } if (JS_IsNull(frame->caller)) { - result = JS_NULL; + result = JS_Throw(ctx, JS_NewString(ctx, "unhandled disruption")); + frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val); goto done; } /* Unwind one frame — read caller's saved pc from its address field */ @@ -34295,8 +34298,8 @@ static int mach_gen_expr (MachGenState *s, cJSON *expr, int target) { /* Function expression */ if (strcmp (kind, "function") == 0) { - int func_id = s->func_counter++; cJSON *func = mach_gen_function (s, expr); + int func_id = s->func_counter++; cJSON_AddItemToArray (s->functions, func); int dest = mach_gen_alloc_slot (s); mach_gen_emit_2 (s, "function", dest, func_id); @@ -34581,8 +34584,8 @@ static void mach_gen_statement (MachGenState *s, cJSON *stmt) { cJSON *name_obj = cJSON_GetObjectItem (stmt, "name"); if (name_obj && cJSON_IsString (name_obj)) { const char *name = cJSON_GetStringValue (name_obj); - int func_id = s->func_counter++; cJSON *func = mach_gen_function (s, stmt); + int func_id = s->func_counter++; cJSON_AddItemToArray (s->functions, func); int local_slot = mach_gen_find_var (s, name); int dest = mach_gen_alloc_slot (s); @@ -34680,8 +34683,8 @@ static cJSON *mach_gen_function (MachGenState *parent, cJSON *func_node) { cJSON_ArrayForEach (fn, hoisted) { const char *fname = cJSON_GetStringValue (cJSON_GetObjectItem (fn, "name")); if (fname) { - int func_id = s.func_counter++; cJSON *compiled = mach_gen_function (&s, fn); + int func_id = s.func_counter++; cJSON_AddItemToArray (s.functions, compiled); int local_slot = mach_gen_find_var (&s, fname); int dest = mach_gen_alloc_slot (&s); @@ -34792,8 +34795,8 @@ static cJSON *mach_gen_program (MachGenState *s, cJSON *ast) { cJSON_ArrayForEach (fn, hoisted) { const char *name = cJSON_GetStringValue (cJSON_GetObjectItem (fn, "name")); if (name) { - int func_id = s->func_counter++; cJSON *compiled = mach_gen_function (s, fn); + int func_id = s->func_counter++; cJSON_AddItemToArray (s->functions, compiled); int local_slot = mach_gen_find_var (s, name); int dest = mach_gen_alloc_slot (s); @@ -35966,7 +35969,6 @@ static JSValue mcode_exec(JSContext *ctx, JSMCode *code, JSValue this_obj, /* Store return address: pc << 16 | ret_slot */ frame->address = JS_NewInt32(ctx, (pc << 16) | ret_reg); new_frame->caller = JS_MKPTR(frame); - /* Switch to new frame */ frame = new_frame; frame_ref.val = JS_MKPTR(frame); @@ -36193,8 +36195,14 @@ static JSValue mcode_exec(JSContext *ctx, JSMCode *code, JSValue this_obj, int arr_slot = (int)a1->valuedouble; JSValue val = frame->slots[(int)a2->valuedouble]; if (!JS_IsArray(frame->slots[arr_slot])) { goto disrupt; } - JS_ArrayPush(ctx, &frame->slots[arr_slot], val); + JSGCRef arr_gc; + JS_PushGCRef(ctx, &arr_gc); + arr_gc.val = frame->slots[arr_slot]; + int rc = JS_ArrayPush(ctx, &arr_gc.val, val); frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val); + JS_PopGCRef(ctx, &arr_gc); + if (rc < 0) goto disrupt; + if (arr_gc.val != frame->slots[arr_slot]) frame->slots[arr_slot] = arr_gc.val; } /* ---- Pop (remove last from array) ---- */ @@ -36236,7 +36244,8 @@ static JSValue mcode_exec(JSContext *ctx, JSMCode *code, JSValue this_obj, break; } if (JS_IsNull(frame->caller)) { - result = JS_NULL; + result = JS_Throw(ctx, JS_NewString(ctx, "unhandled disruption")); + frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val); goto done; } /* Unwind one frame — read caller's saved pc from its address field */ diff --git a/vm_suite.ce b/vm_suite.ce index cd5f05b1..686fb4eb 100644 --- a/vm_suite.ce +++ b/vm_suite.ce @@ -9,7 +9,7 @@ var error_reasons = [] var fail_msg = "" // pre-allocate 500 slots to avoid array growth during disruption handlers -for (var _i = 0; _i < 500; _i++) { +for (var _i = 0; _i < 5; _i++) { error_names[] = null error_reasons[] = null }