Revert "Reland "[builtins] Port getting property from Proxy to CSA""

This reverts commit 15ef03cbf3.

Reason for revert: Found the following bugs

Bug: chromium:752846, chromium:752712, chromium:752850

Original change's description:
> Reland "[builtins] Port getting property from Proxy to CSA"
> 
> This reland is after fix in [heap] Delete wrong DCHECK.
> It includes moving ProxyGetProperty to its own stub to reduce
> binary size.
> 
> This is a reland of 47a97aa53b
> Original change's description:
> > [builtins] Port getting property from Proxy to CSA
> > 
> > Bug: v8:6559, v8:6557
> > Change-Id: If6c51f5483adb73ddd2495cede5d85e887a3c298
> > Reviewed-on: https://chromium-review.googlesource.com/589212
> > Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
> > Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
> > Commit-Queue: Maya Lekova <mslekova@google.com>
> > Cr-Commit-Position: refs/heads/master@{#47113}
> 
> Bug: v8:6559, v8:6557
> Change-Id: I76acd97ba1acb62b7e7983db1741441d997050f0
> Reviewed-on: https://chromium-review.googlesource.com/600215
> Commit-Queue: Maya Lekova <mslekova@google.com>
> Reviewed-by: Jakob Gruber <jgruber@chromium.org>
> Reviewed-by: Franziska Hinkelmann <franzih@chromium.org>
> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#47159}

TBR=jkummerow@chromium.org,mstarzinger@chromium.org,franzih@chromium.org,jgruber@chromium.org,ishell@chromium.org,bmeurer@chromium.org,mslekova@google.com

# Not skipping CQ checks because original CL landed > 1 day ago.

Change-Id: I51bef25a031b02cf4deab11282473acae57f1ed3
Reviewed-on: https://chromium-review.googlesource.com/603708
Commit-Queue: Maya Lekova <mslekova@google.com>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47200}
This commit is contained in:
Maya Lekova 2017-08-07 12:23:41 +00:00 committed by Commit Bot
parent a704cc7932
commit ceb55494bd
18 changed files with 34 additions and 442 deletions

View File

@ -975,8 +975,6 @@ v8_source_set("v8_builtins_generators") {
"src/builtins/builtins-promise-gen.cc",
"src/builtins/builtins-promise-gen.h",
"src/builtins/builtins-proxy-gen.cc",
"src/builtins/builtins-proxy-helpers-gen.cc",
"src/builtins/builtins-proxy-helpers-gen.h",
"src/builtins/builtins-regexp-gen.cc",
"src/builtins/builtins-regexp-gen.h",
"src/builtins/builtins-sharedarraybuffer-gen.cc",

View File

@ -802,7 +802,6 @@ namespace internal {
TFJ(ProxyConstructor, 0) \
TFJ(ProxyConstructor_ConstructStub, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
TFS(ProxyGetProperty, kProxy, kName, kReceiverValue) \
\
/* Reflect */ \
ASM(ReflectApply) \

View File

@ -1,158 +0,0 @@
// 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.
#include "src/builtins/builtins-proxy-helpers-gen.h"
#include "src/builtins/builtins-utils-gen.h"
namespace v8 {
namespace internal {
TF_BUILTIN(ProxyGetProperty, ProxyAssembler) {
Node* context = Parameter(Descriptor::kContext);
Node* proxy = Parameter(Descriptor::kProxy);
Node* name = Parameter(Descriptor::kName);
Node* receiver = Parameter(Descriptor::kReceiverValue);
CSA_ASSERT(this, IsJSProxy(proxy));
// 1. Assert: IsPropertyKey(P) is true.
CSA_ASSERT(this, IsName(name));
Label throw_proxy_handler_revoked(this, Label::kDeferred),
trap_undefined(this), no_target_desc(this, Label::kDeferred),
trap_not_callable(this, Label::kDeferred);
// 2. Let handler be O.[[ProxyHandler]].
Node* handler = LoadObjectField(proxy, JSProxy::kHandlerOffset);
// 3. If handler is null, throw a TypeError exception.
GotoIf(IsNull(handler), &throw_proxy_handler_revoked);
// 4. Assert: Type(handler) is Object.
CSA_ASSERT(this, IsJSReceiver(handler));
// 5. Let target be O.[[ProxyTarget]].
Node* target = LoadObjectField(proxy, JSProxy::kTargetOffset);
// 6. Let trap be ? GetMethod(handler, "get").
// 7. If trap is undefined, then (see 7.a below).
Handle<Name> trap_name = factory()->get_string();
Node* trap = GetMethod(context, handler, trap_name, &trap_undefined);
GotoIfNot(IsCallable(trap), &trap_not_callable);
// 8. Let trapResult be ? Call(trap, handler, « target, P, Receiver »).
Node* trap_result = CallJS(CodeFactory::Call(isolate()), context, trap,
handler, target, name, receiver);
// 9. Let targetDesc be ? target.[[GetOwnProperty]](P).
Label return_result(this);
CheckGetTrapResult(context, target, proxy, name, trap_result, &return_result,
&no_target_desc);
BIND(&return_result);
{
// 11. Return trapResult.
Return(trap_result);
}
BIND(&no_target_desc);
{
CallRuntime(Runtime::kCheckProxyGetTrapResult, context, name, target,
trap_result);
Return(trap_result);
}
BIND(&trap_undefined);
{
// 7.a. Return ? target.[[Get]](P, Receiver).
Return(CallRuntime(Runtime::kGetPropertyWithReceiver, context, target, name,
receiver));
}
BIND(&throw_proxy_handler_revoked);
{ ThrowTypeError(context, MessageTemplate::kProxyRevoked, "get"); }
BIND(&trap_not_callable);
{
ThrowTypeError(context, MessageTemplate::kPropertyNotFunction, trap,
StringConstant("get"), receiver);
}
}
void ProxyAssembler::CheckGetTrapResult(Node* context, Node* target,
Node* proxy, Node* name,
Node* trap_result, Label* check_passed,
Label* if_bailout) {
Node* map = LoadMap(target);
VARIABLE(var_value, MachineRepresentation::kTagged);
VARIABLE(var_details, MachineRepresentation::kWord32);
VARIABLE(var_raw_value, MachineRepresentation::kTagged);
Label if_found_value(this, Label::kDeferred);
Node* instance_type = LoadInstanceType(target);
TryGetOwnProperty(context, proxy, target, map, instance_type, name,
&if_found_value, &var_value, &var_details, &var_raw_value,
check_passed, if_bailout);
BIND(&if_found_value);
{
Label throw_non_configurable_data(this, Label::kDeferred),
throw_non_configurable_accessor(this, Label::kDeferred),
check_accessor(this), check_data(this);
// 10. If targetDesc is not undefined and targetDesc.[[Configurable]] is
// false, then:
GotoIfNot(IsSetWord32(var_details.value(),
PropertyDetails::kAttributesDontDeleteMask),
check_passed);
// 10.a. If IsDataDescriptor(targetDesc) is true and
// targetDesc.[[Writable]] is false, then:
BranchIfAccessorPair(var_raw_value.value(), &check_accessor, &check_data);
BIND(&check_data);
{
Node* read_only = IsSetWord32(var_details.value(),
PropertyDetails::kAttributesReadOnlyMask);
GotoIfNot(read_only, check_passed);
// 10.a.i. If SameValue(trapResult, targetDesc.[[Value]]) is false,
// throw a TypeError exception.
GotoIfNot(SameValue(trap_result, var_value.value()),
&throw_non_configurable_data);
Goto(check_passed);
}
BIND(&check_accessor);
{
// 10.b. If IsAccessorDescriptor(targetDesc) is true and
// targetDesc.[[Get]] is undefined, then:
Node* accessor_pair = var_raw_value.value();
Node* getter =
LoadObjectField(accessor_pair, AccessorPair::kGetterOffset);
// Here we check for null as well because if the getter was never
// defined it's set as null.
GotoIfNot(Word32Or(IsUndefined(getter), IsNull(getter)), check_passed);
// 10.b.i. If trapResult is not undefined, throw a TypeError exception.
GotoIfNot(IsUndefined(trap_result), &throw_non_configurable_accessor);
Goto(check_passed);
}
BIND(&throw_non_configurable_data);
{
ThrowTypeError(context, MessageTemplate::kProxyGetNonConfigurableData,
name, var_value.value(), trap_result);
}
BIND(&throw_non_configurable_accessor);
{
ThrowTypeError(context, MessageTemplate::kProxyGetNonConfigurableAccessor,
name, trap_result);
}
}
}
} // namespace internal
} // namespace v8

View File

@ -1,38 +0,0 @@
// 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.
#ifndef V8_BUILTINS_BUILTINS_PROXY_HELPERS_GEN_H_
#define V8_BUILTINS_BUILTINS_PROXY_HELPERS_GEN_H_
#include "src/code-stub-assembler.h"
namespace v8 {
namespace internal {
using compiler::Node;
class ProxyAssembler : public CodeStubAssembler {
public:
explicit ProxyAssembler(compiler::CodeAssemblerState* state)
: CodeStubAssembler(state) {}
void BranchIfAccessorPair(Node* value, Label* if_accessor_pair,
Label* if_not_accessor_pair) {
GotoIf(TaggedIsSmi(value), if_not_accessor_pair);
Branch(IsAccessorPair(value), if_accessor_pair, if_not_accessor_pair);
}
// ES6 section 9.5.8 [[Get]] ( P, Receiver )
Node* ProxyGetProperty(Node* context, Node* proxy, Node* name,
Node* receiver);
protected:
void CheckGetTrapResult(Node* context, Node* target, Node* proxy, Node* name,
Node* trap_result, Label* if_not_found,
Label* if_bailout);
};
} // namespace internal
} // namespace v8
#endif // V8_BUILTINS_BUILTINS_PROXY_HELPERS_GEN_H_

View File

@ -6033,16 +6033,6 @@ void CodeStubAssembler::TryGetOwnProperty(
Node* context, Node* receiver, Node* object, Node* map, Node* instance_type,
Node* unique_name, Label* if_found_value, Variable* var_value,
Label* if_not_found, Label* if_bailout) {
TryGetOwnProperty(context, receiver, object, map, instance_type, unique_name,
if_found_value, var_value, nullptr, nullptr, if_not_found,
if_bailout);
}
void CodeStubAssembler::TryGetOwnProperty(
Node* context, Node* receiver, Node* object, Node* map, Node* instance_type,
Node* unique_name, Label* if_found_value, Variable* var_value,
Variable* var_details, Variable* var_raw_value, Label* if_not_found,
Label* if_bailout) {
DCHECK_EQ(MachineRepresentation::kTagged, var_value->rep());
Comment("TryGetOwnProperty");
@ -6051,11 +6041,8 @@ void CodeStubAssembler::TryGetOwnProperty(
Label if_found_fast(this), if_found_dict(this), if_found_global(this);
VARIABLE(local_var_details, MachineRepresentation::kWord32);
if (!var_details) {
var_details = &local_var_details;
}
Variable* vars[] = {var_value, var_details};
VARIABLE(var_details, MachineRepresentation::kWord32);
Variable* vars[] = {var_value, &var_details};
Label if_found(this, 2, vars);
TryLookupProperty(object, map, instance_type, unique_name, &if_found_fast,
@ -6067,14 +6054,14 @@ void CodeStubAssembler::TryGetOwnProperty(
Node* name_index = var_entry.value();
LoadPropertyFromFastObject(object, map, descriptors, name_index,
var_details, var_value);
&var_details, var_value);
Goto(&if_found);
}
BIND(&if_found_dict);
{
Node* dictionary = var_meta_storage.value();
Node* entry = var_entry.value();
LoadPropertyFromNameDictionary(dictionary, entry, var_details, var_value);
LoadPropertyFromNameDictionary(dictionary, entry, &var_details, var_value);
Goto(&if_found);
}
BIND(&if_found_global);
@ -6082,17 +6069,14 @@ void CodeStubAssembler::TryGetOwnProperty(
Node* dictionary = var_meta_storage.value();
Node* entry = var_entry.value();
LoadPropertyFromGlobalDictionary(dictionary, entry, var_details, var_value,
LoadPropertyFromGlobalDictionary(dictionary, entry, &var_details, var_value,
if_not_found);
Goto(&if_found);
}
// Here we have details and value which could be an accessor.
BIND(&if_found);
{
if (var_raw_value) {
var_raw_value->Bind(var_value->value());
}
Node* value = CallGetterIfAccessor(var_value->value(), var_details->value(),
Node* value = CallGetterIfAccessor(var_value->value(), var_details.value(),
context, receiver, if_bailout);
var_value->Bind(value);
Goto(if_found_value);

View File

@ -1304,11 +1304,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
Node* instance_type, Node* unique_name,
Label* if_found, Variable* var_value,
Label* if_not_found, Label* if_bailout);
void TryGetOwnProperty(Node* context, Node* receiver, Node* object, Node* map,
Node* instance_type, Node* unique_name,
Label* if_found, Variable* var_value,
Variable* var_details, Variable* var_raw_value,
Label* if_not_found, Label* if_bailout);
Node* GetProperty(Node* context, Node* receiver, Handle<Name> name) {
return GetProperty(context, receiver, HeapConstant(name));

View File

@ -261,8 +261,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase(
Label constant(this), field(this), normal(this, Label::kDeferred),
interceptor(this, Label::kDeferred), nonexistent(this),
accessor(this, Label::kDeferred), proxy(this, Label::kDeferred),
global(this, Label::kDeferred);
accessor(this, Label::kDeferred), global(this, Label::kDeferred);
GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kField)), &field);
GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kConstant)),
@ -277,8 +276,6 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase(
GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kAccessor)),
&accessor);
GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kProxy)), &proxy);
Branch(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kGlobal)), &global,
&interceptor);
@ -365,13 +362,6 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase(
exit_point->Return(CallJS(callable, p->context, getter, p->receiver));
}
BIND(&proxy);
{
exit_point->ReturnCallStub(
Builtins::CallableFor(isolate(), Builtins::kProxyGetProperty),
p->context, holder, p->name, p->receiver);
}
BIND(&global);
{
CSA_ASSERT(this, IsPropertyCell(holder));
@ -1481,15 +1471,15 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map,
Comment("key is unique name");
Label if_found_on_receiver(this), if_property_dictionary(this),
lookup_prototype_chain(this), special_receiver(this);
lookup_prototype_chain(this);
VARIABLE(var_details, MachineRepresentation::kWord32);
VARIABLE(var_value, MachineRepresentation::kTagged);
// Receivers requiring non-standard accesses (interceptors, access
// checks, strings and string wrappers) are handled in the runtime.
// checks, strings and string wrappers, proxies) are handled in the runtime.
GotoIf(Int32LessThanOrEqual(instance_type,
Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)),
&special_receiver);
slow);
// Check if the receiver has fast or slow properties.
Node* bitfield3 = LoadMapBitField3(receiver_map);
@ -1610,16 +1600,6 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map,
BIND(&return_undefined);
Return(UndefinedConstant());
}
BIND(&special_receiver);
{
GotoIfNot(Word32Equal(instance_type, Int32Constant(JS_PROXY_TYPE)), slow);
direct_exit.ReturnCallStub(
Builtins::CallableFor(isolate(), Builtins::kProxyGetProperty),
p->context, receiver /*holder is the same as receiver*/, p->name,
receiver);
}
}
//////////////////// Stub cache access helpers.

View File

@ -53,11 +53,6 @@ Handle<Smi> LoadHandler::LoadAccessor(Isolate* isolate, int descriptor) {
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> LoadHandler::LoadProxy(Isolate* isolate) {
int config = KindBits::encode(kProxy);
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> LoadHandler::LoadApiGetter(Isolate* isolate, int descriptor) {
int config = KindBits::encode(kConstant) | IsAccessorInfoBits::encode(true) |
DescriptorBits::encode(descriptor);

View File

@ -25,10 +25,9 @@ class LoadHandler {
kConstant,
kAccessor,
kInterceptor,
kProxy,
kNonExistent
};
class KindBits : public BitField<Kind, 0, 4> {};
class KindBits : public BitField<Kind, 0, 3> {};
// Defines whether access rights check should be done on receiver object.
// Applicable to named property kinds only when loading value from prototype
@ -114,9 +113,6 @@ class LoadHandler {
// Creates a Smi-handler for calling a getter on a fast object.
static inline Handle<Smi> LoadAccessor(Isolate* isolate, int descriptor);
// Creates a Smi-handler for calling a getter on a proxy.
static inline Handle<Smi> LoadProxy(Isolate* isolate);
// Creates a Smi-handler for loading an Api getter property from fast object.
static inline Handle<Smi> LoadApiGetter(Isolate* isolate, int descriptor);

View File

@ -772,7 +772,7 @@ namespace {
template <bool fill_array = true>
int InitPrototypeChecks(Isolate* isolate, Handle<Map> receiver_map,
Handle<JSReceiver> holder, Handle<Name> name,
Handle<JSObject> holder, Handle<Name> name,
Handle<FixedArray> array, int first_index) {
if (!holder.is_null() && holder->map() == *receiver_map) return 0;
@ -813,8 +813,7 @@ int InitPrototypeChecks(Isolate* isolate, Handle<Map> receiver_map,
: PrototypeIterator::END_AT_NULL;
for (PrototypeIterator iter(receiver_map, end); !iter.IsAtEnd();
iter.Advance()) {
Handle<JSReceiver> current =
PrototypeIterator::GetCurrent<JSReceiver>(iter);
Handle<JSObject> current = PrototypeIterator::GetCurrent<JSObject>(iter);
if (holder.is_identical_to(current)) break;
Handle<Map> current_map(current->map(), isolate);
@ -851,7 +850,7 @@ int InitPrototypeChecks(Isolate* isolate, Handle<Map> receiver_map,
// Returns -1 if the handler has to be compiled or the number of prototype
// checks otherwise.
int GetPrototypeCheckCount(Isolate* isolate, Handle<Map> receiver_map,
Handle<JSReceiver> holder, Handle<Name> name) {
Handle<JSObject> holder, Handle<Name> name) {
return InitPrototypeChecks<false>(isolate, receiver_map, holder, name,
Handle<FixedArray>(), 0);
}
@ -861,7 +860,7 @@ enum class HolderCellRequest {
kHolder,
};
Handle<WeakCell> HolderCell(Isolate* isolate, Handle<JSReceiver> holder,
Handle<WeakCell> HolderCell(Isolate* isolate, Handle<JSObject> holder,
Handle<Name> name, HolderCellRequest request) {
if (request == HolderCellRequest::kGlobalPropertyCell) {
DCHECK(holder->IsJSGlobalObject());
@ -878,7 +877,7 @@ Handle<WeakCell> HolderCell(Isolate* isolate, Handle<JSReceiver> holder,
} // namespace
Handle<Object> LoadIC::LoadFromPrototype(Handle<Map> receiver_map,
Handle<JSReceiver> holder,
Handle<JSObject> holder,
Handle<Name> name,
Handle<Smi> smi_handler) {
int checks_count =
@ -926,7 +925,7 @@ Handle<Object> LoadIC::LoadFromPrototype(Handle<Map> receiver_map,
Handle<Object> LoadIC::LoadFullChain(Handle<Map> receiver_map,
Handle<Object> holder, Handle<Name> name,
Handle<Smi> smi_handler) {
Handle<JSReceiver> end; // null handle
Handle<JSObject> end; // null handle
int checks_count = GetPrototypeCheckCount(isolate(), receiver_map, end, name);
DCHECK_LE(0, checks_count);
@ -977,7 +976,8 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) {
}
Handle<Object> code;
if (lookup->state() == LookupIterator::ACCESS_CHECK) {
if (lookup->state() == LookupIterator::JSPROXY ||
lookup->state() == LookupIterator::ACCESS_CHECK) {
code = slow_stub();
} else if (!lookup->IsFound()) {
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNonexistentDH);
@ -1101,13 +1101,8 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) {
}
Handle<Map> map = receiver_map();
Handle<JSObject> holder;
bool receiver_is_holder;
if (lookup->state() != LookupIterator::JSPROXY) {
holder = lookup->GetHolder<JSObject>();
receiver_is_holder = receiver.is_identical_to(holder);
}
Handle<JSObject> holder = lookup->GetHolder<JSObject>();
bool receiver_is_holder = receiver.is_identical_to(holder);
switch (lookup->state()) {
case LookupIterator::INTERCEPTOR: {
Handle<Smi> smi_handler = LoadHandler::LoadInterceptor(isolate());
@ -1268,16 +1263,8 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) {
case LookupIterator::INTEGER_INDEXED_EXOTIC:
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadIntegerIndexedExoticDH);
return LoadHandler::LoadNonExistent(isolate());
case LookupIterator::JSPROXY: {
Handle<JSProxy> holder_proxy = lookup->GetHolder<JSProxy>();
bool receiver_is_holder_proxy = receiver.is_identical_to(holder_proxy);
Handle<Smi> smi_handler = LoadHandler::LoadProxy(isolate());
if (receiver_is_holder_proxy) {
return smi_handler;
}
return LoadFromPrototype(map, holder_proxy, lookup->name(), smi_handler);
}
case LookupIterator::ACCESS_CHECK:
case LookupIterator::JSPROXY:
case LookupIterator::NOT_FOUND:
case LookupIterator::TRANSITION:
UNREACHABLE();
@ -1734,7 +1721,6 @@ Handle<Object> StoreIC::StoreTransition(Handle<Map> receiver_map,
int checks_count =
GetPrototypeCheckCount(isolate(), receiver_map, holder, name);
DCHECK_LE(0, checks_count);
DCHECK(!receiver_map->IsJSGlobalObjectMap());

View File

@ -283,7 +283,7 @@ class LoadIC : public IC {
// by given Smi-handler that encoded a load from the holder.
// Can be used only if GetPrototypeCheckCount() returns non negative value.
Handle<Object> LoadFromPrototype(Handle<Map> receiver_map,
Handle<JSReceiver> holder, Handle<Name> name,
Handle<JSObject> holder, Handle<Name> name,
Handle<Smi> smi_handler);
// Creates a data handler that represents a load of a non-existent property.

View File

@ -1105,22 +1105,6 @@ MaybeHandle<Object> JSProxy::GetProperty(Isolate* isolate,
ASSIGN_RETURN_ON_EXCEPTION(
isolate, trap_result,
Execution::Call(isolate, trap, handler, arraysize(args), args), Object);
MaybeHandle<Object> result =
JSProxy::CheckGetTrapResult(isolate, name, target, trap_result);
if (result.is_null()) {
return result;
}
// 11. Return trap_result
return trap_result;
}
// static
MaybeHandle<Object> JSProxy::CheckGetTrapResult(Isolate* isolate,
Handle<Name> name,
Handle<JSReceiver> target,
Handle<Object> trap_result) {
// 9. Let targetDesc be ? target.[[GetOwnProperty]](P).
PropertyDescriptor target_desc;
Maybe<bool> target_found =
@ -1157,7 +1141,8 @@ MaybeHandle<Object> JSProxy::CheckGetTrapResult(Isolate* isolate,
Object);
}
}
return isolate->factory()->undefined_value();
// 11. Return trap_result
return trap_result;
}
@ -12622,12 +12607,7 @@ Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
} else {
maybe_prototype =
handle(map->GetPrototypeChainRootMap(isolate)->prototype(), isolate);
if (!maybe_prototype->IsJSReceiver()) return Handle<Cell>::null();
}
if (maybe_prototype->IsJSProxy()) {
Handle<Cell> cell = isolate->factory()->NewCell(
handle(Smi::FromInt(Map::kPrototypeChainValid), isolate));
return cell;
if (!maybe_prototype->IsJSObject()) return Handle<Cell>::null();
}
Handle<JSObject> prototype = Handle<JSObject>::cast(maybe_prototype);
// Ensure the prototype is registered with its own prototypes so its cell
@ -12652,16 +12632,11 @@ Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
}
// static
Handle<WeakCell> Map::GetOrCreatePrototypeWeakCell(Handle<JSReceiver> prototype,
Handle<WeakCell> Map::GetOrCreatePrototypeWeakCell(Handle<JSObject> prototype,
Isolate* isolate) {
DCHECK(!prototype.is_null());
if (prototype->IsJSProxy()) {
Handle<WeakCell> cell = isolate->factory()->NewWeakCell(prototype);
return cell;
}
Handle<PrototypeInfo> proto_info =
GetOrCreatePrototypeInfo(Handle<JSObject>::cast(prototype), isolate);
GetOrCreatePrototypeInfo(prototype, isolate);
Object* maybe_cell = proto_info->weak_cell();
// Return existing cell if it's already created.
if (maybe_cell->IsWeakCell()) {

View File

@ -6299,11 +6299,6 @@ class JSProxy: public JSReceiver {
Isolate* isolate, Handle<JSProxy> proxy, Handle<Name> name,
Handle<Object> receiver, bool* was_found);
static MaybeHandle<Object> CheckGetTrapResult(Isolate* isolate,
Handle<Name> name,
Handle<JSReceiver> target,
Handle<Object> trap_result);
// ES6 9.5.9
MUST_USE_RESULT static Maybe<bool> SetProperty(Handle<JSProxy> proxy,
Handle<Name> name,

View File

@ -319,7 +319,7 @@ class Map : public HeapObject {
// Returns a WeakCell object containing given prototype. The cell is cached
// in PrototypeInfo which is created lazily.
static Handle<WeakCell> GetOrCreatePrototypeWeakCell(
Handle<JSReceiver> prototype, Isolate* isolate);
Handle<JSObject> prototype, Isolate* isolate);
Map* FindRootMap() const;
Map* FindFieldOwner(int descriptor) const;

View File

@ -46,30 +46,5 @@ RUNTIME_FUNCTION(Runtime_JSProxyRevoke) {
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(Runtime_GetPropertyWithReceiver) {
HandleScope scope(isolate);
DCHECK_EQ(3, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, holder, 0);
CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 2);
LookupIterator it =
LookupIterator::PropertyOrElement(isolate, receiver, name, holder);
RETURN_RESULT_OR_FAILURE(isolate, Object::GetProperty(&it));
}
RUNTIME_FUNCTION(Runtime_CheckProxyGetTrapResult) {
HandleScope scope(isolate);
DCHECK_EQ(3, args.length());
CONVERT_ARG_HANDLE_CHECKED(Name, name, 0);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, target, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, trap_result, 2);
RETURN_RESULT_OR_FAILURE(
isolate, JSProxy::CheckGetTrapResult(isolate, name, target, trap_result));
}
} // namespace internal
} // namespace v8

View File

@ -459,13 +459,11 @@ namespace internal {
F(PromiseStatus, 1, 1) \
F(ReportPromiseReject, 2, 1)
#define FOR_EACH_INTRINSIC_PROXY(F) \
F(IsJSProxy, 1, 1) \
F(JSProxyGetTarget, 1, 1) \
F(JSProxyGetHandler, 1, 1) \
F(JSProxyRevoke, 1, 1) \
F(GetPropertyWithReceiver, 2, 1) \
F(CheckProxyGetTrapResult, 2, 1)
#define FOR_EACH_INTRINSIC_PROXY(F) \
F(IsJSProxy, 1, 1) \
F(JSProxyGetTarget, 1, 1) \
F(JSProxyGetHandler, 1, 1) \
F(JSProxyRevoke, 1, 1)
#define FOR_EACH_INTRINSIC_REGEXP(F) \
F(IsRegExp, 1, 1) \

View File

@ -207,8 +207,6 @@
'builtins/builtins-promise-gen.cc',
'builtins/builtins-promise-gen.h',
'builtins/builtins-proxy-gen.cc',
'builtins/builtins-proxy-helpers-gen.cc',
'builtins/builtins-proxy-helpers-gen.h',
'builtins/builtins-regexp-gen.cc',
'builtins/builtins-regexp-gen.h',
'builtins/builtins-sharedarraybuffer-gen.cc',

View File

@ -35,12 +35,6 @@
assertThrows("proxy.property", Error);
})();
(function testThrowOnTrapNotCallable() {
var handler = new Proxy({}, {get: 'not_callable' });
var proxy = new Proxy({}, handler);
assertThrows("proxy.property", Error);
})();
(function testFallback() {
var target = {property:"value"};
var proxy = new Proxy(target, {});
@ -131,83 +125,3 @@
"[[Get]](iterator, next)"
], log);
})();
(function testGetterWithSideEffect() {
var obj = {
key: 0
}
assertEquals(obj.key, 0);
var p = new Proxy(obj, {});
var q = new Proxy(p, {
get(target, name) {
if (name != 'key') return Reflect.get(target, name);
target.key++;
return target.key;
}
});
assertEquals(0, p.key);
// Assert the trap is not called twice.
assertEquals(1, q.key);
})();
(function testReceiverWithTrap() {
var obj = {};
var p = new Proxy(obj, {
get(target, name, receiver) {
if (name != 'key') return Reflect.get(target, name);
assertSame(target, obj);
assertSame(receiver, p);
return 42;
}
});
assertEquals(42, p.key);
})();
(function testReceiverWithoutTrap() {
var obj = {
get prop() {
assertSame(this, p);
return 42;
}
};
var p = new Proxy(obj, {});
assertEquals(42, p.prop);
})();
(function testGetPropertyDetailsBailout() {
var obj = {
}
var p = new Proxy(obj, {
getOwnPropertyDescriptor() {
throw new Error('Error from proxy getOwnPropertyDescriptor trap');
}
});
var q = new Proxy(p, {
get(target, name) {
return 42;
}
});
assertThrows(function(){ q.prop }, Error,
'Error from proxy getOwnPropertyDescriptor trap');
})();
(function testGetPropertyDetailsBailout2() {
var obj = {};
Object.defineProperty(obj, 'prop', {
value: 53,
configurable: false
});
var p = new Proxy(obj, {});
var q = new Proxy(p, {
get(target, name) {
return 42;
}
});
assertThrows(function(){ q.prop }, TypeError,
"'get' on proxy: property 'prop' is a read-only and non-configurable data" +
" property on the proxy target but the proxy did not return its actual" +
" value (expected '53' but got '42')");
})();