set_value(ctx, &pr->u.value, val);
return 0;
}
+ /* XXX: add a fast path where the property exists and the object
+ is not exotic. Otherwise do as in OP_put_ref_value and remove
+ JS_PROP_NO_ADD which is no longer necessary */
flags = JS_PROP_THROW_STRICT;
if (is_strict_mode(ctx))
flags |= JS_PROP_NO_ADD;
CASE(OP_get_ref_value):
{
JSValue val;
+ JSAtom atom;
+ int ret;
+
+ atom = JS_ValueToAtom(ctx, sp[-1]);
+ if (atom == JS_ATOM_NULL)
+ goto exception;
if (unlikely(JS_IsUndefined(sp[-2]))) {
- JSAtom atom = JS_ValueToAtom(ctx, sp[-1]);
- if (atom != JS_ATOM_NULL) {
- JS_ThrowReferenceErrorNotDefined(ctx, atom);
+ JS_ThrowReferenceErrorNotDefined(ctx, atom);
+ JS_FreeAtom(ctx, atom);
+ goto exception;
+ }
+ ret = JS_HasProperty(ctx, sp[-2], atom);
+ if (unlikely(ret <= 0)) {
+ if (ret < 0) {
JS_FreeAtom(ctx, atom);
+ goto exception;
}
- goto exception;
+ if (is_strict_mode(ctx)) {
+ JS_ThrowReferenceErrorNotDefined(ctx, atom);
+ JS_FreeAtom(ctx, atom);
+ goto exception;
+ }
+ val = JS_UNDEFINED;
+ } else {
+ val = JS_GetProperty(ctx, sp[-2], atom);
}
- val = JS_GetPropertyValue(ctx, sp[-2],
- JS_DupValue(ctx, sp[-1]));
+ JS_FreeAtom(ctx, atom);
if (unlikely(JS_IsException(val)))
goto exception;
sp[0] = val;
CASE(OP_put_ref_value):
{
- int ret, flags;
- flags = JS_PROP_THROW_STRICT;
+ int ret;
+ JSAtom atom;
+ atom = JS_ValueToAtom(ctx, sp[-2]);
+ if (unlikely(atom == JS_ATOM_NULL))
+ goto exception;
if (unlikely(JS_IsUndefined(sp[-3]))) {
if (is_strict_mode(ctx)) {
- JSAtom atom = JS_ValueToAtom(ctx, sp[-2]);
- if (atom != JS_ATOM_NULL) {
- JS_ThrowReferenceErrorNotDefined(ctx, atom);
- JS_FreeAtom(ctx, atom);
- }
+ JS_ThrowReferenceErrorNotDefined(ctx, atom);
+ JS_FreeAtom(ctx, atom);
goto exception;
} else {
sp[-3] = JS_DupValue(ctx, ctx->global_obj);
}
- } else {
- if (is_strict_mode(ctx))
- flags |= JS_PROP_NO_ADD;
}
- ret = JS_SetPropertyValue(ctx, sp[-3], sp[-2], sp[-1], flags);
+ ret = JS_HasProperty(ctx, sp[-3], atom);
+ if (unlikely(ret <= 0)) {
+ if (unlikely(ret < 0)) {
+ JS_FreeAtom(ctx, atom);
+ goto exception;
+ }
+ if (is_strict_mode(ctx)) {
+ JS_ThrowReferenceErrorNotDefined(ctx, atom);
+ JS_FreeAtom(ctx, atom);
+ goto exception;
+ }
+ }
+ ret = JS_SetPropertyInternal(ctx, sp[-3], atom, sp[-1], sp[-3], JS_PROP_THROW_STRICT);
+ JS_FreeAtom(ctx, atom);
+ JS_FreeValue(ctx, sp[-2]);
JS_FreeValue(ctx, sp[-3]);
sp -= 3;
if (unlikely(ret < 0))
CASE(OP_with_delete_var):
CASE(OP_with_make_ref):
CASE(OP_with_get_ref):
- CASE(OP_with_get_ref_undef):
{
JSAtom atom;
int32_t diff;
}
switch (opcode) {
case OP_with_get_var:
- val = JS_GetProperty(ctx, obj, atom);
- if (unlikely(JS_IsException(val)))
- goto exception;
+ /* in Object Environment Records, GetBindingValue() calls HasProperty() */
+ ret = JS_HasProperty(ctx, obj, atom);
+ if (unlikely(ret <= 0)) {
+ if (ret < 0)
+ goto exception;
+ if (is_strict_mode(ctx)) {
+ JS_ThrowReferenceErrorNotDefined(ctx, atom);
+ goto exception;
+ }
+ val = JS_UNDEFINED;
+ } else {
+ val = JS_GetProperty(ctx, obj, atom);
+ if (unlikely(JS_IsException(val)))
+ goto exception;
+ }
set_value(ctx, &sp[-1], val);
break;
- case OP_with_put_var:
- /* XXX: check if strict mode */
+ case OP_with_put_var: /* used e.g. in for in/of */
+ /* in Object Environment Records, SetMutableBinding() calls HasProperty() */
+ ret = JS_HasProperty(ctx, obj, atom);
+ if (unlikely(ret <= 0)) {
+ if (ret < 0)
+ goto exception;
+ if (is_strict_mode(ctx)) {
+ JS_ThrowReferenceErrorNotDefined(ctx, atom);
+ goto exception;
+ }
+ }
ret = JS_SetPropertyInternal(ctx, obj, atom, sp[-2], obj,
JS_PROP_THROW_STRICT);
JS_FreeValue(ctx, sp[-1]);
break;
case OP_with_get_ref:
/* produce a pair object/method on the stack */
- val = JS_GetProperty(ctx, obj, atom);
- if (unlikely(JS_IsException(val)))
- goto exception;
- *sp++ = val;
- break;
- case OP_with_get_ref_undef:
- /* produce a pair undefined/function on the stack */
- val = JS_GetProperty(ctx, obj, atom);
- if (unlikely(JS_IsException(val)))
+ /* in Object Environment Records, GetBindingValue() calls HasProperty() */
+ ret = JS_HasProperty(ctx, obj, atom);
+ if (unlikely(ret < 0))
goto exception;
- JS_FreeValue(ctx, sp[-1]);
- sp[-1] = JS_UNDEFINED;
+ if (!ret) {
+ val = JS_UNDEFINED;
+ } else {
+ val = JS_GetProperty(ctx, obj, atom);
+ if (unlikely(JS_IsException(val)))
+ goto exception;
+ }
*sp++ = val;
break;
}
case OP_with_delete_var:
case OP_with_make_ref:
case OP_with_get_ref:
- case OP_with_get_ref_undef:
{
JSAtom atom;
int is_with;
break;
case OP_with_make_ref:
case OP_with_get_ref:
- case OP_with_get_ref_undef:
diff = get_u32(bc_buf + pos + 5);
if (ss_check(ctx, s, pos + 5 + diff, op, stack_len + 2, catch_pos))
goto fail;
test262/test/language/module-code/top-level-await/module-graphs-does-not-hang.js:10: TypeError: $DONE() not called
-test262/test/language/statements/with/get-binding-value-call-with-proxy-env.js:39: Test262Error: Actual [has:Object, get:Symbol(Symbol.unscopables), get:Object] and expected [has:Object, get:Symbol(Symbol.unscopables), has:Object, get:Object] should have the same contents.
-test262/test/language/statements/with/get-binding-value-idref-with-proxy-env.js:39: Test262Error: Actual [has:Object, get:Symbol(Symbol.unscopables), get:Object] and expected [has:Object, get:Symbol(Symbol.unscopables), has:Object, get:Object] should have the same contents.
-test262/test/language/statements/with/get-mutable-binding-binding-deleted-in-get-unscopables-strict-mode.js:21: Test262Error: Expected a ReferenceError to be thrown but no exception was thrown at all
test262/test/language/statements/with/set-mutable-binding-binding-deleted-with-typed-array-in-proto-chain.js:20: Test262Error: Expected SameValue(«[object Object]», «undefined») to be true
-test262/test/language/statements/with/set-mutable-binding-idref-compound-assign-with-proxy-env.js:58: Test262Error: Actual [has:p, get:Symbol(Symbol.unscopables), get:p, set:p, getOwnPropertyDescriptor:p, defineProperty:p] and expected [has:p, get:Symbol(Symbol.unscopables), has:p, get:p, has:p, set:p, getOwnPropertyDescriptor:p, defineProperty:p] should have the same contents.
-test262/test/language/statements/with/set-mutable-binding-idref-with-proxy-env.js:50: Test262Error: Actual [has:p, get:Symbol(Symbol.unscopables), set:p, getOwnPropertyDescriptor:p, defineProperty:p] and expected [has:p, get:Symbol(Symbol.unscopables), has:p, set:p, getOwnPropertyDescriptor:p, defineProperty:p] should have the same contents.