Index: src/code-stub-assembler.cc |
diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc |
index a92daad4979715e5a27d6af92e7d70fba13b4434..5fc710df1184a76ab0f86081896a899a3ab5bc13 100644 |
--- a/src/code-stub-assembler.cc |
+++ b/src/code-stub-assembler.cc |
@@ -2694,6 +2694,11 @@ Node* CodeStubAssembler::IsJSObject(Node* object) { |
Int32Constant(FIRST_JS_RECEIVER_TYPE)); |
} |
+Node* CodeStubAssembler::IsJSGlobalProxy(Node* object) { |
+ return Word32Equal(LoadInstanceType(object), |
+ Int32Constant(JS_GLOBAL_PROXY_TYPE)); |
+} |
+ |
Node* CodeStubAssembler::IsMap(Node* map) { |
return HasInstanceType(map, MAP_TYPE); |
} |
@@ -5647,11 +5652,12 @@ void CodeStubAssembler::HandleLoadICProtoHandler( |
Bind(&validity_cell_check_done); |
Node* smi_handler = LoadObjectField(handler, LoadHandler::kSmiHandlerOffset); |
CSA_ASSERT(TaggedIsSmi(smi_handler)); |
+ Node* handler_flags = SmiUntag(smi_handler); |
Label check_prototypes(this); |
- GotoUnless(IsSetWord<LoadHandler::DoNegativeLookupOnReceiverBits>( |
- SmiUntag(smi_handler)), |
- &check_prototypes); |
+ GotoUnless( |
+ IsSetWord<LoadHandler::DoNegativeLookupOnReceiverBits>(handler_flags), |
+ &check_prototypes); |
{ |
// We have a dictionary receiver, do a negative lookup check. |
NameDictionaryNegativeLookup(p->receiver, p->name, miss); |
@@ -5685,8 +5691,40 @@ void CodeStubAssembler::HandleLoadICProtoHandler( |
Bind(&array_handler); |
{ |
Node* length = SmiUntag(maybe_holder_cell); |
- BuildFastLoop(MachineType::PointerRepresentation(), |
- IntPtrConstant(LoadHandler::kFirstPrototypeIndex), length, |
+ |
+ Variable start_index(this, MachineType::PointerRepresentation()); |
+ start_index.Bind(IntPtrConstant(LoadHandler::kFirstPrototypeIndex)); |
+ |
+ Label can_access(this); |
+ GotoUnless( |
+ IsSetWord<LoadHandler::DoAccessCheckOnReceiverBits>(handler_flags), |
+ &can_access); |
+ { |
+ // Skip this entry of a handler. |
+ start_index.Bind(IntPtrConstant(LoadHandler::kFirstPrototypeIndex + 1)); |
+ |
+ int offset = |
+ FixedArray::OffsetOfElementAt(LoadHandler::kFirstPrototypeIndex); |
+ Node* expected_native_context = |
+ LoadWeakCellValue(LoadObjectField(handler, offset), miss); |
+ CSA_ASSERT(IsNativeContext(expected_native_context)); |
+ |
+ Node* native_context = LoadNativeContext(p->context); |
+ GotoIf(WordEqual(expected_native_context, native_context), &can_access); |
+ // If the receiver is not a JSGlobalProxy then we miss. |
+ GotoUnless(IsJSGlobalProxy(p->receiver), miss); |
+ // For JSGlobalProxy receiver try to compare security tokens of current |
+ // and expected native contexts. |
+ Node* expected_token = LoadContextElement(expected_native_context, |
+ Context::SECURITY_TOKEN_INDEX); |
+ Node* current_token = |
+ LoadContextElement(native_context, Context::SECURITY_TOKEN_INDEX); |
+ Branch(WordEqual(expected_token, current_token), &can_access, miss); |
+ } |
+ Bind(&can_access); |
+ |
+ BuildFastLoop(MachineType::PointerRepresentation(), start_index.value(), |
+ length, |
[this, p, handler, miss](CodeStubAssembler*, Node* current) { |
Node* prototype_cell = LoadFixedArrayElement( |
handler, current, 0, INTPTR_PARAMETERS); |
@@ -5729,6 +5767,7 @@ void CodeStubAssembler::CheckPrototype(Node* prototype_cell, Node* name, |
Bind(&if_dictionary_object); |
{ |
+ CSA_ASSERT(IsDictionaryMap(LoadMap(maybe_prototype))); |
NameDictionaryNegativeLookup(maybe_prototype, name, miss); |
Goto(&done); |
} |