Line data Source code
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
3 : // found in the LICENSE file.
4 :
5 : #include <cmath>
6 :
7 : #include "src/allocation.h"
8 : #include "src/base/logging.h"
9 : #include "src/conversions-inl.h"
10 : #include "src/conversions.h"
11 : #include "src/globals.h"
12 : #include "src/parsing/duplicate-finder.h"
13 : #include "src/parsing/parser-base.h"
14 : #include "src/parsing/preparse-data-format.h"
15 : #include "src/parsing/preparse-data.h"
16 : #include "src/parsing/preparsed-scope-data.h"
17 : #include "src/parsing/preparser.h"
18 : #include "src/unicode.h"
19 : #include "src/utils.h"
20 :
21 : namespace v8 {
22 : namespace internal {
23 :
24 : // ----------------------------------------------------------------------------
25 : // The CHECK_OK macro is a convenient macro to enforce error
26 : // handling for functions that may fail (by returning !*ok).
27 : //
28 : // CAUTION: This macro appends extra statements after a call,
29 : // thus it must never be used where only a single statement
30 : // is correct (e.g. an if statement branch w/o braces)!
31 :
32 : #define CHECK_OK_VALUE(x) ok); \
33 : if (!*ok) return x; \
34 : ((void)0
35 : #define DUMMY ) // to make indentation work
36 : #undef DUMMY
37 :
38 : #define CHECK_OK CHECK_OK_VALUE(Expression::Default())
39 : #define CHECK_OK_VOID CHECK_OK_VALUE(this->Void())
40 :
41 : namespace {
42 :
43 86448196 : PreParserIdentifier GetSymbolHelper(Scanner* scanner) {
44 : // These symbols require slightly different treatement:
45 : // - regular keywords (async, await, etc.; treated in 1st switch.)
46 : // - 'contextual' keywords (and may contain escaped; treated in 2nd switch.)
47 : // - 'contextual' keywords, but may not be escaped (3rd switch).
48 43240864 : switch (scanner->current_token()) {
49 : case Token::AWAIT:
50 : return PreParserIdentifier::Await();
51 : case Token::ASYNC:
52 : return PreParserIdentifier::Async();
53 : default:
54 : break;
55 : }
56 43207332 : switch (scanner->current_contextual_token()) {
57 : case Token::CONSTRUCTOR:
58 : return PreParserIdentifier::Constructor();
59 : case Token::NAME:
60 : return PreParserIdentifier::Name();
61 : default:
62 : break;
63 : }
64 42343636 : if (scanner->literal_contains_escapes()) {
65 : return PreParserIdentifier::Default();
66 : }
67 42340596 : switch (scanner->current_contextual_token()) {
68 : case Token::EVAL:
69 : return PreParserIdentifier::Eval();
70 : case Token::ARGUMENTS:
71 : return PreParserIdentifier::Arguments();
72 : default:
73 : break;
74 : }
75 : return PreParserIdentifier::Default();
76 : }
77 :
78 : } // unnamed namespace
79 :
80 43240864 : PreParserIdentifier PreParser::GetSymbol() const {
81 84526221 : PreParserIdentifier symbol = GetSymbolHelper(scanner());
82 43240864 : if (track_unresolved_variables_) {
83 41285357 : const AstRawString* result = scanner()->CurrentSymbol(ast_value_factory());
84 : DCHECK_NOT_NULL(result);
85 : symbol.string_ = result;
86 : }
87 43240864 : return symbol;
88 : }
89 :
90 436519 : PreParser::PreParseResult PreParser::PreParseProgram(bool is_module) {
91 : DCHECK_NULL(scope_);
92 1578162 : DeclarationScope* scope = NewScriptScope();
93 : #ifdef DEBUG
94 : scope->set_is_being_lazily_parsed(true);
95 : #endif
96 :
97 : // ModuleDeclarationInstantiation for Source Text Module Records creates a
98 : // new Module Environment Record whose outer lexical environment record is
99 : // the global scope.
100 436519 : if (is_module) scope = NewModuleScope(scope);
101 :
102 436519 : FunctionState top_scope(&function_state_, &scope_, scope);
103 436519 : original_scope_ = scope_;
104 436519 : bool ok = true;
105 : int start_position = scanner()->peek_location().beg_pos;
106 436519 : parsing_module_ = is_module;
107 : PreParserStatementList body;
108 : ParseStatementList(body, Token::EOS, &ok);
109 436519 : original_scope_ = nullptr;
110 436519 : if (stack_overflow()) return kPreParseStackOverflow;
111 436514 : if (!ok) {
112 207425 : ReportUnexpectedToken(scanner()->current_token());
113 229089 : } else if (is_strict(language_mode())) {
114 61180 : CheckStrictOctalLiteral(start_position, scanner()->location().end_pos, &ok);
115 : }
116 : return kPreParseSuccess;
117 : }
118 :
119 2234348 : PreParser::PreParseResult PreParser::PreParseFunction(
120 : const AstRawString* function_name, FunctionKind kind,
121 : FunctionLiteral::FunctionType function_type,
122 : DeclarationScope* function_scope, bool parsing_module,
123 : bool is_inner_function, bool may_abort, int* use_counts,
124 2198511 : ProducedPreParsedScopeData** produced_preparsed_scope_data) {
125 : DCHECK_EQ(FUNCTION_SCOPE, function_scope->scope_type());
126 2234348 : parsing_module_ = parsing_module;
127 2234348 : use_counts_ = use_counts;
128 : DCHECK(!track_unresolved_variables_);
129 2234348 : track_unresolved_variables_ = is_inner_function;
130 : #ifdef DEBUG
131 : function_scope->set_is_being_lazily_parsed(true);
132 : #endif
133 :
134 : // Start collecting data for a new function which might contain skippable
135 : // functions.
136 : std::unique_ptr<ProducedPreParsedScopeData::DataGatheringScope>
137 : produced_preparsed_scope_data_scope;
138 4468696 : if (FLAG_preparser_scope_analysis && !IsArrowFunction(kind)) {
139 2210381 : track_unresolved_variables_ = true;
140 : produced_preparsed_scope_data_scope.reset(
141 : new ProducedPreParsedScopeData::DataGatheringScope(function_scope,
142 2210381 : this));
143 : }
144 :
145 : // In the preparser, we use the function literal ids to count how many
146 : // FunctionLiterals were encountered. The PreParser doesn't actually persist
147 : // FunctionLiterals, so there IDs don't matter.
148 7410461 : ResetFunctionLiteralId();
149 :
150 : // The caller passes the function_scope which is not yet inserted into the
151 : // scope stack. All scopes above the function_scope are ignored by the
152 : // PreParser.
153 : DCHECK_NULL(function_state_);
154 : DCHECK_NULL(scope_);
155 2234348 : FunctionState function_state(&function_state_, &scope_, function_scope);
156 : // This indirection is needed so that we can use the CHECK_OK macros.
157 2234348 : bool ok_holder = true;
158 : bool* ok = &ok_holder;
159 :
160 : PreParserFormalParameters formals(function_scope);
161 : DuplicateFinder duplicate_finder;
162 : std::unique_ptr<ExpressionClassifier> formals_classifier;
163 :
164 : // Parse non-arrow function parameters. For arrow functions, the parameters
165 : // have already been parsed.
166 2234348 : if (!IsArrowFunction(kind)) {
167 2210381 : formals_classifier.reset(new ExpressionClassifier(this, &duplicate_finder));
168 : // We return kPreParseSuccess in failure cases too - errors are retrieved
169 : // separately by Parser::SkipLazyFunctionBody.
170 2210381 : ParseFormalParameterList(&formals, CHECK_OK_VALUE(kPreParseSuccess));
171 2199960 : Expect(Token::RPAREN, CHECK_OK_VALUE(kPreParseSuccess));
172 : int formals_end_position = scanner()->location().end_pos;
173 :
174 : CheckArityRestrictions(
175 : formals.arity, kind, formals.has_rest, function_scope->start_position(),
176 2849002 : formals_end_position, CHECK_OK_VALUE(kPreParseSuccess));
177 : }
178 :
179 2222747 : Expect(Token::LBRACE, CHECK_OK_VALUE(kPreParseSuccess));
180 : DeclarationScope* inner_scope = function_scope;
181 : LazyParsingResult result;
182 :
183 2222527 : if (!formals.is_simple) {
184 70235 : inner_scope = NewVarblockScope();
185 : inner_scope->set_start_position(scanner()->location().beg_pos);
186 : }
187 :
188 : {
189 : BlockState block_state(&scope_, inner_scope);
190 2222527 : result = ParseStatementListAndLogFunction(&formals, may_abort, ok);
191 : }
192 :
193 2222527 : if (!formals.is_simple) {
194 70235 : BuildParameterInitializationBlock(formals, ok);
195 :
196 70235 : if (is_sloppy(inner_scope->language_mode())) {
197 55469 : inner_scope->HoistSloppyBlockFunctions(nullptr);
198 : }
199 :
200 : SetLanguageMode(function_scope, inner_scope->language_mode());
201 : inner_scope->set_end_position(scanner()->peek_location().end_pos);
202 70235 : inner_scope->FinalizeBlockScope();
203 : } else {
204 2152292 : if (is_sloppy(function_scope->language_mode())) {
205 1492206 : function_scope->HoistSloppyBlockFunctions(nullptr);
206 : }
207 : }
208 :
209 2222527 : if (!IsArrowFunction(kind) && track_unresolved_variables_ &&
210 : result == kLazyParsingComplete) {
211 : CreateFunctionNameAssignment(function_name, function_type, function_scope);
212 :
213 : // Declare arguments after parsing the function since lexical 'arguments'
214 : // masks the arguments object. Declare arguments before declaring the
215 : // function var since the arguments object masks 'function arguments'.
216 2198511 : function_scope->DeclareArguments(ast_value_factory());
217 : }
218 :
219 2222527 : use_counts_ = nullptr;
220 2222527 : track_unresolved_variables_ = false;
221 :
222 2222527 : if (result == kLazyParsingAborted) {
223 : return kPreParseAbort;
224 2222478 : } else if (stack_overflow()) {
225 : return kPreParseStackOverflow;
226 2222453 : } else if (!*ok) {
227 : DCHECK(pending_error_handler_->has_pending_error());
228 : } else {
229 : DCHECK_EQ(Token::RBRACE, scanner()->peek());
230 :
231 2185060 : if (!IsArrowFunction(kind)) {
232 : // Validate parameter names. We can do this only after parsing the
233 : // function, since the function can declare itself strict.
234 : const bool allow_duplicate_parameters =
235 3621365 : is_sloppy(function_scope->language_mode()) && formals.is_simple &&
236 : !IsConciseMethod(kind);
237 : ValidateFormalParameters(function_scope->language_mode(),
238 : allow_duplicate_parameters,
239 4326566 : CHECK_OK_VALUE(kPreParseSuccess));
240 :
241 2161737 : *produced_preparsed_scope_data = produced_preparsed_scope_data_;
242 : }
243 :
244 2183514 : if (is_strict(function_scope->language_mode())) {
245 : int end_pos = scanner()->location().end_pos;
246 649721 : CheckStrictOctalLiteral(function_scope->start_position(), end_pos, ok);
247 : }
248 : }
249 : return kPreParseSuccess;
250 : }
251 :
252 :
253 : // Preparsing checks a JavaScript program and emits preparse-data that helps
254 : // a later parsing to be faster.
255 : // See preparser-data.h for the data.
256 :
257 : // The PreParser checks that the syntax follows the grammar for JavaScript,
258 : // and collects some information about the program along the way.
259 : // The grammar check is only performed in order to understand the program
260 : // sufficiently to deduce some information about it, that can be used
261 : // to speed up later parsing. Finding errors is not the goal of pre-parsing,
262 : // rather it is to speed up properly written and correct programs.
263 : // That means that contextual checks (like a label being declared where
264 : // it is used) are generally omitted.
265 :
266 386442 : PreParser::Expression PreParser::ParseFunctionLiteral(
267 : Identifier function_name, Scanner::Location function_name_location,
268 : FunctionNameValidity function_name_validity, FunctionKind kind,
269 : int function_token_pos, FunctionLiteral::FunctionType function_type,
270 : LanguageMode language_mode, bool* ok) {
271 : // Function ::
272 : // '(' FormalParameterList? ')' '{' FunctionBody '}'
273 : const RuntimeCallStats::CounterId counters[2][2] = {
274 : {&RuntimeCallStats::PreParseBackgroundNoVariableResolution,
275 : &RuntimeCallStats::PreParseNoVariableResolution},
276 : {&RuntimeCallStats::PreParseBackgroundWithVariableResolution,
277 386442 : &RuntimeCallStats::PreParseWithVariableResolution}};
278 : RuntimeCallTimerScope runtime_timer(
279 : runtime_call_stats_,
280 386442 : counters[track_unresolved_variables_][parsing_on_main_thread_]);
281 :
282 1625659 : DeclarationScope* function_scope = NewFunctionScope(kind);
283 0 : function_scope->SetLanguageMode(language_mode);
284 :
285 : // Start collecting data for a new function which might contain skippable
286 : // functions.
287 : std::unique_ptr<ProducedPreParsedScopeData::DataGatheringScope>
288 : produced_preparsed_scope_data_scope;
289 736912 : if (!function_state_->next_function_is_likely_called() &&
290 350470 : produced_preparsed_scope_data_ != nullptr) {
291 : DCHECK(FLAG_preparser_scope_analysis);
292 : DCHECK(track_unresolved_variables_);
293 : produced_preparsed_scope_data_scope.reset(
294 : new ProducedPreParsedScopeData::DataGatheringScope(function_scope,
295 151280 : this));
296 : }
297 :
298 386442 : FunctionState function_state(&function_state_, &scope_, function_scope);
299 : DuplicateFinder duplicate_finder;
300 386442 : ExpressionClassifier formals_classifier(this, &duplicate_finder);
301 : int func_id = GetNextFunctionLiteralId();
302 :
303 386442 : Expect(Token::LPAREN, CHECK_OK);
304 : int start_position = scanner()->location().beg_pos;
305 : function_scope->set_start_position(start_position);
306 : PreParserFormalParameters formals(function_scope);
307 383776 : ParseFormalParameterList(&formals, CHECK_OK);
308 361795 : Expect(Token::RPAREN, CHECK_OK);
309 : int formals_end_position = scanner()->location().end_pos;
310 :
311 : CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position,
312 360466 : formals_end_position, CHECK_OK);
313 :
314 359476 : Expect(Token::LBRACE, CHECK_OK);
315 :
316 : // Parse function body.
317 : PreParserStatementList body;
318 : int pos = function_token_pos == kNoSourcePosition ? peek_position()
319 359116 : : function_token_pos;
320 : ParseFunctionBody(body, function_name, pos, formals, kind, function_type,
321 359116 : CHECK_OK);
322 :
323 : // Parsing the body may change the language mode in our scope.
324 : language_mode = function_scope->language_mode();
325 :
326 291857 : if (is_sloppy(language_mode)) {
327 163799 : function_scope->HoistSloppyBlockFunctions(nullptr);
328 : }
329 :
330 : // Validate name and parameter names. We can do this only after parsing the
331 : // function, since the function can declare itself strict.
332 : CheckFunctionName(language_mode, function_name, function_name_validity,
333 291857 : function_name_location, CHECK_OK);
334 : const bool allow_duplicate_parameters =
335 445146 : is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind);
336 290296 : ValidateFormalParameters(language_mode, allow_duplicate_parameters, CHECK_OK);
337 :
338 : int end_position = scanner()->location().end_pos;
339 288004 : if (is_strict(language_mode)) {
340 125075 : CheckStrictOctalLiteral(start_position, end_position, CHECK_OK);
341 : }
342 :
343 287949 : if (produced_preparsed_scope_data_scope) {
344 : produced_preparsed_scope_data_scope->MarkFunctionAsSkippable(
345 146305 : end_position, GetLastFunctionLiteralId() - func_id);
346 : }
347 287949 : if (FLAG_trace_preparse) {
348 : PrintF(" [%s]: %i-%i\n",
349 : track_unresolved_variables_ ? "Preparse resolution"
350 : : "Preparse no-resolution",
351 0 : function_scope->start_position(), function_scope->end_position());
352 : }
353 :
354 : return Expression::Default();
355 : }
356 :
357 2222527 : PreParser::LazyParsingResult PreParser::ParseStatementListAndLogFunction(
358 : PreParserFormalParameters* formals, bool may_abort, bool* ok) {
359 : PreParserStatementList body;
360 : LazyParsingResult result = ParseStatementList(
361 4407587 : body, Token::RBRACE, may_abort, CHECK_OK_VALUE(kLazyParsingComplete));
362 2185109 : if (result == kLazyParsingAborted) return result;
363 :
364 : // Position right after terminal '}'.
365 : DCHECK_EQ(Token::RBRACE, scanner()->peek());
366 : int body_end = scanner()->peek_location().end_pos;
367 : DCHECK_EQ(this->scope()->is_function_scope(), formals->is_simple);
368 : log_.LogFunction(body_end, formals->num_parameters(),
369 2185060 : GetLastFunctionLiteralId());
370 2185060 : return kLazyParsingComplete;
371 : }
372 :
373 89305 : PreParserStatement PreParser::BuildParameterInitializationBlock(
374 : const PreParserFormalParameters& parameters, bool* ok) {
375 : DCHECK(!parameters.is_simple);
376 : DCHECK(scope()->is_function_scope());
377 178610 : if (FLAG_preparser_scope_analysis &&
378 89803 : scope()->AsDeclarationScope()->calls_sloppy_eval() &&
379 990 : produced_preparsed_scope_data_ != nullptr) {
380 : // We cannot replicate the Scope structure constructed by the Parser,
381 : // because we've lost information whether each individual parameter was
382 : // simple or not. Give up trying to produce data to skip inner functions.
383 984 : if (produced_preparsed_scope_data_->parent() != nullptr) {
384 : // Lazy parsing started before the current function; the function which
385 : // cannot contain skippable functions is the parent function. (Its inner
386 : // functions cannot either; they are implicitly bailed out.)
387 : produced_preparsed_scope_data_->parent()->Bailout();
388 : } else {
389 : // Lazy parsing started at the current function; it cannot contain
390 : // skippable functions.
391 : produced_preparsed_scope_data_->Bailout();
392 : }
393 : }
394 :
395 89305 : return PreParserStatement::Default();
396 : }
397 :
398 35019270 : PreParserExpression PreParser::ExpressionFromIdentifier(
399 35019270 : const PreParserIdentifier& name, int start_position, InferName infer) {
400 : VariableProxy* proxy = nullptr;
401 35019270 : if (track_unresolved_variables_) {
402 : DCHECK_NOT_NULL(name.string_);
403 : proxy = scope()->NewUnresolved(factory()->ast_node_factory(), name.string_,
404 68462095 : start_position, NORMAL_VARIABLE);
405 : }
406 35019270 : return PreParserExpression::FromIdentifier(name, proxy, zone());
407 : }
408 :
409 4307857 : void PreParser::DeclareAndInitializeVariables(
410 : PreParserStatement block,
411 : const DeclarationDescriptor* declaration_descriptor,
412 : const DeclarationParsingResult::Declaration* declaration,
413 : ZoneList<const AstRawString*>* names, bool* ok) {
414 4307857 : if (declaration->pattern.variables_ != nullptr) {
415 : DCHECK(FLAG_lazy_inner_functions);
416 : DCHECK(track_unresolved_variables_);
417 12037701 : for (auto variable : *(declaration->pattern.variables_)) {
418 4036591 : declaration_descriptor->scope->RemoveUnresolved(variable);
419 : Variable* var = scope()->DeclareVariableName(
420 8165620 : variable->raw_name(), declaration_descriptor->mode);
421 4036591 : if (FLAG_preparser_scope_analysis) {
422 : MarkLoopVariableAsAssigned(declaration_descriptor->scope, var,
423 4036591 : declaration_descriptor->declaration_kind);
424 : // This is only necessary if there is an initializer, but we don't have
425 : // that information here. Consequently, the preparser sometimes says
426 : // maybe-assigned where the parser (correctly) says never-assigned.
427 : }
428 4036591 : if (names) {
429 92438 : names->Add(variable->raw_name(), zone());
430 : }
431 : }
432 : }
433 4307857 : }
434 :
435 : #undef CHECK_OK
436 : #undef CHECK_OK_CUSTOM
437 :
438 :
439 : } // namespace internal
440 : } // namespace v8
|