Index: src/mips/full-codegen-mips.cc |
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc |
index 8a9201a8ec432bb0abe94c5f5ec9fe581e535e5a..841ee4b99586bfae8736407212c72db69e2e0622 100644 |
--- a/src/mips/full-codegen-mips.cc |
+++ b/src/mips/full-codegen-mips.cc |
@@ -1408,15 +1408,9 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, |
__ bind(&fast); |
} |
- __ lw(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
- __ li(LoadDescriptor::NameRegister(), Operand(proxy->var()->name())); |
- __ li(LoadDescriptor::SlotRegister(), |
- Operand(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); |
} |
@@ -1485,7 +1479,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)); |
+ __ lw(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
+ __ li(LoadDescriptor::NameRegister(), Operand(var->name())); |
+ __ li(LoadDescriptor::SlotRegister(), |
+ Operand(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); |
@@ -1497,11 +1507,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
case VariableLocation::GLOBAL: |
case VariableLocation::UNALLOCATED: { |
Comment cmnt(masm_, "[ Global variable"); |
- __ lw(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
- __ li(LoadDescriptor::NameRegister(), Operand(var->name())); |
- __ li(LoadDescriptor::SlotRegister(), |
- Operand(SmiFromSlot(proxy->VariableFeedbackSlot()))); |
- CallGlobalLoadIC(var->name()); |
+ EmitGlobalVariableLoad(proxy, typeof_state); |
context()->Plug(v0); |
break; |
} |
@@ -1509,6 +1515,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()) { |
@@ -1584,11 +1591,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); |
__ li(a1, Operand(var->name())); |
__ Push(cp, a1); // Context and 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(v0); |
} |
@@ -5177,43 +5188,6 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
} |
-void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
- DCHECK(!context()->IsEffect()); |
- DCHECK(!context()->IsTest()); |
- VariableProxy* proxy = expr->AsVariableProxy(); |
- if (proxy != NULL && proxy->var()->IsUnallocatedOrGlobalSlot()) { |
- Comment cmnt(masm_, "[ Global variable"); |
- __ lw(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
- __ li(LoadDescriptor::NameRegister(), Operand(proxy->name())); |
- __ li(LoadDescriptor::SlotRegister(), |
- Operand(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(v0); |
- } 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); |
- __ li(a0, Operand(proxy->name())); |
- __ Push(cp, a0); |
- __ CallRuntime(Runtime::kLoadLookupSlotNoReferenceError, 2); |
- PrepareForBailout(expr, TOS_REG); |
- __ bind(&done); |
- |
- context()->Plug(v0); |
- } 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) { |