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