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 |