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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 // patch with the code required by the debugger. | 103 // patch with the code required by the debugger. |
104 __ mov(esp, ebp); | 104 __ mov(esp, ebp); |
105 __ pop(ebp); | 105 __ pop(ebp); |
106 __ ret((fun->scope()->num_parameters() + 1) * kPointerSize); | 106 __ ret((fun->scope()->num_parameters() + 1) * kPointerSize); |
107 } | 107 } |
108 } | 108 } |
109 | 109 |
110 | 110 |
111 void FastCodeGenerator::Move(Location destination, Slot* source) { | 111 void FastCodeGenerator::Move(Location destination, Slot* source) { |
112 switch (destination.type()) { | 112 switch (destination.type()) { |
113 case Location::UNINITIALIZED: | 113 case Location::kUninitialized: |
114 UNREACHABLE(); | 114 UNREACHABLE(); |
115 case Location::EFFECT: | 115 case Location::kEffect: |
116 break; | 116 break; |
117 case Location::VALUE: | 117 case Location::kValue: |
118 __ push(Operand(ebp, SlotOffset(source))); | 118 __ push(Operand(ebp, SlotOffset(source))); |
119 break; | 119 break; |
120 } | 120 } |
121 } | 121 } |
122 | 122 |
123 | 123 |
124 void FastCodeGenerator::Move(Location destination, Literal* expr) { | 124 void FastCodeGenerator::Move(Location destination, Literal* expr) { |
125 switch (destination.type()) { | 125 switch (destination.type()) { |
126 case Location::UNINITIALIZED: | 126 case Location::kUninitialized: |
127 UNREACHABLE(); | 127 UNREACHABLE(); |
128 case Location::EFFECT: | 128 case Location::kEffect: |
129 break; | 129 break; |
130 case Location::VALUE: | 130 case Location::kValue: |
131 __ push(Immediate(expr->handle())); | 131 __ push(Immediate(expr->handle())); |
132 break; | 132 break; |
133 } | 133 } |
134 } | 134 } |
135 | 135 |
136 | 136 |
137 void FastCodeGenerator::Move(Slot* destination, Location source) { | 137 void FastCodeGenerator::Move(Slot* destination, Location source) { |
138 switch (source.type()) { | 138 switch (source.type()) { |
139 case Location::UNINITIALIZED: // Fall through. | 139 case Location::kUninitialized: // Fall through. |
140 case Location::EFFECT: | 140 case Location::kEffect: |
141 UNREACHABLE(); | 141 UNREACHABLE(); |
142 case Location::VALUE: | 142 case Location::kValue: |
143 __ pop(Operand(ebp, SlotOffset(destination))); | 143 __ pop(Operand(ebp, SlotOffset(destination))); |
144 break; | 144 break; |
145 } | 145 } |
146 } | 146 } |
147 | 147 |
148 | 148 |
149 void FastCodeGenerator::DropAndMove(Location destination, Register source) { | 149 void FastCodeGenerator::DropAndMove(Location destination, Register source) { |
150 switch (destination.type()) { | 150 switch (destination.type()) { |
151 case Location::UNINITIALIZED: | 151 case Location::kUninitialized: |
152 UNREACHABLE(); | 152 UNREACHABLE(); |
153 case Location::EFFECT: | 153 case Location::kEffect: |
154 __ add(Operand(esp), Immediate(kPointerSize)); | 154 __ add(Operand(esp), Immediate(kPointerSize)); |
155 break; | 155 break; |
156 case Location::VALUE: | 156 case Location::kValue: |
157 __ mov(Operand(esp, 0), source); | 157 __ mov(Operand(esp, 0), source); |
158 break; | 158 break; |
159 } | 159 } |
160 } | 160 } |
161 | 161 |
162 | 162 |
163 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 163 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
164 // Call the runtime to declare the globals. | 164 // Call the runtime to declare the globals. |
165 __ push(esi); // The context is the first argument. | 165 __ push(esi); // The context is the first argument. |
166 __ push(Immediate(pairs)); | 166 __ push(Immediate(pairs)); |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 Smi::FromInt(0))); | 345 Smi::FromInt(0))); |
346 Visit(value); | 346 Visit(value); |
347 ASSERT(value->location().is_value()); | 347 ASSERT(value->location().is_value()); |
348 __ CallRuntime(Runtime::kDefineAccessor, 4); | 348 __ CallRuntime(Runtime::kDefineAccessor, 4); |
349 __ mov(eax, Operand(esp, 0)); // Restore result into eax. | 349 __ mov(eax, Operand(esp, 0)); // Restore result into eax. |
350 break; | 350 break; |
351 default: UNREACHABLE(); | 351 default: UNREACHABLE(); |
352 } | 352 } |
353 } | 353 } |
354 switch (expr->location().type()) { | 354 switch (expr->location().type()) { |
355 case Location::UNINITIALIZED: | 355 case Location::kUninitialized: |
356 UNREACHABLE(); | 356 UNREACHABLE(); |
357 case Location::EFFECT: | 357 case Location::kEffect: |
358 if (result_saved) __ add(Operand(esp), Immediate(kPointerSize)); | 358 if (result_saved) __ add(Operand(esp), Immediate(kPointerSize)); |
359 break; | 359 break; |
360 case Location::VALUE: | 360 case Location::kValue: |
361 if (!result_saved) __ push(eax); | 361 if (!result_saved) __ push(eax); |
362 break; | 362 break; |
363 } | 363 } |
364 } | 364 } |
365 | 365 |
366 | 366 |
367 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { | 367 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
368 Comment cmnt(masm_, "[ ArrayLiteral"); | 368 Comment cmnt(masm_, "[ ArrayLiteral"); |
369 Label make_clone; | 369 Label make_clone; |
370 | 370 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 __ mov(ebx, Operand(esp, 0)); // Copy of array literal. | 419 __ mov(ebx, Operand(esp, 0)); // Copy of array literal. |
420 __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset)); | 420 __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset)); |
421 int offset = FixedArray::kHeaderSize + (i * kPointerSize); | 421 int offset = FixedArray::kHeaderSize + (i * kPointerSize); |
422 __ mov(FieldOperand(ebx, offset), eax); | 422 __ mov(FieldOperand(ebx, offset), eax); |
423 | 423 |
424 // Update the write barrier for the array store. | 424 // Update the write barrier for the array store. |
425 __ RecordWrite(ebx, offset, eax, ecx); | 425 __ RecordWrite(ebx, offset, eax, ecx); |
426 } | 426 } |
427 | 427 |
428 switch (expr->location().type()) { | 428 switch (expr->location().type()) { |
429 case Location::UNINITIALIZED: | 429 case Location::kUninitialized: |
430 UNREACHABLE(); | 430 UNREACHABLE(); |
431 case Location::EFFECT: | 431 case Location::kEffect: |
432 if (result_saved) __ add(Operand(esp), Immediate(kPointerSize)); | 432 if (result_saved) __ add(Operand(esp), Immediate(kPointerSize)); |
433 break; | 433 break; |
434 case Location::VALUE: | 434 case Location::kValue: |
435 if (!result_saved) __ push(eax); | 435 if (!result_saved) __ push(eax); |
436 break; | 436 break; |
437 } | 437 } |
438 } | 438 } |
439 | 439 |
440 | 440 |
441 void FastCodeGenerator::VisitAssignment(Assignment* expr) { | 441 void FastCodeGenerator::VisitAssignment(Assignment* expr) { |
442 Comment cmnt(masm_, "[ Assignment"); | 442 Comment cmnt(masm_, "[ Assignment"); |
443 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); | 443 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); |
444 | 444 |
(...skipping 29 matching lines...) Expand all Loading... |
474 if (rhs->AsLiteral() != NULL) { | 474 if (rhs->AsLiteral() != NULL) { |
475 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a | 475 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a |
476 // discarded result. Always perform the assignment. | 476 // discarded result. Always perform the assignment. |
477 __ mov(eax, rhs->AsLiteral()->handle()); | 477 __ mov(eax, rhs->AsLiteral()->handle()); |
478 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); | 478 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); |
479 Move(expr->location(), eax); | 479 Move(expr->location(), eax); |
480 } else { | 480 } else { |
481 ASSERT(rhs->location().is_value()); | 481 ASSERT(rhs->location().is_value()); |
482 Visit(rhs); | 482 Visit(rhs); |
483 switch (expr->location().type()) { | 483 switch (expr->location().type()) { |
484 case Location::UNINITIALIZED: | 484 case Location::kUninitialized: |
485 UNREACHABLE(); | 485 UNREACHABLE(); |
486 case Location::EFFECT: | 486 case Location::kEffect: |
487 // Case 'var = temp'. Discard right-hand-side temporary. | 487 // Case 'var = temp'. Discard right-hand-side temporary. |
488 Move(var->slot(), rhs->location()); | 488 Move(var->slot(), rhs->location()); |
489 break; | 489 break; |
490 case Location::VALUE: | 490 case Location::kValue: |
491 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side | 491 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side |
492 // temporary on the stack. | 492 // temporary on the stack. |
493 __ mov(eax, Operand(esp, 0)); | 493 __ mov(eax, Operand(esp, 0)); |
494 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); | 494 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); |
495 break; | 495 break; |
496 } | 496 } |
497 } | 497 } |
498 } | 498 } |
499 } | 499 } |
500 | 500 |
(...skipping 24 matching lines...) Expand all Loading... |
525 Visit(expr->key()); | 525 Visit(expr->key()); |
526 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 526 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
527 __ call(ic, RelocInfo::CODE_TARGET); | 527 __ call(ic, RelocInfo::CODE_TARGET); |
528 // By emitting a nop we make sure that we do not have a "test eax,..." | 528 // By emitting a nop we make sure that we do not have a "test eax,..." |
529 // instruction after the call it is treated specially by the LoadIC code. | 529 // instruction after the call it is treated specially by the LoadIC code. |
530 __ nop(); | 530 __ nop(); |
531 // Drop key left on the stack by IC. | 531 // Drop key left on the stack by IC. |
532 __ add(Operand(esp), Immediate(kPointerSize)); | 532 __ add(Operand(esp), Immediate(kPointerSize)); |
533 } | 533 } |
534 switch (expr->location().type()) { | 534 switch (expr->location().type()) { |
535 case Location::UNINITIALIZED: | 535 case Location::kUninitialized: |
536 UNREACHABLE(); | 536 UNREACHABLE(); |
537 case Location::VALUE: | 537 case Location::kValue: |
538 __ mov(Operand(esp, 0), eax); | 538 __ mov(Operand(esp, 0), eax); |
539 break; | 539 break; |
540 case Location::EFFECT: | 540 case Location::kEffect: |
541 __ add(Operand(esp), Immediate(kPointerSize)); | 541 __ add(Operand(esp), Immediate(kPointerSize)); |
542 break; | 542 break; |
543 } | 543 } |
544 } | 544 } |
545 | 545 |
546 | 546 |
547 void FastCodeGenerator::VisitCall(Call* expr) { | 547 void FastCodeGenerator::VisitCall(Call* expr) { |
548 Expression* fun = expr->expression(); | 548 Expression* fun = expr->expression(); |
549 ZoneList<Expression*>* args = expr->arguments(); | 549 ZoneList<Expression*>* args = expr->arguments(); |
550 Variable* var = fun->AsVariableProxy()->AsVariable(); | 550 Variable* var = fun->AsVariableProxy()->AsVariable(); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
648 | 648 |
649 // Compile the left-hand value into eax. Put it on the stack if we may | 649 // Compile the left-hand value into eax. Put it on the stack if we may |
650 // need it as the value of the whole expression. | 650 // need it as the value of the whole expression. |
651 if (left->AsLiteral() != NULL) { | 651 if (left->AsLiteral() != NULL) { |
652 __ mov(eax, left->AsLiteral()->handle()); | 652 __ mov(eax, left->AsLiteral()->handle()); |
653 if (destination.is_value()) __ push(eax); | 653 if (destination.is_value()) __ push(eax); |
654 } else { | 654 } else { |
655 Visit(left); | 655 Visit(left); |
656 ASSERT(left->location().is_value()); | 656 ASSERT(left->location().is_value()); |
657 switch (destination.type()) { | 657 switch (destination.type()) { |
658 case Location::UNINITIALIZED: | 658 case Location::kUninitialized: |
659 UNREACHABLE(); | 659 UNREACHABLE(); |
660 case Location::EFFECT: | 660 case Location::kEffect: |
661 // Pop the left-hand value into eax because we will not need it as the | 661 // Pop the left-hand value into eax because we will not need it as the |
662 // final result. | 662 // final result. |
663 __ pop(eax); | 663 __ pop(eax); |
664 break; | 664 break; |
665 case Location::VALUE: | 665 case Location::kValue: |
666 // Copy the left-hand value into eax because we may need it as the | 666 // Copy the left-hand value into eax because we may need it as the |
667 // final result. | 667 // final result. |
668 __ mov(eax, Operand(esp, 0)); | 668 __ mov(eax, Operand(esp, 0)); |
669 break; | 669 break; |
670 } | 670 } |
671 } | 671 } |
672 // The left-hand value is in eax. It is also on the stack iff the | 672 // The left-hand value is in eax. It is also on the stack iff the |
673 // destination location is temporary. | 673 // destination location is temporary. |
674 | 674 |
675 // Perform fast checks assumed by the stub. | 675 // Perform fast checks assumed by the stub. |
(...skipping 15 matching lines...) Expand all Loading... |
691 __ CallStub(&stub); | 691 __ CallStub(&stub); |
692 __ test(eax, Operand(eax)); // The stub returns nonzero for true. | 692 __ test(eax, Operand(eax)); // The stub returns nonzero for true. |
693 __ j(not_zero, &done); | 693 __ j(not_zero, &done); |
694 | 694 |
695 __ bind(&eval_right); | 695 __ bind(&eval_right); |
696 // Discard the left-hand value if present on the stack. | 696 // Discard the left-hand value if present on the stack. |
697 if (destination.is_value()) { | 697 if (destination.is_value()) { |
698 __ add(Operand(esp), Immediate(kPointerSize)); | 698 __ add(Operand(esp), Immediate(kPointerSize)); |
699 } | 699 } |
700 // Save or discard the right-hand value as needed. | 700 // Save or discard the right-hand value as needed. |
701 if (right->AsLiteral() != NULL) { | 701 Visit(right); |
702 Move(destination, right->AsLiteral()); | 702 ASSERT_EQ(destination.type(), right->location().type()); |
703 } else { | |
704 Visit(right); | |
705 Move(destination, right->location()); | |
706 } | |
707 | 703 |
708 __ bind(&done); | 704 __ bind(&done); |
709 } | 705 } |
710 | 706 |
711 | 707 |
712 } } // namespace v8::internal | 708 } } // namespace v8::internal |
OLD | NEW |