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/ieee754.h"
16 : #include "src/base/overflowing-math.h"
17 : #include "src/base/platform/platform.h"
18 : #include "src/char-predicates-inl.h"
19 : #include "src/compiler-dispatcher/compiler-dispatcher.h"
20 : #include "src/conversions-inl.h"
21 : #include "src/log.h"
22 : #include "src/message-template.h"
23 : #include "src/objects/scope-info.h"
24 : #include "src/parsing/expression-scope-reparenter.h"
25 : #include "src/parsing/parse-info.h"
26 : #include "src/parsing/rewriter.h"
27 : #include "src/runtime/runtime.h"
28 : #include "src/string-stream.h"
29 : #include "src/tracing/trace-event.h"
30 : #include "src/zone/zone-list-inl.h"
31 :
32 : namespace v8 {
33 : namespace internal {
34 :
35 97796 : FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name,
36 : bool call_super, int pos,
37 : int end_pos) {
38 : int expected_property_count = 0;
39 : const int parameter_count = 0;
40 :
41 : FunctionKind kind = call_super ? FunctionKind::kDefaultDerivedConstructor
42 97796 : : FunctionKind::kDefaultBaseConstructor;
43 97796 : DeclarationScope* function_scope = NewFunctionScope(kind);
44 : SetLanguageMode(function_scope, LanguageMode::kStrict);
45 : // Set start and end position to the same value
46 : function_scope->set_start_position(pos);
47 : function_scope->set_end_position(pos);
48 : ScopedPtrList<Statement> body(pointer_buffer());
49 :
50 : {
51 97796 : FunctionState function_state(&function_state_, &scope_, function_scope);
52 :
53 97796 : if (call_super) {
54 : // Create a SuperCallReference and handle in BytecodeGenerator.
55 : auto constructor_args_name = ast_value_factory()->empty_string();
56 : bool is_rest = true;
57 : bool is_optional = false;
58 : Variable* constructor_args = function_scope->DeclareParameter(
59 : constructor_args_name, VariableMode::kTemporary, is_optional, is_rest,
60 25353 : ast_value_factory(), pos);
61 :
62 : Expression* call;
63 : {
64 : ScopedPtrList<Expression> args(pointer_buffer());
65 : Spread* spread_args = factory()->NewSpread(
66 : factory()->NewVariableProxy(constructor_args), pos, pos);
67 :
68 : args.Add(spread_args);
69 25353 : Expression* super_call_ref = NewSuperCallReference(pos);
70 25353 : call = factory()->NewCall(super_call_ref, args, pos);
71 : }
72 : body.Add(factory()->NewReturnStatement(call, pos));
73 : }
74 :
75 : expected_property_count = function_state.expected_property_count();
76 : }
77 :
78 97796 : FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
79 : name, function_scope, body, expected_property_count, parameter_count,
80 : parameter_count, FunctionLiteral::kNoDuplicateParameters,
81 : FunctionLiteral::kAnonymousExpression, default_eager_compile_hint(), pos,
82 97796 : true, GetNextFunctionLiteralId());
83 97796 : return function_literal;
84 : }
85 :
86 1906590 : void Parser::ReportUnexpectedTokenAt(Scanner::Location location,
87 : Token::Value token,
88 : MessageTemplate message) {
89 : const char* arg = nullptr;
90 1906590 : switch (token) {
91 : case Token::EOS:
92 : message = MessageTemplate::kUnexpectedEOS;
93 : break;
94 : case Token::SMI:
95 : case Token::NUMBER:
96 : case Token::BIGINT:
97 : message = MessageTemplate::kUnexpectedTokenNumber;
98 426 : break;
99 : case Token::STRING:
100 : message = MessageTemplate::kUnexpectedTokenString;
101 348 : break;
102 : case Token::PRIVATE_NAME:
103 : case Token::IDENTIFIER:
104 : message = MessageTemplate::kUnexpectedTokenIdentifier;
105 9661 : break;
106 : case Token::AWAIT:
107 : case Token::ENUM:
108 : message = MessageTemplate::kUnexpectedReserved;
109 3400 : break;
110 : case Token::LET:
111 : case Token::STATIC:
112 : case Token::YIELD:
113 : case Token::FUTURE_STRICT_RESERVED_WORD:
114 : message = is_strict(language_mode())
115 : ? MessageTemplate::kUnexpectedStrictReserved
116 16207 : : MessageTemplate::kUnexpectedTokenIdentifier;
117 : break;
118 : case Token::TEMPLATE_SPAN:
119 : case Token::TEMPLATE_TAIL:
120 : message = MessageTemplate::kUnexpectedTemplateString;
121 200 : break;
122 : case Token::ESCAPED_STRICT_RESERVED_WORD:
123 : case Token::ESCAPED_KEYWORD:
124 : message = MessageTemplate::kInvalidEscapedReservedWord;
125 4580 : break;
126 : case Token::ILLEGAL:
127 1788319 : if (scanner()->has_error()) {
128 : message = scanner()->error();
129 236515 : location = scanner()->error_location();
130 : } else {
131 : message = MessageTemplate::kInvalidOrUnexpectedToken;
132 : }
133 : break;
134 : case Token::REGEXP_LITERAL:
135 : message = MessageTemplate::kUnexpectedTokenRegExp;
136 0 : break;
137 : default:
138 : const char* name = Token::String(token);
139 : DCHECK_NOT_NULL(name);
140 : arg = name;
141 78890 : break;
142 : }
143 1906590 : ReportMessageAt(location, message, arg);
144 1906590 : }
145 :
146 : // ----------------------------------------------------------------------------
147 : // Implementation of Parser
148 :
149 1725202 : bool Parser::ShortcutNumericLiteralBinaryExpression(Expression** x,
150 : Expression* y,
151 : Token::Value op, int pos) {
152 1725202 : if ((*x)->IsNumberLiteral() && y->IsNumberLiteral()) {
153 1267716 : double x_val = (*x)->AsLiteral()->AsNumber();
154 1267720 : double y_val = y->AsLiteral()->AsNumber();
155 633860 : switch (op) {
156 : case Token::ADD:
157 31314 : *x = factory()->NewNumberLiteral(x_val + y_val, pos);
158 15657 : return true;
159 : case Token::SUB:
160 3394 : *x = factory()->NewNumberLiteral(x_val - y_val, pos);
161 1697 : return true;
162 : case Token::MUL:
163 429430 : *x = factory()->NewNumberLiteral(x_val * y_val, pos);
164 214715 : return true;
165 : case Token::DIV:
166 6468 : *x = factory()->NewNumberLiteral(base::Divide(x_val, y_val), pos);
167 3234 : return true;
168 : case Token::BIT_OR: {
169 10517 : int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
170 21034 : *x = factory()->NewNumberLiteral(value, pos);
171 10517 : return true;
172 : }
173 : case Token::BIT_AND: {
174 369 : int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
175 738 : *x = factory()->NewNumberLiteral(value, pos);
176 369 : return true;
177 : }
178 : case Token::BIT_XOR: {
179 201 : int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
180 402 : *x = factory()->NewNumberLiteral(value, pos);
181 201 : return true;
182 : }
183 : case Token::SHL: {
184 : int value =
185 384944 : base::ShlWithWraparound(DoubleToInt32(x_val), DoubleToInt32(y_val));
186 769872 : *x = factory()->NewNumberLiteral(value, pos);
187 384936 : return true;
188 : }
189 : case Token::SHR: {
190 416 : uint32_t shift = DoubleToInt32(y_val) & 0x1F;
191 416 : uint32_t value = DoubleToUint32(x_val) >> shift;
192 832 : *x = factory()->NewNumberLiteral(value, pos);
193 416 : return true;
194 : }
195 : case Token::SAR: {
196 372 : uint32_t shift = DoubleToInt32(y_val) & 0x1F;
197 372 : int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
198 744 : *x = factory()->NewNumberLiteral(value, pos);
199 372 : return true;
200 : }
201 : case Token::EXP:
202 2516 : *x = factory()->NewNumberLiteral(base::ieee754::pow(x_val, y_val), pos);
203 1258 : return true;
204 : default:
205 : break;
206 : }
207 : }
208 : return false;
209 : }
210 :
211 1091814 : bool Parser::CollapseNaryExpression(Expression** x, Expression* y,
212 : Token::Value op, int pos,
213 : const SourceRange& range) {
214 : // Filter out unsupported ops.
215 1091814 : 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 : NaryOperation* nary = nullptr;
220 2179042 : if ((*x)->IsBinaryOperation()) {
221 199257 : BinaryOperation* binop = (*x)->AsBinaryOperation();
222 199257 : if (binop->op() != op) return false;
223 :
224 257230 : nary = factory()->NewNaryOperation(op, binop->left(), 2);
225 : nary->AddSubsequent(binop->right(), binop->position());
226 : ConvertBinaryToNaryOperationSourceRange(binop, nary);
227 128612 : *x = nary;
228 890264 : } else if ((*x)->IsNaryOperation()) {
229 219140 : nary = (*x)->AsNaryOperation();
230 219140 : 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 688280 : Expression* Parser::BuildUnaryExpression(Expression* expression,
246 : Token::Value op, int pos) {
247 : DCHECK_NOT_NULL(expression);
248 688280 : const Literal* literal = expression->AsLiteral();
249 688280 : if (literal != nullptr) {
250 367525 : if (op == Token::NOT) {
251 : // Convert the literal to a boolean condition and negate it.
252 275 : return factory()->NewBooleanLiteral(literal->ToBooleanIsFalse(), pos);
253 367250 : } else if (literal->IsNumberLiteral()) {
254 : // Compute some expressions involving only number literals.
255 362834 : double value = literal->AsNumber();
256 362834 : switch (op) {
257 : case Token::ADD:
258 : return expression;
259 : case Token::SUB:
260 708322 : return factory()->NewNumberLiteral(-value, pos);
261 : case Token::BIT_NOT:
262 3060 : return factory()->NewNumberLiteral(~DoubleToInt32(value), pos);
263 : default:
264 : break;
265 : }
266 : }
267 : }
268 330932 : return factory()->NewUnaryOperation(op, expression, pos);
269 : }
270 :
271 1234 : Expression* Parser::NewThrowError(Runtime::FunctionId id,
272 : MessageTemplate message,
273 : const AstRawString* arg, int pos) {
274 : ScopedPtrList<Expression> args(pointer_buffer());
275 : args.Add(factory()->NewSmiLiteral(static_cast<int>(message), pos));
276 : args.Add(factory()->NewStringLiteral(arg, pos));
277 1234 : CallRuntime* call_constructor = factory()->NewCallRuntime(id, args, pos);
278 1234 : return factory()->NewThrow(call_constructor, pos);
279 : }
280 :
281 2777 : Expression* Parser::NewSuperPropertyReference(int pos) {
282 : // this_function[home_object_symbol]
283 : VariableProxy* this_function_proxy =
284 : NewUnresolved(ast_value_factory()->this_function_string(), pos);
285 : Expression* home_object_symbol_literal = factory()->NewSymbolLiteral(
286 : AstSymbol::kHomeObjectSymbol, kNoSourcePosition);
287 : Expression* home_object = factory()->NewProperty(
288 : this_function_proxy, home_object_symbol_literal, pos);
289 2777 : return factory()->NewSuperPropertyReference(home_object, pos);
290 : }
291 :
292 28118 : Expression* Parser::NewSuperCallReference(int pos) {
293 : VariableProxy* new_target_proxy =
294 : NewUnresolved(ast_value_factory()->new_target_string(), pos);
295 : VariableProxy* this_function_proxy =
296 : NewUnresolved(ast_value_factory()->this_function_string(), pos);
297 : return factory()->NewSuperCallReference(new_target_proxy, this_function_proxy,
298 28118 : pos);
299 : }
300 :
301 2113 : Expression* Parser::NewTargetExpression(int pos) {
302 : auto proxy = NewUnresolved(ast_value_factory()->new_target_string(), pos);
303 : proxy->set_is_new_target();
304 2113 : return proxy;
305 : }
306 :
307 3210 : Expression* Parser::ImportMetaExpression(int pos) {
308 : ScopedPtrList<Expression> args(pointer_buffer());
309 : return factory()->NewCallRuntime(Runtime::kInlineGetImportMetaObject, args,
310 6420 : pos);
311 : }
312 :
313 25022162 : Expression* Parser::ExpressionFromLiteral(Token::Value token, int pos) {
314 25022162 : switch (token) {
315 : case Token::NULL_LITERAL:
316 77891 : return factory()->NewNullLiteral(pos);
317 : case Token::TRUE_LITERAL:
318 164111 : return factory()->NewBooleanLiteral(true, pos);
319 : case Token::FALSE_LITERAL:
320 248491 : return factory()->NewBooleanLiteral(false, pos);
321 : case Token::SMI: {
322 : uint32_t value = scanner()->smi_value();
323 37567115 : return factory()->NewSmiLiteral(value, pos);
324 : }
325 : case Token::NUMBER: {
326 1305535 : double value = scanner()->DoubleValue();
327 1305539 : return factory()->NewNumberLiteral(value, pos);
328 : }
329 : case Token::BIGINT:
330 12294 : return factory()->NewBigIntLiteral(
331 : AstBigInt(scanner()->CurrentLiteralAsCString(zone())), pos);
332 : case Token::STRING: {
333 4430245 : return factory()->NewStringLiteral(GetSymbol(), pos);
334 : }
335 : default:
336 : DCHECK(false);
337 : }
338 0 : return FailureExpression();
339 : }
340 :
341 66541 : Expression* Parser::NewV8Intrinsic(const AstRawString* name,
342 : const ScopedPtrList<Expression>& args,
343 : int pos) {
344 66541 : if (extension_ != nullptr) {
345 : // The extension structures are only accessible while parsing the
346 : // very first time, not when reparsing because of lazy compilation.
347 : GetClosureScope()->ForceEagerCompilation();
348 : }
349 :
350 66541 : if (!name->is_one_byte()) {
351 : // There are no two-byte named intrinsics.
352 9 : ReportMessage(MessageTemplate::kNotDefined, name);
353 9 : return FailureExpression();
354 : }
355 :
356 : const Runtime::Function* function =
357 66532 : Runtime::FunctionForName(name->raw_data(), name->length());
358 :
359 66536 : if (function != nullptr) {
360 : // Check for possible name clash.
361 : DCHECK_EQ(Context::kNotFound,
362 : Context::IntrinsicIndexForName(name->raw_data(), name->length()));
363 :
364 : // Check that the expected number of arguments are being passed.
365 106007 : if (function->nargs != -1 && function->nargs != args.length()) {
366 9 : ReportMessage(MessageTemplate::kRuntimeWrongNumArgs);
367 9 : return FailureExpression();
368 : }
369 :
370 66482 : return factory()->NewCallRuntime(function, args, pos);
371 : }
372 :
373 : int context_index =
374 45 : Context::IntrinsicIndexForName(name->raw_data(), name->length());
375 :
376 : // Check that the function is defined.
377 45 : if (context_index == Context::kNotFound) {
378 45 : ReportMessage(MessageTemplate::kNotDefined, name);
379 45 : return FailureExpression();
380 : }
381 :
382 0 : return factory()->NewCallRuntime(context_index, args, pos);
383 : }
384 :
385 2465833 : Parser::Parser(ParseInfo* info)
386 : : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(),
387 : info->extension(), info->GetOrCreateAstValueFactory(),
388 : info->pending_error_handler(),
389 : info->runtime_call_stats(), info->logger(),
390 : info->script().is_null() ? -1 : info->script()->id(),
391 : info->is_module(), true),
392 : info_(info),
393 : scanner_(info->character_stream(), info->is_module()),
394 : preparser_zone_(info->zone()->allocator(), ZONE_NAME),
395 : reusable_preparser_(nullptr),
396 : mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
397 : source_range_map_(info->source_range_map()),
398 : target_stack_(nullptr),
399 : total_preparse_skipped_(0),
400 : consumed_preparse_data_(info->consumed_preparse_data()),
401 : preparse_data_buffer_(),
402 19726643 : parameters_end_pos_(info->parameters_end_pos()) {
403 : // Even though we were passed ParseInfo, we should not store it in
404 : // Parser - this makes sure that Isolate is not accidentally accessed via
405 : // ParseInfo during background parsing.
406 : DCHECK_NOT_NULL(info->character_stream());
407 : // Determine if functions can be lazily compiled. This is necessary to
408 : // allow some of our builtin JS files to be lazily compiled. These
409 : // builtins cannot be handled lazily by the parser, since we have to know
410 : // if a function uses the special natives syntax, which is something the
411 : // parser records.
412 : // If the debugger requests compilation for break points, we cannot be
413 : // aggressive about lazy compilation, because it might trigger compilation
414 : // of functions without an outer context when setting a breakpoint through
415 : // Debug::FindSharedFunctionInfoInScript
416 : // We also compile eagerly for kProduceExhaustiveCodeCache.
417 4931295 : bool can_compile_lazily = info->allow_lazy_compile() && !info->is_eager();
418 :
419 2465817 : set_default_eager_compile_hint(can_compile_lazily
420 : ? FunctionLiteral::kShouldLazyCompile
421 : : FunctionLiteral::kShouldEagerCompile);
422 2465476 : allow_lazy_ = info->allow_lazy_compile() && info->allow_lazy_parsing() &&
423 4646849 : info->extension() == nullptr && can_compile_lazily;
424 : set_allow_natives(info->allow_natives_syntax());
425 : set_allow_harmony_public_fields(info->allow_harmony_public_fields());
426 : set_allow_harmony_static_fields(info->allow_harmony_static_fields());
427 : set_allow_harmony_dynamic_import(info->allow_harmony_dynamic_import());
428 : set_allow_harmony_import_meta(info->allow_harmony_import_meta());
429 : set_allow_harmony_numeric_separator(info->allow_harmony_numeric_separator());
430 : set_allow_harmony_private_fields(info->allow_harmony_private_fields());
431 : set_allow_harmony_private_methods(info->allow_harmony_private_methods());
432 377268329 : for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
433 : ++feature) {
434 187401256 : use_counts_[feature] = 0;
435 : }
436 2465817 : }
437 :
438 13468 : void Parser::InitializeEmptyScopeChain(ParseInfo* info) {
439 : DCHECK_NULL(original_scope_);
440 : DCHECK_NULL(info->script_scope());
441 2465826 : DeclarationScope* script_scope = NewScriptScope();
442 : info->set_script_scope(script_scope);
443 2465831 : original_scope_ = script_scope;
444 13468 : }
445 :
446 2452358 : void Parser::DeserializeScopeChain(
447 : Isolate* isolate, ParseInfo* info,
448 : MaybeHandle<ScopeInfo> maybe_outer_scope_info,
449 : Scope::DeserializationMode mode) {
450 : InitializeEmptyScopeChain(info);
451 : Handle<ScopeInfo> outer_scope_info;
452 2452363 : if (maybe_outer_scope_info.ToHandle(&outer_scope_info)) {
453 : DCHECK_EQ(ThreadId::Current(), isolate->thread_id());
454 1021713 : original_scope_ = Scope::DeserializeScopeChain(
455 : isolate, zone(), *outer_scope_info, info->script_scope(),
456 1021711 : ast_value_factory(), mode);
457 1419863 : if (info->is_eval() || IsArrowFunction(info->function_kind())) {
458 785315 : original_scope_->GetReceiverScope()->DeserializeReceiver(
459 785314 : ast_value_factory());
460 : }
461 : }
462 2452356 : }
463 :
464 : namespace {
465 :
466 2465810 : void MaybeResetCharacterStream(ParseInfo* info, FunctionLiteral* literal) {
467 : // Don't reset the character stream if there is an asm.js module since it will
468 : // be used again by the asm-parser.
469 2465810 : if (info->contains_asm_module()) {
470 4247 : if (FLAG_stress_validate_asm) return;
471 4247 : if (literal != nullptr && literal->scope()->ContainsAsmModule()) return;
472 : }
473 2461585 : info->ResetCharacterStream();
474 : }
475 :
476 2452365 : void MaybeProcessSourceRanges(ParseInfo* parse_info, Expression* root,
477 : uintptr_t stack_limit_) {
478 2452365 : if (root != nullptr && parse_info->source_range_map() != nullptr) {
479 : SourceRangeAstVisitor visitor(stack_limit_, root,
480 676 : parse_info->source_range_map());
481 : visitor.Run();
482 : }
483 2452365 : }
484 :
485 : } // namespace
486 :
487 1732527 : FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
488 : // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
489 : // see comment for HistogramTimerScope class.
490 :
491 : // It's OK to use the Isolate & counters here, since this function is only
492 : // called in the main thread.
493 : DCHECK(parsing_on_main_thread_);
494 : RuntimeCallTimerScope runtime_timer(
495 : runtime_call_stats_, info->is_eval()
496 : ? RuntimeCallCounterId::kParseEval
497 1732527 : : RuntimeCallCounterId::kParseProgram);
498 5197577 : TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram");
499 : base::ElapsedTimer timer;
500 1732525 : if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
501 :
502 : // Initialize parser state.
503 : DeserializeScopeChain(isolate, info, info->maybe_outer_scope_info(),
504 1732525 : Scope::DeserializationMode::kIncludingVariables);
505 :
506 1732529 : scanner_.Initialize();
507 1732529 : if (FLAG_harmony_hashbang) {
508 1722810 : scanner_.SkipHashBang();
509 : }
510 1732530 : FunctionLiteral* result = DoParseProgram(isolate, info);
511 1732532 : MaybeResetCharacterStream(info, result);
512 1732538 : MaybeProcessSourceRanges(info, result, stack_limit_);
513 :
514 1732533 : HandleSourceURLComments(isolate, info->script());
515 :
516 1732526 : if (V8_UNLIKELY(FLAG_log_function_events) && result != nullptr) {
517 11 : double ms = timer.Elapsed().InMillisecondsF();
518 : const char* event_name = "parse-eval";
519 : Script script = *info->script();
520 : int start = -1;
521 : int end = -1;
522 11 : if (!info->is_eval()) {
523 : event_name = "parse-script";
524 : start = 0;
525 : end = String::cast(script->source())->length();
526 : }
527 22 : LOG(isolate,
528 : FunctionEvent(event_name, script->id(), ms, start, end, "", 0));
529 : }
530 1732526 : return result;
531 : }
532 :
533 1745923 : FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
534 : // Note that this function can be called from the main thread or from a
535 : // background thread. We should not access anything Isolate / heap dependent
536 : // via ParseInfo, and also not pass it forward. If not on the main thread
537 : // isolate will be nullptr.
538 : DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr);
539 : DCHECK_NULL(scope_);
540 : DCHECK_NULL(target_stack_);
541 :
542 1745923 : ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
543 : ResetFunctionLiteralId();
544 : DCHECK(info->function_literal_id() == kFunctionLiteralIdTopLevel ||
545 : info->function_literal_id() == kFunctionLiteralIdInvalid);
546 :
547 : FunctionLiteral* result = nullptr;
548 : {
549 1745923 : Scope* outer = original_scope_;
550 : DCHECK_NOT_NULL(outer);
551 1745923 : if (info->is_eval()) {
552 969870 : outer = NewEvalScope(outer);
553 776053 : } else if (parsing_module_) {
554 : DCHECK_EQ(outer, info->script_scope());
555 40825 : outer = NewModuleScope(info->script_scope());
556 : }
557 :
558 1745923 : DeclarationScope* scope = outer->AsDeclarationScope();
559 : scope->set_start_position(0);
560 :
561 1745958 : FunctionState function_state(&function_state_, &scope_, scope);
562 : ScopedPtrList<Statement> body(pointer_buffer());
563 1745958 : int beg_pos = scanner()->location().beg_pos;
564 1745958 : if (parsing_module_) {
565 : DCHECK(info->is_module());
566 : // Declare the special module parameter.
567 : auto name = ast_value_factory()->empty_string();
568 : bool is_rest = false;
569 : bool is_optional = false;
570 : VariableMode mode = VariableMode::kVar;
571 : bool was_added;
572 40825 : scope->DeclareLocal(name, mode, PARAMETER_VARIABLE, &was_added,
573 40825 : Variable::DefaultInitializationFlag(mode));
574 : DCHECK(was_added);
575 : auto var = scope->DeclareParameter(name, VariableMode::kVar, is_optional,
576 40825 : is_rest, ast_value_factory(), beg_pos);
577 : var->AllocateTo(VariableLocation::PARAMETER, 0);
578 :
579 40825 : PrepareGeneratorVariables();
580 : Expression* initial_yield =
581 40825 : BuildInitialYield(kNoSourcePosition, kGeneratorFunction);
582 : body.Add(
583 : factory()->NewExpressionStatement(initial_yield, kNoSourcePosition));
584 :
585 40825 : ParseModuleItemList(&body);
586 56197 : if (!has_error() &&
587 30744 : !module()->Validate(this->scope()->AsModuleScope(),
588 : pending_error_handler(), zone())) {
589 : scanner()->set_parser_error();
590 : }
591 1705133 : } else if (info->is_wrapped_as_function()) {
592 74 : ParseWrapped(isolate, info, &body, scope, zone());
593 : } else {
594 : // Don't count the mode in the use counters--give the program a chance
595 : // to enable script-wide strict mode below.
596 : this->scope()->SetLanguageMode(info->language_mode());
597 1705059 : ParseStatementList(&body, Token::EOS);
598 : }
599 :
600 : // The parser will peek but not consume EOS. Our scope logically goes all
601 : // the way to the EOS, though.
602 : scope->set_end_position(peek_position());
603 :
604 1745922 : if (is_strict(language_mode())) {
605 329451 : CheckStrictOctalLiteral(beg_pos, end_position());
606 : }
607 1745922 : if (is_sloppy(language_mode())) {
608 : // TODO(littledan): Function bindings on the global object that modify
609 : // pre-existing bindings should be made writable, enumerable and
610 : // nonconfigurable if possible, whereas this code will leave attributes
611 : // unchanged if the property already exists.
612 1416463 : InsertSloppyBlockFunctionVarBindings(scope);
613 : }
614 : // Internalize the ast strings in the case of eval so we can check for
615 : // conflicting var declarations with outer scope-info-backed scopes.
616 1745917 : if (info->is_eval()) {
617 : DCHECK(parsing_on_main_thread_);
618 969870 : info->ast_value_factory()->Internalize(isolate);
619 : }
620 1745917 : CheckConflictingVarDeclarations(scope);
621 :
622 1745904 : if (info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
623 1025035 : if (body.length() != 1 || !body.at(0)->IsExpressionStatement() ||
624 : !body.at(0)
625 : ->AsExpressionStatement()
626 341211 : ->expression()
627 : ->IsFunctionLiteral()) {
628 1411 : ReportMessage(MessageTemplate::kSingleFunctionLiteral);
629 : }
630 : }
631 :
632 1745894 : int parameter_count = parsing_module_ ? 1 : 0;
633 : result = factory()->NewScriptOrEvalFunctionLiteral(
634 1745894 : scope, body, function_state.expected_property_count(), parameter_count);
635 : result->set_suspend_count(function_state.suspend_count());
636 : }
637 :
638 : info->set_max_function_literal_id(GetLastFunctionLiteralId());
639 :
640 : // Make sure the target stack is empty.
641 : DCHECK_NULL(target_stack_);
642 :
643 1745924 : if (has_error()) return nullptr;
644 1358180 : return result;
645 : }
646 :
647 84 : ZonePtrList<const AstRawString>* Parser::PrepareWrappedArguments(
648 : Isolate* isolate, ParseInfo* info, Zone* zone) {
649 : DCHECK(parsing_on_main_thread_);
650 : DCHECK_NOT_NULL(isolate);
651 : Handle<FixedArray> arguments(info->script()->wrapped_arguments(), isolate);
652 : int arguments_length = arguments->length();
653 : ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
654 : new (zone) ZonePtrList<const AstRawString>(arguments_length, zone);
655 124 : for (int i = 0; i < arguments_length; i++) {
656 40 : const AstRawString* argument_string = ast_value_factory()->GetString(
657 20 : Handle<String>(String::cast(arguments->get(i)), isolate));
658 20 : arguments_for_wrapped_function->Add(argument_string, zone);
659 : }
660 84 : return arguments_for_wrapped_function;
661 : }
662 :
663 74 : void Parser::ParseWrapped(Isolate* isolate, ParseInfo* info,
664 : ScopedPtrList<Statement>* body,
665 : DeclarationScope* outer_scope, Zone* zone) {
666 : DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr);
667 : DCHECK(info->is_wrapped_as_function());
668 : ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
669 :
670 : // Set function and block state for the outer eval scope.
671 : DCHECK(outer_scope->is_eval_scope());
672 74 : FunctionState function_state(&function_state_, &scope_, outer_scope);
673 :
674 : const AstRawString* function_name = nullptr;
675 : Scanner::Location location(0, 0);
676 :
677 : ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
678 74 : PrepareWrappedArguments(isolate, info, zone);
679 :
680 : FunctionLiteral* function_literal = ParseFunctionLiteral(
681 : function_name, location, kSkipFunctionNameCheck, kNormalFunction,
682 : kNoSourcePosition, FunctionLiteral::kWrapped, LanguageMode::kSloppy,
683 74 : arguments_for_wrapped_function);
684 :
685 : Statement* return_statement = factory()->NewReturnStatement(
686 : function_literal, kNoSourcePosition, kNoSourcePosition);
687 : body->Add(return_statement);
688 74 : }
689 :
690 719831 : FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
691 : Handle<SharedFunctionInfo> shared_info) {
692 : // It's OK to use the Isolate & counters here, since this function is only
693 : // called in the main thread.
694 : DCHECK(parsing_on_main_thread_);
695 : RuntimeCallTimerScope runtime_timer(runtime_call_stats_,
696 719831 : RuntimeCallCounterId::kParseFunction);
697 2159502 : TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseFunction");
698 : base::ElapsedTimer timer;
699 719833 : if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
700 :
701 : DeserializeScopeChain(isolate, info, info->maybe_outer_scope_info(),
702 719833 : Scope::DeserializationMode::kIncludingVariables);
703 : DCHECK_EQ(factory()->zone(), info->zone());
704 :
705 : // Initialize parser state.
706 1439668 : Handle<String> name(shared_info->Name(), isolate);
707 719837 : info->set_function_name(ast_value_factory()->GetString(name));
708 719835 : scanner_.Initialize();
709 :
710 : FunctionLiteral* result =
711 719836 : DoParseFunction(isolate, info, info->function_name());
712 719830 : MaybeResetCharacterStream(info, result);
713 719836 : MaybeProcessSourceRanges(info, result, stack_limit_);
714 719837 : if (result != nullptr) {
715 1429910 : Handle<String> inferred_name(shared_info->inferred_name(), isolate);
716 714955 : result->set_inferred_name(inferred_name);
717 : }
718 :
719 719836 : if (V8_UNLIKELY(FLAG_log_function_events) && result != nullptr) {
720 23 : double ms = timer.Elapsed().InMillisecondsF();
721 : // We need to make sure that the debug-name is available.
722 23 : ast_value_factory()->Internalize(isolate);
723 : DeclarationScope* function_scope = result->scope();
724 23 : std::unique_ptr<char[]> function_name = result->GetDebugName();
725 69 : LOG(isolate,
726 : FunctionEvent("parse-function", info->script()->id(), ms,
727 : function_scope->start_position(),
728 : function_scope->end_position(), function_name.get(),
729 : strlen(function_name.get())));
730 : }
731 719836 : return result;
732 : }
733 :
734 719906 : static FunctionLiteral::FunctionType ComputeFunctionType(ParseInfo* info) {
735 719906 : if (info->is_wrapped_as_function()) {
736 : return FunctionLiteral::kWrapped;
737 719897 : } else if (info->is_declaration()) {
738 : return FunctionLiteral::kDeclaration;
739 452062 : } else if (info->is_named_expression()) {
740 : return FunctionLiteral::kNamedExpression;
741 634464 : } else if (IsConciseMethod(info->function_kind()) ||
742 : IsAccessorFunction(info->function_kind())) {
743 : return FunctionLiteral::kAccessorOrMethod;
744 : }
745 257395 : return FunctionLiteral::kAnonymousExpression;
746 : }
747 :
748 719908 : FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
749 : const AstRawString* raw_name) {
750 : DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr);
751 : DCHECK_NOT_NULL(raw_name);
752 : DCHECK_NULL(scope_);
753 : DCHECK_NULL(target_stack_);
754 :
755 : DCHECK(ast_value_factory());
756 719908 : fni_.PushEnclosingName(raw_name);
757 :
758 : ResetFunctionLiteralId();
759 : DCHECK_LT(0, info->function_literal_id());
760 719910 : SkipFunctionLiterals(info->function_literal_id() - 1);
761 :
762 : ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
763 :
764 : // Place holder for the result.
765 : FunctionLiteral* result = nullptr;
766 :
767 : {
768 : // Parse the function literal.
769 719910 : Scope* outer = original_scope_;
770 719910 : DeclarationScope* outer_function = outer->GetClosureScope();
771 : DCHECK(outer);
772 719909 : FunctionState function_state(&function_state_, &scope_, outer_function);
773 : BlockState block_state(&scope_, outer);
774 : DCHECK(is_sloppy(outer->language_mode()) ||
775 : is_strict(info->language_mode()));
776 719909 : FunctionLiteral::FunctionType function_type = ComputeFunctionType(info);
777 : FunctionKind kind = info->function_kind();
778 :
779 719906 : if (IsArrowFunction(kind)) {
780 177533 : if (IsAsyncFunction(kind)) {
781 : DCHECK(!scanner()->HasLineTerminatorAfterNext());
782 664 : if (!Check(Token::ASYNC)) {
783 0 : CHECK(stack_overflow());
784 0 : return nullptr;
785 : }
786 664 : if (!(peek_any_identifier() || peek() == Token::LPAREN)) {
787 0 : CHECK(stack_overflow());
788 : return nullptr;
789 : }
790 : }
791 :
792 : // TODO(adamk): We should construct this scope from the ScopeInfo.
793 177533 : DeclarationScope* scope = NewFunctionScope(kind);
794 : scope->set_has_checked_syntax(true);
795 :
796 : // This bit only needs to be explicitly set because we're
797 : // not passing the ScopeInfo to the Scope constructor.
798 177533 : SetLanguageMode(scope, info->language_mode());
799 :
800 : scope->set_start_position(info->start_position());
801 : ParserFormalParameters formals(scope);
802 : {
803 : ParameterDeclarationParsingScope formals_scope(this);
804 : // Parsing patterns as variable reference expression creates
805 : // NewUnresolved references in current scope. Enter arrow function
806 : // scope for formal parameter parsing.
807 : BlockState block_state(&scope_, scope);
808 177533 : if (Check(Token::LPAREN)) {
809 : // '(' StrictFormalParameters ')'
810 158583 : ParseFormalParameterList(&formals);
811 158583 : Expect(Token::RPAREN);
812 : } else {
813 : // BindingIdentifier
814 : ParameterParsingScope scope(impl(), &formals);
815 : ParseFormalParameter(&formals);
816 : DeclareFormalParameters(&formals);
817 : }
818 177533 : formals.duplicate_loc = formals_scope.duplicate_location();
819 : }
820 :
821 177533 : if (GetLastFunctionLiteralId() != info->function_literal_id() - 1) {
822 279 : if (has_error()) return nullptr;
823 : // If there were FunctionLiterals in the parameters, we need to
824 : // renumber them to shift down so the next function literal id for
825 : // the arrow function is the one requested.
826 : AstFunctionLiteralIdReindexer reindexer(
827 : stack_limit_,
828 558 : (info->function_literal_id() - 1) - GetLastFunctionLiteralId());
829 653 : for (auto p : formals.params) {
830 374 : if (p->pattern != nullptr) reindexer.Reindex(p->pattern);
831 374 : if (p->initializer() != nullptr) {
832 249 : reindexer.Reindex(p->initializer());
833 : }
834 : }
835 : ResetFunctionLiteralId();
836 279 : SkipFunctionLiterals(info->function_literal_id() - 1);
837 : }
838 :
839 177533 : Expression* expression = ParseArrowFunctionLiteral(formals);
840 : // Scanning must end at the same position that was recorded
841 : // previously. If not, parsing has been interrupted due to a stack
842 : // overflow, at which point the partially parsed arrow function
843 : // concise body happens to be a valid expression. This is a problem
844 : // only for arrow functions with single expression bodies, since there
845 : // is no end token such as "}" for normal functions.
846 177535 : if (scanner()->location().end_pos == info->end_position()) {
847 : // The pre-parser saw an arrow function here, so the full parser
848 : // must produce a FunctionLiteral.
849 : DCHECK(expression->IsFunctionLiteral());
850 177535 : result = expression->AsFunctionLiteral();
851 : }
852 542373 : } else if (IsDefaultConstructor(kind)) {
853 : DCHECK_EQ(scope(), outer);
854 8563 : result = DefaultConstructor(raw_name, IsDerivedConstructor(kind),
855 8563 : info->start_position(), info->end_position());
856 : } else {
857 : ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
858 : info->is_wrapped_as_function()
859 : ? PrepareWrappedArguments(isolate, info, zone())
860 533810 : : nullptr;
861 533810 : result = ParseFunctionLiteral(
862 : raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind,
863 : kNoSourcePosition, function_type, info->language_mode(),
864 533810 : arguments_for_wrapped_function);
865 : }
866 :
867 719906 : if (has_error()) return nullptr;
868 : result->set_requires_instance_members_initializer(
869 : info->requires_instance_members_initializer());
870 715023 : if (info->is_oneshot_iife()) {
871 : result->mark_as_oneshot_iife();
872 : }
873 : }
874 :
875 : // Make sure the target stack is empty.
876 : DCHECK_NULL(target_stack_);
877 : DCHECK_IMPLIES(result,
878 : info->function_literal_id() == result->function_literal_id());
879 715023 : return result;
880 : }
881 :
882 140954 : Statement* Parser::ParseModuleItem() {
883 : // ecma262/#prod-ModuleItem
884 : // ModuleItem :
885 : // ImportDeclaration
886 : // ExportDeclaration
887 : // StatementListItem
888 :
889 : Token::Value next = peek();
890 :
891 140954 : if (next == Token::EXPORT) {
892 19524 : return ParseExportDeclaration();
893 : }
894 :
895 121430 : if (next == Token::IMPORT) {
896 : // We must be careful not to parse a dynamic import expression as an import
897 : // declaration. Same for import.meta expressions.
898 : Token::Value peek_ahead = PeekAhead();
899 5968 : if ((!allow_harmony_dynamic_import() || peek_ahead != Token::LPAREN) &&
900 1694 : (!allow_harmony_import_meta() || peek_ahead != Token::PERIOD)) {
901 2484 : ParseImportDeclaration();
902 2484 : return factory()->EmptyStatement();
903 : }
904 : }
905 :
906 118946 : return ParseStatementListItem();
907 : }
908 :
909 40825 : void Parser::ParseModuleItemList(ScopedPtrList<Statement>* body) {
910 : // ecma262/#prod-Module
911 : // Module :
912 : // ModuleBody?
913 : //
914 : // ecma262/#prod-ModuleItemList
915 : // ModuleBody :
916 : // ModuleItem*
917 :
918 : DCHECK(scope()->is_module_scope());
919 156326 : while (peek() != Token::EOS) {
920 140954 : Statement* stat = ParseModuleItem();
921 140954 : if (stat == nullptr) return;
922 115501 : if (stat->IsEmptyStatement()) continue;
923 : body->Add(stat);
924 : }
925 : }
926 :
927 2919 : const AstRawString* Parser::ParseModuleSpecifier() {
928 : // ModuleSpecifier :
929 : // StringLiteral
930 :
931 2919 : Expect(Token::STRING);
932 2919 : return GetSymbol();
933 : }
934 :
935 635 : ZoneChunkList<Parser::ExportClauseData>* Parser::ParseExportClause(
936 : Scanner::Location* reserved_loc) {
937 : // ExportClause :
938 : // '{' '}'
939 : // '{' ExportsList '}'
940 : // '{' ExportsList ',' '}'
941 : //
942 : // ExportsList :
943 : // ExportSpecifier
944 : // ExportsList ',' ExportSpecifier
945 : //
946 : // ExportSpecifier :
947 : // IdentifierName
948 : // IdentifierName 'as' IdentifierName
949 : ZoneChunkList<ExportClauseData>* export_data =
950 : new (zone()) ZoneChunkList<ExportClauseData>(zone());
951 :
952 635 : Expect(Token::LBRACE);
953 :
954 : Token::Value name_tok;
955 755 : while ((name_tok = peek()) != Token::RBRACE) {
956 : // Keep track of the first reserved word encountered in case our
957 : // caller needs to report an error.
958 1410 : if (!reserved_loc->IsValid() &&
959 : !Token::IsValidIdentifier(name_tok, LanguageMode::kStrict, false,
960 705 : parsing_module_)) {
961 65 : *reserved_loc = scanner()->location();
962 : }
963 : const AstRawString* local_name = ParsePropertyName();
964 : const AstRawString* export_name = nullptr;
965 705 : Scanner::Location location = scanner()->location();
966 705 : if (CheckContextualKeyword(ast_value_factory()->as_string())) {
967 : export_name = ParsePropertyName();
968 : // Set the location to the whole "a as b" string, so that it makes sense
969 : // both for errors due to "a" and for errors due to "b".
970 340 : location.end_pos = scanner()->location().end_pos;
971 : }
972 705 : if (export_name == nullptr) {
973 : export_name = local_name;
974 : }
975 705 : export_data->push_back({export_name, local_name, location});
976 705 : if (peek() == Token::RBRACE) break;
977 160 : if (V8_UNLIKELY(!Check(Token::COMMA))) {
978 40 : ReportUnexpectedToken(Next());
979 40 : break;
980 : }
981 : }
982 :
983 635 : Expect(Token::RBRACE);
984 635 : return export_data;
985 : }
986 :
987 1269 : ZonePtrList<const Parser::NamedImport>* Parser::ParseNamedImports(int pos) {
988 : // NamedImports :
989 : // '{' '}'
990 : // '{' ImportsList '}'
991 : // '{' ImportsList ',' '}'
992 : //
993 : // ImportsList :
994 : // ImportSpecifier
995 : // ImportsList ',' ImportSpecifier
996 : //
997 : // ImportSpecifier :
998 : // BindingIdentifier
999 : // IdentifierName 'as' BindingIdentifier
1000 :
1001 1269 : Expect(Token::LBRACE);
1002 :
1003 : auto result = new (zone()) ZonePtrList<const NamedImport>(1, zone());
1004 1629 : while (peek() != Token::RBRACE) {
1005 : const AstRawString* import_name = ParsePropertyName();
1006 : const AstRawString* local_name = import_name;
1007 1424 : Scanner::Location location = scanner()->location();
1008 : // In the presence of 'as', the left-side of the 'as' can
1009 : // be any IdentifierName. But without 'as', it must be a valid
1010 : // BindingIdentifier.
1011 1424 : if (CheckContextualKeyword(ast_value_factory()->as_string())) {
1012 : local_name = ParsePropertyName();
1013 : }
1014 1424 : if (!Token::IsValidIdentifier(scanner()->current_token(),
1015 : LanguageMode::kStrict, false,
1016 1424 : parsing_module_)) {
1017 155 : ReportMessage(MessageTemplate::kUnexpectedReserved);
1018 155 : return nullptr;
1019 1269 : } else if (IsEvalOrArguments(local_name)) {
1020 25 : ReportMessage(MessageTemplate::kStrictEvalArguments);
1021 25 : return nullptr;
1022 : }
1023 :
1024 : DeclareUnboundVariable(local_name, VariableMode::kConst,
1025 : kNeedsInitialization, position());
1026 :
1027 : NamedImport* import =
1028 : new (zone()) NamedImport(import_name, local_name, location);
1029 1244 : result->Add(import, zone());
1030 :
1031 1244 : if (peek() == Token::RBRACE) break;
1032 180 : Expect(Token::COMMA);
1033 : }
1034 :
1035 1089 : Expect(Token::RBRACE);
1036 1089 : return result;
1037 : }
1038 :
1039 2484 : void Parser::ParseImportDeclaration() {
1040 : // ImportDeclaration :
1041 : // 'import' ImportClause 'from' ModuleSpecifier ';'
1042 : // 'import' ModuleSpecifier ';'
1043 : //
1044 : // ImportClause :
1045 : // ImportedDefaultBinding
1046 : // NameSpaceImport
1047 : // NamedImports
1048 : // ImportedDefaultBinding ',' NameSpaceImport
1049 : // ImportedDefaultBinding ',' NamedImports
1050 : //
1051 : // NameSpaceImport :
1052 : // '*' 'as' ImportedBinding
1053 :
1054 : int pos = peek_position();
1055 2484 : Expect(Token::IMPORT);
1056 :
1057 : Token::Value tok = peek();
1058 :
1059 : // 'import' ModuleSpecifier ';'
1060 2484 : if (tok == Token::STRING) {
1061 95 : Scanner::Location specifier_loc = scanner()->peek_location();
1062 95 : const AstRawString* module_specifier = ParseModuleSpecifier();
1063 95 : ExpectSemicolon();
1064 95 : module()->AddEmptyImport(module_specifier, specifier_loc);
1065 : return;
1066 : }
1067 :
1068 : // Parse ImportedDefaultBinding if present.
1069 : const AstRawString* import_default_binding = nullptr;
1070 : Scanner::Location import_default_binding_loc;
1071 2389 : if (tok != Token::MUL && tok != Token::LBRACE) {
1072 985 : import_default_binding = ParseNonRestrictedIdentifier();
1073 985 : import_default_binding_loc = scanner()->location();
1074 : DeclareUnboundVariable(import_default_binding, VariableMode::kConst,
1075 : kNeedsInitialization, pos);
1076 : }
1077 :
1078 : // Parse NameSpaceImport or NamedImports if present.
1079 : const AstRawString* module_namespace_binding = nullptr;
1080 : Scanner::Location module_namespace_binding_loc;
1081 : const ZonePtrList<const NamedImport>* named_imports = nullptr;
1082 3374 : if (import_default_binding == nullptr || Check(Token::COMMA)) {
1083 1429 : switch (peek()) {
1084 : case Token::MUL: {
1085 : Consume(Token::MUL);
1086 150 : ExpectContextualKeyword(ast_value_factory()->as_string());
1087 150 : module_namespace_binding = ParseNonRestrictedIdentifier();
1088 150 : module_namespace_binding_loc = scanner()->location();
1089 : DeclareUnboundVariable(module_namespace_binding, VariableMode::kConst,
1090 : kCreatedInitialized, pos);
1091 : break;
1092 : }
1093 :
1094 : case Token::LBRACE:
1095 1269 : named_imports = ParseNamedImports(pos);
1096 1269 : break;
1097 :
1098 : default:
1099 10 : ReportUnexpectedToken(scanner()->current_token());
1100 10 : return;
1101 : }
1102 : }
1103 :
1104 2379 : ExpectContextualKeyword(ast_value_factory()->from_string());
1105 2379 : Scanner::Location specifier_loc = scanner()->peek_location();
1106 2379 : const AstRawString* module_specifier = ParseModuleSpecifier();
1107 2379 : ExpectSemicolon();
1108 :
1109 : // Now that we have all the information, we can make the appropriate
1110 : // declarations.
1111 :
1112 : // TODO(neis): Would prefer to call DeclareVariable for each case below rather
1113 : // than above and in ParseNamedImports, but then a possible error message
1114 : // would point to the wrong location. Maybe have a DeclareAt version of
1115 : // Declare that takes a location?
1116 :
1117 2379 : if (module_namespace_binding != nullptr) {
1118 : module()->AddStarImport(module_namespace_binding, module_specifier,
1119 : module_namespace_binding_loc, specifier_loc,
1120 150 : zone());
1121 : }
1122 :
1123 2379 : if (import_default_binding != nullptr) {
1124 : module()->AddImport(ast_value_factory()->default_string(),
1125 : import_default_binding, module_specifier,
1126 975 : import_default_binding_loc, specifier_loc, zone());
1127 : }
1128 :
1129 2379 : if (named_imports != nullptr) {
1130 1089 : if (named_imports->length() == 0) {
1131 20 : module()->AddEmptyImport(module_specifier, specifier_loc);
1132 : } else {
1133 3427 : for (const NamedImport* import : *named_imports) {
1134 1179 : module()->AddImport(import->import_name, import->local_name,
1135 : module_specifier, import->location, specifier_loc,
1136 1179 : zone());
1137 : }
1138 : }
1139 : }
1140 : }
1141 :
1142 461 : Statement* Parser::ParseExportDefault() {
1143 : // Supports the following productions, starting after the 'default' token:
1144 : // 'export' 'default' HoistableDeclaration
1145 : // 'export' 'default' ClassDeclaration
1146 : // 'export' 'default' AssignmentExpression[In] ';'
1147 :
1148 461 : Expect(Token::DEFAULT);
1149 461 : Scanner::Location default_loc = scanner()->location();
1150 :
1151 : ZonePtrList<const AstRawString> local_names(1, zone());
1152 : Statement* result = nullptr;
1153 461 : switch (peek()) {
1154 : case Token::FUNCTION:
1155 65 : result = ParseHoistableDeclaration(&local_names, true);
1156 65 : break;
1157 :
1158 : case Token::CLASS:
1159 : Consume(Token::CLASS);
1160 45 : result = ParseClassDeclaration(&local_names, true);
1161 45 : break;
1162 :
1163 : case Token::ASYNC:
1164 120 : if (PeekAhead() == Token::FUNCTION &&
1165 : !scanner()->HasLineTerminatorAfterNext()) {
1166 : Consume(Token::ASYNC);
1167 60 : result = ParseAsyncFunctionDeclaration(&local_names, true);
1168 60 : break;
1169 : }
1170 : V8_FALLTHROUGH;
1171 :
1172 : default: {
1173 : int pos = position();
1174 : AcceptINScope scope(this, true);
1175 : Expression* value = ParseAssignmentExpression();
1176 291 : SetFunctionName(value, ast_value_factory()->default_string());
1177 :
1178 : const AstRawString* local_name =
1179 291 : ast_value_factory()->dot_default_string();
1180 291 : local_names.Add(local_name, zone());
1181 :
1182 : // It's fine to declare this as VariableMode::kConst because the user has
1183 : // no way of writing to it.
1184 : VariableProxy* proxy =
1185 291 : DeclareBoundVariable(local_name, VariableMode::kConst, pos);
1186 : proxy->var()->set_initializer_position(position());
1187 :
1188 : Assignment* assignment = factory()->NewAssignment(
1189 291 : Token::INIT, proxy, value, kNoSourcePosition);
1190 : result = IgnoreCompletion(
1191 291 : factory()->NewExpressionStatement(assignment, kNoSourcePosition));
1192 :
1193 291 : ExpectSemicolon();
1194 : break;
1195 : }
1196 : }
1197 :
1198 461 : if (result != nullptr) {
1199 : DCHECK_EQ(local_names.length(), 1);
1200 461 : module()->AddExport(local_names.first(),
1201 : ast_value_factory()->default_string(), default_loc,
1202 461 : zone());
1203 : }
1204 :
1205 461 : return result;
1206 : }
1207 :
1208 110 : const AstRawString* Parser::NextInternalNamespaceExportName() {
1209 : const char* prefix = ".ns-export";
1210 110 : std::string s(prefix);
1211 220 : s.append(std::to_string(number_of_named_namespace_exports_++));
1212 220 : return ast_value_factory()->GetOneByteString(s.c_str());
1213 : }
1214 :
1215 260 : void Parser::ParseExportStar() {
1216 : int pos = position();
1217 : Consume(Token::MUL);
1218 :
1219 520 : if (!FLAG_harmony_namespace_exports ||
1220 260 : !PeekContextualKeyword(ast_value_factory()->as_string())) {
1221 : // 'export' '*' 'from' ModuleSpecifier ';'
1222 150 : Scanner::Location loc = scanner()->location();
1223 150 : ExpectContextualKeyword(ast_value_factory()->from_string());
1224 150 : Scanner::Location specifier_loc = scanner()->peek_location();
1225 150 : const AstRawString* module_specifier = ParseModuleSpecifier();
1226 150 : ExpectSemicolon();
1227 150 : module()->AddStarExport(module_specifier, loc, specifier_loc, zone());
1228 : return;
1229 : }
1230 110 : if (!FLAG_harmony_namespace_exports) return;
1231 :
1232 : // 'export' '*' 'as' IdentifierName 'from' ModuleSpecifier ';'
1233 : //
1234 : // Desugaring:
1235 : // export * as x from "...";
1236 : // ~>
1237 : // import * as .x from "..."; export {.x as x};
1238 :
1239 110 : ExpectContextualKeyword(ast_value_factory()->as_string());
1240 : const AstRawString* export_name = ParsePropertyName();
1241 110 : Scanner::Location export_name_loc = scanner()->location();
1242 110 : const AstRawString* local_name = NextInternalNamespaceExportName();
1243 110 : Scanner::Location local_name_loc = Scanner::Location::invalid();
1244 : DeclareUnboundVariable(local_name, VariableMode::kConst, kCreatedInitialized,
1245 : pos);
1246 :
1247 110 : ExpectContextualKeyword(ast_value_factory()->from_string());
1248 110 : Scanner::Location specifier_loc = scanner()->peek_location();
1249 110 : const AstRawString* module_specifier = ParseModuleSpecifier();
1250 110 : ExpectSemicolon();
1251 :
1252 : module()->AddStarImport(local_name, module_specifier, local_name_loc,
1253 110 : specifier_loc, zone());
1254 110 : module()->AddExport(local_name, export_name, export_name_loc, zone());
1255 : }
1256 :
1257 19524 : Statement* Parser::ParseExportDeclaration() {
1258 : // ExportDeclaration:
1259 : // 'export' '*' 'from' ModuleSpecifier ';'
1260 : // 'export' '*' 'as' IdentifierName 'from' ModuleSpecifier ';'
1261 : // 'export' ExportClause ('from' ModuleSpecifier)? ';'
1262 : // 'export' VariableStatement
1263 : // 'export' Declaration
1264 : // 'export' 'default' ... (handled in ParseExportDefault)
1265 :
1266 19524 : Expect(Token::EXPORT);
1267 : Statement* result = nullptr;
1268 : ZonePtrList<const AstRawString> names(1, zone());
1269 19524 : Scanner::Location loc = scanner()->peek_location();
1270 19524 : switch (peek()) {
1271 : case Token::DEFAULT:
1272 461 : return ParseExportDefault();
1273 :
1274 : case Token::MUL:
1275 260 : ParseExportStar();
1276 260 : return factory()->EmptyStatement();
1277 :
1278 : case Token::LBRACE: {
1279 : // There are two cases here:
1280 : //
1281 : // 'export' ExportClause ';'
1282 : // and
1283 : // 'export' ExportClause FromClause ';'
1284 : //
1285 : // In the first case, the exported identifiers in ExportClause must
1286 : // not be reserved words, while in the latter they may be. We
1287 : // pass in a location that gets filled with the first reserved word
1288 : // encountered, and then throw a SyntaxError if we are in the
1289 : // non-FromClause case.
1290 635 : Scanner::Location reserved_loc = Scanner::Location::invalid();
1291 : ZoneChunkList<ExportClauseData>* export_data =
1292 635 : ParseExportClause(&reserved_loc);
1293 : const AstRawString* module_specifier = nullptr;
1294 : Scanner::Location specifier_loc;
1295 635 : if (CheckContextualKeyword(ast_value_factory()->from_string())) {
1296 185 : specifier_loc = scanner()->peek_location();
1297 185 : module_specifier = ParseModuleSpecifier();
1298 450 : } else if (reserved_loc.IsValid()) {
1299 : // No FromClause, so reserved words are invalid in ExportClause.
1300 30 : ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved);
1301 30 : return nullptr;
1302 : }
1303 605 : ExpectSemicolon();
1304 605 : if (module_specifier == nullptr) {
1305 910 : for (const ExportClauseData& data : *export_data) {
1306 490 : module()->AddExport(data.local_name, data.export_name, data.location,
1307 490 : zone());
1308 : }
1309 185 : } else if (export_data->is_empty()) {
1310 30 : module()->AddEmptyImport(module_specifier, specifier_loc);
1311 : } else {
1312 330 : for (const ExportClauseData& data : *export_data) {
1313 175 : module()->AddExport(data.local_name, data.export_name,
1314 : module_specifier, data.location, specifier_loc,
1315 175 : zone());
1316 : }
1317 : }
1318 605 : return factory()->EmptyStatement();
1319 : }
1320 :
1321 : case Token::FUNCTION:
1322 350 : result = ParseHoistableDeclaration(&names, false);
1323 350 : break;
1324 :
1325 : case Token::CLASS:
1326 : Consume(Token::CLASS);
1327 35 : result = ParseClassDeclaration(&names, false);
1328 35 : break;
1329 :
1330 : case Token::VAR:
1331 : case Token::LET:
1332 : case Token::CONST:
1333 17673 : result = ParseVariableStatement(kStatementListItem, &names);
1334 17673 : break;
1335 :
1336 : case Token::ASYNC:
1337 : Consume(Token::ASYNC);
1338 190 : if (peek() == Token::FUNCTION &&
1339 : !scanner()->HasLineTerminatorBeforeNext()) {
1340 65 : result = ParseAsyncFunctionDeclaration(&names, false);
1341 65 : break;
1342 : }
1343 : V8_FALLTHROUGH;
1344 :
1345 : default:
1346 45 : ReportUnexpectedToken(scanner()->current_token());
1347 45 : return nullptr;
1348 : }
1349 18123 : loc.end_pos = scanner()->location().end_pos;
1350 :
1351 : ModuleDescriptor* descriptor = module();
1352 54309 : for (const AstRawString* name : names) {
1353 18093 : descriptor->AddExport(name, name, loc, zone());
1354 : }
1355 :
1356 : return result;
1357 : }
1358 :
1359 0 : void Parser::DeclareUnboundVariable(const AstRawString* name, VariableMode mode,
1360 : InitializationFlag init, int pos) {
1361 : bool was_added;
1362 2489 : Variable* var = DeclareVariable(name, NORMAL_VARIABLE, mode, init, scope(),
1363 : &was_added, pos, end_position());
1364 : // The variable will be added to the declarations list, but since we are not
1365 : // binding it to anything, we can simply ignore it here.
1366 : USE(var);
1367 0 : }
1368 :
1369 357525 : VariableProxy* Parser::DeclareBoundVariable(const AstRawString* name,
1370 : VariableMode mode, int pos) {
1371 : DCHECK_NOT_NULL(name);
1372 : VariableProxy* proxy =
1373 : factory()->NewVariableProxy(name, NORMAL_VARIABLE, position());
1374 : bool was_added;
1375 357523 : Variable* var = DeclareVariable(name, NORMAL_VARIABLE, mode,
1376 : Variable::DefaultInitializationFlag(mode),
1377 357523 : scope(), &was_added, pos, end_position());
1378 357527 : proxy->BindTo(var);
1379 357527 : return proxy;
1380 : }
1381 :
1382 143939 : void Parser::DeclareAndBindVariable(VariableProxy* proxy, VariableKind kind,
1383 : VariableMode mode, InitializationFlag init,
1384 : Scope* scope, bool* was_added, int begin,
1385 : int end) {
1386 143939 : Variable* var = DeclareVariable(proxy->raw_name(), kind, mode, init, scope,
1387 143939 : was_added, begin, end);
1388 143939 : proxy->BindTo(var);
1389 143939 : }
1390 :
1391 14439987 : Variable* Parser::DeclareVariable(const AstRawString* name, VariableKind kind,
1392 : VariableMode mode, InitializationFlag init,
1393 : Scope* scope, bool* was_added, int begin,
1394 : int end) {
1395 : Declaration* declaration;
1396 27140818 : if (mode == VariableMode::kVar && !scope->is_declaration_scope()) {
1397 : DCHECK(scope->is_block_scope() || scope->is_with_scope());
1398 : declaration = factory()->NewNestedVariableDeclaration(scope, begin);
1399 : } else {
1400 : declaration = factory()->NewVariableDeclaration(begin);
1401 : }
1402 14439998 : Declare(declaration, name, kind, mode, init, scope, was_added, begin, end);
1403 14439959 : return declaration->var();
1404 : }
1405 :
1406 15429183 : void Parser::Declare(Declaration* declaration, const AstRawString* name,
1407 : VariableKind variable_kind, VariableMode mode,
1408 : InitializationFlag init, Scope* scope, bool* was_added,
1409 : int var_begin_pos, int var_end_pos) {
1410 15429183 : bool local_ok = true;
1411 15429183 : bool sloppy_mode_block_scope_function_redefinition = false;
1412 15429183 : scope->DeclareVariable(
1413 : declaration, name, var_begin_pos, mode, variable_kind, init, was_added,
1414 15429183 : &sloppy_mode_block_scope_function_redefinition, &local_ok);
1415 15429058 : if (!local_ok) {
1416 : // If we only have the start position of a proxy, we can't highlight the
1417 : // whole variable name. Pretend its length is 1 so that we highlight at
1418 : // least the first character.
1419 : Scanner::Location loc(var_begin_pos, var_end_pos != kNoSourcePosition
1420 : ? var_end_pos
1421 63809 : : var_begin_pos + 1);
1422 63809 : if (variable_kind == PARAMETER_VARIABLE) {
1423 309 : ReportMessageAt(loc, MessageTemplate::kParamDupe);
1424 : } else {
1425 : ReportMessageAt(loc, MessageTemplate::kVarRedeclaration,
1426 63500 : declaration->var()->raw_name());
1427 : }
1428 15365249 : } else if (sloppy_mode_block_scope_function_redefinition) {
1429 229 : ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition];
1430 : }
1431 15429058 : }
1432 :
1433 8938366 : Statement* Parser::BuildInitializationBlock(
1434 : DeclarationParsingResult* parsing_result) {
1435 : ScopedPtrList<Statement> statements(pointer_buffer());
1436 18118338 : for (const auto& declaration : parsing_result->declarations) {
1437 9179952 : if (!declaration.initializer) continue;
1438 7176515 : InitializeVariables(&statements, parsing_result->descriptor.kind,
1439 7176515 : &declaration);
1440 : }
1441 17876815 : return factory()->NewBlock(true, statements);
1442 : }
1443 :
1444 989129 : Statement* Parser::DeclareFunction(const AstRawString* variable_name,
1445 : FunctionLiteral* function, VariableMode mode,
1446 : VariableKind kind, int beg_pos, int end_pos,
1447 : ZonePtrList<const AstRawString>* names) {
1448 : Declaration* declaration =
1449 : factory()->NewFunctionDeclaration(function, beg_pos);
1450 : bool was_added;
1451 989137 : Declare(declaration, variable_name, kind, mode, kCreatedInitialized, scope(),
1452 989137 : &was_added, beg_pos);
1453 989135 : if (info()->coverage_enabled()) {
1454 : // Force the function to be allocated when collecting source coverage, so
1455 : // that even dead functions get source coverage data.
1456 : declaration->var()->set_is_used();
1457 : }
1458 989135 : if (names) names->Add(variable_name, zone());
1459 989129 : if (kind == SLOPPY_BLOCK_FUNCTION_VARIABLE) {
1460 9155 : Token::Value init = loop_nesting_depth() > 0 ? Token::ASSIGN : Token::INIT;
1461 : SloppyBlockFunctionStatement* statement =
1462 : factory()->NewSloppyBlockFunctionStatement(end_pos, declaration->var(),
1463 : init);
1464 9155 : GetDeclarationScope()->DeclareSloppyBlockFunction(statement);
1465 9155 : return statement;
1466 : }
1467 979974 : return factory()->EmptyStatement();
1468 : }
1469 :
1470 108473 : Statement* Parser::DeclareClass(const AstRawString* variable_name,
1471 : Expression* value,
1472 : ZonePtrList<const AstRawString>* names,
1473 : int class_token_pos, int end_pos) {
1474 : VariableProxy* proxy =
1475 108473 : DeclareBoundVariable(variable_name, VariableMode::kLet, class_token_pos);
1476 : proxy->var()->set_initializer_position(end_pos);
1477 108473 : if (names) names->Add(variable_name, zone());
1478 :
1479 : Assignment* assignment =
1480 108473 : factory()->NewAssignment(Token::INIT, proxy, value, class_token_pos);
1481 : return IgnoreCompletion(
1482 108473 : factory()->NewExpressionStatement(assignment, kNoSourcePosition));
1483 : }
1484 :
1485 1839 : Statement* Parser::DeclareNative(const AstRawString* name, int pos) {
1486 : // Make sure that the function containing the native declaration
1487 : // isn't lazily compiled. The extension structures are only
1488 : // accessible while parsing the first time not when reparsing
1489 : // because of lazy compilation.
1490 : GetClosureScope()->ForceEagerCompilation();
1491 :
1492 : // TODO(1240846): It's weird that native function declarations are
1493 : // introduced dynamically when we meet their declarations, whereas
1494 : // other functions are set up when entering the surrounding scope.
1495 1839 : VariableProxy* proxy = DeclareBoundVariable(name, VariableMode::kVar, pos);
1496 : NativeFunctionLiteral* lit =
1497 1839 : factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition);
1498 : return factory()->NewExpressionStatement(
1499 1839 : factory()->NewAssignment(Token::INIT, proxy, lit, kNoSourcePosition),
1500 1839 : pos);
1501 : }
1502 :
1503 15738 : void Parser::DeclareLabel(ZonePtrList<const AstRawString>** labels,
1504 : ZonePtrList<const AstRawString>** own_labels,
1505 : VariableProxy* var) {
1506 : DCHECK(IsIdentifier(var));
1507 15738 : const AstRawString* label = var->raw_name();
1508 :
1509 : // TODO(1240780): We don't check for redeclaration of labels
1510 : // during preparsing since keeping track of the set of active
1511 : // labels requires nontrivial changes to the way scopes are
1512 : // structured. However, these are probably changes we want to
1513 : // make later anyway so we should go back and fix this then.
1514 31476 : if (ContainsLabel(*labels, label) || TargetStackContainsLabel(label)) {
1515 0 : ReportMessage(MessageTemplate::kLabelRedeclaration, label);
1516 0 : return;
1517 : }
1518 :
1519 : // Add {label} to both {labels} and {own_labels}.
1520 15738 : if (*labels == nullptr) {
1521 : DCHECK_NULL(*own_labels);
1522 15094 : *labels = new (zone()) ZonePtrList<const AstRawString>(1, zone());
1523 15094 : *own_labels = new (zone()) ZonePtrList<const AstRawString>(1, zone());
1524 : } else {
1525 644 : if (*own_labels == nullptr) {
1526 12 : *own_labels = new (zone()) ZonePtrList<const AstRawString>(1, zone());
1527 : }
1528 : }
1529 15738 : (*labels)->Add(label, zone());
1530 15738 : (*own_labels)->Add(label, zone());
1531 :
1532 : // Remove the "ghost" variable that turned out to be a label
1533 : // from the top scope. This way, we don't try to resolve it
1534 : // during the scope processing.
1535 15738 : scope()->DeleteUnresolved(var);
1536 : }
1537 :
1538 0 : bool Parser::ContainsLabel(ZonePtrList<const AstRawString>* labels,
1539 : const AstRawString* label) {
1540 : DCHECK_NOT_NULL(label);
1541 51221 : if (labels != nullptr) {
1542 11534 : for (int i = labels->length(); i-- > 0;) {
1543 10383 : if (labels->at(i) == label) return true;
1544 : }
1545 : }
1546 : return false;
1547 : }
1548 :
1549 196225 : Block* Parser::IgnoreCompletion(Statement* statement) {
1550 196225 : Block* block = factory()->NewBlock(1, true);
1551 196225 : block->statements()->Add(statement, zone());
1552 196225 : return block;
1553 : }
1554 :
1555 999829 : Expression* Parser::RewriteReturn(Expression* return_value, int pos) {
1556 1999666 : if (IsDerivedConstructor(function_state_->kind())) {
1557 : // For subclass constructors we need to return this in case of undefined;
1558 : // other primitive values trigger an exception in the ConstructStub.
1559 : //
1560 : // return expr;
1561 : //
1562 : // Is rewritten as:
1563 : //
1564 : // return (temp = expr) === undefined ? this : temp;
1565 :
1566 : // temp = expr
1567 : Variable* temp = NewTemporary(ast_value_factory()->empty_string());
1568 : Assignment* assign = factory()->NewAssignment(
1569 334 : Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos);
1570 :
1571 : // temp === undefined
1572 : Expression* is_undefined = factory()->NewCompareOperation(
1573 : Token::EQ_STRICT, assign,
1574 : factory()->NewUndefinedLiteral(kNoSourcePosition), pos);
1575 :
1576 : // is_undefined ? this : temp
1577 : // We don't need to call UseThis() since it's guaranteed to be called
1578 : // for derived constructors after parsing the constructor in
1579 : // ParseFunctionBody.
1580 : return_value =
1581 : factory()->NewConditional(is_undefined, factory()->ThisExpression(),
1582 : factory()->NewVariableProxy(temp), pos);
1583 : }
1584 999837 : return return_value;
1585 : }
1586 :
1587 922 : Statement* Parser::RewriteSwitchStatement(SwitchStatement* switch_statement,
1588 : Scope* scope) {
1589 : // In order to get the CaseClauses to execute in their own lexical scope,
1590 : // but without requiring downstream code to have special scope handling
1591 : // code for switch statements, desugar into blocks as follows:
1592 : // { // To group the statements--harmless to evaluate Expression in scope
1593 : // .tag_variable = Expression;
1594 : // { // To give CaseClauses a scope
1595 : // switch (.tag_variable) { CaseClause* }
1596 : // }
1597 : // }
1598 : DCHECK_NOT_NULL(scope);
1599 : DCHECK(scope->is_block_scope());
1600 : DCHECK_GE(switch_statement->position(), scope->start_position());
1601 : DCHECK_LT(switch_statement->position(), scope->end_position());
1602 :
1603 922 : Block* switch_block = factory()->NewBlock(2, false);
1604 :
1605 : Expression* tag = switch_statement->tag();
1606 : Variable* tag_variable =
1607 : NewTemporary(ast_value_factory()->dot_switch_tag_string());
1608 : Assignment* tag_assign = factory()->NewAssignment(
1609 : Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag,
1610 922 : tag->position());
1611 : // Wrap with IgnoreCompletion so the tag isn't returned as the completion
1612 : // value, in case the switch statements don't have a value.
1613 922 : Statement* tag_statement = IgnoreCompletion(
1614 922 : factory()->NewExpressionStatement(tag_assign, kNoSourcePosition));
1615 922 : switch_block->statements()->Add(tag_statement, zone());
1616 :
1617 : switch_statement->set_tag(factory()->NewVariableProxy(tag_variable));
1618 922 : Block* cases_block = factory()->NewBlock(1, false);
1619 1844 : cases_block->statements()->Add(switch_statement, zone());
1620 : cases_block->set_scope(scope);
1621 922 : switch_block->statements()->Add(cases_block, zone());
1622 922 : return switch_block;
1623 : }
1624 :
1625 7346890 : void Parser::InitializeVariables(
1626 : ScopedPtrList<Statement>* statements, VariableKind kind,
1627 : const DeclarationParsingResult::Declaration* declaration) {
1628 7346890 : if (has_error()) return;
1629 :
1630 : DCHECK_NOT_NULL(declaration->initializer);
1631 :
1632 7276433 : int pos = declaration->value_beg_pos;
1633 7276433 : if (pos == kNoSourcePosition) {
1634 342036 : pos = declaration->initializer->position();
1635 : }
1636 : Assignment* assignment = factory()->NewAssignment(
1637 14552866 : Token::INIT, declaration->pattern, declaration->initializer, pos);
1638 : statements->Add(factory()->NewExpressionStatement(assignment, pos));
1639 : }
1640 :
1641 3024 : Block* Parser::RewriteCatchPattern(CatchInfo* catch_info) {
1642 : DCHECK_NOT_NULL(catch_info->pattern);
1643 :
1644 : DeclarationParsingResult::Declaration decl(
1645 6049 : catch_info->pattern, factory()->NewVariableProxy(catch_info->variable));
1646 :
1647 : ScopedPtrList<Statement> init_statements(pointer_buffer());
1648 3025 : InitializeVariables(&init_statements, NORMAL_VARIABLE, &decl);
1649 6050 : return factory()->NewBlock(true, init_statements);
1650 : }
1651 :
1652 468 : void Parser::ReportVarRedeclarationIn(const AstRawString* name, Scope* scope) {
1653 648 : for (Declaration* decl : *scope->declarations()) {
1654 648 : if (decl->var()->raw_name() == name) {
1655 : int position = decl->position();
1656 : Scanner::Location location =
1657 : position == kNoSourcePosition
1658 : ? Scanner::Location::invalid()
1659 936 : : Scanner::Location(position, position + name->length());
1660 468 : ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
1661 468 : return;
1662 : }
1663 : }
1664 0 : UNREACHABLE();
1665 : }
1666 :
1667 98374 : Statement* Parser::RewriteTryStatement(Block* try_block, Block* catch_block,
1668 : const SourceRange& catch_range,
1669 : Block* finally_block,
1670 : const SourceRange& finally_range,
1671 : const CatchInfo& catch_info, int pos) {
1672 : // Simplify the AST nodes by converting:
1673 : // 'try B0 catch B1 finally B2'
1674 : // to:
1675 : // 'try { try B0 catch B1 } finally B2'
1676 :
1677 98374 : if (catch_block != nullptr && finally_block != nullptr) {
1678 : // If we have both, create an inner try/catch.
1679 : TryCatchStatement* statement;
1680 1019 : statement = factory()->NewTryCatchStatement(try_block, catch_info.scope,
1681 : catch_block, kNoSourcePosition);
1682 : RecordTryCatchStatementSourceRange(statement, catch_range);
1683 :
1684 1019 : try_block = factory()->NewBlock(1, false);
1685 2038 : try_block->statements()->Add(statement, zone());
1686 : catch_block = nullptr; // Clear to indicate it's been handled.
1687 : }
1688 :
1689 98374 : if (catch_block != nullptr) {
1690 : DCHECK_NULL(finally_block);
1691 : TryCatchStatement* stmt = factory()->NewTryCatchStatement(
1692 93117 : try_block, catch_info.scope, catch_block, pos);
1693 : RecordTryCatchStatementSourceRange(stmt, catch_range);
1694 : return stmt;
1695 : } else {
1696 : DCHECK_NOT_NULL(finally_block);
1697 : TryFinallyStatement* stmt =
1698 : factory()->NewTryFinallyStatement(try_block, finally_block, pos);
1699 : RecordTryFinallyStatementSourceRange(stmt, finally_range);
1700 : return stmt;
1701 : }
1702 : }
1703 :
1704 25182 : void Parser::ParseAndRewriteGeneratorFunctionBody(
1705 : int pos, FunctionKind kind, ScopedPtrList<Statement>* body) {
1706 : // For ES6 Generators, we just prepend the initial yield.
1707 25182 : Expression* initial_yield = BuildInitialYield(pos, kind);
1708 : body->Add(
1709 : factory()->NewExpressionStatement(initial_yield, kNoSourcePosition));
1710 25182 : ParseStatementList(body, Token::RBRACE);
1711 25182 : }
1712 :
1713 24534 : void Parser::ParseAndRewriteAsyncGeneratorFunctionBody(
1714 : int pos, FunctionKind kind, ScopedPtrList<Statement>* body) {
1715 : // For ES2017 Async Generators, we produce:
1716 : //
1717 : // try {
1718 : // InitialYield;
1719 : // ...body...;
1720 : // return undefined; // See comment below
1721 : // } catch (.catch) {
1722 : // %AsyncGeneratorReject(generator, .catch);
1723 : // } finally {
1724 : // %_GeneratorClose(generator);
1725 : // }
1726 : //
1727 : // - InitialYield yields the actual generator object.
1728 : // - Any return statement inside the body will have its argument wrapped
1729 : // in an iterator result object with a "done" property set to `true`.
1730 : // - If the generator terminates for whatever reason, we must close it.
1731 : // Hence the finally clause.
1732 : // - BytecodeGenerator performs special handling for ReturnStatements in
1733 : // async generator functions, resolving the appropriate Promise with an
1734 : // "done" iterator result object containing a Promise-unwrapped value.
1735 : DCHECK(IsAsyncGeneratorFunction(kind));
1736 :
1737 : Block* try_block;
1738 : {
1739 : ScopedPtrList<Statement> statements(pointer_buffer());
1740 24534 : Expression* initial_yield = BuildInitialYield(pos, kind);
1741 : statements.Add(
1742 : factory()->NewExpressionStatement(initial_yield, kNoSourcePosition));
1743 24534 : ParseStatementList(&statements, Token::RBRACE);
1744 :
1745 : // Don't create iterator result for async generators, as the resume methods
1746 : // will create it.
1747 : // TODO(leszeks): This will create another suspend point, which is
1748 : // unnecessary if there is already an unconditional return in the body.
1749 : Statement* final_return = BuildReturnStatement(
1750 24534 : factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
1751 : statements.Add(final_return);
1752 :
1753 24534 : try_block = factory()->NewBlock(false, statements);
1754 : }
1755 :
1756 : // For AsyncGenerators, a top-level catch block will reject the Promise.
1757 24534 : Scope* catch_scope = NewHiddenCatchScope();
1758 :
1759 : Block* catch_block;
1760 : {
1761 : ScopedPtrList<Expression> reject_args(pointer_buffer());
1762 : reject_args.Add(factory()->NewVariableProxy(
1763 24534 : function_state_->scope()->generator_object_var()));
1764 : reject_args.Add(factory()->NewVariableProxy(catch_scope->catch_variable()));
1765 :
1766 : Expression* reject_call = factory()->NewCallRuntime(
1767 24534 : Runtime::kInlineAsyncGeneratorReject, reject_args, kNoSourcePosition);
1768 : catch_block = IgnoreCompletion(
1769 24534 : factory()->NewReturnStatement(reject_call, kNoSourcePosition));
1770 : }
1771 :
1772 : {
1773 : ScopedPtrList<Statement> statements(pointer_buffer());
1774 : TryStatement* try_catch = factory()->NewTryCatchStatementForAsyncAwait(
1775 : try_block, catch_scope, catch_block, kNoSourcePosition);
1776 : statements.Add(try_catch);
1777 24534 : try_block = factory()->NewBlock(false, statements);
1778 : }
1779 :
1780 : Expression* close_call;
1781 : {
1782 : ScopedPtrList<Expression> close_args(pointer_buffer());
1783 : VariableProxy* call_proxy = factory()->NewVariableProxy(
1784 24534 : function_state_->scope()->generator_object_var());
1785 : close_args.Add(call_proxy);
1786 : close_call = factory()->NewCallRuntime(Runtime::kInlineGeneratorClose,
1787 24534 : close_args, kNoSourcePosition);
1788 : }
1789 :
1790 : Block* finally_block;
1791 : {
1792 : ScopedPtrList<Statement> statements(pointer_buffer());
1793 : statements.Add(
1794 : factory()->NewExpressionStatement(close_call, kNoSourcePosition));
1795 24534 : finally_block = factory()->NewBlock(false, statements);
1796 : }
1797 :
1798 : body->Add(factory()->NewTryFinallyStatement(try_block, finally_block,
1799 : kNoSourcePosition));
1800 24534 : }
1801 :
1802 1797740 : void Parser::DeclareFunctionNameVar(const AstRawString* function_name,
1803 : FunctionLiteral::FunctionType function_type,
1804 : DeclarationScope* function_scope) {
1805 1928025 : if (function_type == FunctionLiteral::kNamedExpression &&
1806 : function_scope->LookupLocal(function_name) == nullptr) {
1807 : DCHECK_EQ(function_scope, scope());
1808 126604 : function_scope->DeclareFunctionVar(function_name);
1809 : }
1810 1797746 : }
1811 :
1812 : // Special case for legacy for
1813 : //
1814 : // for (var x = initializer in enumerable) body
1815 : //
1816 : // An initialization block of the form
1817 : //
1818 : // {
1819 : // x = initializer;
1820 : // }
1821 : //
1822 : // is returned in this case. It has reserved space for two statements,
1823 : // so that (later on during parsing), the equivalent of
1824 : //
1825 : // for (x in enumerable) body
1826 : //
1827 : // is added as a second statement to it.
1828 91820 : Block* Parser::RewriteForVarInLegacy(const ForInfo& for_info) {
1829 : const DeclarationParsingResult::Declaration& decl =
1830 : for_info.parsing_result.declarations[0];
1831 200357 : if (!IsLexicalVariableMode(for_info.parsing_result.descriptor.mode) &&
1832 92246 : decl.initializer != nullptr && decl.pattern->IsVariableProxy()) {
1833 213 : ++use_counts_[v8::Isolate::kForInInitializer];
1834 213 : const AstRawString* name = decl.pattern->AsVariableProxy()->raw_name();
1835 : VariableProxy* single_var = NewUnresolved(name);
1836 213 : Block* init_block = factory()->NewBlock(2, true);
1837 426 : init_block->statements()->Add(
1838 : factory()->NewExpressionStatement(
1839 213 : factory()->NewAssignment(Token::ASSIGN, single_var,
1840 213 : decl.initializer, decl.value_beg_pos),
1841 : kNoSourcePosition),
1842 213 : zone());
1843 213 : return init_block;
1844 : }
1845 : return nullptr;
1846 : }
1847 :
1848 : // Rewrite a for-in/of statement of the form
1849 : //
1850 : // for (let/const/var x in/of e) b
1851 : //
1852 : // into
1853 : //
1854 : // {
1855 : // var temp;
1856 : // for (temp in/of e) {
1857 : // let/const/var x = temp;
1858 : // b;
1859 : // }
1860 : // let x; // for TDZ
1861 : // }
1862 106562 : void Parser::DesugarBindingInForEachStatement(ForInfo* for_info,
1863 : Block** body_block,
1864 : Expression** each_variable) {
1865 : DCHECK_EQ(1, for_info->parsing_result.declarations.size());
1866 : DeclarationParsingResult::Declaration& decl =
1867 : for_info->parsing_result.declarations[0];
1868 : Variable* temp = NewTemporary(ast_value_factory()->dot_for_string());
1869 : ScopedPtrList<Statement> each_initialization_statements(pointer_buffer());
1870 : DCHECK_IMPLIES(!has_error(), decl.pattern != nullptr);
1871 213125 : decl.initializer = factory()->NewVariableProxy(temp, for_info->position);
1872 106562 : InitializeVariables(&each_initialization_statements, NORMAL_VARIABLE, &decl);
1873 :
1874 106563 : *body_block = factory()->NewBlock(3, false);
1875 : (*body_block)
1876 : ->statements()
1877 213129 : ->Add(factory()->NewBlock(true, each_initialization_statements), zone());
1878 213127 : *each_variable = factory()->NewVariableProxy(temp, for_info->position);
1879 106565 : }
1880 :
1881 : // Create a TDZ for any lexically-bound names in for in/of statements.
1882 106560 : Block* Parser::CreateForEachStatementTDZ(Block* init_block,
1883 : const ForInfo& for_info) {
1884 106560 : if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) {
1885 : DCHECK_NULL(init_block);
1886 :
1887 86833 : init_block = factory()->NewBlock(1, false);
1888 :
1889 274858 : for (const AstRawString* bound_name : for_info.bound_names) {
1890 : // TODO(adamk): This needs to be some sort of special
1891 : // INTERNAL variable that's invisible to the debugger
1892 : // but visible to everything else.
1893 : VariableProxy* tdz_proxy = DeclareBoundVariable(
1894 94011 : bound_name, VariableMode::kLet, kNoSourcePosition);
1895 : tdz_proxy->var()->set_initializer_position(position());
1896 : }
1897 : }
1898 106562 : return init_block;
1899 : }
1900 :
1901 17503 : Statement* Parser::DesugarLexicalBindingsInForStatement(
1902 : ForStatement* loop, Statement* init, Expression* cond, Statement* next,
1903 : Statement* body, Scope* inner_scope, const ForInfo& for_info) {
1904 : // ES6 13.7.4.8 specifies that on each loop iteration the let variables are
1905 : // copied into a new environment. Moreover, the "next" statement must be
1906 : // evaluated not in the environment of the just completed iteration but in
1907 : // that of the upcoming one. We achieve this with the following desugaring.
1908 : // Extra care is needed to preserve the completion value of the original loop.
1909 : //
1910 : // We are given a for statement of the form
1911 : //
1912 : // labels: for (let/const x = i; cond; next) body
1913 : //
1914 : // and rewrite it as follows. Here we write {{ ... }} for init-blocks, ie.,
1915 : // blocks whose ignore_completion_value_ flag is set.
1916 : //
1917 : // {
1918 : // let/const x = i;
1919 : // temp_x = x;
1920 : // first = 1;
1921 : // undefined;
1922 : // outer: for (;;) {
1923 : // let/const x = temp_x;
1924 : // {{ if (first == 1) {
1925 : // first = 0;
1926 : // } else {
1927 : // next;
1928 : // }
1929 : // flag = 1;
1930 : // if (!cond) break;
1931 : // }}
1932 : // labels: for (; flag == 1; flag = 0, temp_x = x) {
1933 : // body
1934 : // }
1935 : // {{ if (flag == 1) // Body used break.
1936 : // break;
1937 : // }}
1938 : // }
1939 : // }
1940 :
1941 : DCHECK_GT(for_info.bound_names.length(), 0);
1942 : ScopedPtrList<Variable> temps(pointer_buffer());
1943 :
1944 : Block* outer_block =
1945 35006 : factory()->NewBlock(for_info.bound_names.length() + 4, false);
1946 :
1947 : // Add statement: let/const x = i.
1948 17503 : outer_block->statements()->Add(init, zone());
1949 :
1950 : const AstRawString* temp_name = ast_value_factory()->dot_for_string();
1951 :
1952 : // For each lexical variable x:
1953 : // make statement: temp_x = x.
1954 64561 : for (const AstRawString* bound_name : for_info.bound_names) {
1955 : VariableProxy* proxy = NewUnresolved(bound_name);
1956 : Variable* temp = NewTemporary(temp_name);
1957 : VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
1958 : Assignment* assignment = factory()->NewAssignment(Token::ASSIGN, temp_proxy,
1959 23529 : proxy, kNoSourcePosition);
1960 : Statement* assignment_statement =
1961 23529 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
1962 23529 : outer_block->statements()->Add(assignment_statement, zone());
1963 : temps.Add(temp);
1964 : }
1965 :
1966 : Variable* first = nullptr;
1967 : // Make statement: first = 1.
1968 17503 : if (next) {
1969 : first = NewTemporary(temp_name);
1970 : VariableProxy* first_proxy = factory()->NewVariableProxy(first);
1971 : Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
1972 : Assignment* assignment = factory()->NewAssignment(
1973 2550 : Token::ASSIGN, first_proxy, const1, kNoSourcePosition);
1974 : Statement* assignment_statement =
1975 2550 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
1976 2550 : outer_block->statements()->Add(assignment_statement, zone());
1977 : }
1978 :
1979 : // make statement: undefined;
1980 35006 : outer_block->statements()->Add(
1981 : factory()->NewExpressionStatement(
1982 : factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
1983 17503 : zone());
1984 :
1985 : // Make statement: outer: for (;;)
1986 : // Note that we don't actually create the label, or set this loop up as an
1987 : // explicit break target, instead handing it directly to those nodes that
1988 : // need to know about it. This should be safe because we don't run any code
1989 : // in this function that looks up break targets.
1990 : ForStatement* outer_loop =
1991 : factory()->NewForStatement(nullptr, nullptr, kNoSourcePosition);
1992 17503 : outer_block->statements()->Add(outer_loop, zone());
1993 : outer_block->set_scope(scope());
1994 :
1995 17503 : Block* inner_block = factory()->NewBlock(3, false);
1996 : {
1997 17503 : BlockState block_state(&scope_, inner_scope);
1998 :
1999 : Block* ignore_completion_block =
2000 17503 : factory()->NewBlock(for_info.bound_names.length() + 3, true);
2001 : ScopedPtrList<Variable> inner_vars(pointer_buffer());
2002 : // For each let variable x:
2003 : // make statement: let/const x = temp_x.
2004 64561 : for (int i = 0; i < for_info.bound_names.length(); i++) {
2005 23529 : VariableProxy* proxy = DeclareBoundVariable(
2006 23529 : for_info.bound_names[i], for_info.parsing_result.descriptor.mode,
2007 23529 : kNoSourcePosition);
2008 : inner_vars.Add(proxy->var());
2009 : VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
2010 : Assignment* assignment = factory()->NewAssignment(
2011 23529 : Token::INIT, proxy, temp_proxy, kNoSourcePosition);
2012 : Statement* assignment_statement =
2013 23529 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2014 23529 : int declaration_pos = for_info.parsing_result.descriptor.declaration_pos;
2015 : DCHECK_NE(declaration_pos, kNoSourcePosition);
2016 : proxy->var()->set_initializer_position(declaration_pos);
2017 23529 : ignore_completion_block->statements()->Add(assignment_statement, zone());
2018 : }
2019 :
2020 : // Make statement: if (first == 1) { first = 0; } else { next; }
2021 17503 : if (next) {
2022 : DCHECK(first);
2023 : Expression* compare = nullptr;
2024 : // Make compare expression: first == 1.
2025 : {
2026 : Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2027 : VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2028 : compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1,
2029 : kNoSourcePosition);
2030 : }
2031 : Statement* clear_first = nullptr;
2032 : // Make statement: first = 0.
2033 : {
2034 : VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2035 : Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
2036 : Assignment* assignment = factory()->NewAssignment(
2037 2550 : Token::ASSIGN, first_proxy, const0, kNoSourcePosition);
2038 : clear_first =
2039 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2040 : }
2041 : Statement* clear_first_or_next = factory()->NewIfStatement(
2042 2550 : compare, clear_first, next, kNoSourcePosition);
2043 2550 : ignore_completion_block->statements()->Add(clear_first_or_next, zone());
2044 : }
2045 :
2046 : Variable* flag = NewTemporary(temp_name);
2047 : // Make statement: flag = 1.
2048 : {
2049 : VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2050 : Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2051 : Assignment* assignment = factory()->NewAssignment(
2052 17503 : Token::ASSIGN, flag_proxy, const1, kNoSourcePosition);
2053 : Statement* assignment_statement =
2054 17503 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2055 17503 : ignore_completion_block->statements()->Add(assignment_statement, zone());
2056 : }
2057 :
2058 : // Make statement: if (!cond) break.
2059 17503 : if (cond) {
2060 : Statement* stop =
2061 : factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
2062 : Statement* noop = factory()->EmptyStatement();
2063 23474 : ignore_completion_block->statements()->Add(
2064 : factory()->NewIfStatement(cond, noop, stop, cond->position()),
2065 11737 : zone());
2066 : }
2067 :
2068 35006 : inner_block->statements()->Add(ignore_completion_block, zone());
2069 : // Make cond expression for main loop: flag == 1.
2070 : Expression* flag_cond = nullptr;
2071 : {
2072 : Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2073 : VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2074 : flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
2075 : kNoSourcePosition);
2076 : }
2077 :
2078 : // Create chain of expressions "flag = 0, temp_x = x, ..."
2079 : Statement* compound_next_statement = nullptr;
2080 : {
2081 : Expression* compound_next = nullptr;
2082 : // Make expression: flag = 0.
2083 : {
2084 : VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2085 : Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
2086 : compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy,
2087 17503 : const0, kNoSourcePosition);
2088 : }
2089 :
2090 : // Make the comma-separated list of temp_x = x assignments.
2091 17503 : int inner_var_proxy_pos = scanner()->location().beg_pos;
2092 64561 : for (int i = 0; i < for_info.bound_names.length(); i++) {
2093 : VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
2094 : VariableProxy* proxy =
2095 : factory()->NewVariableProxy(inner_vars.at(i), inner_var_proxy_pos);
2096 : Assignment* assignment = factory()->NewAssignment(
2097 23529 : Token::ASSIGN, temp_proxy, proxy, kNoSourcePosition);
2098 : compound_next = factory()->NewBinaryOperation(
2099 : Token::COMMA, compound_next, assignment, kNoSourcePosition);
2100 : }
2101 :
2102 : compound_next_statement =
2103 : factory()->NewExpressionStatement(compound_next, kNoSourcePosition);
2104 : }
2105 :
2106 : // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
2107 : // Note that we re-use the original loop node, which retains its labels
2108 : // and ensures that any break or continue statements in body point to
2109 : // the right place.
2110 : loop->Initialize(nullptr, flag_cond, compound_next_statement, body);
2111 17503 : inner_block->statements()->Add(loop, zone());
2112 :
2113 : // Make statement: {{if (flag == 1) break;}}
2114 : {
2115 : Expression* compare = nullptr;
2116 : // Make compare expresion: flag == 1.
2117 : {
2118 : Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2119 : VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2120 : compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
2121 : kNoSourcePosition);
2122 : }
2123 : Statement* stop =
2124 : factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
2125 : Statement* empty = factory()->EmptyStatement();
2126 : Statement* if_flag_break =
2127 : factory()->NewIfStatement(compare, stop, empty, kNoSourcePosition);
2128 17503 : inner_block->statements()->Add(IgnoreCompletion(if_flag_break), zone());
2129 : }
2130 :
2131 : inner_block->set_scope(inner_scope);
2132 : }
2133 :
2134 : outer_loop->Initialize(nullptr, nullptr, nullptr, inner_block);
2135 :
2136 17503 : return outer_block;
2137 : }
2138 :
2139 0 : void ParserFormalParameters::ValidateDuplicate(Parser* parser) const {
2140 794473 : if (has_duplicate()) {
2141 2666 : parser->ReportMessageAt(duplicate_loc, MessageTemplate::kParamDupe);
2142 : }
2143 0 : }
2144 0 : void ParserFormalParameters::ValidateStrictMode(Parser* parser) const {
2145 740439 : if (strict_error_loc.IsValid()) {
2146 1910 : parser->ReportMessageAt(strict_error_loc, strict_error_message);
2147 : }
2148 0 : }
2149 :
2150 128239 : void Parser::AddArrowFunctionFormalParameters(
2151 : ParserFormalParameters* parameters, Expression* expr, int end_pos) {
2152 : // ArrowFunctionFormals ::
2153 : // Nary(Token::COMMA, VariableProxy*, Tail)
2154 : // Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail)
2155 : // Tail
2156 : // NonTailArrowFunctionFormals ::
2157 : // Binary(Token::COMMA, NonTailArrowFunctionFormals, VariableProxy)
2158 : // VariableProxy
2159 : // Tail ::
2160 : // VariableProxy
2161 : // Spread(VariableProxy)
2162 : //
2163 : // We need to visit the parameters in left-to-right order
2164 : //
2165 :
2166 : // For the Nary case, we simply visit the parameters in a loop.
2167 132973 : if (expr->IsNaryOperation()) {
2168 4734 : NaryOperation* nary = expr->AsNaryOperation();
2169 : // The classifier has already run, so we know that the expression is a valid
2170 : // arrow function formals production.
2171 : DCHECK_EQ(nary->op(), Token::COMMA);
2172 : // Each op position is the end position of the *previous* expr, with the
2173 : // second (i.e. first "subsequent") op position being the end position of
2174 : // the first child expression.
2175 : Expression* next = nary->first();
2176 25008 : for (size_t i = 0; i < nary->subsequent_length(); ++i) {
2177 : AddArrowFunctionFormalParameters(parameters, next,
2178 10137 : nary->subsequent_op_position(i));
2179 : next = nary->subsequent(i);
2180 : }
2181 : AddArrowFunctionFormalParameters(parameters, next, end_pos);
2182 : return;
2183 : }
2184 :
2185 : // For the binary case, we recurse on the left-hand side of binary comma
2186 : // expressions.
2187 128239 : if (expr->IsBinaryOperation()) {
2188 14509 : BinaryOperation* binop = expr->AsBinaryOperation();
2189 : // The classifier has already run, so we know that the expression is a valid
2190 : // arrow function formals production.
2191 : DCHECK_EQ(binop->op(), Token::COMMA);
2192 : Expression* left = binop->left();
2193 : Expression* right = binop->right();
2194 : int comma_pos = binop->position();
2195 14509 : AddArrowFunctionFormalParameters(parameters, left, comma_pos);
2196 : // LHS of comma expression should be unparenthesized.
2197 : expr = right;
2198 : }
2199 :
2200 : // Only the right-most expression may be a rest parameter.
2201 : DCHECK(!parameters->has_rest);
2202 :
2203 : bool is_rest = expr->IsSpread();
2204 128239 : if (is_rest) {
2205 1534 : expr = expr->AsSpread()->expression();
2206 1534 : parameters->has_rest = true;
2207 : }
2208 : DCHECK_IMPLIES(parameters->is_simple, !is_rest);
2209 : DCHECK_IMPLIES(parameters->is_simple, expr->IsVariableProxy());
2210 :
2211 : Expression* initializer = nullptr;
2212 128239 : if (expr->IsAssignment()) {
2213 9922 : Assignment* assignment = expr->AsAssignment();
2214 : DCHECK(!assignment->IsCompoundAssignment());
2215 : initializer = assignment->value();
2216 : expr = assignment->target();
2217 : }
2218 :
2219 : AddFormalParameter(parameters, expr, initializer, end_pos, is_rest);
2220 : }
2221 :
2222 365706 : void Parser::DeclareArrowFunctionFormalParameters(
2223 : ParserFormalParameters* parameters, Expression* expr,
2224 : const Scanner::Location& params_loc) {
2225 469299 : if (expr->IsEmptyParentheses() || has_error()) return;
2226 :
2227 103593 : AddArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos);
2228 :
2229 103594 : 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 142482 : 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 142482 : function_state_->scope()->DeclareGeneratorObjectVar(
2244 142482 : ast_value_factory()->dot_generator_object_string());
2245 142482 : }
2246 :
2247 3874853 : 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 : 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 : bool is_wrapped = function_type == FunctionLiteral::kWrapped;
2263 : DCHECK_EQ(is_wrapped, arguments_for_wrapped_function != nullptr);
2264 :
2265 : int pos = function_token_pos == kNoSourcePosition ? peek_position()
2266 3874853 : : 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 : 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 3874853 : if (should_infer_name) {
2277 : function_name = ast_value_factory()->empty_string();
2278 : }
2279 :
2280 : FunctionLiteral::EagerCompileHint eager_compile_hint =
2281 7170569 : function_state_->next_function_is_likely_called() || is_wrapped
2282 : ? FunctionLiteral::kShouldEagerCompile
2283 7170483 : : 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 3874853 : eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
2323 : const bool is_top_level = AllowsLazyParsingWithoutUnresolvedVariables();
2324 3874869 : const bool is_eager_top_level_function = !is_lazy && is_top_level;
2325 3874869 : const bool is_lazy_top_level_function = is_lazy && is_top_level;
2326 : const bool is_lazy_inner_function = is_lazy && !is_top_level;
2327 :
2328 : RuntimeCallTimerScope runtime_timer(
2329 : runtime_call_stats_,
2330 3874869 : parsing_on_main_thread_
2331 : ? RuntimeCallCounterId::kParseFunctionLiteral
2332 3874869 : : RuntimeCallCounterId::kParseBackgroundFunctionLiteral);
2333 : base::ElapsedTimer timer;
2334 3874887 : 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 3874887 : 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 3165008 : parse_lazily() && is_eager_top_level_function &&
2360 3875019 : FLAG_parallel_compile_tasks && info()->parallel_tasks() &&
2361 : scanner()->stream()->can_be_cloned_for_parallel_access();
2362 :
2363 : // This may be modified later to reflect preparsing decision taken
2364 3165003 : bool should_preparse = (parse_lazily() && is_lazy_top_level_function) ||
2365 7052580 : should_preparse_inner || should_post_parallel_task;
2366 :
2367 : ScopedPtrList<Statement> body(pointer_buffer());
2368 3874887 : int expected_property_count = 0;
2369 3874887 : int suspend_count = -1;
2370 3874887 : int num_parameters = -1;
2371 3874887 : int function_length = -1;
2372 3874887 : bool has_duplicate_parameters = false;
2373 : int function_literal_id = GetNextFunctionLiteralId();
2374 3874887 : ProducedPreparseData* produced_preparse_data = nullptr;
2375 :
2376 : // This Scope lives in the main zone. We'll migrate data into that zone later.
2377 3874887 : Zone* parse_zone = should_preparse ? &preparser_zone_ : zone();
2378 3874887 : DeclarationScope* scope = NewFunctionScope(kind, parse_zone);
2379 3874930 : SetLanguageMode(scope, language_mode);
2380 : #ifdef DEBUG
2381 : scope->SetScopeName(function_name);
2382 : #endif
2383 :
2384 7749729 : if (!is_wrapped && V8_UNLIKELY(!Check(Token::LPAREN))) {
2385 17677 : ReportUnexpectedToken(Next());
2386 17677 : return nullptr;
2387 : }
2388 : 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 6451001 : should_preparse &&
2397 2593730 : SkipFunction(function_name, kind, function_type, scope, &num_parameters,
2398 : &function_length, &produced_preparse_data);
2399 :
2400 3857271 : if (!did_preparse_successfully) {
2401 : // If skipping aborted, it rewound the scanner until before the LPAREN.
2402 : // Consume it in that case.
2403 1306767 : if (should_preparse) Consume(Token::LPAREN);
2404 : should_post_parallel_task = false;
2405 : ParseFunction(&body, function_name, pos, kind, function_type, scope,
2406 : &num_parameters, &function_length, &has_duplicate_parameters,
2407 : &expected_property_count, &suspend_count,
2408 1306767 : arguments_for_wrapped_function);
2409 : }
2410 :
2411 3857245 : if (V8_UNLIKELY(FLAG_log_function_events)) {
2412 55 : double ms = timer.Elapsed().InMillisecondsF();
2413 : const char* event_name =
2414 : should_preparse
2415 : ? (is_top_level ? "preparse-no-resolution" : "preparse-resolution")
2416 55 : : "full-parse";
2417 55 : logger_->FunctionEvent(
2418 : event_name, script_id(), ms, scope->start_position(),
2419 : scope->end_position(),
2420 : reinterpret_cast<const char*>(function_name->raw_data()),
2421 55 : function_name->byte_length());
2422 : }
2423 3857245 : if (V8_UNLIKELY(TracingFlags::is_runtime_stats_enabled()) &&
2424 : did_preparse_successfully) {
2425 : const RuntimeCallCounterId counters[2] = {
2426 : RuntimeCallCounterId::kPreParseBackgroundWithVariableResolution,
2427 2 : RuntimeCallCounterId::kPreParseWithVariableResolution};
2428 2 : if (runtime_call_stats_) {
2429 2 : runtime_call_stats_->CorrectCurrentCounterId(
2430 4 : counters[parsing_on_main_thread_]);
2431 : }
2432 : }
2433 :
2434 : // Validate function name. We can do this only after parsing the function,
2435 : // since the function can declare itself strict.
2436 : language_mode = scope->language_mode();
2437 : CheckFunctionName(language_mode, function_name, function_name_validity,
2438 3857245 : function_name_location);
2439 :
2440 3857245 : if (is_strict(language_mode)) {
2441 878076 : CheckStrictOctalLiteral(scope->start_position(), scope->end_position());
2442 : }
2443 :
2444 : FunctionLiteral::ParameterFlag duplicate_parameters =
2445 : has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
2446 3857233 : : FunctionLiteral::kNoDuplicateParameters;
2447 :
2448 : // Note that the FunctionLiteral needs to be created in the main Zone again.
2449 3857233 : FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
2450 : function_name, scope, body, expected_property_count, num_parameters,
2451 : function_length, duplicate_parameters, function_type, eager_compile_hint,
2452 3857233 : pos, true, function_literal_id, produced_preparse_data);
2453 : function_literal->set_function_token_position(function_token_pos);
2454 3857200 : function_literal->set_suspend_count(suspend_count);
2455 :
2456 3857200 : if (should_post_parallel_task) {
2457 : // Start a parallel parse / compile task on the compiler dispatcher.
2458 55 : info()->parallel_tasks()->Enqueue(info(), function_name, function_literal);
2459 : }
2460 :
2461 3857202 : if (should_infer_name) {
2462 : fni_.AddFunction(function_literal);
2463 : }
2464 : return function_literal;
2465 : }
2466 :
2467 2625651 : bool Parser::SkipFunction(const AstRawString* function_name, FunctionKind kind,
2468 : FunctionLiteral::FunctionType function_type,
2469 : DeclarationScope* function_scope, int* num_parameters,
2470 : int* function_length,
2471 : ProducedPreparseData** produced_preparse_data) {
2472 2625651 : FunctionState function_state(&function_state_, &scope_, function_scope);
2473 2625651 : function_scope->set_zone(&preparser_zone_);
2474 :
2475 : DCHECK_NE(kNoSourcePosition, function_scope->start_position());
2476 : DCHECK_EQ(kNoSourcePosition, parameters_end_pos_);
2477 :
2478 : DCHECK_IMPLIES(IsArrowFunction(kind),
2479 : scanner()->current_token() == Token::ARROW);
2480 :
2481 : // FIXME(marja): There are 2 ways to skip functions now. Unify them.
2482 2625651 : if (consumed_preparse_data_) {
2483 : int end_position;
2484 : LanguageMode language_mode;
2485 : int num_inner_functions;
2486 : bool uses_super_property;
2487 60793 : if (stack_overflow()) return true;
2488 : *produced_preparse_data =
2489 60793 : consumed_preparse_data_->GetDataForSkippableFunction(
2490 : main_zone(), function_scope->start_position(), &end_position,
2491 : num_parameters, function_length, &num_inner_functions,
2492 121586 : &uses_super_property, &language_mode);
2493 :
2494 : function_scope->outer_scope()->SetMustUsePreparseData();
2495 : function_scope->set_is_skipped_function(true);
2496 60793 : function_scope->set_end_position(end_position);
2497 60793 : scanner()->SeekForward(end_position - 1);
2498 60793 : Expect(Token::RBRACE);
2499 60793 : SetLanguageMode(function_scope, language_mode);
2500 60793 : if (uses_super_property) {
2501 : function_scope->RecordSuperPropertyUsage();
2502 : }
2503 60793 : SkipFunctionLiterals(num_inner_functions);
2504 60793 : function_scope->ResetAfterPreparsing(ast_value_factory_, false);
2505 60793 : return true;
2506 : }
2507 :
2508 : Scanner::BookmarkScope bookmark(scanner());
2509 2564858 : bookmark.Set(function_scope->start_position());
2510 :
2511 : UnresolvedList::Iterator unresolved_private_tail;
2512 2564851 : ClassScope* closest_class_scope = function_scope->GetClassScope();
2513 2564852 : if (closest_class_scope != nullptr) {
2514 : unresolved_private_tail =
2515 369766 : closest_class_scope->GetUnresolvedPrivateNameTail();
2516 : }
2517 :
2518 : // With no cached data, we partially parse the function, without building an
2519 : // AST. This gathers the data needed to build a lazy function.
2520 7694605 : TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse");
2521 :
2522 2564865 : PreParser::PreParseResult result = reusable_preparser()->PreParseFunction(
2523 : function_name, kind, function_type, function_scope, use_counts_,
2524 2564840 : produced_preparse_data, this->script_id());
2525 :
2526 2564819 : if (result == PreParser::kPreParseStackOverflow) {
2527 : // Propagate stack overflow.
2528 : set_stack_overflow();
2529 2564784 : } else if (pending_error_handler()->has_error_unidentifiable_by_preparser()) {
2530 : // Make sure we don't re-preparse inner functions of the aborted function.
2531 : // The error might be in an inner function.
2532 49034 : allow_lazy_ = false;
2533 49034 : mode_ = PARSE_EAGERLY;
2534 : DCHECK(!pending_error_handler()->stack_overflow());
2535 : // If we encounter an error that the preparser can not identify we reset to
2536 : // the state before preparsing. The caller may then fully parse the function
2537 : // to identify the actual error.
2538 49034 : bookmark.Apply();
2539 49034 : if (closest_class_scope != nullptr) {
2540 : closest_class_scope->ResetUnresolvedPrivateNameTail(
2541 5789 : unresolved_private_tail);
2542 : }
2543 49034 : function_scope->ResetAfterPreparsing(ast_value_factory_, true);
2544 : pending_error_handler()->clear_unidentifiable_error();
2545 49034 : return false;
2546 2515750 : } else if (pending_error_handler()->has_pending_error()) {
2547 : DCHECK(!pending_error_handler()->stack_overflow());
2548 : DCHECK(has_error());
2549 : } else {
2550 : DCHECK(!pending_error_handler()->stack_overflow());
2551 2504658 : set_allow_eval_cache(reusable_preparser()->allow_eval_cache());
2552 :
2553 2504679 : PreParserLogger* logger = reusable_preparser()->logger();
2554 : function_scope->set_end_position(logger->end());
2555 2504670 : Expect(Token::RBRACE);
2556 : total_preparse_skipped_ +=
2557 2504712 : function_scope->end_position() - function_scope->start_position();
2558 2504712 : *num_parameters = logger->num_parameters();
2559 2504712 : *function_length = logger->function_length();
2560 : SkipFunctionLiterals(logger->num_inner_functions());
2561 2504712 : if (closest_class_scope != nullptr) {
2562 : closest_class_scope->MigrateUnresolvedPrivateNameTail(
2563 363582 : factory(), unresolved_private_tail);
2564 : }
2565 2504712 : function_scope->AnalyzePartially(this, factory());
2566 : }
2567 :
2568 : return true;
2569 : }
2570 :
2571 37931 : Block* Parser::BuildParameterInitializationBlock(
2572 : const ParserFormalParameters& parameters) {
2573 : DCHECK(!parameters.is_simple);
2574 : DCHECK(scope()->is_function_scope());
2575 : DCHECK_EQ(scope(), parameters.scope);
2576 : ScopedPtrList<Statement> init_statements(pointer_buffer());
2577 : int index = 0;
2578 98721 : for (auto parameter : parameters.params) {
2579 : Expression* initial_value =
2580 60790 : factory()->NewVariableProxy(parameters.scope->parameter(index));
2581 60790 : if (parameter->initializer() != nullptr) {
2582 : // IS_UNDEFINED($param) ? initializer : $param
2583 :
2584 : auto condition = factory()->NewCompareOperation(
2585 : Token::EQ_STRICT,
2586 21104 : factory()->NewVariableProxy(parameters.scope->parameter(index)),
2587 : factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
2588 : initial_value =
2589 : factory()->NewConditional(condition, parameter->initializer(),
2590 : initial_value, kNoSourcePosition);
2591 : }
2592 :
2593 : Scope* param_scope = scope();
2594 : ScopedPtrList<Statement>* param_init_statements = &init_statements;
2595 :
2596 60790 : base::Optional<ScopedPtrList<Statement>> non_simple_param_init_statements;
2597 101418 : if (!parameter->is_simple() &&
2598 40628 : scope()->AsDeclarationScope()->calls_sloppy_eval()) {
2599 1167 : param_scope = NewVarblockScope();
2600 1167 : param_scope->set_start_position(parameter->pattern->position());
2601 1167 : param_scope->set_end_position(parameter->initializer_end_position);
2602 : param_scope->RecordEvalCall();
2603 1167 : non_simple_param_init_statements.emplace(pointer_buffer());
2604 : param_init_statements = &non_simple_param_init_statements.value();
2605 : // Rewrite the outer initializer to point to param_scope
2606 1167 : ReparentExpressionScope(stack_limit(), parameter->pattern, param_scope);
2607 1167 : ReparentExpressionScope(stack_limit(), initial_value, param_scope);
2608 : }
2609 :
2610 60790 : BlockState block_state(&scope_, param_scope);
2611 60790 : DeclarationParsingResult::Declaration decl(parameter->pattern,
2612 : initial_value);
2613 :
2614 60790 : InitializeVariables(param_init_statements, PARAMETER_VARIABLE, &decl);
2615 :
2616 60790 : if (param_init_statements != &init_statements) {
2617 : DCHECK_EQ(param_init_statements,
2618 : &non_simple_param_init_statements.value());
2619 : Block* param_block =
2620 1167 : factory()->NewBlock(true, *non_simple_param_init_statements);
2621 : non_simple_param_init_statements.reset();
2622 : param_block->set_scope(param_scope);
2623 1167 : param_scope = param_scope->FinalizeBlockScope();
2624 : init_statements.Add(param_block);
2625 : }
2626 60790 : ++index;
2627 : }
2628 75862 : return factory()->NewBlock(true, init_statements);
2629 : }
2630 :
2631 69036 : Scope* Parser::NewHiddenCatchScope() {
2632 69036 : Scope* catch_scope = NewScopeWithParent(scope(), CATCH_SCOPE);
2633 : bool was_added;
2634 : catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(),
2635 69036 : VariableMode::kVar, NORMAL_VARIABLE, &was_added);
2636 : DCHECK(was_added);
2637 : catch_scope->set_is_hidden();
2638 69036 : return catch_scope;
2639 : }
2640 :
2641 44502 : Block* Parser::BuildRejectPromiseOnException(Block* inner_block) {
2642 : // try {
2643 : // <inner_block>
2644 : // } catch (.catch) {
2645 : // return %_AsyncFunctionReject(.generator_object, .catch, can_suspend);
2646 : // }
2647 44502 : Block* result = factory()->NewBlock(1, true);
2648 :
2649 : // catch (.catch) {
2650 : // return %_AsyncFunctionReject(.generator_object, .catch, can_suspend)
2651 : // }
2652 44502 : Scope* catch_scope = NewHiddenCatchScope();
2653 :
2654 : Expression* reject_promise;
2655 : {
2656 : ScopedPtrList<Expression> args(pointer_buffer());
2657 : args.Add(factory()->NewVariableProxy(
2658 44502 : function_state_->scope()->generator_object_var()));
2659 : args.Add(factory()->NewVariableProxy(catch_scope->catch_variable()));
2660 44502 : args.Add(factory()->NewBooleanLiteral(function_state_->CanSuspend(),
2661 : kNoSourcePosition));
2662 : reject_promise = factory()->NewCallRuntime(
2663 44502 : Runtime::kInlineAsyncFunctionReject, args, kNoSourcePosition);
2664 : }
2665 : Block* catch_block = IgnoreCompletion(
2666 44502 : factory()->NewReturnStatement(reject_promise, kNoSourcePosition));
2667 :
2668 : TryStatement* try_catch_statement =
2669 : factory()->NewTryCatchStatementForAsyncAwait(
2670 : inner_block, catch_scope, catch_block, kNoSourcePosition);
2671 89004 : result->statements()->Add(try_catch_statement, zone());
2672 44502 : return result;
2673 : }
2674 :
2675 90541 : Expression* Parser::BuildInitialYield(int pos, FunctionKind kind) {
2676 : Expression* yield_result = factory()->NewVariableProxy(
2677 90541 : function_state_->scope()->generator_object_var());
2678 : // The position of the yield is important for reporting the exception
2679 : // caused by calling the .throw method on a generator suspended at the
2680 : // initial yield (i.e. right after generator instantiation).
2681 90541 : function_state_->AddSuspend();
2682 : return factory()->NewYield(yield_result, scope()->start_position(),
2683 90541 : Suspend::kOnExceptionThrow);
2684 : }
2685 :
2686 1306764 : void Parser::ParseFunction(
2687 : ScopedPtrList<Statement>* body, const AstRawString* function_name, int pos,
2688 : FunctionKind kind, FunctionLiteral::FunctionType function_type,
2689 : DeclarationScope* function_scope, int* num_parameters, int* function_length,
2690 : bool* has_duplicate_parameters, int* expected_property_count,
2691 : int* suspend_count,
2692 : ZonePtrList<const AstRawString>* arguments_for_wrapped_function) {
2693 1306764 : ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
2694 :
2695 1306764 : FunctionState function_state(&function_state_, &scope_, function_scope);
2696 :
2697 : bool is_wrapped = function_type == FunctionLiteral::kWrapped;
2698 :
2699 1306764 : int expected_parameters_end_pos = parameters_end_pos_;
2700 1306764 : if (expected_parameters_end_pos != kNoSourcePosition) {
2701 : // This is the first function encountered in a CreateDynamicFunction eval.
2702 341220 : parameters_end_pos_ = kNoSourcePosition;
2703 : // The function name should have been ignored, giving us the empty string
2704 : // here.
2705 : DCHECK_EQ(function_name, ast_value_factory()->empty_string());
2706 : }
2707 :
2708 : ParserFormalParameters formals(function_scope);
2709 :
2710 : {
2711 : ParameterDeclarationParsingScope formals_scope(this);
2712 1306764 : if (is_wrapped) {
2713 : // For a function implicitly wrapped in function header and footer, the
2714 : // function arguments are provided separately to the source, and are
2715 : // declared directly here.
2716 124 : for (const AstRawString* arg : *arguments_for_wrapped_function) {
2717 : const bool is_rest = false;
2718 : Expression* argument = ExpressionFromIdentifier(arg, kNoSourcePosition);
2719 : AddFormalParameter(&formals, argument, NullExpression(),
2720 : kNoSourcePosition, is_rest);
2721 : }
2722 : DCHECK_EQ(arguments_for_wrapped_function->length(),
2723 : formals.num_parameters());
2724 : DeclareFormalParameters(&formals);
2725 : } else {
2726 : // For a regular function, the function arguments are parsed from source.
2727 : DCHECK_NULL(arguments_for_wrapped_function);
2728 1306680 : ParseFormalParameterList(&formals);
2729 1306675 : if (expected_parameters_end_pos != kNoSourcePosition) {
2730 : // Check for '(' or ')' shenanigans in the parameter string for dynamic
2731 : // functions.
2732 : int position = peek_position();
2733 341220 : if (position < expected_parameters_end_pos) {
2734 100 : ReportMessageAt(Scanner::Location(position, position + 1),
2735 50 : MessageTemplate::kArgStringTerminatesParametersEarly);
2736 50 : return;
2737 341170 : } else if (position > expected_parameters_end_pos) {
2738 36 : ReportMessageAt(Scanner::Location(expected_parameters_end_pos - 2,
2739 : expected_parameters_end_pos),
2740 18 : MessageTemplate::kUnexpectedEndOfArgString);
2741 18 : return;
2742 : }
2743 : }
2744 1306607 : Expect(Token::RPAREN);
2745 1306622 : int formals_end_position = scanner()->location().end_pos;
2746 :
2747 1306622 : CheckArityRestrictions(formals.arity, kind, formals.has_rest,
2748 : function_scope->start_position(),
2749 1306622 : formals_end_position);
2750 1306612 : Expect(Token::LBRACE);
2751 : }
2752 1306712 : formals.duplicate_loc = formals_scope.duplicate_location();
2753 : }
2754 :
2755 1306712 : *num_parameters = formals.num_parameters();
2756 1306712 : *function_length = formals.function_length;
2757 :
2758 1306712 : AcceptINScope scope(this, true);
2759 1306712 : ParseFunctionBody(body, function_name, pos, formals, kind, function_type,
2760 1306712 : FunctionBodyType::kBlock);
2761 :
2762 1306708 : *has_duplicate_parameters = formals.has_duplicate();
2763 :
2764 1306708 : *expected_property_count = function_state.expected_property_count();
2765 1306708 : *suspend_count = function_state.suspend_count();
2766 : }
2767 :
2768 0 : void Parser::DeclareClassVariable(const AstRawString* name,
2769 : ClassInfo* class_info, int class_token_pos) {
2770 : #ifdef DEBUG
2771 : scope()->SetScopeName(name);
2772 : #endif
2773 :
2774 186202 : if (name != nullptr) {
2775 : VariableProxy* proxy =
2776 124169 : DeclareBoundVariable(name, VariableMode::kConst, class_token_pos);
2777 124169 : class_info->variable = proxy->var();
2778 : }
2779 0 : }
2780 :
2781 : // TODO(gsathya): Ideally, this should just bypass scope analysis and
2782 : // allocate a slot directly on the context. We should just store this
2783 : // index in the AST, instead of storing the variable.
2784 5214 : Variable* Parser::CreateSyntheticContextVariable(const AstRawString* name) {
2785 : VariableProxy* proxy =
2786 5214 : DeclareBoundVariable(name, VariableMode::kConst, kNoSourcePosition);
2787 : proxy->var()->ForceContextAllocation();
2788 5214 : return proxy->var();
2789 : }
2790 :
2791 10075 : Variable* Parser::CreatePrivateNameVariable(ClassScope* scope,
2792 : const AstRawString* name) {
2793 : DCHECK_NOT_NULL(name);
2794 : int begin = position();
2795 : int end = end_position();
2796 10075 : bool was_added = false;
2797 10075 : Variable* var = scope->DeclarePrivateName(name, &was_added);
2798 10075 : if (!was_added) {
2799 : Scanner::Location loc(begin, end);
2800 400 : ReportMessageAt(loc, MessageTemplate::kVarRedeclaration, var->raw_name());
2801 : }
2802 : VariableProxy* proxy = factory()->NewVariableProxy(var, begin);
2803 10075 : return proxy->var();
2804 : }
2805 :
2806 32272 : void Parser::DeclareClassField(ClassScope* scope,
2807 : ClassLiteralProperty* property,
2808 : const AstRawString* property_name,
2809 : bool is_static, bool is_computed_name,
2810 : bool is_private, ClassInfo* class_info) {
2811 : DCHECK(allow_harmony_public_fields() || allow_harmony_private_fields());
2812 :
2813 32272 : if (is_static) {
2814 8889 : class_info->static_fields->Add(property, zone());
2815 : } else {
2816 23383 : class_info->instance_fields->Add(property, zone());
2817 : }
2818 :
2819 : DCHECK_IMPLIES(is_computed_name, !is_private);
2820 32272 : if (is_computed_name) {
2821 : // We create a synthetic variable name here so that scope
2822 : // analysis doesn't dedupe the vars.
2823 : Variable* computed_name_var =
2824 5214 : CreateSyntheticContextVariable(ClassFieldVariableName(
2825 5214 : ast_value_factory(), class_info->computed_field_count));
2826 5214 : property->set_computed_name_var(computed_name_var);
2827 5214 : class_info->properties->Add(property, zone());
2828 27058 : } else if (is_private) {
2829 : Variable* private_name_var =
2830 10075 : CreatePrivateNameVariable(scope, property_name);
2831 10075 : int pos = property->value()->position();
2832 10075 : if (pos == kNoSourcePosition) {
2833 : pos = property->key()->position();
2834 : }
2835 : private_name_var->set_initializer_position(pos);
2836 : property->set_private_name_var(private_name_var);
2837 10075 : class_info->properties->Add(property, zone());
2838 : }
2839 32272 : }
2840 :
2841 : // This method declares a property of the given class. It updates the
2842 : // following fields of class_info, as appropriate:
2843 : // - constructor
2844 : // - properties
2845 382818 : void Parser::DeclareClassProperty(ClassScope* scope,
2846 : const AstRawString* class_name,
2847 : ClassLiteralProperty* property,
2848 : bool is_constructor, ClassInfo* class_info) {
2849 382818 : if (is_constructor) {
2850 : DCHECK(!class_info->constructor);
2851 42738 : class_info->constructor = property->value()->AsFunctionLiteral();
2852 : DCHECK_NOT_NULL(class_info->constructor);
2853 21369 : class_info->constructor->set_raw_name(
2854 : class_name != nullptr ? ast_value_factory()->NewConsString(class_name)
2855 : : nullptr);
2856 : return;
2857 : }
2858 :
2859 361449 : class_info->properties->Add(property, zone());
2860 : }
2861 :
2862 27101 : FunctionLiteral* Parser::CreateInitializerFunction(
2863 : const char* name, DeclarationScope* scope,
2864 : ZonePtrList<ClassLiteral::Property>* fields) {
2865 : DCHECK_EQ(scope->function_kind(),
2866 : FunctionKind::kClassMembersInitializerFunction);
2867 : // function() { .. class fields initializer .. }
2868 : ScopedPtrList<Statement> statements(pointer_buffer());
2869 : InitializeClassMembersStatement* static_fields =
2870 : factory()->NewInitializeClassMembersStatement(fields, kNoSourcePosition);
2871 : statements.Add(static_fields);
2872 27101 : return factory()->NewFunctionLiteral(
2873 : ast_value_factory()->GetOneByteString(name), scope, statements, 0, 0, 0,
2874 : FunctionLiteral::kNoDuplicateParameters,
2875 : FunctionLiteral::kAnonymousExpression,
2876 : FunctionLiteral::kShouldEagerCompile, scope->start_position(), false,
2877 54202 : GetNextFunctionLiteralId());
2878 : }
2879 :
2880 : // This method generates a ClassLiteral AST node.
2881 : // It uses the following fields of class_info:
2882 : // - constructor (if missing, it updates it with a default constructor)
2883 : // - proxy
2884 : // - extends
2885 : // - properties
2886 : // - has_name_static_property
2887 : // - has_static_computed_names
2888 110380 : Expression* Parser::RewriteClassLiteral(ClassScope* block_scope,
2889 : const AstRawString* name,
2890 : ClassInfo* class_info, int pos,
2891 : int end_pos) {
2892 : DCHECK_NOT_NULL(block_scope);
2893 : DCHECK_EQ(block_scope->scope_type(), CLASS_SCOPE);
2894 : DCHECK_EQ(block_scope->language_mode(), LanguageMode::kStrict);
2895 :
2896 110380 : bool has_extends = class_info->extends != nullptr;
2897 110380 : bool has_default_constructor = class_info->constructor == nullptr;
2898 110380 : if (has_default_constructor) {
2899 : class_info->constructor =
2900 89233 : DefaultConstructor(name, has_extends, pos, end_pos);
2901 : }
2902 :
2903 110380 : if (name != nullptr) {
2904 : DCHECK_NOT_NULL(class_info->variable);
2905 82329 : class_info->variable->set_initializer_position(end_pos);
2906 : }
2907 :
2908 : FunctionLiteral* static_fields_initializer = nullptr;
2909 110380 : if (class_info->has_static_class_fields) {
2910 8441 : static_fields_initializer = CreateInitializerFunction(
2911 : "<static_fields_initializer>", class_info->static_fields_scope,
2912 8441 : class_info->static_fields);
2913 : }
2914 :
2915 : FunctionLiteral* instance_members_initializer_function = nullptr;
2916 110380 : if (class_info->has_instance_members) {
2917 18660 : instance_members_initializer_function = CreateInitializerFunction(
2918 : "<instance_members_initializer>", class_info->instance_members_scope,
2919 18660 : class_info->instance_fields);
2920 18660 : class_info->constructor->set_requires_instance_members_initializer(true);
2921 18660 : class_info->constructor->add_expected_properties(
2922 18660 : class_info->instance_fields->length());
2923 : }
2924 :
2925 110380 : ClassLiteral* class_literal = factory()->NewClassLiteral(
2926 : block_scope, class_info->variable, class_info->extends,
2927 : class_info->constructor, class_info->properties,
2928 : static_fields_initializer, instance_members_initializer_function, pos,
2929 110380 : end_pos, class_info->has_name_static_property,
2930 110380 : class_info->has_static_computed_names, class_info->is_anonymous);
2931 :
2932 110380 : AddFunctionForNameInference(class_info->constructor);
2933 110380 : return class_literal;
2934 : }
2935 :
2936 11878 : bool Parser::IsPropertyWithPrivateFieldKey(Expression* expression) {
2937 11878 : if (!expression->IsProperty()) return false;
2938 7245 : Property* property = expression->AsProperty();
2939 :
2940 7245 : if (!property->key()->IsVariableProxy()) return false;
2941 1511 : VariableProxy* key = property->key()->AsVariableProxy();
2942 :
2943 1511 : return key->IsPrivateName();
2944 : }
2945 :
2946 8962 : void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) {
2947 : // For each var-binding that shadows a parameter, insert an assignment
2948 : // initializing the variable with the parameter.
2949 : Scope* inner_scope = inner_block->scope();
2950 : DCHECK(inner_scope->is_declaration_scope());
2951 : Scope* function_scope = inner_scope->outer_scope();
2952 : DCHECK(function_scope->is_function_scope());
2953 8962 : BlockState block_state(&scope_, inner_scope);
2954 28645 : for (Declaration* decl : *inner_scope->declarations()) {
2955 30252 : if (decl->var()->mode() != VariableMode::kVar ||
2956 : !decl->IsVariableDeclaration()) {
2957 18824 : continue;
2958 : }
2959 : const AstRawString* name = decl->var()->raw_name();
2960 : Variable* parameter = function_scope->LookupLocal(name);
2961 7053 : if (parameter == nullptr) continue;
2962 : VariableProxy* to = NewUnresolved(name);
2963 : VariableProxy* from = factory()->NewVariableProxy(parameter);
2964 : Expression* assignment =
2965 859 : factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition);
2966 : Statement* statement =
2967 859 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2968 859 : inner_block->statements()->InsertAt(0, statement, zone());
2969 : }
2970 8962 : }
2971 :
2972 2475475 : void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope) {
2973 : // For the outermost eval scope, we cannot hoist during parsing: let
2974 : // declarations in the surrounding scope may prevent hoisting, but the
2975 : // information is unaccessible during parsing. In this case, we hoist later in
2976 : // DeclarationScope::Analyze.
2977 2475475 : if (scope->is_eval_scope() && scope->outer_scope() == original_scope_) {
2978 : return;
2979 : }
2980 1674767 : scope->HoistSloppyBlockFunctions(factory());
2981 : }
2982 :
2983 : // ----------------------------------------------------------------------------
2984 : // Parser support
2985 :
2986 15738 : bool Parser::TargetStackContainsLabel(const AstRawString* label) {
2987 24903 : for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
2988 18330 : if (ContainsLabel(t->statement()->labels(), label)) return true;
2989 : }
2990 : return false;
2991 : }
2992 :
2993 43752 : BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label) {
2994 : bool anonymous = label == nullptr;
2995 59806 : for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
2996 : BreakableStatement* stat = t->statement();
2997 163236 : if ((anonymous && stat->is_target_for_anonymous()) ||
2998 30444 : (!anonymous && ContainsLabel(stat->labels(), label))) {
2999 : return stat;
3000 : }
3001 : }
3002 : return nullptr;
3003 : }
3004 :
3005 13731 : IterationStatement* Parser::LookupContinueTarget(const AstRawString* label) {
3006 : bool anonymous = label == nullptr;
3007 34844 : for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
3008 34477 : IterationStatement* stat = t->statement()->AsIterationStatement();
3009 34477 : if (stat == nullptr) continue;
3010 :
3011 : DCHECK(stat->is_target_for_anonymous());
3012 17026 : if (anonymous || ContainsLabel(stat->own_labels(), label)) {
3013 : return stat;
3014 : }
3015 1272 : if (ContainsLabel(stat->labels(), label)) break;
3016 : }
3017 : return nullptr;
3018 : }
3019 :
3020 1732839 : void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) {
3021 1732839 : Handle<String> source_url = scanner_.SourceUrl(isolate);
3022 1732840 : if (!source_url.is_null()) {
3023 7654 : script->set_source_url(*source_url);
3024 : }
3025 1732840 : Handle<String> source_mapping_url = scanner_.SourceMappingUrl(isolate);
3026 1732841 : if (!source_mapping_url.is_null()) {
3027 200 : script->set_source_mapping_url(*source_mapping_url);
3028 : }
3029 1732841 : }
3030 :
3031 2452768 : void Parser::UpdateStatistics(Isolate* isolate, Handle<Script> script) {
3032 : // Move statistics to Isolate.
3033 375260028 : for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
3034 : ++feature) {
3035 186403703 : if (use_counts_[feature] > 0) {
3036 1924367 : isolate->CountUsage(v8::Isolate::UseCounterFeature(feature));
3037 : }
3038 : }
3039 2452695 : if (scanner_.FoundHtmlComment()) {
3040 10 : isolate->CountUsage(v8::Isolate::kHtmlComment);
3041 20 : if (script->line_offset() == 0 && script->column_offset() == 0) {
3042 10 : isolate->CountUsage(v8::Isolate::kHtmlCommentInExternalScript);
3043 : }
3044 : }
3045 2452695 : isolate->counters()->total_preparse_skipped()->Increment(
3046 2452695 : total_preparse_skipped_);
3047 2452693 : }
3048 :
3049 13468 : void Parser::ParseOnBackground(ParseInfo* info) {
3050 : RuntimeCallTimerScope runtimeTimer(
3051 13468 : runtime_call_stats_, RuntimeCallCounterId::kParseBackgroundProgram);
3052 13468 : parsing_on_main_thread_ = false;
3053 : set_script_id(info->script_id());
3054 :
3055 : DCHECK_NULL(info->literal());
3056 : FunctionLiteral* result = nullptr;
3057 :
3058 13468 : scanner_.Initialize();
3059 : DCHECK(info->maybe_outer_scope_info().is_null());
3060 :
3061 : DCHECK(original_scope_);
3062 :
3063 : // When streaming, we don't know the length of the source until we have parsed
3064 : // it. The raw data can be UTF-8, so we wouldn't know the source length until
3065 : // we have decoded it anyway even if we knew the raw data length (which we
3066 : // don't). We work around this by storing all the scopes which need their end
3067 : // position set at the end of the script (the top scope and possible eval
3068 : // scopes) and set their end position after we know the script length.
3069 13467 : if (info->is_toplevel()) {
3070 13394 : result = DoParseProgram(/* isolate = */ nullptr, info);
3071 : } else {
3072 : result =
3073 73 : DoParseFunction(/* isolate = */ nullptr, info, info->function_name());
3074 : }
3075 13468 : MaybeResetCharacterStream(info, result);
3076 :
3077 : info->set_literal(result);
3078 :
3079 : // We cannot internalize on a background thread; a foreground task will take
3080 : // care of calling AstValueFactory::Internalize just before compilation.
3081 13468 : }
3082 :
3083 38619 : Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
3084 38619 : return new (zone()) TemplateLiteral(zone(), pos);
3085 : }
3086 :
3087 84013 : void Parser::AddTemplateSpan(TemplateLiteralState* state, bool should_cook,
3088 : bool tail) {
3089 : int end = scanner()->location().end_pos - (tail ? 1 : 2);
3090 84013 : const AstRawString* raw = scanner()->CurrentRawSymbol(ast_value_factory());
3091 84013 : if (should_cook) {
3092 80297 : const AstRawString* cooked = scanner()->CurrentSymbol(ast_value_factory());
3093 80297 : (*state)->AddTemplateSpan(cooked, raw, end, zone());
3094 : } else {
3095 3716 : (*state)->AddTemplateSpan(nullptr, raw, end, zone());
3096 : }
3097 84013 : }
3098 :
3099 0 : void Parser::AddTemplateExpression(TemplateLiteralState* state,
3100 : Expression* expression) {
3101 48491 : (*state)->AddExpression(expression, zone());
3102 0 : }
3103 :
3104 35522 : Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
3105 : Expression* tag) {
3106 35522 : TemplateLiteral* lit = *state;
3107 : int pos = lit->position();
3108 : const ZonePtrList<const AstRawString>* cooked_strings = lit->cooked();
3109 : const ZonePtrList<const AstRawString>* raw_strings = lit->raw();
3110 : const ZonePtrList<Expression>* expressions = lit->expressions();
3111 : DCHECK_EQ(cooked_strings->length(), raw_strings->length());
3112 : DCHECK_EQ(cooked_strings->length(), expressions->length() + 1);
3113 :
3114 35522 : if (!tag) {
3115 28327 : if (cooked_strings->length() == 1) {
3116 14370 : return factory()->NewStringLiteral(cooked_strings->first(), pos);
3117 : }
3118 21142 : return factory()->NewTemplateLiteral(cooked_strings, expressions, pos);
3119 : } else {
3120 : // GetTemplateObject
3121 : Expression* template_object =
3122 : factory()->NewGetTemplateObject(cooked_strings, raw_strings, pos);
3123 :
3124 : // Call TagFn
3125 : ScopedPtrList<Expression> call_args(pointer_buffer());
3126 : call_args.Add(template_object);
3127 7195 : call_args.AddAll(*expressions);
3128 7195 : return factory()->NewTaggedTemplate(tag, call_args, pos);
3129 : }
3130 : }
3131 :
3132 : namespace {
3133 :
3134 4375 : bool OnlyLastArgIsSpread(const ScopedPtrList<Expression>& args) {
3135 6349 : for (int i = 0; i < args.length() - 1; i++) {
3136 1740 : if (args.at(i)->IsSpread()) {
3137 : return false;
3138 : }
3139 : }
3140 3622 : return args.at(args.length() - 1)->IsSpread();
3141 : }
3142 :
3143 : } // namespace
3144 :
3145 723 : ArrayLiteral* Parser::ArrayLiteralFromListWithSpread(
3146 : const ScopedPtrList<Expression>& list) {
3147 : // If there's only a single spread argument, a fast path using CallWithSpread
3148 : // is taken.
3149 : DCHECK_LT(1, list.length());
3150 :
3151 : // The arguments of the spread call become a single ArrayLiteral.
3152 : int first_spread = 0;
3153 2172 : for (; first_spread < list.length() && !list.at(first_spread)->IsSpread();
3154 : ++first_spread) {
3155 : }
3156 :
3157 : DCHECK_LT(first_spread, list.length());
3158 723 : return factory()->NewArrayLiteral(list, first_spread, kNoSourcePosition);
3159 : }
3160 :
3161 4145 : Expression* Parser::SpreadCall(Expression* function,
3162 : const ScopedPtrList<Expression>& args_list,
3163 : int pos, Call::PossiblyEval is_possibly_eval) {
3164 : // Handle this case in BytecodeGenerator.
3165 4893 : if (OnlyLastArgIsSpread(args_list) || function->IsSuperCallReference()) {
3166 3427 : return factory()->NewCall(function, args_list, pos);
3167 : }
3168 :
3169 : ScopedPtrList<Expression> args(pointer_buffer());
3170 718 : if (function->IsProperty()) {
3171 : // Method calls
3172 530 : if (function->AsProperty()->IsSuperAccess()) {
3173 0 : Expression* home = ThisExpression();
3174 : args.Add(function);
3175 : args.Add(home);
3176 : } else {
3177 : Variable* temp = NewTemporary(ast_value_factory()->empty_string());
3178 : VariableProxy* obj = factory()->NewVariableProxy(temp);
3179 : Assignment* assign_obj = factory()->NewAssignment(
3180 266 : Token::ASSIGN, obj, function->AsProperty()->obj(), kNoSourcePosition);
3181 : function = factory()->NewProperty(
3182 : assign_obj, function->AsProperty()->key(), kNoSourcePosition);
3183 : args.Add(function);
3184 : obj = factory()->NewVariableProxy(temp);
3185 : args.Add(obj);
3186 : }
3187 : } else {
3188 : // Non-method calls
3189 : args.Add(function);
3190 : args.Add(factory()->NewUndefinedLiteral(kNoSourcePosition));
3191 : }
3192 719 : args.Add(ArrayLiteralFromListWithSpread(args_list));
3193 719 : return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos);
3194 : }
3195 :
3196 230 : Expression* Parser::SpreadCallNew(Expression* function,
3197 : const ScopedPtrList<Expression>& args_list,
3198 : int pos) {
3199 230 : if (OnlyLastArgIsSpread(args_list)) {
3200 : // Handle in BytecodeGenerator.
3201 225 : return factory()->NewCallNew(function, args_list, pos);
3202 : }
3203 : ScopedPtrList<Expression> args(pointer_buffer());
3204 : args.Add(function);
3205 5 : args.Add(ArrayLiteralFromListWithSpread(args_list));
3206 :
3207 5 : return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos);
3208 : }
3209 :
3210 5646635 : void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) {
3211 : v8::Isolate::UseCounterFeature feature;
3212 5646635 : if (is_sloppy(mode))
3213 : feature = v8::Isolate::kSloppyMode;
3214 1404897 : else if (is_strict(mode))
3215 : feature = v8::Isolate::kStrictMode;
3216 : else
3217 0 : UNREACHABLE();
3218 5744431 : ++use_counts_[feature];
3219 : scope->SetLanguageMode(mode);
3220 5646635 : }
3221 :
3222 4307 : void Parser::SetAsmModule() {
3223 : // Store the usage count; The actual use counter on the isolate is
3224 : // incremented after parsing is done.
3225 4307 : ++use_counts_[v8::Isolate::kUseAsm];
3226 : DCHECK(scope()->is_declaration_scope());
3227 4307 : scope()->AsDeclarationScope()->set_is_asm_module();
3228 4307 : info_->set_contains_asm_module(true);
3229 4307 : }
3230 :
3231 62734 : Expression* Parser::ExpressionListToExpression(
3232 : const ScopedPtrList<Expression>& args) {
3233 : Expression* expr = args.at(0);
3234 62734 : if (args.length() == 1) return expr;
3235 59690 : if (args.length() == 2) {
3236 : return factory()->NewBinaryOperation(Token::COMMA, expr, args.at(1),
3237 53612 : args.at(1)->position());
3238 : }
3239 : NaryOperation* result =
3240 12156 : factory()->NewNaryOperation(Token::COMMA, expr, args.length() - 1);
3241 5252362 : for (int i = 1; i < args.length(); i++) {
3242 : result->AddSubsequent(args.at(i), args.at(i)->position());
3243 : }
3244 : return result;
3245 : }
3246 :
3247 : // This method completes the desugaring of the body of async_function.
3248 42755 : void Parser::RewriteAsyncFunctionBody(ScopedPtrList<Statement>* body,
3249 : Block* block, Expression* return_value) {
3250 : // function async_function() {
3251 : // .generator_object = %_AsyncFunctionEnter();
3252 : // BuildRejectPromiseOnException({
3253 : // ... block ...
3254 : // return %_AsyncFunctionResolve(.generator_object, expr);
3255 : // })
3256 : // }
3257 :
3258 85510 : block->statements()->Add(factory()->NewAsyncReturnStatement(
3259 : return_value, return_value->position()),
3260 42755 : zone());
3261 42755 : block = BuildRejectPromiseOnException(block);
3262 : body->Add(block);
3263 42755 : }
3264 :
3265 3471796 : void Parser::SetFunctionNameFromPropertyName(LiteralProperty* property,
3266 : const AstRawString* name,
3267 : const AstRawString* prefix) {
3268 3471796 : if (has_error()) return;
3269 : // Ensure that the function we are going to create has shared name iff
3270 : // we are not going to set it later.
3271 3427183 : if (property->NeedsSetFunctionName()) {
3272 : name = nullptr;
3273 : prefix = nullptr;
3274 : } else {
3275 : // If the property value is an anonymous function or an anonymous class or
3276 : // a concise method or an accessor function which doesn't require the name
3277 : // to be set then the shared name must be provided.
3278 : DCHECK_IMPLIES(property->value()->IsAnonymousFunctionDefinition() ||
3279 : property->value()->IsConciseMethodDefinition() ||
3280 : property->value()->IsAccessorFunctionDefinition(),
3281 : name != nullptr);
3282 : }
3283 :
3284 : Expression* value = property->value();
3285 3427179 : SetFunctionName(value, name, prefix);
3286 : }
3287 :
3288 3041550 : void Parser::SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
3289 : const AstRawString* name,
3290 : const AstRawString* prefix) {
3291 : // Ignore "__proto__" as a name when it's being used to set the [[Prototype]]
3292 : // of an object literal.
3293 : // See ES #sec-__proto__-property-names-in-object-initializers.
3294 6076496 : if (property->IsPrototype() || has_error()) return;
3295 :
3296 : DCHECK(!property->value()->IsAnonymousFunctionDefinition() ||
3297 : property->kind() == ObjectLiteralProperty::COMPUTED);
3298 :
3299 : SetFunctionNameFromPropertyName(static_cast<LiteralProperty*>(property), name,
3300 3012095 : prefix);
3301 : }
3302 :
3303 12620265 : void Parser::SetFunctionNameFromIdentifierRef(Expression* value,
3304 : Expression* identifier) {
3305 12620265 : if (!identifier->IsVariableProxy()) return;
3306 17051638 : SetFunctionName(value, identifier->AsVariableProxy()->raw_name());
3307 : }
3308 :
3309 11953170 : void Parser::SetFunctionName(Expression* value, const AstRawString* name,
3310 : const AstRawString* prefix) {
3311 35507608 : if (!value->IsAnonymousFunctionDefinition() &&
3312 23184402 : !value->IsConciseMethodDefinition() &&
3313 11231203 : !value->IsAccessorFunctionDefinition()) {
3314 : return;
3315 : }
3316 753398 : auto function = value->AsFunctionLiteral();
3317 753398 : if (value->IsClassLiteral()) {
3318 : function = value->AsClassLiteral()->constructor();
3319 : }
3320 753398 : if (function != nullptr) {
3321 : AstConsString* cons_name = nullptr;
3322 753396 : if (name != nullptr) {
3323 743038 : if (prefix != nullptr) {
3324 27718 : cons_name = ast_value_factory()->NewConsString(prefix, name);
3325 : } else {
3326 715320 : cons_name = ast_value_factory()->NewConsString(name);
3327 : }
3328 : } else {
3329 : DCHECK_NULL(prefix);
3330 : }
3331 : function->set_raw_name(cons_name);
3332 : }
3333 : }
3334 :
3335 0 : Statement* Parser::CheckCallable(Variable* var, Expression* error, int pos) {
3336 : const int nopos = kNoSourcePosition;
3337 : Statement* validate_var;
3338 : {
3339 : Expression* type_of = factory()->NewUnaryOperation(
3340 : Token::TYPEOF, factory()->NewVariableProxy(var), nopos);
3341 : Expression* function_literal = factory()->NewStringLiteral(
3342 : ast_value_factory()->function_string(), nopos);
3343 : Expression* condition = factory()->NewCompareOperation(
3344 : Token::EQ_STRICT, type_of, function_literal, nopos);
3345 :
3346 : Statement* throw_call = factory()->NewExpressionStatement(error, pos);
3347 :
3348 : validate_var = factory()->NewIfStatement(
3349 : condition, factory()->EmptyStatement(), throw_call, nopos);
3350 : }
3351 0 : return validate_var;
3352 : }
3353 :
3354 : } // namespace internal
3355 121996 : } // namespace v8
|