Index: src/code-stub-assembler.cc |
diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc |
index dca216718e89fc48262b0a06d194f30773042135..c0380bb8c1df22cff8ce5801e9300d4e4aa5b380 100644 |
--- a/src/code-stub-assembler.cc |
+++ b/src/code-stub-assembler.cc |
@@ -1502,6 +1502,10 @@ void CodeStubAssembler::DecrementCounter(StatsCounter* counter, int delta) { |
} |
} |
+void CodeStubAssembler::Use(Label* label) { |
+ GotoIf(Word32Equal(Int32Constant(0), Int32Constant(1)), label); |
+} |
+ |
void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex, |
Variable* var_index, Label* if_keyisunique, |
Label* if_bailout) { |
@@ -2175,6 +2179,114 @@ template void CodeStubAssembler::NumberDictionaryLookup<SeededNumberDictionary>( |
template void CodeStubAssembler::NumberDictionaryLookup< |
UnseededNumberDictionary>(Node*, Node*, Label*, Variable*, Label*); |
+void CodeStubAssembler::TryPrototypeChainLookup( |
+ Node* receiver, Node* key, LookupInHolder& lookup_property_in_holder, |
+ LookupInHolder& lookup_element_in_holder, Label* if_end, |
+ Label* if_bailout) { |
+ // Ensure receiver is JSReceiver, otherwise bailout. |
+ Label if_objectisnotsmi(this); |
+ Branch(WordIsSmi(receiver), if_bailout, &if_objectisnotsmi); |
+ Bind(&if_objectisnotsmi); |
+ |
+ Node* map = LoadMap(receiver); |
+ Node* instance_type = LoadMapInstanceType(map); |
+ { |
+ Label if_objectisreceiver(this); |
+ STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
+ Branch(Int32GreaterThanOrEqual(instance_type, |
+ Int32Constant(FIRST_JS_RECEIVER_TYPE)), |
+ &if_objectisreceiver, if_bailout); |
+ Bind(&if_objectisreceiver); |
+ } |
+ |
+ Variable var_index(this, MachineRepresentation::kWord32); |
+ |
+ Label if_keyisindex(this), if_iskeyunique(this); |
+ TryToName(key, &if_keyisindex, &var_index, &if_iskeyunique, if_bailout); |
+ |
+ Bind(&if_iskeyunique); |
+ { |
+ Variable var_holder(this, MachineRepresentation::kTagged); |
+ Variable var_holder_map(this, MachineRepresentation::kTagged); |
+ Variable var_holder_instance_type(this, MachineRepresentation::kWord8); |
+ |
+ Variable* merged_variables[] = {&var_holder, &var_holder_map, |
+ &var_holder_instance_type}; |
+ Label loop(this, arraysize(merged_variables), merged_variables); |
+ var_holder.Bind(receiver); |
+ var_holder_map.Bind(map); |
+ var_holder_instance_type.Bind(instance_type); |
+ Goto(&loop); |
+ Bind(&loop); |
+ { |
+ Node* holder_map = var_holder_map.value(); |
+ Node* holder_instance_type = var_holder_instance_type.value(); |
+ |
+ Label next_proto(this); |
+ lookup_property_in_holder(receiver, var_holder.value(), holder_map, |
+ holder_instance_type, key, &next_proto, |
+ if_bailout); |
+ Bind(&next_proto); |
+ |
+ // Bailout if it can be an integer indexed exotic case. |
+ GotoIf( |
+ Word32Equal(holder_instance_type, Int32Constant(JS_TYPED_ARRAY_TYPE)), |
+ if_bailout); |
+ |
+ Node* proto = LoadMapPrototype(holder_map); |
+ |
+ Label if_not_null(this); |
+ Branch(WordEqual(proto, NullConstant()), if_end, &if_not_null); |
+ Bind(&if_not_null); |
+ |
+ Node* map = LoadMap(proto); |
+ Node* instance_type = LoadMapInstanceType(map); |
+ |
+ var_holder.Bind(proto); |
+ var_holder_map.Bind(map); |
+ var_holder_instance_type.Bind(instance_type); |
+ Goto(&loop); |
+ } |
+ } |
+ Bind(&if_keyisindex); |
+ { |
+ Variable var_holder(this, MachineRepresentation::kTagged); |
+ Variable var_holder_map(this, MachineRepresentation::kTagged); |
+ Variable var_holder_instance_type(this, MachineRepresentation::kWord8); |
+ |
+ Variable* merged_variables[] = {&var_holder, &var_holder_map, |
+ &var_holder_instance_type}; |
+ Label loop(this, arraysize(merged_variables), merged_variables); |
+ var_holder.Bind(receiver); |
+ var_holder_map.Bind(map); |
+ var_holder_instance_type.Bind(instance_type); |
+ Goto(&loop); |
+ Bind(&loop); |
+ { |
+ Label next_proto(this); |
+ lookup_element_in_holder(receiver, var_holder.value(), |
+ var_holder_map.value(), |
+ var_holder_instance_type.value(), |
+ var_index.value(), &next_proto, if_bailout); |
+ Bind(&next_proto); |
+ |
+ Node* proto = LoadMapPrototype(var_holder_map.value()); |
+ |
+ Label if_not_null(this); |
+ Branch(WordEqual(proto, NullConstant()), if_end, &if_not_null); |
+ Bind(&if_not_null); |
+ |
+ Node* map = LoadMap(proto); |
+ Node* instance_type = LoadMapInstanceType(map); |
+ |
+ var_holder.Bind(proto); |
+ var_holder_map.Bind(map); |
+ var_holder_instance_type.Bind(instance_type); |
+ Goto(&loop); |
+ } |
+ } |
+} |
+ |
Node* CodeStubAssembler::OrdinaryHasInstance(Node* context, Node* callable, |
Node* object) { |
Variable var_result(this, MachineRepresentation::kTagged); |