OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 978 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
989 class CompleteParserRecorder: public PartialParserRecorder { | 989 class CompleteParserRecorder: public PartialParserRecorder { |
990 public: | 990 public: |
991 CompleteParserRecorder(); | 991 CompleteParserRecorder(); |
992 | 992 |
993 virtual void LogSymbol(int start, Vector<const char> literal) { | 993 virtual void LogSymbol(int start, Vector<const char> literal) { |
994 int hash = vector_hash(literal); | 994 int hash = vector_hash(literal); |
995 HashMap::Entry* entry = symbol_table_.Lookup(&literal, hash, true); | 995 HashMap::Entry* entry = symbol_table_.Lookup(&literal, hash, true); |
996 int id = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); | 996 int id = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); |
997 if (id == 0) { | 997 if (id == 0) { |
998 // Put (symbol_id_ + 1) into entry and increment it. | 998 // Put (symbol_id_ + 1) into entry and increment it. |
999 symbol_id_++; | 999 id = ++symbol_id_; |
1000 entry->value = reinterpret_cast<void*>(symbol_id_); | 1000 entry->value = reinterpret_cast<void*>(id); |
1001 Vector<Vector<const char> > symbol = symbol_entries_.AddBlock(1, literal); | 1001 Vector<Vector<const char> > symbol = symbol_entries_.AddBlock(1, literal); |
1002 entry->key = &symbol[0]; | 1002 entry->key = &symbol[0]; |
1003 } else { | |
1004 // Log a reuse of an earlier seen symbol. | |
1005 symbol_store_.Add(start); | |
1006 symbol_store_.Add(id - 1); | |
1007 } | 1003 } |
| 1004 symbol_store_.Add(id - 1); |
1008 } | 1005 } |
1009 | 1006 |
1010 virtual Vector<unsigned> ExtractData() { | 1007 virtual Vector<unsigned> ExtractData() { |
1011 int function_size = function_store_.size(); | 1008 int function_size = function_store_.size(); |
| 1009 // Add terminator to symbols, then pad to unsigned size. |
1012 int symbol_size = symbol_store_.size(); | 1010 int symbol_size = symbol_store_.size(); |
1013 int total_size = ScriptDataImpl::kHeaderSize + function_size + symbol_size; | 1011 int padding = sizeof(unsigned) - (symbol_size % sizeof(unsigned)); |
| 1012 symbol_store_.AddBlock(padding, ScriptDataImpl::kNumberTerminator); |
| 1013 symbol_size += padding; |
| 1014 int total_size = ScriptDataImpl::kHeaderSize + function_size |
| 1015 + (symbol_size / sizeof(unsigned)); |
1014 Vector<unsigned> data = Vector<unsigned>::New(total_size); | 1016 Vector<unsigned> data = Vector<unsigned>::New(total_size); |
1015 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = function_size; | 1017 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = function_size; |
1016 preamble_[ScriptDataImpl::kSymbolCountOffset] = symbol_id_; | 1018 preamble_[ScriptDataImpl::kSymbolCountOffset] = symbol_id_; |
1017 memcpy(data.start(), preamble_, sizeof(preamble_)); | 1019 memcpy(data.start(), preamble_, sizeof(preamble_)); |
1018 int symbol_start = ScriptDataImpl::kHeaderSize + function_size; | 1020 int symbol_start = ScriptDataImpl::kHeaderSize + function_size; |
1019 if (function_size > 0) { | 1021 if (function_size > 0) { |
1020 function_store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize, | 1022 function_store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize, |
1021 symbol_start)); | 1023 symbol_start)); |
1022 } | 1024 } |
1023 if (symbol_size > 0) { | 1025 if (!has_error()) { |
1024 symbol_store_.WriteTo(data.SubVector(symbol_start, total_size)); | 1026 symbol_store_.WriteTo( |
| 1027 Vector<byte>::cast(data.SubVector(symbol_start, total_size))); |
1025 } | 1028 } |
1026 return data; | 1029 return data; |
1027 } | 1030 } |
1028 | 1031 |
1029 virtual int symbol_position() { return symbol_store_.size(); } | 1032 virtual int symbol_position() { return symbol_store_.size(); } |
1030 virtual int symbol_ids() { return symbol_id_; } | 1033 virtual int symbol_ids() { return symbol_id_; } |
1031 private: | 1034 private: |
1032 Collector<unsigned> symbol_store_; | 1035 static int vector_hash(Vector<const char> string) { |
1033 Collector<Vector<const char> > symbol_entries_; | |
1034 HashMap symbol_table_; | |
1035 int symbol_id_; | |
1036 | |
1037 static int vector_hash(Vector<const char> string) { | |
1038 int hash = 0; | 1036 int hash = 0; |
1039 for (int i = 0; i < string.length(); i++) { | 1037 for (int i = 0; i < string.length(); i++) { |
1040 int c = string[i]; | 1038 int c = string[i]; |
1041 hash += c; | 1039 hash += c; |
1042 hash += (hash << 10); | 1040 hash += (hash << 10); |
1043 hash ^= (hash >> 6); | 1041 hash ^= (hash >> 6); |
1044 } | 1042 } |
1045 return hash; | 1043 return hash; |
1046 } | 1044 } |
1047 | 1045 |
1048 static bool vector_compare(void* a, void* b) { | 1046 static bool vector_compare(void* a, void* b) { |
1049 Vector<const char>* string1 = reinterpret_cast<Vector<const char>* >(a); | 1047 Vector<const char>* string1 = reinterpret_cast<Vector<const char>* >(a); |
1050 Vector<const char>* string2 = reinterpret_cast<Vector<const char>* >(b); | 1048 Vector<const char>* string2 = reinterpret_cast<Vector<const char>* >(b); |
1051 int length = string1->length(); | 1049 int length = string1->length(); |
1052 if (string2->length() != length) return false; | 1050 if (string2->length() != length) return false; |
1053 return memcmp(string1->start(), string2->start(), length) == 0; | 1051 return memcmp(string1->start(), string2->start(), length) == 0; |
1054 } | 1052 } |
| 1053 |
| 1054 // Write a non-negative number to the symbol store. |
| 1055 void WriteNumber(int number); |
| 1056 |
| 1057 Collector<byte> symbol_store_; |
| 1058 Collector<Vector<const char> > symbol_entries_; |
| 1059 HashMap symbol_table_; |
| 1060 int symbol_id_; |
1055 }; | 1061 }; |
1056 | 1062 |
1057 | 1063 |
1058 void ScriptDataImpl::SkipFunctionEntry(int start) { | 1064 void ScriptDataImpl::SkipFunctionEntry(int start) { |
1059 ASSERT(function_index_ + FunctionEntry::kSize <= store_.length()); | 1065 ASSERT(function_index_ + FunctionEntry::kSize <= store_.length()); |
1060 ASSERT(static_cast<int>(store_[function_index_]) == start); | 1066 ASSERT(static_cast<int>(store_[function_index_]) == start); |
1061 function_index_ += FunctionEntry::kSize; | 1067 function_index_ += FunctionEntry::kSize; |
1062 } | 1068 } |
1063 | 1069 |
1064 | 1070 |
1065 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { | 1071 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { |
1066 // The current pre-data entry must be a FunctionEntry with the given | 1072 // The current pre-data entry must be a FunctionEntry with the given |
1067 // start position. | 1073 // start position. |
1068 if ((function_index_ + FunctionEntry::kSize <= store_.length()) | 1074 if ((function_index_ + FunctionEntry::kSize <= store_.length()) |
1069 && (static_cast<int>(store_[function_index_]) == start)) { | 1075 && (static_cast<int>(store_[function_index_]) == start)) { |
1070 int index = function_index_; | 1076 int index = function_index_; |
1071 function_index_ += FunctionEntry::kSize; | 1077 function_index_ += FunctionEntry::kSize; |
1072 return FunctionEntry(store_.SubVector(index, | 1078 return FunctionEntry(store_.SubVector(index, |
1073 index + FunctionEntry::kSize)); | 1079 index + FunctionEntry::kSize)); |
1074 } | 1080 } |
1075 return FunctionEntry(); | 1081 return FunctionEntry(); |
1076 } | 1082 } |
1077 | 1083 |
1078 | 1084 |
1079 int ScriptDataImpl::GetSymbolIdentifier(int start) { | 1085 int ScriptDataImpl::GetSymbolIdentifier() { |
1080 int next = symbol_index_ + 2; | 1086 return ReadNumber(&symbol_data_); |
1081 if (next <= store_.length() | |
1082 && static_cast<int>(store_[symbol_index_]) == start) { | |
1083 symbol_index_ = next; | |
1084 return store_[next - 1]; | |
1085 } | |
1086 return symbol_id_++; | |
1087 } | 1087 } |
1088 | 1088 |
1089 | 1089 |
1090 | |
1091 bool ScriptDataImpl::SanityCheck() { | 1090 bool ScriptDataImpl::SanityCheck() { |
1092 // Check that the header data is valid and doesn't specify | 1091 // Check that the header data is valid and doesn't specify |
1093 // point to positions outside the store. | 1092 // point to positions outside the store. |
1094 if (store_.length() < ScriptDataImpl::kHeaderSize) return false; | 1093 if (store_.length() < ScriptDataImpl::kHeaderSize) return false; |
1095 if (magic() != ScriptDataImpl::kMagicNumber) return false; | 1094 if (magic() != ScriptDataImpl::kMagicNumber) return false; |
1096 if (version() != ScriptDataImpl::kCurrentVersion) return false; | 1095 if (version() != ScriptDataImpl::kCurrentVersion) return false; |
1097 if (has_error()) { | 1096 if (has_error()) { |
1098 // Extra sane sanity check for error message encoding. | 1097 // Extra sane sanity check for error message encoding. |
1099 if (store_.length() <= kHeaderSize + kMessageTextPos) return false; | 1098 if (store_.length() <= kHeaderSize + kMessageTextPos) return false; |
1100 if (Read(kMessageStartPos) > Read(kMessageEndPos)) return false; | 1099 if (Read(kMessageStartPos) > Read(kMessageEndPos)) return false; |
(...skipping 10 matching lines...) Expand all Loading... |
1111 } | 1110 } |
1112 // Check that the space allocated for function entries is sane. | 1111 // Check that the space allocated for function entries is sane. |
1113 int functions_size = | 1112 int functions_size = |
1114 static_cast<int>(store_[ScriptDataImpl::kFunctionsSizeOffset]); | 1113 static_cast<int>(store_[ScriptDataImpl::kFunctionsSizeOffset]); |
1115 if (functions_size < 0) return false; | 1114 if (functions_size < 0) return false; |
1116 if (functions_size % FunctionEntry::kSize != 0) return false; | 1115 if (functions_size % FunctionEntry::kSize != 0) return false; |
1117 // Check that the count of symbols is non-negative. | 1116 // Check that the count of symbols is non-negative. |
1118 int symbol_count = | 1117 int symbol_count = |
1119 static_cast<int>(store_[ScriptDataImpl::kSymbolCountOffset]); | 1118 static_cast<int>(store_[ScriptDataImpl::kSymbolCountOffset]); |
1120 if (symbol_count < 0) return false; | 1119 if (symbol_count < 0) return false; |
1121 // Check that the total size has room both function entries. | 1120 // Check that the total size has room for header and function entries. |
1122 int minimum_size = | 1121 int minimum_size = |
1123 ScriptDataImpl::kHeaderSize + functions_size; | 1122 ScriptDataImpl::kHeaderSize + functions_size; |
1124 if (store_.length() < minimum_size) return false; | 1123 if (store_.length() < minimum_size) return false; |
1125 return true; | 1124 return true; |
1126 } | 1125 } |
1127 | 1126 |
1128 | 1127 |
1129 | 1128 |
1130 PartialParserRecorder::PartialParserRecorder() : function_store_(0) { | 1129 PartialParserRecorder::PartialParserRecorder() : function_store_(0) { |
1131 preamble_[ScriptDataImpl::kMagicOffset] = ScriptDataImpl::kMagicNumber; | 1130 preamble_[ScriptDataImpl::kMagicOffset] = ScriptDataImpl::kMagicNumber; |
(...skipping 19 matching lines...) Expand all Loading... |
1151 | 1150 |
1152 | 1151 |
1153 void PartialParserRecorder::WriteString(Vector<const char> str) { | 1152 void PartialParserRecorder::WriteString(Vector<const char> str) { |
1154 function_store_.Add(str.length()); | 1153 function_store_.Add(str.length()); |
1155 for (int i = 0; i < str.length(); i++) { | 1154 for (int i = 0; i < str.length(); i++) { |
1156 function_store_.Add(str[i]); | 1155 function_store_.Add(str[i]); |
1157 } | 1156 } |
1158 } | 1157 } |
1159 | 1158 |
1160 | 1159 |
| 1160 void CompleteParserRecorder::WriteNumber(int number) { |
| 1161 ASSERT(number >= 0); |
| 1162 |
| 1163 int mask = (1 << 28) - 1; |
| 1164 for (int i = 28; i > 0; i -= 7) { |
| 1165 if (number > mask) { |
| 1166 symbol_store_.Add(static_cast<byte>(number >> i) | 0x80u); |
| 1167 number &= mask; |
| 1168 } |
| 1169 mask >>= 7; |
| 1170 } |
| 1171 symbol_store_.Add(static_cast<byte>(number)); |
| 1172 } |
| 1173 |
| 1174 |
| 1175 |
1161 const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) { | 1176 const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) { |
1162 int length = start[0]; | 1177 int length = start[0]; |
1163 char* result = NewArray<char>(length + 1); | 1178 char* result = NewArray<char>(length + 1); |
1164 for (int i = 0; i < length; i++) { | 1179 for (int i = 0; i < length; i++) { |
1165 result[i] = start[i + 1]; | 1180 result[i] = start[i + 1]; |
1166 } | 1181 } |
1167 result[length] = '\0'; | 1182 result[length] = '\0'; |
1168 if (chars != NULL) *chars = length; | 1183 if (chars != NULL) *chars = length; |
1169 return result; | 1184 return result; |
1170 } | 1185 } |
(...skipping 28 matching lines...) Expand all Loading... |
1199 | 1214 |
1200 const char* ScriptDataImpl::BuildMessage() { | 1215 const char* ScriptDataImpl::BuildMessage() { |
1201 unsigned* start = ReadAddress(kMessageTextPos); | 1216 unsigned* start = ReadAddress(kMessageTextPos); |
1202 return ReadString(start, NULL); | 1217 return ReadString(start, NULL); |
1203 } | 1218 } |
1204 | 1219 |
1205 | 1220 |
1206 Vector<const char*> ScriptDataImpl::BuildArgs() { | 1221 Vector<const char*> ScriptDataImpl::BuildArgs() { |
1207 int arg_count = Read(kMessageArgCountPos); | 1222 int arg_count = Read(kMessageArgCountPos); |
1208 const char** array = NewArray<const char*>(arg_count); | 1223 const char** array = NewArray<const char*>(arg_count); |
1209 // Position after the string starting at position 3. | 1224 // Position after text found by skipping past length field and |
| 1225 // length field content words. |
1210 int pos = kMessageTextPos + 1 + Read(kMessageTextPos); | 1226 int pos = kMessageTextPos + 1 + Read(kMessageTextPos); |
1211 for (int i = 0; i < arg_count; i++) { | 1227 for (int i = 0; i < arg_count; i++) { |
1212 int count = 0; | 1228 int count = 0; |
1213 array[i] = ReadString(ReadAddress(pos), &count); | 1229 array[i] = ReadString(ReadAddress(pos), &count); |
1214 pos += count + 1; | 1230 pos += count + 1; |
1215 } | 1231 } |
1216 return Vector<const char*>(array, arg_count); | 1232 return Vector<const char*>(array, arg_count); |
1217 } | 1233 } |
1218 | 1234 |
1219 | 1235 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1280 | 1296 |
1281 private: | 1297 private: |
1282 ParserFactory factory_; | 1298 ParserFactory factory_; |
1283 }; | 1299 }; |
1284 | 1300 |
1285 | 1301 |
1286 class CompletePreParser : public PreParser { | 1302 class CompletePreParser : public PreParser { |
1287 public: | 1303 public: |
1288 CompletePreParser(Handle<Script> script, bool allow_natives_syntax, | 1304 CompletePreParser(Handle<Script> script, bool allow_natives_syntax, |
1289 v8::Extension* extension) | 1305 v8::Extension* extension) |
1290 : PreParser(script, allow_natives_syntax, extension, &recorder_) { } | 1306 : PreParser(script, allow_natives_syntax, extension, &recorder_), |
| 1307 recorder_() { } |
1291 virtual PartialParserRecorder* recorder() { return &recorder_; } | 1308 virtual PartialParserRecorder* recorder() { return &recorder_; } |
1292 private: | 1309 private: |
1293 CompleteParserRecorder recorder_; | 1310 CompleteParserRecorder recorder_; |
1294 }; | 1311 }; |
1295 | 1312 |
1296 | 1313 |
1297 class PartialPreParser : public PreParser { | 1314 class PartialPreParser : public PreParser { |
1298 public: | 1315 public: |
1299 PartialPreParser(Handle<Script> script, bool allow_natives_syntax, | 1316 PartialPreParser(Handle<Script> script, bool allow_natives_syntax, |
1300 v8::Extension* extension) | 1317 v8::Extension* extension) |
1301 : PreParser(script, allow_natives_syntax, extension, &recorder_) { } | 1318 : PreParser(script, allow_natives_syntax, extension, &recorder_), |
| 1319 recorder_() { } |
1302 virtual PartialParserRecorder* recorder() { return &recorder_; } | 1320 virtual PartialParserRecorder* recorder() { return &recorder_; } |
1303 private: | 1321 private: |
1304 PartialParserRecorder recorder_; | 1322 PartialParserRecorder recorder_; |
1305 }; | 1323 }; |
1306 | 1324 |
1307 | 1325 |
1308 Scope* AstBuildingParserFactory::NewScope(Scope* parent, Scope::Type type, | 1326 Scope* AstBuildingParserFactory::NewScope(Scope* parent, Scope::Type type, |
1309 bool inside_with) { | 1327 bool inside_with) { |
1310 Scope* result = new Scope(parent, type); | 1328 Scope* result = new Scope(parent, type); |
1311 result->Initialize(inside_with); | 1329 result->Initialize(inside_with); |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1632 return result; | 1650 return result; |
1633 } | 1651 } |
1634 | 1652 |
1635 void Parser::ReportMessage(const char* type, Vector<const char*> args) { | 1653 void Parser::ReportMessage(const char* type, Vector<const char*> args) { |
1636 Scanner::Location source_location = scanner_.location(); | 1654 Scanner::Location source_location = scanner_.location(); |
1637 ReportMessageAt(source_location, type, args); | 1655 ReportMessageAt(source_location, type, args); |
1638 } | 1656 } |
1639 | 1657 |
1640 | 1658 |
1641 Handle<String> Parser::GetSymbol(bool* ok) { | 1659 Handle<String> Parser::GetSymbol(bool* ok) { |
| 1660 log()->LogSymbol(scanner_.location().beg_pos, scanner_.literal()); |
| 1661 int symbol_id = -1; |
1642 if (pre_data() != NULL) { | 1662 if (pre_data() != NULL) { |
1643 int symbol_id = | 1663 symbol_id = pre_data()->GetSymbolIdentifier(); |
1644 pre_data()->GetSymbolIdentifier(scanner_.location().beg_pos); | |
1645 if (symbol_id < 0) { | |
1646 ReportInvalidPreparseData(Factory::empty_symbol(), ok); | |
1647 return Handle<String>::null(); | |
1648 } | |
1649 return factory()->LookupSymbol(symbol_id, scanner_.literal()); | |
1650 } | 1664 } |
1651 log()->LogSymbol(scanner_.location().beg_pos, scanner_.literal()); | 1665 return factory()->LookupSymbol(symbol_id, scanner_.literal()); |
1652 return factory()->LookupSymbol(-1, scanner_.literal()); | |
1653 } | 1666 } |
1654 | 1667 |
1655 | 1668 |
1656 void AstBuildingParser::ReportMessageAt(Scanner::Location source_location, | 1669 void AstBuildingParser::ReportMessageAt(Scanner::Location source_location, |
1657 const char* type, | 1670 const char* type, |
1658 Vector<const char*> args) { | 1671 Vector<const char*> args) { |
1659 MessageLocation location(script_, | 1672 MessageLocation location(script_, |
1660 source_location.beg_pos, source_location.end_pos); | 1673 source_location.beg_pos, source_location.end_pos); |
1661 Handle<JSArray> array = Factory::NewJSArray(args.length()); | 1674 Handle<JSArray> array = Factory::NewJSArray(args.length()); |
1662 for (int i = 0; i < args.length(); i++) { | 1675 for (int i = 0; i < args.length(); i++) { |
(...skipping 2506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4169 ReportInvalidPreparseData(name, CHECK_OK); | 4182 ReportInvalidPreparseData(name, CHECK_OK); |
4170 } | 4183 } |
4171 end_pos = entry.end_pos(); | 4184 end_pos = entry.end_pos(); |
4172 if (end_pos <= function_block_pos) { | 4185 if (end_pos <= function_block_pos) { |
4173 // End position greater than end of stream is safe, and hard to check. | 4186 // End position greater than end of stream is safe, and hard to check. |
4174 ReportInvalidPreparseData(name, CHECK_OK); | 4187 ReportInvalidPreparseData(name, CHECK_OK); |
4175 } | 4188 } |
4176 Counters::total_preparse_skipped.Increment(end_pos - function_block_pos); | 4189 Counters::total_preparse_skipped.Increment(end_pos - function_block_pos); |
4177 scanner_.SeekForward(end_pos); | 4190 scanner_.SeekForward(end_pos); |
4178 pre_data()->Skip(entry.predata_function_skip(), | 4191 pre_data()->Skip(entry.predata_function_skip(), |
4179 entry.predata_symbol_skip(), | 4192 entry.predata_symbol_skip()); |
4180 entry.symbol_id_skip()); | |
4181 materialized_literal_count = entry.literal_count(); | 4193 materialized_literal_count = entry.literal_count(); |
4182 expected_property_count = entry.property_count(); | 4194 expected_property_count = entry.property_count(); |
4183 only_simple_this_property_assignments = false; | 4195 only_simple_this_property_assignments = false; |
4184 this_property_assignments = Factory::empty_fixed_array(); | 4196 this_property_assignments = Factory::empty_fixed_array(); |
4185 Expect(Token::RBRACE, CHECK_OK); | 4197 Expect(Token::RBRACE, CHECK_OK); |
4186 } else { | 4198 } else { |
4187 if (pre_data() != NULL) { | 4199 if (pre_data() != NULL) { |
4188 // Skip pre-data entry for non-lazily compiled function. | 4200 // Skip pre-data entry for non-lazily compiled function. |
4189 pre_data()->SkipFunctionEntry(function_block_pos); | 4201 pre_data()->SkipFunctionEntry(function_block_pos); |
4190 } | 4202 } |
4191 FunctionEntry entry = log()->LogFunction(function_block_pos); | 4203 FunctionEntry entry = log()->LogFunction(function_block_pos); |
4192 int predata_function_position_before = log()->function_position(); | 4204 int predata_function_position_before = log()->function_position(); |
4193 int predata_symbol_position_before = log()->symbol_position(); | 4205 int predata_symbol_position_before = log()->symbol_position(); |
4194 int symbol_ids_before = log()->symbol_ids(); | |
4195 ParseSourceElements(&body, Token::RBRACE, CHECK_OK); | 4206 ParseSourceElements(&body, Token::RBRACE, CHECK_OK); |
4196 materialized_literal_count = temp_scope.materialized_literal_count(); | 4207 materialized_literal_count = temp_scope.materialized_literal_count(); |
4197 expected_property_count = temp_scope.expected_property_count(); | 4208 expected_property_count = temp_scope.expected_property_count(); |
4198 only_simple_this_property_assignments = | 4209 only_simple_this_property_assignments = |
4199 temp_scope.only_simple_this_property_assignments(); | 4210 temp_scope.only_simple_this_property_assignments(); |
4200 this_property_assignments = temp_scope.this_property_assignments(); | 4211 this_property_assignments = temp_scope.this_property_assignments(); |
4201 | 4212 |
4202 Expect(Token::RBRACE, CHECK_OK); | 4213 Expect(Token::RBRACE, CHECK_OK); |
4203 end_pos = scanner_.location().end_pos; | 4214 end_pos = scanner_.location().end_pos; |
4204 if (entry.is_valid()) { | 4215 if (entry.is_valid()) { |
4205 entry.set_end_pos(end_pos); | 4216 entry.set_end_pos(end_pos); |
4206 entry.set_literal_count(materialized_literal_count); | 4217 entry.set_literal_count(materialized_literal_count); |
4207 entry.set_property_count(expected_property_count); | 4218 entry.set_property_count(expected_property_count); |
4208 entry.set_predata_function_skip( | 4219 entry.set_predata_function_skip( |
4209 log()->function_position() - predata_function_position_before); | 4220 log()->function_position() - predata_function_position_before); |
4210 entry.set_predata_symbol_skip( | 4221 entry.set_predata_symbol_skip( |
4211 log()->symbol_position() - predata_symbol_position_before); | 4222 log()->symbol_position() - predata_symbol_position_before); |
4212 entry.set_symbol_id_skip( | |
4213 log()->symbol_ids() - symbol_ids_before); | |
4214 } | 4223 } |
4215 } | 4224 } |
4216 | 4225 |
4217 FunctionLiteral* function_literal = | 4226 FunctionLiteral* function_literal = |
4218 NEW(FunctionLiteral(name, | 4227 NEW(FunctionLiteral(name, |
4219 top_scope_, | 4228 top_scope_, |
4220 body.elements(), | 4229 body.elements(), |
4221 materialized_literal_count, | 4230 materialized_literal_count, |
4222 expected_property_count, | 4231 expected_property_count, |
4223 only_simple_this_property_assignments, | 4232 only_simple_this_property_assignments, |
(...skipping 1251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5475 Bootstrapper::IsActive(); | 5484 Bootstrapper::IsActive(); |
5476 PartialPreParser parser(no_script, allow_natives_syntax, extension); | 5485 PartialPreParser parser(no_script, allow_natives_syntax, extension); |
5477 if (!parser.PreParseProgram(source, stream)) return NULL; | 5486 if (!parser.PreParseProgram(source, stream)) return NULL; |
5478 // Extract the accumulated data from the recorder as a single | 5487 // Extract the accumulated data from the recorder as a single |
5479 // contiguous vector that we are responsible for disposing. | 5488 // contiguous vector that we are responsible for disposing. |
5480 Vector<unsigned> store = parser.recorder()->ExtractData(); | 5489 Vector<unsigned> store = parser.recorder()->ExtractData(); |
5481 return new ScriptDataImpl(store); | 5490 return new ScriptDataImpl(store); |
5482 } | 5491 } |
5483 | 5492 |
5484 | 5493 |
| 5494 void ScriptDataImpl::Initialize() { |
| 5495 if (store_.length() >= kHeaderSize) { |
| 5496 int symbol_data_offset = kHeaderSize + store_[kFunctionsSizeOffset]; |
| 5497 if (store_.length() > symbol_data_offset) { |
| 5498 symbol_data_ = reinterpret_cast<byte*>(&store_[symbol_data_offset]); |
| 5499 } else { |
| 5500 // Partial preparse causes no symbol information. |
| 5501 symbol_data_ = reinterpret_cast<byte*>(&store_[0] + store_.length()); |
| 5502 } |
| 5503 symbol_data_end_ = reinterpret_cast<byte*>(&store_[0] + store_.length()); |
| 5504 } |
| 5505 } |
| 5506 |
| 5507 |
| 5508 int ScriptDataImpl::ReadNumber(byte** source) { |
| 5509 // Reads a number from symbol_data_ in base 128. The most significant |
| 5510 // bit marks that there are more digits. |
| 5511 // If the first byte is 0x80 (kNumberTerminator), it would normally |
| 5512 // represent a leading zero. Since that is useless, and therefore won't |
| 5513 // appear as the first digit of any actual value, it is used to |
| 5514 // mark the end of the input stream. |
| 5515 byte* data = *source; |
| 5516 if (data >= symbol_data_end_) return -1; |
| 5517 byte input = *data; |
| 5518 if (input == kNumberTerminator) { |
| 5519 // End of stream marker. |
| 5520 return -1; |
| 5521 } |
| 5522 int result = input & 0x7f; |
| 5523 data++; |
| 5524 while ((input & 0x80u) != 0) { |
| 5525 if (data >= symbol_data_end_) return -1; |
| 5526 input = *data; |
| 5527 result = (result << 7) | (input & 0x7f); |
| 5528 data++; |
| 5529 } |
| 5530 *source = data; |
| 5531 return result; |
| 5532 } |
| 5533 |
| 5534 |
5485 ScriptDataImpl* PreParse(Handle<String> source, | 5535 ScriptDataImpl* PreParse(Handle<String> source, |
5486 unibrow::CharacterStream* stream, | 5536 unibrow::CharacterStream* stream, |
5487 v8::Extension* extension) { | 5537 v8::Extension* extension) { |
5488 Handle<Script> no_script; | 5538 Handle<Script> no_script; |
5489 bool allow_natives_syntax = | 5539 bool allow_natives_syntax = |
5490 always_allow_natives_syntax || | 5540 always_allow_natives_syntax || |
5491 FLAG_allow_natives_syntax || | 5541 FLAG_allow_natives_syntax || |
5492 Bootstrapper::IsActive(); | 5542 Bootstrapper::IsActive(); |
5493 CompletePreParser parser(no_script, allow_natives_syntax, extension); | 5543 CompletePreParser parser(no_script, allow_natives_syntax, extension); |
5494 if (!parser.PreParseProgram(source, stream)) return NULL; | 5544 if (!parser.PreParseProgram(source, stream)) return NULL; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5570 parser.ParseLazy(script_source, name, | 5620 parser.ParseLazy(script_source, name, |
5571 start_position, end_position, is_expression); | 5621 start_position, end_position, is_expression); |
5572 return result; | 5622 return result; |
5573 } | 5623 } |
5574 | 5624 |
5575 | 5625 |
5576 #undef NEW | 5626 #undef NEW |
5577 | 5627 |
5578 | 5628 |
5579 } } // namespace v8::internal | 5629 } } // namespace v8::internal |
OLD | NEW |