Index: src/parsing/parser-base.h |
diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h |
index 18366443b70c1955069e97ec1026fb9d2ce493d7..7b7d356454af04942dec6d0e350639960e38f45f 100644 |
--- a/src/parsing/parser-base.h |
+++ b/src/parsing/parser-base.h |
@@ -425,25 +425,6 @@ class ParserBase { |
FunctionKind kind() const { return scope()->function_kind(); } |
FunctionState* outer() const { return outer_function_state_; } |
- void set_generator_object_variable(typename Types::Variable* variable) { |
- DCHECK_NOT_NULL(variable); |
- DCHECK(IsResumableFunction(kind())); |
- DCHECK(scope()->has_forced_context_allocation()); |
- generator_object_variable_ = variable; |
- } |
- typename Types::Variable* generator_object_variable() const { |
- return generator_object_variable_; |
- } |
- |
- void set_promise_variable(typename Types::Variable* variable) { |
- DCHECK(variable != NULL); |
- DCHECK(IsAsyncFunction(kind())); |
- promise_variable_ = variable; |
- } |
- typename Types::Variable* promise_variable() const { |
- return promise_variable_; |
- } |
- |
const ZoneList<DestructuringAssignment>& |
destructuring_assignments_to_rewrite() const { |
return destructuring_assignments_to_rewrite_; |
@@ -506,14 +487,6 @@ class ParserBase { |
// Properties count estimation. |
int expected_property_count_; |
- // For generators, this variable may hold the generator object. It variable |
- // is used by yield expressions and return statements. It is not necessary |
- // for generator functions to have this variable set. |
- Variable* generator_object_variable_; |
- // For async functions, this variable holds a temporary for the Promise |
- // being created as output of the async function. |
- Variable* promise_variable_; |
- |
FunctionState** function_state_stack_; |
FunctionState* outer_function_state_; |
@@ -739,6 +712,7 @@ class ParserBase { |
if (!IsArrowFunction(kind)) { |
result->DeclareDefaultFunctionVariables(ast_value_factory()); |
} |
+ |
return result; |
} |
@@ -1196,9 +1170,6 @@ class ParserBase { |
ExpressionT ParseArrowFunctionLiteral(bool accept_IN, |
const FormalParametersT& parameters, |
bool* ok); |
- void ParseAsyncFunctionBody(Scope* scope, StatementListT body, |
- FunctionKind kind, FunctionBodyType type, |
- bool accept_IN, int pos, bool* ok); |
ExpressionT ParseAsyncFunctionLiteral(bool* ok); |
ExpressionT ParseClassLiteral(IdentifierT name, |
Scanner::Location class_name_location, |
@@ -1231,9 +1202,9 @@ class ParserBase { |
StatementT ParseNativeDeclaration(bool* ok); |
// Consumes the ending }. |
- void ParseFunctionBody(StatementListT result, IdentifierT function_name, |
- int pos, const FormalParametersT& parameters, |
- FunctionKind kind, |
+ void ParseFunctionBody(StatementListT result, BlockT* init_block, |
+ IdentifierT function_name, int pos, |
+ const FormalParametersT& parameters, FunctionKind kind, |
FunctionLiteral::FunctionType function_type, bool* ok); |
// Under some circumstances, we allow preparsing to abort if the preparsed |
@@ -1495,8 +1466,6 @@ ParserBase<Impl>::FunctionState::FunctionState( |
: ScopeState(scope_stack, scope), |
next_materialized_literal_index_(0), |
expected_property_count_(0), |
- generator_object_variable_(nullptr), |
- promise_variable_(nullptr), |
function_state_stack_(function_state_stack), |
outer_function_state_(*function_state_stack), |
destructuring_assignments_to_rewrite_(16, scope->zone()), |
@@ -2915,8 +2884,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression( |
classifier()->RecordFormalParameterInitializerError( |
scanner()->peek_location(), MessageTemplate::kYieldInParameter); |
Expect(Token::YIELD, CHECK_OK); |
- ExpressionT generator_object = |
- factory()->NewVariableProxy(function_state_->generator_object_variable()); |
+ |
// The following initialization is necessary. |
ExpressionT expression = impl()->EmptyExpression(); |
bool delegating = false; // yield* |
@@ -2944,14 +2912,14 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression( |
} |
if (delegating) { |
- return impl()->RewriteYieldStar(generator_object, expression, pos); |
+ return impl()->RewriteYieldStar(expression, pos); |
} |
expression = impl()->BuildIteratorResult(expression, false); |
// Hackily disambiguate o from o.next and o [Symbol.iterator](). |
// TODO(verwaest): Come up with a better solution. |
- ExpressionT yield = factory()->NewYield(generator_object, expression, pos, |
- Yield::kOnExceptionThrow); |
+ ExpressionT yield = factory()->NewYield( |
+ expression, pos, Yield::kOnExceptionThrow, Yield::kNormal); |
return yield; |
} |
@@ -3111,7 +3079,8 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseUnaryExpression( |
ExpressionT value = ParseUnaryExpression(CHECK_OK); |
- return impl()->RewriteAwaitExpression(value, await_pos); |
+ return factory()->NewYield(value, await_pos, Yield::kOnExceptionRethrow, |
+ Yield::kAwait); |
} else { |
return ParsePostfixExpression(ok); |
} |
@@ -3945,21 +3914,10 @@ ParserBase<Impl>::ParseAsyncFunctionDeclaration( |
template <typename Impl> |
void ParserBase<Impl>::ParseFunctionBody( |
- typename ParserBase<Impl>::StatementListT result, IdentifierT function_name, |
+ typename ParserBase<Impl>::StatementListT result, |
+ typename ParserBase<Impl>::BlockT* init_block, IdentifierT function_name, |
int pos, const FormalParametersT& parameters, FunctionKind kind, |
FunctionLiteral::FunctionType function_type, bool* ok) { |
- static const int kFunctionNameAssignmentIndex = 0; |
- if (function_type == FunctionLiteral::kNamedExpression) { |
- DCHECK(!impl()->IsEmptyIdentifier(function_name)); |
- // If we have a named function expression, we add a local variable |
- // declaration to the body of the function with the name of the |
- // function and let it refer to the function itself (closure). |
- // Not having parsed the function body, the language mode may still change, |
- // so we reserve a spot and create the actual const assignment later. |
- DCHECK_EQ(kFunctionNameAssignmentIndex, result->length()); |
- result->Add(impl()->NullStatement(), zone()); |
- } |
- |
DeclarationScope* function_scope = scope()->AsDeclarationScope(); |
DeclarationScope* inner_scope = function_scope; |
BlockT inner_block = impl()->NullBlock(); |
@@ -3976,15 +3934,7 @@ void ParserBase<Impl>::ParseFunctionBody( |
{ |
BlockState block_state(&scope_state_, inner_scope); |
- if (IsGeneratorFunction(kind)) { |
- impl()->ParseAndRewriteGeneratorFunctionBody(pos, kind, body, ok); |
- } else if (IsAsyncFunction(kind)) { |
- const bool accept_IN = true; |
- ParseAsyncFunctionBody(inner_scope, body, kind, FunctionBodyType::kNormal, |
- accept_IN, pos, CHECK_OK_VOID); |
- } else { |
- ParseStatementList(body, Token::RBRACE, CHECK_OK_VOID); |
- } |
+ ParseStatementList(body, Token::RBRACE, CHECK_OK_VOID); |
if (IsDerivedConstructor(kind)) { |
body->Add(factory()->NewReturnStatement(impl()->ThisExpression(), |
@@ -4001,18 +3951,13 @@ void ParserBase<Impl>::ParseFunctionBody( |
DCHECK_EQ(function_scope, scope()); |
DCHECK_EQ(function_scope, inner_scope->outer_scope()); |
impl()->SetLanguageMode(function_scope, inner_scope->language_mode()); |
- BlockT init_block = |
+ *init_block = |
impl()->BuildParameterInitializationBlock(parameters, CHECK_OK_VOID); |
if (is_sloppy(inner_scope->language_mode())) { |
impl()->InsertSloppyBlockFunctionVarBindings(inner_scope); |
} |
- // TODO(littledan): Merge the two rejection blocks into one |
- if (IsAsyncFunction(kind)) { |
- init_block = impl()->BuildRejectPromiseOnException(init_block); |
- } |
- |
inner_scope->set_end_position(scanner()->location().end_pos); |
if (inner_scope->FinalizeBlockScope() != nullptr) { |
impl()->CheckConflictingVarDeclarations(inner_scope, CHECK_OK_VOID); |
@@ -4020,7 +3965,6 @@ void ParserBase<Impl>::ParseFunctionBody( |
} |
inner_scope = nullptr; |
- result->Add(init_block, zone()); |
result->Add(inner_block, zone()); |
} else { |
DCHECK_EQ(inner_scope, function_scope); |
@@ -4036,9 +3980,8 @@ void ParserBase<Impl>::ParseFunctionBody( |
function_scope->DeclareArguments(ast_value_factory()); |
} |
- impl()->CreateFunctionNameAssignment(function_name, pos, function_type, |
- function_scope, result, |
- kFunctionNameAssignmentIndex); |
+ impl()->CreateFunctionNameVariable(function_name, pos, function_type, |
+ function_scope); |
impl()->MarkCollectedTailCallExpressions(); |
} |
@@ -4136,6 +4079,7 @@ ParserBase<Impl>::ParseArrowFunctionLiteral( |
return impl()->EmptyExpression(); |
} |
+ BlockT parameter_init_block = impl()->NullBlock(); |
StatementListT body = impl()->NullStatementList(); |
int materialized_literal_count = -1; |
int expected_property_count = -1; |
@@ -4155,7 +4099,9 @@ ParserBase<Impl>::ParseArrowFunctionLiteral( |
{ |
FunctionState function_state(&function_state_, &scope_state_, |
formal_parameters.scope); |
- |
+ if (kind == kAsyncArrowFunction) { |
+ function_state.scope()->ForceContextAllocation(); |
+ } |
function_state.SkipMaterializedLiterals( |
formal_parameters.materialized_literals_count); |
@@ -4204,10 +4150,10 @@ ParserBase<Impl>::ParseArrowFunctionLiteral( |
if (!is_lazy_top_level_function) { |
Consume(Token::LBRACE); |
body = impl()->NewStatementList(8); |
- impl()->ParseFunctionBody(body, impl()->EmptyIdentifier(), |
- kNoSourcePosition, formal_parameters, kind, |
- FunctionLiteral::kAnonymousExpression, |
- CHECK_OK); |
+ impl()->ParseFunctionBody( |
+ body, ¶meter_init_block, impl()->EmptyIdentifier(), |
+ kNoSourcePosition, formal_parameters, kind, |
+ FunctionLiteral::kAnonymousExpression, CHECK_OK); |
materialized_literal_count = |
function_state.materialized_literal_count(); |
expected_property_count = function_state.expected_property_count(); |
@@ -4215,31 +4161,27 @@ ParserBase<Impl>::ParseArrowFunctionLiteral( |
} else { |
// Single-expression body |
has_braces = false; |
- int pos = position(); |
DCHECK(ReturnExprContext::kInsideValidBlock == |
function_state_->return_expr_context()); |
ReturnExprScope allow_tail_calls( |
function_state_, ReturnExprContext::kInsideValidReturnStatement); |
body = impl()->NewStatementList(1); |
- impl()->AddParameterInitializationBlock( |
- formal_parameters, body, kind == kAsyncArrowFunction, CHECK_OK); |
+ if (!formal_parameters.is_simple) { |
+ parameter_init_block = impl()->BuildParameterInitializationBlock( |
+ formal_parameters, CHECK_OK); |
+ } |
ExpressionClassifier classifier(this); |
- if (kind == kAsyncArrowFunction) { |
- ParseAsyncFunctionBody(scope(), body, kAsyncArrowFunction, |
- FunctionBodyType::kSingleExpression, accept_IN, |
- pos, CHECK_OK); |
- impl()->RewriteNonPattern(CHECK_OK); |
- } else { |
- ExpressionT expression = ParseAssignmentExpression(accept_IN, CHECK_OK); |
- impl()->RewriteNonPattern(CHECK_OK); |
- body->Add( |
- factory()->NewReturnStatement(expression, expression->position()), |
- zone()); |
- if (allow_tailcalls() && !is_sloppy(language_mode())) { |
- // ES6 14.6.1 Static Semantics: IsInTailPosition |
- impl()->MarkTailPosition(expression); |
- } |
+ ExpressionT expression = ParseAssignmentExpression(accept_IN, CHECK_OK); |
+ impl()->RewriteNonPattern(CHECK_OK); |
+ body->Add( |
+ factory()->NewReturnStatement(expression, expression->position()), |
+ zone()); |
+ if (allow_tailcalls() && !is_sloppy(language_mode()) && |
+ kind != kAsyncArrowFunction) { |
+ // ES6 14.6.1 Static Semantics: IsInTailPosition |
+ impl()->MarkTailPosition(expression); |
} |
+ |
materialized_literal_count = function_state.materialized_literal_count(); |
expected_property_count = function_state.expected_property_count(); |
impl()->MarkCollectedTailCallExpressions(); |
@@ -4279,6 +4221,7 @@ ParserBase<Impl>::ParseArrowFunctionLiteral( |
FunctionLiteral::kAnonymousExpression, eager_compile_hint, |
formal_parameters.scope->start_position(), has_braces, |
function_literal_id); |
+ function_literal->set_parameter_init_block(parameter_init_block); |
function_literal->set_function_token_position( |
formal_parameters.scope->start_position()); |
@@ -4364,31 +4307,6 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral( |
} |
template <typename Impl> |
-void ParserBase<Impl>::ParseAsyncFunctionBody(Scope* scope, StatementListT body, |
- FunctionKind kind, |
- FunctionBodyType body_type, |
- bool accept_IN, int pos, |
- bool* ok) { |
- impl()->PrepareAsyncFunctionBody(body, kind, pos); |
- |
- BlockT block = factory()->NewBlock(nullptr, 8, true, kNoSourcePosition); |
- |
- ExpressionT return_value = impl()->EmptyExpression(); |
- if (body_type == FunctionBodyType::kNormal) { |
- ParseStatementList(block->statements(), Token::RBRACE, |
- CHECK_OK_CUSTOM(Void)); |
- return_value = factory()->NewUndefinedLiteral(kNoSourcePosition); |
- } else { |
- return_value = ParseAssignmentExpression(accept_IN, CHECK_OK_CUSTOM(Void)); |
- impl()->RewriteNonPattern(CHECK_OK_CUSTOM(Void)); |
- } |
- |
- impl()->RewriteAsyncFunctionBody(body, block, return_value, |
- CHECK_OK_CUSTOM(Void)); |
- scope->set_end_position(scanner()->location().end_pos); |
-} |
- |
-template <typename Impl> |
typename ParserBase<Impl>::ExpressionT |
ParserBase<Impl>::ParseAsyncFunctionLiteral(bool* ok) { |
// AsyncFunctionLiteral :: |