| 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 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 case Location::NOWHERE: | 146 case Location::NOWHERE: |
| 147 UNREACHABLE(); | 147 UNREACHABLE(); |
| 148 case Location::TEMP: | 148 case Location::TEMP: |
| 149 __ pop(ip); | 149 __ pop(ip); |
| 150 __ str(ip, MemOperand(fp, SlotOffset(destination))); | 150 __ str(ip, MemOperand(fp, SlotOffset(destination))); |
| 151 break; | 151 break; |
| 152 } | 152 } |
| 153 } | 153 } |
| 154 | 154 |
| 155 | 155 |
| 156 void FastCodeGenerator::DropAndMove(Location destination, Register source) { |
| 157 switch (destination.type()) { |
| 158 case Location::NOWHERE: |
| 159 __ pop(); |
| 160 break; |
| 161 case Location::TEMP: |
| 162 __ str(source, MemOperand(sp)); |
| 163 break; |
| 164 } |
| 165 } |
| 166 |
| 167 |
| 156 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 168 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
| 157 // Call the runtime to declare the globals. | 169 // Call the runtime to declare the globals. |
| 158 // The context is the first argument. | 170 // The context is the first argument. |
| 159 __ mov(r1, Operand(pairs)); | 171 __ mov(r1, Operand(pairs)); |
| 160 __ mov(r0, Operand(Smi::FromInt(is_eval_ ? 1 : 0))); | 172 __ mov(r0, Operand(Smi::FromInt(is_eval_ ? 1 : 0))); |
| 161 __ stm(db_w, sp, cp.bit() | r1.bit() | r0.bit()); | 173 __ stm(db_w, sp, cp.bit() | r1.bit() | r0.bit()); |
| 162 __ CallRuntime(Runtime::kDeclareGlobals, 3); | 174 __ CallRuntime(Runtime::kDeclareGlobals, 3); |
| 163 // Return value is ignored. | 175 // Return value is ignored. |
| 164 } | 176 } |
| 165 | 177 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 Expression* rewrite = expr->var()->rewrite(); | 224 Expression* rewrite = expr->var()->rewrite(); |
| 213 if (rewrite == NULL) { | 225 if (rewrite == NULL) { |
| 214 Comment cmnt(masm_, "Global variable"); | 226 Comment cmnt(masm_, "Global variable"); |
| 215 // Use inline caching. Variable name is passed in r2 and the global | 227 // Use inline caching. Variable name is passed in r2 and the global |
| 216 // object on the stack. | 228 // object on the stack. |
| 217 __ ldr(ip, CodeGenerator::GlobalObject()); | 229 __ ldr(ip, CodeGenerator::GlobalObject()); |
| 218 __ push(ip); | 230 __ push(ip); |
| 219 __ mov(r2, Operand(expr->name())); | 231 __ mov(r2, Operand(expr->name())); |
| 220 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 232 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
| 221 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); | 233 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 222 switch (expr->location().type()) { | 234 DropAndMove(expr->location(), r0); |
| 223 case Location::NOWHERE: | |
| 224 __ pop(); | |
| 225 break; | |
| 226 case Location::TEMP: | |
| 227 // Replace the global object with the result. | |
| 228 __ str(r0, MemOperand(sp)); | |
| 229 break; | |
| 230 } | |
| 231 | |
| 232 } else { | 235 } else { |
| 233 Comment cmnt(masm_, "Stack slot"); | 236 Comment cmnt(masm_, "Stack slot"); |
| 234 Move(expr->location(), rewrite->AsSlot()); | 237 Move(expr->location(), rewrite->AsSlot()); |
| 235 } | 238 } |
| 236 } | 239 } |
| 237 | 240 |
| 238 | 241 |
| 239 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { | 242 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
| 240 Comment cmnt(masm_, "[ ObjectLiteral"); | 243 Comment cmnt(masm_, "[ ObjectLiteral"); |
| 241 Label boilerplate_exists; | 244 Label boilerplate_exists; |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 449 ASSERT(rhs->location().is_temporary()); | 452 ASSERT(rhs->location().is_temporary()); |
| 450 Visit(rhs); | 453 Visit(rhs); |
| 451 __ pop(r0); | 454 __ pop(r0); |
| 452 } | 455 } |
| 453 __ mov(r2, Operand(var->name())); | 456 __ mov(r2, Operand(var->name())); |
| 454 __ ldr(ip, CodeGenerator::GlobalObject()); | 457 __ ldr(ip, CodeGenerator::GlobalObject()); |
| 455 __ push(ip); | 458 __ push(ip); |
| 456 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 459 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
| 457 __ Call(ic, RelocInfo::CODE_TARGET); | 460 __ Call(ic, RelocInfo::CODE_TARGET); |
| 458 // Overwrite the global object on the stack with the result if needed. | 461 // Overwrite the global object on the stack with the result if needed. |
| 459 switch (expr->location().type()) { | 462 DropAndMove(expr->location(), r0); |
| 460 case Location::NOWHERE: | |
| 461 __ pop(); | |
| 462 break; | |
| 463 case Location::TEMP: | |
| 464 __ str(r0, MemOperand(sp)); | |
| 465 break; | |
| 466 } | |
| 467 | |
| 468 } else { | 463 } else { |
| 469 // Local or parameter assignment. | 464 // Local or parameter assignment. |
| 470 | 465 |
| 471 // Code for the right-hand side expression depends on its type. | 466 // Code for the right-hand side expression depends on its type. |
| 472 if (rhs->AsLiteral() != NULL) { | 467 if (rhs->AsLiteral() != NULL) { |
| 473 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a | 468 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a |
| 474 // discarded result. Always perform the assignment. | 469 // discarded result. Always perform the assignment. |
| 475 __ mov(ip, Operand(rhs->AsLiteral()->handle())); | 470 __ mov(ip, Operand(rhs->AsLiteral()->handle())); |
| 476 __ str(ip, MemOperand(fp, SlotOffset(var->slot()))); | 471 __ str(ip, MemOperand(fp, SlotOffset(var->slot()))); |
| 477 Move(expr->location(), ip); | 472 Move(expr->location(), ip); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 554 ASSERT(args->at(i)->location().is_temporary()); | 549 ASSERT(args->at(i)->location().is_temporary()); |
| 555 } | 550 } |
| 556 // Record source position for debugger | 551 // Record source position for debugger |
| 557 SetSourcePosition(expr->position()); | 552 SetSourcePosition(expr->position()); |
| 558 // Call the IC initialization code. | 553 // Call the IC initialization code. |
| 559 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, | 554 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, |
| 560 NOT_IN_LOOP); | 555 NOT_IN_LOOP); |
| 561 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); | 556 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 562 // Restore context register. | 557 // Restore context register. |
| 563 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 558 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 564 switch (expr->location().type()) { | 559 DropAndMove(expr->location(), r0); |
| 565 case Location::NOWHERE: | |
| 566 __ pop(); | |
| 567 break; | |
| 568 case Location::TEMP: | |
| 569 __ str(r0, MemOperand(sp)); | |
| 570 break; | |
| 571 } | |
| 572 } | 560 } |
| 573 | 561 |
| 574 | 562 |
| 575 void FastCodeGenerator::VisitCallNew(CallNew* node) { | 563 void FastCodeGenerator::VisitCallNew(CallNew* node) { |
| 576 Comment cmnt(masm_, "[ CallNew"); | 564 Comment cmnt(masm_, "[ CallNew"); |
| 577 // According to ECMA-262, section 11.2.2, page 44, the function | 565 // According to ECMA-262, section 11.2.2, page 44, the function |
| 578 // expression in new calls must be evaluated before the | 566 // expression in new calls must be evaluated before the |
| 579 // arguments. | 567 // arguments. |
| 580 // Push function on the stack. | 568 // Push function on the stack. |
| 581 Visit(node->expression()); | 569 Visit(node->expression()); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 600 | 588 |
| 601 // Load function, arg_count into r1 and r0. | 589 // Load function, arg_count into r1 and r0. |
| 602 __ mov(r0, Operand(arg_count)); | 590 __ mov(r0, Operand(arg_count)); |
| 603 // Function is in esp[arg_count + 1]. | 591 // Function is in esp[arg_count + 1]. |
| 604 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 592 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 605 | 593 |
| 606 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall)); | 594 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall)); |
| 607 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); | 595 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); |
| 608 | 596 |
| 609 // Replace function on TOS with result in r0, or pop it. | 597 // Replace function on TOS with result in r0, or pop it. |
| 610 switch (node->location().type()) { | 598 DropAndMove(node->location(), r0); |
| 611 case Location::TEMP: | |
| 612 __ str(r0, MemOperand(sp, 0)); | |
| 613 break; | |
| 614 case Location::NOWHERE: | |
| 615 __ pop(); | |
| 616 break; | |
| 617 } | |
| 618 } | 599 } |
| 619 | 600 |
| 620 | 601 |
| 621 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 602 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
| 622 Comment cmnt(masm_, "[ CallRuntime"); | 603 Comment cmnt(masm_, "[ CallRuntime"); |
| 623 ZoneList<Expression*>* args = expr->arguments(); | 604 ZoneList<Expression*>* args = expr->arguments(); |
| 624 Runtime::Function* function = expr->function(); | 605 Runtime::Function* function = expr->function(); |
| 625 | 606 |
| 626 ASSERT(function != NULL); | 607 ASSERT(function != NULL); |
| 627 | 608 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 678 Move(destination, right->AsLiteral()); | 659 Move(destination, right->AsLiteral()); |
| 679 } else { | 660 } else { |
| 680 Visit(right); | 661 Visit(right); |
| 681 Move(destination, right->location()); | 662 Move(destination, right->location()); |
| 682 } | 663 } |
| 683 | 664 |
| 684 __ bind(&done); | 665 __ bind(&done); |
| 685 } | 666 } |
| 686 | 667 |
| 687 } } // namespace v8::internal | 668 } } // namespace v8::internal |
| OLD | NEW |