Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(775)

Unified Diff: src/parsing/parser-base.h

Issue 2638333002: Parsing:Create the same scopes for non-simple params in PreParser & Parser. (Closed)
Patch Set: rest of the impl Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parsing/parser-base.h
diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h
index 5ce82407ca79bd54b3e7219c97b3062e2c017117..7fec44b2e6e2f9976fc7ba5d26509107358e0277 100644
--- a/src/parsing/parser-base.h
+++ b/src/parsing/parser-base.h
@@ -101,6 +101,12 @@ struct FormalParametersBase {
// Used in functions where the return type is ExpressionT.
#define CHECK_OK CHECK_OK_CUSTOM(EmptyExpression)
+#define CHECK_OK_VOID ok); \
+ if (!*ok) return; \
+ ((void)0
+#define DUMMY ) // to make indentation work
+#undef DUMMY
+
// Common base class template shared between parser and pre-parser.
// The Impl parameter is the actual class of the parser/pre-parser,
// following the Curiously Recurring Template Pattern (CRTP).
@@ -1223,6 +1229,12 @@ class ParserBase {
bool default_export, bool* ok);
StatementT ParseNativeDeclaration(bool* ok);
+ // Consumes the ending }.
+ void ParseFunctionBody(StatementListT result, 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
// function is "long and trivial", and fully parse instead. Our current
// definition of "long and trivial" is:
@@ -3885,6 +3897,105 @@ ParserBase<Impl>::ParseAsyncFunctionDeclaration(
}
template <typename Impl>
+void ParserBase<Impl>::ParseFunctionBody(
+ typename ParserBase<Impl>::StatementListT result, 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();
+
+ StatementListT body = result;
+ if (!parameters.is_simple) {
+ inner_scope = NewVarblockScope();
+ inner_scope->set_start_position(scanner()->location().beg_pos);
+ inner_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition);
+ inner_block->set_scope(inner_scope);
+ body = inner_block->statements();
+ }
+
+ {
+ 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);
+ }
+
+ if (IsDerivedConstructor(kind)) {
+ body->Add(factory()->NewReturnStatement(impl()->ThisExpression(),
+ kNoSourcePosition),
+ zone());
+ }
+ }
+
+ Expect(Token::RBRACE, CHECK_OK_VOID);
+ scope()->set_end_position(scanner()->location().end_pos);
+
+ if (!parameters.is_simple) {
+ 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());
+ BlockT 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);
+ impl()->InsertShadowingVarBindingInitializers(inner_block);
+ }
+ inner_scope = nullptr;
+
+ result->Add(init_block, zone());
+ result->Add(inner_block, zone());
+ } else {
+ DCHECK_EQ(inner_scope, function_scope);
+ if (is_sloppy(function_scope->language_mode())) {
+ impl()->InsertSloppyBlockFunctionVarBindings(function_scope);
+ }
+ }
+
+ if (!IsArrowFunction(kind)) {
+ // Declare arguments after parsing the function since lexical 'arguments'
+ // masks the arguments object. Declare arguments before declaring the
+ // function var since the arguments object masks 'function arguments'.
+ function_scope->DeclareArguments(ast_value_factory());
+ }
+
+ impl()->CreateFunctionNameAssignment(function_name, pos, function_type,
+ function_scope, result,
+ kFunctionNameAssignmentIndex);
+ impl()->MarkCollectedTailCallExpressions();
+}
+
+template <typename Impl>
void ParserBase<Impl>::CheckArityRestrictions(int param_count,
FunctionKind function_kind,
bool has_rest,
@@ -4047,9 +4158,11 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
}
if (!is_lazy_top_level_function) {
Consume(Token::LBRACE);
- body = impl()->ParseEagerFunctionBody(
- impl()->EmptyIdentifier(), kNoSourcePosition, formal_parameters,
- kind, FunctionLiteral::kAnonymousExpression, CHECK_OK);
+ body = impl()->NewStatementList(8);
+ impl()->ParseFunctionBody(body, 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();
@@ -5546,6 +5659,7 @@ void ParserBase<Impl>::ClassLiteralChecker::CheckClassMethodName(
}
}
+#undef CHECK_OK_VOID
} // namespace internal
} // namespace v8
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698