| 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 |