| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 __ ldm(ia_w, sp, fp.bit() | lr.bit()); | 112 __ ldm(ia_w, sp, fp.bit() | lr.bit()); |
| 113 int num_parameters = function_->scope()->num_parameters(); | 113 int num_parameters = function_->scope()->num_parameters(); |
| 114 __ add(sp, sp, Operand((num_parameters + 1) * kPointerSize)); | 114 __ add(sp, sp, Operand((num_parameters + 1) * kPointerSize)); |
| 115 __ Jump(lr); | 115 __ Jump(lr); |
| 116 } | 116 } |
| 117 } | 117 } |
| 118 | 118 |
| 119 | 119 |
| 120 void FastCodeGenerator::Move(Location destination, Slot* source) { | 120 void FastCodeGenerator::Move(Location destination, Slot* source) { |
| 121 switch (destination.type()) { | 121 switch (destination.type()) { |
| 122 case Location::UNINITIALIZED: | 122 case Location::kUninitialized: |
| 123 UNREACHABLE(); | 123 UNREACHABLE(); |
| 124 case Location::EFFECT: | 124 case Location::kEffect: |
| 125 break; | 125 break; |
| 126 case Location::VALUE: | 126 case Location::kValue: |
| 127 __ ldr(ip, MemOperand(fp, SlotOffset(source))); | 127 __ ldr(ip, MemOperand(fp, SlotOffset(source))); |
| 128 __ push(ip); | 128 __ push(ip); |
| 129 break; | 129 break; |
| 130 } | 130 } |
| 131 } | 131 } |
| 132 | 132 |
| 133 | 133 |
| 134 void FastCodeGenerator::Move(Location destination, Literal* expr) { | 134 void FastCodeGenerator::Move(Location destination, Literal* expr) { |
| 135 switch (destination.type()) { | 135 switch (destination.type()) { |
| 136 case Location::UNINITIALIZED: | 136 case Location::kUninitialized: |
| 137 UNREACHABLE(); | 137 UNREACHABLE(); |
| 138 case Location::EFFECT: | 138 case Location::kEffect: |
| 139 break; | 139 break; |
| 140 case Location::VALUE: | 140 case Location::kValue: |
| 141 __ mov(ip, Operand(expr->handle())); | 141 __ mov(ip, Operand(expr->handle())); |
| 142 __ push(ip); | 142 __ push(ip); |
| 143 break; | 143 break; |
| 144 } | 144 } |
| 145 } | 145 } |
| 146 | 146 |
| 147 | 147 |
| 148 void FastCodeGenerator::Move(Slot* destination, Location source) { | 148 void FastCodeGenerator::Move(Slot* destination, Location source) { |
| 149 switch (source.type()) { | 149 switch (source.type()) { |
| 150 case Location::UNINITIALIZED: // Fall through. | 150 case Location::kUninitialized: // Fall through. |
| 151 case Location::EFFECT: | 151 case Location::kEffect: |
| 152 UNREACHABLE(); | 152 UNREACHABLE(); |
| 153 case Location::VALUE: | 153 case Location::kValue: |
| 154 __ pop(ip); | 154 __ pop(ip); |
| 155 __ str(ip, MemOperand(fp, SlotOffset(destination))); | 155 __ str(ip, MemOperand(fp, SlotOffset(destination))); |
| 156 break; | 156 break; |
| 157 } | 157 } |
| 158 } | 158 } |
| 159 | 159 |
| 160 | 160 |
| 161 void FastCodeGenerator::DropAndMove(Location destination, Register source) { | 161 void FastCodeGenerator::DropAndMove(Location destination, Register source) { |
| 162 switch (destination.type()) { | 162 switch (destination.type()) { |
| 163 case Location::UNINITIALIZED: | 163 case Location::kUninitialized: |
| 164 UNREACHABLE(); | 164 UNREACHABLE(); |
| 165 case Location::EFFECT: | 165 case Location::kEffect: |
| 166 __ pop(); | 166 __ pop(); |
| 167 break; | 167 break; |
| 168 case Location::VALUE: | 168 case Location::kValue: |
| 169 __ str(source, MemOperand(sp)); | 169 __ str(source, MemOperand(sp)); |
| 170 break; | 170 break; |
| 171 } | 171 } |
| 172 } | 172 } |
| 173 | 173 |
| 174 | 174 |
| 175 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 175 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
| 176 // Call the runtime to declare the globals. | 176 // Call the runtime to declare the globals. |
| 177 // The context is the first argument. | 177 // The context is the first argument. |
| 178 __ mov(r1, Operand(pairs)); | 178 __ mov(r1, Operand(pairs)); |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 Smi::FromInt(0))); | 355 Smi::FromInt(0))); |
| 356 __ push(r1); | 356 __ push(r1); |
| 357 Visit(value); | 357 Visit(value); |
| 358 ASSERT(value->location().is_value()); | 358 ASSERT(value->location().is_value()); |
| 359 __ CallRuntime(Runtime::kDefineAccessor, 4); | 359 __ CallRuntime(Runtime::kDefineAccessor, 4); |
| 360 __ ldr(r0, MemOperand(sp)); // Restore result into r0 | 360 __ ldr(r0, MemOperand(sp)); // Restore result into r0 |
| 361 break; | 361 break; |
| 362 } | 362 } |
| 363 } | 363 } |
| 364 switch (expr->location().type()) { | 364 switch (expr->location().type()) { |
| 365 case Location::UNINITIALIZED: | 365 case Location::kUninitialized: |
| 366 UNREACHABLE(); | 366 UNREACHABLE(); |
| 367 case Location::EFFECT: | 367 case Location::kEffect: |
| 368 if (result_saved) __ pop(); | 368 if (result_saved) __ pop(); |
| 369 break; | 369 break; |
| 370 case Location::VALUE: | 370 case Location::kValue: |
| 371 if (!result_saved) __ push(r0); | 371 if (!result_saved) __ push(r0); |
| 372 break; | 372 break; |
| 373 } | 373 } |
| 374 } | 374 } |
| 375 | 375 |
| 376 | 376 |
| 377 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { | 377 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
| 378 Comment cmnt(masm_, "[ ArrayLiteral"); | 378 Comment cmnt(masm_, "[ ArrayLiteral"); |
| 379 Label make_clone; | 379 Label make_clone; |
| 380 | 380 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 int offset = FixedArray::kHeaderSize + (i * kPointerSize); | 432 int offset = FixedArray::kHeaderSize + (i * kPointerSize); |
| 433 __ str(r0, FieldMemOperand(r1, offset)); | 433 __ str(r0, FieldMemOperand(r1, offset)); |
| 434 | 434 |
| 435 // Update the write barrier for the array store with r0 as the scratch | 435 // Update the write barrier for the array store with r0 as the scratch |
| 436 // register. | 436 // register. |
| 437 __ mov(r2, Operand(offset)); | 437 __ mov(r2, Operand(offset)); |
| 438 __ RecordWrite(r1, r2, r0); | 438 __ RecordWrite(r1, r2, r0); |
| 439 } | 439 } |
| 440 | 440 |
| 441 switch (expr->location().type()) { | 441 switch (expr->location().type()) { |
| 442 case Location::UNINITIALIZED: | 442 case Location::kUninitialized: |
| 443 UNREACHABLE(); | 443 UNREACHABLE(); |
| 444 case Location::EFFECT: | 444 case Location::kEffect: |
| 445 if (result_saved) __ pop(); | 445 if (result_saved) __ pop(); |
| 446 break; | 446 break; |
| 447 case Location::VALUE: | 447 case Location::kValue: |
| 448 if (!result_saved) __ push(r0); | 448 if (!result_saved) __ push(r0); |
| 449 break; | 449 break; |
| 450 } | 450 } |
| 451 } | 451 } |
| 452 | 452 |
| 453 | 453 |
| 454 void FastCodeGenerator::VisitAssignment(Assignment* expr) { | 454 void FastCodeGenerator::VisitAssignment(Assignment* expr) { |
| 455 Comment cmnt(masm_, "[ Assignment"); | 455 Comment cmnt(masm_, "[ Assignment"); |
| 456 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); | 456 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); |
| 457 | 457 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a | 490 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a |
| 491 // discarded result. Always perform the assignment. | 491 // discarded result. Always perform the assignment. |
| 492 __ mov(ip, Operand(rhs->AsLiteral()->handle())); | 492 __ mov(ip, Operand(rhs->AsLiteral()->handle())); |
| 493 __ str(ip, MemOperand(fp, SlotOffset(var->slot()))); | 493 __ str(ip, MemOperand(fp, SlotOffset(var->slot()))); |
| 494 Move(expr->location(), ip); | 494 Move(expr->location(), ip); |
| 495 } else { | 495 } else { |
| 496 ASSERT(rhs->location().is_value()); | 496 ASSERT(rhs->location().is_value()); |
| 497 Visit(rhs); | 497 Visit(rhs); |
| 498 // Load right-hand side into ip. | 498 // Load right-hand side into ip. |
| 499 switch (expr->location().type()) { | 499 switch (expr->location().type()) { |
| 500 case Location::UNINITIALIZED: | 500 case Location::kUninitialized: |
| 501 UNREACHABLE(); | 501 UNREACHABLE(); |
| 502 case Location::EFFECT: | 502 case Location::kEffect: |
| 503 // Case 'var = temp'. Discard right-hand-side temporary. | 503 // Case 'var = temp'. Discard right-hand-side temporary. |
| 504 __ pop(ip); | 504 __ pop(ip); |
| 505 break; | 505 break; |
| 506 case Location::VALUE: | 506 case Location::kValue: |
| 507 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side | 507 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side |
| 508 // temporary on the stack. | 508 // temporary on the stack. |
| 509 __ ldr(ip, MemOperand(sp)); | 509 __ ldr(ip, MemOperand(sp)); |
| 510 break; | 510 break; |
| 511 } | 511 } |
| 512 // Do the slot assignment. | 512 // Do the slot assignment. |
| 513 __ str(ip, MemOperand(fp, SlotOffset(var->slot()))); | 513 __ str(ip, MemOperand(fp, SlotOffset(var->slot()))); |
| 514 } | 514 } |
| 515 } | 515 } |
| 516 } | 516 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 542 Visit(expr->key()); | 542 Visit(expr->key()); |
| 543 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 543 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
| 544 __ Call(ic, RelocInfo::CODE_TARGET); | 544 __ Call(ic, RelocInfo::CODE_TARGET); |
| 545 // By emitting a nop we make sure that we do not have a "test eax,..." | 545 // By emitting a nop we make sure that we do not have a "test eax,..." |
| 546 // instruction after the call it is treated specially by the LoadIC code. | 546 // instruction after the call it is treated specially by the LoadIC code. |
| 547 __ nop(); | 547 __ nop(); |
| 548 // Drop key and receiver left on the stack by IC. | 548 // Drop key and receiver left on the stack by IC. |
| 549 __ pop(); | 549 __ pop(); |
| 550 } | 550 } |
| 551 switch (expr->location().type()) { | 551 switch (expr->location().type()) { |
| 552 case Location::UNINITIALIZED: | 552 case Location::kUninitialized: |
| 553 UNREACHABLE(); | 553 UNREACHABLE(); |
| 554 case Location::VALUE: | 554 case Location::kValue: |
| 555 __ str(r0, MemOperand(sp)); | 555 __ str(r0, MemOperand(sp)); |
| 556 break; | 556 break; |
| 557 case Location::EFFECT: | 557 case Location::kEffect: |
| 558 __ pop(); | 558 __ pop(); |
| 559 } | 559 } |
| 560 } | 560 } |
| 561 | 561 |
| 562 | 562 |
| 563 void FastCodeGenerator::VisitCall(Call* expr) { | 563 void FastCodeGenerator::VisitCall(Call* expr) { |
| 564 Comment cmnt(masm_, "[ Call"); | 564 Comment cmnt(masm_, "[ Call"); |
| 565 Expression* fun = expr->expression(); | 565 Expression* fun = expr->expression(); |
| 566 ZoneList<Expression*>* args = expr->arguments(); | 566 ZoneList<Expression*>* args = expr->arguments(); |
| 567 Variable* var = fun->AsVariableProxy()->AsVariable(); | 567 Variable* var = fun->AsVariableProxy()->AsVariable(); |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 677 // The left-hand value is in on top of the stack. It is duplicated on the | 677 // The left-hand value is in on top of the stack. It is duplicated on the |
| 678 // stack iff the destination location is temporary. | 678 // stack iff the destination location is temporary. |
| 679 __ CallRuntime(Runtime::kToBool, 1); | 679 __ CallRuntime(Runtime::kToBool, 1); |
| 680 __ LoadRoot(ip, Heap::kTrueValueRootIndex); | 680 __ LoadRoot(ip, Heap::kTrueValueRootIndex); |
| 681 __ cmp(r0, ip); | 681 __ cmp(r0, ip); |
| 682 __ b(eq, &done); | 682 __ b(eq, &done); |
| 683 | 683 |
| 684 // Discard the left-hand value if present on the stack. | 684 // Discard the left-hand value if present on the stack. |
| 685 if (destination.is_value()) __ pop(); | 685 if (destination.is_value()) __ pop(); |
| 686 // Save or discard the right-hand value as needed. | 686 // Save or discard the right-hand value as needed. |
| 687 if (right->AsLiteral() != NULL) { | 687 Visit(right); |
| 688 Move(destination, right->AsLiteral()); | 688 ASSERT_EQ(destination.type(), right->location().type()); |
| 689 } else { | |
| 690 Visit(right); | |
| 691 Move(destination, right->location()); | |
| 692 } | |
| 693 | 689 |
| 694 __ bind(&done); | 690 __ bind(&done); |
| 695 } | 691 } |
| 696 | 692 |
| 697 } } // namespace v8::internal | 693 } } // namespace v8::internal |
| OLD | NEW |