From: Fabrice Bellard Date: Sat, 13 Jun 2026 09:53:58 +0000 (+0200) Subject: inlined more cases for equality operators X-Git-Url: http://git.kaiwu.me/sitemap.xml?a=commitdiff_plain;h=445624b24bf04dff9370195a3ce92430320f3476;p=quickjs.git inlined more cases for equality operators --- diff --git a/quickjs.c b/quickjs.c index fa5a7a9..37cd209 100644 --- a/quickjs.c +++ b/quickjs.c @@ -15926,15 +15926,6 @@ BOOL JS_SameValueZero(JSContext *ctx, JSValueConst op1, JSValueConst op2) return js_same_value_zero(ctx, op1, op2); } -static no_inline int js_strict_eq_slow(JSContext *ctx, JSValue *sp, - BOOL is_neq) -{ - BOOL res; - res = js_strict_eq2(ctx, sp[-2], sp[-1], JS_EQ_STRICT); - sp[-2] = JS_NewBool(ctx, res ^ is_neq); - return 0; -} - static __exception int js_operator_in(JSContext *ctx, JSValue *sp) { JSValue op1, op2; @@ -20275,10 +20266,131 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, OP_CMP(OP_lte, <=, js_relational_slow(ctx, sp, opcode)); OP_CMP(OP_gt, >, js_relational_slow(ctx, sp, opcode)); OP_CMP(OP_gte, >=, js_relational_slow(ctx, sp, opcode)); - OP_CMP(OP_eq, ==, js_eq_slow(ctx, sp, 0)); - OP_CMP(OP_neq, !=, js_eq_slow(ctx, sp, 1)); - OP_CMP(OP_strict_eq, ==, js_strict_eq_slow(ctx, sp, 0)); - OP_CMP(OP_strict_neq, !=, js_strict_eq_slow(ctx, sp, 1)); + +#define OP_CMP_EQ(opcode, inv) \ + CASE(opcode): \ + { \ + JSValue op1, op2; \ + int res; \ + uint32_t tag1, tag2; \ + op1 = sp[-2]; \ + op2 = sp[-1]; \ + tag1 = JS_VALUE_GET_TAG(op1); \ + tag2 = JS_VALUE_GET_TAG(op2); \ + if (likely(tag1 == JS_TAG_INT)) { \ + if (tag2 == JS_TAG_INT) { \ + res = JS_VALUE_GET_INT(op1) == JS_VALUE_GET_INT(op2); \ + } else if (JS_TAG_IS_FLOAT64(tag2)) { \ + res = (JS_VALUE_GET_INT(op1) == JS_VALUE_GET_FLOAT64(op2)); \ + } else { \ + goto slow_eq ## inv; \ + } \ + } else if (JS_TAG_IS_FLOAT64(tag1)) { \ + if (tag2 == JS_TAG_INT) { \ + res = JS_VALUE_GET_FLOAT64(op1) == JS_VALUE_GET_INT(op2); \ + } else if (JS_TAG_IS_FLOAT64(tag2)) { \ + res = (JS_VALUE_GET_FLOAT64(op1) == JS_VALUE_GET_FLOAT64(op2)); \ + } else { \ + goto slow_eq ## inv; \ + } \ + } else if (tag1 == JS_TAG_OBJECT) { \ + if (tag2 == JS_TAG_NULL || tag2 == JS_TAG_UNDEFINED) { \ + JSObject *p = JS_VALUE_GET_OBJ(op1); \ + res = p->is_HTMLDDA; \ + JS_FreeValue(ctx, op1); \ + } else if (tag2 == JS_TAG_OBJECT) { \ + res = JS_VALUE_GET_OBJ(op1) == JS_VALUE_GET_OBJ(op2); \ + JS_FreeValue(ctx, op1); \ + JS_FreeValue(ctx, op2); \ + } else { \ + goto slow_eq ## inv; \ + } \ + } else if (tag1 == JS_TAG_NULL || tag1 == JS_TAG_UNDEFINED) { \ + if (tag2 == JS_TAG_NULL || tag2 == JS_TAG_UNDEFINED) { \ + res = TRUE; \ + } else if (tag2 == JS_TAG_OBJECT) { \ + JSObject *p = JS_VALUE_GET_OBJ(op2); \ + res = p->is_HTMLDDA; \ + JS_FreeValue(ctx, op2); \ + } else { \ + goto slow_eq ## inv; \ + } \ + } else if (tag1 == JS_TAG_STRING && tag2 == JS_TAG_STRING) { \ + res = js_string_eq(ctx, JS_VALUE_GET_STRING(op1), \ + JS_VALUE_GET_STRING(op2)); \ + JS_FreeValue(ctx, op1); \ + JS_FreeValue(ctx, op2); \ + } else { \ + slow_eq ## inv: \ + sf->cur_pc = pc; \ + if (js_eq_slow(ctx, sp, inv)) \ + goto exception; \ + sp--; \ + goto slow_eq_done ## inv; \ + } \ + sp[-2] = JS_NewBool(ctx, res ^ inv); \ + sp--; \ + slow_eq_done ## inv: ; \ + } \ + BREAK + + OP_CMP_EQ(OP_eq, 0); + OP_CMP_EQ(OP_neq, 1); + +#define OP_CMP_STRICT_EQ(opcode, inv) \ + CASE(opcode): \ + { \ + JSValue op1, op2; \ + int res; \ + uint32_t tag1, tag2; \ + op1 = sp[-2]; \ + op2 = sp[-1]; \ + tag1 = JS_VALUE_GET_TAG(op1); \ + tag2 = JS_VALUE_GET_TAG(op2); \ + if (likely(tag1 == JS_TAG_INT)) { \ + if (tag2 == JS_TAG_INT) { \ + res = JS_VALUE_GET_INT(op1) == JS_VALUE_GET_INT(op2); \ + } else if (JS_TAG_IS_FLOAT64(tag2)) { \ + res = (JS_VALUE_GET_INT(op1) == JS_VALUE_GET_FLOAT64(op2)); \ + } else { \ + JS_FreeValue(ctx, op2); \ + res = FALSE; \ + } \ + } else if (JS_TAG_IS_FLOAT64(tag1)) { \ + if (tag2 == JS_TAG_INT) { \ + res = JS_VALUE_GET_FLOAT64(op1) == JS_VALUE_GET_INT(op2); \ + } else if (JS_TAG_IS_FLOAT64(tag2)) { \ + res = (JS_VALUE_GET_FLOAT64(op1) == JS_VALUE_GET_FLOAT64(op2)); \ + } else { \ + JS_FreeValue(ctx, op2); \ + res = FALSE; \ + } \ + } else if (tag1 == JS_TAG_OBJECT) { \ + if (tag2 == JS_TAG_OBJECT) { \ + res = JS_VALUE_GET_OBJ(op1) == JS_VALUE_GET_OBJ(op2); \ + } else { \ + res = FALSE; \ + } \ + JS_FreeValue(ctx, op1); \ + JS_FreeValue(ctx, op2); \ + } else if (tag1 == JS_TAG_NULL || tag2 == JS_TAG_UNDEFINED) { \ + res = (tag1 == tag2); \ + JS_FreeValue(ctx, op2); \ + } else if (tag1 == JS_TAG_STRING && tag2 == JS_TAG_STRING) { \ + res = js_string_eq(ctx, JS_VALUE_GET_STRING(op1), \ + JS_VALUE_GET_STRING(op2)); \ + JS_FreeValue(ctx, op1); \ + JS_FreeValue(ctx, op2); \ + } else { \ + res = js_strict_eq2(ctx, op1, op2, JS_EQ_STRICT); \ + } \ + sp[-2] = JS_NewBool(ctx, res ^ inv); \ + sp--; \ + } \ + BREAK + + OP_CMP_STRICT_EQ(OP_strict_eq, 0); + OP_CMP_STRICT_EQ(OP_strict_neq, 1); CASE(OP_in): sf->cur_pc = pc;