guards in mcode
This commit is contained in:
@@ -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: {
|
||||
|
||||
Reference in New Issue
Block a user