Chromium Code Reviews

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