Commit db09c2a6 authored by jgruber's avatar jgruber Committed by Commit Bot

[proxy] Fix invalid call to getter in [[Get/Set/Has]]

Fixes the implementation of step 9 in the Proxy's internal [[Get]]
method:

Let targetDesc be ? target.[[GetOwnProperty]](P)

If P is an accessor, this should not result in a call to the getter.
Likewise in [[Set]] and [[Has]].

https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver

Bug: chromium:776338
Change-Id: I2652ffab2b3e4c38de00a82b8419192fdc768951
Reviewed-on: https://chromium-review.googlesource.com/732897Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48825}
parent 8dfebbc3
...@@ -494,7 +494,7 @@ void ProxiesCodeStubAssembler::CheckGetSetTrapResult( ...@@ -494,7 +494,7 @@ void ProxiesCodeStubAssembler::CheckGetSetTrapResult(
Node* instance_type = LoadInstanceType(target); Node* instance_type = LoadInstanceType(target);
TryGetOwnProperty(context, target, target, map, instance_type, name, TryGetOwnProperty(context, target, target, map, instance_type, name,
&if_found_value, &var_value, &var_details, &var_raw_value, &if_found_value, &var_value, &var_details, &var_raw_value,
check_passed, &check_in_runtime); check_passed, &check_in_runtime, kReturnAccessorPair);
BIND(&if_found_value); BIND(&if_found_value);
{ {
...@@ -592,7 +592,7 @@ void ProxiesCodeStubAssembler::CheckHasTrapResult(Node* context, Node* target, ...@@ -592,7 +592,7 @@ void ProxiesCodeStubAssembler::CheckHasTrapResult(Node* context, Node* target,
Node* instance_type = LoadInstanceType(target); Node* instance_type = LoadInstanceType(target);
TryGetOwnProperty(context, target, target, target_map, instance_type, name, TryGetOwnProperty(context, target, target, target_map, instance_type, name,
&if_found_value, &var_value, &var_details, &var_raw_value, &if_found_value, &var_value, &var_details, &var_raw_value,
check_passed, if_bailout); check_passed, if_bailout, kReturnAccessorPair);
// 9.b. If targetDesc is not undefined, then (see 9.b.i. below). // 9.b. If targetDesc is not undefined, then (see 9.b.i. below).
BIND(&if_found_value); BIND(&if_found_value);
......
...@@ -6761,7 +6761,7 @@ void CodeStubAssembler::TryGetOwnProperty( ...@@ -6761,7 +6761,7 @@ void CodeStubAssembler::TryGetOwnProperty(
Label* if_not_found, Label* if_bailout) { Label* if_not_found, Label* if_bailout) {
TryGetOwnProperty(context, receiver, object, map, instance_type, unique_name, TryGetOwnProperty(context, receiver, object, map, instance_type, unique_name,
if_found_value, var_value, nullptr, nullptr, if_not_found, if_found_value, var_value, nullptr, nullptr, if_not_found,
if_bailout); if_bailout, kCallJSGetter);
} }
void CodeStubAssembler::TryGetOwnProperty( void CodeStubAssembler::TryGetOwnProperty(
......
...@@ -1486,7 +1486,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { ...@@ -1486,7 +1486,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
Label* if_found, Variable* var_value, Label* if_found, Variable* var_value,
Variable* var_details, Variable* var_raw_value, Variable* var_details, Variable* var_raw_value,
Label* if_not_found, Label* if_bailout, Label* if_not_found, Label* if_bailout,
GetOwnPropertyMode mode = kCallJSGetter); GetOwnPropertyMode mode);
Node* GetProperty(Node* context, Node* receiver, Handle<Name> name) { Node* GetProperty(Node* context, Node* receiver, Handle<Name> name) {
return GetProperty(context, receiver, HeapConstant(name)); return GetProperty(context, receiver, HeapConstant(name));
......
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const obj = {};
Object.defineProperty(obj, 'value', {
enumerable: true,
configurable: true,
get: assertUnreachable,
set: assertUnreachable,
});
let called_get = false;
let called_has = false;
let called_set = false;
const has = function(target, prop) {
assertEquals('value', prop);
called_has = true;
return false; // Need to return false to trigger GetOwnProperty call.
};
const get = function(target, prop) {
assertEquals('value', prop);
called_get = true;
return 'yep';
};
const set = function(target, prop, value) {
assertEquals('value', prop);
called_set = true;
return true; // Need to return true to trigger GetOwnProperty call.
};
const proxy = new Proxy(obj, { has, get, set });
assertFalse(Reflect.has(proxy, 'value'));
assertTrue(called_has);
assertEquals('nope', proxy.value = 'nope');
assertTrue(called_set);
assertEquals('yep', proxy.value);
assertTrue(called_get);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment