From: ishell Date: Tue, 7 Jul 2015 15:04:45 +0000 (-0700) Subject: Use FullCodeGenerator::EmitGlobalVariableLoad() where possible to avoid code duplication. X-Git-Tag: upstream/4.7.83~1520 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f043ab861839402d45af3724611671daf6a798c0;p=platform%2Fupstream%2Fv8.git Use FullCodeGenerator::EmitGlobalVariableLoad() where possible to avoid code duplication. Review URL: https://codereview.chromium.org/1222203007 Cr-Commit-Position: refs/heads/master@{#29520} --- diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc index 2f1a23b..e4b7cf3 100644 --- a/src/arm/full-codegen-arm.cc +++ b/src/arm/full-codegen-arm.cc @@ -1416,15 +1416,9 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, __ bind(&fast); } - __ ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); - __ mov(LoadDescriptor::NameRegister(), Operand(proxy->var()->name())); - __ mov(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); } @@ -1493,7 +1487,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)); + __ ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); + __ mov(LoadDescriptor::NameRegister(), Operand(var->name())); + __ mov(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); @@ -1505,11 +1515,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { case VariableLocation::GLOBAL: case VariableLocation::UNALLOCATED: { Comment cmnt(masm_, "[ Global variable"); - __ ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); - __ mov(LoadDescriptor::NameRegister(), Operand(var->name())); - __ mov(LoadDescriptor::SlotRegister(), - Operand(SmiFromSlot(proxy->VariableFeedbackSlot()))); - CallGlobalLoadIC(var->name()); + EmitGlobalVariableLoad(proxy, typeof_state); context()->Plug(r0); break; } @@ -1517,6 +1523,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()) { @@ -1590,11 +1597,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); __ mov(r1, Operand(var->name())); __ Push(cp, r1); // 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(r0); } @@ -5154,44 +5165,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"); - __ ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); - __ mov(LoadDescriptor::NameRegister(), Operand(proxy->name())); - __ mov(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(r0); - } 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); - __ mov(r0, Operand(proxy->name())); - __ Push(cp, r0); - __ CallRuntime(Runtime::kLoadLookupSlotNoReferenceError, 2); - PrepareForBailout(expr, TOS_REG); - __ bind(&done); - - context()->Plug(r0); - } else { - // This expression cannot throw a reference error at the top level. - VisitInDuplicateContext(expr); - } -} - - void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, Expression* sub_expr, Handle check) { diff --git a/src/arm64/full-codegen-arm64.cc b/src/arm64/full-codegen-arm64.cc index cb09314..324bfb8 100644 --- a/src/arm64/full-codegen-arm64.cc +++ b/src/arm64/full-codegen-arm64.cc @@ -1399,14 +1399,9 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, __ Bind(&fast); } - __ Ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectMemOperand()); - __ Mov(LoadDescriptor::NameRegister(), Operand(proxy->var()->name())); - __ Mov(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); } @@ -1472,7 +1467,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)); + __ Ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectMemOperand()); + __ Mov(LoadDescriptor::NameRegister(), Operand(var->name())); + __ Mov(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); @@ -1484,11 +1495,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { case VariableLocation::GLOBAL: case VariableLocation::UNALLOCATED: { Comment cmnt(masm_, "Global variable"); - __ Ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectMemOperand()); - __ Mov(LoadDescriptor::NameRegister(), Operand(var->name())); - __ Mov(LoadDescriptor::SlotRegister(), - SmiFromSlot(proxy->VariableFeedbackSlot())); - CallGlobalLoadIC(var->name()); + EmitGlobalVariableLoad(proxy, typeof_state); context()->Plug(x0); break; } @@ -1496,6 +1503,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"); @@ -1569,12 +1577,16 @@ 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); Comment cmnt(masm_, "Lookup variable"); __ Mov(x1, Operand(var->name())); __ Push(cp, x1); // 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(x0); break; @@ -4841,43 +4853,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"); - __ Ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectMemOperand()); - __ Mov(LoadDescriptor::NameRegister(), Operand(proxy->name())); - __ Mov(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(x0); - } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { - Label done, slow; - - // Generate code for loading from variables potentially shadowed - // by eval-introduced variables. - EmitDynamicLookupFastCase(proxy, INSIDE_TYPEOF, &slow, &done); - - __ Bind(&slow); - __ Mov(x0, Operand(proxy->name())); - __ Push(cp, x0); - __ CallRuntime(Runtime::kLoadLookupSlotNoReferenceError, 2); - PrepareForBailout(expr, TOS_REG); - __ Bind(&done); - - context()->Plug(x0); - } else { - // This expression cannot throw a reference error at the top level. - VisitInDuplicateContext(expr); - } -} - - void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, Expression* sub_expr, Handle check) { diff --git a/src/full-codegen.cc b/src/full-codegen.cc index 03c55d1..8ca40cc 100644 --- a/src/full-codegen.cc +++ b/src/full-codegen.cc @@ -214,11 +214,6 @@ void FullCodeGenerator::CallLoadIC(ContextualMode contextual_mode, } -void FullCodeGenerator::CallGlobalLoadIC(Handle name) { - return CallLoadIC(CONTEXTUAL); -} - - void FullCodeGenerator::CallStoreIC(TypeFeedbackId id) { Handle ic = CodeFactory::StoreIC(isolate(), language_mode()).code(); CallIC(ic, id); @@ -612,6 +607,22 @@ void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) { } +void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { + VariableProxy* proxy = expr->AsVariableProxy(); + DCHECK(!context()->IsEffect()); + DCHECK(!context()->IsTest()); + + if (proxy != NULL && (proxy->var()->IsUnallocatedOrGlobalSlot() || + proxy->var()->IsLookupSlot())) { + EmitVariableLoad(proxy, INSIDE_TYPEOF); + PrepareForBailout(proxy, TOS_REG); + } else { + // This expression cannot throw a reference error at the top level. + VisitInDuplicateContext(expr); + } +} + + void FullCodeGenerator::VisitBlock(Block* stmt) { Comment cmnt(masm_, "[ Block"); NestedBlock nested_block(this, stmt); diff --git a/src/full-codegen.h b/src/full-codegen.h index a2d23f0..b4294f5 100644 --- a/src/full-codegen.h +++ b/src/full-codegen.h @@ -552,7 +552,9 @@ class FullCodeGenerator: public AstVisitor { TypeofState typeof_state, Label* slow, Label* done); - void EmitVariableLoad(VariableProxy* proxy); + void EmitGlobalVariableLoad(VariableProxy* proxy, TypeofState typeof_state); + void EmitVariableLoad(VariableProxy* proxy, + TypeofState typeof_state = NOT_INSIDE_TYPEOF); void EmitAccessor(Expression* expression); @@ -654,7 +656,6 @@ class FullCodeGenerator: public AstVisitor { void CallLoadIC(ContextualMode mode, LanguageMode language_mode = SLOPPY, TypeFeedbackId id = TypeFeedbackId::None()); - void CallGlobalLoadIC(Handle name); void CallStoreIC(TypeFeedbackId id = TypeFeedbackId::None()); void SetFunctionPosition(FunctionLiteral* fun); diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc index 733b72a..535f2c2 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 check) { diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc index 8a9201a..841ee4b 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 check) { diff --git a/src/mips64/full-codegen-mips64.cc b/src/mips64/full-codegen-mips64.cc index 48977f6..569dc51 100644 --- a/src/mips64/full-codegen-mips64.cc +++ b/src/mips64/full-codegen-mips64.cc @@ -1405,15 +1405,9 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, __ bind(&fast); } - __ ld(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); } @@ -1482,7 +1476,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)); + __ ld(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); @@ -1494,13 +1504,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { case VariableLocation::GLOBAL: case VariableLocation::UNALLOCATED: { Comment cmnt(masm_, "[ Global variable"); - // Use inline caching. Variable name is passed in a2 and the global - // object (receiver) in a0. - __ ld(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; } @@ -1508,6 +1512,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()) { @@ -1583,11 +1588,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); } @@ -5181,43 +5190,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"); - __ ld(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 check) { diff --git a/src/ppc/full-codegen-ppc.cc b/src/ppc/full-codegen-ppc.cc index c80f104..ec94a24 100644 --- a/src/ppc/full-codegen-ppc.cc +++ b/src/ppc/full-codegen-ppc.cc @@ -1387,14 +1387,9 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, __ bind(&fast); } - __ LoadP(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); - __ mov(LoadDescriptor::NameRegister(), Operand(proxy->var()->name())); - __ mov(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); } @@ -1462,7 +1457,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)); + __ LoadP(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); + __ mov(LoadDescriptor::NameRegister(), Operand(var->name())); + __ mov(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); @@ -1474,11 +1485,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { case VariableLocation::GLOBAL: case VariableLocation::UNALLOCATED: { Comment cmnt(masm_, "[ Global variable"); - __ LoadP(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); - __ mov(LoadDescriptor::NameRegister(), Operand(var->name())); - __ mov(LoadDescriptor::SlotRegister(), - Operand(SmiFromSlot(proxy->VariableFeedbackSlot()))); - CallGlobalLoadIC(var->name()); + EmitGlobalVariableLoad(proxy, typeof_state); context()->Plug(r3); break; } @@ -1486,6 +1493,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()) { @@ -1559,11 +1567,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); __ mov(r4, Operand(var->name())); __ Push(cp, r4); // 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(r3); } @@ -5178,44 +5190,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"); - __ LoadP(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); - __ mov(LoadDescriptor::NameRegister(), Operand(proxy->name())); - __ mov(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(r3); - } 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); - __ mov(r3, Operand(proxy->name())); - __ Push(cp, r3); - __ CallRuntime(Runtime::kLoadLookupSlotNoReferenceError, 2); - PrepareForBailout(expr, TOS_REG); - __ bind(&done); - - context()->Plug(r3); - } else { - // This expression cannot throw a reference error at the top level. - VisitInDuplicateContext(expr); - } -} - - void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, Expression* sub_expr, Handle check) { diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc index 0011bca..ef8c150 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 check) { diff --git a/src/x87/full-codegen-x87.cc b/src/x87/full-codegen-x87.cc index f267fc4..7b1a35d 100644 --- a/src/x87/full-codegen-x87.cc +++ b/src/x87/full-codegen-x87.cc @@ -1337,18 +1337,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); } @@ -1414,7 +1405,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(); @@ -1425,11 +1432,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; } @@ -1437,6 +1440,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()) { @@ -1509,11 +1513,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; @@ -5082,45 +5090,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 check) {