| 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 |