OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 792 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
803 // introduces 2 local variables 'arguments' and '.arguments', both of | 803 // introduces 2 local variables 'arguments' and '.arguments', both of |
804 // which originally point to the arguments object that was | 804 // which originally point to the arguments object that was |
805 // allocated. All parameters are rewritten into property accesses via | 805 // allocated. All parameters are rewritten into property accesses via |
806 // the '.arguments' variable. Thus, any changes to properties of | 806 // the '.arguments' variable. Thus, any changes to properties of |
807 // 'arguments' are reflected in the variables and vice versa. If the | 807 // 'arguments' are reflected in the variables and vice versa. If the |
808 // 'arguments' variable is changed, '.arguments' still points to the | 808 // 'arguments' variable is changed, '.arguments' still points to the |
809 // correct arguments object and the rewrites still work. | 809 // correct arguments object and the rewrites still work. |
810 | 810 |
811 // We are using 'arguments'. Tell the code generator that is needs to | 811 // We are using 'arguments'. Tell the code generator that is needs to |
812 // allocate the arguments object by setting 'arguments_'. | 812 // allocate the arguments object by setting 'arguments_'. |
813 arguments_ = new VariableProxy(Factory::arguments_symbol(), false, false); | 813 arguments_ = arguments; |
814 arguments_->BindTo(arguments); | |
815 | 814 |
816 // We also need the '.arguments' shadow variable. Declare it and create | 815 // We also need the '.arguments' shadow variable. Declare it and create |
817 // and bind the corresponding proxy. It's ok to declare it only now | 816 // and bind the corresponding proxy. It's ok to declare it only now |
818 // because it's a local variable that is allocated after the parameters | 817 // because it's a local variable that is allocated after the parameters |
819 // have been allocated. | 818 // have been allocated. |
820 // | 819 // |
821 // Note: This is "almost" at temporary variable but we cannot use | 820 // Note: This is "almost" at temporary variable but we cannot use |
822 // NewTemporary() because the mode needs to be INTERNAL since this | 821 // NewTemporary() because the mode needs to be INTERNAL since this |
823 // variable may be allocated in the heap-allocated context (temporaries | 822 // variable may be allocated in the heap-allocated context (temporaries |
824 // are never allocated in the context). | 823 // are never allocated in the context). |
825 Variable* arguments_shadow = | 824 arguments_shadow_ = new Variable(this, |
826 new Variable(this, Factory::arguments_shadow_symbol(), | 825 Factory::arguments_shadow_symbol(), |
827 Variable::INTERNAL, true, Variable::ARGUMENTS); | 826 Variable::INTERNAL, |
828 arguments_shadow_ = | 827 true, |
829 new VariableProxy(Factory::arguments_shadow_symbol(), false, false); | 828 Variable::ARGUMENTS); |
830 arguments_shadow_->BindTo(arguments_shadow); | 829 arguments_shadow_->set_is_used(true); |
831 temps_.Add(arguments_shadow); | 830 temps_.Add(arguments_shadow_); |
832 | 831 |
833 // Allocate the parameters by rewriting them into '.arguments[i]' accesses. | 832 // Allocate the parameters by rewriting them into '.arguments[i]' accesses. |
834 for (int i = 0; i < params_.length(); i++) { | 833 for (int i = 0; i < params_.length(); i++) { |
835 Variable* var = params_[i]; | 834 Variable* var = params_[i]; |
836 ASSERT(var->scope() == this); | 835 ASSERT(var->scope() == this); |
837 if (MustAllocate(var)) { | 836 if (MustAllocate(var)) { |
838 if (MustAllocateInContext(var)) { | 837 if (MustAllocateInContext(var)) { |
839 // It is ok to set this only now, because arguments is a local | 838 // It is ok to set this only now, because arguments is a local |
840 // variable that is allocated after the parameters have been | 839 // variable that is allocated after the parameters have been |
841 // allocated. | 840 // allocated. |
842 arguments_shadow->is_accessed_from_inner_scope_ = true; | 841 arguments_shadow_->is_accessed_from_inner_scope_ = true; |
843 } | 842 } |
844 var->rewrite_ = | 843 var->rewrite_ = |
845 new Property(arguments_shadow_, | 844 new Property(new VariableProxy(arguments_shadow_), |
846 new Literal(Handle<Object>(Smi::FromInt(i))), | 845 new Literal(Handle<Object>(Smi::FromInt(i))), |
847 RelocInfo::kNoPosition, | 846 RelocInfo::kNoPosition, |
848 Property::SYNTHETIC); | 847 Property::SYNTHETIC); |
849 if (var->is_used()) arguments_shadow->set_is_used(true); | |
850 } | 848 } |
851 } | 849 } |
852 | 850 |
853 } else { | 851 } else { |
854 // The arguments object is not used, so we can access parameters directly. | 852 // The arguments object is not used, so we can access parameters directly. |
855 // The same parameter may occur multiple times in the parameters_ list. | 853 // The same parameter may occur multiple times in the parameters_ list. |
856 // If it does, and if it is not copied into the context object, it must | 854 // If it does, and if it is not copied into the context object, it must |
857 // receive the highest parameter index for that parameter; thus iteration | 855 // receive the highest parameter index for that parameter; thus iteration |
858 // order is relevant! | 856 // order is relevant! |
859 for (int i = 0; i < params_.length(); i++) { | 857 for (int i = 0; i < params_.length(); i++) { |
860 Variable* var = params_[i]; | 858 Variable* var = params_[i]; |
861 ASSERT(var->scope() == this); | 859 ASSERT(var->scope() == this); |
862 if (MustAllocate(var)) { | 860 if (MustAllocate(var)) { |
863 if (MustAllocateInContext(var)) { | 861 if (MustAllocateInContext(var)) { |
864 ASSERT(var->rewrite_ == NULL || | 862 ASSERT(var->rewrite_ == NULL || |
865 (var->slot() != NULL && var->slot()->type() == Slot::CONTEXT)); | 863 (var->AsSlot() != NULL && |
| 864 var->AsSlot()->type() == Slot::CONTEXT)); |
866 if (var->rewrite_ == NULL) { | 865 if (var->rewrite_ == NULL) { |
867 // Only set the heap allocation if the parameter has not | 866 // Only set the heap allocation if the parameter has not |
868 // been allocated yet. | 867 // been allocated yet. |
869 AllocateHeapSlot(var); | 868 AllocateHeapSlot(var); |
870 } | 869 } |
871 } else { | 870 } else { |
872 ASSERT(var->rewrite_ == NULL || | 871 ASSERT(var->rewrite_ == NULL || |
873 (var->slot() != NULL && | 872 (var->AsSlot() != NULL && |
874 var->slot()->type() == Slot::PARAMETER)); | 873 var->AsSlot()->type() == Slot::PARAMETER)); |
875 // Set the parameter index always, even if the parameter | 874 // Set the parameter index always, even if the parameter |
876 // was seen before! (We need to access the actual parameter | 875 // was seen before! (We need to access the actual parameter |
877 // supplied for the last occurrence of a multiply declared | 876 // supplied for the last occurrence of a multiply declared |
878 // parameter.) | 877 // parameter.) |
879 var->rewrite_ = new Slot(var, Slot::PARAMETER, i); | 878 var->rewrite_ = new Slot(var, Slot::PARAMETER, i); |
880 } | 879 } |
881 } | 880 } |
882 } | 881 } |
883 } | 882 } |
884 } | 883 } |
885 | 884 |
886 | 885 |
887 void Scope::AllocateNonParameterLocal(Variable* var) { | 886 void Scope::AllocateNonParameterLocal(Variable* var) { |
888 ASSERT(var->scope() == this); | 887 ASSERT(var->scope() == this); |
889 ASSERT(var->rewrite_ == NULL || | 888 ASSERT(var->rewrite_ == NULL || |
890 (!var->IsVariable(Factory::result_symbol())) || | 889 (!var->IsVariable(Factory::result_symbol())) || |
891 (var->slot() == NULL || var->slot()->type() != Slot::LOCAL)); | 890 (var->AsSlot() == NULL || var->AsSlot()->type() != Slot::LOCAL)); |
892 if (var->rewrite_ == NULL && MustAllocate(var)) { | 891 if (var->rewrite_ == NULL && MustAllocate(var)) { |
893 if (MustAllocateInContext(var)) { | 892 if (MustAllocateInContext(var)) { |
894 AllocateHeapSlot(var); | 893 AllocateHeapSlot(var); |
895 } else { | 894 } else { |
896 AllocateStackSlot(var); | 895 AllocateStackSlot(var); |
897 } | 896 } |
898 } | 897 } |
899 } | 898 } |
900 | 899 |
901 | 900 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
953 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && | 952 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && |
954 !must_have_local_context) { | 953 !must_have_local_context) { |
955 num_heap_slots_ = 0; | 954 num_heap_slots_ = 0; |
956 } | 955 } |
957 | 956 |
958 // Allocation done. | 957 // Allocation done. |
959 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); | 958 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); |
960 } | 959 } |
961 | 960 |
962 } } // namespace v8::internal | 961 } } // namespace v8::internal |
OLD | NEW |