Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(154)

Side by Side Diff: src/parser.cc

Issue 3421009: Revision 2.4.4.... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: '' Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/parser.h ('k') | src/profile-generator.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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 12 matching lines...) Expand all
4236 } 4245 }
4237 } 4246 }
4238 4247
4239 4248
4240 Expression* Parser::ParseV8Intrinsic(bool* ok) { 4249 Expression* Parser::ParseV8Intrinsic(bool* ok) {
4241 // CallRuntime :: 4250 // CallRuntime ::
4242 // '%' Identifier Arguments 4251 // '%' Identifier Arguments
4243 4252
4244 Expect(Token::MOD, CHECK_OK); 4253 Expect(Token::MOD, CHECK_OK);
4245 Handle<String> name = ParseIdentifier(CHECK_OK); 4254 Handle<String> name = ParseIdentifier(CHECK_OK);
4246 Runtime::Function* function =
4247 Runtime::FunctionForName(scanner_.literal());
4248 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); 4255 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
4249 if (function == NULL && extension_ != NULL) { 4256 if (is_pre_parsing_) return NULL;
4257
4258 if (extension_ != NULL) {
4250 // The extension structures are only accessible while parsing the 4259 // The extension structures are only accessible while parsing the
4251 // very first time not when reparsing because of lazy compilation. 4260 // very first time not when reparsing because of lazy compilation.
4252 top_scope_->ForceEagerCompilation(); 4261 top_scope_->ForceEagerCompilation();
4253 } 4262 }
4254 4263
4255 // Check for built-in macros. 4264 Runtime::Function* function = Runtime::FunctionForSymbol(name);
4256 if (!is_pre_parsing_) { 4265
4257 if (function == Runtime::FunctionForId(Runtime::kIS_VAR)) { 4266 // Check for built-in IS_VAR macro.
4258 // %IS_VAR(x) 4267 if (function != NULL &&
4259 // evaluates to x if x is a variable, 4268 function->intrinsic_type == Runtime::RUNTIME &&
4260 // leads to a parse error otherwise 4269 function->function_id == Runtime::kIS_VAR) {
4261 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) { 4270 // %IS_VAR(x) evaluates to x if x is a variable,
4262 return args->at(0); 4271 // leads to a parse error otherwise. Could be implemented as an
4263 } 4272 // inline function %_IS_VAR(x) to eliminate this special case.
4273 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
4274 return args->at(0);
4275 } else {
4276 ReportMessage("unable_to_parse", Vector<const char*>::empty());
4264 *ok = false; 4277 *ok = false;
4265 // Check here for other macros.
4266 // } else if (function == Runtime::FunctionForId(Runtime::kIS_VAR)) {
4267 // ...
4268 }
4269
4270 if (!*ok) {
4271 // We found a macro but it failed.
4272 ReportMessage("unable_to_parse", Vector<const char*>::empty());
4273 return NULL; 4278 return NULL;
4274 } 4279 }
4275 } 4280 }
4276 4281
4277 // Check that the expected number arguments are passed to runtime functions. 4282 // Check that the expected number of arguments are being passed.
4278 if (!is_pre_parsing_) { 4283 if (function != NULL &&
4279 if (function != NULL 4284 function->nargs != -1 &&
4280 && function->nargs != -1 4285 function->nargs != args->length()) {
4281 && function->nargs != args->length()) { 4286 ReportMessage("illegal_access", Vector<const char*>::empty());
4282 ReportMessage("illegal_access", Vector<const char*>::empty()); 4287 *ok = false;
4283 *ok = false; 4288 return NULL;
4284 return NULL;
4285 } else if (function == NULL && !name.is_null()) {
4286 // If this is not a runtime function implemented in C++ it might be an
4287 // inlined runtime function.
4288 int argc = CodeGenerator::InlineRuntimeCallArgumentsCount(name);
4289 if (argc != -1 && argc != args->length()) {
4290 ReportMessage("illegal_access", Vector<const char*>::empty());
4291 *ok = false;
4292 return NULL;
4293 }
4294 }
4295 } 4289 }
4296 4290
4297 // Otherwise we have a valid runtime call. 4291 // We have a valid intrinsics call or a call to a builtin.
4298 return NEW(CallRuntime(name, function, args)); 4292 return NEW(CallRuntime(name, function, args));
4299 } 4293 }
4300 4294
4301 4295
4302 void Parser::Consume(Token::Value token) { 4296 void Parser::Consume(Token::Value token) {
4303 Token::Value next = Next(); 4297 Token::Value next = Next();
4304 USE(next); 4298 USE(next);
4305 USE(token); 4299 USE(token);
4306 ASSERT(next == token); 4300 ASSERT(next == token);
4307 } 4301 }
(...skipping 1182 matching lines...) Expand 10 before | Expand all | Expand 10 after
5490 Bootstrapper::IsActive(); 5484 Bootstrapper::IsActive();
5491 PartialPreParser parser(no_script, allow_natives_syntax, extension); 5485 PartialPreParser parser(no_script, allow_natives_syntax, extension);
5492 if (!parser.PreParseProgram(source, stream)) return NULL; 5486 if (!parser.PreParseProgram(source, stream)) return NULL;
5493 // Extract the accumulated data from the recorder as a single 5487 // Extract the accumulated data from the recorder as a single
5494 // contiguous vector that we are responsible for disposing. 5488 // contiguous vector that we are responsible for disposing.
5495 Vector<unsigned> store = parser.recorder()->ExtractData(); 5489 Vector<unsigned> store = parser.recorder()->ExtractData();
5496 return new ScriptDataImpl(store); 5490 return new ScriptDataImpl(store);
5497 } 5491 }
5498 5492
5499 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
5500 ScriptDataImpl* PreParse(Handle<String> source, 5535 ScriptDataImpl* PreParse(Handle<String> source,
5501 unibrow::CharacterStream* stream, 5536 unibrow::CharacterStream* stream,
5502 v8::Extension* extension) { 5537 v8::Extension* extension) {
5503 Handle<Script> no_script; 5538 Handle<Script> no_script;
5504 bool allow_natives_syntax = 5539 bool allow_natives_syntax =
5505 always_allow_natives_syntax || 5540 always_allow_natives_syntax ||
5506 FLAG_allow_natives_syntax || 5541 FLAG_allow_natives_syntax ||
5507 Bootstrapper::IsActive(); 5542 Bootstrapper::IsActive();
5508 CompletePreParser parser(no_script, allow_natives_syntax, extension); 5543 CompletePreParser parser(no_script, allow_natives_syntax, extension);
5509 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
5585 parser.ParseLazy(script_source, name, 5620 parser.ParseLazy(script_source, name,
5586 start_position, end_position, is_expression); 5621 start_position, end_position, is_expression);
5587 return result; 5622 return result;
5588 } 5623 }
5589 5624
5590 5625
5591 #undef NEW 5626 #undef NEW
5592 5627
5593 5628
5594 } } // namespace v8::internal 5629 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/profile-generator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698