1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/parsing/parser.h"
6
7 #include <algorithm>
8 #include <memory>
9
10 #include "src/ast/ast-function-literal-id-reindexer.h"
11 #include "src/ast/ast-traversal-visitor.h"
12 #include "src/ast/ast.h"
13 #include "src/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"
18 #include "src/log.h"
19 #include "src/messages.h"
20 #include "src/objects/scope-info.h"
21 #include "src/parsing/duplicate-finder.h"
22 #include "src/parsing/expression-scope-reparenter.h"
23 #include "src/parsing/parse-info.h"
24 #include "src/parsing/rewriter.h"
25 #include "src/runtime/runtime.h"
26 #include "src/string-stream.h"
27 #include "src/tracing/trace-event.h"
28
29 namespace v8 {
30 namespace internal {
31
32
33
34 // Helper for putting parts of the parse results into a temporary zone when
35 // parsing inner function bodies.
36 class DiscardableZoneScope {
37 public:
DiscardableZoneScope(Parser * parser,Zone * temp_zone,bool use_temp_zone)38 DiscardableZoneScope(Parser* parser, Zone* temp_zone, bool use_temp_zone)
39 : fni_(parser->ast_value_factory_, temp_zone),
40 parser_(parser),
41 prev_fni_(parser->fni_),
42 prev_zone_(parser->zone_),
43 prev_allow_lazy_(parser->allow_lazy_),
44 prev_temp_zoned_(parser->temp_zoned_) {
45 if (use_temp_zone) {
46 DCHECK(!parser_->temp_zoned_);
47 parser_->allow_lazy_ = false;
48 parser_->temp_zoned_ = true;
49 parser_->fni_ = &fni_;
50 parser_->zone_ = temp_zone;
51 parser_->factory()->set_zone(temp_zone);
52 if (parser_->reusable_preparser_ != nullptr) {
53 parser_->reusable_preparser_->zone_ = temp_zone;
54 parser_->reusable_preparser_->factory()->set_zone(temp_zone);
55 }
56 }
57 }
Reset()58 void Reset() {
59 parser_->fni_ = prev_fni_;
60 parser_->zone_ = prev_zone_;
61 parser_->factory()->set_zone(prev_zone_);
62 parser_->allow_lazy_ = prev_allow_lazy_;
63 parser_->temp_zoned_ = prev_temp_zoned_;
64 if (parser_->reusable_preparser_ != nullptr) {
65 parser_->reusable_preparser_->zone_ = prev_zone_;
66 parser_->reusable_preparser_->factory()->set_zone(prev_zone_);
67 }
68 }
~DiscardableZoneScope()69 ~DiscardableZoneScope() { Reset(); }
70
71 private:
72 FuncNameInferrer fni_;
73 Parser* parser_;
74 FuncNameInferrer* prev_fni_;
75 Zone* prev_zone_;
76 bool prev_allow_lazy_;
77 bool prev_temp_zoned_;
78
79 DISALLOW_COPY_AND_ASSIGN(DiscardableZoneScope);
80 };
81
DefaultConstructor(const AstRawString * name,bool call_super,int pos,int end_pos)82 FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name,
83 bool call_super, int pos,
84 int end_pos) {
85 int expected_property_count = -1;
86 const int parameter_count = 0;
87
88 FunctionKind kind = call_super ? FunctionKind::kDefaultDerivedConstructor
89 : FunctionKind::kDefaultBaseConstructor;
90 DeclarationScope* function_scope = NewFunctionScope(kind);
91 SetLanguageMode(function_scope, LanguageMode::kStrict);
92 // Set start and end position to the same value
93 function_scope->set_start_position(pos);
94 function_scope->set_end_position(pos);
95 ZonePtrList<Statement>* body = nullptr;
96
97 {
98 FunctionState function_state(&function_state_, &scope_, function_scope);
99
100 body = new (zone()) ZonePtrList<Statement>(call_super ? 2 : 1, zone());
101 if (call_super) {
102 // Create a SuperCallReference and handle in BytecodeGenerator.
103 auto constructor_args_name = ast_value_factory()->empty_string();
104 bool is_duplicate;
105 bool is_rest = true;
106 bool is_optional = false;
107 Variable* constructor_args = function_scope->DeclareParameter(
108 constructor_args_name, VariableMode::kTemporary, is_optional, is_rest,
109 &is_duplicate, ast_value_factory(), pos);
110
111 ZonePtrList<Expression>* args =
112 new (zone()) ZonePtrList<Expression>(1, zone());
113 Spread* spread_args = factory()->NewSpread(
114 factory()->NewVariableProxy(constructor_args), pos, pos);
115
116 args->Add(spread_args, zone());
117 Expression* super_call_ref = NewSuperCallReference(pos);
118 Expression* call = factory()->NewCall(super_call_ref, args, pos);
119 body->Add(factory()->NewReturnStatement(call, pos), zone());
120 }
121
122 expected_property_count = function_state.expected_property_count();
123 }
124
125 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
126 name, function_scope, body, expected_property_count, parameter_count,
127 parameter_count, FunctionLiteral::kNoDuplicateParameters,
128 FunctionLiteral::kAnonymousExpression, default_eager_compile_hint(), pos,
129 true, GetNextFunctionLiteralId());
130 return function_literal;
131 }
132
133 // ----------------------------------------------------------------------------
134 // The CHECK_OK macro is a convenient macro to enforce error
135 // handling for functions that may fail (by returning !*ok).
136 //
137 // CAUTION: This macro appends extra statements after a call,
138 // thus it must never be used where only a single statement
139 // is correct (e.g. an if statement branch w/o braces)!
140
141 #define CHECK_OK_VALUE(x) ok); \
142 if (!*ok) return x; \
143 ((void)0
144 #define DUMMY ) // to make indentation work
145 #undef DUMMY
146
147 #define CHECK_OK CHECK_OK_VALUE(nullptr)
148 #define CHECK_OK_VOID CHECK_OK_VALUE(this->Void())
149
150 #define CHECK_FAILED /**/); \
151 if (failed_) return nullptr; \
152 ((void)0
153 #define DUMMY ) // to make indentation work
154 #undef DUMMY
155
156 // ----------------------------------------------------------------------------
157 // Implementation of Parser
158
ShortcutNumericLiteralBinaryExpression(Expression ** x,Expression * y,Token::Value op,int pos)159 bool Parser::ShortcutNumericLiteralBinaryExpression(Expression** x,
160 Expression* y,
161 Token::Value op, int pos) {
162 if ((*x)->IsNumberLiteral() && y->IsNumberLiteral()) {
163 double x_val = (*x)->AsLiteral()->AsNumber();
164 double y_val = y->AsLiteral()->AsNumber();
165 switch (op) {
166 case Token::ADD:
167 *x = factory()->NewNumberLiteral(x_val + y_val, pos);
168 return true;
169 case Token::SUB:
170 *x = factory()->NewNumberLiteral(x_val - y_val, pos);
171 return true;
172 case Token::MUL:
173 *x = factory()->NewNumberLiteral(x_val * y_val, pos);
174 return true;
175 case Token::DIV:
176 *x = factory()->NewNumberLiteral(x_val / y_val, pos);
177 return true;
178 case Token::BIT_OR: {
179 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
180 *x = factory()->NewNumberLiteral(value, pos);
181 return true;
182 }
183 case Token::BIT_AND: {
184 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
185 *x = factory()->NewNumberLiteral(value, pos);
186 return true;
187 }
188 case Token::BIT_XOR: {
189 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
190 *x = factory()->NewNumberLiteral(value, pos);
191 return true;
192 }
193 case Token::SHL: {
194 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1F);
195 *x = factory()->NewNumberLiteral(value, pos);
196 return true;
197 }
198 case Token::SHR: {
199 uint32_t shift = DoubleToInt32(y_val) & 0x1F;
200 uint32_t value = DoubleToUint32(x_val) >> shift;
201 *x = factory()->NewNumberLiteral(value, pos);
202 return true;
203 }
204 case Token::SAR: {
205 uint32_t shift = DoubleToInt32(y_val) & 0x1F;
206 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
207 *x = factory()->NewNumberLiteral(value, pos);
208 return true;
209 }
210 case Token::EXP: {
211 double value = Pow(x_val, y_val);
212 int int_value = static_cast<int>(value);
213 *x = factory()->NewNumberLiteral(
214 int_value == value && value != -0.0 ? int_value : value, pos);
215 return true;
216 }
217 default:
218 break;
219 }
220 }
221 return false;
222 }
223
CollapseNaryExpression(Expression ** x,Expression * y,Token::Value op,int pos,const SourceRange & range)224 bool Parser::CollapseNaryExpression(Expression** x, Expression* y,
225 Token::Value op, int pos,
226 const SourceRange& range) {
227 // Filter out unsupported ops.
228 if (!Token::IsBinaryOp(op) || op == Token::EXP) return false;
229
230 // Convert *x into an nary operation with the given op, returning false if
231 // this is not possible.
232 NaryOperation* nary = nullptr;
233 if ((*x)->IsBinaryOperation()) {
234 BinaryOperation* binop = (*x)->AsBinaryOperation();
235 if (binop->op() != op) return false;
236
237 nary = factory()->NewNaryOperation(op, binop->left(), 2);
238 nary->AddSubsequent(binop->right(), binop->position());
239 ConvertBinaryToNaryOperationSourceRange(binop, nary);
240 *x = nary;
241 } else if ((*x)->IsNaryOperation()) {
242 nary = (*x)->AsNaryOperation();
243 if (nary->op() != op) return false;
244 } else {
245 return false;
246 }
247
248 // Append our current expression to the nary operation.
249 // TODO(leszeks): Do some literal collapsing here if we're appending Smi or
250 // String literals.
251 nary->AddSubsequent(y, pos);
252 AppendNaryOperationSourceRange(nary, range);
253
254 return true;
255 }
256
BuildUnaryExpression(Expression * expression,Token::Value op,int pos)257 Expression* Parser::BuildUnaryExpression(Expression* expression,
258 Token::Value op, int pos) {
259 DCHECK_NOT_NULL(expression);
260 const Literal* literal = expression->AsLiteral();
261 if (literal != nullptr) {
262 if (op == Token::NOT) {
263 // Convert the literal to a boolean condition and negate it.
264 return factory()->NewBooleanLiteral(literal->ToBooleanIsFalse(), pos);
265 } else if (literal->IsNumberLiteral()) {
266 // Compute some expressions involving only number literals.
267 double value = literal->AsNumber();
268 switch (op) {
269 case Token::ADD:
270 return expression;
271 case Token::SUB:
272 return factory()->NewNumberLiteral(-value, pos);
273 case Token::BIT_NOT:
274 return factory()->NewNumberLiteral(~DoubleToInt32(value), pos);
275 default:
276 break;
277 }
278 }
279 }
280 return factory()->NewUnaryOperation(op, expression, pos);
281 }
282
NewThrowError(Runtime::FunctionId id,MessageTemplate::Template message,const AstRawString * arg,int pos)283 Expression* Parser::NewThrowError(Runtime::FunctionId id,
284 MessageTemplate::Template message,
285 const AstRawString* arg, int pos) {
286 ZonePtrList<Expression>* args =
287 new (zone()) ZonePtrList<Expression>(2, zone());
288 args->Add(factory()->NewSmiLiteral(message, pos), zone());
289 args->Add(factory()->NewStringLiteral(arg, pos), zone());
290 CallRuntime* call_constructor = factory()->NewCallRuntime(id, args, pos);
291 return factory()->NewThrow(call_constructor, pos);
292 }
293
NewSuperPropertyReference(int pos)294 Expression* Parser::NewSuperPropertyReference(int pos) {
295 // this_function[home_object_symbol]
296 VariableProxy* this_function_proxy =
297 NewUnresolved(ast_value_factory()->this_function_string(), pos);
298 Expression* home_object_symbol_literal = factory()->NewSymbolLiteral(
299 AstSymbol::kHomeObjectSymbol, kNoSourcePosition);
300 Expression* home_object = factory()->NewProperty(
301 this_function_proxy, home_object_symbol_literal, pos);
302 return factory()->NewSuperPropertyReference(
303 ThisExpression(pos)->AsVariableProxy(), home_object, pos);
304 }
305
NewSuperCallReference(int pos)306 Expression* Parser::NewSuperCallReference(int pos) {
307 VariableProxy* new_target_proxy =
308 NewUnresolved(ast_value_factory()->new_target_string(), pos);
309 VariableProxy* this_function_proxy =
310 NewUnresolved(ast_value_factory()->this_function_string(), pos);
311 return factory()->NewSuperCallReference(
312 ThisExpression(pos)->AsVariableProxy(), new_target_proxy,
313 this_function_proxy, pos);
314 }
315
NewTargetExpression(int pos)316 Expression* Parser::NewTargetExpression(int pos) {
317 auto proxy = NewUnresolved(ast_value_factory()->new_target_string(), pos);
318 proxy->set_is_new_target();
319 return proxy;
320 }
321
ImportMetaExpression(int pos)322 Expression* Parser::ImportMetaExpression(int pos) {
323 return factory()->NewCallRuntime(
324 Runtime::kInlineGetImportMetaObject,
325 new (zone()) ZonePtrList<Expression>(0, zone()), pos);
326 }
327
ExpressionFromLiteral(Token::Value token,int pos)328 Literal* Parser::ExpressionFromLiteral(Token::Value token, int pos) {
329 switch (token) {
330 case Token::NULL_LITERAL:
331 return factory()->NewNullLiteral(pos);
332 case Token::TRUE_LITERAL:
333 return factory()->NewBooleanLiteral(true, pos);
334 case Token::FALSE_LITERAL:
335 return factory()->NewBooleanLiteral(false, pos);
336 case Token::SMI: {
337 uint32_t value = scanner()->smi_value();
338 return factory()->NewSmiLiteral(value, pos);
339 }
340 case Token::NUMBER: {
341 double value = scanner()->DoubleValue();
342 return factory()->NewNumberLiteral(value, pos);
343 }
344 case Token::BIGINT:
345 return factory()->NewBigIntLiteral(
346 AstBigInt(scanner()->CurrentLiteralAsCString(zone())), pos);
347 default:
348 DCHECK(false);
349 }
350 return nullptr;
351 }
352
NewV8Intrinsic(const AstRawString * name,ZonePtrList<Expression> * args,int pos,bool * ok)353 Expression* Parser::NewV8Intrinsic(const AstRawString* name,
354 ZonePtrList<Expression>* args, int pos,
355 bool* ok) {
356 if (extension_ != nullptr) {
357 // The extension structures are only accessible while parsing the
358 // very first time, not when reparsing because of lazy compilation.
359 GetClosureScope()->ForceEagerCompilation();
360 }
361
362 DCHECK(name->is_one_byte());
363 const Runtime::Function* function =
364 Runtime::FunctionForName(name->raw_data(), name->length());
365
366 if (function != nullptr) {
367 // Check for possible name clash.
368 DCHECK_EQ(Context::kNotFound,
369 Context::IntrinsicIndexForName(name->raw_data(), name->length()));
370 // Check for built-in IS_VAR macro.
371 if (function->function_id == Runtime::kIS_VAR) {
372 DCHECK_EQ(Runtime::RUNTIME, function->intrinsic_type);
373 // %IS_VAR(x) evaluates to x if x is a variable,
374 // leads to a parse error otherwise. Could be implemented as an
375 // inline function %_IS_VAR(x) to eliminate this special case.
376 if (args->length() == 1 && args->at(0)->AsVariableProxy() != nullptr) {
377 return args->at(0);
378 } else {
379 ReportMessage(MessageTemplate::kNotIsvar);
380 *ok = false;
381 return nullptr;
382 }
383 }
384
385 // Check that the expected number of arguments are being passed.
386 if (function->nargs != -1 && function->nargs != args->length()) {
387 ReportMessage(MessageTemplate::kRuntimeWrongNumArgs);
388 *ok = false;
389 return nullptr;
390 }
391
392 return factory()->NewCallRuntime(function, args, pos);
393 }
394
395 int context_index =
396 Context::IntrinsicIndexForName(name->raw_data(), name->length());
397
398 // Check that the function is defined.
399 if (context_index == Context::kNotFound) {
400 ReportMessage(MessageTemplate::kNotDefined, name);
401 *ok = false;
402 return nullptr;
403 }
404
405 return factory()->NewCallRuntime(context_index, args, pos);
406 }
407
Parser(ParseInfo * info)408 Parser::Parser(ParseInfo* info)
409 : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(),
410 info->extension(), info->GetOrCreateAstValueFactory(),
411 info->pending_error_handler(),
412 info->runtime_call_stats(), info->logger(),
413 info->script().is_null() ? -1 : info->script()->id(),
414 info->is_module(), true),
415 scanner_(info->unicode_cache(), info->character_stream(),
416 info->is_module()),
417 reusable_preparser_(nullptr),
418 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
419 source_range_map_(info->source_range_map()),
420 target_stack_(nullptr),
421 total_preparse_skipped_(0),
422 temp_zoned_(false),
423 consumed_preparsed_scope_data_(info->consumed_preparsed_scope_data()),
424 parameters_end_pos_(info->parameters_end_pos()) {
425 // Even though we were passed ParseInfo, we should not store it in
426 // Parser - this makes sure that Isolate is not accidentally accessed via
427 // ParseInfo during background parsing.
428 DCHECK_NOT_NULL(info->character_stream());
429 // Determine if functions can be lazily compiled. This is necessary to
430 // allow some of our builtin JS files to be lazily compiled. These
431 // builtins cannot be handled lazily by the parser, since we have to know
432 // if a function uses the special natives syntax, which is something the
433 // parser records.
434 // If the debugger requests compilation for break points, we cannot be
435 // aggressive about lazy compilation, because it might trigger compilation
436 // of functions without an outer context when setting a breakpoint through
437 // Debug::FindSharedFunctionInfoInScript
438 // We also compile eagerly for kProduceExhaustiveCodeCache.
439 bool can_compile_lazily = FLAG_lazy && !info->is_eager();
440
441 set_default_eager_compile_hint(can_compile_lazily
442 ? FunctionLiteral::kShouldLazyCompile
443 : FunctionLiteral::kShouldEagerCompile);
444 allow_lazy_ = FLAG_lazy && info->allow_lazy_parsing() && !info->is_native() &&
445 info->extension() == nullptr && can_compile_lazily;
446 set_allow_natives(FLAG_allow_natives_syntax || info->is_native());
447 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions);
448 set_allow_harmony_public_fields(FLAG_harmony_public_fields);
449 set_allow_harmony_static_fields(FLAG_harmony_static_fields);
450 set_allow_harmony_dynamic_import(FLAG_harmony_dynamic_import);
451 set_allow_harmony_import_meta(FLAG_harmony_import_meta);
452 set_allow_harmony_bigint(FLAG_harmony_bigint);
453 set_allow_harmony_numeric_separator(FLAG_harmony_numeric_separator);
454 set_allow_harmony_private_fields(FLAG_harmony_private_fields);
455 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
456 ++feature) {
457 use_counts_[feature] = 0;
458 }
459 }
460
DeserializeScopeChain(Isolate * isolate,ParseInfo * info,MaybeHandle<ScopeInfo> maybe_outer_scope_info)461 void Parser::DeserializeScopeChain(
462 Isolate* isolate, ParseInfo* info,
463 MaybeHandle<ScopeInfo> maybe_outer_scope_info) {
464 // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native
465 // context, which will have the "this" binding for script scopes.
466 DeclarationScope* script_scope = NewScriptScope();
467 info->set_script_scope(script_scope);
468 Scope* scope = script_scope;
469 Handle<ScopeInfo> outer_scope_info;
470 if (maybe_outer_scope_info.ToHandle(&outer_scope_info)) {
471 DCHECK(ThreadId::Current().Equals(isolate->thread_id()));
472 scope = Scope::DeserializeScopeChain(
473 isolate, zone(), *outer_scope_info, script_scope, ast_value_factory(),
474 Scope::DeserializationMode::kScopesOnly);
475 }
476 original_scope_ = scope;
477 }
478
479 namespace {
480
MaybeResetCharacterStream(ParseInfo * info,FunctionLiteral * literal)481 void MaybeResetCharacterStream(ParseInfo* info, FunctionLiteral* literal) {
482 // Don't reset the character stream if there is an asm.js module since it will
483 // be used again by the asm-parser.
484 if (!FLAG_stress_validate_asm &&
485 (literal == nullptr || !literal->scope()->ContainsAsmModule())) {
486 info->ResetCharacterStream();
487 }
488 }
489
490 } // namespace
491
ParseProgram(Isolate * isolate,ParseInfo * info)492 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
493 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
494 // see comment for HistogramTimerScope class.
495
496 // It's OK to use the Isolate & counters here, since this function is only
497 // called in the main thread.
498 DCHECK(parsing_on_main_thread_);
499 RuntimeCallTimerScope runtime_timer(
500 runtime_call_stats_, info->is_eval()
501 ? RuntimeCallCounterId::kParseEval
502 : RuntimeCallCounterId::kParseProgram);
503 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram");
504 base::ElapsedTimer timer;
505 if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
506 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
507
508 // Initialize parser state.
509 DeserializeScopeChain(isolate, info, info->maybe_outer_scope_info());
510
511 scanner_.Initialize();
512 FunctionLiteral* result = DoParseProgram(isolate, info);
513 MaybeResetCharacterStream(info, result);
514
515 HandleSourceURLComments(isolate, info->script());
516
517 if (V8_UNLIKELY(FLAG_log_function_events) && result != nullptr) {
518 double ms = timer.Elapsed().InMillisecondsF();
519 const char* event_name = "parse-eval";
520 Script* script = *info->script();
521 int start = -1;
522 int end = -1;
523 if (!info->is_eval()) {
524 event_name = "parse-script";
525 start = 0;
526 end = String::cast(script->source())->length();
527 }
528 LOG(isolate,
529 FunctionEvent(event_name, script->id(), ms, start, end, "", 0));
530 }
531 return result;
532 }
533
DoParseProgram(Isolate * isolate,ParseInfo * info)534 FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
535 // Note that this function can be called from the main thread or from a
536 // background thread. We should not access anything Isolate / heap dependent
537 // via ParseInfo, and also not pass it forward. If not on the main thread
538 // isolate will be nullptr.
539 DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr);
540 DCHECK_NULL(scope_);
541 DCHECK_NULL(target_stack_);
542
543 ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
544 ResetFunctionLiteralId();
545 DCHECK(info->function_literal_id() == FunctionLiteral::kIdTypeTopLevel ||
546 info->function_literal_id() == FunctionLiteral::kIdTypeInvalid);
547
548 FunctionLiteral* result = nullptr;
549 {
550 Scope* outer = original_scope_;
551 DCHECK_NOT_NULL(outer);
552 if (info->is_eval()) {
553 outer = NewEvalScope(outer);
554 } else if (parsing_module_) {
555 DCHECK_EQ(outer, info->script_scope());
556 outer = NewModuleScope(info->script_scope());
557 }
558
559 DeclarationScope* scope = outer->AsDeclarationScope();
560 scope->set_start_position(0);
561
562 FunctionState function_state(&function_state_, &scope_, scope);
563 ZonePtrList<Statement>* body =
564 new (zone()) ZonePtrList<Statement>(16, zone());
565 bool ok = true;
566 int beg_pos = scanner()->location().beg_pos;
567 if (parsing_module_) {
568 DCHECK(info->is_module());
569 // Declare the special module parameter.
570 auto name = ast_value_factory()->empty_string();
571 bool is_duplicate = false;
572 bool is_rest = false;
573 bool is_optional = false;
574 auto var = scope->DeclareParameter(name, VariableMode::kVar, is_optional,
575 is_rest, &is_duplicate,
576 ast_value_factory(), beg_pos);
577 DCHECK(!is_duplicate);
578 var->AllocateTo(VariableLocation::PARAMETER, 0);
579
580 PrepareGeneratorVariables();
581 Expression* initial_yield =
582 BuildInitialYield(kNoSourcePosition, kGeneratorFunction);
583 body->Add(
584 factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
585 zone());
586
587 ParseModuleItemList(body, &ok);
588 ok = ok && module()->Validate(this->scope()->AsModuleScope(),
589 pending_error_handler(), zone());
590 } else if (info->is_wrapped_as_function()) {
591 ParseWrapped(isolate, info, body, scope, zone(), &ok);
592 } else {
593 // Don't count the mode in the use counters--give the program a chance
594 // to enable script-wide strict mode below.
595 this->scope()->SetLanguageMode(info->language_mode());
596 ParseStatementList(body, Token::EOS, &ok);
597 }
598
599 // The parser will peek but not consume EOS. Our scope logically goes all
600 // the way to the EOS, though.
601 scope->set_end_position(scanner()->peek_location().beg_pos);
602
603 if (ok && is_strict(language_mode())) {
604 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
605 }
606 if (ok && is_sloppy(language_mode())) {
607 // TODO(littledan): Function bindings on the global object that modify
608 // pre-existing bindings should be made writable, enumerable and
609 // nonconfigurable if possible, whereas this code will leave attributes
610 // unchanged if the property already exists.
611 InsertSloppyBlockFunctionVarBindings(scope);
612 }
613 if (ok) {
614 CheckConflictingVarDeclarations(scope, &ok);
615 }
616
617 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
618 if (body->length() != 1 ||
619 !body->at(0)->IsExpressionStatement() ||
620 !body->at(0)->AsExpressionStatement()->
621 expression()->IsFunctionLiteral()) {
622 ReportMessage(MessageTemplate::kSingleFunctionLiteral);
623 ok = false;
624 }
625 }
626
627 if (ok) {
628 RewriteDestructuringAssignments();
629 int parameter_count = parsing_module_ ? 1 : 0;
630 result = factory()->NewScriptOrEvalFunctionLiteral(
631 scope, body, function_state.expected_property_count(),
632 parameter_count);
633 result->set_suspend_count(function_state.suspend_count());
634 }
635 }
636
637 info->set_max_function_literal_id(GetLastFunctionLiteralId());
638
639 // Make sure the target stack is empty.
640 DCHECK_NULL(target_stack_);
641
642 return result;
643 }
644
PrepareWrappedArguments(Isolate * isolate,ParseInfo * info,Zone * zone)645 ZonePtrList<const AstRawString>* Parser::PrepareWrappedArguments(
646 Isolate* isolate, ParseInfo* info, Zone* zone) {
647 DCHECK(parsing_on_main_thread_);
648 DCHECK_NOT_NULL(isolate);
649 Handle<FixedArray> arguments(info->script()->wrapped_arguments(), isolate);
650 int arguments_length = arguments->length();
651 ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
652 new (zone) ZonePtrList<const AstRawString>(arguments_length, zone);
653 for (int i = 0; i < arguments_length; i++) {
654 const AstRawString* argument_string = ast_value_factory()->GetString(
655 Handle<String>(String::cast(arguments->get(i)), isolate));
656 arguments_for_wrapped_function->Add(argument_string, zone);
657 }
658 return arguments_for_wrapped_function;
659 }
660
ParseWrapped(Isolate * isolate,ParseInfo * info,ZonePtrList<Statement> * body,DeclarationScope * outer_scope,Zone * zone,bool * ok)661 void Parser::ParseWrapped(Isolate* isolate, ParseInfo* info,
662 ZonePtrList<Statement>* body,
663 DeclarationScope* outer_scope, Zone* zone, bool* ok) {
664 DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr);
665 DCHECK(info->is_wrapped_as_function());
666 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
667
668 // Set function and block state for the outer eval scope.
669 DCHECK(outer_scope->is_eval_scope());
670 FunctionState function_state(&function_state_, &scope_, outer_scope);
671
672 const AstRawString* function_name = nullptr;
673 Scanner::Location location(0, 0);
674
675 ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
676 PrepareWrappedArguments(isolate, info, zone);
677
678 FunctionLiteral* function_literal = ParseFunctionLiteral(
679 function_name, location, kSkipFunctionNameCheck, kNormalFunction,
680 kNoSourcePosition, FunctionLiteral::kWrapped, LanguageMode::kSloppy,
681 arguments_for_wrapped_function, CHECK_OK_VOID);
682
683 Statement* return_statement = factory()->NewReturnStatement(
684 function_literal, kNoSourcePosition, kNoSourcePosition);
685 body->Add(return_statement, zone);
686 }
687
ParseFunction(Isolate * isolate,ParseInfo * info,Handle<SharedFunctionInfo> shared_info)688 FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
689 Handle<SharedFunctionInfo> shared_info) {
690 // It's OK to use the Isolate & counters here, since this function is only
691 // called in the main thread.
692 DCHECK(parsing_on_main_thread_);
693 RuntimeCallTimerScope runtime_timer(runtime_call_stats_,
694 RuntimeCallCounterId::kParseFunction);
695 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseFunction");
696 base::ElapsedTimer timer;
697 if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
698
699 DeserializeScopeChain(isolate, info, info->maybe_outer_scope_info());
700 DCHECK_EQ(factory()->zone(), info->zone());
701
702 // Initialize parser state.
703 Handle<String> name(shared_info->Name(), isolate);
704 info->set_function_name(ast_value_factory()->GetString(name));
705 scanner_.Initialize();
706
707 FunctionLiteral* result =
708 DoParseFunction(isolate, info, info->function_name());
709 MaybeResetCharacterStream(info, result);
710 if (result != nullptr) {
711 Handle<String> inferred_name(shared_info->inferred_name(), isolate);
712 result->set_inferred_name(inferred_name);
713 }
714
715 if (V8_UNLIKELY(FLAG_log_function_events) && result != nullptr) {
716 double ms = timer.Elapsed().InMillisecondsF();
717 // We need to make sure that the debug-name is available.
718 ast_value_factory()->Internalize(isolate);
719 DeclarationScope* function_scope = result->scope();
720 std::unique_ptr<char[]> function_name = result->GetDebugName();
721 LOG(isolate,
722 FunctionEvent("parse-function", info->script()->id(), ms,
723 function_scope->start_position(),
724 function_scope->end_position(), function_name.get(),
725 strlen(function_name.get())));
726 }
727 return result;
728 }
729
ComputeFunctionType(ParseInfo * info)730 static FunctionLiteral::FunctionType ComputeFunctionType(ParseInfo* info) {
731 if (info->is_wrapped_as_function()) {
732 return FunctionLiteral::kWrapped;
733 } else if (info->is_declaration()) {
734 return FunctionLiteral::kDeclaration;
735 } else if (info->is_named_expression()) {
736 return FunctionLiteral::kNamedExpression;
737 } else if (IsConciseMethod(info->function_kind()) ||
738 IsAccessorFunction(info->function_kind())) {
739 return FunctionLiteral::kAccessorOrMethod;
740 }
741 return FunctionLiteral::kAnonymousExpression;
742 }
743
DoParseFunction(Isolate * isolate,ParseInfo * info,const AstRawString * raw_name)744 FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
745 const AstRawString* raw_name) {
746 DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr);
747 DCHECK_NOT_NULL(raw_name);
748 DCHECK_NULL(scope_);
749 DCHECK_NULL(target_stack_);
750
751 DCHECK(ast_value_factory());
752 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
753 fni_->PushEnclosingName(raw_name);
754
755 ResetFunctionLiteralId();
756 DCHECK_LT(0, info->function_literal_id());
757 SkipFunctionLiterals(info->function_literal_id() - 1);
758
759 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
760
761 // Place holder for the result.
762 FunctionLiteral* result = nullptr;
763
764 {
765 // Parse the function literal.
766 Scope* outer = original_scope_;
767 DeclarationScope* outer_function = outer->GetClosureScope();
768 DCHECK(outer);
769 FunctionState function_state(&function_state_, &scope_, outer_function);
770 BlockState block_state(&scope_, outer);
771 DCHECK(is_sloppy(outer->language_mode()) ||
772 is_strict(info->language_mode()));
773 FunctionLiteral::FunctionType function_type = ComputeFunctionType(info);
774 FunctionKind kind = info->function_kind();
775 bool ok = true;
776
777 if (IsArrowFunction(kind)) {
778 if (IsAsyncFunction(kind)) {
779 DCHECK(!scanner()->HasLineTerminatorAfterNext());
780 if (!Check(Token::ASYNC)) {
781 CHECK(stack_overflow());
782 return nullptr;
783 }
784 if (!(peek_any_identifier() || peek() == Token::LPAREN)) {
785 CHECK(stack_overflow());
786 return nullptr;
787 }
788 }
789
790 // TODO(adamk): We should construct this scope from the ScopeInfo.
791 DeclarationScope* scope = NewFunctionScope(kind);
792
793 // This bit only needs to be explicitly set because we're
794 // not passing the ScopeInfo to the Scope constructor.
795 SetLanguageMode(scope, info->language_mode());
796
797 scope->set_start_position(info->start_position());
798 ExpressionClassifier formals_classifier(this);
799 ParserFormalParameters formals(scope);
800 // The outer FunctionState should not contain destructuring assignments.
801 DCHECK_EQ(0,
802 function_state.destructuring_assignments_to_rewrite().size());
803 {
804 // Parsing patterns as variable reference expression creates
805 // NewUnresolved references in current scope. Enter arrow function
806 // scope for formal parameter parsing.
807 BlockState block_state(&scope_, scope);
808 if (Check(Token::LPAREN)) {
809 // '(' StrictFormalParameters ')'
810 ParseFormalParameterList(&formals, &ok);
811 if (ok) ok = Check(Token::RPAREN);
812 } else {
813 // BindingIdentifier
814 ParseFormalParameter(&formals, &ok);
815 if (ok) {
816 DeclareFormalParameters(formals.scope, formals.params,
817 formals.is_simple);
818 }
819 }
820 }
821
822 if (ok) {
823 if (GetLastFunctionLiteralId() != info->function_literal_id() - 1) {
824 // If there were FunctionLiterals in the parameters, we need to
825 // renumber them to shift down so the next function literal id for
826 // the arrow function is the one requested.
827 AstFunctionLiteralIdReindexer reindexer(
828 stack_limit_,
829 (info->function_literal_id() - 1) - GetLastFunctionLiteralId());
830 for (auto p : formals.params) {
831 if (p->pattern != nullptr) reindexer.Reindex(p->pattern);
832 if (p->initializer != nullptr) reindexer.Reindex(p->initializer);
833 }
834 ResetFunctionLiteralId();
835 SkipFunctionLiterals(info->function_literal_id() - 1);
836 }
837
838 // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should
839 // not be observable, or else the preparser would have failed.
840 const bool accept_IN = true;
841 // Any destructuring assignments in the current FunctionState
842 // actually belong to the arrow function itself.
843 const int rewritable_length = 0;
844 Expression* expression = ParseArrowFunctionLiteral(
845 accept_IN, formals, rewritable_length, &ok);
846 if (ok) {
847 // Scanning must end at the same position that was recorded
848 // previously. If not, parsing has been interrupted due to a stack
849 // overflow, at which point the partially parsed arrow function
850 // concise body happens to be a valid expression. This is a problem
851 // only for arrow functions with single expression bodies, since there
852 // is no end token such as "}" for normal functions.
853 if (scanner()->location().end_pos == info->end_position()) {
854 // The pre-parser saw an arrow function here, so the full parser
855 // must produce a FunctionLiteral.
856 DCHECK(expression->IsFunctionLiteral());
857 result = expression->AsFunctionLiteral();
858 } else {
859 ok = false;
860 }
861 }
862 }
863 } else if (IsDefaultConstructor(kind)) {
864 DCHECK_EQ(scope(), outer);
865 result = DefaultConstructor(raw_name, IsDerivedConstructor(kind),
866 info->start_position(), info->end_position());
867 } else {
868 ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
869 info->is_wrapped_as_function()
870 ? PrepareWrappedArguments(isolate, info, zone())
871 : nullptr;
872 result = ParseFunctionLiteral(
873 raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind,
874 kNoSourcePosition, function_type, info->language_mode(),
875 arguments_for_wrapped_function, &ok);
876 }
877
878 if (ok) {
879 result->set_requires_instance_fields_initializer(
880 info->requires_instance_fields_initializer());
881 }
882 // Make sure the results agree.
883 DCHECK(ok == (result != nullptr));
884 }
885
886 // Make sure the target stack is empty.
887 DCHECK_NULL(target_stack_);
888 DCHECK_IMPLIES(result,
889 info->function_literal_id() == result->function_literal_id());
890 return result;
891 }
892
ParseModuleItem(bool * ok)893 Statement* Parser::ParseModuleItem(bool* ok) {
894 // ecma262/#prod-ModuleItem
895 // ModuleItem :
896 // ImportDeclaration
897 // ExportDeclaration
898 // StatementListItem
899
900 Token::Value next = peek();
901
902 if (next == Token::EXPORT) {
903 return ParseExportDeclaration(ok);
904 }
905
906 if (next == Token::IMPORT) {
907 // We must be careful not to parse a dynamic import expression as an import
908 // declaration. Same for import.meta expressions.
909 Token::Value peek_ahead = PeekAhead();
910 if ((!allow_harmony_dynamic_import() || peek_ahead != Token::LPAREN) &&
911 (!allow_harmony_import_meta() || peek_ahead != Token::PERIOD)) {
912 ParseImportDeclaration(CHECK_OK);
913 return factory()->NewEmptyStatement(kNoSourcePosition);
914 }
915 }
916
917 return ParseStatementListItem(ok);
918 }
919
ParseModuleItemList(ZonePtrList<Statement> * body,bool * ok)920 void Parser::ParseModuleItemList(ZonePtrList<Statement>* body, bool* ok) {
921 // ecma262/#prod-Module
922 // Module :
923 // ModuleBody?
924 //
925 // ecma262/#prod-ModuleItemList
926 // ModuleBody :
927 // ModuleItem*
928
929 DCHECK(scope()->is_module_scope());
930 while (peek() != Token::EOS) {
931 Statement* stat = ParseModuleItem(CHECK_OK_VOID);
932 if (stat && !stat->IsEmpty()) {
933 body->Add(stat, zone());
934 }
935 }
936 }
937
938
ParseModuleSpecifier(bool * ok)939 const AstRawString* Parser::ParseModuleSpecifier(bool* ok) {
940 // ModuleSpecifier :
941 // StringLiteral
942
943 Expect(Token::STRING, CHECK_OK);
944 return GetSymbol();
945 }
946
ParseExportClause(Scanner::Location * reserved_loc,bool * ok)947 ZoneChunkList<Parser::ExportClauseData>* Parser::ParseExportClause(
948 Scanner::Location* reserved_loc, bool* ok) {
949 // ExportClause :
950 // '{' '}'
951 // '{' ExportsList '}'
952 // '{' ExportsList ',' '}'
953 //
954 // ExportsList :
955 // ExportSpecifier
956 // ExportsList ',' ExportSpecifier
957 //
958 // ExportSpecifier :
959 // IdentifierName
960 // IdentifierName 'as' IdentifierName
961 ZoneChunkList<ExportClauseData>* export_data =
962 new (zone()) ZoneChunkList<ExportClauseData>(zone());
963
964 Expect(Token::LBRACE, CHECK_OK);
965
966 Token::Value name_tok;
967 while ((name_tok = peek()) != Token::RBRACE) {
968 // Keep track of the first reserved word encountered in case our
969 // caller needs to report an error.
970 if (!reserved_loc->IsValid() &&
971 !Token::IsIdentifier(name_tok, LanguageMode::kStrict, false,
972 parsing_module_)) {
973 *reserved_loc = scanner()->location();
974 }
975 const AstRawString* local_name = ParseIdentifierName(CHECK_OK);
976 const AstRawString* export_name = nullptr;
977 Scanner::Location location = scanner()->location();
978 if (CheckContextualKeyword(Token::AS)) {
979 export_name = ParseIdentifierName(CHECK_OK);
980 // Set the location to the whole "a as b" string, so that it makes sense
981 // both for errors due to "a" and for errors due to "b".
982 location.end_pos = scanner()->location().end_pos;
983 }
984 if (export_name == nullptr) {
985 export_name = local_name;
986 }
987 export_data->push_back({export_name, local_name, location});
988 if (peek() == Token::RBRACE) break;
989 Expect(Token::COMMA, CHECK_OK);
990 }
991
992 Expect(Token::RBRACE, CHECK_OK);
993 return export_data;
994 }
995
ParseNamedImports(int pos,bool * ok)996 ZonePtrList<const Parser::NamedImport>* Parser::ParseNamedImports(int pos,
997 bool* ok) {
998 // NamedImports :
999 // '{' '}'
1000 // '{' ImportsList '}'
1001 // '{' ImportsList ',' '}'
1002 //
1003 // ImportsList :
1004 // ImportSpecifier
1005 // ImportsList ',' ImportSpecifier
1006 //
1007 // ImportSpecifier :
1008 // BindingIdentifier
1009 // IdentifierName 'as' BindingIdentifier
1010
1011 Expect(Token::LBRACE, CHECK_OK);
1012
1013 auto result = new (zone()) ZonePtrList<const NamedImport>(1, zone());
1014 while (peek() != Token::RBRACE) {
1015 const AstRawString* import_name = ParseIdentifierName(CHECK_OK);
1016 const AstRawString* local_name = import_name;
1017 Scanner::Location location = scanner()->location();
1018 // In the presence of 'as', the left-side of the 'as' can
1019 // be any IdentifierName. But without 'as', it must be a valid
1020 // BindingIdentifier.
1021 if (CheckContextualKeyword(Token::AS)) {
1022 local_name = ParseIdentifierName(CHECK_OK);
1023 }
1024 if (!Token::IsIdentifier(scanner()->current_token(), LanguageMode::kStrict,
1025 false, parsing_module_)) {
1026 *ok = false;
1027 ReportMessage(MessageTemplate::kUnexpectedReserved);
1028 return nullptr;
1029 } else if (IsEvalOrArguments(local_name)) {
1030 *ok = false;
1031 ReportMessage(MessageTemplate::kStrictEvalArguments);
1032 return nullptr;
1033 }
1034
1035 DeclareVariable(local_name, VariableMode::kConst, kNeedsInitialization,
1036 position(), CHECK_OK);
1037
1038 NamedImport* import =
1039 new (zone()) NamedImport(import_name, local_name, location);
1040 result->Add(import, zone());
1041
1042 if (peek() == Token::RBRACE) break;
1043 Expect(Token::COMMA, CHECK_OK);
1044 }
1045
1046 Expect(Token::RBRACE, CHECK_OK);
1047 return result;
1048 }
1049
1050
ParseImportDeclaration(bool * ok)1051 void Parser::ParseImportDeclaration(bool* ok) {
1052 // ImportDeclaration :
1053 // 'import' ImportClause 'from' ModuleSpecifier ';'
1054 // 'import' ModuleSpecifier ';'
1055 //
1056 // ImportClause :
1057 // ImportedDefaultBinding
1058 // NameSpaceImport
1059 // NamedImports
1060 // ImportedDefaultBinding ',' NameSpaceImport
1061 // ImportedDefaultBinding ',' NamedImports
1062 //
1063 // NameSpaceImport :
1064 // '*' 'as' ImportedBinding
1065
1066 int pos = peek_position();
1067 Expect(Token::IMPORT, CHECK_OK_VOID);
1068
1069 Token::Value tok = peek();
1070
1071 // 'import' ModuleSpecifier ';'
1072 if (tok == Token::STRING) {
1073 Scanner::Location specifier_loc = scanner()->peek_location();
1074 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID);
1075 ExpectSemicolon(CHECK_OK_VOID);
1076 module()->AddEmptyImport(module_specifier, specifier_loc);
1077 return;
1078 }
1079
1080 // Parse ImportedDefaultBinding if present.
1081 const AstRawString* import_default_binding = nullptr;
1082 Scanner::Location import_default_binding_loc;
1083 if (tok != Token::MUL && tok != Token::LBRACE) {
1084 import_default_binding =
1085 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK_VOID);
1086 import_default_binding_loc = scanner()->location();
1087 DeclareVariable(import_default_binding, VariableMode::kConst,
1088 kNeedsInitialization, pos, CHECK_OK_VOID);
1089 }
1090
1091 // Parse NameSpaceImport or NamedImports if present.
1092 const AstRawString* module_namespace_binding = nullptr;
1093 Scanner::Location module_namespace_binding_loc;
1094 const ZonePtrList<const NamedImport>* named_imports = nullptr;
1095 if (import_default_binding == nullptr || Check(Token::COMMA)) {
1096 switch (peek()) {
1097 case Token::MUL: {
1098 Consume(Token::MUL);
1099 ExpectContextualKeyword(Token::AS, CHECK_OK_VOID);
1100 module_namespace_binding =
1101 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK_VOID);
1102 module_namespace_binding_loc = scanner()->location();
1103 DeclareVariable(module_namespace_binding, VariableMode::kConst,
1104 kCreatedInitialized, pos, CHECK_OK_VOID);
1105 break;
1106 }
1107
1108 case Token::LBRACE:
1109 named_imports = ParseNamedImports(pos, CHECK_OK_VOID);
1110 break;
1111
1112 default:
1113 *ok = false;
1114 ReportUnexpectedToken(scanner()->current_token());
1115 return;
1116 }
1117 }
1118
1119 ExpectContextualKeyword(Token::FROM, CHECK_OK_VOID);
1120 Scanner::Location specifier_loc = scanner()->peek_location();
1121 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID);
1122 ExpectSemicolon(CHECK_OK_VOID);
1123
1124 // Now that we have all the information, we can make the appropriate
1125 // declarations.
1126
1127 // TODO(neis): Would prefer to call DeclareVariable for each case below rather
1128 // than above and in ParseNamedImports, but then a possible error message
1129 // would point to the wrong location. Maybe have a DeclareAt version of
1130 // Declare that takes a location?
1131
1132 if (module_namespace_binding != nullptr) {
1133 module()->AddStarImport(module_namespace_binding, module_specifier,
1134 module_namespace_binding_loc, specifier_loc,
1135 zone());
1136 }
1137
1138 if (import_default_binding != nullptr) {
1139 module()->AddImport(ast_value_factory()->default_string(),
1140 import_default_binding, module_specifier,
1141 import_default_binding_loc, specifier_loc, zone());
1142 }
1143
1144 if (named_imports != nullptr) {
1145 if (named_imports->length() == 0) {
1146 module()->AddEmptyImport(module_specifier, specifier_loc);
1147 } else {
1148 for (int i = 0; i < named_imports->length(); ++i) {
1149 const NamedImport* import = named_imports->at(i);
1150 module()->AddImport(import->import_name, import->local_name,
1151 module_specifier, import->location, specifier_loc,
1152 zone());
1153 }
1154 }
1155 }
1156 }
1157
1158
ParseExportDefault(bool * ok)1159 Statement* Parser::ParseExportDefault(bool* ok) {
1160 // Supports the following productions, starting after the 'default' token:
1161 // 'export' 'default' HoistableDeclaration
1162 // 'export' 'default' ClassDeclaration
1163 // 'export' 'default' AssignmentExpression[In] ';'
1164
1165 Expect(Token::DEFAULT, CHECK_OK);
1166 Scanner::Location default_loc = scanner()->location();
1167
1168 ZonePtrList<const AstRawString> local_names(1, zone());
1169 Statement* result = nullptr;
1170 switch (peek()) {
1171 case Token::FUNCTION:
1172 result = ParseHoistableDeclaration(&local_names, true, CHECK_OK);
1173 break;
1174
1175 case Token::CLASS:
1176 Consume(Token::CLASS);
1177 result = ParseClassDeclaration(&local_names, true, CHECK_OK);
1178 break;
1179
1180 case Token::ASYNC:
1181 if (PeekAhead() == Token::FUNCTION &&
1182 !scanner()->HasLineTerminatorAfterNext()) {
1183 Consume(Token::ASYNC);
1184 result = ParseAsyncFunctionDeclaration(&local_names, true, CHECK_OK);
1185 break;
1186 }
1187 V8_FALLTHROUGH;
1188
1189 default: {
1190 int pos = position();
1191 ExpressionClassifier classifier(this);
1192 Expression* value = ParseAssignmentExpression(true, CHECK_OK);
1193 ValidateExpression(CHECK_OK);
1194 SetFunctionName(value, ast_value_factory()->default_string());
1195
1196 const AstRawString* local_name =
1197 ast_value_factory()->star_default_star_string();
1198 local_names.Add(local_name, zone());
1199
1200 // It's fine to declare this as VariableMode::kConst because the user has
1201 // no way of writing to it.
1202 Declaration* decl =
1203 DeclareVariable(local_name, VariableMode::kConst, pos, CHECK_OK);
1204 decl->proxy()->var()->set_initializer_position(position());
1205
1206 Assignment* assignment = factory()->NewAssignment(
1207 Token::INIT, decl->proxy(), value, kNoSourcePosition);
1208 result = IgnoreCompletion(
1209 factory()->NewExpressionStatement(assignment, kNoSourcePosition));
1210
1211 ExpectSemicolon(CHECK_OK);
1212 break;
1213 }
1214 }
1215
1216 DCHECK_EQ(local_names.length(), 1);
1217 module()->AddExport(local_names.first(),
1218 ast_value_factory()->default_string(), default_loc,
1219 zone());
1220
1221 DCHECK_NOT_NULL(result);
1222 return result;
1223 }
1224
ParseExportDeclaration(bool * ok)1225 Statement* Parser::ParseExportDeclaration(bool* ok) {
1226 // ExportDeclaration:
1227 // 'export' '*' 'from' ModuleSpecifier ';'
1228 // 'export' ExportClause ('from' ModuleSpecifier)? ';'
1229 // 'export' VariableStatement
1230 // 'export' Declaration
1231 // 'export' 'default' ... (handled in ParseExportDefault)
1232
1233 Expect(Token::EXPORT, CHECK_OK);
1234 int pos = position();
1235
1236 Statement* result = nullptr;
1237 ZonePtrList<const AstRawString> names(1, zone());
1238 Scanner::Location loc = scanner()->peek_location();
1239 switch (peek()) {
1240 case Token::DEFAULT:
1241 return ParseExportDefault(ok);
1242
1243 case Token::MUL: {
1244 Consume(Token::MUL);
1245 loc = scanner()->location();
1246 ExpectContextualKeyword(Token::FROM, CHECK_OK);
1247 Scanner::Location specifier_loc = scanner()->peek_location();
1248 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1249 ExpectSemicolon(CHECK_OK);
1250 module()->AddStarExport(module_specifier, loc, specifier_loc, zone());
1251 return factory()->NewEmptyStatement(pos);
1252 }
1253
1254 case Token::LBRACE: {
1255 // There are two cases here:
1256 //
1257 // 'export' ExportClause ';'
1258 // and
1259 // 'export' ExportClause FromClause ';'
1260 //
1261 // In the first case, the exported identifiers in ExportClause must
1262 // not be reserved words, while in the latter they may be. We
1263 // pass in a location that gets filled with the first reserved word
1264 // encountered, and then throw a SyntaxError if we are in the
1265 // non-FromClause case.
1266 Scanner::Location reserved_loc = Scanner::Location::invalid();
1267 ZoneChunkList<ExportClauseData>* export_data =
1268 ParseExportClause(&reserved_loc, CHECK_OK);
1269 const AstRawString* module_specifier = nullptr;
1270 Scanner::Location specifier_loc;
1271 if (CheckContextualKeyword(Token::FROM)) {
1272 specifier_loc = scanner()->peek_location();
1273 module_specifier = ParseModuleSpecifier(CHECK_OK);
1274 } else if (reserved_loc.IsValid()) {
1275 // No FromClause, so reserved words are invalid in ExportClause.
1276 *ok = false;
1277 ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved);
1278 return nullptr;
1279 }
1280 ExpectSemicolon(CHECK_OK);
1281 if (module_specifier == nullptr) {
1282 for (const ExportClauseData& data : *export_data) {
1283 module()->AddExport(data.local_name, data.export_name, data.location,
1284 zone());
1285 }
1286 } else if (export_data->is_empty()) {
1287 module()->AddEmptyImport(module_specifier, specifier_loc);
1288 } else {
1289 for (const ExportClauseData& data : *export_data) {
1290 module()->AddExport(data.local_name, data.export_name,
1291 module_specifier, data.location, specifier_loc,
1292 zone());
1293 }
1294 }
1295 return factory()->NewEmptyStatement(pos);
1296 }
1297
1298 case Token::FUNCTION:
1299 result = ParseHoistableDeclaration(&names, false, CHECK_OK);
1300 break;
1301
1302 case Token::CLASS:
1303 Consume(Token::CLASS);
1304 result = ParseClassDeclaration(&names, false, CHECK_OK);
1305 break;
1306
1307 case Token::VAR:
1308 case Token::LET:
1309 case Token::CONST:
1310 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK);
1311 break;
1312
1313 case Token::ASYNC:
1314 // TODO(neis): Why don't we have the same check here as in
1315 // ParseStatementListItem?
1316 Consume(Token::ASYNC);
1317 result = ParseAsyncFunctionDeclaration(&names, false, CHECK_OK);
1318 break;
1319
1320 default:
1321 *ok = false;
1322 ReportUnexpectedToken(scanner()->current_token());
1323 return nullptr;
1324 }
1325 loc.end_pos = scanner()->location().end_pos;
1326
1327 ModuleDescriptor* descriptor = module();
1328 for (int i = 0; i < names.length(); ++i) {
1329 descriptor->AddExport(names[i], names[i], loc, zone());
1330 }
1331
1332 DCHECK_NOT_NULL(result);
1333 return result;
1334 }
1335
NewUnresolved(const AstRawString * name,int begin_pos,VariableKind kind)1336 VariableProxy* Parser::NewUnresolved(const AstRawString* name, int begin_pos,
1337 VariableKind kind) {
1338 return scope()->NewUnresolved(factory(), name, begin_pos, kind);
1339 }
1340
NewUnresolved(const AstRawString * name)1341 VariableProxy* Parser::NewUnresolved(const AstRawString* name) {
1342 return scope()->NewUnresolved(factory(), name, scanner()->location().beg_pos);
1343 }
1344
DeclareVariable(const AstRawString * name,VariableMode mode,int pos,bool * ok)1345 Declaration* Parser::DeclareVariable(const AstRawString* name,
1346 VariableMode mode, int pos, bool* ok) {
1347 return DeclareVariable(name, mode, Variable::DefaultInitializationFlag(mode),
1348 pos, ok);
1349 }
1350
DeclareVariable(const AstRawString * name,VariableMode mode,InitializationFlag init,int pos,bool * ok)1351 Declaration* Parser::DeclareVariable(const AstRawString* name,
1352 VariableMode mode, InitializationFlag init,
1353 int pos, bool* ok) {
1354 DCHECK_NOT_NULL(name);
1355 VariableProxy* proxy = factory()->NewVariableProxy(
1356 name, NORMAL_VARIABLE, scanner()->location().beg_pos);
1357 Declaration* declaration;
1358 if (mode == VariableMode::kVar && !scope()->is_declaration_scope()) {
1359 DCHECK(scope()->is_block_scope() || scope()->is_with_scope());
1360 declaration = factory()->NewNestedVariableDeclaration(proxy, scope(), pos);
1361 } else {
1362 declaration = factory()->NewVariableDeclaration(proxy, pos);
1363 }
1364 Declare(declaration, DeclarationDescriptor::NORMAL, mode, init, ok, nullptr,
1365 scanner()->location().end_pos);
1366 if (!*ok) return nullptr;
1367 return declaration;
1368 }
1369
Declare(Declaration * declaration,DeclarationDescriptor::Kind declaration_kind,VariableMode mode,InitializationFlag init,bool * ok,Scope * scope,int var_end_pos)1370 Variable* Parser::Declare(Declaration* declaration,
1371 DeclarationDescriptor::Kind declaration_kind,
1372 VariableMode mode, InitializationFlag init, bool* ok,
1373 Scope* scope, int var_end_pos) {
1374 if (scope == nullptr) {
1375 scope = this->scope();
1376 }
1377 bool sloppy_mode_block_scope_function_redefinition = false;
1378 Variable* variable = scope->DeclareVariable(
1379 declaration, mode, init, &sloppy_mode_block_scope_function_redefinition,
1380 ok);
1381 if (!*ok) {
1382 // If we only have the start position of a proxy, we can't highlight the
1383 // whole variable name. Pretend its length is 1 so that we highlight at
1384 // least the first character.
1385 Scanner::Location loc(declaration->proxy()->position(),
1386 var_end_pos != kNoSourcePosition
1387 ? var_end_pos
1388 : declaration->proxy()->position() + 1);
1389 if (declaration_kind == DeclarationDescriptor::PARAMETER) {
1390 ReportMessageAt(loc, MessageTemplate::kParamDupe);
1391 } else {
1392 ReportMessageAt(loc, MessageTemplate::kVarRedeclaration,
1393 declaration->proxy()->raw_name());
1394 }
1395 return nullptr;
1396 }
1397 if (sloppy_mode_block_scope_function_redefinition) {
1398 ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition];
1399 }
1400 return variable;
1401 }
1402
BuildInitializationBlock(DeclarationParsingResult * parsing_result,ZonePtrList<const AstRawString> * names,bool * ok)1403 Block* Parser::BuildInitializationBlock(
1404 DeclarationParsingResult* parsing_result,
1405 ZonePtrList<const AstRawString>* names, bool* ok) {
1406 Block* result = factory()->NewBlock(1, true);
1407 for (const auto& declaration : parsing_result->declarations) {
1408 DeclareAndInitializeVariables(result, &(parsing_result->descriptor),
1409 &declaration, names, CHECK_OK);
1410 }
1411 return result;
1412 }
1413
DeclareFunction(const AstRawString * variable_name,FunctionLiteral * function,VariableMode mode,int pos,bool is_sloppy_block_function,ZonePtrList<const AstRawString> * names,bool * ok)1414 Statement* Parser::DeclareFunction(const AstRawString* variable_name,
1415 FunctionLiteral* function, VariableMode mode,
1416 int pos, bool is_sloppy_block_function,
1417 ZonePtrList<const AstRawString>* names,
1418 bool* ok) {
1419 VariableProxy* proxy =
1420 factory()->NewVariableProxy(variable_name, NORMAL_VARIABLE, pos);
1421 Declaration* declaration =
1422 factory()->NewFunctionDeclaration(proxy, function, pos);
1423 Declare(declaration, DeclarationDescriptor::NORMAL, mode, kCreatedInitialized,
1424 CHECK_OK);
1425 if (names) names->Add(variable_name, zone());
1426 if (is_sloppy_block_function) {
1427 SloppyBlockFunctionStatement* statement =
1428 factory()->NewSloppyBlockFunctionStatement();
1429 GetDeclarationScope()->DeclareSloppyBlockFunction(variable_name, scope(),
1430 statement);
1431 return statement;
1432 }
1433 return factory()->NewEmptyStatement(kNoSourcePosition);
1434 }
1435
DeclareClass(const AstRawString * variable_name,Expression * value,ZonePtrList<const AstRawString> * names,int class_token_pos,int end_pos,bool * ok)1436 Statement* Parser::DeclareClass(const AstRawString* variable_name,
1437 Expression* value,
1438 ZonePtrList<const AstRawString>* names,
1439 int class_token_pos, int end_pos, bool* ok) {
1440 Declaration* decl = DeclareVariable(variable_name, VariableMode::kLet,
1441 class_token_pos, CHECK_OK);
1442 decl->proxy()->var()->set_initializer_position(end_pos);
1443 if (names) names->Add(variable_name, zone());
1444
1445 Assignment* assignment = factory()->NewAssignment(Token::INIT, decl->proxy(),
1446 value, class_token_pos);
1447 return IgnoreCompletion(
1448 factory()->NewExpressionStatement(assignment, kNoSourcePosition));
1449 }
1450
DeclareNative(const AstRawString * name,int pos,bool * ok)1451 Statement* Parser::DeclareNative(const AstRawString* name, int pos, bool* ok) {
1452 // Make sure that the function containing the native declaration
1453 // isn't lazily compiled. The extension structures are only
1454 // accessible while parsing the first time not when reparsing
1455 // because of lazy compilation.
1456 GetClosureScope()->ForceEagerCompilation();
1457
1458 // TODO(1240846): It's weird that native function declarations are
1459 // introduced dynamically when we meet their declarations, whereas
1460 // other functions are set up when entering the surrounding scope.
1461 Declaration* decl = DeclareVariable(name, VariableMode::kVar, pos, CHECK_OK);
1462 NativeFunctionLiteral* lit =
1463 factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition);
1464 return factory()->NewExpressionStatement(
1465 factory()->NewAssignment(Token::INIT, decl->proxy(), lit,
1466 kNoSourcePosition),
1467 pos);
1468 }
1469
DeclareLabel(ZonePtrList<const AstRawString> ** labels,ZonePtrList<const AstRawString> ** own_labels,VariableProxy * var,bool * ok)1470 void Parser::DeclareLabel(ZonePtrList<const AstRawString>** labels,
1471 ZonePtrList<const AstRawString>** own_labels,
1472 VariableProxy* var, bool* ok) {
1473 DCHECK(IsIdentifier(var));
1474 const AstRawString* label = var->raw_name();
1475
1476 // TODO(1240780): We don't check for redeclaration of labels
1477 // during preparsing since keeping track of the set of active
1478 // labels requires nontrivial changes to the way scopes are
1479 // structured. However, these are probably changes we want to
1480 // make later anyway so we should go back and fix this then.
1481 if (ContainsLabel(*labels, label) || TargetStackContainsLabel(label)) {
1482 ReportMessage(MessageTemplate::kLabelRedeclaration, label);
1483 *ok = false;
1484 return;
1485 }
1486
1487 // Add {label} to both {labels} and {own_labels}.
1488 if (*labels == nullptr) {
1489 DCHECK_NULL(*own_labels);
1490 *labels = new (zone()) ZonePtrList<const AstRawString>(1, zone());
1491 *own_labels = new (zone()) ZonePtrList<const AstRawString>(1, zone());
1492 } else {
1493 if (*own_labels == nullptr) {
1494 *own_labels = new (zone()) ZonePtrList<const AstRawString>(1, zone());
1495 }
1496 }
1497 (*labels)->Add(label, zone());
1498 (*own_labels)->Add(label, zone());
1499
1500 // Remove the "ghost" variable that turned out to be a label
1501 // from the top scope. This way, we don't try to resolve it
1502 // during the scope processing.
1503 scope()->RemoveUnresolved(var);
1504 }
1505
ContainsLabel(ZonePtrList<const AstRawString> * labels,const AstRawString * label)1506 bool Parser::ContainsLabel(ZonePtrList<const AstRawString>* labels,
1507 const AstRawString* label) {
1508 DCHECK_NOT_NULL(label);
1509 if (labels != nullptr) {
1510 for (int i = labels->length(); i-- > 0;) {
1511 if (labels->at(i) == label) return true;
1512 }
1513 }
1514 return false;
1515 }
1516
IgnoreCompletion(Statement * statement)1517 Block* Parser::IgnoreCompletion(Statement* statement) {
1518 Block* block = factory()->NewBlock(1, true);
1519 block->statements()->Add(statement, zone());
1520 return block;
1521 }
1522
RewriteReturn(Expression * return_value,int pos)1523 Expression* Parser::RewriteReturn(Expression* return_value, int pos) {
1524 if (IsDerivedConstructor(function_state_->kind())) {
1525 // For subclass constructors we need to return this in case of undefined;
1526 // other primitive values trigger an exception in the ConstructStub.
1527 //
1528 // return expr;
1529 //
1530 // Is rewritten as:
1531 //
1532 // return (temp = expr) === undefined ? this : temp;
1533
1534 // temp = expr
1535 Variable* temp = NewTemporary(ast_value_factory()->empty_string());
1536 Assignment* assign = factory()->NewAssignment(
1537 Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos);
1538
1539 // temp === undefined
1540 Expression* is_undefined = factory()->NewCompareOperation(
1541 Token::EQ_STRICT, assign,
1542 factory()->NewUndefinedLiteral(kNoSourcePosition), pos);
1543
1544 // is_undefined ? this : temp
1545 return_value =
1546 factory()->NewConditional(is_undefined, ThisExpression(pos),
1547 factory()->NewVariableProxy(temp), pos);
1548 }
1549 return return_value;
1550 }
1551
RewriteDoExpression(Block * body,int pos,bool * ok)1552 Expression* Parser::RewriteDoExpression(Block* body, int pos, bool* ok) {
1553 Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
1554 DoExpression* expr = factory()->NewDoExpression(body, result, pos);
1555 if (!Rewriter::Rewrite(this, GetClosureScope(), expr, ast_value_factory())) {
1556 *ok = false;
1557 return nullptr;
1558 }
1559 return expr;
1560 }
1561
RewriteSwitchStatement(SwitchStatement * switch_statement,Scope * scope)1562 Statement* Parser::RewriteSwitchStatement(SwitchStatement* switch_statement,
1563 Scope* scope) {
1564 // In order to get the CaseClauses to execute in their own lexical scope,
1565 // but without requiring downstream code to have special scope handling
1566 // code for switch statements, desugar into blocks as follows:
1567 // { // To group the statements--harmless to evaluate Expression in scope
1568 // .tag_variable = Expression;
1569 // { // To give CaseClauses a scope
1570 // switch (.tag_variable) { CaseClause* }
1571 // }
1572 // }
1573 DCHECK_NOT_NULL(scope);
1574 DCHECK(scope->is_block_scope());
1575 DCHECK_GE(switch_statement->position(), scope->start_position());
1576 DCHECK_LT(switch_statement->position(), scope->end_position());
1577
1578 Block* switch_block = factory()->NewBlock(2, false);
1579
1580 Expression* tag = switch_statement->tag();
1581 Variable* tag_variable =
1582 NewTemporary(ast_value_factory()->dot_switch_tag_string());
1583 Assignment* tag_assign = factory()->NewAssignment(
1584 Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag,
1585 tag->position());
1586 // Wrap with IgnoreCompletion so the tag isn't returned as the completion
1587 // value, in case the switch statements don't have a value.
1588 Statement* tag_statement = IgnoreCompletion(
1589 factory()->NewExpressionStatement(tag_assign, kNoSourcePosition));
1590 switch_block->statements()->Add(tag_statement, zone());
1591
1592 switch_statement->set_tag(factory()->NewVariableProxy(tag_variable));
1593 Block* cases_block = factory()->NewBlock(1, false);
1594 cases_block->statements()->Add(switch_statement, zone());
1595 cases_block->set_scope(scope);
1596 switch_block->statements()->Add(cases_block, zone());
1597 return switch_block;
1598 }
1599
RewriteCatchPattern(CatchInfo * catch_info,bool * ok)1600 void Parser::RewriteCatchPattern(CatchInfo* catch_info, bool* ok) {
1601 if (catch_info->name == nullptr) {
1602 DCHECK_NOT_NULL(catch_info->pattern);
1603 catch_info->name = ast_value_factory()->dot_catch_string();
1604 }
1605 Variable* catch_variable =
1606 catch_info->scope->DeclareLocal(catch_info->name, VariableMode::kVar);
1607 if (catch_info->pattern != nullptr) {
1608 DeclarationDescriptor descriptor;
1609 descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
1610 descriptor.scope = scope();
1611 descriptor.mode = VariableMode::kLet;
1612 descriptor.declaration_pos = catch_info->pattern->position();
1613 descriptor.initialization_pos = catch_info->pattern->position();
1614
1615 // Initializer position for variables declared by the pattern.
1616 const int initializer_position = position();
1617
1618 DeclarationParsingResult::Declaration decl(
1619 catch_info->pattern, initializer_position,
1620 factory()->NewVariableProxy(catch_variable));
1621
1622 catch_info->init_block = factory()->NewBlock(8, true);
1623 DeclareAndInitializeVariables(catch_info->init_block, &descriptor, &decl,
1624 &catch_info->bound_names, ok);
1625 } else {
1626 catch_info->bound_names.Add(catch_info->name, zone());
1627 }
1628 }
1629
ValidateCatchBlock(const CatchInfo & catch_info,bool * ok)1630 void Parser::ValidateCatchBlock(const CatchInfo& catch_info, bool* ok) {
1631 // Check for `catch(e) { let e; }` and similar errors.
1632 Scope* inner_block_scope = catch_info.inner_block->scope();
1633 if (inner_block_scope != nullptr) {
1634 Declaration* decl = inner_block_scope->CheckLexDeclarationsConflictingWith(
1635 catch_info.bound_names);
1636 if (decl != nullptr) {
1637 const AstRawString* name = decl->proxy()->raw_name();
1638 int position = decl->proxy()->position();
1639 Scanner::Location location =
1640 position == kNoSourcePosition
1641 ? Scanner::Location::invalid()
1642 : Scanner::Location(position, position + 1);
1643 ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
1644 *ok = false;
1645 }
1646 }
1647 }
1648
RewriteTryStatement(Block * try_block,Block * catch_block,const SourceRange & catch_range,Block * finally_block,const SourceRange & finally_range,const CatchInfo & catch_info,int pos)1649 Statement* Parser::RewriteTryStatement(Block* try_block, Block* catch_block,
1650 const SourceRange& catch_range,
1651 Block* finally_block,
1652 const SourceRange& finally_range,
1653 const CatchInfo& catch_info, int pos) {
1654 // Simplify the AST nodes by converting:
1655 // 'try B0 catch B1 finally B2'
1656 // to:
1657 // 'try { try B0 catch B1 } finally B2'
1658
1659 if (catch_block != nullptr && finally_block != nullptr) {
1660 // If we have both, create an inner try/catch.
1661 TryCatchStatement* statement;
1662 statement = factory()->NewTryCatchStatement(try_block, catch_info.scope,
1663 catch_block, kNoSourcePosition);
1664 RecordTryCatchStatementSourceRange(statement, catch_range);
1665
1666 try_block = factory()->NewBlock(1, false);
1667 try_block->statements()->Add(statement, zone());
1668 catch_block = nullptr; // Clear to indicate it's been handled.
1669 }
1670
1671 if (catch_block != nullptr) {
1672 DCHECK_NULL(finally_block);
1673 TryCatchStatement* stmt = factory()->NewTryCatchStatement(
1674 try_block, catch_info.scope, catch_block, pos);
1675 RecordTryCatchStatementSourceRange(stmt, catch_range);
1676 return stmt;
1677 } else {
1678 DCHECK_NOT_NULL(finally_block);
1679 TryFinallyStatement* stmt =
1680 factory()->NewTryFinallyStatement(try_block, finally_block, pos);
1681 RecordTryFinallyStatementSourceRange(stmt, finally_range);
1682 return stmt;
1683 }
1684 }
1685
ParseAndRewriteGeneratorFunctionBody(int pos,FunctionKind kind,ZonePtrList<Statement> * body,bool * ok)1686 void Parser::ParseAndRewriteGeneratorFunctionBody(int pos, FunctionKind kind,
1687 ZonePtrList<Statement>* body,
1688 bool* ok) {
1689 // For ES6 Generators, we just prepend the initial yield.
1690 Expression* initial_yield = BuildInitialYield(pos, kind);
1691 body->Add(factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
1692 zone());
1693 ParseStatementList(body, Token::RBRACE, ok);
1694 }
1695
ParseAndRewriteAsyncGeneratorFunctionBody(int pos,FunctionKind kind,ZonePtrList<Statement> * body,bool * ok)1696 void Parser::ParseAndRewriteAsyncGeneratorFunctionBody(
1697 int pos, FunctionKind kind, ZonePtrList<Statement>* body, bool* ok) {
1698 // For ES2017 Async Generators, we produce:
1699 //
1700 // try {
1701 // InitialYield;
1702 // ...body...;
1703 // return undefined; // See comment below
1704 // } catch (.catch) {
1705 // %AsyncGeneratorReject(generator, .catch);
1706 // } finally {
1707 // %_GeneratorClose(generator);
1708 // }
1709 //
1710 // - InitialYield yields the actual generator object.
1711 // - Any return statement inside the body will have its argument wrapped
1712 // in an iterator result object with a "done" property set to `true`.
1713 // - If the generator terminates for whatever reason, we must close it.
1714 // Hence the finally clause.
1715 // - BytecodeGenerator performs special handling for ReturnStatements in
1716 // async generator functions, resolving the appropriate Promise with an
1717 // "done" iterator result object containing a Promise-unwrapped value.
1718 DCHECK(IsAsyncGeneratorFunction(kind));
1719
1720 Block* try_block = factory()->NewBlock(3, false);
1721 Expression* initial_yield = BuildInitialYield(pos, kind);
1722 try_block->statements()->Add(
1723 factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
1724 zone());
1725 ParseStatementList(try_block->statements(), Token::RBRACE, ok);
1726 if (!*ok) return;
1727
1728 // Don't create iterator result for async generators, as the resume methods
1729 // will create it.
1730 // TODO(leszeks): This will create another suspend point, which is unnecessary
1731 // if there is already an unconditional return in the body.
1732 Statement* final_return = BuildReturnStatement(
1733 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
1734 try_block->statements()->Add(final_return, zone());
1735
1736 // For AsyncGenerators, a top-level catch block will reject the Promise.
1737 Scope* catch_scope = NewHiddenCatchScope();
1738
1739 ZonePtrList<Expression>* reject_args =
1740 new (zone()) ZonePtrList<Expression>(2, zone());
1741 reject_args->Add(factory()->NewVariableProxy(
1742 function_state_->scope()->generator_object_var()),
1743 zone());
1744 reject_args->Add(factory()->NewVariableProxy(catch_scope->catch_variable()),
1745 zone());
1746
1747 Expression* reject_call = factory()->NewCallRuntime(
1748 Runtime::kInlineAsyncGeneratorReject, reject_args, kNoSourcePosition);
1749 Block* catch_block = IgnoreCompletion(
1750 factory()->NewReturnStatement(reject_call, kNoSourcePosition));
1751
1752 TryStatement* try_catch = factory()->NewTryCatchStatementForAsyncAwait(
1753 try_block, catch_scope, catch_block, kNoSourcePosition);
1754
1755 try_block = factory()->NewBlock(1, false);
1756 try_block->statements()->Add(try_catch, zone());
1757
1758 Block* finally_block = factory()->NewBlock(1, false);
1759 ZonePtrList<Expression>* close_args =
1760 new (zone()) ZonePtrList<Expression>(1, zone());
1761 VariableProxy* call_proxy = factory()->NewVariableProxy(
1762 function_state_->scope()->generator_object_var());
1763 close_args->Add(call_proxy, zone());
1764 Expression* close_call = factory()->NewCallRuntime(
1765 Runtime::kInlineGeneratorClose, close_args, kNoSourcePosition);
1766 finally_block->statements()->Add(
1767 factory()->NewExpressionStatement(close_call, kNoSourcePosition), zone());
1768
1769 body->Add(factory()->NewTryFinallyStatement(try_block, finally_block,
1770 kNoSourcePosition),
1771 zone());
1772 }
1773
DeclareFunctionNameVar(const AstRawString * function_name,FunctionLiteral::FunctionType function_type,DeclarationScope * function_scope)1774 void Parser::DeclareFunctionNameVar(const AstRawString* function_name,
1775 FunctionLiteral::FunctionType function_type,
1776 DeclarationScope* function_scope) {
1777 if (function_type == FunctionLiteral::kNamedExpression &&
1778 function_scope->LookupLocal(function_name) == nullptr) {
1779 DCHECK_EQ(function_scope, scope());
1780 function_scope->DeclareFunctionVar(function_name);
1781 }
1782 }
1783
1784 // [if (IteratorType == kNormal)]
1785 // !%_IsJSReceiver(result = iterator.next()) &&
1786 // %ThrowIteratorResultNotAnObject(result)
1787 // [else if (IteratorType == kAsync)]
1788 // !%_IsJSReceiver(result = Await(iterator.next())) &&
1789 // %ThrowIteratorResultNotAnObject(result)
1790 // [endif]
BuildIteratorNextResult(VariableProxy * iterator,VariableProxy * next,Variable * result,IteratorType type,int pos)1791 Expression* Parser::BuildIteratorNextResult(VariableProxy* iterator,
1792 VariableProxy* next,
1793 Variable* result, IteratorType type,
1794 int pos) {
1795 Expression* next_property = factory()->NewResolvedProperty(iterator, next);
1796 ZonePtrList<Expression>* next_arguments =
1797 new (zone()) ZonePtrList<Expression>(0, zone());
1798 Expression* next_call =
1799 factory()->NewCall(next_property, next_arguments, kNoSourcePosition);
1800 if (type == IteratorType::kAsync) {
1801 function_state_->AddSuspend();
1802 next_call = factory()->NewAwait(next_call, pos);
1803 }
1804 Expression* result_proxy = factory()->NewVariableProxy(result);
1805 Expression* left =
1806 factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos);
1807
1808 // %_IsJSReceiver(...)
1809 ZonePtrList<Expression>* is_spec_object_args =
1810 new (zone()) ZonePtrList<Expression>(1, zone());
1811 is_spec_object_args->Add(left, zone());
1812 Expression* is_spec_object_call = factory()->NewCallRuntime(
1813 Runtime::kInlineIsJSReceiver, is_spec_object_args, pos);
1814
1815 // %ThrowIteratorResultNotAnObject(result)
1816 Expression* result_proxy_again = factory()->NewVariableProxy(result);
1817 ZonePtrList<Expression>* throw_arguments =
1818 new (zone()) ZonePtrList<Expression>(1, zone());
1819 throw_arguments->Add(result_proxy_again, zone());
1820 Expression* throw_call = factory()->NewCallRuntime(
1821 Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos);
1822
1823 return factory()->NewBinaryOperation(
1824 Token::AND,
1825 factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos),
1826 throw_call, pos);
1827 }
1828
InitializeForEachStatement(ForEachStatement * stmt,Expression * each,Expression * subject,Statement * body)1829 Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt,
1830 Expression* each,
1831 Expression* subject,
1832 Statement* body) {
1833 ForOfStatement* for_of = stmt->AsForOfStatement();
1834 if (for_of != nullptr) {
1835 const bool finalize = true;
1836 return InitializeForOfStatement(for_of, each, subject, body, finalize,
1837 IteratorType::kNormal, each->position());
1838 } else {
1839 if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
1840 Variable* temp = NewTemporary(ast_value_factory()->empty_string());
1841 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
1842 Expression* assign_each =
1843 RewriteDestructuringAssignment(factory()->NewAssignment(
1844 Token::ASSIGN, each, temp_proxy, kNoSourcePosition));
1845 auto block = factory()->NewBlock(2, false);
1846 block->statements()->Add(
1847 factory()->NewExpressionStatement(assign_each, kNoSourcePosition),
1848 zone());
1849 block->statements()->Add(body, zone());
1850 body = block;
1851 each = factory()->NewVariableProxy(temp);
1852 }
1853 MarkExpressionAsAssigned(each);
1854 stmt->AsForInStatement()->Initialize(each, subject, body);
1855 }
1856 return stmt;
1857 }
1858
1859 // Special case for legacy for
1860 //
1861 // for (var x = initializer in enumerable) body
1862 //
1863 // An initialization block of the form
1864 //
1865 // {
1866 // x = initializer;
1867 // }
1868 //
1869 // is returned in this case. It has reserved space for two statements,
1870 // so that (later on during parsing), the equivalent of
1871 //
1872 // for (x in enumerable) body
1873 //
1874 // is added as a second statement to it.
RewriteForVarInLegacy(const ForInfo & for_info)1875 Block* Parser::RewriteForVarInLegacy(const ForInfo& for_info) {
1876 const DeclarationParsingResult::Declaration& decl =
1877 for_info.parsing_result.declarations[0];
1878 if (!IsLexicalVariableMode(for_info.parsing_result.descriptor.mode) &&
1879 decl.pattern->IsVariableProxy() && decl.initializer != nullptr) {
1880 ++use_counts_[v8::Isolate::kForInInitializer];
1881 const AstRawString* name = decl.pattern->AsVariableProxy()->raw_name();
1882 VariableProxy* single_var = NewUnresolved(name);
1883 Block* init_block = factory()->NewBlock(2, true);
1884 init_block->statements()->Add(
1885 factory()->NewExpressionStatement(
1886 factory()->NewAssignment(Token::ASSIGN, single_var,
1887 decl.initializer, kNoSourcePosition),
1888 kNoSourcePosition),
1889 zone());
1890 return init_block;
1891 }
1892 return nullptr;
1893 }
1894
1895 // Rewrite a for-in/of statement of the form
1896 //
1897 // for (let/const/var x in/of e) b
1898 //
1899 // into
1900 //
1901 // {
1902 // var temp;
1903 // for (temp in/of e) {
1904 // let/const/var x = temp;
1905 // b;
1906 // }
1907 // let x; // for TDZ
1908 // }
DesugarBindingInForEachStatement(ForInfo * for_info,Block ** body_block,Expression ** each_variable,bool * ok)1909 void Parser::DesugarBindingInForEachStatement(ForInfo* for_info,
1910 Block** body_block,
1911 Expression** each_variable,
1912 bool* ok) {
1913 DCHECK_EQ(1, for_info->parsing_result.declarations.size());
1914 DeclarationParsingResult::Declaration& decl =
1915 for_info->parsing_result.declarations[0];
1916 Variable* temp = NewTemporary(ast_value_factory()->dot_for_string());
1917 auto each_initialization_block = factory()->NewBlock(1, true);
1918 {
1919 auto descriptor = for_info->parsing_result.descriptor;
1920 descriptor.declaration_pos = kNoSourcePosition;
1921 descriptor.initialization_pos = kNoSourcePosition;
1922 descriptor.scope = scope();
1923 decl.initializer = factory()->NewVariableProxy(temp);
1924
1925 bool is_for_var_of =
1926 for_info->mode == ForEachStatement::ITERATE &&
1927 for_info->parsing_result.descriptor.mode == VariableMode::kVar;
1928 bool collect_names =
1929 IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) ||
1930 is_for_var_of;
1931
1932 DeclareAndInitializeVariables(
1933 each_initialization_block, &descriptor, &decl,
1934 collect_names ? &for_info->bound_names : nullptr, CHECK_OK_VOID);
1935
1936 // Annex B.3.5 prohibits the form
1937 // `try {} catch(e) { for (var e of {}); }`
1938 // So if we are parsing a statement like `for (var ... of ...)`
1939 // we need to walk up the scope chain and look for catch scopes
1940 // which have a simple binding, then compare their binding against
1941 // all of the names declared in the init of the for-of we're
1942 // parsing.
1943 if (is_for_var_of) {
1944 Scope* catch_scope = scope();
1945 while (catch_scope != nullptr && !catch_scope->is_declaration_scope()) {
1946 if (catch_scope->is_catch_scope()) {
1947 auto name = catch_scope->catch_variable()->raw_name();
1948 // If it's a simple binding and the name is declared in the for loop.
1949 if (name != ast_value_factory()->dot_catch_string() &&
1950 for_info->bound_names.Contains(name)) {
1951 ReportMessageAt(for_info->parsing_result.bindings_loc,
1952 MessageTemplate::kVarRedeclaration, name);
1953 *ok = false;
1954 return;
1955 }
1956 }
1957 catch_scope = catch_scope->outer_scope();
1958 }
1959 }
1960 }
1961
1962 *body_block = factory()->NewBlock(3, false);
1963 (*body_block)->statements()->Add(each_initialization_block, zone());
1964 *each_variable = factory()->NewVariableProxy(temp, for_info->position);
1965 }
1966
1967 // Create a TDZ for any lexically-bound names in for in/of statements.
CreateForEachStatementTDZ(Block * init_block,const ForInfo & for_info,bool * ok)1968 Block* Parser::CreateForEachStatementTDZ(Block* init_block,
1969 const ForInfo& for_info, bool* ok) {
1970 if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) {
1971 DCHECK_NULL(init_block);
1972
1973 init_block = factory()->NewBlock(1, false);
1974
1975 for (int i = 0; i < for_info.bound_names.length(); ++i) {
1976 // TODO(adamk): This needs to be some sort of special
1977 // INTERNAL variable that's invisible to the debugger
1978 // but visible to everything else.
1979 Declaration* tdz_decl =
1980 DeclareVariable(for_info.bound_names[i], VariableMode::kLet,
1981 kNoSourcePosition, CHECK_OK);
1982 tdz_decl->proxy()->var()->set_initializer_position(position());
1983 }
1984 }
1985 return init_block;
1986 }
1987
InitializeForOfStatement(ForOfStatement * for_of,Expression * each,Expression * iterable,Statement * body,bool finalize,IteratorType type,int next_result_pos)1988 Statement* Parser::InitializeForOfStatement(
1989 ForOfStatement* for_of, Expression* each, Expression* iterable,
1990 Statement* body, bool finalize, IteratorType type, int next_result_pos) {
1991 // Create the auxiliary expressions needed for iterating over the iterable,
1992 // and initialize the given ForOfStatement with them.
1993 // If finalize is true, also instrument the loop with code that performs the
1994 // proper ES6 iterator finalization. In that case, the result is not
1995 // immediately a ForOfStatement.
1996 const int nopos = kNoSourcePosition;
1997 auto avfactory = ast_value_factory();
1998
1999 Variable* iterator = NewTemporary(avfactory->dot_iterator_string());
2000 Variable* next = NewTemporary(avfactory->empty_string());
2001 Variable* result = NewTemporary(avfactory->dot_result_string());
2002 Variable* completion = NewTemporary(avfactory->empty_string());
2003
2004 // iterator = GetIterator(iterable, type)
2005 Expression* assign_iterator;
2006 {
2007 assign_iterator = factory()->NewAssignment(
2008 Token::ASSIGN, factory()->NewVariableProxy(iterator),
2009 factory()->NewGetIterator(iterable, type, iterable->position()),
2010 iterable->position());
2011 }
2012
2013 Expression* assign_next;
2014 {
2015 assign_next = factory()->NewAssignment(
2016 Token::ASSIGN, factory()->NewVariableProxy(next),
2017 factory()->NewProperty(factory()->NewVariableProxy(iterator),
2018 factory()->NewStringLiteral(
2019 avfactory->next_string(), kNoSourcePosition),
2020 kNoSourcePosition),
2021 kNoSourcePosition);
2022 }
2023
2024 // [if (IteratorType == kNormal)]
2025 // !%_IsJSReceiver(result = iterator.next()) &&
2026 // %ThrowIteratorResultNotAnObject(result)
2027 // [else if (IteratorType == kAsync)]
2028 // !%_IsJSReceiver(result = Await(iterator.next())) &&
2029 // %ThrowIteratorResultNotAnObject(result)
2030 // [endif]
2031 Expression* next_result;
2032 {
2033 VariableProxy* iterator_proxy = factory()->NewVariableProxy(iterator);
2034 VariableProxy* next_proxy = factory()->NewVariableProxy(next);
2035 next_result = BuildIteratorNextResult(iterator_proxy, next_proxy, result,
2036 type, next_result_pos);
2037 }
2038
2039 // result.done
2040 Expression* result_done;
2041 {
2042 Expression* done_literal = factory()->NewStringLiteral(
2043 ast_value_factory()->done_string(), kNoSourcePosition);
2044 Expression* result_proxy = factory()->NewVariableProxy(result);
2045 result_done =
2046 factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition);
2047 }
2048
2049 // result.value
2050 Expression* result_value;
2051 {
2052 Expression* value_literal =
2053 factory()->NewStringLiteral(avfactory->value_string(), nopos);
2054 Expression* result_proxy = factory()->NewVariableProxy(result);
2055 result_value = factory()->NewProperty(result_proxy, value_literal, nopos);
2056 }
2057
2058 // {{tmp = #result_value, completion = kAbruptCompletion, tmp}}
2059 // Expression* result_value (gets overwritten)
2060 if (finalize) {
2061 Variable* tmp = NewTemporary(avfactory->empty_string());
2062 Expression* save_result = factory()->NewAssignment(
2063 Token::ASSIGN, factory()->NewVariableProxy(tmp), result_value, nopos);
2064
2065 Expression* set_completion_abrupt = factory()->NewAssignment(
2066 Token::ASSIGN, factory()->NewVariableProxy(completion),
2067 factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
2068
2069 result_value = factory()->NewBinaryOperation(Token::COMMA, save_result,
2070 set_completion_abrupt, nopos);
2071 result_value = factory()->NewBinaryOperation(
2072 Token::COMMA, result_value, factory()->NewVariableProxy(tmp), nopos);
2073 }
2074
2075 // each = #result_value;
2076 Expression* assign_each;
2077 {
2078 assign_each =
2079 factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos);
2080 if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
2081 assign_each = RewriteDestructuringAssignment(assign_each->AsAssignment());
2082 }
2083 }
2084
2085 // {{completion = kNormalCompletion;}}
2086 Statement* set_completion_normal;
2087 if (finalize) {
2088 Expression* proxy = factory()->NewVariableProxy(completion);
2089 Expression* assignment = factory()->NewAssignment(
2090 Token::ASSIGN, proxy,
2091 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
2092
2093 set_completion_normal =
2094 IgnoreCompletion(factory()->NewExpressionStatement(assignment, nopos));
2095 }
2096
2097 // { #loop-body; #set_completion_normal }
2098 // Statement* body (gets overwritten)
2099 if (finalize) {
2100 Block* block = factory()->NewBlock(2, false);
2101 block->statements()->Add(body, zone());
2102 block->statements()->Add(set_completion_normal, zone());
2103 body = block;
2104 }
2105
2106 for_of->Initialize(body, iterator, assign_iterator, assign_next, next_result,
2107 result_done, assign_each);
2108 return finalize ? FinalizeForOfStatement(for_of, completion, type, nopos)
2109 : for_of;
2110 }
2111
DesugarLexicalBindingsInForStatement(ForStatement * loop,Statement * init,Expression * cond,Statement * next,Statement * body,Scope * inner_scope,const ForInfo & for_info,bool * ok)2112 Statement* Parser::DesugarLexicalBindingsInForStatement(
2113 ForStatement* loop, Statement* init, Expression* cond, Statement* next,
2114 Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) {
2115 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are
2116 // copied into a new environment. Moreover, the "next" statement must be
2117 // evaluated not in the environment of the just completed iteration but in
2118 // that of the upcoming one. We achieve this with the following desugaring.
2119 // Extra care is needed to preserve the completion value of the original loop.
2120 //
2121 // We are given a for statement of the form
2122 //
2123 // labels: for (let/const x = i; cond; next) body
2124 //
2125 // and rewrite it as follows. Here we write {{ ... }} for init-blocks, ie.,
2126 // blocks whose ignore_completion_value_ flag is set.
2127 //
2128 // {
2129 // let/const x = i;
2130 // temp_x = x;
2131 // first = 1;
2132 // undefined;
2133 // outer: for (;;) {
2134 // let/const x = temp_x;
2135 // {{ if (first == 1) {
2136 // first = 0;
2137 // } else {
2138 // next;
2139 // }
2140 // flag = 1;
2141 // if (!cond) break;
2142 // }}
2143 // labels: for (; flag == 1; flag = 0, temp_x = x) {
2144 // body
2145 // }
2146 // {{ if (flag == 1) // Body used break.
2147 // break;
2148 // }}
2149 // }
2150 // }
2151
2152 DCHECK_GT(for_info.bound_names.length(), 0);
2153 ZonePtrList<Variable> temps(for_info.bound_names.length(), zone());
2154
2155 Block* outer_block =
2156 factory()->NewBlock(for_info.bound_names.length() + 4, false);
2157
2158 // Add statement: let/const x = i.
2159 outer_block->statements()->Add(init, zone());
2160
2161 const AstRawString* temp_name = ast_value_factory()->dot_for_string();
2162
2163 // For each lexical variable x:
2164 // make statement: temp_x = x.
2165 for (int i = 0; i < for_info.bound_names.length(); i++) {
2166 VariableProxy* proxy = NewUnresolved(for_info.bound_names[i]);
2167 Variable* temp = NewTemporary(temp_name);
2168 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
2169 Assignment* assignment = factory()->NewAssignment(Token::ASSIGN, temp_proxy,
2170 proxy, kNoSourcePosition);
2171 Statement* assignment_statement =
2172 factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2173 outer_block->statements()->Add(assignment_statement, zone());
2174 temps.Add(temp, zone());
2175 }
2176
2177 Variable* first = nullptr;
2178 // Make statement: first = 1.
2179 if (next) {
2180 first = NewTemporary(temp_name);
2181 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2182 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2183 Assignment* assignment = factory()->NewAssignment(
2184 Token::ASSIGN, first_proxy, const1, kNoSourcePosition);
2185 Statement* assignment_statement =
2186 factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2187 outer_block->statements()->Add(assignment_statement, zone());
2188 }
2189
2190 // make statement: undefined;
2191 outer_block->statements()->Add(
2192 factory()->NewExpressionStatement(
2193 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
2194 zone());
2195
2196 // Make statement: outer: for (;;)
2197 // Note that we don't actually create the label, or set this loop up as an
2198 // explicit break target, instead handing it directly to those nodes that
2199 // need to know about it. This should be safe because we don't run any code
2200 // in this function that looks up break targets.
2201 ForStatement* outer_loop =
2202 factory()->NewForStatement(nullptr, nullptr, kNoSourcePosition);
2203 outer_block->statements()->Add(outer_loop, zone());
2204 outer_block->set_scope(scope());
2205
2206 Block* inner_block = factory()->NewBlock(3, false);
2207 {
2208 BlockState block_state(&scope_, inner_scope);
2209
2210 Block* ignore_completion_block =
2211 factory()->NewBlock(for_info.bound_names.length() + 3, true);
2212 ZonePtrList<Variable> inner_vars(for_info.bound_names.length(), zone());
2213 // For each let variable x:
2214 // make statement: let/const x = temp_x.
2215 for (int i = 0; i < for_info.bound_names.length(); i++) {
2216 Declaration* decl = DeclareVariable(
2217 for_info.bound_names[i], for_info.parsing_result.descriptor.mode,
2218 kNoSourcePosition, CHECK_OK);
2219 inner_vars.Add(decl->proxy()->var(), zone());
2220 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
2221 Assignment* assignment = factory()->NewAssignment(
2222 Token::INIT, decl->proxy(), temp_proxy, kNoSourcePosition);
2223 Statement* assignment_statement =
2224 factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2225 int declaration_pos = for_info.parsing_result.descriptor.declaration_pos;
2226 DCHECK_NE(declaration_pos, kNoSourcePosition);
2227 decl->proxy()->var()->set_initializer_position(declaration_pos);
2228 ignore_completion_block->statements()->Add(assignment_statement, zone());
2229 }
2230
2231 // Make statement: if (first == 1) { first = 0; } else { next; }
2232 if (next) {
2233 DCHECK(first);
2234 Expression* compare = nullptr;
2235 // Make compare expression: first == 1.
2236 {
2237 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2238 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2239 compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1,
2240 kNoSourcePosition);
2241 }
2242 Statement* clear_first = nullptr;
2243 // Make statement: first = 0.
2244 {
2245 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2246 Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
2247 Assignment* assignment = factory()->NewAssignment(
2248 Token::ASSIGN, first_proxy, const0, kNoSourcePosition);
2249 clear_first =
2250 factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2251 }
2252 Statement* clear_first_or_next = factory()->NewIfStatement(
2253 compare, clear_first, next, kNoSourcePosition);
2254 ignore_completion_block->statements()->Add(clear_first_or_next, zone());
2255 }
2256
2257 Variable* flag = NewTemporary(temp_name);
2258 // Make statement: flag = 1.
2259 {
2260 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2261 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2262 Assignment* assignment = factory()->NewAssignment(
2263 Token::ASSIGN, flag_proxy, const1, kNoSourcePosition);
2264 Statement* assignment_statement =
2265 factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2266 ignore_completion_block->statements()->Add(assignment_statement, zone());
2267 }
2268
2269 // Make statement: if (!cond) break.
2270 if (cond) {
2271 Statement* stop =
2272 factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
2273 Statement* noop = factory()->NewEmptyStatement(kNoSourcePosition);
2274 ignore_completion_block->statements()->Add(
2275 factory()->NewIfStatement(cond, noop, stop, cond->position()),
2276 zone());
2277 }
2278
2279 inner_block->statements()->Add(ignore_completion_block, zone());
2280 // Make cond expression for main loop: flag == 1.
2281 Expression* flag_cond = nullptr;
2282 {
2283 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2284 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2285 flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
2286 kNoSourcePosition);
2287 }
2288
2289 // Create chain of expressions "flag = 0, temp_x = x, ..."
2290 Statement* compound_next_statement = nullptr;
2291 {
2292 Expression* compound_next = nullptr;
2293 // Make expression: flag = 0.
2294 {
2295 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2296 Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
2297 compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy,
2298 const0, kNoSourcePosition);
2299 }
2300
2301 // Make the comma-separated list of temp_x = x assignments.
2302 int inner_var_proxy_pos = scanner()->location().beg_pos;
2303 for (int i = 0; i < for_info.bound_names.length(); i++) {
2304 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
2305 VariableProxy* proxy =
2306 factory()->NewVariableProxy(inner_vars.at(i), inner_var_proxy_pos);
2307 Assignment* assignment = factory()->NewAssignment(
2308 Token::ASSIGN, temp_proxy, proxy, kNoSourcePosition);
2309 compound_next = factory()->NewBinaryOperation(
2310 Token::COMMA, compound_next, assignment, kNoSourcePosition);
2311 }
2312
2313 compound_next_statement =
2314 factory()->NewExpressionStatement(compound_next, kNoSourcePosition);
2315 }
2316
2317 // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
2318 // Note that we re-use the original loop node, which retains its labels
2319 // and ensures that any break or continue statements in body point to
2320 // the right place.
2321 loop->Initialize(nullptr, flag_cond, compound_next_statement, body);
2322 inner_block->statements()->Add(loop, zone());
2323
2324 // Make statement: {{if (flag == 1) break;}}
2325 {
2326 Expression* compare = nullptr;
2327 // Make compare expresion: flag == 1.
2328 {
2329 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2330 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2331 compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
2332 kNoSourcePosition);
2333 }
2334 Statement* stop =
2335 factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
2336 Statement* empty = factory()->NewEmptyStatement(kNoSourcePosition);
2337 Statement* if_flag_break =
2338 factory()->NewIfStatement(compare, stop, empty, kNoSourcePosition);
2339 inner_block->statements()->Add(IgnoreCompletion(if_flag_break), zone());
2340 }
2341
2342 inner_block->set_scope(inner_scope);
2343 }
2344
2345 outer_loop->Initialize(nullptr, nullptr, nullptr, inner_block);
2346
2347 return outer_block;
2348 }
2349
AddArrowFunctionFormalParameters(ParserFormalParameters * parameters,Expression * expr,int end_pos,bool * ok)2350 void Parser::AddArrowFunctionFormalParameters(
2351 ParserFormalParameters* parameters, Expression* expr, int end_pos,
2352 bool* ok) {
2353 // ArrowFunctionFormals ::
2354 // Nary(Token::COMMA, VariableProxy*, Tail)
2355 // Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail)
2356 // Tail
2357 // NonTailArrowFunctionFormals ::
2358 // Binary(Token::COMMA, NonTailArrowFunctionFormals, VariableProxy)
2359 // VariableProxy
2360 // Tail ::
2361 // VariableProxy
2362 // Spread(VariableProxy)
2363 //
2364 // We need to visit the parameters in left-to-right order
2365 //
2366
2367 // For the Nary case, we simply visit the parameters in a loop.
2368 if (expr->IsNaryOperation()) {
2369 NaryOperation* nary = expr->AsNaryOperation();
2370 // The classifier has already run, so we know that the expression is a valid
2371 // arrow function formals production.
2372 DCHECK_EQ(nary->op(), Token::COMMA);
2373 // Each op position is the end position of the *previous* expr, with the
2374 // second (i.e. first "subsequent") op position being the end position of
2375 // the first child expression.
2376 Expression* next = nary->first();
2377 for (size_t i = 0; i < nary->subsequent_length(); ++i) {
2378 AddArrowFunctionFormalParameters(
2379 parameters, next, nary->subsequent_op_position(i), CHECK_OK_VOID);
2380 next = nary->subsequent(i);
2381 }
2382 AddArrowFunctionFormalParameters(parameters, next, end_pos, CHECK_OK_VOID);
2383 return;
2384 }
2385
2386 // For the binary case, we recurse on the left-hand side of binary comma
2387 // expressions.
2388 if (expr->IsBinaryOperation()) {
2389 BinaryOperation* binop = expr->AsBinaryOperation();
2390 // The classifier has already run, so we know that the expression is a valid
2391 // arrow function formals production.
2392 DCHECK_EQ(binop->op(), Token::COMMA);
2393 Expression* left = binop->left();
2394 Expression* right = binop->right();
2395 int comma_pos = binop->position();
2396 AddArrowFunctionFormalParameters(parameters, left, comma_pos,
2397 CHECK_OK_VOID);
2398 // LHS of comma expression should be unparenthesized.
2399 expr = right;
2400 }
2401
2402 // Only the right-most expression may be a rest parameter.
2403 DCHECK(!parameters->has_rest);
2404
2405 bool is_rest = expr->IsSpread();
2406 if (is_rest) {
2407 expr = expr->AsSpread()->expression();
2408 parameters->has_rest = true;
2409 }
2410 DCHECK_IMPLIES(parameters->is_simple, !is_rest);
2411 DCHECK_IMPLIES(parameters->is_simple, expr->IsVariableProxy());
2412
2413 Expression* initializer = nullptr;
2414 if (expr->IsAssignment()) {
2415 if (expr->IsRewritableExpression()) {
2416 // This expression was parsed as a possible destructuring assignment.
2417 // Mark it as already-rewritten to avoid an unnecessary visit later.
2418 expr->AsRewritableExpression()->set_rewritten();
2419 }
2420 Assignment* assignment = expr->AsAssignment();
2421 DCHECK(!assignment->IsCompoundAssignment());
2422 initializer = assignment->value();
2423 expr = assignment->target();
2424 }
2425
2426 AddFormalParameter(parameters, expr, initializer,
2427 end_pos, is_rest);
2428 }
2429
DeclareArrowFunctionFormalParameters(ParserFormalParameters * parameters,Expression * expr,const Scanner::Location & params_loc,Scanner::Location * duplicate_loc,bool * ok)2430 void Parser::DeclareArrowFunctionFormalParameters(
2431 ParserFormalParameters* parameters, Expression* expr,
2432 const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
2433 bool* ok) {
2434 if (expr->IsEmptyParentheses()) return;
2435
2436 AddArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos,
2437 CHECK_OK_VOID);
2438
2439 if (parameters->arity > Code::kMaxArguments) {
2440 ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
2441 *ok = false;
2442 return;
2443 }
2444
2445 bool has_duplicate = false;
2446 DeclareFormalParameters(parameters->scope, parameters->params,
2447 parameters->is_simple, &has_duplicate);
2448 if (has_duplicate) {
2449 *duplicate_loc = scanner()->location();
2450 }
2451 DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters());
2452 }
2453
PrepareGeneratorVariables()2454 void Parser::PrepareGeneratorVariables() {
2455 // Calling a generator returns a generator object. That object is stored
2456 // in a temporary variable, a definition that is used by "yield"
2457 // expressions.
2458 function_state_->scope()->DeclareGeneratorObjectVar(
2459 ast_value_factory()->dot_generator_object_string());
2460 }
2461
ParseFunctionLiteral(const AstRawString * function_name,Scanner::Location function_name_location,FunctionNameValidity function_name_validity,FunctionKind kind,int function_token_pos,FunctionLiteral::FunctionType function_type,LanguageMode language_mode,ZonePtrList<const AstRawString> * arguments_for_wrapped_function,bool * ok)2462 FunctionLiteral* Parser::ParseFunctionLiteral(
2463 const AstRawString* function_name, Scanner::Location function_name_location,
2464 FunctionNameValidity function_name_validity, FunctionKind kind,
2465 int function_token_pos, FunctionLiteral::FunctionType function_type,
2466 LanguageMode language_mode,
2467 ZonePtrList<const AstRawString>* arguments_for_wrapped_function, bool* ok) {
2468 // Function ::
2469 // '(' FormalParameterList? ')' '{' FunctionBody '}'
2470 //
2471 // Getter ::
2472 // '(' ')' '{' FunctionBody '}'
2473 //
2474 // Setter ::
2475 // '(' PropertySetParameterList ')' '{' FunctionBody '}'
2476
2477 bool is_wrapped = function_type == FunctionLiteral::kWrapped;
2478 DCHECK_EQ(is_wrapped, arguments_for_wrapped_function != nullptr);
2479
2480 int pos = function_token_pos == kNoSourcePosition ? peek_position()
2481 : function_token_pos;
2482 DCHECK_NE(kNoSourcePosition, pos);
2483
2484 // Anonymous functions were passed either the empty symbol or a null
2485 // handle as the function name. Remember if we were passed a non-empty
2486 // handle to decide whether to invoke function name inference.
2487 bool should_infer_name = function_name == nullptr;
2488
2489 // We want a non-null handle as the function name by default. We will handle
2490 // the "function does not have a shared name" case later.
2491 if (should_infer_name) {
2492 function_name = ast_value_factory()->empty_string();
2493 }
2494
2495 FunctionLiteral::EagerCompileHint eager_compile_hint =
2496 function_state_->next_function_is_likely_called() || is_wrapped
2497 ? FunctionLiteral::kShouldEagerCompile
2498 : default_eager_compile_hint();
2499
2500 // Determine if the function can be parsed lazily. Lazy parsing is
2501 // different from lazy compilation; we need to parse more eagerly than we
2502 // compile.
2503
2504 // We can only parse lazily if we also compile lazily. The heuristics for lazy
2505 // compilation are:
2506 // - It must not have been prohibited by the caller to Parse (some callers
2507 // need a full AST).
2508 // - The outer scope must allow lazy compilation of inner functions.
2509 // - The function mustn't be a function expression with an open parenthesis
2510 // before; we consider that a hint that the function will be called
2511 // immediately, and it would be a waste of time to make it lazily
2512 // compiled.
2513 // These are all things we can know at this point, without looking at the
2514 // function itself.
2515
2516 // We separate between lazy parsing top level functions and lazy parsing inner
2517 // functions, because the latter needs to do more work. In particular, we need
2518 // to track unresolved variables to distinguish between these cases:
2519 // (function foo() {
2520 // bar = function() { return 1; }
2521 // })();
2522 // and
2523 // (function foo() {
2524 // var a = 1;
2525 // bar = function() { return a; }
2526 // })();
2527
2528 // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
2529 // parenthesis before the function means that it will be called
2530 // immediately). bar can be parsed lazily, but we need to parse it in a mode
2531 // that tracks unresolved variables.
2532 DCHECK_IMPLIES(parse_lazily(), FLAG_lazy);
2533 DCHECK_IMPLIES(parse_lazily(), allow_lazy_);
2534 DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr);
2535
2536 const bool is_lazy =
2537 eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
2538 const bool is_top_level = AllowsLazyParsingWithoutUnresolvedVariables();
2539 const bool is_lazy_top_level_function = is_lazy && is_top_level;
2540 const bool is_lazy_inner_function = is_lazy && !is_top_level;
2541 const bool is_expression =
2542 function_type == FunctionLiteral::kAnonymousExpression ||
2543 function_type == FunctionLiteral::kNamedExpression;
2544
2545 RuntimeCallTimerScope runtime_timer(
2546 runtime_call_stats_,
2547 parsing_on_main_thread_
2548 ? RuntimeCallCounterId::kParseFunctionLiteral
2549 : RuntimeCallCounterId::kParseBackgroundFunctionLiteral);
2550 base::ElapsedTimer timer;
2551 if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
2552
2553 // Determine whether we can still lazy parse the inner function.
2554 // The preconditions are:
2555 // - Lazy compilation has to be enabled.
2556 // - Neither V8 natives nor native function declarations can be allowed,
2557 // since parsing one would retroactively force the function to be
2558 // eagerly compiled.
2559 // - The invoker of this parser can't depend on the AST being eagerly
2560 // built (either because the function is about to be compiled, or
2561 // because the AST is going to be inspected for some reason).
2562 // - Because of the above, we can't be attempting to parse a
2563 // FunctionExpression; even without enclosing parentheses it might be
2564 // immediately invoked.
2565 // - The function literal shouldn't be hinted to eagerly compile.
2566
2567 // Inner functions will be parsed using a temporary Zone. After parsing, we
2568 // will migrate unresolved variable into a Scope in the main Zone.
2569
2570 const bool should_preparse_inner =
2571 parse_lazily() && FLAG_lazy_inner_functions && is_lazy_inner_function &&
2572 (!is_expression || FLAG_aggressive_lazy_inner_functions);
2573
2574 // This may be modified later to reflect preparsing decision taken
2575 bool should_preparse =
2576 (parse_lazily() && is_lazy_top_level_function) || should_preparse_inner;
2577
2578 ZonePtrList<Statement>* body = nullptr;
2579 int expected_property_count = -1;
2580 int suspend_count = -1;
2581 int num_parameters = -1;
2582 int function_length = -1;
2583 bool has_duplicate_parameters = false;
2584 int function_literal_id = GetNextFunctionLiteralId();
2585 ProducedPreParsedScopeData* produced_preparsed_scope_data = nullptr;
2586
2587 Zone* outer_zone = zone();
2588 DeclarationScope* scope;
2589
2590 {
2591 // Temporary zones can nest. When we migrate free variables (see below), we
2592 // need to recreate them in the previous Zone.
2593 AstNodeFactory previous_zone_ast_node_factory(ast_value_factory(), zone());
2594
2595 // Open a new zone scope, which sets our AstNodeFactory to allocate in the
2596 // new temporary zone if the preconditions are satisfied, and ensures that
2597 // the previous zone is always restored after parsing the body. To be able
2598 // to do scope analysis correctly after full parsing, we migrate needed
2599 // information when the function is parsed.
2600 Zone temp_zone(zone()->allocator(), ZONE_NAME);
2601 DiscardableZoneScope zone_scope(this, &temp_zone, should_preparse);
2602
2603 // This Scope lives in the main zone. We'll migrate data into that zone
2604 // later.
2605 scope = NewFunctionScope(kind, outer_zone);
2606 SetLanguageMode(scope, language_mode);
2607 #ifdef DEBUG
2608 scope->SetScopeName(function_name);
2609 if (should_preparse) scope->set_needs_migration();
2610 #endif
2611
2612 if (!is_wrapped) Expect(Token::LPAREN, CHECK_OK);
2613 scope->set_start_position(scanner()->location().beg_pos);
2614
2615 // Eager or lazy parse? If is_lazy_top_level_function, we'll parse
2616 // lazily. We'll call SkipFunction, which may decide to
2617 // abort lazy parsing if it suspects that wasn't a good idea. If so (in
2618 // which case the parser is expected to have backtracked), or if we didn't
2619 // try to lazy parse in the first place, we'll have to parse eagerly.
2620 if (should_preparse) {
2621 DCHECK(parse_lazily());
2622 DCHECK(is_lazy_top_level_function || is_lazy_inner_function);
2623 DCHECK(!is_wrapped);
2624 Scanner::BookmarkScope bookmark(scanner());
2625 bookmark.Set();
2626 LazyParsingResult result = SkipFunction(
2627 function_name, kind, function_type, scope, &num_parameters,
2628 &produced_preparsed_scope_data, is_lazy_inner_function,
2629 is_lazy_top_level_function, CHECK_OK);
2630
2631 if (result == kLazyParsingAborted) {
2632 DCHECK(is_lazy_top_level_function);
2633 bookmark.Apply();
2634 // This is probably an initialization function. Inform the compiler it
2635 // should also eager-compile this function.
2636 eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
2637 scope->ResetAfterPreparsing(ast_value_factory(), true);
2638 zone_scope.Reset();
2639 // Trigger eager (re-)parsing, just below this block.
2640 should_preparse = false;
2641 }
2642 }
2643
2644 if (should_preparse) {
2645 scope->AnalyzePartially(&previous_zone_ast_node_factory);
2646 } else {
2647 body = ParseFunction(
2648 function_name, pos, kind, function_type, scope, &num_parameters,
2649 &function_length, &has_duplicate_parameters, &expected_property_count,
2650 &suspend_count, arguments_for_wrapped_function, CHECK_OK);
2651 }
2652
2653 DCHECK_EQ(should_preparse, temp_zoned_);
2654 if (V8_UNLIKELY(FLAG_log_function_events)) {
2655 double ms = timer.Elapsed().InMillisecondsF();
2656 const char* event_name = should_preparse
2657 ? (is_top_level ? "preparse-no-resolution"
2658 : "preparse-resolution")
2659 : "full-parse";
2660 logger_->FunctionEvent(
2661 event_name, script_id(), ms, scope->start_position(),
2662 scope->end_position(),
2663 reinterpret_cast<const char*>(function_name->raw_data()),
2664 function_name->byte_length());
2665 }
2666 if (V8_UNLIKELY(FLAG_runtime_stats)) {
2667 if (should_preparse) {
2668 RuntimeCallCounterId counter_id =
2669 parsing_on_main_thread_
2670 ? RuntimeCallCounterId::kPreParseWithVariableResolution
2671 : RuntimeCallCounterId::
2672 kPreParseBackgroundWithVariableResolution;
2673 if (is_top_level) {
2674 counter_id = parsing_on_main_thread_
2675 ? RuntimeCallCounterId::kPreParseNoVariableResolution
2676 : RuntimeCallCounterId::
2677 kPreParseBackgroundNoVariableResolution;
2678 }
2679 if (runtime_call_stats_) {
2680 runtime_call_stats_->CorrectCurrentCounterId(counter_id);
2681 }
2682 }
2683 }
2684
2685 // Validate function name. We can do this only after parsing the function,
2686 // since the function can declare itself strict.
2687 language_mode = scope->language_mode();
2688 CheckFunctionName(language_mode, function_name, function_name_validity,
2689 function_name_location, CHECK_OK);
2690
2691 if (is_strict(language_mode)) {
2692 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
2693 CHECK_OK);
2694 }
2695 CheckConflictingVarDeclarations(scope, CHECK_OK);
2696 } // DiscardableZoneScope goes out of scope.
2697
2698 FunctionLiteral::ParameterFlag duplicate_parameters =
2699 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
2700 : FunctionLiteral::kNoDuplicateParameters;
2701
2702 // Note that the FunctionLiteral needs to be created in the main Zone again.
2703 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
2704 function_name, scope, body, expected_property_count, num_parameters,
2705 function_length, duplicate_parameters, function_type, eager_compile_hint,
2706 pos, true, function_literal_id, produced_preparsed_scope_data);
2707 function_literal->set_function_token_position(function_token_pos);
2708 function_literal->set_suspend_count(suspend_count);
2709
2710 if (should_infer_name) {
2711 DCHECK_NOT_NULL(fni_);
2712 fni_->AddFunction(function_literal);
2713 }
2714 return function_literal;
2715 }
2716
SkipFunction(const AstRawString * function_name,FunctionKind kind,FunctionLiteral::FunctionType function_type,DeclarationScope * function_scope,int * num_parameters,ProducedPreParsedScopeData ** produced_preparsed_scope_data,bool is_inner_function,bool may_abort,bool * ok)2717 Parser::LazyParsingResult Parser::SkipFunction(
2718 const AstRawString* function_name, FunctionKind kind,
2719 FunctionLiteral::FunctionType function_type,
2720 DeclarationScope* function_scope, int* num_parameters,
2721 ProducedPreParsedScopeData** produced_preparsed_scope_data,
2722 bool is_inner_function, bool may_abort, bool* ok) {
2723 FunctionState function_state(&function_state_, &scope_, function_scope);
2724
2725 DCHECK_NE(kNoSourcePosition, function_scope->start_position());
2726 DCHECK_EQ(kNoSourcePosition, parameters_end_pos_);
2727
2728 DCHECK_IMPLIES(IsArrowFunction(kind),
2729 scanner()->current_token() == Token::ARROW);
2730
2731 // FIXME(marja): There are 2 ways to skip functions now. Unify them.
2732 DCHECK_NOT_NULL(consumed_preparsed_scope_data_);
2733 if (consumed_preparsed_scope_data_->HasData()) {
2734 DCHECK(FLAG_preparser_scope_analysis);
2735 int end_position;
2736 LanguageMode language_mode;
2737 int num_inner_functions;
2738 bool uses_super_property;
2739 *produced_preparsed_scope_data =
2740 consumed_preparsed_scope_data_->GetDataForSkippableFunction(
2741 main_zone(), function_scope->start_position(), &end_position,
2742 num_parameters, &num_inner_functions, &uses_super_property,
2743 &language_mode);
2744
2745 function_scope->outer_scope()->SetMustUsePreParsedScopeData();
2746 function_scope->set_is_skipped_function(true);
2747 function_scope->set_end_position(end_position);
2748 scanner()->SeekForward(end_position - 1);
2749 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
2750 SetLanguageMode(function_scope, language_mode);
2751 if (uses_super_property) {
2752 function_scope->RecordSuperPropertyUsage();
2753 }
2754 SkipFunctionLiterals(num_inner_functions);
2755 return kLazyParsingComplete;
2756 }
2757
2758 // With no cached data, we partially parse the function, without building an
2759 // AST. This gathers the data needed to build a lazy function.
2760 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse");
2761
2762 // Aborting inner function preparsing would leave scopes in an inconsistent
2763 // state; we don't parse inner functions in the abortable mode anyway.
2764 DCHECK(!is_inner_function || !may_abort);
2765
2766 PreParser::PreParseResult result = reusable_preparser()->PreParseFunction(
2767 function_name, kind, function_type, function_scope, is_inner_function,
2768 may_abort, use_counts_, produced_preparsed_scope_data, this->script_id());
2769
2770 // Return immediately if pre-parser decided to abort parsing.
2771 if (result == PreParser::kPreParseAbort) return kLazyParsingAborted;
2772 if (result == PreParser::kPreParseStackOverflow) {
2773 // Propagate stack overflow.
2774 set_stack_overflow();
2775 *ok = false;
2776 return kLazyParsingComplete;
2777 }
2778 if (pending_error_handler()->has_pending_error()) {
2779 *ok = false;
2780 return kLazyParsingComplete;
2781 }
2782
2783 set_allow_eval_cache(reusable_preparser()->allow_eval_cache());
2784
2785 PreParserLogger* logger = reusable_preparser()->logger();
2786 function_scope->set_end_position(logger->end());
2787 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
2788 total_preparse_skipped_ +=
2789 function_scope->end_position() - function_scope->start_position();
2790 *num_parameters = logger->num_parameters();
2791 SkipFunctionLiterals(logger->num_inner_functions());
2792 return kLazyParsingComplete;
2793 }
2794
BuildAssertIsCoercible(Variable * var,ObjectLiteral * pattern)2795 Statement* Parser::BuildAssertIsCoercible(Variable* var,
2796 ObjectLiteral* pattern) {
2797 // if (var === null || var === undefined)
2798 // throw /* type error kNonCoercible) */;
2799 auto source_position = pattern->position();
2800 const AstRawString* property = ast_value_factory()->empty_string();
2801 MessageTemplate::Template msg = MessageTemplate::kNonCoercible;
2802 for (ObjectLiteralProperty* literal_property : *pattern->properties()) {
2803 Expression* key = literal_property->key();
2804 if (key->IsPropertyName()) {
2805 property = key->AsLiteral()->AsRawPropertyName();
2806 msg = MessageTemplate::kNonCoercibleWithProperty;
2807 source_position = key->position();
2808 break;
2809 }
2810 }
2811
2812 Expression* condition = factory()->NewBinaryOperation(
2813 Token::OR,
2814 factory()->NewCompareOperation(
2815 Token::EQ_STRICT, factory()->NewVariableProxy(var),
2816 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
2817 factory()->NewCompareOperation(
2818 Token::EQ_STRICT, factory()->NewVariableProxy(var),
2819 factory()->NewNullLiteral(kNoSourcePosition), kNoSourcePosition),
2820 kNoSourcePosition);
2821 Expression* throw_type_error =
2822 NewThrowTypeError(msg, property, source_position);
2823 IfStatement* if_statement = factory()->NewIfStatement(
2824 condition,
2825 factory()->NewExpressionStatement(throw_type_error, kNoSourcePosition),
2826 factory()->NewEmptyStatement(kNoSourcePosition), kNoSourcePosition);
2827 return if_statement;
2828 }
2829
2830 class InitializerRewriter final
2831 : public AstTraversalVisitor<InitializerRewriter> {
2832 public:
InitializerRewriter(uintptr_t stack_limit,Expression * root,Parser * parser)2833 InitializerRewriter(uintptr_t stack_limit, Expression* root, Parser* parser)
2834 : AstTraversalVisitor(stack_limit, root), parser_(parser) {}
2835
2836 private:
2837 // This is required so that the overriden Visit* methods can be
2838 // called by the base class (template).
2839 friend class AstTraversalVisitor<InitializerRewriter>;
2840
2841 // Just rewrite destructuring assignments wrapped in RewritableExpressions.
VisitRewritableExpression(RewritableExpression * to_rewrite)2842 void VisitRewritableExpression(RewritableExpression* to_rewrite) {
2843 if (to_rewrite->is_rewritten()) return;
2844 parser_->RewriteDestructuringAssignment(to_rewrite);
2845 AstTraversalVisitor::VisitRewritableExpression(to_rewrite);
2846 }
2847
2848 // Code in function literals does not need to be eagerly rewritten, it will be
2849 // rewritten when scheduled.
VisitFunctionLiteral(FunctionLiteral * expr)2850 void VisitFunctionLiteral(FunctionLiteral* expr) {}
2851
2852 Parser* parser_;
2853 };
2854
RewriteParameterInitializer(Expression * expr)2855 void Parser::RewriteParameterInitializer(Expression* expr) {
2856 InitializerRewriter rewriter(stack_limit_, expr, this);
2857 rewriter.Run();
2858 }
2859
2860
BuildParameterInitializationBlock(const ParserFormalParameters & parameters,bool * ok)2861 Block* Parser::BuildParameterInitializationBlock(
2862 const ParserFormalParameters& parameters, bool* ok) {
2863 DCHECK(!parameters.is_simple);
2864 DCHECK(scope()->is_function_scope());
2865 DCHECK_EQ(scope(), parameters.scope);
2866 Block* init_block = factory()->NewBlock(1, true);
2867 int index = 0;
2868 for (auto parameter : parameters.params) {
2869 DeclarationDescriptor descriptor;
2870 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER;
2871 descriptor.scope = scope();
2872 descriptor.mode = VariableMode::kLet;
2873 descriptor.declaration_pos = parameter->pattern->position();
2874 // The position that will be used by the AssignmentExpression
2875 // which copies from the temp parameter to the pattern.
2876 //
2877 // TODO(adamk): Should this be kNoSourcePosition, since
2878 // it's just copying from a temp var to the real param var?
2879 descriptor.initialization_pos = parameter->pattern->position();
2880 Expression* initial_value =
2881 factory()->NewVariableProxy(parameters.scope->parameter(index));
2882 if (parameter->initializer != nullptr) {
2883 // IS_UNDEFINED($param) ? initializer : $param
2884
2885 // Ensure initializer is rewritten
2886 RewriteParameterInitializer(parameter->initializer);
2887
2888 auto condition = factory()->NewCompareOperation(
2889 Token::EQ_STRICT,
2890 factory()->NewVariableProxy(parameters.scope->parameter(index)),
2891 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
2892 initial_value = factory()->NewConditional(
2893 condition, parameter->initializer, initial_value, kNoSourcePosition);
2894 descriptor.initialization_pos = parameter->initializer->position();
2895 }
2896
2897 Scope* param_scope = scope();
2898 Block* param_block = init_block;
2899 if (!parameter->is_simple() &&
2900 scope()->AsDeclarationScope()->calls_sloppy_eval()) {
2901 param_scope = NewVarblockScope();
2902 param_scope->set_start_position(descriptor.initialization_pos);
2903 param_scope->set_end_position(parameter->initializer_end_position);
2904 param_scope->RecordEvalCall();
2905 param_block = factory()->NewBlock(8, true);
2906 param_block->set_scope(param_scope);
2907 // Pass the appropriate scope in so that PatternRewriter can appropriately
2908 // rewrite inner initializers of the pattern to param_scope
2909 descriptor.scope = param_scope;
2910 // Rewrite the outer initializer to point to param_scope
2911 ReparentExpressionScope(stack_limit(), initial_value, param_scope);
2912 }
2913
2914 BlockState block_state(&scope_, param_scope);
2915 DeclarationParsingResult::Declaration decl(
2916 parameter->pattern, parameter->initializer_end_position, initial_value);
2917 DeclareAndInitializeVariables(param_block, &descriptor, &decl, nullptr,
2918 CHECK_OK);
2919
2920 if (param_block != init_block) {
2921 param_scope = param_scope->FinalizeBlockScope();
2922 if (param_scope != nullptr) {
2923 CheckConflictingVarDeclarations(param_scope, CHECK_OK);
2924 }
2925 init_block->statements()->Add(param_block, zone());
2926 }
2927 ++index;
2928 }
2929 return init_block;
2930 }
2931
NewHiddenCatchScope()2932 Scope* Parser::NewHiddenCatchScope() {
2933 Scope* catch_scope = NewScopeWithParent(scope(), CATCH_SCOPE);
2934 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(),
2935 VariableMode::kVar);
2936 catch_scope->set_is_hidden();
2937 return catch_scope;
2938 }
2939
BuildRejectPromiseOnException(Block * inner_block)2940 Block* Parser::BuildRejectPromiseOnException(Block* inner_block) {
2941 // .promise = %AsyncFunctionPromiseCreate();
2942 // try {
2943 // <inner_block>
2944 // } catch (.catch) {
2945 // %RejectPromise(.promise, .catch);
2946 // return .promise;
2947 // } finally {
2948 // %AsyncFunctionPromiseRelease(.promise);
2949 // }
2950 Block* result = factory()->NewBlock(2, true);
2951
2952 // .promise = %AsyncFunctionPromiseCreate();
2953 Statement* set_promise;
2954 {
2955 Expression* create_promise = factory()->NewCallRuntime(
2956 Context::ASYNC_FUNCTION_PROMISE_CREATE_INDEX,
2957 new (zone()) ZonePtrList<Expression>(0, zone()), kNoSourcePosition);
2958 Assignment* assign_promise = factory()->NewAssignment(
2959 Token::ASSIGN, factory()->NewVariableProxy(PromiseVariable()),
2960 create_promise, kNoSourcePosition);
2961 set_promise =
2962 factory()->NewExpressionStatement(assign_promise, kNoSourcePosition);
2963 }
2964 result->statements()->Add(set_promise, zone());
2965
2966 // catch (.catch) { return %RejectPromise(.promise, .catch), .promise }
2967 Scope* catch_scope = NewHiddenCatchScope();
2968
2969 Expression* promise_reject = BuildRejectPromise(
2970 factory()->NewVariableProxy(catch_scope->catch_variable()),
2971 kNoSourcePosition);
2972 Block* catch_block = IgnoreCompletion(
2973 factory()->NewReturnStatement(promise_reject, kNoSourcePosition));
2974
2975 TryStatement* try_catch_statement =
2976 factory()->NewTryCatchStatementForAsyncAwait(
2977 inner_block, catch_scope, catch_block, kNoSourcePosition);
2978
2979 // There is no TryCatchFinally node, so wrap it in an outer try/finally
2980 Block* outer_try_block = IgnoreCompletion(try_catch_statement);
2981
2982 // finally { %AsyncFunctionPromiseRelease(.promise, can_suspend) }
2983 Block* finally_block;
2984 {
2985 ZonePtrList<Expression>* args =
2986 new (zone()) ZonePtrList<Expression>(1, zone());
2987 args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
2988 args->Add(factory()->NewBooleanLiteral(function_state_->CanSuspend(),
2989 kNoSourcePosition),
2990 zone());
2991 Expression* call_promise_release = factory()->NewCallRuntime(
2992 Context::ASYNC_FUNCTION_PROMISE_RELEASE_INDEX, args, kNoSourcePosition);
2993 Statement* promise_release = factory()->NewExpressionStatement(
2994 call_promise_release, kNoSourcePosition);
2995 finally_block = IgnoreCompletion(promise_release);
2996 }
2997
2998 Statement* try_finally_statement = factory()->NewTryFinallyStatement(
2999 outer_try_block, finally_block, kNoSourcePosition);
3000
3001 result->statements()->Add(try_finally_statement, zone());
3002 return result;
3003 }
3004
BuildResolvePromise(Expression * value,int pos)3005 Expression* Parser::BuildResolvePromise(Expression* value, int pos) {
3006 // %ResolvePromise(.promise, value), .promise
3007 ZonePtrList<Expression>* args =
3008 new (zone()) ZonePtrList<Expression>(2, zone());
3009 args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
3010 args->Add(value, zone());
3011 Expression* call_runtime =
3012 factory()->NewCallRuntime(Runtime::kInlineResolvePromise, args, pos);
3013 return factory()->NewBinaryOperation(
3014 Token::COMMA, call_runtime,
3015 factory()->NewVariableProxy(PromiseVariable()), pos);
3016 }
3017
BuildRejectPromise(Expression * value,int pos)3018 Expression* Parser::BuildRejectPromise(Expression* value, int pos) {
3019 // %promise_internal_reject(.promise, value, false), .promise
3020 // Disables the additional debug event for the rejection since a debug event
3021 // already happened for the exception that got us here.
3022 ZonePtrList<Expression>* args =
3023 new (zone()) ZonePtrList<Expression>(3, zone());
3024 args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
3025 args->Add(value, zone());
3026 args->Add(factory()->NewBooleanLiteral(false, pos), zone());
3027 Expression* call_runtime =
3028 factory()->NewCallRuntime(Runtime::kInlineRejectPromise, args, pos);
3029 return factory()->NewBinaryOperation(
3030 Token::COMMA, call_runtime,
3031 factory()->NewVariableProxy(PromiseVariable()), pos);
3032 }
3033
PromiseVariable()3034 Variable* Parser::PromiseVariable() {
3035 // Based on the various compilation paths, there are many different code
3036 // paths which may be the first to access the Promise temporary. Whichever
3037 // comes first should create it and stash it in the FunctionState.
3038 Variable* promise = function_state_->scope()->promise_var();
3039 if (promise == nullptr) {
3040 promise = function_state_->scope()->DeclarePromiseVar(
3041 ast_value_factory()->empty_string());
3042 }
3043 return promise;
3044 }
3045
BuildInitialYield(int pos,FunctionKind kind)3046 Expression* Parser::BuildInitialYield(int pos, FunctionKind kind) {
3047 Expression* yield_result = factory()->NewVariableProxy(
3048 function_state_->scope()->generator_object_var());
3049 // The position of the yield is important for reporting the exception
3050 // caused by calling the .throw method on a generator suspended at the
3051 // initial yield (i.e. right after generator instantiation).
3052 function_state_->AddSuspend();
3053 return factory()->NewYield(yield_result, scope()->start_position(),
3054 Suspend::kOnExceptionThrow);
3055 }
3056
ParseFunction(const AstRawString * function_name,int pos,FunctionKind kind,FunctionLiteral::FunctionType function_type,DeclarationScope * function_scope,int * num_parameters,int * function_length,bool * has_duplicate_parameters,int * expected_property_count,int * suspend_count,ZonePtrList<const AstRawString> * arguments_for_wrapped_function,bool * ok)3057 ZonePtrList<Statement>* Parser::ParseFunction(
3058 const AstRawString* function_name, int pos, FunctionKind kind,
3059 FunctionLiteral::FunctionType function_type,
3060 DeclarationScope* function_scope, int* num_parameters, int* function_length,
3061 bool* has_duplicate_parameters, int* expected_property_count,
3062 int* suspend_count,
3063 ZonePtrList<const AstRawString>* arguments_for_wrapped_function, bool* ok) {
3064 ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
3065
3066 FunctionState function_state(&function_state_, &scope_, function_scope);
3067
3068 bool is_wrapped = function_type == FunctionLiteral::kWrapped;
3069
3070 DuplicateFinder duplicate_finder;
3071 ExpressionClassifier formals_classifier(this, &duplicate_finder);
3072
3073 int expected_parameters_end_pos = parameters_end_pos_;
3074 if (expected_parameters_end_pos != kNoSourcePosition) {
3075 // This is the first function encountered in a CreateDynamicFunction eval.
3076 parameters_end_pos_ = kNoSourcePosition;
3077 // The function name should have been ignored, giving us the empty string
3078 // here.
3079 DCHECK_EQ(function_name, ast_value_factory()->empty_string());
3080 }
3081
3082 ParserFormalParameters formals(function_scope);
3083
3084 if (is_wrapped) {
3085 // For a function implicitly wrapped in function header and footer, the
3086 // function arguments are provided separately to the source, and are
3087 // declared directly here.
3088 int arguments_length = arguments_for_wrapped_function->length();
3089 for (int i = 0; i < arguments_length; i++) {
3090 const bool is_rest = false;
3091 Expression* argument = ExpressionFromIdentifier(
3092 arguments_for_wrapped_function->at(i), kNoSourcePosition);
3093 AddFormalParameter(&formals, argument, NullExpression(),
3094 kNoSourcePosition, is_rest);
3095 }
3096 DCHECK_EQ(arguments_length, formals.num_parameters());
3097 DeclareFormalParameters(formals.scope, formals.params, formals.is_simple);
3098 } else {
3099 // For a regular function, the function arguments are parsed from source.
3100 DCHECK_NULL(arguments_for_wrapped_function);
3101 ParseFormalParameterList(&formals, CHECK_OK);
3102 if (expected_parameters_end_pos != kNoSourcePosition) {
3103 // Check for '(' or ')' shenanigans in the parameter string for dynamic
3104 // functions.
3105 int position = peek_position();
3106 if (position < expected_parameters_end_pos) {
3107 ReportMessageAt(Scanner::Location(position, position + 1),
3108 MessageTemplate::kArgStringTerminatesParametersEarly);
3109 *ok = false;
3110 return nullptr;
3111 } else if (position > expected_parameters_end_pos) {
3112 ReportMessageAt(Scanner::Location(expected_parameters_end_pos - 2,
3113 expected_parameters_end_pos),
3114 MessageTemplate::kUnexpectedEndOfArgString);
3115 *ok = false;
3116 return nullptr;
3117 }
3118 }
3119 Expect(Token::RPAREN, CHECK_OK);
3120 int formals_end_position = scanner()->location().end_pos;
3121
3122 CheckArityRestrictions(formals.arity, kind, formals.has_rest,
3123 function_scope->start_position(),
3124 formals_end_position, CHECK_OK);
3125 Expect(Token::LBRACE, CHECK_OK);
3126 }
3127 *num_parameters = formals.num_parameters();
3128 *function_length = formals.function_length;
3129
3130 ZonePtrList<Statement>* body = new (zone()) ZonePtrList<Statement>(8, zone());
3131 ParseFunctionBody(body, function_name, pos, formals, kind, function_type, ok);
3132
3133 // Validate parameter names. We can do this only after parsing the function,
3134 // since the function can declare itself strict.
3135 const bool allow_duplicate_parameters =
3136 is_sloppy(function_scope->language_mode()) && formals.is_simple &&
3137 !IsConciseMethod(kind);
3138 ValidateFormalParameters(function_scope->language_mode(),
3139 allow_duplicate_parameters, CHECK_OK);
3140
3141 RewriteDestructuringAssignments();
3142
3143 *has_duplicate_parameters =
3144 !classifier()->is_valid_formal_parameter_list_without_duplicates();
3145
3146 *expected_property_count = function_state.expected_property_count();
3147 *suspend_count = function_state.suspend_count();
3148 return body;
3149 }
3150
DeclareClassVariable(const AstRawString * name,ClassInfo * class_info,int class_token_pos,bool * ok)3151 void Parser::DeclareClassVariable(const AstRawString* name,
3152 ClassInfo* class_info, int class_token_pos,
3153 bool* ok) {
3154 #ifdef DEBUG
3155 scope()->SetScopeName(name);
3156 #endif
3157
3158 if (name != nullptr) {
3159 VariableProxy* proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE);
3160 Declaration* declaration =
3161 factory()->NewVariableDeclaration(proxy, class_token_pos);
3162 class_info->variable = Declare(
3163 declaration, DeclarationDescriptor::NORMAL, VariableMode::kConst,
3164 Variable::DefaultInitializationFlag(VariableMode::kConst), ok);
3165 }
3166 }
3167
3168 // TODO(gsathya): Ideally, this should just bypass scope analysis and
3169 // allocate a slot directly on the context. We should just store this
3170 // index in the AST, instead of storing the variable.
CreateSyntheticContextVariable(const AstRawString * name,bool * ok)3171 Variable* Parser::CreateSyntheticContextVariable(const AstRawString* name,
3172 bool* ok) {
3173 VariableProxy* proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE);
3174 Declaration* declaration =
3175 factory()->NewVariableDeclaration(proxy, kNoSourcePosition);
3176 Variable* var = Declare(
3177 declaration, DeclarationDescriptor::NORMAL, VariableMode::kConst,
3178 Variable::DefaultInitializationFlag(VariableMode::kConst), CHECK_OK);
3179 var->ForceContextAllocation();
3180 return var;
3181 }
3182
3183 // This method declares a property of the given class. It updates the
3184 // following fields of class_info, as appropriate:
3185 // - constructor
3186 // - properties
DeclareClassProperty(const AstRawString * class_name,ClassLiteralProperty * property,const AstRawString * property_name,ClassLiteralProperty::Kind kind,bool is_static,bool is_constructor,bool is_computed_name,ClassInfo * class_info,bool * ok)3187 void Parser::DeclareClassProperty(const AstRawString* class_name,
3188 ClassLiteralProperty* property,
3189 const AstRawString* property_name,
3190 ClassLiteralProperty::Kind kind,
3191 bool is_static, bool is_constructor,
3192 bool is_computed_name, ClassInfo* class_info,
3193 bool* ok) {
3194 if (is_constructor) {
3195 DCHECK(!class_info->constructor);
3196 class_info->constructor = property->value()->AsFunctionLiteral();
3197 DCHECK_NOT_NULL(class_info->constructor);
3198 class_info->constructor->set_raw_name(
3199 class_name != nullptr ? ast_value_factory()->NewConsString(class_name)
3200 : nullptr);
3201 return;
3202 }
3203
3204 if (kind != ClassLiteralProperty::PUBLIC_FIELD &&
3205 kind != ClassLiteralProperty::PRIVATE_FIELD) {
3206 class_info->properties->Add(property, zone());
3207 return;
3208 }
3209
3210 DCHECK(allow_harmony_public_fields() || allow_harmony_private_fields());
3211
3212 if (is_static) {
3213 DCHECK(allow_harmony_static_fields());
3214 DCHECK_EQ(kind, ClassLiteralProperty::PUBLIC_FIELD);
3215 class_info->static_fields->Add(property, zone());
3216 } else {
3217 class_info->instance_fields->Add(property, zone());
3218 }
3219
3220 if (is_computed_name) {
3221 DCHECK_EQ(kind, ClassLiteralProperty::PUBLIC_FIELD);
3222 // We create a synthetic variable name here so that scope
3223 // analysis doesn't dedupe the vars.
3224 Variable* computed_name_var = CreateSyntheticContextVariable(
3225 ClassFieldVariableName(ast_value_factory(),
3226 class_info->computed_field_count),
3227 CHECK_OK_VOID);
3228 property->set_computed_name_var(computed_name_var);
3229 class_info->properties->Add(property, zone());
3230 }
3231
3232 if (kind == ClassLiteralProperty::PRIVATE_FIELD) {
3233 Variable* private_field_name_var =
3234 CreateSyntheticContextVariable(property_name, CHECK_OK_VOID);
3235 property->set_private_field_name_var(private_field_name_var);
3236 class_info->properties->Add(property, zone());
3237 }
3238 }
3239
CreateInitializerFunction(DeclarationScope * scope,ZonePtrList<ClassLiteral::Property> * fields)3240 FunctionLiteral* Parser::CreateInitializerFunction(
3241 DeclarationScope* scope, ZonePtrList<ClassLiteral::Property>* fields) {
3242 DCHECK_EQ(scope->function_kind(),
3243 FunctionKind::kClassFieldsInitializerFunction);
3244 // function() { .. class fields initializer .. }
3245 ZonePtrList<Statement>* statements = NewStatementList(1);
3246 InitializeClassFieldsStatement* static_fields =
3247 factory()->NewInitializeClassFieldsStatement(fields, kNoSourcePosition);
3248 statements->Add(static_fields, zone());
3249 return factory()->NewFunctionLiteral(
3250 ast_value_factory()->empty_string(), scope, statements, 0, 0, 0,
3251 FunctionLiteral::kNoDuplicateParameters,
3252 FunctionLiteral::kAnonymousExpression,
3253 FunctionLiteral::kShouldEagerCompile, scope->start_position(), true,
3254 GetNextFunctionLiteralId());
3255 }
3256
3257 // This method generates a ClassLiteral AST node.
3258 // It uses the following fields of class_info:
3259 // - constructor (if missing, it updates it with a default constructor)
3260 // - proxy
3261 // - extends
3262 // - properties
3263 // - has_name_static_property
3264 // - has_static_computed_names
RewriteClassLiteral(Scope * block_scope,const AstRawString * name,ClassInfo * class_info,int pos,int end_pos,bool * ok)3265 Expression* Parser::RewriteClassLiteral(Scope* block_scope,
3266 const AstRawString* name,
3267 ClassInfo* class_info, int pos,
3268 int end_pos, bool* ok) {
3269 DCHECK_NOT_NULL(block_scope);
3270 DCHECK_EQ(block_scope->scope_type(), BLOCK_SCOPE);
3271 DCHECK_EQ(block_scope->language_mode(), LanguageMode::kStrict);
3272
3273 bool has_extends = class_info->extends != nullptr;
3274 bool has_default_constructor = class_info->constructor == nullptr;
3275 if (has_default_constructor) {
3276 class_info->constructor =
3277 DefaultConstructor(name, has_extends, pos, end_pos);
3278 }
3279
3280 if (name != nullptr) {
3281 DCHECK_NOT_NULL(class_info->variable);
3282 class_info->variable->set_initializer_position(end_pos);
3283 }
3284
3285 FunctionLiteral* static_fields_initializer = nullptr;
3286 if (class_info->has_static_class_fields) {
3287 static_fields_initializer = CreateInitializerFunction(
3288 class_info->static_fields_scope, class_info->static_fields);
3289 }
3290
3291 FunctionLiteral* instance_fields_initializer_function = nullptr;
3292 if (class_info->has_instance_class_fields) {
3293 instance_fields_initializer_function = CreateInitializerFunction(
3294 class_info->instance_fields_scope, class_info->instance_fields);
3295 class_info->constructor->set_requires_instance_fields_initializer(true);
3296 }
3297
3298 ClassLiteral* class_literal = factory()->NewClassLiteral(
3299 block_scope, class_info->variable, class_info->extends,
3300 class_info->constructor, class_info->properties,
3301 static_fields_initializer, instance_fields_initializer_function, pos,
3302 end_pos, class_info->has_name_static_property,
3303 class_info->has_static_computed_names, class_info->is_anonymous);
3304
3305 AddFunctionForNameInference(class_info->constructor);
3306 return class_literal;
3307 }
3308
CheckConflictingVarDeclarations(Scope * scope,bool * ok)3309 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
3310 Declaration* decl = scope->CheckConflictingVarDeclarations();
3311 if (decl != nullptr) {
3312 // In ES6, conflicting variable bindings are early errors.
3313 const AstRawString* name = decl->proxy()->raw_name();
3314 int position = decl->proxy()->position();
3315 Scanner::Location location =
3316 position == kNoSourcePosition
3317 ? Scanner::Location::invalid()
3318 : Scanner::Location(position, position + 1);
3319 ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
3320 *ok = false;
3321 }
3322 }
3323
IsPropertyWithPrivateFieldKey(Expression * expression)3324 bool Parser::IsPropertyWithPrivateFieldKey(Expression* expression) {
3325 if (!expression->IsProperty()) return false;
3326 Property* property = expression->AsProperty();
3327
3328 if (!property->key()->IsVariableProxy()) return false;
3329 VariableProxy* key = property->key()->AsVariableProxy();
3330
3331 return key->is_private_field();
3332 }
3333
InsertShadowingVarBindingInitializers(Block * inner_block)3334 void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) {
3335 // For each var-binding that shadows a parameter, insert an assignment
3336 // initializing the variable with the parameter.
3337 Scope* inner_scope = inner_block->scope();
3338 DCHECK(inner_scope->is_declaration_scope());
3339 Scope* function_scope = inner_scope->outer_scope();
3340 DCHECK(function_scope->is_function_scope());
3341 BlockState block_state(&scope_, inner_scope);
3342 for (Declaration* decl : *inner_scope->declarations()) {
3343 if (decl->proxy()->var()->mode() != VariableMode::kVar ||
3344 !decl->IsVariableDeclaration()) {
3345 continue;
3346 }
3347 const AstRawString* name = decl->proxy()->raw_name();
3348 Variable* parameter = function_scope->LookupLocal(name);
3349 if (parameter == nullptr) continue;
3350 VariableProxy* to = NewUnresolved(name);
3351 VariableProxy* from = factory()->NewVariableProxy(parameter);
3352 Expression* assignment =
3353 factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition);
3354 Statement* statement =
3355 factory()->NewExpressionStatement(assignment, kNoSourcePosition);
3356 inner_block->statements()->InsertAt(0, statement, zone());
3357 }
3358 }
3359
InsertSloppyBlockFunctionVarBindings(DeclarationScope * scope)3360 void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope) {
3361 // For the outermost eval scope, we cannot hoist during parsing: let
3362 // declarations in the surrounding scope may prevent hoisting, but the
3363 // information is unaccessible during parsing. In this case, we hoist later in
3364 // DeclarationScope::Analyze.
3365 if (scope->is_eval_scope() && scope->outer_scope() == original_scope_) {
3366 return;
3367 }
3368 scope->HoistSloppyBlockFunctions(factory());
3369 }
3370
3371 // ----------------------------------------------------------------------------
3372 // Parser support
3373
TargetStackContainsLabel(const AstRawString * label)3374 bool Parser::TargetStackContainsLabel(const AstRawString* label) {
3375 for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
3376 if (ContainsLabel(t->statement()->labels(), label)) return true;
3377 }
3378 return false;
3379 }
3380
3381
LookupBreakTarget(const AstRawString * label,bool * ok)3382 BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label,
3383 bool* ok) {
3384 bool anonymous = label == nullptr;
3385 for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
3386 BreakableStatement* stat = t->statement();
3387 if ((anonymous && stat->is_target_for_anonymous()) ||
3388 (!anonymous && ContainsLabel(stat->labels(), label))) {
3389 return stat;
3390 }
3391 }
3392 return nullptr;
3393 }
3394
3395
LookupContinueTarget(const AstRawString * label,bool * ok)3396 IterationStatement* Parser::LookupContinueTarget(const AstRawString* label,
3397 bool* ok) {
3398 bool anonymous = label == nullptr;
3399 for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
3400 IterationStatement* stat = t->statement()->AsIterationStatement();
3401 if (stat == nullptr) continue;
3402
3403 DCHECK(stat->is_target_for_anonymous());
3404 if (anonymous || ContainsLabel(stat->own_labels(), label)) {
3405 return stat;
3406 }
3407 if (ContainsLabel(stat->labels(), label)) break;
3408 }
3409 return nullptr;
3410 }
3411
3412
HandleSourceURLComments(Isolate * isolate,Handle<Script> script)3413 void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) {
3414 Handle<String> source_url = scanner_.SourceUrl(isolate);
3415 if (!source_url.is_null()) {
3416 script->set_source_url(*source_url);
3417 }
3418 Handle<String> source_mapping_url = scanner_.SourceMappingUrl(isolate);
3419 if (!source_mapping_url.is_null()) {
3420 script->set_source_mapping_url(*source_mapping_url);
3421 }
3422 }
3423
UpdateStatistics(Isolate * isolate,Handle<Script> script)3424 void Parser::UpdateStatistics(Isolate* isolate, Handle<Script> script) {
3425 // Move statistics to Isolate.
3426 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
3427 ++feature) {
3428 if (use_counts_[feature] > 0) {
3429 isolate->CountUsage(v8::Isolate::UseCounterFeature(feature));
3430 }
3431 }
3432 if (scanner_.FoundHtmlComment()) {
3433 isolate->CountUsage(v8::Isolate::kHtmlComment);
3434 if (script->line_offset() == 0 && script->column_offset() == 0) {
3435 isolate->CountUsage(v8::Isolate::kHtmlCommentInExternalScript);
3436 }
3437 }
3438 isolate->counters()->total_preparse_skipped()->Increment(
3439 total_preparse_skipped_);
3440 }
3441
ParseOnBackground(ParseInfo * info)3442 void Parser::ParseOnBackground(ParseInfo* info) {
3443 RuntimeCallTimerScope runtimeTimer(
3444 runtime_call_stats_, RuntimeCallCounterId::kParseBackgroundProgram);
3445 parsing_on_main_thread_ = false;
3446 set_script_id(info->script_id());
3447
3448 DCHECK_NULL(info->literal());
3449 FunctionLiteral* result = nullptr;
3450
3451 scanner_.Initialize();
3452 DCHECK(info->maybe_outer_scope_info().is_null());
3453
3454 DCHECK(original_scope_);
3455
3456 // When streaming, we don't know the length of the source until we have parsed
3457 // it. The raw data can be UTF-8, so we wouldn't know the source length until
3458 // we have decoded it anyway even if we knew the raw data length (which we
3459 // don't). We work around this by storing all the scopes which need their end
3460 // position set at the end of the script (the top scope and possible eval
3461 // scopes) and set their end position after we know the script length.
3462 if (info->is_toplevel()) {
3463 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
3464 result = DoParseProgram(/* isolate = */ nullptr, info);
3465 } else {
3466 result =
3467 DoParseFunction(/* isolate = */ nullptr, info, info->function_name());
3468 }
3469 MaybeResetCharacterStream(info, result);
3470
3471 info->set_literal(result);
3472
3473 // We cannot internalize on a background thread; a foreground task will take
3474 // care of calling AstValueFactory::Internalize just before compilation.
3475 }
3476
OpenTemplateLiteral(int pos)3477 Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
3478 return new (zone()) TemplateLiteral(zone(), pos);
3479 }
3480
AddTemplateSpan(TemplateLiteralState * state,bool should_cook,bool tail)3481 void Parser::AddTemplateSpan(TemplateLiteralState* state, bool should_cook,
3482 bool tail) {
3483 int end = scanner()->location().end_pos - (tail ? 1 : 2);
3484 const AstRawString* raw = scanner()->CurrentRawSymbol(ast_value_factory());
3485 if (should_cook) {
3486 const AstRawString* cooked = scanner()->CurrentSymbol(ast_value_factory());
3487 (*state)->AddTemplateSpan(cooked, raw, end, zone());
3488 } else {
3489 (*state)->AddTemplateSpan(nullptr, raw, end, zone());
3490 }
3491 }
3492
3493
AddTemplateExpression(TemplateLiteralState * state,Expression * expression)3494 void Parser::AddTemplateExpression(TemplateLiteralState* state,
3495 Expression* expression) {
3496 (*state)->AddExpression(expression, zone());
3497 }
3498
3499
CloseTemplateLiteral(TemplateLiteralState * state,int start,Expression * tag)3500 Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
3501 Expression* tag) {
3502 TemplateLiteral* lit = *state;
3503 int pos = lit->position();
3504 const ZonePtrList<const AstRawString>* cooked_strings = lit->cooked();
3505 const ZonePtrList<const AstRawString>* raw_strings = lit->raw();
3506 const ZonePtrList<Expression>* expressions = lit->expressions();
3507 DCHECK_EQ(cooked_strings->length(), raw_strings->length());
3508 DCHECK_EQ(cooked_strings->length(), expressions->length() + 1);
3509
3510 if (!tag) {
3511 if (cooked_strings->length() == 1) {
3512 return factory()->NewStringLiteral(cooked_strings->first(), pos);
3513 }
3514 return factory()->NewTemplateLiteral(cooked_strings, expressions, pos);
3515 } else {
3516 // GetTemplateObject
3517 Expression* template_object =
3518 factory()->NewGetTemplateObject(cooked_strings, raw_strings, pos);
3519
3520 // Call TagFn
3521 ZonePtrList<Expression>* call_args =
3522 new (zone()) ZonePtrList<Expression>(expressions->length() + 1, zone());
3523 call_args->Add(template_object, zone());
3524 call_args->AddAll(*expressions, zone());
3525 return factory()->NewTaggedTemplate(tag, call_args, pos);
3526 }
3527 }
3528
3529 namespace {
3530
OnlyLastArgIsSpread(ZonePtrList<Expression> * args)3531 bool OnlyLastArgIsSpread(ZonePtrList<Expression>* args) {
3532 for (int i = 0; i < args->length() - 1; i++) {
3533 if (args->at(i)->IsSpread()) {
3534 return false;
3535 }
3536 }
3537 return args->at(args->length() - 1)->IsSpread();
3538 }
3539
3540 } // namespace
3541
ArrayLiteralFromListWithSpread(ZonePtrList<Expression> * list)3542 ArrayLiteral* Parser::ArrayLiteralFromListWithSpread(
3543 ZonePtrList<Expression>* list) {
3544 // If there's only a single spread argument, a fast path using CallWithSpread
3545 // is taken.
3546 DCHECK_LT(1, list->length());
3547
3548 // The arguments of the spread call become a single ArrayLiteral.
3549 int first_spread = 0;
3550 for (; first_spread < list->length() && !list->at(first_spread)->IsSpread();
3551 ++first_spread) {
3552 }
3553
3554 DCHECK_LT(first_spread, list->length());
3555 return factory()->NewArrayLiteral(list, first_spread, kNoSourcePosition);
3556 }
3557
SpreadCall(Expression * function,ZonePtrList<Expression> * args_list,int pos,Call::PossiblyEval is_possibly_eval)3558 Expression* Parser::SpreadCall(Expression* function,
3559 ZonePtrList<Expression>* args_list, int pos,
3560 Call::PossiblyEval is_possibly_eval) {
3561 // Handle this case in BytecodeGenerator.
3562 if (OnlyLastArgIsSpread(args_list) || function->IsSuperCallReference()) {
3563 return factory()->NewCall(function, args_list, pos);
3564 }
3565
3566 ZonePtrList<Expression>* args =
3567 new (zone()) ZonePtrList<Expression>(3, zone());
3568 if (function->IsProperty()) {
3569 // Method calls
3570 if (function->AsProperty()->IsSuperAccess()) {
3571 Expression* home = ThisExpression(kNoSourcePosition);
3572 args->Add(function, zone());
3573 args->Add(home, zone());
3574 } else {
3575 Variable* temp = NewTemporary(ast_value_factory()->empty_string());
3576 VariableProxy* obj = factory()->NewVariableProxy(temp);
3577 Assignment* assign_obj = factory()->NewAssignment(
3578 Token::ASSIGN, obj, function->AsProperty()->obj(), kNoSourcePosition);
3579 function = factory()->NewProperty(
3580 assign_obj, function->AsProperty()->key(), kNoSourcePosition);
3581 args->Add(function, zone());
3582 obj = factory()->NewVariableProxy(temp);
3583 args->Add(obj, zone());
3584 }
3585 } else {
3586 // Non-method calls
3587 args->Add(function, zone());
3588 args->Add(factory()->NewUndefinedLiteral(kNoSourcePosition), zone());
3589 }
3590 args->Add(ArrayLiteralFromListWithSpread(args_list), zone());
3591 return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos);
3592 }
3593
SpreadCallNew(Expression * function,ZonePtrList<Expression> * args_list,int pos)3594 Expression* Parser::SpreadCallNew(Expression* function,
3595 ZonePtrList<Expression>* args_list, int pos) {
3596 if (OnlyLastArgIsSpread(args_list)) {
3597 // Handle in BytecodeGenerator.
3598 return factory()->NewCallNew(function, args_list, pos);
3599 }
3600 ZonePtrList<Expression>* args =
3601 new (zone()) ZonePtrList<Expression>(2, zone());
3602 args->Add(function, zone());
3603 args->Add(ArrayLiteralFromListWithSpread(args_list), zone());
3604
3605 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos);
3606 }
3607
3608
SetLanguageMode(Scope * scope,LanguageMode mode)3609 void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) {
3610 v8::Isolate::UseCounterFeature feature;
3611 if (is_sloppy(mode))
3612 feature = v8::Isolate::kSloppyMode;
3613 else if (is_strict(mode))
3614 feature = v8::Isolate::kStrictMode;
3615 else
3616 UNREACHABLE();
3617 ++use_counts_[feature];
3618 scope->SetLanguageMode(mode);
3619 }
3620
SetAsmModule()3621 void Parser::SetAsmModule() {
3622 // Store the usage count; The actual use counter on the isolate is
3623 // incremented after parsing is done.
3624 ++use_counts_[v8::Isolate::kUseAsm];
3625 DCHECK(scope()->is_declaration_scope());
3626 scope()->AsDeclarationScope()->set_asm_module();
3627 }
3628
ExpressionListToExpression(ZonePtrList<Expression> * args)3629 Expression* Parser::ExpressionListToExpression(ZonePtrList<Expression>* args) {
3630 Expression* expr = args->at(0);
3631 for (int i = 1; i < args->length(); ++i) {
3632 expr = factory()->NewBinaryOperation(Token::COMMA, expr, args->at(i),
3633 expr->position());
3634 }
3635 return expr;
3636 }
3637
3638 // This method completes the desugaring of the body of async_function.
RewriteAsyncFunctionBody(ZonePtrList<Statement> * body,Block * block,Expression * return_value,bool * ok)3639 void Parser::RewriteAsyncFunctionBody(ZonePtrList<Statement>* body,
3640 Block* block, Expression* return_value,
3641 bool* ok) {
3642 // function async_function() {
3643 // .generator_object = %CreateJSGeneratorObject();
3644 // BuildRejectPromiseOnException({
3645 // ... block ...
3646 // return %ResolvePromise(.promise, expr), .promise;
3647 // })
3648 // }
3649
3650 return_value = BuildResolvePromise(return_value, return_value->position());
3651 block->statements()->Add(
3652 factory()->NewReturnStatement(return_value, return_value->position()),
3653 zone());
3654 block = BuildRejectPromiseOnException(block);
3655 body->Add(block, zone());
3656 }
3657
RewriteDestructuringAssignments()3658 void Parser::RewriteDestructuringAssignments() {
3659 const auto& assignments =
3660 function_state_->destructuring_assignments_to_rewrite();
3661 auto it = assignments.rbegin();
3662 for (; it != assignments.rend(); ++it) {
3663 // Rewrite list in reverse, so that nested assignment patterns are rewritten
3664 // correctly.
3665 RewritableExpression* to_rewrite = *it;
3666 DCHECK_NOT_NULL(to_rewrite);
3667 if (!to_rewrite->is_rewritten()) {
3668 // Since this function is called at the end of parsing the program,
3669 // pair.scope may already have been removed by FinalizeBlockScope in the
3670 // meantime.
3671 Scope* scope = to_rewrite->scope()->GetUnremovedScope();
3672 // Scope at the time of the rewriting and the original parsing
3673 // should be in the same function.
3674 DCHECK(scope->GetClosureScope() == scope_->GetClosureScope());
3675 BlockState block_state(&scope_, scope);
3676 RewriteDestructuringAssignment(to_rewrite);
3677 }
3678 }
3679 }
3680
QueueDestructuringAssignmentForRewriting(RewritableExpression * expr)3681 void Parser::QueueDestructuringAssignmentForRewriting(
3682 RewritableExpression* expr) {
3683 function_state_->AddDestructuringAssignment(expr);
3684 }
3685
SetFunctionNameFromPropertyName(LiteralProperty * property,const AstRawString * name,const AstRawString * prefix)3686 void Parser::SetFunctionNameFromPropertyName(LiteralProperty* property,
3687 const AstRawString* name,
3688 const AstRawString* prefix) {
3689 // Ensure that the function we are going to create has shared name iff
3690 // we are not going to set it later.
3691 if (property->NeedsSetFunctionName()) {
3692 name = nullptr;
3693 prefix = nullptr;
3694 } else {
3695 // If the property value is an anonymous function or an anonymous class or
3696 // a concise method or an accessor function which doesn't require the name
3697 // to be set then the shared name must be provided.
3698 DCHECK_IMPLIES(property->value()->IsAnonymousFunctionDefinition() ||
3699 property->value()->IsConciseMethodDefinition() ||
3700 property->value()->IsAccessorFunctionDefinition(),
3701 name != nullptr);
3702 }
3703
3704 Expression* value = property->value();
3705 SetFunctionName(value, name, prefix);
3706 }
3707
SetFunctionNameFromPropertyName(ObjectLiteralProperty * property,const AstRawString * name,const AstRawString * prefix)3708 void Parser::SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
3709 const AstRawString* name,
3710 const AstRawString* prefix) {
3711 // Ignore "__proto__" as a name when it's being used to set the [[Prototype]]
3712 // of an object literal.
3713 // See ES #sec-__proto__-property-names-in-object-initializers.
3714 if (property->IsPrototype()) return;
3715
3716 DCHECK(!property->value()->IsAnonymousFunctionDefinition() ||
3717 property->kind() == ObjectLiteralProperty::COMPUTED);
3718
3719 SetFunctionNameFromPropertyName(static_cast<LiteralProperty*>(property), name,
3720 prefix);
3721 }
3722
SetFunctionNameFromIdentifierRef(Expression * value,Expression * identifier)3723 void Parser::SetFunctionNameFromIdentifierRef(Expression* value,
3724 Expression* identifier) {
3725 if (!identifier->IsVariableProxy()) return;
3726 SetFunctionName(value, identifier->AsVariableProxy()->raw_name());
3727 }
3728
SetFunctionName(Expression * value,const AstRawString * name,const AstRawString * prefix)3729 void Parser::SetFunctionName(Expression* value, const AstRawString* name,
3730 const AstRawString* prefix) {
3731 if (!value->IsAnonymousFunctionDefinition() &&
3732 !value->IsConciseMethodDefinition() &&
3733 !value->IsAccessorFunctionDefinition()) {
3734 return;
3735 }
3736 auto function = value->AsFunctionLiteral();
3737 if (value->IsClassLiteral()) {
3738 function = value->AsClassLiteral()->constructor();
3739 }
3740 if (function != nullptr) {
3741 AstConsString* cons_name = nullptr;
3742 if (name != nullptr) {
3743 if (prefix != nullptr) {
3744 cons_name = ast_value_factory()->NewConsString(prefix, name);
3745 } else {
3746 cons_name = ast_value_factory()->NewConsString(name);
3747 }
3748 } else {
3749 DCHECK_NULL(prefix);
3750 }
3751 function->set_raw_name(cons_name);
3752 }
3753 }
3754
CheckCallable(Variable * var,Expression * error,int pos)3755 Statement* Parser::CheckCallable(Variable* var, Expression* error, int pos) {
3756 const int nopos = kNoSourcePosition;
3757 Statement* validate_var;
3758 {
3759 Expression* type_of = factory()->NewUnaryOperation(
3760 Token::TYPEOF, factory()->NewVariableProxy(var), nopos);
3761 Expression* function_literal = factory()->NewStringLiteral(
3762 ast_value_factory()->function_string(), nopos);
3763 Expression* condition = factory()->NewCompareOperation(
3764 Token::EQ_STRICT, type_of, function_literal, nopos);
3765
3766 Statement* throw_call = factory()->NewExpressionStatement(error, pos);
3767
3768 validate_var = factory()->NewIfStatement(
3769 condition, factory()->NewEmptyStatement(nopos), throw_call, nopos);
3770 }
3771 return validate_var;
3772 }
3773
BuildIteratorClose(ZonePtrList<Statement> * statements,Variable * iterator,Variable * input,Variable * var_output,IteratorType type)3774 void Parser::BuildIteratorClose(ZonePtrList<Statement>* statements,
3775 Variable* iterator, Variable* input,
3776 Variable* var_output, IteratorType type) {
3777 //
3778 // This function adds four statements to [statements], corresponding to the
3779 // following code:
3780 //
3781 // let iteratorReturn = iterator.return;
3782 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) {
3783 // return {value: input, done: true};
3784 // }
3785 // output = %_Call(iteratorReturn, iterator, input);
3786 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
3787 //
3788
3789 const int nopos = kNoSourcePosition;
3790
3791 // let iteratorReturn = iterator.return;
3792 Variable* var_return = var_output; // Reusing the output variable.
3793 Statement* get_return;
3794 {
3795 Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
3796 Expression* literal = factory()->NewStringLiteral(
3797 ast_value_factory()->return_string(), nopos);
3798 Expression* property =
3799 factory()->NewProperty(iterator_proxy, literal, nopos);
3800 Expression* return_proxy = factory()->NewVariableProxy(var_return);
3801 Expression* assignment =
3802 factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos);
3803 get_return = factory()->NewExpressionStatement(assignment, nopos);
3804 }
3805
3806 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) {
3807 // return {value: input, done: true};
3808 // }
3809 Statement* check_return;
3810 {
3811 Expression* condition = factory()->NewCompareOperation(
3812 Token::EQ, factory()->NewVariableProxy(var_return),
3813 factory()->NewNullLiteral(nopos), nopos);
3814
3815 Expression* value = factory()->NewVariableProxy(input);
3816
3817 Statement* return_input = BuildReturnStatement(value, nopos);
3818
3819 check_return = factory()->NewIfStatement(
3820 condition, return_input, factory()->NewEmptyStatement(nopos), nopos);
3821 }
3822
3823 // output = %_Call(iteratorReturn, iterator, input);
3824 Statement* call_return;
3825 {
3826 auto args = new (zone()) ZonePtrList<Expression>(3, zone());
3827 args->Add(factory()->NewVariableProxy(var_return), zone());
3828 args->Add(factory()->NewVariableProxy(iterator), zone());
3829 args->Add(factory()->NewVariableProxy(input), zone());
3830
3831 Expression* call =
3832 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
3833 if (type == IteratorType::kAsync) {
3834 function_state_->AddSuspend();
3835 call = factory()->NewAwait(call, nopos);
3836 }
3837 Expression* output_proxy = factory()->NewVariableProxy(var_output);
3838 Expression* assignment =
3839 factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
3840 call_return = factory()->NewExpressionStatement(assignment, nopos);
3841 }
3842
3843 // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output);
3844 Statement* validate_output;
3845 {
3846 Expression* is_receiver_call;
3847 {
3848 auto args = new (zone()) ZonePtrList<Expression>(1, zone());
3849 args->Add(factory()->NewVariableProxy(var_output), zone());
3850 is_receiver_call =
3851 factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
3852 }
3853
3854 Statement* throw_call;
3855 {
3856 auto args = new (zone()) ZonePtrList<Expression>(1, zone());
3857 args->Add(factory()->NewVariableProxy(var_output), zone());
3858 Expression* call = factory()->NewCallRuntime(
3859 Runtime::kThrowIteratorResultNotAnObject, args, nopos);
3860 throw_call = factory()->NewExpressionStatement(call, nopos);
3861 }
3862
3863 validate_output = factory()->NewIfStatement(
3864 is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
3865 nopos);
3866 }
3867
3868 statements->Add(get_return, zone());
3869 statements->Add(check_return, zone());
3870 statements->Add(call_return, zone());
3871 statements->Add(validate_output, zone());
3872 }
3873
FinalizeIteratorUse(Variable * completion,Expression * condition,Variable * iter,Block * iterator_use,Block * target,IteratorType type)3874 void Parser::FinalizeIteratorUse(Variable* completion, Expression* condition,
3875 Variable* iter, Block* iterator_use,
3876 Block* target, IteratorType type) {
3877 //
3878 // This function adds two statements to [target], corresponding to the
3879 // following code:
3880 //
3881 // completion = kNormalCompletion;
3882 // try {
3883 // try {
3884 // iterator_use
3885 // } catch(e) {
3886 // if (completion === kAbruptCompletion) completion = kThrowCompletion;
3887 // %ReThrow(e);
3888 // }
3889 // } finally {
3890 // if (condition) {
3891 // #BuildIteratorCloseForCompletion(iter, completion)
3892 // }
3893 // }
3894 //
3895
3896 const int nopos = kNoSourcePosition;
3897
3898 // completion = kNormalCompletion;
3899 Statement* initialize_completion;
3900 {
3901 Expression* proxy = factory()->NewVariableProxy(completion);
3902 Expression* assignment = factory()->NewAssignment(
3903 Token::ASSIGN, proxy,
3904 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
3905 initialize_completion =
3906 factory()->NewExpressionStatement(assignment, nopos);
3907 }
3908
3909 // if (completion === kAbruptCompletion) completion = kThrowCompletion;
3910 Statement* set_completion_throw;
3911 {
3912 Expression* condition = factory()->NewCompareOperation(
3913 Token::EQ_STRICT, factory()->NewVariableProxy(completion),
3914 factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
3915
3916 Expression* proxy = factory()->NewVariableProxy(completion);
3917 Expression* assignment = factory()->NewAssignment(
3918 Token::ASSIGN, proxy,
3919 factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos);
3920 Statement* statement = factory()->NewExpressionStatement(assignment, nopos);
3921 set_completion_throw = factory()->NewIfStatement(
3922 condition, statement, factory()->NewEmptyStatement(nopos), nopos);
3923 }
3924
3925 // if (condition) {
3926 // #BuildIteratorCloseForCompletion(iter, completion)
3927 // }
3928 Block* maybe_close;
3929 {
3930 Block* block = factory()->NewBlock(2, true);
3931 Expression* proxy = factory()->NewVariableProxy(completion);
3932 BuildIteratorCloseForCompletion(block->statements(), iter, proxy, type);
3933 DCHECK_EQ(block->statements()->length(), 2);
3934
3935 maybe_close = IgnoreCompletion(factory()->NewIfStatement(
3936 condition, block, factory()->NewEmptyStatement(nopos), nopos));
3937 }
3938
3939 // try { #try_block }
3940 // catch(e) {
3941 // #set_completion_throw;
3942 // %ReThrow(e);
3943 // }
3944 Statement* try_catch;
3945 {
3946 Scope* catch_scope = NewHiddenCatchScope();
3947
3948 Statement* rethrow;
3949 // We use %ReThrow rather than the ordinary throw because we want to
3950 // preserve the original exception message. This is also why we create a
3951 // TryCatchStatementForReThrow below (which does not clear the pending
3952 // message), rather than a TryCatchStatement.
3953 {
3954 auto args = new (zone()) ZonePtrList<Expression>(1, zone());
3955 args->Add(factory()->NewVariableProxy(catch_scope->catch_variable()),
3956 zone());
3957 rethrow = factory()->NewExpressionStatement(
3958 factory()->NewCallRuntime(Runtime::kReThrow, args, nopos), nopos);
3959 }
3960
3961 Block* catch_block = factory()->NewBlock(2, false);
3962 catch_block->statements()->Add(set_completion_throw, zone());
3963 catch_block->statements()->Add(rethrow, zone());
3964
3965 try_catch = factory()->NewTryCatchStatementForReThrow(
3966 iterator_use, catch_scope, catch_block, nopos);
3967 }
3968
3969 // try { #try_catch } finally { #maybe_close }
3970 Statement* try_finally;
3971 {
3972 Block* try_block = factory()->NewBlock(1, false);
3973 try_block->statements()->Add(try_catch, zone());
3974
3975 try_finally =
3976 factory()->NewTryFinallyStatement(try_block, maybe_close, nopos);
3977 }
3978
3979 target->statements()->Add(initialize_completion, zone());
3980 target->statements()->Add(try_finally, zone());
3981 }
3982
BuildIteratorCloseForCompletion(ZonePtrList<Statement> * statements,Variable * iterator,Expression * completion,IteratorType type)3983 void Parser::BuildIteratorCloseForCompletion(ZonePtrList<Statement>* statements,
3984 Variable* iterator,
3985 Expression* completion,
3986 IteratorType type) {
3987 //
3988 // This function adds two statements to [statements], corresponding to the
3989 // following code:
3990 //
3991 // let iteratorReturn = iterator.return;
3992 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
3993 // if (completion === kThrowCompletion) {
3994 // if (!IS_CALLABLE(iteratorReturn)) {
3995 // throw MakeTypeError(kReturnMethodNotCallable);
3996 // }
3997 // [if (IteratorType == kAsync)]
3998 // try { Await(%_Call(iteratorReturn, iterator) } catch (_) { }
3999 // [else]
4000 // try { %_Call(iteratorReturn, iterator) } catch (_) { }
4001 // [endif]
4002 // } else {
4003 // [if (IteratorType == kAsync)]
4004 // let output = Await(%_Call(iteratorReturn, iterator));
4005 // [else]
4006 // let output = %_Call(iteratorReturn, iterator);
4007 // [endif]
4008 // if (!IS_RECEIVER(output)) {
4009 // %ThrowIterResultNotAnObject(output);
4010 // }
4011 // }
4012 // }
4013 //
4014
4015 const int nopos = kNoSourcePosition;
4016 // let iteratorReturn = iterator.return;
4017 Variable* var_return = NewTemporary(ast_value_factory()->empty_string());
4018 Statement* get_return;
4019 {
4020 Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
4021 Expression* literal = factory()->NewStringLiteral(
4022 ast_value_factory()->return_string(), nopos);
4023 Expression* property =
4024 factory()->NewProperty(iterator_proxy, literal, nopos);
4025 Expression* return_proxy = factory()->NewVariableProxy(var_return);
4026 Expression* assignment =
4027 factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos);
4028 get_return = factory()->NewExpressionStatement(assignment, nopos);
4029 }
4030
4031 // if (!IS_CALLABLE(iteratorReturn)) {
4032 // throw MakeTypeError(kReturnMethodNotCallable);
4033 // }
4034 Statement* check_return_callable;
4035 {
4036 Expression* throw_expr =
4037 NewThrowTypeError(MessageTemplate::kReturnMethodNotCallable,
4038 ast_value_factory()->empty_string(), nopos);
4039 check_return_callable = CheckCallable(var_return, throw_expr, nopos);
4040 }
4041
4042 // try { %_Call(iteratorReturn, iterator) } catch (_) { }
4043 Statement* try_call_return;
4044 {
4045 auto args = new (zone()) ZonePtrList<Expression>(2, zone());
4046 args->Add(factory()->NewVariableProxy(var_return), zone());
4047 args->Add(factory()->NewVariableProxy(iterator), zone());
4048
4049 Expression* call =
4050 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
4051
4052 if (type == IteratorType::kAsync) {
4053 function_state_->AddSuspend();
4054 call = factory()->NewAwait(call, nopos);
4055 }
4056
4057 Block* try_block = factory()->NewBlock(1, false);
4058 try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos),
4059 zone());
4060
4061 Block* catch_block = factory()->NewBlock(0, false);
4062 try_call_return =
4063 factory()->NewTryCatchStatement(try_block, nullptr, catch_block, nopos);
4064 }
4065
4066 // let output = %_Call(iteratorReturn, iterator);
4067 // if (!IS_RECEIVER(output)) {
4068 // %ThrowIteratorResultNotAnObject(output);
4069 // }
4070 Block* validate_return;
4071 {
4072 Variable* var_output = NewTemporary(ast_value_factory()->empty_string());
4073 Statement* call_return;
4074 {
4075 auto args = new (zone()) ZonePtrList<Expression>(2, zone());
4076 args->Add(factory()->NewVariableProxy(var_return), zone());
4077 args->Add(factory()->NewVariableProxy(iterator), zone());
4078 Expression* call =
4079 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
4080 if (type == IteratorType::kAsync) {
4081 function_state_->AddSuspend();
4082 call = factory()->NewAwait(call, nopos);
4083 }
4084
4085 Expression* output_proxy = factory()->NewVariableProxy(var_output);
4086 Expression* assignment =
4087 factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
4088 call_return = factory()->NewExpressionStatement(assignment, nopos);
4089 }
4090
4091 Expression* is_receiver_call;
4092 {
4093 auto args = new (zone()) ZonePtrList<Expression>(1, zone());
4094 args->Add(factory()->NewVariableProxy(var_output), zone());
4095 is_receiver_call =
4096 factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
4097 }
4098
4099 Statement* throw_call;
4100 {
4101 auto args = new (zone()) ZonePtrList<Expression>(1, zone());
4102 args->Add(factory()->NewVariableProxy(var_output), zone());
4103 Expression* call = factory()->NewCallRuntime(
4104 Runtime::kThrowIteratorResultNotAnObject, args, nopos);
4105 throw_call = factory()->NewExpressionStatement(call, nopos);
4106 }
4107
4108 Statement* check_return = factory()->NewIfStatement(
4109 is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
4110 nopos);
4111
4112 validate_return = factory()->NewBlock(2, false);
4113 validate_return->statements()->Add(call_return, zone());
4114 validate_return->statements()->Add(check_return, zone());
4115 }
4116
4117 // if (completion === kThrowCompletion) {
4118 // #check_return_callable;
4119 // #try_call_return;
4120 // } else {
4121 // #validate_return;
4122 // }
4123 Statement* call_return_carefully;
4124 {
4125 Expression* condition = factory()->NewCompareOperation(
4126 Token::EQ_STRICT, completion,
4127 factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos);
4128
4129 Block* then_block = factory()->NewBlock(2, false);
4130 then_block->statements()->Add(check_return_callable, zone());
4131 then_block->statements()->Add(try_call_return, zone());
4132
4133 call_return_carefully = factory()->NewIfStatement(condition, then_block,
4134 validate_return, nopos);
4135 }
4136
4137 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... }
4138 Statement* maybe_call_return;
4139 {
4140 Expression* condition = factory()->NewCompareOperation(
4141 Token::EQ, factory()->NewVariableProxy(var_return),
4142 factory()->NewNullLiteral(nopos), nopos);
4143
4144 maybe_call_return = factory()->NewIfStatement(
4145 condition, factory()->NewEmptyStatement(nopos), call_return_carefully,
4146 nopos);
4147 }
4148
4149 statements->Add(get_return, zone());
4150 statements->Add(maybe_call_return, zone());
4151 }
4152
FinalizeForOfStatement(ForOfStatement * loop,Variable * var_completion,IteratorType type,int pos)4153 Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop,
4154 Variable* var_completion,
4155 IteratorType type, int pos) {
4156 //
4157 // This function replaces the loop with the following wrapping:
4158 //
4159 // completion = kNormalCompletion;
4160 // try {
4161 // try {
4162 // #loop;
4163 // } catch(e) {
4164 // if (completion === kAbruptCompletion) completion = kThrowCompletion;
4165 // %ReThrow(e);
4166 // }
4167 // } finally {
4168 // if (!(completion === kNormalCompletion)) {
4169 // #BuildIteratorCloseForCompletion(#iterator, completion)
4170 // }
4171 // }
4172 //
4173 // Note that the loop's body and its assign_each already contain appropriate
4174 // assignments to completion (see InitializeForOfStatement).
4175 //
4176
4177 const int nopos = kNoSourcePosition;
4178
4179 // !(completion === kNormalCompletion)
4180 Expression* closing_condition;
4181 {
4182 Expression* cmp = factory()->NewCompareOperation(
4183 Token::EQ_STRICT, factory()->NewVariableProxy(var_completion),
4184 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
4185 closing_condition = factory()->NewUnaryOperation(Token::NOT, cmp, nopos);
4186 }
4187
4188 Block* final_loop = factory()->NewBlock(2, false);
4189 {
4190 Block* try_block = factory()->NewBlock(1, false);
4191 try_block->statements()->Add(loop, zone());
4192
4193 FinalizeIteratorUse(var_completion, closing_condition, loop->iterator(),
4194 try_block, final_loop, type);
4195 }
4196
4197 return final_loop;
4198 }
4199
4200 #undef CHECK_OK
4201 #undef CHECK_OK_VOID
4202 #undef CHECK_FAILED
4203
4204 } // namespace internal
4205 } // namespace v8
4206