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