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 99870 : 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 99870 : : FunctionKind::kDefaultBaseConstructor;
43 227636 : DeclarationScope* function_scope = NewFunctionScope(kind);
44 99877 : 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 99877 : ScopedPtrList<Statement> body(pointer_buffer());
49 :
50 : {
51 99877 : FunctionState function_state(&function_state_, &scope_, function_scope);
52 :
53 99877 : if (call_super) {
54 : // Create a SuperCallReference and handle in BytecodeGenerator.
55 27886 : 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 27886 : ast_value_factory(), pos);
61 :
62 : Expression* call;
63 : {
64 : ScopedPtrList<Expression> args(pointer_buffer());
65 : Spread* spread_args = factory()->NewSpread(
66 55773 : factory()->NewVariableProxy(constructor_args), pos, pos);
67 :
68 27888 : args.Add(spread_args);
69 27886 : Expression* super_call_ref = NewSuperCallReference(pos);
70 27887 : call = factory()->NewCall(super_call_ref, args, pos);
71 : }
72 55775 : body.Add(factory()->NewReturnStatement(call, pos));
73 : }
74 :
75 99880 : expected_property_count = function_state.expected_property_count();
76 : }
77 :
78 : 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 99880 : true, GetNextFunctionLiteralId());
83 99877 : return function_literal;
84 : }
85 :
86 1884719 : void Parser::ReportUnexpectedTokenAt(Scanner::Location location,
87 : Token::Value token,
88 : MessageTemplate message) {
89 : const char* arg = nullptr;
90 1884719 : 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 9478 : 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 1767009 : message = is_strict(language_mode())
115 : ? MessageTemplate::kUnexpectedStrictReserved
116 16207 : : MessageTemplate::kUnexpectedTokenIdentifier;
117 16207 : 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 1767009 : if (scanner()->has_error()) {
128 : message = scanner()->error();
129 223238 : 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 78573 : break;
142 : }
143 1884719 : ReportMessageAt(location, message, arg);
144 1884717 : }
145 :
146 : // ----------------------------------------------------------------------------
147 : // Implementation of Parser
148 :
149 1689298 : bool Parser::ShortcutNumericLiteralBinaryExpression(Expression** x,
150 : Expression* y,
151 : Token::Value op, int pos) {
152 1689298 : if ((*x)->IsNumberLiteral() && y->IsNumberLiteral()) {
153 1251988 : double x_val = (*x)->AsLiteral()->AsNumber();
154 1251963 : double y_val = y->AsLiteral()->AsNumber();
155 625974 : switch (op) {
156 : case Token::ADD:
157 15640 : *x = factory()->NewNumberLiteral(x_val + y_val, pos);
158 15640 : return true;
159 : case Token::SUB:
160 1692 : *x = factory()->NewNumberLiteral(x_val - y_val, pos);
161 1693 : return true;
162 : case Token::MUL:
163 214656 : *x = factory()->NewNumberLiteral(x_val * y_val, pos);
164 214657 : return true;
165 : case Token::DIV:
166 3230 : *x = factory()->NewNumberLiteral(base::Divide(x_val, y_val), pos);
167 3230 : return true;
168 : case Token::BIT_OR: {
169 10510 : int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
170 10511 : *x = factory()->NewNumberLiteral(value, pos);
171 10511 : return true;
172 : }
173 : case Token::BIT_AND: {
174 375 : int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
175 375 : *x = factory()->NewNumberLiteral(value, pos);
176 375 : return true;
177 : }
178 : case Token::BIT_XOR: {
179 201 : int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
180 201 : *x = factory()->NewNumberLiteral(value, pos);
181 201 : return true;
182 : }
183 : case Token::SHL: {
184 : int value =
185 377139 : base::ShlWithWraparound(DoubleToInt32(x_val), DoubleToInt32(y_val));
186 377146 : *x = factory()->NewNumberLiteral(value, pos);
187 377160 : 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 416 : *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 372 : *x = factory()->NewNumberLiteral(value, pos);
199 372 : return true;
200 : }
201 : case Token::EXP:
202 1251 : *x = factory()->NewNumberLiteral(base::ieee754::pow(x_val, y_val), pos);
203 1251 : return true;
204 : default:
205 : break;
206 : }
207 : }
208 : return false;
209 : }
210 :
211 1063812 : bool Parser::CollapseNaryExpression(Expression** x, Expression* y,
212 : Token::Value op, int pos,
213 341950 : const SourceRange& range) {
214 : // Filter out unsupported ops.
215 1063812 : 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 217926 : NaryOperation* nary = nullptr;
220 2123069 : if ((*x)->IsBinaryOperation()) {
221 642093 : BinaryOperation* binop = (*x)->AsBinaryOperation();
222 195810 : if (binop->op() != op) return false;
223 :
224 125238 : nary = factory()->NewNaryOperation(op, binop->left(), 2);
225 125235 : nary->AddSubsequent(binop->right(), binop->position());
226 : ConvertBinaryToNaryOperationSourceRange(binop, nary);
227 125235 : *x = nary;
228 865723 : } else if ((*x)->IsNaryOperation()) {
229 217926 : nary = (*x)->AsNaryOperation();
230 217926 : 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 683388 : Expression* Parser::BuildUnaryExpression(Expression* expression,
246 : Token::Value op, int pos) {
247 : DCHECK_NOT_NULL(expression);
248 683388 : const Literal* literal = expression->AsLiteral();
249 683401 : if (literal != nullptr) {
250 365564 : if (op == Token::NOT) {
251 : // Convert the literal to a boolean condition and negate it.
252 548 : return factory()->NewBooleanLiteral(literal->ToBooleanIsFalse(), pos);
253 365289 : } else if (literal->IsNumberLiteral()) {
254 : // Compute some expressions involving only number literals.
255 360878 : double value = literal->AsNumber();
256 360876 : switch (op) {
257 : case Token::ADD:
258 : return expression;
259 : case Token::SUB:
260 352273 : return factory()->NewNumberLiteral(-value, pos);
261 : case Token::BIT_NOT:
262 1463 : return factory()->NewNumberLiteral(~DoubleToInt32(value), pos);
263 : default:
264 : break;
265 : }
266 : }
267 : }
268 656029 : return factory()->NewUnaryOperation(op, expression, pos);
269 : }
270 :
271 1219 : Expression* Parser::NewThrowError(Runtime::FunctionId id,
272 : MessageTemplate message,
273 : const AstRawString* arg, int pos) {
274 1219 : ScopedPtrList<Expression> args(pointer_buffer());
275 2438 : args.Add(factory()->NewSmiLiteral(static_cast<int>(message), pos));
276 2438 : args.Add(factory()->NewStringLiteral(arg, pos));
277 1219 : CallRuntime* call_constructor = factory()->NewCallRuntime(id, args, pos);
278 2438 : return factory()->NewThrow(call_constructor, pos);
279 : }
280 :
281 2758 : Expression* Parser::NewSuperPropertyReference(int pos) {
282 : // this_function[home_object_symbol]
283 : VariableProxy* this_function_proxy =
284 2758 : NewUnresolved(ast_value_factory()->this_function_string(), pos);
285 : Expression* home_object_symbol_literal = factory()->NewSymbolLiteral(
286 2758 : AstSymbol::kHomeObjectSymbol, kNoSourcePosition);
287 : Expression* home_object = factory()->NewProperty(
288 2758 : this_function_proxy, home_object_symbol_literal, pos);
289 5516 : return factory()->NewSuperPropertyReference(home_object, pos);
290 : }
291 :
292 30623 : Expression* Parser::NewSuperCallReference(int pos) {
293 : VariableProxy* new_target_proxy =
294 61252 : NewUnresolved(ast_value_factory()->new_target_string(), pos);
295 : VariableProxy* this_function_proxy =
296 30629 : NewUnresolved(ast_value_factory()->this_function_string(), pos);
297 : return factory()->NewSuperCallReference(new_target_proxy, this_function_proxy,
298 61260 : pos);
299 : }
300 :
301 2032 : Expression* Parser::NewTargetExpression(int pos) {
302 2032 : auto proxy = NewUnresolved(ast_value_factory()->new_target_string(), pos);
303 : proxy->set_is_new_target();
304 2032 : return proxy;
305 : }
306 :
307 3210 : Expression* Parser::ImportMetaExpression(int pos) {
308 3210 : ScopedPtrList<Expression> args(pointer_buffer());
309 : return factory()->NewCallRuntime(Runtime::kInlineGetImportMetaObject, args,
310 6420 : pos);
311 : }
312 :
313 25734033 : Expression* Parser::ExpressionFromLiteral(Token::Value token, int pos) {
314 25734033 : switch (token) {
315 : case Token::NULL_LITERAL:
316 20993598 : return factory()->NewNullLiteral(pos);
317 : case Token::TRUE_LITERAL:
318 326682 : return factory()->NewBooleanLiteral(true, pos);
319 : case Token::FALSE_LITERAL:
320 491554 : return factory()->NewBooleanLiteral(false, pos);
321 : case Token::SMI: {
322 : uint32_t value = scanner()->smi_value();
323 39166400 : return factory()->NewSmiLiteral(value, pos);
324 : }
325 : case Token::NUMBER: {
326 1247095 : double value = scanner()->DoubleValue();
327 1247162 : return factory()->NewNumberLiteral(value, pos);
328 : }
329 : case Token::BIGINT:
330 : return factory()->NewBigIntLiteral(
331 12251 : AstBigInt(scanner()->CurrentLiteralAsCString(zone())), pos);
332 : case Token::STRING: {
333 8814008 : return factory()->NewStringLiteral(GetSymbol(), pos);
334 : }
335 : default:
336 : DCHECK(false);
337 : }
338 0 : return FailureExpression();
339 : }
340 :
341 54057 : Expression* Parser::NewV8Intrinsic(const AstRawString* name,
342 29336 : const ScopedPtrList<Expression>& args,
343 : int pos) {
344 54057 : 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 5 : GetClosureScope()->ForceEagerCompilation();
348 : }
349 :
350 : DCHECK(name->is_one_byte());
351 : const Runtime::Function* function =
352 54037 : Runtime::FunctionForName(name->raw_data(), name->length());
353 :
354 54118 : 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 83409 : if (function->nargs != -1 && function->nargs != args.length()) {
361 9 : ReportMessage(MessageTemplate::kRuntimeWrongNumArgs);
362 9 : return FailureExpression();
363 : }
364 :
365 54064 : 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 14346052 : 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 24376088 : 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 4874854 : bool can_compile_lazily = info->allow_lazy_compile() && !info->is_eager();
413 :
414 : set_default_eager_compile_hint(can_compile_lazily
415 : ? FunctionLiteral::kShouldLazyCompile
416 2437590 : : FunctionLiteral::kShouldEagerCompile);
417 4595247 : allow_lazy_ = info->allow_lazy_compile() && info->allow_lazy_parsing() &&
418 4595580 : !info->is_native() && info->extension() == nullptr &&
419 2437590 : can_compile_lazily;
420 4126345 : 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 185253165 : for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
429 : ++feature) {
430 182815575 : use_counts_[feature] = 0;
431 : }
432 2437590 : }
433 :
434 13179 : void Parser::InitializeEmptyScopeChain(ParseInfo* info) {
435 : DCHECK_NULL(original_scope_);
436 : DCHECK_NULL(info->script_scope());
437 2437625 : DeclarationScope* script_scope = NewScriptScope();
438 : info->set_script_scope(script_scope);
439 2437632 : original_scope_ = script_scope;
440 13179 : }
441 :
442 2424446 : void Parser::DeserializeScopeChain(
443 1394903 : 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 2424453 : if (maybe_outer_scope_info.ToHandle(&outer_scope_info)) {
449 : DCHECK(ThreadId::Current().Equals(isolate->thread_id()));
450 : original_scope_ = Scope::DeserializeScopeChain(
451 : isolate, zone(), *outer_scope_info, info->script_scope(),
452 2788528 : ast_value_factory(), mode);
453 1394902 : if (info->is_eval() || IsArrowFunction(info->function_kind())) {
454 : original_scope_->GetReceiverScope()->DeserializeReceiver(
455 778424 : ast_value_factory());
456 : }
457 : }
458 2424452 : }
459 :
460 : namespace {
461 :
462 2441660 : 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 2437454 : if (info->contains_asm_module()) {
466 4202 : if (FLAG_stress_validate_asm) return;
467 8411 : if (literal != nullptr && literal->scope()->ContainsAsmModule()) return;
468 : }
469 2433273 : info->ResetCharacterStream();
470 : }
471 :
472 4461828 : void MaybeProcessSourceRanges(ParseInfo* parse_info, Expression* root,
473 : uintptr_t stack_limit_) {
474 4461160 : if (root != nullptr && parse_info->source_range_map() != nullptr) {
475 : SourceRangeAstVisitor visitor(stack_limit_, root,
476 668 : parse_info->source_range_map());
477 : visitor.Run();
478 : }
479 2424450 : }
480 :
481 : } // namespace
482 :
483 1718006 : 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 1717995 : : RuntimeCallCounterId::kParseProgram);
494 5153989 : TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram");
495 : base::ElapsedTimer timer;
496 1717997 : if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
497 :
498 : // Initialize parser state.
499 : DeserializeScopeChain(isolate, info, info->maybe_outer_scope_info(),
500 1717997 : Scope::DeserializationMode::kIncludingVariables);
501 :
502 1718000 : scanner_.Initialize();
503 1730325 : if (FLAG_harmony_hashbang && !info->is_eval()) {
504 11056 : scanner_.SkipHashBang();
505 : }
506 1717998 : FunctionLiteral* result = DoParseProgram(isolate, info);
507 1718000 : MaybeResetCharacterStream(info, result);
508 1717999 : MaybeProcessSourceRanges(info, result, stack_limit_);
509 :
510 1717997 : HandleSourceURLComments(isolate, info->script());
511 :
512 1717995 : 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 1717996 : return result;
527 : }
528 :
529 1771881 : 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 1731076 : ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
539 7309086 : ResetFunctionLiteralId();
540 : DCHECK(info->function_literal_id() == FunctionLiteral::kIdTypeTopLevel ||
541 : info->function_literal_id() == FunctionLiteral::kIdTypeInvalid);
542 :
543 : FunctionLiteral* result = nullptr;
544 : {
545 1731076 : Scope* outer = original_scope_;
546 : DCHECK_NOT_NULL(outer);
547 1731076 : if (info->is_eval()) {
548 961392 : outer = NewEvalScope(outer);
549 769684 : } else if (parsing_module_) {
550 : DCHECK_EQ(outer, info->script_scope());
551 40805 : outer = NewModuleScope(info->script_scope());
552 : }
553 :
554 1731076 : DeclarationScope* scope = outer->AsDeclarationScope();
555 : scope->set_start_position(0);
556 :
557 1731037 : FunctionState function_state(&function_state_, &scope_, scope);
558 1731037 : ScopedPtrList<Statement> body(pointer_buffer());
559 1731037 : int beg_pos = scanner()->location().beg_pos;
560 1731037 : if (parsing_module_) {
561 : DCHECK(info->is_module());
562 : // Declare the special module parameter.
563 40805 : 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 : scope->DeclareLocal(name, mode, PARAMETER_VARIABLE, &was_added,
569 40805 : Variable::DefaultInitializationFlag(mode));
570 : DCHECK(was_added);
571 : auto var = scope->DeclareParameter(name, VariableMode::kVar, is_optional,
572 40805 : is_rest, ast_value_factory(), beg_pos);
573 : var->AllocateTo(VariableLocation::PARAMETER, 0);
574 :
575 40805 : PrepareGeneratorVariables();
576 : Expression* initial_yield =
577 40805 : BuildInitialYield(kNoSourcePosition, kGeneratorFunction);
578 : body.Add(
579 81610 : factory()->NewExpressionStatement(initial_yield, kNoSourcePosition));
580 :
581 40805 : ParseModuleItemList(&body);
582 56162 : if (!has_error() &&
583 : !module()->Validate(this->scope()->AsModuleScope(),
584 30714 : pending_error_handler(), zone())) {
585 : scanner()->set_parser_error();
586 : }
587 1690232 : } 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 1690158 : 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 1730972 : if (is_strict(language_mode())) {
601 328728 : CheckStrictOctalLiteral(beg_pos, end_position());
602 : }
603 1730977 : 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 1402198 : 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 1730981 : if (info->is_eval()) {
613 : DCHECK(parsing_on_main_thread_);
614 961392 : info->ast_value_factory()->Internalize(isolate);
615 : }
616 1730981 : CheckConflictingVarDeclarations(scope);
617 :
618 1731032 : if (info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
619 1354634 : if (body.length() != 1 || !body.at(0)->IsExpressionStatement() ||
620 : !body.at(0)
621 : ->AsExpressionStatement()
622 675964 : ->expression()
623 : ->IsFunctionLiteral()) {
624 1362 : ReportMessage(MessageTemplate::kSingleFunctionLiteral);
625 : }
626 : }
627 :
628 1730819 : int parameter_count = parsing_module_ ? 1 : 0;
629 : result = factory()->NewScriptOrEvalFunctionLiteral(
630 1730819 : scope, body, function_state.expected_property_count(), parameter_count);
631 1731054 : 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 1731052 : if (has_error()) return nullptr;
640 1348437 : 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 168 : Handle<FixedArray> arguments(info->script()->wrapped_arguments(), isolate);
648 : int arguments_length = arguments->length();
649 : ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
650 84 : new (zone) ZonePtrList<const AstRawString>(arguments_length, zone);
651 104 : for (int i = 0; i < arguments_length; i++) {
652 : 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 74 : 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 74 : function_literal, kNoSourcePosition, kNoSourcePosition);
683 : body->Add(return_statement);
684 74 : }
685 :
686 1412924 : 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 706450 : RuntimeCallCounterId::kParseFunction);
693 2119350 : TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseFunction");
694 : base::ElapsedTimer timer;
695 706449 : if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
696 :
697 : DeserializeScopeChain(isolate, info, info->maybe_outer_scope_info(),
698 706449 : Scope::DeserializationMode::kIncludingVariables);
699 : DCHECK_EQ(factory()->zone(), info->zone());
700 :
701 : // Initialize parser state.
702 1412904 : Handle<String> name(shared_info->Name(), isolate);
703 706475 : info->set_function_name(ast_value_factory()->GetString(name));
704 706453 : scanner_.Initialize();
705 :
706 23 : FunctionLiteral* result =
707 706451 : DoParseFunction(isolate, info, info->function_name());
708 706448 : MaybeResetCharacterStream(info, result);
709 706453 : MaybeProcessSourceRanges(info, result, stack_limit_);
710 706453 : if (result != nullptr) {
711 1402479 : Handle<String> inferred_name(shared_info->inferred_name(), isolate);
712 701240 : result->set_inferred_name(inferred_name);
713 : }
714 :
715 706452 : 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 706451 : return result;
728 : }
729 :
730 1069496 : static FunctionLiteral::FunctionType ComputeFunctionType(ParseInfo* info) {
731 706525 : if (info->is_wrapped_as_function()) {
732 : return FunctionLiteral::kWrapped;
733 706518 : } else if (info->is_declaration()) {
734 : return FunctionLiteral::kDeclaration;
735 443055 : } else if (info->is_named_expression()) {
736 : return FunctionLiteral::kNamedExpression;
737 625357 : } else if (IsConciseMethod(info->function_kind()) ||
738 : IsAccessorFunction(info->function_kind())) {
739 : return FunctionLiteral::kAccessorOrMethod;
740 : }
741 256155 : return FunctionLiteral::kAnonymousExpression;
742 : }
743 :
744 2661475 : 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 706525 : fni_.PushEnclosingName(raw_name);
753 :
754 354732 : ResetFunctionLiteralId();
755 : DCHECK_LT(0, info->function_literal_id());
756 706529 : 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 706529 : Scope* outer = original_scope_;
766 706529 : DeclarationScope* outer_function = outer->GetClosureScope();
767 : DCHECK(outer);
768 706529 : 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 706529 : FunctionLiteral::FunctionType function_type = ComputeFunctionType(info);
773 : FunctionKind kind = info->function_kind();
774 :
775 706527 : if (IsArrowFunction(kind)) {
776 177227 : if (IsAsyncFunction(kind)) {
777 : DCHECK(!scanner()->HasLineTerminatorAfterNext());
778 1083 : if (!Check(Token::ASYNC)) {
779 0 : CHECK(stack_overflow());
780 14 : return nullptr;
781 : }
782 2138 : 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 177227 : 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 177227 : 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 177226 : if (Check(Token::LPAREN)) {
805 : // '(' StrictFormalParameters ')'
806 159142 : ParseFormalParameterList(&formals);
807 159142 : Expect(Token::RPAREN);
808 : } else {
809 : // BindingIdentifier
810 : ParameterParsingScope scope(impl(), &formals);
811 : ParseFormalParameter(&formals);
812 : DeclareFormalParameters(&formals);
813 : }
814 177227 : formals.duplicate_loc = formals_scope.duplicate_location();
815 : }
816 :
817 177227 : if (GetLastFunctionLiteralId() != info->function_literal_id() - 1) {
818 299 : 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 947 : 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 568 : SkipFunctionLiterals(info->function_literal_id() - 1);
833 : }
834 :
835 177212 : 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 354422 : 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 177121 : result = expression->AsFunctionLiteral();
847 : }
848 529300 : } else if (IsDefaultConstructor(kind)) {
849 : DCHECK_EQ(scope(), outer);
850 : result = DefaultConstructor(raw_name, IsDerivedConstructor(kind),
851 9661 : 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 519649 : : nullptr;
857 : result = ParseFunctionLiteral(
858 : raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind,
859 : kNoSourcePosition, function_type, info->language_mode(),
860 519639 : arguments_for_wrapped_function);
861 : }
862 :
863 706510 : if (has_error()) return nullptr;
864 : result->set_requires_instance_members_initializer(
865 : info->requires_instance_members_initializer());
866 701310 : 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 701310 : return result;
876 : }
877 :
878 140899 : Statement* Parser::ParseModuleItem() {
879 : // ecma262/#prod-ModuleItem
880 : // ModuleItem :
881 : // ImportDeclaration
882 : // ExportDeclaration
883 : // StatementListItem
884 :
885 5668 : Token::Value next = peek();
886 :
887 140899 : if (next == Token::EXPORT) {
888 19484 : return ParseExportDeclaration();
889 : }
890 :
891 121415 : 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 8647 : if ((!allow_harmony_dynamic_import() || peek_ahead != Token::LPAREN) &&
896 1689 : (!allow_harmony_import_meta() || peek_ahead != Token::PERIOD)) {
897 2479 : ParseImportDeclaration();
898 2479 : return factory()->EmptyStatement();
899 : }
900 : }
901 :
902 118936 : return ParseStatementListItem();
903 : }
904 :
905 133668 : 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 197061 : while (peek() != Token::EOS) {
916 140899 : Statement* stat = ParseModuleItem();
917 181704 : if (stat == nullptr) return;
918 115451 : if (stat->IsEmptyStatement()) continue;
919 : body->Add(stat);
920 : }
921 : }
922 :
923 2909 : const AstRawString* Parser::ParseModuleSpecifier() {
924 : // ModuleSpecifier :
925 : // StringLiteral
926 :
927 2909 : Expect(Token::STRING);
928 2909 : 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 2450 : new (zone()) ZoneChunkList<ExportClauseData>(zone());
947 :
948 635 : Expect(Token::LBRACE);
949 :
950 : Token::Value name_tok;
951 1390 : 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 1410 : 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 9273 : Expect(Token::LBRACE);
998 :
999 1269 : auto result = new (zone()) ZonePtrList<const NamedImport>(1, zone());
1000 2718 : 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 2848 : 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 1244 : 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 2479 : 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 10906 : int pos = peek_position();
1051 2479 : Expect(Token::IMPORT);
1052 :
1053 : Token::Value tok = peek();
1054 :
1055 : // 'import' ModuleSpecifier ';'
1056 2479 : 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 2384 : 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 985 : 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 3337 : const ZonePtrList<const NamedImport>* named_imports = nullptr;
1078 3369 : if (import_default_binding == nullptr || Check(Token::COMMA)) {
1079 1424 : switch (peek()) {
1080 : case Token::MUL: {
1081 : Consume(Token::MUL);
1082 290 : ExpectContextualKeyword(ast_value_factory()->as_string());
1083 145 : module_namespace_binding = ParseNonRestrictedIdentifier();
1084 145 : module_namespace_binding_loc = scanner()->location();
1085 : DeclareUnboundVariable(module_namespace_binding, VariableMode::kConst,
1086 145 : kCreatedInitialized, pos);
1087 145 : 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 4748 : ExpectContextualKeyword(ast_value_factory()->from_string());
1101 2374 : Scanner::Location specifier_loc = scanner()->peek_location();
1102 2374 : const AstRawString* module_specifier = ParseModuleSpecifier();
1103 2374 : 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 2374 : if (module_namespace_binding != nullptr) {
1114 : module()->AddStarImport(module_namespace_binding, module_specifier,
1115 : module_namespace_binding_loc, specifier_loc,
1116 145 : zone());
1117 : }
1118 :
1119 2374 : if (import_default_binding != nullptr) {
1120 : module()->AddImport(ast_value_factory()->default_string(),
1121 : import_default_binding, module_specifier,
1122 1950 : import_default_binding_loc, specifier_loc, zone());
1123 : }
1124 :
1125 2374 : 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 : module()->AddImport(import->import_name, import->local_name,
1132 : module_specifier, import->location, specifier_loc,
1133 2358 : zone());
1134 : }
1135 : }
1136 : }
1137 : }
1138 :
1139 456 : 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 2858 : Expect(Token::DEFAULT);
1146 456 : Scanner::Location default_loc = scanner()->location();
1147 :
1148 456 : ZonePtrList<const AstRawString> local_names(1, zone());
1149 : Statement* result = nullptr;
1150 456 : 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 572 : SetFunctionName(value, ast_value_factory()->default_string());
1174 :
1175 : const AstRawString* local_name =
1176 572 : ast_value_factory()->star_default_star_string();
1177 286 : 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 286 : VariableProxy* proxy =
1182 286 : DeclareBoundVariable(local_name, VariableMode::kConst, pos);
1183 : proxy->var()->set_initializer_position(position());
1184 :
1185 : Assignment* assignment = factory()->NewAssignment(
1186 286 : Token::INIT, proxy, value, kNoSourcePosition);
1187 : result = IgnoreCompletion(
1188 572 : factory()->NewExpressionStatement(assignment, kNoSourcePosition));
1189 :
1190 286 : ExpectSemicolon();
1191 : break;
1192 : }
1193 : }
1194 :
1195 456 : if (result != nullptr) {
1196 : DCHECK_EQ(local_names.length(), 1);
1197 : module()->AddExport(local_names.first(),
1198 : ast_value_factory()->default_string(), default_loc,
1199 1368 : zone());
1200 : }
1201 :
1202 456 : return result;
1203 : }
1204 :
1205 105 : const AstRawString* Parser::NextInternalNamespaceExportName() {
1206 : const char* prefix = ".ns-export";
1207 105 : std::string s(prefix);
1208 315 : s.append(std::to_string(number_of_named_namespace_exports_++));
1209 210 : return ast_value_factory()->GetOneByteString(s.c_str());
1210 : }
1211 :
1212 255 : void Parser::ParseExportStar() {
1213 1740 : int pos = position();
1214 : Consume(Token::MUL);
1215 :
1216 510 : if (!FLAG_harmony_namespace_exports ||
1217 510 : !PeekContextualKeyword(ast_value_factory()->as_string())) {
1218 : // 'export' '*' 'from' ModuleSpecifier ';'
1219 150 : Scanner::Location loc = scanner()->location();
1220 300 : 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 105 : 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 210 : ExpectContextualKeyword(ast_value_factory()->as_string());
1237 : const AstRawString* export_name = ParsePropertyName();
1238 105 : Scanner::Location export_name_loc = scanner()->location();
1239 105 : const AstRawString* local_name = NextInternalNamespaceExportName();
1240 105 : Scanner::Location local_name_loc = Scanner::Location::invalid();
1241 : DeclareUnboundVariable(local_name, VariableMode::kConst, kCreatedInitialized,
1242 105 : pos);
1243 :
1244 210 : ExpectContextualKeyword(ast_value_factory()->from_string());
1245 105 : Scanner::Location specifier_loc = scanner()->peek_location();
1246 105 : const AstRawString* module_specifier = ParseModuleSpecifier();
1247 105 : ExpectSemicolon();
1248 :
1249 : module()->AddStarImport(local_name, module_specifier, local_name_loc,
1250 105 : specifier_loc, zone());
1251 105 : module()->AddExport(local_name, export_name, export_name_loc, zone());
1252 : }
1253 :
1254 19484 : 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 76769 : Expect(Token::EXPORT);
1264 : Statement* result = nullptr;
1265 19484 : ZonePtrList<const AstRawString> names(1, zone());
1266 19484 : Scanner::Location loc = scanner()->peek_location();
1267 19484 : switch (peek()) {
1268 : case Token::DEFAULT:
1269 456 : return ParseExportDefault();
1270 :
1271 : case Token::MUL:
1272 255 : ParseExportStar();
1273 255 : 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 1270 : 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 1330 : for (const ExportClauseData& data : *export_data) {
1303 : module()->AddExport(data.local_name, data.export_name, data.location,
1304 980 : zone());
1305 : }
1306 185 : } else if (export_data->is_empty()) {
1307 30 : module()->AddEmptyImport(module_specifier, specifier_loc);
1308 : } else {
1309 485 : for (const ExportClauseData& data : *export_data) {
1310 : module()->AddExport(data.local_name, data.export_name,
1311 : module_specifier, data.location, specifier_loc,
1312 350 : 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 17643 : result = ParseVariableStatement(kStatementListItem, &names);
1331 17643 : 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 18093 : loc.end_pos = scanner()->location().end_pos;
1347 :
1348 : ModuleDescriptor* descriptor = module();
1349 36186 : for (int i = 0; i < names.length(); ++i) {
1350 36186 : descriptor->AddExport(names[i], names[i], loc, zone());
1351 : }
1352 :
1353 : return result;
1354 : }
1355 :
1356 2479 : void Parser::DeclareUnboundVariable(const AstRawString* name, VariableMode mode,
1357 : InitializationFlag init, int pos) {
1358 : bool was_added;
1359 : Variable* var = DeclareVariable(name, NORMAL_VARIABLE, mode, init, scope(),
1360 4958 : &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 2479 : }
1365 :
1366 359717 : VariableProxy* Parser::DeclareBoundVariable(const AstRawString* name,
1367 : VariableMode mode, int pos) {
1368 : DCHECK_NOT_NULL(name);
1369 : VariableProxy* proxy =
1370 1438902 : factory()->NewVariableProxy(name, NORMAL_VARIABLE, position());
1371 : bool was_added;
1372 : Variable* var = DeclareVariable(name, NORMAL_VARIABLE, mode,
1373 : Variable::DefaultInitializationFlag(mode),
1374 359734 : scope(), &was_added, pos, end_position());
1375 359746 : proxy->BindTo(var);
1376 359741 : return proxy;
1377 : }
1378 :
1379 140756 : void Parser::DeclareAndBindVariable(VariableProxy* proxy, VariableKind kind,
1380 : VariableMode mode, InitializationFlag init,
1381 : Scope* scope, bool* was_added, int begin,
1382 : int end) {
1383 : Variable* var = DeclareVariable(proxy->raw_name(), kind, mode, init, scope,
1384 281512 : was_added, begin, end);
1385 140766 : proxy->BindTo(var);
1386 140766 : }
1387 :
1388 14281030 : 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 14281136 : Declaration* declaration;
1393 26913328 : if (mode == VariableMode::kVar && !scope->is_declaration_scope()) {
1394 : DCHECK(scope->is_block_scope() || scope->is_with_scope());
1395 400520 : declaration = factory()->NewNestedVariableDeclaration(scope, begin);
1396 : } else {
1397 13880510 : declaration = factory()->NewVariableDeclaration(begin);
1398 : }
1399 14280930 : Declare(declaration, name, kind, mode, init, scope, was_added, begin, end);
1400 14281136 : return declaration->var();
1401 : }
1402 :
1403 15323852 : 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 15259931 : bool local_ok = true;
1408 15259931 : bool sloppy_mode_block_scope_function_redefinition = false;
1409 : scope->DeclareVariable(
1410 : declaration, name, var_begin_pos, mode, variable_kind, init, was_added,
1411 15259931 : &sloppy_mode_block_scope_function_redefinition, &local_ok);
1412 15260169 : 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 64230 : : var_begin_pos + 1);
1419 64230 : if (variable_kind == PARAMETER_VARIABLE) {
1420 309 : ReportMessageAt(loc, MessageTemplate::kParamDupe);
1421 : } else {
1422 : ReportMessageAt(loc, MessageTemplate::kVarRedeclaration,
1423 63921 : declaration->var()->raw_name());
1424 : }
1425 15195939 : } else if (sloppy_mode_block_scope_function_redefinition) {
1426 229 : ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition];
1427 : }
1428 15260168 : }
1429 :
1430 8804533 : Statement* Parser::BuildInitializationBlock(
1431 : DeclarationParsingResult* parsing_result) {
1432 8804533 : ScopedPtrList<Statement> statements(pointer_buffer());
1433 26655220 : for (const auto& declaration : parsing_result->declarations) {
1434 9046097 : if (!declaration.initializer) continue;
1435 : InitializeVariables(&statements, parsing_result->descriptor.kind,
1436 7066553 : &declaration);
1437 : }
1438 17609081 : return factory()->NewBlock(true, statements);
1439 : }
1440 :
1441 978995 : Statement* Parser::DeclareFunction(const AstRawString* variable_name,
1442 : FunctionLiteral* function, VariableMode mode,
1443 : VariableKind kind, int beg_pos, int end_pos,
1444 979118 : ZonePtrList<const AstRawString>* names) {
1445 9350 : Declaration* declaration =
1446 1967710 : factory()->NewFunctionDeclaration(function, beg_pos);
1447 : bool was_added;
1448 : Declare(declaration, variable_name, kind, mode, kCreatedInitialized, scope(),
1449 979032 : &was_added, beg_pos);
1450 979118 : 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 979658 : if (names) names->Add(variable_name, zone());
1456 979054 : if (kind == SLOPPY_BLOCK_FUNCTION_VARIABLE) {
1457 9143 : Token::Value init = loop_nesting_depth() > 0 ? Token::ASSIGN : Token::INIT;
1458 : SloppyBlockFunctionStatement* statement =
1459 : factory()->NewSloppyBlockFunctionStatement(end_pos, declaration->var(),
1460 18286 : init);
1461 9142 : GetDeclarationScope()->DeclareSloppyBlockFunction(statement);
1462 9142 : return statement;
1463 : }
1464 969911 : return factory()->EmptyStatement();
1465 : }
1466 :
1467 105961 : Statement* Parser::DeclareClass(const AstRawString* variable_name,
1468 : Expression* value,
1469 : ZonePtrList<const AstRawString>* names,
1470 : int class_token_pos, int end_pos) {
1471 105971 : VariableProxy* proxy =
1472 105961 : DeclareBoundVariable(variable_name, VariableMode::kLet, class_token_pos);
1473 : proxy->var()->set_initializer_position(end_pos);
1474 105971 : if (names) names->Add(variable_name, zone());
1475 :
1476 : Assignment* assignment =
1477 105971 : factory()->NewAssignment(Token::INIT, proxy, value, class_token_pos);
1478 : return IgnoreCompletion(
1479 211934 : factory()->NewExpressionStatement(assignment, kNoSourcePosition));
1480 : }
1481 :
1482 1734 : 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 1734 : 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 1734 : VariableProxy* proxy = DeclareBoundVariable(name, VariableMode::kVar, pos);
1493 : NativeFunctionLiteral* lit =
1494 1734 : factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition);
1495 : return factory()->NewExpressionStatement(
1496 1734 : factory()->NewAssignment(Token::INIT, proxy, lit, kNoSourcePosition),
1497 3468 : pos);
1498 : }
1499 :
1500 15714 : void Parser::DeclareLabel(ZonePtrList<const AstRawString>** labels,
1501 : ZonePtrList<const AstRawString>** own_labels,
1502 : VariableProxy* var) {
1503 : DCHECK(IsIdentifier(var));
1504 15714 : 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 31428 : if (ContainsLabel(*labels, label) || TargetStackContainsLabel(label)) {
1512 77292 : ReportMessage(MessageTemplate::kLabelRedeclaration, label);
1513 15713 : return;
1514 : }
1515 :
1516 : // Add {label} to both {labels} and {own_labels}.
1517 15714 : if (*labels == nullptr) {
1518 : DCHECK_NULL(*own_labels);
1519 15070 : *labels = new (zone()) ZonePtrList<const AstRawString>(1, zone());
1520 15070 : *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 15714 : (*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 15714 : scope()->DeleteUnresolved(var);
1533 : }
1534 :
1535 9977 : bool Parser::ContainsLabel(ZonePtrList<const AstRawString>* labels,
1536 : const AstRawString* label) {
1537 : DCHECK_NOT_NULL(label);
1538 51147 : if (labels != nullptr) {
1539 11509 : for (int i = labels->length(); i-- > 0;) {
1540 10358 : if (labels->at(i) == label) return true;
1541 : }
1542 : }
1543 : return false;
1544 : }
1545 :
1546 193869 : Block* Parser::IgnoreCompletion(Statement* statement) {
1547 193869 : Block* block = factory()->NewBlock(1, true);
1548 193875 : block->statements()->Add(statement, zone());
1549 193875 : return block;
1550 : }
1551 :
1552 981139 : Expression* Parser::RewriteReturn(Expression* return_value, int pos) {
1553 1962284 : 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 332 : Variable* temp = NewTemporary(ast_value_factory()->empty_string());
1565 : Assignment* assign = factory()->NewAssignment(
1566 664 : Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos);
1567 :
1568 : // temp === undefined
1569 : Expression* is_undefined = factory()->NewCompareOperation(
1570 : Token::EQ_STRICT, assign,
1571 664 : 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 332 : factory()->NewConditional(is_undefined, factory()->ThisExpression(),
1579 664 : factory()->NewVariableProxy(temp), pos);
1580 : }
1581 981145 : return return_value;
1582 : }
1583 :
1584 1844 : 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 4610 : Block* switch_block = factory()->NewBlock(2, false);
1601 :
1602 : Expression* tag = switch_statement->tag();
1603 : Variable* tag_variable =
1604 922 : NewTemporary(ast_value_factory()->dot_switch_tag_string());
1605 : Assignment* tag_assign = factory()->NewAssignment(
1606 922 : Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag,
1607 1844 : 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 : Statement* tag_statement = IgnoreCompletion(
1611 1844 : factory()->NewExpressionStatement(tag_assign, kNoSourcePosition));
1612 922 : switch_block->statements()->Add(tag_statement, zone());
1613 :
1614 922 : switch_statement->set_tag(factory()->NewVariableProxy(tag_variable));
1615 922 : Block* cases_block = factory()->NewBlock(1, false);
1616 922 : 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 7234334 : void Parser::InitializeVariables(
1623 7165663 : ScopedPtrList<Statement>* statements, VariableKind kind,
1624 : const DeclarationParsingResult::Declaration* declaration) {
1625 14468695 : if (has_error()) return;
1626 :
1627 : DCHECK_NOT_NULL(declaration->initializer);
1628 :
1629 7165700 : int pos = declaration->value_beg_pos;
1630 7165700 : if (pos == kNoSourcePosition) {
1631 339597 : pos = declaration->initializer->position();
1632 : }
1633 : Assignment* assignment = factory()->NewAssignment(
1634 7165700 : Token::INIT, declaration->pattern, declaration->initializer, pos);
1635 7165657 : 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 3024 : 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 1116 : for (Declaration* decl : *scope->declarations()) {
1651 648 : if (decl->var()->raw_name() == name) {
1652 468 : 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 92515 : 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 92515 : if (catch_block != nullptr && finally_block != nullptr) {
1675 : // If we have both, create an inner try/catch.
1676 : TryCatchStatement* statement;
1677 : statement = factory()->NewTryCatchStatement(try_block, catch_info.scope,
1678 2029 : catch_block, kNoSourcePosition);
1679 : RecordTryCatchStatementSourceRange(statement, catch_range);
1680 :
1681 1015 : try_block = factory()->NewBlock(1, false);
1682 1014 : try_block->statements()->Add(statement, zone());
1683 : catch_block = nullptr; // Clear to indicate it's been handled.
1684 : }
1685 :
1686 92514 : if (catch_block != nullptr) {
1687 : DCHECK_NULL(finally_block);
1688 : TryCatchStatement* stmt = factory()->NewTryCatchStatement(
1689 87270 : try_block, catch_info.scope, catch_block, pos);
1690 : RecordTryCatchStatementSourceRange(stmt, catch_range);
1691 87277 : return stmt;
1692 : } else {
1693 : DCHECK_NOT_NULL(finally_block);
1694 : TryFinallyStatement* stmt =
1695 5244 : factory()->NewTryFinallyStatement(try_block, finally_block, pos);
1696 : RecordTryFinallyStatementSourceRange(stmt, finally_range);
1697 5245 : return stmt;
1698 : }
1699 : }
1700 :
1701 25191 : void Parser::ParseAndRewriteGeneratorFunctionBody(
1702 25191 : int pos, FunctionKind kind, ScopedPtrList<Statement>* body) {
1703 : // For ES6 Generators, we just prepend the initial yield.
1704 25191 : Expression* initial_yield = BuildInitialYield(pos, kind);
1705 : body->Add(
1706 25191 : factory()->NewExpressionStatement(initial_yield, kNoSourcePosition));
1707 25191 : ParseStatementList(body, Token::RBRACE);
1708 25191 : }
1709 :
1710 24603 : void Parser::ParseAndRewriteAsyncGeneratorFunctionBody(
1711 24603 : 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 24603 : ScopedPtrList<Statement> statements(pointer_buffer());
1737 24603 : Expression* initial_yield = BuildInitialYield(pos, kind);
1738 : statements.Add(
1739 49206 : 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 49206 : factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
1748 24603 : 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 98412 : function_state_->scope()->generator_object_var()));
1761 49206 : 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 49206 : factory()->NewReturnStatement(reject_call, kNoSourcePosition));
1767 : }
1768 :
1769 : {
1770 : ScopedPtrList<Statement> statements(pointer_buffer());
1771 : TryStatement* try_catch = factory()->NewTryCatchStatementForAsyncAwait(
1772 24603 : try_block, catch_scope, catch_block, kNoSourcePosition);
1773 24603 : 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 49206 : function_state_->scope()->generator_object_var());
1782 24603 : 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 49206 : 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 24603 : kNoSourcePosition));
1797 24603 : }
1798 :
1799 1773144 : void Parser::DeclareFunctionNameVar(const AstRawString* function_name,
1800 : FunctionLiteral::FunctionType function_type,
1801 : DeclarationScope* function_scope) {
1802 1900979 : if (function_type == FunctionLiteral::kNamedExpression &&
1803 : function_scope->LookupLocal(function_name) == nullptr) {
1804 : DCHECK_EQ(function_scope, scope());
1805 124147 : function_scope->DeclareFunctionVar(function_name);
1806 : }
1807 1773154 : }
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 89302 : Block* Parser::RewriteForVarInLegacy(const ForInfo& for_info) {
1826 : const DeclarationParsingResult::Declaration& decl =
1827 89302 : for_info.parsing_result.declarations[0];
1828 195264 : if (!IsLexicalVariableMode(for_info.parsing_result.descriptor.mode) &&
1829 89728 : decl.initializer != nullptr && decl.pattern->IsVariableProxy()) {
1830 213 : ++use_counts_[v8::Isolate::kForInInitializer];
1831 213 : const AstRawString* name = decl.pattern->AsVariableProxy()->raw_name();
1832 213 : VariableProxy* single_var = NewUnresolved(name);
1833 213 : Block* init_block = factory()->NewBlock(2, true);
1834 : init_block->statements()->Add(
1835 : factory()->NewExpressionStatement(
1836 : factory()->NewAssignment(Token::ASSIGN, single_var,
1837 213 : decl.initializer, decl.value_beg_pos),
1838 213 : 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 104034 : 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 104034 : for_info->parsing_result.declarations[0];
1865 208079 : Variable* temp = NewTemporary(ast_value_factory()->dot_for_string());
1866 104038 : ScopedPtrList<Statement> each_initialization_statements(pointer_buffer());
1867 : DCHECK_IMPLIES(!has_error(), decl.pattern != nullptr);
1868 208078 : decl.initializer = factory()->NewVariableProxy(temp, for_info->position);
1869 104040 : InitializeVariables(&each_initialization_statements, NORMAL_VARIABLE, &decl);
1870 :
1871 104041 : *body_block = factory()->NewBlock(3, false);
1872 : (*body_block)
1873 : ->statements()
1874 104045 : ->Add(factory()->NewBlock(true, each_initialization_statements), zone());
1875 208082 : *each_variable = factory()->NewVariableProxy(temp, for_info->position);
1876 104045 : }
1877 :
1878 : // Create a TDZ for any lexically-bound names in for in/of statements.
1879 104038 : Block* Parser::CreateForEachStatementTDZ(Block* init_block,
1880 : const ForInfo& for_info) {
1881 104038 : if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) {
1882 : DCHECK_NULL(init_block);
1883 :
1884 175919 : init_block = factory()->NewBlock(1, false);
1885 :
1886 351838 : 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 91547 : VariableProxy* tdz_proxy = DeclareBoundVariable(
1891 359005 : for_info.bound_names[i], VariableMode::kLet, kNoSourcePosition);
1892 : tdz_proxy->var()->set_initializer_position(position());
1893 : }
1894 : }
1895 104042 : return init_block;
1896 : }
1897 :
1898 17508 : 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 508802 : ZonePtrList<Variable> temps(for_info.bound_names.length(), zone());
1940 :
1941 : Block* outer_block =
1942 17508 : factory()->NewBlock(for_info.bound_names.length() + 4, false);
1943 :
1944 : // Add statement: let/const x = i.
1945 17508 : outer_block->statements()->Add(init, zone());
1946 :
1947 17509 : const AstRawString* temp_name = ast_value_factory()->dot_for_string();
1948 :
1949 : // For each lexical variable x:
1950 : // make statement: temp_x = x.
1951 82084 : for (int i = 0; i < for_info.bound_names.length(); i++) {
1952 23533 : VariableProxy* proxy = NewUnresolved(for_info.bound_names[i]);
1953 23534 : Variable* temp = NewTemporary(temp_name);
1954 23534 : VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
1955 : Assignment* assignment = factory()->NewAssignment(Token::ASSIGN, temp_proxy,
1956 23533 : proxy, kNoSourcePosition);
1957 : Statement* assignment_statement =
1958 47068 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
1959 23534 : outer_block->statements()->Add(assignment_statement, zone());
1960 23534 : temps.Add(temp, zone());
1961 : }
1962 :
1963 : Variable* first = nullptr;
1964 : // Make statement: first = 1.
1965 17509 : if (next) {
1966 : first = NewTemporary(temp_name);
1967 2557 : VariableProxy* first_proxy = factory()->NewVariableProxy(first);
1968 2557 : Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
1969 : Assignment* assignment = factory()->NewAssignment(
1970 2557 : Token::ASSIGN, first_proxy, const1, kNoSourcePosition);
1971 : Statement* assignment_statement =
1972 5114 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
1973 2557 : outer_block->statements()->Add(assignment_statement, zone());
1974 : }
1975 :
1976 : // make statement: undefined;
1977 : outer_block->statements()->Add(
1978 : factory()->NewExpressionStatement(
1979 35018 : 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 17509 : 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 17509 : ZonePtrList<Variable> inner_vars(for_info.bound_names.length(), zone());
1999 : // For each let variable x:
2000 : // make statement: let/const x = temp_x.
2001 82084 : for (int i = 0; i < for_info.bound_names.length(); i++) {
2002 47068 : VariableProxy* proxy = DeclareBoundVariable(
2003 : for_info.bound_names[i], for_info.parsing_result.descriptor.mode,
2004 47068 : kNoSourcePosition);
2005 23534 : inner_vars.Add(proxy->var(), zone());
2006 23534 : 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 47067 : 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 17508 : if (next) {
2019 : DCHECK(first);
2020 : Expression* compare = nullptr;
2021 : // Make compare expression: first == 1.
2022 : {
2023 2556 : Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2024 2556 : VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2025 : compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1,
2026 2557 : kNoSourcePosition);
2027 : }
2028 : Statement* clear_first = nullptr;
2029 : // Make statement: first = 0.
2030 : {
2031 2557 : VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2032 2557 : Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
2033 : Assignment* assignment = factory()->NewAssignment(
2034 2557 : Token::ASSIGN, first_proxy, const0, kNoSourcePosition);
2035 : clear_first =
2036 2557 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2037 : }
2038 : Statement* clear_first_or_next = factory()->NewIfStatement(
2039 5114 : 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 17509 : VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2047 17509 : Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2048 : Assignment* assignment = factory()->NewAssignment(
2049 17509 : Token::ASSIGN, flag_proxy, const1, kNoSourcePosition);
2050 : Statement* assignment_statement =
2051 35018 : 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 11743 : factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
2059 11743 : Statement* noop = factory()->EmptyStatement();
2060 : ignore_completion_block->statements()->Add(
2061 11743 : factory()->NewIfStatement(cond, noop, stop, cond->position()),
2062 11743 : zone());
2063 : }
2064 :
2065 17509 : inner_block->statements()->Add(ignore_completion_block, zone());
2066 : // Make cond expression for main loop: flag == 1.
2067 : Expression* flag_cond = nullptr;
2068 : {
2069 17509 : Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2070 17509 : VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2071 : flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
2072 17509 : 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 17508 : VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2082 17509 : 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 82086 : for (int i = 0; i < for_info.bound_names.length(); i++) {
2090 23534 : VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
2091 : VariableProxy* proxy =
2092 23534 : 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 23534 : Token::COMMA, compound_next, assignment, kNoSourcePosition);
2097 : }
2098 :
2099 : compound_next_statement =
2100 17509 : 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 17509 : Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2116 17509 : VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2117 : compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
2118 17509 : kNoSourcePosition);
2119 : }
2120 : Statement* stop =
2121 17509 : factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
2122 17509 : Statement* empty = factory()->EmptyStatement();
2123 : Statement* if_flag_break =
2124 17509 : 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 17508 : return outer_block;
2134 : }
2135 :
2136 785821 : void ParserFormalParameters::ValidateDuplicate(Parser* parser) const {
2137 785821 : if (has_duplicate()) {
2138 2666 : parser->ReportMessageAt(duplicate_loc, MessageTemplate::kParamDupe);
2139 : }
2140 785821 : }
2141 733618 : void ParserFormalParameters::ValidateStrictMode(Parser* parser) const {
2142 733618 : if (strict_error_loc.IsValid()) {
2143 1910 : parser->ReportMessageAt(strict_error_loc, strict_error_message);
2144 : }
2145 733618 : }
2146 :
2147 125078 : 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 129679 : if (expr->IsNaryOperation()) {
2165 9198 : 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 28890 : for (size_t i = 0; i < nary->subsequent_length(); ++i) {
2174 : AddArrowFunctionFormalParameters(parameters, next,
2175 9846 : nary->subsequent_op_position(i));
2176 : next = nary->subsequent(i);
2177 : }
2178 : AddArrowFunctionFormalParameters(parameters, next, end_pos);
2179 125084 : return;
2180 : }
2181 :
2182 : // For the binary case, we recurse on the left-hand side of binary comma
2183 : // expressions.
2184 125080 : if (expr->IsBinaryOperation()) {
2185 28924 : 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 14462 : int comma_pos = binop->position();
2192 14462 : 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 125081 : if (is_rest) {
2202 3068 : 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 125084 : if (expr->IsAssignment()) {
2210 19618 : 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 363569 : void Parser::DeclareArrowFunctionFormalParameters(
2220 : ParserFormalParameters* parameters, Expression* expr,
2221 : const Scanner::Location& params_loc) {
2222 464357 : if (expr->IsEmptyParentheses() || has_error()) return;
2223 :
2224 100775 : AddArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos);
2225 :
2226 100777 : 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 142689 : 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 : function_state_->scope()->DeclareGeneratorObjectVar(
2241 428067 : ast_value_factory()->dot_generator_object_string());
2242 142688 : }
2243 :
2244 3799008 : 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 7598373 : 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 3799008 : bool is_wrapped = function_type == FunctionLiteral::kWrapped;
2260 : DCHECK_EQ(is_wrapped, arguments_for_wrapped_function != nullptr);
2261 :
2262 9741153 : int pos = function_token_pos == kNoSourcePosition ? peek_position()
2263 3799008 : : 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 3799008 : 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 3799008 : if (should_infer_name) {
2274 964514 : function_name = ast_value_factory()->empty_string();
2275 : }
2276 :
2277 : FunctionLiteral::EagerCompileHint eager_compile_hint =
2278 7024477 : function_state_->next_function_is_likely_called() || is_wrapped
2279 : ? FunctionLiteral::kShouldEagerCompile
2280 7024332 : : 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 3799008 : eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
2320 : const bool is_top_level = AllowsLazyParsingWithoutUnresolvedVariables();
2321 3799211 : const bool is_eager_top_level_function = !is_lazy && is_top_level;
2322 3799211 : const bool is_lazy_top_level_function = is_lazy && is_top_level;
2323 3799211 : const bool is_lazy_inner_function = is_lazy && !is_top_level;
2324 :
2325 : RuntimeCallTimerScope runtime_timer(
2326 : runtime_call_stats_,
2327 : parsing_on_main_thread_
2328 : ? RuntimeCallCounterId::kParseFunctionLiteral
2329 3799211 : : RuntimeCallCounterId::kParseBackgroundFunctionLiteral);
2330 : base::ElapsedTimer timer;
2331 3799126 : 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 3799126 : 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 3106597 : parse_lazily() && is_eager_top_level_function &&
2357 3799258 : FLAG_parallel_compile_tasks && info()->parallel_tasks() &&
2358 66 : scanner()->stream()->can_be_cloned_for_parallel_access();
2359 :
2360 : // This may be modified later to reflect preparsing decision taken
2361 3106449 : bool should_preparse = (parse_lazily() && is_lazy_top_level_function) ||
2362 6904623 : should_preparse_inner || should_post_parallel_task;
2363 :
2364 3799126 : ScopedPtrList<Statement> body(pointer_buffer());
2365 3799126 : int expected_property_count = -1;
2366 3799126 : int suspend_count = -1;
2367 3799126 : int num_parameters = -1;
2368 3799126 : int function_length = -1;
2369 3799126 : bool has_duplicate_parameters = false;
2370 : int function_literal_id = GetNextFunctionLiteralId();
2371 3799126 : ProducedPreparseData* produced_preparse_data = nullptr;
2372 :
2373 : // This Scope lives in the main zone. We'll migrate data into that zone later.
2374 3799126 : Zone* parse_zone = should_preparse ? &preparser_zone_ : zone();
2375 3799126 : DeclarationScope* scope = NewFunctionScope(kind, parse_zone);
2376 3799508 : SetLanguageMode(scope, language_mode);
2377 : #ifdef DEBUG
2378 : scope->SetScopeName(function_name);
2379 : #endif
2380 :
2381 7598802 : if (!is_wrapped && V8_UNLIKELY(!Check(Token::LPAREN))) {
2382 18343 : ReportUnexpectedToken(Next());
2383 18343 : return nullptr;
2384 : }
2385 847316 : 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 6321698 : should_preparse && SkipFunction(function_name, kind, function_type, scope,
2394 2540412 : &num_parameters, &produced_preparse_data);
2395 :
2396 3781286 : if (!did_preparse_successfully) {
2397 : // If skipping aborted, it rewound the scanner until before the LPAREN.
2398 : // Consume it in that case.
2399 1283059 : 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 1283059 : arguments_for_wrapped_function);
2405 : }
2406 :
2407 3781104 : 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 : 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 110 : function_name->byte_length());
2418 : }
2419 3781104 : if (V8_UNLIKELY(FLAG_runtime_stats) && did_preparse_successfully) {
2420 : const RuntimeCallCounterId counters[2] = {
2421 : RuntimeCallCounterId::kPreParseBackgroundWithVariableResolution,
2422 2 : RuntimeCallCounterId::kPreParseWithVariableResolution};
2423 2 : if (runtime_call_stats_) {
2424 : runtime_call_stats_->CorrectCurrentCounterId(
2425 2 : counters[parsing_on_main_thread_]);
2426 : }
2427 : }
2428 :
2429 : // Validate function name. We can do this only after parsing the function,
2430 : // since the function can declare itself strict.
2431 : language_mode = scope->language_mode();
2432 : CheckFunctionName(language_mode, function_name, function_name_validity,
2433 3781104 : function_name_location);
2434 :
2435 3781147 : if (is_strict(language_mode)) {
2436 847261 : CheckStrictOctalLiteral(scope->start_position(), scope->end_position());
2437 : }
2438 :
2439 : FunctionLiteral::ParameterFlag duplicate_parameters =
2440 : has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
2441 3781129 : : FunctionLiteral::kNoDuplicateParameters;
2442 :
2443 : // Note that the FunctionLiteral needs to be created in the main Zone again.
2444 : FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
2445 : function_name, scope, body, expected_property_count, num_parameters,
2446 : function_length, duplicate_parameters, function_type, eager_compile_hint,
2447 3781129 : pos, true, function_literal_id, produced_preparse_data);
2448 : function_literal->set_function_token_position(function_token_pos);
2449 3781103 : function_literal->set_suspend_count(suspend_count);
2450 :
2451 3781103 : if (should_post_parallel_task) {
2452 : // Start a parallel parse / compile task on the compiler dispatcher.
2453 55 : info()->parallel_tasks()->Enqueue(info(), function_name, function_literal);
2454 : }
2455 :
2456 3781102 : if (should_infer_name) {
2457 : fni_.AddFunction(function_literal);
2458 : }
2459 3781086 : return function_literal;
2460 : }
2461 :
2462 2570582 : bool Parser::SkipFunction(const AstRawString* function_name, FunctionKind kind,
2463 : FunctionLiteral::FunctionType function_type,
2464 : DeclarationScope* function_scope, int* num_parameters,
2465 : ProducedPreparseData** produced_preparse_data) {
2466 2570582 : FunctionState function_state(&function_state_, &scope_, function_scope);
2467 2570582 : function_scope->set_zone(&preparser_zone_);
2468 :
2469 : DCHECK_NE(kNoSourcePosition, function_scope->start_position());
2470 : DCHECK_EQ(kNoSourcePosition, parameters_end_pos_);
2471 :
2472 : DCHECK_IMPLIES(IsArrowFunction(kind),
2473 : scanner()->current_token() == Token::ARROW);
2474 :
2475 : // FIXME(marja): There are 2 ways to skip functions now. Unify them.
2476 2570582 : if (consumed_preparse_data_) {
2477 : int end_position;
2478 : LanguageMode language_mode;
2479 : int num_inner_functions;
2480 : bool uses_super_property;
2481 7747568 : if (stack_overflow()) return true;
2482 : *produced_preparse_data =
2483 : consumed_preparse_data_->GetDataForSkippableFunction(
2484 : main_zone(), function_scope->start_position(), &end_position,
2485 : num_parameters, &num_inner_functions, &uses_super_property,
2486 5082023 : &language_mode);
2487 :
2488 : function_scope->outer_scope()->SetMustUsePreparseData();
2489 : function_scope->set_is_skipped_function(true);
2490 60389 : function_scope->set_end_position(end_position);
2491 120778 : scanner()->SeekForward(end_position - 1);
2492 60389 : Expect(Token::RBRACE);
2493 60389 : SetLanguageMode(function_scope, language_mode);
2494 60389 : if (uses_super_property) {
2495 : function_scope->RecordSuperPropertyUsage();
2496 : }
2497 60389 : SkipFunctionLiterals(num_inner_functions);
2498 60389 : function_scope->ResetAfterPreparsing(ast_value_factory_, false);
2499 60389 : return true;
2500 : }
2501 :
2502 : Scanner::BookmarkScope bookmark(scanner());
2503 2510193 : bookmark.Set(function_scope->start_position());
2504 :
2505 : // With no cached data, we partially parse the function, without building an
2506 : // AST. This gathers the data needed to build a lazy function.
2507 7530939 : TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse");
2508 :
2509 : PreParser::PreParseResult result = reusable_preparser()->PreParseFunction(
2510 : function_name, kind, function_type, function_scope, use_counts_,
2511 2510269 : produced_preparse_data, this->script_id());
2512 :
2513 2510184 : if (result == PreParser::kPreParseStackOverflow) {
2514 : // Propagate stack overflow.
2515 43 : set_stack_overflow();
2516 2510141 : } else if (pending_error_handler()->has_error_unidentifiable_by_preparser()) {
2517 : // Make sure we don't re-preparse inner functions of the aborted function.
2518 : // The error might be in an inner function.
2519 48092 : allow_lazy_ = false;
2520 48092 : mode_ = PARSE_EAGERLY;
2521 : DCHECK(!pending_error_handler()->stack_overflow());
2522 : // If we encounter an error that the preparser can not identify we reset to
2523 : // the state before preparsing. The caller may then fully parse the function
2524 : // to identify the actual error.
2525 48092 : bookmark.Apply();
2526 48092 : function_scope->ResetAfterPreparsing(ast_value_factory(), true);
2527 : pending_error_handler()->clear_unidentifiable_error();
2528 48095 : return false;
2529 2462049 : } else if (pending_error_handler()->has_pending_error()) {
2530 : DCHECK(!pending_error_handler()->stack_overflow());
2531 : DCHECK(has_error());
2532 : } else {
2533 : DCHECK(!pending_error_handler()->stack_overflow());
2534 2450828 : set_allow_eval_cache(reusable_preparser()->allow_eval_cache());
2535 :
2536 7352987 : PreParserLogger* logger = reusable_preparser()->logger();
2537 : function_scope->set_end_position(logger->end());
2538 2450934 : Expect(Token::RBRACE);
2539 : total_preparse_skipped_ +=
2540 2451052 : function_scope->end_position() - function_scope->start_position();
2541 2451052 : *num_parameters = logger->num_parameters();
2542 : SkipFunctionLiterals(logger->num_inner_functions());
2543 2451052 : function_scope->AnalyzePartially(this, factory());
2544 : }
2545 :
2546 : return true;
2547 : }
2548 :
2549 38047 : Block* Parser::BuildParameterInitializationBlock(
2550 : const ParserFormalParameters& parameters) {
2551 : DCHECK(!parameters.is_simple);
2552 : DCHECK(scope()->is_function_scope());
2553 : DCHECK_EQ(scope(), parameters.scope);
2554 101165 : ScopedPtrList<Statement> init_statements(pointer_buffer());
2555 : int index = 0;
2556 136879 : for (auto parameter : parameters.params) {
2557 : Expression* initial_value =
2558 121566 : factory()->NewVariableProxy(parameters.scope->parameter(index));
2559 60784 : if (parameter->initializer() != nullptr) {
2560 : // IS_UNDEFINED($param) ? initializer : $param
2561 :
2562 : auto condition = factory()->NewCompareOperation(
2563 : Token::EQ_STRICT,
2564 42532 : factory()->NewVariableProxy(parameters.scope->parameter(index)),
2565 42532 : factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
2566 : initial_value =
2567 : factory()->NewConditional(condition, parameter->initializer(),
2568 21266 : initial_value, kNoSourcePosition);
2569 : }
2570 :
2571 : Scope* param_scope = scope();
2572 : ScopedPtrList<Statement>* param_init_statements = &init_statements;
2573 :
2574 60784 : base::Optional<ScopedPtrList<Statement>> non_simple_param_init_statements;
2575 101551 : if (!parameter->is_simple() &&
2576 40767 : scope()->AsDeclarationScope()->calls_sloppy_eval()) {
2577 1167 : param_scope = NewVarblockScope();
2578 1167 : param_scope->set_start_position(parameter->pattern->position());
2579 1167 : param_scope->set_end_position(parameter->initializer_end_position);
2580 : param_scope->RecordEvalCall();
2581 1167 : non_simple_param_init_statements.emplace(pointer_buffer());
2582 1167 : param_init_statements = &non_simple_param_init_statements.value();
2583 : // Rewrite the outer initializer to point to param_scope
2584 2334 : ReparentExpressionScope(stack_limit(), parameter->pattern, param_scope);
2585 1167 : ReparentExpressionScope(stack_limit(), initial_value, param_scope);
2586 : }
2587 :
2588 60783 : BlockState block_state(&scope_, param_scope);
2589 : DeclarationParsingResult::Declaration decl(parameter->pattern,
2590 60783 : initial_value);
2591 :
2592 60783 : InitializeVariables(param_init_statements, PARAMETER_VARIABLE, &decl);
2593 :
2594 60786 : if (param_init_statements != &init_statements) {
2595 : DCHECK_EQ(param_init_statements,
2596 : &non_simple_param_init_statements.value());
2597 : Block* param_block =
2598 1167 : factory()->NewBlock(true, *non_simple_param_init_statements);
2599 : non_simple_param_init_statements.reset();
2600 : param_block->set_scope(param_scope);
2601 1167 : param_scope = param_scope->FinalizeBlockScope();
2602 1167 : init_statements.Add(param_block);
2603 : }
2604 60786 : ++index;
2605 : }
2606 76100 : return factory()->NewBlock(true, init_statements);
2607 : }
2608 :
2609 69192 : Scope* Parser::NewHiddenCatchScope() {
2610 69192 : Scope* catch_scope = NewScopeWithParent(scope(), CATCH_SCOPE);
2611 : bool was_added;
2612 : catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(),
2613 138388 : VariableMode::kVar, NORMAL_VARIABLE, &was_added);
2614 : DCHECK(was_added);
2615 : catch_scope->set_is_hidden();
2616 69195 : return catch_scope;
2617 : }
2618 :
2619 44589 : Block* Parser::BuildRejectPromiseOnException(Block* inner_block) {
2620 : // try {
2621 : // <inner_block>
2622 : // } catch (.catch) {
2623 : // return %_AsyncFunctionReject(.generator_object, .catch, can_suspend);
2624 : // }
2625 89181 : Block* result = factory()->NewBlock(1, true);
2626 :
2627 : // catch (.catch) {
2628 : // return %_AsyncFunctionReject(.generator_object, .catch, can_suspend)
2629 : // }
2630 44590 : Scope* catch_scope = NewHiddenCatchScope();
2631 :
2632 : Expression* reject_promise;
2633 : {
2634 44592 : ScopedPtrList<Expression> args(pointer_buffer());
2635 : args.Add(factory()->NewVariableProxy(
2636 178367 : function_state_->scope()->generator_object_var()));
2637 89184 : args.Add(factory()->NewVariableProxy(catch_scope->catch_variable()));
2638 44591 : args.Add(factory()->NewBooleanLiteral(function_state_->CanSuspend(),
2639 89182 : kNoSourcePosition));
2640 : reject_promise = factory()->NewCallRuntime(
2641 44592 : Runtime::kInlineAsyncFunctionReject, args, kNoSourcePosition);
2642 : }
2643 : Block* catch_block = IgnoreCompletion(
2644 89183 : factory()->NewReturnStatement(reject_promise, kNoSourcePosition));
2645 :
2646 : TryStatement* try_catch_statement =
2647 : factory()->NewTryCatchStatementForAsyncAwait(
2648 44591 : inner_block, catch_scope, catch_block, kNoSourcePosition);
2649 44592 : result->statements()->Add(try_catch_statement, zone());
2650 44592 : return result;
2651 : }
2652 :
2653 90599 : Expression* Parser::BuildInitialYield(int pos, FunctionKind kind) {
2654 : Expression* yield_result = factory()->NewVariableProxy(
2655 271797 : function_state_->scope()->generator_object_var());
2656 : // The position of the yield is important for reporting the exception
2657 : // caused by calling the .throw method on a generator suspended at the
2658 : // initial yield (i.e. right after generator instantiation).
2659 90599 : function_state_->AddSuspend();
2660 : return factory()->NewYield(yield_result, scope()->start_position(),
2661 90599 : Suspend::kOnExceptionThrow);
2662 : }
2663 :
2664 1282982 : void Parser::ParseFunction(
2665 : ScopedPtrList<Statement>* body, const AstRawString* function_name, int pos,
2666 : FunctionKind kind, FunctionLiteral::FunctionType function_type,
2667 : DeclarationScope* function_scope, int* num_parameters, int* function_length,
2668 : bool* has_duplicate_parameters, int* expected_property_count,
2669 : int* suspend_count,
2670 84 : ZonePtrList<const AstRawString>* arguments_for_wrapped_function) {
2671 1282982 : ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
2672 :
2673 1282982 : FunctionState function_state(&function_state_, &scope_, function_scope);
2674 :
2675 : bool is_wrapped = function_type == FunctionLiteral::kWrapped;
2676 :
2677 1282982 : int expected_parameters_end_pos = parameters_end_pos_;
2678 1282982 : if (expected_parameters_end_pos != kNoSourcePosition) {
2679 : // This is the first function encountered in a CreateDynamicFunction eval.
2680 337991 : parameters_end_pos_ = kNoSourcePosition;
2681 : // The function name should have been ignored, giving us the empty string
2682 : // here.
2683 : DCHECK_EQ(function_name, ast_value_factory()->empty_string());
2684 : }
2685 :
2686 : ParserFormalParameters formals(function_scope);
2687 :
2688 : {
2689 : ParameterDeclarationParsingScope formals_scope(this);
2690 1282982 : if (is_wrapped) {
2691 : // For a function implicitly wrapped in function header and footer, the
2692 : // function arguments are provided separately to the source, and are
2693 : // declared directly here.
2694 : int arguments_length = arguments_for_wrapped_function->length();
2695 104 : for (int i = 0; i < arguments_length; i++) {
2696 : const bool is_rest = false;
2697 : Expression* argument = ExpressionFromIdentifier(
2698 20 : arguments_for_wrapped_function->at(i), kNoSourcePosition);
2699 : AddFormalParameter(&formals, argument, NullExpression(),
2700 : kNoSourcePosition, is_rest);
2701 : }
2702 : DCHECK_EQ(arguments_length, formals.num_parameters());
2703 : DeclareFormalParameters(&formals);
2704 : } else {
2705 : // For a regular function, the function arguments are parsed from source.
2706 : DCHECK_NULL(arguments_for_wrapped_function);
2707 2903787 : ParseFormalParameterList(&formals);
2708 1282875 : if (expected_parameters_end_pos != kNoSourcePosition) {
2709 : // Check for '(' or ')' shenanigans in the parameter string for dynamic
2710 : // functions.
2711 : int position = peek_position();
2712 337991 : if (position < expected_parameters_end_pos) {
2713 : ReportMessageAt(Scanner::Location(position, position + 1),
2714 100 : MessageTemplate::kArgStringTerminatesParametersEarly);
2715 50 : return;
2716 337941 : } else if (position > expected_parameters_end_pos) {
2717 : ReportMessageAt(Scanner::Location(expected_parameters_end_pos - 2,
2718 : expected_parameters_end_pos),
2719 36 : MessageTemplate::kUnexpectedEndOfArgString);
2720 18 : return;
2721 : }
2722 : }
2723 1282807 : Expect(Token::RPAREN);
2724 1282898 : int formals_end_position = scanner()->location().end_pos;
2725 :
2726 : CheckArityRestrictions(formals.arity, kind, formals.has_rest,
2727 : function_scope->start_position(),
2728 1282898 : formals_end_position);
2729 1282884 : Expect(Token::LBRACE);
2730 : }
2731 1282997 : formals.duplicate_loc = formals_scope.duplicate_location();
2732 : }
2733 :
2734 2565994 : *num_parameters = formals.num_parameters();
2735 1282997 : *function_length = formals.function_length;
2736 :
2737 1282997 : AcceptINScope scope(this, true);
2738 : ParseFunctionBody(body, function_name, pos, formals, kind, function_type,
2739 1282997 : FunctionBodyType::kBlock);
2740 :
2741 1282941 : *has_duplicate_parameters = formals.has_duplicate();
2742 :
2743 1282941 : *expected_property_count = function_state.expected_property_count();
2744 1282941 : *suspend_count = function_state.suspend_count();
2745 : }
2746 :
2747 0 : void Parser::DeclareClassVariable(const AstRawString* name,
2748 : ClassInfo* class_info, int class_token_pos) {
2749 : #ifdef DEBUG
2750 : scope()->SetScopeName(name);
2751 : #endif
2752 :
2753 183003 : if (name != nullptr) {
2754 121653 : VariableProxy* proxy =
2755 121652 : DeclareBoundVariable(name, VariableMode::kConst, class_token_pos);
2756 121653 : class_info->variable = proxy->var();
2757 : }
2758 0 : }
2759 :
2760 : // TODO(gsathya): Ideally, this should just bypass scope analysis and
2761 : // allocate a slot directly on the context. We should just store this
2762 : // index in the AST, instead of storing the variable.
2763 15016 : Variable* Parser::CreateSyntheticContextVariable(const AstRawString* name) {
2764 30034 : VariableProxy* proxy =
2765 15016 : DeclareBoundVariable(name, VariableMode::kConst, kNoSourcePosition);
2766 : proxy->var()->ForceContextAllocation();
2767 15017 : return proxy->var();
2768 : }
2769 :
2770 31753 : void Parser::DeclareClassField(ClassLiteralProperty* property,
2771 : const AstRawString* property_name,
2772 : bool is_static, bool is_computed_name,
2773 : bool is_private, ClassInfo* class_info) {
2774 : DCHECK(allow_harmony_public_fields() || allow_harmony_private_fields());
2775 :
2776 31753 : if (is_static) {
2777 29108 : class_info->static_fields->Add(property, zone());
2778 : } else {
2779 22876 : class_info->instance_fields->Add(property, zone());
2780 : }
2781 :
2782 : DCHECK_IMPLIES(is_computed_name, !is_private);
2783 31753 : if (is_computed_name) {
2784 : // We create a synthetic variable name here so that scope
2785 : // analysis doesn't dedupe the vars.
2786 : Variable* computed_name_var =
2787 : CreateSyntheticContextVariable(ClassFieldVariableName(
2788 10428 : ast_value_factory(), class_info->computed_field_count));
2789 5214 : property->set_computed_name_var(computed_name_var);
2790 5214 : class_info->properties->Add(property, zone());
2791 26539 : } else if (is_private) {
2792 9802 : Variable* private_name_var = CreateSyntheticContextVariable(property_name);
2793 9803 : private_name_var->set_initializer_position(property->value()->position());
2794 : property->set_private_name_var(private_name_var);
2795 9803 : class_info->properties->Add(property, zone());
2796 : }
2797 31754 : }
2798 :
2799 : // This method declares a property of the given class. It updates the
2800 : // following fields of class_info, as appropriate:
2801 : // - constructor
2802 : // - properties
2803 360795 : void Parser::DeclareClassProperty(const AstRawString* class_name,
2804 : ClassLiteralProperty* property,
2805 : bool is_constructor, ClassInfo* class_info) {
2806 360795 : if (is_constructor) {
2807 : DCHECK(!class_info->constructor);
2808 37995 : class_info->constructor = property->value()->AsFunctionLiteral();
2809 : DCHECK_NOT_NULL(class_info->constructor);
2810 : class_info->constructor->set_raw_name(
2811 357722 : class_name != nullptr ? ast_value_factory()->NewConsString(class_name)
2812 34922 : : nullptr);
2813 360795 : return;
2814 : }
2815 :
2816 341798 : class_info->properties->Add(property, zone());
2817 : }
2818 :
2819 26939 : FunctionLiteral* Parser::CreateInitializerFunction(
2820 : const char* name, DeclarationScope* scope,
2821 : ZonePtrList<ClassLiteral::Property>* fields) {
2822 : DCHECK_EQ(scope->function_kind(),
2823 : FunctionKind::kClassMembersInitializerFunction);
2824 : // function() { .. class fields initializer .. }
2825 53878 : ScopedPtrList<Statement> statements(pointer_buffer());
2826 : InitializeClassMembersStatement* static_fields =
2827 26939 : factory()->NewInitializeClassMembersStatement(fields, kNoSourcePosition);
2828 26939 : statements.Add(static_fields);
2829 : return factory()->NewFunctionLiteral(
2830 : ast_value_factory()->GetOneByteString(name), scope, statements, 0, 0, 0,
2831 : FunctionLiteral::kNoDuplicateParameters,
2832 : FunctionLiteral::kAnonymousExpression,
2833 : FunctionLiteral::kShouldEagerCompile, scope->start_position(), false,
2834 80818 : GetNextFunctionLiteralId());
2835 : }
2836 :
2837 : // This method generates a ClassLiteral AST node.
2838 : // It uses the following fields of class_info:
2839 : // - constructor (if missing, it updates it with a default constructor)
2840 : // - proxy
2841 : // - extends
2842 : // - properties
2843 : // - has_name_static_property
2844 : // - has_static_computed_names
2845 109000 : Expression* Parser::RewriteClassLiteral(Scope* block_scope,
2846 : const AstRawString* name,
2847 : ClassInfo* class_info, int pos,
2848 : int end_pos) {
2849 : DCHECK_NOT_NULL(block_scope);
2850 : DCHECK_EQ(block_scope->scope_type(), BLOCK_SCOPE);
2851 : DCHECK_EQ(block_scope->language_mode(), LanguageMode::kStrict);
2852 :
2853 109000 : bool has_extends = class_info->extends != nullptr;
2854 109000 : bool has_default_constructor = class_info->constructor == nullptr;
2855 109000 : if (has_default_constructor) {
2856 : class_info->constructor =
2857 90211 : DefaultConstructor(name, has_extends, pos, end_pos);
2858 : }
2859 :
2860 109005 : if (name != nullptr) {
2861 : DCHECK_NOT_NULL(class_info->variable);
2862 81276 : class_info->variable->set_initializer_position(end_pos);
2863 : }
2864 :
2865 : FunctionLiteral* static_fields_initializer = nullptr;
2866 109005 : if (class_info->has_static_class_fields) {
2867 : static_fields_initializer = CreateInitializerFunction(
2868 : "<static_fields_initializer>", class_info->static_fields_scope,
2869 8435 : class_info->static_fields);
2870 : }
2871 :
2872 : FunctionLiteral* instance_members_initializer_function = nullptr;
2873 109002 : if (class_info->has_instance_members) {
2874 : instance_members_initializer_function = CreateInitializerFunction(
2875 : "<instance_members_initializer>", class_info->instance_members_scope,
2876 18505 : class_info->instance_fields);
2877 18505 : class_info->constructor->set_requires_instance_members_initializer(true);
2878 : }
2879 :
2880 : ClassLiteral* class_literal = factory()->NewClassLiteral(
2881 : block_scope, class_info->variable, class_info->extends,
2882 : class_info->constructor, class_info->properties,
2883 : static_fields_initializer, instance_members_initializer_function, pos,
2884 : end_pos, class_info->has_name_static_property,
2885 109002 : class_info->has_static_computed_names, class_info->is_anonymous);
2886 :
2887 109002 : AddFunctionForNameInference(class_info->constructor);
2888 109002 : return class_literal;
2889 : }
2890 :
2891 11764 : bool Parser::IsPropertyWithPrivateFieldKey(Expression* expression) {
2892 11765 : if (!expression->IsProperty()) return false;
2893 14410 : Property* property = expression->AsProperty();
2894 :
2895 7208 : if (!property->key()->IsVariableProxy()) return false;
2896 1514 : VariableProxy* key = property->key()->AsVariableProxy();
2897 :
2898 1514 : return key->IsPrivateName();
2899 : }
2900 :
2901 10021 : void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) {
2902 : // For each var-binding that shadows a parameter, insert an assignment
2903 : // initializing the variable with the parameter.
2904 10021 : Scope* inner_scope = inner_block->scope();
2905 : DCHECK(inner_scope->is_declaration_scope());
2906 : Scope* function_scope = inner_scope->outer_scope();
2907 : DCHECK(function_scope->is_function_scope());
2908 10021 : BlockState block_state(&scope_, inner_scope);
2909 41551 : for (Declaration* decl : *inner_scope->declarations()) {
2910 52139 : if (decl->var()->mode() != VariableMode::kVar ||
2911 : !decl->IsVariableDeclaration()) {
2912 20650 : continue;
2913 : }
2914 5624 : const AstRawString* name = decl->var()->raw_name();
2915 : Variable* parameter = function_scope->LookupLocal(name);
2916 5624 : if (parameter == nullptr) continue;
2917 859 : VariableProxy* to = NewUnresolved(name);
2918 858 : VariableProxy* from = factory()->NewVariableProxy(parameter);
2919 : Expression* assignment =
2920 859 : factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition);
2921 : Statement* statement =
2922 1718 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2923 859 : inner_block->statements()->InsertAt(0, statement, zone());
2924 : }
2925 10023 : }
2926 :
2927 2443360 : void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope) {
2928 : // For the outermost eval scope, we cannot hoist during parsing: let
2929 : // declarations in the surrounding scope may prevent hoisting, but the
2930 : // information is unaccessible during parsing. In this case, we hoist later in
2931 : // DeclarationScope::Analyze.
2932 2443360 : if (scope->is_eval_scope() && scope->outer_scope() == original_scope_) {
2933 2443323 : return;
2934 : }
2935 1651169 : scope->HoistSloppyBlockFunctions(factory());
2936 : }
2937 :
2938 : // ----------------------------------------------------------------------------
2939 : // Parser support
2940 :
2941 15713 : bool Parser::TargetStackContainsLabel(const AstRawString* label) {
2942 24879 : for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
2943 18332 : if (ContainsLabel(t->statement()->labels(), label)) return true;
2944 : }
2945 : return false;
2946 : }
2947 :
2948 44447 : BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label) {
2949 44447 : bool anonymous = label == nullptr;
2950 62849 : for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
2951 47335 : BreakableStatement* stat = t->statement();
2952 172392 : if ((anonymous && stat->is_target_for_anonymous()) ||
2953 30391 : (!anonymous && ContainsLabel(stat->labels(), label))) {
2954 : return stat;
2955 : }
2956 : }
2957 : return nullptr;
2958 : }
2959 :
2960 13258 : IterationStatement* Parser::LookupContinueTarget(const AstRawString* label) {
2961 : bool anonymous = label == nullptr;
2962 33889 : for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
2963 37273 : IterationStatement* stat = t->statement()->AsIterationStatement();
2964 33523 : if (stat == nullptr) continue;
2965 :
2966 : DCHECK(stat->is_target_for_anonymous());
2967 16554 : if (anonymous || ContainsLabel(stat->own_labels(), label)) {
2968 : return stat;
2969 : }
2970 1272 : if (ContainsLabel(stat->labels(), label)) break;
2971 : }
2972 : return nullptr;
2973 : }
2974 :
2975 1718311 : void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) {
2976 1718311 : Handle<String> source_url = scanner_.SourceUrl(isolate);
2977 1718311 : if (!source_url.is_null()) {
2978 7606 : script->set_source_url(*source_url);
2979 : }
2980 1718311 : Handle<String> source_mapping_url = scanner_.SourceMappingUrl(isolate);
2981 1718314 : if (!source_mapping_url.is_null()) {
2982 200 : script->set_source_mapping_url(*source_mapping_url);
2983 : }
2984 1718314 : }
2985 :
2986 2424736 : void Parser::UpdateStatistics(Isolate* isolate, Handle<Script> script) {
2987 : // Move statistics to Isolate.
2988 184281726 : for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
2989 : ++feature) {
2990 181856958 : if (use_counts_[feature] > 0) {
2991 1903161 : isolate->CountUsage(v8::Isolate::UseCounterFeature(feature));
2992 : }
2993 : }
2994 2424768 : if (scanner_.FoundHtmlComment()) {
2995 10 : isolate->CountUsage(v8::Isolate::kHtmlComment);
2996 20 : if (script->line_offset() == 0 && script->column_offset() == 0) {
2997 10 : isolate->CountUsage(v8::Isolate::kHtmlCommentInExternalScript);
2998 : }
2999 : }
3000 : isolate->counters()->total_preparse_skipped()->Increment(
3001 4849536 : total_preparse_skipped_);
3002 2424767 : }
3003 :
3004 26433 : void Parser::ParseOnBackground(ParseInfo* info) {
3005 : RuntimeCallTimerScope runtimeTimer(
3006 13179 : runtime_call_stats_, RuntimeCallCounterId::kParseBackgroundProgram);
3007 13179 : parsing_on_main_thread_ = false;
3008 : set_script_id(info->script_id());
3009 :
3010 : DCHECK_NULL(info->literal());
3011 : FunctionLiteral* result = nullptr;
3012 :
3013 13179 : scanner_.Initialize();
3014 : DCHECK(info->maybe_outer_scope_info().is_null());
3015 :
3016 : DCHECK(original_scope_);
3017 :
3018 : // When streaming, we don't know the length of the source until we have parsed
3019 : // it. The raw data can be UTF-8, so we wouldn't know the source length until
3020 : // we have decoded it anyway even if we knew the raw data length (which we
3021 : // don't). We work around this by storing all the scopes which need their end
3022 : // position set at the end of the script (the top scope and possible eval
3023 : // scopes) and set their end position after we know the script length.
3024 13179 : if (info->is_toplevel()) {
3025 13104 : result = DoParseProgram(/* isolate = */ nullptr, info);
3026 : } else {
3027 : result =
3028 75 : DoParseFunction(/* isolate = */ nullptr, info, info->function_name());
3029 : }
3030 13179 : MaybeResetCharacterStream(info, result);
3031 :
3032 : info->set_literal(result);
3033 :
3034 : // We cannot internalize on a background thread; a foreground task will take
3035 : // care of calling AstValueFactory::Internalize just before compilation.
3036 13179 : }
3037 :
3038 37904 : Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
3039 75809 : return new (zone()) TemplateLiteral(zone(), pos);
3040 : }
3041 :
3042 82294 : void Parser::AddTemplateSpan(TemplateLiteralState* state, bool should_cook,
3043 : bool tail) {
3044 243169 : int end = scanner()->location().end_pos - (tail ? 1 : 2);
3045 82294 : const AstRawString* raw = scanner()->CurrentRawSymbol(ast_value_factory());
3046 82296 : if (should_cook) {
3047 78580 : const AstRawString* cooked = scanner()->CurrentSymbol(ast_value_factory());
3048 78579 : (*state)->AddTemplateSpan(cooked, raw, end, zone());
3049 : } else {
3050 3716 : (*state)->AddTemplateSpan(nullptr, raw, end, zone());
3051 : }
3052 82296 : }
3053 :
3054 0 : void Parser::AddTemplateExpression(TemplateLiteralState* state,
3055 : Expression* expression) {
3056 47485 : (*state)->AddExpression(expression, zone());
3057 0 : }
3058 :
3059 34807 : Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
3060 : Expression* tag) {
3061 34807 : TemplateLiteral* lit = *state;
3062 : int pos = lit->position();
3063 62438 : const ZonePtrList<const AstRawString>* cooked_strings = lit->cooked();
3064 34807 : const ZonePtrList<const AstRawString>* raw_strings = lit->raw();
3065 34807 : const ZonePtrList<Expression>* expressions = lit->expressions();
3066 : DCHECK_EQ(cooked_strings->length(), raw_strings->length());
3067 : DCHECK_EQ(cooked_strings->length(), expressions->length() + 1);
3068 :
3069 34807 : if (!tag) {
3070 27631 : if (cooked_strings->length() == 1) {
3071 14038 : return factory()->NewStringLiteral(cooked_strings->first(), pos);
3072 : }
3073 41225 : return factory()->NewTemplateLiteral(cooked_strings, expressions, pos);
3074 : } else {
3075 : // GetTemplateObject
3076 : Expression* template_object =
3077 7176 : factory()->NewGetTemplateObject(cooked_strings, raw_strings, pos);
3078 :
3079 : // Call TagFn
3080 7176 : ScopedPtrList<Expression> call_args(pointer_buffer());
3081 : call_args.Add(template_object);
3082 7176 : call_args.AddAll(*expressions);
3083 7176 : return factory()->NewTaggedTemplate(tag, call_args, pos);
3084 : }
3085 : }
3086 :
3087 : namespace {
3088 :
3089 15015 : bool OnlyLastArgIsSpread(const ScopedPtrList<Expression>& args) {
3090 10668 : for (int i = 0; i < args.length() - 1; i++) {
3091 1718 : if (args.at(i)->IsSpread()) {
3092 : return false;
3093 : }
3094 : }
3095 3617 : return args.at(args.length() - 1)->IsSpread();
3096 : }
3097 :
3098 : } // namespace
3099 :
3100 702 : ArrayLiteral* Parser::ArrayLiteralFromListWithSpread(
3101 2129 : const ScopedPtrList<Expression>& list) {
3102 : // If there's only a single spread argument, a fast path using CallWithSpread
3103 : // is taken.
3104 : DCHECK_LT(1, list.length());
3105 :
3106 : // The arguments of the spread call become a single ArrayLiteral.
3107 : int first_spread = 0;
3108 2831 : for (; first_spread < list.length() && !list.at(first_spread)->IsSpread();
3109 : ++first_spread) {
3110 : }
3111 :
3112 : DCHECK_LT(first_spread, list.length());
3113 702 : return factory()->NewArrayLiteral(list, first_spread, kNoSourcePosition);
3114 : }
3115 :
3116 4122 : Expression* Parser::SpreadCall(Expression* function,
3117 : const ScopedPtrList<Expression>& args_list,
3118 : int pos, Call::PossiblyEval is_possibly_eval) {
3119 : // Handle this case in BytecodeGenerator.
3120 4849 : if (OnlyLastArgIsSpread(args_list) || function->IsSuperCallReference()) {
3121 3670 : return factory()->NewCall(function, args_list, pos);
3122 : }
3123 :
3124 696 : ScopedPtrList<Expression> args(pointer_buffer());
3125 697 : if (function->IsProperty()) {
3126 : // Method calls
3127 488 : if (function->AsProperty()->IsSuperAccess()) {
3128 0 : Expression* home = ThisExpression();
3129 0 : args.Add(function);
3130 0 : args.Add(home);
3131 : } else {
3132 244 : Variable* temp = NewTemporary(ast_value_factory()->empty_string());
3133 243 : VariableProxy* obj = factory()->NewVariableProxy(temp);
3134 : Assignment* assign_obj = factory()->NewAssignment(
3135 243 : Token::ASSIGN, obj, function->AsProperty()->obj(), kNoSourcePosition);
3136 : function = factory()->NewProperty(
3137 244 : assign_obj, function->AsProperty()->key(), kNoSourcePosition);
3138 244 : args.Add(function);
3139 244 : obj = factory()->NewVariableProxy(temp);
3140 244 : args.Add(obj);
3141 : }
3142 : } else {
3143 : // Non-method calls
3144 : args.Add(function);
3145 906 : args.Add(factory()->NewUndefinedLiteral(kNoSourcePosition));
3146 : }
3147 697 : args.Add(ArrayLiteralFromListWithSpread(args_list));
3148 697 : return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos);
3149 : }
3150 :
3151 225 : Expression* Parser::SpreadCallNew(Expression* function,
3152 : const ScopedPtrList<Expression>& args_list,
3153 : int pos) {
3154 225 : if (OnlyLastArgIsSpread(args_list)) {
3155 : // Handle in BytecodeGenerator.
3156 220 : return factory()->NewCallNew(function, args_list, pos);
3157 : }
3158 5 : ScopedPtrList<Expression> args(pointer_buffer());
3159 : args.Add(function);
3160 5 : args.Add(ArrayLiteralFromListWithSpread(args_list));
3161 :
3162 5 : return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos);
3163 : }
3164 :
3165 5655032 : void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) {
3166 : v8::Isolate::UseCounterFeature feature;
3167 5655032 : if (is_sloppy(mode))
3168 : feature = v8::Isolate::kSloppyMode;
3169 1472208 : else if (is_strict(mode))
3170 : feature = v8::Isolate::kStrictMode;
3171 : else
3172 0 : UNREACHABLE();
3173 5655032 : ++use_counts_[feature];
3174 : scope->SetLanguageMode(mode);
3175 5655032 : }
3176 :
3177 4265 : void Parser::SetAsmModule() {
3178 : // Store the usage count; The actual use counter on the isolate is
3179 : // incremented after parsing is done.
3180 4265 : ++use_counts_[v8::Isolate::kUseAsm];
3181 : DCHECK(scope()->is_declaration_scope());
3182 4265 : scope()->AsDeclarationScope()->set_is_asm_module();
3183 4265 : info_->set_contains_asm_module(true);
3184 4265 : }
3185 :
3186 62424 : Expression* Parser::ExpressionListToExpression(
3187 5376483 : const ScopedPtrList<Expression>& args) {
3188 : Expression* expr = args.at(0);
3189 62424 : if (args.length() == 1) return expr;
3190 59383 : if (args.length() == 2) {
3191 : return factory()->NewBinaryOperation(Token::COMMA, expr, args.at(1),
3192 106882 : args.at(1)->position());
3193 : }
3194 : NaryOperation* result =
3195 5942 : factory()->NewNaryOperation(Token::COMMA, expr, args.length() - 1);
3196 5257576 : for (int i = 1; i < args.length(); i++) {
3197 2622847 : result->AddSubsequent(args.at(i), args.at(i)->position());
3198 : }
3199 : return result;
3200 : }
3201 :
3202 : // This method completes the desugaring of the body of async_function.
3203 85629 : void Parser::RewriteAsyncFunctionBody(ScopedPtrList<Statement>* body,
3204 : Block* block, Expression* return_value) {
3205 : // function async_function() {
3206 : // .generator_object = %_AsyncFunctionEnter();
3207 : // BuildRejectPromiseOnException({
3208 : // ... block ...
3209 : // return %_AsyncFunctionResolve(.generator_object, expr);
3210 : // })
3211 : // }
3212 :
3213 : block->statements()->Add(factory()->NewAsyncReturnStatement(
3214 42814 : return_value, return_value->position()),
3215 85629 : zone());
3216 42814 : block = BuildRejectPromiseOnException(block);
3217 : body->Add(block);
3218 42815 : }
3219 :
3220 6819981 : void Parser::SetFunctionNameFromPropertyName(LiteralProperty* property,
3221 : const AstRawString* name,
3222 : const AstRawString* prefix) {
3223 6863834 : if (has_error()) return;
3224 : // Ensure that the function we are going to create has shared name iff
3225 : // we are not going to set it later.
3226 3388059 : if (property->NeedsSetFunctionName()) {
3227 : name = nullptr;
3228 : prefix = nullptr;
3229 : } else {
3230 : // If the property value is an anonymous function or an anonymous class or
3231 : // a concise method or an accessor function which doesn't require the name
3232 : // to be set then the shared name must be provided.
3233 : DCHECK_IMPLIES(property->value()->IsAnonymousFunctionDefinition() ||
3234 : property->value()->IsConciseMethodDefinition() ||
3235 : property->value()->IsAccessorFunctionDefinition(),
3236 : name != nullptr);
3237 : }
3238 :
3239 : Expression* value = property->value();
3240 3388064 : SetFunctionName(value, name, prefix);
3241 : }
3242 :
3243 3024876 : void Parser::SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
3244 : const AstRawString* name,
3245 : const AstRawString* prefix) {
3246 : // Ignore "__proto__" as a name when it's being used to set the [[Prototype]]
3247 : // of an object literal.
3248 : // See ES #sec-__proto__-property-names-in-object-initializers.
3249 9068174 : if (property->IsPrototype() || has_error()) return;
3250 :
3251 : DCHECK(!property->value()->IsAnonymousFunctionDefinition() ||
3252 : property->kind() == ObjectLiteralProperty::COMPUTED);
3253 :
3254 : SetFunctionNameFromPropertyName(static_cast<LiteralProperty*>(property), name,
3255 2995526 : prefix);
3256 : }
3257 :
3258 12472057 : void Parser::SetFunctionNameFromIdentifierRef(Expression* value,
3259 : Expression* identifier) {
3260 24944253 : if (!identifier->IsVariableProxy()) return;
3261 16786284 : SetFunctionName(value, identifier->AsVariableProxy()->raw_name());
3262 : }
3263 :
3264 11781346 : void Parser::SetFunctionName(Expression* value, const AstRawString* name,
3265 : const AstRawString* prefix) {
3266 34996041 : if (!value->IsAnonymousFunctionDefinition() &&
3267 22864305 : !value->IsConciseMethodDefinition() &&
3268 11082954 : !value->IsAccessorFunctionDefinition()) {
3269 11781322 : return;
3270 : }
3271 729648 : auto function = value->AsFunctionLiteral();
3272 729613 : if (value->IsClassLiteral()) {
3273 2395 : function = value->AsClassLiteral()->constructor();
3274 : }
3275 729613 : if (function != nullptr) {
3276 : AstConsString* cons_name = nullptr;
3277 729627 : if (name != nullptr) {
3278 719411 : if (prefix != nullptr) {
3279 27558 : cons_name = ast_value_factory()->NewConsString(prefix, name);
3280 : } else {
3281 691853 : cons_name = ast_value_factory()->NewConsString(name);
3282 : }
3283 : } else {
3284 : DCHECK_NULL(prefix);
3285 : }
3286 : function->set_raw_name(cons_name);
3287 : }
3288 : }
3289 :
3290 0 : Statement* Parser::CheckCallable(Variable* var, Expression* error, int pos) {
3291 : const int nopos = kNoSourcePosition;
3292 : Statement* validate_var;
3293 : {
3294 : Expression* type_of = factory()->NewUnaryOperation(
3295 0 : Token::TYPEOF, factory()->NewVariableProxy(var), nopos);
3296 : Expression* function_literal = factory()->NewStringLiteral(
3297 0 : ast_value_factory()->function_string(), nopos);
3298 : Expression* condition = factory()->NewCompareOperation(
3299 0 : Token::EQ_STRICT, type_of, function_literal, nopos);
3300 :
3301 0 : Statement* throw_call = factory()->NewExpressionStatement(error, pos);
3302 :
3303 : validate_var = factory()->NewIfStatement(
3304 0 : condition, factory()->EmptyStatement(), throw_call, nopos);
3305 : }
3306 0 : return validate_var;
3307 : }
3308 :
3309 : } // namespace internal
3310 178779 : } // namespace v8
|