better streamline

This commit is contained in:
2026-02-16 00:34:49 -06:00
parent dc440587ff
commit ff61ab1f50
5 changed files with 166 additions and 63 deletions

View File

@@ -927,17 +927,18 @@ JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
frame->slots[a] = frame->slots[b];
VM_BREAK();
/* Arithmetic — inline integer fast paths, slow path calls reg_vm_binop */
/* Arithmetic — mcode guarantees both operands are numbers */
VM_CASE(MACH_ADD): {
JSValue left = frame->slots[b], right = frame->slots[c];
if (JS_VALUE_IS_BOTH_INT(left, right)) {
int64_t r = (int64_t)JS_VALUE_GET_INT(left) + (int64_t)JS_VALUE_GET_INT(right);
frame->slots[a] = (r >= INT32_MIN && r <= INT32_MAX) ? JS_NewInt32(ctx, (int32_t)r) : JS_NewFloat64(ctx, (double)r);
} else {
JSValue res = reg_vm_binop(ctx, MACH_ADD, left, right);
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
if (JS_IsException(res)) goto disrupt;
frame->slots[a] = res;
double da, db, r;
JS_ToFloat64(ctx, &da, left);
JS_ToFloat64(ctx, &db, right);
r = da + db;
frame->slots[a] = !isfinite(r) ? JS_NULL : JS_NewFloat64(ctx, r);
}
VM_BREAK();
}
@@ -947,10 +948,11 @@ JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
int64_t r = (int64_t)JS_VALUE_GET_INT(left) - (int64_t)JS_VALUE_GET_INT(right);
frame->slots[a] = (r >= INT32_MIN && r <= INT32_MAX) ? JS_NewInt32(ctx, (int32_t)r) : JS_NewFloat64(ctx, (double)r);
} else {
JSValue res = reg_vm_binop(ctx, MACH_SUB, left, right);
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
if (JS_IsException(res)) goto disrupt;
frame->slots[a] = res;
double da, db, r;
JS_ToFloat64(ctx, &da, left);
JS_ToFloat64(ctx, &db, right);
r = da - db;
frame->slots[a] = !isfinite(r) ? JS_NULL : JS_NewFloat64(ctx, r);
}
VM_BREAK();
}
@@ -960,10 +962,11 @@ JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
int64_t r = (int64_t)JS_VALUE_GET_INT(left) * (int64_t)JS_VALUE_GET_INT(right);
frame->slots[a] = (r >= INT32_MIN && r <= INT32_MAX) ? JS_NewInt32(ctx, (int32_t)r) : JS_NewFloat64(ctx, (double)r);
} else {
JSValue res = reg_vm_binop(ctx, MACH_MUL, left, right);
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
if (JS_IsException(res)) goto disrupt;
frame->slots[a] = res;
double da, db, r;
JS_ToFloat64(ctx, &da, left);
JS_ToFloat64(ctx, &db, right);
r = da * db;
frame->slots[a] = !isfinite(r) ? JS_NULL : JS_NewFloat64(ctx, r);
}
VM_BREAK();
}
@@ -978,10 +981,14 @@ JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
else
frame->slots[a] = JS_NULL;
} else {
JSValue res = reg_vm_binop(ctx, MACH_DIV, left, right);
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
if (JS_IsException(res)) goto disrupt;
frame->slots[a] = res;
double da, db, r;
JS_ToFloat64(ctx, &da, left);
JS_ToFloat64(ctx, &db, right);
if (db == 0.0) { frame->slots[a] = JS_NULL; }
else {
r = da / db;
frame->slots[a] = !isfinite(r) ? JS_NULL : JS_NewFloat64(ctx, r);
}
}
VM_BREAK();
}
@@ -991,19 +998,33 @@ JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
int32_t ib = JS_VALUE_GET_INT(right);
frame->slots[a] = (ib != 0) ? JS_NewInt32(ctx, JS_VALUE_GET_INT(left) % ib) : JS_NULL;
} else {
JSValue res = reg_vm_binop(ctx, MACH_MOD, left, right);
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
if (JS_IsException(res)) goto disrupt;
frame->slots[a] = res;
double da, db, r;
JS_ToFloat64(ctx, &da, left);
JS_ToFloat64(ctx, &db, right);
if (db == 0.0) { frame->slots[a] = JS_NULL; }
else {
r = fmod(da, db);
frame->slots[a] = !isfinite(r) ? JS_NULL : JS_NewFloat64(ctx, r);
}
}
VM_BREAK();
}
VM_CASE(MACH_POW): {
JSValue left = frame->slots[b], right = frame->slots[c];
JSValue res = reg_vm_binop(ctx, MACH_POW, left, right);
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
if (JS_IsException(res)) goto disrupt;
frame->slots[a] = res;
if (JS_VALUE_IS_BOTH_INT(left, right)) {
double r = pow((double)JS_VALUE_GET_INT(left), (double)JS_VALUE_GET_INT(right));
if (!isfinite(r)) frame->slots[a] = JS_NULL;
else if (r >= INT32_MIN && r <= INT32_MAX && r == (int32_t)r)
frame->slots[a] = JS_NewInt32(ctx, (int32_t)r);
else
frame->slots[a] = JS_NewFloat64(ctx, r);
} else {
double da, db, r;
JS_ToFloat64(ctx, &da, left);
JS_ToFloat64(ctx, &db, right);
r = pow(da, db);
frame->slots[a] = (!isfinite(r) && isfinite(da) && isfinite(db)) ? JS_NULL : JS_NewFloat64(ctx, r);
}
VM_BREAK();
}