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 "src/api.h" | 7 #include "src/api.h" |
8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
9 #include "src/ast/ast-expression-rewriter.h" | 9 #include "src/ast/ast-expression-rewriter.h" |
10 #include "src/ast/ast-expression-visitor.h" | 10 #include "src/ast/ast-expression-visitor.h" |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 // CAUTION: This macro appends extra statements after a call, | 307 // CAUTION: This macro appends extra statements after a call, |
308 // thus it must never be used where only a single statement | 308 // thus it must never be used where only a single statement |
309 // is correct (e.g. an if statement branch w/o braces)! | 309 // is correct (e.g. an if statement branch w/o braces)! |
310 | 310 |
311 #define CHECK_OK ok); \ | 311 #define CHECK_OK ok); \ |
312 if (!*ok) return NULL; \ | 312 if (!*ok) return NULL; \ |
313 ((void)0 | 313 ((void)0 |
314 #define DUMMY ) // to make indentation work | 314 #define DUMMY ) // to make indentation work |
315 #undef DUMMY | 315 #undef DUMMY |
316 | 316 |
317 #define CHECK_FAILED /**/); \ | 317 // Used in functions where the return type is not ExpressionT. |
318 if (failed_) return NULL; \ | 318 #define CHECK_OK_CUSTOM(x) ok); \ |
| 319 if (!*ok) return this->x(); \ |
319 ((void)0 | 320 ((void)0 |
320 #define DUMMY ) // to make indentation work | 321 #define DUMMY ) // to make indentation work |
321 #undef DUMMY | 322 #undef DUMMY |
| 323 |
| 324 #define CHECK_FAILED /**/); \ |
| 325 if (failed_) return NULL; \ |
| 326 ((void)0 |
| 327 #define DUMMY ) // to make indentation work |
| 328 #undef DUMMY |
322 | 329 |
323 // ---------------------------------------------------------------------------- | 330 // ---------------------------------------------------------------------------- |
324 // Implementation of Parser | 331 // Implementation of Parser |
325 | 332 |
326 bool ParserTraits::IsEval(const AstRawString* identifier) const { | 333 bool ParserTraits::IsEval(const AstRawString* identifier) const { |
327 return identifier == parser_->ast_value_factory()->eval_string(); | 334 return identifier == parser_->ast_value_factory()->eval_string(); |
328 } | 335 } |
329 | 336 |
330 | 337 |
331 bool ParserTraits::IsArguments(const AstRawString* identifier) const { | 338 bool ParserTraits::IsArguments(const AstRawString* identifier) const { |
(...skipping 3537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3869 init = parsing_result.BuildInitializationBlock( | 3876 init = parsing_result.BuildInitializationBlock( |
3870 bound_names_are_lexical ? &bound_names : nullptr, CHECK_OK); | 3877 bound_names_are_lexical ? &bound_names : nullptr, CHECK_OK); |
3871 } | 3878 } |
3872 } else { | 3879 } else { |
3873 int lhs_beg_pos = peek_position(); | 3880 int lhs_beg_pos = peek_position(); |
3874 ExpressionClassifier classifier(this); | 3881 ExpressionClassifier classifier(this); |
3875 Expression* expression = ParseExpression(false, &classifier, CHECK_OK); | 3882 Expression* expression = ParseExpression(false, &classifier, CHECK_OK); |
3876 int lhs_end_pos = scanner()->location().end_pos; | 3883 int lhs_end_pos = scanner()->location().end_pos; |
3877 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE; | 3884 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE; |
3878 | 3885 |
3879 bool is_for_each = CheckInOrOf(&mode, ok); | 3886 bool is_for_each = CheckInOrOf(&mode, CHECK_OK); |
3880 if (!*ok) return nullptr; | |
3881 bool is_destructuring = is_for_each && (expression->IsArrayLiteral() || | 3887 bool is_destructuring = is_for_each && (expression->IsArrayLiteral() || |
3882 expression->IsObjectLiteral()); | 3888 expression->IsObjectLiteral()); |
3883 | 3889 |
3884 if (is_destructuring) { | 3890 if (is_destructuring) { |
3885 ValidateAssignmentPattern(&classifier, CHECK_OK); | 3891 ValidateAssignmentPattern(&classifier, CHECK_OK); |
3886 } else { | 3892 } else { |
3887 RewriteNonPattern(&classifier, CHECK_OK); | 3893 RewriteNonPattern(&classifier, CHECK_OK); |
3888 } | 3894 } |
3889 | 3895 |
3890 if (is_for_each) { | 3896 if (is_for_each) { |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4082 // the left-hand side of comma expressions. | 4088 // the left-hand side of comma expressions. |
4083 // | 4089 // |
4084 if (expr->IsBinaryOperation()) { | 4090 if (expr->IsBinaryOperation()) { |
4085 BinaryOperation* binop = expr->AsBinaryOperation(); | 4091 BinaryOperation* binop = expr->AsBinaryOperation(); |
4086 // The classifier has already run, so we know that the expression is a valid | 4092 // The classifier has already run, so we know that the expression is a valid |
4087 // arrow function formals production. | 4093 // arrow function formals production. |
4088 DCHECK_EQ(binop->op(), Token::COMMA); | 4094 DCHECK_EQ(binop->op(), Token::COMMA); |
4089 Expression* left = binop->left(); | 4095 Expression* left = binop->left(); |
4090 Expression* right = binop->right(); | 4096 Expression* right = binop->right(); |
4091 int comma_pos = binop->position(); | 4097 int comma_pos = binop->position(); |
4092 ParseArrowFunctionFormalParameters(parameters, left, comma_pos, ok); | 4098 ParseArrowFunctionFormalParameters(parameters, left, comma_pos, |
4093 if (!*ok) return; | 4099 CHECK_OK_CUSTOM(Void)); |
4094 // LHS of comma expression should be unparenthesized. | 4100 // LHS of comma expression should be unparenthesized. |
4095 expr = right; | 4101 expr = right; |
4096 } | 4102 } |
4097 | 4103 |
4098 // Only the right-most expression may be a rest parameter. | 4104 // Only the right-most expression may be a rest parameter. |
4099 DCHECK(!parameters->has_rest); | 4105 DCHECK(!parameters->has_rest); |
4100 | 4106 |
4101 bool is_rest = expr->IsSpread(); | 4107 bool is_rest = expr->IsSpread(); |
4102 if (is_rest) { | 4108 if (is_rest) { |
4103 expr = expr->AsSpread()->expression(); | 4109 expr = expr->AsSpread()->expression(); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4162 body->Add(factory()->NewExpressionStatement(init_generator_variable, | 4168 body->Add(factory()->NewExpressionStatement(init_generator_variable, |
4163 kNoSourcePosition), | 4169 kNoSourcePosition), |
4164 zone()); | 4170 zone()); |
4165 | 4171 |
4166 Block* try_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition); | 4172 Block* try_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition); |
4167 | 4173 |
4168 ZoneList<Statement*>* inner_body = try_block->statements(); | 4174 ZoneList<Statement*>* inner_body = try_block->statements(); |
4169 | 4175 |
4170 Expression* return_value = nullptr; | 4176 Expression* return_value = nullptr; |
4171 if (body_type == FunctionBody::Normal) { | 4177 if (body_type == FunctionBody::Normal) { |
4172 ParseStatementList(inner_body, Token::RBRACE, ok); | 4178 ParseStatementList(inner_body, Token::RBRACE, CHECK_OK_CUSTOM(Void)); |
4173 if (!*ok) return; | |
4174 return_value = factory()->NewUndefinedLiteral(kNoSourcePosition); | 4179 return_value = factory()->NewUndefinedLiteral(kNoSourcePosition); |
4175 } else { | 4180 } else { |
4176 return_value = ParseAssignmentExpression(accept_IN, classifier, ok); | 4181 return_value = |
4177 if (!*ok) return; | 4182 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK_CUSTOM(Void)); |
4178 ParserTraits::RewriteNonPattern(classifier, ok); | 4183 ParserTraits::RewriteNonPattern(classifier, CHECK_OK_CUSTOM(Void)); |
4179 if (!*ok) return; | |
4180 } | 4184 } |
4181 | 4185 |
4182 return_value = BuildPromiseResolve(return_value, return_value->position()); | 4186 return_value = BuildPromiseResolve(return_value, return_value->position()); |
4183 inner_body->Add( | 4187 inner_body->Add( |
4184 factory()->NewReturnStatement(return_value, return_value->position()), | 4188 factory()->NewReturnStatement(return_value, return_value->position()), |
4185 zone()); | 4189 zone()); |
4186 body->Add(BuildRejectPromiseOnException(try_block), zone()); | 4190 body->Add(BuildRejectPromiseOnException(try_block), zone()); |
4187 scope->set_end_position(scanner()->location().end_pos); | 4191 scope->set_end_position(scanner()->location().end_pos); |
4188 } | 4192 } |
4189 | 4193 |
(...skipping 15 matching lines...) Expand all Loading... |
4205 return expr; | 4209 return expr; |
4206 } | 4210 } |
4207 | 4211 |
4208 | 4212 |
4209 void ParserTraits::ParseArrowFunctionFormalParameterList( | 4213 void ParserTraits::ParseArrowFunctionFormalParameterList( |
4210 ParserFormalParameters* parameters, Expression* expr, | 4214 ParserFormalParameters* parameters, Expression* expr, |
4211 const Scanner::Location& params_loc, | 4215 const Scanner::Location& params_loc, |
4212 Scanner::Location* duplicate_loc, bool* ok) { | 4216 Scanner::Location* duplicate_loc, bool* ok) { |
4213 if (expr->IsEmptyParentheses()) return; | 4217 if (expr->IsEmptyParentheses()) return; |
4214 | 4218 |
4215 ParseArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos, ok); | 4219 ParseArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos, |
4216 if (!*ok) return; | 4220 CHECK_OK_CUSTOM(Void)); |
4217 | 4221 |
4218 if (parameters->Arity() > Code::kMaxArguments) { | 4222 if (parameters->Arity() > Code::kMaxArguments) { |
4219 ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList); | 4223 ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList); |
4220 *ok = false; | 4224 *ok = false; |
4221 return; | 4225 return; |
4222 } | 4226 } |
4223 | 4227 |
4224 Type::ExpressionClassifier classifier(parser_); | 4228 Type::ExpressionClassifier classifier(parser_); |
4225 if (!parameters->is_simple) { | 4229 if (!parameters->is_simple) { |
4226 classifier.RecordNonSimpleParameter(); | 4230 classifier.RecordNonSimpleParameter(); |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4530 // data contains the information we need to construct the lazy function. | 4534 // data contains the information we need to construct the lazy function. |
4531 FunctionEntry entry = | 4535 FunctionEntry entry = |
4532 cached_parse_data_->GetFunctionEntry(function_block_pos); | 4536 cached_parse_data_->GetFunctionEntry(function_block_pos); |
4533 // Check that cached data is valid. If not, mark it as invalid (the embedder | 4537 // Check that cached data is valid. If not, mark it as invalid (the embedder |
4534 // handles it). Note that end position greater than end of stream is safe, | 4538 // handles it). Note that end position greater than end of stream is safe, |
4535 // and hard to check. | 4539 // and hard to check. |
4536 if (entry.is_valid() && entry.end_pos() > function_block_pos) { | 4540 if (entry.is_valid() && entry.end_pos() > function_block_pos) { |
4537 scanner()->SeekForward(entry.end_pos() - 1); | 4541 scanner()->SeekForward(entry.end_pos() - 1); |
4538 | 4542 |
4539 scope_->set_end_position(entry.end_pos()); | 4543 scope_->set_end_position(entry.end_pos()); |
4540 Expect(Token::RBRACE, ok); | 4544 Expect(Token::RBRACE, CHECK_OK_CUSTOM(Void)); |
4541 if (!*ok) { | |
4542 return; | |
4543 } | |
4544 total_preparse_skipped_ += scope_->end_position() - function_block_pos; | 4545 total_preparse_skipped_ += scope_->end_position() - function_block_pos; |
4545 *materialized_literal_count = entry.literal_count(); | 4546 *materialized_literal_count = entry.literal_count(); |
4546 *expected_property_count = entry.property_count(); | 4547 *expected_property_count = entry.property_count(); |
4547 SetLanguageMode(scope_, entry.language_mode()); | 4548 SetLanguageMode(scope_, entry.language_mode()); |
4548 if (entry.uses_super_property()) scope_->RecordSuperPropertyUsage(); | 4549 if (entry.uses_super_property()) scope_->RecordSuperPropertyUsage(); |
4549 if (entry.calls_eval()) scope_->RecordEvalCall(); | 4550 if (entry.calls_eval()) scope_->RecordEvalCall(); |
4550 return; | 4551 return; |
4551 } | 4552 } |
4552 cached_parse_data_->Reject(); | 4553 cached_parse_data_->Reject(); |
4553 } | 4554 } |
(...skipping 12 matching lines...) Expand all Loading... |
4566 return; | 4567 return; |
4567 } | 4568 } |
4568 if (logger.has_error()) { | 4569 if (logger.has_error()) { |
4569 ParserTraits::ReportMessageAt( | 4570 ParserTraits::ReportMessageAt( |
4570 Scanner::Location(logger.start(), logger.end()), logger.message(), | 4571 Scanner::Location(logger.start(), logger.end()), logger.message(), |
4571 logger.argument_opt(), logger.error_type()); | 4572 logger.argument_opt(), logger.error_type()); |
4572 *ok = false; | 4573 *ok = false; |
4573 return; | 4574 return; |
4574 } | 4575 } |
4575 scope_->set_end_position(logger.end()); | 4576 scope_->set_end_position(logger.end()); |
4576 Expect(Token::RBRACE, ok); | 4577 Expect(Token::RBRACE, CHECK_OK_CUSTOM(Void)); |
4577 if (!*ok) { | |
4578 return; | |
4579 } | |
4580 total_preparse_skipped_ += scope_->end_position() - function_block_pos; | 4578 total_preparse_skipped_ += scope_->end_position() - function_block_pos; |
4581 *materialized_literal_count = logger.literals(); | 4579 *materialized_literal_count = logger.literals(); |
4582 *expected_property_count = logger.properties(); | 4580 *expected_property_count = logger.properties(); |
4583 SetLanguageMode(scope_, logger.language_mode()); | 4581 SetLanguageMode(scope_, logger.language_mode()); |
4584 if (logger.uses_super_property()) { | 4582 if (logger.uses_super_property()) { |
4585 scope_->RecordSuperPropertyUsage(); | 4583 scope_->RecordSuperPropertyUsage(); |
4586 } | 4584 } |
4587 if (logger.calls_eval()) { | 4585 if (logger.calls_eval()) { |
4588 scope_->RecordEvalCall(); | 4586 scope_->RecordEvalCall(); |
4589 } | 4587 } |
(...skipping 1268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5858 if (property == nullptr) return; | 5856 if (property == nullptr) return; |
5859 // Do not rewrite (computed) key expressions | 5857 // Do not rewrite (computed) key expressions |
5860 AST_REWRITE_PROPERTY(Expression, property, value); | 5858 AST_REWRITE_PROPERTY(Expression, property, value); |
5861 } | 5859 } |
5862 | 5860 |
5863 Parser* parser_; | 5861 Parser* parser_; |
5864 }; | 5862 }; |
5865 | 5863 |
5866 | 5864 |
5867 void Parser::RewriteNonPattern(ExpressionClassifier* classifier, bool* ok) { | 5865 void Parser::RewriteNonPattern(ExpressionClassifier* classifier, bool* ok) { |
5868 ValidateExpression(classifier, ok); | 5866 ValidateExpression(classifier, CHECK_OK_CUSTOM(Void)); |
5869 if (!*ok) return; | |
5870 auto non_patterns_to_rewrite = function_state_->non_patterns_to_rewrite(); | 5867 auto non_patterns_to_rewrite = function_state_->non_patterns_to_rewrite(); |
5871 int begin = classifier->GetNonPatternBegin(); | 5868 int begin = classifier->GetNonPatternBegin(); |
5872 int end = non_patterns_to_rewrite->length(); | 5869 int end = non_patterns_to_rewrite->length(); |
5873 if (begin < end) { | 5870 if (begin < end) { |
5874 NonPatternRewriter rewriter(stack_limit_, this); | 5871 NonPatternRewriter rewriter(stack_limit_, this); |
5875 for (int i = begin; i < end; i++) { | 5872 for (int i = begin; i < end; i++) { |
5876 DCHECK(non_patterns_to_rewrite->at(i)->IsRewritableExpression()); | 5873 DCHECK(non_patterns_to_rewrite->at(i)->IsRewritableExpression()); |
5877 rewriter.Rewrite(non_patterns_to_rewrite->at(i)); | 5874 rewriter.Rewrite(non_patterns_to_rewrite->at(i)); |
5878 } | 5875 } |
5879 non_patterns_to_rewrite->Rewind(begin); | 5876 non_patterns_to_rewrite->Rewind(begin); |
(...skipping 1180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7060 return final_loop; | 7057 return final_loop; |
7061 } | 7058 } |
7062 | 7059 |
7063 #ifdef DEBUG | 7060 #ifdef DEBUG |
7064 void Parser::Print(AstNode* node) { | 7061 void Parser::Print(AstNode* node) { |
7065 ast_value_factory()->Internalize(Isolate::Current()); | 7062 ast_value_factory()->Internalize(Isolate::Current()); |
7066 node->Print(Isolate::Current()); | 7063 node->Print(Isolate::Current()); |
7067 } | 7064 } |
7068 #endif // DEBUG | 7065 #endif // DEBUG |
7069 | 7066 |
| 7067 #undef CHECK_OK |
| 7068 #undef CHECK_OK_CUSTOM |
| 7069 #undef CHECK_FAILED |
| 7070 |
7070 } // namespace internal | 7071 } // namespace internal |
7071 } // namespace v8 | 7072 } // namespace v8 |
OLD | NEW |