| 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 927 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 938 | 938 |
| 939 const bool enabled_; | 939 const bool enabled_; |
| 940 Assignment* first_in_block_; | 940 Assignment* first_in_block_; |
| 941 Assignment* last_in_block_; | 941 Assignment* last_in_block_; |
| 942 int block_size_; | 942 int block_size_; |
| 943 | 943 |
| 944 DISALLOW_COPY_AND_ASSIGN(InitializationBlockFinder); | 944 DISALLOW_COPY_AND_ASSIGN(InitializationBlockFinder); |
| 945 }; | 945 }; |
| 946 | 946 |
| 947 | 947 |
| 948 // A ThisNamedPropertyAssigmentFinder finds and marks statements of the form | 948 // A ThisNamedPropertyAssignmentFinder finds and marks statements of the form |
| 949 // this.x = ...;, where x is a named property. It also determines whether a | 949 // this.x = ...;, where x is a named property. It also determines whether a |
| 950 // function contains only assignments of this type. | 950 // function contains only assignments of this type. |
| 951 class ThisNamedPropertyAssigmentFinder : public ParserFinder { | 951 class ThisNamedPropertyAssignmentFinder : public ParserFinder { |
| 952 public: | 952 public: |
| 953 explicit ThisNamedPropertyAssigmentFinder(Isolate* isolate) | 953 explicit ThisNamedPropertyAssignmentFinder(Isolate* isolate) |
| 954 : isolate_(isolate), | 954 : isolate_(isolate), |
| 955 only_simple_this_property_assignments_(true), | 955 only_simple_this_property_assignments_(true), |
| 956 names_(NULL), | 956 names_(0), |
| 957 assigned_arguments_(NULL), | 957 assigned_arguments_(0), |
| 958 assigned_constants_(NULL) {} | 958 assigned_constants_(0) { |
| 959 } |
| 959 | 960 |
| 960 void Update(Scope* scope, Statement* stat) { | 961 void Update(Scope* scope, Statement* stat) { |
| 961 // Bail out if function already has property assignment that are | 962 // Bail out if function already has property assignment that are |
| 962 // not simple this property assignments. | 963 // not simple this property assignments. |
| 963 if (!only_simple_this_property_assignments_) { | 964 if (!only_simple_this_property_assignments_) { |
| 964 return; | 965 return; |
| 965 } | 966 } |
| 966 | 967 |
| 967 // Check whether this statement is of the form this.x = ...; | 968 // Check whether this statement is of the form this.x = ...; |
| 968 Assignment* assignment = AsAssignment(stat); | 969 Assignment* assignment = AsAssignment(stat); |
| 969 if (IsThisPropertyAssignment(assignment)) { | 970 if (IsThisPropertyAssignment(assignment)) { |
| 970 HandleThisPropertyAssignment(scope, assignment); | 971 HandleThisPropertyAssignment(scope, assignment); |
| 971 } else { | 972 } else { |
| 972 only_simple_this_property_assignments_ = false; | 973 only_simple_this_property_assignments_ = false; |
| 973 } | 974 } |
| 974 } | 975 } |
| 975 | 976 |
| 976 // Returns whether only statements of the form this.x = y; where y is either a | 977 // Returns whether only statements of the form this.x = y; where y is either a |
| 977 // constant or a function argument was encountered. | 978 // constant or a function argument was encountered. |
| 978 bool only_simple_this_property_assignments() { | 979 bool only_simple_this_property_assignments() { |
| 979 return only_simple_this_property_assignments_; | 980 return only_simple_this_property_assignments_; |
| 980 } | 981 } |
| 981 | 982 |
| 982 // Returns a fixed array containing three elements for each assignment of the | 983 // Returns a fixed array containing three elements for each assignment of the |
| 983 // form this.x = y; | 984 // form this.x = y; |
| 984 Handle<FixedArray> GetThisPropertyAssignments() { | 985 Handle<FixedArray> GetThisPropertyAssignments() { |
| 985 if (names_ == NULL) { | 986 if (names_.is_empty()) { |
| 986 return isolate_->factory()->empty_fixed_array(); | 987 return isolate_->factory()->empty_fixed_array(); |
| 987 } | 988 } |
| 988 ASSERT(names_ != NULL); | 989 ASSERT_EQ(names_.length(), assigned_arguments_.length()); |
| 989 ASSERT(assigned_arguments_ != NULL); | 990 ASSERT_EQ(names_.length(), assigned_constants_.length()); |
| 990 ASSERT_EQ(names_->length(), assigned_arguments_->length()); | |
| 991 ASSERT_EQ(names_->length(), assigned_constants_->length()); | |
| 992 Handle<FixedArray> assignments = | 991 Handle<FixedArray> assignments = |
| 993 isolate_->factory()->NewFixedArray(names_->length() * 3); | 992 isolate_->factory()->NewFixedArray(names_.length() * 3); |
| 994 for (int i = 0; i < names_->length(); i++) { | 993 for (int i = 0; i < names_.length(); ++i) { |
| 995 assignments->set(i * 3, *names_->at(i)); | 994 assignments->set(i * 3, *names_[i]); |
| 996 assignments->set(i * 3 + 1, Smi::FromInt(assigned_arguments_->at(i))); | 995 assignments->set(i * 3 + 1, Smi::FromInt(assigned_arguments_[i])); |
| 997 assignments->set(i * 3 + 2, *assigned_constants_->at(i)); | 996 assignments->set(i * 3 + 2, *assigned_constants_[i]); |
| 998 } | 997 } |
| 999 return assignments; | 998 return assignments; |
| 1000 } | 999 } |
| 1001 | 1000 |
| 1002 private: | 1001 private: |
| 1003 bool IsThisPropertyAssignment(Assignment* assignment) { | 1002 bool IsThisPropertyAssignment(Assignment* assignment) { |
| 1004 if (assignment != NULL) { | 1003 if (assignment != NULL) { |
| 1005 Property* property = assignment->target()->AsProperty(); | 1004 Property* property = assignment->target()->AsProperty(); |
| 1006 return assignment->op() == Token::ASSIGN | 1005 return assignment->op() == Token::ASSIGN |
| 1007 && property != NULL | 1006 && property != NULL |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1044 return; | 1043 return; |
| 1045 } | 1044 } |
| 1046 } | 1045 } |
| 1047 } | 1046 } |
| 1048 } | 1047 } |
| 1049 // It is not a simple "this.x = value;" assignment with a constant | 1048 // It is not a simple "this.x = value;" assignment with a constant |
| 1050 // or parameter value. | 1049 // or parameter value. |
| 1051 AssignmentFromSomethingElse(); | 1050 AssignmentFromSomethingElse(); |
| 1052 } | 1051 } |
| 1053 | 1052 |
| 1053 |
| 1054 |
| 1055 |
| 1056 // We will potentially reorder the property assignments, so they must be |
| 1057 // simple enough that the ordering does not matter. |
| 1054 void AssignmentFromParameter(Handle<String> name, int index) { | 1058 void AssignmentFromParameter(Handle<String> name, int index) { |
| 1055 EnsureAllocation(); | 1059 EnsureInitialized(); |
| 1056 names_->Add(name); | 1060 for (int i = 0; i < names_.length(); ++i) { |
| 1057 assigned_arguments_->Add(index); | 1061 if (name->Equals(*names_[i])) { |
| 1058 assigned_constants_->Add(isolate_->factory()->undefined_value()); | 1062 assigned_arguments_[i] = index; |
| 1063 assigned_constants_[i] = isolate_->factory()->undefined_value(); |
| 1064 return; |
| 1065 } |
| 1066 } |
| 1067 names_.Add(name); |
| 1068 assigned_arguments_.Add(index); |
| 1069 assigned_constants_.Add(isolate_->factory()->undefined_value()); |
| 1059 } | 1070 } |
| 1060 | 1071 |
| 1061 void AssignmentFromConstant(Handle<String> name, Handle<Object> value) { | 1072 void AssignmentFromConstant(Handle<String> name, Handle<Object> value) { |
| 1062 EnsureAllocation(); | 1073 EnsureInitialized(); |
| 1063 names_->Add(name); | 1074 for (int i = 0; i < names_.length(); ++i) { |
| 1064 assigned_arguments_->Add(-1); | 1075 if (name->Equals(*names_[i])) { |
| 1065 assigned_constants_->Add(value); | 1076 assigned_arguments_[i] = -1; |
| 1077 assigned_constants_[i] = value; |
| 1078 return; |
| 1079 } |
| 1080 } |
| 1081 names_.Add(name); |
| 1082 assigned_arguments_.Add(-1); |
| 1083 assigned_constants_.Add(value); |
| 1066 } | 1084 } |
| 1067 | 1085 |
| 1068 void AssignmentFromSomethingElse() { | 1086 void AssignmentFromSomethingElse() { |
| 1069 // The this assignment is not a simple one. | 1087 // The this assignment is not a simple one. |
| 1070 only_simple_this_property_assignments_ = false; | 1088 only_simple_this_property_assignments_ = false; |
| 1071 } | 1089 } |
| 1072 | 1090 |
| 1073 void EnsureAllocation() { | 1091 void EnsureInitialized() { |
| 1074 if (names_ == NULL) { | 1092 if (names_.capacity() == 0) { |
| 1075 ASSERT(assigned_arguments_ == NULL); | 1093 ASSERT(assigned_arguments_.capacity() == 0); |
| 1076 ASSERT(assigned_constants_ == NULL); | 1094 ASSERT(assigned_constants_.capacity() == 0); |
| 1077 Zone* zone = isolate_->zone(); | 1095 names_.Initialize(4); |
| 1078 names_ = new(zone) ZoneStringList(4); | 1096 assigned_arguments_.Initialize(4); |
| 1079 assigned_arguments_ = new(zone) ZoneList<int>(4); | 1097 assigned_constants_.Initialize(4); |
| 1080 assigned_constants_ = new(zone) ZoneObjectList(4); | |
| 1081 } | 1098 } |
| 1082 } | 1099 } |
| 1083 | 1100 |
| 1084 Isolate* isolate_; | 1101 Isolate* isolate_; |
| 1085 bool only_simple_this_property_assignments_; | 1102 bool only_simple_this_property_assignments_; |
| 1086 ZoneStringList* names_; | 1103 ZoneStringList names_; |
| 1087 ZoneList<int>* assigned_arguments_; | 1104 ZoneList<int> assigned_arguments_; |
| 1088 ZoneObjectList* assigned_constants_; | 1105 ZoneObjectList assigned_constants_; |
| 1089 }; | 1106 }; |
| 1090 | 1107 |
| 1091 | 1108 |
| 1092 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, | 1109 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, |
| 1093 int end_token, | 1110 int end_token, |
| 1094 bool* ok) { | 1111 bool* ok) { |
| 1095 // SourceElements :: | 1112 // SourceElements :: |
| 1096 // (Statement)* <end_token> | 1113 // (Statement)* <end_token> |
| 1097 | 1114 |
| 1098 // Allocate a target stack to use for this set of source | 1115 // Allocate a target stack to use for this set of source |
| 1099 // elements. This way, all scripts and functions get their own | 1116 // elements. This way, all scripts and functions get their own |
| 1100 // target stack thus avoiding illegal breaks and continues across | 1117 // target stack thus avoiding illegal breaks and continues across |
| 1101 // functions. | 1118 // functions. |
| 1102 TargetScope scope(&this->target_stack_); | 1119 TargetScope scope(&this->target_stack_); |
| 1103 | 1120 |
| 1104 ASSERT(processor != NULL); | 1121 ASSERT(processor != NULL); |
| 1105 InitializationBlockFinder block_finder(top_scope_, target_stack_); | 1122 InitializationBlockFinder block_finder(top_scope_, target_stack_); |
| 1106 ThisNamedPropertyAssigmentFinder this_property_assignment_finder(isolate()); | 1123 ThisNamedPropertyAssignmentFinder this_property_assignment_finder(isolate()); |
| 1107 bool directive_prologue = true; // Parsing directive prologue. | 1124 bool directive_prologue = true; // Parsing directive prologue. |
| 1108 | 1125 |
| 1109 while (peek() != end_token) { | 1126 while (peek() != end_token) { |
| 1110 if (directive_prologue && peek() != Token::STRING) { | 1127 if (directive_prologue && peek() != Token::STRING) { |
| 1111 directive_prologue = false; | 1128 directive_prologue = false; |
| 1112 } | 1129 } |
| 1113 | 1130 |
| 1114 Scanner::Location token_loc = scanner().peek_location(); | 1131 Scanner::Location token_loc = scanner().peek_location(); |
| 1115 | 1132 |
| 1116 Statement* stat; | 1133 Statement* stat; |
| (...skipping 4012 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5129 info->is_global(), | 5146 info->is_global(), |
| 5130 info->StrictMode()); | 5147 info->StrictMode()); |
| 5131 } | 5148 } |
| 5132 } | 5149 } |
| 5133 | 5150 |
| 5134 info->SetFunction(result); | 5151 info->SetFunction(result); |
| 5135 return (result != NULL); | 5152 return (result != NULL); |
| 5136 } | 5153 } |
| 5137 | 5154 |
| 5138 } } // namespace v8::internal | 5155 } } // namespace v8::internal |
| OLD | NEW |