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 |