Line data Source code
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
3 : // found in the LICENSE file.
4 :
5 : #include "src/parsing/parser.h"
6 :
7 : #include <algorithm>
8 : #include <memory>
9 :
10 : #include "src/ast/ast-function-literal-id-reindexer.h"
11 : #include "src/ast/ast-traversal-visitor.h"
12 : #include "src/ast/ast.h"
13 : #include "src/ast/source-range-ast-visitor.h"
14 : #include "src/bailout-reason.h"
15 : #include "src/base/overflowing-math.h"
16 : #include "src/base/platform/platform.h"
17 : #include "src/char-predicates-inl.h"
18 : #include "src/compiler-dispatcher/compiler-dispatcher.h"
19 : #include "src/conversions-inl.h"
20 : #include "src/log.h"
21 : #include "src/message-template.h"
22 : #include "src/objects/scope-info.h"
23 : #include "src/parsing/expression-scope-reparenter.h"
24 : #include "src/parsing/parse-info.h"
25 : #include "src/parsing/rewriter.h"
26 : #include "src/runtime/runtime.h"
27 : #include "src/string-stream.h"
28 : #include "src/tracing/trace-event.h"
29 :
30 : namespace v8 {
31 : namespace internal {
32 :
33 99730 : FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name,
34 : bool call_super, int pos,
35 : int end_pos) {
36 : int expected_property_count = -1;
37 : const int parameter_count = 0;
38 :
39 : FunctionKind kind = call_super ? FunctionKind::kDefaultDerivedConstructor
40 99730 : : FunctionKind::kDefaultBaseConstructor;
41 227343 : DeclarationScope* function_scope = NewFunctionScope(kind);
42 99737 : SetLanguageMode(function_scope, LanguageMode::kStrict);
43 : // Set start and end position to the same value
44 : function_scope->set_start_position(pos);
45 : function_scope->set_end_position(pos);
46 99737 : ScopedPtrList<Statement> body(pointer_buffer());
47 :
48 : {
49 99737 : FunctionState function_state(&function_state_, &scope_, function_scope);
50 :
51 99737 : if (call_super) {
52 : // Create a SuperCallReference and handle in BytecodeGenerator.
53 27875 : auto constructor_args_name = ast_value_factory()->empty_string();
54 : bool is_rest = true;
55 : bool is_optional = false;
56 : Variable* constructor_args = function_scope->DeclareParameter(
57 : constructor_args_name, VariableMode::kTemporary, is_optional, is_rest,
58 27875 : ast_value_factory(), pos);
59 :
60 : Expression* call;
61 : {
62 : ScopedPtrList<Expression> args(pointer_buffer());
63 : Spread* spread_args = factory()->NewSpread(
64 55746 : factory()->NewVariableProxy(constructor_args), pos, pos);
65 :
66 27874 : args.Add(spread_args);
67 27874 : Expression* super_call_ref = NewSuperCallReference(pos);
68 27874 : call = factory()->NewCall(super_call_ref, args, pos);
69 : }
70 55751 : body.Add(factory()->NewReturnStatement(call, pos));
71 : }
72 :
73 99738 : expected_property_count = function_state.expected_property_count();
74 : }
75 :
76 : FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
77 : name, function_scope, body, expected_property_count, parameter_count,
78 : parameter_count, FunctionLiteral::kNoDuplicateParameters,
79 : FunctionLiteral::kAnonymousExpression, default_eager_compile_hint(), pos,
80 99738 : true, GetNextFunctionLiteralId());
81 99731 : return function_literal;
82 : }
83 :
84 1763886 : void Parser::GetUnexpectedTokenMessage(Token::Value token,
85 : MessageTemplate* message,
86 : Scanner::Location* location,
87 : const char** arg) {
88 1763886 : switch (token) {
89 : case Token::EOS:
90 1635 : *message = MessageTemplate::kUnexpectedEOS;
91 1635 : break;
92 : case Token::SMI:
93 : case Token::NUMBER:
94 : case Token::BIGINT:
95 426 : *message = MessageTemplate::kUnexpectedTokenNumber;
96 426 : break;
97 : case Token::STRING:
98 348 : *message = MessageTemplate::kUnexpectedTokenString;
99 348 : break;
100 : case Token::PRIVATE_NAME:
101 : case Token::IDENTIFIER:
102 9023 : *message = MessageTemplate::kUnexpectedTokenIdentifier;
103 9023 : break;
104 : case Token::AWAIT:
105 : case Token::ENUM:
106 3340 : *message = MessageTemplate::kUnexpectedReserved;
107 3340 : break;
108 : case Token::LET:
109 : case Token::STATIC:
110 : case Token::YIELD:
111 : case Token::FUTURE_STRICT_RESERVED_WORD:
112 1855678 : *message = is_strict(language_mode())
113 : ? MessageTemplate::kUnexpectedStrictReserved
114 16089 : : MessageTemplate::kUnexpectedTokenIdentifier;
115 16089 : break;
116 : case Token::TEMPLATE_SPAN:
117 : case Token::TEMPLATE_TAIL:
118 200 : *message = MessageTemplate::kUnexpectedTemplateString;
119 200 : break;
120 : case Token::ESCAPED_STRICT_RESERVED_WORD:
121 : case Token::ESCAPED_KEYWORD:
122 4340 : *message = MessageTemplate::kInvalidEscapedReservedWord;
123 4340 : break;
124 : case Token::ILLEGAL:
125 1648171 : if (scanner()->has_error()) {
126 207507 : *message = scanner()->error();
127 207507 : *location = scanner()->error_location();
128 : } else {
129 1440664 : *message = MessageTemplate::kInvalidOrUnexpectedToken;
130 : }
131 : break;
132 : case Token::REGEXP_LITERAL:
133 0 : *message = MessageTemplate::kUnexpectedTokenRegExp;
134 0 : break;
135 : default:
136 : const char* name = Token::String(token);
137 : DCHECK_NOT_NULL(name);
138 80314 : *arg = name;
139 80314 : break;
140 : }
141 1763886 : }
142 :
143 : // ----------------------------------------------------------------------------
144 : // Implementation of Parser
145 :
146 1645236 : bool Parser::ShortcutNumericLiteralBinaryExpression(Expression** x,
147 : Expression* y,
148 : Token::Value op, int pos) {
149 1645236 : if ((*x)->IsNumberLiteral() && y->IsNumberLiteral()) {
150 1257881 : double x_val = (*x)->AsLiteral()->AsNumber();
151 1257870 : double y_val = y->AsLiteral()->AsNumber();
152 628932 : switch (op) {
153 : case Token::ADD:
154 15786 : *x = factory()->NewNumberLiteral(x_val + y_val, pos);
155 15786 : return true;
156 : case Token::SUB:
157 1716 : *x = factory()->NewNumberLiteral(x_val - y_val, pos);
158 1715 : return true;
159 : case Token::MUL:
160 214756 : *x = factory()->NewNumberLiteral(x_val * y_val, pos);
161 214758 : return true;
162 : case Token::DIV:
163 3278 : *x = factory()->NewNumberLiteral(base::Divide(x_val, y_val), pos);
164 3279 : return true;
165 : case Token::BIT_OR: {
166 10592 : int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
167 10593 : *x = factory()->NewNumberLiteral(value, pos);
168 10593 : return true;
169 : }
170 : case Token::BIT_AND: {
171 376 : int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
172 376 : *x = factory()->NewNumberLiteral(value, pos);
173 376 : return true;
174 : }
175 : case Token::BIT_XOR: {
176 201 : int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
177 201 : *x = factory()->NewNumberLiteral(value, pos);
178 201 : return true;
179 : }
180 : case Token::SHL: {
181 379702 : int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1F);
182 379698 : *x = factory()->NewNumberLiteral(value, pos);
183 379703 : return true;
184 : }
185 : case Token::SHR: {
186 437 : uint32_t shift = DoubleToInt32(y_val) & 0x1F;
187 437 : uint32_t value = DoubleToUint32(x_val) >> shift;
188 437 : *x = factory()->NewNumberLiteral(value, pos);
189 437 : return true;
190 : }
191 : case Token::SAR: {
192 374 : uint32_t shift = DoubleToInt32(y_val) & 0x1F;
193 374 : int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
194 374 : *x = factory()->NewNumberLiteral(value, pos);
195 374 : return true;
196 : }
197 : case Token::EXP: {
198 1240 : double value = Pow(x_val, y_val);
199 1239 : int int_value = static_cast<int>(value);
200 : *x = factory()->NewNumberLiteral(
201 1239 : int_value == value && value != -0.0 ? int_value : value, pos);
202 1240 : return true;
203 : }
204 : default:
205 : break;
206 : }
207 : }
208 : return false;
209 : }
210 :
211 1016778 : bool Parser::CollapseNaryExpression(Expression** x, Expression* y,
212 : Token::Value op, int pos,
213 317759 : const SourceRange& range) {
214 : // Filter out unsupported ops.
215 1016778 : if (!Token::IsBinaryOp(op) || op == Token::EXP) return false;
216 :
217 : // Convert *x into an nary operation with the given op, returning false if
218 : // this is not possible.
219 201526 : NaryOperation* nary = nullptr;
220 2029079 : if ((*x)->IsBinaryOperation()) {
221 611962 : BinaryOperation* binop = (*x)->AsBinaryOperation();
222 188503 : if (binop->op() != op) return false;
223 :
224 117481 : nary = factory()->NewNaryOperation(op, binop->left(), 2);
225 117475 : nary->AddSubsequent(binop->right(), binop->position());
226 : ConvertBinaryToNaryOperationSourceRange(binop, nary);
227 117475 : *x = nary;
228 826037 : } else if ((*x)->IsNaryOperation()) {
229 201526 : nary = (*x)->AsNaryOperation();
230 201526 : if (nary->op() != op) return false;
231 : } else {
232 : return false;
233 : }
234 :
235 : // Append our current expression to the nary operation.
236 : // TODO(leszeks): Do some literal collapsing here if we're appending Smi or
237 : // String literals.
238 : nary->AddSubsequent(y, pos);
239 : nary->clear_parenthesized();
240 : AppendNaryOperationSourceRange(nary, range);
241 :
242 : return true;
243 : }
244 :
245 664443 : Expression* Parser::BuildUnaryExpression(Expression* expression,
246 : Token::Value op, int pos) {
247 : DCHECK_NOT_NULL(expression);
248 664443 : const Literal* literal = expression->AsLiteral();
249 664445 : if (literal != nullptr) {
250 373744 : if (op == Token::NOT) {
251 : // Convert the literal to a boolean condition and negate it.
252 550 : return factory()->NewBooleanLiteral(literal->ToBooleanIsFalse(), pos);
253 373469 : } else if (literal->IsNumberLiteral()) {
254 : // Compute some expressions involving only number literals.
255 369052 : double value = literal->AsNumber();
256 369053 : switch (op) {
257 : case Token::ADD:
258 : return expression;
259 : case Token::SUB:
260 355548 : return factory()->NewNumberLiteral(-value, pos);
261 : case Token::BIT_NOT:
262 1624 : return factory()->NewNumberLiteral(~DoubleToInt32(value), pos);
263 : default:
264 : break;
265 : }
266 : }
267 : }
268 611092 : return factory()->NewUnaryOperation(op, expression, pos);
269 : }
270 :
271 1219 : Expression* Parser::NewThrowError(Runtime::FunctionId id,
272 : MessageTemplate message,
273 : const AstRawString* arg, int pos) {
274 1219 : ScopedPtrList<Expression> args(pointer_buffer());
275 2438 : args.Add(factory()->NewSmiLiteral(static_cast<int>(message), pos));
276 2438 : args.Add(factory()->NewStringLiteral(arg, pos));
277 1219 : CallRuntime* call_constructor = factory()->NewCallRuntime(id, args, pos);
278 2438 : return factory()->NewThrow(call_constructor, pos);
279 : }
280 :
281 2758 : Expression* Parser::NewSuperPropertyReference(int pos) {
282 : // this_function[home_object_symbol]
283 : VariableProxy* this_function_proxy =
284 5516 : NewUnresolved(ast_value_factory()->this_function_string(), pos);
285 : Expression* home_object_symbol_literal = factory()->NewSymbolLiteral(
286 2758 : AstSymbol::kHomeObjectSymbol, kNoSourcePosition);
287 : Expression* home_object = factory()->NewProperty(
288 2758 : this_function_proxy, home_object_symbol_literal, pos);
289 : return factory()->NewSuperPropertyReference(
290 8274 : ThisExpression(pos)->AsVariableProxy(), home_object, pos);
291 : }
292 :
293 30616 : Expression* Parser::NewSuperCallReference(int pos) {
294 : VariableProxy* new_target_proxy =
295 61232 : NewUnresolved(ast_value_factory()->new_target_string(), pos);
296 : VariableProxy* this_function_proxy =
297 61234 : NewUnresolved(ast_value_factory()->this_function_string(), pos);
298 : return factory()->NewSuperCallReference(
299 : ThisExpression(pos)->AsVariableProxy(), new_target_proxy,
300 91859 : this_function_proxy, pos);
301 : }
302 :
303 2003 : Expression* Parser::NewTargetExpression(int pos) {
304 4006 : auto proxy = NewUnresolved(ast_value_factory()->new_target_string(), pos);
305 : proxy->set_is_new_target();
306 2003 : return proxy;
307 : }
308 :
309 3210 : Expression* Parser::ImportMetaExpression(int pos) {
310 3210 : ScopedPtrList<Expression> args(pointer_buffer());
311 : return factory()->NewCallRuntime(Runtime::kInlineGetImportMetaObject, args,
312 6420 : pos);
313 : }
314 :
315 26026750 : Expression* Parser::ExpressionFromLiteral(Token::Value token, int pos) {
316 26026750 : switch (token) {
317 : case Token::NULL_LITERAL:
318 21220330 : return factory()->NewNullLiteral(pos);
319 : case Token::TRUE_LITERAL:
320 323935 : return factory()->NewBooleanLiteral(true, pos);
321 : case Token::FALSE_LITERAL:
322 478282 : return factory()->NewBooleanLiteral(false, pos);
323 : case Token::SMI: {
324 : uint32_t value = scanner()->smi_value();
325 39492088 : return factory()->NewSmiLiteral(value, pos);
326 : }
327 : case Token::NUMBER: {
328 1311091 : double value = scanner()->DoubleValue();
329 1311197 : return factory()->NewNumberLiteral(value, pos);
330 : }
331 : case Token::BIGINT:
332 : return factory()->NewBigIntLiteral(
333 12241 : AstBigInt(scanner()->CurrentLiteralAsCString(zone())), pos);
334 : case Token::STRING: {
335 8962036 : return factory()->NewStringLiteral(GetSymbol(), pos);
336 : }
337 : default:
338 : DCHECK(false);
339 : }
340 0 : return FailureExpression();
341 : }
342 :
343 54646 : Expression* Parser::NewV8Intrinsic(const AstRawString* name,
344 29279 : const ScopedPtrList<Expression>& args,
345 : int pos) {
346 54646 : if (extension_ != nullptr) {
347 : // The extension structures are only accessible while parsing the
348 : // very first time, not when reparsing because of lazy compilation.
349 5 : GetClosureScope()->ForceEagerCompilation();
350 : }
351 :
352 : DCHECK(name->is_one_byte());
353 : const Runtime::Function* function =
354 54649 : Runtime::FunctionForName(name->raw_data(), name->length());
355 :
356 54709 : if (function != nullptr) {
357 : // Check for possible name clash.
358 : DCHECK_EQ(Context::kNotFound,
359 : Context::IntrinsicIndexForName(name->raw_data(), name->length()));
360 :
361 : // Check that the expected number of arguments are being passed.
362 83938 : if (function->nargs != -1 && function->nargs != args.length()) {
363 9 : ReportMessage(MessageTemplate::kRuntimeWrongNumArgs);
364 9 : return FailureExpression();
365 : }
366 :
367 54650 : return factory()->NewCallRuntime(function, args, pos);
368 : }
369 :
370 : int context_index =
371 50 : Context::IntrinsicIndexForName(name->raw_data(), name->length());
372 :
373 : // Check that the function is defined.
374 50 : if (context_index == Context::kNotFound) {
375 45 : ReportMessage(MessageTemplate::kNotDefined, name);
376 45 : return FailureExpression();
377 : }
378 :
379 5 : return factory()->NewCallRuntime(context_index, args, pos);
380 : }
381 :
382 14371920 : Parser::Parser(ParseInfo* info)
383 : : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(),
384 : info->extension(), info->GetOrCreateAstValueFactory(),
385 : info->pending_error_handler(),
386 : info->runtime_call_stats(), info->logger(),
387 : info->script().is_null() ? -1 : info->script()->id(),
388 : info->is_module(), true),
389 : info_(info),
390 : scanner_(info->character_stream(), info->is_module()),
391 : preparser_zone_(info->zone()->allocator(), ZONE_NAME),
392 : reusable_preparser_(nullptr),
393 : mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
394 : source_range_map_(info->source_range_map()),
395 : target_stack_(nullptr),
396 : total_preparse_skipped_(0),
397 : consumed_preparse_data_(info->consumed_preparse_data()),
398 : preparse_data_buffer_(),
399 24410341 : parameters_end_pos_(info->parameters_end_pos()) {
400 : // Even though we were passed ParseInfo, we should not store it in
401 : // Parser - this makes sure that Isolate is not accidentally accessed via
402 : // ParseInfo during background parsing.
403 : DCHECK_NOT_NULL(info->character_stream());
404 : // Determine if functions can be lazily compiled. This is necessary to
405 : // allow some of our builtin JS files to be lazily compiled. These
406 : // builtins cannot be handled lazily by the parser, since we have to know
407 : // if a function uses the special natives syntax, which is something the
408 : // parser records.
409 : // If the debugger requests compilation for break points, we cannot be
410 : // aggressive about lazy compilation, because it might trigger compilation
411 : // of functions without an outer context when setting a breakpoint through
412 : // Debug::FindSharedFunctionInfoInScript
413 : // We also compile eagerly for kProduceExhaustiveCodeCache.
414 4881683 : bool can_compile_lazily = info->allow_lazy_compile() && !info->is_eager();
415 :
416 : set_default_eager_compile_hint(can_compile_lazily
417 : ? FunctionLiteral::kShouldLazyCompile
418 2441005 : : FunctionLiteral::kShouldEagerCompile);
419 4607432 : allow_lazy_ = info->allow_lazy_compile() && info->allow_lazy_parsing() &&
420 4607772 : !info->is_native() && info->extension() == nullptr &&
421 2441005 : can_compile_lazily;
422 4137218 : set_allow_natives(info->allow_natives_syntax() || info->is_native());
423 : set_allow_harmony_public_fields(info->allow_harmony_public_fields());
424 : set_allow_harmony_static_fields(info->allow_harmony_static_fields());
425 : set_allow_harmony_dynamic_import(info->allow_harmony_dynamic_import());
426 : set_allow_harmony_import_meta(info->allow_harmony_import_meta());
427 : set_allow_harmony_numeric_separator(info->allow_harmony_numeric_separator());
428 : set_allow_harmony_private_fields(info->allow_harmony_private_fields());
429 : set_allow_harmony_private_methods(info->allow_harmony_private_methods());
430 185512405 : for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
431 : ++feature) {
432 183071400 : use_counts_[feature] = 0;
433 : }
434 2441005 : }
435 :
436 13122 : void Parser::InitializeEmptyScopeChain(ParseInfo* info) {
437 : DCHECK_NULL(original_scope_);
438 : DCHECK_NULL(info->script_scope());
439 2441036 : DeclarationScope* script_scope = NewScriptScope();
440 : info->set_script_scope(script_scope);
441 2441037 : original_scope_ = script_scope;
442 13122 : }
443 :
444 2427914 : void Parser::DeserializeScopeChain(
445 1010989 : Isolate* isolate, ParseInfo* info,
446 : MaybeHandle<ScopeInfo> maybe_outer_scope_info,
447 : Scope::DeserializationMode mode) {
448 : InitializeEmptyScopeChain(info);
449 : Handle<ScopeInfo> outer_scope_info;
450 2427915 : if (maybe_outer_scope_info.ToHandle(&outer_scope_info)) {
451 : DCHECK(ThreadId::Current().Equals(isolate->thread_id()));
452 : original_scope_ = Scope::DeserializeScopeChain(
453 : isolate, zone(), *outer_scope_info, info->script_scope(),
454 2021979 : ast_value_factory(), mode);
455 : }
456 2427924 : }
457 :
458 : namespace {
459 :
460 2445650 : void MaybeResetCharacterStream(ParseInfo* info, FunctionLiteral* literal) {
461 : // Don't reset the character stream if there is an asm.js module since it will
462 : // be used again by the asm-parser.
463 2440880 : if (info->contains_asm_module()) {
464 4768 : if (FLAG_stress_validate_asm) return;
465 9539 : if (literal != nullptr && literal->scope()->ContainsAsmModule()) return;
466 : }
467 2436134 : info->ResetCharacterStream();
468 : }
469 :
470 4483348 : void MaybeProcessSourceRanges(ParseInfo* parse_info, Expression* root,
471 : uintptr_t stack_limit_) {
472 4482533 : if (root != nullptr && parse_info->source_range_map() != nullptr) {
473 : SourceRangeAstVisitor visitor(stack_limit_, root,
474 815 : parse_info->source_range_map());
475 : visitor.Run();
476 : }
477 2427916 : }
478 :
479 : } // namespace
480 :
481 1710502 : FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
482 : // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
483 : // see comment for HistogramTimerScope class.
484 :
485 : // It's OK to use the Isolate & counters here, since this function is only
486 : // called in the main thread.
487 : DCHECK(parsing_on_main_thread_);
488 : RuntimeCallTimerScope runtime_timer(
489 : runtime_call_stats_, info->is_eval()
490 : ? RuntimeCallCounterId::kParseEval
491 1710489 : : RuntimeCallCounterId::kParseProgram);
492 5131471 : TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram");
493 : base::ElapsedTimer timer;
494 1710492 : if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
495 :
496 : // Initialize parser state.
497 : DeserializeScopeChain(isolate, info, info->maybe_outer_scope_info(),
498 1710492 : Scope::DeserializationMode::kIncludingVariables);
499 :
500 1710493 : scanner_.Initialize();
501 1717901 : if (FLAG_harmony_hashbang && !info->is_eval()) {
502 6136 : scanner_.SkipHashBang();
503 : }
504 1710494 : FunctionLiteral* result = DoParseProgram(isolate, info);
505 1710498 : MaybeResetCharacterStream(info, result);
506 1710501 : MaybeProcessSourceRanges(info, result, stack_limit_);
507 :
508 1710495 : HandleSourceURLComments(isolate, info->script());
509 :
510 1710487 : if (V8_UNLIKELY(FLAG_log_function_events) && result != nullptr) {
511 13 : double ms = timer.Elapsed().InMillisecondsF();
512 : const char* event_name = "parse-eval";
513 13 : Script script = *info->script();
514 : int start = -1;
515 : int end = -1;
516 13 : if (!info->is_eval()) {
517 : event_name = "parse-script";
518 : start = 0;
519 13 : end = String::cast(script->source())->length();
520 : }
521 26 : LOG(isolate,
522 : FunctionEvent(event_name, script->id(), ms, start, end, "", 0));
523 : }
524 1710490 : return result;
525 : }
526 :
527 1759148 : FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
528 : // Note that this function can be called from the main thread or from a
529 : // background thread. We should not access anything Isolate / heap dependent
530 : // via ParseInfo, and also not pass it forward. If not on the main thread
531 : // isolate will be nullptr.
532 : DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr);
533 : DCHECK_NULL(scope_);
534 : DCHECK_NULL(target_stack_);
535 :
536 1723537 : ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
537 7253207 : ResetFunctionLiteralId();
538 : DCHECK(info->function_literal_id() == FunctionLiteral::kIdTypeTopLevel ||
539 : info->function_literal_id() == FunctionLiteral::kIdTypeInvalid);
540 :
541 : FunctionLiteral* result = nullptr;
542 : {
543 1723537 : Scope* outer = original_scope_;
544 : DCHECK_NOT_NULL(outer);
545 1723537 : if (info->is_eval()) {
546 961938 : outer = NewEvalScope(outer);
547 761599 : } else if (parsing_module_) {
548 : DCHECK_EQ(outer, info->script_scope());
549 35611 : outer = NewModuleScope(info->script_scope());
550 : }
551 :
552 1723537 : DeclarationScope* scope = outer->AsDeclarationScope();
553 : scope->set_start_position(0);
554 :
555 1723529 : FunctionState function_state(&function_state_, &scope_, scope);
556 1723529 : ScopedPtrList<Statement> body(pointer_buffer());
557 1723529 : int beg_pos = scanner()->location().beg_pos;
558 1723529 : if (parsing_module_) {
559 : DCHECK(info->is_module());
560 : // Declare the special module parameter.
561 35611 : auto name = ast_value_factory()->empty_string();
562 : bool is_rest = false;
563 : bool is_optional = false;
564 : auto var = scope->DeclareParameter(name, VariableMode::kVar, is_optional,
565 35611 : is_rest, ast_value_factory(), beg_pos);
566 : var->AllocateTo(VariableLocation::PARAMETER, 0);
567 :
568 35611 : PrepareGeneratorVariables();
569 : Expression* initial_yield =
570 35611 : BuildInitialYield(kNoSourcePosition, kGeneratorFunction);
571 : body.Add(
572 71222 : factory()->NewExpressionStatement(initial_yield, kNoSourcePosition));
573 :
574 35611 : ParseModuleItemList(&body);
575 35611 : if (!module()->Validate(this->scope()->AsModuleScope(),
576 71222 : pending_error_handler(), zone())) {
577 : scanner()->set_parser_error();
578 : }
579 1687918 : } else if (info->is_wrapped_as_function()) {
580 74 : ParseWrapped(isolate, info, &body, scope, zone());
581 : } else {
582 : // Don't count the mode in the use counters--give the program a chance
583 : // to enable script-wide strict mode below.
584 : this->scope()->SetLanguageMode(info->language_mode());
585 1687844 : ParseStatementList(&body, Token::EOS);
586 : }
587 :
588 : // The parser will peek but not consume EOS. Our scope logically goes all
589 : // the way to the EOS, though.
590 : scope->set_end_position(peek_position());
591 :
592 1723434 : if (is_strict(language_mode())) {
593 323540 : CheckStrictOctalLiteral(beg_pos, end_position());
594 : }
595 1723436 : if (is_sloppy(language_mode())) {
596 : // TODO(littledan): Function bindings on the global object that modify
597 : // pre-existing bindings should be made writable, enumerable and
598 : // nonconfigurable if possible, whereas this code will leave attributes
599 : // unchanged if the property already exists.
600 1399860 : InsertSloppyBlockFunctionVarBindings(scope);
601 : }
602 : // Internalize the ast strings in the case of eval so we can check for
603 : // conflicting var declarations with outer scope-info-backed scopes.
604 1723432 : if (info->is_eval()) {
605 : DCHECK(parsing_on_main_thread_);
606 961938 : info->ast_value_factory()->Internalize(isolate);
607 : }
608 1723432 : CheckConflictingVarDeclarations(scope);
609 :
610 1723478 : if (info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
611 1367188 : if (body.length() != 1 || !body.at(0)->IsExpressionStatement() ||
612 : !body.at(0)
613 : ->AsExpressionStatement()
614 682240 : ->expression()
615 : ->IsFunctionLiteral()) {
616 1363 : ReportMessage(MessageTemplate::kSingleFunctionLiteral);
617 : }
618 : }
619 :
620 1723328 : int parameter_count = parsing_module_ ? 1 : 0;
621 : result = factory()->NewScriptOrEvalFunctionLiteral(
622 1723328 : scope, body, function_state.expected_property_count(), parameter_count);
623 1723518 : result->set_suspend_count(function_state.suspend_count());
624 : }
625 :
626 : info->set_max_function_literal_id(GetLastFunctionLiteralId());
627 :
628 : // Make sure the target stack is empty.
629 : DCHECK_NULL(target_stack_);
630 :
631 1723517 : if (has_error()) return nullptr;
632 1355391 : return result;
633 : }
634 :
635 84 : ZonePtrList<const AstRawString>* Parser::PrepareWrappedArguments(
636 : Isolate* isolate, ParseInfo* info, Zone* zone) {
637 : DCHECK(parsing_on_main_thread_);
638 : DCHECK_NOT_NULL(isolate);
639 168 : Handle<FixedArray> arguments(info->script()->wrapped_arguments(), isolate);
640 : int arguments_length = arguments->length();
641 : ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
642 84 : new (zone) ZonePtrList<const AstRawString>(arguments_length, zone);
643 104 : for (int i = 0; i < arguments_length; i++) {
644 : const AstRawString* argument_string = ast_value_factory()->GetString(
645 20 : Handle<String>(String::cast(arguments->get(i)), isolate));
646 20 : arguments_for_wrapped_function->Add(argument_string, zone);
647 : }
648 84 : return arguments_for_wrapped_function;
649 : }
650 :
651 74 : void Parser::ParseWrapped(Isolate* isolate, ParseInfo* info,
652 74 : ScopedPtrList<Statement>* body,
653 : DeclarationScope* outer_scope, Zone* zone) {
654 : DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr);
655 : DCHECK(info->is_wrapped_as_function());
656 : ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
657 :
658 : // Set function and block state for the outer eval scope.
659 : DCHECK(outer_scope->is_eval_scope());
660 74 : FunctionState function_state(&function_state_, &scope_, outer_scope);
661 :
662 : const AstRawString* function_name = nullptr;
663 : Scanner::Location location(0, 0);
664 :
665 : ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
666 74 : PrepareWrappedArguments(isolate, info, zone);
667 :
668 : FunctionLiteral* function_literal = ParseFunctionLiteral(
669 : function_name, location, kSkipFunctionNameCheck, kNormalFunction,
670 : kNoSourcePosition, FunctionLiteral::kWrapped, LanguageMode::kSloppy,
671 74 : arguments_for_wrapped_function);
672 :
673 : Statement* return_statement = factory()->NewReturnStatement(
674 74 : function_literal, kNoSourcePosition, kNoSourcePosition);
675 : body->Add(return_statement);
676 74 : }
677 :
678 1434878 : FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
679 : Handle<SharedFunctionInfo> shared_info) {
680 : // It's OK to use the Isolate & counters here, since this function is only
681 : // called in the main thread.
682 : DCHECK(parsing_on_main_thread_);
683 : RuntimeCallTimerScope runtime_timer(runtime_call_stats_,
684 717422 : RuntimeCallCounterId::kParseFunction);
685 2152275 : TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseFunction");
686 : base::ElapsedTimer timer;
687 717424 : if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
688 :
689 : DeserializeScopeChain(isolate, info, info->maybe_outer_scope_info(),
690 717424 : Scope::DeserializationMode::kIncludingVariables);
691 : DCHECK_EQ(factory()->zone(), info->zone());
692 :
693 : // Initialize parser state.
694 1434864 : Handle<String> name(shared_info->Name(), isolate);
695 717462 : info->set_function_name(ast_value_factory()->GetString(name));
696 717425 : scanner_.Initialize();
697 :
698 29 : FunctionLiteral* result =
699 717427 : DoParseFunction(isolate, info, info->function_name());
700 717423 : MaybeResetCharacterStream(info, result);
701 717446 : MaybeProcessSourceRanges(info, result, stack_limit_);
702 717436 : if (result != nullptr) {
703 1424490 : Handle<String> inferred_name(shared_info->inferred_name(), isolate);
704 712243 : result->set_inferred_name(inferred_name);
705 : }
706 :
707 717427 : if (V8_UNLIKELY(FLAG_log_function_events) && result != nullptr) {
708 29 : double ms = timer.Elapsed().InMillisecondsF();
709 : // We need to make sure that the debug-name is available.
710 29 : ast_value_factory()->Internalize(isolate);
711 : DeclarationScope* function_scope = result->scope();
712 29 : std::unique_ptr<char[]> function_name = result->GetDebugName();
713 87 : LOG(isolate,
714 : FunctionEvent("parse-function", info->script()->id(), ms,
715 : function_scope->start_position(),
716 : function_scope->end_position(), function_name.get(),
717 : strlen(function_name.get())));
718 : }
719 717428 : return result;
720 : }
721 :
722 1100600 : static FunctionLiteral::FunctionType ComputeFunctionType(ParseInfo* info) {
723 717500 : if (info->is_wrapped_as_function()) {
724 : return FunctionLiteral::kWrapped;
725 717489 : } else if (info->is_declaration()) {
726 : return FunctionLiteral::kDeclaration;
727 460666 : } else if (info->is_named_expression()) {
728 : return FunctionLiteral::kNamedExpression;
729 663950 : } else if (IsConciseMethod(info->function_kind()) ||
730 : IsAccessorFunction(info->function_kind())) {
731 : return FunctionLiteral::kAccessorOrMethod;
732 : }
733 274858 : return FunctionLiteral::kAnonymousExpression;
734 : }
735 :
736 2747887 : FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
737 : const AstRawString* raw_name) {
738 : DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr);
739 : DCHECK_NOT_NULL(raw_name);
740 : DCHECK_NULL(scope_);
741 : DCHECK_NULL(target_stack_);
742 :
743 : DCHECK(ast_value_factory());
744 717495 : fni_.PushEnclosingName(raw_name);
745 :
746 390454 : ResetFunctionLiteralId();
747 : DCHECK_LT(0, info->function_literal_id());
748 717503 : SkipFunctionLiterals(info->function_literal_id() - 1);
749 :
750 : ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
751 :
752 : // Place holder for the result.
753 : FunctionLiteral* result = nullptr;
754 :
755 : {
756 : // Parse the function literal.
757 717503 : Scope* outer = original_scope_;
758 717503 : DeclarationScope* outer_function = outer->GetClosureScope();
759 : DCHECK(outer);
760 717506 : FunctionState function_state(&function_state_, &scope_, outer_function);
761 : BlockState block_state(&scope_, outer);
762 : DCHECK(is_sloppy(outer->language_mode()) ||
763 : is_strict(info->language_mode()));
764 717506 : FunctionLiteral::FunctionType function_type = ComputeFunctionType(info);
765 : FunctionKind kind = info->function_kind();
766 :
767 717492 : if (IsArrowFunction(kind)) {
768 195085 : if (IsAsyncFunction(kind)) {
769 : DCHECK(!scanner()->HasLineTerminatorAfterNext());
770 1026 : if (!Check(Token::ASYNC)) {
771 2 : CHECK(stack_overflow());
772 12 : return nullptr;
773 : }
774 2018 : if (!(peek_any_identifier() || peek() == Token::LPAREN)) {
775 0 : CHECK(stack_overflow());
776 : return nullptr;
777 : }
778 : }
779 :
780 : // TODO(adamk): We should construct this scope from the ScopeInfo.
781 195085 : DeclarationScope* scope = NewFunctionScope(kind);
782 :
783 : // This bit only needs to be explicitly set because we're
784 : // not passing the ScopeInfo to the Scope constructor.
785 195086 : SetLanguageMode(scope, info->language_mode());
786 :
787 : scope->set_start_position(info->start_position());
788 : ParserFormalParameters formals(scope);
789 : {
790 : ParameterDeclarationParsingScope formals_scope(this);
791 : // Parsing patterns as variable reference expression creates
792 : // NewUnresolved references in current scope. Enter arrow function
793 : // scope for formal parameter parsing.
794 : BlockState block_state(&scope_, scope);
795 195082 : if (Check(Token::LPAREN)) {
796 : // '(' StrictFormalParameters ')'
797 175931 : ParseFormalParameterList(&formals);
798 175931 : Expect(Token::RPAREN);
799 : } else {
800 : // BindingIdentifier
801 : ParameterParsingScope scope(impl(), &formals);
802 : ParseFormalParameter(&formals);
803 : DeclareFormalParameters(&formals);
804 : }
805 : }
806 :
807 195086 : if (GetLastFunctionLiteralId() != info->function_literal_id() - 1) {
808 289 : if (has_error()) return nullptr;
809 : // If there were FunctionLiterals in the parameters, we need to
810 : // renumber them to shift down so the next function literal id for
811 : // the arrow function is the one requested.
812 : AstFunctionLiteralIdReindexer reindexer(
813 : stack_limit_,
814 558 : (info->function_literal_id() - 1) - GetLastFunctionLiteralId());
815 932 : for (auto p : formals.params) {
816 374 : if (p->pattern != nullptr) reindexer.Reindex(p->pattern);
817 374 : if (p->initializer() != nullptr) {
818 249 : reindexer.Reindex(p->initializer());
819 : }
820 : }
821 : ResetFunctionLiteralId();
822 558 : SkipFunctionLiterals(info->function_literal_id() - 1);
823 : }
824 :
825 195076 : Expression* expression = ParseArrowFunctionLiteral(formals);
826 : // Scanning must end at the same position that was recorded
827 : // previously. If not, parsing has been interrupted due to a stack
828 : // overflow, at which point the partially parsed arrow function
829 : // concise body happens to be a valid expression. This is a problem
830 : // only for arrow functions with single expression bodies, since there
831 : // is no end token such as "}" for normal functions.
832 390158 : if (scanner()->location().end_pos == info->end_position()) {
833 : // The pre-parser saw an arrow function here, so the full parser
834 : // must produce a FunctionLiteral.
835 : DCHECK(expression->IsFunctionLiteral());
836 194989 : result = expression->AsFunctionLiteral();
837 : }
838 522407 : } else if (IsDefaultConstructor(kind)) {
839 : DCHECK_EQ(scope(), outer);
840 : result = DefaultConstructor(raw_name, IsDerivedConstructor(kind),
841 9590 : info->start_position(), info->end_position());
842 : } else {
843 : ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
844 : info->is_wrapped_as_function()
845 : ? PrepareWrappedArguments(isolate, info, zone())
846 512827 : : nullptr;
847 : result = ParseFunctionLiteral(
848 : raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind,
849 : kNoSourcePosition, function_type, info->language_mode(),
850 512817 : arguments_for_wrapped_function);
851 : }
852 :
853 717493 : if (has_error()) return nullptr;
854 : result->set_requires_instance_members_initializer(
855 : info->requires_instance_members_initializer());
856 712316 : if (info->is_iife()) {
857 : result->mark_as_iife();
858 : }
859 : }
860 :
861 : // Make sure the target stack is empty.
862 : DCHECK_NULL(target_stack_);
863 : DCHECK_IMPLIES(result,
864 : info->function_literal_id() == result->function_literal_id());
865 712316 : return result;
866 : }
867 :
868 131717 : Statement* Parser::ParseModuleItem() {
869 : // ecma262/#prod-ModuleItem
870 : // ModuleItem :
871 : // ImportDeclaration
872 : // ExportDeclaration
873 : // StatementListItem
874 :
875 5408 : Token::Value next = peek();
876 :
877 131717 : if (next == Token::EXPORT) {
878 19155 : return ParseExportDeclaration();
879 : }
880 :
881 112562 : if (next == Token::IMPORT) {
882 : // We must be careful not to parse a dynamic import expression as an import
883 : // declaration. Same for import.meta expressions.
884 : Token::Value peek_ahead = PeekAhead();
885 8257 : if ((!allow_harmony_dynamic_import() || peek_ahead != Token::LPAREN) &&
886 1559 : (!allow_harmony_import_meta() || peek_ahead != Token::PERIOD)) {
887 2349 : ParseImportDeclaration();
888 2349 : return factory()->EmptyStatement();
889 : }
890 : }
891 :
892 110213 : return ParseStatementListItem();
893 : }
894 :
895 126860 : void Parser::ParseModuleItemList(ScopedPtrList<Statement>* body) {
896 : // ecma262/#prod-Module
897 : // Module :
898 : // ModuleBody?
899 : //
900 : // ecma262/#prod-ModuleItemList
901 : // ModuleBody :
902 : // ModuleItem*
903 :
904 : DCHECK(scope()->is_module_scope());
905 182431 : while (peek() != Token::EOS) {
906 131717 : Statement* stat = ParseModuleItem();
907 167328 : if (stat == nullptr) return;
908 111209 : if (stat->IsEmptyStatement()) continue;
909 : body->Add(stat);
910 : }
911 : }
912 :
913 2654 : const AstRawString* Parser::ParseModuleSpecifier() {
914 : // ModuleSpecifier :
915 : // StringLiteral
916 :
917 2654 : Expect(Token::STRING);
918 2654 : return GetSymbol();
919 : }
920 :
921 480 : ZoneChunkList<Parser::ExportClauseData>* Parser::ParseExportClause(
922 : Scanner::Location* reserved_loc) {
923 : // ExportClause :
924 : // '{' '}'
925 : // '{' ExportsList '}'
926 : // '{' ExportsList ',' '}'
927 : //
928 : // ExportsList :
929 : // ExportSpecifier
930 : // ExportsList ',' ExportSpecifier
931 : //
932 : // ExportSpecifier :
933 : // IdentifierName
934 : // IdentifierName 'as' IdentifierName
935 : ZoneChunkList<ExportClauseData>* export_data =
936 1805 : new (zone()) ZoneChunkList<ExportClauseData>(zone());
937 :
938 480 : Expect(Token::LBRACE);
939 :
940 : Token::Value name_tok;
941 1045 : while ((name_tok = peek()) != Token::RBRACE) {
942 : // Keep track of the first reserved word encountered in case our
943 : // caller needs to report an error.
944 1030 : if (!reserved_loc->IsValid() &&
945 : !Token::IsValidIdentifier(name_tok, LanguageMode::kStrict, false,
946 515 : parsing_module_)) {
947 65 : *reserved_loc = scanner()->location();
948 : }
949 : const AstRawString* local_name = ParsePropertyName();
950 : const AstRawString* export_name = nullptr;
951 515 : Scanner::Location location = scanner()->location();
952 1030 : if (CheckContextualKeyword(ast_value_factory()->as_string())) {
953 : export_name = ParsePropertyName();
954 : // Set the location to the whole "a as b" string, so that it makes sense
955 : // both for errors due to "a" and for errors due to "b".
956 230 : location.end_pos = scanner()->location().end_pos;
957 : }
958 515 : if (export_name == nullptr) {
959 : export_name = local_name;
960 : }
961 515 : export_data->push_back({export_name, local_name, location});
962 515 : if (peek() == Token::RBRACE) break;
963 125 : if (V8_UNLIKELY(!Check(Token::COMMA))) {
964 40 : ReportUnexpectedToken(Next());
965 40 : break;
966 : }
967 : }
968 :
969 480 : Expect(Token::RBRACE);
970 480 : return export_data;
971 : }
972 :
973 1159 : ZonePtrList<const Parser::NamedImport>* Parser::ParseNamedImports(int pos) {
974 : // NamedImports :
975 : // '{' '}'
976 : // '{' ImportsList '}'
977 : // '{' ImportsList ',' '}'
978 : //
979 : // ImportsList :
980 : // ImportSpecifier
981 : // ImportsList ',' ImportSpecifier
982 : //
983 : // ImportSpecifier :
984 : // BindingIdentifier
985 : // IdentifierName 'as' BindingIdentifier
986 :
987 8413 : Expect(Token::LBRACE);
988 :
989 1159 : auto result = new (zone()) ZonePtrList<const NamedImport>(1, zone());
990 2463 : while (peek() != Token::RBRACE) {
991 : const AstRawString* import_name = ParsePropertyName();
992 : const AstRawString* local_name = import_name;
993 1279 : Scanner::Location location = scanner()->location();
994 : // In the presence of 'as', the left-side of the 'as' can
995 : // be any IdentifierName. But without 'as', it must be a valid
996 : // BindingIdentifier.
997 2558 : if (CheckContextualKeyword(ast_value_factory()->as_string())) {
998 : local_name = ParsePropertyName();
999 : }
1000 1279 : if (!Token::IsValidIdentifier(scanner()->current_token(),
1001 : LanguageMode::kStrict, false,
1002 1279 : parsing_module_)) {
1003 125 : ReportMessage(MessageTemplate::kUnexpectedReserved);
1004 125 : return nullptr;
1005 1154 : } else if (IsEvalOrArguments(local_name)) {
1006 15 : ReportMessage(MessageTemplate::kStrictEvalArguments);
1007 15 : return nullptr;
1008 : }
1009 :
1010 : DeclareVariable(local_name, VariableMode::kConst, kNeedsInitialization,
1011 1139 : position());
1012 :
1013 : NamedImport* import =
1014 : new (zone()) NamedImport(import_name, local_name, location);
1015 1139 : result->Add(import, zone());
1016 :
1017 1139 : if (peek() == Token::RBRACE) break;
1018 145 : Expect(Token::COMMA);
1019 : }
1020 :
1021 1019 : Expect(Token::RBRACE);
1022 1019 : return result;
1023 : }
1024 :
1025 2349 : void Parser::ParseImportDeclaration() {
1026 : // ImportDeclaration :
1027 : // 'import' ImportClause 'from' ModuleSpecifier ';'
1028 : // 'import' ModuleSpecifier ';'
1029 : //
1030 : // ImportClause :
1031 : // ImportedDefaultBinding
1032 : // NameSpaceImport
1033 : // NamedImports
1034 : // ImportedDefaultBinding ',' NameSpaceImport
1035 : // ImportedDefaultBinding ',' NamedImports
1036 : //
1037 : // NameSpaceImport :
1038 : // '*' 'as' ImportedBinding
1039 :
1040 10426 : int pos = peek_position();
1041 2349 : Expect(Token::IMPORT);
1042 :
1043 : Token::Value tok = peek();
1044 :
1045 : // 'import' ModuleSpecifier ';'
1046 2349 : if (tok == Token::STRING) {
1047 85 : Scanner::Location specifier_loc = scanner()->peek_location();
1048 85 : const AstRawString* module_specifier = ParseModuleSpecifier();
1049 85 : ExpectSemicolon();
1050 85 : module()->AddEmptyImport(module_specifier, specifier_loc);
1051 : return;
1052 : }
1053 :
1054 : // Parse ImportedDefaultBinding if present.
1055 : const AstRawString* import_default_binding = nullptr;
1056 : Scanner::Location import_default_binding_loc;
1057 2264 : if (tok != Token::MUL && tok != Token::LBRACE) {
1058 975 : import_default_binding = ParseNonRestrictedIdentifier();
1059 975 : import_default_binding_loc = scanner()->location();
1060 : DeclareVariable(import_default_binding, VariableMode::kConst,
1061 975 : kNeedsInitialization, pos);
1062 : }
1063 :
1064 : // Parse NameSpaceImport or NamedImports if present.
1065 : const AstRawString* module_namespace_binding = nullptr;
1066 : Scanner::Location module_namespace_binding_loc;
1067 3117 : const ZonePtrList<const NamedImport>* named_imports = nullptr;
1068 3239 : if (import_default_binding == nullptr || Check(Token::COMMA)) {
1069 1314 : switch (peek()) {
1070 : case Token::MUL: {
1071 : Consume(Token::MUL);
1072 290 : ExpectContextualKeyword(ast_value_factory()->as_string());
1073 145 : module_namespace_binding = ParseNonRestrictedIdentifier();
1074 145 : module_namespace_binding_loc = scanner()->location();
1075 : DeclareVariable(module_namespace_binding, VariableMode::kConst,
1076 145 : kCreatedInitialized, pos);
1077 145 : break;
1078 : }
1079 :
1080 : case Token::LBRACE:
1081 1159 : named_imports = ParseNamedImports(pos);
1082 1159 : break;
1083 :
1084 : default:
1085 10 : ReportUnexpectedToken(scanner()->current_token());
1086 10 : return;
1087 : }
1088 : }
1089 :
1090 4508 : ExpectContextualKeyword(ast_value_factory()->from_string());
1091 2254 : Scanner::Location specifier_loc = scanner()->peek_location();
1092 2254 : const AstRawString* module_specifier = ParseModuleSpecifier();
1093 2254 : ExpectSemicolon();
1094 :
1095 : // Now that we have all the information, we can make the appropriate
1096 : // declarations.
1097 :
1098 : // TODO(neis): Would prefer to call DeclareVariable for each case below rather
1099 : // than above and in ParseNamedImports, but then a possible error message
1100 : // would point to the wrong location. Maybe have a DeclareAt version of
1101 : // Declare that takes a location?
1102 :
1103 2254 : if (module_namespace_binding != nullptr) {
1104 : module()->AddStarImport(module_namespace_binding, module_specifier,
1105 : module_namespace_binding_loc, specifier_loc,
1106 145 : zone());
1107 : }
1108 :
1109 2254 : if (import_default_binding != nullptr) {
1110 : module()->AddImport(ast_value_factory()->default_string(),
1111 : import_default_binding, module_specifier,
1112 1930 : import_default_binding_loc, specifier_loc, zone());
1113 : }
1114 :
1115 2254 : if (named_imports != nullptr) {
1116 1019 : if (named_imports->length() == 0) {
1117 20 : module()->AddEmptyImport(module_specifier, specifier_loc);
1118 : } else {
1119 3197 : for (int i = 0; i < named_imports->length(); ++i) {
1120 1099 : const NamedImport* import = named_imports->at(i);
1121 : module()->AddImport(import->import_name, import->local_name,
1122 : module_specifier, import->location, specifier_loc,
1123 2198 : zone());
1124 : }
1125 : }
1126 : }
1127 : }
1128 :
1129 421 : Statement* Parser::ParseExportDefault() {
1130 : // Supports the following productions, starting after the 'default' token:
1131 : // 'export' 'default' HoistableDeclaration
1132 : // 'export' 'default' ClassDeclaration
1133 : // 'export' 'default' AssignmentExpression[In] ';'
1134 :
1135 2628 : Expect(Token::DEFAULT);
1136 421 : Scanner::Location default_loc = scanner()->location();
1137 :
1138 421 : ZonePtrList<const AstRawString> local_names(1, zone());
1139 : Statement* result = nullptr;
1140 421 : switch (peek()) {
1141 : case Token::FUNCTION:
1142 60 : result = ParseHoistableDeclaration(&local_names, true);
1143 60 : break;
1144 :
1145 : case Token::CLASS:
1146 : Consume(Token::CLASS);
1147 40 : result = ParseClassDeclaration(&local_names, true);
1148 40 : break;
1149 :
1150 : case Token::ASYNC:
1151 120 : if (PeekAhead() == Token::FUNCTION &&
1152 : !scanner()->HasLineTerminatorAfterNext()) {
1153 : Consume(Token::ASYNC);
1154 60 : result = ParseAsyncFunctionDeclaration(&local_names, true);
1155 60 : break;
1156 : }
1157 : V8_FALLTHROUGH;
1158 :
1159 : default: {
1160 : int pos = position();
1161 : AcceptINScope scope(this, true);
1162 : Expression* value = ParseAssignmentExpression();
1163 522 : SetFunctionName(value, ast_value_factory()->default_string());
1164 :
1165 : const AstRawString* local_name =
1166 522 : ast_value_factory()->star_default_star_string();
1167 261 : local_names.Add(local_name, zone());
1168 :
1169 : // It's fine to declare this as VariableMode::kConst because the user has
1170 : // no way of writing to it.
1171 261 : VariableProxy* proxy =
1172 261 : DeclareVariable(local_name, VariableMode::kConst, pos);
1173 : proxy->var()->set_initializer_position(position());
1174 :
1175 : Assignment* assignment = factory()->NewAssignment(
1176 261 : Token::INIT, proxy, value, kNoSourcePosition);
1177 : result = IgnoreCompletion(
1178 522 : factory()->NewExpressionStatement(assignment, kNoSourcePosition));
1179 :
1180 261 : ExpectSemicolon();
1181 : break;
1182 : }
1183 : }
1184 :
1185 421 : if (result != nullptr) {
1186 : DCHECK_EQ(local_names.length(), 1);
1187 : module()->AddExport(local_names.first(),
1188 : ast_value_factory()->default_string(), default_loc,
1189 1263 : zone());
1190 : }
1191 :
1192 421 : return result;
1193 : }
1194 :
1195 100 : const AstRawString* Parser::NextInternalNamespaceExportName() {
1196 : const char* prefix = ".ns-export";
1197 100 : std::string s(prefix);
1198 300 : s.append(std::to_string(number_of_named_namespace_exports_++));
1199 200 : return ast_value_factory()->GetOneByteString(s.c_str());
1200 : }
1201 :
1202 205 : void Parser::ParseExportStar() {
1203 1430 : int pos = position();
1204 : Consume(Token::MUL);
1205 :
1206 410 : if (!FLAG_harmony_namespace_exports ||
1207 410 : !PeekContextualKeyword(ast_value_factory()->as_string())) {
1208 : // 'export' '*' 'from' ModuleSpecifier ';'
1209 105 : Scanner::Location loc = scanner()->location();
1210 210 : ExpectContextualKeyword(ast_value_factory()->from_string());
1211 105 : Scanner::Location specifier_loc = scanner()->peek_location();
1212 105 : const AstRawString* module_specifier = ParseModuleSpecifier();
1213 105 : ExpectSemicolon();
1214 105 : module()->AddStarExport(module_specifier, loc, specifier_loc, zone());
1215 : return;
1216 : }
1217 100 : if (!FLAG_harmony_namespace_exports) return;
1218 :
1219 : // 'export' '*' 'as' IdentifierName 'from' ModuleSpecifier ';'
1220 : //
1221 : // Desugaring:
1222 : // export * as x from "...";
1223 : // ~>
1224 : // import * as .x from "..."; export {.x as x};
1225 :
1226 200 : ExpectContextualKeyword(ast_value_factory()->as_string());
1227 : const AstRawString* export_name = ParsePropertyName();
1228 100 : Scanner::Location export_name_loc = scanner()->location();
1229 100 : const AstRawString* local_name = NextInternalNamespaceExportName();
1230 100 : Scanner::Location local_name_loc = Scanner::Location::invalid();
1231 100 : DeclareVariable(local_name, VariableMode::kConst, kCreatedInitialized, pos);
1232 :
1233 200 : ExpectContextualKeyword(ast_value_factory()->from_string());
1234 100 : Scanner::Location specifier_loc = scanner()->peek_location();
1235 100 : const AstRawString* module_specifier = ParseModuleSpecifier();
1236 100 : ExpectSemicolon();
1237 :
1238 : module()->AddStarImport(local_name, module_specifier, local_name_loc,
1239 100 : specifier_loc, zone());
1240 100 : module()->AddExport(local_name, export_name, export_name_loc, zone());
1241 : }
1242 :
1243 19155 : Statement* Parser::ParseExportDeclaration() {
1244 : // ExportDeclaration:
1245 : // 'export' '*' 'from' ModuleSpecifier ';'
1246 : // 'export' '*' 'as' IdentifierName 'from' ModuleSpecifier ';'
1247 : // 'export' ExportClause ('from' ModuleSpecifier)? ';'
1248 : // 'export' VariableStatement
1249 : // 'export' Declaration
1250 : // 'export' 'default' ... (handled in ParseExportDefault)
1251 :
1252 75513 : Expect(Token::EXPORT);
1253 : Statement* result = nullptr;
1254 19155 : ZonePtrList<const AstRawString> names(1, zone());
1255 19155 : Scanner::Location loc = scanner()->peek_location();
1256 19155 : switch (peek()) {
1257 : case Token::DEFAULT:
1258 421 : return ParseExportDefault();
1259 :
1260 : case Token::MUL:
1261 205 : ParseExportStar();
1262 205 : return factory()->EmptyStatement();
1263 :
1264 : case Token::LBRACE: {
1265 : // There are two cases here:
1266 : //
1267 : // 'export' ExportClause ';'
1268 : // and
1269 : // 'export' ExportClause FromClause ';'
1270 : //
1271 : // In the first case, the exported identifiers in ExportClause must
1272 : // not be reserved words, while in the latter they may be. We
1273 : // pass in a location that gets filled with the first reserved word
1274 : // encountered, and then throw a SyntaxError if we are in the
1275 : // non-FromClause case.
1276 480 : Scanner::Location reserved_loc = Scanner::Location::invalid();
1277 : ZoneChunkList<ExportClauseData>* export_data =
1278 480 : ParseExportClause(&reserved_loc);
1279 : const AstRawString* module_specifier = nullptr;
1280 : Scanner::Location specifier_loc;
1281 960 : if (CheckContextualKeyword(ast_value_factory()->from_string())) {
1282 110 : specifier_loc = scanner()->peek_location();
1283 110 : module_specifier = ParseModuleSpecifier();
1284 370 : } else if (reserved_loc.IsValid()) {
1285 : // No FromClause, so reserved words are invalid in ExportClause.
1286 30 : ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved);
1287 30 : return nullptr;
1288 : }
1289 450 : ExpectSemicolon();
1290 450 : if (module_specifier == nullptr) {
1291 1055 : for (const ExportClauseData& data : *export_data) {
1292 : module()->AddExport(data.local_name, data.export_name, data.location,
1293 750 : zone());
1294 : }
1295 110 : } else if (export_data->is_empty()) {
1296 30 : module()->AddEmptyImport(module_specifier, specifier_loc);
1297 : } else {
1298 260 : for (const ExportClauseData& data : *export_data) {
1299 : module()->AddExport(data.local_name, data.export_name,
1300 : module_specifier, data.location, specifier_loc,
1301 200 : zone());
1302 : }
1303 : }
1304 450 : return factory()->EmptyStatement();
1305 : }
1306 :
1307 : case Token::FUNCTION:
1308 320 : result = ParseHoistableDeclaration(&names, false);
1309 320 : break;
1310 :
1311 : case Token::CLASS:
1312 : Consume(Token::CLASS);
1313 30 : result = ParseClassDeclaration(&names, false);
1314 30 : break;
1315 :
1316 : case Token::VAR:
1317 : case Token::LET:
1318 : case Token::CONST:
1319 17589 : result = ParseVariableStatement(kStatementListItem, &names);
1320 17589 : break;
1321 :
1322 : case Token::ASYNC:
1323 : Consume(Token::ASYNC);
1324 190 : if (peek() == Token::FUNCTION &&
1325 : !scanner()->HasLineTerminatorBeforeNext()) {
1326 65 : result = ParseAsyncFunctionDeclaration(&names, false);
1327 65 : break;
1328 : }
1329 : V8_FALLTHROUGH;
1330 :
1331 : default:
1332 45 : ReportUnexpectedToken(scanner()->current_token());
1333 45 : return nullptr;
1334 : }
1335 18004 : loc.end_pos = scanner()->location().end_pos;
1336 :
1337 : ModuleDescriptor* descriptor = module();
1338 36008 : for (int i = 0; i < names.length(); ++i) {
1339 36008 : descriptor->AddExport(names[i], names[i], loc, zone());
1340 : }
1341 :
1342 : return result;
1343 : }
1344 :
1345 2590077 : VariableProxy* Parser::NewUnresolved(const AstRawString* name, int begin_pos,
1346 : VariableKind kind) {
1347 5180160 : return scope()->NewUnresolved(factory(), name, begin_pos, kind);
1348 : }
1349 :
1350 24612 : VariableProxy* Parser::NewUnresolved(const AstRawString* name) {
1351 73836 : return scope()->NewUnresolved(factory(), name, scanner()->location().beg_pos);
1352 : }
1353 :
1354 0 : VariableProxy* Parser::DeclareVariable(const AstRawString* name,
1355 : VariableMode mode, int pos) {
1356 : return DeclareVariable(name, mode, Variable::DefaultInitializationFlag(mode),
1357 361054 : pos);
1358 : }
1359 :
1360 363400 : VariableProxy* Parser::DeclareVariable(const AstRawString* name,
1361 : VariableMode mode,
1362 : InitializationFlag init, int pos) {
1363 : DCHECK_NOT_NULL(name);
1364 : VariableProxy* proxy =
1365 1090209 : factory()->NewVariableProxy(name, NORMAL_VARIABLE, position());
1366 : DeclareVariable(proxy, NORMAL_VARIABLE, mode, init, scope(), pos,
1367 363409 : end_position());
1368 363431 : return proxy;
1369 : }
1370 :
1371 9712125 : void Parser::DeclareVariable(VariableProxy* proxy, VariableKind kind,
1372 : VariableMode mode, InitializationFlag init,
1373 : Scope* scope, int begin, int end) {
1374 : Declaration* declaration;
1375 17691925 : if (mode == VariableMode::kVar && !scope->is_declaration_scope()) {
1376 : DCHECK(scope->is_block_scope() || scope->is_with_scope());
1377 410960 : declaration = factory()->NewNestedVariableDeclaration(scope, begin);
1378 : } else {
1379 9301165 : declaration = factory()->NewVariableDeclaration(begin);
1380 : }
1381 9712047 : Declare(declaration, proxy, kind, mode, init, scope, end);
1382 9712069 : }
1383 :
1384 10701632 : void Parser::Declare(Declaration* declaration, VariableProxy* proxy,
1385 : VariableKind variable_kind, VariableMode mode,
1386 : InitializationFlag init, Scope* scope, int var_end_pos) {
1387 10637935 : bool local_ok = true;
1388 10637935 : bool sloppy_mode_block_scope_function_redefinition = false;
1389 : scope->DeclareVariable(declaration, proxy, mode, variable_kind, init,
1390 : &sloppy_mode_block_scope_function_redefinition,
1391 10637935 : &local_ok);
1392 10637984 : if (!local_ok) {
1393 : // If we only have the start position of a proxy, we can't highlight the
1394 : // whole variable name. Pretend its length is 1 so that we highlight at
1395 : // least the first character.
1396 : Scanner::Location loc(proxy->position(), var_end_pos != kNoSourcePosition
1397 : ? var_end_pos
1398 65340 : : proxy->position() + 1);
1399 65340 : if (variable_kind == PARAMETER_VARIABLE) {
1400 1643 : ReportMessageAt(loc, MessageTemplate::kParamDupe);
1401 : } else {
1402 : ReportMessageAt(loc, MessageTemplate::kVarRedeclaration,
1403 63697 : declaration->var()->raw_name());
1404 : }
1405 10572644 : } else if (sloppy_mode_block_scope_function_redefinition) {
1406 235 : ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition];
1407 : }
1408 10637984 : }
1409 :
1410 8927530 : Statement* Parser::BuildInitializationBlock(
1411 : DeclarationParsingResult* parsing_result,
1412 : ZonePtrList<const AstRawString>* names) {
1413 8927530 : ScopedPtrList<Statement> statements(pointer_buffer());
1414 27057532 : for (const auto& declaration : parsing_result->declarations) {
1415 : InitializeVariables(&statements, &(parsing_result->descriptor),
1416 9202544 : &declaration, names);
1417 : }
1418 17854709 : return factory()->NewBlock(true, statements);
1419 : }
1420 :
1421 925973 : Statement* Parser::DeclareFunction(const AstRawString* variable_name,
1422 : FunctionLiteral* function, VariableMode mode,
1423 : int beg_pos, int end_pos,
1424 : bool is_sloppy_block_function,
1425 : ZonePtrList<const AstRawString>* names) {
1426 : VariableProxy* proxy =
1427 1861592 : factory()->NewVariableProxy(variable_name, NORMAL_VARIABLE, beg_pos);
1428 : Declaration* declaration = factory()->NewFunctionDeclaration(
1429 925984 : function, is_sloppy_block_function, beg_pos);
1430 : Declare(declaration, proxy, NORMAL_VARIABLE, mode, kCreatedInitialized,
1431 926014 : scope());
1432 926544 : if (names) names->Add(variable_name, zone());
1433 925959 : if (is_sloppy_block_function) {
1434 : SloppyBlockFunctionStatement* statement =
1435 : factory()->NewSloppyBlockFunctionStatement(end_pos);
1436 : GetDeclarationScope()->DeclareSloppyBlockFunction(variable_name, scope(),
1437 18200 : statement);
1438 9100 : return statement;
1439 : }
1440 916859 : return factory()->EmptyStatement();
1441 : }
1442 :
1443 104691 : Statement* Parser::DeclareClass(const AstRawString* variable_name,
1444 : Expression* value,
1445 : ZonePtrList<const AstRawString>* names,
1446 : int class_token_pos, int end_pos) {
1447 104699 : VariableProxy* proxy =
1448 104691 : DeclareVariable(variable_name, VariableMode::kLet, class_token_pos);
1449 : proxy->var()->set_initializer_position(end_pos);
1450 104699 : if (names) names->Add(variable_name, zone());
1451 :
1452 : Assignment* assignment =
1453 104699 : factory()->NewAssignment(Token::INIT, proxy, value, class_token_pos);
1454 : return IgnoreCompletion(
1455 209391 : factory()->NewExpressionStatement(assignment, kNoSourcePosition));
1456 : }
1457 :
1458 1761 : Statement* Parser::DeclareNative(const AstRawString* name, int pos) {
1459 : // Make sure that the function containing the native declaration
1460 : // isn't lazily compiled. The extension structures are only
1461 : // accessible while parsing the first time not when reparsing
1462 : // because of lazy compilation.
1463 1761 : GetClosureScope()->ForceEagerCompilation();
1464 :
1465 : // TODO(1240846): It's weird that native function declarations are
1466 : // introduced dynamically when we meet their declarations, whereas
1467 : // other functions are set up when entering the surrounding scope.
1468 : VariableProxy* proxy = DeclareVariable(name, VariableMode::kVar, pos);
1469 : NativeFunctionLiteral* lit =
1470 1761 : factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition);
1471 : return factory()->NewExpressionStatement(
1472 1761 : factory()->NewAssignment(Token::INIT, proxy, lit, kNoSourcePosition),
1473 3522 : pos);
1474 : }
1475 :
1476 15783 : void Parser::DeclareLabel(ZonePtrList<const AstRawString>** labels,
1477 : ZonePtrList<const AstRawString>** own_labels,
1478 : VariableProxy* var) {
1479 : DCHECK(IsIdentifier(var));
1480 15783 : const AstRawString* label = var->raw_name();
1481 :
1482 : // TODO(1240780): We don't check for redeclaration of labels
1483 : // during preparsing since keeping track of the set of active
1484 : // labels requires nontrivial changes to the way scopes are
1485 : // structured. However, these are probably changes we want to
1486 : // make later anyway so we should go back and fix this then.
1487 31566 : if (ContainsLabel(*labels, label) || TargetStackContainsLabel(label)) {
1488 77641 : ReportMessage(MessageTemplate::kLabelRedeclaration, label);
1489 15783 : return;
1490 : }
1491 :
1492 : // Add {label} to both {labels} and {own_labels}.
1493 15783 : if (*labels == nullptr) {
1494 : DCHECK_NULL(*own_labels);
1495 15140 : *labels = new (zone()) ZonePtrList<const AstRawString>(1, zone());
1496 15139 : *own_labels = new (zone()) ZonePtrList<const AstRawString>(1, zone());
1497 : } else {
1498 644 : if (*own_labels == nullptr) {
1499 12 : *own_labels = new (zone()) ZonePtrList<const AstRawString>(1, zone());
1500 : }
1501 : }
1502 15784 : (*labels)->Add(label, zone());
1503 15784 : (*own_labels)->Add(label, zone());
1504 :
1505 : // Remove the "ghost" variable that turned out to be a label
1506 : // from the top scope. This way, we don't try to resolve it
1507 : // during the scope processing.
1508 15783 : scope()->DeleteUnresolved(var);
1509 : }
1510 :
1511 10057 : bool Parser::ContainsLabel(ZonePtrList<const AstRawString>* labels,
1512 : const AstRawString* label) {
1513 : DCHECK_NOT_NULL(label);
1514 51470 : if (labels != nullptr) {
1515 11589 : for (int i = labels->length(); i-- > 0;) {
1516 10437 : if (labels->at(i) == label) return true;
1517 : }
1518 : }
1519 : return false;
1520 : }
1521 :
1522 191475 : Block* Parser::IgnoreCompletion(Statement* statement) {
1523 191475 : Block* block = factory()->NewBlock(1, true);
1524 191476 : block->statements()->Add(statement, zone());
1525 191475 : return block;
1526 : }
1527 :
1528 966308 : Expression* Parser::RewriteReturn(Expression* return_value, int pos) {
1529 1932635 : if (IsDerivedConstructor(function_state_->kind())) {
1530 : // For subclass constructors we need to return this in case of undefined;
1531 : // other primitive values trigger an exception in the ConstructStub.
1532 : //
1533 : // return expr;
1534 : //
1535 : // Is rewritten as:
1536 : //
1537 : // return (temp = expr) === undefined ? this : temp;
1538 :
1539 : // temp = expr
1540 332 : Variable* temp = NewTemporary(ast_value_factory()->empty_string());
1541 : Assignment* assign = factory()->NewAssignment(
1542 664 : Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos);
1543 :
1544 : // temp === undefined
1545 : Expression* is_undefined = factory()->NewCompareOperation(
1546 : Token::EQ_STRICT, assign,
1547 664 : factory()->NewUndefinedLiteral(kNoSourcePosition), pos);
1548 :
1549 : // is_undefined ? this : temp
1550 : return_value =
1551 : factory()->NewConditional(is_undefined, ThisExpression(pos),
1552 664 : factory()->NewVariableProxy(temp), pos);
1553 : }
1554 966327 : return return_value;
1555 : }
1556 :
1557 1848 : Statement* Parser::RewriteSwitchStatement(SwitchStatement* switch_statement,
1558 : Scope* scope) {
1559 : // In order to get the CaseClauses to execute in their own lexical scope,
1560 : // but without requiring downstream code to have special scope handling
1561 : // code for switch statements, desugar into blocks as follows:
1562 : // { // To group the statements--harmless to evaluate Expression in scope
1563 : // .tag_variable = Expression;
1564 : // { // To give CaseClauses a scope
1565 : // switch (.tag_variable) { CaseClause* }
1566 : // }
1567 : // }
1568 : DCHECK_NOT_NULL(scope);
1569 : DCHECK(scope->is_block_scope());
1570 : DCHECK_GE(switch_statement->position(), scope->start_position());
1571 : DCHECK_LT(switch_statement->position(), scope->end_position());
1572 :
1573 4620 : Block* switch_block = factory()->NewBlock(2, false);
1574 :
1575 : Expression* tag = switch_statement->tag();
1576 : Variable* tag_variable =
1577 924 : NewTemporary(ast_value_factory()->dot_switch_tag_string());
1578 : Assignment* tag_assign = factory()->NewAssignment(
1579 924 : Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag,
1580 1848 : tag->position());
1581 : // Wrap with IgnoreCompletion so the tag isn't returned as the completion
1582 : // value, in case the switch statements don't have a value.
1583 : Statement* tag_statement = IgnoreCompletion(
1584 1848 : factory()->NewExpressionStatement(tag_assign, kNoSourcePosition));
1585 924 : switch_block->statements()->Add(tag_statement, zone());
1586 :
1587 924 : switch_statement->set_tag(factory()->NewVariableProxy(tag_variable));
1588 924 : Block* cases_block = factory()->NewBlock(1, false);
1589 924 : cases_block->statements()->Add(switch_statement, zone());
1590 : cases_block->set_scope(scope);
1591 924 : switch_block->statements()->Add(cases_block, zone());
1592 924 : return switch_block;
1593 : }
1594 :
1595 3087 : Block* Parser::RewriteCatchPattern(CatchInfo* catch_info) {
1596 : DCHECK_NOT_NULL(catch_info->pattern);
1597 : DeclarationDescriptor descriptor;
1598 3087 : descriptor.kind = NORMAL_VARIABLE;
1599 3087 : descriptor.mode = VariableMode::kLet;
1600 3087 : descriptor.declaration_pos = catch_info->pattern->position();
1601 3087 : descriptor.initialization_pos = catch_info->pattern->position();
1602 :
1603 : // Initializer position for variables declared by the pattern.
1604 3087 : const int initializer_position = position();
1605 :
1606 : DeclarationParsingResult::Declaration decl(
1607 : catch_info->pattern, initializer_position,
1608 6174 : factory()->NewVariableProxy(catch_info->variable));
1609 :
1610 3087 : ScopedPtrList<Statement> init_statements(pointer_buffer());
1611 3087 : InitializeVariables(&init_statements, &descriptor, &decl, nullptr);
1612 6174 : return factory()->NewBlock(true, init_statements);
1613 : }
1614 :
1615 432 : void Parser::ReportVarRedeclarationIn(const AstRawString* name, Scope* scope) {
1616 1044 : for (Declaration* decl : *scope->declarations()) {
1617 612 : if (decl->var()->raw_name() == name) {
1618 432 : int position = decl->position();
1619 : Scanner::Location location =
1620 : position == kNoSourcePosition
1621 : ? Scanner::Location::invalid()
1622 864 : : Scanner::Location(position, position + name->length());
1623 432 : ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
1624 432 : return;
1625 : }
1626 : }
1627 0 : UNREACHABLE();
1628 : }
1629 :
1630 93072 : Statement* Parser::RewriteTryStatement(Block* try_block, Block* catch_block,
1631 : const SourceRange& catch_range,
1632 : Block* finally_block,
1633 : const SourceRange& finally_range,
1634 : const CatchInfo& catch_info, int pos) {
1635 : // Simplify the AST nodes by converting:
1636 : // 'try B0 catch B1 finally B2'
1637 : // to:
1638 : // 'try { try B0 catch B1 } finally B2'
1639 :
1640 93072 : if (catch_block != nullptr && finally_block != nullptr) {
1641 : // If we have both, create an inner try/catch.
1642 : TryCatchStatement* statement;
1643 : statement = factory()->NewTryCatchStatement(try_block, catch_info.scope,
1644 2038 : catch_block, kNoSourcePosition);
1645 : RecordTryCatchStatementSourceRange(statement, catch_range);
1646 :
1647 1019 : try_block = factory()->NewBlock(1, false);
1648 1019 : try_block->statements()->Add(statement, zone());
1649 : catch_block = nullptr; // Clear to indicate it's been handled.
1650 : }
1651 :
1652 93072 : if (catch_block != nullptr) {
1653 : DCHECK_NULL(finally_block);
1654 : TryCatchStatement* stmt = factory()->NewTryCatchStatement(
1655 87882 : try_block, catch_info.scope, catch_block, pos);
1656 : RecordTryCatchStatementSourceRange(stmt, catch_range);
1657 87884 : return stmt;
1658 : } else {
1659 : DCHECK_NOT_NULL(finally_block);
1660 : TryFinallyStatement* stmt =
1661 5190 : factory()->NewTryFinallyStatement(try_block, finally_block, pos);
1662 : RecordTryFinallyStatementSourceRange(stmt, finally_range);
1663 5190 : return stmt;
1664 : }
1665 : }
1666 :
1667 24691 : void Parser::ParseAndRewriteGeneratorFunctionBody(
1668 24692 : int pos, FunctionKind kind, ScopedPtrList<Statement>* body) {
1669 : // For ES6 Generators, we just prepend the initial yield.
1670 24691 : Expression* initial_yield = BuildInitialYield(pos, kind);
1671 : body->Add(
1672 24692 : factory()->NewExpressionStatement(initial_yield, kNoSourcePosition));
1673 24691 : ParseStatementList(body, Token::RBRACE);
1674 24692 : }
1675 :
1676 24123 : void Parser::ParseAndRewriteAsyncGeneratorFunctionBody(
1677 24123 : int pos, FunctionKind kind, ScopedPtrList<Statement>* body) {
1678 : // For ES2017 Async Generators, we produce:
1679 : //
1680 : // try {
1681 : // InitialYield;
1682 : // ...body...;
1683 : // return undefined; // See comment below
1684 : // } catch (.catch) {
1685 : // %AsyncGeneratorReject(generator, .catch);
1686 : // } finally {
1687 : // %_GeneratorClose(generator);
1688 : // }
1689 : //
1690 : // - InitialYield yields the actual generator object.
1691 : // - Any return statement inside the body will have its argument wrapped
1692 : // in an iterator result object with a "done" property set to `true`.
1693 : // - If the generator terminates for whatever reason, we must close it.
1694 : // Hence the finally clause.
1695 : // - BytecodeGenerator performs special handling for ReturnStatements in
1696 : // async generator functions, resolving the appropriate Promise with an
1697 : // "done" iterator result object containing a Promise-unwrapped value.
1698 : DCHECK(IsAsyncGeneratorFunction(kind));
1699 :
1700 : Block* try_block;
1701 : {
1702 24123 : ScopedPtrList<Statement> statements(pointer_buffer());
1703 24123 : Expression* initial_yield = BuildInitialYield(pos, kind);
1704 : statements.Add(
1705 48246 : factory()->NewExpressionStatement(initial_yield, kNoSourcePosition));
1706 24123 : ParseStatementList(&statements, Token::RBRACE);
1707 :
1708 : // Don't create iterator result for async generators, as the resume methods
1709 : // will create it.
1710 : // TODO(leszeks): This will create another suspend point, which is
1711 : // unnecessary if there is already an unconditional return in the body.
1712 : Statement* final_return = BuildReturnStatement(
1713 48246 : factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
1714 24123 : statements.Add(final_return);
1715 :
1716 24123 : try_block = factory()->NewBlock(false, statements);
1717 : }
1718 :
1719 : // For AsyncGenerators, a top-level catch block will reject the Promise.
1720 24123 : Scope* catch_scope = NewHiddenCatchScope();
1721 :
1722 : Block* catch_block;
1723 : {
1724 : ScopedPtrList<Expression> reject_args(pointer_buffer());
1725 : reject_args.Add(factory()->NewVariableProxy(
1726 96492 : function_state_->scope()->generator_object_var()));
1727 48246 : reject_args.Add(factory()->NewVariableProxy(catch_scope->catch_variable()));
1728 :
1729 : Expression* reject_call = factory()->NewCallRuntime(
1730 24123 : Runtime::kInlineAsyncGeneratorReject, reject_args, kNoSourcePosition);
1731 : catch_block = IgnoreCompletion(
1732 48246 : factory()->NewReturnStatement(reject_call, kNoSourcePosition));
1733 : }
1734 :
1735 : {
1736 : ScopedPtrList<Statement> statements(pointer_buffer());
1737 : TryStatement* try_catch = factory()->NewTryCatchStatementForAsyncAwait(
1738 24123 : try_block, catch_scope, catch_block, kNoSourcePosition);
1739 24123 : statements.Add(try_catch);
1740 24123 : try_block = factory()->NewBlock(false, statements);
1741 : }
1742 :
1743 : Expression* close_call;
1744 : {
1745 : ScopedPtrList<Expression> close_args(pointer_buffer());
1746 : VariableProxy* call_proxy = factory()->NewVariableProxy(
1747 48246 : function_state_->scope()->generator_object_var());
1748 24123 : close_args.Add(call_proxy);
1749 : close_call = factory()->NewCallRuntime(Runtime::kInlineGeneratorClose,
1750 24123 : close_args, kNoSourcePosition);
1751 : }
1752 :
1753 : Block* finally_block;
1754 : {
1755 : ScopedPtrList<Statement> statements(pointer_buffer());
1756 : statements.Add(
1757 48246 : factory()->NewExpressionStatement(close_call, kNoSourcePosition));
1758 24123 : finally_block = factory()->NewBlock(false, statements);
1759 : }
1760 :
1761 : body->Add(factory()->NewTryFinallyStatement(try_block, finally_block,
1762 24123 : kNoSourcePosition));
1763 24123 : }
1764 :
1765 1800573 : void Parser::DeclareFunctionNameVar(const AstRawString* function_name,
1766 : FunctionLiteral::FunctionType function_type,
1767 : DeclarationScope* function_scope) {
1768 1926857 : if (function_type == FunctionLiteral::kNamedExpression &&
1769 : function_scope->LookupLocal(function_name) == nullptr) {
1770 : DCHECK_EQ(function_scope, scope());
1771 122604 : function_scope->DeclareFunctionVar(function_name);
1772 : }
1773 1800579 : }
1774 :
1775 : // Special case for legacy for
1776 : //
1777 : // for (var x = initializer in enumerable) body
1778 : //
1779 : // An initialization block of the form
1780 : //
1781 : // {
1782 : // x = initializer;
1783 : // }
1784 : //
1785 : // is returned in this case. It has reserved space for two statements,
1786 : // so that (later on during parsing), the equivalent of
1787 : //
1788 : // for (x in enumerable) body
1789 : //
1790 : // is added as a second statement to it.
1791 93628 : Block* Parser::RewriteForVarInLegacy(const ForInfo& for_info) {
1792 : const DeclarationParsingResult::Declaration& decl =
1793 93628 : for_info.parsing_result.declarations[0];
1794 203997 : if (!IsLexicalVariableMode(for_info.parsing_result.descriptor.mode) &&
1795 108404 : decl.pattern->IsVariableProxy() && decl.initializer != nullptr) {
1796 212 : ++use_counts_[v8::Isolate::kForInInitializer];
1797 212 : const AstRawString* name = decl.pattern->AsVariableProxy()->raw_name();
1798 212 : VariableProxy* single_var = NewUnresolved(name);
1799 212 : Block* init_block = factory()->NewBlock(2, true);
1800 : init_block->statements()->Add(
1801 : factory()->NewExpressionStatement(
1802 : factory()->NewAssignment(Token::ASSIGN, single_var,
1803 212 : decl.initializer, kNoSourcePosition),
1804 212 : kNoSourcePosition),
1805 212 : zone());
1806 212 : return init_block;
1807 : }
1808 : return nullptr;
1809 : }
1810 :
1811 : // Rewrite a for-in/of statement of the form
1812 : //
1813 : // for (let/const/var x in/of e) b
1814 : //
1815 : // into
1816 : //
1817 : // {
1818 : // var temp;
1819 : // for (temp in/of e) {
1820 : // let/const/var x = temp;
1821 : // b;
1822 : // }
1823 : // let x; // for TDZ
1824 : // }
1825 108364 : void Parser::DesugarBindingInForEachStatement(ForInfo* for_info,
1826 : Block** body_block,
1827 : Expression** each_variable) {
1828 : DCHECK_EQ(1, for_info->parsing_result.declarations.size());
1829 : DeclarationParsingResult::Declaration& decl =
1830 108364 : for_info->parsing_result.declarations[0];
1831 227627 : Variable* temp = NewTemporary(ast_value_factory()->dot_for_string());
1832 108370 : ScopedPtrList<Statement> each_initialization_statements(pointer_buffer());
1833 : {
1834 108370 : auto descriptor = for_info->parsing_result.descriptor;
1835 108370 : descriptor.declaration_pos = kNoSourcePosition;
1836 108370 : descriptor.initialization_pos = kNoSourcePosition;
1837 216730 : decl.initializer = factory()->NewVariableProxy(temp);
1838 :
1839 : bool is_for_var_of =
1840 199990 : for_info->mode == ForEachStatement::ITERATE &&
1841 91630 : for_info->parsing_result.descriptor.mode == VariableMode::kVar;
1842 : bool collect_names =
1843 108360 : IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) ||
1844 : is_for_var_of;
1845 :
1846 : InitializeVariables(&each_initialization_statements, &descriptor, &decl,
1847 108360 : collect_names ? &for_info->bound_names : nullptr);
1848 :
1849 : // Annex B.3.5 prohibits the form
1850 : // `try {} catch(e) { for (var e of {}); }`
1851 : // So if we are parsing a statement like `for (var ... of ...)`
1852 : // we need to walk up the scope chain and look for catch scopes
1853 : // which have a simple binding, then compare their binding against
1854 : // all of the names declared in the init of the for-of we're
1855 : // parsing.
1856 108369 : if (is_for_var_of) {
1857 15440 : Scope* catch_scope = scope();
1858 46795 : while (catch_scope != nullptr && !catch_scope->is_declaration_scope()) {
1859 7720 : if (catch_scope->is_catch_scope()) {
1860 450 : auto name = catch_scope->catch_variable()->raw_name();
1861 : // If it's a simple binding and the name is declared in the for loop.
1862 1134 : if (name != ast_value_factory()->dot_catch_string() &&
1863 234 : for_info->bound_names.Contains(name)) {
1864 : ReportMessageAt(for_info->parsing_result.bindings_loc,
1865 126 : MessageTemplate::kVarRedeclaration, name);
1866 : }
1867 : }
1868 : catch_scope = catch_scope->outer_scope();
1869 : }
1870 : }
1871 : }
1872 :
1873 108369 : *body_block = factory()->NewBlock(3, false);
1874 : (*body_block)
1875 : ->statements()
1876 108361 : ->Add(factory()->NewBlock(true, each_initialization_statements), zone());
1877 216735 : *each_variable = factory()->NewVariableProxy(temp, for_info->position);
1878 108372 : }
1879 :
1880 : // Create a TDZ for any lexically-bound names in for in/of statements.
1881 108363 : Block* Parser::CreateForEachStatementTDZ(Block* init_block,
1882 : const ForInfo& for_info) {
1883 108363 : if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) {
1884 : DCHECK_NULL(init_block);
1885 :
1886 184100 : init_block = factory()->NewBlock(1, false);
1887 :
1888 368206 : for (int i = 0; i < for_info.bound_names.length(); ++i) {
1889 : // TODO(adamk): This needs to be some sort of special
1890 : // INTERNAL variable that's invisible to the debugger
1891 : // but visible to everything else.
1892 95474 : VariableProxy* tdz_proxy = DeclareVariable(
1893 375033 : for_info.bound_names[i], VariableMode::kLet, kNoSourcePosition);
1894 : tdz_proxy->var()->set_initializer_position(position());
1895 : }
1896 : }
1897 108375 : return init_block;
1898 : }
1899 :
1900 17516 : Statement* Parser::DesugarLexicalBindingsInForStatement(
1901 : ForStatement* loop, Statement* init, Expression* cond, Statement* next,
1902 : Statement* body, Scope* inner_scope, const ForInfo& for_info) {
1903 : // ES6 13.7.4.8 specifies that on each loop iteration the let variables are
1904 : // copied into a new environment. Moreover, the "next" statement must be
1905 : // evaluated not in the environment of the just completed iteration but in
1906 : // that of the upcoming one. We achieve this with the following desugaring.
1907 : // Extra care is needed to preserve the completion value of the original loop.
1908 : //
1909 : // We are given a for statement of the form
1910 : //
1911 : // labels: for (let/const x = i; cond; next) body
1912 : //
1913 : // and rewrite it as follows. Here we write {{ ... }} for init-blocks, ie.,
1914 : // blocks whose ignore_completion_value_ flag is set.
1915 : //
1916 : // {
1917 : // let/const x = i;
1918 : // temp_x = x;
1919 : // first = 1;
1920 : // undefined;
1921 : // outer: for (;;) {
1922 : // let/const x = temp_x;
1923 : // {{ if (first == 1) {
1924 : // first = 0;
1925 : // } else {
1926 : // next;
1927 : // }
1928 : // flag = 1;
1929 : // if (!cond) break;
1930 : // }}
1931 : // labels: for (; flag == 1; flag = 0, temp_x = x) {
1932 : // body
1933 : // }
1934 : // {{ if (flag == 1) // Body used break.
1935 : // break;
1936 : // }}
1937 : // }
1938 : // }
1939 :
1940 : DCHECK_GT(for_info.bound_names.length(), 0);
1941 509003 : ZonePtrList<Variable> temps(for_info.bound_names.length(), zone());
1942 :
1943 : Block* outer_block =
1944 17516 : factory()->NewBlock(for_info.bound_names.length() + 4, false);
1945 :
1946 : // Add statement: let/const x = i.
1947 17516 : outer_block->statements()->Add(init, zone());
1948 :
1949 17516 : const AstRawString* temp_name = ast_value_factory()->dot_for_string();
1950 :
1951 : // For each lexical variable x:
1952 : // make statement: temp_x = x.
1953 82114 : for (int i = 0; i < for_info.bound_names.length(); i++) {
1954 23541 : VariableProxy* proxy = NewUnresolved(for_info.bound_names[i]);
1955 23541 : Variable* temp = NewTemporary(temp_name);
1956 23541 : VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
1957 : Assignment* assignment = factory()->NewAssignment(Token::ASSIGN, temp_proxy,
1958 23541 : proxy, kNoSourcePosition);
1959 : Statement* assignment_statement =
1960 47082 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
1961 23541 : outer_block->statements()->Add(assignment_statement, zone());
1962 23541 : temps.Add(temp, zone());
1963 : }
1964 :
1965 : Variable* first = nullptr;
1966 : // Make statement: first = 1.
1967 17516 : if (next) {
1968 : first = NewTemporary(temp_name);
1969 2564 : VariableProxy* first_proxy = factory()->NewVariableProxy(first);
1970 2564 : Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
1971 : Assignment* assignment = factory()->NewAssignment(
1972 2564 : Token::ASSIGN, first_proxy, const1, kNoSourcePosition);
1973 : Statement* assignment_statement =
1974 5128 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
1975 2564 : outer_block->statements()->Add(assignment_statement, zone());
1976 : }
1977 :
1978 : // make statement: undefined;
1979 : outer_block->statements()->Add(
1980 : factory()->NewExpressionStatement(
1981 35032 : factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
1982 17516 : zone());
1983 :
1984 : // Make statement: outer: for (;;)
1985 : // Note that we don't actually create the label, or set this loop up as an
1986 : // explicit break target, instead handing it directly to those nodes that
1987 : // need to know about it. This should be safe because we don't run any code
1988 : // in this function that looks up break targets.
1989 : ForStatement* outer_loop =
1990 17516 : factory()->NewForStatement(nullptr, nullptr, kNoSourcePosition);
1991 17516 : outer_block->statements()->Add(outer_loop, zone());
1992 : outer_block->set_scope(scope());
1993 :
1994 17516 : Block* inner_block = factory()->NewBlock(3, false);
1995 : {
1996 17516 : BlockState block_state(&scope_, inner_scope);
1997 :
1998 : Block* ignore_completion_block =
1999 17516 : factory()->NewBlock(for_info.bound_names.length() + 3, true);
2000 17516 : ZonePtrList<Variable> inner_vars(for_info.bound_names.length(), zone());
2001 : // For each let variable x:
2002 : // make statement: let/const x = temp_x.
2003 82114 : for (int i = 0; i < for_info.bound_names.length(); i++) {
2004 47082 : VariableProxy* proxy = DeclareVariable(
2005 : for_info.bound_names[i], for_info.parsing_result.descriptor.mode,
2006 47082 : kNoSourcePosition);
2007 23541 : inner_vars.Add(proxy->var(), zone());
2008 23541 : VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
2009 : Assignment* assignment = factory()->NewAssignment(
2010 23541 : Token::INIT, proxy, temp_proxy, kNoSourcePosition);
2011 : Statement* assignment_statement =
2012 47082 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2013 23541 : int declaration_pos = for_info.parsing_result.descriptor.declaration_pos;
2014 : DCHECK_NE(declaration_pos, kNoSourcePosition);
2015 : proxy->var()->set_initializer_position(declaration_pos);
2016 23541 : ignore_completion_block->statements()->Add(assignment_statement, zone());
2017 : }
2018 :
2019 : // Make statement: if (first == 1) { first = 0; } else { next; }
2020 17516 : if (next) {
2021 : DCHECK(first);
2022 : Expression* compare = nullptr;
2023 : // Make compare expression: first == 1.
2024 : {
2025 2564 : Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2026 2564 : VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2027 : compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1,
2028 2564 : kNoSourcePosition);
2029 : }
2030 : Statement* clear_first = nullptr;
2031 : // Make statement: first = 0.
2032 : {
2033 2564 : VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2034 2564 : Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
2035 : Assignment* assignment = factory()->NewAssignment(
2036 2564 : Token::ASSIGN, first_proxy, const0, kNoSourcePosition);
2037 : clear_first =
2038 2564 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2039 : }
2040 : Statement* clear_first_or_next = factory()->NewIfStatement(
2041 5128 : compare, clear_first, next, kNoSourcePosition);
2042 2564 : ignore_completion_block->statements()->Add(clear_first_or_next, zone());
2043 : }
2044 :
2045 : Variable* flag = NewTemporary(temp_name);
2046 : // Make statement: flag = 1.
2047 : {
2048 17516 : VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2049 17516 : Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2050 : Assignment* assignment = factory()->NewAssignment(
2051 17516 : Token::ASSIGN, flag_proxy, const1, kNoSourcePosition);
2052 : Statement* assignment_statement =
2053 35032 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2054 17516 : ignore_completion_block->statements()->Add(assignment_statement, zone());
2055 : }
2056 :
2057 : // Make statement: if (!cond) break.
2058 17516 : if (cond) {
2059 : Statement* stop =
2060 11750 : factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
2061 11750 : Statement* noop = factory()->EmptyStatement();
2062 : ignore_completion_block->statements()->Add(
2063 11750 : factory()->NewIfStatement(cond, noop, stop, cond->position()),
2064 11750 : zone());
2065 : }
2066 :
2067 17516 : inner_block->statements()->Add(ignore_completion_block, zone());
2068 : // Make cond expression for main loop: flag == 1.
2069 : Expression* flag_cond = nullptr;
2070 : {
2071 17516 : Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2072 17516 : VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2073 : flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
2074 17516 : kNoSourcePosition);
2075 : }
2076 :
2077 : // Create chain of expressions "flag = 0, temp_x = x, ..."
2078 : Statement* compound_next_statement = nullptr;
2079 : {
2080 : Expression* compound_next = nullptr;
2081 : // Make expression: flag = 0.
2082 : {
2083 17516 : VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2084 17516 : Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
2085 : compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy,
2086 17516 : const0, kNoSourcePosition);
2087 : }
2088 :
2089 : // Make the comma-separated list of temp_x = x assignments.
2090 17516 : int inner_var_proxy_pos = scanner()->location().beg_pos;
2091 82114 : for (int i = 0; i < for_info.bound_names.length(); i++) {
2092 23541 : VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
2093 : VariableProxy* proxy =
2094 23541 : factory()->NewVariableProxy(inner_vars.at(i), inner_var_proxy_pos);
2095 : Assignment* assignment = factory()->NewAssignment(
2096 23541 : Token::ASSIGN, temp_proxy, proxy, kNoSourcePosition);
2097 : compound_next = factory()->NewBinaryOperation(
2098 23541 : Token::COMMA, compound_next, assignment, kNoSourcePosition);
2099 : }
2100 :
2101 : compound_next_statement =
2102 17516 : factory()->NewExpressionStatement(compound_next, kNoSourcePosition);
2103 : }
2104 :
2105 : // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
2106 : // Note that we re-use the original loop node, which retains its labels
2107 : // and ensures that any break or continue statements in body point to
2108 : // the right place.
2109 : loop->Initialize(nullptr, flag_cond, compound_next_statement, body);
2110 17516 : inner_block->statements()->Add(loop, zone());
2111 :
2112 : // Make statement: {{if (flag == 1) break;}}
2113 : {
2114 : Expression* compare = nullptr;
2115 : // Make compare expresion: flag == 1.
2116 : {
2117 17516 : Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2118 17516 : VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2119 : compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
2120 17516 : kNoSourcePosition);
2121 : }
2122 : Statement* stop =
2123 17516 : factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
2124 17516 : Statement* empty = factory()->EmptyStatement();
2125 : Statement* if_flag_break =
2126 17516 : factory()->NewIfStatement(compare, stop, empty, kNoSourcePosition);
2127 17516 : inner_block->statements()->Add(IgnoreCompletion(if_flag_break), zone());
2128 : }
2129 :
2130 : inner_block->set_scope(inner_scope);
2131 : }
2132 :
2133 : outer_loop->Initialize(nullptr, nullptr, nullptr, inner_block);
2134 :
2135 17516 : return outer_block;
2136 : }
2137 :
2138 927530 : void ParserFormalParameters::ValidateDuplicate(Parser* parser) const {
2139 927530 : if (has_duplicate()) {
2140 1260 : parser->ReportMessageAt(duplicate_loc, MessageTemplate::kParamDupe);
2141 : }
2142 927530 : }
2143 768393 : void ParserFormalParameters::ValidateStrictMode(Parser* parser) const {
2144 768393 : if (strict_error_loc.IsValid()) {
2145 1904 : parser->ReportMessageAt(strict_error_loc, strict_error_message);
2146 : }
2147 768393 : }
2148 :
2149 123267 : void Parser::AddArrowFunctionFormalParameters(
2150 : ParserFormalParameters* parameters, Expression* expr, int end_pos) {
2151 : // ArrowFunctionFormals ::
2152 : // Nary(Token::COMMA, VariableProxy*, Tail)
2153 : // Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail)
2154 : // Tail
2155 : // NonTailArrowFunctionFormals ::
2156 : // Binary(Token::COMMA, NonTailArrowFunctionFormals, VariableProxy)
2157 : // VariableProxy
2158 : // Tail ::
2159 : // VariableProxy
2160 : // Spread(VariableProxy)
2161 : //
2162 : // We need to visit the parameters in left-to-right order
2163 : //
2164 :
2165 : // For the Nary case, we simply visit the parameters in a loop.
2166 128134 : if (expr->IsNaryOperation()) {
2167 9726 : NaryOperation* nary = expr->AsNaryOperation();
2168 : // The classifier has already run, so we know that the expression is a valid
2169 : // arrow function formals production.
2170 : DCHECK_EQ(nary->op(), Token::COMMA);
2171 : // Each op position is the end position of the *previous* expr, with the
2172 : // second (i.e. first "subsequent") op position being the end position of
2173 : // the first child expression.
2174 : Expression* next = nary->first();
2175 30806 : for (size_t i = 0; i < nary->subsequent_length(); ++i) {
2176 : AddArrowFunctionFormalParameters(parameters, next,
2177 10540 : nary->subsequent_op_position(i));
2178 : next = nary->subsequent(i);
2179 : }
2180 : AddArrowFunctionFormalParameters(parameters, next, end_pos);
2181 123272 : return;
2182 : }
2183 :
2184 : // For the binary case, we recurse on the left-hand side of binary comma
2185 : // expressions.
2186 123271 : if (expr->IsBinaryOperation()) {
2187 28972 : BinaryOperation* binop = expr->AsBinaryOperation();
2188 : // The classifier has already run, so we know that the expression is a valid
2189 : // arrow function formals production.
2190 : DCHECK_EQ(binop->op(), Token::COMMA);
2191 : Expression* left = binop->left();
2192 : Expression* right = binop->right();
2193 14486 : int comma_pos = binop->position();
2194 14486 : AddArrowFunctionFormalParameters(parameters, left, comma_pos);
2195 : // LHS of comma expression should be unparenthesized.
2196 : expr = right;
2197 : }
2198 :
2199 : // Only the right-most expression may be a rest parameter.
2200 : DCHECK(!parameters->has_rest);
2201 :
2202 : bool is_rest = expr->IsSpread();
2203 123269 : if (is_rest) {
2204 3182 : expr = expr->AsSpread()->expression();
2205 1591 : parameters->has_rest = true;
2206 : }
2207 : DCHECK_IMPLIES(parameters->is_simple, !is_rest);
2208 : DCHECK_IMPLIES(parameters->is_simple, expr->IsVariableProxy());
2209 :
2210 : Expression* initializer = nullptr;
2211 123270 : if (expr->IsAssignment()) {
2212 8118 : Assignment* assignment = expr->AsAssignment();
2213 : DCHECK(!assignment->IsCompoundAssignment());
2214 : initializer = assignment->value();
2215 : expr = assignment->target();
2216 : }
2217 :
2218 : AddFormalParameter(parameters, expr, initializer,
2219 : end_pos, is_rest);
2220 : }
2221 :
2222 375317 : void Parser::DeclareArrowFunctionFormalParameters(
2223 : ParserFormalParameters* parameters, Expression* expr,
2224 : const Scanner::Location& params_loc) {
2225 473571 : if (expr->IsEmptyParentheses() || has_error()) return;
2226 :
2227 98248 : AddArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos);
2228 :
2229 98246 : if (parameters->arity > Code::kMaxArguments) {
2230 0 : ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
2231 0 : return;
2232 : }
2233 :
2234 : DeclareFormalParameters(parameters);
2235 : DCHECK_IMPLIES(parameters->is_simple,
2236 : parameters->scope->has_simple_parameters());
2237 : }
2238 :
2239 134449 : void Parser::PrepareGeneratorVariables() {
2240 : // Calling a generator returns a generator object. That object is stored
2241 : // in a temporary variable, a definition that is used by "yield"
2242 : // expressions.
2243 : function_state_->scope()->DeclareGeneratorObjectVar(
2244 403348 : ast_value_factory()->dot_generator_object_string());
2245 134450 : }
2246 :
2247 3737467 : FunctionLiteral* Parser::ParseFunctionLiteral(
2248 : const AstRawString* function_name, Scanner::Location function_name_location,
2249 : FunctionNameValidity function_name_validity, FunctionKind kind,
2250 : int function_token_pos, FunctionLiteral::FunctionType function_type,
2251 : LanguageMode language_mode,
2252 7475363 : ZonePtrList<const AstRawString>* arguments_for_wrapped_function) {
2253 : // Function ::
2254 : // '(' FormalParameterList? ')' '{' FunctionBody '}'
2255 : //
2256 : // Getter ::
2257 : // '(' ')' '{' FunctionBody '}'
2258 : //
2259 : // Setter ::
2260 : // '(' PropertySetParameterList ')' '{' FunctionBody '}'
2261 :
2262 3737467 : bool is_wrapped = function_type == FunctionLiteral::kWrapped;
2263 : DCHECK_EQ(is_wrapped, arguments_for_wrapped_function != nullptr);
2264 :
2265 9620083 : int pos = function_token_pos == kNoSourcePosition ? peek_position()
2266 3737467 : : function_token_pos;
2267 : DCHECK_NE(kNoSourcePosition, pos);
2268 :
2269 : // Anonymous functions were passed either the empty symbol or a null
2270 : // handle as the function name. Remember if we were passed a non-empty
2271 : // handle to decide whether to invoke function name inference.
2272 3737467 : bool should_infer_name = function_name == nullptr;
2273 :
2274 : // We want a non-null handle as the function name by default. We will handle
2275 : // the "function does not have a shared name" case later.
2276 3737467 : if (should_infer_name) {
2277 982868 : function_name = ast_value_factory()->empty_string();
2278 : }
2279 :
2280 : FunctionLiteral::EagerCompileHint eager_compile_hint =
2281 6895661 : function_state_->next_function_is_likely_called() || is_wrapped
2282 : ? FunctionLiteral::kShouldEagerCompile
2283 6895544 : : default_eager_compile_hint();
2284 :
2285 : // Determine if the function can be parsed lazily. Lazy parsing is
2286 : // different from lazy compilation; we need to parse more eagerly than we
2287 : // compile.
2288 :
2289 : // We can only parse lazily if we also compile lazily. The heuristics for lazy
2290 : // compilation are:
2291 : // - It must not have been prohibited by the caller to Parse (some callers
2292 : // need a full AST).
2293 : // - The outer scope must allow lazy compilation of inner functions.
2294 : // - The function mustn't be a function expression with an open parenthesis
2295 : // before; we consider that a hint that the function will be called
2296 : // immediately, and it would be a waste of time to make it lazily
2297 : // compiled.
2298 : // These are all things we can know at this point, without looking at the
2299 : // function itself.
2300 :
2301 : // We separate between lazy parsing top level functions and lazy parsing inner
2302 : // functions, because the latter needs to do more work. In particular, we need
2303 : // to track unresolved variables to distinguish between these cases:
2304 : // (function foo() {
2305 : // bar = function() { return 1; }
2306 : // })();
2307 : // and
2308 : // (function foo() {
2309 : // var a = 1;
2310 : // bar = function() { return a; }
2311 : // })();
2312 :
2313 : // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
2314 : // parenthesis before the function means that it will be called
2315 : // immediately). bar can be parsed lazily, but we need to parse it in a mode
2316 : // that tracks unresolved variables.
2317 : DCHECK_IMPLIES(parse_lazily(), info()->allow_lazy_compile());
2318 : DCHECK_IMPLIES(parse_lazily(), has_error() || allow_lazy_);
2319 : DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr);
2320 :
2321 : const bool is_lazy =
2322 3737467 : eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
2323 : const bool is_top_level = AllowsLazyParsingWithoutUnresolvedVariables();
2324 3737684 : const bool is_eager_top_level_function = !is_lazy && is_top_level;
2325 3737684 : const bool is_lazy_top_level_function = is_lazy && is_top_level;
2326 3737684 : const bool is_lazy_inner_function = is_lazy && !is_top_level;
2327 :
2328 : RuntimeCallTimerScope runtime_timer(
2329 : runtime_call_stats_,
2330 : parsing_on_main_thread_
2331 : ? RuntimeCallCounterId::kParseFunctionLiteral
2332 3737684 : : RuntimeCallCounterId::kParseBackgroundFunctionLiteral);
2333 : base::ElapsedTimer timer;
2334 3737621 : if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
2335 :
2336 : // Determine whether we can still lazy parse the inner function.
2337 : // The preconditions are:
2338 : // - Lazy compilation has to be enabled.
2339 : // - Neither V8 natives nor native function declarations can be allowed,
2340 : // since parsing one would retroactively force the function to be
2341 : // eagerly compiled.
2342 : // - The invoker of this parser can't depend on the AST being eagerly
2343 : // built (either because the function is about to be compiled, or
2344 : // because the AST is going to be inspected for some reason).
2345 : // - Because of the above, we can't be attempting to parse a
2346 : // FunctionExpression; even without enclosing parentheses it might be
2347 : // immediately invoked.
2348 : // - The function literal shouldn't be hinted to eagerly compile.
2349 :
2350 : // Inner functions will be parsed using a temporary Zone. After parsing, we
2351 : // will migrate unresolved variable into a Scope in the main Zone.
2352 :
2353 3737621 : const bool should_preparse_inner = parse_lazily() && is_lazy_inner_function;
2354 :
2355 : // If parallel compile tasks are enabled, and the function is an eager
2356 : // top level function, then we can pre-parse the function and parse / compile
2357 : // in a parallel task on a worker thread.
2358 : bool should_post_parallel_task =
2359 3053702 : parse_lazily() && is_eager_top_level_function &&
2360 3737753 : FLAG_parallel_compile_tasks && info()->parallel_tasks() &&
2361 66 : scanner()->stream()->can_be_cloned_for_parallel_access();
2362 :
2363 : // This may be modified later to reflect preparsing decision taken
2364 3053582 : bool should_preparse = (parse_lazily() && is_lazy_top_level_function) ||
2365 6772293 : should_preparse_inner || should_post_parallel_task;
2366 :
2367 3737621 : ScopedPtrList<Statement> body(pointer_buffer());
2368 3737621 : int expected_property_count = -1;
2369 3737621 : int suspend_count = -1;
2370 3737621 : int num_parameters = -1;
2371 3737621 : int function_length = -1;
2372 3737621 : bool has_duplicate_parameters = false;
2373 : int function_literal_id = GetNextFunctionLiteralId();
2374 3737621 : ProducedPreparseData* produced_preparse_data = nullptr;
2375 :
2376 : // This Scope lives in the main zone. We'll migrate data into that zone later.
2377 3737621 : Zone* parse_zone = should_preparse ? &preparser_zone_ : zone();
2378 3737621 : DeclarationScope* scope = NewFunctionScope(kind, parse_zone);
2379 3737974 : SetLanguageMode(scope, language_mode);
2380 : #ifdef DEBUG
2381 : scope->SetScopeName(function_name);
2382 : #endif
2383 :
2384 7475758 : if (!is_wrapped && V8_UNLIKELY(!Check(Token::LPAREN))) {
2385 19219 : ReportUnexpectedToken(Next());
2386 19219 : return nullptr;
2387 : }
2388 855960 : scope->set_start_position(position());
2389 :
2390 : // Eager or lazy parse? If is_lazy_top_level_function, we'll parse
2391 : // lazily. We'll call SkipFunction, which may decide to
2392 : // abort lazy parsing if it suspects that wasn't a good idea. If so (in
2393 : // which case the parser is expected to have backtracked), or if we didn't
2394 : // try to lazy parse in the first place, we'll have to parse eagerly.
2395 : bool did_preparse_successfully =
2396 6200207 : should_preparse && SkipFunction(function_name, kind, function_type, scope,
2397 2481388 : &num_parameters, &produced_preparse_data);
2398 :
2399 3718819 : if (!did_preparse_successfully) {
2400 : // If skipping aborted, it rewound the scanner until before the LPAREN.
2401 : // Consume it in that case.
2402 1277592 : if (should_preparse) Consume(Token::LPAREN);
2403 : should_post_parallel_task = false;
2404 : ParseFunction(&body, function_name, pos, kind, function_type, scope,
2405 : &num_parameters, &function_length, &has_duplicate_parameters,
2406 : &expected_property_count, &suspend_count,
2407 1277592 : arguments_for_wrapped_function);
2408 : }
2409 :
2410 3718717 : if (V8_UNLIKELY(FLAG_log_function_events)) {
2411 70 : double ms = timer.Elapsed().InMillisecondsF();
2412 : const char* event_name =
2413 : should_preparse
2414 : ? (is_top_level ? "preparse-no-resolution" : "preparse-resolution")
2415 70 : : "full-parse";
2416 : logger_->FunctionEvent(
2417 : event_name, script_id(), ms, scope->start_position(),
2418 : scope->end_position(),
2419 : reinterpret_cast<const char*>(function_name->raw_data()),
2420 140 : function_name->byte_length());
2421 : }
2422 3718717 : if (V8_UNLIKELY(FLAG_runtime_stats) && did_preparse_successfully) {
2423 : const RuntimeCallCounterId counters[2] = {
2424 : RuntimeCallCounterId::kPreParseBackgroundWithVariableResolution,
2425 2 : RuntimeCallCounterId::kPreParseWithVariableResolution};
2426 2 : if (runtime_call_stats_) {
2427 : runtime_call_stats_->CorrectCurrentCounterId(
2428 2 : counters[parsing_on_main_thread_]);
2429 : }
2430 : }
2431 :
2432 : // Validate function name. We can do this only after parsing the function,
2433 : // since the function can declare itself strict.
2434 : language_mode = scope->language_mode();
2435 : CheckFunctionName(language_mode, function_name, function_name_validity,
2436 3718717 : function_name_location);
2437 :
2438 3718740 : if (is_strict(language_mode)) {
2439 855890 : CheckStrictOctalLiteral(scope->start_position(), scope->end_position());
2440 : }
2441 3718736 : CheckConflictingVarDeclarations(scope);
2442 :
2443 : FunctionLiteral::ParameterFlag duplicate_parameters =
2444 : has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
2445 3718730 : : FunctionLiteral::kNoDuplicateParameters;
2446 :
2447 : // Note that the FunctionLiteral needs to be created in the main Zone again.
2448 : FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
2449 : function_name, scope, body, expected_property_count, num_parameters,
2450 : function_length, duplicate_parameters, function_type, eager_compile_hint,
2451 3718730 : pos, true, function_literal_id, produced_preparse_data);
2452 : function_literal->set_function_token_position(function_token_pos);
2453 3718683 : function_literal->set_suspend_count(suspend_count);
2454 :
2455 3718683 : if (should_post_parallel_task) {
2456 : // Start a parallel parse / compile task on the compiler dispatcher.
2457 55 : info()->parallel_tasks()->Enqueue(info(), function_name, function_literal);
2458 : }
2459 :
2460 3718662 : if (should_infer_name) {
2461 : fni_.AddFunction(function_literal);
2462 : }
2463 3718649 : return function_literal;
2464 : }
2465 :
2466 2508535 : bool Parser::SkipFunction(const AstRawString* function_name, FunctionKind kind,
2467 : FunctionLiteral::FunctionType function_type,
2468 : DeclarationScope* function_scope, int* num_parameters,
2469 : ProducedPreparseData** produced_preparse_data) {
2470 2508535 : FunctionState function_state(&function_state_, &scope_, function_scope);
2471 2508535 : function_scope->set_zone(&preparser_zone_);
2472 :
2473 : DCHECK_NE(kNoSourcePosition, function_scope->start_position());
2474 : DCHECK_EQ(kNoSourcePosition, parameters_end_pos_);
2475 :
2476 : DCHECK_IMPLIES(IsArrowFunction(kind),
2477 : scanner()->current_token() == Token::ARROW);
2478 :
2479 : // FIXME(marja): There are 2 ways to skip functions now. Unify them.
2480 2508535 : if (consumed_preparse_data_) {
2481 : int end_position;
2482 : LanguageMode language_mode;
2483 : int num_inner_functions;
2484 : bool uses_super_property;
2485 7549092 : if (stack_overflow()) {
2486 : return true;
2487 : }
2488 : *produced_preparse_data =
2489 : consumed_preparse_data_->GetDataForSkippableFunction(
2490 : main_zone(), function_scope->start_position(), &end_position,
2491 : num_parameters, &num_inner_functions, &uses_super_property,
2492 4963212 : &language_mode);
2493 :
2494 : function_scope->outer_scope()->SetMustUsePreparseData();
2495 : function_scope->set_is_skipped_function(true);
2496 62342 : function_scope->set_end_position(end_position);
2497 124684 : scanner()->SeekForward(end_position - 1);
2498 62342 : Expect(Token::RBRACE);
2499 62342 : SetLanguageMode(function_scope, language_mode);
2500 62342 : if (uses_super_property) {
2501 : function_scope->RecordSuperPropertyUsage();
2502 : }
2503 62342 : SkipFunctionLiterals(num_inner_functions);
2504 62342 : function_scope->ResetAfterPreparsing(ast_value_factory_, false);
2505 62342 : return true;
2506 : }
2507 :
2508 : Scanner::BookmarkScope bookmark(scanner());
2509 2446193 : bookmark.Set(function_scope->start_position());
2510 :
2511 : // With no cached data, we partially parse the function, without building an
2512 : // AST. This gathers the data needed to build a lazy function.
2513 7338887 : TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse");
2514 :
2515 : PreParser::PreParseResult result = reusable_preparser()->PreParseFunction(
2516 : function_name, kind, function_type, function_scope, use_counts_,
2517 2446271 : produced_preparse_data, this->script_id());
2518 :
2519 2446134 : if (result == PreParser::kPreParseStackOverflow) {
2520 : // Propagate stack overflow.
2521 24 : set_stack_overflow();
2522 2446110 : } else if (pending_error_handler()->has_error_unidentifiable_by_preparser()) {
2523 : // Make sure we don't re-preparse inner functions of the aborted function.
2524 : // The error might be in an inner function.
2525 42917 : allow_lazy_ = false;
2526 42917 : mode_ = PARSE_EAGERLY;
2527 : DCHECK(!pending_error_handler()->stack_overflow());
2528 : // If we encounter an error that the preparser can not identify we reset to
2529 : // the state before preparsing. The caller may then fully parse the function
2530 : // to identify the actual error.
2531 42917 : bookmark.Apply();
2532 42917 : function_scope->ResetAfterPreparsing(ast_value_factory(), true);
2533 : pending_error_handler()->clear_unidentifiable_error();
2534 42917 : return false;
2535 2403193 : } else if (pending_error_handler()->has_pending_error()) {
2536 : DCHECK(!pending_error_handler()->stack_overflow());
2537 : DCHECK(has_error());
2538 : } else {
2539 : DCHECK(!pending_error_handler()->stack_overflow());
2540 2392107 : set_allow_eval_cache(reusable_preparser()->allow_eval_cache());
2541 :
2542 7176824 : PreParserLogger* logger = reusable_preparser()->logger();
2543 : function_scope->set_end_position(logger->end());
2544 2392214 : Expect(Token::RBRACE);
2545 : total_preparse_skipped_ +=
2546 2392335 : function_scope->end_position() - function_scope->start_position();
2547 2392335 : *num_parameters = logger->num_parameters();
2548 : SkipFunctionLiterals(logger->num_inner_functions());
2549 2392335 : function_scope->AnalyzePartially(this, factory());
2550 : }
2551 :
2552 : return true;
2553 : }
2554 :
2555 0 : Statement* Parser::BuildAssertIsCoercible(Variable* var,
2556 : ObjectLiteral* pattern) {
2557 : // if (var === null || var === undefined)
2558 : // throw /* type error kNonCoercible) */;
2559 0 : auto source_position = pattern->position();
2560 0 : const AstRawString* property = ast_value_factory()->empty_string();
2561 : MessageTemplate msg = MessageTemplate::kNonCoercible;
2562 0 : for (ObjectLiteralProperty* literal_property : *pattern->properties()) {
2563 : Expression* key = literal_property->key();
2564 0 : if (key->IsPropertyName()) {
2565 0 : property = key->AsLiteral()->AsRawPropertyName();
2566 : msg = MessageTemplate::kNonCoercibleWithProperty;
2567 : source_position = key->position();
2568 0 : break;
2569 : }
2570 : }
2571 :
2572 : Expression* condition = factory()->NewBinaryOperation(
2573 : Token::OR,
2574 : factory()->NewCompareOperation(
2575 0 : Token::EQ_STRICT, factory()->NewVariableProxy(var),
2576 0 : factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
2577 : factory()->NewCompareOperation(
2578 0 : Token::EQ_STRICT, factory()->NewVariableProxy(var),
2579 0 : factory()->NewNullLiteral(kNoSourcePosition), kNoSourcePosition),
2580 0 : kNoSourcePosition);
2581 : Expression* throw_type_error =
2582 : NewThrowTypeError(msg, property, source_position);
2583 : IfStatement* if_statement = factory()->NewIfStatement(
2584 : condition,
2585 0 : factory()->NewExpressionStatement(throw_type_error, kNoSourcePosition),
2586 0 : factory()->EmptyStatement(), kNoSourcePosition);
2587 0 : return if_statement;
2588 : }
2589 :
2590 : class InitializerRewriter final
2591 : : public AstTraversalVisitor<InitializerRewriter> {
2592 : public:
2593 : InitializerRewriter(uintptr_t stack_limit, Expression* root, Parser* parser)
2594 15891 : : AstTraversalVisitor(stack_limit, root), parser_(parser) {}
2595 :
2596 : private:
2597 : // This is required so that the overriden Visit* methods can be
2598 : // called by the base class (template).
2599 : friend class AstTraversalVisitor<InitializerRewriter>;
2600 :
2601 : // Code in function literals does not need to be eagerly rewritten, it will be
2602 : // rewritten when scheduled.
2603 : void VisitFunctionLiteral(FunctionLiteral* expr) {}
2604 :
2605 : Parser* parser_;
2606 : };
2607 :
2608 16052 : void Parser::RewriteParameterInitializer(Expression* expr) {
2609 16215 : if (has_error()) return;
2610 15891 : InitializerRewriter rewriter(stack_limit_, expr, this);
2611 : rewriter.Run();
2612 : }
2613 :
2614 33027 : Block* Parser::BuildParameterInitializationBlock(
2615 : const ParserFormalParameters& parameters) {
2616 : DCHECK(!parameters.is_simple);
2617 : DCHECK(scope()->is_function_scope());
2618 : DCHECK_EQ(scope(), parameters.scope);
2619 91008 : ScopedPtrList<Statement> init_statements(pointer_buffer());
2620 : int index = 0;
2621 122878 : for (auto parameter : parameters.params) {
2622 : DeclarationDescriptor descriptor;
2623 56822 : descriptor.kind = PARAMETER_VARIABLE;
2624 56822 : descriptor.mode = VariableMode::kLet;
2625 56822 : descriptor.declaration_pos = parameter->pattern->position();
2626 : // The position that will be used by the AssignmentExpression
2627 : // which copies from the temp parameter to the pattern.
2628 : //
2629 : // TODO(adamk): Should this be kNoSourcePosition, since
2630 : // it's just copying from a temp var to the real param var?
2631 56822 : descriptor.initialization_pos = parameter->pattern->position();
2632 : Expression* initial_value =
2633 113644 : factory()->NewVariableProxy(parameters.scope->parameter(index));
2634 56821 : if (parameter->initializer() != nullptr) {
2635 : // IS_UNDEFINED($param) ? initializer : $param
2636 :
2637 16054 : if (parameter->initializer()->IsClassLiteral()) {
2638 : // Initializers could have their own scopes. So set the scope
2639 : // here if necessary.
2640 : BlockState block_state(
2641 94 : &scope_, parameter->initializer()->AsClassLiteral()->scope());
2642 :
2643 : // Ensure initializer is rewritten
2644 47 : RewriteParameterInitializer(parameter->initializer());
2645 : } else {
2646 : // Ensure initializer is rewritten
2647 16007 : RewriteParameterInitializer(parameter->initializer());
2648 : }
2649 :
2650 : auto condition = factory()->NewCompareOperation(
2651 : Token::EQ_STRICT,
2652 32112 : factory()->NewVariableProxy(parameters.scope->parameter(index)),
2653 32111 : factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
2654 : initial_value =
2655 : factory()->NewConditional(condition, parameter->initializer(),
2656 16056 : initial_value, kNoSourcePosition);
2657 16057 : descriptor.initialization_pos = parameter->initializer()->position();
2658 : }
2659 :
2660 : Scope* param_scope = scope();
2661 : ScopedPtrList<Statement>* param_init_statements = &init_statements;
2662 :
2663 56824 : base::Optional<ScopedPtrList<Statement>> non_simple_param_init_statements;
2664 92603 : if (!parameter->is_simple() &&
2665 35779 : scope()->AsDeclarationScope()->calls_sloppy_eval()) {
2666 1157 : param_scope = NewVarblockScope();
2667 1157 : param_scope->set_start_position(descriptor.initialization_pos);
2668 1157 : param_scope->set_end_position(parameter->initializer_end_position);
2669 : param_scope->RecordEvalCall();
2670 1157 : non_simple_param_init_statements.emplace(pointer_buffer());
2671 1157 : param_init_statements = &non_simple_param_init_statements.value();
2672 : // Rewrite the outer initializer to point to param_scope
2673 1157 : ReparentExpressionScope(stack_limit(), initial_value, param_scope);
2674 : }
2675 :
2676 56825 : BlockState block_state(&scope_, param_scope);
2677 : DeclarationParsingResult::Declaration decl(
2678 56825 : parameter->pattern, parameter->initializer_end_position, initial_value);
2679 :
2680 56825 : InitializeVariables(param_init_statements, &descriptor, &decl, nullptr);
2681 :
2682 56825 : if (param_init_statements != &init_statements) {
2683 : DCHECK_EQ(param_init_statements,
2684 : &non_simple_param_init_statements.value());
2685 : Block* param_block =
2686 1157 : factory()->NewBlock(true, *non_simple_param_init_statements);
2687 : non_simple_param_init_statements.reset();
2688 : param_block->set_scope(param_scope);
2689 1157 : param_scope = param_scope->FinalizeBlockScope();
2690 1157 : if (param_scope != nullptr) {
2691 1157 : CheckConflictingVarDeclarations(param_scope);
2692 : }
2693 1157 : init_statements.Add(param_block);
2694 : }
2695 56825 : ++index;
2696 : }
2697 66058 : return factory()->NewBlock(true, init_statements);
2698 : }
2699 :
2700 68081 : Scope* Parser::NewHiddenCatchScope() {
2701 68081 : Scope* catch_scope = NewScopeWithParent(scope(), CATCH_SCOPE);
2702 : catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(),
2703 136166 : VariableMode::kVar);
2704 : catch_scope->set_is_hidden();
2705 68083 : return catch_scope;
2706 : }
2707 :
2708 43957 : Block* Parser::BuildRejectPromiseOnException(Block* inner_block) {
2709 : // try {
2710 : // <inner_block>
2711 : // } catch (.catch) {
2712 : // return %_AsyncFunctionReject(.generator_object, .catch, can_suspend);
2713 : // }
2714 87917 : Block* result = factory()->NewBlock(1, true);
2715 :
2716 : // catch (.catch) {
2717 : // return %_AsyncFunctionReject(.generator_object, .catch, can_suspend)
2718 : // }
2719 43957 : Scope* catch_scope = NewHiddenCatchScope();
2720 :
2721 : Expression* reject_promise;
2722 : {
2723 43960 : ScopedPtrList<Expression> args(pointer_buffer());
2724 : args.Add(factory()->NewVariableProxy(
2725 175838 : function_state_->scope()->generator_object_var()));
2726 87920 : args.Add(factory()->NewVariableProxy(catch_scope->catch_variable()));
2727 43959 : args.Add(factory()->NewBooleanLiteral(function_state_->CanSuspend(),
2728 87918 : kNoSourcePosition));
2729 : reject_promise = factory()->NewCallRuntime(
2730 43960 : Runtime::kInlineAsyncFunctionReject, args, kNoSourcePosition);
2731 : }
2732 : Block* catch_block = IgnoreCompletion(
2733 87920 : factory()->NewReturnStatement(reject_promise, kNoSourcePosition));
2734 :
2735 : TryStatement* try_catch_statement =
2736 : factory()->NewTryCatchStatementForAsyncAwait(
2737 43959 : inner_block, catch_scope, catch_block, kNoSourcePosition);
2738 43960 : result->statements()->Add(try_catch_statement, zone());
2739 43960 : return result;
2740 : }
2741 :
2742 84425 : Expression* Parser::BuildInitialYield(int pos, FunctionKind kind) {
2743 : Expression* yield_result = factory()->NewVariableProxy(
2744 253276 : function_state_->scope()->generator_object_var());
2745 : // The position of the yield is important for reporting the exception
2746 : // caused by calling the .throw method on a generator suspended at the
2747 : // initial yield (i.e. right after generator instantiation).
2748 84426 : function_state_->AddSuspend();
2749 : return factory()->NewYield(yield_result, scope()->start_position(),
2750 84426 : Suspend::kOnExceptionThrow);
2751 : }
2752 :
2753 1277576 : void Parser::ParseFunction(
2754 : ScopedPtrList<Statement>* body, const AstRawString* function_name, int pos,
2755 : FunctionKind kind, FunctionLiteral::FunctionType function_type,
2756 : DeclarationScope* function_scope, int* num_parameters, int* function_length,
2757 : bool* has_duplicate_parameters, int* expected_property_count,
2758 : int* suspend_count,
2759 84 : ZonePtrList<const AstRawString>* arguments_for_wrapped_function) {
2760 1277576 : ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
2761 :
2762 1277576 : FunctionState function_state(&function_state_, &scope_, function_scope);
2763 :
2764 : bool is_wrapped = function_type == FunctionLiteral::kWrapped;
2765 :
2766 1277576 : int expected_parameters_end_pos = parameters_end_pos_;
2767 1277576 : if (expected_parameters_end_pos != kNoSourcePosition) {
2768 : // This is the first function encountered in a CreateDynamicFunction eval.
2769 341129 : parameters_end_pos_ = kNoSourcePosition;
2770 : // The function name should have been ignored, giving us the empty string
2771 : // here.
2772 : DCHECK_EQ(function_name, ast_value_factory()->empty_string());
2773 : }
2774 :
2775 : ParserFormalParameters formals(function_scope);
2776 :
2777 : {
2778 : ParameterDeclarationParsingScope formals_scope(this);
2779 1277576 : if (is_wrapped) {
2780 : // For a function implicitly wrapped in function header and footer, the
2781 : // function arguments are provided separately to the source, and are
2782 : // declared directly here.
2783 : int arguments_length = arguments_for_wrapped_function->length();
2784 104 : for (int i = 0; i < arguments_length; i++) {
2785 : const bool is_rest = false;
2786 : Expression* argument = ExpressionFromIdentifier(
2787 20 : arguments_for_wrapped_function->at(i), kNoSourcePosition);
2788 : AddFormalParameter(&formals, argument, NullExpression(),
2789 : kNoSourcePosition, is_rest);
2790 : }
2791 : DCHECK_EQ(arguments_length, formals.num_parameters());
2792 : DeclareFormalParameters(&formals);
2793 : } else {
2794 : // For a regular function, the function arguments are parsed from source.
2795 : DCHECK_NULL(arguments_for_wrapped_function);
2796 2896062 : ParseFormalParameterList(&formals);
2797 1277480 : if (expected_parameters_end_pos != kNoSourcePosition) {
2798 : // Check for '(' or ')' shenanigans in the parameter string for dynamic
2799 : // functions.
2800 : int position = peek_position();
2801 341129 : if (position < expected_parameters_end_pos) {
2802 : ReportMessageAt(Scanner::Location(position, position + 1),
2803 90 : MessageTemplate::kArgStringTerminatesParametersEarly);
2804 45 : return;
2805 341084 : } else if (position > expected_parameters_end_pos) {
2806 : ReportMessageAt(Scanner::Location(expected_parameters_end_pos - 2,
2807 : expected_parameters_end_pos),
2808 36 : MessageTemplate::kUnexpectedEndOfArgString);
2809 18 : return;
2810 : }
2811 : }
2812 1277417 : Expect(Token::RPAREN);
2813 1277441 : int formals_end_position = scanner()->location().end_pos;
2814 :
2815 : CheckArityRestrictions(formals.arity, kind, formals.has_rest,
2816 : function_scope->start_position(),
2817 1277441 : formals_end_position);
2818 1277419 : Expect(Token::LBRACE);
2819 : }
2820 : }
2821 :
2822 2555088 : *num_parameters = formals.num_parameters();
2823 1277544 : *function_length = formals.function_length;
2824 :
2825 1277544 : AcceptINScope scope(this, true);
2826 : ParseFunctionBody(body, function_name, pos, formals, kind, function_type,
2827 1277544 : FunctionBodyType::kBlock);
2828 :
2829 1277505 : *has_duplicate_parameters = formals.has_duplicate();
2830 :
2831 1277505 : *expected_property_count = function_state.expected_property_count();
2832 1277505 : *suspend_count = function_state.suspend_count();
2833 : }
2834 :
2835 181496 : void Parser::DeclareClassVariable(const AstRawString* name,
2836 : ClassInfo* class_info, int class_token_pos) {
2837 : #ifdef DEBUG
2838 : scope()->SetScopeName(name);
2839 : #endif
2840 :
2841 181496 : if (name != nullptr) {
2842 120372 : VariableProxy* proxy =
2843 : DeclareVariable(name, VariableMode::kConst, class_token_pos);
2844 120372 : class_info->variable = proxy->var();
2845 : }
2846 181499 : }
2847 :
2848 : // TODO(gsathya): Ideally, this should just bypass scope analysis and
2849 : // allocate a slot directly on the context. We should just store this
2850 : // index in the AST, instead of storing the variable.
2851 14966 : Variable* Parser::CreateSyntheticContextVariable(const AstRawString* name) {
2852 29936 : VariableProxy* proxy =
2853 : DeclareVariable(name, VariableMode::kConst, kNoSourcePosition);
2854 : proxy->var()->ForceContextAllocation();
2855 14968 : return proxy->var();
2856 : }
2857 :
2858 31703 : void Parser::DeclareClassField(ClassLiteralProperty* property,
2859 : const AstRawString* property_name,
2860 : bool is_static, bool is_computed_name,
2861 : bool is_private, ClassInfo* class_info) {
2862 : DCHECK(allow_harmony_public_fields() || allow_harmony_private_fields());
2863 :
2864 31703 : if (is_static) {
2865 29052 : class_info->static_fields->Add(property, zone());
2866 : } else {
2867 22829 : class_info->instance_fields->Add(property, zone());
2868 : }
2869 :
2870 : DCHECK_IMPLIES(is_computed_name, !is_private);
2871 31703 : if (is_computed_name) {
2872 : // We create a synthetic variable name here so that scope
2873 : // analysis doesn't dedupe the vars.
2874 : Variable* computed_name_var =
2875 : CreateSyntheticContextVariable(ClassFieldVariableName(
2876 10420 : ast_value_factory(), class_info->computed_field_count));
2877 5210 : property->set_computed_name_var(computed_name_var);
2878 5210 : class_info->properties->Add(property, zone());
2879 26493 : } else if (is_private) {
2880 9757 : Variable* private_name_var = CreateSyntheticContextVariable(property_name);
2881 9758 : private_name_var->set_initializer_position(property->value()->position());
2882 : property->set_private_name_var(private_name_var);
2883 9758 : class_info->properties->Add(property, zone());
2884 : }
2885 31704 : }
2886 :
2887 : // This method declares a property of the given class. It updates the
2888 : // following fields of class_info, as appropriate:
2889 : // - constructor
2890 : // - properties
2891 362134 : void Parser::DeclareClassProperty(const AstRawString* class_name,
2892 : ClassLiteralProperty* property,
2893 : bool is_constructor, ClassInfo* class_info) {
2894 362134 : if (is_constructor) {
2895 : DCHECK(!class_info->constructor);
2896 36242 : class_info->constructor = property->value()->AsFunctionLiteral();
2897 : DCHECK_NOT_NULL(class_info->constructor);
2898 : class_info->constructor->set_raw_name(
2899 359038 : class_name != nullptr ? ast_value_factory()->NewConsString(class_name)
2900 33146 : : nullptr);
2901 362133 : return;
2902 : }
2903 :
2904 344013 : class_info->properties->Add(property, zone());
2905 : }
2906 :
2907 26902 : FunctionLiteral* Parser::CreateInitializerFunction(
2908 : const char* name, DeclarationScope* scope,
2909 : ZonePtrList<ClassLiteral::Property>* fields) {
2910 : DCHECK_EQ(scope->function_kind(),
2911 : FunctionKind::kClassMembersInitializerFunction);
2912 : // function() { .. class fields initializer .. }
2913 53804 : ScopedPtrList<Statement> statements(pointer_buffer());
2914 : InitializeClassMembersStatement* static_fields =
2915 26902 : factory()->NewInitializeClassMembersStatement(fields, kNoSourcePosition);
2916 26902 : statements.Add(static_fields);
2917 : return factory()->NewFunctionLiteral(
2918 : ast_value_factory()->GetOneByteString(name), scope, statements, 0, 0, 0,
2919 : FunctionLiteral::kNoDuplicateParameters,
2920 : FunctionLiteral::kAnonymousExpression,
2921 : FunctionLiteral::kShouldEagerCompile, scope->start_position(), false,
2922 80707 : GetNextFunctionLiteralId());
2923 : }
2924 :
2925 : // This method generates a ClassLiteral AST node.
2926 : // It uses the following fields of class_info:
2927 : // - constructor (if missing, it updates it with a default constructor)
2928 : // - proxy
2929 : // - extends
2930 : // - properties
2931 : // - has_name_static_property
2932 : // - has_static_computed_names
2933 108052 : Expression* Parser::RewriteClassLiteral(Scope* block_scope,
2934 : const AstRawString* name,
2935 : ClassInfo* class_info, int pos,
2936 : int end_pos) {
2937 : DCHECK_NOT_NULL(block_scope);
2938 : DCHECK_EQ(block_scope->scope_type(), BLOCK_SCOPE);
2939 : DCHECK_EQ(block_scope->language_mode(), LanguageMode::kStrict);
2940 :
2941 108052 : bool has_extends = class_info->extends != nullptr;
2942 108052 : bool has_default_constructor = class_info->constructor == nullptr;
2943 108052 : if (has_default_constructor) {
2944 : class_info->constructor =
2945 90144 : DefaultConstructor(name, has_extends, pos, end_pos);
2946 : }
2947 :
2948 108049 : if (name != nullptr) {
2949 : DCHECK_NOT_NULL(class_info->variable);
2950 80545 : class_info->variable->set_initializer_position(end_pos);
2951 : }
2952 :
2953 : FunctionLiteral* static_fields_initializer = nullptr;
2954 108049 : if (class_info->has_static_class_fields) {
2955 : static_fields_initializer = CreateInitializerFunction(
2956 : "<static_fields_initializer>", class_info->static_fields_scope,
2957 8433 : class_info->static_fields);
2958 : }
2959 :
2960 : FunctionLiteral* instance_members_initializer_function = nullptr;
2961 108050 : if (class_info->has_instance_members) {
2962 : instance_members_initializer_function = CreateInitializerFunction(
2963 : "<instance_members_initializer>", class_info->instance_members_scope,
2964 18470 : class_info->instance_fields);
2965 18470 : class_info->constructor->set_requires_instance_members_initializer(true);
2966 : }
2967 :
2968 : ClassLiteral* class_literal = factory()->NewClassLiteral(
2969 : block_scope, class_info->variable, class_info->extends,
2970 : class_info->constructor, class_info->properties,
2971 : static_fields_initializer, instance_members_initializer_function, pos,
2972 : end_pos, class_info->has_name_static_property,
2973 108050 : class_info->has_static_computed_names, class_info->is_anonymous);
2974 :
2975 108051 : AddFunctionForNameInference(class_info->constructor);
2976 108051 : return class_literal;
2977 : }
2978 :
2979 6018602 : void Parser::CheckConflictingVarDeclarations(Scope* scope) {
2980 12037284 : if (has_error()) return;
2981 5521759 : Declaration* decl = scope->CheckConflictingVarDeclarations();
2982 5508481 : if (decl != nullptr) {
2983 : // In ES6, conflicting variable bindings are early errors.
2984 13262 : const AstRawString* name = decl->var()->raw_name();
2985 13262 : int position = decl->position();
2986 : Scanner::Location location =
2987 : position == kNoSourcePosition
2988 : ? Scanner::Location::invalid()
2989 13262 : : Scanner::Location(position, position + 1);
2990 13262 : ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
2991 : }
2992 : }
2993 :
2994 11770 : bool Parser::IsPropertyWithPrivateFieldKey(Expression* expression) {
2995 11771 : if (!expression->IsProperty()) return false;
2996 14392 : Property* property = expression->AsProperty();
2997 :
2998 7197 : if (!property->key()->IsVariableProxy()) return false;
2999 1508 : VariableProxy* key = property->key()->AsVariableProxy();
3000 :
3001 1508 : return key->IsPrivateName();
3002 : }
3003 :
3004 10498 : void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) {
3005 : // For each var-binding that shadows a parameter, insert an assignment
3006 : // initializing the variable with the parameter.
3007 10498 : Scope* inner_scope = inner_block->scope();
3008 : DCHECK(inner_scope->is_declaration_scope());
3009 : Scope* function_scope = inner_scope->outer_scope();
3010 : DCHECK(function_scope->is_function_scope());
3011 10498 : BlockState block_state(&scope_, inner_scope);
3012 44245 : for (Declaration* decl : *inner_scope->declarations()) {
3013 56131 : if (decl->var()->mode() != VariableMode::kVar ||
3014 : !decl->IsVariableDeclaration()) {
3015 22390 : continue;
3016 : }
3017 6131 : const AstRawString* name = decl->var()->raw_name();
3018 : Variable* parameter = function_scope->LookupLocal(name);
3019 6132 : if (parameter == nullptr) continue;
3020 859 : VariableProxy* to = NewUnresolved(name);
3021 1718 : VariableProxy* from = factory()->NewVariableProxy(parameter);
3022 : Expression* assignment =
3023 859 : factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition);
3024 : Statement* statement =
3025 1718 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
3026 859 : inner_block->statements()->InsertAt(0, statement, zone());
3027 : }
3028 10498 : }
3029 :
3030 2433857 : void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope) {
3031 : // For the outermost eval scope, we cannot hoist during parsing: let
3032 : // declarations in the surrounding scope may prevent hoisting, but the
3033 : // information is unaccessible during parsing. In this case, we hoist later in
3034 : // DeclarationScope::Analyze.
3035 2433857 : if (scope->is_eval_scope() && scope->outer_scope() == original_scope_) {
3036 2433842 : return;
3037 : }
3038 1641212 : scope->HoistSloppyBlockFunctions(factory());
3039 : }
3040 :
3041 : // ----------------------------------------------------------------------------
3042 : // Parser support
3043 :
3044 15783 : bool Parser::TargetStackContainsLabel(const AstRawString* label) {
3045 24979 : for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
3046 18392 : if (ContainsLabel(t->statement()->labels(), label)) return true;
3047 : }
3048 : return false;
3049 : }
3050 :
3051 45347 : BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label) {
3052 45347 : bool anonymous = label == nullptr;
3053 64157 : for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
3054 48511 : BreakableStatement* stat = t->statement();
3055 176191 : if ((anonymous && stat->is_target_for_anonymous()) ||
3056 30660 : (!anonymous && ContainsLabel(stat->labels(), label))) {
3057 : return stat;
3058 : }
3059 : }
3060 : return nullptr;
3061 : }
3062 :
3063 14303 : IterationStatement* Parser::LookupContinueTarget(const AstRawString* label) {
3064 : bool anonymous = label == nullptr;
3065 36002 : for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
3066 39404 : IterationStatement* stat = t->statement()->AsIterationStatement();
3067 35635 : if (stat == nullptr) continue;
3068 :
3069 : DCHECK(stat->is_target_for_anonymous());
3070 17615 : if (anonymous || ContainsLabel(stat->own_labels(), label)) {
3071 : return stat;
3072 : }
3073 1277 : if (ContainsLabel(stat->labels(), label)) break;
3074 : }
3075 : return nullptr;
3076 : }
3077 :
3078 1710704 : void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) {
3079 1710704 : Handle<String> source_url = scanner_.SourceUrl(isolate);
3080 1710702 : if (!source_url.is_null()) {
3081 7744 : script->set_source_url(*source_url);
3082 : }
3083 1710702 : Handle<String> source_mapping_url = scanner_.SourceMappingUrl(isolate);
3084 1710701 : if (!source_mapping_url.is_null()) {
3085 200 : script->set_source_mapping_url(*source_mapping_url);
3086 : }
3087 1710701 : }
3088 :
3089 2428143 : void Parser::UpdateStatistics(Isolate* isolate, Handle<Script> script) {
3090 : // Move statistics to Isolate.
3091 184538892 : for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
3092 : ++feature) {
3093 182110731 : if (use_counts_[feature] > 0) {
3094 1918051 : isolate->CountUsage(v8::Isolate::UseCounterFeature(feature));
3095 : }
3096 : }
3097 2428161 : if (scanner_.FoundHtmlComment()) {
3098 10 : isolate->CountUsage(v8::Isolate::kHtmlComment);
3099 20 : if (script->line_offset() == 0 && script->column_offset() == 0) {
3100 10 : isolate->CountUsage(v8::Isolate::kHtmlCommentInExternalScript);
3101 : }
3102 : }
3103 : isolate->counters()->total_preparse_skipped()->Increment(
3104 4856322 : total_preparse_skipped_);
3105 2428161 : }
3106 :
3107 26315 : void Parser::ParseOnBackground(ParseInfo* info) {
3108 : RuntimeCallTimerScope runtimeTimer(
3109 13122 : runtime_call_stats_, RuntimeCallCounterId::kParseBackgroundProgram);
3110 13122 : parsing_on_main_thread_ = false;
3111 : set_script_id(info->script_id());
3112 :
3113 : DCHECK_NULL(info->literal());
3114 : FunctionLiteral* result = nullptr;
3115 :
3116 13122 : scanner_.Initialize();
3117 : DCHECK(info->maybe_outer_scope_info().is_null());
3118 :
3119 : DCHECK(original_scope_);
3120 :
3121 : // When streaming, we don't know the length of the source until we have parsed
3122 : // it. The raw data can be UTF-8, so we wouldn't know the source length until
3123 : // we have decoded it anyway even if we knew the raw data length (which we
3124 : // don't). We work around this by storing all the scopes which need their end
3125 : // position set at the end of the script (the top scope and possible eval
3126 : // scopes) and set their end position after we know the script length.
3127 13122 : if (info->is_toplevel()) {
3128 13051 : result = DoParseProgram(/* isolate = */ nullptr, info);
3129 : } else {
3130 : result =
3131 71 : DoParseFunction(/* isolate = */ nullptr, info, info->function_name());
3132 : }
3133 13122 : MaybeResetCharacterStream(info, result);
3134 :
3135 : info->set_literal(result);
3136 :
3137 : // We cannot internalize on a background thread; a foreground task will take
3138 : // care of calling AstValueFactory::Internalize just before compilation.
3139 13122 : }
3140 :
3141 38639 : Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
3142 77277 : return new (zone()) TemplateLiteral(zone(), pos);
3143 : }
3144 :
3145 83836 : void Parser::AddTemplateSpan(TemplateLiteralState* state, bool should_cook,
3146 : bool tail) {
3147 247785 : int end = scanner()->location().end_pos - (tail ? 1 : 2);
3148 83836 : const AstRawString* raw = scanner()->CurrentRawSymbol(ast_value_factory());
3149 83839 : if (should_cook) {
3150 80108 : const AstRawString* cooked = scanner()->CurrentSymbol(ast_value_factory());
3151 80110 : (*state)->AddTemplateSpan(cooked, raw, end, zone());
3152 : } else {
3153 3731 : (*state)->AddTemplateSpan(nullptr, raw, end, zone());
3154 : }
3155 83840 : }
3156 :
3157 :
3158 0 : void Parser::AddTemplateExpression(TemplateLiteralState* state,
3159 : Expression* expression) {
3160 48298 : (*state)->AddExpression(expression, zone());
3161 0 : }
3162 :
3163 :
3164 35541 : Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
3165 : Expression* tag) {
3166 35541 : TemplateLiteral* lit = *state;
3167 : int pos = lit->position();
3168 63768 : const ZonePtrList<const AstRawString>* cooked_strings = lit->cooked();
3169 35541 : const ZonePtrList<const AstRawString>* raw_strings = lit->raw();
3170 35541 : const ZonePtrList<Expression>* expressions = lit->expressions();
3171 : DCHECK_EQ(cooked_strings->length(), raw_strings->length());
3172 : DCHECK_EQ(cooked_strings->length(), expressions->length() + 1);
3173 :
3174 35541 : if (!tag) {
3175 28227 : if (cooked_strings->length() == 1) {
3176 14221 : return factory()->NewStringLiteral(cooked_strings->first(), pos);
3177 : }
3178 42234 : return factory()->NewTemplateLiteral(cooked_strings, expressions, pos);
3179 : } else {
3180 : // GetTemplateObject
3181 : Expression* template_object =
3182 7314 : factory()->NewGetTemplateObject(cooked_strings, raw_strings, pos);
3183 :
3184 : // Call TagFn
3185 7314 : ScopedPtrList<Expression> call_args(pointer_buffer());
3186 : call_args.Add(template_object);
3187 7314 : call_args.AddAll(*expressions);
3188 7314 : return factory()->NewTaggedTemplate(tag, call_args, pos);
3189 : }
3190 : }
3191 :
3192 : namespace {
3193 :
3194 15440 : bool OnlyLastArgIsSpread(const ScopedPtrList<Expression>& args) {
3195 10960 : for (int i = 0; i < args.length() - 1; i++) {
3196 1746 : if (args.at(i)->IsSpread()) {
3197 : return false;
3198 : }
3199 : }
3200 3734 : return args.at(args.length() - 1)->IsSpread();
3201 : }
3202 :
3203 : } // namespace
3204 :
3205 718 : ArrayLiteral* Parser::ArrayLiteralFromListWithSpread(
3206 2163 : const ScopedPtrList<Expression>& list) {
3207 : // If there's only a single spread argument, a fast path using CallWithSpread
3208 : // is taken.
3209 : DCHECK_LT(1, list.length());
3210 :
3211 : // The arguments of the spread call become a single ArrayLiteral.
3212 : int first_spread = 0;
3213 2881 : for (; first_spread < list.length() && !list.at(first_spread)->IsSpread();
3214 : ++first_spread) {
3215 : }
3216 :
3217 : DCHECK_LT(first_spread, list.length());
3218 718 : return factory()->NewArrayLiteral(list, first_spread, kNoSourcePosition);
3219 : }
3220 :
3221 4254 : Expression* Parser::SpreadCall(Expression* function,
3222 : const ScopedPtrList<Expression>& args_list,
3223 : int pos, Call::PossiblyEval is_possibly_eval) {
3224 : // Handle this case in BytecodeGenerator.
3225 4996 : if (OnlyLastArgIsSpread(args_list) || function->IsSuperCallReference()) {
3226 3801 : return factory()->NewCall(function, args_list, pos);
3227 : }
3228 :
3229 711 : ScopedPtrList<Expression> args(pointer_buffer());
3230 711 : if (function->IsProperty()) {
3231 : // Method calls
3232 516 : if (function->AsProperty()->IsSuperAccess()) {
3233 : Expression* home = ThisExpression(kNoSourcePosition);
3234 0 : args.Add(function);
3235 0 : args.Add(home);
3236 : } else {
3237 258 : Variable* temp = NewTemporary(ast_value_factory()->empty_string());
3238 259 : VariableProxy* obj = factory()->NewVariableProxy(temp);
3239 : Assignment* assign_obj = factory()->NewAssignment(
3240 258 : Token::ASSIGN, obj, function->AsProperty()->obj(), kNoSourcePosition);
3241 : function = factory()->NewProperty(
3242 260 : assign_obj, function->AsProperty()->key(), kNoSourcePosition);
3243 260 : args.Add(function);
3244 260 : obj = factory()->NewVariableProxy(temp);
3245 259 : args.Add(obj);
3246 : }
3247 : } else {
3248 : // Non-method calls
3249 : args.Add(function);
3250 906 : args.Add(factory()->NewUndefinedLiteral(kNoSourcePosition));
3251 : }
3252 712 : args.Add(ArrayLiteralFromListWithSpread(args_list));
3253 712 : return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos);
3254 : }
3255 :
3256 226 : Expression* Parser::SpreadCallNew(Expression* function,
3257 : const ScopedPtrList<Expression>& args_list,
3258 : int pos) {
3259 226 : if (OnlyLastArgIsSpread(args_list)) {
3260 : // Handle in BytecodeGenerator.
3261 221 : return factory()->NewCallNew(function, args_list, pos);
3262 : }
3263 5 : ScopedPtrList<Expression> args(pointer_buffer());
3264 : args.Add(function);
3265 5 : args.Add(ArrayLiteralFromListWithSpread(args_list));
3266 :
3267 5 : return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos);
3268 : }
3269 :
3270 :
3271 5608058 : void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) {
3272 : v8::Isolate::UseCounterFeature feature;
3273 5608058 : if (is_sloppy(mode))
3274 : feature = v8::Isolate::kSloppyMode;
3275 1495880 : else if (is_strict(mode))
3276 : feature = v8::Isolate::kStrictMode;
3277 : else
3278 0 : UNREACHABLE();
3279 5608058 : ++use_counts_[feature];
3280 : scope->SetLanguageMode(mode);
3281 5608058 : }
3282 :
3283 4830 : void Parser::SetAsmModule() {
3284 : // Store the usage count; The actual use counter on the isolate is
3285 : // incremented after parsing is done.
3286 4830 : ++use_counts_[v8::Isolate::kUseAsm];
3287 : DCHECK(scope()->is_declaration_scope());
3288 4830 : scope()->AsDeclarationScope()->set_is_asm_module();
3289 4828 : info_->set_contains_asm_module(true);
3290 4828 : }
3291 :
3292 62408 : Expression* Parser::ExpressionListToExpression(
3293 5376650 : const ScopedPtrList<Expression>& args) {
3294 : Expression* expr = args.at(0);
3295 62408 : if (args.length() == 1) return expr;
3296 59382 : if (args.length() == 2) {
3297 : return factory()->NewBinaryOperation(Token::COMMA, expr, args.at(1),
3298 106800 : args.at(1)->position());
3299 : }
3300 : NaryOperation* result =
3301 5982 : factory()->NewNaryOperation(Token::COMMA, expr, args.length() - 1);
3302 5257816 : for (int i = 1; i < args.length(); i++) {
3303 2622926 : result->AddSubsequent(args.at(i), args.at(i)->position());
3304 : }
3305 : return result;
3306 : }
3307 :
3308 : // This method completes the desugaring of the body of async_function.
3309 84388 : void Parser::RewriteAsyncFunctionBody(ScopedPtrList<Statement>* body,
3310 : Block* block, Expression* return_value) {
3311 : // function async_function() {
3312 : // .generator_object = %_AsyncFunctionEnter();
3313 : // BuildRejectPromiseOnException({
3314 : // ... block ...
3315 : // return %_AsyncFunctionResolve(.generator_object, expr);
3316 : // })
3317 : // }
3318 :
3319 : block->statements()->Add(factory()->NewAsyncReturnStatement(
3320 42193 : return_value, return_value->position()),
3321 84387 : zone());
3322 42194 : block = BuildRejectPromiseOnException(block);
3323 : body->Add(block);
3324 42194 : }
3325 :
3326 6827713 : void Parser::SetFunctionNameFromPropertyName(LiteralProperty* property,
3327 : const AstRawString* name,
3328 : const AstRawString* prefix) {
3329 6871568 : if (has_error()) return;
3330 : // Ensure that the function we are going to create has shared name iff
3331 : // we are not going to set it later.
3332 3391966 : if (property->NeedsSetFunctionName()) {
3333 : name = nullptr;
3334 : prefix = nullptr;
3335 : } else {
3336 : // If the property value is an anonymous function or an anonymous class or
3337 : // a concise method or an accessor function which doesn't require the name
3338 : // to be set then the shared name must be provided.
3339 : DCHECK_IMPLIES(property->value()->IsAnonymousFunctionDefinition() ||
3340 : property->value()->IsConciseMethodDefinition() ||
3341 : property->value()->IsAccessorFunctionDefinition(),
3342 : name != nullptr);
3343 : }
3344 :
3345 : Expression* value = property->value();
3346 3391943 : SetFunctionName(value, name, prefix);
3347 : }
3348 :
3349 3027333 : void Parser::SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
3350 : const AstRawString* name,
3351 : const AstRawString* prefix) {
3352 : // Ignore "__proto__" as a name when it's being used to set the [[Prototype]]
3353 : // of an object literal.
3354 : // See ES #sec-__proto__-property-names-in-object-initializers.
3355 9075471 : if (property->IsPrototype() || has_error()) return;
3356 :
3357 : DCHECK(!property->value()->IsAnonymousFunctionDefinition() ||
3358 : property->kind() == ObjectLiteralProperty::COMPUTED);
3359 :
3360 : SetFunctionNameFromPropertyName(static_cast<LiteralProperty*>(property), name,
3361 2998134 : prefix);
3362 : }
3363 :
3364 12639615 : void Parser::SetFunctionNameFromIdentifierRef(Expression* value,
3365 : Expression* identifier) {
3366 25279393 : if (!identifier->IsVariableProxy()) return;
3367 17118180 : SetFunctionName(value, identifier->AsVariableProxy()->raw_name());
3368 : }
3369 :
3370 11951233 : void Parser::SetFunctionName(Expression* value, const AstRawString* name,
3371 : const AstRawString* prefix) {
3372 35494100 : if (!value->IsAnonymousFunctionDefinition() &&
3373 23190129 : !value->IsConciseMethodDefinition() &&
3374 11238827 : !value->IsAccessorFunctionDefinition()) {
3375 11951303 : return;
3376 : }
3377 743294 : auto function = value->AsFunctionLiteral();
3378 743299 : if (value->IsClassLiteral()) {
3379 2387 : function = value->AsClassLiteral()->constructor();
3380 : }
3381 743299 : if (function != nullptr) {
3382 : AstConsString* cons_name = nullptr;
3383 743287 : if (name != nullptr) {
3384 733077 : if (prefix != nullptr) {
3385 27168 : cons_name = ast_value_factory()->NewConsString(prefix, name);
3386 : } else {
3387 705909 : cons_name = ast_value_factory()->NewConsString(name);
3388 : }
3389 : } else {
3390 : DCHECK_NULL(prefix);
3391 : }
3392 : function->set_raw_name(cons_name);
3393 : }
3394 : }
3395 :
3396 0 : Statement* Parser::CheckCallable(Variable* var, Expression* error, int pos) {
3397 : const int nopos = kNoSourcePosition;
3398 : Statement* validate_var;
3399 : {
3400 : Expression* type_of = factory()->NewUnaryOperation(
3401 0 : Token::TYPEOF, factory()->NewVariableProxy(var), nopos);
3402 : Expression* function_literal = factory()->NewStringLiteral(
3403 0 : ast_value_factory()->function_string(), nopos);
3404 : Expression* condition = factory()->NewCompareOperation(
3405 0 : Token::EQ_STRICT, type_of, function_literal, nopos);
3406 :
3407 0 : Statement* throw_call = factory()->NewExpressionStatement(error, pos);
3408 :
3409 : validate_var = factory()->NewIfStatement(
3410 0 : condition, factory()->EmptyStatement(), throw_call, nopos);
3411 : }
3412 0 : return validate_var;
3413 : }
3414 :
3415 : } // namespace internal
3416 183867 : } // namespace v8
|