Index: src/x64/full-codegen-x64.cc |
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc |
index 0011bcacd7c12916fcdd021574fe981cd8e4536d..ef8c15087fe292930e5322509eccd9be17b7b4cd 100644 |
--- a/src/x64/full-codegen-x64.cc |
+++ b/src/x64/full-codegen-x64.cc |
@@ -1381,17 +1381,9 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, |
__ bind(&fast); |
} |
- // All extension objects were empty and it is safe to use a global |
- // load IC call. |
- __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
- __ Move(LoadDescriptor::NameRegister(), proxy->var()->name()); |
- __ Move(LoadDescriptor::SlotRegister(), |
- SmiFromSlot(proxy->VariableFeedbackSlot())); |
- |
- ContextualMode mode = (typeof_state == INSIDE_TYPEOF) |
- ? NOT_CONTEXTUAL |
- : CONTEXTUAL; |
- CallLoadIC(mode); |
+ // All extension objects were empty and it is safe to use a normal global |
+ // load machinery. |
+ EmitGlobalVariableLoad(proxy, typeof_state); |
} |
@@ -1457,7 +1449,23 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy, |
} |
-void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
+void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, |
+ TypeofState typeof_state) { |
+ Variable* var = proxy->var(); |
+ DCHECK(var->IsUnallocatedOrGlobalSlot() || |
+ (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL)); |
+ __ Move(LoadDescriptor::NameRegister(), var->name()); |
+ __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
+ __ Move(LoadDescriptor::SlotRegister(), |
+ SmiFromSlot(proxy->VariableFeedbackSlot())); |
+ // Inside typeof use a regular load, not a contextual load, to avoid |
+ // a reference error. |
+ CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL); |
+} |
+ |
+ |
+void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, |
+ TypeofState typeof_state) { |
// Record position before possible IC call. |
SetExpressionPosition(proxy); |
PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); |
@@ -1469,11 +1477,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
case VariableLocation::GLOBAL: |
case VariableLocation::UNALLOCATED: { |
Comment cmnt(masm_, "[ Global variable"); |
- __ Move(LoadDescriptor::NameRegister(), var->name()); |
- __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
- __ Move(LoadDescriptor::SlotRegister(), |
- SmiFromSlot(proxy->VariableFeedbackSlot())); |
- CallGlobalLoadIC(var->name()); |
+ EmitGlobalVariableLoad(proxy, typeof_state); |
context()->Plug(rax); |
break; |
} |
@@ -1481,6 +1485,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
case VariableLocation::PARAMETER: |
case VariableLocation::LOCAL: |
case VariableLocation::CONTEXT: { |
+ DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state); |
Comment cmnt(masm_, var->IsContextSlot() ? "[ Context slot" |
: "[ Stack slot"); |
if (var->binding_needs_init()) { |
@@ -1553,11 +1558,15 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
Label done, slow; |
// Generate code for loading from variables potentially shadowed |
// by eval-introduced variables. |
- EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done); |
+ EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done); |
__ bind(&slow); |
__ Push(rsi); // Context. |
__ Push(var->name()); |
- __ CallRuntime(Runtime::kLoadLookupSlot, 2); |
+ Runtime::FunctionId function_id = |
+ typeof_state == NOT_INSIDE_TYPEOF |
+ ? Runtime::kLoadLookupSlot |
+ : Runtime::kLoadLookupSlotNoReferenceError; |
+ __ CallRuntime(function_id, 2); |
__ bind(&done); |
context()->Plug(rax); |
break; |
@@ -5112,45 +5121,6 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
} |
-void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
- VariableProxy* proxy = expr->AsVariableProxy(); |
- DCHECK(!context()->IsEffect()); |
- DCHECK(!context()->IsTest()); |
- |
- if (proxy != NULL && proxy->var()->IsUnallocatedOrGlobalSlot()) { |
- Comment cmnt(masm_, "[ Global variable"); |
- __ Move(LoadDescriptor::NameRegister(), proxy->name()); |
- __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
- __ Move(LoadDescriptor::SlotRegister(), |
- SmiFromSlot(proxy->VariableFeedbackSlot())); |
- // Use a regular load, not a contextual load, to avoid a reference |
- // error. |
- CallLoadIC(NOT_CONTEXTUAL); |
- PrepareForBailout(expr, TOS_REG); |
- context()->Plug(rax); |
- } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
- Comment cmnt(masm_, "[ Lookup slot"); |
- Label done, slow; |
- |
- // Generate code for loading from variables potentially shadowed |
- // by eval-introduced variables. |
- EmitDynamicLookupFastCase(proxy, INSIDE_TYPEOF, &slow, &done); |
- |
- __ bind(&slow); |
- __ Push(rsi); |
- __ Push(proxy->name()); |
- __ CallRuntime(Runtime::kLoadLookupSlotNoReferenceError, 2); |
- PrepareForBailout(expr, TOS_REG); |
- __ bind(&done); |
- |
- context()->Plug(rax); |
- } else { |
- // This expression cannot throw a reference error at the top level. |
- VisitInDuplicateContext(expr); |
- } |
-} |
- |
- |
void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, |
Expression* sub_expr, |
Handle<String> check) { |