Index: src/ia32/full-codegen-ia32.cc |
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc |
index 733b72a0e1e33d03e68a888084f849f2ac406a38..535f2c2c63e7b68d50307d7465f4bda6cae68708 100644 |
--- a/src/ia32/full-codegen-ia32.cc |
+++ b/src/ia32/full-codegen-ia32.cc |
@@ -1344,18 +1344,9 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, |
__ bind(&fast); |
} |
- // All extension objects were empty and it is safe to use a global |
- // load IC call. |
- __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
- __ mov(LoadDescriptor::NameRegister(), proxy->var()->name()); |
- __ mov(LoadDescriptor::SlotRegister(), |
- Immediate(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); |
} |
@@ -1421,7 +1412,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)); |
+ __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
+ __ mov(LoadDescriptor::NameRegister(), var->name()); |
+ __ mov(LoadDescriptor::SlotRegister(), |
+ Immediate(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) { |
SetExpressionPosition(proxy); |
PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); |
Variable* var = proxy->var(); |
@@ -1432,11 +1439,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
case VariableLocation::GLOBAL: |
case VariableLocation::UNALLOCATED: { |
Comment cmnt(masm_, "[ Global variable"); |
- __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
- __ mov(LoadDescriptor::NameRegister(), var->name()); |
- __ mov(LoadDescriptor::SlotRegister(), |
- Immediate(SmiFromSlot(proxy->VariableFeedbackSlot()))); |
- CallGlobalLoadIC(var->name()); |
+ EmitGlobalVariableLoad(proxy, typeof_state); |
context()->Plug(eax); |
break; |
} |
@@ -1444,6 +1447,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 variable" |
: "[ Stack variable"); |
if (var->binding_needs_init()) { |
@@ -1516,11 +1520,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(esi); // Context. |
__ push(Immediate(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(eax); |
break; |
@@ -5092,45 +5100,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"); |
- __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
- __ mov(LoadDescriptor::NameRegister(), Immediate(proxy->name())); |
- __ mov(LoadDescriptor::SlotRegister(), |
- Immediate(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(eax); |
- } 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(esi); |
- __ push(Immediate(proxy->name())); |
- __ CallRuntime(Runtime::kLoadLookupSlotNoReferenceError, 2); |
- PrepareForBailout(expr, TOS_REG); |
- __ bind(&done); |
- |
- context()->Plug(eax); |
- } 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) { |