| 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());
|
|
|