| 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 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 // This turns a super call `super()` into a do expression of the form | 185 // This turns a super call `super()` into a do expression of the form |
| 186 // do { | 186 // do { |
| 187 // tmp x = super(); | 187 // tmp x = super(); |
| 188 // if (.class-field-init) | 188 // if (.class-field-init) |
| 189 // .class-field-init(x) | 189 // .class-field-init(x) |
| 190 // x; // This isn't actually present; our do-expression representation | 190 // x; // This isn't actually present; our do-expression representation |
| 191 // allows specifying that the expression returns x directly. | 191 // allows specifying that the expression returns x directly. |
| 192 // } | 192 // } |
| 193 Variable* var_tmp = | 193 Variable* var_tmp = |
| 194 scope()->NewTemporary(ast_value_factory()->empty_string()); | 194 scope()->NewTemporary(ast_value_factory()->empty_string()); |
| 195 Block* block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); | 195 Block* block = factory()->NewBlock(nullptr, false, kNoSourcePosition); |
| 196 Assignment* assignment = factory()->NewAssignment( | 196 Assignment* assignment = factory()->NewAssignment( |
| 197 Token::ASSIGN, factory()->NewVariableProxy(var_tmp), super_call, | 197 Token::ASSIGN, factory()->NewVariableProxy(var_tmp), super_call, |
| 198 kNoSourcePosition); | 198 kNoSourcePosition); |
| 199 block->statements()->Add( | 199 block->statements()->push_back( |
| 200 factory()->NewExpressionStatement(assignment, kNoSourcePosition), zone()); | 200 factory()->NewExpressionStatement(assignment, kNoSourcePosition)); |
| 201 const AstRawString* init_fn_name = | 201 const AstRawString* init_fn_name = |
| 202 ast_value_factory()->dot_class_field_init_string(); | 202 ast_value_factory()->dot_class_field_init_string(); |
| 203 VariableProxy* init_fn_proxy = | 203 VariableProxy* init_fn_proxy = |
| 204 scope()->NewUnresolved(factory(), init_fn_name); | 204 scope()->NewUnresolved(factory(), init_fn_name); |
| 205 Expression* condition = init_fn_proxy; | 205 Expression* condition = init_fn_proxy; |
| 206 Statement* initialize = factory()->NewExpressionStatement( | 206 Statement* initialize = factory()->NewExpressionStatement( |
| 207 CallClassFieldInitializer(scope(), factory()->NewVariableProxy(var_tmp)), | 207 CallClassFieldInitializer(scope(), factory()->NewVariableProxy(var_tmp)), |
| 208 kNoSourcePosition); | 208 kNoSourcePosition); |
| 209 IfStatement* if_statement = factory()->NewIfStatement( | 209 IfStatement* if_statement = factory()->NewIfStatement( |
| 210 condition, initialize, factory()->NewEmptyStatement(kNoSourcePosition), | 210 condition, initialize, factory()->NewEmptyStatement(kNoSourcePosition), |
| 211 kNoSourcePosition); | 211 kNoSourcePosition); |
| 212 block->statements()->Add(if_statement, zone()); | 212 block->statements()->push_back(if_statement); |
| 213 return factory()->NewDoExpression(block, var_tmp, kNoSourcePosition); | 213 return factory()->NewDoExpression(block, var_tmp, kNoSourcePosition); |
| 214 } | 214 } |
| 215 | 215 |
| 216 FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name, | 216 FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name, |
| 217 bool call_super, | 217 bool call_super, |
| 218 bool requires_class_field_init, | 218 bool requires_class_field_init, |
| 219 int pos, int end_pos, | 219 int pos, int end_pos, |
| 220 LanguageMode language_mode) { | 220 LanguageMode language_mode) { |
| 221 int materialized_literal_count = -1; | 221 int materialized_literal_count = -1; |
| 222 int expected_property_count = -1; | 222 int expected_property_count = -1; |
| 223 const int parameter_count = 0; | 223 const int parameter_count = 0; |
| 224 if (name == nullptr) name = ast_value_factory()->empty_string(); | 224 if (name == nullptr) name = ast_value_factory()->empty_string(); |
| 225 | 225 |
| 226 FunctionKind kind = call_super ? FunctionKind::kDefaultSubclassConstructor | 226 FunctionKind kind = call_super ? FunctionKind::kDefaultSubclassConstructor |
| 227 : FunctionKind::kDefaultBaseConstructor; | 227 : FunctionKind::kDefaultBaseConstructor; |
| 228 DeclarationScope* function_scope = NewFunctionScope(kind); | 228 DeclarationScope* function_scope = NewFunctionScope(kind); |
| 229 SetLanguageMode(function_scope, | 229 SetLanguageMode(function_scope, |
| 230 static_cast<LanguageMode>(language_mode | STRICT)); | 230 static_cast<LanguageMode>(language_mode | STRICT)); |
| 231 // Set start and end position to the same value | 231 // Set start and end position to the same value |
| 232 function_scope->set_start_position(pos); | 232 function_scope->set_start_position(pos); |
| 233 function_scope->set_end_position(pos); | 233 function_scope->set_end_position(pos); |
| 234 ZoneList<Statement*>* body = NULL; | 234 ZoneChunkList<Statement*>* body = NULL; |
| 235 | 235 |
| 236 { | 236 { |
| 237 FunctionState function_state(&function_state_, &scope_state_, | 237 FunctionState function_state(&function_state_, &scope_state_, |
| 238 function_scope); | 238 function_scope); |
| 239 | 239 |
| 240 body = new (zone()) ZoneList<Statement*>(call_super ? 2 : 1, zone()); | 240 body = new (zone()) ZoneChunkList<Statement*>(zone()); |
| 241 if (call_super) { | 241 if (call_super) { |
| 242 // $super_constructor = %_GetSuperConstructor(<this-function>) | 242 // $super_constructor = %_GetSuperConstructor(<this-function>) |
| 243 // %reflect_construct( | 243 // %reflect_construct( |
| 244 // $super_constructor, InternalArray(...args), new.target) | 244 // $super_constructor, InternalArray(...args), new.target) |
| 245 auto constructor_args_name = ast_value_factory()->empty_string(); | 245 auto constructor_args_name = ast_value_factory()->empty_string(); |
| 246 bool is_duplicate; | 246 bool is_duplicate; |
| 247 bool is_rest = true; | 247 bool is_rest = true; |
| 248 bool is_optional = false; | 248 bool is_optional = false; |
| 249 Variable* constructor_args = function_scope->DeclareParameter( | 249 Variable* constructor_args = function_scope->DeclareParameter( |
| 250 constructor_args_name, TEMPORARY, is_optional, is_rest, &is_duplicate, | 250 constructor_args_name, TEMPORARY, is_optional, is_rest, &is_duplicate, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 267 spread_args_expr->Add(spread_args, zone()); | 267 spread_args_expr->Add(spread_args, zone()); |
| 268 args->AddAll(*PrepareSpreadArguments(spread_args_expr), zone()); | 268 args->AddAll(*PrepareSpreadArguments(spread_args_expr), zone()); |
| 269 VariableProxy* new_target_proxy = | 269 VariableProxy* new_target_proxy = |
| 270 NewUnresolved(ast_value_factory()->new_target_string(), pos); | 270 NewUnresolved(ast_value_factory()->new_target_string(), pos); |
| 271 args->Add(new_target_proxy, zone()); | 271 args->Add(new_target_proxy, zone()); |
| 272 Expression* call = factory()->NewCallRuntime( | 272 Expression* call = factory()->NewCallRuntime( |
| 273 Context::REFLECT_CONSTRUCT_INDEX, args, pos); | 273 Context::REFLECT_CONSTRUCT_INDEX, args, pos); |
| 274 if (requires_class_field_init) { | 274 if (requires_class_field_init) { |
| 275 call = CallClassFieldInitializer(scope(), call); | 275 call = CallClassFieldInitializer(scope(), call); |
| 276 } | 276 } |
| 277 body->Add(factory()->NewReturnStatement(call, pos), zone()); | 277 body->push_back(factory()->NewReturnStatement(call, pos)); |
| 278 } | 278 } |
| 279 | 279 |
| 280 materialized_literal_count = function_state.materialized_literal_count(); | 280 materialized_literal_count = function_state.materialized_literal_count(); |
| 281 expected_property_count = function_state.expected_property_count(); | 281 expected_property_count = function_state.expected_property_count(); |
| 282 } | 282 } |
| 283 | 283 |
| 284 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( | 284 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( |
| 285 name, function_scope, body, materialized_literal_count, | 285 name, function_scope, body, materialized_literal_count, |
| 286 expected_property_count, parameter_count, parameter_count, | 286 expected_property_count, parameter_count, parameter_count, |
| 287 FunctionLiteral::kNoDuplicateParameters, | 287 FunctionLiteral::kNoDuplicateParameters, |
| (...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 749 DCHECK_EQ(outer, info->script_scope()); | 749 DCHECK_EQ(outer, info->script_scope()); |
| 750 outer = NewModuleScope(info->script_scope()); | 750 outer = NewModuleScope(info->script_scope()); |
| 751 } | 751 } |
| 752 | 752 |
| 753 DeclarationScope* scope = outer->AsDeclarationScope(); | 753 DeclarationScope* scope = outer->AsDeclarationScope(); |
| 754 | 754 |
| 755 scope->set_start_position(0); | 755 scope->set_start_position(0); |
| 756 | 756 |
| 757 FunctionState function_state(&function_state_, &scope_state_, scope); | 757 FunctionState function_state(&function_state_, &scope_state_, scope); |
| 758 | 758 |
| 759 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); | 759 ZoneChunkList<Statement*>* body = |
| 760 new (zone()) ZoneChunkList<Statement*>(zone()); |
| 760 bool ok = true; | 761 bool ok = true; |
| 761 int beg_pos = scanner()->location().beg_pos; | 762 int beg_pos = scanner()->location().beg_pos; |
| 762 if (parsing_module_) { | 763 if (parsing_module_) { |
| 763 // Declare the special module parameter. | 764 // Declare the special module parameter. |
| 764 auto name = ast_value_factory()->empty_string(); | 765 auto name = ast_value_factory()->empty_string(); |
| 765 bool is_duplicate; | 766 bool is_duplicate; |
| 766 bool is_rest = false; | 767 bool is_rest = false; |
| 767 bool is_optional = false; | 768 bool is_optional = false; |
| 768 auto var = scope->DeclareParameter(name, VAR, is_optional, is_rest, | 769 auto var = scope->DeclareParameter(name, VAR, is_optional, is_rest, |
| 769 &is_duplicate, ast_value_factory()); | 770 &is_duplicate, ast_value_factory()); |
| 770 DCHECK(!is_duplicate); | 771 DCHECK(!is_duplicate); |
| 771 var->AllocateTo(VariableLocation::PARAMETER, 0); | 772 var->AllocateTo(VariableLocation::PARAMETER, 0); |
| 772 | 773 |
| 773 PrepareGeneratorVariables(&function_state); | 774 PrepareGeneratorVariables(&function_state); |
| 774 Expression* initial_yield = | 775 Expression* initial_yield = |
| 775 BuildInitialYield(kNoSourcePosition, kGeneratorFunction); | 776 BuildInitialYield(kNoSourcePosition, kGeneratorFunction); |
| 776 body->Add( | 777 body->push_back( |
| 777 factory()->NewExpressionStatement(initial_yield, kNoSourcePosition), | 778 factory()->NewExpressionStatement(initial_yield, kNoSourcePosition)); |
| 778 zone()); | |
| 779 | 779 |
| 780 ParseModuleItemList(body, &ok); | 780 ParseModuleItemList(body, &ok); |
| 781 ok = ok && | 781 ok = ok && |
| 782 module()->Validate(this->scope()->AsModuleScope(), | 782 module()->Validate(this->scope()->AsModuleScope(), |
| 783 &pending_error_handler_, zone()); | 783 &pending_error_handler_, zone()); |
| 784 } else { | 784 } else { |
| 785 // Don't count the mode in the use counters--give the program a chance | 785 // Don't count the mode in the use counters--give the program a chance |
| 786 // to enable script-wide strict mode below. | 786 // to enable script-wide strict mode below. |
| 787 this->scope()->SetLanguageMode(info->language_mode()); | 787 this->scope()->SetLanguageMode(info->language_mode()); |
| 788 ParseStatementList(body, Token::EOS, &ok); | 788 ParseStatementList(body, Token::EOS, &ok); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 802 // pre-existing bindings should be made writable, enumerable and | 802 // pre-existing bindings should be made writable, enumerable and |
| 803 // nonconfigurable if possible, whereas this code will leave attributes | 803 // nonconfigurable if possible, whereas this code will leave attributes |
| 804 // unchanged if the property already exists. | 804 // unchanged if the property already exists. |
| 805 InsertSloppyBlockFunctionVarBindings(scope); | 805 InsertSloppyBlockFunctionVarBindings(scope); |
| 806 } | 806 } |
| 807 if (ok) { | 807 if (ok) { |
| 808 CheckConflictingVarDeclarations(scope, &ok); | 808 CheckConflictingVarDeclarations(scope, &ok); |
| 809 } | 809 } |
| 810 | 810 |
| 811 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { | 811 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { |
| 812 if (body->length() != 1 || | 812 if (body->size() != 1 || !body->front()->IsExpressionStatement() || |
| 813 !body->at(0)->IsExpressionStatement() || | 813 !body->front() |
| 814 !body->at(0)->AsExpressionStatement()-> | 814 ->AsExpressionStatement() |
| 815 expression()->IsFunctionLiteral()) { | 815 ->expression() |
| 816 ->IsFunctionLiteral()) { |
| 816 ReportMessage(MessageTemplate::kSingleFunctionLiteral); | 817 ReportMessage(MessageTemplate::kSingleFunctionLiteral); |
| 817 ok = false; | 818 ok = false; |
| 818 } | 819 } |
| 819 } | 820 } |
| 820 | 821 |
| 821 if (ok) { | 822 if (ok) { |
| 822 RewriteDestructuringAssignments(); | 823 RewriteDestructuringAssignments(); |
| 823 int parameter_count = parsing_module_ ? 1 : 0; | 824 int parameter_count = parsing_module_ ? 1 : 0; |
| 824 result = factory()->NewScriptOrEvalFunctionLiteral( | 825 result = factory()->NewScriptOrEvalFunctionLiteral( |
| 825 scope, body, function_state.materialized_literal_count(), | 826 scope, body, function_state.materialized_literal_count(), |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1029 case Token::IMPORT: | 1030 case Token::IMPORT: |
| 1030 ParseImportDeclaration(CHECK_OK); | 1031 ParseImportDeclaration(CHECK_OK); |
| 1031 return factory()->NewEmptyStatement(kNoSourcePosition); | 1032 return factory()->NewEmptyStatement(kNoSourcePosition); |
| 1032 case Token::EXPORT: | 1033 case Token::EXPORT: |
| 1033 return ParseExportDeclaration(ok); | 1034 return ParseExportDeclaration(ok); |
| 1034 default: | 1035 default: |
| 1035 return ParseStatementListItem(ok); | 1036 return ParseStatementListItem(ok); |
| 1036 } | 1037 } |
| 1037 } | 1038 } |
| 1038 | 1039 |
| 1039 | 1040 void Parser::ParseModuleItemList(ZoneChunkList<Statement*>* body, bool* ok) { |
| 1040 void Parser::ParseModuleItemList(ZoneList<Statement*>* body, bool* ok) { | |
| 1041 // ecma262/#prod-Module | 1041 // ecma262/#prod-Module |
| 1042 // Module : | 1042 // Module : |
| 1043 // ModuleBody? | 1043 // ModuleBody? |
| 1044 // | 1044 // |
| 1045 // ecma262/#prod-ModuleItemList | 1045 // ecma262/#prod-ModuleItemList |
| 1046 // ModuleBody : | 1046 // ModuleBody : |
| 1047 // ModuleItem* | 1047 // ModuleItem* |
| 1048 | 1048 |
| 1049 DCHECK(scope()->is_module_scope()); | 1049 DCHECK(scope()->is_module_scope()); |
| 1050 while (peek() != Token::EOS) { | 1050 while (peek() != Token::EOS) { |
| 1051 Statement* stat = ParseModuleItem(CHECK_OK_VOID); | 1051 Statement* stat = ParseModuleItem(CHECK_OK_VOID); |
| 1052 if (stat && !stat->IsEmpty()) { | 1052 if (stat && !stat->IsEmpty()) { |
| 1053 body->Add(stat, zone()); | 1053 body->push_back(stat); |
| 1054 } | 1054 } |
| 1055 } | 1055 } |
| 1056 } | 1056 } |
| 1057 | 1057 |
| 1058 | 1058 |
| 1059 const AstRawString* Parser::ParseModuleSpecifier(bool* ok) { | 1059 const AstRawString* Parser::ParseModuleSpecifier(bool* ok) { |
| 1060 // ModuleSpecifier : | 1060 // ModuleSpecifier : |
| 1061 // StringLiteral | 1061 // StringLiteral |
| 1062 | 1062 |
| 1063 Expect(Token::STRING, CHECK_OK); | 1063 Expect(Token::STRING, CHECK_OK); |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1513 if (sloppy_mode_block_scope_function_redefinition) { | 1513 if (sloppy_mode_block_scope_function_redefinition) { |
| 1514 ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition]; | 1514 ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition]; |
| 1515 } | 1515 } |
| 1516 return variable; | 1516 return variable; |
| 1517 } | 1517 } |
| 1518 | 1518 |
| 1519 Block* Parser::BuildInitializationBlock( | 1519 Block* Parser::BuildInitializationBlock( |
| 1520 DeclarationParsingResult* parsing_result, | 1520 DeclarationParsingResult* parsing_result, |
| 1521 ZoneList<const AstRawString*>* names, bool* ok) { | 1521 ZoneList<const AstRawString*>* names, bool* ok) { |
| 1522 Block* result = factory()->NewBlock( | 1522 Block* result = factory()->NewBlock( |
| 1523 NULL, 1, true, parsing_result->descriptor.declaration_pos); | 1523 NULL, true, parsing_result->descriptor.declaration_pos); |
| 1524 for (auto declaration : parsing_result->declarations) { | 1524 for (auto declaration : parsing_result->declarations) { |
| 1525 PatternRewriter::DeclareAndInitializeVariables( | 1525 PatternRewriter::DeclareAndInitializeVariables( |
| 1526 this, result, &(parsing_result->descriptor), &declaration, names, | 1526 this, result, &(parsing_result->descriptor), &declaration, names, |
| 1527 CHECK_OK); | 1527 CHECK_OK); |
| 1528 } | 1528 } |
| 1529 return result; | 1529 return result; |
| 1530 } | 1530 } |
| 1531 | 1531 |
| 1532 void Parser::DeclareAndInitializeVariables( | 1532 void Parser::DeclareAndInitializeVariables( |
| 1533 Block* block, const DeclarationDescriptor* declaration_descriptor, | 1533 Block* block, const DeclarationDescriptor* declaration_descriptor, |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1704 // In order to get the CaseClauses to execute in their own lexical scope, | 1704 // In order to get the CaseClauses to execute in their own lexical scope, |
| 1705 // but without requiring downstream code to have special scope handling | 1705 // but without requiring downstream code to have special scope handling |
| 1706 // code for switch statements, desugar into blocks as follows: | 1706 // code for switch statements, desugar into blocks as follows: |
| 1707 // { // To group the statements--harmless to evaluate Expression in scope | 1707 // { // To group the statements--harmless to evaluate Expression in scope |
| 1708 // .tag_variable = Expression; | 1708 // .tag_variable = Expression; |
| 1709 // { // To give CaseClauses a scope | 1709 // { // To give CaseClauses a scope |
| 1710 // switch (.tag_variable) { CaseClause* } | 1710 // switch (.tag_variable) { CaseClause* } |
| 1711 // } | 1711 // } |
| 1712 // } | 1712 // } |
| 1713 | 1713 |
| 1714 Block* switch_block = factory()->NewBlock(NULL, 2, false, kNoSourcePosition); | 1714 Block* switch_block = factory()->NewBlock(NULL, false, kNoSourcePosition); |
| 1715 | 1715 |
| 1716 Variable* tag_variable = | 1716 Variable* tag_variable = |
| 1717 NewTemporary(ast_value_factory()->dot_switch_tag_string()); | 1717 NewTemporary(ast_value_factory()->dot_switch_tag_string()); |
| 1718 Assignment* tag_assign = factory()->NewAssignment( | 1718 Assignment* tag_assign = factory()->NewAssignment( |
| 1719 Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag, | 1719 Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag, |
| 1720 tag->position()); | 1720 tag->position()); |
| 1721 Statement* tag_statement = | 1721 Statement* tag_statement = |
| 1722 factory()->NewExpressionStatement(tag_assign, kNoSourcePosition); | 1722 factory()->NewExpressionStatement(tag_assign, kNoSourcePosition); |
| 1723 switch_block->statements()->Add(tag_statement, zone()); | 1723 switch_block->statements()->push_back(tag_statement); |
| 1724 | 1724 |
| 1725 // make statement: undefined; | 1725 // make statement: undefined; |
| 1726 // This is needed so the tag isn't returned as the value, in case the switch | 1726 // This is needed so the tag isn't returned as the value, in case the switch |
| 1727 // statements don't have a value. | 1727 // statements don't have a value. |
| 1728 switch_block->statements()->Add( | 1728 switch_block->statements()->push_back(factory()->NewExpressionStatement( |
| 1729 factory()->NewExpressionStatement( | 1729 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition)); |
| 1730 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition), | |
| 1731 zone()); | |
| 1732 | 1730 |
| 1733 Expression* tag_read = factory()->NewVariableProxy(tag_variable); | 1731 Expression* tag_read = factory()->NewVariableProxy(tag_variable); |
| 1734 switch_statement->Initialize(tag_read, cases); | 1732 switch_statement->Initialize(tag_read, cases); |
| 1735 Block* cases_block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition); | 1733 Block* cases_block = factory()->NewBlock(NULL, false, kNoSourcePosition); |
| 1736 cases_block->statements()->Add(switch_statement, zone()); | 1734 cases_block->statements()->push_back(switch_statement); |
| 1737 cases_block->set_scope(scope); | 1735 cases_block->set_scope(scope); |
| 1738 switch_block->statements()->Add(cases_block, zone()); | 1736 switch_block->statements()->push_back(cases_block); |
| 1739 return switch_block; | 1737 return switch_block; |
| 1740 } | 1738 } |
| 1741 | 1739 |
| 1742 void Parser::RewriteCatchPattern(CatchInfo* catch_info, bool* ok) { | 1740 void Parser::RewriteCatchPattern(CatchInfo* catch_info, bool* ok) { |
| 1743 if (catch_info->name == nullptr) { | 1741 if (catch_info->name == nullptr) { |
| 1744 DCHECK_NOT_NULL(catch_info->pattern); | 1742 DCHECK_NOT_NULL(catch_info->pattern); |
| 1745 catch_info->name = ast_value_factory()->dot_catch_string(); | 1743 catch_info->name = ast_value_factory()->dot_catch_string(); |
| 1746 } | 1744 } |
| 1747 catch_info->variable = catch_info->scope->DeclareLocal( | 1745 catch_info->variable = catch_info->scope->DeclareLocal( |
| 1748 catch_info->name, VAR, kCreatedInitialized, NORMAL_VARIABLE); | 1746 catch_info->name, VAR, kCreatedInitialized, NORMAL_VARIABLE); |
| 1749 if (catch_info->pattern != nullptr) { | 1747 if (catch_info->pattern != nullptr) { |
| 1750 DeclarationDescriptor descriptor; | 1748 DeclarationDescriptor descriptor; |
| 1751 descriptor.declaration_kind = DeclarationDescriptor::NORMAL; | 1749 descriptor.declaration_kind = DeclarationDescriptor::NORMAL; |
| 1752 descriptor.scope = scope(); | 1750 descriptor.scope = scope(); |
| 1753 descriptor.hoist_scope = nullptr; | 1751 descriptor.hoist_scope = nullptr; |
| 1754 descriptor.mode = LET; | 1752 descriptor.mode = LET; |
| 1755 descriptor.declaration_pos = catch_info->pattern->position(); | 1753 descriptor.declaration_pos = catch_info->pattern->position(); |
| 1756 descriptor.initialization_pos = catch_info->pattern->position(); | 1754 descriptor.initialization_pos = catch_info->pattern->position(); |
| 1757 | 1755 |
| 1758 // Initializer position for variables declared by the pattern. | 1756 // Initializer position for variables declared by the pattern. |
| 1759 const int initializer_position = position(); | 1757 const int initializer_position = position(); |
| 1760 | 1758 |
| 1761 DeclarationParsingResult::Declaration decl( | 1759 DeclarationParsingResult::Declaration decl( |
| 1762 catch_info->pattern, initializer_position, | 1760 catch_info->pattern, initializer_position, |
| 1763 factory()->NewVariableProxy(catch_info->variable)); | 1761 factory()->NewVariableProxy(catch_info->variable)); |
| 1764 | 1762 |
| 1765 catch_info->init_block = | 1763 catch_info->init_block = |
| 1766 factory()->NewBlock(nullptr, 8, true, kNoSourcePosition); | 1764 factory()->NewBlock(nullptr, true, kNoSourcePosition); |
| 1767 PatternRewriter::DeclareAndInitializeVariables( | 1765 PatternRewriter::DeclareAndInitializeVariables( |
| 1768 this, catch_info->init_block, &descriptor, &decl, | 1766 this, catch_info->init_block, &descriptor, &decl, |
| 1769 &catch_info->bound_names, ok); | 1767 &catch_info->bound_names, ok); |
| 1770 } else { | 1768 } else { |
| 1771 catch_info->bound_names.Add(catch_info->name, zone()); | 1769 catch_info->bound_names.Add(catch_info->name, zone()); |
| 1772 } | 1770 } |
| 1773 } | 1771 } |
| 1774 | 1772 |
| 1775 void Parser::ValidateCatchBlock(const CatchInfo& catch_info, bool* ok) { | 1773 void Parser::ValidateCatchBlock(const CatchInfo& catch_info, bool* ok) { |
| 1776 // Check for `catch(e) { let e; }` and similar errors. | 1774 // Check for `catch(e) { let e; }` and similar errors. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1807 if (catch_info.for_promise_reject) { | 1805 if (catch_info.for_promise_reject) { |
| 1808 statement = factory()->NewTryCatchStatementForPromiseReject( | 1806 statement = factory()->NewTryCatchStatementForPromiseReject( |
| 1809 try_block, catch_info.scope, catch_info.variable, catch_block, | 1807 try_block, catch_info.scope, catch_info.variable, catch_block, |
| 1810 kNoSourcePosition); | 1808 kNoSourcePosition); |
| 1811 } else { | 1809 } else { |
| 1812 statement = factory()->NewTryCatchStatement( | 1810 statement = factory()->NewTryCatchStatement( |
| 1813 try_block, catch_info.scope, catch_info.variable, catch_block, | 1811 try_block, catch_info.scope, catch_info.variable, catch_block, |
| 1814 kNoSourcePosition); | 1812 kNoSourcePosition); |
| 1815 } | 1813 } |
| 1816 | 1814 |
| 1817 try_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); | 1815 try_block = factory()->NewBlock(nullptr, false, kNoSourcePosition); |
| 1818 try_block->statements()->Add(statement, zone()); | 1816 try_block->statements()->push_back(statement); |
| 1819 catch_block = nullptr; // Clear to indicate it's been handled. | 1817 catch_block = nullptr; // Clear to indicate it's been handled. |
| 1820 } | 1818 } |
| 1821 | 1819 |
| 1822 if (catch_block != nullptr) { | 1820 if (catch_block != nullptr) { |
| 1823 // For a try-catch construct append return expressions from the catch block | 1821 // For a try-catch construct append return expressions from the catch block |
| 1824 // to the list of return expressions. | 1822 // to the list of return expressions. |
| 1825 function_state_->tail_call_expressions().Append( | 1823 function_state_->tail_call_expressions().Append( |
| 1826 catch_info.tail_call_expressions); | 1824 catch_info.tail_call_expressions); |
| 1827 | 1825 |
| 1828 DCHECK_NULL(finally_block); | 1826 DCHECK_NULL(finally_block); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1884 return InitializeForOfStatement(for_of, each, subject, body, finalize, | 1882 return InitializeForOfStatement(for_of, each, subject, body, finalize, |
| 1885 each_keyword_pos); | 1883 each_keyword_pos); |
| 1886 } else { | 1884 } else { |
| 1887 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { | 1885 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { |
| 1888 Variable* temp = NewTemporary(ast_value_factory()->empty_string()); | 1886 Variable* temp = NewTemporary(ast_value_factory()->empty_string()); |
| 1889 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | 1887 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
| 1890 Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment( | 1888 Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment( |
| 1891 this, factory()->NewAssignment(Token::ASSIGN, each, temp_proxy, | 1889 this, factory()->NewAssignment(Token::ASSIGN, each, temp_proxy, |
| 1892 kNoSourcePosition), | 1890 kNoSourcePosition), |
| 1893 scope()); | 1891 scope()); |
| 1894 auto block = factory()->NewBlock(nullptr, 2, false, kNoSourcePosition); | 1892 auto block = factory()->NewBlock(nullptr, false, kNoSourcePosition); |
| 1895 block->statements()->Add( | 1893 block->statements()->push_back( |
| 1896 factory()->NewExpressionStatement(assign_each, kNoSourcePosition), | 1894 factory()->NewExpressionStatement(assign_each, kNoSourcePosition)); |
| 1897 zone()); | 1895 block->statements()->push_back(body); |
| 1898 block->statements()->Add(body, zone()); | |
| 1899 body = block; | 1896 body = block; |
| 1900 each = factory()->NewVariableProxy(temp); | 1897 each = factory()->NewVariableProxy(temp); |
| 1901 } | 1898 } |
| 1902 stmt->AsForInStatement()->Initialize(each, subject, body); | 1899 stmt->AsForInStatement()->Initialize(each, subject, body); |
| 1903 } | 1900 } |
| 1904 return stmt; | 1901 return stmt; |
| 1905 } | 1902 } |
| 1906 | 1903 |
| 1907 // Special case for legacy for | 1904 // Special case for legacy for |
| 1908 // | 1905 // |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1922 // is added as a second statement to it. | 1919 // is added as a second statement to it. |
| 1923 Block* Parser::RewriteForVarInLegacy(const ForInfo& for_info) { | 1920 Block* Parser::RewriteForVarInLegacy(const ForInfo& for_info) { |
| 1924 const DeclarationParsingResult::Declaration& decl = | 1921 const DeclarationParsingResult::Declaration& decl = |
| 1925 for_info.parsing_result.declarations[0]; | 1922 for_info.parsing_result.declarations[0]; |
| 1926 if (!IsLexicalVariableMode(for_info.parsing_result.descriptor.mode) && | 1923 if (!IsLexicalVariableMode(for_info.parsing_result.descriptor.mode) && |
| 1927 decl.pattern->IsVariableProxy() && decl.initializer != nullptr) { | 1924 decl.pattern->IsVariableProxy() && decl.initializer != nullptr) { |
| 1928 ++use_counts_[v8::Isolate::kForInInitializer]; | 1925 ++use_counts_[v8::Isolate::kForInInitializer]; |
| 1929 const AstRawString* name = decl.pattern->AsVariableProxy()->raw_name(); | 1926 const AstRawString* name = decl.pattern->AsVariableProxy()->raw_name(); |
| 1930 VariableProxy* single_var = NewUnresolved(name); | 1927 VariableProxy* single_var = NewUnresolved(name); |
| 1931 Block* init_block = factory()->NewBlock( | 1928 Block* init_block = factory()->NewBlock( |
| 1932 nullptr, 2, true, for_info.parsing_result.descriptor.declaration_pos); | 1929 nullptr, true, for_info.parsing_result.descriptor.declaration_pos); |
| 1933 init_block->statements()->Add( | 1930 init_block->statements()->push_back(factory()->NewExpressionStatement( |
| 1934 factory()->NewExpressionStatement( | 1931 factory()->NewAssignment(Token::ASSIGN, single_var, decl.initializer, |
| 1935 factory()->NewAssignment(Token::ASSIGN, single_var, | 1932 kNoSourcePosition), |
| 1936 decl.initializer, kNoSourcePosition), | 1933 kNoSourcePosition)); |
| 1937 kNoSourcePosition), | |
| 1938 zone()); | |
| 1939 return init_block; | 1934 return init_block; |
| 1940 } | 1935 } |
| 1941 return nullptr; | 1936 return nullptr; |
| 1942 } | 1937 } |
| 1943 | 1938 |
| 1944 // Rewrite a for-in/of statement of the form | 1939 // Rewrite a for-in/of statement of the form |
| 1945 // | 1940 // |
| 1946 // for (let/const/var x in/of e) b | 1941 // for (let/const/var x in/of e) b |
| 1947 // | 1942 // |
| 1948 // into | 1943 // into |
| 1949 // | 1944 // |
| 1950 // { | 1945 // { |
| 1951 // <let x' be a temporary variable> | 1946 // <let x' be a temporary variable> |
| 1952 // for (x' in/of e) { | 1947 // for (x' in/of e) { |
| 1953 // let/const/var x; | 1948 // let/const/var x; |
| 1954 // x = x'; | 1949 // x = x'; |
| 1955 // b; | 1950 // b; |
| 1956 // } | 1951 // } |
| 1957 // let x; // for TDZ | 1952 // let x; // for TDZ |
| 1958 // } | 1953 // } |
| 1959 void Parser::DesugarBindingInForEachStatement(ForInfo* for_info, | 1954 void Parser::DesugarBindingInForEachStatement(ForInfo* for_info, |
| 1960 Block** body_block, | 1955 Block** body_block, |
| 1961 Expression** each_variable, | 1956 Expression** each_variable, |
| 1962 bool* ok) { | 1957 bool* ok) { |
| 1963 DeclarationParsingResult::Declaration& decl = | 1958 DeclarationParsingResult::Declaration& decl = |
| 1964 for_info->parsing_result.declarations[0]; | 1959 for_info->parsing_result.declarations[0]; |
| 1965 Variable* temp = NewTemporary(ast_value_factory()->dot_for_string()); | 1960 Variable* temp = NewTemporary(ast_value_factory()->dot_for_string()); |
| 1966 auto each_initialization_block = | 1961 auto each_initialization_block = |
| 1967 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); | 1962 factory()->NewBlock(nullptr, true, kNoSourcePosition); |
| 1968 { | 1963 { |
| 1969 auto descriptor = for_info->parsing_result.descriptor; | 1964 auto descriptor = for_info->parsing_result.descriptor; |
| 1970 descriptor.declaration_pos = kNoSourcePosition; | 1965 descriptor.declaration_pos = kNoSourcePosition; |
| 1971 descriptor.initialization_pos = kNoSourcePosition; | 1966 descriptor.initialization_pos = kNoSourcePosition; |
| 1972 decl.initializer = factory()->NewVariableProxy(temp); | 1967 decl.initializer = factory()->NewVariableProxy(temp); |
| 1973 | 1968 |
| 1974 bool is_for_var_of = | 1969 bool is_for_var_of = |
| 1975 for_info->mode == ForEachStatement::ITERATE && | 1970 for_info->mode == ForEachStatement::ITERATE && |
| 1976 for_info->parsing_result.descriptor.mode == VariableMode::VAR; | 1971 for_info->parsing_result.descriptor.mode == VariableMode::VAR; |
| 1977 | 1972 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2002 MessageTemplate::kVarRedeclaration, name); | 1997 MessageTemplate::kVarRedeclaration, name); |
| 2003 *ok = false; | 1998 *ok = false; |
| 2004 return; | 1999 return; |
| 2005 } | 2000 } |
| 2006 } | 2001 } |
| 2007 catch_scope = catch_scope->outer_scope(); | 2002 catch_scope = catch_scope->outer_scope(); |
| 2008 } | 2003 } |
| 2009 } | 2004 } |
| 2010 } | 2005 } |
| 2011 | 2006 |
| 2012 *body_block = factory()->NewBlock(nullptr, 3, false, kNoSourcePosition); | 2007 *body_block = factory()->NewBlock(nullptr, false, kNoSourcePosition); |
| 2013 (*body_block)->statements()->Add(each_initialization_block, zone()); | 2008 (*body_block)->statements()->push_back(each_initialization_block); |
| 2014 *each_variable = factory()->NewVariableProxy(temp, for_info->position); | 2009 *each_variable = factory()->NewVariableProxy(temp, for_info->position); |
| 2015 } | 2010 } |
| 2016 | 2011 |
| 2017 // Create a TDZ for any lexically-bound names in for in/of statements. | 2012 // Create a TDZ for any lexically-bound names in for in/of statements. |
| 2018 Block* Parser::CreateForEachStatementTDZ(Block* init_block, | 2013 Block* Parser::CreateForEachStatementTDZ(Block* init_block, |
| 2019 const ForInfo& for_info, bool* ok) { | 2014 const ForInfo& for_info, bool* ok) { |
| 2020 if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) { | 2015 if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) { |
| 2021 DCHECK_NULL(init_block); | 2016 DCHECK_NULL(init_block); |
| 2022 | 2017 |
| 2023 init_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); | 2018 init_block = factory()->NewBlock(nullptr, false, kNoSourcePosition); |
| 2024 | 2019 |
| 2025 for (int i = 0; i < for_info.bound_names.length(); ++i) { | 2020 for (int i = 0; i < for_info.bound_names.length(); ++i) { |
| 2026 // TODO(adamk): This needs to be some sort of special | 2021 // TODO(adamk): This needs to be some sort of special |
| 2027 // INTERNAL variable that's invisible to the debugger | 2022 // INTERNAL variable that's invisible to the debugger |
| 2028 // but visible to everything else. | 2023 // but visible to everything else. |
| 2029 Declaration* tdz_decl = DeclareVariable(for_info.bound_names[i], LET, | 2024 Declaration* tdz_decl = DeclareVariable(for_info.bound_names[i], LET, |
| 2030 kNoSourcePosition, CHECK_OK); | 2025 kNoSourcePosition, CHECK_OK); |
| 2031 tdz_decl->proxy()->var()->set_initializer_position(position()); | 2026 tdz_decl->proxy()->var()->set_initializer_position(position()); |
| 2032 } | 2027 } |
| 2033 } | 2028 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2089 } | 2084 } |
| 2090 | 2085 |
| 2091 // {{completion = kAbruptCompletion;}} | 2086 // {{completion = kAbruptCompletion;}} |
| 2092 Statement* set_completion_abrupt; | 2087 Statement* set_completion_abrupt; |
| 2093 if (finalize) { | 2088 if (finalize) { |
| 2094 Expression* proxy = factory()->NewVariableProxy(completion); | 2089 Expression* proxy = factory()->NewVariableProxy(completion); |
| 2095 Expression* assignment = factory()->NewAssignment( | 2090 Expression* assignment = factory()->NewAssignment( |
| 2096 Token::ASSIGN, proxy, | 2091 Token::ASSIGN, proxy, |
| 2097 factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos); | 2092 factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos); |
| 2098 | 2093 |
| 2099 Block* block = factory()->NewBlock(nullptr, 1, true, nopos); | 2094 Block* block = factory()->NewBlock(nullptr, true, nopos); |
| 2100 block->statements()->Add( | 2095 block->statements()->push_back( |
| 2101 factory()->NewExpressionStatement(assignment, nopos), zone()); | 2096 factory()->NewExpressionStatement(assignment, nopos)); |
| 2102 set_completion_abrupt = block; | 2097 set_completion_abrupt = block; |
| 2103 } | 2098 } |
| 2104 | 2099 |
| 2105 // do { let tmp = #result_value; #set_completion_abrupt; tmp } | 2100 // do { let tmp = #result_value; #set_completion_abrupt; tmp } |
| 2106 // Expression* result_value (gets overwritten) | 2101 // Expression* result_value (gets overwritten) |
| 2107 if (finalize) { | 2102 if (finalize) { |
| 2108 Variable* var_tmp = NewTemporary(avfactory->empty_string()); | 2103 Variable* var_tmp = NewTemporary(avfactory->empty_string()); |
| 2109 Expression* tmp = factory()->NewVariableProxy(var_tmp); | 2104 Expression* tmp = factory()->NewVariableProxy(var_tmp); |
| 2110 Expression* assignment = | 2105 Expression* assignment = |
| 2111 factory()->NewAssignment(Token::ASSIGN, tmp, result_value, nopos); | 2106 factory()->NewAssignment(Token::ASSIGN, tmp, result_value, nopos); |
| 2112 | 2107 |
| 2113 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); | 2108 Block* block = factory()->NewBlock(nullptr, false, nopos); |
| 2114 block->statements()->Add( | 2109 block->statements()->push_back( |
| 2115 factory()->NewExpressionStatement(assignment, nopos), zone()); | 2110 factory()->NewExpressionStatement(assignment, nopos)); |
| 2116 block->statements()->Add(set_completion_abrupt, zone()); | 2111 block->statements()->push_back(set_completion_abrupt); |
| 2117 | 2112 |
| 2118 result_value = factory()->NewDoExpression(block, var_tmp, nopos); | 2113 result_value = factory()->NewDoExpression(block, var_tmp, nopos); |
| 2119 } | 2114 } |
| 2120 | 2115 |
| 2121 // each = #result_value; | 2116 // each = #result_value; |
| 2122 Expression* assign_each; | 2117 Expression* assign_each; |
| 2123 { | 2118 { |
| 2124 assign_each = | 2119 assign_each = |
| 2125 factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos); | 2120 factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos); |
| 2126 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { | 2121 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { |
| 2127 assign_each = PatternRewriter::RewriteDestructuringAssignment( | 2122 assign_each = PatternRewriter::RewriteDestructuringAssignment( |
| 2128 this, assign_each->AsAssignment(), scope()); | 2123 this, assign_each->AsAssignment(), scope()); |
| 2129 } | 2124 } |
| 2130 } | 2125 } |
| 2131 | 2126 |
| 2132 // {{completion = kNormalCompletion;}} | 2127 // {{completion = kNormalCompletion;}} |
| 2133 Statement* set_completion_normal; | 2128 Statement* set_completion_normal; |
| 2134 if (finalize) { | 2129 if (finalize) { |
| 2135 Expression* proxy = factory()->NewVariableProxy(completion); | 2130 Expression* proxy = factory()->NewVariableProxy(completion); |
| 2136 Expression* assignment = factory()->NewAssignment( | 2131 Expression* assignment = factory()->NewAssignment( |
| 2137 Token::ASSIGN, proxy, | 2132 Token::ASSIGN, proxy, |
| 2138 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); | 2133 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); |
| 2139 | 2134 |
| 2140 Block* block = factory()->NewBlock(nullptr, 1, true, nopos); | 2135 Block* block = factory()->NewBlock(nullptr, true, nopos); |
| 2141 block->statements()->Add( | 2136 block->statements()->push_back( |
| 2142 factory()->NewExpressionStatement(assignment, nopos), zone()); | 2137 factory()->NewExpressionStatement(assignment, nopos)); |
| 2143 set_completion_normal = block; | 2138 set_completion_normal = block; |
| 2144 } | 2139 } |
| 2145 | 2140 |
| 2146 // { #loop-body; #set_completion_normal } | 2141 // { #loop-body; #set_completion_normal } |
| 2147 // Statement* body (gets overwritten) | 2142 // Statement* body (gets overwritten) |
| 2148 if (finalize) { | 2143 if (finalize) { |
| 2149 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); | 2144 Block* block = factory()->NewBlock(nullptr, false, nopos); |
| 2150 block->statements()->Add(body, zone()); | 2145 block->statements()->push_back(body); |
| 2151 block->statements()->Add(set_completion_normal, zone()); | 2146 block->statements()->push_back(set_completion_normal); |
| 2152 body = block; | 2147 body = block; |
| 2153 } | 2148 } |
| 2154 | 2149 |
| 2155 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, | 2150 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, |
| 2156 assign_each); | 2151 assign_each); |
| 2157 return finalize ? FinalizeForOfStatement(for_of, completion, nopos) : for_of; | 2152 return finalize ? FinalizeForOfStatement(for_of, completion, nopos) : for_of; |
| 2158 } | 2153 } |
| 2159 | 2154 |
| 2160 Statement* Parser::DesugarLexicalBindingsInForStatement( | 2155 Statement* Parser::DesugarLexicalBindingsInForStatement( |
| 2161 ForStatement* loop, Statement* init, Expression* cond, Statement* next, | 2156 ForStatement* loop, Statement* init, Expression* cond, Statement* next, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2193 // } | 2188 // } |
| 2194 // {{ if (flag == 1) // Body used break. | 2189 // {{ if (flag == 1) // Body used break. |
| 2195 // break; | 2190 // break; |
| 2196 // }} | 2191 // }} |
| 2197 // } | 2192 // } |
| 2198 // } | 2193 // } |
| 2199 | 2194 |
| 2200 DCHECK(for_info.bound_names.length() > 0); | 2195 DCHECK(for_info.bound_names.length() > 0); |
| 2201 ZoneList<Variable*> temps(for_info.bound_names.length(), zone()); | 2196 ZoneList<Variable*> temps(for_info.bound_names.length(), zone()); |
| 2202 | 2197 |
| 2203 Block* outer_block = factory()->NewBlock( | 2198 Block* outer_block = factory()->NewBlock(nullptr, false, kNoSourcePosition); |
| 2204 nullptr, for_info.bound_names.length() + 4, false, kNoSourcePosition); | |
| 2205 | 2199 |
| 2206 // Add statement: let/const x = i. | 2200 // Add statement: let/const x = i. |
| 2207 outer_block->statements()->Add(init, zone()); | 2201 outer_block->statements()->push_back(init); |
| 2208 | 2202 |
| 2209 const AstRawString* temp_name = ast_value_factory()->dot_for_string(); | 2203 const AstRawString* temp_name = ast_value_factory()->dot_for_string(); |
| 2210 | 2204 |
| 2211 // For each lexical variable x: | 2205 // For each lexical variable x: |
| 2212 // make statement: temp_x = x. | 2206 // make statement: temp_x = x. |
| 2213 for (int i = 0; i < for_info.bound_names.length(); i++) { | 2207 for (int i = 0; i < for_info.bound_names.length(); i++) { |
| 2214 VariableProxy* proxy = NewUnresolved(for_info.bound_names[i]); | 2208 VariableProxy* proxy = NewUnresolved(for_info.bound_names[i]); |
| 2215 Variable* temp = NewTemporary(temp_name); | 2209 Variable* temp = NewTemporary(temp_name); |
| 2216 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | 2210 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
| 2217 Assignment* assignment = factory()->NewAssignment(Token::ASSIGN, temp_proxy, | 2211 Assignment* assignment = factory()->NewAssignment(Token::ASSIGN, temp_proxy, |
| 2218 proxy, kNoSourcePosition); | 2212 proxy, kNoSourcePosition); |
| 2219 Statement* assignment_statement = | 2213 Statement* assignment_statement = |
| 2220 factory()->NewExpressionStatement(assignment, kNoSourcePosition); | 2214 factory()->NewExpressionStatement(assignment, kNoSourcePosition); |
| 2221 outer_block->statements()->Add(assignment_statement, zone()); | 2215 outer_block->statements()->push_back(assignment_statement); |
| 2222 temps.Add(temp, zone()); | 2216 temps.Add(temp, zone()); |
| 2223 } | 2217 } |
| 2224 | 2218 |
| 2225 Variable* first = NULL; | 2219 Variable* first = NULL; |
| 2226 // Make statement: first = 1. | 2220 // Make statement: first = 1. |
| 2227 if (next) { | 2221 if (next) { |
| 2228 first = NewTemporary(temp_name); | 2222 first = NewTemporary(temp_name); |
| 2229 VariableProxy* first_proxy = factory()->NewVariableProxy(first); | 2223 VariableProxy* first_proxy = factory()->NewVariableProxy(first); |
| 2230 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition); | 2224 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition); |
| 2231 Assignment* assignment = factory()->NewAssignment( | 2225 Assignment* assignment = factory()->NewAssignment( |
| 2232 Token::ASSIGN, first_proxy, const1, kNoSourcePosition); | 2226 Token::ASSIGN, first_proxy, const1, kNoSourcePosition); |
| 2233 Statement* assignment_statement = | 2227 Statement* assignment_statement = |
| 2234 factory()->NewExpressionStatement(assignment, kNoSourcePosition); | 2228 factory()->NewExpressionStatement(assignment, kNoSourcePosition); |
| 2235 outer_block->statements()->Add(assignment_statement, zone()); | 2229 outer_block->statements()->push_back(assignment_statement); |
| 2236 } | 2230 } |
| 2237 | 2231 |
| 2238 // make statement: undefined; | 2232 // make statement: undefined; |
| 2239 outer_block->statements()->Add( | 2233 outer_block->statements()->push_back(factory()->NewExpressionStatement( |
| 2240 factory()->NewExpressionStatement( | 2234 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition)); |
| 2241 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition), | |
| 2242 zone()); | |
| 2243 | 2235 |
| 2244 // Make statement: outer: for (;;) | 2236 // Make statement: outer: for (;;) |
| 2245 // Note that we don't actually create the label, or set this loop up as an | 2237 // Note that we don't actually create the label, or set this loop up as an |
| 2246 // explicit break target, instead handing it directly to those nodes that | 2238 // explicit break target, instead handing it directly to those nodes that |
| 2247 // need to know about it. This should be safe because we don't run any code | 2239 // need to know about it. This should be safe because we don't run any code |
| 2248 // in this function that looks up break targets. | 2240 // in this function that looks up break targets. |
| 2249 ForStatement* outer_loop = | 2241 ForStatement* outer_loop = |
| 2250 factory()->NewForStatement(NULL, kNoSourcePosition); | 2242 factory()->NewForStatement(NULL, kNoSourcePosition); |
| 2251 outer_block->statements()->Add(outer_loop, zone()); | 2243 outer_block->statements()->push_back(outer_loop); |
| 2252 outer_block->set_scope(scope()); | 2244 outer_block->set_scope(scope()); |
| 2253 | 2245 |
| 2254 Block* inner_block = factory()->NewBlock(NULL, 3, false, kNoSourcePosition); | 2246 Block* inner_block = factory()->NewBlock(NULL, false, kNoSourcePosition); |
| 2255 { | 2247 { |
| 2256 BlockState block_state(&scope_state_, inner_scope); | 2248 BlockState block_state(&scope_state_, inner_scope); |
| 2257 | 2249 |
| 2258 Block* ignore_completion_block = factory()->NewBlock( | 2250 Block* ignore_completion_block = |
| 2259 nullptr, for_info.bound_names.length() + 3, true, kNoSourcePosition); | 2251 factory()->NewBlock(nullptr, true, kNoSourcePosition); |
| 2260 ZoneList<Variable*> inner_vars(for_info.bound_names.length(), zone()); | 2252 ZoneList<Variable*> inner_vars(for_info.bound_names.length(), zone()); |
| 2261 // For each let variable x: | 2253 // For each let variable x: |
| 2262 // make statement: let/const x = temp_x. | 2254 // make statement: let/const x = temp_x. |
| 2263 for (int i = 0; i < for_info.bound_names.length(); i++) { | 2255 for (int i = 0; i < for_info.bound_names.length(); i++) { |
| 2264 Declaration* decl = DeclareVariable( | 2256 Declaration* decl = DeclareVariable( |
| 2265 for_info.bound_names[i], for_info.parsing_result.descriptor.mode, | 2257 for_info.bound_names[i], for_info.parsing_result.descriptor.mode, |
| 2266 kNoSourcePosition, CHECK_OK); | 2258 kNoSourcePosition, CHECK_OK); |
| 2267 inner_vars.Add(decl->proxy()->var(), zone()); | 2259 inner_vars.Add(decl->proxy()->var(), zone()); |
| 2268 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); | 2260 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); |
| 2269 Assignment* assignment = factory()->NewAssignment( | 2261 Assignment* assignment = factory()->NewAssignment( |
| 2270 Token::INIT, decl->proxy(), temp_proxy, kNoSourcePosition); | 2262 Token::INIT, decl->proxy(), temp_proxy, kNoSourcePosition); |
| 2271 Statement* assignment_statement = | 2263 Statement* assignment_statement = |
| 2272 factory()->NewExpressionStatement(assignment, kNoSourcePosition); | 2264 factory()->NewExpressionStatement(assignment, kNoSourcePosition); |
| 2273 DCHECK(init->position() != kNoSourcePosition); | 2265 DCHECK(init->position() != kNoSourcePosition); |
| 2274 decl->proxy()->var()->set_initializer_position(init->position()); | 2266 decl->proxy()->var()->set_initializer_position(init->position()); |
| 2275 ignore_completion_block->statements()->Add(assignment_statement, zone()); | 2267 ignore_completion_block->statements()->push_back(assignment_statement); |
| 2276 } | 2268 } |
| 2277 | 2269 |
| 2278 // Make statement: if (first == 1) { first = 0; } else { next; } | 2270 // Make statement: if (first == 1) { first = 0; } else { next; } |
| 2279 if (next) { | 2271 if (next) { |
| 2280 DCHECK(first); | 2272 DCHECK(first); |
| 2281 Expression* compare = NULL; | 2273 Expression* compare = NULL; |
| 2282 // Make compare expression: first == 1. | 2274 // Make compare expression: first == 1. |
| 2283 { | 2275 { |
| 2284 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition); | 2276 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition); |
| 2285 VariableProxy* first_proxy = factory()->NewVariableProxy(first); | 2277 VariableProxy* first_proxy = factory()->NewVariableProxy(first); |
| 2286 compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1, | 2278 compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1, |
| 2287 kNoSourcePosition); | 2279 kNoSourcePosition); |
| 2288 } | 2280 } |
| 2289 Statement* clear_first = NULL; | 2281 Statement* clear_first = NULL; |
| 2290 // Make statement: first = 0. | 2282 // Make statement: first = 0. |
| 2291 { | 2283 { |
| 2292 VariableProxy* first_proxy = factory()->NewVariableProxy(first); | 2284 VariableProxy* first_proxy = factory()->NewVariableProxy(first); |
| 2293 Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition); | 2285 Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition); |
| 2294 Assignment* assignment = factory()->NewAssignment( | 2286 Assignment* assignment = factory()->NewAssignment( |
| 2295 Token::ASSIGN, first_proxy, const0, kNoSourcePosition); | 2287 Token::ASSIGN, first_proxy, const0, kNoSourcePosition); |
| 2296 clear_first = | 2288 clear_first = |
| 2297 factory()->NewExpressionStatement(assignment, kNoSourcePosition); | 2289 factory()->NewExpressionStatement(assignment, kNoSourcePosition); |
| 2298 } | 2290 } |
| 2299 Statement* clear_first_or_next = factory()->NewIfStatement( | 2291 Statement* clear_first_or_next = factory()->NewIfStatement( |
| 2300 compare, clear_first, next, kNoSourcePosition); | 2292 compare, clear_first, next, kNoSourcePosition); |
| 2301 ignore_completion_block->statements()->Add(clear_first_or_next, zone()); | 2293 ignore_completion_block->statements()->push_back(clear_first_or_next); |
| 2302 } | 2294 } |
| 2303 | 2295 |
| 2304 Variable* flag = NewTemporary(temp_name); | 2296 Variable* flag = NewTemporary(temp_name); |
| 2305 // Make statement: flag = 1. | 2297 // Make statement: flag = 1. |
| 2306 { | 2298 { |
| 2307 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); | 2299 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); |
| 2308 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition); | 2300 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition); |
| 2309 Assignment* assignment = factory()->NewAssignment( | 2301 Assignment* assignment = factory()->NewAssignment( |
| 2310 Token::ASSIGN, flag_proxy, const1, kNoSourcePosition); | 2302 Token::ASSIGN, flag_proxy, const1, kNoSourcePosition); |
| 2311 Statement* assignment_statement = | 2303 Statement* assignment_statement = |
| 2312 factory()->NewExpressionStatement(assignment, kNoSourcePosition); | 2304 factory()->NewExpressionStatement(assignment, kNoSourcePosition); |
| 2313 ignore_completion_block->statements()->Add(assignment_statement, zone()); | 2305 ignore_completion_block->statements()->push_back(assignment_statement); |
| 2314 } | 2306 } |
| 2315 | 2307 |
| 2316 // Make statement: if (!cond) break. | 2308 // Make statement: if (!cond) break. |
| 2317 if (cond) { | 2309 if (cond) { |
| 2318 Statement* stop = | 2310 Statement* stop = |
| 2319 factory()->NewBreakStatement(outer_loop, kNoSourcePosition); | 2311 factory()->NewBreakStatement(outer_loop, kNoSourcePosition); |
| 2320 Statement* noop = factory()->NewEmptyStatement(kNoSourcePosition); | 2312 Statement* noop = factory()->NewEmptyStatement(kNoSourcePosition); |
| 2321 ignore_completion_block->statements()->Add( | 2313 ignore_completion_block->statements()->push_back( |
| 2322 factory()->NewIfStatement(cond, noop, stop, cond->position()), | 2314 factory()->NewIfStatement(cond, noop, stop, cond->position())); |
| 2323 zone()); | |
| 2324 } | 2315 } |
| 2325 | 2316 |
| 2326 inner_block->statements()->Add(ignore_completion_block, zone()); | 2317 inner_block->statements()->push_back(ignore_completion_block); |
| 2327 // Make cond expression for main loop: flag == 1. | 2318 // Make cond expression for main loop: flag == 1. |
| 2328 Expression* flag_cond = NULL; | 2319 Expression* flag_cond = NULL; |
| 2329 { | 2320 { |
| 2330 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition); | 2321 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition); |
| 2331 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); | 2322 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); |
| 2332 flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1, | 2323 flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1, |
| 2333 kNoSourcePosition); | 2324 kNoSourcePosition); |
| 2334 } | 2325 } |
| 2335 | 2326 |
| 2336 // Create chain of expressions "flag = 0, temp_x = x, ..." | 2327 // Create chain of expressions "flag = 0, temp_x = x, ..." |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2359 | 2350 |
| 2360 compound_next_statement = | 2351 compound_next_statement = |
| 2361 factory()->NewExpressionStatement(compound_next, kNoSourcePosition); | 2352 factory()->NewExpressionStatement(compound_next, kNoSourcePosition); |
| 2362 } | 2353 } |
| 2363 | 2354 |
| 2364 // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x) | 2355 // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x) |
| 2365 // Note that we re-use the original loop node, which retains its labels | 2356 // Note that we re-use the original loop node, which retains its labels |
| 2366 // and ensures that any break or continue statements in body point to | 2357 // and ensures that any break or continue statements in body point to |
| 2367 // the right place. | 2358 // the right place. |
| 2368 loop->Initialize(NULL, flag_cond, compound_next_statement, body); | 2359 loop->Initialize(NULL, flag_cond, compound_next_statement, body); |
| 2369 inner_block->statements()->Add(loop, zone()); | 2360 inner_block->statements()->push_back(loop); |
| 2370 | 2361 |
| 2371 // Make statement: {{if (flag == 1) break;}} | 2362 // Make statement: {{if (flag == 1) break;}} |
| 2372 { | 2363 { |
| 2373 Expression* compare = NULL; | 2364 Expression* compare = NULL; |
| 2374 // Make compare expresion: flag == 1. | 2365 // Make compare expresion: flag == 1. |
| 2375 { | 2366 { |
| 2376 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition); | 2367 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition); |
| 2377 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); | 2368 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); |
| 2378 compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1, | 2369 compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1, |
| 2379 kNoSourcePosition); | 2370 kNoSourcePosition); |
| 2380 } | 2371 } |
| 2381 Statement* stop = | 2372 Statement* stop = |
| 2382 factory()->NewBreakStatement(outer_loop, kNoSourcePosition); | 2373 factory()->NewBreakStatement(outer_loop, kNoSourcePosition); |
| 2383 Statement* empty = factory()->NewEmptyStatement(kNoSourcePosition); | 2374 Statement* empty = factory()->NewEmptyStatement(kNoSourcePosition); |
| 2384 Statement* if_flag_break = | 2375 Statement* if_flag_break = |
| 2385 factory()->NewIfStatement(compare, stop, empty, kNoSourcePosition); | 2376 factory()->NewIfStatement(compare, stop, empty, kNoSourcePosition); |
| 2386 Block* ignore_completion_block = | 2377 Block* ignore_completion_block = |
| 2387 factory()->NewBlock(NULL, 1, true, kNoSourcePosition); | 2378 factory()->NewBlock(NULL, true, kNoSourcePosition); |
| 2388 ignore_completion_block->statements()->Add(if_flag_break, zone()); | 2379 ignore_completion_block->statements()->push_back(if_flag_break); |
| 2389 inner_block->statements()->Add(ignore_completion_block, zone()); | 2380 inner_block->statements()->push_back(ignore_completion_block); |
| 2390 } | 2381 } |
| 2391 | 2382 |
| 2392 inner_scope->set_end_position(scanner()->location().end_pos); | 2383 inner_scope->set_end_position(scanner()->location().end_pos); |
| 2393 inner_block->set_scope(inner_scope); | 2384 inner_block->set_scope(inner_scope); |
| 2394 } | 2385 } |
| 2395 | 2386 |
| 2396 outer_loop->Initialize(NULL, NULL, NULL, inner_block); | 2387 outer_loop->Initialize(NULL, NULL, NULL, inner_block); |
| 2397 return outer_block; | 2388 return outer_block; |
| 2398 } | 2389 } |
| 2399 | 2390 |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2612 (allow_lazy() && function_type == FunctionLiteral::kDeclaration && | 2603 (allow_lazy() && function_type == FunctionLiteral::kDeclaration && |
| 2613 eager_compile_hint == FunctionLiteral::kShouldLazyCompile))) && | 2604 eager_compile_hint == FunctionLiteral::kShouldLazyCompile))) && |
| 2614 !(FLAG_validate_asm && scope()->IsAsmModule()); | 2605 !(FLAG_validate_asm && scope()->IsAsmModule()); |
| 2615 bool is_lazy_inner_function = | 2606 bool is_lazy_inner_function = |
| 2616 use_temp_zone && FLAG_lazy_inner_functions && !is_lazy_top_level_function; | 2607 use_temp_zone && FLAG_lazy_inner_functions && !is_lazy_top_level_function; |
| 2617 | 2608 |
| 2618 // This Scope lives in the main zone. We'll migrate data into that zone later. | 2609 // This Scope lives in the main zone. We'll migrate data into that zone later. |
| 2619 DeclarationScope* scope = NewFunctionScope(kind); | 2610 DeclarationScope* scope = NewFunctionScope(kind); |
| 2620 SetLanguageMode(scope, language_mode); | 2611 SetLanguageMode(scope, language_mode); |
| 2621 | 2612 |
| 2622 ZoneList<Statement*>* body = nullptr; | 2613 ZoneChunkList<Statement*>* body = nullptr; |
| 2623 int materialized_literal_count = -1; | 2614 int materialized_literal_count = -1; |
| 2624 int expected_property_count = -1; | 2615 int expected_property_count = -1; |
| 2625 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); | 2616 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); |
| 2626 bool should_be_used_once_hint = false; | 2617 bool should_be_used_once_hint = false; |
| 2627 bool has_duplicate_parameters; | 2618 bool has_duplicate_parameters; |
| 2628 | 2619 |
| 2629 FunctionState function_state(&function_state_, &scope_state_, scope); | 2620 FunctionState function_state(&function_state_, &scope_state_, scope); |
| 2630 #ifdef DEBUG | 2621 #ifdef DEBUG |
| 2631 scope->SetScopeName(function_name); | 2622 scope->SetScopeName(function_name); |
| 2632 #endif | 2623 #endif |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2901 void Parser::RewriteParameterInitializer(Expression* expr, Scope* scope) { | 2892 void Parser::RewriteParameterInitializer(Expression* expr, Scope* scope) { |
| 2902 InitializerRewriter rewriter(stack_limit_, expr, this, scope); | 2893 InitializerRewriter rewriter(stack_limit_, expr, this, scope); |
| 2903 rewriter.Run(); | 2894 rewriter.Run(); |
| 2904 } | 2895 } |
| 2905 | 2896 |
| 2906 | 2897 |
| 2907 Block* Parser::BuildParameterInitializationBlock( | 2898 Block* Parser::BuildParameterInitializationBlock( |
| 2908 const ParserFormalParameters& parameters, bool* ok) { | 2899 const ParserFormalParameters& parameters, bool* ok) { |
| 2909 DCHECK(!parameters.is_simple); | 2900 DCHECK(!parameters.is_simple); |
| 2910 DCHECK(scope()->is_function_scope()); | 2901 DCHECK(scope()->is_function_scope()); |
| 2911 Block* init_block = factory()->NewBlock(NULL, 1, true, kNoSourcePosition); | 2902 Block* init_block = factory()->NewBlock(NULL, true, kNoSourcePosition); |
| 2912 for (int i = 0; i < parameters.params.length(); ++i) { | 2903 for (int i = 0; i < parameters.params.length(); ++i) { |
| 2913 auto parameter = parameters.params[i]; | 2904 auto parameter = parameters.params[i]; |
| 2914 if (parameter.is_rest && parameter.pattern->IsVariableProxy()) break; | 2905 if (parameter.is_rest && parameter.pattern->IsVariableProxy()) break; |
| 2915 DeclarationDescriptor descriptor; | 2906 DeclarationDescriptor descriptor; |
| 2916 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER; | 2907 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER; |
| 2917 descriptor.scope = scope(); | 2908 descriptor.scope = scope(); |
| 2918 descriptor.hoist_scope = nullptr; | 2909 descriptor.hoist_scope = nullptr; |
| 2919 descriptor.mode = LET; | 2910 descriptor.mode = LET; |
| 2920 descriptor.declaration_pos = parameter.pattern->position(); | 2911 descriptor.declaration_pos = parameter.pattern->position(); |
| 2921 // The position that will be used by the AssignmentExpression | 2912 // The position that will be used by the AssignmentExpression |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2941 descriptor.initialization_pos = parameter.initializer->position(); | 2932 descriptor.initialization_pos = parameter.initializer->position(); |
| 2942 } | 2933 } |
| 2943 | 2934 |
| 2944 Scope* param_scope = scope(); | 2935 Scope* param_scope = scope(); |
| 2945 Block* param_block = init_block; | 2936 Block* param_block = init_block; |
| 2946 if (!parameter.is_simple() && scope()->calls_sloppy_eval()) { | 2937 if (!parameter.is_simple() && scope()->calls_sloppy_eval()) { |
| 2947 param_scope = NewVarblockScope(); | 2938 param_scope = NewVarblockScope(); |
| 2948 param_scope->set_start_position(descriptor.initialization_pos); | 2939 param_scope->set_start_position(descriptor.initialization_pos); |
| 2949 param_scope->set_end_position(parameter.initializer_end_position); | 2940 param_scope->set_end_position(parameter.initializer_end_position); |
| 2950 param_scope->RecordEvalCall(); | 2941 param_scope->RecordEvalCall(); |
| 2951 param_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition); | 2942 param_block = factory()->NewBlock(NULL, true, kNoSourcePosition); |
| 2952 param_block->set_scope(param_scope); | 2943 param_block->set_scope(param_scope); |
| 2953 descriptor.hoist_scope = scope(); | 2944 descriptor.hoist_scope = scope(); |
| 2954 // Pass the appropriate scope in so that PatternRewriter can appropriately | 2945 // Pass the appropriate scope in so that PatternRewriter can appropriately |
| 2955 // rewrite inner initializers of the pattern to param_scope | 2946 // rewrite inner initializers of the pattern to param_scope |
| 2956 descriptor.scope = param_scope; | 2947 descriptor.scope = param_scope; |
| 2957 // Rewrite the outer initializer to point to param_scope | 2948 // Rewrite the outer initializer to point to param_scope |
| 2958 ReparentParameterExpressionScope(stack_limit(), initial_value, | 2949 ReparentParameterExpressionScope(stack_limit(), initial_value, |
| 2959 param_scope); | 2950 param_scope); |
| 2960 } | 2951 } |
| 2961 | 2952 |
| 2962 BlockState block_state(&scope_state_, param_scope); | 2953 BlockState block_state(&scope_state_, param_scope); |
| 2963 DeclarationParsingResult::Declaration decl( | 2954 DeclarationParsingResult::Declaration decl( |
| 2964 parameter.pattern, parameter.initializer_end_position, initial_value); | 2955 parameter.pattern, parameter.initializer_end_position, initial_value); |
| 2965 PatternRewriter::DeclareAndInitializeVariables( | 2956 PatternRewriter::DeclareAndInitializeVariables( |
| 2966 this, param_block, &descriptor, &decl, nullptr, CHECK_OK); | 2957 this, param_block, &descriptor, &decl, nullptr, CHECK_OK); |
| 2967 | 2958 |
| 2968 if (param_block != init_block) { | 2959 if (param_block != init_block) { |
| 2969 param_scope = block_state.FinalizedBlockScope(); | 2960 param_scope = block_state.FinalizedBlockScope(); |
| 2970 if (param_scope != nullptr) { | 2961 if (param_scope != nullptr) { |
| 2971 CheckConflictingVarDeclarations(param_scope, CHECK_OK); | 2962 CheckConflictingVarDeclarations(param_scope, CHECK_OK); |
| 2972 } | 2963 } |
| 2973 init_block->statements()->Add(param_block, zone()); | 2964 init_block->statements()->push_back(param_block); |
| 2974 } | 2965 } |
| 2975 } | 2966 } |
| 2976 return init_block; | 2967 return init_block; |
| 2977 } | 2968 } |
| 2978 | 2969 |
| 2979 Block* Parser::BuildRejectPromiseOnException(Block* inner_block, bool* ok) { | 2970 Block* Parser::BuildRejectPromiseOnException(Block* inner_block, bool* ok) { |
| 2980 // .promise = %AsyncFunctionPromiseCreate(); | 2971 // .promise = %AsyncFunctionPromiseCreate(); |
| 2981 // try { | 2972 // try { |
| 2982 // <inner_block> | 2973 // <inner_block> |
| 2983 // } catch (.catch) { | 2974 // } catch (.catch) { |
| 2984 // %RejectPromise(.promise, .catch); | 2975 // %RejectPromise(.promise, .catch); |
| 2985 // return .promise; | 2976 // return .promise; |
| 2986 // } finally { | 2977 // } finally { |
| 2987 // %AsyncFunctionPromiseRelease(.promise); | 2978 // %AsyncFunctionPromiseRelease(.promise); |
| 2988 // } | 2979 // } |
| 2989 Block* result = factory()->NewBlock(nullptr, 2, true, kNoSourcePosition); | 2980 Block* result = factory()->NewBlock(nullptr, true, kNoSourcePosition); |
| 2990 | 2981 |
| 2991 // .promise = %AsyncFunctionPromiseCreate(); | 2982 // .promise = %AsyncFunctionPromiseCreate(); |
| 2992 Statement* set_promise; | 2983 Statement* set_promise; |
| 2993 { | 2984 { |
| 2994 Expression* create_promise = factory()->NewCallRuntime( | 2985 Expression* create_promise = factory()->NewCallRuntime( |
| 2995 Context::ASYNC_FUNCTION_PROMISE_CREATE_INDEX, | 2986 Context::ASYNC_FUNCTION_PROMISE_CREATE_INDEX, |
| 2996 new (zone()) ZoneList<Expression*>(0, zone()), kNoSourcePosition); | 2987 new (zone()) ZoneList<Expression*>(0, zone()), kNoSourcePosition); |
| 2997 Assignment* assign_promise = factory()->NewAssignment( | 2988 Assignment* assign_promise = factory()->NewAssignment( |
| 2998 Token::INIT, factory()->NewVariableProxy(PromiseVariable()), | 2989 Token::INIT, factory()->NewVariableProxy(PromiseVariable()), |
| 2999 create_promise, kNoSourcePosition); | 2990 create_promise, kNoSourcePosition); |
| 3000 set_promise = | 2991 set_promise = |
| 3001 factory()->NewExpressionStatement(assign_promise, kNoSourcePosition); | 2992 factory()->NewExpressionStatement(assign_promise, kNoSourcePosition); |
| 3002 } | 2993 } |
| 3003 result->statements()->Add(set_promise, zone()); | 2994 result->statements()->push_back(set_promise); |
| 3004 | 2995 |
| 3005 // catch (.catch) { return %RejectPromise(.promise, .catch), .promise } | 2996 // catch (.catch) { return %RejectPromise(.promise, .catch), .promise } |
| 3006 Scope* catch_scope = NewScope(CATCH_SCOPE); | 2997 Scope* catch_scope = NewScope(CATCH_SCOPE); |
| 3007 catch_scope->set_is_hidden(); | 2998 catch_scope->set_is_hidden(); |
| 3008 Variable* catch_variable = | 2999 Variable* catch_variable = |
| 3009 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR, | 3000 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR, |
| 3010 kCreatedInitialized, NORMAL_VARIABLE); | 3001 kCreatedInitialized, NORMAL_VARIABLE); |
| 3011 Block* catch_block = factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); | 3002 Block* catch_block = factory()->NewBlock(nullptr, true, kNoSourcePosition); |
| 3012 | 3003 |
| 3013 Expression* promise_reject = BuildRejectPromise( | 3004 Expression* promise_reject = BuildRejectPromise( |
| 3014 factory()->NewVariableProxy(catch_variable), kNoSourcePosition); | 3005 factory()->NewVariableProxy(catch_variable), kNoSourcePosition); |
| 3015 ReturnStatement* return_promise_reject = | 3006 ReturnStatement* return_promise_reject = |
| 3016 factory()->NewReturnStatement(promise_reject, kNoSourcePosition); | 3007 factory()->NewReturnStatement(promise_reject, kNoSourcePosition); |
| 3017 catch_block->statements()->Add(return_promise_reject, zone()); | 3008 catch_block->statements()->push_back(return_promise_reject); |
| 3018 | 3009 |
| 3019 TryStatement* try_catch_statement = | 3010 TryStatement* try_catch_statement = |
| 3020 factory()->NewTryCatchStatementForAsyncAwait(inner_block, catch_scope, | 3011 factory()->NewTryCatchStatementForAsyncAwait(inner_block, catch_scope, |
| 3021 catch_variable, catch_block, | 3012 catch_variable, catch_block, |
| 3022 kNoSourcePosition); | 3013 kNoSourcePosition); |
| 3023 | 3014 |
| 3024 // There is no TryCatchFinally node, so wrap it in an outer try/finally | 3015 // There is no TryCatchFinally node, so wrap it in an outer try/finally |
| 3025 Block* outer_try_block = | 3016 Block* outer_try_block = |
| 3026 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); | 3017 factory()->NewBlock(nullptr, true, kNoSourcePosition); |
| 3027 outer_try_block->statements()->Add(try_catch_statement, zone()); | 3018 outer_try_block->statements()->push_back(try_catch_statement); |
| 3028 | 3019 |
| 3029 // finally { %AsyncFunctionPromiseRelease(.promise) } | 3020 // finally { %AsyncFunctionPromiseRelease(.promise) } |
| 3030 Block* finally_block = | 3021 Block* finally_block = factory()->NewBlock(nullptr, true, kNoSourcePosition); |
| 3031 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); | |
| 3032 { | 3022 { |
| 3033 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone()); | 3023 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone()); |
| 3034 args->Add(factory()->NewVariableProxy(PromiseVariable()), zone()); | 3024 args->Add(factory()->NewVariableProxy(PromiseVariable()), zone()); |
| 3035 Expression* call_promise_release = factory()->NewCallRuntime( | 3025 Expression* call_promise_release = factory()->NewCallRuntime( |
| 3036 Context::ASYNC_FUNCTION_PROMISE_RELEASE_INDEX, args, kNoSourcePosition); | 3026 Context::ASYNC_FUNCTION_PROMISE_RELEASE_INDEX, args, kNoSourcePosition); |
| 3037 Statement* promise_release = factory()->NewExpressionStatement( | 3027 Statement* promise_release = factory()->NewExpressionStatement( |
| 3038 call_promise_release, kNoSourcePosition); | 3028 call_promise_release, kNoSourcePosition); |
| 3039 finally_block->statements()->Add(promise_release, zone()); | 3029 finally_block->statements()->push_back(promise_release); |
| 3040 } | 3030 } |
| 3041 | 3031 |
| 3042 Statement* try_finally_statement = factory()->NewTryFinallyStatement( | 3032 Statement* try_finally_statement = factory()->NewTryFinallyStatement( |
| 3043 outer_try_block, finally_block, kNoSourcePosition); | 3033 outer_try_block, finally_block, kNoSourcePosition); |
| 3044 | 3034 |
| 3045 result->statements()->Add(try_finally_statement, zone()); | 3035 result->statements()->push_back(try_finally_statement); |
| 3046 return result; | 3036 return result; |
| 3047 } | 3037 } |
| 3048 | 3038 |
| 3049 Expression* Parser::BuildCreateJSGeneratorObject(int pos, FunctionKind kind) { | 3039 Expression* Parser::BuildCreateJSGeneratorObject(int pos, FunctionKind kind) { |
| 3050 DCHECK_NOT_NULL(function_state_->generator_object_variable()); | 3040 DCHECK_NOT_NULL(function_state_->generator_object_variable()); |
| 3051 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); | 3041 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); |
| 3052 args->Add(factory()->NewThisFunction(pos), zone()); | 3042 args->Add(factory()->NewThisFunction(pos), zone()); |
| 3053 args->Add(IsArrowFunction(kind) ? GetLiteralUndefined(pos) | 3043 args->Add(IsArrowFunction(kind) ? GetLiteralUndefined(pos) |
| 3054 : ThisExpression(kNoSourcePosition), | 3044 : ThisExpression(kNoSourcePosition), |
| 3055 zone()); | 3045 zone()); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3104 Token::INIT, init_proxy, allocation, kNoSourcePosition); | 3094 Token::INIT, init_proxy, allocation, kNoSourcePosition); |
| 3105 VariableProxy* get_proxy = | 3095 VariableProxy* get_proxy = |
| 3106 factory()->NewVariableProxy(function_state_->generator_object_variable()); | 3096 factory()->NewVariableProxy(function_state_->generator_object_variable()); |
| 3107 // The position of the yield is important for reporting the exception | 3097 // The position of the yield is important for reporting the exception |
| 3108 // caused by calling the .throw method on a generator suspended at the | 3098 // caused by calling the .throw method on a generator suspended at the |
| 3109 // initial yield (i.e. right after generator instantiation). | 3099 // initial yield (i.e. right after generator instantiation). |
| 3110 return factory()->NewYield(get_proxy, assignment, scope()->start_position(), | 3100 return factory()->NewYield(get_proxy, assignment, scope()->start_position(), |
| 3111 Yield::kOnExceptionThrow); | 3101 Yield::kOnExceptionThrow); |
| 3112 } | 3102 } |
| 3113 | 3103 |
| 3114 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( | 3104 ZoneChunkList<Statement*>* Parser::ParseEagerFunctionBody( |
| 3115 const AstRawString* function_name, int pos, | 3105 const AstRawString* function_name, int pos, |
| 3116 const ParserFormalParameters& parameters, FunctionKind kind, | 3106 const ParserFormalParameters& parameters, FunctionKind kind, |
| 3117 FunctionLiteral::FunctionType function_type, bool* ok) { | 3107 FunctionLiteral::FunctionType function_type, bool* ok) { |
| 3118 ParsingModeScope mode(this, allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY); | 3108 ParsingModeScope mode(this, allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY); |
| 3119 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone()); | 3109 ZoneChunkList<Statement*>* result = |
| 3110 new (zone()) ZoneChunkList<Statement*>(zone()); |
| 3120 | 3111 |
| 3121 static const int kFunctionNameAssignmentIndex = 0; | 3112 static const int kFunctionNameAssignmentIndex = 0; |
| 3122 if (function_type == FunctionLiteral::kNamedExpression) { | 3113 if (function_type == FunctionLiteral::kNamedExpression) { |
| 3123 DCHECK(function_name != NULL); | 3114 DCHECK(function_name != NULL); |
| 3124 // If we have a named function expression, we add a local variable | 3115 // If we have a named function expression, we add a local variable |
| 3125 // declaration to the body of the function with the name of the | 3116 // declaration to the body of the function with the name of the |
| 3126 // function and let it refer to the function itself (closure). | 3117 // function and let it refer to the function itself (closure). |
| 3127 // Not having parsed the function body, the language mode may still change, | 3118 // Not having parsed the function body, the language mode may still change, |
| 3128 // so we reserve a spot and create the actual const assignment later. | 3119 // so we reserve a spot and create the actual const assignment later. |
| 3129 DCHECK_EQ(kFunctionNameAssignmentIndex, result->length()); | 3120 DCHECK_EQ(kFunctionNameAssignmentIndex, result->size()); |
| 3130 result->Add(NULL, zone()); | 3121 result->push_back(NULL); |
| 3131 } | 3122 } |
| 3132 | 3123 |
| 3133 ZoneList<Statement*>* body = result; | 3124 ZoneChunkList<Statement*>* body = result; |
| 3134 DeclarationScope* function_scope = scope()->AsDeclarationScope(); | 3125 DeclarationScope* function_scope = scope()->AsDeclarationScope(); |
| 3135 DeclarationScope* inner_scope = function_scope; | 3126 DeclarationScope* inner_scope = function_scope; |
| 3136 Block* inner_block = nullptr; | 3127 Block* inner_block = nullptr; |
| 3137 if (!parameters.is_simple) { | 3128 if (!parameters.is_simple) { |
| 3138 inner_scope = NewVarblockScope(); | 3129 inner_scope = NewVarblockScope(); |
| 3139 inner_scope->set_start_position(scanner()->location().beg_pos); | 3130 inner_scope->set_start_position(scanner()->location().beg_pos); |
| 3140 inner_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition); | 3131 inner_block = factory()->NewBlock(NULL, true, kNoSourcePosition); |
| 3141 inner_block->set_scope(inner_scope); | 3132 inner_block->set_scope(inner_scope); |
| 3142 body = inner_block->statements(); | 3133 body = inner_block->statements(); |
| 3143 } | 3134 } |
| 3144 | 3135 |
| 3145 { | 3136 { |
| 3146 BlockState block_state(&scope_state_, inner_scope); | 3137 BlockState block_state(&scope_state_, inner_scope); |
| 3147 | 3138 |
| 3148 if (IsGeneratorFunction(kind)) { | 3139 if (IsGeneratorFunction(kind)) { |
| 3149 // We produce: | 3140 // We produce: |
| 3150 // | 3141 // |
| 3151 // try { InitialYield; ...body...; return {value: undefined, done: true} } | 3142 // try { InitialYield; ...body...; return {value: undefined, done: true} } |
| 3152 // finally { %_GeneratorClose(generator) } | 3143 // finally { %_GeneratorClose(generator) } |
| 3153 // | 3144 // |
| 3154 // - InitialYield yields the actual generator object. | 3145 // - InitialYield yields the actual generator object. |
| 3155 // - Any return statement inside the body will have its argument wrapped | 3146 // - Any return statement inside the body will have its argument wrapped |
| 3156 // in a "done" iterator result object. | 3147 // in a "done" iterator result object. |
| 3157 // - If the generator terminates for whatever reason, we must close it. | 3148 // - If the generator terminates for whatever reason, we must close it. |
| 3158 // Hence the finally clause. | 3149 // Hence the finally clause. |
| 3159 | 3150 |
| 3160 Block* try_block = | 3151 Block* try_block = factory()->NewBlock(nullptr, false, kNoSourcePosition); |
| 3161 factory()->NewBlock(nullptr, 3, false, kNoSourcePosition); | |
| 3162 Expression* initial_yield = BuildInitialYield(pos, kind); | 3152 Expression* initial_yield = BuildInitialYield(pos, kind); |
| 3163 try_block->statements()->Add( | 3153 try_block->statements()->push_back( |
| 3164 factory()->NewExpressionStatement(initial_yield, kNoSourcePosition), | 3154 factory()->NewExpressionStatement(initial_yield, kNoSourcePosition)); |
| 3165 zone()); | |
| 3166 ParseStatementList(try_block->statements(), Token::RBRACE, CHECK_OK); | 3155 ParseStatementList(try_block->statements(), Token::RBRACE, CHECK_OK); |
| 3167 | 3156 |
| 3168 Statement* final_return = factory()->NewReturnStatement( | 3157 Statement* final_return = factory()->NewReturnStatement( |
| 3169 BuildIteratorResult(nullptr, true), kNoSourcePosition); | 3158 BuildIteratorResult(nullptr, true), kNoSourcePosition); |
| 3170 try_block->statements()->Add(final_return, zone()); | 3159 try_block->statements()->push_back(final_return); |
| 3171 | 3160 |
| 3172 Block* finally_block = | 3161 Block* finally_block = |
| 3173 factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); | 3162 factory()->NewBlock(nullptr, false, kNoSourcePosition); |
| 3174 ZoneList<Expression*>* args = | 3163 ZoneList<Expression*>* args = |
| 3175 new (zone()) ZoneList<Expression*>(1, zone()); | 3164 new (zone()) ZoneList<Expression*>(1, zone()); |
| 3176 VariableProxy* call_proxy = factory()->NewVariableProxy( | 3165 VariableProxy* call_proxy = factory()->NewVariableProxy( |
| 3177 function_state_->generator_object_variable()); | 3166 function_state_->generator_object_variable()); |
| 3178 args->Add(call_proxy, zone()); | 3167 args->Add(call_proxy, zone()); |
| 3179 Expression* call = factory()->NewCallRuntime( | 3168 Expression* call = factory()->NewCallRuntime( |
| 3180 Runtime::kInlineGeneratorClose, args, kNoSourcePosition); | 3169 Runtime::kInlineGeneratorClose, args, kNoSourcePosition); |
| 3181 finally_block->statements()->Add( | 3170 finally_block->statements()->push_back( |
| 3182 factory()->NewExpressionStatement(call, kNoSourcePosition), zone()); | 3171 factory()->NewExpressionStatement(call, kNoSourcePosition)); |
| 3183 | 3172 |
| 3184 body->Add(factory()->NewTryFinallyStatement(try_block, finally_block, | 3173 body->push_back(factory()->NewTryFinallyStatement( |
| 3185 kNoSourcePosition), | 3174 try_block, finally_block, kNoSourcePosition)); |
| 3186 zone()); | |
| 3187 } else if (IsAsyncFunction(kind)) { | 3175 } else if (IsAsyncFunction(kind)) { |
| 3188 const bool accept_IN = true; | 3176 const bool accept_IN = true; |
| 3189 ParseAsyncFunctionBody(inner_scope, body, kind, FunctionBodyType::kNormal, | 3177 ParseAsyncFunctionBody(inner_scope, body, kind, FunctionBodyType::kNormal, |
| 3190 accept_IN, pos, CHECK_OK); | 3178 accept_IN, pos, CHECK_OK); |
| 3191 } else { | 3179 } else { |
| 3192 ParseStatementList(body, Token::RBRACE, CHECK_OK); | 3180 ParseStatementList(body, Token::RBRACE, CHECK_OK); |
| 3193 } | 3181 } |
| 3194 | 3182 |
| 3195 if (IsSubclassConstructor(kind)) { | 3183 if (IsSubclassConstructor(kind)) { |
| 3196 body->Add(factory()->NewReturnStatement(ThisExpression(kNoSourcePosition), | 3184 body->push_back(factory()->NewReturnStatement( |
| 3197 kNoSourcePosition), | 3185 ThisExpression(kNoSourcePosition), kNoSourcePosition)); |
| 3198 zone()); | |
| 3199 } | 3186 } |
| 3200 } | 3187 } |
| 3201 | 3188 |
| 3202 Expect(Token::RBRACE, CHECK_OK); | 3189 Expect(Token::RBRACE, CHECK_OK); |
| 3203 scope()->set_end_position(scanner()->location().end_pos); | 3190 scope()->set_end_position(scanner()->location().end_pos); |
| 3204 | 3191 |
| 3205 if (!parameters.is_simple) { | 3192 if (!parameters.is_simple) { |
| 3206 DCHECK_NOT_NULL(inner_scope); | 3193 DCHECK_NOT_NULL(inner_scope); |
| 3207 DCHECK_EQ(function_scope, scope()); | 3194 DCHECK_EQ(function_scope, scope()); |
| 3208 DCHECK_EQ(function_scope, inner_scope->outer_scope()); | 3195 DCHECK_EQ(function_scope, inner_scope->outer_scope()); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3221 | 3208 |
| 3222 DCHECK_NOT_NULL(init_block); | 3209 DCHECK_NOT_NULL(init_block); |
| 3223 | 3210 |
| 3224 inner_scope->set_end_position(scanner()->location().end_pos); | 3211 inner_scope->set_end_position(scanner()->location().end_pos); |
| 3225 if (inner_scope->FinalizeBlockScope() != nullptr) { | 3212 if (inner_scope->FinalizeBlockScope() != nullptr) { |
| 3226 CheckConflictingVarDeclarations(inner_scope, CHECK_OK); | 3213 CheckConflictingVarDeclarations(inner_scope, CHECK_OK); |
| 3227 InsertShadowingVarBindingInitializers(inner_block); | 3214 InsertShadowingVarBindingInitializers(inner_block); |
| 3228 } | 3215 } |
| 3229 inner_scope = nullptr; | 3216 inner_scope = nullptr; |
| 3230 | 3217 |
| 3231 result->Add(init_block, zone()); | 3218 result->push_back(init_block); |
| 3232 result->Add(inner_block, zone()); | 3219 result->push_back(inner_block); |
| 3233 } else { | 3220 } else { |
| 3234 DCHECK_EQ(inner_scope, function_scope); | 3221 DCHECK_EQ(inner_scope, function_scope); |
| 3235 if (is_sloppy(function_scope->language_mode())) { | 3222 if (is_sloppy(function_scope->language_mode())) { |
| 3236 InsertSloppyBlockFunctionVarBindings(function_scope); | 3223 InsertSloppyBlockFunctionVarBindings(function_scope); |
| 3237 } | 3224 } |
| 3238 } | 3225 } |
| 3239 | 3226 |
| 3240 if (!IsArrowFunction(kind)) { | 3227 if (!IsArrowFunction(kind)) { |
| 3241 // Declare arguments after parsing the function since lexical 'arguments' | 3228 // Declare arguments after parsing the function since lexical 'arguments' |
| 3242 // masks the arguments object. Declare arguments before declaring the | 3229 // masks the arguments object. Declare arguments before declaring the |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3253 Variable* fvar = function_scope->DeclareFunctionVar(function_name); | 3240 Variable* fvar = function_scope->DeclareFunctionVar(function_name); |
| 3254 VariableProxy* fproxy = factory()->NewVariableProxy(fvar); | 3241 VariableProxy* fproxy = factory()->NewVariableProxy(fvar); |
| 3255 statement = factory()->NewExpressionStatement( | 3242 statement = factory()->NewExpressionStatement( |
| 3256 factory()->NewAssignment(Token::INIT, fproxy, | 3243 factory()->NewAssignment(Token::INIT, fproxy, |
| 3257 factory()->NewThisFunction(pos), | 3244 factory()->NewThisFunction(pos), |
| 3258 kNoSourcePosition), | 3245 kNoSourcePosition), |
| 3259 kNoSourcePosition); | 3246 kNoSourcePosition); |
| 3260 } else { | 3247 } else { |
| 3261 statement = factory()->NewEmptyStatement(kNoSourcePosition); | 3248 statement = factory()->NewEmptyStatement(kNoSourcePosition); |
| 3262 } | 3249 } |
| 3263 result->Set(kFunctionNameAssignmentIndex, statement); | 3250 |
| 3251 { |
| 3252 auto it = result->begin(); |
| 3253 for (int i = 0; i < kFunctionNameAssignmentIndex; i++) it++; |
| 3254 *it = statement; |
| 3255 } |
| 3264 } | 3256 } |
| 3265 | 3257 |
| 3266 MarkCollectedTailCallExpressions(); | 3258 MarkCollectedTailCallExpressions(); |
| 3267 return result; | 3259 return result; |
| 3268 } | 3260 } |
| 3269 | 3261 |
| 3270 PreParser::PreParseResult Parser::ParseFunctionBodyWithPreParser( | 3262 PreParser::PreParseResult Parser::ParseFunctionBodyWithPreParser( |
| 3271 SingletonLogger* logger, bool is_inner_function, bool may_abort) { | 3263 SingletonLogger* logger, bool is_inner_function, bool may_abort) { |
| 3272 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse"); | 3264 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse"); |
| 3273 | 3265 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3293 | 3285 |
| 3294 DeclarationScope* function_scope = function_state_->scope(); | 3286 DeclarationScope* function_scope = function_state_->scope(); |
| 3295 PreParser::PreParseResult result = reusable_preparser_->PreParseFunction( | 3287 PreParser::PreParseResult result = reusable_preparser_->PreParseFunction( |
| 3296 function_scope, parsing_module_, logger, is_inner_function, may_abort, | 3288 function_scope, parsing_module_, logger, is_inner_function, may_abort, |
| 3297 use_counts_); | 3289 use_counts_); |
| 3298 return result; | 3290 return result; |
| 3299 } | 3291 } |
| 3300 | 3292 |
| 3301 Expression* Parser::InstallHomeObject(Expression* function_literal, | 3293 Expression* Parser::InstallHomeObject(Expression* function_literal, |
| 3302 Expression* home_object) { | 3294 Expression* home_object) { |
| 3303 Block* do_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); | 3295 Block* do_block = factory()->NewBlock(nullptr, false, kNoSourcePosition); |
| 3304 Variable* result_var = | 3296 Variable* result_var = |
| 3305 scope()->NewTemporary(ast_value_factory()->empty_string()); | 3297 scope()->NewTemporary(ast_value_factory()->empty_string()); |
| 3306 DoExpression* do_expr = | 3298 DoExpression* do_expr = |
| 3307 factory()->NewDoExpression(do_block, result_var, kNoSourcePosition); | 3299 factory()->NewDoExpression(do_block, result_var, kNoSourcePosition); |
| 3308 Assignment* init = factory()->NewAssignment( | 3300 Assignment* init = factory()->NewAssignment( |
| 3309 Token::ASSIGN, factory()->NewVariableProxy(result_var), function_literal, | 3301 Token::ASSIGN, factory()->NewVariableProxy(result_var), function_literal, |
| 3310 kNoSourcePosition); | 3302 kNoSourcePosition); |
| 3311 do_block->statements()->Add( | 3303 do_block->statements()->push_back( |
| 3312 factory()->NewExpressionStatement(init, kNoSourcePosition), zone()); | 3304 factory()->NewExpressionStatement(init, kNoSourcePosition)); |
| 3313 Property* home_object_property = factory()->NewProperty( | 3305 Property* home_object_property = factory()->NewProperty( |
| 3314 factory()->NewVariableProxy(result_var), | 3306 factory()->NewVariableProxy(result_var), |
| 3315 factory()->NewSymbolLiteral("home_object_symbol", kNoSourcePosition), | 3307 factory()->NewSymbolLiteral("home_object_symbol", kNoSourcePosition), |
| 3316 kNoSourcePosition); | 3308 kNoSourcePosition); |
| 3317 Assignment* assignment = factory()->NewAssignment( | 3309 Assignment* assignment = factory()->NewAssignment( |
| 3318 Token::ASSIGN, home_object_property, home_object, kNoSourcePosition); | 3310 Token::ASSIGN, home_object_property, home_object, kNoSourcePosition); |
| 3319 do_block->statements()->Add( | 3311 do_block->statements()->push_back( |
| 3320 factory()->NewExpressionStatement(assignment, kNoSourcePosition), zone()); | 3312 factory()->NewExpressionStatement(assignment, kNoSourcePosition)); |
| 3321 return do_expr; | 3313 return do_expr; |
| 3322 } | 3314 } |
| 3323 | 3315 |
| 3324 const AstRawString* ClassFieldVariableName(bool is_name, | 3316 const AstRawString* ClassFieldVariableName(bool is_name, |
| 3325 AstValueFactory* ast_value_factory, | 3317 AstValueFactory* ast_value_factory, |
| 3326 int index) { | 3318 int index) { |
| 3327 std::string name = | 3319 std::string name = |
| 3328 ".class-field-" + std::to_string(index) + (is_name ? "-name" : "-func"); | 3320 ".class-field-" + std::to_string(index) + (is_name ? "-name" : "-func"); |
| 3329 return ast_value_factory->GetOneByteString(name.c_str()); | 3321 return ast_value_factory->GetOneByteString(name.c_str()); |
| 3330 } | 3322 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3349 // DONT_ENUM, false) | 3341 // DONT_ENUM, false) |
| 3350 | 3342 |
| 3351 RaiseLanguageMode(STRICT); | 3343 RaiseLanguageMode(STRICT); |
| 3352 FunctionKind kind = FunctionKind::kConciseMethod; | 3344 FunctionKind kind = FunctionKind::kConciseMethod; |
| 3353 DeclarationScope* initializer_scope = NewFunctionScope(kind); | 3345 DeclarationScope* initializer_scope = NewFunctionScope(kind); |
| 3354 SetLanguageMode(initializer_scope, language_mode()); | 3346 SetLanguageMode(initializer_scope, language_mode()); |
| 3355 initializer_scope->set_start_position(scanner()->location().end_pos); | 3347 initializer_scope->set_start_position(scanner()->location().end_pos); |
| 3356 initializer_scope->set_end_position(scanner()->location().end_pos); | 3348 initializer_scope->set_end_position(scanner()->location().end_pos); |
| 3357 FunctionState initializer_state(&function_state_, &scope_state_, | 3349 FunctionState initializer_state(&function_state_, &scope_state_, |
| 3358 initializer_scope); | 3350 initializer_scope); |
| 3359 ZoneList<Statement*>* body = new (zone()) ZoneList<Statement*>(count, zone()); | 3351 ZoneChunkList<Statement*>* body = |
| 3352 new (zone()) ZoneChunkList<Statement*>(zone()); |
| 3360 for (int i = 0; i < count; ++i) { | 3353 for (int i = 0; i < count; ++i) { |
| 3361 const AstRawString* name = | 3354 const AstRawString* name = |
| 3362 ClassFieldVariableName(true, ast_value_factory(), i); | 3355 ClassFieldVariableName(true, ast_value_factory(), i); |
| 3363 VariableProxy* name_proxy = scope()->NewUnresolved(factory(), name); | 3356 VariableProxy* name_proxy = scope()->NewUnresolved(factory(), name); |
| 3364 const AstRawString* function_name = | 3357 const AstRawString* function_name = |
| 3365 ClassFieldVariableName(false, ast_value_factory(), i); | 3358 ClassFieldVariableName(false, ast_value_factory(), i); |
| 3366 VariableProxy* function_proxy = | 3359 VariableProxy* function_proxy = |
| 3367 scope()->NewUnresolved(factory(), function_name); | 3360 scope()->NewUnresolved(factory(), function_name); |
| 3368 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); | 3361 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); |
| 3369 args->Add(function_proxy, zone()); | 3362 args->Add(function_proxy, zone()); |
| 3370 args->Add(ThisExpression(kNoSourcePosition), zone()); | 3363 args->Add(ThisExpression(kNoSourcePosition), zone()); |
| 3371 Expression* call = factory()->NewCallRuntime(Runtime::kInlineCall, args, | 3364 Expression* call = factory()->NewCallRuntime(Runtime::kInlineCall, args, |
| 3372 kNoSourcePosition); | 3365 kNoSourcePosition); |
| 3373 ZoneList<Expression*>* define_property_args = | 3366 ZoneList<Expression*>* define_property_args = |
| 3374 new (zone()) ZoneList<Expression*>(5, zone()); | 3367 new (zone()) ZoneList<Expression*>(5, zone()); |
| 3375 define_property_args->Add(ThisExpression(kNoSourcePosition), zone()); | 3368 define_property_args->Add(ThisExpression(kNoSourcePosition), zone()); |
| 3376 define_property_args->Add(name_proxy, zone()); | 3369 define_property_args->Add(name_proxy, zone()); |
| 3377 define_property_args->Add(call, zone()); | 3370 define_property_args->Add(call, zone()); |
| 3378 define_property_args->Add( | 3371 define_property_args->Add( |
| 3379 factory()->NewNumberLiteral(DONT_ENUM, kNoSourcePosition), zone()); | 3372 factory()->NewNumberLiteral(DONT_ENUM, kNoSourcePosition), zone()); |
| 3380 define_property_args->Add( | 3373 define_property_args->Add( |
| 3381 factory()->NewNumberLiteral( | 3374 factory()->NewNumberLiteral( |
| 3382 false, // TODO(bakkot) function name inference a la class { x = | 3375 false, // TODO(bakkot) function name inference a la class { x = |
| 3383 // function(){}; static y = function(){}; } | 3376 // function(){}; static y = function(){}; } |
| 3384 kNoSourcePosition), | 3377 kNoSourcePosition), |
| 3385 zone()); | 3378 zone()); |
| 3386 body->Add(factory()->NewExpressionStatement( | 3379 body->push_back(factory()->NewExpressionStatement( |
| 3387 factory()->NewCallRuntime( | 3380 factory()->NewCallRuntime( |
| 3388 Runtime::kDefineDataProperty, | 3381 Runtime::kDefineDataProperty, |
| 3389 define_property_args, // TODO(bakkot) verify that this is | 3382 define_property_args, // TODO(bakkot) verify that this is |
| 3390 // the same as object_define_property | 3383 // the same as object_define_property |
| 3391 kNoSourcePosition), | 3384 kNoSourcePosition), |
| 3392 kNoSourcePosition), | 3385 kNoSourcePosition)); |
| 3393 zone()); | |
| 3394 } | 3386 } |
| 3395 body->Add(factory()->NewReturnStatement(ThisExpression(kNoSourcePosition), | 3387 body->push_back(factory()->NewReturnStatement( |
| 3396 kNoSourcePosition), | 3388 ThisExpression(kNoSourcePosition), kNoSourcePosition)); |
| 3397 zone()); | |
| 3398 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( | 3389 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( |
| 3399 ast_value_factory()->empty_string(), initializer_scope, body, | 3390 ast_value_factory()->empty_string(), initializer_scope, body, |
| 3400 initializer_state.materialized_literal_count(), | 3391 initializer_state.materialized_literal_count(), |
| 3401 initializer_state.expected_property_count(), 0, count, | 3392 initializer_state.expected_property_count(), 0, count, |
| 3402 FunctionLiteral::kNoDuplicateParameters, | 3393 FunctionLiteral::kNoDuplicateParameters, |
| 3403 FunctionLiteral::kAnonymousExpression, | 3394 FunctionLiteral::kAnonymousExpression, |
| 3404 FunctionLiteral::kShouldLazyCompile, initializer_scope->start_position()); | 3395 FunctionLiteral::kShouldLazyCompile, initializer_scope->start_position()); |
| 3405 function_literal->set_is_class_field_initializer(true); | 3396 function_literal->set_is_class_field_initializer(true); |
| 3406 return function_literal; | 3397 return function_literal; |
| 3407 } | 3398 } |
| 3408 | 3399 |
| 3409 FunctionLiteral* Parser::InsertClassFieldInitializer( | 3400 FunctionLiteral* Parser::InsertClassFieldInitializer( |
| 3410 FunctionLiteral* constructor) { | 3401 FunctionLiteral* constructor) { |
| 3411 Statement* call_initializer = factory()->NewExpressionStatement( | 3402 Statement* call_initializer = factory()->NewExpressionStatement( |
| 3412 CallClassFieldInitializer( | 3403 CallClassFieldInitializer( |
| 3413 constructor->scope(), | 3404 constructor->scope(), |
| 3414 constructor->scope()->NewUnresolved( | 3405 constructor->scope()->NewUnresolved( |
| 3415 factory(), ast_value_factory()->this_string(), kNoSourcePosition, | 3406 factory(), ast_value_factory()->this_string(), kNoSourcePosition, |
| 3416 THIS_VARIABLE)), | 3407 THIS_VARIABLE)), |
| 3417 kNoSourcePosition); | 3408 kNoSourcePosition); |
| 3418 constructor->body()->InsertAt(0, call_initializer, zone()); | 3409 constructor->body()->push_front(call_initializer); |
| 3419 return constructor; | 3410 return constructor; |
| 3420 } | 3411 } |
| 3421 | 3412 |
| 3422 // If a class name is specified, this method declares the class variable | 3413 // If a class name is specified, this method declares the class variable |
| 3423 // and sets class_info->proxy to point to that name. | 3414 // and sets class_info->proxy to point to that name. |
| 3424 void Parser::DeclareClassVariable(const AstRawString* name, Scope* block_scope, | 3415 void Parser::DeclareClassVariable(const AstRawString* name, Scope* block_scope, |
| 3425 ClassInfo* class_info, int class_token_pos, | 3416 ClassInfo* class_info, int class_token_pos, |
| 3426 bool* ok) { | 3417 bool* ok) { |
| 3427 #ifdef DEBUG | 3418 #ifdef DEBUG |
| 3428 scope()->SetScopeName(name); | 3419 scope()->SetScopeName(name); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3507 // - constructor (if missing, it updates it with a default constructor) | 3498 // - constructor (if missing, it updates it with a default constructor) |
| 3508 // - proxy | 3499 // - proxy |
| 3509 // - extends | 3500 // - extends |
| 3510 // - static_initializer_var | 3501 // - static_initializer_var |
| 3511 // - instance_field_initializers | 3502 // - instance_field_initializers |
| 3512 // - properties | 3503 // - properties |
| 3513 Expression* Parser::RewriteClassLiteral(const AstRawString* name, | 3504 Expression* Parser::RewriteClassLiteral(const AstRawString* name, |
| 3514 ClassInfo* class_info, int pos, | 3505 ClassInfo* class_info, int pos, |
| 3515 bool* ok) { | 3506 bool* ok) { |
| 3516 int end_pos = scanner()->location().end_pos; | 3507 int end_pos = scanner()->location().end_pos; |
| 3517 Block* do_block = factory()->NewBlock(nullptr, 1, false, pos); | 3508 Block* do_block = factory()->NewBlock(nullptr, false, pos); |
| 3518 Variable* result_var = NewTemporary(ast_value_factory()->empty_string()); | 3509 Variable* result_var = NewTemporary(ast_value_factory()->empty_string()); |
| 3519 DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos); | 3510 DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos); |
| 3520 | 3511 |
| 3521 bool has_extends = class_info->extends != nullptr; | 3512 bool has_extends = class_info->extends != nullptr; |
| 3522 bool has_instance_fields = | 3513 bool has_instance_fields = |
| 3523 class_info->instance_field_initializers->length() > 0; | 3514 class_info->instance_field_initializers->length() > 0; |
| 3524 DCHECK(!has_instance_fields || allow_harmony_class_fields()); | 3515 DCHECK(!has_instance_fields || allow_harmony_class_fields()); |
| 3525 bool has_default_constructor = class_info->constructor == nullptr; | 3516 bool has_default_constructor = class_info->constructor == nullptr; |
| 3526 if (has_default_constructor) { | 3517 if (has_default_constructor) { |
| 3527 class_info->constructor = | 3518 class_info->constructor = |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3544 | 3535 |
| 3545 ClassLiteral* class_literal = factory()->NewClassLiteral( | 3536 ClassLiteral* class_literal = factory()->NewClassLiteral( |
| 3546 class_info->proxy, class_info->extends, class_info->constructor, | 3537 class_info->proxy, class_info->extends, class_info->constructor, |
| 3547 class_info->properties, pos, end_pos); | 3538 class_info->properties, pos, end_pos); |
| 3548 | 3539 |
| 3549 if (class_info->static_initializer_var != nullptr) { | 3540 if (class_info->static_initializer_var != nullptr) { |
| 3550 class_literal->set_static_initializer_proxy( | 3541 class_literal->set_static_initializer_proxy( |
| 3551 factory()->NewVariableProxy(class_info->static_initializer_var)); | 3542 factory()->NewVariableProxy(class_info->static_initializer_var)); |
| 3552 } | 3543 } |
| 3553 | 3544 |
| 3554 do_block->statements()->Add( | 3545 do_block->statements()->push_back(factory()->NewExpressionStatement( |
| 3555 factory()->NewExpressionStatement( | 3546 factory()->NewAssignment(Token::ASSIGN, |
| 3556 factory()->NewAssignment(Token::ASSIGN, | 3547 factory()->NewVariableProxy(result_var), |
| 3557 factory()->NewVariableProxy(result_var), | 3548 class_literal, kNoSourcePosition), |
| 3558 class_literal, kNoSourcePosition), | 3549 pos)); |
| 3559 pos), | |
| 3560 zone()); | |
| 3561 if (allow_harmony_class_fields() && | 3550 if (allow_harmony_class_fields() && |
| 3562 (has_instance_fields || (has_extends && !has_default_constructor))) { | 3551 (has_instance_fields || (has_extends && !has_default_constructor))) { |
| 3563 // Default constructors for derived classes without fields will not try to | 3552 // Default constructors for derived classes without fields will not try to |
| 3564 // read this variable, so there's no need to create it. | 3553 // read this variable, so there's no need to create it. |
| 3565 const AstRawString* init_fn_name = | 3554 const AstRawString* init_fn_name = |
| 3566 ast_value_factory()->dot_class_field_init_string(); | 3555 ast_value_factory()->dot_class_field_init_string(); |
| 3567 Variable* init_fn_var = scope()->DeclareLocal( | 3556 Variable* init_fn_var = scope()->DeclareLocal( |
| 3568 init_fn_name, CONST, kCreatedInitialized, NORMAL_VARIABLE); | 3557 init_fn_name, CONST, kCreatedInitialized, NORMAL_VARIABLE); |
| 3569 Expression* initializer = | 3558 Expression* initializer = |
| 3570 has_instance_fields | 3559 has_instance_fields |
| 3571 ? static_cast<Expression*>(SynthesizeClassFieldInitializer( | 3560 ? static_cast<Expression*>(SynthesizeClassFieldInitializer( |
| 3572 class_info->instance_field_initializers->length())) | 3561 class_info->instance_field_initializers->length())) |
| 3573 : factory()->NewBooleanLiteral(false, kNoSourcePosition); | 3562 : factory()->NewBooleanLiteral(false, kNoSourcePosition); |
| 3574 Assignment* assignment = factory()->NewAssignment( | 3563 Assignment* assignment = factory()->NewAssignment( |
| 3575 Token::INIT, factory()->NewVariableProxy(init_fn_var), initializer, | 3564 Token::INIT, factory()->NewVariableProxy(init_fn_var), initializer, |
| 3576 kNoSourcePosition); | 3565 kNoSourcePosition); |
| 3577 do_block->statements()->Add( | 3566 do_block->statements()->push_back( |
| 3578 factory()->NewExpressionStatement(assignment, kNoSourcePosition), | 3567 factory()->NewExpressionStatement(assignment, kNoSourcePosition)); |
| 3579 zone()); | |
| 3580 } | 3568 } |
| 3581 for (int i = 0; i < class_info->instance_field_initializers->length(); ++i) { | 3569 for (int i = 0; i < class_info->instance_field_initializers->length(); ++i) { |
| 3582 const AstRawString* function_name = | 3570 const AstRawString* function_name = |
| 3583 ClassFieldVariableName(false, ast_value_factory(), i); | 3571 ClassFieldVariableName(false, ast_value_factory(), i); |
| 3584 VariableProxy* function_proxy = | 3572 VariableProxy* function_proxy = |
| 3585 factory()->NewVariableProxy(function_name, NORMAL_VARIABLE); | 3573 factory()->NewVariableProxy(function_name, NORMAL_VARIABLE); |
| 3586 Declaration* function_declaration = factory()->NewVariableDeclaration( | 3574 Declaration* function_declaration = factory()->NewVariableDeclaration( |
| 3587 function_proxy, scope(), kNoSourcePosition); | 3575 function_proxy, scope(), kNoSourcePosition); |
| 3588 Variable* function_var = | 3576 Variable* function_var = |
| 3589 Declare(function_declaration, DeclarationDescriptor::NORMAL, CONST, | 3577 Declare(function_declaration, DeclarationDescriptor::NORMAL, CONST, |
| 3590 kNeedsInitialization, ok, scope()); | 3578 kNeedsInitialization, ok, scope()); |
| 3591 if (!*ok) return nullptr; | 3579 if (!*ok) return nullptr; |
| 3592 Property* prototype_property = factory()->NewProperty( | 3580 Property* prototype_property = factory()->NewProperty( |
| 3593 factory()->NewVariableProxy(result_var), | 3581 factory()->NewVariableProxy(result_var), |
| 3594 factory()->NewStringLiteral(ast_value_factory()->prototype_string(), | 3582 factory()->NewStringLiteral(ast_value_factory()->prototype_string(), |
| 3595 kNoSourcePosition), | 3583 kNoSourcePosition), |
| 3596 kNoSourcePosition); | 3584 kNoSourcePosition); |
| 3597 Expression* function_value = InstallHomeObject( | 3585 Expression* function_value = InstallHomeObject( |
| 3598 class_info->instance_field_initializers->at(i), | 3586 class_info->instance_field_initializers->at(i), |
| 3599 prototype_property); // TODO(bakkot) ideally this would be conditional, | 3587 prototype_property); // TODO(bakkot) ideally this would be conditional, |
| 3600 // especially in trivial cases | 3588 // especially in trivial cases |
| 3601 Assignment* function_assignment = factory()->NewAssignment( | 3589 Assignment* function_assignment = factory()->NewAssignment( |
| 3602 Token::INIT, factory()->NewVariableProxy(function_var), function_value, | 3590 Token::INIT, factory()->NewVariableProxy(function_var), function_value, |
| 3603 kNoSourcePosition); | 3591 kNoSourcePosition); |
| 3604 do_block->statements()->Add(factory()->NewExpressionStatement( | 3592 do_block->statements()->push_back(factory()->NewExpressionStatement( |
| 3605 function_assignment, kNoSourcePosition), | 3593 function_assignment, kNoSourcePosition)); |
| 3606 zone()); | |
| 3607 } | 3594 } |
| 3608 do_block->set_scope(scope()->FinalizeBlockScope()); | 3595 do_block->set_scope(scope()->FinalizeBlockScope()); |
| 3609 do_expr->set_represented_function(class_info->constructor); | 3596 do_expr->set_represented_function(class_info->constructor); |
| 3610 | 3597 |
| 3611 return do_expr; | 3598 return do_expr; |
| 3612 } | 3599 } |
| 3613 | 3600 |
| 3614 Literal* Parser::GetLiteralUndefined(int position) { | 3601 Literal* Parser::GetLiteralUndefined(int position) { |
| 3615 return factory()->NewUndefinedLiteral(position); | 3602 return factory()->NewUndefinedLiteral(position); |
| 3616 } | 3603 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3648 } | 3635 } |
| 3649 const AstRawString* name = decl->proxy()->raw_name(); | 3636 const AstRawString* name = decl->proxy()->raw_name(); |
| 3650 Variable* parameter = function_scope->LookupLocal(name); | 3637 Variable* parameter = function_scope->LookupLocal(name); |
| 3651 if (parameter == nullptr) continue; | 3638 if (parameter == nullptr) continue; |
| 3652 VariableProxy* to = NewUnresolved(name); | 3639 VariableProxy* to = NewUnresolved(name); |
| 3653 VariableProxy* from = factory()->NewVariableProxy(parameter); | 3640 VariableProxy* from = factory()->NewVariableProxy(parameter); |
| 3654 Expression* assignment = | 3641 Expression* assignment = |
| 3655 factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition); | 3642 factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition); |
| 3656 Statement* statement = | 3643 Statement* statement = |
| 3657 factory()->NewExpressionStatement(assignment, kNoSourcePosition); | 3644 factory()->NewExpressionStatement(assignment, kNoSourcePosition); |
| 3658 inner_block->statements()->InsertAt(0, statement, zone()); | 3645 inner_block->statements()->push_front(statement); |
| 3659 } | 3646 } |
| 3660 } | 3647 } |
| 3661 | 3648 |
| 3662 void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope) { | 3649 void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope) { |
| 3663 // For the outermost eval scope, we cannot hoist during parsing: let | 3650 // For the outermost eval scope, we cannot hoist during parsing: let |
| 3664 // declarations in the surrounding scope may prevent hoisting, but the | 3651 // declarations in the surrounding scope may prevent hoisting, but the |
| 3665 // information is unaccessible during parsing. In this case, we hoist later in | 3652 // information is unaccessible during parsing. In this case, we hoist later in |
| 3666 // DeclarationScope::Analyze. | 3653 // DeclarationScope::Analyze. |
| 3667 if (scope->is_eval_scope() && scope->outer_scope() == original_scope_) { | 3654 if (scope->is_eval_scope() && scope->outer_scope() == original_scope_) { |
| 3668 return; | 3655 return; |
| (...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4099 Expression* expr = args->at(0); | 4086 Expression* expr = args->at(0); |
| 4100 for (int i = 1; i < args->length(); ++i) { | 4087 for (int i = 1; i < args->length(); ++i) { |
| 4101 expr = factory()->NewBinaryOperation(Token::COMMA, expr, args->at(i), | 4088 expr = factory()->NewBinaryOperation(Token::COMMA, expr, args->at(i), |
| 4102 expr->position()); | 4089 expr->position()); |
| 4103 } | 4090 } |
| 4104 return expr; | 4091 return expr; |
| 4105 } | 4092 } |
| 4106 | 4093 |
| 4107 // This method intoduces the line initializing the generator object | 4094 // This method intoduces the line initializing the generator object |
| 4108 // when desugaring the body of async_function. | 4095 // when desugaring the body of async_function. |
| 4109 void Parser::PrepareAsyncFunctionBody(ZoneList<Statement*>* body, | 4096 void Parser::PrepareAsyncFunctionBody(ZoneChunkList<Statement*>* body, |
| 4110 FunctionKind kind, int pos) { | 4097 FunctionKind kind, int pos) { |
| 4111 // function async_function() { | 4098 // function async_function() { |
| 4112 // .generator_object = %CreateGeneratorObject(); | 4099 // .generator_object = %CreateGeneratorObject(); |
| 4113 // BuildRejectPromiseOnException({ | 4100 // BuildRejectPromiseOnException({ |
| 4114 // ... block ... | 4101 // ... block ... |
| 4115 // return %ResolvePromise(.promise, expr), .promise; | 4102 // return %ResolvePromise(.promise, expr), .promise; |
| 4116 // }) | 4103 // }) |
| 4117 // } | 4104 // } |
| 4118 | 4105 |
| 4119 Variable* temp = | 4106 Variable* temp = |
| 4120 NewTemporary(ast_value_factory()->dot_generator_object_string()); | 4107 NewTemporary(ast_value_factory()->dot_generator_object_string()); |
| 4121 function_state_->set_generator_object_variable(temp); | 4108 function_state_->set_generator_object_variable(temp); |
| 4122 | 4109 |
| 4123 Expression* init_generator_variable = factory()->NewAssignment( | 4110 Expression* init_generator_variable = factory()->NewAssignment( |
| 4124 Token::INIT, factory()->NewVariableProxy(temp), | 4111 Token::INIT, factory()->NewVariableProxy(temp), |
| 4125 BuildCreateJSGeneratorObject(pos, kind), kNoSourcePosition); | 4112 BuildCreateJSGeneratorObject(pos, kind), kNoSourcePosition); |
| 4126 body->Add(factory()->NewExpressionStatement(init_generator_variable, | 4113 body->push_back(factory()->NewExpressionStatement(init_generator_variable, |
| 4127 kNoSourcePosition), | 4114 kNoSourcePosition)); |
| 4128 zone()); | |
| 4129 } | 4115 } |
| 4130 | 4116 |
| 4131 // This method completes the desugaring of the body of async_function. | 4117 // This method completes the desugaring of the body of async_function. |
| 4132 void Parser::RewriteAsyncFunctionBody(ZoneList<Statement*>* body, Block* block, | 4118 void Parser::RewriteAsyncFunctionBody(ZoneChunkList<Statement*>* body, |
| 4133 Expression* return_value, bool* ok) { | 4119 Block* block, Expression* return_value, |
| 4120 bool* ok) { |
| 4134 // function async_function() { | 4121 // function async_function() { |
| 4135 // .generator_object = %CreateGeneratorObject(); | 4122 // .generator_object = %CreateGeneratorObject(); |
| 4136 // BuildRejectPromiseOnException({ | 4123 // BuildRejectPromiseOnException({ |
| 4137 // ... block ... | 4124 // ... block ... |
| 4138 // return %ResolvePromise(.promise, expr), .promise; | 4125 // return %ResolvePromise(.promise, expr), .promise; |
| 4139 // }) | 4126 // }) |
| 4140 // } | 4127 // } |
| 4141 | 4128 |
| 4142 return_value = BuildResolvePromise(return_value, return_value->position()); | 4129 return_value = BuildResolvePromise(return_value, return_value->position()); |
| 4143 block->statements()->Add( | 4130 block->statements()->push_back( |
| 4144 factory()->NewReturnStatement(return_value, return_value->position()), | 4131 factory()->NewReturnStatement(return_value, return_value->position())); |
| 4145 zone()); | |
| 4146 block = BuildRejectPromiseOnException(block, CHECK_OK_VOID); | 4132 block = BuildRejectPromiseOnException(block, CHECK_OK_VOID); |
| 4147 body->Add(block, zone()); | 4133 body->push_back(block); |
| 4148 } | 4134 } |
| 4149 | 4135 |
| 4150 Expression* Parser::RewriteAwaitExpression(Expression* value, int await_pos) { | 4136 Expression* Parser::RewriteAwaitExpression(Expression* value, int await_pos) { |
| 4151 // yield do { | 4137 // yield do { |
| 4152 // tmp = <operand>; | 4138 // tmp = <operand>; |
| 4153 // %AsyncFunctionAwait(.generator_object, tmp, .promise); | 4139 // %AsyncFunctionAwait(.generator_object, tmp, .promise); |
| 4154 // .promise | 4140 // .promise |
| 4155 // } | 4141 // } |
| 4156 // The value of the expression is returned to the caller of the async | 4142 // The value of the expression is returned to the caller of the async |
| 4157 // function for the first yield statement; for this, .promise is the | 4143 // function for the first yield statement; for this, .promise is the |
| (...skipping 11 matching lines...) Expand all Loading... |
| 4169 // TODO(littledan): investigate why this ordering is needed in more detail. | 4155 // TODO(littledan): investigate why this ordering is needed in more detail. |
| 4170 Variable* generator_object_variable = | 4156 Variable* generator_object_variable = |
| 4171 function_state_->generator_object_variable(); | 4157 function_state_->generator_object_variable(); |
| 4172 | 4158 |
| 4173 // If generator_object_variable is null, | 4159 // If generator_object_variable is null, |
| 4174 // TODO(littledan): Is this necessary? | 4160 // TODO(littledan): Is this necessary? |
| 4175 if (!generator_object_variable) return value; | 4161 if (!generator_object_variable) return value; |
| 4176 | 4162 |
| 4177 const int nopos = kNoSourcePosition; | 4163 const int nopos = kNoSourcePosition; |
| 4178 | 4164 |
| 4179 Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos); | 4165 Block* do_block = factory()->NewBlock(nullptr, false, nopos); |
| 4180 | 4166 |
| 4181 Variable* promise = PromiseVariable(); | 4167 Variable* promise = PromiseVariable(); |
| 4182 | 4168 |
| 4183 // Wrap value evaluation to provide a break location. | 4169 // Wrap value evaluation to provide a break location. |
| 4184 Variable* temp_var = NewTemporary(ast_value_factory()->empty_string()); | 4170 Variable* temp_var = NewTemporary(ast_value_factory()->empty_string()); |
| 4185 Expression* value_assignment = factory()->NewAssignment( | 4171 Expression* value_assignment = factory()->NewAssignment( |
| 4186 Token::ASSIGN, factory()->NewVariableProxy(temp_var), value, nopos); | 4172 Token::ASSIGN, factory()->NewVariableProxy(temp_var), value, nopos); |
| 4187 do_block->statements()->Add( | 4173 do_block->statements()->push_back( |
| 4188 factory()->NewExpressionStatement(value_assignment, value->position()), | 4174 factory()->NewExpressionStatement(value_assignment, value->position())); |
| 4189 zone()); | |
| 4190 | 4175 |
| 4191 ZoneList<Expression*>* async_function_await_args = | 4176 ZoneList<Expression*>* async_function_await_args = |
| 4192 new (zone()) ZoneList<Expression*>(3, zone()); | 4177 new (zone()) ZoneList<Expression*>(3, zone()); |
| 4193 Expression* generator_object = | 4178 Expression* generator_object = |
| 4194 factory()->NewVariableProxy(generator_object_variable); | 4179 factory()->NewVariableProxy(generator_object_variable); |
| 4195 async_function_await_args->Add(generator_object, zone()); | 4180 async_function_await_args->Add(generator_object, zone()); |
| 4196 async_function_await_args->Add(factory()->NewVariableProxy(temp_var), zone()); | 4181 async_function_await_args->Add(factory()->NewVariableProxy(temp_var), zone()); |
| 4197 async_function_await_args->Add(factory()->NewVariableProxy(promise), zone()); | 4182 async_function_await_args->Add(factory()->NewVariableProxy(promise), zone()); |
| 4198 | 4183 |
| 4199 // The parser emits calls to AsyncFunctionAwaitCaught, but the | 4184 // The parser emits calls to AsyncFunctionAwaitCaught, but the |
| 4200 // AstNumberingVisitor will rewrite this to AsyncFunctionAwaitUncaught | 4185 // AstNumberingVisitor will rewrite this to AsyncFunctionAwaitUncaught |
| 4201 // if there is no local enclosing try/catch block. | 4186 // if there is no local enclosing try/catch block. |
| 4202 Expression* async_function_await = | 4187 Expression* async_function_await = |
| 4203 factory()->NewCallRuntime(Context::ASYNC_FUNCTION_AWAIT_CAUGHT_INDEX, | 4188 factory()->NewCallRuntime(Context::ASYNC_FUNCTION_AWAIT_CAUGHT_INDEX, |
| 4204 async_function_await_args, nopos); | 4189 async_function_await_args, nopos); |
| 4205 do_block->statements()->Add( | 4190 do_block->statements()->push_back( |
| 4206 factory()->NewExpressionStatement(async_function_await, await_pos), | 4191 factory()->NewExpressionStatement(async_function_await, await_pos)); |
| 4207 zone()); | |
| 4208 | 4192 |
| 4209 // Wrap await to provide a break location between value evaluation and yield. | 4193 // Wrap await to provide a break location between value evaluation and yield. |
| 4210 Expression* do_expr = factory()->NewDoExpression(do_block, promise, nopos); | 4194 Expression* do_expr = factory()->NewDoExpression(do_block, promise, nopos); |
| 4211 | 4195 |
| 4212 generator_object = factory()->NewVariableProxy(generator_object_variable); | 4196 generator_object = factory()->NewVariableProxy(generator_object_variable); |
| 4213 return factory()->NewYield(generator_object, do_expr, nopos, | 4197 return factory()->NewYield(generator_object, do_expr, nopos, |
| 4214 Yield::kOnExceptionRethrow); | 4198 Yield::kOnExceptionRethrow); |
| 4215 } | 4199 } |
| 4216 | 4200 |
| 4217 class NonPatternRewriter : public AstExpressionRewriter { | 4201 class NonPatternRewriter : public AstExpressionRewriter { |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4351 // } | 4335 // } |
| 4352 // where $R, $i and $j are fresh temporary variables. | 4336 // where $R, $i and $j are fresh temporary variables. |
| 4353 ZoneList<Expression*>::iterator s = lit->FirstSpread(); | 4337 ZoneList<Expression*>::iterator s = lit->FirstSpread(); |
| 4354 if (s == lit->EndValue()) return nullptr; // no spread, no rewriting... | 4338 if (s == lit->EndValue()) return nullptr; // no spread, no rewriting... |
| 4355 Variable* result = NewTemporary(ast_value_factory()->dot_result_string()); | 4339 Variable* result = NewTemporary(ast_value_factory()->dot_result_string()); |
| 4356 // NOTE: The value assigned to R is the whole original array literal, | 4340 // NOTE: The value assigned to R is the whole original array literal, |
| 4357 // spreads included. This will be fixed before the rewritten AST is returned. | 4341 // spreads included. This will be fixed before the rewritten AST is returned. |
| 4358 // $R = lit | 4342 // $R = lit |
| 4359 Expression* init_result = factory()->NewAssignment( | 4343 Expression* init_result = factory()->NewAssignment( |
| 4360 Token::INIT, factory()->NewVariableProxy(result), lit, kNoSourcePosition); | 4344 Token::INIT, factory()->NewVariableProxy(result), lit, kNoSourcePosition); |
| 4361 Block* do_block = factory()->NewBlock(nullptr, 16, false, kNoSourcePosition); | 4345 Block* do_block = factory()->NewBlock(nullptr, false, kNoSourcePosition); |
| 4362 do_block->statements()->Add( | 4346 do_block->statements()->push_back( |
| 4363 factory()->NewExpressionStatement(init_result, kNoSourcePosition), | 4347 factory()->NewExpressionStatement(init_result, kNoSourcePosition)); |
| 4364 zone()); | |
| 4365 // Traverse the array literal starting from the first spread. | 4348 // Traverse the array literal starting from the first spread. |
| 4366 while (s != lit->EndValue()) { | 4349 while (s != lit->EndValue()) { |
| 4367 Expression* value = *s++; | 4350 Expression* value = *s++; |
| 4368 Spread* spread = value->AsSpread(); | 4351 Spread* spread = value->AsSpread(); |
| 4369 if (spread == nullptr) { | 4352 if (spread == nullptr) { |
| 4370 // If the element is not a spread, we're adding a single: | 4353 // If the element is not a spread, we're adding a single: |
| 4371 // %AppendElement($R, value) | 4354 // %AppendElement($R, value) |
| 4372 // or, in case of a hole, | 4355 // or, in case of a hole, |
| 4373 // ++($R.length) | 4356 // ++($R.length) |
| 4374 if (!value->IsLiteral() || | 4357 if (!value->IsLiteral() || |
| 4375 !value->AsLiteral()->raw_value()->IsTheHole()) { | 4358 !value->AsLiteral()->raw_value()->IsTheHole()) { |
| 4376 ZoneList<Expression*>* append_element_args = NewExpressionList(2); | 4359 ZoneList<Expression*>* append_element_args = NewExpressionList(2); |
| 4377 append_element_args->Add(factory()->NewVariableProxy(result), zone()); | 4360 append_element_args->Add(factory()->NewVariableProxy(result), zone()); |
| 4378 append_element_args->Add(value, zone()); | 4361 append_element_args->Add(value, zone()); |
| 4379 do_block->statements()->Add( | 4362 do_block->statements()->push_back(factory()->NewExpressionStatement( |
| 4380 factory()->NewExpressionStatement( | 4363 factory()->NewCallRuntime(Runtime::kAppendElement, |
| 4381 factory()->NewCallRuntime(Runtime::kAppendElement, | 4364 append_element_args, kNoSourcePosition), |
| 4382 append_element_args, | 4365 kNoSourcePosition)); |
| 4383 kNoSourcePosition), | |
| 4384 kNoSourcePosition), | |
| 4385 zone()); | |
| 4386 } else { | 4366 } else { |
| 4387 Property* length_property = factory()->NewProperty( | 4367 Property* length_property = factory()->NewProperty( |
| 4388 factory()->NewVariableProxy(result), | 4368 factory()->NewVariableProxy(result), |
| 4389 factory()->NewStringLiteral(ast_value_factory()->length_string(), | 4369 factory()->NewStringLiteral(ast_value_factory()->length_string(), |
| 4390 kNoSourcePosition), | 4370 kNoSourcePosition), |
| 4391 kNoSourcePosition); | 4371 kNoSourcePosition); |
| 4392 CountOperation* count_op = factory()->NewCountOperation( | 4372 CountOperation* count_op = factory()->NewCountOperation( |
| 4393 Token::INC, true /* prefix */, length_property, kNoSourcePosition); | 4373 Token::INC, true /* prefix */, length_property, kNoSourcePosition); |
| 4394 do_block->statements()->Add( | 4374 do_block->statements()->push_back( |
| 4395 factory()->NewExpressionStatement(count_op, kNoSourcePosition), | 4375 factory()->NewExpressionStatement(count_op, kNoSourcePosition)); |
| 4396 zone()); | |
| 4397 } | 4376 } |
| 4398 } else { | 4377 } else { |
| 4399 // If it's a spread, we're adding a for/of loop iterating through it. | 4378 // If it's a spread, we're adding a for/of loop iterating through it. |
| 4400 Variable* each = NewTemporary(ast_value_factory()->dot_for_string()); | 4379 Variable* each = NewTemporary(ast_value_factory()->dot_for_string()); |
| 4401 Expression* subject = spread->expression(); | 4380 Expression* subject = spread->expression(); |
| 4402 // %AppendElement($R, each) | 4381 // %AppendElement($R, each) |
| 4403 Statement* append_body; | 4382 Statement* append_body; |
| 4404 { | 4383 { |
| 4405 ZoneList<Expression*>* append_element_args = NewExpressionList(2); | 4384 ZoneList<Expression*>* append_element_args = NewExpressionList(2); |
| 4406 append_element_args->Add(factory()->NewVariableProxy(result), zone()); | 4385 append_element_args->Add(factory()->NewVariableProxy(result), zone()); |
| 4407 append_element_args->Add(factory()->NewVariableProxy(each), zone()); | 4386 append_element_args->Add(factory()->NewVariableProxy(each), zone()); |
| 4408 append_body = factory()->NewExpressionStatement( | 4387 append_body = factory()->NewExpressionStatement( |
| 4409 factory()->NewCallRuntime(Runtime::kAppendElement, | 4388 factory()->NewCallRuntime(Runtime::kAppendElement, |
| 4410 append_element_args, kNoSourcePosition), | 4389 append_element_args, kNoSourcePosition), |
| 4411 kNoSourcePosition); | 4390 kNoSourcePosition); |
| 4412 } | 4391 } |
| 4413 // for (each of spread) %AppendElement($R, each) | 4392 // for (each of spread) %AppendElement($R, each) |
| 4414 ForEachStatement* loop = factory()->NewForEachStatement( | 4393 ForEachStatement* loop = factory()->NewForEachStatement( |
| 4415 ForEachStatement::ITERATE, nullptr, kNoSourcePosition); | 4394 ForEachStatement::ITERATE, nullptr, kNoSourcePosition); |
| 4416 const bool finalize = false; | 4395 const bool finalize = false; |
| 4417 InitializeForOfStatement(loop->AsForOfStatement(), | 4396 InitializeForOfStatement(loop->AsForOfStatement(), |
| 4418 factory()->NewVariableProxy(each), subject, | 4397 factory()->NewVariableProxy(each), subject, |
| 4419 append_body, finalize); | 4398 append_body, finalize); |
| 4420 do_block->statements()->Add(loop, zone()); | 4399 do_block->statements()->push_back(loop); |
| 4421 } | 4400 } |
| 4422 } | 4401 } |
| 4423 // Now, rewind the original array literal to truncate everything from the | 4402 // Now, rewind the original array literal to truncate everything from the |
| 4424 // first spread (included) until the end. This fixes $R's initialization. | 4403 // first spread (included) until the end. This fixes $R's initialization. |
| 4425 lit->RewindSpreads(); | 4404 lit->RewindSpreads(); |
| 4426 return factory()->NewDoExpression(do_block, result, lit->position()); | 4405 return factory()->NewDoExpression(do_block, result, lit->position()); |
| 4427 } | 4406 } |
| 4428 | 4407 |
| 4429 void Parser::QueueDestructuringAssignmentForRewriting(Expression* expr) { | 4408 void Parser::QueueDestructuringAssignmentForRewriting(Expression* expr) { |
| 4430 DCHECK(expr->IsRewritableExpression()); | 4409 DCHECK(expr->IsRewritableExpression()); |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4705 Statement* check_throw; | 4684 Statement* check_throw; |
| 4706 { | 4685 { |
| 4707 Expression* condition = factory()->NewCompareOperation( | 4686 Expression* condition = factory()->NewCompareOperation( |
| 4708 Token::EQ, factory()->NewVariableProxy(var_throw), | 4687 Token::EQ, factory()->NewVariableProxy(var_throw), |
| 4709 factory()->NewNullLiteral(nopos), nopos); | 4688 factory()->NewNullLiteral(nopos), nopos); |
| 4710 Expression* call = | 4689 Expression* call = |
| 4711 NewThrowTypeError(MessageTemplate::kThrowMethodMissing, | 4690 NewThrowTypeError(MessageTemplate::kThrowMethodMissing, |
| 4712 ast_value_factory()->empty_string(), nopos); | 4691 ast_value_factory()->empty_string(), nopos); |
| 4713 Statement* throw_call = factory()->NewExpressionStatement(call, nopos); | 4692 Statement* throw_call = factory()->NewExpressionStatement(call, nopos); |
| 4714 | 4693 |
| 4715 Block* then = factory()->NewBlock(nullptr, 4 + 1, false, nopos); | 4694 Block* then = factory()->NewBlock(nullptr, false, nopos); |
| 4716 BuildIteratorCloseForCompletion( | 4695 BuildIteratorCloseForCompletion( |
| 4717 then->statements(), var_iterator, | 4696 then->statements(), var_iterator, |
| 4718 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos)); | 4697 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos)); |
| 4719 then->statements()->Add(throw_call, zone()); | 4698 then->statements()->push_back(throw_call); |
| 4720 check_throw = factory()->NewIfStatement( | 4699 check_throw = factory()->NewIfStatement( |
| 4721 condition, then, factory()->NewEmptyStatement(nopos), nopos); | 4700 condition, then, factory()->NewEmptyStatement(nopos), nopos); |
| 4722 } | 4701 } |
| 4723 | 4702 |
| 4724 // output = %_Call(iteratorThrow, iterator, input); | 4703 // output = %_Call(iteratorThrow, iterator, input); |
| 4725 Statement* call_throw; | 4704 Statement* call_throw; |
| 4726 { | 4705 { |
| 4727 auto args = new (zone()) ZoneList<Expression*>(3, zone()); | 4706 auto args = new (zone()) ZoneList<Expression*>(3, zone()); |
| 4728 args->Add(factory()->NewVariableProxy(var_throw), zone()); | 4707 args->Add(factory()->NewVariableProxy(var_throw), zone()); |
| 4729 args->Add(factory()->NewVariableProxy(var_iterator), zone()); | 4708 args->Add(factory()->NewVariableProxy(var_iterator), zone()); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4855 factory()->NewStringLiteral(ast_value_factory()->value_string(), nopos); | 4834 factory()->NewStringLiteral(ast_value_factory()->value_string(), nopos); |
| 4856 Expression* property = factory()->NewProperty(output_proxy, literal, nopos); | 4835 Expression* property = factory()->NewProperty(output_proxy, literal, nopos); |
| 4857 get_value = factory()->NewExpressionStatement(property, nopos); | 4836 get_value = factory()->NewExpressionStatement(property, nopos); |
| 4858 } | 4837 } |
| 4859 | 4838 |
| 4860 // Now put things together. | 4839 // Now put things together. |
| 4861 | 4840 |
| 4862 // try { ... } catch(e) { ... } | 4841 // try { ... } catch(e) { ... } |
| 4863 Statement* try_catch; | 4842 Statement* try_catch; |
| 4864 { | 4843 { |
| 4865 Block* try_block = factory()->NewBlock(nullptr, 2, false, nopos); | 4844 Block* try_block = factory()->NewBlock(nullptr, false, nopos); |
| 4866 try_block->statements()->Add(yield_output, zone()); | 4845 try_block->statements()->push_back(yield_output); |
| 4867 try_block->statements()->Add(set_mode_next, zone()); | 4846 try_block->statements()->push_back(set_mode_next); |
| 4868 | 4847 |
| 4869 Block* catch_block = factory()->NewBlock(nullptr, 1, false, nopos); | 4848 Block* catch_block = factory()->NewBlock(nullptr, false, nopos); |
| 4870 catch_block->statements()->Add(set_mode_throw, zone()); | 4849 catch_block->statements()->push_back(set_mode_throw); |
| 4871 | 4850 |
| 4872 Scope* catch_scope = NewScope(CATCH_SCOPE); | 4851 Scope* catch_scope = NewScope(CATCH_SCOPE); |
| 4873 catch_scope->set_is_hidden(); | 4852 catch_scope->set_is_hidden(); |
| 4874 const AstRawString* name = ast_value_factory()->dot_catch_string(); | 4853 const AstRawString* name = ast_value_factory()->dot_catch_string(); |
| 4875 Variable* catch_variable = catch_scope->DeclareLocal( | 4854 Variable* catch_variable = catch_scope->DeclareLocal( |
| 4876 name, VAR, kCreatedInitialized, NORMAL_VARIABLE); | 4855 name, VAR, kCreatedInitialized, NORMAL_VARIABLE); |
| 4877 | 4856 |
| 4878 try_catch = factory()->NewTryCatchStatementForDesugaring( | 4857 try_catch = factory()->NewTryCatchStatementForDesugaring( |
| 4879 try_block, catch_scope, catch_variable, catch_block, nopos); | 4858 try_block, catch_scope, catch_variable, catch_block, nopos); |
| 4880 } | 4859 } |
| 4881 | 4860 |
| 4882 // try { ... } finally { ... } | 4861 // try { ... } finally { ... } |
| 4883 Statement* try_finally; | 4862 Statement* try_finally; |
| 4884 { | 4863 { |
| 4885 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); | 4864 Block* try_block = factory()->NewBlock(nullptr, false, nopos); |
| 4886 try_block->statements()->Add(try_catch, zone()); | 4865 try_block->statements()->push_back(try_catch); |
| 4887 | 4866 |
| 4888 Block* finally = factory()->NewBlock(nullptr, 2, false, nopos); | 4867 Block* finally = factory()->NewBlock(nullptr, false, nopos); |
| 4889 finally->statements()->Add(get_input, zone()); | 4868 finally->statements()->push_back(get_input); |
| 4890 finally->statements()->Add(factory()->NewContinueStatement(loop, nopos), | 4869 finally->statements()->push_back( |
| 4891 zone()); | 4870 factory()->NewContinueStatement(loop, nopos)); |
| 4892 | 4871 |
| 4893 try_finally = factory()->NewTryFinallyStatement(try_block, finally, nopos); | 4872 try_finally = factory()->NewTryFinallyStatement(try_block, finally, nopos); |
| 4894 } | 4873 } |
| 4895 | 4874 |
| 4896 // switch (mode) { ... } | 4875 // switch (mode) { ... } |
| 4897 SwitchStatement* switch_mode = factory()->NewSwitchStatement(nullptr, nopos); | 4876 SwitchStatement* switch_mode = factory()->NewSwitchStatement(nullptr, nopos); |
| 4898 { | 4877 { |
| 4899 auto case_next = new (zone()) ZoneList<Statement*>(3, zone()); | 4878 auto case_next = new (zone()) ZoneChunkList<Statement*>(zone()); |
| 4900 case_next->Add(call_next, zone()); | 4879 case_next->push_back(call_next); |
| 4901 case_next->Add(validate_next_output, zone()); | 4880 case_next->push_back(validate_next_output); |
| 4902 case_next->Add(factory()->NewBreakStatement(switch_mode, nopos), zone()); | 4881 case_next->push_back(factory()->NewBreakStatement(switch_mode, nopos)); |
| 4903 | 4882 |
| 4904 auto case_return = new (zone()) ZoneList<Statement*>(5, zone()); | 4883 auto case_return = new (zone()) ZoneChunkList<Statement*>(zone()); |
| 4905 BuildIteratorClose(case_return, var_iterator, var_input, var_output); | 4884 BuildIteratorClose(case_return, var_iterator, var_input, var_output); |
| 4906 case_return->Add(factory()->NewBreakStatement(switch_mode, nopos), zone()); | 4885 case_return->push_back(factory()->NewBreakStatement(switch_mode, nopos)); |
| 4907 | 4886 |
| 4908 auto case_throw = new (zone()) ZoneList<Statement*>(5, zone()); | 4887 auto case_throw = new (zone()) ZoneChunkList<Statement*>(zone()); |
| 4909 case_throw->Add(get_throw, zone()); | 4888 case_throw->push_back(get_throw); |
| 4910 case_throw->Add(check_throw, zone()); | 4889 case_throw->push_back(check_throw); |
| 4911 case_throw->Add(call_throw, zone()); | 4890 case_throw->push_back(call_throw); |
| 4912 case_throw->Add(validate_throw_output, zone()); | 4891 case_throw->push_back(validate_throw_output); |
| 4913 case_throw->Add(factory()->NewBreakStatement(switch_mode, nopos), zone()); | 4892 case_throw->push_back(factory()->NewBreakStatement(switch_mode, nopos)); |
| 4914 | 4893 |
| 4915 auto cases = new (zone()) ZoneList<CaseClause*>(3, zone()); | 4894 auto cases = new (zone()) ZoneList<CaseClause*>(3, zone()); |
| 4916 Expression* knext = | 4895 Expression* knext = |
| 4917 factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos); | 4896 factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos); |
| 4918 Expression* kreturn = | 4897 Expression* kreturn = |
| 4919 factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos); | 4898 factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos); |
| 4920 Expression* kthrow = | 4899 Expression* kthrow = |
| 4921 factory()->NewSmiLiteral(JSGeneratorObject::kThrow, nopos); | 4900 factory()->NewSmiLiteral(JSGeneratorObject::kThrow, nopos); |
| 4922 cases->Add(factory()->NewCaseClause(knext, case_next, nopos), zone()); | 4901 cases->Add(factory()->NewCaseClause(knext, case_next, nopos), zone()); |
| 4923 cases->Add(factory()->NewCaseClause(kreturn, case_return, nopos), zone()); | 4902 cases->Add(factory()->NewCaseClause(kreturn, case_return, nopos), zone()); |
| 4924 cases->Add(factory()->NewCaseClause(kthrow, case_throw, nopos), zone()); | 4903 cases->Add(factory()->NewCaseClause(kthrow, case_throw, nopos), zone()); |
| 4925 | 4904 |
| 4926 switch_mode->Initialize(factory()->NewVariableProxy(var_mode), cases); | 4905 switch_mode->Initialize(factory()->NewVariableProxy(var_mode), cases); |
| 4927 } | 4906 } |
| 4928 | 4907 |
| 4929 // while (true) { ... } | 4908 // while (true) { ... } |
| 4930 // Already defined earlier: WhileStatement* loop = ... | 4909 // Already defined earlier: WhileStatement* loop = ... |
| 4931 { | 4910 { |
| 4932 Block* loop_body = factory()->NewBlock(nullptr, 4, false, nopos); | 4911 Block* loop_body = factory()->NewBlock(nullptr, false, nopos); |
| 4933 loop_body->statements()->Add(switch_mode, zone()); | 4912 loop_body->statements()->push_back(switch_mode); |
| 4934 loop_body->statements()->Add(if_done, zone()); | 4913 loop_body->statements()->push_back(if_done); |
| 4935 loop_body->statements()->Add(set_mode_return, zone()); | 4914 loop_body->statements()->push_back(set_mode_return); |
| 4936 loop_body->statements()->Add(try_finally, zone()); | 4915 loop_body->statements()->push_back(try_finally); |
| 4937 | 4916 |
| 4938 loop->Initialize(factory()->NewBooleanLiteral(true, nopos), loop_body); | 4917 loop->Initialize(factory()->NewBooleanLiteral(true, nopos), loop_body); |
| 4939 } | 4918 } |
| 4940 | 4919 |
| 4941 // do { ... } | 4920 // do { ... } |
| 4942 DoExpression* yield_star; | 4921 DoExpression* yield_star; |
| 4943 { | 4922 { |
| 4944 // The rewriter needs to process the get_value statement only, hence we | 4923 // The rewriter needs to process the get_value statement only, hence we |
| 4945 // put the preceding statements into an init block. | 4924 // put the preceding statements into an init block. |
| 4946 | 4925 |
| 4947 Block* do_block_ = factory()->NewBlock(nullptr, 7, true, nopos); | 4926 Block* do_block_ = factory()->NewBlock(nullptr, true, nopos); |
| 4948 do_block_->statements()->Add(initialize_input, zone()); | 4927 do_block_->statements()->push_back(initialize_input); |
| 4949 do_block_->statements()->Add(initialize_mode, zone()); | 4928 do_block_->statements()->push_back(initialize_mode); |
| 4950 do_block_->statements()->Add(initialize_output, zone()); | 4929 do_block_->statements()->push_back(initialize_output); |
| 4951 do_block_->statements()->Add(get_iterator, zone()); | 4930 do_block_->statements()->push_back(get_iterator); |
| 4952 do_block_->statements()->Add(validate_iterator, zone()); | 4931 do_block_->statements()->push_back(validate_iterator); |
| 4953 do_block_->statements()->Add(loop, zone()); | 4932 do_block_->statements()->push_back(loop); |
| 4954 do_block_->statements()->Add(maybe_return_value, zone()); | 4933 do_block_->statements()->push_back(maybe_return_value); |
| 4955 | 4934 |
| 4956 Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos); | 4935 Block* do_block = factory()->NewBlock(nullptr, false, nopos); |
| 4957 do_block->statements()->Add(do_block_, zone()); | 4936 do_block->statements()->push_back(do_block_); |
| 4958 do_block->statements()->Add(get_value, zone()); | 4937 do_block->statements()->push_back(get_value); |
| 4959 | 4938 |
| 4960 Variable* dot_result = | 4939 Variable* dot_result = |
| 4961 NewTemporary(ast_value_factory()->dot_result_string()); | 4940 NewTemporary(ast_value_factory()->dot_result_string()); |
| 4962 yield_star = factory()->NewDoExpression(do_block, dot_result, nopos); | 4941 yield_star = factory()->NewDoExpression(do_block, dot_result, nopos); |
| 4963 Rewriter::Rewrite(this, GetClosureScope(), yield_star, ast_value_factory()); | 4942 Rewriter::Rewrite(this, GetClosureScope(), yield_star, ast_value_factory()); |
| 4964 } | 4943 } |
| 4965 | 4944 |
| 4966 return yield_star; | 4945 return yield_star; |
| 4967 } | 4946 } |
| 4968 | 4947 |
| 4969 Statement* Parser::CheckCallable(Variable* var, Expression* error, int pos) { | 4948 Statement* Parser::CheckCallable(Variable* var, Expression* error, int pos) { |
| 4970 const int nopos = kNoSourcePosition; | 4949 const int nopos = kNoSourcePosition; |
| 4971 Statement* validate_var; | 4950 Statement* validate_var; |
| 4972 { | 4951 { |
| 4973 Expression* type_of = factory()->NewUnaryOperation( | 4952 Expression* type_of = factory()->NewUnaryOperation( |
| 4974 Token::TYPEOF, factory()->NewVariableProxy(var), nopos); | 4953 Token::TYPEOF, factory()->NewVariableProxy(var), nopos); |
| 4975 Expression* function_literal = factory()->NewStringLiteral( | 4954 Expression* function_literal = factory()->NewStringLiteral( |
| 4976 ast_value_factory()->function_string(), nopos); | 4955 ast_value_factory()->function_string(), nopos); |
| 4977 Expression* condition = factory()->NewCompareOperation( | 4956 Expression* condition = factory()->NewCompareOperation( |
| 4978 Token::EQ_STRICT, type_of, function_literal, nopos); | 4957 Token::EQ_STRICT, type_of, function_literal, nopos); |
| 4979 | 4958 |
| 4980 Statement* throw_call = factory()->NewExpressionStatement(error, pos); | 4959 Statement* throw_call = factory()->NewExpressionStatement(error, pos); |
| 4981 | 4960 |
| 4982 validate_var = factory()->NewIfStatement( | 4961 validate_var = factory()->NewIfStatement( |
| 4983 condition, factory()->NewEmptyStatement(nopos), throw_call, nopos); | 4962 condition, factory()->NewEmptyStatement(nopos), throw_call, nopos); |
| 4984 } | 4963 } |
| 4985 return validate_var; | 4964 return validate_var; |
| 4986 } | 4965 } |
| 4987 | 4966 |
| 4988 void Parser::BuildIteratorClose(ZoneList<Statement*>* statements, | 4967 void Parser::BuildIteratorClose(ZoneChunkList<Statement*>* statements, |
| 4989 Variable* iterator, Variable* input, | 4968 Variable* iterator, Variable* input, |
| 4990 Variable* var_output) { | 4969 Variable* var_output) { |
| 4991 // | 4970 // |
| 4992 // This function adds four statements to [statements], corresponding to the | 4971 // This function adds four statements to [statements], corresponding to the |
| 4993 // following code: | 4972 // following code: |
| 4994 // | 4973 // |
| 4995 // let iteratorReturn = iterator.return; | 4974 // let iteratorReturn = iterator.return; |
| 4996 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) { | 4975 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) { |
| 4997 // return {value: input, done: true}; | 4976 // return {value: input, done: true}; |
| 4998 // } | 4977 // } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5069 Expression* call = factory()->NewCallRuntime( | 5048 Expression* call = factory()->NewCallRuntime( |
| 5070 Runtime::kThrowIteratorResultNotAnObject, args, nopos); | 5049 Runtime::kThrowIteratorResultNotAnObject, args, nopos); |
| 5071 throw_call = factory()->NewExpressionStatement(call, nopos); | 5050 throw_call = factory()->NewExpressionStatement(call, nopos); |
| 5072 } | 5051 } |
| 5073 | 5052 |
| 5074 validate_output = factory()->NewIfStatement( | 5053 validate_output = factory()->NewIfStatement( |
| 5075 is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call, | 5054 is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call, |
| 5076 nopos); | 5055 nopos); |
| 5077 } | 5056 } |
| 5078 | 5057 |
| 5079 statements->Add(get_return, zone()); | 5058 statements->push_back(get_return); |
| 5080 statements->Add(check_return, zone()); | 5059 statements->push_back(check_return); |
| 5081 statements->Add(call_return, zone()); | 5060 statements->push_back(call_return); |
| 5082 statements->Add(validate_output, zone()); | 5061 statements->push_back(validate_output); |
| 5083 } | 5062 } |
| 5084 | 5063 |
| 5085 void Parser::FinalizeIteratorUse(Variable* completion, Expression* condition, | 5064 void Parser::FinalizeIteratorUse(Variable* completion, Expression* condition, |
| 5086 Variable* iter, Block* iterator_use, | 5065 Variable* iter, Block* iterator_use, |
| 5087 Block* target) { | 5066 Block* target) { |
| 5088 // | 5067 // |
| 5089 // This function adds two statements to [target], corresponding to the | 5068 // This function adds two statements to [target], corresponding to the |
| 5090 // following code: | 5069 // following code: |
| 5091 // | 5070 // |
| 5092 // completion = kNormalCompletion; | 5071 // completion = kNormalCompletion; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5131 Statement* statement = factory()->NewExpressionStatement(assignment, nopos); | 5110 Statement* statement = factory()->NewExpressionStatement(assignment, nopos); |
| 5132 set_completion_throw = factory()->NewIfStatement( | 5111 set_completion_throw = factory()->NewIfStatement( |
| 5133 condition, statement, factory()->NewEmptyStatement(nopos), nopos); | 5112 condition, statement, factory()->NewEmptyStatement(nopos), nopos); |
| 5134 } | 5113 } |
| 5135 | 5114 |
| 5136 // if (condition) { | 5115 // if (condition) { |
| 5137 // #BuildIteratorCloseForCompletion(iter, completion) | 5116 // #BuildIteratorCloseForCompletion(iter, completion) |
| 5138 // } | 5117 // } |
| 5139 Block* maybe_close; | 5118 Block* maybe_close; |
| 5140 { | 5119 { |
| 5141 Block* block = factory()->NewBlock(nullptr, 2, true, nopos); | 5120 Block* block = factory()->NewBlock(nullptr, true, nopos); |
| 5142 Expression* proxy = factory()->NewVariableProxy(completion); | 5121 Expression* proxy = factory()->NewVariableProxy(completion); |
| 5143 BuildIteratorCloseForCompletion(block->statements(), iter, proxy); | 5122 BuildIteratorCloseForCompletion(block->statements(), iter, proxy); |
| 5144 DCHECK(block->statements()->length() == 2); | 5123 DCHECK(block->statements()->size() == 2); |
| 5145 | 5124 |
| 5146 maybe_close = factory()->NewBlock(nullptr, 1, true, nopos); | 5125 maybe_close = factory()->NewBlock(nullptr, true, nopos); |
| 5147 maybe_close->statements()->Add( | 5126 maybe_close->statements()->push_back(factory()->NewIfStatement( |
| 5148 factory()->NewIfStatement(condition, block, | 5127 condition, block, factory()->NewEmptyStatement(nopos), nopos)); |
| 5149 factory()->NewEmptyStatement(nopos), nopos), | |
| 5150 zone()); | |
| 5151 } | 5128 } |
| 5152 | 5129 |
| 5153 // try { #try_block } | 5130 // try { #try_block } |
| 5154 // catch(e) { | 5131 // catch(e) { |
| 5155 // #set_completion_throw; | 5132 // #set_completion_throw; |
| 5156 // %ReThrow(e); | 5133 // %ReThrow(e); |
| 5157 // } | 5134 // } |
| 5158 Statement* try_catch; | 5135 Statement* try_catch; |
| 5159 { | 5136 { |
| 5160 Scope* catch_scope = NewScopeWithParent(scope(), CATCH_SCOPE); | 5137 Scope* catch_scope = NewScopeWithParent(scope(), CATCH_SCOPE); |
| 5161 Variable* catch_variable = | 5138 Variable* catch_variable = |
| 5162 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR, | 5139 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR, |
| 5163 kCreatedInitialized, NORMAL_VARIABLE); | 5140 kCreatedInitialized, NORMAL_VARIABLE); |
| 5164 catch_scope->set_is_hidden(); | 5141 catch_scope->set_is_hidden(); |
| 5165 | 5142 |
| 5166 Statement* rethrow; | 5143 Statement* rethrow; |
| 5167 // We use %ReThrow rather than the ordinary throw because we want to | 5144 // We use %ReThrow rather than the ordinary throw because we want to |
| 5168 // preserve the original exception message. This is also why we create a | 5145 // preserve the original exception message. This is also why we create a |
| 5169 // TryCatchStatementForReThrow below (which does not clear the pending | 5146 // TryCatchStatementForReThrow below (which does not clear the pending |
| 5170 // message), rather than a TryCatchStatement. | 5147 // message), rather than a TryCatchStatement. |
| 5171 { | 5148 { |
| 5172 auto args = new (zone()) ZoneList<Expression*>(1, zone()); | 5149 auto args = new (zone()) ZoneList<Expression*>(1, zone()); |
| 5173 args->Add(factory()->NewVariableProxy(catch_variable), zone()); | 5150 args->Add(factory()->NewVariableProxy(catch_variable), zone()); |
| 5174 rethrow = factory()->NewExpressionStatement( | 5151 rethrow = factory()->NewExpressionStatement( |
| 5175 factory()->NewCallRuntime(Runtime::kReThrow, args, nopos), nopos); | 5152 factory()->NewCallRuntime(Runtime::kReThrow, args, nopos), nopos); |
| 5176 } | 5153 } |
| 5177 | 5154 |
| 5178 Block* catch_block = factory()->NewBlock(nullptr, 2, false, nopos); | 5155 Block* catch_block = factory()->NewBlock(nullptr, false, nopos); |
| 5179 catch_block->statements()->Add(set_completion_throw, zone()); | 5156 catch_block->statements()->push_back(set_completion_throw); |
| 5180 catch_block->statements()->Add(rethrow, zone()); | 5157 catch_block->statements()->push_back(rethrow); |
| 5181 | 5158 |
| 5182 try_catch = factory()->NewTryCatchStatementForReThrow( | 5159 try_catch = factory()->NewTryCatchStatementForReThrow( |
| 5183 iterator_use, catch_scope, catch_variable, catch_block, nopos); | 5160 iterator_use, catch_scope, catch_variable, catch_block, nopos); |
| 5184 } | 5161 } |
| 5185 | 5162 |
| 5186 // try { #try_catch } finally { #maybe_close } | 5163 // try { #try_catch } finally { #maybe_close } |
| 5187 Statement* try_finally; | 5164 Statement* try_finally; |
| 5188 { | 5165 { |
| 5189 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); | 5166 Block* try_block = factory()->NewBlock(nullptr, false, nopos); |
| 5190 try_block->statements()->Add(try_catch, zone()); | 5167 try_block->statements()->push_back(try_catch); |
| 5191 | 5168 |
| 5192 try_finally = | 5169 try_finally = |
| 5193 factory()->NewTryFinallyStatement(try_block, maybe_close, nopos); | 5170 factory()->NewTryFinallyStatement(try_block, maybe_close, nopos); |
| 5194 } | 5171 } |
| 5195 | 5172 |
| 5196 target->statements()->Add(initialize_completion, zone()); | 5173 target->statements()->push_back(initialize_completion); |
| 5197 target->statements()->Add(try_finally, zone()); | 5174 target->statements()->push_back(try_finally); |
| 5198 } | 5175 } |
| 5199 | 5176 |
| 5200 void Parser::BuildIteratorCloseForCompletion(ZoneList<Statement*>* statements, | 5177 void Parser::BuildIteratorCloseForCompletion( |
| 5201 Variable* iterator, | 5178 ZoneChunkList<Statement*>* statements, Variable* iterator, |
| 5202 Expression* completion) { | 5179 Expression* completion) { |
| 5203 // | 5180 // |
| 5204 // This function adds two statements to [statements], corresponding to the | 5181 // This function adds two statements to [statements], corresponding to the |
| 5205 // following code: | 5182 // following code: |
| 5206 // | 5183 // |
| 5207 // let iteratorReturn = iterator.return; | 5184 // let iteratorReturn = iterator.return; |
| 5208 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { | 5185 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { |
| 5209 // if (completion === kThrowCompletion) { | 5186 // if (completion === kThrowCompletion) { |
| 5210 // if (!IS_CALLABLE(iteratorReturn)) { | 5187 // if (!IS_CALLABLE(iteratorReturn)) { |
| 5211 // throw MakeTypeError(kReturnMethodNotCallable); | 5188 // throw MakeTypeError(kReturnMethodNotCallable); |
| 5212 // } | 5189 // } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5250 // try { %_Call(iteratorReturn, iterator) } catch (_) { } | 5227 // try { %_Call(iteratorReturn, iterator) } catch (_) { } |
| 5251 Statement* try_call_return; | 5228 Statement* try_call_return; |
| 5252 { | 5229 { |
| 5253 auto args = new (zone()) ZoneList<Expression*>(2, zone()); | 5230 auto args = new (zone()) ZoneList<Expression*>(2, zone()); |
| 5254 args->Add(factory()->NewVariableProxy(var_return), zone()); | 5231 args->Add(factory()->NewVariableProxy(var_return), zone()); |
| 5255 args->Add(factory()->NewVariableProxy(iterator), zone()); | 5232 args->Add(factory()->NewVariableProxy(iterator), zone()); |
| 5256 | 5233 |
| 5257 Expression* call = | 5234 Expression* call = |
| 5258 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); | 5235 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); |
| 5259 | 5236 |
| 5260 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); | 5237 Block* try_block = factory()->NewBlock(nullptr, false, nopos); |
| 5261 try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos), | 5238 try_block->statements()->push_back( |
| 5262 zone()); | 5239 factory()->NewExpressionStatement(call, nopos)); |
| 5263 | 5240 |
| 5264 Block* catch_block = factory()->NewBlock(nullptr, 0, false, nopos); | 5241 Block* catch_block = factory()->NewBlock(nullptr, false, nopos); |
| 5265 | 5242 |
| 5266 Scope* catch_scope = NewScope(CATCH_SCOPE); | 5243 Scope* catch_scope = NewScope(CATCH_SCOPE); |
| 5267 Variable* catch_variable = | 5244 Variable* catch_variable = |
| 5268 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR, | 5245 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR, |
| 5269 kCreatedInitialized, NORMAL_VARIABLE); | 5246 kCreatedInitialized, NORMAL_VARIABLE); |
| 5270 catch_scope->set_is_hidden(); | 5247 catch_scope->set_is_hidden(); |
| 5271 | 5248 |
| 5272 try_call_return = factory()->NewTryCatchStatement( | 5249 try_call_return = factory()->NewTryCatchStatement( |
| 5273 try_block, catch_scope, catch_variable, catch_block, nopos); | 5250 try_block, catch_scope, catch_variable, catch_block, nopos); |
| 5274 } | 5251 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5308 args->Add(factory()->NewVariableProxy(var_output), zone()); | 5285 args->Add(factory()->NewVariableProxy(var_output), zone()); |
| 5309 Expression* call = factory()->NewCallRuntime( | 5286 Expression* call = factory()->NewCallRuntime( |
| 5310 Runtime::kThrowIteratorResultNotAnObject, args, nopos); | 5287 Runtime::kThrowIteratorResultNotAnObject, args, nopos); |
| 5311 throw_call = factory()->NewExpressionStatement(call, nopos); | 5288 throw_call = factory()->NewExpressionStatement(call, nopos); |
| 5312 } | 5289 } |
| 5313 | 5290 |
| 5314 Statement* check_return = factory()->NewIfStatement( | 5291 Statement* check_return = factory()->NewIfStatement( |
| 5315 is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call, | 5292 is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call, |
| 5316 nopos); | 5293 nopos); |
| 5317 | 5294 |
| 5318 validate_return = factory()->NewBlock(nullptr, 2, false, nopos); | 5295 validate_return = factory()->NewBlock(nullptr, false, nopos); |
| 5319 validate_return->statements()->Add(call_return, zone()); | 5296 validate_return->statements()->push_back(call_return); |
| 5320 validate_return->statements()->Add(check_return, zone()); | 5297 validate_return->statements()->push_back(check_return); |
| 5321 } | 5298 } |
| 5322 | 5299 |
| 5323 // if (completion === kThrowCompletion) { | 5300 // if (completion === kThrowCompletion) { |
| 5324 // #check_return_callable; | 5301 // #check_return_callable; |
| 5325 // #try_call_return; | 5302 // #try_call_return; |
| 5326 // } else { | 5303 // } else { |
| 5327 // #validate_return; | 5304 // #validate_return; |
| 5328 // } | 5305 // } |
| 5329 Statement* call_return_carefully; | 5306 Statement* call_return_carefully; |
| 5330 { | 5307 { |
| 5331 Expression* condition = factory()->NewCompareOperation( | 5308 Expression* condition = factory()->NewCompareOperation( |
| 5332 Token::EQ_STRICT, completion, | 5309 Token::EQ_STRICT, completion, |
| 5333 factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos); | 5310 factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos); |
| 5334 | 5311 |
| 5335 Block* then_block = factory()->NewBlock(nullptr, 2, false, nopos); | 5312 Block* then_block = factory()->NewBlock(nullptr, false, nopos); |
| 5336 then_block->statements()->Add(check_return_callable, zone()); | 5313 then_block->statements()->push_back(check_return_callable); |
| 5337 then_block->statements()->Add(try_call_return, zone()); | 5314 then_block->statements()->push_back(try_call_return); |
| 5338 | 5315 |
| 5339 call_return_carefully = factory()->NewIfStatement(condition, then_block, | 5316 call_return_carefully = factory()->NewIfStatement(condition, then_block, |
| 5340 validate_return, nopos); | 5317 validate_return, nopos); |
| 5341 } | 5318 } |
| 5342 | 5319 |
| 5343 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... } | 5320 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... } |
| 5344 Statement* maybe_call_return; | 5321 Statement* maybe_call_return; |
| 5345 { | 5322 { |
| 5346 Expression* condition = factory()->NewCompareOperation( | 5323 Expression* condition = factory()->NewCompareOperation( |
| 5347 Token::EQ, factory()->NewVariableProxy(var_return), | 5324 Token::EQ, factory()->NewVariableProxy(var_return), |
| 5348 factory()->NewNullLiteral(nopos), nopos); | 5325 factory()->NewNullLiteral(nopos), nopos); |
| 5349 | 5326 |
| 5350 maybe_call_return = factory()->NewIfStatement( | 5327 maybe_call_return = factory()->NewIfStatement( |
| 5351 condition, factory()->NewEmptyStatement(nopos), call_return_carefully, | 5328 condition, factory()->NewEmptyStatement(nopos), call_return_carefully, |
| 5352 nopos); | 5329 nopos); |
| 5353 } | 5330 } |
| 5354 | 5331 |
| 5355 statements->Add(get_return, zone()); | 5332 statements->push_back(get_return); |
| 5356 statements->Add(maybe_call_return, zone()); | 5333 statements->push_back(maybe_call_return); |
| 5357 } | 5334 } |
| 5358 | 5335 |
| 5359 Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop, | 5336 Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop, |
| 5360 Variable* var_completion, int pos) { | 5337 Variable* var_completion, int pos) { |
| 5361 // | 5338 // |
| 5362 // This function replaces the loop with the following wrapping: | 5339 // This function replaces the loop with the following wrapping: |
| 5363 // | 5340 // |
| 5364 // completion = kNormalCompletion; | 5341 // completion = kNormalCompletion; |
| 5365 // try { | 5342 // try { |
| 5366 // try { | 5343 // try { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 5388 Token::EQ_STRICT, factory()->NewVariableProxy(var_completion), | 5365 Token::EQ_STRICT, factory()->NewVariableProxy(var_completion), |
| 5389 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); | 5366 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); |
| 5390 Expression* rhs = factory()->NewCompareOperation( | 5367 Expression* rhs = factory()->NewCompareOperation( |
| 5391 Token::EQ_STRICT, factory()->NewVariableProxy(loop->iterator()), | 5368 Token::EQ_STRICT, factory()->NewVariableProxy(loop->iterator()), |
| 5392 factory()->NewUndefinedLiteral(nopos), nopos); | 5369 factory()->NewUndefinedLiteral(nopos), nopos); |
| 5393 closing_condition = factory()->NewUnaryOperation( | 5370 closing_condition = factory()->NewUnaryOperation( |
| 5394 Token::NOT, factory()->NewBinaryOperation(Token::OR, lhs, rhs, nopos), | 5371 Token::NOT, factory()->NewBinaryOperation(Token::OR, lhs, rhs, nopos), |
| 5395 nopos); | 5372 nopos); |
| 5396 } | 5373 } |
| 5397 | 5374 |
| 5398 Block* final_loop = factory()->NewBlock(nullptr, 2, false, nopos); | 5375 Block* final_loop = factory()->NewBlock(nullptr, false, nopos); |
| 5399 { | 5376 { |
| 5400 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); | 5377 Block* try_block = factory()->NewBlock(nullptr, false, nopos); |
| 5401 try_block->statements()->Add(loop, zone()); | 5378 try_block->statements()->push_back(loop); |
| 5402 | 5379 |
| 5403 FinalizeIteratorUse(var_completion, closing_condition, loop->iterator(), | 5380 FinalizeIteratorUse(var_completion, closing_condition, loop->iterator(), |
| 5404 try_block, final_loop); | 5381 try_block, final_loop); |
| 5405 } | 5382 } |
| 5406 | 5383 |
| 5407 return final_loop; | 5384 return final_loop; |
| 5408 } | 5385 } |
| 5409 | 5386 |
| 5410 #undef CHECK_OK | 5387 #undef CHECK_OK |
| 5411 #undef CHECK_OK_VOID | 5388 #undef CHECK_OK_VOID |
| 5412 #undef CHECK_FAILED | 5389 #undef CHECK_FAILED |
| 5413 | 5390 |
| 5414 } // namespace internal | 5391 } // namespace internal |
| 5415 } // namespace v8 | 5392 } // namespace v8 |
| OLD | NEW |