| 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 1684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1695 is_object_conditional, pos); | 1695 is_object_conditional, pos); |
| 1696 } | 1696 } |
| 1697 if (is_generator()) { | 1697 if (is_generator()) { |
| 1698 return_value = BuildIteratorResult(return_value, true); | 1698 return_value = BuildIteratorResult(return_value, true); |
| 1699 } else if (is_async_function()) { | 1699 } else if (is_async_function()) { |
| 1700 return_value = BuildResolvePromise(return_value, return_value->position()); | 1700 return_value = BuildResolvePromise(return_value, return_value->position()); |
| 1701 } | 1701 } |
| 1702 return return_value; | 1702 return return_value; |
| 1703 } | 1703 } |
| 1704 | 1704 |
| 1705 Expression* Parser::RewriteDoExpression(Block* body, int pos, bool* ok) { |
| 1706 Variable* result = NewTemporary(ast_value_factory()->dot_result_string()); |
| 1707 DoExpression* expr = factory()->NewDoExpression(body, result, pos); |
| 1708 if (!Rewriter::Rewrite(this, GetClosureScope(), expr, ast_value_factory())) { |
| 1709 *ok = false; |
| 1710 return nullptr; |
| 1711 } |
| 1712 return expr; |
| 1713 } |
| 1714 |
| 1705 Statement* Parser::ParseFunctionDeclaration(bool* ok) { | 1715 Statement* Parser::ParseFunctionDeclaration(bool* ok) { |
| 1706 Consume(Token::FUNCTION); | 1716 Consume(Token::FUNCTION); |
| 1707 int pos = position(); | 1717 int pos = position(); |
| 1708 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; | 1718 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; |
| 1709 if (Check(Token::MUL)) { | 1719 if (Check(Token::MUL)) { |
| 1710 flags |= ParseFunctionFlags::kIsGenerator; | 1720 flags |= ParseFunctionFlags::kIsGenerator; |
| 1711 if (allow_harmony_restrictive_declarations()) { | 1721 if (allow_harmony_restrictive_declarations()) { |
| 1712 ReportMessageAt(scanner()->location(), | 1722 ReportMessageAt(scanner()->location(), |
| 1713 MessageTemplate::kGeneratorInLegacyContext); | 1723 MessageTemplate::kGeneratorInLegacyContext); |
| 1714 *ok = false; | 1724 *ok = false; |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1818 | 1828 |
| 1819 cases_block_state.set_end_position(scanner()->location().end_pos); | 1829 cases_block_state.set_end_position(scanner()->location().end_pos); |
| 1820 cases_block->set_scope(cases_block_state.FinalizedBlockScope()); | 1830 cases_block->set_scope(cases_block_state.FinalizedBlockScope()); |
| 1821 } | 1831 } |
| 1822 | 1832 |
| 1823 switch_block->statements()->Add(cases_block, zone()); | 1833 switch_block->statements()->Add(cases_block, zone()); |
| 1824 | 1834 |
| 1825 return switch_block; | 1835 return switch_block; |
| 1826 } | 1836 } |
| 1827 | 1837 |
| 1828 | |
| 1829 Statement* Parser::ParseThrowStatement(bool* ok) { | |
| 1830 // ThrowStatement :: | |
| 1831 // 'throw' Expression ';' | |
| 1832 | |
| 1833 Expect(Token::THROW, CHECK_OK); | |
| 1834 int pos = position(); | |
| 1835 if (scanner()->HasAnyLineTerminatorBeforeNext()) { | |
| 1836 ReportMessage(MessageTemplate::kNewlineAfterThrow); | |
| 1837 *ok = false; | |
| 1838 return NULL; | |
| 1839 } | |
| 1840 Expression* exception = ParseExpression(true, CHECK_OK); | |
| 1841 ExpectSemicolon(CHECK_OK); | |
| 1842 | |
| 1843 return factory()->NewExpressionStatement( | |
| 1844 factory()->NewThrow(exception, pos), pos); | |
| 1845 } | |
| 1846 | |
| 1847 | |
| 1848 TryStatement* Parser::ParseTryStatement(bool* ok) { | 1838 TryStatement* Parser::ParseTryStatement(bool* ok) { |
| 1849 // TryStatement :: | 1839 // TryStatement :: |
| 1850 // 'try' Block Catch | 1840 // 'try' Block Catch |
| 1851 // 'try' Block Finally | 1841 // 'try' Block Finally |
| 1852 // 'try' Block Catch Finally | 1842 // 'try' Block Catch Finally |
| 1853 // | 1843 // |
| 1854 // Catch :: | 1844 // Catch :: |
| 1855 // 'catch' '(' Identifier ')' Block | 1845 // 'catch' '(' Identifier ')' Block |
| 1856 // | 1846 // |
| 1857 // Finally :: | 1847 // Finally :: |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2031 return NULL; | 2021 return NULL; |
| 2032 } | 2022 } |
| 2033 DCHECK(finally_block != NULL); | 2023 DCHECK(finally_block != NULL); |
| 2034 result = factory()->NewTryFinallyStatement(try_block, finally_block, pos); | 2024 result = factory()->NewTryFinallyStatement(try_block, finally_block, pos); |
| 2035 } | 2025 } |
| 2036 | 2026 |
| 2037 return result; | 2027 return result; |
| 2038 } | 2028 } |
| 2039 | 2029 |
| 2040 | 2030 |
| 2041 DoWhileStatement* Parser::ParseDoWhileStatement( | |
| 2042 ZoneList<const AstRawString*>* labels, bool* ok) { | |
| 2043 // DoStatement :: | |
| 2044 // 'do' Statement 'while' '(' Expression ')' ';' | |
| 2045 | |
| 2046 DoWhileStatement* loop = | |
| 2047 factory()->NewDoWhileStatement(labels, peek_position()); | |
| 2048 ParserTarget target(this, loop); | |
| 2049 | |
| 2050 Expect(Token::DO, CHECK_OK); | |
| 2051 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); | |
| 2052 Expect(Token::WHILE, CHECK_OK); | |
| 2053 Expect(Token::LPAREN, CHECK_OK); | |
| 2054 | |
| 2055 Expression* cond = ParseExpression(true, CHECK_OK); | |
| 2056 Expect(Token::RPAREN, CHECK_OK); | |
| 2057 | |
| 2058 // Allow do-statements to be terminated with and without | |
| 2059 // semi-colons. This allows code such as 'do;while(0)return' to | |
| 2060 // parse, which would not be the case if we had used the | |
| 2061 // ExpectSemicolon() functionality here. | |
| 2062 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); | |
| 2063 | |
| 2064 if (loop != NULL) loop->Initialize(cond, body); | |
| 2065 return loop; | |
| 2066 } | |
| 2067 | |
| 2068 | |
| 2069 WhileStatement* Parser::ParseWhileStatement( | |
| 2070 ZoneList<const AstRawString*>* labels, bool* ok) { | |
| 2071 // WhileStatement :: | |
| 2072 // 'while' '(' Expression ')' Statement | |
| 2073 | |
| 2074 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position()); | |
| 2075 ParserTarget target(this, loop); | |
| 2076 | |
| 2077 Expect(Token::WHILE, CHECK_OK); | |
| 2078 Expect(Token::LPAREN, CHECK_OK); | |
| 2079 Expression* cond = ParseExpression(true, CHECK_OK); | |
| 2080 Expect(Token::RPAREN, CHECK_OK); | |
| 2081 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); | |
| 2082 | |
| 2083 if (loop != NULL) loop->Initialize(cond, body); | |
| 2084 return loop; | |
| 2085 } | |
| 2086 | |
| 2087 | |
| 2088 // !%_IsJSReceiver(result = iterator.next()) && | 2031 // !%_IsJSReceiver(result = iterator.next()) && |
| 2089 // %ThrowIteratorResultNotAnObject(result) | 2032 // %ThrowIteratorResultNotAnObject(result) |
| 2090 Expression* Parser::BuildIteratorNextResult(Expression* iterator, | 2033 Expression* Parser::BuildIteratorNextResult(Expression* iterator, |
| 2091 Variable* result, int pos) { | 2034 Variable* result, int pos) { |
| 2092 Expression* next_literal = factory()->NewStringLiteral( | 2035 Expression* next_literal = factory()->NewStringLiteral( |
| 2093 ast_value_factory()->next_string(), kNoSourcePosition); | 2036 ast_value_factory()->next_string(), kNoSourcePosition); |
| 2094 Expression* next_property = | 2037 Expression* next_property = |
| 2095 factory()->NewProperty(iterator, next_literal, kNoSourcePosition); | 2038 factory()->NewProperty(iterator, next_literal, kNoSourcePosition); |
| 2096 ZoneList<Expression*>* next_arguments = | 2039 ZoneList<Expression*>* next_arguments = |
| 2097 new (zone()) ZoneList<Expression*>(0, zone()); | 2040 new (zone()) ZoneList<Expression*>(0, zone()); |
| (...skipping 854 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2952 | 2895 |
| 2953 return_value = BuildResolvePromise(return_value, return_value->position()); | 2896 return_value = BuildResolvePromise(return_value, return_value->position()); |
| 2954 block->statements()->Add( | 2897 block->statements()->Add( |
| 2955 factory()->NewReturnStatement(return_value, return_value->position()), | 2898 factory()->NewReturnStatement(return_value, return_value->position()), |
| 2956 zone()); | 2899 zone()); |
| 2957 block = BuildRejectPromiseOnException(block, CHECK_OK_VOID); | 2900 block = BuildRejectPromiseOnException(block, CHECK_OK_VOID); |
| 2958 body->Add(block, zone()); | 2901 body->Add(block, zone()); |
| 2959 scope->set_end_position(scanner()->location().end_pos); | 2902 scope->set_end_position(scanner()->location().end_pos); |
| 2960 } | 2903 } |
| 2961 | 2904 |
| 2962 DoExpression* Parser::ParseDoExpression(bool* ok) { | |
| 2963 // AssignmentExpression :: | |
| 2964 // do '{' StatementList '}' | |
| 2965 int pos = peek_position(); | |
| 2966 | |
| 2967 Expect(Token::DO, CHECK_OK); | |
| 2968 Variable* result = NewTemporary(ast_value_factory()->dot_result_string()); | |
| 2969 Block* block = ParseBlock(nullptr, CHECK_OK); | |
| 2970 DoExpression* expr = factory()->NewDoExpression(block, result, pos); | |
| 2971 if (!Rewriter::Rewrite(this, GetClosureScope(), expr, ast_value_factory())) { | |
| 2972 *ok = false; | |
| 2973 return nullptr; | |
| 2974 } | |
| 2975 return expr; | |
| 2976 } | |
| 2977 | |
| 2978 void Parser::ParseArrowFunctionFormalParameterList( | 2905 void Parser::ParseArrowFunctionFormalParameterList( |
| 2979 ParserFormalParameters* parameters, Expression* expr, | 2906 ParserFormalParameters* parameters, Expression* expr, |
| 2980 const Scanner::Location& params_loc, Scanner::Location* duplicate_loc, | 2907 const Scanner::Location& params_loc, Scanner::Location* duplicate_loc, |
| 2981 const Scope::Snapshot& scope_snapshot, bool* ok) { | 2908 const Scope::Snapshot& scope_snapshot, bool* ok) { |
| 2982 if (expr->IsEmptyParentheses()) return; | 2909 if (expr->IsEmptyParentheses()) return; |
| 2983 | 2910 |
| 2984 ParseArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos, | 2911 ParseArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos, |
| 2985 CHECK_OK_VOID); | 2912 CHECK_OK_VOID); |
| 2986 | 2913 |
| 2987 scope_snapshot.Reparent(parameters->scope); | 2914 scope_snapshot.Reparent(parameters->scope); |
| (...skipping 2761 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5749 node->Print(Isolate::Current()); | 5676 node->Print(Isolate::Current()); |
| 5750 } | 5677 } |
| 5751 #endif // DEBUG | 5678 #endif // DEBUG |
| 5752 | 5679 |
| 5753 #undef CHECK_OK | 5680 #undef CHECK_OK |
| 5754 #undef CHECK_OK_VOID | 5681 #undef CHECK_OK_VOID |
| 5755 #undef CHECK_FAILED | 5682 #undef CHECK_FAILED |
| 5756 | 5683 |
| 5757 } // namespace internal | 5684 } // namespace internal |
| 5758 } // namespace v8 | 5685 } // namespace v8 |
| OLD | NEW |