Commit b19a1baf authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[ic] Fix storing to JSGlobalProxy having JSProxy in prototype chain.

Bug: chromium:764219
Change-Id: Ic68111e49da508aba255b1c651a85b2b00e62947
Reviewed-on: https://chromium-review.googlesource.com/718108Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48534}
parent caead4da
......@@ -758,7 +758,7 @@ void AccessorAssembler::HandleStoreICProtoHandler(
// IC dispatchers rely on these assumptions to be held.
STATIC_ASSERT(FixedArray::kLengthOffset ==
StoreHandler::kTransitionCellOffset);
StoreHandler::kTransitionOrHolderCellOffset);
DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kSmiHandlerIndex),
StoreHandler::kSmiHandlerOffset);
DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kValidityCellIndex),
......@@ -779,18 +779,16 @@ void AccessorAssembler::HandleStoreICProtoHandler(
Node* smi_or_code = LoadObjectField(handler, StoreHandler::kSmiHandlerOffset);
Node* maybe_transition_cell =
LoadObjectField(handler, StoreHandler::kTransitionCellOffset);
LoadObjectField(handler, StoreHandler::kTransitionOrHolderCellOffset);
Label array_handler(this), tuple_handler(this);
Branch(TaggedIsSmi(maybe_transition_cell), &array_handler, &tuple_handler);
VARIABLE(var_transition, MachineRepresentation::kTagged);
Label if_transition(this), if_transition_to_constant(this),
if_store_normal(this), if_store_global_proxy(this), if_proxy(this),
do_store(this);
VARIABLE(var_transition_map_or_holder, MachineRepresentation::kTagged);
Label do_store(this), if_transition_map(this), if_holder_object(this);
BIND(&tuple_handler);
{
Node* transition = LoadWeakCellValue(maybe_transition_cell, miss);
var_transition.Bind(transition);
var_transition_map_or_holder.Bind(transition);
Goto(&do_store);
}
......@@ -831,32 +829,27 @@ void AccessorAssembler::HandleStoreICProtoHandler(
},
1, INTPTR_PARAMETERS, IndexAdvanceMode::kPost);
Node* maybe_transition_cell =
LoadFixedArrayElement(handler, StoreHandler::kTransitionCellIndex);
Node* maybe_transition_cell = LoadFixedArrayElement(
handler, StoreHandler::kTransitionMapOrHolderCellIndex);
Node* transition = LoadWeakCellValue(maybe_transition_cell, miss);
var_transition.Bind(transition);
var_transition_map_or_holder.Bind(transition);
Goto(&do_store);
}
BIND(&do_store);
{
Branch(SmiEqual(smi_or_code, SmiConstant(StoreHandler::kProxy)), &if_proxy,
&if_transition);
Node* transition = var_transition_map_or_holder.value();
Branch(IsMap(transition), &if_transition_map, &if_holder_object);
}
BIND(&if_proxy);
BIND(&if_transition_map);
{
Node* proxy = var_transition.value();
HandleStoreToProxy(p, proxy, miss, support_elements);
}
Label if_transition_to_constant(this), if_store_normal(this);
BIND(&if_transition);
{
Node* holder = p->receiver;
Node* transition = var_transition.value();
Node* transition_map = var_transition_map_or_holder.value();
GotoIfNot(IsMap(transition), &if_store_global_proxy);
GotoIf(IsDeprecatedMap(transition), miss);
GotoIf(IsDeprecatedMap(transition_map), miss);
if (support_elements == kSupportElements) {
Label if_smi_handler(this);
......@@ -867,7 +860,7 @@ void AccessorAssembler::HandleStoreICProtoHandler(
StoreTransitionDescriptor descriptor(isolate());
TailCallStub(descriptor, code_handler, p->context, p->receiver, p->name,
transition, p->value, p->slot, p->vector);
transition_map, p->value, p->slot, p->vector);
BIND(&if_smi_handler);
}
......@@ -882,13 +875,12 @@ void AccessorAssembler::HandleStoreICProtoHandler(
GotoIf(WordEqual(handler_kind,
IntPtrConstant(StoreHandler::kTransitionToConstant)),
&if_transition_to_constant);
// This case is already handled above.
CSA_ASSERT(this,
WordNotEqual(handler_kind,
IntPtrConstant(StoreHandler::kStoreGlobalProxy)));
WordEqual(handler_kind,
IntPtrConstant(StoreHandler::kTransitionToField)));
// Handle transitioning field stores.
HandleStoreICSmiHandlerCase(handler_word, holder, p->value, transition,
HandleStoreICSmiHandlerCase(handler_word, holder, p->value, transition_map,
miss);
BIND(&if_transition_to_constant);
......@@ -901,7 +893,7 @@ void AccessorAssembler::HandleStoreICProtoHandler(
IntPtrAdd(scaled_descriptor,
IntPtrConstant(DescriptorArray::kFirstIndex +
DescriptorArray::kEntryValueIndex));
Node* descriptors = LoadMapDescriptors(transition);
Node* descriptors = LoadMapDescriptors(transition_map);
CSA_ASSERT(
this, UintPtrLessThan(descriptor,
LoadAndUntagFixedArrayBaseLength(descriptors)));
......@@ -909,7 +901,7 @@ void AccessorAssembler::HandleStoreICProtoHandler(
Node* constant = LoadFixedArrayElement(descriptors, value_index);
GotoIf(WordNotEqual(p->value, constant), miss);
StoreMap(p->receiver, transition);
StoreMap(p->receiver, transition_map);
Return(p->value);
}
......@@ -948,10 +940,28 @@ void AccessorAssembler::HandleStoreICProtoHandler(
p->receiver, p->name, p->value);
}
}
}
BIND(&if_holder_object);
{
Label if_store_global_proxy(this);
Node* holder = var_transition_map_or_holder.value();
Node* smi_handler = smi_or_code;
CSA_ASSERT(this, TaggedIsSmi(smi_handler));
Node* handler_word = SmiUntag(smi_handler);
Node* handler_kind = DecodeWord<StoreHandler::KindBits>(handler_word);
GotoIf(WordEqual(handler_kind,
IntPtrConstant(StoreHandler::kStoreGlobalProxy)),
&if_store_global_proxy);
CSA_ASSERT(this,
WordEqual(handler_kind, IntPtrConstant(StoreHandler::kProxy)));
HandleStoreToProxy(p, holder, miss, support_elements);
BIND(&if_store_global_proxy);
{
ExitPoint direct_exit(this);
StoreGlobalIC_PropertyCellCase(transition, p->value, &direct_exit, miss);
StoreGlobalIC_PropertyCellCase(holder, p->value, &direct_exit, miss);
}
}
}
......
......@@ -196,15 +196,15 @@ Handle<Smi> StoreHandler::TransitionToConstant(Isolate* isolate,
// static
WeakCell* StoreHandler::GetTransitionCell(Object* handler) {
if (handler->IsTuple3()) {
STATIC_ASSERT(kTransitionCellOffset == Tuple3::kValue1Offset);
STATIC_ASSERT(kTransitionOrHolderCellOffset == Tuple3::kValue1Offset);
WeakCell* cell = WeakCell::cast(Tuple3::cast(handler)->value1());
DCHECK(!cell->cleared());
return cell;
}
DCHECK(handler->IsFixedArray());
WeakCell* cell =
WeakCell::cast(FixedArray::cast(handler)->get(kTransitionCellIndex));
WeakCell* cell = WeakCell::cast(
FixedArray::cast(handler)->get(kTransitionMapOrHolderCellIndex));
DCHECK(!cell->cleared());
return cell;
}
......
......@@ -314,7 +314,7 @@ Handle<Object> StoreHandler::StoreTransition(Isolate* isolate,
factory->NewFixedArray(kFirstPrototypeIndex + checks_count, TENURED));
handler_array->set(kSmiHandlerIndex, *smi_handler);
handler_array->set(kValidityCellIndex, *validity_cell);
handler_array->set(kTransitionCellIndex, *transition_cell);
handler_array->set(kTransitionMapOrHolderCellIndex, *transition_cell);
InitPrototypeChecks(isolate, receiver_map, holder, name, handler_array,
kFirstPrototypeIndex);
return handler_array;
......@@ -363,7 +363,7 @@ Handle<Object> StoreHandler::StoreProxy(Isolate* isolate,
factory->NewFixedArray(kFirstPrototypeIndex + checks_count, TENURED));
handler_array->set(kSmiHandlerIndex, *smi_handler);
handler_array->set(kValidityCellIndex, *validity_cell);
handler_array->set(kTransitionCellIndex, *holder_cell);
handler_array->set(kTransitionMapOrHolderCellIndex, *holder_cell);
InitPrototypeChecks(isolate, receiver_map, proxy, name, handler_array,
kFirstPrototypeIndex);
return handler_array;
......
......@@ -229,7 +229,7 @@ class StoreHandler {
// The layout of an Tuple3 handler representing a transitioning store
// when prototype chain checks do not include non-existing lookups or access
// checks.
static const int kTransitionCellOffset = Tuple3::kValue1Offset;
static const int kTransitionOrHolderCellOffset = Tuple3::kValue1Offset;
static const int kSmiHandlerOffset = Tuple3::kValue2Offset;
static const int kValidityCellOffset = Tuple3::kValue3Offset;
......@@ -241,7 +241,7 @@ class StoreHandler {
// when prototype chain checks include non-existing lookups and access checks.
static const int kSmiHandlerIndex = 0;
static const int kValidityCellIndex = 1;
static const int kTransitionCellIndex = 2;
static const int kTransitionMapOrHolderCellIndex = 2;
static const int kFirstPrototypeIndex = 3;
// Creates a Smi-handler for storing a field to fast object.
......
......@@ -811,14 +811,14 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore(
BIND(&tuple3);
{
var_transition_cell.Bind(LoadObjectField(
maybe_handler, StoreHandler::kTransitionCellOffset));
maybe_handler, StoreHandler::kTransitionOrHolderCellOffset));
Goto(&check_key);
}
BIND(&fixedarray);
{
var_transition_cell.Bind(LoadFixedArrayElement(
maybe_handler, StoreHandler::kTransitionCellIndex));
maybe_handler, StoreHandler::kTransitionMapOrHolderCellIndex));
Goto(&check_key);
}
......
......@@ -22,3 +22,14 @@
f(this);
f(this);
})();
(function() {
function f(o) {
o.z = 153;
};
Object.setPrototypeOf(this, new Proxy({get z(){}}, {}));
f({});
f(this);
f(this);
})();
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