From 3d0cc291d440bc4788fcf72e5ebf6608a701f956 Mon Sep 17 00:00:00 2001 From: Fabrice Bellard Date: Sat, 15 Nov 2025 12:18:18 +0100 Subject: [PATCH] optimized add/sub int32 overflow --- quickjs.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/quickjs.c b/quickjs.c index d938d4e..cfc24b7 100644 --- a/quickjs.c +++ b/quickjs.c @@ -19197,9 +19197,11 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { int64_t r; r = (int64_t)JS_VALUE_GET_INT(op1) + JS_VALUE_GET_INT(op2); - if (unlikely((int)r != r)) - goto add_slow; - sp[-2] = JS_NewInt32(ctx, r); + if (unlikely((int)r != r)) { + sp[-2] = __JS_NewFloat64(ctx, (double)r); + } else { + sp[-2] = JS_NewInt32(ctx, r); + } sp--; } else if (JS_VALUE_IS_BOTH_FLOAT(op1, op2)) { sp[-2] = __JS_NewFloat64(ctx, JS_VALUE_GET_FLOAT64(op1) + @@ -19211,7 +19213,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, if (JS_IsException(sp[-1])) goto exception; } else { - add_slow: sf->cur_pc = pc; if (js_add_slow(ctx, sp)) goto exception; @@ -19232,9 +19233,11 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, if (likely(JS_VALUE_IS_BOTH_INT(*pv, op2))) { int64_t r; r = (int64_t)JS_VALUE_GET_INT(*pv) + JS_VALUE_GET_INT(op2); - if (unlikely((int)r != r)) - goto add_loc_slow; - *pv = JS_NewInt32(ctx, r); + if (unlikely((int)r != r)) { + *pv = __JS_NewFloat64(ctx, (double)r); + } else { + *pv = JS_NewInt32(ctx, r); + } sp--; } else if (JS_VALUE_IS_BOTH_FLOAT(*pv, op2)) { *pv = __JS_NewFloat64(ctx, JS_VALUE_GET_FLOAT64(*pv) + @@ -19254,7 +19257,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, } } else { JSValue ops[2]; - add_loc_slow: /* In case of exception, js_add_slow frees ops[0] and ops[1], so we must duplicate *pv */ sf->cur_pc = pc; @@ -19275,9 +19277,11 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { int64_t r; r = (int64_t)JS_VALUE_GET_INT(op1) - JS_VALUE_GET_INT(op2); - if (unlikely((int)r != r)) - goto binary_arith_slow; - sp[-2] = JS_NewInt32(ctx, r); + if (unlikely((int)r != r)) { + sp[-2] = __JS_NewFloat64(ctx, (double)r); + } else { + sp[-2] = JS_NewInt32(ctx, r); + } sp--; } else if (JS_VALUE_IS_BOTH_FLOAT(op1, op2)) { sp[-2] = __JS_NewFloat64(ctx, JS_VALUE_GET_FLOAT64(op1) - @@ -19373,6 +19377,8 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, op1 = sp[-1]; tag = JS_VALUE_GET_TAG(op1); if (tag == JS_TAG_INT || JS_TAG_IS_FLOAT64(tag)) { + } else if (tag == JS_TAG_NULL || tag == JS_TAG_BOOL) { + sp[-1] = JS_NewInt32(ctx, JS_VALUE_GET_INT(op1)); } else { sf->cur_pc = pc; if (js_unary_arith_slow(ctx, sp, opcode)) @@ -19388,7 +19394,9 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, double d; op1 = sp[-1]; tag = JS_VALUE_GET_TAG(op1); - if (tag == JS_TAG_INT) { + if (tag == JS_TAG_INT || + tag == JS_TAG_BOOL || + tag == JS_TAG_NULL) { val = JS_VALUE_GET_INT(op1); /* Note: -0 cannot be expressed as integer */ if (unlikely(val == 0)) {