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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #ifndef V8_PARSING_PARSER_BASE_H 5 #ifndef V8_PARSING_PARSER_BASE_H
6 #define V8_PARSING_PARSER_BASE_H 6 #define V8_PARSING_PARSER_BASE_H
7 7
8 #include "src/ast/ast.h" 8 #include "src/ast/ast.h"
9 #include "src/ast/scopes.h" 9 #include "src/ast/scopes.h"
10 #include "src/bailout-reason.h" 10 #include "src/bailout-reason.h"
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 94
95 #define CHECK_OK_CUSTOM(x, ...) ok); \ 95 #define CHECK_OK_CUSTOM(x, ...) ok); \
96 if (!*ok) return impl()->x(__VA_ARGS__); \ 96 if (!*ok) return impl()->x(__VA_ARGS__); \
97 ((void)0 97 ((void)0
98 #define DUMMY ) // to make indentation work 98 #define DUMMY ) // to make indentation work
99 #undef DUMMY 99 #undef DUMMY
100 100
101 // Used in functions where the return type is ExpressionT. 101 // Used in functions where the return type is ExpressionT.
102 #define CHECK_OK CHECK_OK_CUSTOM(EmptyExpression) 102 #define CHECK_OK CHECK_OK_CUSTOM(EmptyExpression)
103 103
104 #define CHECK_OK_VOID ok); \
105 if (!*ok) return; \
106 ((void)0
107 #define DUMMY ) // to make indentation work
108 #undef DUMMY
109
104 // Common base class template shared between parser and pre-parser. 110 // Common base class template shared between parser and pre-parser.
105 // The Impl parameter is the actual class of the parser/pre-parser, 111 // The Impl parameter is the actual class of the parser/pre-parser,
106 // following the Curiously Recurring Template Pattern (CRTP). 112 // following the Curiously Recurring Template Pattern (CRTP).
107 // The structure of the parser objects is roughly the following: 113 // The structure of the parser objects is roughly the following:
108 // 114 //
109 // // A structure template containing type definitions, needed to 115 // // A structure template containing type definitions, needed to
110 // // avoid a cyclic dependency. 116 // // avoid a cyclic dependency.
111 // template <typename Impl> 117 // template <typename Impl>
112 // struct ParserTypes; 118 // struct ParserTypes;
113 // 119 //
(...skipping 1102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1216 StatementT ParseFunctionDeclaration(bool* ok); 1222 StatementT ParseFunctionDeclaration(bool* ok);
1217 StatementT ParseHoistableDeclaration(ZoneList<const AstRawString*>* names, 1223 StatementT ParseHoistableDeclaration(ZoneList<const AstRawString*>* names,
1218 bool default_export, bool* ok); 1224 bool default_export, bool* ok);
1219 StatementT ParseHoistableDeclaration(int pos, ParseFunctionFlags flags, 1225 StatementT ParseHoistableDeclaration(int pos, ParseFunctionFlags flags,
1220 ZoneList<const AstRawString*>* names, 1226 ZoneList<const AstRawString*>* names,
1221 bool default_export, bool* ok); 1227 bool default_export, bool* ok);
1222 StatementT ParseClassDeclaration(ZoneList<const AstRawString*>* names, 1228 StatementT ParseClassDeclaration(ZoneList<const AstRawString*>* names,
1223 bool default_export, bool* ok); 1229 bool default_export, bool* ok);
1224 StatementT ParseNativeDeclaration(bool* ok); 1230 StatementT ParseNativeDeclaration(bool* ok);
1225 1231
1232 // Consumes the ending }.
1233 void ParseFunctionBody(StatementListT result, IdentifierT function_name,
1234 int pos, const FormalParametersT& parameters,
1235 FunctionKind kind,
1236 FunctionLiteral::FunctionType function_type, bool* ok);
1237
1226 // Under some circumstances, we allow preparsing to abort if the preparsed 1238 // Under some circumstances, we allow preparsing to abort if the preparsed
1227 // function is "long and trivial", and fully parse instead. Our current 1239 // function is "long and trivial", and fully parse instead. Our current
1228 // definition of "long and trivial" is: 1240 // definition of "long and trivial" is:
1229 // - over kLazyParseTrialLimit statements 1241 // - over kLazyParseTrialLimit statements
1230 // - all starting with an identifier (i.e., no if, for, while, etc.) 1242 // - all starting with an identifier (i.e., no if, for, while, etc.)
1231 static const int kLazyParseTrialLimit = 200; 1243 static const int kLazyParseTrialLimit = 200;
1232 1244
1233 // TODO(nikolaos, marja): The first argument should not really be passed 1245 // TODO(nikolaos, marja): The first argument should not really be passed
1234 // by value. The method is expected to add the parsed statements to the 1246 // by value. The method is expected to add the parsed statements to the
1235 // list. This works because in the case of the parser, StatementListT is 1247 // list. This works because in the case of the parser, StatementListT is
(...skipping 2642 matching lines...) Expand 10 before | Expand all | Expand 10 after
3878 *ok = false; 3890 *ok = false;
3879 impl()->ReportUnexpectedToken(scanner()->current_token()); 3891 impl()->ReportUnexpectedToken(scanner()->current_token());
3880 return impl()->NullStatement(); 3892 return impl()->NullStatement();
3881 } 3893 }
3882 Expect(Token::FUNCTION, CHECK_OK_CUSTOM(NullStatement)); 3894 Expect(Token::FUNCTION, CHECK_OK_CUSTOM(NullStatement));
3883 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync; 3895 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync;
3884 return ParseHoistableDeclaration(pos, flags, names, default_export, ok); 3896 return ParseHoistableDeclaration(pos, flags, names, default_export, ok);
3885 } 3897 }
3886 3898
3887 template <typename Impl> 3899 template <typename Impl>
3900 void ParserBase<Impl>::ParseFunctionBody(
3901 typename ParserBase<Impl>::StatementListT result, IdentifierT function_name,
3902 int pos, const FormalParametersT& parameters, FunctionKind kind,
3903 FunctionLiteral::FunctionType function_type, bool* ok) {
3904 static const int kFunctionNameAssignmentIndex = 0;
3905 if (function_type == FunctionLiteral::kNamedExpression) {
3906 DCHECK(!impl()->IsEmptyIdentifier(function_name));
3907 // If we have a named function expression, we add a local variable
3908 // declaration to the body of the function with the name of the
3909 // function and let it refer to the function itself (closure).
3910 // Not having parsed the function body, the language mode may still change,
3911 // so we reserve a spot and create the actual const assignment later.
3912 DCHECK_EQ(kFunctionNameAssignmentIndex, result->length());
3913 result->Add(impl()->NullStatement(), zone());
3914 }
3915
3916 DeclarationScope* function_scope = scope()->AsDeclarationScope();
3917 DeclarationScope* inner_scope = function_scope;
3918 BlockT inner_block = impl()->NullBlock();
3919
3920 StatementListT body = result;
3921 if (!parameters.is_simple) {
3922 inner_scope = NewVarblockScope();
3923 inner_scope->set_start_position(scanner()->location().beg_pos);
3924 inner_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition);
3925 inner_block->set_scope(inner_scope);
3926 body = inner_block->statements();
3927 }
3928
3929 {
3930 BlockState block_state(&scope_state_, inner_scope);
3931
3932 if (IsGeneratorFunction(kind)) {
3933 impl()->ParseAndRewriteGeneratorFunctionBody(pos, kind, body, ok);
3934 } else if (IsAsyncFunction(kind)) {
3935 const bool accept_IN = true;
3936 ParseAsyncFunctionBody(inner_scope, body, kind, FunctionBodyType::kNormal,
3937 accept_IN, pos, CHECK_OK_VOID);
3938 } else {
3939 ParseStatementList(body, Token::RBRACE, CHECK_OK_VOID);
3940 }
3941
3942 if (IsDerivedConstructor(kind)) {
3943 body->Add(factory()->NewReturnStatement(impl()->ThisExpression(),
3944 kNoSourcePosition),
3945 zone());
3946 }
3947 }
3948
3949 Expect(Token::RBRACE, CHECK_OK_VOID);
3950 scope()->set_end_position(scanner()->location().end_pos);
3951
3952 if (!parameters.is_simple) {
3953 DCHECK_NOT_NULL(inner_scope);
3954 DCHECK_EQ(function_scope, scope());
3955 DCHECK_EQ(function_scope, inner_scope->outer_scope());
3956 impl()->SetLanguageMode(function_scope, inner_scope->language_mode());
3957 BlockT init_block =
3958 impl()->BuildParameterInitializationBlock(parameters, CHECK_OK_VOID);
3959
3960 if (is_sloppy(inner_scope->language_mode())) {
3961 impl()->InsertSloppyBlockFunctionVarBindings(inner_scope);
3962 }
3963
3964 // TODO(littledan): Merge the two rejection blocks into one
3965 if (IsAsyncFunction(kind)) {
3966 init_block = impl()->BuildRejectPromiseOnException(init_block);
3967 }
3968
3969 inner_scope->set_end_position(scanner()->location().end_pos);
3970 if (inner_scope->FinalizeBlockScope() != nullptr) {
3971 impl()->CheckConflictingVarDeclarations(inner_scope, CHECK_OK_VOID);
3972 impl()->InsertShadowingVarBindingInitializers(inner_block);
3973 }
3974 inner_scope = nullptr;
3975
3976 result->Add(init_block, zone());
3977 result->Add(inner_block, zone());
3978 } else {
3979 DCHECK_EQ(inner_scope, function_scope);
3980 if (is_sloppy(function_scope->language_mode())) {
3981 impl()->InsertSloppyBlockFunctionVarBindings(function_scope);
3982 }
3983 }
3984
3985 if (!IsArrowFunction(kind)) {
3986 // Declare arguments after parsing the function since lexical 'arguments'
3987 // masks the arguments object. Declare arguments before declaring the
3988 // function var since the arguments object masks 'function arguments'.
3989 function_scope->DeclareArguments(ast_value_factory());
3990 }
3991
3992 impl()->CreateFunctionNameAssignment(function_name, pos, function_type,
3993 function_scope, result,
3994 kFunctionNameAssignmentIndex);
3995 impl()->MarkCollectedTailCallExpressions();
3996 }
3997
3998 template <typename Impl>
3888 void ParserBase<Impl>::CheckArityRestrictions(int param_count, 3999 void ParserBase<Impl>::CheckArityRestrictions(int param_count,
3889 FunctionKind function_kind, 4000 FunctionKind function_kind,
3890 bool has_rest, 4001 bool has_rest,
3891 int formals_start_pos, 4002 int formals_start_pos,
3892 int formals_end_pos, bool* ok) { 4003 int formals_end_pos, bool* ok) {
3893 if (IsGetterFunction(function_kind)) { 4004 if (IsGetterFunction(function_kind)) {
3894 if (param_count != 0) { 4005 if (param_count != 0) {
3895 impl()->ReportMessageAt( 4006 impl()->ReportMessageAt(
3896 Scanner::Location(formals_start_pos, formals_end_pos), 4007 Scanner::Location(formals_start_pos, formals_end_pos),
3897 MessageTemplate::kBadGetterArity); 4008 MessageTemplate::kBadGetterArity);
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
4040 4151
4041 // This is probably an initialization function. Inform the compiler it 4152 // This is probably an initialization function. Inform the compiler it
4042 // should also eager-compile this function, and that we expect it to 4153 // should also eager-compile this function, and that we expect it to
4043 // be used once. 4154 // be used once.
4044 eager_compile_hint = FunctionLiteral::kShouldEagerCompile; 4155 eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
4045 should_be_used_once_hint = true; 4156 should_be_used_once_hint = true;
4046 } 4157 }
4047 } 4158 }
4048 if (!is_lazy_top_level_function) { 4159 if (!is_lazy_top_level_function) {
4049 Consume(Token::LBRACE); 4160 Consume(Token::LBRACE);
4050 body = impl()->ParseEagerFunctionBody( 4161 body = impl()->NewStatementList(8);
4051 impl()->EmptyIdentifier(), kNoSourcePosition, formal_parameters, 4162 impl()->ParseFunctionBody(body, impl()->EmptyIdentifier(),
4052 kind, FunctionLiteral::kAnonymousExpression, CHECK_OK); 4163 kNoSourcePosition, formal_parameters, kind,
4164 FunctionLiteral::kAnonymousExpression,
4165 CHECK_OK);
4053 materialized_literal_count = 4166 materialized_literal_count =
4054 function_state.materialized_literal_count(); 4167 function_state.materialized_literal_count();
4055 expected_property_count = function_state.expected_property_count(); 4168 expected_property_count = function_state.expected_property_count();
4056 } 4169 }
4057 } else { 4170 } else {
4058 // Single-expression body 4171 // Single-expression body
4059 has_braces = false; 4172 has_braces = false;
4060 int pos = position(); 4173 int pos = position();
4061 DCHECK(ReturnExprContext::kInsideValidBlock == 4174 DCHECK(ReturnExprContext::kInsideValidBlock ==
4062 function_state_->return_expr_context()); 4175 function_state_->return_expr_context());
(...skipping 1476 matching lines...) Expand 10 before | Expand all | Expand 10 after
5539 if (has_seen_constructor_) { 5652 if (has_seen_constructor_) {
5540 this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor); 5653 this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor);
5541 *ok = false; 5654 *ok = false;
5542 return; 5655 return;
5543 } 5656 }
5544 has_seen_constructor_ = true; 5657 has_seen_constructor_ = true;
5545 return; 5658 return;
5546 } 5659 }
5547 } 5660 }
5548 5661
5662 #undef CHECK_OK_VOID
5549 5663
5550 } // namespace internal 5664 } // namespace internal
5551 } // namespace v8 5665 } // namespace v8
5552 5666
5553 #endif // V8_PARSING_PARSER_BASE_H 5667 #endif // V8_PARSING_PARSER_BASE_H
OLDNEW
« 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