| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/parsing/parser.h" | 5 #include "src/parsing/parser.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/ast/ast-expression-rewriter.h" | 10 #include "src/ast/ast-expression-rewriter.h" |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 return function_literal; | 224 return function_literal; |
| 225 } | 225 } |
| 226 | 226 |
| 227 | 227 |
| 228 // ---------------------------------------------------------------------------- | 228 // ---------------------------------------------------------------------------- |
| 229 // Target is a support class to facilitate manipulation of the | 229 // Target is a support class to facilitate manipulation of the |
| 230 // Parser's target_stack_ (the stack of potential 'break' and | 230 // Parser's target_stack_ (the stack of potential 'break' and |
| 231 // 'continue' statement targets). Upon construction, a new target is | 231 // 'continue' statement targets). Upon construction, a new target is |
| 232 // added; it is removed upon destruction. | 232 // added; it is removed upon destruction. |
| 233 | 233 |
| 234 class Target BASE_EMBEDDED { | 234 class ParserTarget BASE_EMBEDDED { |
| 235 public: | 235 public: |
| 236 Target(Target** variable, BreakableStatement* statement) | 236 ParserTarget(ParserBase<Parser>* parser, BreakableStatement* statement) |
| 237 : variable_(variable), statement_(statement), previous_(*variable) { | 237 : variable_(&parser->impl()->target_stack_), |
| 238 *variable = this; | 238 statement_(statement), |
| 239 previous_(parser->impl()->target_stack_) { |
| 240 parser->impl()->target_stack_ = this; |
| 239 } | 241 } |
| 240 | 242 |
| 241 ~Target() { | 243 ~ParserTarget() { *variable_ = previous_; } |
| 242 *variable_ = previous_; | |
| 243 } | |
| 244 | 244 |
| 245 Target* previous() { return previous_; } | 245 ParserTarget* previous() { return previous_; } |
| 246 BreakableStatement* statement() { return statement_; } | 246 BreakableStatement* statement() { return statement_; } |
| 247 | 247 |
| 248 private: | 248 private: |
| 249 Target** variable_; | 249 ParserTarget** variable_; |
| 250 BreakableStatement* statement_; | 250 BreakableStatement* statement_; |
| 251 Target* previous_; | 251 ParserTarget* previous_; |
| 252 }; |
| 253 |
| 254 class ParserTargetScope BASE_EMBEDDED { |
| 255 public: |
| 256 explicit ParserTargetScope(ParserBase<Parser>* parser) |
| 257 : variable_(&parser->impl()->target_stack_), |
| 258 previous_(parser->impl()->target_stack_) { |
| 259 parser->impl()->target_stack_ = nullptr; |
| 260 } |
| 261 |
| 262 ~ParserTargetScope() { *variable_ = previous_; } |
| 263 |
| 264 private: |
| 265 ParserTarget** variable_; |
| 266 ParserTarget* previous_; |
| 252 }; | 267 }; |
| 253 | 268 |
| 254 | 269 |
| 255 class TargetScope BASE_EMBEDDED { | |
| 256 public: | |
| 257 explicit TargetScope(Target** variable) | |
| 258 : variable_(variable), previous_(*variable) { | |
| 259 *variable = NULL; | |
| 260 } | |
| 261 | |
| 262 ~TargetScope() { | |
| 263 *variable_ = previous_; | |
| 264 } | |
| 265 | |
| 266 private: | |
| 267 Target** variable_; | |
| 268 Target* previous_; | |
| 269 }; | |
| 270 | |
| 271 | |
| 272 // ---------------------------------------------------------------------------- | 270 // ---------------------------------------------------------------------------- |
| 273 // The CHECK_OK macro is a convenient macro to enforce error | 271 // The CHECK_OK macro is a convenient macro to enforce error |
| 274 // handling for functions that may fail (by returning !*ok). | 272 // handling for functions that may fail (by returning !*ok). |
| 275 // | 273 // |
| 276 // CAUTION: This macro appends extra statements after a call, | 274 // CAUTION: This macro appends extra statements after a call, |
| 277 // thus it must never be used where only a single statement | 275 // thus it must never be used where only a single statement |
| 278 // is correct (e.g. an if statement branch w/o braces)! | 276 // is correct (e.g. an if statement branch w/o braces)! |
| 279 | 277 |
| 280 #define CHECK_OK_VALUE(x) ok); \ | 278 #define CHECK_OK_VALUE(x) ok); \ |
| 281 if (!*ok) return x; \ | 279 if (!*ok) return x; \ |
| (...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 924 } | 922 } |
| 925 // Make sure the results agree. | 923 // Make sure the results agree. |
| 926 DCHECK(ok == (result != nullptr)); | 924 DCHECK(ok == (result != nullptr)); |
| 927 } | 925 } |
| 928 | 926 |
| 929 // Make sure the target stack is empty. | 927 // Make sure the target stack is empty. |
| 930 DCHECK_NULL(target_stack_); | 928 DCHECK_NULL(target_stack_); |
| 931 return result; | 929 return result; |
| 932 } | 930 } |
| 933 | 931 |
| 934 | |
| 935 void Parser::ParseStatementList(ZoneList<Statement*>* body, int end_token, | |
| 936 bool* ok) { | |
| 937 // StatementList :: | |
| 938 // (StatementListItem)* <end_token> | |
| 939 | |
| 940 // Allocate a target stack to use for this set of source | |
| 941 // elements. This way, all scripts and functions get their own | |
| 942 // target stack thus avoiding illegal breaks and continues across | |
| 943 // functions. | |
| 944 TargetScope scope(&this->target_stack_); | |
| 945 | |
| 946 DCHECK(body != NULL); | |
| 947 bool directive_prologue = true; // Parsing directive prologue. | |
| 948 | |
| 949 while (peek() != end_token) { | |
| 950 if (directive_prologue && peek() != Token::STRING) { | |
| 951 directive_prologue = false; | |
| 952 } | |
| 953 | |
| 954 Scanner::Location token_loc = scanner()->peek_location(); | |
| 955 Statement* stat = ParseStatementListItem(CHECK_OK_VOID); | |
| 956 if (stat == NULL || stat->IsEmpty()) { | |
| 957 directive_prologue = false; // End of directive prologue. | |
| 958 continue; | |
| 959 } | |
| 960 | |
| 961 if (directive_prologue) { | |
| 962 // A shot at a directive. | |
| 963 ExpressionStatement* e_stat; | |
| 964 Literal* literal; | |
| 965 // Still processing directive prologue? | |
| 966 if ((e_stat = stat->AsExpressionStatement()) != NULL && | |
| 967 (literal = e_stat->expression()->AsLiteral()) != NULL && | |
| 968 literal->raw_value()->IsString()) { | |
| 969 // Check "use strict" directive (ES5 14.1), "use asm" directive. | |
| 970 bool use_strict_found = | |
| 971 literal->raw_value()->AsString() == | |
| 972 ast_value_factory()->use_strict_string() && | |
| 973 token_loc.end_pos - token_loc.beg_pos == | |
| 974 ast_value_factory()->use_strict_string()->length() + 2; | |
| 975 if (use_strict_found) { | |
| 976 if (is_sloppy(language_mode())) { | |
| 977 RaiseLanguageMode(STRICT); | |
| 978 } | |
| 979 | |
| 980 if (!this->scope()->HasSimpleParameters()) { | |
| 981 // TC39 deemed "use strict" directives to be an error when occurring | |
| 982 // in the body of a function with non-simple parameter list, on | |
| 983 // 29/7/2015. https://goo.gl/ueA7Ln | |
| 984 const AstRawString* string = literal->raw_value()->AsString(); | |
| 985 ReportMessageAt(token_loc, | |
| 986 MessageTemplate::kIllegalLanguageModeDirective, | |
| 987 string); | |
| 988 *ok = false; | |
| 989 return; | |
| 990 } | |
| 991 // Because declarations in strict eval code don't leak into the scope | |
| 992 // of the eval call, it is likely that functions declared in strict | |
| 993 // eval code will be used within the eval code, so lazy parsing is | |
| 994 // probably not a win. | |
| 995 if (this->scope()->is_eval_scope()) mode_ = PARSE_EAGERLY; | |
| 996 } else if (literal->raw_value()->AsString() == | |
| 997 ast_value_factory()->use_asm_string() && | |
| 998 token_loc.end_pos - token_loc.beg_pos == | |
| 999 ast_value_factory()->use_asm_string()->length() + 2) { | |
| 1000 // Store the usage count; The actual use counter on the isolate is | |
| 1001 // incremented after parsing is done. | |
| 1002 ++use_counts_[v8::Isolate::kUseAsm]; | |
| 1003 DCHECK(this->scope()->is_declaration_scope()); | |
| 1004 this->scope()->AsDeclarationScope()->set_asm_module(); | |
| 1005 } else { | |
| 1006 // Should not change mode, but will increment UseCounter | |
| 1007 // if appropriate. Ditto usages below. | |
| 1008 RaiseLanguageMode(SLOPPY); | |
| 1009 } | |
| 1010 } else { | |
| 1011 // End of the directive prologue. | |
| 1012 directive_prologue = false; | |
| 1013 RaiseLanguageMode(SLOPPY); | |
| 1014 } | |
| 1015 } else { | |
| 1016 RaiseLanguageMode(SLOPPY); | |
| 1017 } | |
| 1018 | |
| 1019 body->Add(stat, zone()); | |
| 1020 } | |
| 1021 } | |
| 1022 | |
| 1023 | |
| 1024 Statement* Parser::ParseStatementListItem(bool* ok) { | |
| 1025 // (Ecma 262 6th Edition, 13.1): | |
| 1026 // StatementListItem: | |
| 1027 // Statement | |
| 1028 // Declaration | |
| 1029 const Token::Value peeked = peek(); | |
| 1030 switch (peeked) { | |
| 1031 case Token::FUNCTION: | |
| 1032 return ParseHoistableDeclaration(NULL, false, ok); | |
| 1033 case Token::CLASS: | |
| 1034 Consume(Token::CLASS); | |
| 1035 return ParseClassDeclaration(NULL, false, ok); | |
| 1036 case Token::CONST: | |
| 1037 return ParseVariableStatement(kStatementListItem, NULL, ok); | |
| 1038 case Token::VAR: | |
| 1039 return ParseVariableStatement(kStatementListItem, NULL, ok); | |
| 1040 case Token::LET: | |
| 1041 if (IsNextLetKeyword()) { | |
| 1042 return ParseVariableStatement(kStatementListItem, NULL, ok); | |
| 1043 } | |
| 1044 break; | |
| 1045 case Token::ASYNC: | |
| 1046 if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION && | |
| 1047 !scanner()->HasAnyLineTerminatorAfterNext()) { | |
| 1048 Consume(Token::ASYNC); | |
| 1049 return ParseAsyncFunctionDeclaration(NULL, false, ok); | |
| 1050 } | |
| 1051 /* falls through */ | |
| 1052 default: | |
| 1053 break; | |
| 1054 } | |
| 1055 return ParseStatement(NULL, kAllowLabelledFunctionStatement, ok); | |
| 1056 } | |
| 1057 | |
| 1058 | |
| 1059 Statement* Parser::ParseModuleItem(bool* ok) { | 932 Statement* Parser::ParseModuleItem(bool* ok) { |
| 1060 // ecma262/#prod-ModuleItem | 933 // ecma262/#prod-ModuleItem |
| 1061 // ModuleItem : | 934 // ModuleItem : |
| 1062 // ImportDeclaration | 935 // ImportDeclaration |
| 1063 // ExportDeclaration | 936 // ExportDeclaration |
| 1064 // StatementListItem | 937 // StatementListItem |
| 1065 | 938 |
| 1066 switch (peek()) { | 939 switch (peek()) { |
| 1067 case Token::IMPORT: | 940 case Token::IMPORT: |
| 1068 ParseImportDeclaration(CHECK_OK); | 941 ParseImportDeclaration(CHECK_OK); |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1479 ModuleDescriptor* descriptor = module(); | 1352 ModuleDescriptor* descriptor = module(); |
| 1480 for (int i = 0; i < names.length(); ++i) { | 1353 for (int i = 0; i < names.length(); ++i) { |
| 1481 // TODO(neis): Provide better location. | 1354 // TODO(neis): Provide better location. |
| 1482 descriptor->AddExport(names[i], names[i], scanner()->location(), zone()); | 1355 descriptor->AddExport(names[i], names[i], scanner()->location(), zone()); |
| 1483 } | 1356 } |
| 1484 | 1357 |
| 1485 DCHECK_NOT_NULL(result); | 1358 DCHECK_NOT_NULL(result); |
| 1486 return result; | 1359 return result; |
| 1487 } | 1360 } |
| 1488 | 1361 |
| 1489 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels, | |
| 1490 AllowLabelledFunctionStatement allow_function, | |
| 1491 bool* ok) { | |
| 1492 // Statement :: | |
| 1493 // EmptyStatement | |
| 1494 // ... | |
| 1495 | |
| 1496 if (peek() == Token::SEMICOLON) { | |
| 1497 Next(); | |
| 1498 return factory()->NewEmptyStatement(kNoSourcePosition); | |
| 1499 } | |
| 1500 return ParseSubStatement(labels, allow_function, ok); | |
| 1501 } | |
| 1502 | |
| 1503 Statement* Parser::ParseSubStatement( | |
| 1504 ZoneList<const AstRawString*>* labels, | |
| 1505 AllowLabelledFunctionStatement allow_function, bool* ok) { | |
| 1506 // Statement :: | |
| 1507 // Block | |
| 1508 // VariableStatement | |
| 1509 // EmptyStatement | |
| 1510 // ExpressionStatement | |
| 1511 // IfStatement | |
| 1512 // IterationStatement | |
| 1513 // ContinueStatement | |
| 1514 // BreakStatement | |
| 1515 // ReturnStatement | |
| 1516 // WithStatement | |
| 1517 // LabelledStatement | |
| 1518 // SwitchStatement | |
| 1519 // ThrowStatement | |
| 1520 // TryStatement | |
| 1521 // DebuggerStatement | |
| 1522 | |
| 1523 // Note: Since labels can only be used by 'break' and 'continue' | |
| 1524 // statements, which themselves are only valid within blocks, | |
| 1525 // iterations or 'switch' statements (i.e., BreakableStatements), | |
| 1526 // labels can be simply ignored in all other cases; except for | |
| 1527 // trivial labeled break statements 'label: break label' which is | |
| 1528 // parsed into an empty statement. | |
| 1529 switch (peek()) { | |
| 1530 case Token::LBRACE: | |
| 1531 return ParseBlock(labels, ok); | |
| 1532 | |
| 1533 case Token::SEMICOLON: | |
| 1534 Next(); | |
| 1535 return factory()->NewEmptyStatement(kNoSourcePosition); | |
| 1536 | |
| 1537 case Token::IF: | |
| 1538 return ParseIfStatement(labels, ok); | |
| 1539 | |
| 1540 case Token::DO: | |
| 1541 return ParseDoWhileStatement(labels, ok); | |
| 1542 | |
| 1543 case Token::WHILE: | |
| 1544 return ParseWhileStatement(labels, ok); | |
| 1545 | |
| 1546 case Token::FOR: | |
| 1547 return ParseForStatement(labels, ok); | |
| 1548 | |
| 1549 case Token::CONTINUE: | |
| 1550 case Token::BREAK: | |
| 1551 case Token::RETURN: | |
| 1552 case Token::THROW: | |
| 1553 case Token::TRY: { | |
| 1554 // These statements must have their labels preserved in an enclosing | |
| 1555 // block | |
| 1556 if (labels == NULL) { | |
| 1557 return ParseStatementAsUnlabelled(labels, ok); | |
| 1558 } else { | |
| 1559 Block* result = | |
| 1560 factory()->NewBlock(labels, 1, false, kNoSourcePosition); | |
| 1561 Target target(&this->target_stack_, result); | |
| 1562 Statement* statement = ParseStatementAsUnlabelled(labels, CHECK_OK); | |
| 1563 if (result) result->statements()->Add(statement, zone()); | |
| 1564 return result; | |
| 1565 } | |
| 1566 } | |
| 1567 | |
| 1568 case Token::WITH: | |
| 1569 return ParseWithStatement(labels, ok); | |
| 1570 | |
| 1571 case Token::SWITCH: | |
| 1572 return ParseSwitchStatement(labels, ok); | |
| 1573 | |
| 1574 case Token::FUNCTION: | |
| 1575 // FunctionDeclaration only allowed as a StatementListItem, not in | |
| 1576 // an arbitrary Statement position. Exceptions such as | |
| 1577 // ES#sec-functiondeclarations-in-ifstatement-statement-clauses | |
| 1578 // are handled by calling ParseScopedStatement rather than | |
| 1579 // ParseSubStatement directly. | |
| 1580 ReportMessageAt(scanner()->peek_location(), | |
| 1581 is_strict(language_mode()) | |
| 1582 ? MessageTemplate::kStrictFunction | |
| 1583 : MessageTemplate::kSloppyFunction); | |
| 1584 *ok = false; | |
| 1585 return nullptr; | |
| 1586 | |
| 1587 case Token::DEBUGGER: | |
| 1588 return ParseDebuggerStatement(ok); | |
| 1589 | |
| 1590 case Token::VAR: | |
| 1591 return ParseVariableStatement(kStatement, NULL, ok); | |
| 1592 | |
| 1593 default: | |
| 1594 return ParseExpressionOrLabelledStatement(labels, allow_function, ok); | |
| 1595 } | |
| 1596 } | |
| 1597 | |
| 1598 Statement* Parser::ParseStatementAsUnlabelled( | |
| 1599 ZoneList<const AstRawString*>* labels, bool* ok) { | |
| 1600 switch (peek()) { | |
| 1601 case Token::CONTINUE: | |
| 1602 return ParseContinueStatement(ok); | |
| 1603 | |
| 1604 case Token::BREAK: | |
| 1605 return ParseBreakStatement(labels, ok); | |
| 1606 | |
| 1607 case Token::RETURN: | |
| 1608 return ParseReturnStatement(ok); | |
| 1609 | |
| 1610 case Token::THROW: | |
| 1611 return ParseThrowStatement(ok); | |
| 1612 | |
| 1613 case Token::TRY: | |
| 1614 return ParseTryStatement(ok); | |
| 1615 | |
| 1616 default: | |
| 1617 UNREACHABLE(); | |
| 1618 return NULL; | |
| 1619 } | |
| 1620 } | |
| 1621 | |
| 1622 VariableProxy* Parser::NewUnresolved(const AstRawString* name, int begin_pos, | 1362 VariableProxy* Parser::NewUnresolved(const AstRawString* name, int begin_pos, |
| 1623 int end_pos, Variable::Kind kind) { | 1363 int end_pos, Variable::Kind kind) { |
| 1624 return scope()->NewUnresolved(factory(), name, begin_pos, end_pos, kind); | 1364 return scope()->NewUnresolved(factory(), name, begin_pos, end_pos, kind); |
| 1625 } | 1365 } |
| 1626 | 1366 |
| 1627 VariableProxy* Parser::NewUnresolved(const AstRawString* name) { | 1367 VariableProxy* Parser::NewUnresolved(const AstRawString* name) { |
| 1628 return scope()->NewUnresolved(factory(), name, scanner()->location().beg_pos, | 1368 return scope()->NewUnresolved(factory(), name, scanner()->location().beg_pos, |
| 1629 scanner()->location().end_pos); | 1369 scanner()->location().end_pos); |
| 1630 } | 1370 } |
| 1631 | 1371 |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1870 // '{' StatementList '}' | 1610 // '{' StatementList '}' |
| 1871 | 1611 |
| 1872 // Construct block expecting 16 statements. | 1612 // Construct block expecting 16 statements. |
| 1873 Block* body = factory()->NewBlock(labels, 16, false, kNoSourcePosition); | 1613 Block* body = factory()->NewBlock(labels, 16, false, kNoSourcePosition); |
| 1874 | 1614 |
| 1875 // Parse the statements and collect escaping labels. | 1615 // Parse the statements and collect escaping labels. |
| 1876 Expect(Token::LBRACE, CHECK_OK); | 1616 Expect(Token::LBRACE, CHECK_OK); |
| 1877 { | 1617 { |
| 1878 BlockState block_state(&scope_state_); | 1618 BlockState block_state(&scope_state_); |
| 1879 block_state.set_start_position(scanner()->location().beg_pos); | 1619 block_state.set_start_position(scanner()->location().beg_pos); |
| 1880 Target target(&this->target_stack_, body); | 1620 ParserTarget target(this, body); |
| 1881 | 1621 |
| 1882 while (peek() != Token::RBRACE) { | 1622 while (peek() != Token::RBRACE) { |
| 1883 Statement* stat = ParseStatementListItem(CHECK_OK); | 1623 Statement* stat = ParseStatementListItem(CHECK_OK); |
| 1884 if (stat && !stat->IsEmpty()) { | 1624 if (stat && !stat->IsEmpty()) { |
| 1885 body->statements()->Add(stat, zone()); | 1625 body->statements()->Add(stat, zone()); |
| 1886 } | 1626 } |
| 1887 } | 1627 } |
| 1888 | 1628 |
| 1889 Expect(Token::RBRACE, CHECK_OK); | 1629 Expect(Token::RBRACE, CHECK_OK); |
| 1890 block_state.set_end_position(scanner()->location().end_pos); | 1630 block_state.set_end_position(scanner()->location().end_pos); |
| (...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2342 | 2082 |
| 2343 Block* cases_block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition); | 2083 Block* cases_block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition); |
| 2344 | 2084 |
| 2345 SwitchStatement* switch_statement = | 2085 SwitchStatement* switch_statement = |
| 2346 factory()->NewSwitchStatement(labels, switch_pos); | 2086 factory()->NewSwitchStatement(labels, switch_pos); |
| 2347 | 2087 |
| 2348 { | 2088 { |
| 2349 BlockState cases_block_state(&scope_state_); | 2089 BlockState cases_block_state(&scope_state_); |
| 2350 cases_block_state.set_start_position(scanner()->location().beg_pos); | 2090 cases_block_state.set_start_position(scanner()->location().beg_pos); |
| 2351 cases_block_state.SetNonlinear(); | 2091 cases_block_state.SetNonlinear(); |
| 2352 Target target(&this->target_stack_, switch_statement); | 2092 ParserTarget target(this, switch_statement); |
| 2353 | 2093 |
| 2354 Expression* tag_read = factory()->NewVariableProxy(tag_variable); | 2094 Expression* tag_read = factory()->NewVariableProxy(tag_variable); |
| 2355 | 2095 |
| 2356 bool default_seen = false; | 2096 bool default_seen = false; |
| 2357 ZoneList<CaseClause*>* cases = | 2097 ZoneList<CaseClause*>* cases = |
| 2358 new (zone()) ZoneList<CaseClause*>(4, zone()); | 2098 new (zone()) ZoneList<CaseClause*>(4, zone()); |
| 2359 Expect(Token::LBRACE, CHECK_OK); | 2099 Expect(Token::LBRACE, CHECK_OK); |
| 2360 while (peek() != Token::RBRACE) { | 2100 while (peek() != Token::RBRACE) { |
| 2361 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK); | 2101 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK); |
| 2362 cases->Add(clause, zone()); | 2102 cases->Add(clause, zone()); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2448 function_state_, &tail_call_expressions_in_catch_block); | 2188 function_state_, &tail_call_expressions_in_catch_block); |
| 2449 BlockState block_state(&scope_state_, catch_scope); | 2189 BlockState block_state(&scope_state_, catch_scope); |
| 2450 | 2190 |
| 2451 catch_block = factory()->NewBlock(nullptr, 16, false, kNoSourcePosition); | 2191 catch_block = factory()->NewBlock(nullptr, 16, false, kNoSourcePosition); |
| 2452 | 2192 |
| 2453 // Create a block scope to hold any lexical declarations created | 2193 // Create a block scope to hold any lexical declarations created |
| 2454 // as part of destructuring the catch parameter. | 2194 // as part of destructuring the catch parameter. |
| 2455 { | 2195 { |
| 2456 BlockState block_state(&scope_state_); | 2196 BlockState block_state(&scope_state_); |
| 2457 block_state.set_start_position(scanner()->location().beg_pos); | 2197 block_state.set_start_position(scanner()->location().beg_pos); |
| 2458 Target target(&this->target_stack_, catch_block); | 2198 ParserTarget target(this, catch_block); |
| 2459 | 2199 |
| 2460 const AstRawString* name = ast_value_factory()->dot_catch_string(); | 2200 const AstRawString* name = ast_value_factory()->dot_catch_string(); |
| 2461 Expression* pattern = nullptr; | 2201 Expression* pattern = nullptr; |
| 2462 if (peek_any_identifier()) { | 2202 if (peek_any_identifier()) { |
| 2463 name = ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK); | 2203 name = ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK); |
| 2464 } else { | 2204 } else { |
| 2465 ExpressionClassifier pattern_classifier(this); | 2205 ExpressionClassifier pattern_classifier(this); |
| 2466 pattern = ParsePrimaryExpression(CHECK_OK); | 2206 pattern = ParsePrimaryExpression(CHECK_OK); |
| 2467 ValidateBindingPattern(CHECK_OK); | 2207 ValidateBindingPattern(CHECK_OK); |
| 2468 } | 2208 } |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2587 } | 2327 } |
| 2588 | 2328 |
| 2589 | 2329 |
| 2590 DoWhileStatement* Parser::ParseDoWhileStatement( | 2330 DoWhileStatement* Parser::ParseDoWhileStatement( |
| 2591 ZoneList<const AstRawString*>* labels, bool* ok) { | 2331 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 2592 // DoStatement :: | 2332 // DoStatement :: |
| 2593 // 'do' Statement 'while' '(' Expression ')' ';' | 2333 // 'do' Statement 'while' '(' Expression ')' ';' |
| 2594 | 2334 |
| 2595 DoWhileStatement* loop = | 2335 DoWhileStatement* loop = |
| 2596 factory()->NewDoWhileStatement(labels, peek_position()); | 2336 factory()->NewDoWhileStatement(labels, peek_position()); |
| 2597 Target target(&this->target_stack_, loop); | 2337 ParserTarget target(this, loop); |
| 2598 | 2338 |
| 2599 Expect(Token::DO, CHECK_OK); | 2339 Expect(Token::DO, CHECK_OK); |
| 2600 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); | 2340 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); |
| 2601 Expect(Token::WHILE, CHECK_OK); | 2341 Expect(Token::WHILE, CHECK_OK); |
| 2602 Expect(Token::LPAREN, CHECK_OK); | 2342 Expect(Token::LPAREN, CHECK_OK); |
| 2603 | 2343 |
| 2604 Expression* cond = ParseExpression(true, CHECK_OK); | 2344 Expression* cond = ParseExpression(true, CHECK_OK); |
| 2605 Expect(Token::RPAREN, CHECK_OK); | 2345 Expect(Token::RPAREN, CHECK_OK); |
| 2606 | 2346 |
| 2607 // Allow do-statements to be terminated with and without | 2347 // Allow do-statements to be terminated with and without |
| 2608 // semi-colons. This allows code such as 'do;while(0)return' to | 2348 // semi-colons. This allows code such as 'do;while(0)return' to |
| 2609 // parse, which would not be the case if we had used the | 2349 // parse, which would not be the case if we had used the |
| 2610 // ExpectSemicolon() functionality here. | 2350 // ExpectSemicolon() functionality here. |
| 2611 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); | 2351 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); |
| 2612 | 2352 |
| 2613 if (loop != NULL) loop->Initialize(cond, body); | 2353 if (loop != NULL) loop->Initialize(cond, body); |
| 2614 return loop; | 2354 return loop; |
| 2615 } | 2355 } |
| 2616 | 2356 |
| 2617 | 2357 |
| 2618 WhileStatement* Parser::ParseWhileStatement( | 2358 WhileStatement* Parser::ParseWhileStatement( |
| 2619 ZoneList<const AstRawString*>* labels, bool* ok) { | 2359 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 2620 // WhileStatement :: | 2360 // WhileStatement :: |
| 2621 // 'while' '(' Expression ')' Statement | 2361 // 'while' '(' Expression ')' Statement |
| 2622 | 2362 |
| 2623 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position()); | 2363 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position()); |
| 2624 Target target(&this->target_stack_, loop); | 2364 ParserTarget target(this, loop); |
| 2625 | 2365 |
| 2626 Expect(Token::WHILE, CHECK_OK); | 2366 Expect(Token::WHILE, CHECK_OK); |
| 2627 Expect(Token::LPAREN, CHECK_OK); | 2367 Expect(Token::LPAREN, CHECK_OK); |
| 2628 Expression* cond = ParseExpression(true, CHECK_OK); | 2368 Expression* cond = ParseExpression(true, CHECK_OK); |
| 2629 Expect(Token::RPAREN, CHECK_OK); | 2369 Expect(Token::RPAREN, CHECK_OK); |
| 2630 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); | 2370 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); |
| 2631 | 2371 |
| 2632 if (loop != NULL) loop->Initialize(cond, body); | 2372 if (loop != NULL) loop->Initialize(cond, body); |
| 2633 return loop; | 2373 return loop; |
| 2634 } | 2374 } |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3062 } | 2802 } |
| 3063 | 2803 |
| 3064 outer_loop->Initialize(NULL, NULL, NULL, inner_block); | 2804 outer_loop->Initialize(NULL, NULL, NULL, inner_block); |
| 3065 return outer_block; | 2805 return outer_block; |
| 3066 } | 2806 } |
| 3067 | 2807 |
| 3068 Statement* Parser::ParseScopedStatement(ZoneList<const AstRawString*>* labels, | 2808 Statement* Parser::ParseScopedStatement(ZoneList<const AstRawString*>* labels, |
| 3069 bool legacy, bool* ok) { | 2809 bool legacy, bool* ok) { |
| 3070 if (is_strict(language_mode()) || peek() != Token::FUNCTION || | 2810 if (is_strict(language_mode()) || peek() != Token::FUNCTION || |
| 3071 (legacy && allow_harmony_restrictive_declarations())) { | 2811 (legacy && allow_harmony_restrictive_declarations())) { |
| 3072 return ParseSubStatement(labels, kDisallowLabelledFunctionStatement, ok); | 2812 return ParseStatement(labels, kDisallowLabelledFunctionStatement, ok); |
| 3073 } else { | 2813 } else { |
| 3074 if (legacy) { | 2814 if (legacy) { |
| 3075 ++use_counts_[v8::Isolate::kLegacyFunctionDeclaration]; | 2815 ++use_counts_[v8::Isolate::kLegacyFunctionDeclaration]; |
| 3076 } | 2816 } |
| 3077 // Make a block around the statement for a lexical binding | 2817 // Make a block around the statement for a lexical binding |
| 3078 // is introduced by a FunctionDeclaration. | 2818 // is introduced by a FunctionDeclaration. |
| 3079 BlockState block_state(&scope_state_); | 2819 BlockState block_state(&scope_state_); |
| 3080 block_state.set_start_position(scanner()->location().beg_pos); | 2820 block_state.set_start_position(scanner()->location().beg_pos); |
| 3081 Block* block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition); | 2821 Block* block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition); |
| 3082 Statement* body = ParseFunctionDeclaration(CHECK_OK); | 2822 Statement* body = ParseFunctionDeclaration(CHECK_OK); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3171 // let/const/var x; | 2911 // let/const/var x; |
| 3172 // x = x'; | 2912 // x = x'; |
| 3173 // b; | 2913 // b; |
| 3174 // } | 2914 // } |
| 3175 // let x; // for TDZ | 2915 // let x; // for TDZ |
| 3176 // } | 2916 // } |
| 3177 | 2917 |
| 3178 Variable* temp = NewTemporary(ast_value_factory()->dot_for_string()); | 2918 Variable* temp = NewTemporary(ast_value_factory()->dot_for_string()); |
| 3179 ForEachStatement* loop = | 2919 ForEachStatement* loop = |
| 3180 factory()->NewForEachStatement(mode, labels, stmt_pos); | 2920 factory()->NewForEachStatement(mode, labels, stmt_pos); |
| 3181 Target target(&this->target_stack_, loop); | 2921 ParserTarget target(this, loop); |
| 3182 | 2922 |
| 3183 int each_keyword_position = scanner()->location().beg_pos; | 2923 int each_keyword_position = scanner()->location().beg_pos; |
| 3184 | 2924 |
| 3185 Expression* enumerable; | 2925 Expression* enumerable; |
| 3186 if (mode == ForEachStatement::ITERATE) { | 2926 if (mode == ForEachStatement::ITERATE) { |
| 3187 ExpressionClassifier classifier(this); | 2927 ExpressionClassifier classifier(this); |
| 3188 enumerable = ParseAssignmentExpression(true, CHECK_OK); | 2928 enumerable = ParseAssignmentExpression(true, CHECK_OK); |
| 3189 RewriteNonPattern(CHECK_OK); | 2929 RewriteNonPattern(CHECK_OK); |
| 3190 } else { | 2930 } else { |
| 3191 enumerable = ParseExpression(true, CHECK_OK); | 2931 enumerable = ParseExpression(true, CHECK_OK); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3317 | 3057 |
| 3318 if (is_for_each) { | 3058 if (is_for_each) { |
| 3319 if (!is_destructuring) { | 3059 if (!is_destructuring) { |
| 3320 expression = CheckAndRewriteReferenceExpression( | 3060 expression = CheckAndRewriteReferenceExpression( |
| 3321 expression, lhs_beg_pos, lhs_end_pos, | 3061 expression, lhs_beg_pos, lhs_end_pos, |
| 3322 MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK); | 3062 MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK); |
| 3323 } | 3063 } |
| 3324 | 3064 |
| 3325 ForEachStatement* loop = | 3065 ForEachStatement* loop = |
| 3326 factory()->NewForEachStatement(mode, labels, stmt_pos); | 3066 factory()->NewForEachStatement(mode, labels, stmt_pos); |
| 3327 Target target(&this->target_stack_, loop); | 3067 ParserTarget target(this, loop); |
| 3328 | 3068 |
| 3329 int each_keyword_position = scanner()->location().beg_pos; | 3069 int each_keyword_position = scanner()->location().beg_pos; |
| 3330 | 3070 |
| 3331 Expression* enumerable; | 3071 Expression* enumerable; |
| 3332 if (mode == ForEachStatement::ITERATE) { | 3072 if (mode == ForEachStatement::ITERATE) { |
| 3333 ExpressionClassifier classifier(this); | 3073 ExpressionClassifier classifier(this); |
| 3334 enumerable = ParseAssignmentExpression(true, CHECK_OK); | 3074 enumerable = ParseAssignmentExpression(true, CHECK_OK); |
| 3335 RewriteNonPattern(CHECK_OK); | 3075 RewriteNonPattern(CHECK_OK); |
| 3336 } else { | 3076 } else { |
| 3337 enumerable = ParseExpression(true, CHECK_OK); | 3077 enumerable = ParseExpression(true, CHECK_OK); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3349 return final_loop; | 3089 return final_loop; |
| 3350 | 3090 |
| 3351 } else { | 3091 } else { |
| 3352 init = factory()->NewExpressionStatement(expression, lhs_beg_pos); | 3092 init = factory()->NewExpressionStatement(expression, lhs_beg_pos); |
| 3353 } | 3093 } |
| 3354 } | 3094 } |
| 3355 } | 3095 } |
| 3356 | 3096 |
| 3357 // Standard 'for' loop | 3097 // Standard 'for' loop |
| 3358 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos); | 3098 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos); |
| 3359 Target target(&this->target_stack_, loop); | 3099 ParserTarget target(this, loop); |
| 3360 | 3100 |
| 3361 // Parsed initializer at this point. | 3101 // Parsed initializer at this point. |
| 3362 Expect(Token::SEMICOLON, CHECK_OK); | 3102 Expect(Token::SEMICOLON, CHECK_OK); |
| 3363 | 3103 |
| 3364 Expression* cond = NULL; | 3104 Expression* cond = NULL; |
| 3365 Statement* next = NULL; | 3105 Statement* next = NULL; |
| 3366 Statement* body = NULL; | 3106 Statement* body = NULL; |
| 3367 | 3107 |
| 3368 // If there are let bindings, then condition and the next statement of the | 3108 // If there are let bindings, then condition and the next statement of the |
| 3369 // for loop must be parsed in a new scope. | 3109 // for loop must be parsed in a new scope. |
| (...skipping 1438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4808 delegate->set_statement(statement); | 4548 delegate->set_statement(statement); |
| 4809 } | 4549 } |
| 4810 } | 4550 } |
| 4811 } | 4551 } |
| 4812 | 4552 |
| 4813 | 4553 |
| 4814 // ---------------------------------------------------------------------------- | 4554 // ---------------------------------------------------------------------------- |
| 4815 // Parser support | 4555 // Parser support |
| 4816 | 4556 |
| 4817 bool Parser::TargetStackContainsLabel(const AstRawString* label) { | 4557 bool Parser::TargetStackContainsLabel(const AstRawString* label) { |
| 4818 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 4558 for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) { |
| 4819 if (ContainsLabel(t->statement()->labels(), label)) return true; | 4559 if (ContainsLabel(t->statement()->labels(), label)) return true; |
| 4820 } | 4560 } |
| 4821 return false; | 4561 return false; |
| 4822 } | 4562 } |
| 4823 | 4563 |
| 4824 | 4564 |
| 4825 BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label, | 4565 BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label, |
| 4826 bool* ok) { | 4566 bool* ok) { |
| 4827 bool anonymous = label == NULL; | 4567 bool anonymous = label == NULL; |
| 4828 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 4568 for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) { |
| 4829 BreakableStatement* stat = t->statement(); | 4569 BreakableStatement* stat = t->statement(); |
| 4830 if ((anonymous && stat->is_target_for_anonymous()) || | 4570 if ((anonymous && stat->is_target_for_anonymous()) || |
| 4831 (!anonymous && ContainsLabel(stat->labels(), label))) { | 4571 (!anonymous && ContainsLabel(stat->labels(), label))) { |
| 4832 return stat; | 4572 return stat; |
| 4833 } | 4573 } |
| 4834 } | 4574 } |
| 4835 return NULL; | 4575 return NULL; |
| 4836 } | 4576 } |
| 4837 | 4577 |
| 4838 | 4578 |
| 4839 IterationStatement* Parser::LookupContinueTarget(const AstRawString* label, | 4579 IterationStatement* Parser::LookupContinueTarget(const AstRawString* label, |
| 4840 bool* ok) { | 4580 bool* ok) { |
| 4841 bool anonymous = label == NULL; | 4581 bool anonymous = label == NULL; |
| 4842 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 4582 for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) { |
| 4843 IterationStatement* stat = t->statement()->AsIterationStatement(); | 4583 IterationStatement* stat = t->statement()->AsIterationStatement(); |
| 4844 if (stat == NULL) continue; | 4584 if (stat == NULL) continue; |
| 4845 | 4585 |
| 4846 DCHECK(stat->is_target_for_anonymous()); | 4586 DCHECK(stat->is_target_for_anonymous()); |
| 4847 if (anonymous || ContainsLabel(stat->labels(), label)) { | 4587 if (anonymous || ContainsLabel(stat->labels(), label)) { |
| 4848 return stat; | 4588 return stat; |
| 4849 } | 4589 } |
| 4850 } | 4590 } |
| 4851 return NULL; | 4591 return NULL; |
| 4852 } | 4592 } |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5226 if (is_sloppy(mode)) | 4966 if (is_sloppy(mode)) |
| 5227 feature = v8::Isolate::kSloppyMode; | 4967 feature = v8::Isolate::kSloppyMode; |
| 5228 else if (is_strict(mode)) | 4968 else if (is_strict(mode)) |
| 5229 feature = v8::Isolate::kStrictMode; | 4969 feature = v8::Isolate::kStrictMode; |
| 5230 else | 4970 else |
| 5231 UNREACHABLE(); | 4971 UNREACHABLE(); |
| 5232 ++use_counts_[feature]; | 4972 ++use_counts_[feature]; |
| 5233 scope->SetLanguageMode(mode); | 4973 scope->SetLanguageMode(mode); |
| 5234 } | 4974 } |
| 5235 | 4975 |
| 5236 | 4976 void Parser::SetAsmModule() { |
| 5237 void Parser::RaiseLanguageMode(LanguageMode mode) { | 4977 // Store the usage count; The actual use counter on the isolate is |
| 5238 LanguageMode old = scope()->language_mode(); | 4978 // incremented after parsing is done. |
| 5239 SetLanguageMode(scope(), old > mode ? old : mode); | 4979 ++use_counts_[v8::Isolate::kUseAsm]; |
| 4980 DCHECK(scope()->is_declaration_scope()); |
| 4981 scope()->AsDeclarationScope()->set_asm_module(); |
| 5240 } | 4982 } |
| 5241 | 4983 |
| 5242 void Parser::MarkCollectedTailCallExpressions() { | 4984 void Parser::MarkCollectedTailCallExpressions() { |
| 5243 const ZoneList<Expression*>& tail_call_expressions = | 4985 const ZoneList<Expression*>& tail_call_expressions = |
| 5244 function_state_->tail_call_expressions().expressions(); | 4986 function_state_->tail_call_expressions().expressions(); |
| 5245 for (int i = 0; i < tail_call_expressions.length(); ++i) { | 4987 for (int i = 0; i < tail_call_expressions.length(); ++i) { |
| 5246 Expression* expression = tail_call_expressions[i]; | 4988 Expression* expression = tail_call_expressions[i]; |
| 5247 // If only FLAG_harmony_explicit_tailcalls is enabled then expression | 4989 // If only FLAG_harmony_explicit_tailcalls is enabled then expression |
| 5248 // must be a Call expression. | 4990 // must be a Call expression. |
| 5249 DCHECK(FLAG_harmony_tailcalls || !FLAG_harmony_explicit_tailcalls || | 4991 DCHECK(FLAG_harmony_tailcalls || !FLAG_harmony_explicit_tailcalls || |
| (...skipping 1240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6490 node->Print(Isolate::Current()); | 6232 node->Print(Isolate::Current()); |
| 6491 } | 6233 } |
| 6492 #endif // DEBUG | 6234 #endif // DEBUG |
| 6493 | 6235 |
| 6494 #undef CHECK_OK | 6236 #undef CHECK_OK |
| 6495 #undef CHECK_OK_VOID | 6237 #undef CHECK_OK_VOID |
| 6496 #undef CHECK_FAILED | 6238 #undef CHECK_FAILED |
| 6497 | 6239 |
| 6498 } // namespace internal | 6240 } // namespace internal |
| 6499 } // namespace v8 | 6241 } // namespace v8 |
| OLD | NEW |