Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index 640befc4a63ab60726caa13fedb5b2a83dd7146c..d5efbcd2cb38d0364bdccfe3c8728d6f62d09841 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -339,7 +339,7 @@ void HBasicBlock::RegisterPredecessor(HBasicBlock* pred) { |
DCHECK(IsLoopHeader() || first_ == NULL); |
HEnvironment* incoming_env = pred->last_environment(); |
if (IsLoopHeader()) { |
- DCHECK(phis()->length() == incoming_env->length()); |
+ DCHECK_EQ(phis()->length(), incoming_env->length()); |
for (int i = 0; i < phis_.length(); ++i) { |
phis_[i]->AddInput(incoming_env->values()->at(i)); |
} |
@@ -997,6 +997,13 @@ void HGraphBuilder::IfBuilder::Finish(HBasicBlock** then_continuation, |
} |
+void HGraphBuilder::IfBuilder::EndUnreachable() { |
+ if (captured_) return; |
+ Finish(); |
+ builder()->set_current_block(nullptr); |
+} |
+ |
+ |
void HGraphBuilder::IfBuilder::End() { |
if (captured_) return; |
Finish(); |
@@ -3134,6 +3141,17 @@ void HGraphBuilder::BuildCreateAllocationMemento( |
} |
+HInstruction* HGraphBuilder::BuildGetNativeContext() { |
+ // Get the global object, then the native context |
+ HValue* global_object = Add<HLoadNamedField>( |
+ context(), nullptr, |
+ HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
+ return Add<HLoadNamedField>(global_object, nullptr, |
+ HObjectAccess::ForObservableJSObjectOffset( |
+ GlobalObject::kNativeContextOffset)); |
+} |
+ |
+ |
HInstruction* HGraphBuilder::BuildGetNativeContext(HValue* closure) { |
// Get the global object, then the native context |
HInstruction* context = Add<HLoadNamedField>( |
@@ -3157,14 +3175,51 @@ HInstruction* HGraphBuilder::BuildGetScriptContext(int context_index) { |
} |
-HInstruction* HGraphBuilder::BuildGetNativeContext() { |
- // Get the global object, then the native context |
- HValue* global_object = Add<HLoadNamedField>( |
- context(), nullptr, |
- HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
- return Add<HLoadNamedField>(global_object, nullptr, |
- HObjectAccess::ForObservableJSObjectOffset( |
- GlobalObject::kNativeContextOffset)); |
+HValue* HGraphBuilder::BuildGetParentContext(HValue* depth, int depth_value) { |
+ HValue* script_context = context(); |
+ if (depth != NULL) { |
+ HValue* zero = graph()->GetConstant0(); |
+ |
+ Push(script_context); |
+ Push(depth); |
+ |
+ LoopBuilder loop(this); |
+ loop.BeginBody(2); // Drop script_context and depth from last environment |
+ // to appease live range building without simulates. |
+ depth = Pop(); |
+ script_context = Pop(); |
+ |
+ script_context = Add<HLoadNamedField>( |
+ script_context, nullptr, |
+ HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); |
+ depth = AddUncasted<HSub>(depth, graph()->GetConstant1()); |
+ depth->ClearFlag(HValue::kCanOverflow); |
+ |
+ IfBuilder if_break(this); |
+ if_break.If<HCompareNumericAndBranch, HValue*>(depth, zero, Token::EQ); |
+ if_break.Then(); |
+ { |
+ Push(script_context); // The result. |
+ loop.Break(); |
+ } |
+ if_break.Else(); |
+ { |
+ Push(script_context); |
+ Push(depth); |
+ } |
+ loop.EndBody(); |
+ if_break.End(); |
+ |
+ script_context = Pop(); |
+ } else if (depth_value > 0) { |
+ // Unroll the above loop. |
+ for (int i = 0; i < depth_value; i++) { |
+ script_context = Add<HLoadNamedField>( |
+ script_context, nullptr, |
+ HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); |
+ } |
+ } |
+ return script_context; |
} |