| 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 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 switch (source.type()) { | 134 switch (source.type()) { |
| 135 case Location::NOWHERE: | 135 case Location::NOWHERE: |
| 136 UNREACHABLE(); | 136 UNREACHABLE(); |
| 137 case Location::TEMP: | 137 case Location::TEMP: |
| 138 __ pop(Operand(ebp, SlotOffset(destination))); | 138 __ pop(Operand(ebp, SlotOffset(destination))); |
| 139 break; | 139 break; |
| 140 } | 140 } |
| 141 } | 141 } |
| 142 | 142 |
| 143 | 143 |
| 144 void FastCodeGenerator::DropAndMove(Location destination, Register source) { |
| 145 switch (destination.type()) { |
| 146 case Location::NOWHERE: |
| 147 __ add(Operand(esp), Immediate(kPointerSize)); |
| 148 break; |
| 149 case Location::TEMP: |
| 150 __ mov(Operand(esp, 0), source); |
| 151 break; |
| 152 } |
| 153 } |
| 154 |
| 155 |
| 144 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 156 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
| 145 // Call the runtime to declare the globals. | 157 // Call the runtime to declare the globals. |
| 146 __ push(esi); // The context is the first argument. | 158 __ push(esi); // The context is the first argument. |
| 147 __ push(Immediate(pairs)); | 159 __ push(Immediate(pairs)); |
| 148 __ push(Immediate(Smi::FromInt(is_eval_ ? 1 : 0))); | 160 __ push(Immediate(Smi::FromInt(is_eval_ ? 1 : 0))); |
| 149 __ CallRuntime(Runtime::kDeclareGlobals, 3); | 161 __ CallRuntime(Runtime::kDeclareGlobals, 3); |
| 150 // Return value is ignored. | 162 // Return value is ignored. |
| 151 } | 163 } |
| 152 | 164 |
| 153 | 165 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 __ push(CodeGenerator::GlobalObject()); | 216 __ push(CodeGenerator::GlobalObject()); |
| 205 __ mov(ecx, expr->name()); | 217 __ mov(ecx, expr->name()); |
| 206 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 218 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
| 207 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); | 219 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 208 // By emitting a nop we make sure that we do not have a test eax | 220 // By emitting a nop we make sure that we do not have a test eax |
| 209 // instruction after the call it is treated specially by the LoadIC code | 221 // instruction after the call it is treated specially by the LoadIC code |
| 210 // Remember that the assembler may choose to do peephole optimization | 222 // Remember that the assembler may choose to do peephole optimization |
| 211 // (eg, push/pop elimination). | 223 // (eg, push/pop elimination). |
| 212 __ nop(); | 224 __ nop(); |
| 213 | 225 |
| 214 switch (expr->location().type()) { | 226 DropAndMove(expr->location(), eax); |
| 215 case Location::NOWHERE: | |
| 216 __ add(Operand(esp), Immediate(kPointerSize)); | |
| 217 break; | |
| 218 case Location::TEMP: | |
| 219 // Replace the global object with the result. | |
| 220 __ mov(Operand(esp, 0), eax); | |
| 221 break; | |
| 222 } | |
| 223 | |
| 224 } else { | 227 } else { |
| 225 Comment cmnt(masm_, "Stack slot"); | 228 Comment cmnt(masm_, "Stack slot"); |
| 226 Move(expr->location(), rewrite->AsSlot()); | 229 Move(expr->location(), rewrite->AsSlot()); |
| 227 } | 230 } |
| 228 } | 231 } |
| 229 | 232 |
| 230 | 233 |
| 231 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { | 234 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
| 232 Comment cmnt(masm_, "[ ObjectLiteral"); | 235 Comment cmnt(masm_, "[ ObjectLiteral"); |
| 233 Label exists; | 236 Label exists; |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 448 } else { | 451 } else { |
| 449 ASSERT(rhs->location().is_temporary()); | 452 ASSERT(rhs->location().is_temporary()); |
| 450 Visit(rhs); | 453 Visit(rhs); |
| 451 __ pop(eax); | 454 __ pop(eax); |
| 452 } | 455 } |
| 453 __ mov(ecx, var->name()); | 456 __ mov(ecx, var->name()); |
| 454 __ push(CodeGenerator::GlobalObject()); | 457 __ push(CodeGenerator::GlobalObject()); |
| 455 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 458 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
| 456 __ call(ic, RelocInfo::CODE_TARGET); | 459 __ call(ic, RelocInfo::CODE_TARGET); |
| 457 // Overwrite the global object on the stack with the result if needed. | 460 // Overwrite the global object on the stack with the result if needed. |
| 458 switch (expr->location().type()) { | 461 DropAndMove(expr->location(), eax); |
| 459 case Location::NOWHERE: | |
| 460 __ add(Operand(esp), Immediate(kPointerSize)); | |
| 461 break; | |
| 462 case Location::TEMP: | |
| 463 __ mov(Operand(esp, 0), eax); | |
| 464 break; | |
| 465 } | |
| 466 } else { | 462 } else { |
| 467 // Local or parameter assignment. | 463 // Local or parameter assignment. |
| 468 | 464 |
| 469 // Code for the right-hand side expression depends on its type. | 465 // Code for the right-hand side expression depends on its type. |
| 470 if (rhs->AsLiteral() != NULL) { | 466 if (rhs->AsLiteral() != NULL) { |
| 471 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a | 467 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a |
| 472 // discarded result. Always perform the assignment. | 468 // discarded result. Always perform the assignment. |
| 473 __ mov(eax, rhs->AsLiteral()->handle()); | 469 __ mov(eax, rhs->AsLiteral()->handle()); |
| 474 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); | 470 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); |
| 475 Move(expr->location(), eax); | 471 Move(expr->location(), eax); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 550 } | 546 } |
| 551 // Record source position for debugger | 547 // Record source position for debugger |
| 552 SetSourcePosition(expr->position()); | 548 SetSourcePosition(expr->position()); |
| 553 // Call the IC initialization code. | 549 // Call the IC initialization code. |
| 554 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, | 550 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, |
| 555 NOT_IN_LOOP); | 551 NOT_IN_LOOP); |
| 556 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); | 552 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 557 // Restore context register. | 553 // Restore context register. |
| 558 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 554 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 559 // Discard the function left on TOS. | 555 // Discard the function left on TOS. |
| 560 switch (expr->location().type()) { | 556 DropAndMove(expr->location(), eax); |
| 561 case Location::NOWHERE: | |
| 562 __ add(Operand(esp), Immediate(kPointerSize)); | |
| 563 break; | |
| 564 case Location::TEMP: | |
| 565 __ mov(Operand(esp, 0), eax); | |
| 566 break; | |
| 567 } | |
| 568 } | 557 } |
| 569 | 558 |
| 570 | 559 |
| 571 void FastCodeGenerator::VisitCallNew(CallNew* node) { | 560 void FastCodeGenerator::VisitCallNew(CallNew* node) { |
| 572 Comment cmnt(masm_, "[ CallNew"); | 561 Comment cmnt(masm_, "[ CallNew"); |
| 573 // According to ECMA-262, section 11.2.2, page 44, the function | 562 // According to ECMA-262, section 11.2.2, page 44, the function |
| 574 // expression in new calls must be evaluated before the | 563 // expression in new calls must be evaluated before the |
| 575 // arguments. | 564 // arguments. |
| 576 // Push function on the stack. | 565 // Push function on the stack. |
| 577 Visit(node->expression()); | 566 Visit(node->expression()); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 596 | 585 |
| 597 // Load function, arg_count into edi and eax. | 586 // Load function, arg_count into edi and eax. |
| 598 __ Set(eax, Immediate(arg_count)); | 587 __ Set(eax, Immediate(arg_count)); |
| 599 // Function is in esp[arg_count + 1]. | 588 // Function is in esp[arg_count + 1]. |
| 600 __ mov(edi, Operand(esp, eax, times_pointer_size, kPointerSize)); | 589 __ mov(edi, Operand(esp, eax, times_pointer_size, kPointerSize)); |
| 601 | 590 |
| 602 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall)); | 591 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall)); |
| 603 __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL); | 592 __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL); |
| 604 | 593 |
| 605 // Replace function on TOS with result in eax, or pop it. | 594 // Replace function on TOS with result in eax, or pop it. |
| 606 switch (node->location().type()) { | 595 DropAndMove(node->location(), eax); |
| 607 case Location::TEMP: | |
| 608 __ mov(Operand(esp, 0), eax); | |
| 609 break; | |
| 610 case Location::NOWHERE: | |
| 611 __ add(Operand(esp), Immediate(kPointerSize)); | |
| 612 break; | |
| 613 } | |
| 614 } | 596 } |
| 615 | 597 |
| 616 | 598 |
| 617 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 599 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
| 618 Comment cmnt(masm_, "[ CallRuntime"); | 600 Comment cmnt(masm_, "[ CallRuntime"); |
| 619 ZoneList<Expression*>* args = expr->arguments(); | 601 ZoneList<Expression*>* args = expr->arguments(); |
| 620 Runtime::Function* function = expr->function(); | 602 Runtime::Function* function = expr->function(); |
| 621 | 603 |
| 622 ASSERT(function != NULL); | 604 ASSERT(function != NULL); |
| 623 | 605 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 } else { | 686 } else { |
| 705 Visit(right); | 687 Visit(right); |
| 706 Move(destination, right->location()); | 688 Move(destination, right->location()); |
| 707 } | 689 } |
| 708 | 690 |
| 709 __ bind(&done); | 691 __ bind(&done); |
| 710 } | 692 } |
| 711 | 693 |
| 712 | 694 |
| 713 } } // namespace v8::internal | 695 } } // namespace v8::internal |
| OLD | NEW |