30 #include "../include/v8stdint.h"
59 Scope top_scope(&scope_, kTopLevelScope);
60 set_language_mode(mode);
61 Scope function_scope(&scope_, kFunctionScope);
65 ParseLazyFunctionLiteralBody(&ok);
71 if (!is_classic_mode()) {
73 CheckOctalLiteral(start_position, end_pos, &ok);
75 CheckDelayedStrictModeViolation(start_position, end_pos, &ok);
100 if (token == i::Token::ILLEGAL && stack_overflow_) {
103 i::Scanner::Location source_location = scanner_->
location();
108 return ReportMessageAt(source_location,
"unexpected_eos",
NULL);
109 case i::Token::NUMBER:
110 return ReportMessageAt(source_location,
"unexpected_token_number",
NULL);
111 case i::Token::STRING:
112 return ReportMessageAt(source_location,
"unexpected_token_string",
NULL);
113 case i::Token::IDENTIFIER:
114 return ReportMessageAt(source_location,
115 "unexpected_token_identifier",
NULL);
116 case i::Token::FUTURE_RESERVED_WORD:
117 return ReportMessageAt(source_location,
"unexpected_reserved",
NULL);
118 case i::Token::FUTURE_STRICT_RESERVED_WORD:
119 return ReportMessageAt(source_location,
120 "unexpected_strict_reserved",
NULL);
123 ReportMessageAt(source_location,
"unexpected_token", name);
130 void PreParser::CheckOctalLiteral(
int beg_pos,
int end_pos,
bool* ok) {
132 if (beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) {
133 ReportMessageAt(octal,
"strict_octal_literal",
NULL);
140 #define CHECK_OK ok); \
141 if (!*ok) return kUnknownSourceElements; \
143 #define DUMMY ) // to make indentation work
147 PreParser::Statement PreParser::ParseSourceElement(
bool* ok) {
159 case i::Token::FUNCTION:
160 return ParseFunctionDeclaration(ok);
163 return ParseVariableStatement(kSourceElement, ok);
165 return ParseStatement(ok);
170 PreParser::SourceElements PreParser::ParseSourceElements(
int end_token,
175 bool allow_directive_prologue =
true;
176 while (peek() != end_token) {
177 Statement statement = ParseSourceElement(
CHECK_OK);
178 if (allow_directive_prologue) {
179 if (statement.IsUseStrictLiteral()) {
180 set_language_mode(harmony_scoping_ ?
182 }
else if (!statement.IsStringLiteral()) {
183 allow_directive_prologue =
false;
187 return kUnknownSourceElements;
192 #define CHECK_OK ok); \
193 if (!*ok) return Statement::Default(); \
195 #define DUMMY ) // to make indentation work
199 PreParser::Statement PreParser::ParseStatement(
bool* ok) {
226 case i::Token::LBRACE:
227 return ParseBlock(ok);
232 return ParseVariableStatement(kStatement, ok);
234 case i::Token::SEMICOLON:
236 return Statement::Default();
239 return ParseIfStatement(ok);
242 return ParseDoWhileStatement(ok);
244 case i::Token::WHILE:
245 return ParseWhileStatement(ok);
248 return ParseForStatement(ok);
250 case i::Token::CONTINUE:
251 return ParseContinueStatement(ok);
254 return ParseBreakStatement(ok);
256 case i::Token::RETURN:
257 return ParseReturnStatement(ok);
260 return ParseWithStatement(ok);
262 case i::Token::SWITCH:
263 return ParseSwitchStatement(ok);
265 case i::Token::THROW:
266 return ParseThrowStatement(ok);
269 return ParseTryStatement(ok);
271 case i::Token::FUNCTION: {
272 i::Scanner::Location start_location = scanner_->
peek_location();
273 Statement statement = ParseFunctionDeclaration(
CHECK_OK);
274 i::Scanner::Location end_location = scanner_->
location();
275 if (!is_classic_mode()) {
276 ReportMessageAt(start_location.beg_pos, end_location.end_pos,
277 "strict_function",
NULL);
279 return Statement::Default();
285 case i::Token::DEBUGGER:
286 return ParseDebuggerStatement(ok);
289 return ParseExpressionOrLabelledStatement(ok);
294 PreParser::Statement PreParser::ParseFunctionDeclaration(
bool* ok) {
297 Expect(i::Token::FUNCTION,
CHECK_OK);
299 Identifier identifier = ParseIdentifier(
CHECK_OK);
300 i::Scanner::Location location = scanner_->
location();
302 Expression function_value = ParseFunctionLiteral(
CHECK_OK);
304 if (function_value.IsStrictFunction() &&
305 !identifier.IsValidStrictVariable()) {
308 const char* type =
"strict_function_name";
309 if (identifier.IsFutureStrictReserved()) {
310 type =
"strict_reserved_word";
312 ReportMessageAt(location, type,
NULL);
315 return Statement::FunctionDeclaration();
319 PreParser::Statement PreParser::ParseBlock(
bool* ok) {
327 while (peek() != i::Token::RBRACE) {
328 if (is_extended_mode()) {
334 Expect(i::Token::RBRACE, ok);
335 return Statement::Default();
339 PreParser::Statement PreParser::ParseVariableStatement(
340 VariableDeclarationContext var_context,
345 Statement result = ParseVariableDeclarations(var_context,
359 PreParser::Statement PreParser::ParseVariableDeclarations(
360 VariableDeclarationContext var_context,
361 VariableDeclarationProperties* decl_props,
377 bool require_initializer =
false;
392 switch (language_mode()) {
397 ReportMessageAt(location,
"strict_const",
NULL);
399 return Statement::Default();
402 if (var_context != kSourceElement &&
403 var_context != kForStatement) {
405 ReportMessageAt(location.beg_pos, location.end_pos,
406 "unprotected_const",
NULL);
408 return Statement::Default();
410 require_initializer =
true;
420 if (!is_extended_mode()) {
422 ReportMessageAt(location.beg_pos, location.end_pos,
423 "illegal_let",
NULL);
425 return Statement::Default();
428 if (var_context != kSourceElement &&
429 var_context != kForStatement) {
431 ReportMessageAt(location.beg_pos, location.end_pos,
432 "unprotected_let",
NULL);
434 return Statement::Default();
438 return Statement::Default();
448 if (nvars > 0) Consume(i::Token::COMMA);
449 Identifier identifier = ParseIdentifier(
CHECK_OK);
450 if (!is_classic_mode() && !identifier.IsValidStrictVariable()) {
451 StrictModeIdentifierViolation(scanner_->
location(),
455 return Statement::Default();
458 if (peek() == i::Token::ASSIGN || require_initializer) {
460 ParseAssignmentExpression(var_context != kForStatement,
CHECK_OK);
461 if (decl_props !=
NULL) *decl_props = kHasInitializers;
463 }
while (peek() == i::Token::COMMA);
465 if (num_decl !=
NULL) *num_decl = nvars;
466 return Statement::Default();
470 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(
bool* ok) {
475 Expression expr = ParseExpression(
true,
CHECK_OK);
476 if (expr.IsRawIdentifier()) {
477 ASSERT(!expr.AsIdentifier().IsFutureReserved());
478 ASSERT(is_classic_mode() || !expr.AsIdentifier().IsFutureStrictReserved());
479 if (peek() == i::Token::COLON) {
480 Consume(i::Token::COLON);
481 return ParseStatement(ok);
489 return Statement::ExpressionStatement(expr);
493 PreParser::Statement PreParser::ParseIfStatement(
bool* ok) {
502 if (peek() == i::Token::ELSE) {
506 return Statement::Default();
510 PreParser::Statement PreParser::ParseContinueStatement(
bool* ok) {
514 Expect(i::Token::CONTINUE,
CHECK_OK);
517 tok != i::Token::SEMICOLON &&
518 tok != i::Token::RBRACE &&
519 tok != i::Token::EOS) {
523 return Statement::Default();
527 PreParser::Statement PreParser::ParseBreakStatement(
bool* ok) {
534 tok != i::Token::SEMICOLON &&
535 tok != i::Token::RBRACE &&
536 tok != i::Token::EOS) {
540 return Statement::Default();
544 PreParser::Statement PreParser::ParseReturnStatement(
bool* ok) {
560 tok != i::Token::SEMICOLON &&
561 tok != i::Token::RBRACE &&
562 tok != i::Token::EOS) {
566 return Statement::Default();
570 PreParser::Statement PreParser::ParseWithStatement(
bool* ok) {
574 if (!is_classic_mode()) {
575 i::Scanner::Location location = scanner_->
location();
576 ReportMessageAt(location,
"strict_mode_with",
NULL);
578 return Statement::Default();
584 Scope::InsideWith iw(scope_);
586 return Statement::Default();
590 PreParser::Statement PreParser::ParseSwitchStatement(
bool* ok) {
601 while (token != i::Token::RBRACE) {
602 if (token == i::Token::CASE) {
610 while (token != i::Token::CASE &&
612 token != i::Token::RBRACE) {
617 Expect(i::Token::RBRACE, ok);
618 return Statement::Default();
622 PreParser::Statement PreParser::ParseDoWhileStatement(
bool* ok) {
631 Expect(i::Token::RPAREN, ok);
632 if (peek() == i::Token::SEMICOLON) Consume(i::Token::SEMICOLON);
633 return Statement::Default();
637 PreParser::Statement PreParser::ParseWhileStatement(
bool* ok) {
646 return Statement::Default();
650 PreParser::Statement PreParser::ParseForStatement(
bool* ok) {
656 if (peek() != i::Token::SEMICOLON) {
661 VariableDeclarationProperties decl_props = kHasNoInitializers;
662 ParseVariableDeclarations(
663 kForStatement, &decl_props, &decl_count,
CHECK_OK);
664 bool accept_IN = decl_count == 1 &&
665 !(is_let && decl_props == kHasInitializers);
672 return Statement::Default();
682 return Statement::Default();
688 Expect(i::Token::SEMICOLON,
CHECK_OK);
690 if (peek() != i::Token::SEMICOLON) {
693 Expect(i::Token::SEMICOLON,
CHECK_OK);
695 if (peek() != i::Token::RPAREN) {
701 return Statement::Default();
705 PreParser::Statement PreParser::ParseThrowStatement(
bool* ok) {
711 i::Scanner::Location pos = scanner_->
location();
712 ReportMessageAt(pos,
"newline_after_throw",
NULL);
714 return Statement::Default();
718 return Statement::Default();
722 PreParser::Statement PreParser::ParseTryStatement(
bool* ok) {
741 bool catch_or_finally_seen =
false;
742 if (peek() == i::Token::CATCH) {
743 Consume(i::Token::CATCH);
745 Identifier
id = ParseIdentifier(
CHECK_OK);
746 if (!is_classic_mode() && !
id.IsValidStrictVariable()) {
747 StrictModeIdentifierViolation(scanner_->
location(),
748 "strict_catch_variable",
751 return Statement::Default();
754 { Scope::InsideWith iw(scope_);
757 catch_or_finally_seen =
true;
759 if (peek() == i::Token::FINALLY) {
760 Consume(i::Token::FINALLY);
762 catch_or_finally_seen =
true;
764 if (!catch_or_finally_seen) {
767 return Statement::Default();
771 PreParser::Statement PreParser::ParseDebuggerStatement(
bool* ok) {
778 Expect(i::Token::DEBUGGER,
CHECK_OK);
780 return Statement::Default();
785 #define CHECK_OK ok); \
786 if (!*ok) return Expression::Default(); \
788 #define DUMMY ) // to make indentation work
793 PreParser::Expression PreParser::ParseExpression(
bool accept_IN,
bool* ok) {
798 Expression result = ParseAssignmentExpression(accept_IN,
CHECK_OK);
799 while (peek() == i::Token::COMMA) {
801 ParseAssignmentExpression(accept_IN,
CHECK_OK);
802 result = Expression::Default();
809 PreParser::Expression PreParser::ParseAssignmentExpression(
bool accept_IN,
816 Expression expression = ParseConditionalExpression(accept_IN,
CHECK_OK);
823 if (!is_classic_mode() &&
824 expression.IsIdentifier() &&
825 expression.AsIdentifier().IsEvalOrArguments()) {
826 i::Scanner::Location after = scanner_->
location();
827 ReportMessageAt(before.beg_pos, after.end_pos,
828 "strict_lhs_assignment",
NULL);
830 return Expression::Default();
834 ParseAssignmentExpression(accept_IN,
CHECK_OK);
836 if ((op == i::Token::ASSIGN) && expression.IsThisProperty()) {
837 scope_->AddProperty();
840 return Expression::Default();
845 PreParser::Expression PreParser::ParseConditionalExpression(
bool accept_IN,
852 Expression expression = ParseBinaryExpression(4, accept_IN,
CHECK_OK);
853 if (peek() != i::Token::CONDITIONAL)
return expression;
854 Consume(i::Token::CONDITIONAL);
858 ParseAssignmentExpression(
true,
CHECK_OK);
860 ParseAssignmentExpression(accept_IN,
CHECK_OK);
861 return Expression::Default();
874 PreParser::Expression PreParser::ParseBinaryExpression(
int prec,
877 Expression result = ParseUnaryExpression(
CHECK_OK);
878 for (
int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
880 while (Precedence(peek(), accept_IN) == prec1) {
882 ParseBinaryExpression(prec1 + 1, accept_IN,
CHECK_OK);
883 result = Expression::Default();
890 PreParser::Expression PreParser::ParseUnaryExpression(
bool* ok) {
906 ParseUnaryExpression(ok);
907 return Expression::Default();
911 Expression expression = ParseUnaryExpression(
CHECK_OK);
912 if (!is_classic_mode() &&
913 expression.IsIdentifier() &&
914 expression.AsIdentifier().IsEvalOrArguments()) {
915 i::Scanner::Location after = scanner_->
location();
916 ReportMessageAt(before.beg_pos, after.end_pos,
917 "strict_lhs_prefix",
NULL);
920 return Expression::Default();
922 return ParsePostfixExpression(ok);
927 PreParser::Expression PreParser::ParsePostfixExpression(
bool* ok) {
932 Expression expression = ParseLeftHandSideExpression(
CHECK_OK);
935 if (!is_classic_mode() &&
936 expression.IsIdentifier() &&
937 expression.AsIdentifier().IsEvalOrArguments()) {
938 i::Scanner::Location after = scanner_->
location();
939 ReportMessageAt(before.beg_pos, after.end_pos,
940 "strict_lhs_postfix",
NULL);
942 return Expression::Default();
945 return Expression::Default();
951 PreParser::Expression PreParser::ParseLeftHandSideExpression(
bool* ok) {
955 Expression result = Expression::Default();
956 if (peek() == i::Token::NEW) {
957 result = ParseNewExpression(
CHECK_OK);
959 result = ParseMemberExpression(
CHECK_OK);
964 case i::Token::LBRACK: {
965 Consume(i::Token::LBRACK);
968 if (result.IsThis()) {
969 result = Expression::ThisProperty();
971 result = Expression::Default();
976 case i::Token::LPAREN: {
978 result = Expression::Default();
982 case i::Token::PERIOD: {
983 Consume(i::Token::PERIOD);
985 if (result.IsThis()) {
986 result = Expression::ThisProperty();
988 result = Expression::Default();
1000 PreParser::Expression PreParser::ParseNewExpression(
bool* ok) {
1012 unsigned new_count = 0;
1014 Consume(i::Token::NEW);
1016 }
while (peek() == i::Token::NEW);
1018 return ParseMemberWithNewPrefixesExpression(new_count, ok);
1022 PreParser::Expression PreParser::ParseMemberExpression(
bool* ok) {
1023 return ParseMemberWithNewPrefixesExpression(0, ok);
1027 PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression(
1028 unsigned new_count,
bool* ok) {
1034 Expression result = Expression::Default();
1035 if (peek() == i::Token::FUNCTION) {
1036 Consume(i::Token::FUNCTION);
1037 Identifier identifier = Identifier::Default();
1038 if (peek_any_identifier()) {
1039 identifier = ParseIdentifier(
CHECK_OK);
1041 result = ParseFunctionLiteral(
CHECK_OK);
1042 if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) {
1043 StrictModeIdentifierViolation(scanner_->
location(),
1044 "strict_function_name",
1047 return Expression::Default();
1050 result = ParsePrimaryExpression(
CHECK_OK);
1055 case i::Token::LBRACK: {
1056 Consume(i::Token::LBRACK);
1058 Expect(i::Token::RBRACK,
CHECK_OK);
1059 if (result.IsThis()) {
1060 result = Expression::ThisProperty();
1062 result = Expression::Default();
1066 case i::Token::PERIOD: {
1067 Consume(i::Token::PERIOD);
1069 if (result.IsThis()) {
1070 result = Expression::ThisProperty();
1072 result = Expression::Default();
1076 case i::Token::LPAREN: {
1077 if (new_count == 0)
return result;
1081 result = Expression::Default();
1091 PreParser::Expression PreParser::ParsePrimaryExpression(
bool* ok) {
1105 Expression result = Expression::Default();
1107 case i::Token::THIS: {
1109 result = Expression::This();
1113 case i::Token::FUTURE_RESERVED_WORD: {
1115 i::Scanner::Location location = scanner_->
location();
1116 ReportMessageAt(location.beg_pos, location.end_pos,
1117 "reserved_word",
NULL);
1119 return Expression::Default();
1122 case i::Token::FUTURE_STRICT_RESERVED_WORD:
1123 if (!is_classic_mode()) {
1125 i::Scanner::Location location = scanner_->
location();
1126 ReportMessageAt(location,
"strict_reserved_word",
NULL);
1128 return Expression::Default();
1131 case i::Token::IDENTIFIER: {
1132 Identifier
id = ParseIdentifier(
CHECK_OK);
1133 result = Expression::FromIdentifier(
id);
1137 case i::Token::NULL_LITERAL:
1138 case i::Token::TRUE_LITERAL:
1139 case i::Token::FALSE_LITERAL:
1140 case i::Token::NUMBER: {
1144 case i::Token::STRING: {
1146 result = GetStringSymbol();
1150 case i::Token::ASSIGN_DIV:
1151 result = ParseRegExpLiteral(
true,
CHECK_OK);
1155 result = ParseRegExpLiteral(
false,
CHECK_OK);
1158 case i::Token::LBRACK:
1159 result = ParseArrayLiteral(
CHECK_OK);
1162 case i::Token::LBRACE:
1163 result = ParseObjectLiteral(
CHECK_OK);
1166 case i::Token::LPAREN:
1167 Consume(i::Token::LPAREN);
1168 parenthesized_function_ = (peek() == i::Token::FUNCTION);
1169 result = ParseExpression(
true,
CHECK_OK);
1170 Expect(i::Token::RPAREN,
CHECK_OK);
1171 result = result.Parenthesize();
1175 result = ParseV8Intrinsic(
CHECK_OK);
1181 return Expression::Default();
1189 PreParser::Expression PreParser::ParseArrayLiteral(
bool* ok) {
1192 Expect(i::Token::LBRACK,
CHECK_OK);
1193 while (peek() != i::Token::RBRACK) {
1194 if (peek() != i::Token::COMMA) {
1195 ParseAssignmentExpression(
true,
CHECK_OK);
1197 if (peek() != i::Token::RBRACK) {
1201 Expect(i::Token::RBRACK,
CHECK_OK);
1203 scope_->NextMaterializedLiteralIndex();
1204 return Expression::Default();
1207 void PreParser::CheckDuplicate(DuplicateFinder* finder,
1212 if (property == i::Token::NUMBER) {
1220 if (HasConflict(old_type, type)) {
1221 if (IsDataDataConflict(old_type, type)) {
1223 if (is_classic_mode())
return;
1224 ReportMessageAt(scanner_->
location(),
1225 "strict_duplicate_property",
NULL);
1226 }
else if (IsDataAccessorConflict(old_type, type)) {
1228 ReportMessageAt(scanner_->
location(),
1229 "accessor_data_property",
NULL);
1231 ASSERT(IsAccessorAccessorConflict(old_type, type));
1233 ReportMessageAt(scanner_->
location(),
1234 "accessor_get_set",
NULL);
1241 PreParser::Expression PreParser::ParseObjectLiteral(
bool* ok) {
1248 Expect(i::Token::LBRACE,
CHECK_OK);
1249 DuplicateFinder duplicate_finder(scanner_->
unicode_cache());
1250 while (peek() != i::Token::RBRACE) {
1253 case i::Token::IDENTIFIER:
1254 case i::Token::FUTURE_RESERVED_WORD:
1255 case i::Token::FUTURE_STRICT_RESERVED_WORD: {
1256 bool is_getter =
false;
1257 bool is_setter =
false;
1258 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter,
CHECK_OK);
1259 if ((is_getter || is_setter) && peek() != i::Token::COLON) {
1262 if (name != i::Token::IDENTIFIER &&
1263 name != i::Token::FUTURE_RESERVED_WORD &&
1264 name != i::Token::FUTURE_STRICT_RESERVED_WORD &&
1265 name != i::Token::NUMBER &&
1266 name != i::Token::STRING &&
1269 return Expression::Default();
1274 PropertyType type = is_getter ? kGetterProperty : kSetterProperty;
1275 CheckDuplicate(&duplicate_finder, name, type,
CHECK_OK);
1277 if (peek() != i::Token::RBRACE) {
1282 CheckDuplicate(&duplicate_finder, next, kValueProperty,
CHECK_OK);
1285 case i::Token::STRING:
1287 CheckDuplicate(&duplicate_finder, next, kValueProperty,
CHECK_OK);
1290 case i::Token::NUMBER:
1292 CheckDuplicate(&duplicate_finder, next, kValueProperty,
CHECK_OK);
1297 CheckDuplicate(&duplicate_finder, next, kValueProperty,
CHECK_OK);
1301 return Expression::Default();
1306 ParseAssignmentExpression(
true,
CHECK_OK);
1309 if (peek() != i::Token::RBRACE) Expect(i::Token::COMMA,
CHECK_OK);
1311 Expect(i::Token::RBRACE,
CHECK_OK);
1313 scope_->NextMaterializedLiteralIndex();
1314 return Expression::Default();
1318 PreParser::Expression PreParser::ParseRegExpLiteral(
bool seen_equal,
1322 ReportMessageAt(scanner_->
location(),
"unterminated_regexp",
NULL);
1324 return Expression::Default();
1327 scope_->NextMaterializedLiteralIndex();
1331 ReportMessageAt(scanner_->
location(),
"invalid_regexp_flags",
NULL);
1333 return Expression::Default();
1336 return Expression::Default();
1340 PreParser::Arguments PreParser::ParseArguments(
bool* ok) {
1344 Expect(i::Token::LPAREN, ok);
1345 if (!*ok)
return -1;
1346 bool done = (peek() == i::Token::RPAREN);
1349 ParseAssignmentExpression(
true, ok);
1350 if (!*ok)
return -1;
1352 done = (peek() == i::Token::RPAREN);
1354 Expect(i::Token::COMMA, ok);
1355 if (!*ok)
return -1;
1358 Expect(i::Token::RPAREN, ok);
1363 PreParser::Expression PreParser::ParseFunctionLiteral(
bool* ok) {
1368 ScopeType outer_scope_type = scope_->type();
1369 bool inside_with = scope_->IsInsideWith();
1370 Scope function_scope(&scope_, kFunctionScope);
1373 Expect(i::Token::LPAREN,
CHECK_OK);
1375 bool done = (peek() == i::Token::RPAREN);
1376 DuplicateFinder duplicate_finder(scanner_->
unicode_cache());
1378 Identifier
id = ParseIdentifier(
CHECK_OK);
1379 if (!
id.IsValidStrictVariable()) {
1380 StrictModeIdentifierViolation(scanner_->
location(),
1381 "strict_param_name",
1394 if (prev_value != 0) {
1395 SetStrictModeViolation(scanner_->
location(),
1396 "strict_param_dupe",
1399 done = (peek() == i::Token::RPAREN);
1404 Expect(i::Token::RPAREN,
CHECK_OK);
1409 bool is_lazily_compiled = (outer_scope_type == kTopLevelScope &&
1410 !inside_with && allow_lazy_ &&
1411 !parenthesized_function_);
1412 parenthesized_function_ =
false;
1414 Expect(i::Token::LBRACE,
CHECK_OK);
1415 if (is_lazily_compiled) {
1416 ParseLazyFunctionLiteralBody(
CHECK_OK);
1418 ParseSourceElements(i::Token::RBRACE, ok);
1420 Expect(i::Token::RBRACE,
CHECK_OK);
1422 if (!is_classic_mode()) {
1424 CheckOctalLiteral(start_position, end_position,
CHECK_OK);
1425 CheckDelayedStrictModeViolation(start_position, end_position,
CHECK_OK);
1426 return Expression::StrictFunction();
1429 return Expression::Default();
1433 void PreParser::ParseLazyFunctionLiteralBody(
bool* ok) {
1436 ParseSourceElements(i::Token::RBRACE, ok);
1444 scope_->materialized_literal_count(),
1445 scope_->expected_properties(),
1450 PreParser::Expression PreParser::ParseV8Intrinsic(
bool* ok) {
1454 if (!allow_natives_syntax_) {
1456 return Expression::Default();
1461 return Expression::Default();
1467 void PreParser::ExpectSemicolon(
bool* ok) {
1471 if (tok == i::Token::SEMICOLON) {
1476 tok == i::Token::RBRACE ||
1477 tok == i::Token::EOS) {
1480 Expect(i::Token::SEMICOLON, ok);
1484 void PreParser::LogSymbol() {
1494 PreParser::Expression PreParser::GetStringSymbol() {
1495 const int kUseStrictLength = 10;
1496 const char* kUseStrictChars =
"use strict";
1502 kUseStrictLength)) {
1503 return Expression::UseStrictStringLiteral();
1505 return Expression::StringLiteral();
1509 PreParser::Identifier PreParser::GetIdentifierSymbol() {
1511 if (scanner_->
current_token() == i::Token::FUTURE_RESERVED_WORD) {
1512 return Identifier::FutureReserved();
1514 i::Token::FUTURE_STRICT_RESERVED_WORD) {
1515 return Identifier::FutureStrictReserved();
1521 return Identifier::Eval();
1525 return Identifier::Arguments();
1528 return Identifier::Default();
1532 PreParser::Identifier PreParser::ParseIdentifier(
bool* ok) {
1535 case i::Token::FUTURE_RESERVED_WORD: {
1536 i::Scanner::Location location = scanner_->
location();
1537 ReportMessageAt(location.beg_pos, location.end_pos,
1538 "reserved_word",
NULL);
1540 return GetIdentifierSymbol();
1542 case i::Token::FUTURE_STRICT_RESERVED_WORD:
1543 if (!is_classic_mode()) {
1544 i::Scanner::Location location = scanner_->
location();
1545 ReportMessageAt(location.beg_pos, location.end_pos,
1546 "strict_reserved_word",
NULL);
1550 case i::Token::IDENTIFIER:
1551 return GetIdentifierSymbol();
1554 return Identifier::Default();
1559 void PreParser::SetStrictModeViolation(i::Scanner::Location location,
1562 if (!is_classic_mode()) {
1563 ReportMessageAt(location, type,
NULL);
1575 strict_mode_violation_location_ = location;
1576 strict_mode_violation_type_ = type;
1580 void PreParser::CheckDelayedStrictModeViolation(
int beg_pos,
1583 i::Scanner::Location location = strict_mode_violation_location_;
1584 if (location.IsValid() &&
1585 location.beg_pos > beg_pos && location.end_pos < end_pos) {
1586 ReportMessageAt(location, strict_mode_violation_type_,
NULL);
1592 void PreParser::StrictModeIdentifierViolation(i::Scanner::Location location,
1593 const char* eval_args_type,
1594 Identifier identifier,
1596 const char* type = eval_args_type;
1597 if (identifier.IsFutureReserved()) {
1598 type =
"reserved_word";
1599 }
else if (identifier.IsFutureStrictReserved()) {
1600 type =
"strict_reserved_word";
1602 if (!is_classic_mode()) {
1603 ReportMessageAt(location, type,
NULL);
1607 strict_mode_violation_location_ = location;
1608 strict_mode_violation_type_ = type;
1612 PreParser::Identifier PreParser::ParseIdentifierName(
bool* ok) {
1619 return Identifier::Default();
1621 if (next == i::Token::IDENTIFIER ||
1622 next == i::Token::FUTURE_RESERVED_WORD ||
1623 next == i::Token::FUTURE_STRICT_RESERVED_WORD) {
1624 return GetIdentifierSymbol();
1627 return Identifier::Default();
1635 PreParser::Identifier PreParser::ParseIdentifierNameOrGetOrSet(
bool* is_get,
1638 Identifier result = ParseIdentifierName(ok);
1639 if (!*ok)
return Identifier::Default();
1643 *is_get = strncmp(token,
"get", 3) == 0;
1644 *is_set = !*is_get && strncmp(token,
"set", 3) == 0;
1649 bool PreParser::peek_any_identifier() {
1651 return next == i::Token::IDENTIFIER ||
1652 next == i::Token::FUTURE_RESERVED_WORD ||
1653 next == i::Token::FUTURE_STRICT_RESERVED_WORD;
1668 uint32_t hash = Hash(key, is_ascii);
1669 byte* encoding = BackupKey(key, is_ascii);
1670 i::HashMap::Entry* entry = map_.
Lookup(encoding, hash,
true);
1671 int old_value =
static_cast<int>(
reinterpret_cast<intptr_t
>(entry->value));
1673 reinterpret_cast<void*
>(
static_cast<intptr_t
>(value | old_value));
1681 if (IsNumberCanonical(key)) {
1686 double double_value =
StringToDouble(unicode_constants_, key, flags, 0.0);
1690 string =
"Infinity";
1698 length),
true, value);
1708 int length = number.
length();
1709 if (number.
length() > 15)
return false;
1710 if (number[pos] ==
'0') {
1713 while (pos < length &&
1714 static_cast<unsigned>(number[pos] -
'0') <= (
'9' -
'0')) pos++;
1716 if (length == pos)
return true;
1717 if (number[pos] !=
'.')
return false;
1719 bool invalid_last_digit =
true;
1720 while (pos < length) {
1721 byte digit = number[pos] -
'0';
1722 if (digit >
'9' -
'0')
return false;
1723 invalid_last_digit = (digit == 0);
1726 return !invalid_last_digit;
1733 int length = key.
length();
1734 uint32_t hash = (length << 1) | (is_ascii ? 1 : 0) ;
1735 for (
int i = 0; i < length; i++) {
1736 uint32_t c = key[i];
1737 hash = (hash + c) * 1025;
1738 hash ^= (hash >> 6);
1744 bool DuplicateFinder::Match(
void* first,
void* second) {
1752 uint32_t length_ascii_field = 0;
1756 if (c1 != *s2)
return false;
1757 length_ascii_field = (length_ascii_field << 7) | (c1 & 0x7f);
1760 }
while ((c1 & 0x80) != 0);
1761 int length =
static_cast<int>(length_ascii_field >> 1);
1762 return memcmp(s1, s2, length) == 0;
1768 uint32_t ascii_length = (bytes.
length() << 1) | (is_ascii ? 1 : 0);
1772 if (ascii_length >= (1 << 7)) {
1773 if (ascii_length >= (1 << 14)) {
1774 if (ascii_length >= (1 << 21)) {
1775 if (ascii_length >= (1 << 28)) {
1776 backing_store_.
Add(static_cast<byte>((ascii_length >> 28) | 0x80));
1778 backing_store_.
Add(static_cast<byte>((ascii_length >> 21) | 0x80u));
1780 backing_store_.
Add(static_cast<byte>((ascii_length >> 14) | 0x80u));
1782 backing_store_.
Add(static_cast<byte>((ascii_length >> 7) | 0x80u));
1784 backing_store_.
Add(static_cast<byte>(ascii_length & 0x7f));
static int Precedence(Value tok)
static bool IsUnaryOp(Value op)
int literal_length() const
#define ASSERT(condition)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if expose natives in global object expose gc extension number of stack frames to capture disable builtin natives files print a stack trace if an assertion failure occurs use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations prepare for turning on always opt minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions automatically set the debug break flag when debugger commands are in the queue always cause a debug break before aborting maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print more details following each garbage collection print amount of external allocated memory after each time it is adjusted flush code that we expect not to use again before full gc do incremental marking steps track object counts and memory usage use caching Perform compaction on every full GC Never perform compaction on full GC testing only Compact code space on full incremental collections Default seed for initializing random allows verbose printing trace parsing and preparsing Check icache flushes in ARM and MIPS simulator Stack alingment in bytes in print stack trace when throwing exceptions randomize hashes to avoid predictable hash Fixed seed to use to hash property activate a timer that switches between V8 threads testing_bool_flag float flag Seed used for threading test randomness A filename with extra code to be included in the Print usage including flags
bool HasAnyLineTerminatorBeforeNext() const
int AddNumber(i::Vector< const char > key, int value)
virtual void LogFunction(int start, int end, int literals, int properties, LanguageMode language_mode)=0
double StringToDouble(UnicodeCache *unicode_cache, const char *str, int flags, double empty_string_val)
Vector< T > AddBlock(int size, T initial_value)
bool literal_contains_escapes() const
virtual void LogAsciiSymbol(int start, Vector< const char > literal)
static const char * String(Value tok)
const char * DoubleToCString(double v, Vector< char > buffer)
static bool IsAssignmentOp(Value tok)
virtual void ResumeRecording()=0
Entry * Lookup(void *key, uint32_t hash, bool insert, AllocationPolicy allocator=AllocationPolicy())
int AddUtf16Symbol(i::Vector< const uint16_t > key, int value)
static bool IsKeyword(Value tok)
int AddAsciiSymbol(i::Vector< const char > key, int value)
int StrLength(const char *string)
PreParseResult PreParseLazyFunction(i::LanguageMode mode, i::ParserRecorder *log)
Location location() const
Vector< T > EndSequence()
virtual void PauseRecording()=0
virtual void LogUtf16Symbol(int start, Vector< const uc16 > literal)
void clear_octal_position()
#define ASSERT_EQ(v1, v2)
Vector< const char > literal_ascii_string()
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
Token::Value peek() const
Location octal_position() const
Token::Value current_token()
Vector< const uc16 > literal_utf16_string()
bool ScanRegExpPattern(bool seen_equal)
static bool IsCountOp(Value op)
UnicodeCache * unicode_cache()
Location peek_location() const