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

Side by Side Diff: src/preparser.h

Issue 203493002: (Pre)Parser unification: use shorter type names. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: code review (mstarzinger) Created 6 years, 9 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 // typedef PropertyList; 74 // typedef PropertyList;
75 // // For constructing objects returned by the traversing functions. 75 // // For constructing objects returned by the traversing functions.
76 // typedef Factory; 76 // typedef Factory;
77 // }; 77 // };
78 // // ... 78 // // ...
79 // }; 79 // };
80 80
81 template <typename Traits> 81 template <typename Traits>
82 class ParserBase : public Traits { 82 class ParserBase : public Traits {
83 public: 83 public:
84 // Shorten type names defined by Traits.
85 typedef typename Traits::Type::Expression ExpressionT;
86 typedef typename Traits::Type::Identifier IdentifierT;
87
84 ParserBase(Scanner* scanner, uintptr_t stack_limit, 88 ParserBase(Scanner* scanner, uintptr_t stack_limit,
85 v8::Extension* extension, 89 v8::Extension* extension,
86 typename Traits::Type::Zone* zone, 90 typename Traits::Type::Zone* zone,
87 typename Traits::Type::Parser this_object) 91 typename Traits::Type::Parser this_object)
88 : Traits(this_object), 92 : Traits(this_object),
89 parenthesized_function_(false), 93 parenthesized_function_(false),
90 scope_(NULL), 94 scope_(NULL),
91 function_state_(NULL), 95 function_state_(NULL),
92 extension_(extension), 96 extension_(extension),
93 fni_(NULL), 97 fni_(NULL),
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 360
357 void ReportUnexpectedToken(Token::Value token); 361 void ReportUnexpectedToken(Token::Value token);
358 362
359 // Recursive descent functions: 363 // Recursive descent functions:
360 364
361 // Parses an identifier that is valid for the current scope, in particular it 365 // Parses an identifier that is valid for the current scope, in particular it
362 // fails on strict mode future reserved keywords in a strict scope. If 366 // fails on strict mode future reserved keywords in a strict scope. If
363 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or 367 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
364 // "arguments" as identifier even in strict mode (this is needed in cases like 368 // "arguments" as identifier even in strict mode (this is needed in cases like
365 // "var foo = eval;"). 369 // "var foo = eval;").
366 typename Traits::Type::Identifier ParseIdentifier( 370 IdentifierT ParseIdentifier(
367 AllowEvalOrArgumentsAsIdentifier, 371 AllowEvalOrArgumentsAsIdentifier,
368 bool* ok); 372 bool* ok);
369 // 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
370 // whether it is strict mode future reserved. 374 // whether it is strict mode future reserved.
371 typename Traits::Type::Identifier ParseIdentifierOrStrictReservedWord( 375 IdentifierT ParseIdentifierOrStrictReservedWord(
372 bool* is_strict_reserved, 376 bool* is_strict_reserved,
373 bool* ok); 377 bool* ok);
374 typename Traits::Type::Identifier ParseIdentifierName(bool* ok); 378 IdentifierT ParseIdentifierName(bool* ok);
375 // 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'.
376 typename Traits::Type::Identifier ParseIdentifierNameOrGetOrSet(bool* is_get, 380 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get,
377 bool* is_set, 381 bool* is_set,
378 bool* ok); 382 bool* ok);
379 383
380 typename Traits::Type::Expression ParseRegExpLiteral(bool seen_equal, 384 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok);
381 bool* ok);
382 385
383 typename Traits::Type::Expression ParsePrimaryExpression(bool* ok); 386 ExpressionT ParsePrimaryExpression(bool* ok);
384 typename Traits::Type::Expression ParseExpression(bool accept_IN, bool* ok); 387 ExpressionT ParseExpression(bool accept_IN, bool* ok);
385 typename Traits::Type::Expression ParseArrayLiteral(bool* ok); 388 ExpressionT ParseArrayLiteral(bool* ok);
386 typename Traits::Type::Expression ParseObjectLiteral(bool* ok); 389 ExpressionT ParseObjectLiteral(bool* ok);
387 typename Traits::Type::ExpressionList ParseArguments(bool* ok); 390 typename Traits::Type::ExpressionList ParseArguments(bool* ok);
388 typename Traits::Type::Expression ParseAssignmentExpression(bool accept_IN, 391 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok);
389 bool* ok); 392 ExpressionT ParseYieldExpression(bool* ok);
390 typename Traits::Type::Expression ParseYieldExpression(bool* ok); 393 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok);
391 typename Traits::Type::Expression ParseConditionalExpression(bool accept_IN, 394 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
392 bool* ok);
393 typename Traits::Type::Expression ParseBinaryExpression(int prec,
394 bool accept_IN,
395 bool* ok);
396 395
397 // Used to detect duplicates in object literals. Each of the values 396 // Used to detect duplicates in object literals. Each of the values
398 // kGetterProperty, kSetterProperty and kValueProperty represents 397 // kGetterProperty, kSetterProperty and kValueProperty represents
399 // a type of object literal property. When parsing a property, its 398 // a type of object literal property. When parsing a property, its
400 // type value is stored in the DuplicateFinder for the property name. 399 // type value is stored in the DuplicateFinder for the property name.
401 // Values are chosen so that having intersection bits means the there is 400 // Values are chosen so that having intersection bits means the there is
402 // an incompatibility. 401 // an incompatibility.
403 // I.e., you can add a getter to a property that already has a setter, since 402 // I.e., you can add a getter to a property that already has a setter, since
404 // kGetterProperty and kSetterProperty doesn't intersect, but not if it 403 // kGetterProperty and kSetterProperty doesn't intersect, but not if it
405 // already has a getter or a value. Adding the getter to an existing 404 // already has a getter or a value. Adding the getter to an existing
(...skipping 766 matching lines...) Expand 10 before | Expand all | Expand 10 after
1172 default: 1171 default:
1173 const char* name = Token::String(token); 1172 const char* name = Token::String(token);
1174 ASSERT(name != NULL); 1173 ASSERT(name != NULL);
1175 Traits::ReportMessageAt( 1174 Traits::ReportMessageAt(
1176 source_location, "unexpected_token", Vector<const char*>(&name, 1)); 1175 source_location, "unexpected_token", Vector<const char*>(&name, 1));
1177 } 1176 }
1178 } 1177 }
1179 1178
1180 1179
1181 template<class Traits> 1180 template<class Traits>
1182 typename Traits::Type::Identifier ParserBase<Traits>::ParseIdentifier( 1181 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
1183 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, 1182 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments,
1184 bool* ok) { 1183 bool* ok) {
1185 Token::Value next = Next(); 1184 Token::Value next = Next();
1186 if (next == Token::IDENTIFIER) { 1185 if (next == Token::IDENTIFIER) {
1187 typename Traits::Type::Identifier name = this->GetSymbol(scanner()); 1186 IdentifierT name = this->GetSymbol(scanner());
1188 if (allow_eval_or_arguments == kDontAllowEvalOrArguments && 1187 if (allow_eval_or_arguments == kDontAllowEvalOrArguments &&
1189 strict_mode() == STRICT && this->IsEvalOrArguments(name)) { 1188 strict_mode() == STRICT && this->IsEvalOrArguments(name)) {
1190 ReportMessageAt(scanner()->location(), "strict_eval_arguments"); 1189 ReportMessageAt(scanner()->location(), "strict_eval_arguments");
1191 *ok = false; 1190 *ok = false;
1192 } 1191 }
1193 return name; 1192 return name;
1194 } else if (strict_mode() == SLOPPY && 1193 } else if (strict_mode() == SLOPPY &&
1195 (next == Token::FUTURE_STRICT_RESERVED_WORD || 1194 (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1196 (next == Token::YIELD && !is_generator()))) { 1195 (next == Token::YIELD && !is_generator()))) {
1197 return this->GetSymbol(scanner()); 1196 return this->GetSymbol(scanner());
1198 } else { 1197 } else {
1199 this->ReportUnexpectedToken(next); 1198 this->ReportUnexpectedToken(next);
1200 *ok = false; 1199 *ok = false;
1201 return Traits::EmptyIdentifier(); 1200 return Traits::EmptyIdentifier();
1202 } 1201 }
1203 } 1202 }
1204 1203
1205 1204
1206 template <class Traits> 1205 template <class Traits>
1207 typename Traits::Type::Identifier ParserBase< 1206 typename ParserBase<Traits>::IdentifierT ParserBase<
1208 Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved, 1207 Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
1209 bool* ok) { 1208 bool* ok) {
1210 Token::Value next = Next(); 1209 Token::Value next = Next();
1211 if (next == Token::IDENTIFIER) { 1210 if (next == Token::IDENTIFIER) {
1212 *is_strict_reserved = false; 1211 *is_strict_reserved = false;
1213 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || 1212 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1214 (next == Token::YIELD && !this->is_generator())) { 1213 (next == Token::YIELD && !this->is_generator())) {
1215 *is_strict_reserved = true; 1214 *is_strict_reserved = true;
1216 } else { 1215 } else {
1217 ReportUnexpectedToken(next); 1216 ReportUnexpectedToken(next);
1218 *ok = false; 1217 *ok = false;
1219 return Traits::EmptyIdentifier(); 1218 return Traits::EmptyIdentifier();
1220 } 1219 }
1221 return this->GetSymbol(scanner()); 1220 return this->GetSymbol(scanner());
1222 } 1221 }
1223 1222
1224 1223
1225 template <class Traits> 1224 template <class Traits>
1226 typename Traits::Type::Identifier ParserBase<Traits>::ParseIdentifierName( 1225 typename ParserBase<Traits>::IdentifierT
1227 bool* ok) { 1226 ParserBase<Traits>::ParseIdentifierName(bool* ok) {
1228 Token::Value next = Next(); 1227 Token::Value next = Next();
1229 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD && 1228 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD &&
1230 next != Token::FUTURE_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { 1229 next != Token::FUTURE_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
1231 this->ReportUnexpectedToken(next); 1230 this->ReportUnexpectedToken(next);
1232 *ok = false; 1231 *ok = false;
1233 return Traits::EmptyIdentifier(); 1232 return Traits::EmptyIdentifier();
1234 } 1233 }
1235 return this->GetSymbol(scanner()); 1234 return this->GetSymbol(scanner());
1236 } 1235 }
1237 1236
1238 1237
1239 template <class Traits> 1238 template <class Traits>
1240 typename Traits::Type::Identifier 1239 typename ParserBase<Traits>::IdentifierT
1241 ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get, 1240 ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get,
1242 bool* is_set, 1241 bool* is_set,
1243 bool* ok) { 1242 bool* ok) {
1244 typename Traits::Type::Identifier result = ParseIdentifierName(ok); 1243 IdentifierT result = ParseIdentifierName(ok);
1245 if (!*ok) return Traits::EmptyIdentifier(); 1244 if (!*ok) return Traits::EmptyIdentifier();
1246 scanner()->IsGetOrSet(is_get, is_set); 1245 scanner()->IsGetOrSet(is_get, is_set);
1247 return result; 1246 return result;
1248 } 1247 }
1249 1248
1250 1249
1251 template <class Traits> 1250 template <class Traits>
1252 typename Traits::Type::Expression 1251 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
1253 ParserBase<Traits>::ParseRegExpLiteral(bool seen_equal, bool* ok) { 1252 bool seen_equal, bool* ok) {
1254 int pos = peek_position(); 1253 int pos = peek_position();
1255 if (!scanner()->ScanRegExpPattern(seen_equal)) { 1254 if (!scanner()->ScanRegExpPattern(seen_equal)) {
1256 Next(); 1255 Next();
1257 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); 1256 ReportMessage("unterminated_regexp", Vector<const char*>::empty());
1258 *ok = false; 1257 *ok = false;
1259 return Traits::EmptyExpression(); 1258 return Traits::EmptyExpression();
1260 } 1259 }
1261 1260
1262 int literal_index = function_state_->NextMaterializedLiteralIndex(); 1261 int literal_index = function_state_->NextMaterializedLiteralIndex();
1263 1262
1264 typename Traits::Type::Identifier js_pattern = 1263 IdentifierT js_pattern = this->NextLiteralString(scanner(), TENURED);
1265 this->NextLiteralString(scanner(), TENURED);
1266 if (!scanner()->ScanRegExpFlags()) { 1264 if (!scanner()->ScanRegExpFlags()) {
1267 Next(); 1265 Next();
1268 ReportMessageAt(scanner()->location(), "invalid_regexp_flags"); 1266 ReportMessageAt(scanner()->location(), "invalid_regexp_flags");
1269 *ok = false; 1267 *ok = false;
1270 return Traits::EmptyExpression(); 1268 return Traits::EmptyExpression();
1271 } 1269 }
1272 typename Traits::Type::Identifier js_flags = 1270 IdentifierT js_flags = this->NextLiteralString(scanner(), TENURED);
1273 this->NextLiteralString(scanner(), TENURED);
1274 Next(); 1271 Next();
1275 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); 1272 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
1276 } 1273 }
1277 1274
1278 1275
1279 #define CHECK_OK ok); \ 1276 #define CHECK_OK ok); \
1280 if (!*ok) return this->EmptyExpression(); \ 1277 if (!*ok) return this->EmptyExpression(); \
1281 ((void)0 1278 ((void)0
1282 #define DUMMY ) // to make indentation work 1279 #define DUMMY ) // to make indentation work
1283 #undef DUMMY 1280 #undef DUMMY
1284 1281
1285 // Used in functions where the return type is not Traits::Type::Expression. 1282 // Used in functions where the return type is not ExpressionT.
1286 #define CHECK_OK_CUSTOM(x) ok); \ 1283 #define CHECK_OK_CUSTOM(x) ok); \
1287 if (!*ok) return this->x(); \ 1284 if (!*ok) return this->x(); \
1288 ((void)0 1285 ((void)0
1289 #define DUMMY ) // to make indentation work 1286 #define DUMMY ) // to make indentation work
1290 #undef DUMMY 1287 #undef DUMMY
1291 1288
1292 template <class Traits> 1289 template <class Traits>
1293 typename Traits::Type::Expression ParserBase<Traits>::ParsePrimaryExpression( 1290 typename ParserBase<Traits>::ExpressionT
1294 bool* ok) { 1291 ParserBase<Traits>::ParsePrimaryExpression(bool* ok) {
1295 // PrimaryExpression :: 1292 // PrimaryExpression ::
1296 // 'this' 1293 // 'this'
1297 // 'null' 1294 // 'null'
1298 // 'true' 1295 // 'true'
1299 // 'false' 1296 // 'false'
1300 // Identifier 1297 // Identifier
1301 // Number 1298 // Number
1302 // String 1299 // String
1303 // ArrayLiteral 1300 // ArrayLiteral
1304 // ObjectLiteral 1301 // ObjectLiteral
1305 // RegExpLiteral 1302 // RegExpLiteral
1306 // '(' Expression ')' 1303 // '(' Expression ')'
1307 1304
1308 int pos = peek_position(); 1305 int pos = peek_position();
1309 typename Traits::Type::Expression result = this->EmptyExpression(); 1306 ExpressionT result = this->EmptyExpression();
1310 Token::Value token = peek(); 1307 Token::Value token = peek();
1311 switch (token) { 1308 switch (token) {
1312 case Token::THIS: { 1309 case Token::THIS: {
1313 Consume(Token::THIS); 1310 Consume(Token::THIS);
1314 result = this->ThisExpression(scope_, factory()); 1311 result = this->ThisExpression(scope_, factory());
1315 break; 1312 break;
1316 } 1313 }
1317 1314
1318 case Token::NULL_LITERAL: 1315 case Token::NULL_LITERAL:
1319 case Token::TRUE_LITERAL: 1316 case Token::TRUE_LITERAL:
1320 case Token::FALSE_LITERAL: 1317 case Token::FALSE_LITERAL:
1321 case Token::NUMBER: 1318 case Token::NUMBER:
1322 Next(); 1319 Next();
1323 result = this->ExpressionFromLiteral(token, pos, scanner(), factory()); 1320 result = this->ExpressionFromLiteral(token, pos, scanner(), factory());
1324 break; 1321 break;
1325 1322
1326 case Token::IDENTIFIER: 1323 case Token::IDENTIFIER:
1327 case Token::YIELD: 1324 case Token::YIELD:
1328 case Token::FUTURE_STRICT_RESERVED_WORD: { 1325 case Token::FUTURE_STRICT_RESERVED_WORD: {
1329 // Using eval or arguments in this context is OK even in strict mode. 1326 // Using eval or arguments in this context is OK even in strict mode.
1330 typename Traits::Type::Identifier name = 1327 IdentifierT name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
1331 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 1328 result = this->ExpressionFromIdentifier(name, pos, scope_, factory());
1332 result =
1333 this->ExpressionFromIdentifier(name, pos, scope_, factory());
1334 break; 1329 break;
1335 } 1330 }
1336 1331
1337 case Token::STRING: { 1332 case Token::STRING: {
1338 Consume(Token::STRING); 1333 Consume(Token::STRING);
1339 result = this->ExpressionFromString(pos, scanner(), factory()); 1334 result = this->ExpressionFromString(pos, scanner(), factory());
1340 break; 1335 break;
1341 } 1336 }
1342 1337
1343 case Token::ASSIGN_DIV: 1338 case Token::ASSIGN_DIV:
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1378 ReportUnexpectedToken(token); 1373 ReportUnexpectedToken(token);
1379 *ok = false; 1374 *ok = false;
1380 } 1375 }
1381 } 1376 }
1382 1377
1383 return result; 1378 return result;
1384 } 1379 }
1385 1380
1386 // Precedence = 1 1381 // Precedence = 1
1387 template <class Traits> 1382 template <class Traits>
1388 typename Traits::Type::Expression ParserBase<Traits>::ParseExpression( 1383 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
1389 bool accept_IN, bool* ok) { 1384 bool accept_IN, bool* ok) {
1390 // Expression :: 1385 // Expression ::
1391 // AssignmentExpression 1386 // AssignmentExpression
1392 // Expression ',' AssignmentExpression 1387 // Expression ',' AssignmentExpression
1393 1388
1394 typename Traits::Type::Expression result = 1389 ExpressionT result = this->ParseAssignmentExpression(accept_IN, CHECK_OK);
1395 this->ParseAssignmentExpression(accept_IN, CHECK_OK);
1396 while (peek() == Token::COMMA) { 1390 while (peek() == Token::COMMA) {
1397 Expect(Token::COMMA, CHECK_OK); 1391 Expect(Token::COMMA, CHECK_OK);
1398 int pos = position(); 1392 int pos = position();
1399 typename Traits::Type::Expression right = 1393 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK);
1400 this->ParseAssignmentExpression(accept_IN, CHECK_OK);
1401 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); 1394 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
1402 } 1395 }
1403 return result; 1396 return result;
1404 } 1397 }
1405 1398
1406 1399
1407 template <class Traits> 1400 template <class Traits>
1408 typename Traits::Type::Expression ParserBase<Traits>::ParseArrayLiteral( 1401 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
1409 bool* ok) { 1402 bool* ok) {
1410 // ArrayLiteral :: 1403 // ArrayLiteral ::
1411 // '[' Expression? (',' Expression?)* ']' 1404 // '[' Expression? (',' Expression?)* ']'
1412 1405
1413 int pos = peek_position(); 1406 int pos = peek_position();
1414 typename Traits::Type::ExpressionList values = 1407 typename Traits::Type::ExpressionList values =
1415 this->NewExpressionList(4, zone_); 1408 this->NewExpressionList(4, zone_);
1416 Expect(Token::LBRACK, CHECK_OK); 1409 Expect(Token::LBRACK, CHECK_OK);
1417 while (peek() != Token::RBRACK) { 1410 while (peek() != Token::RBRACK) {
1418 typename Traits::Type::Expression elem = this->EmptyExpression(); 1411 ExpressionT elem = this->EmptyExpression();
1419 if (peek() == Token::COMMA) { 1412 if (peek() == Token::COMMA) {
1420 elem = this->GetLiteralTheHole(peek_position(), factory()); 1413 elem = this->GetLiteralTheHole(peek_position(), factory());
1421 } else { 1414 } else {
1422 elem = this->ParseAssignmentExpression(true, CHECK_OK); 1415 elem = this->ParseAssignmentExpression(true, CHECK_OK);
1423 } 1416 }
1424 values->Add(elem, zone_); 1417 values->Add(elem, zone_);
1425 if (peek() != Token::RBRACK) { 1418 if (peek() != Token::RBRACK) {
1426 Expect(Token::COMMA, CHECK_OK); 1419 Expect(Token::COMMA, CHECK_OK);
1427 } 1420 }
1428 } 1421 }
1429 Expect(Token::RBRACK, CHECK_OK); 1422 Expect(Token::RBRACK, CHECK_OK);
1430 1423
1431 // Update the scope information before the pre-parsing bailout. 1424 // Update the scope information before the pre-parsing bailout.
1432 int literal_index = function_state_->NextMaterializedLiteralIndex(); 1425 int literal_index = function_state_->NextMaterializedLiteralIndex();
1433 1426
1434 return factory()->NewArrayLiteral(values, literal_index, pos); 1427 return factory()->NewArrayLiteral(values, literal_index, pos);
1435 } 1428 }
1436 1429
1437 1430
1438 template <class Traits> 1431 template <class Traits>
1439 typename Traits::Type::Expression ParserBase<Traits>::ParseObjectLiteral( 1432 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
1440 bool* ok) { 1433 bool* ok) {
1441 // ObjectLiteral :: 1434 // ObjectLiteral ::
1442 // '{' (( 1435 // '{' ((
1443 // ((IdentifierName | String | Number) ':' AssignmentExpression) | 1436 // ((IdentifierName | String | Number) ':' AssignmentExpression) |
1444 // (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) 1437 // (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
1445 // ) ',')* '}' 1438 // ) ',')* '}'
1446 // (Except that trailing comma is not required and not allowed.) 1439 // (Except that trailing comma is not required and not allowed.)
1447 1440
1448 int pos = peek_position(); 1441 int pos = peek_position();
1449 typename Traits::Type::PropertyList properties = 1442 typename Traits::Type::PropertyList properties =
(...skipping 11 matching lines...) Expand all
1461 typename Traits::Type::Literal key = this->EmptyLiteral(); 1454 typename Traits::Type::Literal key = this->EmptyLiteral();
1462 Token::Value next = peek(); 1455 Token::Value next = peek();
1463 int next_pos = peek_position(); 1456 int next_pos = peek_position();
1464 1457
1465 switch (next) { 1458 switch (next) {
1466 case Token::FUTURE_RESERVED_WORD: 1459 case Token::FUTURE_RESERVED_WORD:
1467 case Token::FUTURE_STRICT_RESERVED_WORD: 1460 case Token::FUTURE_STRICT_RESERVED_WORD:
1468 case Token::IDENTIFIER: { 1461 case Token::IDENTIFIER: {
1469 bool is_getter = false; 1462 bool is_getter = false;
1470 bool is_setter = false; 1463 bool is_setter = false;
1471 typename Traits::Type::Identifier id = 1464 IdentifierT id =
1472 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); 1465 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
1473 if (fni_ != NULL) this->PushLiteralName(fni_, id); 1466 if (fni_ != NULL) this->PushLiteralName(fni_, id);
1474 1467
1475 if ((is_getter || is_setter) && peek() != Token::COLON) { 1468 if ((is_getter || is_setter) && peek() != Token::COLON) {
1476 // Special handling of getter and setter syntax: 1469 // Special handling of getter and setter syntax:
1477 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } 1470 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
1478 // We have already read the "get" or "set" keyword. 1471 // We have already read the "get" or "set" keyword.
1479 Token::Value next = Next(); 1472 Token::Value next = Next();
1480 if (next != i::Token::IDENTIFIER && 1473 if (next != i::Token::IDENTIFIER &&
1481 next != i::Token::FUTURE_RESERVED_WORD && 1474 next != i::Token::FUTURE_RESERVED_WORD &&
1482 next != i::Token::FUTURE_STRICT_RESERVED_WORD && 1475 next != i::Token::FUTURE_STRICT_RESERVED_WORD &&
1483 next != i::Token::NUMBER && 1476 next != i::Token::NUMBER &&
1484 next != i::Token::STRING && 1477 next != i::Token::STRING &&
1485 !Token::IsKeyword(next)) { 1478 !Token::IsKeyword(next)) {
1486 ReportUnexpectedToken(next); 1479 ReportUnexpectedToken(next);
1487 *ok = false; 1480 *ok = false;
1488 return this->EmptyLiteral(); 1481 return this->EmptyLiteral();
1489 } 1482 }
1490 // Validate the property. 1483 // Validate the property.
1491 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; 1484 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
1492 checker.CheckProperty(next, type, CHECK_OK); 1485 checker.CheckProperty(next, type, CHECK_OK);
1493 typename Traits::Type::Identifier name = this->GetSymbol(scanner_); 1486 IdentifierT name = this->GetSymbol(scanner_);
1494 typename Traits::Type::FunctionLiteral value = 1487 typename Traits::Type::FunctionLiteral value =
1495 this->ParseFunctionLiteral( 1488 this->ParseFunctionLiteral(
1496 name, scanner()->location(), 1489 name, scanner()->location(),
1497 false, // reserved words are allowed here 1490 false, // reserved words are allowed here
1498 false, // not a generator 1491 false, // not a generator
1499 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, 1492 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
1500 CHECK_OK); 1493 CHECK_OK);
1501 // Allow any number of parameters for compatibilty with JSC. 1494 // Allow any number of parameters for compatibilty with JSC.
1502 // Specification only allows zero parameters for get and one for set. 1495 // Specification only allows zero parameters for get and one for set.
1503 typename Traits::Type::ObjectLiteralProperty property = 1496 typename Traits::Type::ObjectLiteralProperty property =
(...skipping 13 matching lines...) Expand all
1517 } 1510 }
1518 continue; // restart the while 1511 continue; // restart the while
1519 } 1512 }
1520 // Failed to parse as get/set property, so it's just a normal property 1513 // Failed to parse as get/set property, so it's just a normal property
1521 // (which might be called "get" or "set" or something else). 1514 // (which might be called "get" or "set" or something else).
1522 key = factory()->NewLiteral(id, next_pos); 1515 key = factory()->NewLiteral(id, next_pos);
1523 break; 1516 break;
1524 } 1517 }
1525 case Token::STRING: { 1518 case Token::STRING: {
1526 Consume(Token::STRING); 1519 Consume(Token::STRING);
1527 typename Traits::Type::Identifier string = this->GetSymbol(scanner_); 1520 IdentifierT string = this->GetSymbol(scanner_);
1528 if (fni_ != NULL) this->PushLiteralName(fni_, string); 1521 if (fni_ != NULL) this->PushLiteralName(fni_, string);
1529 uint32_t index; 1522 uint32_t index;
1530 if (this->IsArrayIndex(string, &index)) { 1523 if (this->IsArrayIndex(string, &index)) {
1531 key = factory()->NewNumberLiteral(index, next_pos); 1524 key = factory()->NewNumberLiteral(index, next_pos);
1532 break; 1525 break;
1533 } 1526 }
1534 key = factory()->NewLiteral(string, next_pos); 1527 key = factory()->NewLiteral(string, next_pos);
1535 break; 1528 break;
1536 } 1529 }
1537 case Token::NUMBER: { 1530 case Token::NUMBER: {
1538 Consume(Token::NUMBER); 1531 Consume(Token::NUMBER);
1539 key = this->ExpressionFromLiteral(Token::NUMBER, next_pos, scanner_, 1532 key = this->ExpressionFromLiteral(Token::NUMBER, next_pos, scanner_,
1540 factory()); 1533 factory());
1541 break; 1534 break;
1542 } 1535 }
1543 default: 1536 default:
1544 if (Token::IsKeyword(next)) { 1537 if (Token::IsKeyword(next)) {
1545 Consume(next); 1538 Consume(next);
1546 typename Traits::Type::Identifier string = this->GetSymbol(scanner_); 1539 IdentifierT string = this->GetSymbol(scanner_);
1547 key = factory()->NewLiteral(string, next_pos); 1540 key = factory()->NewLiteral(string, next_pos);
1548 } else { 1541 } else {
1549 Token::Value next = Next(); 1542 Token::Value next = Next();
1550 ReportUnexpectedToken(next); 1543 ReportUnexpectedToken(next);
1551 *ok = false; 1544 *ok = false;
1552 return this->EmptyLiteral(); 1545 return this->EmptyLiteral();
1553 } 1546 }
1554 } 1547 }
1555 1548
1556 // Validate the property 1549 // Validate the property
1557 checker.CheckProperty(next, kValueProperty, CHECK_OK); 1550 checker.CheckProperty(next, kValueProperty, CHECK_OK);
1558 1551
1559 Expect(Token::COLON, CHECK_OK); 1552 Expect(Token::COLON, CHECK_OK);
1560 typename Traits::Type::Expression value = 1553 ExpressionT value = this->ParseAssignmentExpression(true, CHECK_OK);
1561 this->ParseAssignmentExpression(true, CHECK_OK);
1562 1554
1563 typename Traits::Type::ObjectLiteralProperty property = 1555 typename Traits::Type::ObjectLiteralProperty property =
1564 factory()->NewObjectLiteralProperty(key, value); 1556 factory()->NewObjectLiteralProperty(key, value);
1565 1557
1566 // Mark top-level object literals that contain function literals and 1558 // Mark top-level object literals that contain function literals and
1567 // pretenure the literal so it can be added as a constant function 1559 // pretenure the literal so it can be added as a constant function
1568 // property. (Parser only.) 1560 // property. (Parser only.)
1569 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, value, 1561 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, value,
1570 &has_function); 1562 &has_function);
1571 1563
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1603 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( 1595 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
1604 bool* ok) { 1596 bool* ok) {
1605 // Arguments :: 1597 // Arguments ::
1606 // '(' (AssignmentExpression)*[','] ')' 1598 // '(' (AssignmentExpression)*[','] ')'
1607 1599
1608 typename Traits::Type::ExpressionList result = 1600 typename Traits::Type::ExpressionList result =
1609 this->NewExpressionList(4, zone_); 1601 this->NewExpressionList(4, zone_);
1610 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); 1602 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList));
1611 bool done = (peek() == Token::RPAREN); 1603 bool done = (peek() == Token::RPAREN);
1612 while (!done) { 1604 while (!done) {
1613 typename Traits::Type::Expression argument = 1605 ExpressionT argument = this->ParseAssignmentExpression(
1614 this->ParseAssignmentExpression(true, 1606 true, CHECK_OK_CUSTOM(NullExpressionList));
1615 CHECK_OK_CUSTOM(NullExpressionList));
1616 result->Add(argument, zone_); 1607 result->Add(argument, zone_);
1617 if (result->length() > Code::kMaxArguments) { 1608 if (result->length() > Code::kMaxArguments) {
1618 ReportMessageAt(scanner()->location(), "too_many_arguments"); 1609 ReportMessageAt(scanner()->location(), "too_many_arguments");
1619 *ok = false; 1610 *ok = false;
1620 return this->NullExpressionList(); 1611 return this->NullExpressionList();
1621 } 1612 }
1622 done = (peek() == Token::RPAREN); 1613 done = (peek() == Token::RPAREN);
1623 if (!done) { 1614 if (!done) {
1624 // Need {} because of the CHECK_OK_CUSTOM macro. 1615 // Need {} because of the CHECK_OK_CUSTOM macro.
1625 Expect(Token::COMMA, CHECK_OK_CUSTOM(NullExpressionList)); 1616 Expect(Token::COMMA, CHECK_OK_CUSTOM(NullExpressionList));
1626 } 1617 }
1627 } 1618 }
1628 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); 1619 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList));
1629 return result; 1620 return result;
1630 } 1621 }
1631 1622
1632 // Precedence = 2 1623 // Precedence = 2
1633 template <class Traits> 1624 template <class Traits>
1634 typename Traits::Type::Expression ParserBase<Traits>::ParseAssignmentExpression( 1625 typename ParserBase<Traits>::ExpressionT
1635 bool accept_IN, bool* ok) { 1626 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
1636 // AssignmentExpression :: 1627 // AssignmentExpression ::
1637 // ConditionalExpression 1628 // ConditionalExpression
1638 // YieldExpression 1629 // YieldExpression
1639 // LeftHandSideExpression AssignmentOperator AssignmentExpression 1630 // LeftHandSideExpression AssignmentOperator AssignmentExpression
1640 1631
1641 Scanner::Location lhs_location = scanner()->peek_location(); 1632 Scanner::Location lhs_location = scanner()->peek_location();
1642 1633
1643 if (peek() == Token::YIELD && is_generator()) { 1634 if (peek() == Token::YIELD && is_generator()) {
1644 return this->ParseYieldExpression(ok); 1635 return this->ParseYieldExpression(ok);
1645 } 1636 }
1646 1637
1647 if (fni_ != NULL) fni_->Enter(); 1638 if (fni_ != NULL) fni_->Enter();
1648 typename Traits::Type::Expression expression = 1639 ExpressionT expression =
1649 this->ParseConditionalExpression(accept_IN, CHECK_OK); 1640 this->ParseConditionalExpression(accept_IN, CHECK_OK);
1650 1641
1651 if (!Token::IsAssignmentOp(peek())) { 1642 if (!Token::IsAssignmentOp(peek())) {
1652 if (fni_ != NULL) fni_->Leave(); 1643 if (fni_ != NULL) fni_->Leave();
1653 // Parsed conditional expression only (no assignment). 1644 // Parsed conditional expression only (no assignment).
1654 return expression; 1645 return expression;
1655 } 1646 }
1656 1647
1657 if (!this->IsValidLeftHandSide(expression)) { 1648 if (!this->IsValidLeftHandSide(expression)) {
1658 this->ReportMessageAt(lhs_location, "invalid_lhs_in_assignment", true); 1649 this->ReportMessageAt(lhs_location, "invalid_lhs_in_assignment", true);
1659 *ok = false; 1650 *ok = false;
1660 return this->EmptyExpression(); 1651 return this->EmptyExpression();
1661 } 1652 }
1662 1653
1663 if (strict_mode() == STRICT) { 1654 if (strict_mode() == STRICT) {
1664 // Assignment to eval or arguments is disallowed in strict mode. 1655 // Assignment to eval or arguments is disallowed in strict mode.
1665 this->CheckStrictModeLValue(expression, CHECK_OK); 1656 this->CheckStrictModeLValue(expression, CHECK_OK);
1666 } 1657 }
1667 expression = this->MarkExpressionAsLValue(expression); 1658 expression = this->MarkExpressionAsLValue(expression);
1668 1659
1669 Token::Value op = Next(); // Get assignment operator. 1660 Token::Value op = Next(); // Get assignment operator.
1670 int pos = position(); 1661 int pos = position();
1671 typename Traits::Type::Expression right = 1662 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK);
1672 this->ParseAssignmentExpression(accept_IN, CHECK_OK);
1673 1663
1674 // TODO(1231235): We try to estimate the set of properties set by 1664 // TODO(1231235): We try to estimate the set of properties set by
1675 // constructors. We define a new property whenever there is an 1665 // constructors. We define a new property whenever there is an
1676 // assignment to a property of 'this'. We should probably only add 1666 // assignment to a property of 'this'. We should probably only add
1677 // properties if we haven't seen them before. Otherwise we'll 1667 // properties if we haven't seen them before. Otherwise we'll
1678 // probably overestimate the number of properties. 1668 // probably overestimate the number of properties.
1679 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { 1669 if (op == Token::ASSIGN && this->IsThisProperty(expression)) {
1680 function_state_->AddProperty(); 1670 function_state_->AddProperty();
1681 } 1671 }
1682 1672
(...skipping 11 matching lines...) Expand all
1694 } else { 1684 } else {
1695 fni_->RemoveLastFunction(); 1685 fni_->RemoveLastFunction();
1696 } 1686 }
1697 fni_->Leave(); 1687 fni_->Leave();
1698 } 1688 }
1699 1689
1700 return factory()->NewAssignment(op, expression, right, pos); 1690 return factory()->NewAssignment(op, expression, right, pos);
1701 } 1691 }
1702 1692
1703 template <class Traits> 1693 template <class Traits>
1704 typename Traits::Type::Expression ParserBase<Traits>::ParseYieldExpression( 1694 typename ParserBase<Traits>::ExpressionT
1705 bool* ok) { 1695 ParserBase<Traits>::ParseYieldExpression(bool* ok) {
1706 // YieldExpression :: 1696 // YieldExpression ::
1707 // 'yield' '*'? AssignmentExpression 1697 // 'yield' '*'? AssignmentExpression
1708 int pos = peek_position(); 1698 int pos = peek_position();
1709 Expect(Token::YIELD, CHECK_OK); 1699 Expect(Token::YIELD, CHECK_OK);
1710 Yield::Kind kind = 1700 Yield::Kind kind =
1711 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; 1701 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND;
1712 typename Traits::Type::Expression generator_object = 1702 ExpressionT generator_object =
1713 factory()->NewVariableProxy(function_state_->generator_object_variable()); 1703 factory()->NewVariableProxy(function_state_->generator_object_variable());
1714 typename Traits::Type::Expression expression = 1704 ExpressionT expression =
1715 ParseAssignmentExpression(false, CHECK_OK); 1705 ParseAssignmentExpression(false, CHECK_OK);
1716 typename Traits::Type::YieldExpression yield = 1706 typename Traits::Type::YieldExpression yield =
1717 factory()->NewYield(generator_object, expression, kind, pos); 1707 factory()->NewYield(generator_object, expression, kind, pos);
1718 if (kind == Yield::DELEGATING) { 1708 if (kind == Yield::DELEGATING) {
1719 yield->set_index(function_state_->NextHandlerIndex()); 1709 yield->set_index(function_state_->NextHandlerIndex());
1720 } 1710 }
1721 return yield; 1711 return yield;
1722 } 1712 }
1723 1713
1724 1714
1725 // Precedence = 3 1715 // Precedence = 3
1726 template <class Traits> 1716 template <class Traits>
1727 typename Traits::Type::Expression 1717 typename ParserBase<Traits>::ExpressionT
1728 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, bool* ok) { 1718 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, bool* ok) {
1729 // ConditionalExpression :: 1719 // ConditionalExpression ::
1730 // LogicalOrExpression 1720 // LogicalOrExpression
1731 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression 1721 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
1732 1722
1733 int pos = peek_position(); 1723 int pos = peek_position();
1734 // We start using the binary expression parser for prec >= 4 only! 1724 // We start using the binary expression parser for prec >= 4 only!
1735 typename Traits::Type::Expression expression = 1725 ExpressionT expression = this->ParseBinaryExpression(4, accept_IN, CHECK_OK);
1736 this->ParseBinaryExpression(4, accept_IN, CHECK_OK);
1737 if (peek() != Token::CONDITIONAL) return expression; 1726 if (peek() != Token::CONDITIONAL) return expression;
1738 Consume(Token::CONDITIONAL); 1727 Consume(Token::CONDITIONAL);
1739 // In parsing the first assignment expression in conditional 1728 // In parsing the first assignment expression in conditional
1740 // expressions we always accept the 'in' keyword; see ECMA-262, 1729 // expressions we always accept the 'in' keyword; see ECMA-262,
1741 // section 11.12, page 58. 1730 // section 11.12, page 58.
1742 typename Traits::Type::Expression left = 1731 ExpressionT left = ParseAssignmentExpression(true, CHECK_OK);
1743 ParseAssignmentExpression(true, CHECK_OK);
1744 Expect(Token::COLON, CHECK_OK); 1732 Expect(Token::COLON, CHECK_OK);
1745 typename Traits::Type::Expression right = 1733 ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK);
1746 ParseAssignmentExpression(accept_IN, CHECK_OK);
1747 return factory()->NewConditional(expression, left, right, pos); 1734 return factory()->NewConditional(expression, left, right, pos);
1748 } 1735 }
1749 1736
1750 1737
1751 // Precedence >= 4 1738 // Precedence >= 4
1752 template <class Traits> 1739 template <class Traits>
1753 typename Traits::Type::Expression 1740 typename ParserBase<Traits>::ExpressionT
1754 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { 1741 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) {
1755 ASSERT(prec >= 4); 1742 ASSERT(prec >= 4);
1756 typename Traits::Type::Expression x = this->ParseUnaryExpression(CHECK_OK); 1743 ExpressionT x = this->ParseUnaryExpression(CHECK_OK);
1757 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { 1744 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
1758 // prec1 >= 4 1745 // prec1 >= 4
1759 while (Precedence(peek(), accept_IN) == prec1) { 1746 while (Precedence(peek(), accept_IN) == prec1) {
1760 Token::Value op = Next(); 1747 Token::Value op = Next();
1761 int pos = position(); 1748 int pos = position();
1762 typename Traits::Type::Expression y = 1749 ExpressionT y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
1763 ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
1764 1750
1765 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, 1751 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
1766 factory())) { 1752 factory())) {
1767 continue; 1753 continue;
1768 } 1754 }
1769 1755
1770 // For now we distinguish between comparisons and other binary 1756 // For now we distinguish between comparisons and other binary
1771 // operations. (We could combine the two and get rid of this 1757 // operations. (We could combine the two and get rid of this
1772 // code and AST node eventually.) 1758 // code and AST node eventually.)
1773 if (Token::IsCompareOp(op)) { 1759 if (Token::IsCompareOp(op)) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1827 "accessor_get_set"); 1813 "accessor_get_set");
1828 } 1814 }
1829 *ok = false; 1815 *ok = false;
1830 } 1816 }
1831 } 1817 }
1832 1818
1833 1819
1834 } } // v8::internal 1820 } } // v8::internal
1835 1821
1836 #endif // V8_PREPARSER_H 1822 #endif // V8_PREPARSER_H
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698