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

Side by Side Diff: src/parsing/preparser.cc

Issue 2472063002: Preparse lazy function parameters (Closed)
Patch Set: IsArrowFunction Created 4 years, 1 month 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/preparser.h ('k') | test/cctest/test-parsing.cc » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 #include <cmath> 5 #include <cmath>
6 6
7 #include "src/allocation.h" 7 #include "src/allocation.h"
8 #include "src/base/logging.h" 8 #include "src/base/logging.h"
9 #include "src/conversions-inl.h" 9 #include "src/conversions-inl.h"
10 #include "src/conversions.h" 10 #include "src/conversions.h"
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 PreParserIdentifier symbol = GetSymbolHelper(scanner()); 77 PreParserIdentifier symbol = GetSymbolHelper(scanner());
78 if (track_unresolved_variables_) { 78 if (track_unresolved_variables_) {
79 const AstRawString* result = scanner()->CurrentSymbol(ast_value_factory()); 79 const AstRawString* result = scanner()->CurrentSymbol(ast_value_factory());
80 DCHECK_NOT_NULL(result); 80 DCHECK_NOT_NULL(result);
81 symbol.string_ = result; 81 symbol.string_ = result;
82 } 82 }
83 return symbol; 83 return symbol;
84 } 84 }
85 85
86 PreParser::PreParseResult PreParser::PreParseFunction( 86 PreParser::PreParseResult PreParser::PreParseFunction(
87 DeclarationScope* function_scope, bool parsing_module, SingletonLogger* log, 87 FunctionKind kind, DeclarationScope* function_scope, bool parsing_module,
88 bool is_inner_function, bool may_abort, int* use_counts) { 88 SingletonLogger* log, bool is_inner_function, bool may_abort,
89 int* use_counts) {
89 DCHECK_EQ(FUNCTION_SCOPE, function_scope->scope_type()); 90 DCHECK_EQ(FUNCTION_SCOPE, function_scope->scope_type());
90 parsing_module_ = parsing_module; 91 parsing_module_ = parsing_module;
91 log_ = log; 92 log_ = log;
92 use_counts_ = use_counts; 93 use_counts_ = use_counts;
93 DCHECK(!track_unresolved_variables_); 94 DCHECK(!track_unresolved_variables_);
94 track_unresolved_variables_ = is_inner_function; 95 track_unresolved_variables_ = is_inner_function;
95 96
96 // The caller passes the function_scope which is not yet inserted into the 97 // The caller passes the function_scope which is not yet inserted into the
97 // scope_state_. All scopes above the function_scope are ignored by the 98 // scope_state_. All scopes above the function_scope are ignored by the
98 // PreParser. 99 // PreParser.
99 DCHECK_NULL(scope_state_); 100 DCHECK_NULL(scope_state_);
100 FunctionState function_state(&function_state_, &scope_state_, function_scope); 101 FunctionState function_state(&function_state_, &scope_state_, function_scope);
101 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); 102 // This indirection is needed so that we can use the CHECK_OK macros.
102 bool ok = true; 103 bool ok_holder = true;
103 int start_position = peek_position(); 104 bool* ok = &ok_holder;
104 LazyParsingResult result = ParseStatementListAndLogFunction(may_abort, &ok); 105
106 PreParserFormalParameters formals(function_scope);
107 bool has_duplicate_parameters = false;
108 DuplicateFinder duplicate_finder(scanner()->unicode_cache());
109 std::unique_ptr<ExpressionClassifier> formals_classifier;
110
111 // Parse non-arrow function parameters. For arrow functions, the parameters
112 // have already been parsed.
113 if (!IsArrowFunction(kind)) {
114 formals_classifier.reset(new ExpressionClassifier(this, &duplicate_finder));
115 // We return kPreParseSuccess in failure cases too - errors are retrieved
116 // separately by Parser::SkipLazyFunctionBody.
117 ParseFormalParameterList(&formals, CHECK_OK_VALUE(kPreParseSuccess));
118 Expect(Token::RPAREN, CHECK_OK_VALUE(kPreParseSuccess));
119 int formals_end_position = scanner()->location().end_pos;
120
121 CheckArityRestrictions(
122 formals.arity, kind, formals.has_rest, function_scope->start_position(),
123 formals_end_position, CHECK_OK_VALUE(kPreParseSuccess));
124 has_duplicate_parameters =
125 !classifier()->is_valid_formal_parameter_list_without_duplicates();
126 }
127
128 Expect(Token::LBRACE, CHECK_OK_VALUE(kPreParseSuccess));
129 LazyParsingResult result = ParseStatementListAndLogFunction(
130 function_scope->start_position(), &formals, has_duplicate_parameters,
131 may_abort, ok);
105 use_counts_ = nullptr; 132 use_counts_ = nullptr;
106 track_unresolved_variables_ = false; 133 track_unresolved_variables_ = false;
107 if (result == kLazyParsingAborted) { 134 if (result == kLazyParsingAborted) {
108 return kPreParseAbort; 135 return kPreParseAbort;
109 } else if (stack_overflow()) { 136 } else if (stack_overflow()) {
110 return kPreParseStackOverflow; 137 return kPreParseStackOverflow;
111 } else if (!ok) { 138 } else if (!*ok) {
112 DCHECK(log->has_error()); 139 DCHECK(log->has_error());
113 } else { 140 } else {
114 DCHECK_EQ(Token::RBRACE, scanner()->peek()); 141 DCHECK_EQ(Token::RBRACE, scanner()->peek());
142
143 if (!IsArrowFunction(kind)) {
144 // Validate parameter names. We can do this only after parsing the
145 // function, since the function can declare itself strict.
146 const bool allow_duplicate_parameters =
147 is_sloppy(function_scope->language_mode()) && formals.is_simple &&
148 !IsConciseMethod(kind);
149 ValidateFormalParameters(function_scope->language_mode(),
150 allow_duplicate_parameters,
151 CHECK_OK_VALUE(kPreParseSuccess));
152 }
153
115 if (is_strict(function_scope->language_mode())) { 154 if (is_strict(function_scope->language_mode())) {
116 int end_pos = scanner()->location().end_pos; 155 int end_pos = scanner()->location().end_pos;
117 CheckStrictOctalLiteral(start_position, end_pos, &ok); 156 CheckStrictOctalLiteral(function_scope->start_position(), end_pos, ok);
118 CheckDecimalLiteralWithLeadingZero(start_position, end_pos); 157 CheckDecimalLiteralWithLeadingZero(function_scope->start_position(),
158 end_pos);
119 } 159 }
120 } 160 }
121 return kPreParseSuccess; 161 return kPreParseSuccess;
122 } 162 }
123 163
124 164
125 // Preparsing checks a JavaScript program and emits preparse-data that helps 165 // Preparsing checks a JavaScript program and emits preparse-data that helps
126 // a later parsing to be faster. 166 // a later parsing to be faster.
127 // See preparser-data.h for the data. 167 // See preparser-data.h for the data.
128 168
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 PrintF(" [%s]: %i-%i\n", 228 PrintF(" [%s]: %i-%i\n",
189 track_unresolved_variables_ ? "Preparse resolution" 229 track_unresolved_variables_ ? "Preparse resolution"
190 : "Preparse no-resolution", 230 : "Preparse no-resolution",
191 function_scope->start_position(), function_scope->end_position()); 231 function_scope->start_position(), function_scope->end_position());
192 } 232 }
193 233
194 return Expression::Default(); 234 return Expression::Default();
195 } 235 }
196 236
197 PreParser::LazyParsingResult PreParser::ParseStatementListAndLogFunction( 237 PreParser::LazyParsingResult PreParser::ParseStatementListAndLogFunction(
198 bool may_abort, bool* ok) { 238 int start_position, PreParserFormalParameters* formals,
199 int body_start = position(); 239 bool has_duplicate_parameters, bool may_abort, bool* ok) {
200 PreParserStatementList body; 240 PreParserStatementList body;
201 LazyParsingResult result = ParseStatementList( 241 LazyParsingResult result = ParseStatementList(
202 body, Token::RBRACE, may_abort, CHECK_OK_VALUE(kLazyParsingComplete)); 242 body, Token::RBRACE, may_abort, CHECK_OK_VALUE(kLazyParsingComplete));
203 if (result == kLazyParsingAborted) return result; 243 if (result == kLazyParsingAborted) return result;
204 244
205 // Position right after terminal '}'. 245 // Position right after terminal '}'.
206 DCHECK_EQ(Token::RBRACE, scanner()->peek()); 246 DCHECK_EQ(Token::RBRACE, scanner()->peek());
207 int body_end = scanner()->peek_location().end_pos; 247 int body_end = scanner()->peek_location().end_pos;
208 DeclarationScope* scope = this->scope()->AsDeclarationScope(); 248 DeclarationScope* scope = this->scope()->AsDeclarationScope();
209 DCHECK(scope->is_function_scope()); 249 DCHECK(scope->is_function_scope());
210 log_->LogFunction(body_start, body_end, 250 log_->LogFunction(start_position, body_end, formals->num_parameters(),
251 formals->function_length, has_duplicate_parameters,
211 function_state_->materialized_literal_count(), 252 function_state_->materialized_literal_count(),
212 function_state_->expected_property_count(), language_mode(), 253 function_state_->expected_property_count(), language_mode(),
213 scope->uses_super_property(), scope->calls_eval()); 254 scope->uses_super_property(), scope->calls_eval());
214 return kLazyParsingComplete; 255 return kLazyParsingComplete;
215 } 256 }
216 257
217 PreParserExpression PreParser::ExpressionFromIdentifier( 258 PreParserExpression PreParser::ExpressionFromIdentifier(
218 PreParserIdentifier name, int start_position, InferName infer) { 259 PreParserIdentifier name, int start_position, InferName infer) {
219 if (track_unresolved_variables_) { 260 if (track_unresolved_variables_) {
220 AstNodeFactory factory(ast_value_factory()); 261 AstNodeFactory factory(ast_value_factory());
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 } 294 }
254 } 295 }
255 } 296 }
256 297
257 #undef CHECK_OK 298 #undef CHECK_OK
258 #undef CHECK_OK_CUSTOM 299 #undef CHECK_OK_CUSTOM
259 300
260 301
261 } // namespace internal 302 } // namespace internal
262 } // namespace v8 303 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/preparser.h ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698