Rename the kinds of locations to be consistent with the (codegen)
authorkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 29 Oct 2009 10:35:29 +0000 (10:35 +0000)
committerkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 29 Oct 2009 10:35:29 +0000 (10:35 +0000)
context of the expressions they label.  Introduce an "unintialized"
location to catch failure to assign any location at all.

Changed the object literal initialization on ARM to use a Store IC in
the same cases where it did on the other platforms.  This was required
because the location of the literal property name is given an
"unitialized" location.

Review URL: http://codereview.chromium.org/339045

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3171 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/arm/fast-codegen-arm.cc
src/ast.h
src/compiler.cc
src/fast-codegen.cc
src/ia32/fast-codegen-ia32.cc
src/location.h
src/x64/fast-codegen-x64.cc

index 21ee6d7e02393396cd176c7fcda9fca8ed1aafad..49b25746bcb6ecf5140e41148cc714063dbcb1a1 100644 (file)
@@ -119,9 +119,11 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun) {
 
 void FastCodeGenerator::Move(Location destination, Slot* source) {
   switch (destination.type()) {
-    case Location::NOWHERE:
+    case Location::UNINITIALIZED:
+      UNREACHABLE();
+    case Location::EFFECT:
       break;
-    case Location::TEMP:
+    case Location::VALUE:
       __ ldr(ip, MemOperand(fp, SlotOffset(source)));
       __ push(ip);
       break;
@@ -131,9 +133,11 @@ void FastCodeGenerator::Move(Location destination, Slot* source) {
 
 void FastCodeGenerator::Move(Location destination, Literal* expr) {
   switch (destination.type()) {
-    case Location::NOWHERE:
+    case Location::UNINITIALIZED:
+      UNREACHABLE();
+    case Location::EFFECT:
       break;
-    case Location::TEMP:
+    case Location::VALUE:
       __ mov(ip, Operand(expr->handle()));
       __ push(ip);
       break;
@@ -143,9 +147,10 @@ void FastCodeGenerator::Move(Location destination, Literal* expr) {
 
 void FastCodeGenerator::Move(Slot* destination, Location source) {
   switch (source.type()) {
-    case Location::NOWHERE:
+    case Location::UNINITIALIZED:  // Fall through.
+    case Location::EFFECT:
       UNREACHABLE();
-    case Location::TEMP:
+    case Location::VALUE:
       __ pop(ip);
       __ str(ip, MemOperand(fp, SlotOffset(destination)));
       break;
@@ -155,10 +160,12 @@ void FastCodeGenerator::Move(Slot* destination, Location source) {
 
 void FastCodeGenerator::DropAndMove(Location destination, Register source) {
   switch (destination.type()) {
-    case Location::NOWHERE:
+    case Location::UNINITIALIZED:
+      UNREACHABLE();
+    case Location::EFFECT:
       __ pop();
       break;
-    case Location::TEMP:
+    case Location::VALUE:
       __ str(source, MemOperand(sp));
       break;
   }
@@ -239,6 +246,33 @@ void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
 }
 
 
+void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
+  Comment cmnt(masm_, "[ RegExp Literal");
+  Label done;
+  // Registers will be used as follows:
+  // r4 = JS function, literals array
+  // r3 = literal index
+  // r2 = RegExp pattern
+  // r1 = RegExp flags
+  // r0 = temp + return value (RegExp literal)
+  __ ldr(r0, MemOperand(fp,  JavaScriptFrameConstants::kFunctionOffset));
+  __ ldr(r4,  FieldMemOperand(r0, JSFunction::kLiteralsOffset));
+  int literal_offset =
+    FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
+  __ ldr(r0, FieldMemOperand(r4, literal_offset));
+  __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
+  __ cmp(r0, ip);
+  __ b(ne, &done);
+  __ mov(r3, Operand(Smi::FromInt(expr->literal_index())));
+  __ mov(r2, Operand(expr->pattern()));
+  __ mov(r1, Operand(expr->flags()));
+  __ stm(db_w, sp, r4.bit() | r3.bit() | r2.bit() | r1.bit());
+  __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
+  __ bind(&done);
+  Move(expr->location(), r0);
+}
+
+
 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
   Comment cmnt(masm_, "[ ObjectLiteral");
   Label boilerplate_exists;
@@ -284,73 +318,62 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
       result_saved = true;
     }
     switch (property->kind()) {
-      case ObjectLiteral::Property::MATERIALIZED_LITERAL:   // fall through
+      case ObjectLiteral::Property::CONSTANT:
+        UNREACHABLE();
+
+      case ObjectLiteral::Property::MATERIALIZED_LITERAL:   // Fall through.
         ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value()));
-      case ObjectLiteral::Property::COMPUTED:  // fall through
+      case ObjectLiteral::Property::COMPUTED:
+        if (key->handle()->IsSymbol()) {
+          Visit(value);
+          Move(r0, value->location());
+          __ mov(r2, Operand(key->handle()));
+          Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
+          __ Call(ic, RelocInfo::CODE_TARGET);
+          // StoreIC leaves the receiver on the stack.
+          break;
+        }
+        // Fall through.
+
       case ObjectLiteral::Property::PROTOTYPE:
         __ push(r0);
         Visit(key);
-        ASSERT(key->location().is_temporary());
+        ASSERT(key->location().is_value());
         Visit(value);
-        ASSERT(value->location().is_temporary());
+        ASSERT(value->location().is_value());
         __ CallRuntime(Runtime::kSetProperty, 3);
         __ ldr(r0, MemOperand(sp));  // Restore result into r0
         break;
-      case ObjectLiteral::Property::SETTER:  // fall through
-      case ObjectLiteral::Property::GETTER:
+
+      case ObjectLiteral::Property::GETTER:  // Fall through.
+      case ObjectLiteral::Property::SETTER:
         __ push(r0);
         Visit(key);
-        ASSERT(key->location().is_temporary());
+        ASSERT(key->location().is_value());
         __ mov(r1, Operand(property->kind() == ObjectLiteral::Property::SETTER ?
                            Smi::FromInt(1) :
                            Smi::FromInt(0)));
         __ push(r1);
         Visit(value);
-        ASSERT(value->location().is_temporary());
+        ASSERT(value->location().is_value());
         __ CallRuntime(Runtime::kDefineAccessor, 4);
         __ ldr(r0, MemOperand(sp));  // Restore result into r0
         break;
-      default: UNREACHABLE();
     }
   }
   switch (expr->location().type()) {
-    case Location::NOWHERE:
+    case Location::UNINITIALIZED:
+      UNREACHABLE();
+    case Location::EFFECT:
       if (result_saved) __ pop();
       break;
-    case Location::TEMP:
+    case Location::VALUE:
       if (!result_saved) __ push(r0);
       break;
   }
 }
 
 
-void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
-  Comment cmnt(masm_, "[ RegExp Literal");
-  Label done;
-  // Registers will be used as follows:
-  // r4 = JS function, literals array
-  // r3 = literal index
-  // r2 = RegExp pattern
-  // r1 = RegExp flags
-  // r0 = temp + return value (RegExp literal)
-  __ ldr(r0, MemOperand(fp,  JavaScriptFrameConstants::kFunctionOffset));
-  __ ldr(r4,  FieldMemOperand(r0, JSFunction::kLiteralsOffset));
-  int literal_offset =
-    FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
-  __ ldr(r0, FieldMemOperand(r4, literal_offset));
-  __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
-  __ cmp(r0, ip);
-  __ b(ne, &done);
-  __ mov(r3, Operand(Smi::FromInt(expr->literal_index())));
-  __ mov(r2, Operand(expr->pattern()));
-  __ mov(r1, Operand(expr->flags()));
-  __ stm(db_w, sp, r4.bit() | r3.bit() | r2.bit() | r1.bit());
-  __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
-  __ bind(&done);
-  Move(expr->location(), r0);
-}
-
-
 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
   Comment cmnt(masm_, "[ ArrayLiteral");
   Label make_clone;
@@ -400,7 +423,7 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
       result_saved = true;
     }
     Visit(subexpr);
-    ASSERT(subexpr->location().is_temporary());
+    ASSERT(subexpr->location().is_value());
 
     // Store the subexpression value in the array's elements.
     __ pop(r0);  // Subexpression value.
@@ -416,10 +439,12 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
   }
 
   switch (expr->location().type()) {
-    case Location::NOWHERE:
+    case Location::UNINITIALIZED:
+      UNREACHABLE();
+    case Location::EFFECT:
       if (result_saved) __ pop();
       break;
-    case Location::TEMP:
+    case Location::VALUE:
       if (!result_saved) __ push(r0);
       break;
   }
@@ -446,7 +471,7 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
     if (rhs->AsLiteral() != NULL) {
       __ mov(r0, Operand(rhs->AsLiteral()->handle()));
     } else {
-      ASSERT(rhs->location().is_temporary());
+      ASSERT(rhs->location().is_value());
       Visit(rhs);
       __ pop(r0);
     }
@@ -468,15 +493,17 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
       __ str(ip, MemOperand(fp, SlotOffset(var->slot())));
       Move(expr->location(), ip);
     } else {
-      ASSERT(rhs->location().is_temporary());
+      ASSERT(rhs->location().is_value());
       Visit(rhs);
       // Load right-hand side into ip.
       switch (expr->location().type()) {
-        case Location::NOWHERE:
+        case Location::UNINITIALIZED:
+          UNREACHABLE();
+        case Location::EFFECT:
           // Case 'var = temp'.  Discard right-hand-side temporary.
           __ pop(ip);
           break;
-        case Location::TEMP:
+        case Location::VALUE:
           // Case 'temp1 <- (var = temp0)'.  Preserve right-hand-side
           // temporary on the stack.
           __ ldr(ip, MemOperand(sp));
@@ -522,10 +549,12 @@ void FastCodeGenerator::VisitProperty(Property* expr) {
     __ pop();
   }
   switch (expr->location().type()) {
-    case Location::TEMP:
+    case Location::UNINITIALIZED:
+      UNREACHABLE();
+    case Location::VALUE:
       __ str(r0, MemOperand(sp));
       break;
-    case Location::NOWHERE:
+    case Location::EFFECT:
       __ pop();
   }
 }
@@ -546,7 +575,7 @@ void FastCodeGenerator::VisitCall(Call* expr) {
   int arg_count = args->length();
   for (int i = 0; i < arg_count; i++) {
     Visit(args->at(i));
-    ASSERT(args->at(i)->location().is_temporary());
+    ASSERT(args->at(i)->location().is_value());
   }
   // Record source position for debugger
   SetSourcePosition(expr->position());
@@ -567,7 +596,7 @@ void FastCodeGenerator::VisitCallNew(CallNew* node) {
   // arguments.
   // Push function on the stack.
   Visit(node->expression());
-  ASSERT(node->expression()->location().is_temporary());
+  ASSERT(node->expression()->location().is_value());
 
   // Push global object (receiver).
   __ ldr(r0, CodeGenerator::GlobalObject());
@@ -577,7 +606,7 @@ void FastCodeGenerator::VisitCallNew(CallNew* node) {
   int arg_count = args->length();
   for (int i = 0; i < arg_count; i++) {
     Visit(args->at(i));
-    ASSERT(args->at(i)->location().is_temporary());
+    ASSERT(args->at(i)->location().is_value());
     // If location is temporary, it is already on the stack,
     // so nothing to do here.
   }
@@ -610,7 +639,7 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
   int arg_count = args->length();
   for (int i = 0; i < arg_count; i++) {
     Visit(args->at(i));
-    ASSERT(args->at(i)->location().is_temporary());
+    ASSERT(args->at(i)->location().is_value());
   }
 
   __ CallRuntime(function, arg_count);
@@ -636,11 +665,11 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
   if (left->AsLiteral() != NULL) {
     __ mov(r0, Operand(left->AsLiteral()->handle()));
     __ push(r0);
-    if (destination.is_temporary()) __ push(r0);
+    if (destination.is_value()) __ push(r0);
   } else {
     Visit(left);
-    ASSERT(left->location().is_temporary());
-    if (destination.is_temporary()) {
+    ASSERT(left->location().is_value());
+    if (destination.is_value()) {
       __ ldr(r0, MemOperand(sp));
       __ push(r0);
     }
@@ -653,7 +682,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
   __ b(eq, &done);
 
   // Discard the left-hand value if present on the stack.
-  if (destination.is_temporary()) __ pop();
+  if (destination.is_value()) __ pop();
   // Save or discard the right-hand value as needed.
   if (right->AsLiteral() != NULL) {
     Move(destination, right->AsLiteral());
index 9b7d9ddb05e810eeafa4010078342a4938ceb5d7..be64dcb3c6bfa857770b1a0bd4e45095d00717fd 100644 (file)
--- a/src/ast.h
+++ b/src/ast.h
@@ -162,7 +162,7 @@ class Statement: public AstNode {
 
 class Expression: public AstNode {
  public:
-  Expression() : location_(Location::Temporary()) {}
+  Expression() : location_(Location::Uninitialized()) {}
 
   virtual Expression* AsExpression()  { return this; }
 
index bad209e1388ee7a659a0c69ce1f6f0cc0e05956e..63bf2ecade2133d9bd19f2246354cb89e055e570 100644 (file)
@@ -48,7 +48,7 @@ class CodeGenSelector: public AstVisitor {
 
   CodeGenSelector()
       : has_supported_syntax_(true),
-        location_(Location::Nowhere()) {
+        location_(Location::Uninitialized()) {
   }
 
   CodeGenTag Select(FunctionLiteral* fun);
@@ -514,11 +514,11 @@ void CodeGenSelector::VisitStatements(ZoneList<Statement*>* stmts) {
 
 
 void CodeGenSelector::VisitAsEffect(Expression* expr) {
-  if (location_.is_nowhere()) {
+  if (location_.is_effect()) {
     Visit(expr);
   } else {
     Location saved = location_;
-    location_ = Location::Nowhere();
+    location_ = Location::Effect();
     Visit(expr);
     location_ = saved;
   }
@@ -526,11 +526,11 @@ void CodeGenSelector::VisitAsEffect(Expression* expr) {
 
 
 void CodeGenSelector::VisitAsValue(Expression* expr) {
-  if (location_.is_temporary()) {
+  if (location_.is_value()) {
     Visit(expr);
   } else {
     Location saved = location_;
-    location_ = Location::Temporary();
+    location_ = Location::Value();
     Visit(expr);
     location_ = saved;
   }
index 8655e97a8622809c3225b5f126967b68ad2eb5cb..20c17b33cb6ec9aced9ff3718810b69cb1ae9f50 100644 (file)
@@ -73,14 +73,18 @@ int FastCodeGenerator::SlotOffset(Slot* slot) {
 
 void FastCodeGenerator::Move(Location destination, Location source) {
   switch (destination.type()) {
-    case Location::NOWHERE:
+    case Location::UNINITIALIZED:
+      UNREACHABLE();
+
+    case Location::EFFECT:
       break;
 
-    case Location::TEMP:
+    case Location::VALUE:
       switch (source.type()) {
-        case Location::NOWHERE:
+        case Location::UNINITIALIZED:  // Fall through.
+        case Location::EFFECT:
           UNREACHABLE();
-        case Location::TEMP:
+        case Location::VALUE:
           break;
       }
       break;
@@ -92,9 +96,11 @@ void FastCodeGenerator::Move(Location destination, Location source) {
 // function.
 void FastCodeGenerator::Move(Location destination, Register source) {
   switch (destination.type()) {
-    case Location::NOWHERE:
+    case Location::UNINITIALIZED:
+      UNREACHABLE();
+    case Location::EFFECT:
       break;
-    case Location::TEMP:
+    case Location::VALUE:
       masm_->push(source);
       break;
   }
@@ -105,9 +111,10 @@ void FastCodeGenerator::Move(Location destination, Register source) {
 // function.
 void FastCodeGenerator::Move(Register destination, Location source) {
   switch (source.type()) {
-    case Location::NOWHERE:
+    case Location::UNINITIALIZED:  // Fall through.
+    case Location::EFFECT:
       UNREACHABLE();
-    case Location::TEMP:
+    case Location::VALUE:
       masm_->pop(destination);
   }
 }
index 0d661c3b67be065c85a8b6ab1cc752cc0f8e6895..520fd077a961c1e799505f5c2cfc0badf166ce6c 100644 (file)
@@ -110,9 +110,11 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun) {
 
 void FastCodeGenerator::Move(Location destination, Slot* source) {
   switch (destination.type()) {
-    case Location::NOWHERE:
+    case Location::UNINITIALIZED:
+      UNREACHABLE();
+    case Location::EFFECT:
       break;
-    case Location::TEMP:
+    case Location::VALUE:
       __ push(Operand(ebp, SlotOffset(source)));
       break;
   }
@@ -121,9 +123,11 @@ void FastCodeGenerator::Move(Location destination, Slot* source) {
 
 void FastCodeGenerator::Move(Location destination, Literal* expr) {
   switch (destination.type()) {
-    case Location::NOWHERE:
+    case Location::UNINITIALIZED:
+      UNREACHABLE();
+    case Location::EFFECT:
       break;
-    case Location::TEMP:
+    case Location::VALUE:
       __ push(Immediate(expr->handle()));
       break;
   }
@@ -132,9 +136,10 @@ void FastCodeGenerator::Move(Location destination, Literal* expr) {
 
 void FastCodeGenerator::Move(Slot* destination, Location source) {
   switch (source.type()) {
-    case Location::NOWHERE:
+    case Location::UNINITIALIZED:  // Fall through.
+    case Location::EFFECT:
       UNREACHABLE();
-    case Location::TEMP:
+    case Location::VALUE:
       __ pop(Operand(ebp, SlotOffset(destination)));
       break;
   }
@@ -143,10 +148,12 @@ void FastCodeGenerator::Move(Slot* destination, Location source) {
 
 void FastCodeGenerator::DropAndMove(Location destination, Register source) {
   switch (destination.type()) {
-    case Location::NOWHERE:
+    case Location::UNINITIALIZED:
+      UNREACHABLE();
+    case Location::EFFECT:
       __ add(Operand(esp), Immediate(kPointerSize));
       break;
-    case Location::TEMP:
+    case Location::VALUE:
       __ mov(Operand(esp, 0), source);
       break;
   }
@@ -231,6 +238,33 @@ void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
 }
 
 
+void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
+  Comment cmnt(masm_, "[ RegExp Literal");
+  Label done;
+  // Registers will be used as follows:
+  // edi = JS function.
+  // ebx = literals array.
+  // eax = regexp literal.
+  __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
+  __ mov(ebx, FieldOperand(edi, JSFunction::kLiteralsOffset));
+  int literal_offset =
+    FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
+  __ mov(eax, FieldOperand(ebx, literal_offset));
+  __ cmp(eax, Factory::undefined_value());
+  __ j(not_equal, &done);
+  // Create regexp literal using runtime function
+  // Result will be in eax.
+  __ push(ebx);
+  __ push(Immediate(Smi::FromInt(expr->literal_index())));
+  __ push(Immediate(expr->pattern()));
+  __ push(Immediate(expr->flags()));
+  __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
+  // Label done:
+  __ bind(&done);
+  Move(expr->location(), eax);
+}
+
+
 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
   Comment cmnt(masm_, "[ ObjectLiteral");
   Label exists;
@@ -295,9 +329,9 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
       case ObjectLiteral::Property::PROTOTYPE:
         __ push(eax);
         Visit(key);
-        ASSERT(key->location().is_temporary());
+        ASSERT(key->location().is_value());
         Visit(value);
-        ASSERT(value->location().is_temporary());
+        ASSERT(value->location().is_value());
         __ CallRuntime(Runtime::kSetProperty, 3);
         __ mov(eax, Operand(esp, 0));  // Restore result into eax.
         break;
@@ -305,12 +339,12 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
       case ObjectLiteral::Property::GETTER:
         __ push(eax);
         Visit(key);
-        ASSERT(key->location().is_temporary());
+        ASSERT(key->location().is_value());
         __ push(Immediate(property->kind() == ObjectLiteral::Property::SETTER ?
                           Smi::FromInt(1) :
                           Smi::FromInt(0)));
         Visit(value);
-        ASSERT(value->location().is_temporary());
+        ASSERT(value->location().is_value());
         __ CallRuntime(Runtime::kDefineAccessor, 4);
         __ mov(eax, Operand(esp, 0));  // Restore result into eax.
         break;
@@ -318,43 +352,18 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
     }
   }
   switch (expr->location().type()) {
-    case Location::NOWHERE:
+    case Location::UNINITIALIZED:
+      UNREACHABLE();
+    case Location::EFFECT:
       if (result_saved) __ add(Operand(esp), Immediate(kPointerSize));
       break;
-    case Location::TEMP:
+    case Location::VALUE:
       if (!result_saved) __ push(eax);
       break;
   }
 }
 
 
-void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
-  Comment cmnt(masm_, "[ RegExp Literal");
-  Label done;
-  // Registers will be used as follows:
-  // edi = JS function.
-  // ebx = literals array.
-  // eax = regexp literal.
-  __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
-  __ mov(ebx, FieldOperand(edi, JSFunction::kLiteralsOffset));
-  int literal_offset =
-    FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
-  __ mov(eax, FieldOperand(ebx, literal_offset));
-  __ cmp(eax, Factory::undefined_value());
-  __ j(not_equal, &done);
-  // Create regexp literal using runtime function
-  // Result will be in eax.
-  __ push(ebx);
-  __ push(Immediate(Smi::FromInt(expr->literal_index())));
-  __ push(Immediate(expr->pattern()));
-  __ push(Immediate(expr->flags()));
-  __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
-  // Label done:
-  __ bind(&done);
-  Move(expr->location(), eax);
-}
-
-
 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
   Comment cmnt(masm_, "[ ArrayLiteral");
   Label make_clone;
@@ -403,7 +412,7 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
       result_saved = true;
     }
     Visit(subexpr);
-    ASSERT(subexpr->location().is_temporary());
+    ASSERT(subexpr->location().is_value());
 
     // Store the subexpression value in the array's elements.
     __ pop(eax);  // Subexpression value.
@@ -417,10 +426,12 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
   }
 
   switch (expr->location().type()) {
-    case Location::NOWHERE:
+    case Location::UNINITIALIZED:
+      UNREACHABLE();
+    case Location::EFFECT:
       if (result_saved) __ add(Operand(esp), Immediate(kPointerSize));
       break;
-    case Location::TEMP:
+    case Location::VALUE:
       if (!result_saved) __ push(eax);
       break;
   }
@@ -446,7 +457,7 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
     if (rhs->AsLiteral() != NULL) {
       __ mov(eax, rhs->AsLiteral()->handle());
     } else {
-      ASSERT(rhs->location().is_temporary());
+      ASSERT(rhs->location().is_value());
       Visit(rhs);
       __ pop(eax);
     }
@@ -467,14 +478,16 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
       __ mov(Operand(ebp, SlotOffset(var->slot())), eax);
       Move(expr->location(), eax);
     } else {
-      ASSERT(rhs->location().is_temporary());
+      ASSERT(rhs->location().is_value());
       Visit(rhs);
       switch (expr->location().type()) {
-        case Location::NOWHERE:
+        case Location::UNINITIALIZED:
+          UNREACHABLE();
+        case Location::EFFECT:
           // Case 'var = temp'.  Discard right-hand-side temporary.
           Move(var->slot(), rhs->location());
           break;
-        case Location::TEMP:
+        case Location::VALUE:
           // Case 'temp1 <- (var = temp0)'.  Preserve right-hand-side
           // temporary on the stack.
           __ mov(eax, Operand(esp, 0));
@@ -519,10 +532,12 @@ void FastCodeGenerator::VisitProperty(Property* expr) {
     __ add(Operand(esp), Immediate(kPointerSize));
   }
   switch (expr->location().type()) {
-    case Location::TEMP:
+    case Location::UNINITIALIZED:
+      UNREACHABLE();
+    case Location::VALUE:
       __ mov(Operand(esp, 0), eax);
       break;
-    case Location::NOWHERE:
+    case Location::EFFECT:
       __ add(Operand(esp), Immediate(kPointerSize));
       break;
   }
@@ -542,7 +557,7 @@ void FastCodeGenerator::VisitCall(Call* expr) {
   int arg_count = args->length();
   for (int i = 0; i < arg_count; i++) {
     Visit(args->at(i));
-    ASSERT(args->at(i)->location().is_temporary());
+    ASSERT(args->at(i)->location().is_value());
   }
   // Record source position for debugger
   SetSourcePosition(expr->position());
@@ -564,7 +579,7 @@ void FastCodeGenerator::VisitCallNew(CallNew* node) {
   // arguments.
   // Push function on the stack.
   Visit(node->expression());
-  ASSERT(node->expression()->location().is_temporary());
+  ASSERT(node->expression()->location().is_value());
 
   // Push global object (receiver).
   __ push(CodeGenerator::GlobalObject());
@@ -574,7 +589,7 @@ void FastCodeGenerator::VisitCallNew(CallNew* node) {
   int arg_count = args->length();
   for (int i = 0; i < arg_count; i++) {
     Visit(args->at(i));
-    ASSERT(args->at(i)->location().is_temporary());
+    ASSERT(args->at(i)->location().is_value());
     // If location is temporary, it is already on the stack,
     // so nothing to do here.
   }
@@ -607,7 +622,7 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
   int arg_count = args->length();
   for (int i = 0; i < arg_count; i++) {
     Visit(args->at(i));
-    ASSERT(args->at(i)->location().is_temporary());
+    ASSERT(args->at(i)->location().is_value());
   }
 
   __ CallRuntime(function, arg_count);
@@ -635,17 +650,19 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
   // need it as the value of the whole expression.
   if (left->AsLiteral() != NULL) {
     __ mov(eax, left->AsLiteral()->handle());
-    if (destination.is_temporary()) __ push(eax);
+    if (destination.is_value()) __ push(eax);
   } else {
     Visit(left);
-    ASSERT(left->location().is_temporary());
+    ASSERT(left->location().is_value());
     switch (destination.type()) {
-      case Location::NOWHERE:
+      case Location::UNINITIALIZED:
+        UNREACHABLE();
+      case Location::EFFECT:
         // Pop the left-hand value into eax because we will not need it as the
         // final result.
         __ pop(eax);
         break;
-      case Location::TEMP:
+      case Location::VALUE:
         // Copy the left-hand value into eax because we may need it as the
         // final result.
         __ mov(eax, Operand(esp, 0));
@@ -677,7 +694,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
 
   __ bind(&eval_right);
   // Discard the left-hand value if present on the stack.
-  if (destination.is_temporary()) {
+  if (destination.is_value()) {
     __ add(Operand(esp), Immediate(kPointerSize));
   }
   // Save or discard the right-hand value as needed.
index c4a77cb5d13fc2f59ef3b606606fd8cf27346608..7a11c4ab588e27fc9e484d6f417c0f25da1e5add 100644 (file)
@@ -35,13 +35,14 @@ namespace internal {
 
 class Location BASE_EMBEDDED {
  public:
-  enum Type { NOWHERE, TEMP };
+  enum Type { UNINITIALIZED, EFFECT, VALUE };
 
-  static Location Temporary() { return Location(TEMP); }
-  static Location Nowhere() { return Location(NOWHERE); }
+  static Location Uninitialized() { return Location(UNINITIALIZED); }
+  static Location Effect() { return Location(EFFECT); }
+  static Location Value() { return Location(VALUE); }
 
-  bool is_temporary() { return type_ == TEMP; }
-  bool is_nowhere() { return type_ == NOWHERE; }
+  bool is_effect() { return type_ == EFFECT; }
+  bool is_value() { return type_ == VALUE; }
 
   Type type() { return type_; }
 
index 53ee35758d5e138fa2f6ac110f8a4263ae57e2eb..2c9212b39e60ff17f296f320594156994b4fdc32 100644 (file)
@@ -118,9 +118,11 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun) {
 
 void FastCodeGenerator::Move(Location destination, Slot* source) {
   switch (destination.type()) {
-    case Location::NOWHERE:
+    case Location::UNINITIALIZED:
+      UNREACHABLE();
+    case Location::EFFECT:
       break;
-    case Location::TEMP:
+    case Location::VALUE:
       __ push(Operand(rbp, SlotOffset(source)));
       break;
   }
@@ -129,9 +131,11 @@ void FastCodeGenerator::Move(Location destination, Slot* source) {
 
 void FastCodeGenerator::Move(Location destination, Literal* expr) {
   switch (destination.type()) {
-    case Location::NOWHERE:
+    case Location::UNINITIALIZED:
+      UNREACHABLE();
+    case Location::EFFECT:
       break;
-    case Location::TEMP:
+    case Location::VALUE:
       __ Push(expr->handle());
       break;
   }
@@ -140,9 +144,10 @@ void FastCodeGenerator::Move(Location destination, Literal* expr) {
 
 void FastCodeGenerator::Move(Slot* destination, Location source) {
   switch (source.type()) {
-    case Location::NOWHERE:
+    case Location::UNINITIALIZED:  // Fall through.
+    case Location::EFFECT:
       UNREACHABLE();
-    case Location::TEMP:
+    case Location::VALUE:
       __ pop(Operand(rbp, SlotOffset(destination)));
       break;
   }
@@ -151,10 +156,12 @@ void FastCodeGenerator::Move(Slot* destination, Location source) {
 
 void FastCodeGenerator::DropAndMove(Location destination, Register source) {
   switch (destination.type()) {
-    case Location::NOWHERE:
+    case Location::UNINITIALIZED:
+      UNREACHABLE();
+    case Location::EFFECT:
       __ addq(rsp, Immediate(kPointerSize));
       break;
-    case Location::TEMP:
+    case Location::VALUE:
       __ movq(Operand(rsp, 0), source);
       break;
   }
@@ -246,6 +253,33 @@ void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
 }
 
 
+void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
+  Comment cmnt(masm_, "[ RegExp Literal");
+  Label done;
+  // Registers will be used as follows:
+  // rdi = JS function.
+  // rbx = literals array.
+  // rax = regexp literal.
+  __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
+  __ movq(rbx, FieldOperand(rdi, JSFunction::kLiteralsOffset));
+  int literal_offset =
+    FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
+  __ movq(rax, FieldOperand(rbx, literal_offset));
+  __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
+  __ j(not_equal, &done);
+  // Create regexp literal using runtime function
+  // Result will be in rax.
+  __ push(rbx);
+  __ Push(Smi::FromInt(expr->literal_index()));
+  __ Push(expr->pattern());
+  __ Push(expr->flags());
+  __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
+  // Label done:
+  __ bind(&done);
+  Move(expr->location(), rax);
+}
+
+
 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
   Comment cmnt(masm_, "[ ObjectLiteral");
   Label boilerplate_exists;
@@ -295,7 +329,7 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
       case ObjectLiteral::Property::COMPUTED:
         if (key->handle()->IsSymbol()) {
           Visit(value);
-          ASSERT(value->location().is_temporary());
+          ASSERT(value->location().is_value());
           __ pop(rax);
           __ Move(rcx, key->handle());
           Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
@@ -307,9 +341,9 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
       case ObjectLiteral::Property::PROTOTYPE:
         __ push(rax);
         Visit(key);
-        ASSERT(key->location().is_temporary());
+        ASSERT(key->location().is_value());
         Visit(value);
-        ASSERT(value->location().is_temporary());
+        ASSERT(value->location().is_value());
         __ CallRuntime(Runtime::kSetProperty, 3);
         __ movq(rax, Operand(rsp, 0));  // Restore result into rax.
         break;
@@ -317,12 +351,12 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
       case ObjectLiteral::Property::GETTER:
         __ push(rax);
         Visit(key);
-        ASSERT(key->location().is_temporary());
+        ASSERT(key->location().is_value());
         __ Push(property->kind() == ObjectLiteral::Property::SETTER ?
                 Smi::FromInt(1) :
                 Smi::FromInt(0));
         Visit(value);
-        ASSERT(value->location().is_temporary());
+        ASSERT(value->location().is_value());
         __ CallRuntime(Runtime::kDefineAccessor, 4);
         __ movq(rax, Operand(rsp, 0));  // Restore result into rax.
         break;
@@ -330,43 +364,18 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
     }
   }
   switch (expr->location().type()) {
-    case Location::NOWHERE:
+    case Location::UNINITIALIZED:
+      UNREACHABLE();
+    case Location::EFFECT:
       if (result_saved) __ addq(rsp, Immediate(kPointerSize));
       break;
-    case Location::TEMP:
+    case Location::VALUE:
       if (!result_saved) __ push(rax);
       break;
   }
 }
 
 
-void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
-  Comment cmnt(masm_, "[ RegExp Literal");
-  Label done;
-  // Registers will be used as follows:
-  // rdi = JS function.
-  // rbx = literals array.
-  // rax = regexp literal.
-  __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
-  __ movq(rbx, FieldOperand(rdi, JSFunction::kLiteralsOffset));
-  int literal_offset =
-    FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
-  __ movq(rax, FieldOperand(rbx, literal_offset));
-  __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
-  __ j(not_equal, &done);
-  // Create regexp literal using runtime function
-  // Result will be in rax.
-  __ push(rbx);
-  __ Push(Smi::FromInt(expr->literal_index()));
-  __ Push(expr->pattern());
-  __ Push(expr->flags());
-  __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
-  // Label done:
-  __ bind(&done);
-  Move(expr->location(), rax);
-}
-
-
 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
   Comment cmnt(masm_, "[ ArrayLiteral");
   Label make_clone;
@@ -415,7 +424,7 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
       result_saved = true;
     }
     Visit(subexpr);
-    ASSERT(subexpr->location().is_temporary());
+    ASSERT(subexpr->location().is_value());
 
     // Store the subexpression value in the array's elements.
     __ pop(rax);  // Subexpression value.
@@ -429,10 +438,12 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
   }
 
   switch (expr->location().type()) {
-    case Location::NOWHERE:
+    case Location::UNINITIALIZED:
+      UNREACHABLE();
+    case Location::EFFECT:
       if (result_saved) __ addq(rsp, Immediate(kPointerSize));
       break;
-    case Location::TEMP:
+    case Location::VALUE:
       if (!result_saved) __ push(rax);
       break;
   }
@@ -459,7 +470,7 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
     if (rhs->AsLiteral() != NULL) {
       __ Move(rax, rhs->AsLiteral()->handle());
     } else {
-      ASSERT(rhs->location().is_temporary());
+      ASSERT(rhs->location().is_value());
       Visit(rhs);
       __ pop(rax);
     }
@@ -480,14 +491,16 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
       __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister);
       Move(expr->location(), kScratchRegister);
     } else {
-      ASSERT(rhs->location().is_temporary());
+      ASSERT(rhs->location().is_value());
       Visit(rhs);
       switch (expr->location().type()) {
-        case Location::NOWHERE:
+        case Location::UNINITIALIZED:
+          UNREACHABLE();
+        case Location::EFFECT:
           // Case 'var = temp'.  Discard right-hand-side temporary.
           Move(var->slot(), rhs->location());
           break;
-        case Location::TEMP:
+        case Location::VALUE:
           // Case 'temp1 <- (var = temp0)'.  Preserve right-hand-side
           // temporary on the stack.
           __ movq(kScratchRegister, Operand(rsp, 0));
@@ -532,10 +545,12 @@ void FastCodeGenerator::VisitProperty(Property* expr) {
     __ addq(rsp, Immediate(kPointerSize));
   }
   switch (expr->location().type()) {
-    case Location::TEMP:
+    case Location::UNINITIALIZED:
+      UNREACHABLE();
+    case Location::VALUE:
       __ movq(Operand(rsp, 0), rax);
       break;
-    case Location::NOWHERE:
+    case Location::EFFECT:
       __ addq(rsp, Immediate(kPointerSize));
       break;
   }
@@ -555,7 +570,7 @@ void FastCodeGenerator::VisitCall(Call* expr) {
   int arg_count = args->length();
   for (int i = 0; i < arg_count; i++) {
     Visit(args->at(i));
-    ASSERT(args->at(i)->location().is_temporary());
+    ASSERT(args->at(i)->location().is_value());
   }
   // Record source position for debugger
   SetSourcePosition(expr->position());
@@ -577,7 +592,7 @@ void FastCodeGenerator::VisitCallNew(CallNew* node) {
   // arguments.
   // Push function on the stack.
   Visit(node->expression());
-  ASSERT(node->expression()->location().is_temporary());
+  ASSERT(node->expression()->location().is_value());
   // If location is temporary, already on the stack,
 
   // Push global object (receiver).
@@ -588,7 +603,7 @@ void FastCodeGenerator::VisitCallNew(CallNew* node) {
   int arg_count = args->length();
   for (int i = 0; i < arg_count; i++) {
     Visit(args->at(i));
-    ASSERT(args->at(i)->location().is_temporary());
+    ASSERT(args->at(i)->location().is_value());
     // If location is temporary, it is already on the stack,
     // so nothing to do here.
   }
@@ -621,7 +636,7 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
   int arg_count = args->length();
   for (int i = 0; i < arg_count; i++) {
     Visit(args->at(i));
-    ASSERT(args->at(i)->location().is_temporary());
+    ASSERT(args->at(i)->location().is_value());
   }
 
   __ CallRuntime(function, arg_count);
@@ -649,17 +664,19 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
   // need it as the value of the whole expression.
   if (left->AsLiteral() != NULL) {
     __ Move(rax, left->AsLiteral()->handle());
-    if (destination.is_temporary()) __ push(rax);
+    if (destination.is_value()) __ push(rax);
   } else {
     Visit(left);
-    ASSERT(left->location().is_temporary());
+    ASSERT(left->location().is_value());
     switch (destination.type()) {
-      case Location::NOWHERE:
+      case Location::UNINITIALIZED:
+        UNREACHABLE();
+      case Location::EFFECT:
         // Pop the left-hand value into rax because we will not need it as the
         // final result.
         __ pop(rax);
         break;
-      case Location::TEMP:
+      case Location::VALUE:
         // Copy the left-hand value into rax because we may need it as the
         // final result.
         __ movq(rax, Operand(rsp, 0));
@@ -692,7 +709,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
 
   __ bind(&eval_right);
   // Discard the left-hand value if present on the stack.
-  if (destination.is_temporary()) {
+  if (destination.is_value()) {
     __ addq(rsp, Immediate(kPointerSize));
   }
   // Save or discard the right-hand value as needed.