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

Side by Side Diff: src/preparser.h

Issue 231073002: WIP: Parser: delay string internalization. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: internalizing better Created 6 years, 7 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_PREPARSER_H 5 #ifndef V8_PREPARSER_H
6 #define V8_PREPARSER_H 6 #define V8_PREPARSER_H
7 7
8 #include "func-name-inferrer.h" 8 #include "func-name-inferrer.h"
9 #include "hashmap.h" 9 #include "hashmap.h"
10 #include "scopes.h" 10 #include "scopes.h"
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 *ok = false; 320 *ok = false;
321 } 321 }
322 } 322 }
323 323
324 // Checks whether an octal literal was last seen between beg_pos and end_pos. 324 // Checks whether an octal literal was last seen between beg_pos and end_pos.
325 // If so, reports an error. Only called for strict mode. 325 // If so, reports an error. Only called for strict mode.
326 void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { 326 void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
327 Scanner::Location octal = scanner()->octal_position(); 327 Scanner::Location octal = scanner()->octal_position();
328 if (octal.IsValid() && beg_pos <= octal.beg_pos && 328 if (octal.IsValid() && beg_pos <= octal.beg_pos &&
329 octal.end_pos <= end_pos) { 329 octal.end_pos <= end_pos) {
330 ReportMessageAt(octal, "strict_octal_literal"); 330 this->ReportMessageAt(octal, "strict_octal_literal");
331 scanner()->clear_octal_position(); 331 scanner()->clear_octal_position();
332 *ok = false; 332 *ok = false;
333 } 333 }
334 } 334 }
335 335
336 // Determine precedence of given token. 336 // Determine precedence of given token.
337 static int Precedence(Token::Value token, bool accept_IN) { 337 static int Precedence(Token::Value token, bool accept_IN) {
338 if (token == Token::IN && !accept_IN) 338 if (token == Token::IN && !accept_IN)
339 return 0; // 0 precedence will terminate binary expression parsing 339 return 0; // 0 precedence will terminate binary expression parsing
340 return Token::Precedence(token); 340 return Token::Precedence(token);
341 } 341 }
342 342
343 typename Traits::Type::Factory* factory() { 343 typename Traits::Type::Factory* factory() {
344 return function_state_->factory(); 344 return function_state_->factory();
345 } 345 }
346 346
347 StrictMode strict_mode() { return scope_->strict_mode(); } 347 StrictMode strict_mode() { return scope_->strict_mode(); }
348 bool is_generator() const { return function_state_->is_generator(); } 348 bool is_generator() const { return function_state_->is_generator(); }
349 349
350 // Report syntax errors. 350 // Report syntax errors.
351 void ReportMessage(const char* message, Vector<const char*> args, 351 void ReportMessage(const char* message, const char* arg = NULL,
352 bool is_reference_error = false) { 352 bool is_reference_error = false) {
353 Scanner::Location source_location = scanner()->location(); 353 Scanner::Location source_location = scanner()->location();
354 Traits::ReportMessageAt(source_location, message, args, is_reference_error); 354 Traits::ReportMessageAt(source_location, message, arg, is_reference_error);
355 }
356
357 void ReportMessageAt(Scanner::Location location, const char* message,
358 bool is_reference_error = false) {
359 Traits::ReportMessageAt(location, message, Vector<const char*>::empty(),
360 is_reference_error);
361 } 355 }
362 356
363 void ReportUnexpectedToken(Token::Value token); 357 void ReportUnexpectedToken(Token::Value token);
364 358
365 // Recursive descent functions: 359 // Recursive descent functions:
366 360
367 // Parses an identifier that is valid for the current scope, in particular it 361 // Parses an identifier that is valid for the current scope, in particular it
368 // fails on strict mode future reserved keywords in a strict scope. If 362 // fails on strict mode future reserved keywords in a strict scope. If
369 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or 363 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
370 // "arguments" as identifier even in strict mode (this is needed in cases like 364 // "arguments" as identifier even in strict mode (this is needed in cases like
371 // "var foo = eval;"). 365 // "var foo = eval;").
372 IdentifierT ParseIdentifier( 366 IdentifierT ParseIdentifier(AllowEvalOrArgumentsAsIdentifier, bool* ok);
373 AllowEvalOrArgumentsAsIdentifier,
374 bool* ok);
375 // Parses an identifier or a strict mode future reserved word, and indicate 367 // Parses an identifier or a strict mode future reserved word, and indicate
376 // whether it is strict mode future reserved. 368 // whether it is strict mode future reserved.
377 IdentifierT ParseIdentifierOrStrictReservedWord( 369 IdentifierT ParseIdentifierOrStrictReservedWord(
378 bool* is_strict_reserved, 370 bool* is_strict_reserved,
379 bool* ok); 371 bool* ok);
380 IdentifierT ParseIdentifierName(bool* ok); 372 IdentifierT ParseIdentifierName(bool* ok);
381 // Parses an identifier and determines whether or not it is 'get' or 'set'. 373 // Parses an identifier and determines whether or not it is 'get' or 'set'.
382 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, 374 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get,
383 bool* is_set, 375 bool* is_set,
384 bool* ok); 376 bool* ok);
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after
961 return PreParserExpression::Default(); 953 return PreParserExpression::Default();
962 } 954 }
963 PreParserExpression NewThrowTypeError( 955 PreParserExpression NewThrowTypeError(
964 const char* type, Handle<Object> arg, int pos) { 956 const char* type, Handle<Object> arg, int pos) {
965 return PreParserExpression::Default(); 957 return PreParserExpression::Default();
966 } 958 }
967 959
968 // Reporting errors. 960 // Reporting errors.
969 void ReportMessageAt(Scanner::Location location, 961 void ReportMessageAt(Scanner::Location location,
970 const char* message, 962 const char* message,
971 Vector<const char*> args, 963 const char* arg = NULL,
972 bool is_reference_error = false);
973 void ReportMessageAt(Scanner::Location location,
974 const char* type,
975 const char* name_opt,
976 bool is_reference_error = false); 964 bool is_reference_error = false);
977 void ReportMessageAt(int start_pos, 965 void ReportMessageAt(int start_pos,
978 int end_pos, 966 int end_pos,
979 const char* type, 967 const char* message,
980 const char* name_opt, 968 const char* arg = NULL,
981 bool is_reference_error = false); 969 bool is_reference_error = false);
982 970
983 // "null" return type creators. 971 // "null" return type creators.
984 static PreParserIdentifier EmptyIdentifier() { 972 static PreParserIdentifier EmptyIdentifier() {
985 return PreParserIdentifier::Default(); 973 return PreParserIdentifier::Default();
986 } 974 }
987 static PreParserExpression EmptyExpression() { 975 static PreParserExpression EmptyExpression() {
988 return PreParserExpression::Default(); 976 return PreParserExpression::Default();
989 } 977 }
990 static PreParserExpression EmptyLiteral() { 978 static PreParserExpression EmptyLiteral() {
991 return PreParserExpression::Default(); 979 return PreParserExpression::Default();
992 } 980 }
993 static PreParserExpressionList NullExpressionList() { 981 static PreParserExpressionList NullExpressionList() {
994 return PreParserExpressionList(); 982 return PreParserExpressionList();
995 } 983 }
996 984
997 // Odd-ball literal creators. 985 // Odd-ball literal creators.
998 static PreParserExpression GetLiteralTheHole(int position, 986 static PreParserExpression GetLiteralTheHole(int position,
999 PreParserFactory* factory) { 987 PreParserFactory* factory) {
1000 return PreParserExpression::Default(); 988 return PreParserExpression::Default();
1001 } 989 }
1002 990
1003 // Producing data during the recursive descent. 991 // Producing data during the recursive descent.
1004 PreParserIdentifier GetSymbol(Scanner* scanner); 992 PreParserIdentifier GetSymbol(Scanner* scanner);
1005 static PreParserIdentifier NextLiteralString(Scanner* scanner, 993
1006 PretenureFlag tenured) { 994 PreParserIdentifier GetNextSymbol(Scanner* scanner) {
1007 return PreParserIdentifier::Default(); 995 return PreParserIdentifier::Default();
1008 } 996 }
1009 997
1010 static PreParserExpression ThisExpression(PreParserScope* scope, 998 static PreParserExpression ThisExpression(PreParserScope* scope,
1011 PreParserFactory* factory) { 999 PreParserFactory* factory) {
1012 return PreParserExpression::This(); 1000 return PreParserExpression::This();
1013 } 1001 }
1014 1002
1015 static PreParserExpression ExpressionFromLiteral( 1003 static PreParserExpression ExpressionFromLiteral(
1016 Token::Value token, int pos, Scanner* scanner, 1004 Token::Value token, int pos, Scanner* scanner,
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
1216 } 1204 }
1217 1205
1218 1206
1219 template<class Traits> 1207 template<class Traits>
1220 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { 1208 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
1221 Scanner::Location source_location = scanner()->location(); 1209 Scanner::Location source_location = scanner()->location();
1222 1210
1223 // Four of the tokens are treated specially 1211 // Four of the tokens are treated specially
1224 switch (token) { 1212 switch (token) {
1225 case Token::EOS: 1213 case Token::EOS:
1226 return ReportMessageAt(source_location, "unexpected_eos"); 1214 return this->ReportMessageAt(source_location, "unexpected_eos");
1227 case Token::NUMBER: 1215 case Token::NUMBER:
1228 return ReportMessageAt(source_location, "unexpected_token_number"); 1216 return this->ReportMessageAt(source_location, "unexpected_token_number");
1229 case Token::STRING: 1217 case Token::STRING:
1230 return ReportMessageAt(source_location, "unexpected_token_string"); 1218 return this->ReportMessageAt(source_location, "unexpected_token_string");
1231 case Token::IDENTIFIER: 1219 case Token::IDENTIFIER:
1232 return ReportMessageAt(source_location, "unexpected_token_identifier"); 1220 return this->ReportMessageAt(source_location,
1221 "unexpected_token_identifier");
1233 case Token::FUTURE_RESERVED_WORD: 1222 case Token::FUTURE_RESERVED_WORD:
1234 return ReportMessageAt(source_location, "unexpected_reserved"); 1223 return this->ReportMessageAt(source_location, "unexpected_reserved");
1235 case Token::YIELD: 1224 case Token::YIELD:
1236 case Token::FUTURE_STRICT_RESERVED_WORD: 1225 case Token::FUTURE_STRICT_RESERVED_WORD:
1237 return ReportMessageAt(source_location, strict_mode() == SLOPPY 1226 return this->ReportMessageAt(source_location, strict_mode() == SLOPPY
1238 ? "unexpected_token_identifier" : "unexpected_strict_reserved"); 1227 ? "unexpected_token_identifier" : "unexpected_strict_reserved");
1239 default: 1228 default:
1240 const char* name = Token::String(token); 1229 const char* name = Token::String(token);
1241 ASSERT(name != NULL); 1230 ASSERT(name != NULL);
1242 Traits::ReportMessageAt( 1231 Traits::ReportMessageAt(
1243 source_location, "unexpected_token", Vector<const char*>(&name, 1)); 1232 source_location, "unexpected_token", name);
1244 } 1233 }
1245 } 1234 }
1246 1235
1247 1236
1248 template<class Traits> 1237 template<class Traits>
1249 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( 1238 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
1250 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, 1239 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments,
1251 bool* ok) { 1240 bool* ok) {
1252 Token::Value next = Next(); 1241 Token::Value next = Next();
1253 if (next == Token::IDENTIFIER) { 1242 if (next == Token::IDENTIFIER) {
1254 IdentifierT name = this->GetSymbol(scanner()); 1243 IdentifierT name = this->GetSymbol(scanner());
1255 if (allow_eval_or_arguments == kDontAllowEvalOrArguments && 1244 if (allow_eval_or_arguments == kDontAllowEvalOrArguments &&
1256 strict_mode() == STRICT && this->IsEvalOrArguments(name)) { 1245 strict_mode() == STRICT &&
1246 this->IsEvalOrArguments(name)) {
1257 ReportMessageAt(scanner()->location(), "strict_eval_arguments"); 1247 ReportMessageAt(scanner()->location(), "strict_eval_arguments");
1258 *ok = false; 1248 *ok = false;
1259 } 1249 }
1260 return name; 1250 return name;
1261 } else if (strict_mode() == SLOPPY && 1251 } else if (strict_mode() == SLOPPY &&
1262 (next == Token::FUTURE_STRICT_RESERVED_WORD || 1252 (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1263 (next == Token::YIELD && !is_generator()))) { 1253 (next == Token::YIELD && !is_generator()))) {
1264 return this->GetSymbol(scanner()); 1254 return this->GetSymbol(scanner());
1265 } else { 1255 } else {
1266 this->ReportUnexpectedToken(next); 1256 this->ReportUnexpectedToken(next);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1298 this->ReportUnexpectedToken(next); 1288 this->ReportUnexpectedToken(next);
1299 *ok = false; 1289 *ok = false;
1300 return Traits::EmptyIdentifier(); 1290 return Traits::EmptyIdentifier();
1301 } 1291 }
1302 return this->GetSymbol(scanner()); 1292 return this->GetSymbol(scanner());
1303 } 1293 }
1304 1294
1305 1295
1306 template <class Traits> 1296 template <class Traits>
1307 typename ParserBase<Traits>::IdentifierT 1297 typename ParserBase<Traits>::IdentifierT
1308 ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get, 1298 ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get, bool* is_set,
1309 bool* is_set,
1310 bool* ok) { 1299 bool* ok) {
1311 IdentifierT result = ParseIdentifierName(ok); 1300 IdentifierT result = ParseIdentifierName(ok);
1312 if (!*ok) return Traits::EmptyIdentifier(); 1301 if (!*ok) return Traits::EmptyIdentifier();
1313 scanner()->IsGetOrSet(is_get, is_set); 1302 scanner()->IsGetOrSet(is_get, is_set);
1314 return result; 1303 return result;
1315 } 1304 }
1316 1305
1317 1306
1318 template <class Traits> 1307 template <class Traits>
1319 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral( 1308 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
1320 bool seen_equal, bool* ok) { 1309 bool seen_equal, bool* ok) {
1321 int pos = peek_position(); 1310 int pos = peek_position();
1322 if (!scanner()->ScanRegExpPattern(seen_equal)) { 1311 if (!scanner()->ScanRegExpPattern(seen_equal)) {
1323 Next(); 1312 Next();
1324 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); 1313 this->ReportMessage("unterminated_regexp");
1325 *ok = false; 1314 *ok = false;
1326 return Traits::EmptyExpression(); 1315 return Traits::EmptyExpression();
1327 } 1316 }
1328 1317
1329 int literal_index = function_state_->NextMaterializedLiteralIndex(); 1318 int literal_index = function_state_->NextMaterializedLiteralIndex();
1330 1319
1331 IdentifierT js_pattern = this->NextLiteralString(scanner(), TENURED); 1320 IdentifierT js_pattern = this->GetNextSymbol(scanner());
1332 if (!scanner()->ScanRegExpFlags()) { 1321 if (!scanner()->ScanRegExpFlags()) {
1333 Next(); 1322 Next();
1334 ReportMessageAt(scanner()->location(), "invalid_regexp_flags"); 1323 this->ReportMessage("invalid_regexp_flags");
1335 *ok = false; 1324 *ok = false;
1336 return Traits::EmptyExpression(); 1325 return Traits::EmptyExpression();
1337 } 1326 }
1338 IdentifierT js_flags = this->NextLiteralString(scanner(), TENURED); 1327 IdentifierT js_flags = this->GetNextSymbol(scanner());
1339 Next(); 1328 Next();
1340 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); 1329 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
1341 } 1330 }
1342 1331
1343 1332
1344 #define CHECK_OK ok); \ 1333 #define CHECK_OK ok); \
1345 if (!*ok) return this->EmptyExpression(); \ 1334 if (!*ok) return this->EmptyExpression(); \
1346 ((void)0 1335 ((void)0
1347 #define DUMMY ) // to make indentation work 1336 #define DUMMY ) // to make indentation work
1348 #undef DUMMY 1337 #undef DUMMY
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after
1857 1846
1858 Token::Value op = peek(); 1847 Token::Value op = peek();
1859 if (Token::IsUnaryOp(op)) { 1848 if (Token::IsUnaryOp(op)) {
1860 op = Next(); 1849 op = Next();
1861 int pos = position(); 1850 int pos = position();
1862 ExpressionT expression = ParseUnaryExpression(CHECK_OK); 1851 ExpressionT expression = ParseUnaryExpression(CHECK_OK);
1863 1852
1864 // "delete identifier" is a syntax error in strict mode. 1853 // "delete identifier" is a syntax error in strict mode.
1865 if (op == Token::DELETE && strict_mode() == STRICT && 1854 if (op == Token::DELETE && strict_mode() == STRICT &&
1866 this->IsIdentifier(expression)) { 1855 this->IsIdentifier(expression)) {
1867 ReportMessage("strict_delete", Vector<const char*>::empty()); 1856 this->ReportMessage("strict_delete");
1868 *ok = false; 1857 *ok = false;
1869 return this->EmptyExpression(); 1858 return this->EmptyExpression();
1870 } 1859 }
1871 1860
1872 // Allow Traits do rewrite the expression. 1861 // Allow Traits do rewrite the expression.
1873 return this->BuildUnaryExpression(expression, op, pos, factory()); 1862 return this->BuildUnaryExpression(expression, op, pos, factory());
1874 } else if (Token::IsCountOp(op)) { 1863 } else if (Token::IsCountOp(op)) {
1875 op = Next(); 1864 op = Next();
1876 Scanner::Location lhs_location = scanner()->peek_location(); 1865 Scanner::Location lhs_location = scanner()->peek_location();
1877 ExpressionT expression = this->ParseUnaryExpression(CHECK_OK); 1866 ExpressionT expression = this->ParseUnaryExpression(CHECK_OK);
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
2111 } 2100 }
2112 2101
2113 2102
2114 template <typename Traits> 2103 template <typename Traits>
2115 typename ParserBase<Traits>::ExpressionT 2104 typename ParserBase<Traits>::ExpressionT
2116 ParserBase<Traits>::CheckAndRewriteReferenceExpression( 2105 ParserBase<Traits>::CheckAndRewriteReferenceExpression(
2117 ExpressionT expression, 2106 ExpressionT expression,
2118 Scanner::Location location, const char* message, bool* ok) { 2107 Scanner::Location location, const char* message, bool* ok) {
2119 if (strict_mode() == STRICT && this->IsIdentifier(expression) && 2108 if (strict_mode() == STRICT && this->IsIdentifier(expression) &&
2120 this->IsEvalOrArguments(this->AsIdentifier(expression))) { 2109 this->IsEvalOrArguments(this->AsIdentifier(expression))) {
2121 this->ReportMessageAt(location, "strict_eval_arguments", false); 2110 this->ReportMessageAt(location, "strict_eval_arguments", (const char*)NULL,
rossberg 2014/05/08 12:52:08 Nit: style guide forbids C casts
marja 2014/06/03 08:48:20 This change is no longer needed
2111 false);
2122 *ok = false; 2112 *ok = false;
2123 return this->EmptyExpression(); 2113 return this->EmptyExpression();
2124 } else if (expression->IsValidReferenceExpression()) { 2114 } else if (expression->IsValidReferenceExpression()) {
2125 return expression; 2115 return expression;
2126 } else if (expression->IsCall()) { 2116 } else if (expression->IsCall()) {
2127 // If it is a call, make it a runtime error for legacy web compatibility. 2117 // If it is a call, make it a runtime error for legacy web compatibility.
2128 // Rewrite `expr' to `expr[throw ReferenceError]'. 2118 // Rewrite `expr' to `expr[throw ReferenceError]'.
2129 int pos = location.beg_pos; 2119 int pos = location.beg_pos;
2130 ExpressionT error = this->NewThrowReferenceError(message, pos); 2120 ExpressionT error = this->NewThrowReferenceError(message, pos);
2131 return factory()->NewProperty(expression, error, pos); 2121 return factory()->NewProperty(expression, error, pos);
2132 } else { 2122 } else {
2133 this->ReportMessageAt(location, message, true); 2123 this->ReportMessageAt(location, message, (const char*)NULL, true);
rossberg 2014/05/08 12:52:08 Same here
marja 2014/06/03 08:48:20 This change is no longer needed
2134 *ok = false; 2124 *ok = false;
2135 return this->EmptyExpression(); 2125 return this->EmptyExpression();
2136 } 2126 }
2137 } 2127 }
2138 2128
2139 2129
2140 #undef CHECK_OK 2130 #undef CHECK_OK
2141 #undef CHECK_OK_CUSTOM 2131 #undef CHECK_OK_CUSTOM
2142 2132
2143 2133
(...skipping 26 matching lines...) Expand all
2170 "accessor_get_set"); 2160 "accessor_get_set");
2171 } 2161 }
2172 *ok = false; 2162 *ok = false;
2173 } 2163 }
2174 } 2164 }
2175 2165
2176 2166
2177 } } // v8::internal 2167 } } // v8::internal
2178 2168
2179 #endif // V8_PREPARSER_H 2169 #endif // V8_PREPARSER_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698