Index: src/x64/full-codegen-x64.cc |
=================================================================== |
--- src/x64/full-codegen-x64.cc (revision 3713) |
+++ src/x64/full-codegen-x64.cc (working copy) |
@@ -790,9 +790,13 @@ |
void FullCodeGenerator::EmitVariableLoad(Variable* var, |
Expression::Context context) { |
- Expression* rewrite = var->rewrite(); |
- if (rewrite == NULL) { |
- ASSERT(var->is_global()); |
+ // Four cases: non-this global variables, lookup slots, all other |
+ // types of slots, and parameters that rewrite to explicit property |
+ // accesses on the arguments object. |
+ Slot* slot = var->slot(); |
+ Property* property = var->AsProperty(); |
+ |
+ if (var->is_global() && !var->is_this()) { |
Comment cmnt(masm_, "Global variable"); |
// Use inline caching. Variable name is passed in rcx and the global |
// object on the stack. |
@@ -805,35 +809,25 @@ |
// is no test rax instruction here. |
__ nop(); |
DropAndApply(1, context, rax); |
- } else if (rewrite->AsSlot() != NULL) { |
- Slot* slot = rewrite->AsSlot(); |
- if (FLAG_debug_code) { |
- switch (slot->type()) { |
- case Slot::PARAMETER: |
- case Slot::LOCAL: { |
- Comment cmnt(masm_, "Stack slot"); |
- break; |
- } |
- case Slot::CONTEXT: { |
- Comment cmnt(masm_, "Context slot"); |
- break; |
- } |
- case Slot::LOOKUP: |
- UNIMPLEMENTED(); |
- break; |
- } |
- } |
+ |
+ } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
+ Comment cmnt(masm_, "Lookup slot"); |
+ __ push(rsi); // Context. |
+ __ Push(var->name()); |
+ __ CallRuntime(Runtime::kLoadContextSlot, 2); |
+ Apply(context, rax); |
+ |
+ } else if (slot != NULL) { |
+ Comment cmnt(masm_, (slot->type() == Slot::CONTEXT) |
+ ? "Context slot" |
+ : "Stack slot"); |
Apply(context, slot); |
+ |
} else { |
- Comment cmnt(masm_, "Variable rewritten to property"); |
- // A variable has been rewritten into an explicit access to an object |
- // property. |
- Property* property = rewrite->AsProperty(); |
+ Comment cmnt(masm_, "Rewritten parameter"); |
ASSERT_NOT_NULL(property); |
+ // Rewritten parameter accesses are of the form "slot[literal]". |
- // The only property expressions that can occur are of the form |
- // "slot[literal]". |
- |
// Assert that the object is in a slot. |
Variable* object_var = property->obj()->AsVariableProxy()->AsVariable(); |
ASSERT_NOT_NULL(object_var); |
@@ -1041,9 +1035,14 @@ |
void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
Expression::Context context) { |
+ // Three main cases: non-this global variables, lookup slots, and |
+ // all other types of slots. Left-hand-side parameters that rewrite |
+ // to explicit property accesses do not reach here. |
ASSERT(var != NULL); |
ASSERT(var->is_global() || var->slot() != NULL); |
+ Slot* slot = var->slot(); |
if (var->is_global()) { |
+ ASSERT(!var->is_this()); |
// Assignment to a global variable. Use inline caching for the |
// assignment. Right-hand-side value is passed in rax, variable name in |
// rcx, and the global object on the stack. |
@@ -1054,8 +1053,14 @@ |
// Overwrite the global object on the stack with the result if needed. |
DropAndApply(1, context, rax); |
+ } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
+ __ push(result_register()); // Value. |
+ __ push(rsi); // Context. |
+ __ Push(var->name()); |
+ __ CallRuntime(Runtime::kStoreContextSlot, 3); |
+ Apply(context, rax); |
+ |
} else if (var->slot() != NULL) { |
- Slot* slot = var->slot(); |
switch (slot->type()) { |
case Slot::LOCAL: |
case Slot::PARAMETER: |
@@ -1078,6 +1083,7 @@ |
break; |
} |
Apply(context, result_register()); |
+ |
} else { |
// Variables rewritten as properties are not treated as variables in |
// assignments. |