inlined fast path for get_field, get_field2 and put_field

This commit is contained in:
Fabrice Bellard
2025-10-03 15:41:21 +02:00
parent 2c90110287
commit 57f8ec0099

126
quickjs.c
View File

@@ -18238,15 +18238,47 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
CASE(OP_get_field): CASE(OP_get_field):
{ {
JSValue val; JSValue val, obj;
JSAtom atom; JSAtom atom;
JSObject *p;
JSProperty *pr;
JSShapeProperty *prs;
atom = get_u32(pc); atom = get_u32(pc);
pc += 4; pc += 4;
sf->cur_pc = pc; obj = sp[-1];
val = JS_GetProperty(ctx, sp[-1], atom); if (likely(JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT)) {
if (unlikely(JS_IsException(val))) p = JS_VALUE_GET_OBJ(obj);
goto exception; for(;;) {
prs = find_own_property(&pr, p, atom);
if (prs) {
/* found */
if (unlikely(prs->flags & JS_PROP_TMASK))
goto get_field_slow_path;
val = JS_DupValue(ctx, pr->u.value);
break;
}
if (unlikely(p->is_exotic)) {
/* XXX: should avoid the slow path for arrays
and typed arrays by ensuring that 'prop' is
not numeric */
obj = JS_MKPTR(JS_TAG_OBJECT, p);
goto get_field_slow_path;
}
p = p->shape->proto;
if (!p) {
val = JS_UNDEFINED;
break;
}
}
} else {
get_field_slow_path:
sf->cur_pc = pc;
val = JS_GetPropertyInternal(ctx, obj, atom, sp[-1], 0);
if (unlikely(JS_IsException(val)))
goto exception;
}
JS_FreeValue(ctx, sp[-1]); JS_FreeValue(ctx, sp[-1]);
sp[-1] = val; sp[-1] = val;
} }
@@ -18254,15 +18286,47 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
CASE(OP_get_field2): CASE(OP_get_field2):
{ {
JSValue val; JSValue val, obj;
JSAtom atom; JSAtom atom;
JSObject *p;
JSProperty *pr;
JSShapeProperty *prs;
atom = get_u32(pc); atom = get_u32(pc);
pc += 4; pc += 4;
sf->cur_pc = pc; obj = sp[-1];
val = JS_GetProperty(ctx, sp[-1], atom); if (likely(JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT)) {
if (unlikely(JS_IsException(val))) p = JS_VALUE_GET_OBJ(obj);
goto exception; for(;;) {
prs = find_own_property(&pr, p, atom);
if (prs) {
/* found */
if (unlikely(prs->flags & JS_PROP_TMASK))
goto get_field2_slow_path;
val = JS_DupValue(ctx, pr->u.value);
break;
}
if (unlikely(p->is_exotic)) {
/* XXX: should avoid the slow path for arrays
and typed arrays by ensuring that 'prop' is
not numeric */
obj = JS_MKPTR(JS_TAG_OBJECT, p);
goto get_field2_slow_path;
}
p = p->shape->proto;
if (!p) {
val = JS_UNDEFINED;
break;
}
}
} else {
get_field2_slow_path:
sf->cur_pc = pc;
val = JS_GetPropertyInternal(ctx, obj, atom, sp[-1], 0);
if (unlikely(JS_IsException(val)))
goto exception;
}
*sp++ = val; *sp++ = val;
} }
BREAK; BREAK;
@@ -18270,17 +18334,41 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
CASE(OP_put_field): CASE(OP_put_field):
{ {
int ret; int ret;
JSValue obj;
JSAtom atom; JSAtom atom;
JSObject *p;
JSProperty *pr;
JSShapeProperty *prs;
atom = get_u32(pc); atom = get_u32(pc);
pc += 4; pc += 4;
sf->cur_pc = pc;
ret = JS_SetPropertyInternal(ctx, sp[-2], atom, sp[-1], sp[-2], obj = sp[-2];
JS_PROP_THROW_STRICT); if (likely(JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT)) {
JS_FreeValue(ctx, sp[-2]); p = JS_VALUE_GET_OBJ(obj);
sp -= 2; prs = find_own_property(&pr, p, atom);
if (unlikely(ret < 0)) if (!prs)
goto exception; goto put_field_slow_path;
if (likely((prs->flags & (JS_PROP_TMASK | JS_PROP_WRITABLE |
JS_PROP_LENGTH)) == JS_PROP_WRITABLE)) {
/* fast path */
set_value(ctx, &pr->u.value, sp[-1]);
} else {
goto put_field_slow_path;
}
JS_FreeValue(ctx, obj);
sp -= 2;
} else {
put_field_slow_path:
sf->cur_pc = pc;
ret = JS_SetPropertyInternal(ctx, obj, atom, sp[-1], obj,
JS_PROP_THROW_STRICT);
JS_FreeValue(ctx, obj);
sp -= 2;
if (unlikely(ret < 0))
goto exception;
}
} }
BREAK; BREAK;