| 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) {
|
|
|