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

102
quickjs.c
View File

@@ -18238,15 +18238,47 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
CASE(OP_get_field):
{
JSValue val;
JSValue val, obj;
JSAtom atom;
JSObject *p;
JSProperty *pr;
JSShapeProperty *prs;
atom = get_u32(pc);
pc += 4;
obj = sp[-1];
if (likely(JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT)) {
p = JS_VALUE_GET_OBJ(obj);
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_GetProperty(ctx, sp[-1], atom);
val = JS_GetPropertyInternal(ctx, obj, atom, sp[-1], 0);
if (unlikely(JS_IsException(val)))
goto exception;
}
JS_FreeValue(ctx, sp[-1]);
sp[-1] = val;
}
@@ -18254,15 +18286,47 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
CASE(OP_get_field2):
{
JSValue val;
JSValue val, obj;
JSAtom atom;
JSObject *p;
JSProperty *pr;
JSShapeProperty *prs;
atom = get_u32(pc);
pc += 4;
obj = sp[-1];
if (likely(JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT)) {
p = JS_VALUE_GET_OBJ(obj);
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_GetProperty(ctx, sp[-1], atom);
val = JS_GetPropertyInternal(ctx, obj, atom, sp[-1], 0);
if (unlikely(JS_IsException(val)))
goto exception;
}
*sp++ = val;
}
BREAK;
@@ -18270,18 +18334,42 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
CASE(OP_put_field):
{
int ret;
JSValue obj;
JSAtom atom;
JSObject *p;
JSProperty *pr;
JSShapeProperty *prs;
atom = get_u32(pc);
pc += 4;
sf->cur_pc = pc;
ret = JS_SetPropertyInternal(ctx, sp[-2], atom, sp[-1], sp[-2],
obj = sp[-2];
if (likely(JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT)) {
p = JS_VALUE_GET_OBJ(obj);
prs = find_own_property(&pr, p, atom);
if (!prs)
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, sp[-2]);
JS_FreeValue(ctx, obj);
sp -= 2;
if (unlikely(ret < 0))
goto exception;
}
}
BREAK;
CASE(OP_private_symbol):