From 3459d85a824421b34c75c4d1f6a14cb00bdcbaf0 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Tue, 17 Jun 2025 12:54:20 -0500 Subject: [PATCH] binary logic only works on ints; returns null otherwise --- source/quickjs.c | 201 ++++++----------------------------------------- 1 file changed, 22 insertions(+), 179 deletions(-) diff --git a/source/quickjs.c b/source/quickjs.c index 50167541..bfb79c78 100644 --- a/source/quickjs.c +++ b/source/quickjs.c @@ -12904,6 +12904,19 @@ static no_inline __exception int js_binary_arith_slow(JSContext *ctx, JSValue *s d2 = JS_VALUE_GET_FLOAT64(op2); goto handle_float64; } + + if ((tag1 == JS_TAG_INT && tag2 == JS_TAG_FLOAT64) || (tag1 == JS_TAG_FLOAT64 && tag2 == JS_TAG_INT)) { + if(tag1 == JS_TAG_INT) + d1 = (double)JS_VALUE_GET_INT(op1); + else + d1 = JS_VALUE_GET_FLOAT64(op1); + if(tag2 == JS_TAG_INT) + d2 = (double)JS_VALUE_GET_INT(op2); + else + d2 = JS_VALUE_GET_FLOAT64(op2); + goto handle_float64; + } + /* fast path for short big int operations */ if (tag1 == JS_TAG_SHORT_BIG_INT && tag2 == JS_TAG_SHORT_BIG_INT) { js_slimb_t v1, v2; @@ -12948,6 +12961,9 @@ static no_inline __exception int js_binary_arith_slow(JSContext *ctx, JSValue *s } return 0; } + + + op1 = JS_ToNumericFree(ctx, op1); if (JS_IsException(op1)) { JS_FreeValue(ctx, op2); @@ -13195,167 +13211,6 @@ static no_inline __exception int js_add_slow(JSContext *ctx, JSValue *sp) return -1; } -static no_inline __exception int js_binary_logic_slow(JSContext *ctx, - JSValue *sp, - OPCodeEnum op) -{ - JSValue op1, op2; - uint32_t tag1, tag2; - uint32_t v1, v2, r; - - op1 = sp[-2]; - op2 = sp[-1]; - tag1 = JS_VALUE_GET_NORM_TAG(op1); - tag2 = JS_VALUE_GET_NORM_TAG(op2); - - if (tag1 == JS_TAG_SHORT_BIG_INT && tag2 == JS_TAG_SHORT_BIG_INT) { - js_slimb_t v1, v2, v; - js_sdlimb_t vd; - v1 = JS_VALUE_GET_SHORT_BIG_INT(op1); - v2 = JS_VALUE_GET_SHORT_BIG_INT(op2); - /* bigint fast path */ - switch(op) { - case OP_and: - v = v1 & v2; - break; - case OP_or: - v = v1 | v2; - break; - case OP_xor: - v = v1 ^ v2; - break; - case OP_sar: - if (v2 > (JS_LIMB_BITS - 1)) { - goto slow_big_int; - } else if (v2 < 0) { - if (v2 < -(JS_LIMB_BITS - 1)) - goto slow_big_int; - v2 = -v2; - goto bigint_shl; - } - bigint_sar: - v = v1 >> v2; - break; - case OP_shl: - if (v2 > (JS_LIMB_BITS - 1)) { - goto slow_big_int; - } else if (v2 < 0) { - if (v2 < -(JS_LIMB_BITS - 1)) - goto slow_big_int; - v2 = -v2; - goto bigint_sar; - } - bigint_shl: - vd = (js_dlimb_t)v1 << v2; - if (likely(vd >= JS_SHORT_BIG_INT_MIN && - vd <= JS_SHORT_BIG_INT_MAX)) { - v = vd; - } else { - JSBigInt *r = js_bigint_new_di(ctx, vd); - if (!r) - goto exception; - sp[-2] = JS_MKPTR(JS_TAG_BIG_INT, r); - return 0; - } - break; - default: - abort(); - } - sp[-2] = __JS_NewShortBigInt(ctx, v); - return 0; - } - op1 = JS_ToNumericFree(ctx, op1); - if (JS_IsException(op1)) { - JS_FreeValue(ctx, op2); - goto exception; - } - op2 = JS_ToNumericFree(ctx, op2); - if (JS_IsException(op2)) { - JS_FreeValue(ctx, op1); - goto exception; - } - - tag1 = JS_VALUE_GET_TAG(op1); - tag2 = JS_VALUE_GET_TAG(op2); - if ((tag1 == JS_TAG_BIG_INT || tag1 == JS_TAG_SHORT_BIG_INT) && - (tag2 == JS_TAG_BIG_INT || tag2 == JS_TAG_SHORT_BIG_INT)) { - JSBigInt *p1, *p2, *r; - JSBigIntBuf buf1, buf2; - slow_big_int: - if (JS_VALUE_GET_TAG(op1) == JS_TAG_SHORT_BIG_INT) - p1 = js_bigint_set_short(&buf1, op1); - else - p1 = JS_VALUE_GET_PTR(op1); - if (JS_VALUE_GET_TAG(op2) == JS_TAG_SHORT_BIG_INT) - p2 = js_bigint_set_short(&buf2, op2); - else - p2 = JS_VALUE_GET_PTR(op2); - switch(op) { - case OP_and: - case OP_or: - case OP_xor: - r = js_bigint_logic(ctx, p1, p2, op); - break; - case OP_shl: - case OP_sar: - { - js_slimb_t shift; - shift = js_bigint_get_si_sat(p2); - if (shift > INT32_MAX) - shift = INT32_MAX; - else if (shift < -INT32_MAX) - shift = -INT32_MAX; - if (op == OP_sar) - shift = -shift; - if (shift >= 0) - r = js_bigint_shl(ctx, p1, shift); - else - r = js_bigint_shr(ctx, p1, -shift); - } - break; - default: - abort(); - } - JS_FreeValue(ctx, op1); - JS_FreeValue(ctx, op2); - if (!r) - goto exception; - sp[-2] = JS_CompactBigInt(ctx, r); - } else { - if (unlikely(JS_ToInt32Free(ctx, (int32_t *)&v1, op1))) { - JS_FreeValue(ctx, op2); - goto exception; - } - if (unlikely(JS_ToInt32Free(ctx, (int32_t *)&v2, op2))) - goto exception; - switch(op) { - case OP_shl: - r = v1 << (v2 & 0x1f); - break; - case OP_sar: - r = (int)v1 >> (v2 & 0x1f); - break; - case OP_and: - r = v1 & v2; - break; - case OP_or: - r = v1 | v2; - break; - case OP_xor: - r = v1 ^ v2; - break; - default: - abort(); - } - sp[-2] = JS_NewInt32(ctx, r); - } - return 0; - exception: - sp[-2] = JS_UNDEFINED; - sp[-1] = JS_UNDEFINED; - return -1; -} - /* op1 must be a bigint or int. */ static JSBigInt *JS_ToBigIntBuf(JSContext *ctx, JSBigIntBuf *buf1, JSValue op1) @@ -17309,9 +17164,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, sp[-2] = JS_NewInt32(ctx, v1 << v2); sp--; } else { - sf->cur_pc = pc; - if (js_binary_logic_slow(ctx, sp, opcode)) - goto exception; + sp[-2] = JS_NULL; sp--; } } @@ -17330,9 +17183,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, v2); sp--; } else { - sf->cur_pc = pc; - if (js_shr_slow(ctx, sp)) - goto exception; + sp[-2] = JS_NULL; sp--; } } @@ -17350,9 +17201,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, (int)JS_VALUE_GET_INT(op1) >> v2); sp--; } else { - sf->cur_pc = pc; - if (js_binary_logic_slow(ctx, sp, opcode)) - goto exception; + sp[-2] = JS_NULL; sp--; } } @@ -17368,9 +17217,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, JS_VALUE_GET_INT(op2)); sp--; } else { - sf->cur_pc = pc; - if (js_binary_logic_slow(ctx, sp, opcode)) - goto exception; + sp[-2] = JS_NULL; sp--; } } @@ -17386,9 +17233,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, JS_VALUE_GET_INT(op2)); sp--; } else { - sf->cur_pc = pc; - if (js_binary_logic_slow(ctx, sp, opcode)) - goto exception; + sp[-2] = JS_NULL; sp--; } } @@ -17404,9 +17249,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, JS_VALUE_GET_INT(op2)); sp--; } else { - sf->cur_pc = pc; - if (js_binary_logic_slow(ctx, sp, opcode)) - goto exception; + sp[-2] = JS_NULL; sp--; } }