Commit 2963f1b2 authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

[parser] Simplify ParseFunctionBody

- Merge is_simple branches at the top
- Remove block around inner_body parsing. Always merge fully at the end.
- Remove conditional inner block adding to outer body. Simply add it to the
  inner body making merge push it to the parent.

Change-Id: I1f062918a7abac354b949136463517bd0440984f
Reviewed-on: https://chromium-review.googlesource.com/c/1386111
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58390}
parent 71180e54
...@@ -3820,9 +3820,13 @@ void ParserBase<Impl>::ParseFunctionBody( ...@@ -3820,9 +3820,13 @@ void ParserBase<Impl>::ParseFunctionBody(
const FormalParametersT& parameters, FunctionKind kind, const FormalParametersT& parameters, FunctionKind kind,
FunctionLiteral::FunctionType function_type, FunctionBodyType body_type) { FunctionLiteral::FunctionType function_type, FunctionBodyType body_type) {
if (IsResumableFunction(kind)) impl()->PrepareGeneratorVariables(); if (IsResumableFunction(kind)) impl()->PrepareGeneratorVariables();
DeclarationScope* function_scope = parameters.scope;
DeclarationScope* inner_scope = function_scope;
// Building the parameter initialization block declares the parameters. // Building the parameter initialization block declares the parameters.
// TODO(verwaest): Rely on ArrowHeadParsingScope instead. // TODO(verwaest): Rely on ArrowHeadParsingScope instead.
if (!parameters.is_simple) { if (V8_UNLIKELY(!parameters.is_simple)) {
if (has_error()) return; if (has_error()) return;
BlockT init_block = impl()->BuildParameterInitializationBlock(parameters); BlockT init_block = impl()->BuildParameterInitializationBlock(parameters);
if (IsAsyncFunction(kind) && !IsAsyncGeneratorFunction(kind)) { if (IsAsyncFunction(kind) && !IsAsyncGeneratorFunction(kind)) {
...@@ -3830,100 +3834,92 @@ void ParserBase<Impl>::ParseFunctionBody( ...@@ -3830,100 +3834,92 @@ void ParserBase<Impl>::ParseFunctionBody(
} }
body->Add(init_block); body->Add(init_block);
if (has_error()) return; if (has_error()) return;
}
DeclarationScope* function_scope = scope()->AsDeclarationScope(); inner_scope = NewVarblockScope();
bool allow_duplicate_parameters = false; inner_scope->set_start_position(scanner()->location().beg_pos);
BlockT inner_block = impl()->NullBlock(); }
{
StatementListT inner_body(pointer_buffer());
DeclarationScope* inner_scope = function_scope;
if (!parameters.is_simple) { StatementListT inner_body(pointer_buffer());
inner_scope = NewVarblockScope();
inner_scope->set_start_position(scanner()->location().beg_pos);
}
{ {
BlockState block_state(&scope_, inner_scope); BlockState block_state(&scope_, inner_scope);
if (body_type == FunctionBodyType::kExpression) { if (body_type == FunctionBodyType::kExpression) {
ExpressionT expression = ParseAssignmentExpression(); ExpressionT expression = ParseAssignmentExpression();
if (IsAsyncFunction(kind)) { if (IsAsyncFunction(kind)) {
BlockT block = factory()->NewBlock(1, true); BlockT block = factory()->NewBlock(1, true);
impl()->RewriteAsyncFunctionBody(&inner_body, block, expression); impl()->RewriteAsyncFunctionBody(&inner_body, block, expression);
} else {
inner_body.Add(
BuildReturnStatement(expression, expression->position()));
}
} else { } else {
DCHECK(accept_IN_); inner_body.Add(
DCHECK_EQ(FunctionBodyType::kBlock, body_type); BuildReturnStatement(expression, expression->position()));
// If we are parsing the source as if it is wrapped in a function, the }
// source ends without a closing brace. } else {
Token::Value closing_token = function_type == FunctionLiteral::kWrapped DCHECK(accept_IN_);
? Token::EOS DCHECK_EQ(FunctionBodyType::kBlock, body_type);
: Token::RBRACE; // If we are parsing the source as if it is wrapped in a function, the
// source ends without a closing brace.
if (IsAsyncGeneratorFunction(kind)) { Token::Value closing_token = function_type == FunctionLiteral::kWrapped
impl()->ParseAndRewriteAsyncGeneratorFunctionBody(pos, kind, ? Token::EOS
&inner_body); : Token::RBRACE;
} else if (IsGeneratorFunction(kind)) {
impl()->ParseAndRewriteGeneratorFunctionBody(pos, kind, &inner_body); if (IsAsyncGeneratorFunction(kind)) {
} else if (IsAsyncFunction(kind)) { impl()->ParseAndRewriteAsyncGeneratorFunctionBody(pos, kind,
ParseAsyncFunctionBody(inner_scope, &inner_body); &inner_body);
} else { } else if (IsGeneratorFunction(kind)) {
ParseStatementList(&inner_body, closing_token); impl()->ParseAndRewriteGeneratorFunctionBody(pos, kind, &inner_body);
} } else if (IsAsyncFunction(kind)) {
ParseAsyncFunctionBody(inner_scope, &inner_body);
} else {
ParseStatementList(&inner_body, closing_token);
}
if (IsDerivedConstructor(kind)) { if (IsDerivedConstructor(kind)) {
inner_body.Add(factory()->NewReturnStatement(impl()->ThisExpression(), inner_body.Add(factory()->NewReturnStatement(impl()->ThisExpression(),
kNoSourcePosition)); kNoSourcePosition));
}
Expect(closing_token);
} }
Expect(closing_token);
} }
}
scope()->set_end_position(end_position()); scope()->set_end_position(end_position());
if (parameters.is_simple) {
DCHECK_EQ(inner_scope, function_scope);
if (is_sloppy(function_scope->language_mode())) {
impl()->InsertSloppyBlockFunctionVarBindings(function_scope);
}
allow_duplicate_parameters = is_sloppy(function_scope->language_mode()) &&
!IsConciseMethod(kind) &&
!IsArrowFunction(kind);
} else {
DCHECK_NOT_NULL(inner_scope);
DCHECK_EQ(function_scope, scope());
DCHECK_EQ(function_scope, inner_scope->outer_scope());
impl()->SetLanguageMode(function_scope, inner_scope->language_mode());
if (is_sloppy(inner_scope->language_mode())) { bool allow_duplicate_parameters = false;
impl()->InsertSloppyBlockFunctionVarBindings(inner_scope);
}
inner_scope->set_end_position(end_position()); if (V8_LIKELY(parameters.is_simple)) {
if (inner_scope->FinalizeBlockScope() != nullptr) { DCHECK_EQ(inner_scope, function_scope);
inner_block = factory()->NewBlock(true, inner_body); if (is_sloppy(function_scope->language_mode())) {
inner_body.Rewind(); impl()->InsertSloppyBlockFunctionVarBindings(function_scope);
inner_block->set_scope(inner_scope); }
const AstRawString* conflict = inner_scope->FindVariableDeclaredIn( allow_duplicate_parameters = is_sloppy(function_scope->language_mode()) &&
function_scope, VariableMode::kLastLexicalVariableMode); !IsConciseMethod(kind) &&
if (conflict != nullptr) { !IsArrowFunction(kind);
impl()->ReportVarRedeclarationIn(conflict, inner_scope); } else {
} DCHECK_NOT_NULL(inner_scope);
impl()->CheckConflictingVarDeclarations(inner_scope); DCHECK_EQ(function_scope, scope());
impl()->InsertShadowingVarBindingInitializers(inner_block); DCHECK_EQ(function_scope, inner_scope->outer_scope());
impl()->SetLanguageMode(function_scope, inner_scope->language_mode());
if (is_sloppy(inner_scope->language_mode())) {
impl()->InsertSloppyBlockFunctionVarBindings(inner_scope);
}
inner_scope->set_end_position(end_position());
if (inner_scope->FinalizeBlockScope() != nullptr) {
BlockT inner_block = factory()->NewBlock(true, inner_body);
inner_body.Rewind();
inner_body.Add(inner_block);
inner_block->set_scope(inner_scope);
const AstRawString* conflict = inner_scope->FindVariableDeclaredIn(
function_scope, VariableMode::kLastLexicalVariableMode);
if (conflict != nullptr) {
impl()->ReportVarRedeclarationIn(conflict, inner_scope);
} }
impl()->CheckConflictingVarDeclarations(inner_scope);
impl()->InsertShadowingVarBindingInitializers(inner_block);
} }
inner_body.MergeInto(body);
} }
if (!impl()->IsNull(inner_block)) body->Add(inner_block);
ValidateFormalParameters(language_mode(), parameters, ValidateFormalParameters(language_mode(), parameters,
allow_duplicate_parameters); allow_duplicate_parameters);
...@@ -3935,6 +3931,8 @@ void ParserBase<Impl>::ParseFunctionBody( ...@@ -3935,6 +3931,8 @@ void ParserBase<Impl>::ParseFunctionBody(
} }
impl()->DeclareFunctionNameVar(function_name, function_type, function_scope); impl()->DeclareFunctionNameVar(function_name, function_type, function_scope);
inner_body.MergeInto(body);
} }
template <typename Impl> template <typename Impl>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment