Index: src/arm/fast-codegen-arm.cc |
=================================================================== |
--- src/arm/fast-codegen-arm.cc (revision 3167) |
+++ src/arm/fast-codegen-arm.cc (working copy) |
@@ -119,9 +119,11 @@ |
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, 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(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::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::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 @@ |
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 @@ |
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 @@ |
} |
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 @@ |
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 @@ |
__ 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 @@ |
__ 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 @@ |
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 @@ |
// 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 @@ |
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 @@ |
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 @@ |
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 @@ |
__ 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()); |