5 #include "src/parsing/parser.h" 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/bailout-reason.h" 14 #include "src/base/platform/platform.h" 15 #include "src/char-predicates-inl.h" 16 #include "src/compiler-dispatcher/compiler-dispatcher.h" 17 #include "src/conversions-inl.h" 19 #include "src/message-template.h" 20 #include "src/objects/scope-info.h" 21 #include "src/parsing/expression-scope-reparenter.h" 22 #include "src/parsing/parse-info.h" 23 #include "src/parsing/rewriter.h" 24 #include "src/runtime/runtime.h" 25 #include "src/string-stream.h" 26 #include "src/tracing/trace-event.h" 31 FunctionLiteral* Parser::DefaultConstructor(
const AstRawString* name,
32 bool call_super,
int pos,
34 int expected_property_count = -1;
35 const int parameter_count = 0;
37 FunctionKind kind = call_super ? FunctionKind::kDefaultDerivedConstructor
38 : FunctionKind::kDefaultBaseConstructor;
39 DeclarationScope* function_scope = NewFunctionScope(kind);
40 SetLanguageMode(function_scope, LanguageMode::kStrict);
42 function_scope->set_start_position(pos);
43 function_scope->set_end_position(pos);
44 ScopedPtrList<Statement> body(pointer_buffer());
47 FunctionState function_state(&function_state_, &scope_, function_scope);
51 auto constructor_args_name = ast_value_factory()->empty_string();
53 bool is_optional =
false;
54 Variable* constructor_args = function_scope->DeclareParameter(
55 constructor_args_name, VariableMode::kTemporary, is_optional, is_rest,
56 ast_value_factory(), pos);
60 ScopedPtrList<Expression> args(pointer_buffer());
61 Spread* spread_args = factory()->NewSpread(
62 factory()->NewVariableProxy(constructor_args), pos, pos);
64 args.Add(spread_args);
65 Expression* super_call_ref = NewSuperCallReference(pos);
66 call = factory()->NewCall(super_call_ref, args, pos);
68 body.Add(factory()->NewReturnStatement(call, pos));
71 expected_property_count = function_state.expected_property_count();
74 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
75 name, function_scope, body, expected_property_count, parameter_count,
76 parameter_count, FunctionLiteral::kNoDuplicateParameters,
77 FunctionLiteral::kAnonymousExpression, default_eager_compile_hint(), pos,
78 true, GetNextFunctionLiteralId());
79 return function_literal;
82 void Parser::GetUnexpectedTokenMessage(Token::Value token,
83 MessageTemplate* message,
84 Scanner::Location* location,
88 *message = MessageTemplate::kUnexpectedEOS;
93 *message = MessageTemplate::kUnexpectedTokenNumber;
96 *message = MessageTemplate::kUnexpectedTokenString;
98 case Token::PRIVATE_NAME:
99 case Token::IDENTIFIER:
100 *message = MessageTemplate::kUnexpectedTokenIdentifier;
104 *message = MessageTemplate::kUnexpectedReserved;
109 case Token::FUTURE_STRICT_RESERVED_WORD:
110 *message = is_strict(language_mode())
111 ? MessageTemplate::kUnexpectedStrictReserved
112 : MessageTemplate::kUnexpectedTokenIdentifier;
114 case Token::TEMPLATE_SPAN:
115 case Token::TEMPLATE_TAIL:
116 *message = MessageTemplate::kUnexpectedTemplateString;
118 case Token::ESCAPED_STRICT_RESERVED_WORD:
119 case Token::ESCAPED_KEYWORD:
120 *message = MessageTemplate::kInvalidEscapedReservedWord;
123 if (scanner()->has_error()) {
124 *message = scanner()->error();
125 *location = scanner()->error_location();
127 *message = MessageTemplate::kInvalidOrUnexpectedToken;
130 case Token::REGEXP_LITERAL:
131 *message = MessageTemplate::kUnexpectedTokenRegExp;
134 const char* name = Token::String(token);
135 DCHECK_NOT_NULL(name);
144 bool Parser::ShortcutNumericLiteralBinaryExpression(Expression** x,
146 Token::Value op,
int pos) {
147 if ((*x)->IsNumberLiteral() && y->IsNumberLiteral()) {
148 double x_val = (*x)->AsLiteral()->AsNumber();
149 double y_val = y->AsLiteral()->AsNumber();
152 *x = factory()->NewNumberLiteral(x_val + y_val, pos);
155 *x = factory()->NewNumberLiteral(x_val - y_val, pos);
158 *x = factory()->NewNumberLiteral(x_val * y_val, pos);
161 *x = factory()->NewNumberLiteral(x_val / y_val, pos);
163 case Token::BIT_OR: {
164 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
165 *x = factory()->NewNumberLiteral(value, pos);
168 case Token::BIT_AND: {
169 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
170 *x = factory()->NewNumberLiteral(value, pos);
173 case Token::BIT_XOR: {
174 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
175 *x = factory()->NewNumberLiteral(value, pos);
179 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1F);
180 *x = factory()->NewNumberLiteral(value, pos);
184 uint32_t shift = DoubleToInt32(y_val) & 0x1F;
185 uint32_t value = DoubleToUint32(x_val) >> shift;
186 *x = factory()->NewNumberLiteral(value, pos);
190 uint32_t shift = DoubleToInt32(y_val) & 0x1F;
191 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
192 *x = factory()->NewNumberLiteral(value, pos);
196 double value = Pow(x_val, y_val);
197 int int_value =
static_cast<int>(value);
198 *x = factory()->NewNumberLiteral(
199 int_value == value && value != -0.0 ? int_value : value, pos);
209 bool Parser::CollapseNaryExpression(Expression** x, Expression* y,
210 Token::Value op,
int pos,
211 const SourceRange& range) {
213 if (!Token::IsBinaryOp(op) || op == Token::EXP)
return false;
217 NaryOperation* nary =
nullptr;
218 if ((*x)->IsBinaryOperation()) {
219 BinaryOperation* binop = (*x)->AsBinaryOperation();
220 if (binop->op() != op)
return false;
222 nary = factory()->NewNaryOperation(op, binop->left(), 2);
223 nary->AddSubsequent(binop->right(), binop->position());
224 ConvertBinaryToNaryOperationSourceRange(binop, nary);
226 }
else if ((*x)->IsNaryOperation()) {
227 nary = (*x)->AsNaryOperation();
228 if (nary->op() != op)
return false;
236 nary->AddSubsequent(y, pos);
237 AppendNaryOperationSourceRange(nary, range);
242 Expression* Parser::BuildUnaryExpression(Expression* expression,
243 Token::Value op,
int pos) {
244 DCHECK_NOT_NULL(expression);
245 const Literal* literal = expression->AsLiteral();
246 if (literal !=
nullptr) {
247 if (op == Token::NOT) {
249 return factory()->NewBooleanLiteral(literal->ToBooleanIsFalse(), pos);
250 }
else if (literal->IsNumberLiteral()) {
252 double value = literal->AsNumber();
257 return factory()->NewNumberLiteral(-value, pos);
259 return factory()->NewNumberLiteral(~DoubleToInt32(value), pos);
265 return factory()->NewUnaryOperation(op, expression, pos);
268 Expression* Parser::NewThrowError(Runtime::FunctionId
id,
269 MessageTemplate message,
270 const AstRawString* arg,
int pos) {
271 ScopedPtrList<Expression> args(pointer_buffer());
272 args.Add(factory()->NewSmiLiteral(static_cast<int>(message), pos));
273 args.Add(factory()->NewStringLiteral(arg, pos));
274 CallRuntime* call_constructor = factory()->NewCallRuntime(
id, args, pos);
275 return factory()->NewThrow(call_constructor, pos);
278 Expression* Parser::NewSuperPropertyReference(
int pos) {
280 VariableProxy* this_function_proxy =
281 NewUnresolved(ast_value_factory()->this_function_string(), pos);
282 Expression* home_object_symbol_literal = factory()->NewSymbolLiteral(
283 AstSymbol::kHomeObjectSymbol, kNoSourcePosition);
284 Expression* home_object = factory()->NewProperty(
285 this_function_proxy, home_object_symbol_literal, pos);
286 return factory()->NewSuperPropertyReference(
287 ThisExpression(pos)->AsVariableProxy(), home_object, pos);
290 Expression* Parser::NewSuperCallReference(
int pos) {
291 VariableProxy* new_target_proxy =
292 NewUnresolved(ast_value_factory()->new_target_string(), pos);
293 VariableProxy* this_function_proxy =
294 NewUnresolved(ast_value_factory()->this_function_string(), pos);
295 return factory()->NewSuperCallReference(
296 ThisExpression(pos)->AsVariableProxy(), new_target_proxy,
297 this_function_proxy, pos);
300 Expression* Parser::NewTargetExpression(
int pos) {
301 auto proxy = NewUnresolved(ast_value_factory()->new_target_string(), pos);
302 proxy->set_is_new_target();
306 Expression* Parser::ImportMetaExpression(
int pos) {
307 ScopedPtrList<Expression> args(pointer_buffer());
308 return factory()->NewCallRuntime(Runtime::kInlineGetImportMetaObject, args,
312 Expression* Parser::ExpressionFromLiteral(Token::Value token,
int pos) {
314 case Token::NULL_LITERAL:
315 return factory()->NewNullLiteral(pos);
316 case Token::TRUE_LITERAL:
317 return factory()->NewBooleanLiteral(
true, pos);
318 case Token::FALSE_LITERAL:
319 return factory()->NewBooleanLiteral(
false, pos);
321 uint32_t value = scanner()->smi_value();
322 return factory()->NewSmiLiteral(value, pos);
324 case Token::NUMBER: {
325 double value = scanner()->DoubleValue();
326 return factory()->NewNumberLiteral(value, pos);
329 return factory()->NewBigIntLiteral(
330 AstBigInt(scanner()->CurrentLiteralAsCString(zone())), pos);
331 case Token::STRING: {
332 const AstRawString* symbol = GetSymbol();
333 fni_.PushLiteralName(symbol);
334 return factory()->NewStringLiteral(symbol, pos);
339 return FailureExpression();
342 Expression* Parser::NewV8Intrinsic(
const AstRawString* name,
343 const ScopedPtrList<Expression>& args,
345 if (extension_ !=
nullptr) {
348 GetClosureScope()->ForceEagerCompilation();
351 DCHECK(name->is_one_byte());
352 const Runtime::Function*
function =
353 Runtime::FunctionForName(name->raw_data(), name->length());
355 if (
function !=
nullptr) {
357 DCHECK_EQ(Context::kNotFound,
358 Context::IntrinsicIndexForName(name->raw_data(), name->length()));
361 if (function->nargs != -1 && function->nargs != args.length()) {
362 ReportMessage(MessageTemplate::kRuntimeWrongNumArgs);
363 return FailureExpression();
366 return factory()->NewCallRuntime(
function, args, pos);
370 Context::IntrinsicIndexForName(name->raw_data(), name->length());
373 if (context_index == Context::kNotFound) {
374 ReportMessage(MessageTemplate::kNotDefined, name);
375 return FailureExpression();
378 return factory()->NewCallRuntime(context_index, args, pos);
381 Parser::Parser(ParseInfo* info)
382 : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(),
383 info->extension(), info->GetOrCreateAstValueFactory(),
384 info->pending_error_handler(),
385 info->runtime_call_stats(), info->logger(),
386 info->script().is_null() ? -1 : info->script()->id(),
387 info->is_module(), true),
389 scanner_(info->character_stream(), info->is_module()),
390 preparser_zone_(info->zone()->allocator(), ZONE_NAME),
391 reusable_preparser_(nullptr),
392 mode_(PARSE_EAGERLY),
393 source_range_map_(info->source_range_map()),
394 target_stack_(nullptr),
395 total_preparse_skipped_(0),
396 consumed_preparsed_scope_data_(info->consumed_preparsed_scope_data()),
397 parameters_end_pos_(info->parameters_end_pos()) {
401 DCHECK_NOT_NULL(info->character_stream());
412 bool can_compile_lazily = FLAG_lazy && !info->is_eager();
414 set_default_eager_compile_hint(can_compile_lazily
415 ? FunctionLiteral::kShouldLazyCompile
416 : FunctionLiteral::kShouldEagerCompile);
417 allow_lazy_ = FLAG_lazy && info->allow_lazy_parsing() && !info->is_native() &&
418 info->extension() ==
nullptr && can_compile_lazily;
419 set_allow_natives(FLAG_allow_natives_syntax || info->is_native());
420 set_allow_harmony_public_fields(FLAG_harmony_public_fields);
421 set_allow_harmony_static_fields(FLAG_harmony_static_fields);
422 set_allow_harmony_dynamic_import(FLAG_harmony_dynamic_import);
423 set_allow_harmony_import_meta(FLAG_harmony_import_meta);
424 set_allow_harmony_numeric_separator(FLAG_harmony_numeric_separator);
425 set_allow_harmony_private_fields(FLAG_harmony_private_fields);
426 set_allow_harmony_private_methods(FLAG_harmony_private_methods);
427 for (
int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
429 use_counts_[feature] = 0;
433 void Parser::InitializeEmptyScopeChain(ParseInfo* info) {
434 DCHECK_NULL(original_scope_);
435 DCHECK_NULL(info->script_scope());
436 DeclarationScope* script_scope = NewScriptScope();
437 info->set_script_scope(script_scope);
438 original_scope_ = script_scope;
441 void Parser::DeserializeScopeChain(
442 Isolate* isolate, ParseInfo* info,
443 MaybeHandle<ScopeInfo> maybe_outer_scope_info) {
444 InitializeEmptyScopeChain(info);
445 Handle<ScopeInfo> outer_scope_info;
446 if (maybe_outer_scope_info.ToHandle(&outer_scope_info)) {
447 DCHECK(ThreadId::Current().Equals(isolate->thread_id()));
448 original_scope_ = Scope::DeserializeScopeChain(
449 isolate, zone(), *outer_scope_info, info->script_scope(),
450 ast_value_factory(), Scope::DeserializationMode::kScopesOnly);
456 void MaybeResetCharacterStream(ParseInfo* info, FunctionLiteral* literal) {
459 if (!FLAG_stress_validate_asm &&
460 (literal ==
nullptr || !literal->scope()->ContainsAsmModule())) {
461 info->ResetCharacterStream();
467 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
473 DCHECK(parsing_on_main_thread_);
474 RuntimeCallTimerScope runtime_timer(
475 runtime_call_stats_, info->is_eval()
476 ? RuntimeCallCounterId::kParseEval
477 : RuntimeCallCounterId::kParseProgram);
478 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT(
"v8.compile"),
"V8.ParseProgram");
479 base::ElapsedTimer timer;
480 if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
483 DeserializeScopeChain(isolate, info, info->maybe_outer_scope_info());
485 scanner_.Initialize();
486 FunctionLiteral* result = DoParseProgram(isolate, info);
487 MaybeResetCharacterStream(info, result);
489 HandleSourceURLComments(isolate, info->script());
491 if (V8_UNLIKELY(FLAG_log_function_events) && result !=
nullptr) {
492 double ms = timer.Elapsed().InMillisecondsF();
493 const char* event_name =
"parse-eval";
494 Script* script = *info->script();
497 if (!info->is_eval()) {
498 event_name =
"parse-script";
500 end = String::cast(script->source())->length();
503 FunctionEvent(event_name, script->id(), ms, start, end,
"", 0));
508 FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
513 DCHECK_EQ(parsing_on_main_thread_, isolate !=
nullptr);
515 DCHECK_NULL(target_stack_);
517 ParsingModeScope mode(
this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
518 ResetFunctionLiteralId();
519 DCHECK(info->function_literal_id() == FunctionLiteral::kIdTypeTopLevel ||
520 info->function_literal_id() == FunctionLiteral::kIdTypeInvalid);
522 FunctionLiteral* result =
nullptr;
524 Scope* outer = original_scope_;
525 DCHECK_NOT_NULL(outer);
526 if (info->is_eval()) {
527 outer = NewEvalScope(outer);
528 }
else if (parsing_module_) {
529 DCHECK_EQ(outer, info->script_scope());
530 outer = NewModuleScope(info->script_scope());
533 DeclarationScope* scope = outer->AsDeclarationScope();
534 scope->set_start_position(0);
536 FunctionState function_state(&function_state_, &scope_, scope);
537 ScopedPtrList<Statement> body(pointer_buffer());
538 int beg_pos = scanner()->location().beg_pos;
539 if (parsing_module_) {
540 DCHECK(info->is_module());
542 auto name = ast_value_factory()->empty_string();
543 bool is_rest =
false;
544 bool is_optional =
false;
545 auto var = scope->DeclareParameter(name, VariableMode::kVar, is_optional,
546 is_rest, ast_value_factory(), beg_pos);
547 var->AllocateTo(VariableLocation::PARAMETER, 0);
549 PrepareGeneratorVariables();
550 Expression* initial_yield =
551 BuildInitialYield(kNoSourcePosition, kGeneratorFunction);
553 factory()->NewExpressionStatement(initial_yield, kNoSourcePosition));
555 ParseModuleItemList(&body);
556 if (!module()->Validate(this->scope()->AsModuleScope(),
557 pending_error_handler(), zone())) {
558 scanner()->set_parser_error();
560 }
else if (info->is_wrapped_as_function()) {
561 ParseWrapped(isolate, info, &body, scope, zone());
565 this->scope()->SetLanguageMode(info->language_mode());
566 ParseStatementList(&body, Token::EOS);
571 scope->set_end_position(peek_position());
573 if (is_strict(language_mode())) {
574 CheckStrictOctalLiteral(beg_pos, end_position());
576 if (is_sloppy(language_mode())) {
581 InsertSloppyBlockFunctionVarBindings(scope);
583 CheckConflictingVarDeclarations(scope);
585 if (info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
586 if (body.length() != 1 || !body.at(0)->IsExpressionStatement() ||
588 ->AsExpressionStatement()
590 ->IsFunctionLiteral()) {
591 ReportMessage(MessageTemplate::kSingleFunctionLiteral);
595 RewriteDestructuringAssignments();
596 int parameter_count = parsing_module_ ? 1 : 0;
597 result = factory()->NewScriptOrEvalFunctionLiteral(
598 scope, body, function_state.expected_property_count(), parameter_count);
599 result->set_suspend_count(function_state.suspend_count());
602 info->set_max_function_literal_id(GetLastFunctionLiteralId());
605 DCHECK_NULL(target_stack_);
607 if (has_error())
return nullptr;
611 ZonePtrList<const AstRawString>* Parser::PrepareWrappedArguments(
612 Isolate* isolate, ParseInfo* info, Zone* zone) {
613 DCHECK(parsing_on_main_thread_);
614 DCHECK_NOT_NULL(isolate);
615 Handle<FixedArray> arguments(info->script()->wrapped_arguments(), isolate);
616 int arguments_length = arguments->length();
617 ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
618 new (zone) ZonePtrList<const AstRawString>(arguments_length, zone);
619 for (
int i = 0;
i < arguments_length;
i++) {
620 const AstRawString* argument_string = ast_value_factory()->GetString(
621 Handle<String>(String::cast(arguments->get(
i)), isolate));
622 arguments_for_wrapped_function->Add(argument_string, zone);
624 return arguments_for_wrapped_function;
627 void Parser::ParseWrapped(Isolate* isolate, ParseInfo* info,
628 ScopedPtrList<Statement>* body,
629 DeclarationScope* outer_scope, Zone* zone) {
630 DCHECK_EQ(parsing_on_main_thread_, isolate !=
nullptr);
631 DCHECK(info->is_wrapped_as_function());
632 ParsingModeScope parsing_mode(
this, PARSE_EAGERLY);
635 DCHECK(outer_scope->is_eval_scope());
636 FunctionState function_state(&function_state_, &scope_, outer_scope);
638 const AstRawString* function_name =
nullptr;
639 Scanner::Location location(0, 0);
641 ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
642 PrepareWrappedArguments(isolate, info, zone);
644 FunctionLiteral* function_literal = ParseFunctionLiteral(
645 function_name, location, kSkipFunctionNameCheck, kNormalFunction,
646 kNoSourcePosition, FunctionLiteral::kWrapped, LanguageMode::kSloppy,
647 arguments_for_wrapped_function);
649 Statement* return_statement = factory()->NewReturnStatement(
650 function_literal, kNoSourcePosition, kNoSourcePosition);
651 body->Add(return_statement);
654 FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
655 Handle<SharedFunctionInfo> shared_info) {
658 DCHECK(parsing_on_main_thread_);
659 RuntimeCallTimerScope runtime_timer(runtime_call_stats_,
660 RuntimeCallCounterId::kParseFunction);
661 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT(
"v8.compile"),
"V8.ParseFunction");
662 base::ElapsedTimer timer;
663 if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
665 DeserializeScopeChain(isolate, info, info->maybe_outer_scope_info());
666 DCHECK_EQ(factory()->zone(), info->zone());
669 Handle<String> name(shared_info->Name(), isolate);
670 info->set_function_name(ast_value_factory()->GetString(name));
671 scanner_.Initialize();
673 FunctionLiteral* result =
674 DoParseFunction(isolate, info, info->function_name());
675 MaybeResetCharacterStream(info, result);
676 if (result !=
nullptr) {
677 Handle<String> inferred_name(shared_info->inferred_name(), isolate);
678 result->set_inferred_name(inferred_name);
681 if (V8_UNLIKELY(FLAG_log_function_events) && result !=
nullptr) {
682 double ms = timer.Elapsed().InMillisecondsF();
684 ast_value_factory()->Internalize(isolate);
685 DeclarationScope* function_scope = result->scope();
686 std::unique_ptr<char[]> function_name = result->GetDebugName();
688 FunctionEvent(
"parse-function", info->script()->id(), ms,
689 function_scope->start_position(),
690 function_scope->end_position(), function_name.get(),
691 strlen(function_name.get())));
696 static FunctionLiteral::FunctionType ComputeFunctionType(ParseInfo* info) {
697 if (info->is_wrapped_as_function()) {
698 return FunctionLiteral::kWrapped;
699 }
else if (info->is_declaration()) {
700 return FunctionLiteral::kDeclaration;
701 }
else if (info->is_named_expression()) {
702 return FunctionLiteral::kNamedExpression;
703 }
else if (IsConciseMethod(info->function_kind()) ||
704 IsAccessorFunction(info->function_kind())) {
705 return FunctionLiteral::kAccessorOrMethod;
707 return FunctionLiteral::kAnonymousExpression;
710 FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
711 const AstRawString* raw_name) {
712 DCHECK_EQ(parsing_on_main_thread_, isolate !=
nullptr);
713 DCHECK_NOT_NULL(raw_name);
715 DCHECK_NULL(target_stack_);
717 DCHECK(ast_value_factory());
718 fni_.PushEnclosingName(raw_name);
720 ResetFunctionLiteralId();
721 DCHECK_LT(0, info->function_literal_id());
722 SkipFunctionLiterals(info->function_literal_id() - 1);
724 ParsingModeScope parsing_mode(
this, PARSE_EAGERLY);
727 FunctionLiteral* result =
nullptr;
731 Scope* outer = original_scope_;
732 DeclarationScope* outer_function = outer->GetClosureScope();
734 FunctionState function_state(&function_state_, &scope_, outer_function);
735 BlockState block_state(&scope_, outer);
736 DCHECK(is_sloppy(outer->language_mode()) ||
737 is_strict(info->language_mode()));
738 FunctionLiteral::FunctionType function_type = ComputeFunctionType(info);
739 FunctionKind kind = info->function_kind();
741 if (IsArrowFunction(kind)) {
742 if (IsAsyncFunction(kind)) {
743 DCHECK(!scanner()->HasLineTerminatorAfterNext());
744 if (!Check(Token::ASYNC)) {
745 CHECK(stack_overflow());
748 if (!(peek_any_identifier() || peek() == Token::LPAREN)) {
749 CHECK(stack_overflow());
755 DeclarationScope* scope = NewFunctionScope(kind);
759 SetLanguageMode(scope, info->language_mode());
761 scope->set_start_position(info->start_position());
762 ExpressionClassifier formals_classifier(
this);
763 ParserFormalParameters formals(scope);
766 function_state.destructuring_assignments_to_rewrite().size());
771 BlockState block_state(&scope_, scope);
772 if (Check(Token::LPAREN)) {
774 ParseFormalParameterList(&formals);
775 Expect(Token::RPAREN);
778 ParseFormalParameter(&formals);
779 DeclareFormalParameters(&formals);
783 if (GetLastFunctionLiteralId() != info->function_literal_id() - 1) {
784 if (has_error())
return nullptr;
788 AstFunctionLiteralIdReindexer reindexer(
790 (info->function_literal_id() - 1) - GetLastFunctionLiteralId());
791 for (
auto p : formals.params) {
792 if (p->pattern !=
nullptr) reindexer.Reindex(p->pattern);
793 if (p->initializer() !=
nullptr) {
794 reindexer.Reindex(p->initializer());
797 ResetFunctionLiteralId();
798 SkipFunctionLiterals(info->function_literal_id() - 1);
801 set_rewritable_length(0);
802 Expression* expression = ParseArrowFunctionLiteral(formals);
809 if (scanner()->location().end_pos == info->end_position()) {
812 DCHECK(expression->IsFunctionLiteral());
813 result = expression->AsFunctionLiteral();
815 }
else if (IsDefaultConstructor(kind)) {
816 DCHECK_EQ(scope(), outer);
817 result = DefaultConstructor(raw_name, IsDerivedConstructor(kind),
818 info->start_position(), info->end_position());
820 ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
821 info->is_wrapped_as_function()
822 ? PrepareWrappedArguments(isolate, info, zone())
824 result = ParseFunctionLiteral(
825 raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind,
826 kNoSourcePosition, function_type, info->language_mode(),
827 arguments_for_wrapped_function);
830 if (has_error())
return nullptr;
831 result->set_requires_instance_members_initializer(
832 info->requires_instance_members_initializer());
836 DCHECK_NULL(target_stack_);
837 DCHECK_IMPLIES(result,
838 info->function_literal_id() == result->function_literal_id());
842 Statement* Parser::ParseModuleItem() {
849 Token::Value next = peek();
851 if (next == Token::EXPORT) {
852 return ParseExportDeclaration();
855 if (next == Token::IMPORT) {
858 Token::Value peek_ahead = PeekAhead();
859 if ((!allow_harmony_dynamic_import() || peek_ahead != Token::LPAREN) &&
860 (!allow_harmony_import_meta() || peek_ahead != Token::PERIOD)) {
861 ParseImportDeclaration();
862 return factory()->EmptyStatement();
866 return ParseStatementListItem();
869 void Parser::ParseModuleItemList(ScopedPtrList<Statement>* body) {
878 DCHECK(scope()->is_module_scope());
879 while (peek() != Token::EOS) {
880 Statement* stat = ParseModuleItem();
881 if (stat ==
nullptr)
return;
882 if (stat->IsEmptyStatement())
continue;
887 const AstRawString* Parser::ParseModuleSpecifier() {
891 Expect(Token::STRING);
895 ZoneChunkList<Parser::ExportClauseData>* Parser::ParseExportClause(
896 Scanner::Location* reserved_loc) {
909 ZoneChunkList<ExportClauseData>* export_data =
910 new (zone()) ZoneChunkList<ExportClauseData>(zone());
912 Expect(Token::LBRACE);
914 Token::Value name_tok;
915 while ((name_tok = peek()) != Token::RBRACE) {
918 if (!reserved_loc->IsValid() &&
919 !Token::IsIdentifier(name_tok, LanguageMode::kStrict,
false,
921 *reserved_loc = scanner()->location();
923 const AstRawString* local_name = ParseIdentifierName();
924 const AstRawString* export_name =
nullptr;
925 Scanner::Location location = scanner()->location();
926 if (CheckContextualKeyword(ast_value_factory()->as_string())) {
927 export_name = ParseIdentifierName();
930 location.end_pos = scanner()->location().end_pos;
932 if (export_name ==
nullptr) {
933 export_name = local_name;
935 export_data->push_back({export_name, local_name, location});
936 if (peek() == Token::RBRACE)
break;
937 if (V8_UNLIKELY(!Check(Token::COMMA))) {
938 ReportUnexpectedToken(Next());
943 Expect(Token::RBRACE);
947 ZonePtrList<const Parser::NamedImport>* Parser::ParseNamedImports(
int pos) {
961 Expect(Token::LBRACE);
963 auto result =
new (zone()) ZonePtrList<const NamedImport>(1, zone());
964 while (peek() != Token::RBRACE) {
965 const AstRawString* import_name = ParseIdentifierName();
966 const AstRawString* local_name = import_name;
967 Scanner::Location location = scanner()->location();
971 if (CheckContextualKeyword(ast_value_factory()->as_string())) {
972 local_name = ParseIdentifierName();
974 if (!Token::IsIdentifier(scanner()->current_token(), LanguageMode::kStrict,
975 false, parsing_module_)) {
976 ReportMessage(MessageTemplate::kUnexpectedReserved);
978 }
else if (IsEvalOrArguments(local_name)) {
979 ReportMessage(MessageTemplate::kStrictEvalArguments);
983 DeclareVariable(local_name, VariableMode::kConst, kNeedsInitialization,
986 NamedImport*
import =
987 new (zone()) NamedImport(import_name, local_name, location);
988 result->Add(
import, zone());
990 if (peek() == Token::RBRACE)
break;
991 Expect(Token::COMMA);
994 Expect(Token::RBRACE);
998 void Parser::ParseImportDeclaration() {
1013 int pos = peek_position();
1014 Expect(Token::IMPORT);
1016 Token::Value tok = peek();
1019 if (tok == Token::STRING) {
1020 Scanner::Location specifier_loc = scanner()->peek_location();
1021 const AstRawString* module_specifier = ParseModuleSpecifier();
1023 module()->AddEmptyImport(module_specifier, specifier_loc);
1028 const AstRawString* import_default_binding =
nullptr;
1029 Scanner::Location import_default_binding_loc;
1030 if (tok != Token::MUL && tok != Token::LBRACE) {
1031 import_default_binding = ParseIdentifier(kDontAllowRestrictedIdentifiers);
1032 import_default_binding_loc = scanner()->location();
1033 DeclareVariable(import_default_binding, VariableMode::kConst,
1034 kNeedsInitialization, pos);
1038 const AstRawString* module_namespace_binding =
nullptr;
1039 Scanner::Location module_namespace_binding_loc;
1040 const ZonePtrList<const NamedImport>* named_imports =
nullptr;
1041 if (import_default_binding ==
nullptr || Check(Token::COMMA)) {
1044 Consume(Token::MUL);
1045 ExpectContextualKeyword(ast_value_factory()->as_string());
1046 module_namespace_binding =
1047 ParseIdentifier(kDontAllowRestrictedIdentifiers);
1048 module_namespace_binding_loc = scanner()->location();
1049 DeclareVariable(module_namespace_binding, VariableMode::kConst,
1050 kCreatedInitialized, pos);
1055 named_imports = ParseNamedImports(pos);
1059 ReportUnexpectedToken(scanner()->current_token());
1064 ExpectContextualKeyword(ast_value_factory()->from_string());
1065 Scanner::Location specifier_loc = scanner()->peek_location();
1066 const AstRawString* module_specifier = ParseModuleSpecifier();
1077 if (module_namespace_binding !=
nullptr) {
1078 module()->AddStarImport(module_namespace_binding, module_specifier,
1079 module_namespace_binding_loc, specifier_loc,
1083 if (import_default_binding !=
nullptr) {
1084 module()->AddImport(ast_value_factory()->default_string(),
1085 import_default_binding, module_specifier,
1086 import_default_binding_loc, specifier_loc, zone());
1089 if (named_imports !=
nullptr) {
1090 if (named_imports->length() == 0) {
1091 module()->AddEmptyImport(module_specifier, specifier_loc);
1093 for (
int i = 0;
i < named_imports->length(); ++
i) {
1094 const NamedImport*
import = named_imports->at(
i);
1095 module()->AddImport(import->import_name, import->local_name,
1096 module_specifier, import->location, specifier_loc,
1103 Statement* Parser::ParseExportDefault() {
1109 Expect(Token::DEFAULT);
1110 Scanner::Location default_loc = scanner()->location();
1112 ZonePtrList<const AstRawString> local_names(1, zone());
1113 Statement* result =
nullptr;
1115 case Token::FUNCTION:
1116 result = ParseHoistableDeclaration(&local_names,
true);
1120 Consume(Token::CLASS);
1121 result = ParseClassDeclaration(&local_names,
true);
1125 if (PeekAhead() == Token::FUNCTION &&
1126 !scanner()->HasLineTerminatorAfterNext()) {
1127 Consume(Token::ASYNC);
1128 result = ParseAsyncFunctionDeclaration(&local_names,
true);
1134 int pos = position();
1135 ExpressionClassifier classifier(
this);
1136 AcceptINScope scope(
this,
true);
1137 Expression* value = ParseAssignmentExpression();
1138 ValidateExpression();
1139 SetFunctionName(value, ast_value_factory()->default_string());
1141 const AstRawString* local_name =
1142 ast_value_factory()->star_default_star_string();
1143 local_names.Add(local_name, zone());
1148 DeclareVariable(local_name, VariableMode::kConst, pos);
1149 decl->proxy()->var()->set_initializer_position(position());
1151 Assignment* assignment = factory()->NewAssignment(
1152 Token::INIT, decl->proxy(), value, kNoSourcePosition);
1153 result = IgnoreCompletion(
1154 factory()->NewExpressionStatement(assignment, kNoSourcePosition));
1161 if (result !=
nullptr) {
1162 DCHECK_EQ(local_names.length(), 1);
1163 module()->AddExport(local_names.first(),
1164 ast_value_factory()->default_string(), default_loc,
1171 const AstRawString* Parser::NextInternalNamespaceExportName() {
1172 const char* prefix =
".ns-export";
1173 std::string s(prefix);
1174 s.append(std::to_string(number_of_named_namespace_exports_++));
1175 return ast_value_factory()->GetOneByteString(s.c_str());
1178 void Parser::ParseExportStar() {
1179 int pos = position();
1180 Consume(Token::MUL);
1182 if (!FLAG_harmony_namespace_exports ||
1183 !PeekContextualKeyword(ast_value_factory()->as_string())) {
1185 Scanner::Location loc = scanner()->location();
1186 ExpectContextualKeyword(ast_value_factory()->from_string());
1187 Scanner::Location specifier_loc = scanner()->peek_location();
1188 const AstRawString* module_specifier = ParseModuleSpecifier();
1190 module()->AddStarExport(module_specifier, loc, specifier_loc, zone());
1193 if (!FLAG_harmony_namespace_exports)
return;
1202 ExpectContextualKeyword(ast_value_factory()->as_string());
1203 const AstRawString* export_name = ParseIdentifierName();
1204 Scanner::Location export_name_loc = scanner()->location();
1205 const AstRawString* local_name = NextInternalNamespaceExportName();
1206 Scanner::Location local_name_loc = Scanner::Location::invalid();
1207 DeclareVariable(local_name, VariableMode::kConst, kCreatedInitialized, pos);
1209 ExpectContextualKeyword(ast_value_factory()->from_string());
1210 Scanner::Location specifier_loc = scanner()->peek_location();
1211 const AstRawString* module_specifier = ParseModuleSpecifier();
1214 module()->AddStarImport(local_name, module_specifier, local_name_loc,
1215 specifier_loc, zone());
1216 module()->AddExport(local_name, export_name, export_name_loc, zone());
1219 Statement* Parser::ParseExportDeclaration() {
1228 Expect(Token::EXPORT);
1229 Statement* result =
nullptr;
1230 ZonePtrList<const AstRawString> names(1, zone());
1231 Scanner::Location loc = scanner()->peek_location();
1233 case Token::DEFAULT:
1234 return ParseExportDefault();
1238 return factory()->EmptyStatement();
1240 case Token::LBRACE: {
1252 Scanner::Location reserved_loc = Scanner::Location::invalid();
1253 ZoneChunkList<ExportClauseData>* export_data =
1254 ParseExportClause(&reserved_loc);
1255 const AstRawString* module_specifier =
nullptr;
1256 Scanner::Location specifier_loc;
1257 if (CheckContextualKeyword(ast_value_factory()->from_string())) {
1258 specifier_loc = scanner()->peek_location();
1259 module_specifier = ParseModuleSpecifier();
1260 }
else if (reserved_loc.IsValid()) {
1262 ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved);
1266 if (module_specifier ==
nullptr) {
1267 for (
const ExportClauseData& data : *export_data) {
1268 module()->AddExport(data.local_name, data.export_name, data.location,
1271 }
else if (export_data->is_empty()) {
1272 module()->AddEmptyImport(module_specifier, specifier_loc);
1274 for (
const ExportClauseData& data : *export_data) {
1275 module()->AddExport(data.local_name, data.export_name,
1276 module_specifier, data.location, specifier_loc,
1280 return factory()->EmptyStatement();
1283 case Token::FUNCTION:
1284 result = ParseHoistableDeclaration(&names,
false);
1288 Consume(Token::CLASS);
1289 result = ParseClassDeclaration(&names,
false);
1295 result = ParseVariableStatement(kStatementListItem, &names);
1299 Consume(Token::ASYNC);
1300 if (peek() == Token::FUNCTION &&
1301 !scanner()->HasLineTerminatorBeforeNext()) {
1302 result = ParseAsyncFunctionDeclaration(&names,
false);
1308 ReportUnexpectedToken(scanner()->current_token());
1311 loc.end_pos = scanner()->location().end_pos;
1313 ModuleDescriptor* descriptor = module();
1314 for (
int i = 0;
i < names.length(); ++
i) {
1315 descriptor->AddExport(names[
i], names[
i], loc, zone());
1321 VariableProxy* Parser::NewUnresolved(
const AstRawString* name,
int begin_pos,
1322 VariableKind kind) {
1323 return scope()->NewUnresolved(factory(), name, begin_pos, kind);
1326 VariableProxy* Parser::NewUnresolved(
const AstRawString* name) {
1327 return scope()->NewUnresolved(factory(), name, scanner()->location().beg_pos);
1330 Declaration* Parser::DeclareVariable(
const AstRawString* name,
1331 VariableMode mode,
int pos) {
1332 return DeclareVariable(name, mode, Variable::DefaultInitializationFlag(mode),
1336 Declaration* Parser::DeclareVariable(
const AstRawString* name,
1337 VariableMode mode, InitializationFlag init,
1339 DCHECK_NOT_NULL(name);
1340 VariableProxy* proxy = factory()->NewVariableProxy(
1341 name, NORMAL_VARIABLE, scanner()->location().beg_pos);
1342 Declaration* declaration;
1343 if (mode == VariableMode::kVar && !scope()->is_declaration_scope()) {
1344 DCHECK(scope()->is_block_scope() || scope()->is_with_scope());
1345 declaration = factory()->NewNestedVariableDeclaration(proxy, scope(), pos);
1347 declaration = factory()->NewVariableDeclaration(proxy, pos);
1349 Declare(declaration, DeclarationDescriptor::NORMAL, mode, init,
nullptr,
1350 scanner()->location().end_pos);
1354 Variable* Parser::Declare(Declaration* declaration,
1355 DeclarationDescriptor::Kind declaration_kind,
1356 VariableMode mode, InitializationFlag init,
1357 Scope* scope,
int var_end_pos) {
1358 bool local_ok =
true;
1359 if (scope ==
nullptr) {
1360 scope = this->scope();
1362 bool sloppy_mode_block_scope_function_redefinition =
false;
1363 Variable* variable = scope->DeclareVariable(
1364 declaration, mode, init, &sloppy_mode_block_scope_function_redefinition,
1370 Scanner::Location loc(declaration->proxy()->position(),
1371 var_end_pos != kNoSourcePosition
1373 : declaration->proxy()->position() + 1);
1374 if (declaration_kind == DeclarationDescriptor::PARAMETER) {
1375 ReportMessageAt(loc, MessageTemplate::kParamDupe);
1377 ReportMessageAt(loc, MessageTemplate::kVarRedeclaration,
1378 declaration->proxy()->raw_name());
1380 }
else if (sloppy_mode_block_scope_function_redefinition) {
1381 ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition];
1386 Block* Parser::BuildInitializationBlock(
1387 DeclarationParsingResult* parsing_result,
1388 ZonePtrList<const AstRawString>* names) {
1389 Block* result = factory()->NewBlock(1,
true);
1390 for (
const auto& declaration : parsing_result->declarations) {
1391 DeclareAndInitializeVariables(result, &(parsing_result->descriptor),
1392 &declaration, names);
1397 Statement* Parser::DeclareFunction(
const AstRawString* variable_name,
1398 FunctionLiteral*
function, VariableMode mode,
1399 int pos,
bool is_sloppy_block_function,
1400 ZonePtrList<const AstRawString>* names) {
1401 VariableProxy* proxy =
1402 factory()->NewVariableProxy(variable_name, NORMAL_VARIABLE, pos);
1403 Declaration* declaration = factory()->NewFunctionDeclaration(
1404 proxy,
function, is_sloppy_block_function, pos);
1405 Declare(declaration, DeclarationDescriptor::NORMAL, mode,
1406 kCreatedInitialized);
1407 if (names) names->Add(variable_name, zone());
1408 if (is_sloppy_block_function) {
1409 SloppyBlockFunctionStatement* statement =
1410 factory()->NewSloppyBlockFunctionStatement();
1411 GetDeclarationScope()->DeclareSloppyBlockFunction(variable_name, scope(),
1415 return factory()->EmptyStatement();
1418 Statement* Parser::DeclareClass(
const AstRawString* variable_name,
1420 ZonePtrList<const AstRawString>* names,
1421 int class_token_pos,
int end_pos) {
1423 DeclareVariable(variable_name, VariableMode::kLet, class_token_pos);
1424 decl->proxy()->var()->set_initializer_position(end_pos);
1425 if (names) names->Add(variable_name, zone());
1427 Assignment* assignment = factory()->NewAssignment(Token::INIT, decl->proxy(),
1428 value, class_token_pos);
1429 return IgnoreCompletion(
1430 factory()->NewExpressionStatement(assignment, kNoSourcePosition));
1433 Statement* Parser::DeclareNative(
const AstRawString* name,
int pos) {
1438 GetClosureScope()->ForceEagerCompilation();
1443 Declaration* decl = DeclareVariable(name, VariableMode::kVar, pos);
1444 NativeFunctionLiteral* lit =
1445 factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition);
1446 return factory()->NewExpressionStatement(
1447 factory()->NewAssignment(Token::INIT, decl->proxy(), lit,
1452 void Parser::DeclareLabel(ZonePtrList<const AstRawString>** labels,
1453 ZonePtrList<const AstRawString>** own_labels,
1454 VariableProxy* var) {
1455 DCHECK(IsIdentifier(var));
1456 const AstRawString* label = var->raw_name();
1463 if (ContainsLabel(*labels, label) || TargetStackContainsLabel(label)) {
1464 ReportMessage(MessageTemplate::kLabelRedeclaration, label);
1469 if (*labels ==
nullptr) {
1470 DCHECK_NULL(*own_labels);
1471 *labels =
new (zone()) ZonePtrList<const AstRawString>(1, zone());
1472 *own_labels =
new (zone()) ZonePtrList<const AstRawString>(1, zone());
1474 if (*own_labels ==
nullptr) {
1475 *own_labels =
new (zone()) ZonePtrList<const AstRawString>(1, zone());
1478 (*labels)->Add(label, zone());
1479 (*own_labels)->Add(label, zone());
1484 scope()->DeleteUnresolved(var);
1487 bool Parser::ContainsLabel(ZonePtrList<const AstRawString>* labels,
1488 const AstRawString* label) {
1489 DCHECK_NOT_NULL(label);
1490 if (labels !=
nullptr) {
1491 for (
int i = labels->length();
i-- > 0;) {
1492 if (labels->at(
i) == label)
return true;
1498 Block* Parser::IgnoreCompletion(Statement* statement) {
1499 Block* block = factory()->NewBlock(1,
true);
1500 block->statements()->Add(statement, zone());
1504 Expression* Parser::RewriteReturn(Expression* return_value,
int pos) {
1505 if (IsDerivedConstructor(function_state_->kind())) {
1516 Variable* temp = NewTemporary(ast_value_factory()->empty_string());
1517 Assignment* assign = factory()->NewAssignment(
1518 Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos);
1521 Expression* is_undefined = factory()->NewCompareOperation(
1522 Token::EQ_STRICT, assign,
1523 factory()->NewUndefinedLiteral(kNoSourcePosition), pos);
1527 factory()->NewConditional(is_undefined, ThisExpression(pos),
1528 factory()->NewVariableProxy(temp), pos);
1530 return return_value;
1533 Statement* Parser::RewriteSwitchStatement(SwitchStatement* switch_statement,
1544 DCHECK_NOT_NULL(scope);
1545 DCHECK(scope->is_block_scope());
1546 DCHECK_GE(switch_statement->position(), scope->start_position());
1547 DCHECK_LT(switch_statement->position(), scope->end_position());
1549 Block* switch_block = factory()->NewBlock(2,
false);
1551 Expression* tag = switch_statement->tag();
1552 Variable* tag_variable =
1553 NewTemporary(ast_value_factory()->dot_switch_tag_string());
1554 Assignment* tag_assign = factory()->NewAssignment(
1555 Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag,
1559 Statement* tag_statement = IgnoreCompletion(
1560 factory()->NewExpressionStatement(tag_assign, kNoSourcePosition));
1561 switch_block->statements()->Add(tag_statement, zone());
1563 switch_statement->set_tag(factory()->NewVariableProxy(tag_variable));
1564 Block* cases_block = factory()->NewBlock(1,
false);
1565 cases_block->statements()->Add(switch_statement, zone());
1566 cases_block->set_scope(scope);
1567 switch_block->statements()->Add(cases_block, zone());
1568 return switch_block;
1571 void Parser::RewriteCatchPattern(CatchInfo* catch_info) {
1572 if (catch_info->name ==
nullptr) {
1573 DCHECK_NOT_NULL(catch_info->pattern);
1574 catch_info->name = ast_value_factory()->dot_catch_string();
1576 Variable* catch_variable =
1577 catch_info->scope->DeclareLocal(catch_info->name, VariableMode::kVar);
1578 if (catch_info->pattern !=
nullptr) {
1579 DeclarationDescriptor descriptor;
1580 descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
1581 descriptor.scope = scope();
1582 descriptor.mode = VariableMode::kLet;
1583 descriptor.declaration_pos = catch_info->pattern->position();
1584 descriptor.initialization_pos = catch_info->pattern->position();
1587 const int initializer_position = position();
1589 DeclarationParsingResult::Declaration decl(
1590 catch_info->pattern, initializer_position,
1591 factory()->NewVariableProxy(catch_variable));
1593 catch_info->init_block = factory()->NewBlock(8,
true);
1594 DeclareAndInitializeVariables(catch_info->init_block, &descriptor, &decl,
1595 &catch_info->bound_names);
1597 catch_info->bound_names.Add(catch_info->name, zone());
1601 void Parser::ValidateCatchBlock(
const CatchInfo& catch_info) {
1603 Scope* inner_block_scope = catch_info.inner_block->scope();
1604 if (inner_block_scope !=
nullptr) {
1605 Declaration* decl = inner_block_scope->CheckLexDeclarationsConflictingWith(
1606 catch_info.bound_names);
1607 if (decl !=
nullptr) {
1608 const AstRawString* name = decl->proxy()->raw_name();
1609 int position = decl->proxy()->position();
1610 Scanner::Location location =
1611 position == kNoSourcePosition
1612 ? Scanner::Location::invalid()
1613 : Scanner::Location(position, position + 1);
1614 ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
1619 Statement* Parser::RewriteTryStatement(Block* try_block, Block* catch_block,
1620 const SourceRange& catch_range,
1621 Block* finally_block,
1622 const SourceRange& finally_range,
1623 const CatchInfo& catch_info,
int pos) {
1629 if (catch_block !=
nullptr && finally_block !=
nullptr) {
1631 TryCatchStatement* statement;
1632 statement = factory()->NewTryCatchStatement(try_block, catch_info.scope,
1633 catch_block, kNoSourcePosition);
1634 RecordTryCatchStatementSourceRange(statement, catch_range);
1636 try_block = factory()->NewBlock(1,
false);
1637 try_block->statements()->Add(statement, zone());
1638 catch_block =
nullptr;
1641 if (catch_block !=
nullptr) {
1642 DCHECK_NULL(finally_block);
1643 TryCatchStatement* stmt = factory()->NewTryCatchStatement(
1644 try_block, catch_info.scope, catch_block, pos);
1645 RecordTryCatchStatementSourceRange(stmt, catch_range);
1648 DCHECK_NOT_NULL(finally_block);
1649 TryFinallyStatement* stmt =
1650 factory()->NewTryFinallyStatement(try_block, finally_block, pos);
1651 RecordTryFinallyStatementSourceRange(stmt, finally_range);
1656 void Parser::ParseAndRewriteGeneratorFunctionBody(
1657 int pos, FunctionKind kind, ScopedPtrList<Statement>* body) {
1659 Expression* initial_yield = BuildInitialYield(pos, kind);
1661 factory()->NewExpressionStatement(initial_yield, kNoSourcePosition));
1662 ParseStatementList(body, Token::RBRACE);
1665 void Parser::ParseAndRewriteAsyncGeneratorFunctionBody(
1666 int pos, FunctionKind kind, ScopedPtrList<Statement>* body) {
1687 DCHECK(IsAsyncGeneratorFunction(kind));
1691 ScopedPtrList<Statement> statements(pointer_buffer());
1692 Expression* initial_yield = BuildInitialYield(pos, kind);
1694 factory()->NewExpressionStatement(initial_yield, kNoSourcePosition));
1695 ParseStatementList(&statements, Token::RBRACE);
1701 Statement* final_return = BuildReturnStatement(
1702 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
1703 statements.Add(final_return);
1705 try_block = factory()->NewBlock(
false, statements);
1709 Scope* catch_scope = NewHiddenCatchScope();
1713 ScopedPtrList<Expression> reject_args(pointer_buffer());
1714 reject_args.Add(factory()->NewVariableProxy(
1715 function_state_->scope()->generator_object_var()));
1716 reject_args.Add(factory()->NewVariableProxy(catch_scope->catch_variable()));
1718 Expression* reject_call = factory()->NewCallRuntime(
1719 Runtime::kInlineAsyncGeneratorReject, reject_args, kNoSourcePosition);
1720 catch_block = IgnoreCompletion(
1721 factory()->NewReturnStatement(reject_call, kNoSourcePosition));
1725 ScopedPtrList<Statement> statements(pointer_buffer());
1726 TryStatement* try_catch = factory()->NewTryCatchStatementForAsyncAwait(
1727 try_block, catch_scope, catch_block, kNoSourcePosition);
1728 statements.Add(try_catch);
1729 try_block = factory()->NewBlock(
false, statements);
1732 Expression* close_call;
1734 ScopedPtrList<Expression> close_args(pointer_buffer());
1735 VariableProxy* call_proxy = factory()->NewVariableProxy(
1736 function_state_->scope()->generator_object_var());
1737 close_args.Add(call_proxy);
1738 close_call = factory()->NewCallRuntime(Runtime::kInlineGeneratorClose,
1739 close_args, kNoSourcePosition);
1742 Block* finally_block;
1744 ScopedPtrList<Statement> statements(pointer_buffer());
1746 factory()->NewExpressionStatement(close_call, kNoSourcePosition));
1747 finally_block = factory()->NewBlock(
false, statements);
1750 body->Add(factory()->NewTryFinallyStatement(try_block, finally_block,
1751 kNoSourcePosition));
1754 void Parser::DeclareFunctionNameVar(
const AstRawString* function_name,
1755 FunctionLiteral::FunctionType function_type,
1756 DeclarationScope* function_scope) {
1757 if (function_type == FunctionLiteral::kNamedExpression &&
1758 function_scope->LookupLocal(function_name) ==
nullptr) {
1759 DCHECK_EQ(function_scope, scope());
1760 function_scope->DeclareFunctionVar(function_name);
1771 Expression* Parser::BuildIteratorNextResult(VariableProxy* iterator,
1772 VariableProxy* next,
1773 Variable* result, IteratorType type,
1775 Expression* next_property = factory()->NewResolvedProperty(iterator, next);
1776 ScopedPtrList<Expression> next_arguments(pointer_buffer());
1777 Expression* next_call =
1778 factory()->NewCall(next_property, next_arguments, kNoSourcePosition);
1779 if (type == IteratorType::kAsync) {
1780 function_state_->AddSuspend();
1781 next_call = factory()->NewAwait(next_call, pos);
1783 Expression* result_proxy = factory()->NewVariableProxy(result);
1785 factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos);
1788 ScopedPtrList<Expression> is_spec_object_args(pointer_buffer());
1789 is_spec_object_args.Add(left);
1790 Expression* is_spec_object_call = factory()->NewCallRuntime(
1791 Runtime::kInlineIsJSReceiver, is_spec_object_args, pos);
1794 Expression* result_proxy_again = factory()->NewVariableProxy(result);
1795 ScopedPtrList<Expression> throw_arguments(pointer_buffer());
1796 throw_arguments.Add(result_proxy_again);
1797 Expression* throw_call = factory()->NewCallRuntime(
1798 Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos);
1800 return factory()->NewBinaryOperation(
1802 factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos),
1806 Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt,
1808 Expression* subject,
1810 ForOfStatement* for_of = stmt->AsForOfStatement();
1811 if (for_of !=
nullptr) {
1812 const bool finalize =
true;
1813 return InitializeForOfStatement(for_of, each, subject, body, finalize,
1814 IteratorType::kNormal, each->position());
1816 if (each->IsPattern()) {
1817 Variable* temp = NewTemporary(ast_value_factory()->empty_string());
1818 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
1819 Expression* assign_each =
1820 RewriteDestructuringAssignment(factory()->NewAssignment(
1821 Token::ASSIGN, each, temp_proxy, kNoSourcePosition));
1822 auto block = factory()->NewBlock(2,
false);
1823 block->statements()->Add(
1824 factory()->NewExpressionStatement(assign_each, kNoSourcePosition),
1826 block->statements()->Add(body, zone());
1828 each = factory()->NewVariableProxy(temp);
1830 MarkExpressionAsAssigned(each);
1831 stmt->AsForInStatement()->Initialize(each, subject, body);
1852 Block* Parser::RewriteForVarInLegacy(
const ForInfo& for_info) {
1853 const DeclarationParsingResult::Declaration& decl =
1854 for_info.parsing_result.declarations[0];
1855 if (!IsLexicalVariableMode(for_info.parsing_result.descriptor.mode) &&
1856 decl.pattern->IsVariableProxy() && decl.initializer !=
nullptr) {
1857 ++use_counts_[v8::Isolate::kForInInitializer];
1858 const AstRawString* name = decl.pattern->AsVariableProxy()->raw_name();
1859 VariableProxy* single_var = NewUnresolved(name);
1860 Block* init_block = factory()->NewBlock(2,
true);
1861 init_block->statements()->Add(
1862 factory()->NewExpressionStatement(
1863 factory()->NewAssignment(Token::ASSIGN, single_var,
1864 decl.initializer, kNoSourcePosition),
1886 void Parser::DesugarBindingInForEachStatement(ForInfo* for_info,
1888 Expression** each_variable) {
1889 DCHECK_EQ(1, for_info->parsing_result.declarations.size());
1890 DeclarationParsingResult::Declaration& decl =
1891 for_info->parsing_result.declarations[0];
1892 Variable* temp = NewTemporary(ast_value_factory()->dot_for_string());
1893 auto each_initialization_block = factory()->NewBlock(1,
true);
1895 auto descriptor = for_info->parsing_result.descriptor;
1896 descriptor.declaration_pos = kNoSourcePosition;
1897 descriptor.initialization_pos = kNoSourcePosition;
1898 descriptor.scope = scope();
1899 decl.initializer = factory()->NewVariableProxy(temp);
1901 bool is_for_var_of =
1902 for_info->mode == ForEachStatement::ITERATE &&
1903 for_info->parsing_result.descriptor.mode == VariableMode::kVar;
1904 bool collect_names =
1905 IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) ||
1908 DeclareAndInitializeVariables(
1909 each_initialization_block, &descriptor, &decl,
1910 collect_names ? &for_info->bound_names :
nullptr);
1919 if (is_for_var_of) {
1920 Scope* catch_scope = scope();
1921 while (catch_scope !=
nullptr && !catch_scope->is_declaration_scope()) {
1922 if (catch_scope->is_catch_scope()) {
1923 auto name = catch_scope->catch_variable()->raw_name();
1925 if (name != ast_value_factory()->dot_catch_string() &&
1926 for_info->bound_names.Contains(name)) {
1927 ReportMessageAt(for_info->parsing_result.bindings_loc,
1928 MessageTemplate::kVarRedeclaration, name);
1931 catch_scope = catch_scope->outer_scope();
1936 *body_block = factory()->NewBlock(3,
false);
1937 (*body_block)->statements()->Add(each_initialization_block, zone());
1938 *each_variable = factory()->NewVariableProxy(temp, for_info->position);
1942 Block* Parser::CreateForEachStatementTDZ(Block* init_block,
1943 const ForInfo& for_info) {
1944 if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) {
1945 DCHECK_NULL(init_block);
1947 init_block = factory()->NewBlock(1,
false);
1949 for (
int i = 0;
i < for_info.bound_names.length(); ++
i) {
1953 Declaration* tdz_decl = DeclareVariable(
1954 for_info.bound_names[
i], VariableMode::kLet, kNoSourcePosition);
1955 tdz_decl->proxy()->var()->set_initializer_position(position());
1961 Statement* Parser::InitializeForOfStatement(
1962 ForOfStatement* for_of, Expression* each, Expression* iterable,
1963 Statement* body,
bool finalize, IteratorType type,
int next_result_pos) {
1969 const int nopos = kNoSourcePosition;
1970 auto avfactory = ast_value_factory();
1972 Variable* iterator = NewTemporary(avfactory->dot_iterator_string());
1973 Variable* next = NewTemporary(avfactory->empty_string());
1974 Variable* result = NewTemporary(avfactory->dot_result_string());
1975 Variable* completion = NewTemporary(avfactory->empty_string());
1978 Expression* assign_iterator;
1980 assign_iterator = factory()->NewAssignment(
1981 Token::ASSIGN, factory()->NewVariableProxy(iterator),
1982 factory()->NewGetIterator(iterable, type, iterable->position()),
1983 iterable->position());
1986 Expression* assign_next;
1988 assign_next = factory()->NewAssignment(
1989 Token::ASSIGN, factory()->NewVariableProxy(next),
1990 factory()->NewProperty(factory()->NewVariableProxy(iterator),
1991 factory()->NewStringLiteral(
1992 avfactory->next_string(), kNoSourcePosition),
2004 Expression* next_result;
2006 VariableProxy* iterator_proxy = factory()->NewVariableProxy(iterator);
2007 VariableProxy* next_proxy = factory()->NewVariableProxy(next);
2008 next_result = BuildIteratorNextResult(iterator_proxy, next_proxy, result,
2009 type, next_result_pos);
2013 Expression* result_done;
2015 Expression* done_literal = factory()->NewStringLiteral(
2016 ast_value_factory()->done_string(), kNoSourcePosition);
2017 Expression* result_proxy = factory()->NewVariableProxy(result);
2019 factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition);
2023 Expression* result_value;
2025 Expression* value_literal =
2026 factory()->NewStringLiteral(avfactory->value_string(), nopos);
2027 Expression* result_proxy = factory()->NewVariableProxy(result);
2028 result_value = factory()->NewProperty(result_proxy, value_literal, nopos);
2034 Variable* tmp = NewTemporary(avfactory->empty_string());
2035 Expression* save_result = factory()->NewAssignment(
2036 Token::ASSIGN, factory()->NewVariableProxy(tmp), result_value, nopos);
2038 Expression* set_completion_abrupt = factory()->NewAssignment(
2039 Token::ASSIGN, factory()->NewVariableProxy(completion),
2040 factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
2042 result_value = factory()->NewBinaryOperation(Token::COMMA, save_result,
2043 set_completion_abrupt, nopos);
2044 result_value = factory()->NewBinaryOperation(
2045 Token::COMMA, result_value, factory()->NewVariableProxy(tmp), nopos);
2049 Expression* assign_each;
2052 factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos);
2053 if (each->IsPattern()) {
2054 assign_each = RewriteDestructuringAssignment(assign_each->AsAssignment());
2059 Statement* set_completion_normal;
2061 Expression* proxy = factory()->NewVariableProxy(completion);
2062 Expression* assignment = factory()->NewAssignment(
2063 Token::ASSIGN, proxy,
2064 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
2066 set_completion_normal =
2067 IgnoreCompletion(factory()->NewExpressionStatement(assignment, nopos));
2073 Block* block = factory()->NewBlock(2,
false);
2074 block->statements()->Add(body, zone());
2075 block->statements()->Add(set_completion_normal, zone());
2079 for_of->Initialize(body, iterator, assign_iterator, assign_next, next_result,
2080 result_done, assign_each);
2081 return finalize ? FinalizeForOfStatement(for_of, completion, type, nopos)
2085 Statement* Parser::DesugarLexicalBindingsInForStatement(
2086 ForStatement* loop, Statement* init, Expression* cond, Statement* next,
2087 Statement* body, Scope* inner_scope,
const ForInfo& for_info) {
2125 DCHECK_GT(for_info.bound_names.length(), 0);
2126 ZonePtrList<Variable> temps(for_info.bound_names.length(), zone());
2128 Block* outer_block =
2129 factory()->NewBlock(for_info.bound_names.length() + 4,
false);
2132 outer_block->statements()->Add(init, zone());
2134 const AstRawString* temp_name = ast_value_factory()->dot_for_string();
2138 for (
int i = 0;
i < for_info.bound_names.length();
i++) {
2139 VariableProxy* proxy = NewUnresolved(for_info.bound_names[
i]);
2140 Variable* temp = NewTemporary(temp_name);
2141 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
2142 Assignment* assignment = factory()->NewAssignment(Token::ASSIGN, temp_proxy,
2143 proxy, kNoSourcePosition);
2144 Statement* assignment_statement =
2145 factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2146 outer_block->statements()->Add(assignment_statement, zone());
2147 temps.Add(temp, zone());
2150 Variable* first =
nullptr;
2153 first = NewTemporary(temp_name);
2154 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2155 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2156 Assignment* assignment = factory()->NewAssignment(
2157 Token::ASSIGN, first_proxy, const1, kNoSourcePosition);
2158 Statement* assignment_statement =
2159 factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2160 outer_block->statements()->Add(assignment_statement, zone());
2164 outer_block->statements()->Add(
2165 factory()->NewExpressionStatement(
2166 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
2174 ForStatement* outer_loop =
2175 factory()->NewForStatement(
nullptr,
nullptr, kNoSourcePosition);
2176 outer_block->statements()->Add(outer_loop, zone());
2177 outer_block->set_scope(scope());
2179 Block* inner_block = factory()->NewBlock(3,
false);
2181 BlockState block_state(&scope_, inner_scope);
2183 Block* ignore_completion_block =
2184 factory()->NewBlock(for_info.bound_names.length() + 3,
true);
2185 ZonePtrList<Variable> inner_vars(for_info.bound_names.length(), zone());
2188 for (
int i = 0;
i < for_info.bound_names.length();
i++) {
2189 Declaration* decl = DeclareVariable(
2190 for_info.bound_names[
i], for_info.parsing_result.descriptor.mode,
2192 inner_vars.Add(decl->proxy()->var(), zone());
2193 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(
i));
2194 Assignment* assignment = factory()->NewAssignment(
2195 Token::INIT, decl->proxy(), temp_proxy, kNoSourcePosition);
2196 Statement* assignment_statement =
2197 factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2198 int declaration_pos = for_info.parsing_result.descriptor.declaration_pos;
2199 DCHECK_NE(declaration_pos, kNoSourcePosition);
2200 decl->proxy()->var()->set_initializer_position(declaration_pos);
2201 ignore_completion_block->statements()->Add(assignment_statement, zone());
2207 Expression* compare =
nullptr;
2210 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2211 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2212 compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1,
2215 Statement* clear_first =
nullptr;
2218 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2219 Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
2220 Assignment* assignment = factory()->NewAssignment(
2221 Token::ASSIGN, first_proxy, const0, kNoSourcePosition);
2223 factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2225 Statement* clear_first_or_next = factory()->NewIfStatement(
2226 compare, clear_first, next, kNoSourcePosition);
2227 ignore_completion_block->statements()->Add(clear_first_or_next, zone());
2230 Variable* flag = NewTemporary(temp_name);
2233 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2234 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2235 Assignment* assignment = factory()->NewAssignment(
2236 Token::ASSIGN, flag_proxy, const1, kNoSourcePosition);
2237 Statement* assignment_statement =
2238 factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2239 ignore_completion_block->statements()->Add(assignment_statement, zone());
2245 factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
2246 Statement* noop = factory()->EmptyStatement();
2247 ignore_completion_block->statements()->Add(
2248 factory()->NewIfStatement(cond, noop, stop, cond->position()),
2252 inner_block->statements()->Add(ignore_completion_block, zone());
2254 Expression* flag_cond =
nullptr;
2256 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2257 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2258 flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
2263 Statement* compound_next_statement =
nullptr;
2265 Expression* compound_next =
nullptr;
2268 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2269 Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
2270 compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy,
2271 const0, kNoSourcePosition);
2275 int inner_var_proxy_pos = scanner()->location().beg_pos;
2276 for (
int i = 0;
i < for_info.bound_names.length();
i++) {
2277 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(
i));
2278 VariableProxy* proxy =
2279 factory()->NewVariableProxy(inner_vars.at(
i), inner_var_proxy_pos);
2280 Assignment* assignment = factory()->NewAssignment(
2281 Token::ASSIGN, temp_proxy, proxy, kNoSourcePosition);
2282 compound_next = factory()->NewBinaryOperation(
2283 Token::COMMA, compound_next, assignment, kNoSourcePosition);
2286 compound_next_statement =
2287 factory()->NewExpressionStatement(compound_next, kNoSourcePosition);
2294 loop->Initialize(
nullptr, flag_cond, compound_next_statement, body);
2295 inner_block->statements()->Add(loop, zone());
2299 Expression* compare =
nullptr;
2302 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2303 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2304 compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
2308 factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
2309 Statement* empty = factory()->EmptyStatement();
2310 Statement* if_flag_break =
2311 factory()->NewIfStatement(compare, stop, empty, kNoSourcePosition);
2312 inner_block->statements()->Add(IgnoreCompletion(if_flag_break), zone());
2315 inner_block->set_scope(inner_scope);
2318 outer_loop->Initialize(
nullptr,
nullptr,
nullptr, inner_block);
2323 void Parser::AddArrowFunctionFormalParameters(
2324 ParserFormalParameters* parameters, Expression* expr,
int end_pos) {
2340 if (expr->IsNaryOperation()) {
2341 NaryOperation* nary = expr->AsNaryOperation();
2344 DCHECK_EQ(nary->op(), Token::COMMA);
2348 Expression* next = nary->first();
2349 for (
size_t i = 0;
i < nary->subsequent_length(); ++
i) {
2350 AddArrowFunctionFormalParameters(parameters, next,
2351 nary->subsequent_op_position(
i));
2352 next = nary->subsequent(
i);
2354 AddArrowFunctionFormalParameters(parameters, next, end_pos);
2360 if (expr->IsBinaryOperation()) {
2361 BinaryOperation* binop = expr->AsBinaryOperation();
2364 DCHECK_EQ(binop->op(), Token::COMMA);
2365 Expression* left = binop->left();
2366 Expression* right = binop->right();
2367 int comma_pos = binop->position();
2368 AddArrowFunctionFormalParameters(parameters, left, comma_pos);
2374 DCHECK(!parameters->has_rest);
2376 bool is_rest = expr->IsSpread();
2378 expr = expr->AsSpread()->expression();
2379 parameters->has_rest =
true;
2381 DCHECK_IMPLIES(parameters->is_simple, !is_rest);
2382 DCHECK_IMPLIES(parameters->is_simple, expr->IsVariableProxy());
2384 Expression* initializer =
nullptr;
2385 if (expr->IsAssignment()) {
2386 if (expr->IsRewritableExpression()) {
2389 expr->AsRewritableExpression()->set_rewritten();
2391 Assignment* assignment = expr->AsAssignment();
2392 DCHECK(!assignment->IsCompoundAssignment());
2393 initializer = assignment->value();
2394 expr = assignment->target();
2397 AddFormalParameter(parameters, expr, initializer,
2401 void Parser::DeclareArrowFunctionFormalParameters(
2402 ParserFormalParameters* parameters, Expression* expr,
2403 const Scanner::Location& params_loc) {
2404 if (expr->IsEmptyParentheses() || has_error())
return;
2406 AddArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos);
2408 if (parameters->arity > Code::kMaxArguments) {
2409 ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
2413 DeclareFormalParameters(parameters);
2414 DCHECK_IMPLIES(parameters->is_simple,
2415 parameters->scope->has_simple_parameters());
2418 void Parser::PrepareGeneratorVariables() {
2422 function_state_->scope()->DeclareGeneratorObjectVar(
2423 ast_value_factory()->dot_generator_object_string());
2426 FunctionLiteral* Parser::ParseFunctionLiteral(
2427 const AstRawString* function_name, Scanner::Location function_name_location,
2428 FunctionNameValidity function_name_validity, FunctionKind kind,
2429 int function_token_pos, FunctionLiteral::FunctionType function_type,
2430 LanguageMode language_mode,
2431 ZonePtrList<const AstRawString>* arguments_for_wrapped_function) {
2441 bool is_wrapped = function_type == FunctionLiteral::kWrapped;
2442 DCHECK_EQ(is_wrapped, arguments_for_wrapped_function !=
nullptr);
2444 int pos = function_token_pos == kNoSourcePosition ? peek_position()
2445 : function_token_pos;
2446 DCHECK_NE(kNoSourcePosition, pos);
2451 bool should_infer_name = function_name ==
nullptr;
2455 if (should_infer_name) {
2456 function_name = ast_value_factory()->empty_string();
2459 FunctionLiteral::EagerCompileHint eager_compile_hint =
2460 function_state_->next_function_is_likely_called() || is_wrapped
2461 ? FunctionLiteral::kShouldEagerCompile
2462 : default_eager_compile_hint();
2496 DCHECK_IMPLIES(parse_lazily(), FLAG_lazy);
2497 DCHECK_IMPLIES(parse_lazily(), has_error() || allow_lazy_);
2498 DCHECK_IMPLIES(parse_lazily(), extension_ ==
nullptr);
2500 const bool is_lazy =
2501 eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
2502 const bool is_top_level = AllowsLazyParsingWithoutUnresolvedVariables();
2503 const bool is_eager_top_level_function = !is_lazy && is_top_level;
2504 const bool is_lazy_top_level_function = is_lazy && is_top_level;
2505 const bool is_lazy_inner_function = is_lazy && !is_top_level;
2507 RuntimeCallTimerScope runtime_timer(
2508 runtime_call_stats_,
2509 parsing_on_main_thread_
2510 ? RuntimeCallCounterId::kParseFunctionLiteral
2511 : RuntimeCallCounterId::kParseBackgroundFunctionLiteral);
2512 base::ElapsedTimer timer;
2513 if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
2532 const bool should_preparse_inner = parse_lazily() && is_lazy_inner_function;
2537 bool should_post_parallel_task =
2538 parse_lazily() && is_eager_top_level_function &&
2539 FLAG_parallel_compile_tasks && info()->parallel_tasks() &&
2540 scanner()->stream()->can_be_cloned_for_parallel_access();
2543 bool should_preparse = (parse_lazily() && is_lazy_top_level_function) ||
2544 should_preparse_inner || should_post_parallel_task;
2546 ScopedPtrList<Statement> body(pointer_buffer());
2547 int expected_property_count = -1;
2548 int suspend_count = -1;
2549 int num_parameters = -1;
2550 int function_length = -1;
2551 bool has_duplicate_parameters =
false;
2552 int function_literal_id = GetNextFunctionLiteralId();
2553 ProducedPreParsedScopeData* produced_preparsed_scope_data =
nullptr;
2556 Zone* parse_zone = should_preparse ? &preparser_zone_ : zone();
2557 DeclarationScope* scope = NewFunctionScope(kind, parse_zone);
2558 SetLanguageMode(scope, language_mode);
2560 scope->SetScopeName(function_name);
2563 if (!is_wrapped && V8_UNLIKELY(!Check(Token::LPAREN))) {
2564 ReportUnexpectedToken(Next());
2567 scope->set_start_position(position());
2574 bool did_preparse_successfully =
2576 SkipFunction(function_name, kind, function_type, scope, &num_parameters,
2577 &produced_preparsed_scope_data, is_lazy_top_level_function,
2578 &eager_compile_hint);
2579 if (!did_preparse_successfully) {
2580 should_post_parallel_task =
false;
2581 ParseFunction(&body, function_name, pos, kind, function_type, scope,
2582 &num_parameters, &function_length, &has_duplicate_parameters,
2583 &expected_property_count, &suspend_count,
2584 arguments_for_wrapped_function);
2587 if (V8_UNLIKELY(FLAG_log_function_events)) {
2588 double ms = timer.Elapsed().InMillisecondsF();
2589 const char* event_name =
2591 ? (is_top_level ?
"preparse-no-resolution" :
"preparse-resolution")
2593 logger_->FunctionEvent(
2594 event_name, script_id(), ms, scope->start_position(),
2595 scope->end_position(),
2596 reinterpret_cast<const char*
>(function_name->raw_data()),
2597 function_name->byte_length());
2599 if (V8_UNLIKELY(FLAG_runtime_stats) && did_preparse_successfully) {
2600 const RuntimeCallCounterId counters[2] = {
2601 RuntimeCallCounterId::kPreParseBackgroundWithVariableResolution,
2602 RuntimeCallCounterId::kPreParseWithVariableResolution};
2603 if (runtime_call_stats_) {
2604 runtime_call_stats_->CorrectCurrentCounterId(
2605 counters[parsing_on_main_thread_]);
2611 language_mode = scope->language_mode();
2612 CheckFunctionName(language_mode, function_name, function_name_validity,
2613 function_name_location);
2615 if (is_strict(language_mode)) {
2616 CheckStrictOctalLiteral(scope->start_position(), scope->end_position());
2618 CheckConflictingVarDeclarations(scope);
2620 FunctionLiteral::ParameterFlag duplicate_parameters =
2621 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
2622 : FunctionLiteral::kNoDuplicateParameters;
2625 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
2626 function_name, scope, body, expected_property_count, num_parameters,
2627 function_length, duplicate_parameters, function_type, eager_compile_hint,
2628 pos,
true, function_literal_id, produced_preparsed_scope_data);
2629 function_literal->set_function_token_position(function_token_pos);
2630 function_literal->set_suspend_count(suspend_count);
2632 if (should_post_parallel_task) {
2634 info()->parallel_tasks()->Enqueue(info(), function_name, function_literal);
2637 if (should_infer_name) {
2638 fni_.AddFunction(function_literal);
2640 return function_literal;
2643 bool Parser::SkipFunction(
2644 const AstRawString* function_name, FunctionKind kind,
2645 FunctionLiteral::FunctionType function_type,
2646 DeclarationScope* function_scope,
int* num_parameters,
2647 ProducedPreParsedScopeData** produced_preparsed_scope_data,
bool may_abort,
2648 FunctionLiteral::EagerCompileHint* hint) {
2649 FunctionState function_state(&function_state_, &scope_, function_scope);
2650 function_scope->set_zone(&preparser_zone_);
2652 DCHECK_NE(kNoSourcePosition, function_scope->start_position());
2653 DCHECK_EQ(kNoSourcePosition, parameters_end_pos_);
2655 DCHECK_IMPLIES(IsArrowFunction(kind),
2656 scanner()->current_token() == Token::ARROW);
2659 if (consumed_preparsed_scope_data_) {
2661 LanguageMode language_mode;
2662 int num_inner_functions;
2663 bool uses_super_property;
2664 if (stack_overflow()) {
2667 *produced_preparsed_scope_data =
2668 consumed_preparsed_scope_data_->GetDataForSkippableFunction(
2669 main_zone(), function_scope->start_position(), &end_position,
2670 num_parameters, &num_inner_functions, &uses_super_property,
2673 function_scope->outer_scope()->SetMustUsePreParsedScopeData();
2674 function_scope->set_is_skipped_function(
true);
2675 function_scope->set_end_position(end_position);
2676 scanner()->SeekForward(end_position - 1);
2677 Expect(Token::RBRACE);
2678 SetLanguageMode(function_scope, language_mode);
2679 if (uses_super_property) {
2680 function_scope->RecordSuperPropertyUsage();
2682 SkipFunctionLiterals(num_inner_functions);
2683 function_scope->ResetAfterPreparsing(ast_value_factory_,
false);
2687 Scanner::BookmarkScope bookmark(scanner());
2692 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT(
"v8.compile"),
"V8.PreParse");
2694 PreParser::PreParseResult result = reusable_preparser()->PreParseFunction(
2695 function_name, kind, function_type, function_scope, may_abort,
2696 use_counts_, produced_preparsed_scope_data, this->script_id());
2699 if (result == PreParser::kPreParseAbort) {
2701 function_scope->ResetAfterPreparsing(ast_value_factory(),
true);
2702 *hint = FunctionLiteral::kShouldEagerCompile;
2706 if (result == PreParser::kPreParseStackOverflow) {
2708 set_stack_overflow();
2709 }
else if (pending_error_handler()->has_error_unidentifiable_by_preparser()) {
2712 allow_lazy_ =
false;
2713 mode_ = PARSE_EAGERLY;
2714 DCHECK(!pending_error_handler()->stack_overflow());
2719 function_scope->ResetAfterPreparsing(ast_value_factory(),
true);
2720 pending_error_handler()->clear_unidentifiable_error();
2722 }
else if (pending_error_handler()->has_pending_error()) {
2723 DCHECK(!pending_error_handler()->stack_overflow());
2724 DCHECK(has_error());
2726 DCHECK(!pending_error_handler()->stack_overflow());
2727 set_allow_eval_cache(reusable_preparser()->allow_eval_cache());
2729 PreParserLogger* logger = reusable_preparser()->logger();
2730 function_scope->set_end_position(logger->end());
2731 Expect(Token::RBRACE);
2732 total_preparse_skipped_ +=
2733 function_scope->end_position() - function_scope->start_position();
2734 *num_parameters = logger->num_parameters();
2735 SkipFunctionLiterals(logger->num_inner_functions());
2736 function_scope->AnalyzePartially(factory());
2742 Statement* Parser::BuildAssertIsCoercible(Variable* var,
2743 ObjectLiteral* pattern) {
2746 auto source_position = pattern->position();
2747 const AstRawString*
property = ast_value_factory()->empty_string();
2748 MessageTemplate msg = MessageTemplate::kNonCoercible;
2749 for (ObjectLiteralProperty* literal_property : *pattern->properties()) {
2750 Expression* key = literal_property->key();
2751 if (key->IsPropertyName()) {
2752 property = key->AsLiteral()->AsRawPropertyName();
2753 msg = MessageTemplate::kNonCoercibleWithProperty;
2754 source_position = key->position();
2759 Expression* condition = factory()->NewBinaryOperation(
2761 factory()->NewCompareOperation(
2762 Token::EQ_STRICT, factory()->NewVariableProxy(var),
2763 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
2764 factory()->NewCompareOperation(
2765 Token::EQ_STRICT, factory()->NewVariableProxy(var),
2766 factory()->NewNullLiteral(kNoSourcePosition), kNoSourcePosition),
2768 Expression* throw_type_error =
2769 NewThrowTypeError(msg, property, source_position);
2770 IfStatement* if_statement = factory()->NewIfStatement(
2772 factory()->NewExpressionStatement(throw_type_error, kNoSourcePosition),
2773 factory()->EmptyStatement(), kNoSourcePosition);
2774 return if_statement;
2790 if (to_rewrite->is_rewritten())
return;
2791 parser_->RewriteDestructuringAssignment(to_rewrite);
2792 AstTraversalVisitor::VisitRewritableExpression(to_rewrite);
2802 void Parser::RewriteParameterInitializer(
Expression* expr) {
2803 if (has_error())
return;
2808 Block* Parser::BuildParameterInitializationBlock(
2809 const ParserFormalParameters& parameters) {
2810 DCHECK(!parameters.is_simple);
2811 DCHECK(scope()->is_function_scope());
2812 DCHECK_EQ(scope(), parameters.scope);
2813 Block* init_block = factory()->NewBlock(parameters.num_parameters(),
true);
2815 for (
auto parameter : parameters.params) {
2816 DeclarationDescriptor descriptor;
2817 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER;
2818 descriptor.scope = scope();
2819 descriptor.mode = VariableMode::kLet;
2820 descriptor.declaration_pos = parameter->pattern->position();
2826 descriptor.initialization_pos = parameter->pattern->position();
2827 Expression* initial_value =
2828 factory()->NewVariableProxy(parameters.scope->parameter(index));
2829 if (parameter->initializer() !=
nullptr) {
2833 RewriteParameterInitializer(parameter->initializer());
2835 auto condition = factory()->NewCompareOperation(
2837 factory()->NewVariableProxy(parameters.scope->parameter(index)),
2838 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
2840 factory()->NewConditional(condition, parameter->initializer(),
2841 initial_value, kNoSourcePosition);
2842 descriptor.initialization_pos = parameter->initializer()->position();
2845 Scope* param_scope = scope();
2846 Block* param_block = init_block;
2847 if (!parameter->is_simple() &&
2848 scope()->AsDeclarationScope()->calls_sloppy_eval()) {
2849 param_scope = NewVarblockScope();
2850 param_scope->set_start_position(descriptor.initialization_pos);
2851 param_scope->set_end_position(parameter->initializer_end_position);
2852 param_scope->RecordEvalCall();
2853 param_block = factory()->NewBlock(8,
true);
2854 param_block->set_scope(param_scope);
2857 descriptor.scope = param_scope;
2859 ReparentExpressionScope(stack_limit(), initial_value, param_scope);
2862 BlockState block_state(&scope_, param_scope);
2863 DeclarationParsingResult::Declaration decl(
2864 parameter->pattern, parameter->initializer_end_position, initial_value);
2865 DeclareAndInitializeVariables(param_block, &descriptor, &decl,
nullptr);
2867 if (param_block != init_block) {
2868 param_scope = param_scope->FinalizeBlockScope();
2869 if (param_scope !=
nullptr) {
2870 CheckConflictingVarDeclarations(param_scope);
2872 init_block->statements()->Add(param_block, zone());
2879 Scope* Parser::NewHiddenCatchScope() {
2880 Scope* catch_scope = NewScopeWithParent(scope(), CATCH_SCOPE);
2881 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(),
2882 VariableMode::kVar);
2883 catch_scope->set_is_hidden();
2887 Block* Parser::BuildRejectPromiseOnException(Block* inner_block) {
2893 Block* result = factory()->NewBlock(1,
true);
2898 Scope* catch_scope = NewHiddenCatchScope();
2900 Expression* reject_promise;
2902 ScopedPtrList<Expression> args(pointer_buffer());
2903 args.Add(factory()->NewVariableProxy(
2904 function_state_->scope()->generator_object_var()));
2905 args.Add(factory()->NewVariableProxy(catch_scope->catch_variable()));
2906 args.Add(factory()->NewBooleanLiteral(function_state_->CanSuspend(),
2907 kNoSourcePosition));
2908 reject_promise = factory()->NewCallRuntime(
2909 Runtime::kInlineAsyncFunctionReject, args, kNoSourcePosition);
2911 Block* catch_block = IgnoreCompletion(
2912 factory()->NewReturnStatement(reject_promise, kNoSourcePosition));
2914 TryStatement* try_catch_statement =
2915 factory()->NewTryCatchStatementForAsyncAwait(
2916 inner_block, catch_scope, catch_block, kNoSourcePosition);
2917 result->statements()->Add(try_catch_statement, zone());
2921 Expression* Parser::BuildInitialYield(
int pos, FunctionKind kind) {
2922 Expression* yield_result = factory()->NewVariableProxy(
2923 function_state_->scope()->generator_object_var());
2927 function_state_->AddSuspend();
2928 return factory()->NewYield(yield_result, scope()->start_position(),
2929 Suspend::kOnExceptionThrow);
2932 void Parser::ParseFunction(
2933 ScopedPtrList<Statement>* body,
const AstRawString* function_name,
int pos,
2934 FunctionKind kind, FunctionLiteral::FunctionType function_type,
2935 DeclarationScope* function_scope,
int* num_parameters,
int* function_length,
2936 bool* has_duplicate_parameters,
int* expected_property_count,
2938 ZonePtrList<const AstRawString>* arguments_for_wrapped_function) {
2939 ParsingModeScope mode(
this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
2941 FunctionState function_state(&function_state_, &scope_, function_scope);
2943 bool is_wrapped = function_type == FunctionLiteral::kWrapped;
2945 ExpressionClassifier formals_classifier(
this);
2947 int expected_parameters_end_pos = parameters_end_pos_;
2948 if (expected_parameters_end_pos != kNoSourcePosition) {
2950 parameters_end_pos_ = kNoSourcePosition;
2953 DCHECK_EQ(function_name, ast_value_factory()->empty_string());
2956 ParserFormalParameters formals(function_scope);
2962 int arguments_length = arguments_for_wrapped_function->length();
2963 for (
int i = 0;
i < arguments_length;
i++) {
2964 const bool is_rest =
false;
2965 Expression* argument = ExpressionFromIdentifier(
2966 arguments_for_wrapped_function->at(
i), kNoSourcePosition);
2967 AddFormalParameter(&formals, argument, NullExpression(),
2968 kNoSourcePosition, is_rest);
2970 DCHECK_EQ(arguments_length, formals.num_parameters());
2971 DeclareFormalParameters(&formals);
2974 DCHECK_NULL(arguments_for_wrapped_function);
2975 ParseFormalParameterList(&formals);
2976 if (expected_parameters_end_pos != kNoSourcePosition) {
2979 int position = peek_position();
2980 if (position < expected_parameters_end_pos) {
2981 ReportMessageAt(Scanner::Location(position, position + 1),
2982 MessageTemplate::kArgStringTerminatesParametersEarly);
2984 }
else if (position > expected_parameters_end_pos) {
2985 ReportMessageAt(Scanner::Location(expected_parameters_end_pos - 2,
2986 expected_parameters_end_pos),
2987 MessageTemplate::kUnexpectedEndOfArgString);
2991 Expect(Token::RPAREN);
2992 int formals_end_position = scanner()->location().end_pos;
2994 CheckArityRestrictions(formals.arity, kind, formals.has_rest,
2995 function_scope->start_position(),
2996 formals_end_position);
2997 Expect(Token::LBRACE);
2999 *num_parameters = formals.num_parameters();
3000 *function_length = formals.function_length;
3002 AcceptINScope scope(
this,
true);
3003 ParseFunctionBody(body, function_name, pos, formals, kind, function_type,
3004 FunctionBodyType::kBlock);
3006 RewriteDestructuringAssignments();
3008 *has_duplicate_parameters = formals.has_duplicate();
3010 *expected_property_count = function_state.expected_property_count();
3011 *suspend_count = function_state.suspend_count();
3014 void Parser::DeclareClassVariable(
const AstRawString* name,
3015 ClassInfo* class_info,
int class_token_pos) {
3017 scope()->SetScopeName(name);
3020 if (name !=
nullptr) {
3021 VariableProxy* proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE);
3022 Declaration* declaration =
3023 factory()->NewVariableDeclaration(proxy, class_token_pos);
3024 class_info->variable = Declare(
3025 declaration, DeclarationDescriptor::NORMAL, VariableMode::kConst,
3026 Variable::DefaultInitializationFlag(VariableMode::kConst));
3033 Variable* Parser::CreateSyntheticContextVariable(
const AstRawString* name) {
3034 VariableProxy* proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE);
3035 Declaration* declaration =
3036 factory()->NewVariableDeclaration(proxy, kNoSourcePosition);
3038 Declare(declaration, DeclarationDescriptor::NORMAL, VariableMode::kConst,
3039 Variable::DefaultInitializationFlag(VariableMode::kConst));
3040 var->ForceContextAllocation();
3048 void Parser::DeclareClassProperty(
const AstRawString* class_name,
3049 ClassLiteralProperty* property,
3050 const AstRawString* property_name,
3051 ClassLiteralProperty::Kind kind,
3052 bool is_static,
bool is_constructor,
3053 bool is_computed_name,
bool is_private,
3054 ClassInfo* class_info) {
3055 if (is_constructor) {
3056 DCHECK(!class_info->constructor);
3057 class_info->constructor =
property->value()->AsFunctionLiteral();
3058 DCHECK_NOT_NULL(class_info->constructor);
3059 class_info->constructor->set_raw_name(
3060 class_name !=
nullptr ? ast_value_factory()->NewConsString(class_name)
3065 if (kind != ClassLiteralProperty::FIELD) {
3066 class_info->properties->Add(property, zone());
3070 DCHECK(allow_harmony_public_fields() || allow_harmony_private_fields());
3073 DCHECK(allow_harmony_static_fields());
3074 DCHECK_EQ(kind, ClassLiteralProperty::FIELD);
3075 DCHECK(!is_private);
3076 class_info->static_fields->Add(property, zone());
3078 class_info->instance_fields->Add(property, zone());
3081 if (is_computed_name) {
3082 DCHECK_EQ(kind, ClassLiteralProperty::FIELD);
3083 DCHECK(!is_private);
3086 Variable* computed_name_var =
3087 CreateSyntheticContextVariable(ClassFieldVariableName(
3088 ast_value_factory(), class_info->computed_field_count));
3089 property->set_computed_name_var(computed_name_var);
3090 class_info->properties->Add(property, zone());
3093 if (kind == ClassLiteralProperty::FIELD && is_private) {
3094 Variable* private_name_var = CreateSyntheticContextVariable(property_name);
3095 property->set_private_name_var(private_name_var);
3096 class_info->properties->Add(property, zone());
3100 FunctionLiteral* Parser::CreateInitializerFunction(
3101 const char* name, DeclarationScope* scope,
3102 ZonePtrList<ClassLiteral::Property>* fields) {
3103 DCHECK_EQ(scope->function_kind(),
3104 FunctionKind::kClassMembersInitializerFunction);
3106 ScopedPtrList<Statement> statements(pointer_buffer());
3107 InitializeClassMembersStatement* static_fields =
3108 factory()->NewInitializeClassMembersStatement(fields, kNoSourcePosition);
3109 statements.Add(static_fields);
3110 return factory()->NewFunctionLiteral(
3111 ast_value_factory()->GetOneByteString(name), scope, statements, 0, 0, 0,
3112 FunctionLiteral::kNoDuplicateParameters,
3113 FunctionLiteral::kAnonymousExpression,
3114 FunctionLiteral::kShouldEagerCompile, scope->start_position(),
false,
3115 GetNextFunctionLiteralId());
3126 Expression* Parser::RewriteClassLiteral(Scope* block_scope,
3127 const AstRawString* name,
3128 ClassInfo* class_info,
int pos,
3130 DCHECK_NOT_NULL(block_scope);
3131 DCHECK_EQ(block_scope->scope_type(), BLOCK_SCOPE);
3132 DCHECK_EQ(block_scope->language_mode(), LanguageMode::kStrict);
3134 bool has_extends = class_info->extends !=
nullptr;
3135 bool has_default_constructor = class_info->constructor ==
nullptr;
3136 if (has_default_constructor) {
3137 class_info->constructor =
3138 DefaultConstructor(name, has_extends, pos, end_pos);
3141 if (name !=
nullptr) {
3142 DCHECK_NOT_NULL(class_info->variable);
3143 class_info->variable->set_initializer_position(end_pos);
3146 FunctionLiteral* static_fields_initializer =
nullptr;
3147 if (class_info->has_static_class_fields) {
3148 static_fields_initializer = CreateInitializerFunction(
3149 "<static_fields_initializer>", class_info->static_fields_scope,
3150 class_info->static_fields);
3153 FunctionLiteral* instance_members_initializer_function =
nullptr;
3154 if (class_info->has_instance_members) {
3155 instance_members_initializer_function = CreateInitializerFunction(
3156 "<instance_members_initializer>", class_info->instance_members_scope,
3157 class_info->instance_fields);
3158 class_info->constructor->set_requires_instance_members_initializer(
true);
3161 ClassLiteral* class_literal = factory()->NewClassLiteral(
3162 block_scope, class_info->variable, class_info->extends,
3163 class_info->constructor, class_info->properties,
3164 static_fields_initializer, instance_members_initializer_function, pos,
3165 end_pos, class_info->has_name_static_property,
3166 class_info->has_static_computed_names, class_info->is_anonymous);
3168 AddFunctionForNameInference(class_info->constructor);
3169 return class_literal;
3172 void Parser::CheckConflictingVarDeclarations(Scope* scope) {
3173 if (has_error())
return;
3174 Declaration* decl = scope->CheckConflictingVarDeclarations();
3175 if (decl !=
nullptr) {
3177 const AstRawString* name = decl->proxy()->raw_name();
3178 int position = decl->proxy()->position();
3179 Scanner::Location location =
3180 position == kNoSourcePosition
3181 ? Scanner::Location::invalid()
3182 : Scanner::Location(position, position + 1);
3183 ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
3187 bool Parser::IsPropertyWithPrivateFieldKey(Expression* expression) {
3188 if (!expression->IsProperty())
return false;
3189 Property*
property = expression->AsProperty();
3191 if (!property->key()->IsVariableProxy())
return false;
3192 VariableProxy* key =
property->key()->AsVariableProxy();
3194 return key->is_private_name();
3197 void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) {
3200 Scope* inner_scope = inner_block->scope();
3201 DCHECK(inner_scope->is_declaration_scope());
3202 Scope* function_scope = inner_scope->outer_scope();
3203 DCHECK(function_scope->is_function_scope());
3204 BlockState block_state(&scope_, inner_scope);
3205 for (Declaration* decl : *inner_scope->declarations()) {
3206 if (decl->proxy()->var()->mode() != VariableMode::kVar ||
3207 !decl->IsVariableDeclaration()) {
3210 const AstRawString* name = decl->proxy()->raw_name();
3211 Variable* parameter = function_scope->LookupLocal(name);
3212 if (parameter ==
nullptr)
continue;
3213 VariableProxy* to = NewUnresolved(name);
3214 VariableProxy* from = factory()->NewVariableProxy(parameter);
3215 Expression* assignment =
3216 factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition);
3217 Statement* statement =
3218 factory()->NewExpressionStatement(assignment, kNoSourcePosition);
3219 inner_block->statements()->InsertAt(0, statement, zone());
3223 void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope) {
3228 if (scope->is_eval_scope() && scope->outer_scope() == original_scope_) {
3231 scope->HoistSloppyBlockFunctions(factory());
3237 bool Parser::TargetStackContainsLabel(
const AstRawString* label) {
3238 for (ParserTarget* t = target_stack_; t !=
nullptr; t = t->previous()) {
3239 if (ContainsLabel(t->statement()->labels(), label))
return true;
3244 BreakableStatement* Parser::LookupBreakTarget(
const AstRawString* label) {
3245 bool anonymous = label ==
nullptr;
3246 for (ParserTarget* t = target_stack_; t !=
nullptr; t = t->previous()) {
3247 BreakableStatement* stat = t->statement();
3248 if ((anonymous && stat->is_target_for_anonymous()) ||
3249 (!anonymous && ContainsLabel(stat->labels(), label))) {
3256 IterationStatement* Parser::LookupContinueTarget(
const AstRawString* label) {
3257 bool anonymous = label ==
nullptr;
3258 for (ParserTarget* t = target_stack_; t !=
nullptr; t = t->previous()) {
3259 IterationStatement* stat = t->statement()->AsIterationStatement();
3260 if (stat ==
nullptr)
continue;
3262 DCHECK(stat->is_target_for_anonymous());
3263 if (anonymous || ContainsLabel(stat->own_labels(), label)) {
3266 if (ContainsLabel(stat->labels(), label))
break;
3271 void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) {
3272 Handle<String> source_url = scanner_.SourceUrl(isolate);
3273 if (!source_url.is_null()) {
3274 script->set_source_url(*source_url);
3276 Handle<String> source_mapping_url = scanner_.SourceMappingUrl(isolate);
3277 if (!source_mapping_url.is_null()) {
3278 script->set_source_mapping_url(*source_mapping_url);
3282 void Parser::UpdateStatistics(Isolate* isolate, Handle<Script> script) {
3284 for (
int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
3286 if (use_counts_[feature] > 0) {
3287 isolate->CountUsage(v8::Isolate::UseCounterFeature(feature));
3290 if (scanner_.FoundHtmlComment()) {
3291 isolate->CountUsage(v8::Isolate::kHtmlComment);
3292 if (script->line_offset() == 0 && script->column_offset() == 0) {
3293 isolate->CountUsage(v8::Isolate::kHtmlCommentInExternalScript);
3296 isolate->counters()->total_preparse_skipped()->Increment(
3297 total_preparse_skipped_);
3300 void Parser::ParseOnBackground(ParseInfo* info) {
3301 RuntimeCallTimerScope runtimeTimer(
3302 runtime_call_stats_, RuntimeCallCounterId::kParseBackgroundProgram);
3303 parsing_on_main_thread_ =
false;
3304 set_script_id(info->script_id());
3306 DCHECK_NULL(info->literal());
3307 FunctionLiteral* result =
nullptr;
3309 scanner_.Initialize();
3310 DCHECK(info->maybe_outer_scope_info().is_null());
3312 DCHECK(original_scope_);
3320 if (info->is_toplevel()) {
3321 result = DoParseProgram(
nullptr, info);
3324 DoParseFunction(
nullptr, info, info->function_name());
3326 MaybeResetCharacterStream(info, result);
3328 info->set_literal(result);
3334 Parser::TemplateLiteralState Parser::OpenTemplateLiteral(
int pos) {
3335 return new (zone()) TemplateLiteral(zone(), pos);
3338 void Parser::AddTemplateSpan(TemplateLiteralState* state,
bool should_cook,
3340 int end = scanner()->location().end_pos - (tail ? 1 : 2);
3341 const AstRawString* raw = scanner()->CurrentRawSymbol(ast_value_factory());
3343 const AstRawString* cooked = scanner()->CurrentSymbol(ast_value_factory());
3344 (*state)->AddTemplateSpan(cooked, raw, end, zone());
3346 (*state)->AddTemplateSpan(
nullptr, raw, end, zone());
3351 void Parser::AddTemplateExpression(TemplateLiteralState* state,
3352 Expression* expression) {
3353 (*state)->AddExpression(expression, zone());
3357 Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state,
int start,
3359 TemplateLiteral* lit = *state;
3360 int pos = lit->position();
3361 const ZonePtrList<const AstRawString>* cooked_strings = lit->cooked();
3362 const ZonePtrList<const AstRawString>* raw_strings = lit->raw();
3363 const ZonePtrList<Expression>* expressions = lit->expressions();
3364 DCHECK_EQ(cooked_strings->length(), raw_strings->length());
3365 DCHECK_EQ(cooked_strings->length(), expressions->length() + 1);
3368 if (cooked_strings->length() == 1) {
3369 return factory()->NewStringLiteral(cooked_strings->first(), pos);
3371 return factory()->NewTemplateLiteral(cooked_strings, expressions, pos);
3374 Expression* template_object =
3375 factory()->NewGetTemplateObject(cooked_strings, raw_strings, pos);
3378 ScopedPtrList<Expression> call_args(pointer_buffer());
3379 call_args.Add(template_object);
3380 call_args.AddAll(*expressions);
3381 return factory()->NewTaggedTemplate(tag, call_args, pos);
3387 bool OnlyLastArgIsSpread(
const ScopedPtrList<Expression>& args) {
3388 for (
int i = 0;
i < args.length() - 1;
i++) {
3389 if (args.at(
i)->IsSpread()) {
3393 return args.at(args.length() - 1)->IsSpread();
3398 ArrayLiteral* Parser::ArrayLiteralFromListWithSpread(
3399 const ScopedPtrList<Expression>& list) {
3402 DCHECK_LT(1, list.length());
3405 int first_spread = 0;
3406 for (; first_spread < list.length() && !list.at(first_spread)->IsSpread();
3410 DCHECK_LT(first_spread, list.length());
3411 return factory()->NewArrayLiteral(list, first_spread, kNoSourcePosition);
3414 Expression* Parser::SpreadCall(Expression*
function,
3415 const ScopedPtrList<Expression>& args_list,
3416 int pos, Call::PossiblyEval is_possibly_eval) {
3418 if (OnlyLastArgIsSpread(args_list) || function->IsSuperCallReference()) {
3419 return factory()->NewCall(
function, args_list, pos);
3422 ScopedPtrList<Expression> args(pointer_buffer());
3423 if (function->IsProperty()) {
3425 if (function->AsProperty()->IsSuperAccess()) {
3426 Expression* home = ThisExpression(kNoSourcePosition);
3430 Variable* temp = NewTemporary(ast_value_factory()->empty_string());
3431 VariableProxy* obj = factory()->NewVariableProxy(temp);
3432 Assignment* assign_obj = factory()->NewAssignment(
3433 Token::ASSIGN, obj, function->AsProperty()->obj(), kNoSourcePosition);
3434 function = factory()->NewProperty(
3435 assign_obj, function->AsProperty()->key(), kNoSourcePosition);
3437 obj = factory()->NewVariableProxy(temp);
3443 args.Add(factory()->NewUndefinedLiteral(kNoSourcePosition));
3445 args.Add(ArrayLiteralFromListWithSpread(args_list));
3446 return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos);
3449 Expression* Parser::SpreadCallNew(Expression*
function,
3450 const ScopedPtrList<Expression>& args_list,
3452 if (OnlyLastArgIsSpread(args_list)) {
3454 return factory()->NewCallNew(
function, args_list, pos);
3456 ScopedPtrList<Expression> args(pointer_buffer());
3458 args.Add(ArrayLiteralFromListWithSpread(args_list));
3460 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos);
3464 void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) {
3465 v8::Isolate::UseCounterFeature feature;
3466 if (is_sloppy(mode))
3467 feature = v8::Isolate::kSloppyMode;
3468 else if (is_strict(mode))
3469 feature = v8::Isolate::kStrictMode;
3472 ++use_counts_[feature];
3473 scope->SetLanguageMode(mode);
3476 void Parser::SetAsmModule() {
3479 ++use_counts_[v8::Isolate::kUseAsm];
3480 DCHECK(scope()->is_declaration_scope());
3481 scope()->AsDeclarationScope()->set_asm_module();
3484 Expression* Parser::ExpressionListToExpression(
3485 const ScopedPtrList<Expression>& args) {
3486 Expression* expr = args.at(0);
3487 if (args.length() == 1)
return expr;
3488 if (args.length() == 2) {
3489 return factory()->NewBinaryOperation(Token::COMMA, expr, args.at(1),
3490 args.at(1)->position());
3492 NaryOperation* result =
3493 factory()->NewNaryOperation(Token::COMMA, expr, args.length() - 1);
3494 for (
int i = 1;
i < args.length();
i++) {
3495 result->AddSubsequent(args.at(
i), args.at(
i)->position());
3501 void Parser::RewriteAsyncFunctionBody(ScopedPtrList<Statement>* body,
3502 Block* block, Expression* return_value) {
3511 block->statements()->Add(factory()->NewAsyncReturnStatement(
3512 return_value, return_value->position()),
3514 block = BuildRejectPromiseOnException(block);
3518 void Parser::RewriteDestructuringAssignments() {
3519 const auto& assignments =
3520 function_state_->destructuring_assignments_to_rewrite();
3521 auto it = assignments.rbegin();
3522 for (; it != assignments.rend(); ++it) {
3525 RewritableExpression* to_rewrite = *it;
3526 DCHECK_NOT_NULL(to_rewrite);
3527 if (!to_rewrite->is_rewritten()) {
3531 Scope* scope = to_rewrite->scope()->GetUnremovedScope();
3534 DCHECK(scope->GetClosureScope() == scope_->GetClosureScope());
3535 BlockState block_state(&scope_, scope);
3536 RewriteDestructuringAssignment(to_rewrite);
3541 void Parser::QueueDestructuringAssignmentForRewriting(
3542 RewritableExpression* expr) {
3543 function_state_->AddDestructuringAssignment(expr);
3546 void Parser::SetFunctionNameFromPropertyName(LiteralProperty* property,
3547 const AstRawString* name,
3548 const AstRawString* prefix) {
3549 if (has_error())
return;
3552 if (property->NeedsSetFunctionName()) {
3559 DCHECK_IMPLIES(property->value()->IsAnonymousFunctionDefinition() ||
3560 property->value()->IsConciseMethodDefinition() ||
3561 property->value()->IsAccessorFunctionDefinition(),
3565 Expression* value =
property->value();
3566 SetFunctionName(value, name, prefix);
3569 void Parser::SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
3570 const AstRawString* name,
3571 const AstRawString* prefix) {
3575 if (property->IsPrototype() || has_error())
return;
3577 DCHECK(!property->value()->IsAnonymousFunctionDefinition() ||
3578 property->kind() == ObjectLiteralProperty::COMPUTED);
3580 SetFunctionNameFromPropertyName(static_cast<LiteralProperty*>(property), name,
3584 void Parser::SetFunctionNameFromIdentifierRef(Expression* value,
3585 Expression* identifier) {
3586 if (!identifier->IsVariableProxy())
return;
3587 SetFunctionName(value, identifier->AsVariableProxy()->raw_name());
3590 void Parser::SetFunctionName(Expression* value,
const AstRawString* name,
3591 const AstRawString* prefix) {
3592 if (!value->IsAnonymousFunctionDefinition() &&
3593 !value->IsConciseMethodDefinition() &&
3594 !value->IsAccessorFunctionDefinition()) {
3597 auto function = value->AsFunctionLiteral();
3598 if (value->IsClassLiteral()) {
3599 function = value->AsClassLiteral()->constructor();
3601 if (
function !=
nullptr) {
3602 AstConsString* cons_name =
nullptr;
3603 if (name !=
nullptr) {
3604 if (prefix !=
nullptr) {
3605 cons_name = ast_value_factory()->NewConsString(prefix, name);
3607 cons_name = ast_value_factory()->NewConsString(name);
3610 DCHECK_NULL(prefix);
3612 function->set_raw_name(cons_name);
3616 Statement* Parser::CheckCallable(Variable* var, Expression* error,
int pos) {
3617 const int nopos = kNoSourcePosition;
3618 Statement* validate_var;
3620 Expression* type_of = factory()->NewUnaryOperation(
3621 Token::TYPEOF, factory()->NewVariableProxy(var), nopos);
3622 Expression* function_literal = factory()->NewStringLiteral(
3623 ast_value_factory()->function_string(), nopos);
3624 Expression* condition = factory()->NewCompareOperation(
3625 Token::EQ_STRICT, type_of, function_literal, nopos);
3627 Statement* throw_call = factory()->NewExpressionStatement(error, pos);
3629 validate_var = factory()->NewIfStatement(
3630 condition, factory()->EmptyStatement(), throw_call, nopos);
3632 return validate_var;
3635 void Parser::BuildIteratorClose(ZonePtrList<Statement>* statements,
3636 Variable* iterator, Variable* input,
3637 Variable* var_output, IteratorType type) {
3650 const int nopos = kNoSourcePosition;
3653 Variable* var_return = var_output;
3654 Statement* get_return;
3656 Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
3657 Expression* literal = factory()->NewStringLiteral(
3658 ast_value_factory()->return_string(), nopos);
3659 Expression*
property =
3660 factory()->NewProperty(iterator_proxy, literal, nopos);
3661 Expression* return_proxy = factory()->NewVariableProxy(var_return);
3662 Expression* assignment =
3663 factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos);
3664 get_return = factory()->NewExpressionStatement(assignment, nopos);
3670 Statement* check_return;
3672 Expression* condition = factory()->NewCompareOperation(
3673 Token::EQ, factory()->NewVariableProxy(var_return),
3674 factory()->NewNullLiteral(nopos), nopos);
3676 Expression* value = factory()->NewVariableProxy(input);
3678 Statement* return_input = BuildReturnStatement(value, nopos);
3680 check_return = factory()->NewIfStatement(
3681 condition, return_input, factory()->EmptyStatement(), nopos);
3685 Statement* call_return;
3687 ScopedPtrList<Expression> args(pointer_buffer());
3688 args.Add(factory()->NewVariableProxy(var_return));
3689 args.Add(factory()->NewVariableProxy(iterator));
3690 args.Add(factory()->NewVariableProxy(input));
3693 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
3694 if (type == IteratorType::kAsync) {
3695 function_state_->AddSuspend();
3696 call = factory()->NewAwait(call, nopos);
3698 Expression* output_proxy = factory()->NewVariableProxy(var_output);
3699 Expression* assignment =
3700 factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
3701 call_return = factory()->NewExpressionStatement(assignment, nopos);
3705 Statement* validate_output;
3707 Expression* is_receiver_call;
3709 ScopedPtrList<Expression> args(pointer_buffer());
3710 args.Add(factory()->NewVariableProxy(var_output));
3712 factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
3715 Statement* throw_call;
3717 ScopedPtrList<Expression> args(pointer_buffer());
3718 args.Add(factory()->NewVariableProxy(var_output));
3719 Expression* call = factory()->NewCallRuntime(
3720 Runtime::kThrowIteratorResultNotAnObject, args, nopos);
3721 throw_call = factory()->NewExpressionStatement(call, nopos);
3724 validate_output = factory()->NewIfStatement(
3725 is_receiver_call, factory()->EmptyStatement(), throw_call, nopos);
3728 statements->Add(get_return, zone());
3729 statements->Add(check_return, zone());
3730 statements->Add(call_return, zone());
3731 statements->Add(validate_output, zone());
3734 void Parser::FinalizeIteratorUse(Variable* completion, Expression* condition,
3735 Variable* iter, Block* iterator_use,
3736 Block* target, IteratorType type) {
3756 const int nopos = kNoSourcePosition;
3759 Statement* initialize_completion;
3761 Expression* proxy = factory()->NewVariableProxy(completion);
3762 Expression* assignment = factory()->NewAssignment(
3763 Token::ASSIGN, proxy,
3764 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
3765 initialize_completion =
3766 factory()->NewExpressionStatement(assignment, nopos);
3770 Statement* set_completion_throw;
3772 Expression* condition = factory()->NewCompareOperation(
3773 Token::EQ_STRICT, factory()->NewVariableProxy(completion),
3774 factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
3776 Expression* proxy = factory()->NewVariableProxy(completion);
3777 Expression* assignment = factory()->NewAssignment(
3778 Token::ASSIGN, proxy,
3779 factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos);
3780 Statement* statement = factory()->NewExpressionStatement(assignment, nopos);
3781 set_completion_throw = factory()->NewIfStatement(
3782 condition, statement, factory()->EmptyStatement(), nopos);
3790 Block* block = factory()->NewBlock(2,
true);
3791 Expression* proxy = factory()->NewVariableProxy(completion);
3792 BuildIteratorCloseForCompletion(block->statements(), iter, proxy, type);
3793 DCHECK_EQ(block->statements()->length(), 2);
3795 maybe_close = IgnoreCompletion(factory()->NewIfStatement(
3796 condition, block, factory()->EmptyStatement(), nopos));
3804 Statement* try_catch;
3806 Scope* catch_scope = NewHiddenCatchScope();
3814 ScopedPtrList<Expression> args(pointer_buffer());
3815 args.Add(factory()->NewVariableProxy(catch_scope->catch_variable()));
3816 rethrow = factory()->NewExpressionStatement(
3817 factory()->NewCallRuntime(Runtime::kReThrow, args, nopos), nopos);
3820 Block* catch_block = factory()->NewBlock(2,
false);
3821 catch_block->statements()->Add(set_completion_throw, zone());
3822 catch_block->statements()->Add(rethrow, zone());
3824 try_catch = factory()->NewTryCatchStatementForReThrow(
3825 iterator_use, catch_scope, catch_block, nopos);
3829 Statement* try_finally;
3831 Block* try_block = factory()->NewBlock(1,
false);
3832 try_block->statements()->Add(try_catch, zone());
3835 factory()->NewTryFinallyStatement(try_block, maybe_close, nopos);
3838 target->statements()->Add(initialize_completion, zone());
3839 target->statements()->Add(try_finally, zone());
3842 void Parser::BuildIteratorCloseForCompletion(ZonePtrList<Statement>* statements,
3844 Expression* completion,
3845 IteratorType type) {
3874 const int nopos = kNoSourcePosition;
3876 Variable* var_return = NewTemporary(ast_value_factory()->empty_string());
3877 Statement* get_return;
3879 Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
3880 Expression* literal = factory()->NewStringLiteral(
3881 ast_value_factory()->return_string(), nopos);
3882 Expression*
property =
3883 factory()->NewProperty(iterator_proxy, literal, nopos);
3884 Expression* return_proxy = factory()->NewVariableProxy(var_return);
3885 Expression* assignment =
3886 factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos);
3887 get_return = factory()->NewExpressionStatement(assignment, nopos);
3893 Statement* check_return_callable;
3895 Expression* throw_expr =
3896 NewThrowTypeError(MessageTemplate::kReturnMethodNotCallable,
3897 ast_value_factory()->empty_string(), nopos);
3898 check_return_callable = CheckCallable(var_return, throw_expr, nopos);
3902 Statement* try_call_return;
3904 ScopedPtrList<Expression> args(pointer_buffer());
3905 args.Add(factory()->NewVariableProxy(var_return));
3906 args.Add(factory()->NewVariableProxy(iterator));
3909 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
3911 if (type == IteratorType::kAsync) {
3912 function_state_->AddSuspend();
3913 call = factory()->NewAwait(call, nopos);
3916 Block* try_block = factory()->NewBlock(1,
false);
3917 try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos),
3920 Block* catch_block = factory()->NewBlock(0,
false);
3922 factory()->NewTryCatchStatement(try_block,
nullptr, catch_block, nopos);
3929 Block* validate_return;
3931 Variable* var_output = NewTemporary(ast_value_factory()->empty_string());
3932 Statement* call_return;
3934 ScopedPtrList<Expression> args(pointer_buffer());
3935 args.Add(factory()->NewVariableProxy(var_return));
3936 args.Add(factory()->NewVariableProxy(iterator));
3938 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
3939 if (type == IteratorType::kAsync) {
3940 function_state_->AddSuspend();
3941 call = factory()->NewAwait(call, nopos);
3944 Expression* output_proxy = factory()->NewVariableProxy(var_output);
3945 Expression* assignment =
3946 factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
3947 call_return = factory()->NewExpressionStatement(assignment, nopos);
3950 Expression* is_receiver_call;
3952 ScopedPtrList<Expression> args(pointer_buffer());
3953 args.Add(factory()->NewVariableProxy(var_output));
3955 factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
3958 Statement* throw_call;
3960 ScopedPtrList<Expression> args(pointer_buffer());
3961 args.Add(factory()->NewVariableProxy(var_output));
3962 Expression* call = factory()->NewCallRuntime(
3963 Runtime::kThrowIteratorResultNotAnObject, args, nopos);
3964 throw_call = factory()->NewExpressionStatement(call, nopos);
3967 Statement* check_return = factory()->NewIfStatement(
3968 is_receiver_call, factory()->EmptyStatement(), throw_call, nopos);
3970 validate_return = factory()->NewBlock(2,
false);
3971 validate_return->statements()->Add(call_return, zone());
3972 validate_return->statements()->Add(check_return, zone());
3981 Statement* call_return_carefully;
3983 Expression* condition = factory()->NewCompareOperation(
3984 Token::EQ_STRICT, completion,
3985 factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos);
3987 Block* then_block = factory()->NewBlock(2,
false);
3988 then_block->statements()->Add(check_return_callable, zone());
3989 then_block->statements()->Add(try_call_return, zone());
3991 call_return_carefully = factory()->NewIfStatement(condition, then_block,
3992 validate_return, nopos);
3996 Statement* maybe_call_return;
3998 Expression* condition = factory()->NewCompareOperation(
3999 Token::EQ, factory()->NewVariableProxy(var_return),
4000 factory()->NewNullLiteral(nopos), nopos);
4002 maybe_call_return = factory()->NewIfStatement(
4003 condition, factory()->EmptyStatement(), call_return_carefully, nopos);
4006 statements->Add(get_return, zone());
4007 statements->Add(maybe_call_return, zone());
4010 Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop,
4011 Variable* var_completion,
4012 IteratorType type,
int pos) {
4034 const int nopos = kNoSourcePosition;
4037 Expression* closing_condition;
4039 Expression* cmp = factory()->NewCompareOperation(
4040 Token::EQ_STRICT, factory()->NewVariableProxy(var_completion),
4041 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
4042 closing_condition = factory()->NewUnaryOperation(Token::NOT, cmp, nopos);
4045 Block* final_loop = factory()->NewBlock(2,
false);
4047 Block* try_block = factory()->NewBlock(1,
false);
4048 try_block->statements()->Add(loop, zone());
4050 FinalizeIteratorUse(var_completion, closing_condition, loop->iterator(),
4051 try_block, final_loop, type);