| 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 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 Expression* prop = | 499 Expression* prop = |
| 500 factory()->NewProperty(iterable, iterator_symbol_literal, pos); | 500 factory()->NewProperty(iterable, iterator_symbol_literal, pos); |
| 501 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(0, zone()); | 501 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(0, zone()); |
| 502 return factory()->NewCall(prop, args, pos); | 502 return factory()->NewCall(prop, args, pos); |
| 503 } | 503 } |
| 504 | 504 |
| 505 void Parser::MarkTailPosition(Expression* expression) { | 505 void Parser::MarkTailPosition(Expression* expression) { |
| 506 expression->MarkTail(); | 506 expression->MarkTail(); |
| 507 } | 507 } |
| 508 | 508 |
| 509 Expression* Parser::NewV8Intrinsic(const AstRawString* name, |
| 510 ZoneList<Expression*>* args, int pos, |
| 511 bool* ok) { |
| 512 if (extension_ != nullptr) { |
| 513 // The extension structures are only accessible while parsing the |
| 514 // very first time, not when reparsing because of lazy compilation. |
| 515 GetClosureScope()->ForceEagerCompilation(); |
| 516 } |
| 517 |
| 518 const Runtime::Function* function = Runtime::FunctionForName(name->string()); |
| 519 |
| 520 if (function != nullptr) { |
| 521 // Check for possible name clash. |
| 522 DCHECK_EQ(Context::kNotFound, |
| 523 Context::IntrinsicIndexForName(name->string())); |
| 524 // Check for built-in IS_VAR macro. |
| 525 if (function->function_id == Runtime::kIS_VAR) { |
| 526 DCHECK_EQ(Runtime::RUNTIME, function->intrinsic_type); |
| 527 // %IS_VAR(x) evaluates to x if x is a variable, |
| 528 // leads to a parse error otherwise. Could be implemented as an |
| 529 // inline function %_IS_VAR(x) to eliminate this special case. |
| 530 if (args->length() == 1 && args->at(0)->AsVariableProxy() != nullptr) { |
| 531 return args->at(0); |
| 532 } else { |
| 533 ReportMessage(MessageTemplate::kNotIsvar); |
| 534 *ok = false; |
| 535 return nullptr; |
| 536 } |
| 537 } |
| 538 |
| 539 // Check that the expected number of arguments are being passed. |
| 540 if (function->nargs != -1 && function->nargs != args->length()) { |
| 541 ReportMessage(MessageTemplate::kRuntimeWrongNumArgs); |
| 542 *ok = false; |
| 543 return nullptr; |
| 544 } |
| 545 |
| 546 return factory()->NewCallRuntime(function, args, pos); |
| 547 } |
| 548 |
| 549 int context_index = Context::IntrinsicIndexForName(name->string()); |
| 550 |
| 551 // Check that the function is defined. |
| 552 if (context_index == Context::kNotFound) { |
| 553 ReportMessage(MessageTemplate::kNotDefined, name); |
| 554 *ok = false; |
| 555 return nullptr; |
| 556 } |
| 557 |
| 558 return factory()->NewCallRuntime(context_index, args, pos); |
| 559 } |
| 560 |
| 509 Parser::Parser(ParseInfo* info) | 561 Parser::Parser(ParseInfo* info) |
| 510 : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(), | 562 : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(), |
| 511 info->extension(), info->ast_value_factory(), NULL), | 563 info->extension(), info->ast_value_factory(), NULL), |
| 512 scanner_(info->unicode_cache()), | 564 scanner_(info->unicode_cache()), |
| 513 reusable_preparser_(NULL), | 565 reusable_preparser_(NULL), |
| 514 original_scope_(NULL), | 566 original_scope_(NULL), |
| 515 target_stack_(NULL), | 567 target_stack_(NULL), |
| 516 compile_options_(info->compile_options()), | 568 compile_options_(info->compile_options()), |
| 517 cached_parse_data_(NULL), | 569 cached_parse_data_(NULL), |
| 518 total_preparse_skipped_(0), | 570 total_preparse_skipped_(0), |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 700 this->scope()->SetLanguageMode(info->language_mode()); | 752 this->scope()->SetLanguageMode(info->language_mode()); |
| 701 ParseStatementList(body, Token::EOS, &ok); | 753 ParseStatementList(body, Token::EOS, &ok); |
| 702 } | 754 } |
| 703 | 755 |
| 704 // The parser will peek but not consume EOS. Our scope logically goes all | 756 // The parser will peek but not consume EOS. Our scope logically goes all |
| 705 // the way to the EOS, though. | 757 // the way to the EOS, though. |
| 706 scope->set_end_position(scanner()->peek_location().beg_pos); | 758 scope->set_end_position(scanner()->peek_location().beg_pos); |
| 707 | 759 |
| 708 if (ok && is_strict(language_mode())) { | 760 if (ok && is_strict(language_mode())) { |
| 709 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); | 761 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); |
| 710 CheckDecimalLiteralWithLeadingZero(use_counts_, beg_pos, | 762 CheckDecimalLiteralWithLeadingZero(beg_pos, |
| 711 scanner()->location().end_pos); | 763 scanner()->location().end_pos); |
| 712 } | 764 } |
| 713 if (ok && is_sloppy(language_mode())) { | 765 if (ok && is_sloppy(language_mode())) { |
| 714 // TODO(littledan): Function bindings on the global object that modify | 766 // TODO(littledan): Function bindings on the global object that modify |
| 715 // pre-existing bindings should be made writable, enumerable and | 767 // pre-existing bindings should be made writable, enumerable and |
| 716 // nonconfigurable if possible, whereas this code will leave attributes | 768 // nonconfigurable if possible, whereas this code will leave attributes |
| 717 // unchanged if the property already exists. | 769 // unchanged if the property already exists. |
| 718 InsertSloppyBlockFunctionVarBindings(scope, &ok); | 770 InsertSloppyBlockFunctionVarBindings(scope, &ok); |
| 719 } | 771 } |
| 720 if (ok) { | 772 if (ok) { |
| (...skipping 889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1610 | 1662 |
| 1611 void Parser::DeclareAndInitializeVariables( | 1663 void Parser::DeclareAndInitializeVariables( |
| 1612 Block* block, const DeclarationDescriptor* declaration_descriptor, | 1664 Block* block, const DeclarationDescriptor* declaration_descriptor, |
| 1613 const DeclarationParsingResult::Declaration* declaration, | 1665 const DeclarationParsingResult::Declaration* declaration, |
| 1614 ZoneList<const AstRawString*>* names, bool* ok) { | 1666 ZoneList<const AstRawString*>* names, bool* ok) { |
| 1615 DCHECK_NOT_NULL(block); | 1667 DCHECK_NOT_NULL(block); |
| 1616 PatternRewriter::DeclareAndInitializeVariables( | 1668 PatternRewriter::DeclareAndInitializeVariables( |
| 1617 this, block, declaration_descriptor, declaration, names, ok); | 1669 this, block, declaration_descriptor, declaration, names, ok); |
| 1618 } | 1670 } |
| 1619 | 1671 |
| 1620 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, | |
| 1621 ZoneList<const AstRawString*>* names, | |
| 1622 bool* ok) { | |
| 1623 // VariableStatement :: | |
| 1624 // VariableDeclarations ';' | |
| 1625 | |
| 1626 // The scope of a var declared variable anywhere inside a function | |
| 1627 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can | |
| 1628 // transform a source-level var declaration into a (Function) Scope | |
| 1629 // declaration, and rewrite the source-level initialization into an assignment | |
| 1630 // statement. We use a block to collect multiple assignments. | |
| 1631 // | |
| 1632 // We mark the block as initializer block because we don't want the | |
| 1633 // rewriter to add a '.result' assignment to such a block (to get compliant | |
| 1634 // behavior for code such as print(eval('var x = 7')), and for cosmetic | |
| 1635 // reasons when pretty-printing. Also, unless an assignment (initialization) | |
| 1636 // is inside an initializer block, it is ignored. | |
| 1637 | |
| 1638 DeclarationParsingResult parsing_result; | |
| 1639 Block* result = | |
| 1640 ParseVariableDeclarations(var_context, &parsing_result, names, CHECK_OK); | |
| 1641 ExpectSemicolon(CHECK_OK); | |
| 1642 return result; | |
| 1643 } | |
| 1644 | |
| 1645 static bool ContainsLabel(ZoneList<const AstRawString*>* labels, | 1672 static bool ContainsLabel(ZoneList<const AstRawString*>* labels, |
| 1646 const AstRawString* label) { | 1673 const AstRawString* label) { |
| 1647 DCHECK(label != NULL); | 1674 DCHECK(label != NULL); |
| 1648 if (labels != NULL) { | 1675 if (labels != NULL) { |
| 1649 for (int i = labels->length(); i-- > 0; ) { | 1676 for (int i = labels->length(); i-- > 0; ) { |
| 1650 if (labels->at(i) == label) { | 1677 if (labels->at(i) == label) { |
| 1651 return true; | 1678 return true; |
| 1652 } | 1679 } |
| 1653 } | 1680 } |
| 1654 } | 1681 } |
| (...skipping 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2760 } | 2787 } |
| 2761 | 2788 |
| 2762 inner_scope->set_end_position(scanner()->location().end_pos); | 2789 inner_scope->set_end_position(scanner()->location().end_pos); |
| 2763 inner_block->set_scope(inner_scope); | 2790 inner_block->set_scope(inner_scope); |
| 2764 } | 2791 } |
| 2765 | 2792 |
| 2766 outer_loop->Initialize(NULL, NULL, NULL, inner_block); | 2793 outer_loop->Initialize(NULL, NULL, NULL, inner_block); |
| 2767 return outer_block; | 2794 return outer_block; |
| 2768 } | 2795 } |
| 2769 | 2796 |
| 2770 Statement* Parser::ParseScopedStatement(ZoneList<const AstRawString*>* labels, | |
| 2771 bool legacy, bool* ok) { | |
| 2772 if (is_strict(language_mode()) || peek() != Token::FUNCTION || | |
| 2773 (legacy && allow_harmony_restrictive_declarations())) { | |
| 2774 return ParseStatement(labels, kDisallowLabelledFunctionStatement, ok); | |
| 2775 } else { | |
| 2776 if (legacy) { | |
| 2777 ++use_counts_[v8::Isolate::kLegacyFunctionDeclaration]; | |
| 2778 } | |
| 2779 // Make a block around the statement for a lexical binding | |
| 2780 // is introduced by a FunctionDeclaration. | |
| 2781 BlockState block_state(&scope_state_); | |
| 2782 block_state.set_start_position(scanner()->location().beg_pos); | |
| 2783 Block* block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition); | |
| 2784 Statement* body = ParseFunctionDeclaration(CHECK_OK); | |
| 2785 block->statements()->Add(body, zone()); | |
| 2786 block_state.set_end_position(scanner()->location().end_pos); | |
| 2787 block->set_scope(block_state.FinalizedBlockScope()); | |
| 2788 return block; | |
| 2789 } | |
| 2790 } | |
| 2791 | |
| 2792 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, | 2797 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, |
| 2793 bool* ok) { | 2798 bool* ok) { |
| 2794 int stmt_pos = peek_position(); | 2799 int stmt_pos = peek_position(); |
| 2795 Statement* init = NULL; | 2800 Statement* init = NULL; |
| 2796 ZoneList<const AstRawString*> bound_names(1, zone()); | 2801 ZoneList<const AstRawString*> bound_names(1, zone()); |
| 2797 bool bound_names_are_lexical = false; | 2802 bool bound_names_are_lexical = false; |
| 2798 | 2803 |
| 2799 // Create an in-between scope for let-bound iteration variables. | 2804 // Create an in-between scope for let-bound iteration variables. |
| 2800 BlockState for_state(&scope_state_); | 2805 BlockState for_state(&scope_state_); |
| 2801 Expect(Token::FOR, CHECK_OK); | 2806 Expect(Token::FOR, CHECK_OK); |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3129 loop->Initialize(NULL, cond, next, body); | 3134 loop->Initialize(NULL, cond, next, body); |
| 3130 result = block; | 3135 result = block; |
| 3131 } else { | 3136 } else { |
| 3132 loop->Initialize(init, cond, next, body); | 3137 loop->Initialize(init, cond, next, body); |
| 3133 result = loop; | 3138 result = loop; |
| 3134 } | 3139 } |
| 3135 } | 3140 } |
| 3136 return result; | 3141 return result; |
| 3137 } | 3142 } |
| 3138 | 3143 |
| 3139 | |
| 3140 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { | |
| 3141 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser | |
| 3142 // contexts this is used as a statement which invokes the debugger as i a | |
| 3143 // break point is present. | |
| 3144 // DebuggerStatement :: | |
| 3145 // 'debugger' ';' | |
| 3146 | |
| 3147 int pos = peek_position(); | |
| 3148 Expect(Token::DEBUGGER, CHECK_OK); | |
| 3149 ExpectSemicolon(CHECK_OK); | |
| 3150 return factory()->NewDebuggerStatement(pos); | |
| 3151 } | |
| 3152 | |
| 3153 | |
| 3154 void Parser::ParseArrowFunctionFormalParameters( | 3144 void Parser::ParseArrowFunctionFormalParameters( |
| 3155 ParserFormalParameters* parameters, Expression* expr, int end_pos, | 3145 ParserFormalParameters* parameters, Expression* expr, int end_pos, |
| 3156 bool* ok) { | 3146 bool* ok) { |
| 3157 // ArrowFunctionFormals :: | 3147 // ArrowFunctionFormals :: |
| 3158 // Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail) | 3148 // Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail) |
| 3159 // Tail | 3149 // Tail |
| 3160 // NonTailArrowFunctionFormals :: | 3150 // NonTailArrowFunctionFormals :: |
| 3161 // Binary(Token::COMMA, NonTailArrowFunctionFormals, VariableProxy) | 3151 // Binary(Token::COMMA, NonTailArrowFunctionFormals, VariableProxy) |
| 3162 // VariableProxy | 3152 // VariableProxy |
| 3163 // Tail :: | 3153 // Tail :: |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3530 CheckFunctionName(language_mode, function_name, function_name_validity, | 3520 CheckFunctionName(language_mode, function_name, function_name_validity, |
| 3531 function_name_location, CHECK_OK); | 3521 function_name_location, CHECK_OK); |
| 3532 const bool allow_duplicate_parameters = | 3522 const bool allow_duplicate_parameters = |
| 3533 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind); | 3523 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind); |
| 3534 ValidateFormalParameters(language_mode, allow_duplicate_parameters, | 3524 ValidateFormalParameters(language_mode, allow_duplicate_parameters, |
| 3535 CHECK_OK); | 3525 CHECK_OK); |
| 3536 | 3526 |
| 3537 if (is_strict(language_mode)) { | 3527 if (is_strict(language_mode)) { |
| 3538 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), | 3528 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), |
| 3539 CHECK_OK); | 3529 CHECK_OK); |
| 3540 CheckDecimalLiteralWithLeadingZero(use_counts_, scope->start_position(), | 3530 CheckDecimalLiteralWithLeadingZero(scope->start_position(), |
| 3541 scope->end_position()); | 3531 scope->end_position()); |
| 3542 } | 3532 } |
| 3543 CheckConflictingVarDeclarations(scope, CHECK_OK); | 3533 CheckConflictingVarDeclarations(scope, CHECK_OK); |
| 3544 | 3534 |
| 3545 if (body) { | 3535 if (body) { |
| 3546 // If body can be inspected, rewrite queued destructuring assignments | 3536 // If body can be inspected, rewrite queued destructuring assignments |
| 3547 RewriteDestructuringAssignments(); | 3537 RewriteDestructuringAssignments(); |
| 3548 } | 3538 } |
| 3549 has_duplicate_parameters = | 3539 has_duplicate_parameters = |
| 3550 !classifier()->is_valid_formal_parameter_list_without_duplicates(); | 3540 !classifier()->is_valid_formal_parameter_list_without_duplicates(); |
| (...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4262 | 4252 |
| 4263 do_block->statements()->Add( | 4253 do_block->statements()->Add( |
| 4264 factory()->NewExpressionStatement(class_literal, pos), zone()); | 4254 factory()->NewExpressionStatement(class_literal, pos), zone()); |
| 4265 do_expr->set_represented_function(constructor); | 4255 do_expr->set_represented_function(constructor); |
| 4266 Rewriter::Rewrite(this, GetClosureScope(), do_expr, ast_value_factory()); | 4256 Rewriter::Rewrite(this, GetClosureScope(), do_expr, ast_value_factory()); |
| 4267 | 4257 |
| 4268 return do_expr; | 4258 return do_expr; |
| 4269 } | 4259 } |
| 4270 | 4260 |
| 4271 | 4261 |
| 4272 Expression* Parser::ParseV8Intrinsic(bool* ok) { | |
| 4273 // CallRuntime :: | |
| 4274 // '%' Identifier Arguments | |
| 4275 | |
| 4276 int pos = peek_position(); | |
| 4277 Expect(Token::MOD, CHECK_OK); | |
| 4278 // Allow "eval" or "arguments" for backward compatibility. | |
| 4279 const AstRawString* name = ParseIdentifier(kAllowRestrictedIdentifiers, | |
| 4280 CHECK_OK); | |
| 4281 Scanner::Location spread_pos; | |
| 4282 ExpressionClassifier classifier(this); | |
| 4283 ZoneList<Expression*>* args = ParseArguments(&spread_pos, CHECK_OK); | |
| 4284 | |
| 4285 DCHECK(!spread_pos.IsValid()); | |
| 4286 | |
| 4287 if (extension_ != NULL) { | |
| 4288 // The extension structures are only accessible while parsing the | |
| 4289 // very first time not when reparsing because of lazy compilation. | |
| 4290 GetClosureScope()->ForceEagerCompilation(); | |
| 4291 } | |
| 4292 | |
| 4293 const Runtime::Function* function = Runtime::FunctionForName(name->string()); | |
| 4294 | |
| 4295 if (function != NULL) { | |
| 4296 // Check for possible name clash. | |
| 4297 DCHECK_EQ(Context::kNotFound, | |
| 4298 Context::IntrinsicIndexForName(name->string())); | |
| 4299 // Check for built-in IS_VAR macro. | |
| 4300 if (function->function_id == Runtime::kIS_VAR) { | |
| 4301 DCHECK_EQ(Runtime::RUNTIME, function->intrinsic_type); | |
| 4302 // %IS_VAR(x) evaluates to x if x is a variable, | |
| 4303 // leads to a parse error otherwise. Could be implemented as an | |
| 4304 // inline function %_IS_VAR(x) to eliminate this special case. | |
| 4305 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) { | |
| 4306 return args->at(0); | |
| 4307 } else { | |
| 4308 ReportMessage(MessageTemplate::kNotIsvar); | |
| 4309 *ok = false; | |
| 4310 return NULL; | |
| 4311 } | |
| 4312 } | |
| 4313 | |
| 4314 // Check that the expected number of arguments are being passed. | |
| 4315 if (function->nargs != -1 && function->nargs != args->length()) { | |
| 4316 ReportMessage(MessageTemplate::kRuntimeWrongNumArgs); | |
| 4317 *ok = false; | |
| 4318 return NULL; | |
| 4319 } | |
| 4320 | |
| 4321 return factory()->NewCallRuntime(function, args, pos); | |
| 4322 } | |
| 4323 | |
| 4324 int context_index = Context::IntrinsicIndexForName(name->string()); | |
| 4325 | |
| 4326 // Check that the function is defined. | |
| 4327 if (context_index == Context::kNotFound) { | |
| 4328 ReportMessage(MessageTemplate::kNotDefined, name); | |
| 4329 *ok = false; | |
| 4330 return NULL; | |
| 4331 } | |
| 4332 | |
| 4333 return factory()->NewCallRuntime(context_index, args, pos); | |
| 4334 } | |
| 4335 | |
| 4336 | |
| 4337 Literal* Parser::GetLiteralUndefined(int position) { | 4262 Literal* Parser::GetLiteralUndefined(int position) { |
| 4338 return factory()->NewUndefinedLiteral(position); | 4263 return factory()->NewUndefinedLiteral(position); |
| 4339 } | 4264 } |
| 4340 | 4265 |
| 4341 | 4266 |
| 4342 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { | 4267 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
| 4343 Declaration* decl = scope->CheckConflictingVarDeclarations(); | 4268 Declaration* decl = scope->CheckConflictingVarDeclarations(); |
| 4344 if (decl != NULL) { | 4269 if (decl != NULL) { |
| 4345 // In ES6, conflicting variable bindings are early errors. | 4270 // In ES6, conflicting variable bindings are early errors. |
| 4346 const AstRawString* name = decl->proxy()->raw_name(); | 4271 const AstRawString* name = decl->proxy()->raw_name(); |
| (...skipping 1735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6082 node->Print(Isolate::Current()); | 6007 node->Print(Isolate::Current()); |
| 6083 } | 6008 } |
| 6084 #endif // DEBUG | 6009 #endif // DEBUG |
| 6085 | 6010 |
| 6086 #undef CHECK_OK | 6011 #undef CHECK_OK |
| 6087 #undef CHECK_OK_VOID | 6012 #undef CHECK_OK_VOID |
| 6088 #undef CHECK_FAILED | 6013 #undef CHECK_FAILED |
| 6089 | 6014 |
| 6090 } // namespace internal | 6015 } // namespace internal |
| 6091 } // namespace v8 | 6016 } // namespace v8 |
| OLD | NEW |