| Index: src/parsing/parser.cc
|
| diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc
|
| index 842d3520330f80965b332222072408b5d4f0bdf8..87b86d6be79f816839085c9cf1d57dfc9a93a3a6 100644
|
| --- a/src/parsing/parser.cc
|
| +++ b/src/parsing/parser.cc
|
| @@ -754,7 +754,7 @@ FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
|
| DCHECK(!is_duplicate);
|
| var->AllocateTo(VariableLocation::PARAMETER, 0);
|
|
|
| - PrepareGeneratorVariables(&function_state);
|
| + PrepareGeneratorVariables();
|
| Expression* initial_yield =
|
| BuildInitialYield(kNoSourcePosition, kGeneratorFunction);
|
| body->Add(
|
| @@ -2505,19 +2505,19 @@ void Parser::ReindexLiterals(const ParserFormalParameters& parameters) {
|
| }
|
| }
|
|
|
| -void Parser::PrepareGeneratorVariables(FunctionState* function_state) {
|
| +void Parser::PrepareGeneratorVariables() {
|
| // For generators, allocating variables in contexts is currently a win because
|
| // it minimizes the work needed to suspend and resume an activation. The
|
| - // code produced for generators relies on this forced context allocation, but
|
| - // not in an essential way.
|
| - scope()->ForceContextAllocation();
|
| + // code produced for generators relies on this forced context allocation (it
|
| + // does not restore the frame's parameters upon resume).
|
| + function_state_->scope()->ForceContextAllocation();
|
|
|
| // Calling a generator returns a generator object. That object is stored
|
| // in a temporary variable, a definition that is used by "yield"
|
| // expressions.
|
| Variable* temp =
|
| NewTemporary(ast_value_factory()->dot_generator_object_string());
|
| - function_state->set_generator_object_variable(temp);
|
| + function_state_->set_generator_object_variable(temp);
|
| }
|
|
|
| FunctionLiteral* Parser::ParseFunctionLiteral(
|
| @@ -3075,15 +3075,20 @@ Block* Parser::BuildRejectPromiseOnException(Block* inner_block, bool* ok) {
|
| return result;
|
| }
|
|
|
| -Expression* Parser::BuildCreateJSGeneratorObject(int pos, FunctionKind kind) {
|
| +Assignment* Parser::BuildCreateJSGeneratorObject(int pos, FunctionKind kind) {
|
| + // .generator = %CreateJSGeneratorObject(...);
|
| DCHECK_NOT_NULL(function_state_->generator_object_variable());
|
| ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
|
| args->Add(factory()->NewThisFunction(pos), zone());
|
| args->Add(IsArrowFunction(kind) ? GetLiteralUndefined(pos)
|
| : ThisExpression(kNoSourcePosition),
|
| zone());
|
| - return factory()->NewCallRuntime(Runtime::kCreateJSGeneratorObject, args,
|
| - pos);
|
| + Expression* allocation =
|
| + factory()->NewCallRuntime(Runtime::kCreateJSGeneratorObject, args, pos);
|
| + VariableProxy* proxy =
|
| + factory()->NewVariableProxy(function_state_->generator_object_variable());
|
| + return factory()->NewAssignment(Token::INIT, proxy, allocation,
|
| + kNoSourcePosition);
|
| }
|
|
|
| Expression* Parser::BuildResolvePromise(Expression* value, int pos) {
|
| @@ -3126,17 +3131,13 @@ Variable* Parser::PromiseVariable() {
|
| }
|
|
|
| Expression* Parser::BuildInitialYield(int pos, FunctionKind kind) {
|
| - Expression* allocation = BuildCreateJSGeneratorObject(pos, kind);
|
| - VariableProxy* init_proxy =
|
| - factory()->NewVariableProxy(function_state_->generator_object_variable());
|
| - Assignment* assignment = factory()->NewAssignment(
|
| - Token::INIT, init_proxy, allocation, kNoSourcePosition);
|
| - VariableProxy* get_proxy =
|
| + Assignment* assignment = BuildCreateJSGeneratorObject(pos, kind);
|
| + VariableProxy* generator =
|
| factory()->NewVariableProxy(function_state_->generator_object_variable());
|
| // The position of the yield is important for reporting the exception
|
| // caused by calling the .throw method on a generator suspended at the
|
| // initial yield (i.e. right after generator instantiation).
|
| - return factory()->NewYield(get_proxy, assignment, scope()->start_position(),
|
| + return factory()->NewYield(generator, assignment, scope()->start_position(),
|
| Yield::kOnExceptionThrow);
|
| }
|
|
|
| @@ -3153,7 +3154,7 @@ ZoneList<Statement*>* Parser::ParseFunction(
|
| DuplicateFinder duplicate_finder;
|
| ExpressionClassifier formals_classifier(this, &duplicate_finder);
|
|
|
| - if (IsGeneratorFunction(kind)) PrepareGeneratorVariables(&function_state);
|
| + if (IsResumableFunction(kind)) PrepareGeneratorVariables();
|
|
|
| ParserFormalParameters formals(function_scope);
|
| ParseFormalParameterList(&formals, CHECK_OK);
|
| @@ -4168,23 +4169,13 @@ Expression* Parser::ExpressionListToExpression(ZoneList<Expression*>* args) {
|
| // when desugaring the body of async_function.
|
| void Parser::PrepareAsyncFunctionBody(ZoneList<Statement*>* body,
|
| FunctionKind kind, int pos) {
|
| - // function async_function() {
|
| - // .generator_object = %CreateGeneratorObject();
|
| - // BuildRejectPromiseOnException({
|
| - // ... block ...
|
| - // return %ResolvePromise(.promise, expr), .promise;
|
| - // })
|
| - // }
|
| -
|
| - Variable* temp =
|
| - NewTemporary(ast_value_factory()->dot_generator_object_string());
|
| - function_state_->set_generator_object_variable(temp);
|
| -
|
| - Expression* init_generator_variable = factory()->NewAssignment(
|
| - Token::INIT, factory()->NewVariableProxy(temp),
|
| - BuildCreateJSGeneratorObject(pos, kind), kNoSourcePosition);
|
| - body->Add(factory()->NewExpressionStatement(init_generator_variable,
|
| - kNoSourcePosition),
|
| + // When parsing an async arrow function, we get here without having called
|
| + // PrepareGeneratorVariables yet, so do it now.
|
| + if (function_state_->generator_object_variable() == nullptr) {
|
| + PrepareGeneratorVariables();
|
| + }
|
| + body->Add(factory()->NewExpressionStatement(
|
| + BuildCreateJSGeneratorObject(pos, kind), kNoSourcePosition),
|
| zone());
|
| }
|
|
|
| @@ -4192,7 +4183,7 @@ void Parser::PrepareAsyncFunctionBody(ZoneList<Statement*>* body,
|
| void Parser::RewriteAsyncFunctionBody(ZoneList<Statement*>* body, Block* block,
|
| Expression* return_value, bool* ok) {
|
| // function async_function() {
|
| - // .generator_object = %CreateGeneratorObject();
|
| + // .generator_object = %CreateJSGeneratorObject();
|
| // BuildRejectPromiseOnException({
|
| // ... block ...
|
| // return %ResolvePromise(.promise, expr), .promise;
|
| @@ -4229,10 +4220,7 @@ Expression* Parser::RewriteAwaitExpression(Expression* value, int await_pos) {
|
| // TODO(littledan): investigate why this ordering is needed in more detail.
|
| Variable* generator_object_variable =
|
| function_state_->generator_object_variable();
|
| -
|
| - // If generator_object_variable is null,
|
| - // TODO(littledan): Is this necessary?
|
| - if (!generator_object_variable) return value;
|
| + DCHECK_NOT_NULL(generator_object_variable);
|
|
|
| const int nopos = kNoSourcePosition;
|
|
|
|
|