diff --git a/quickjs.c b/quickjs.c index 7d8ce86..9c04108 100644 --- a/quickjs.c +++ b/quickjs.c @@ -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; - - sf->cur_pc = pc; - val = JS_GetProperty(ctx, sp[-1], atom); - if (unlikely(JS_IsException(val))) - goto exception; + + 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_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; - - sf->cur_pc = pc; - val = JS_GetProperty(ctx, sp[-1], atom); - if (unlikely(JS_IsException(val))) - goto exception; + + 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_GetPropertyInternal(ctx, obj, atom, sp[-1], 0); + if (unlikely(JS_IsException(val))) + goto exception; + } *sp++ = val; } BREAK; @@ -18270,17 +18334,41 @@ 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], - JS_PROP_THROW_STRICT); - JS_FreeValue(ctx, sp[-2]); - sp -= 2; - if (unlikely(ret < 0)) - goto exception; + 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, obj); + sp -= 2; + if (unlikely(ret < 0)) + goto exception; + } + } BREAK;