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

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: rebased 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, const char* arg = NULL, 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, arg, is_reference_error); 354 Traits::ReportMessageAt(source_location, message, arg, is_reference_error);
355 } 355 }
356 356
357 void ReportMessageAt(Scanner::Location location, const char* message, 357 void ReportMessageAt(Scanner::Location location, const char* message,
358 bool is_reference_error = false) { 358 bool is_reference_error = false) {
359 Traits::ReportMessageAt(location, message, NULL, is_reference_error); 359 Traits::ReportMessageAt(location, message, (const char*)NULL,
360 is_reference_error);
360 } 361 }
361 362
362 void ReportUnexpectedToken(Token::Value token); 363 void ReportUnexpectedToken(Token::Value token);
363 364
364 // Recursive descent functions: 365 // Recursive descent functions:
365 366
366 // Parses an identifier that is valid for the current scope, in particular it 367 // Parses an identifier that is valid for the current scope, in particular it
367 // fails on strict mode future reserved keywords in a strict scope. If 368 // fails on strict mode future reserved keywords in a strict scope. If
368 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or 369 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
369 // "arguments" as identifier even in strict mode (this is needed in cases like 370 // "arguments" as identifier even in strict mode (this is needed in cases like
370 // "var foo = eval;"). 371 // "var foo = eval;").
371 IdentifierT ParseIdentifier( 372 IdentifierT ParseIdentifier(AllowEvalOrArgumentsAsIdentifier, bool* ok);
372 AllowEvalOrArgumentsAsIdentifier,
373 bool* ok);
374 // Parses an identifier or a strict mode future reserved word, and indicate 373 // Parses an identifier or a strict mode future reserved word, and indicate
375 // whether it is strict mode future reserved. 374 // whether it is strict mode future reserved.
376 IdentifierT ParseIdentifierOrStrictReservedWord( 375 IdentifierT ParseIdentifierOrStrictReservedWord(
377 bool* is_strict_reserved, 376 bool* is_strict_reserved,
378 bool* ok); 377 bool* ok);
379 IdentifierT ParseIdentifierName(bool* ok); 378 IdentifierT ParseIdentifierName(bool* ok);
380 // Parses an identifier and determines whether or not it is 'get' or 'set'. 379 // Parses an identifier and determines whether or not it is 'get' or 'set'.
381 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, 380 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get,
382 bool* is_set, 381 bool* is_set,
383 bool* ok); 382 bool* ok);
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after
990 } 989 }
991 990
992 // Odd-ball literal creators. 991 // Odd-ball literal creators.
993 static PreParserExpression GetLiteralTheHole(int position, 992 static PreParserExpression GetLiteralTheHole(int position,
994 PreParserFactory* factory) { 993 PreParserFactory* factory) {
995 return PreParserExpression::Default(); 994 return PreParserExpression::Default();
996 } 995 }
997 996
998 // Producing data during the recursive descent. 997 // Producing data during the recursive descent.
999 PreParserIdentifier GetSymbol(Scanner* scanner); 998 PreParserIdentifier GetSymbol(Scanner* scanner);
1000 static PreParserIdentifier NextLiteralString(Scanner* scanner, 999
1001 PretenureFlag tenured) { 1000 PreParserIdentifier GetNextSymbol(Scanner* scanner) {
1002 return PreParserIdentifier::Default(); 1001 return PreParserIdentifier::Default();
1003 } 1002 }
1004 1003
1005 static PreParserExpression ThisExpression(PreParserScope* scope, 1004 static PreParserExpression ThisExpression(PreParserScope* scope,
1006 PreParserFactory* factory) { 1005 PreParserFactory* factory) {
1007 return PreParserExpression::This(); 1006 return PreParserExpression::This();
1008 } 1007 }
1009 1008
1010 static PreParserExpression ExpressionFromLiteral( 1009 static PreParserExpression ExpressionFromLiteral(
1011 Token::Value token, int pos, Scanner* scanner, 1010 Token::Value token, int pos, Scanner* scanner,
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
1211 } 1210 }
1212 1211
1213 1212
1214 template<class Traits> 1213 template<class Traits>
1215 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { 1214 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
1216 Scanner::Location source_location = scanner()->location(); 1215 Scanner::Location source_location = scanner()->location();
1217 1216
1218 // Four of the tokens are treated specially 1217 // Four of the tokens are treated specially
1219 switch (token) { 1218 switch (token) {
1220 case Token::EOS: 1219 case Token::EOS:
1221 return ReportMessageAt(source_location, "unexpected_eos"); 1220 return this->ReportMessageAt(source_location, "unexpected_eos");
1222 case Token::NUMBER: 1221 case Token::NUMBER:
1223 return ReportMessageAt(source_location, "unexpected_token_number"); 1222 return this->ReportMessageAt(source_location, "unexpected_token_number");
1224 case Token::STRING: 1223 case Token::STRING:
1225 return ReportMessageAt(source_location, "unexpected_token_string"); 1224 return this->ReportMessageAt(source_location, "unexpected_token_string");
1226 case Token::IDENTIFIER: 1225 case Token::IDENTIFIER:
1227 return ReportMessageAt(source_location, "unexpected_token_identifier"); 1226 return this->ReportMessageAt(source_location,
1227 "unexpected_token_identifier");
1228 case Token::FUTURE_RESERVED_WORD: 1228 case Token::FUTURE_RESERVED_WORD:
1229 return ReportMessageAt(source_location, "unexpected_reserved"); 1229 return this->ReportMessageAt(source_location, "unexpected_reserved");
1230 case Token::YIELD: 1230 case Token::YIELD:
1231 case Token::FUTURE_STRICT_RESERVED_WORD: 1231 case Token::FUTURE_STRICT_RESERVED_WORD:
1232 return ReportMessageAt(source_location, strict_mode() == SLOPPY 1232 return this->ReportMessageAt(source_location, strict_mode() == SLOPPY
1233 ? "unexpected_token_identifier" : "unexpected_strict_reserved"); 1233 ? "unexpected_token_identifier" : "unexpected_strict_reserved");
1234 default: 1234 default:
1235 const char* name = Token::String(token); 1235 const char* name = Token::String(token);
1236 ASSERT(name != NULL); 1236 ASSERT(name != NULL);
1237 Traits::ReportMessageAt( 1237 Traits::ReportMessageAt(
1238 source_location, "unexpected_token", name); 1238 source_location, "unexpected_token", name);
1239 } 1239 }
1240 } 1240 }
1241 1241
1242 1242
1243 template<class Traits> 1243 template<class Traits>
1244 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( 1244 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
1245 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, 1245 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments,
1246 bool* ok) { 1246 bool* ok) {
1247 Token::Value next = Next(); 1247 Token::Value next = Next();
1248 if (next == Token::IDENTIFIER) { 1248 if (next == Token::IDENTIFIER) {
1249 IdentifierT name = this->GetSymbol(scanner()); 1249 IdentifierT name = this->GetSymbol(scanner());
1250 if (allow_eval_or_arguments == kDontAllowEvalOrArguments && 1250 if (allow_eval_or_arguments == kDontAllowEvalOrArguments &&
1251 strict_mode() == STRICT && this->IsEvalOrArguments(name)) { 1251 strict_mode() == STRICT &&
1252 this->IsEvalOrArguments(name)) {
1252 ReportMessageAt(scanner()->location(), "strict_eval_arguments"); 1253 ReportMessageAt(scanner()->location(), "strict_eval_arguments");
1253 *ok = false; 1254 *ok = false;
1254 } 1255 }
1255 return name; 1256 return name;
1256 } else if (strict_mode() == SLOPPY && 1257 } else if (strict_mode() == SLOPPY &&
1257 (next == Token::FUTURE_STRICT_RESERVED_WORD || 1258 (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1258 (next == Token::YIELD && !is_generator()))) { 1259 (next == Token::YIELD && !is_generator()))) {
1259 return this->GetSymbol(scanner()); 1260 return this->GetSymbol(scanner());
1260 } else { 1261 } else {
1261 this->ReportUnexpectedToken(next); 1262 this->ReportUnexpectedToken(next);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1293 this->ReportUnexpectedToken(next); 1294 this->ReportUnexpectedToken(next);
1294 *ok = false; 1295 *ok = false;
1295 return Traits::EmptyIdentifier(); 1296 return Traits::EmptyIdentifier();
1296 } 1297 }
1297 return this->GetSymbol(scanner()); 1298 return this->GetSymbol(scanner());
1298 } 1299 }
1299 1300
1300 1301
1301 template <class Traits> 1302 template <class Traits>
1302 typename ParserBase<Traits>::IdentifierT 1303 typename ParserBase<Traits>::IdentifierT
1303 ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get, 1304 ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get, bool* is_set,
1304 bool* is_set,
1305 bool* ok) { 1305 bool* ok) {
1306 IdentifierT result = ParseIdentifierName(ok); 1306 IdentifierT result = ParseIdentifierName(ok);
1307 if (!*ok) return Traits::EmptyIdentifier(); 1307 if (!*ok) return Traits::EmptyIdentifier();
1308 scanner()->IsGetOrSet(is_get, is_set); 1308 scanner()->IsGetOrSet(is_get, is_set);
1309 return result; 1309 return result;
1310 } 1310 }
1311 1311
1312 1312
1313 template <class Traits> 1313 template <class Traits>
1314 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral( 1314 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
1315 bool seen_equal, bool* ok) { 1315 bool seen_equal, bool* ok) {
1316 int pos = peek_position(); 1316 int pos = peek_position();
1317 if (!scanner()->ScanRegExpPattern(seen_equal)) { 1317 if (!scanner()->ScanRegExpPattern(seen_equal)) {
1318 Next(); 1318 Next();
1319 ReportMessage("unterminated_regexp"); 1319 ReportMessage("unterminated_regexp");
1320 *ok = false; 1320 *ok = false;
1321 return Traits::EmptyExpression(); 1321 return Traits::EmptyExpression();
1322 } 1322 }
1323 1323
1324 int literal_index = function_state_->NextMaterializedLiteralIndex(); 1324 int literal_index = function_state_->NextMaterializedLiteralIndex();
1325 1325
1326 IdentifierT js_pattern = this->NextLiteralString(scanner(), TENURED); 1326 IdentifierT js_pattern = this->GetNextSymbol(scanner());
1327 if (!scanner()->ScanRegExpFlags()) { 1327 if (!scanner()->ScanRegExpFlags()) {
1328 Next(); 1328 Next();
1329 ReportMessageAt(scanner()->location(), "invalid_regexp_flags"); 1329 this->ReportMessage("invalid_regexp_flags");
1330 *ok = false; 1330 *ok = false;
1331 return Traits::EmptyExpression(); 1331 return Traits::EmptyExpression();
1332 } 1332 }
1333 IdentifierT js_flags = this->NextLiteralString(scanner(), TENURED); 1333 IdentifierT js_flags = this->GetNextSymbol(scanner());
1334 Next(); 1334 Next();
1335 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); 1335 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
1336 } 1336 }
1337 1337
1338 1338
1339 #define CHECK_OK ok); \ 1339 #define CHECK_OK ok); \
1340 if (!*ok) return this->EmptyExpression(); \ 1340 if (!*ok) return this->EmptyExpression(); \
1341 ((void)0 1341 ((void)0
1342 #define DUMMY ) // to make indentation work 1342 #define DUMMY ) // to make indentation work
1343 #undef DUMMY 1343 #undef DUMMY
(...skipping 762 matching lines...) Expand 10 before | Expand all | Expand 10 after
2106 } 2106 }
2107 2107
2108 2108
2109 template <typename Traits> 2109 template <typename Traits>
2110 typename ParserBase<Traits>::ExpressionT 2110 typename ParserBase<Traits>::ExpressionT
2111 ParserBase<Traits>::CheckAndRewriteReferenceExpression( 2111 ParserBase<Traits>::CheckAndRewriteReferenceExpression(
2112 ExpressionT expression, 2112 ExpressionT expression,
2113 Scanner::Location location, const char* message, bool* ok) { 2113 Scanner::Location location, const char* message, bool* ok) {
2114 if (strict_mode() == STRICT && this->IsIdentifier(expression) && 2114 if (strict_mode() == STRICT && this->IsIdentifier(expression) &&
2115 this->IsEvalOrArguments(this->AsIdentifier(expression))) { 2115 this->IsEvalOrArguments(this->AsIdentifier(expression))) {
2116 this->ReportMessageAt(location, "strict_eval_arguments", false); 2116 this->ReportMessageAt(location, "strict_eval_arguments");
2117 *ok = false; 2117 *ok = false;
2118 return this->EmptyExpression(); 2118 return this->EmptyExpression();
2119 } else if (expression->IsValidReferenceExpression()) { 2119 } else if (expression->IsValidReferenceExpression()) {
2120 return expression; 2120 return expression;
2121 } else if (expression->IsCall()) { 2121 } else if (expression->IsCall()) {
2122 // If it is a call, make it a runtime error for legacy web compatibility. 2122 // If it is a call, make it a runtime error for legacy web compatibility.
2123 // Rewrite `expr' to `expr[throw ReferenceError]'. 2123 // Rewrite `expr' to `expr[throw ReferenceError]'.
2124 int pos = location.beg_pos; 2124 int pos = location.beg_pos;
2125 ExpressionT error = this->NewThrowReferenceError(message, pos); 2125 ExpressionT error = this->NewThrowReferenceError(message, pos);
2126 return factory()->NewProperty(expression, error, pos); 2126 return factory()->NewProperty(expression, error, pos);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2165 "accessor_get_set"); 2165 "accessor_get_set");
2166 } 2166 }
2167 *ok = false; 2167 *ok = false;
2168 } 2168 }
2169 } 2169 }
2170 2170
2171 2171
2172 } } // v8::internal 2172 } } // v8::internal
2173 2173
2174 #endif // V8_PREPARSER_H 2174 #endif // V8_PREPARSER_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698