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

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

Issue 2411793003: Preparse lazy function parameters (Closed)
Patch Set: rebased 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 ((kind & FunctionKind::kArrowFunction) == 0) {
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 Expect(Token::LPAREN, CHECK_OK_VALUE(kPreParseSuccess));
118 function_scope->set_start_position(scanner()->location().beg_pos);
119 ParseFormalParameterList(&formals, CHECK_OK_VALUE(kPreParseSuccess));
120 Expect(Token::RPAREN, CHECK_OK_VALUE(kPreParseSuccess));
121 int formals_end_position = scanner()->location().end_pos;
122
123 CheckArityRestrictions(
124 formals.arity, kind, formals.has_rest, function_scope->start_position(),
125 formals_end_position, CHECK_OK_VALUE(kPreParseSuccess));
126 has_duplicate_parameters =
127 !classifier()->is_valid_formal_parameter_list_without_duplicates();
128 }
129
130 Expect(Token::LBRACE, CHECK_OK_VALUE(kPreParseSuccess));
131 LazyParsingResult result = ParseStatementListAndLogFunction(
132 function_scope->start_position(), &formals, has_duplicate_parameters,
133 may_abort, ok);
105 use_counts_ = nullptr; 134 use_counts_ = nullptr;
106 track_unresolved_variables_ = false; 135 track_unresolved_variables_ = false;
107 if (result == kLazyParsingAborted) { 136 if (result == kLazyParsingAborted) {
108 return kPreParseAbort; 137 return kPreParseAbort;
109 } else if (stack_overflow()) { 138 } else if (stack_overflow()) {
110 return kPreParseStackOverflow; 139 return kPreParseStackOverflow;
111 } else if (!ok) { 140 } else if (!*ok) {
112 DCHECK(log->has_error()); 141 DCHECK(log->has_error());
113 } else { 142 } else {
114 DCHECK_EQ(Token::RBRACE, scanner()->peek()); 143 DCHECK_EQ(Token::RBRACE, scanner()->peek());
144
145 if ((kind & FunctionKind::kArrowFunction) == 0) {
146 // Validate parameter names. We can do this only after parsing the
147 // function, since the function can declare itself strict.
148 const bool allow_duplicate_parameters =
149 is_sloppy(function_scope->language_mode()) && formals.is_simple &&
150 !IsConciseMethod(kind);
151 ValidateFormalParameters(function_scope->language_mode(),
152 allow_duplicate_parameters,
153 CHECK_OK_VALUE(kPreParseSuccess));
154 }
155
115 if (is_strict(function_scope->language_mode())) { 156 if (is_strict(function_scope->language_mode())) {
116 int end_pos = scanner()->location().end_pos; 157 int end_pos = scanner()->location().end_pos;
117 CheckStrictOctalLiteral(start_position, end_pos, &ok); 158 CheckStrictOctalLiteral(function_scope->start_position(), end_pos, ok);
118 CheckDecimalLiteralWithLeadingZero(start_position, end_pos); 159 CheckDecimalLiteralWithLeadingZero(function_scope->start_position(),
160 end_pos);
119 } 161 }
120 } 162 }
121 return kPreParseSuccess; 163 return kPreParseSuccess;
122 } 164 }
123 165
124 166
125 // Preparsing checks a JavaScript program and emits preparse-data that helps 167 // Preparsing checks a JavaScript program and emits preparse-data that helps
126 // a later parsing to be faster. 168 // a later parsing to be faster.
127 // See preparser-data.h for the data. 169 // See preparser-data.h for the data.
128 170
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 PrintF(" [%s]: %i-%i\n", 230 PrintF(" [%s]: %i-%i\n",
189 track_unresolved_variables_ ? "Preparse resolution" 231 track_unresolved_variables_ ? "Preparse resolution"
190 : "Preparse no-resolution", 232 : "Preparse no-resolution",
191 function_scope->start_position(), function_scope->end_position()); 233 function_scope->start_position(), function_scope->end_position());
192 } 234 }
193 235
194 return Expression::Default(); 236 return Expression::Default();
195 } 237 }
196 238
197 PreParser::LazyParsingResult PreParser::ParseStatementListAndLogFunction( 239 PreParser::LazyParsingResult PreParser::ParseStatementListAndLogFunction(
198 bool may_abort, bool* ok) { 240 int start_position, PreParserFormalParameters* formals,
199 int body_start = position(); 241 bool has_duplicate_parameters, bool may_abort, bool* ok) {
200 PreParserStatementList body; 242 PreParserStatementList body;
201 LazyParsingResult result = ParseStatementList( 243 LazyParsingResult result = ParseStatementList(
202 body, Token::RBRACE, may_abort, CHECK_OK_VALUE(kLazyParsingComplete)); 244 body, Token::RBRACE, may_abort, CHECK_OK_VALUE(kLazyParsingComplete));
203 if (result == kLazyParsingAborted) return result; 245 if (result == kLazyParsingAborted) return result;
204 246
205 // Position right after terminal '}'. 247 // Position right after terminal '}'.
206 DCHECK_EQ(Token::RBRACE, scanner()->peek()); 248 DCHECK_EQ(Token::RBRACE, scanner()->peek());
207 int body_end = scanner()->peek_location().end_pos; 249 int body_end = scanner()->peek_location().end_pos;
208 DeclarationScope* scope = this->scope()->AsDeclarationScope(); 250 DeclarationScope* scope = this->scope()->AsDeclarationScope();
209 DCHECK(scope->is_function_scope()); 251 DCHECK(scope->is_function_scope());
210 log_->LogFunction(body_start, body_end, 252 // Key position doesn't matter, since it's decided when writing the function
253 // position cache (see Parser::SkipLazyFunction).
254 log_->LogFunction(-1, start_position, body_end, formals->num_parameters(),
255 formals->function_length, has_duplicate_parameters,
211 function_state_->materialized_literal_count(), 256 function_state_->materialized_literal_count(),
212 function_state_->expected_property_count(), language_mode(), 257 function_state_->expected_property_count(), language_mode(),
213 scope->uses_super_property(), scope->calls_eval()); 258 scope->uses_super_property(), scope->calls_eval());
214 return kLazyParsingComplete; 259 return kLazyParsingComplete;
215 } 260 }
216 261
217 PreParserExpression PreParser::ExpressionFromIdentifier( 262 PreParserExpression PreParser::ExpressionFromIdentifier(
218 PreParserIdentifier name, int start_position, int end_position, 263 PreParserIdentifier name, int start_position, int end_position,
219 InferName infer) { 264 InferName infer) {
220 if (track_unresolved_variables_) { 265 if (track_unresolved_variables_) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 } 299 }
255 } 300 }
256 } 301 }
257 302
258 #undef CHECK_OK 303 #undef CHECK_OK
259 #undef CHECK_OK_CUSTOM 304 #undef CHECK_OK_CUSTOM
260 305
261 306
262 } // namespace internal 307 } // namespace internal
263 } // namespace v8 308 } // 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