guards in mcode

This commit is contained in:
2026-02-13 02:30:41 -06:00
parent e346348eb5
commit 4a50d0587d
14 changed files with 72485 additions and 69473 deletions

View File

@@ -987,13 +987,9 @@ JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
}
case MACH_GETINDEX: {
/* R(A) = R(B)[R(C)] — mcode guarantees R(C) is int */
JSValue obj = frame->slots[b];
JSValue idx = frame->slots[c];
JSValue val;
if (JS_IsInt(idx))
val = JS_GetPropertyNumber(ctx, obj, JS_VALUE_GET_INT(idx));
else
val = JS_GetProperty(ctx, obj, idx);
JSValue val = JS_GetPropertyNumber(ctx, obj, JS_VALUE_GET_INT(frame->slots[c]));
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
if (JS_IsException(val)) goto disrupt;
frame->slots[a] = val;
@@ -1001,25 +997,12 @@ JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
}
case MACH_SETINDEX: {
/* R(A)[R(B)] = R(C) */
/* R(A)[R(B)] = R(C) — mcode guarantees R(B) is int */
JSValue obj = frame->slots[a];
JSValue idx = frame->slots[b];
JSValue val = frame->slots[c];
int ret;
if (JS_IsInt(idx)) {
JSValue r = JS_SetPropertyNumber(ctx, obj, JS_VALUE_GET_INT(idx), val);
ret = JS_IsException(r) ? -1 : 0;
} else if (mist_is_array(obj)) {
JS_ThrowTypeError(ctx, "array index must be a number");
ret = -1;
} else if (mist_is_record(obj) && !mist_is_text(idx) && !mist_is_record(idx)) {
JS_ThrowTypeError(ctx, "object key must be a string or object");
ret = -1;
} else {
ret = JS_SetProperty(ctx, obj, idx, val);
}
JSValue r = JS_SetPropertyNumber(ctx, obj, JS_VALUE_GET_INT(frame->slots[b]), val);
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
if (ret < 0) goto disrupt;
if (JS_IsException(r)) goto disrupt;
break;
}
@@ -1187,16 +1170,10 @@ JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
}
case MACH_NEWARRAY: {
int count = b;
JSValue arr = JS_NewArray(ctx);
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
if (JS_IsException(arr)) { goto disrupt; }
/* Store array in dest immediately so GC can track it */
frame->slots[a] = arr;
for (int i = 0; i < count; i++) {
JS_SetPropertyNumber(ctx, frame->slots[a], i, frame->slots[a + 1 + i]);
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
}
break;
}
@@ -1216,14 +1193,9 @@ JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
}
case MACH_PUSH: {
/* push R(B) onto array R(A) */
/* push R(B) onto array R(A) — mcode guarantees R(A) is array */
JSValue arr = frame->slots[a];
JSValue val = frame->slots[b];
if (!mist_is_array(arr)) {
JS_ThrowTypeError(ctx, "cannot push to non-array");
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
goto disrupt;
}
JSGCRef arr_gc;
JS_PushGCRef(ctx, &arr_gc);
arr_gc.val = arr;
@@ -1236,13 +1208,8 @@ JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
}
case MACH_POP: {
/* R(A) = pop last element from array R(B) */
/* R(A) = pop last element from array R(B) — mcode guarantees R(B) is array */
JSValue arr = frame->slots[b];
if (!mist_is_array(arr)) {
JS_ThrowTypeError(ctx, "cannot pop from non-array");
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
goto disrupt;
}
JSValue val = JS_ArrayPop(ctx, arr);
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
if (JS_IsException(val)) goto disrupt;
@@ -1594,30 +1561,21 @@ JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
break;
}
case MACH_LOAD_INDEX: {
/* R(A) = R(B)[R(C)] — mcode guarantees R(C) is int */
JSValue obj = frame->slots[b];
JSValue idx = frame->slots[c];
JSValue val;
if (JS_IsInt(idx))
val = JS_GetPropertyNumber(ctx, obj, JS_VALUE_GET_INT(idx));
else
val = JS_GetProperty(ctx, obj, idx);
JSValue val = JS_GetPropertyNumber(ctx, obj, JS_VALUE_GET_INT(frame->slots[c]));
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
if (JS_IsException(val)) goto disrupt;
frame->slots[a] = val;
break;
}
case MACH_STORE_INDEX: {
/* R(A)[R(B)] = R(C) — mcode guarantees R(B) is int */
JSValue obj = frame->slots[a];
JSValue idx = frame->slots[b];
JSValue val = frame->slots[c];
int ret;
if (JS_IsInt(idx)) {
JSValue r = JS_SetPropertyNumber(ctx, obj, JS_VALUE_GET_INT(idx), val);
ret = JS_IsException(r) ? -1 : 0;
} else
ret = JS_SetProperty(ctx, obj, idx, val);
JSValue r = JS_SetPropertyNumber(ctx, obj, JS_VALUE_GET_INT(frame->slots[b]), val);
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
if (ret < 0) goto disrupt;
if (JS_IsException(r)) goto disrupt;
break;
}
case MACH_LOAD_DYNAMIC: {