OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-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 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
602 frame_->Push(Factory::the_hole_value()); | 602 frame_->Push(Factory::the_hole_value()); |
603 } else { | 603 } else { |
604 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); | 604 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); |
605 frame_->PushFunction(); | 605 frame_->PushFunction(); |
606 frame_->PushReceiverSlotAddress(); | 606 frame_->PushReceiverSlotAddress(); |
607 frame_->Push(Smi::FromInt(scope_->num_parameters())); | 607 frame_->Push(Smi::FromInt(scope_->num_parameters())); |
608 Result result = frame_->CallStub(&stub, 3); | 608 Result result = frame_->CallStub(&stub, 3); |
609 frame_->Push(&result); | 609 frame_->Push(&result); |
610 } | 610 } |
611 | 611 |
612 { Reference shadow_ref(this, scope_->arguments_shadow()); | 612 Variable* arguments = scope_->arguments()->var(); |
613 Reference arguments_ref(this, scope_->arguments()); | 613 Variable* shadow = scope_->arguments_shadow()->var(); |
614 ASSERT(shadow_ref.is_slot() && arguments_ref.is_slot()); | 614 ASSERT(arguments != NULL && arguments->slot() != NULL); |
615 // Here we rely on the convenient property that references to slot | 615 ASSERT(shadow != NULL && shadow->slot() != NULL); |
616 // take up zero space in the frame (ie, it doesn't matter that the | 616 JumpTarget done; |
617 // stored value is actually below the reference on the frame). | 617 bool skip_arguments = false; |
618 JumpTarget done; | 618 if (mode == LAZY_ARGUMENTS_ALLOCATION && !initial) { |
619 bool skip_arguments = false; | 619 // We have to skip storing into the arguments slot if it has already |
620 if (mode == LAZY_ARGUMENTS_ALLOCATION && !initial) { | 620 // been written to. This can happen if the a function has a local |
621 // We have to skip storing into the arguments slot if it has | 621 // variable named 'arguments'. |
622 // already been written to. This can happen if the a function | 622 LoadFromSlot(arguments->slot(), NOT_INSIDE_TYPEOF); |
623 // has a local variable named 'arguments'. | 623 Result probe = frame_->Pop(); |
624 LoadFromSlot(scope_->arguments()->var()->slot(), NOT_INSIDE_TYPEOF); | 624 if (probe.is_constant()) { |
625 Result arguments = frame_->Pop(); | 625 // We have to skip updating the arguments object if it has |
626 if (arguments.is_constant()) { | 626 // been assigned a proper value. |
627 // We have to skip updating the arguments object if it has | 627 skip_arguments = !probe.handle()->IsTheHole(); |
628 // been assigned a proper value. | 628 } else { |
629 skip_arguments = !arguments.handle()->IsTheHole(); | 629 __ cmp(Operand(probe.reg()), Immediate(Factory::the_hole_value())); |
630 } else { | 630 probe.Unuse(); |
631 __ cmp(Operand(arguments.reg()), Immediate(Factory::the_hole_value())); | 631 done.Branch(not_equal); |
632 arguments.Unuse(); | |
633 done.Branch(not_equal); | |
634 } | |
635 } | 632 } |
636 if (!skip_arguments) { | |
637 arguments_ref.SetValue(NOT_CONST_INIT); | |
638 if (mode == LAZY_ARGUMENTS_ALLOCATION) done.Bind(); | |
639 } | |
640 shadow_ref.SetValue(NOT_CONST_INIT); | |
641 } | 633 } |
| 634 if (!skip_arguments) { |
| 635 StoreToSlot(arguments->slot(), NOT_CONST_INIT); |
| 636 if (mode == LAZY_ARGUMENTS_ALLOCATION) done.Bind(); |
| 637 } |
| 638 StoreToSlot(shadow->slot(), NOT_CONST_INIT); |
642 return frame_->Pop(); | 639 return frame_->Pop(); |
643 } | 640 } |
644 | 641 |
645 | 642 |
646 Reference::Reference(CodeGenerator* cgen, Expression* expression) | 643 Reference::Reference(CodeGenerator* cgen, Expression* expression) |
647 : cgen_(cgen), expression_(expression), type_(ILLEGAL) { | 644 : cgen_(cgen), expression_(expression), type_(ILLEGAL) { |
648 cgen->LoadReference(this); | 645 cgen->LoadReference(this); |
649 } | 646 } |
650 | 647 |
651 | 648 |
(...skipping 2922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3574 CodeForStatementPosition(node); | 3571 CodeForStatementPosition(node); |
3575 | 3572 |
3576 JumpTarget try_block; | 3573 JumpTarget try_block; |
3577 JumpTarget exit; | 3574 JumpTarget exit; |
3578 | 3575 |
3579 try_block.Call(); | 3576 try_block.Call(); |
3580 // --- Catch block --- | 3577 // --- Catch block --- |
3581 frame_->EmitPush(eax); | 3578 frame_->EmitPush(eax); |
3582 | 3579 |
3583 // Store the caught exception in the catch variable. | 3580 // Store the caught exception in the catch variable. |
3584 { Reference ref(this, node->catch_var()); | 3581 Variable* catch_var = node->catch_var()->var(); |
3585 ASSERT(ref.is_slot()); | 3582 ASSERT(catch_var != NULL && catch_var->slot() != NULL); |
3586 // Load the exception to the top of the stack. Here we make use of the | 3583 StoreToSlot(catch_var->slot(), NOT_CONST_INIT); |
3587 // convenient property that it doesn't matter whether a value is | |
3588 // immediately on top of or underneath a zero-sized reference. | |
3589 ref.SetValue(NOT_CONST_INIT); | |
3590 } | |
3591 | 3584 |
3592 // Remove the exception from the stack. | 3585 // Remove the exception from the stack. |
3593 frame_->Drop(); | 3586 frame_->Drop(); |
3594 | 3587 |
3595 VisitStatementsAndSpill(node->catch_block()->statements()); | 3588 VisitStatementsAndSpill(node->catch_block()->statements()); |
3596 if (has_valid_frame()) { | 3589 if (has_valid_frame()) { |
3597 exit.Jump(); | 3590 exit.Jump(); |
3598 } | 3591 } |
3599 | 3592 |
3600 | 3593 |
(...skipping 6167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9768 | 9761 |
9769 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 9762 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
9770 // tagged as a small integer. | 9763 // tagged as a small integer. |
9771 __ bind(&runtime); | 9764 __ bind(&runtime); |
9772 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); | 9765 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); |
9773 } | 9766 } |
9774 | 9767 |
9775 #undef __ | 9768 #undef __ |
9776 | 9769 |
9777 } } // namespace v8::internal | 9770 } } // namespace v8::internal |
OLD | NEW |