OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
604 LoadFromSlotCheckForArguments(variable->AsSlot(), INSIDE_TYPEOF); | 604 LoadFromSlotCheckForArguments(variable->AsSlot(), INSIDE_TYPEOF); |
605 } else { | 605 } else { |
606 // Anything else can be handled normally. | 606 // Anything else can be handled normally. |
607 Load(expr); | 607 Load(expr); |
608 } | 608 } |
609 } | 609 } |
610 | 610 |
611 | 611 |
612 ArgumentsAllocationMode CodeGenerator::ArgumentsMode() { | 612 ArgumentsAllocationMode CodeGenerator::ArgumentsMode() { |
613 if (scope()->arguments() == NULL) return NO_ARGUMENTS_ALLOCATION; | 613 if (scope()->arguments() == NULL) return NO_ARGUMENTS_ALLOCATION; |
614 ASSERT(scope()->arguments_shadow() != NULL); | 614 |
| 615 // In strict mode there is no need for shadow arguments. |
| 616 ASSERT(scope()->arguments_shadow() != NULL || scope()->is_strict_mode()); |
615 // We don't want to do lazy arguments allocation for functions that | 617 // We don't want to do lazy arguments allocation for functions that |
616 // have heap-allocated contexts, because it interfers with the | 618 // have heap-allocated contexts, because it interfers with the |
617 // uninitialized const tracking in the context objects. | 619 // uninitialized const tracking in the context objects. |
618 return (scope()->num_heap_slots() > 0) | 620 return (scope()->num_heap_slots() > 0 || scope()->is_strict_mode()) |
619 ? EAGER_ARGUMENTS_ALLOCATION | 621 ? EAGER_ARGUMENTS_ALLOCATION |
620 : LAZY_ARGUMENTS_ALLOCATION; | 622 : LAZY_ARGUMENTS_ALLOCATION; |
621 } | 623 } |
622 | 624 |
623 | 625 |
624 Result CodeGenerator::StoreArgumentsObject(bool initial) { | 626 Result CodeGenerator::StoreArgumentsObject(bool initial) { |
625 ArgumentsAllocationMode mode = ArgumentsMode(); | 627 ArgumentsAllocationMode mode = ArgumentsMode(); |
626 ASSERT(mode != NO_ARGUMENTS_ALLOCATION); | 628 ASSERT(mode != NO_ARGUMENTS_ALLOCATION); |
627 | 629 |
628 Comment cmnt(masm_, "[ store arguments object"); | 630 Comment cmnt(masm_, "[ store arguments object"); |
629 if (mode == LAZY_ARGUMENTS_ALLOCATION && initial) { | 631 if (mode == LAZY_ARGUMENTS_ALLOCATION && initial) { |
630 // When using lazy arguments allocation, we store the arguments marker value | 632 // When using lazy arguments allocation, we store the arguments marker value |
631 // as a sentinel indicating that the arguments object hasn't been | 633 // as a sentinel indicating that the arguments object hasn't been |
632 // allocated yet. | 634 // allocated yet. |
633 frame_->Push(Factory::arguments_marker()); | 635 frame_->Push(Factory::arguments_marker()); |
634 } else { | 636 } else { |
635 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); | 637 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); |
636 frame_->PushFunction(); | 638 frame_->PushFunction(); |
637 frame_->PushReceiverSlotAddress(); | 639 frame_->PushReceiverSlotAddress(); |
638 frame_->Push(Smi::FromInt(scope()->num_parameters())); | 640 frame_->Push(Smi::FromInt(scope()->num_parameters())); |
639 Result result = frame_->CallStub(&stub, 3); | 641 Result result = frame_->CallStub(&stub, 3); |
640 frame_->Push(&result); | 642 frame_->Push(&result); |
641 } | 643 } |
642 | 644 |
643 Variable* arguments = scope()->arguments(); | 645 Variable* arguments = scope()->arguments(); |
644 Variable* shadow = scope()->arguments_shadow(); | 646 Variable* shadow = scope()->arguments_shadow(); |
645 ASSERT(arguments != NULL && arguments->AsSlot() != NULL); | 647 ASSERT(arguments != NULL && arguments->AsSlot() != NULL); |
646 ASSERT(shadow != NULL && shadow->AsSlot() != NULL); | 648 ASSERT(shadow != NULL && shadow->AsSlot() != NULL || |
| 649 scope()->is_strict_mode()); |
| 650 |
647 JumpTarget done; | 651 JumpTarget done; |
648 bool skip_arguments = false; | 652 bool skip_arguments = false; |
649 if (mode == LAZY_ARGUMENTS_ALLOCATION && !initial) { | 653 if (mode == LAZY_ARGUMENTS_ALLOCATION && !initial) { |
650 // We have to skip storing into the arguments slot if it has | 654 // We have to skip storing into the arguments slot if it has |
651 // already been written to. This can happen if the a function | 655 // already been written to. This can happen if the a function |
652 // has a local variable named 'arguments'. | 656 // has a local variable named 'arguments'. |
653 LoadFromSlot(arguments->AsSlot(), NOT_INSIDE_TYPEOF); | 657 LoadFromSlot(arguments->AsSlot(), NOT_INSIDE_TYPEOF); |
654 Result probe = frame_->Pop(); | 658 Result probe = frame_->Pop(); |
655 if (probe.is_constant()) { | 659 if (probe.is_constant()) { |
656 // We have to skip updating the arguments object if it has | 660 // We have to skip updating the arguments object if it has |
657 // been assigned a proper value. | 661 // been assigned a proper value. |
658 skip_arguments = !probe.handle()->IsArgumentsMarker(); | 662 skip_arguments = !probe.handle()->IsArgumentsMarker(); |
659 } else { | 663 } else { |
660 __ CompareRoot(probe.reg(), Heap::kArgumentsMarkerRootIndex); | 664 __ CompareRoot(probe.reg(), Heap::kArgumentsMarkerRootIndex); |
661 probe.Unuse(); | 665 probe.Unuse(); |
662 done.Branch(not_equal); | 666 done.Branch(not_equal); |
663 } | 667 } |
664 } | 668 } |
665 if (!skip_arguments) { | 669 if (!skip_arguments) { |
666 StoreToSlot(arguments->AsSlot(), NOT_CONST_INIT); | 670 StoreToSlot(arguments->AsSlot(), NOT_CONST_INIT); |
667 if (mode == LAZY_ARGUMENTS_ALLOCATION) done.Bind(); | 671 if (mode == LAZY_ARGUMENTS_ALLOCATION) done.Bind(); |
668 } | 672 } |
669 StoreToSlot(shadow->AsSlot(), NOT_CONST_INIT); | 673 if (shadow != NULL) { |
| 674 StoreToSlot(shadow->AsSlot(), NOT_CONST_INIT); |
| 675 } |
670 return frame_->Pop(); | 676 return frame_->Pop(); |
671 } | 677 } |
672 | 678 |
673 //------------------------------------------------------------------------------ | 679 //------------------------------------------------------------------------------ |
674 // CodeGenerator implementation of variables, lookups, and stores. | 680 // CodeGenerator implementation of variables, lookups, and stores. |
675 | 681 |
676 Reference::Reference(CodeGenerator* cgen, | 682 Reference::Reference(CodeGenerator* cgen, |
677 Expression* expression, | 683 Expression* expression, |
678 bool persist_after_get) | 684 bool persist_after_get) |
679 : cgen_(cgen), | 685 : cgen_(cgen), |
(...skipping 8146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8826 } | 8832 } |
8827 | 8833 |
8828 #endif | 8834 #endif |
8829 | 8835 |
8830 | 8836 |
8831 #undef __ | 8837 #undef __ |
8832 | 8838 |
8833 } } // namespace v8::internal | 8839 } } // namespace v8::internal |
8834 | 8840 |
8835 #endif // V8_TARGET_ARCH_X64 | 8841 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |