• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <memory>
8 
9 #include "src/api.h"
10 #include "src/ast/ast-expression-rewriter.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/bailout-reason.h"
15 #include "src/base/platform/platform.h"
16 #include "src/char-predicates-inl.h"
17 #include "src/messages.h"
18 #include "src/objects-inl.h"
19 #include "src/parsing/duplicate-finder.h"
20 #include "src/parsing/parameter-initializer-rewriter.h"
21 #include "src/parsing/parse-info.h"
22 #include "src/parsing/rewriter.h"
23 #include "src/parsing/scanner-character-streams.h"
24 #include "src/runtime/runtime.h"
25 #include "src/string-stream.h"
26 #include "src/tracing/trace-event.h"
27 
28 namespace v8 {
29 namespace internal {
30 
ScriptData(const byte * data,int length)31 ScriptData::ScriptData(const byte* data, int length)
32     : owns_data_(false), rejected_(false), data_(data), length_(length) {
33   if (!IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)) {
34     byte* copy = NewArray<byte>(length);
35     DCHECK(IsAligned(reinterpret_cast<intptr_t>(copy), kPointerAlignment));
36     CopyBytes(copy, data, length);
37     data_ = copy;
38     AcquireDataOwnership();
39   }
40 }
41 
GetFunctionEntry(int start)42 FunctionEntry ParseData::GetFunctionEntry(int start) {
43   // The current pre-data entry must be a FunctionEntry with the given
44   // start position.
45   if ((function_index_ + FunctionEntry::kSize <= Length()) &&
46       (static_cast<int>(Data()[function_index_]) == start)) {
47     int index = function_index_;
48     function_index_ += FunctionEntry::kSize;
49     Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize);
50     return FunctionEntry(subvector);
51   }
52   return FunctionEntry();
53 }
54 
55 
FunctionCount()56 int ParseData::FunctionCount() {
57   int functions_size = FunctionsSize();
58   if (functions_size < 0) return 0;
59   if (functions_size % FunctionEntry::kSize != 0) return 0;
60   return functions_size / FunctionEntry::kSize;
61 }
62 
63 
IsSane()64 bool ParseData::IsSane() {
65   if (!IsAligned(script_data_->length(), sizeof(unsigned))) return false;
66   // Check that the header data is valid and doesn't specify
67   // point to positions outside the store.
68   int data_length = Length();
69   if (data_length < PreparseDataConstants::kHeaderSize) return false;
70   if (Magic() != PreparseDataConstants::kMagicNumber) return false;
71   if (Version() != PreparseDataConstants::kCurrentVersion) return false;
72   // Check that the space allocated for function entries is sane.
73   int functions_size = FunctionsSize();
74   if (functions_size < 0) return false;
75   if (functions_size % FunctionEntry::kSize != 0) return false;
76   // Check that the total size has room for header and function entries.
77   int minimum_size =
78       PreparseDataConstants::kHeaderSize + functions_size;
79   if (data_length < minimum_size) return false;
80   return true;
81 }
82 
83 
Initialize()84 void ParseData::Initialize() {
85   // Prepares state for use.
86   int data_length = Length();
87   if (data_length >= PreparseDataConstants::kHeaderSize) {
88     function_index_ = PreparseDataConstants::kHeaderSize;
89   }
90 }
91 
92 
Magic()93 unsigned ParseData::Magic() {
94   return Data()[PreparseDataConstants::kMagicOffset];
95 }
96 
97 
Version()98 unsigned ParseData::Version() {
99   return Data()[PreparseDataConstants::kVersionOffset];
100 }
101 
102 
FunctionsSize()103 int ParseData::FunctionsSize() {
104   return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]);
105 }
106 
107 // Helper for putting parts of the parse results into a temporary zone when
108 // parsing inner function bodies.
109 class DiscardableZoneScope {
110  public:
DiscardableZoneScope(Parser * parser,Zone * temp_zone,bool use_temp_zone)111   DiscardableZoneScope(Parser* parser, Zone* temp_zone, bool use_temp_zone)
112       : ast_node_factory_scope_(parser->factory(), temp_zone, use_temp_zone),
113         fni_(parser->ast_value_factory_, temp_zone),
114         parser_(parser),
115         prev_fni_(parser->fni_),
116         prev_zone_(parser->zone_),
117         prev_allow_lazy_(parser->allow_lazy_),
118         prev_temp_zoned_(parser->temp_zoned_) {
119     if (use_temp_zone) {
120       DCHECK(!parser_->temp_zoned_);
121       parser_->allow_lazy_ = false;
122       parser_->temp_zoned_ = true;
123       parser_->fni_ = &fni_;
124       parser_->zone_ = temp_zone;
125       if (parser_->reusable_preparser_ != nullptr) {
126         parser_->reusable_preparser_->zone_ = temp_zone;
127         parser_->reusable_preparser_->factory()->set_zone(temp_zone);
128       }
129     }
130   }
Reset()131   void Reset() {
132     parser_->fni_ = prev_fni_;
133     parser_->zone_ = prev_zone_;
134     parser_->allow_lazy_ = prev_allow_lazy_;
135     parser_->temp_zoned_ = prev_temp_zoned_;
136     if (parser_->reusable_preparser_ != nullptr) {
137       parser_->reusable_preparser_->zone_ = prev_zone_;
138       parser_->reusable_preparser_->factory()->set_zone(prev_zone_);
139     }
140     ast_node_factory_scope_.Reset();
141   }
~DiscardableZoneScope()142   ~DiscardableZoneScope() { Reset(); }
143 
144  private:
145   AstNodeFactory::BodyScope ast_node_factory_scope_;
146   FuncNameInferrer fni_;
147   Parser* parser_;
148   FuncNameInferrer* prev_fni_;
149   Zone* prev_zone_;
150   bool prev_allow_lazy_;
151   bool prev_temp_zoned_;
152 
153   DISALLOW_COPY_AND_ASSIGN(DiscardableZoneScope);
154 };
155 
SetCachedData(ParseInfo * info)156 void Parser::SetCachedData(ParseInfo* info) {
157   DCHECK_NULL(cached_parse_data_);
158   if (consume_cached_parse_data()) {
159     if (allow_lazy_) {
160       cached_parse_data_ = ParseData::FromCachedData(*info->cached_data());
161       if (cached_parse_data_ != nullptr) return;
162     }
163     compile_options_ = ScriptCompiler::kNoCompileOptions;
164   }
165 }
166 
DefaultConstructor(const AstRawString * name,bool call_super,int pos,int end_pos)167 FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name,
168                                             bool call_super, int pos,
169                                             int end_pos) {
170   int expected_property_count = -1;
171   const int parameter_count = 0;
172   if (name == nullptr) name = ast_value_factory()->empty_string();
173 
174   FunctionKind kind = call_super ? FunctionKind::kDefaultDerivedConstructor
175                                  : FunctionKind::kDefaultBaseConstructor;
176   DeclarationScope* function_scope = NewFunctionScope(kind);
177   SetLanguageMode(function_scope, STRICT);
178   // Set start and end position to the same value
179   function_scope->set_start_position(pos);
180   function_scope->set_end_position(pos);
181   ZoneList<Statement*>* body = NULL;
182 
183   {
184     FunctionState function_state(&function_state_, &scope_, function_scope);
185 
186     body = new (zone()) ZoneList<Statement*>(call_super ? 2 : 1, zone());
187     if (call_super) {
188       // Create a SuperCallReference and handle in BytecodeGenerator.
189       auto constructor_args_name = ast_value_factory()->empty_string();
190       bool is_duplicate;
191       bool is_rest = true;
192       bool is_optional = false;
193       Variable* constructor_args = function_scope->DeclareParameter(
194           constructor_args_name, TEMPORARY, is_optional, is_rest, &is_duplicate,
195           ast_value_factory());
196 
197       ZoneList<Expression*>* args =
198           new (zone()) ZoneList<Expression*>(1, zone());
199       Spread* spread_args = factory()->NewSpread(
200           factory()->NewVariableProxy(constructor_args), pos, pos);
201 
202       args->Add(spread_args, zone());
203       Expression* super_call_ref = NewSuperCallReference(pos);
204       Expression* call = factory()->NewCall(super_call_ref, args, pos);
205       body->Add(factory()->NewReturnStatement(call, pos), zone());
206     }
207 
208     expected_property_count = function_state.expected_property_count();
209   }
210 
211   FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
212       name, function_scope, body, expected_property_count, parameter_count,
213       parameter_count, FunctionLiteral::kNoDuplicateParameters,
214       FunctionLiteral::kAnonymousExpression, default_eager_compile_hint(), pos,
215       true, GetNextFunctionLiteralId());
216 
217   return function_literal;
218 }
219 
220 // ----------------------------------------------------------------------------
221 // The CHECK_OK macro is a convenient macro to enforce error
222 // handling for functions that may fail (by returning !*ok).
223 //
224 // CAUTION: This macro appends extra statements after a call,
225 // thus it must never be used where only a single statement
226 // is correct (e.g. an if statement branch w/o braces)!
227 
228 #define CHECK_OK_VALUE(x) ok); \
229   if (!*ok) return x;          \
230   ((void)0
231 #define DUMMY )  // to make indentation work
232 #undef DUMMY
233 
234 #define CHECK_OK CHECK_OK_VALUE(nullptr)
235 #define CHECK_OK_VOID CHECK_OK_VALUE(this->Void())
236 
237 #define CHECK_FAILED /**/); \
238   if (failed_) return nullptr;  \
239   ((void)0
240 #define DUMMY )  // to make indentation work
241 #undef DUMMY
242 
243 // ----------------------------------------------------------------------------
244 // Implementation of Parser
245 
ShortcutNumericLiteralBinaryExpression(Expression ** x,Expression * y,Token::Value op,int pos)246 bool Parser::ShortcutNumericLiteralBinaryExpression(Expression** x,
247                                                     Expression* y,
248                                                     Token::Value op, int pos) {
249   if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() &&
250       y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) {
251     double x_val = (*x)->AsLiteral()->raw_value()->AsNumber();
252     double y_val = y->AsLiteral()->raw_value()->AsNumber();
253     bool x_has_dot = (*x)->AsLiteral()->raw_value()->ContainsDot();
254     bool y_has_dot = y->AsLiteral()->raw_value()->ContainsDot();
255     bool has_dot = x_has_dot || y_has_dot;
256     switch (op) {
257       case Token::ADD:
258         *x = factory()->NewNumberLiteral(x_val + y_val, pos, has_dot);
259         return true;
260       case Token::SUB:
261         *x = factory()->NewNumberLiteral(x_val - y_val, pos, has_dot);
262         return true;
263       case Token::MUL:
264         *x = factory()->NewNumberLiteral(x_val * y_val, pos, has_dot);
265         return true;
266       case Token::DIV:
267         *x = factory()->NewNumberLiteral(x_val / y_val, pos, has_dot);
268         return true;
269       case Token::BIT_OR: {
270         int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
271         *x = factory()->NewNumberLiteral(value, pos, has_dot);
272         return true;
273       }
274       case Token::BIT_AND: {
275         int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
276         *x = factory()->NewNumberLiteral(value, pos, has_dot);
277         return true;
278       }
279       case Token::BIT_XOR: {
280         int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
281         *x = factory()->NewNumberLiteral(value, pos, has_dot);
282         return true;
283       }
284       case Token::SHL: {
285         int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
286         *x = factory()->NewNumberLiteral(value, pos, has_dot);
287         return true;
288       }
289       case Token::SHR: {
290         uint32_t shift = DoubleToInt32(y_val) & 0x1f;
291         uint32_t value = DoubleToUint32(x_val) >> shift;
292         *x = factory()->NewNumberLiteral(value, pos, has_dot);
293         return true;
294       }
295       case Token::SAR: {
296         uint32_t shift = DoubleToInt32(y_val) & 0x1f;
297         int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
298         *x = factory()->NewNumberLiteral(value, pos, has_dot);
299         return true;
300       }
301       case Token::EXP: {
302         double value = Pow(x_val, y_val);
303         int int_value = static_cast<int>(value);
304         *x = factory()->NewNumberLiteral(
305             int_value == value && value != -0.0 ? int_value : value, pos,
306             has_dot);
307         return true;
308       }
309       default:
310         break;
311     }
312   }
313   return false;
314 }
315 
BuildUnaryExpression(Expression * expression,Token::Value op,int pos)316 Expression* Parser::BuildUnaryExpression(Expression* expression,
317                                          Token::Value op, int pos) {
318   DCHECK(expression != NULL);
319   if (expression->IsLiteral()) {
320     const AstValue* literal = expression->AsLiteral()->raw_value();
321     if (op == Token::NOT) {
322       // Convert the literal to a boolean condition and negate it.
323       bool condition = literal->BooleanValue();
324       return factory()->NewBooleanLiteral(!condition, pos);
325     } else if (literal->IsNumber()) {
326       // Compute some expressions involving only number literals.
327       double value = literal->AsNumber();
328       bool has_dot = literal->ContainsDot();
329       switch (op) {
330         case Token::ADD:
331           return expression;
332         case Token::SUB:
333           return factory()->NewNumberLiteral(-value, pos, has_dot);
334         case Token::BIT_NOT:
335           return factory()->NewNumberLiteral(~DoubleToInt32(value), pos,
336                                              has_dot);
337         default:
338           break;
339       }
340     }
341   }
342   // Desugar '+foo' => 'foo*1'
343   if (op == Token::ADD) {
344     return factory()->NewBinaryOperation(
345         Token::MUL, expression, factory()->NewNumberLiteral(1, pos, true), pos);
346   }
347   // The same idea for '-foo' => 'foo*(-1)'.
348   if (op == Token::SUB) {
349     return factory()->NewBinaryOperation(
350         Token::MUL, expression, factory()->NewNumberLiteral(-1, pos), pos);
351   }
352   // ...and one more time for '~foo' => 'foo^(~0)'.
353   if (op == Token::BIT_NOT) {
354     return factory()->NewBinaryOperation(
355         Token::BIT_XOR, expression, factory()->NewNumberLiteral(~0, pos), pos);
356   }
357   return factory()->NewUnaryOperation(op, expression, pos);
358 }
359 
BuildIteratorResult(Expression * value,bool done)360 Expression* Parser::BuildIteratorResult(Expression* value, bool done) {
361   int pos = kNoSourcePosition;
362 
363   if (value == nullptr) value = factory()->NewUndefinedLiteral(pos);
364 
365   auto args = new (zone()) ZoneList<Expression*>(2, zone());
366   args->Add(value, zone());
367   args->Add(factory()->NewBooleanLiteral(done, pos), zone());
368 
369   return factory()->NewCallRuntime(Runtime::kInlineCreateIterResultObject, args,
370                                    pos);
371 }
372 
NewThrowError(Runtime::FunctionId id,MessageTemplate::Template message,const AstRawString * arg,int pos)373 Expression* Parser::NewThrowError(Runtime::FunctionId id,
374                                   MessageTemplate::Template message,
375                                   const AstRawString* arg, int pos) {
376   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
377   args->Add(factory()->NewSmiLiteral(message, pos), zone());
378   args->Add(factory()->NewStringLiteral(arg, pos), zone());
379   CallRuntime* call_constructor = factory()->NewCallRuntime(id, args, pos);
380   return factory()->NewThrow(call_constructor, pos);
381 }
382 
NewSuperPropertyReference(int pos)383 Expression* Parser::NewSuperPropertyReference(int pos) {
384   // this_function[home_object_symbol]
385   VariableProxy* this_function_proxy =
386       NewUnresolved(ast_value_factory()->this_function_string(), pos);
387   Expression* home_object_symbol_literal = factory()->NewSymbolLiteral(
388       AstSymbol::kHomeObjectSymbol, kNoSourcePosition);
389   Expression* home_object = factory()->NewProperty(
390       this_function_proxy, home_object_symbol_literal, pos);
391   return factory()->NewSuperPropertyReference(
392       ThisExpression(pos)->AsVariableProxy(), home_object, pos);
393 }
394 
NewSuperCallReference(int pos)395 Expression* Parser::NewSuperCallReference(int pos) {
396   VariableProxy* new_target_proxy =
397       NewUnresolved(ast_value_factory()->new_target_string(), pos);
398   VariableProxy* this_function_proxy =
399       NewUnresolved(ast_value_factory()->this_function_string(), pos);
400   return factory()->NewSuperCallReference(
401       ThisExpression(pos)->AsVariableProxy(), new_target_proxy,
402       this_function_proxy, pos);
403 }
404 
NewTargetExpression(int pos)405 Expression* Parser::NewTargetExpression(int pos) {
406   auto proxy = NewUnresolved(ast_value_factory()->new_target_string(), pos);
407   proxy->set_is_new_target();
408   return proxy;
409 }
410 
FunctionSentExpression(int pos)411 Expression* Parser::FunctionSentExpression(int pos) {
412   // We desugar function.sent into %_GeneratorGetInputOrDebugPos(generator).
413   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
414   VariableProxy* generator =
415       factory()->NewVariableProxy(function_state_->generator_object_variable());
416   args->Add(generator, zone());
417   return factory()->NewCallRuntime(Runtime::kInlineGeneratorGetInputOrDebugPos,
418                                    args, pos);
419 }
420 
ExpressionFromLiteral(Token::Value token,int pos)421 Literal* Parser::ExpressionFromLiteral(Token::Value token, int pos) {
422   switch (token) {
423     case Token::NULL_LITERAL:
424       return factory()->NewNullLiteral(pos);
425     case Token::TRUE_LITERAL:
426       return factory()->NewBooleanLiteral(true, pos);
427     case Token::FALSE_LITERAL:
428       return factory()->NewBooleanLiteral(false, pos);
429     case Token::SMI: {
430       uint32_t value = scanner()->smi_value();
431       return factory()->NewSmiLiteral(value, pos);
432     }
433     case Token::NUMBER: {
434       bool has_dot = scanner()->ContainsDot();
435       double value = scanner()->DoubleValue();
436       return factory()->NewNumberLiteral(value, pos, has_dot);
437     }
438     default:
439       DCHECK(false);
440   }
441   return NULL;
442 }
443 
MarkTailPosition(Expression * expression)444 void Parser::MarkTailPosition(Expression* expression) {
445   expression->MarkTail();
446 }
447 
NewV8Intrinsic(const AstRawString * name,ZoneList<Expression * > * args,int pos,bool * ok)448 Expression* Parser::NewV8Intrinsic(const AstRawString* name,
449                                    ZoneList<Expression*>* args, int pos,
450                                    bool* ok) {
451   if (extension_ != nullptr) {
452     // The extension structures are only accessible while parsing the
453     // very first time, not when reparsing because of lazy compilation.
454     GetClosureScope()->ForceEagerCompilation();
455   }
456 
457   DCHECK(name->is_one_byte());
458   const Runtime::Function* function =
459       Runtime::FunctionForName(name->raw_data(), name->length());
460 
461   if (function != nullptr) {
462     // Check for possible name clash.
463     DCHECK_EQ(Context::kNotFound,
464               Context::IntrinsicIndexForName(name->raw_data(), name->length()));
465     // Check for built-in IS_VAR macro.
466     if (function->function_id == Runtime::kIS_VAR) {
467       DCHECK_EQ(Runtime::RUNTIME, function->intrinsic_type);
468       // %IS_VAR(x) evaluates to x if x is a variable,
469       // leads to a parse error otherwise.  Could be implemented as an
470       // inline function %_IS_VAR(x) to eliminate this special case.
471       if (args->length() == 1 && args->at(0)->AsVariableProxy() != nullptr) {
472         return args->at(0);
473       } else {
474         ReportMessage(MessageTemplate::kNotIsvar);
475         *ok = false;
476         return nullptr;
477       }
478     }
479 
480     // Check that the expected number of arguments are being passed.
481     if (function->nargs != -1 && function->nargs != args->length()) {
482       ReportMessage(MessageTemplate::kRuntimeWrongNumArgs);
483       *ok = false;
484       return nullptr;
485     }
486 
487     return factory()->NewCallRuntime(function, args, pos);
488   }
489 
490   int context_index =
491       Context::IntrinsicIndexForName(name->raw_data(), name->length());
492 
493   // Check that the function is defined.
494   if (context_index == Context::kNotFound) {
495     ReportMessage(MessageTemplate::kNotDefined, name);
496     *ok = false;
497     return nullptr;
498   }
499 
500   return factory()->NewCallRuntime(context_index, args, pos);
501 }
502 
Parser(ParseInfo * info)503 Parser::Parser(ParseInfo* info)
504     : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(),
505                          info->extension(), info->ast_value_factory(),
506                          info->isolate()->counters()->runtime_call_stats(),
507                          true),
508       scanner_(info->unicode_cache()),
509       reusable_preparser_(nullptr),
510       original_scope_(nullptr),
511       mode_(PARSE_EAGERLY),  // Lazy mode must be set explicitly.
512       target_stack_(nullptr),
513       compile_options_(info->compile_options()),
514       cached_parse_data_(nullptr),
515       total_preparse_skipped_(0),
516       temp_zoned_(false),
517       log_(nullptr),
518       preparsed_scope_data_(info->preparsed_scope_data()),
519       parameters_end_pos_(info->parameters_end_pos()) {
520   // Even though we were passed ParseInfo, we should not store it in
521   // Parser - this makes sure that Isolate is not accidentally accessed via
522   // ParseInfo during background parsing.
523   DCHECK(!info->script().is_null() || info->source_stream() != nullptr ||
524          info->character_stream() != nullptr);
525   // Determine if functions can be lazily compiled. This is necessary to
526   // allow some of our builtin JS files to be lazily compiled. These
527   // builtins cannot be handled lazily by the parser, since we have to know
528   // if a function uses the special natives syntax, which is something the
529   // parser records.
530   // If the debugger requests compilation for break points, we cannot be
531   // aggressive about lazy compilation, because it might trigger compilation
532   // of functions without an outer context when setting a breakpoint through
533   // Debug::FindSharedFunctionInfoInScript
534   bool can_compile_lazily = FLAG_lazy && !info->is_debug();
535 
536   // Consider compiling eagerly when targeting the code cache.
537   can_compile_lazily &= !(FLAG_serialize_eager && info->will_serialize());
538 
539   set_default_eager_compile_hint(can_compile_lazily
540                                      ? FunctionLiteral::kShouldLazyCompile
541                                      : FunctionLiteral::kShouldEagerCompile);
542   allow_lazy_ = FLAG_lazy && info->allow_lazy_parsing() && !info->is_native() &&
543                 info->extension() == nullptr && can_compile_lazily;
544   set_allow_natives(FLAG_allow_natives_syntax || info->is_native());
545   set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() &&
546                       info->isolate()->is_tail_call_elimination_enabled());
547   set_allow_harmony_do_expressions(FLAG_harmony_do_expressions);
548   set_allow_harmony_function_sent(FLAG_harmony_function_sent);
549   set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators);
550   set_allow_harmony_trailing_commas(FLAG_harmony_trailing_commas);
551   set_allow_harmony_class_fields(FLAG_harmony_class_fields);
552   set_allow_harmony_object_rest_spread(FLAG_harmony_object_rest_spread);
553   set_allow_harmony_dynamic_import(FLAG_harmony_dynamic_import);
554   set_allow_harmony_async_iteration(FLAG_harmony_async_iteration);
555   set_allow_harmony_template_escapes(FLAG_harmony_template_escapes);
556   for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
557        ++feature) {
558     use_counts_[feature] = 0;
559   }
560   if (info->ast_value_factory() == NULL) {
561     // info takes ownership of AstValueFactory.
562     info->set_ast_value_factory(new AstValueFactory(
563         zone(), info->isolate()->ast_string_constants(), info->hash_seed()));
564     info->set_ast_value_factory_owned();
565     ast_value_factory_ = info->ast_value_factory();
566     ast_node_factory_.set_ast_value_factory(ast_value_factory_);
567   }
568 }
569 
DeserializeScopeChain(ParseInfo * info,MaybeHandle<ScopeInfo> maybe_outer_scope_info)570 void Parser::DeserializeScopeChain(
571     ParseInfo* info, MaybeHandle<ScopeInfo> maybe_outer_scope_info) {
572   DCHECK(ThreadId::Current().Equals(info->isolate()->thread_id()));
573   // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native
574   // context, which will have the "this" binding for script scopes.
575   DeclarationScope* script_scope = NewScriptScope();
576   info->set_script_scope(script_scope);
577   Scope* scope = script_scope;
578   Handle<ScopeInfo> outer_scope_info;
579   if (maybe_outer_scope_info.ToHandle(&outer_scope_info)) {
580     scope = Scope::DeserializeScopeChain(
581         info->isolate(), zone(), *outer_scope_info, script_scope,
582         ast_value_factory(), Scope::DeserializationMode::kScopesOnly);
583     DCHECK(!info->is_module() || scope->is_module_scope());
584   }
585   original_scope_ = scope;
586 }
587 
ParseProgram(Isolate * isolate,ParseInfo * info)588 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
589   // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
590   // see comment for HistogramTimerScope class.
591 
592   // It's OK to use the Isolate & counters here, since this function is only
593   // called in the main thread.
594   DCHECK(parsing_on_main_thread_);
595   RuntimeCallTimerScope runtime_timer(
596       runtime_call_stats_, info->is_eval() ? &RuntimeCallStats::ParseEval
597                                            : &RuntimeCallStats::ParseProgram);
598   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram");
599   Handle<String> source(String::cast(info->script()->source()));
600   isolate->counters()->total_parse_size()->Increment(source->length());
601   base::ElapsedTimer timer;
602   if (FLAG_trace_parse) {
603     timer.Start();
604   }
605   fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
606 
607   // Initialize parser state.
608   ParserLogger logger;
609 
610   if (produce_cached_parse_data()) {
611     if (allow_lazy_) {
612       log_ = &logger;
613     } else {
614       compile_options_ = ScriptCompiler::kNoCompileOptions;
615     }
616   } else if (consume_cached_parse_data()) {
617     cached_parse_data_->Initialize();
618   }
619 
620   DeserializeScopeChain(info, info->maybe_outer_scope_info());
621 
622   source = String::Flatten(source);
623   FunctionLiteral* result;
624 
625   {
626     std::unique_ptr<Utf16CharacterStream> stream(ScannerStream::For(source));
627     scanner_.Initialize(stream.get());
628     result = DoParseProgram(info);
629   }
630   if (result != NULL) {
631     DCHECK_EQ(scanner_.peek_location().beg_pos, source->length());
632   }
633   HandleSourceURLComments(isolate, info->script());
634 
635   if (FLAG_trace_parse && result != nullptr) {
636     double ms = timer.Elapsed().InMillisecondsF();
637     if (info->is_eval()) {
638       PrintF("[parsing eval");
639     } else if (info->script()->name()->IsString()) {
640       String* name = String::cast(info->script()->name());
641       std::unique_ptr<char[]> name_chars = name->ToCString();
642       PrintF("[parsing script: %s", name_chars.get());
643     } else {
644       PrintF("[parsing script");
645     }
646     PrintF(" - took %0.3f ms]\n", ms);
647   }
648   if (produce_cached_parse_data() && result != nullptr) {
649     *info->cached_data() = logger.GetScriptData();
650   }
651   log_ = nullptr;
652   return result;
653 }
654 
655 
DoParseProgram(ParseInfo * info)656 FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
657   // Note that this function can be called from the main thread or from a
658   // background thread. We should not access anything Isolate / heap dependent
659   // via ParseInfo, and also not pass it forward.
660   DCHECK_NULL(scope_);
661   DCHECK_NULL(target_stack_);
662 
663   ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
664   ResetFunctionLiteralId();
665   DCHECK(info->function_literal_id() == FunctionLiteral::kIdTypeTopLevel ||
666          info->function_literal_id() == FunctionLiteral::kIdTypeInvalid);
667 
668   FunctionLiteral* result = NULL;
669   {
670     Scope* outer = original_scope_;
671     DCHECK_NOT_NULL(outer);
672     parsing_module_ = info->is_module();
673     if (info->is_eval()) {
674       outer = NewEvalScope(outer);
675     } else if (parsing_module_) {
676       DCHECK_EQ(outer, info->script_scope());
677       outer = NewModuleScope(info->script_scope());
678     }
679 
680     DeclarationScope* scope = outer->AsDeclarationScope();
681 
682     scope->set_start_position(0);
683 
684     FunctionState function_state(&function_state_, &scope_, scope);
685 
686     ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
687     bool ok = true;
688     int beg_pos = scanner()->location().beg_pos;
689     if (parsing_module_) {
690       // Declare the special module parameter.
691       auto name = ast_value_factory()->empty_string();
692       bool is_duplicate;
693       bool is_rest = false;
694       bool is_optional = false;
695       auto var = scope->DeclareParameter(name, VAR, is_optional, is_rest,
696                                          &is_duplicate, ast_value_factory());
697       DCHECK(!is_duplicate);
698       var->AllocateTo(VariableLocation::PARAMETER, 0);
699 
700       PrepareGeneratorVariables();
701       Expression* initial_yield =
702           BuildInitialYield(kNoSourcePosition, kGeneratorFunction);
703       body->Add(
704           factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
705           zone());
706 
707       ParseModuleItemList(body, &ok);
708       ok = ok &&
709            module()->Validate(this->scope()->AsModuleScope(),
710                               &pending_error_handler_, zone());
711     } else {
712       // Don't count the mode in the use counters--give the program a chance
713       // to enable script-wide strict mode below.
714       this->scope()->SetLanguageMode(info->language_mode());
715       ParseStatementList(body, Token::EOS, &ok);
716     }
717 
718     // The parser will peek but not consume EOS.  Our scope logically goes all
719     // the way to the EOS, though.
720     scope->set_end_position(scanner()->peek_location().beg_pos);
721 
722     if (ok && is_strict(language_mode())) {
723       CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
724     }
725     if (ok && is_sloppy(language_mode())) {
726       // TODO(littledan): Function bindings on the global object that modify
727       // pre-existing bindings should be made writable, enumerable and
728       // nonconfigurable if possible, whereas this code will leave attributes
729       // unchanged if the property already exists.
730       InsertSloppyBlockFunctionVarBindings(scope);
731     }
732     if (ok) {
733       CheckConflictingVarDeclarations(scope, &ok);
734     }
735 
736     if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
737       if (body->length() != 1 ||
738           !body->at(0)->IsExpressionStatement() ||
739           !body->at(0)->AsExpressionStatement()->
740               expression()->IsFunctionLiteral()) {
741         ReportMessage(MessageTemplate::kSingleFunctionLiteral);
742         ok = false;
743       }
744     }
745 
746     if (ok) {
747       RewriteDestructuringAssignments();
748       int parameter_count = parsing_module_ ? 1 : 0;
749       result = factory()->NewScriptOrEvalFunctionLiteral(
750           scope, body, function_state.expected_property_count(),
751           parameter_count);
752     }
753   }
754 
755   info->set_max_function_literal_id(GetLastFunctionLiteralId());
756 
757   // Make sure the target stack is empty.
758   DCHECK(target_stack_ == NULL);
759 
760   return result;
761 }
762 
ParseFunction(Isolate * isolate,ParseInfo * info)763 FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info) {
764   // It's OK to use the Isolate & counters here, since this function is only
765   // called in the main thread.
766   DCHECK(parsing_on_main_thread_);
767   RuntimeCallTimerScope runtime_timer(runtime_call_stats_,
768                                       &RuntimeCallStats::ParseFunction);
769   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseFunction");
770   Handle<String> source(String::cast(info->script()->source()));
771   isolate->counters()->total_parse_size()->Increment(source->length());
772   base::ElapsedTimer timer;
773   if (FLAG_trace_parse) {
774     timer.Start();
775   }
776   Handle<SharedFunctionInfo> shared_info = info->shared_info();
777   DeserializeScopeChain(info, info->maybe_outer_scope_info());
778   if (info->asm_function_scope()) {
779     original_scope_ = info->asm_function_scope();
780     factory()->set_zone(info->zone());
781   } else {
782     DCHECK_EQ(factory()->zone(), info->zone());
783   }
784 
785   // Initialize parser state.
786   source = String::Flatten(source);
787   FunctionLiteral* result;
788   {
789     std::unique_ptr<Utf16CharacterStream> stream(ScannerStream::For(
790         source, shared_info->start_position(), shared_info->end_position()));
791     Handle<String> name(String::cast(shared_info->name()));
792     result = DoParseFunction(info, ast_value_factory()->GetString(name),
793                              stream.get());
794     if (result != nullptr) {
795       Handle<String> inferred_name(shared_info->inferred_name());
796       result->set_inferred_name(inferred_name);
797     }
798   }
799 
800   if (FLAG_trace_parse && result != NULL) {
801     double ms = timer.Elapsed().InMillisecondsF();
802     // We need to make sure that the debug-name is available.
803     ast_value_factory()->Internalize(isolate);
804     std::unique_ptr<char[]> name_chars = result->debug_name()->ToCString();
805     PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms);
806   }
807   return result;
808 }
809 
ComputeFunctionType(ParseInfo * info)810 static FunctionLiteral::FunctionType ComputeFunctionType(ParseInfo* info) {
811   if (info->is_declaration()) {
812     return FunctionLiteral::kDeclaration;
813   } else if (info->is_named_expression()) {
814     return FunctionLiteral::kNamedExpression;
815   } else if (IsConciseMethod(info->function_kind()) ||
816              IsAccessorFunction(info->function_kind())) {
817     return FunctionLiteral::kAccessorOrMethod;
818   }
819   return FunctionLiteral::kAnonymousExpression;
820 }
821 
DoParseFunction(ParseInfo * info,const AstRawString * raw_name,Utf16CharacterStream * source)822 FunctionLiteral* Parser::DoParseFunction(ParseInfo* info,
823                                          const AstRawString* raw_name,
824                                          Utf16CharacterStream* source) {
825   scanner_.Initialize(source);
826   DCHECK_NULL(scope_);
827   DCHECK_NULL(target_stack_);
828 
829   DCHECK(ast_value_factory());
830   fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
831   fni_->PushEnclosingName(raw_name);
832 
833   ResetFunctionLiteralId();
834   DCHECK_LT(0, info->function_literal_id());
835   SkipFunctionLiterals(info->function_literal_id() - 1);
836 
837   ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
838 
839   // Place holder for the result.
840   FunctionLiteral* result = nullptr;
841 
842   {
843     // Parse the function literal.
844     Scope* outer = original_scope_;
845     DeclarationScope* outer_function = outer->GetClosureScope();
846     DCHECK(outer);
847     FunctionState function_state(&function_state_, &scope_, outer_function);
848     BlockState block_state(&scope_, outer);
849     DCHECK(is_sloppy(outer->language_mode()) ||
850            is_strict(info->language_mode()));
851     FunctionLiteral::FunctionType function_type = ComputeFunctionType(info);
852     FunctionKind kind = info->function_kind();
853     bool ok = true;
854 
855     if (IsArrowFunction(kind)) {
856       if (IsAsyncFunction(kind)) {
857         DCHECK(!scanner()->HasAnyLineTerminatorAfterNext());
858         if (!Check(Token::ASYNC)) {
859           CHECK(stack_overflow());
860           return nullptr;
861         }
862         if (!(peek_any_identifier() || peek() == Token::LPAREN)) {
863           CHECK(stack_overflow());
864           return nullptr;
865         }
866       }
867 
868       // TODO(adamk): We should construct this scope from the ScopeInfo.
869       DeclarationScope* scope = NewFunctionScope(kind);
870 
871       // These two bits only need to be explicitly set because we're
872       // not passing the ScopeInfo to the Scope constructor.
873       // TODO(adamk): Remove these calls once the above NewScope call
874       // passes the ScopeInfo.
875       if (info->calls_eval()) {
876         scope->RecordEvalCall();
877       }
878       SetLanguageMode(scope, info->language_mode());
879 
880       scope->set_start_position(info->start_position());
881       ExpressionClassifier formals_classifier(this);
882       ParserFormalParameters formals(scope);
883       int rewritable_length =
884           function_state.destructuring_assignments_to_rewrite().length();
885       Checkpoint checkpoint(this);
886       {
887         // Parsing patterns as variable reference expression creates
888         // NewUnresolved references in current scope. Entrer arrow function
889         // scope for formal parameter parsing.
890         BlockState block_state(&scope_, scope);
891         if (Check(Token::LPAREN)) {
892           // '(' StrictFormalParameters ')'
893           ParseFormalParameterList(&formals, &ok);
894           if (ok) ok = Check(Token::RPAREN);
895         } else {
896           // BindingIdentifier
897           ParseFormalParameter(&formals, &ok);
898           if (ok) DeclareFormalParameters(formals.scope, formals.params);
899         }
900       }
901 
902       if (ok) {
903         checkpoint.Restore(&formals.materialized_literals_count);
904         if (GetLastFunctionLiteralId() != info->function_literal_id() - 1) {
905           // If there were FunctionLiterals in the parameters, we need to
906           // renumber them to shift down so the next function literal id for
907           // the arrow function is the one requested.
908           AstFunctionLiteralIdReindexer reindexer(
909               stack_limit_,
910               (info->function_literal_id() - 1) - GetLastFunctionLiteralId());
911           for (auto p : formals.params) {
912             if (p->pattern != nullptr) reindexer.Reindex(p->pattern);
913             if (p->initializer != nullptr) reindexer.Reindex(p->initializer);
914           }
915           ResetFunctionLiteralId();
916           SkipFunctionLiterals(info->function_literal_id() - 1);
917         }
918 
919         // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should
920         // not be observable, or else the preparser would have failed.
921         Expression* expression =
922             ParseArrowFunctionLiteral(true, formals, rewritable_length, &ok);
923         if (ok) {
924           // Scanning must end at the same position that was recorded
925           // previously. If not, parsing has been interrupted due to a stack
926           // overflow, at which point the partially parsed arrow function
927           // concise body happens to be a valid expression. This is a problem
928           // only for arrow functions with single expression bodies, since there
929           // is no end token such as "}" for normal functions.
930           if (scanner()->location().end_pos == info->end_position()) {
931             // The pre-parser saw an arrow function here, so the full parser
932             // must produce a FunctionLiteral.
933             DCHECK(expression->IsFunctionLiteral());
934             result = expression->AsFunctionLiteral();
935             // Rewrite destructuring assignments in the parameters. (The ones
936             // inside the function body are rewritten by
937             // ParseArrowFunctionLiteral.)
938             RewriteDestructuringAssignments();
939           } else {
940             ok = false;
941           }
942         }
943       }
944     } else if (IsDefaultConstructor(kind)) {
945       DCHECK_EQ(scope(), outer);
946       result = DefaultConstructor(raw_name, IsDerivedConstructor(kind),
947                                   info->start_position(), info->end_position());
948     } else {
949       result = ParseFunctionLiteral(
950           raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind,
951           kNoSourcePosition, function_type, info->language_mode(), &ok);
952     }
953     // Make sure the results agree.
954     DCHECK(ok == (result != nullptr));
955   }
956 
957   // Make sure the target stack is empty.
958   DCHECK_NULL(target_stack_);
959   DCHECK_IMPLIES(result,
960                  info->function_literal_id() == result->function_literal_id());
961   return result;
962 }
963 
ParseModuleItem(bool * ok)964 Statement* Parser::ParseModuleItem(bool* ok) {
965   // ecma262/#prod-ModuleItem
966   // ModuleItem :
967   //    ImportDeclaration
968   //    ExportDeclaration
969   //    StatementListItem
970 
971   Token::Value next = peek();
972 
973   if (next == Token::EXPORT) {
974     return ParseExportDeclaration(ok);
975   }
976 
977   // We must be careful not to parse a dynamic import expression as an import
978   // declaration.
979   if (next == Token::IMPORT &&
980       (!allow_harmony_dynamic_import() || PeekAhead() != Token::LPAREN)) {
981     ParseImportDeclaration(CHECK_OK);
982     return factory()->NewEmptyStatement(kNoSourcePosition);
983   }
984 
985   return ParseStatementListItem(ok);
986 }
987 
988 
ParseModuleItemList(ZoneList<Statement * > * body,bool * ok)989 void Parser::ParseModuleItemList(ZoneList<Statement*>* body, bool* ok) {
990   // ecma262/#prod-Module
991   // Module :
992   //    ModuleBody?
993   //
994   // ecma262/#prod-ModuleItemList
995   // ModuleBody :
996   //    ModuleItem*
997 
998   DCHECK(scope()->is_module_scope());
999   while (peek() != Token::EOS) {
1000     Statement* stat = ParseModuleItem(CHECK_OK_VOID);
1001     if (stat && !stat->IsEmpty()) {
1002       body->Add(stat, zone());
1003     }
1004   }
1005 }
1006 
1007 
ParseModuleSpecifier(bool * ok)1008 const AstRawString* Parser::ParseModuleSpecifier(bool* ok) {
1009   // ModuleSpecifier :
1010   //    StringLiteral
1011 
1012   Expect(Token::STRING, CHECK_OK);
1013   return GetSymbol();
1014 }
1015 
1016 
ParseExportClause(ZoneList<const AstRawString * > * export_names,ZoneList<Scanner::Location> * export_locations,ZoneList<const AstRawString * > * local_names,Scanner::Location * reserved_loc,bool * ok)1017 void Parser::ParseExportClause(ZoneList<const AstRawString*>* export_names,
1018                                ZoneList<Scanner::Location>* export_locations,
1019                                ZoneList<const AstRawString*>* local_names,
1020                                Scanner::Location* reserved_loc, bool* ok) {
1021   // ExportClause :
1022   //   '{' '}'
1023   //   '{' ExportsList '}'
1024   //   '{' ExportsList ',' '}'
1025   //
1026   // ExportsList :
1027   //   ExportSpecifier
1028   //   ExportsList ',' ExportSpecifier
1029   //
1030   // ExportSpecifier :
1031   //   IdentifierName
1032   //   IdentifierName 'as' IdentifierName
1033 
1034   Expect(Token::LBRACE, CHECK_OK_VOID);
1035 
1036   Token::Value name_tok;
1037   while ((name_tok = peek()) != Token::RBRACE) {
1038     // Keep track of the first reserved word encountered in case our
1039     // caller needs to report an error.
1040     if (!reserved_loc->IsValid() &&
1041         !Token::IsIdentifier(name_tok, STRICT, false, parsing_module_)) {
1042       *reserved_loc = scanner()->location();
1043     }
1044     const AstRawString* local_name = ParseIdentifierName(CHECK_OK_VOID);
1045     const AstRawString* export_name = NULL;
1046     Scanner::Location location = scanner()->location();
1047     if (CheckContextualKeyword(CStrVector("as"))) {
1048       export_name = ParseIdentifierName(CHECK_OK_VOID);
1049       // Set the location to the whole "a as b" string, so that it makes sense
1050       // both for errors due to "a" and for errors due to "b".
1051       location.end_pos = scanner()->location().end_pos;
1052     }
1053     if (export_name == NULL) {
1054       export_name = local_name;
1055     }
1056     export_names->Add(export_name, zone());
1057     local_names->Add(local_name, zone());
1058     export_locations->Add(location, zone());
1059     if (peek() == Token::RBRACE) break;
1060     Expect(Token::COMMA, CHECK_OK_VOID);
1061   }
1062 
1063   Expect(Token::RBRACE, CHECK_OK_VOID);
1064 }
1065 
1066 
ParseNamedImports(int pos,bool * ok)1067 ZoneList<const Parser::NamedImport*>* Parser::ParseNamedImports(
1068     int pos, bool* ok) {
1069   // NamedImports :
1070   //   '{' '}'
1071   //   '{' ImportsList '}'
1072   //   '{' ImportsList ',' '}'
1073   //
1074   // ImportsList :
1075   //   ImportSpecifier
1076   //   ImportsList ',' ImportSpecifier
1077   //
1078   // ImportSpecifier :
1079   //   BindingIdentifier
1080   //   IdentifierName 'as' BindingIdentifier
1081 
1082   Expect(Token::LBRACE, CHECK_OK);
1083 
1084   auto result = new (zone()) ZoneList<const NamedImport*>(1, zone());
1085   while (peek() != Token::RBRACE) {
1086     const AstRawString* import_name = ParseIdentifierName(CHECK_OK);
1087     const AstRawString* local_name = import_name;
1088     Scanner::Location location = scanner()->location();
1089     // In the presence of 'as', the left-side of the 'as' can
1090     // be any IdentifierName. But without 'as', it must be a valid
1091     // BindingIdentifier.
1092     if (CheckContextualKeyword(CStrVector("as"))) {
1093       local_name = ParseIdentifierName(CHECK_OK);
1094     }
1095     if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false,
1096                              parsing_module_)) {
1097       *ok = false;
1098       ReportMessage(MessageTemplate::kUnexpectedReserved);
1099       return nullptr;
1100     } else if (IsEvalOrArguments(local_name)) {
1101       *ok = false;
1102       ReportMessage(MessageTemplate::kStrictEvalArguments);
1103       return nullptr;
1104     }
1105 
1106     DeclareVariable(local_name, CONST, kNeedsInitialization, position(),
1107                     CHECK_OK);
1108 
1109     NamedImport* import =
1110         new (zone()) NamedImport(import_name, local_name, location);
1111     result->Add(import, zone());
1112 
1113     if (peek() == Token::RBRACE) break;
1114     Expect(Token::COMMA, CHECK_OK);
1115   }
1116 
1117   Expect(Token::RBRACE, CHECK_OK);
1118   return result;
1119 }
1120 
1121 
ParseImportDeclaration(bool * ok)1122 void Parser::ParseImportDeclaration(bool* ok) {
1123   // ImportDeclaration :
1124   //   'import' ImportClause 'from' ModuleSpecifier ';'
1125   //   'import' ModuleSpecifier ';'
1126   //
1127   // ImportClause :
1128   //   ImportedDefaultBinding
1129   //   NameSpaceImport
1130   //   NamedImports
1131   //   ImportedDefaultBinding ',' NameSpaceImport
1132   //   ImportedDefaultBinding ',' NamedImports
1133   //
1134   // NameSpaceImport :
1135   //   '*' 'as' ImportedBinding
1136 
1137   int pos = peek_position();
1138   Expect(Token::IMPORT, CHECK_OK_VOID);
1139 
1140   Token::Value tok = peek();
1141 
1142   // 'import' ModuleSpecifier ';'
1143   if (tok == Token::STRING) {
1144     const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID);
1145     ExpectSemicolon(CHECK_OK_VOID);
1146     module()->AddEmptyImport(module_specifier);
1147     return;
1148   }
1149 
1150   // Parse ImportedDefaultBinding if present.
1151   const AstRawString* import_default_binding = nullptr;
1152   Scanner::Location import_default_binding_loc;
1153   if (tok != Token::MUL && tok != Token::LBRACE) {
1154     import_default_binding =
1155         ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK_VOID);
1156     import_default_binding_loc = scanner()->location();
1157     DeclareVariable(import_default_binding, CONST, kNeedsInitialization, pos,
1158                     CHECK_OK_VOID);
1159   }
1160 
1161   // Parse NameSpaceImport or NamedImports if present.
1162   const AstRawString* module_namespace_binding = nullptr;
1163   Scanner::Location module_namespace_binding_loc;
1164   const ZoneList<const NamedImport*>* named_imports = nullptr;
1165   if (import_default_binding == nullptr || Check(Token::COMMA)) {
1166     switch (peek()) {
1167       case Token::MUL: {
1168         Consume(Token::MUL);
1169         ExpectContextualKeyword(CStrVector("as"), CHECK_OK_VOID);
1170         module_namespace_binding =
1171             ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK_VOID);
1172         module_namespace_binding_loc = scanner()->location();
1173         DeclareVariable(module_namespace_binding, CONST, kCreatedInitialized,
1174                         pos, CHECK_OK_VOID);
1175         break;
1176       }
1177 
1178       case Token::LBRACE:
1179         named_imports = ParseNamedImports(pos, CHECK_OK_VOID);
1180         break;
1181 
1182       default:
1183         *ok = false;
1184         ReportUnexpectedToken(scanner()->current_token());
1185         return;
1186     }
1187   }
1188 
1189   ExpectContextualKeyword(CStrVector("from"), CHECK_OK_VOID);
1190   const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID);
1191   ExpectSemicolon(CHECK_OK_VOID);
1192 
1193   // Now that we have all the information, we can make the appropriate
1194   // declarations.
1195 
1196   // TODO(neis): Would prefer to call DeclareVariable for each case below rather
1197   // than above and in ParseNamedImports, but then a possible error message
1198   // would point to the wrong location.  Maybe have a DeclareAt version of
1199   // Declare that takes a location?
1200 
1201   if (module_namespace_binding != nullptr) {
1202     module()->AddStarImport(module_namespace_binding, module_specifier,
1203                             module_namespace_binding_loc, zone());
1204   }
1205 
1206   if (import_default_binding != nullptr) {
1207     module()->AddImport(ast_value_factory()->default_string(),
1208                         import_default_binding, module_specifier,
1209                         import_default_binding_loc, zone());
1210   }
1211 
1212   if (named_imports != nullptr) {
1213     if (named_imports->length() == 0) {
1214       module()->AddEmptyImport(module_specifier);
1215     } else {
1216       for (int i = 0; i < named_imports->length(); ++i) {
1217         const NamedImport* import = named_imports->at(i);
1218         module()->AddImport(import->import_name, import->local_name,
1219                             module_specifier, import->location, zone());
1220       }
1221     }
1222   }
1223 }
1224 
1225 
ParseExportDefault(bool * ok)1226 Statement* Parser::ParseExportDefault(bool* ok) {
1227   //  Supports the following productions, starting after the 'default' token:
1228   //    'export' 'default' HoistableDeclaration
1229   //    'export' 'default' ClassDeclaration
1230   //    'export' 'default' AssignmentExpression[In] ';'
1231 
1232   Expect(Token::DEFAULT, CHECK_OK);
1233   Scanner::Location default_loc = scanner()->location();
1234 
1235   ZoneList<const AstRawString*> local_names(1, zone());
1236   Statement* result = nullptr;
1237   switch (peek()) {
1238     case Token::FUNCTION:
1239       result = ParseHoistableDeclaration(&local_names, true, CHECK_OK);
1240       break;
1241 
1242     case Token::CLASS:
1243       Consume(Token::CLASS);
1244       result = ParseClassDeclaration(&local_names, true, CHECK_OK);
1245       break;
1246 
1247     case Token::ASYNC:
1248       if (PeekAhead() == Token::FUNCTION &&
1249           !scanner()->HasAnyLineTerminatorAfterNext()) {
1250         Consume(Token::ASYNC);
1251         result = ParseAsyncFunctionDeclaration(&local_names, true, CHECK_OK);
1252         break;
1253       }
1254     /* falls through */
1255 
1256     default: {
1257       int pos = position();
1258       ExpressionClassifier classifier(this);
1259       Expression* value = ParseAssignmentExpression(true, CHECK_OK);
1260       RewriteNonPattern(CHECK_OK);
1261       SetFunctionName(value, ast_value_factory()->default_string());
1262 
1263       const AstRawString* local_name =
1264           ast_value_factory()->star_default_star_string();
1265       local_names.Add(local_name, zone());
1266 
1267       // It's fine to declare this as CONST because the user has no way of
1268       // writing to it.
1269       Declaration* decl = DeclareVariable(local_name, CONST, pos, CHECK_OK);
1270       decl->proxy()->var()->set_initializer_position(position());
1271 
1272       Assignment* assignment = factory()->NewAssignment(
1273           Token::INIT, decl->proxy(), value, kNoSourcePosition);
1274       result = factory()->NewExpressionStatement(assignment, kNoSourcePosition);
1275 
1276       ExpectSemicolon(CHECK_OK);
1277       break;
1278     }
1279   }
1280 
1281   DCHECK_EQ(local_names.length(), 1);
1282   module()->AddExport(local_names.first(),
1283                       ast_value_factory()->default_string(), default_loc,
1284                       zone());
1285 
1286   DCHECK_NOT_NULL(result);
1287   return result;
1288 }
1289 
ParseExportDeclaration(bool * ok)1290 Statement* Parser::ParseExportDeclaration(bool* ok) {
1291   // ExportDeclaration:
1292   //    'export' '*' 'from' ModuleSpecifier ';'
1293   //    'export' ExportClause ('from' ModuleSpecifier)? ';'
1294   //    'export' VariableStatement
1295   //    'export' Declaration
1296   //    'export' 'default' ... (handled in ParseExportDefault)
1297 
1298   Expect(Token::EXPORT, CHECK_OK);
1299   int pos = position();
1300 
1301   Statement* result = nullptr;
1302   ZoneList<const AstRawString*> names(1, zone());
1303   Scanner::Location loc = scanner()->peek_location();
1304   switch (peek()) {
1305     case Token::DEFAULT:
1306       return ParseExportDefault(ok);
1307 
1308     case Token::MUL: {
1309       Consume(Token::MUL);
1310       loc = scanner()->location();
1311       ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1312       const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1313       ExpectSemicolon(CHECK_OK);
1314       module()->AddStarExport(module_specifier, loc, zone());
1315       return factory()->NewEmptyStatement(pos);
1316     }
1317 
1318     case Token::LBRACE: {
1319       // There are two cases here:
1320       //
1321       // 'export' ExportClause ';'
1322       // and
1323       // 'export' ExportClause FromClause ';'
1324       //
1325       // In the first case, the exported identifiers in ExportClause must
1326       // not be reserved words, while in the latter they may be. We
1327       // pass in a location that gets filled with the first reserved word
1328       // encountered, and then throw a SyntaxError if we are in the
1329       // non-FromClause case.
1330       Scanner::Location reserved_loc = Scanner::Location::invalid();
1331       ZoneList<const AstRawString*> export_names(1, zone());
1332       ZoneList<Scanner::Location> export_locations(1, zone());
1333       ZoneList<const AstRawString*> original_names(1, zone());
1334       ParseExportClause(&export_names, &export_locations, &original_names,
1335                         &reserved_loc, CHECK_OK);
1336       const AstRawString* module_specifier = nullptr;
1337       if (CheckContextualKeyword(CStrVector("from"))) {
1338         module_specifier = ParseModuleSpecifier(CHECK_OK);
1339       } else if (reserved_loc.IsValid()) {
1340         // No FromClause, so reserved words are invalid in ExportClause.
1341         *ok = false;
1342         ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved);
1343         return nullptr;
1344       }
1345       ExpectSemicolon(CHECK_OK);
1346       const int length = export_names.length();
1347       DCHECK_EQ(length, original_names.length());
1348       DCHECK_EQ(length, export_locations.length());
1349       if (module_specifier == nullptr) {
1350         for (int i = 0; i < length; ++i) {
1351           module()->AddExport(original_names[i], export_names[i],
1352                               export_locations[i], zone());
1353         }
1354       } else if (length == 0) {
1355         module()->AddEmptyImport(module_specifier);
1356       } else {
1357         for (int i = 0; i < length; ++i) {
1358           module()->AddExport(original_names[i], export_names[i],
1359                               module_specifier, export_locations[i], zone());
1360         }
1361       }
1362       return factory()->NewEmptyStatement(pos);
1363     }
1364 
1365     case Token::FUNCTION:
1366       result = ParseHoistableDeclaration(&names, false, CHECK_OK);
1367       break;
1368 
1369     case Token::CLASS:
1370       Consume(Token::CLASS);
1371       result = ParseClassDeclaration(&names, false, CHECK_OK);
1372       break;
1373 
1374     case Token::VAR:
1375     case Token::LET:
1376     case Token::CONST:
1377       result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK);
1378       break;
1379 
1380     case Token::ASYNC:
1381       // TODO(neis): Why don't we have the same check here as in
1382       // ParseStatementListItem?
1383       Consume(Token::ASYNC);
1384       result = ParseAsyncFunctionDeclaration(&names, false, CHECK_OK);
1385       break;
1386 
1387     default:
1388       *ok = false;
1389       ReportUnexpectedToken(scanner()->current_token());
1390       return nullptr;
1391   }
1392   loc.end_pos = scanner()->location().end_pos;
1393 
1394   ModuleDescriptor* descriptor = module();
1395   for (int i = 0; i < names.length(); ++i) {
1396     descriptor->AddExport(names[i], names[i], loc, zone());
1397   }
1398 
1399   DCHECK_NOT_NULL(result);
1400   return result;
1401 }
1402 
NewUnresolved(const AstRawString * name,int begin_pos,VariableKind kind)1403 VariableProxy* Parser::NewUnresolved(const AstRawString* name, int begin_pos,
1404                                      VariableKind kind) {
1405   return scope()->NewUnresolved(factory(), name, begin_pos, kind);
1406 }
1407 
NewUnresolved(const AstRawString * name)1408 VariableProxy* Parser::NewUnresolved(const AstRawString* name) {
1409   return scope()->NewUnresolved(factory(), name, scanner()->location().beg_pos);
1410 }
1411 
DeclareVariable(const AstRawString * name,VariableMode mode,int pos,bool * ok)1412 Declaration* Parser::DeclareVariable(const AstRawString* name,
1413                                      VariableMode mode, int pos, bool* ok) {
1414   return DeclareVariable(name, mode, Variable::DefaultInitializationFlag(mode),
1415                          pos, ok);
1416 }
1417 
DeclareVariable(const AstRawString * name,VariableMode mode,InitializationFlag init,int pos,bool * ok)1418 Declaration* Parser::DeclareVariable(const AstRawString* name,
1419                                      VariableMode mode, InitializationFlag init,
1420                                      int pos, bool* ok) {
1421   DCHECK_NOT_NULL(name);
1422   VariableProxy* proxy = factory()->NewVariableProxy(
1423       name, NORMAL_VARIABLE, scanner()->location().beg_pos);
1424   Declaration* declaration =
1425       factory()->NewVariableDeclaration(proxy, this->scope(), pos);
1426   Declare(declaration, DeclarationDescriptor::NORMAL, mode, init, ok, nullptr,
1427           scanner()->location().end_pos);
1428   if (!*ok) return nullptr;
1429   return declaration;
1430 }
1431 
Declare(Declaration * declaration,DeclarationDescriptor::Kind declaration_kind,VariableMode mode,InitializationFlag init,bool * ok,Scope * scope,int var_end_pos)1432 Variable* Parser::Declare(Declaration* declaration,
1433                           DeclarationDescriptor::Kind declaration_kind,
1434                           VariableMode mode, InitializationFlag init, bool* ok,
1435                           Scope* scope, int var_end_pos) {
1436   if (scope == nullptr) {
1437     scope = this->scope();
1438   }
1439   bool sloppy_mode_block_scope_function_redefinition = false;
1440   Variable* variable = scope->DeclareVariable(
1441       declaration, mode, init, allow_harmony_restrictive_generators(),
1442       &sloppy_mode_block_scope_function_redefinition, ok);
1443   if (!*ok) {
1444     // If we only have the start position of a proxy, we can't highlight the
1445     // whole variable name.  Pretend its length is 1 so that we highlight at
1446     // least the first character.
1447     Scanner::Location loc(declaration->proxy()->position(),
1448                           var_end_pos != kNoSourcePosition
1449                               ? var_end_pos
1450                               : declaration->proxy()->position() + 1);
1451     if (declaration_kind == DeclarationDescriptor::NORMAL) {
1452       ReportMessageAt(loc, MessageTemplate::kVarRedeclaration,
1453                       declaration->proxy()->raw_name());
1454     } else {
1455       ReportMessageAt(loc, MessageTemplate::kParamDupe);
1456     }
1457     return nullptr;
1458   }
1459   if (sloppy_mode_block_scope_function_redefinition) {
1460     ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition];
1461   }
1462   return variable;
1463 }
1464 
BuildInitializationBlock(DeclarationParsingResult * parsing_result,ZoneList<const AstRawString * > * names,bool * ok)1465 Block* Parser::BuildInitializationBlock(
1466     DeclarationParsingResult* parsing_result,
1467     ZoneList<const AstRawString*>* names, bool* ok) {
1468   Block* result = factory()->NewBlock(
1469       NULL, 1, true, parsing_result->descriptor.declaration_pos);
1470   for (auto declaration : parsing_result->declarations) {
1471     PatternRewriter::DeclareAndInitializeVariables(
1472         this, result, &(parsing_result->descriptor), &declaration, names,
1473         CHECK_OK);
1474   }
1475   return result;
1476 }
1477 
DeclareAndInitializeVariables(Block * block,const DeclarationDescriptor * declaration_descriptor,const DeclarationParsingResult::Declaration * declaration,ZoneList<const AstRawString * > * names,bool * ok)1478 void Parser::DeclareAndInitializeVariables(
1479     Block* block, const DeclarationDescriptor* declaration_descriptor,
1480     const DeclarationParsingResult::Declaration* declaration,
1481     ZoneList<const AstRawString*>* names, bool* ok) {
1482   DCHECK_NOT_NULL(block);
1483   PatternRewriter::DeclareAndInitializeVariables(
1484       this, block, declaration_descriptor, declaration, names, ok);
1485 }
1486 
DeclareFunction(const AstRawString * variable_name,FunctionLiteral * function,VariableMode mode,int pos,bool is_sloppy_block_function,ZoneList<const AstRawString * > * names,bool * ok)1487 Statement* Parser::DeclareFunction(const AstRawString* variable_name,
1488                                    FunctionLiteral* function, VariableMode mode,
1489                                    int pos, bool is_sloppy_block_function,
1490                                    ZoneList<const AstRawString*>* names,
1491                                    bool* ok) {
1492   VariableProxy* proxy =
1493       factory()->NewVariableProxy(variable_name, NORMAL_VARIABLE);
1494 
1495   Declaration* declaration =
1496       factory()->NewFunctionDeclaration(proxy, function, scope(), pos);
1497   Declare(declaration, DeclarationDescriptor::NORMAL, mode, kCreatedInitialized,
1498           CHECK_OK);
1499   if (names) names->Add(variable_name, zone());
1500   if (is_sloppy_block_function) {
1501     SloppyBlockFunctionStatement* statement =
1502         factory()->NewSloppyBlockFunctionStatement();
1503     GetDeclarationScope()->DeclareSloppyBlockFunction(variable_name, scope(),
1504                                                       statement);
1505     return statement;
1506   }
1507   return factory()->NewEmptyStatement(kNoSourcePosition);
1508 }
1509 
DeclareClass(const AstRawString * variable_name,Expression * value,ZoneList<const AstRawString * > * names,int class_token_pos,int end_pos,bool * ok)1510 Statement* Parser::DeclareClass(const AstRawString* variable_name,
1511                                 Expression* value,
1512                                 ZoneList<const AstRawString*>* names,
1513                                 int class_token_pos, int end_pos, bool* ok) {
1514   Declaration* decl =
1515       DeclareVariable(variable_name, LET, class_token_pos, CHECK_OK);
1516   decl->proxy()->var()->set_initializer_position(end_pos);
1517   Assignment* assignment = factory()->NewAssignment(Token::INIT, decl->proxy(),
1518                                                     value, class_token_pos);
1519   Statement* assignment_statement =
1520       factory()->NewExpressionStatement(assignment, kNoSourcePosition);
1521   if (names) names->Add(variable_name, zone());
1522   return assignment_statement;
1523 }
1524 
DeclareNative(const AstRawString * name,int pos,bool * ok)1525 Statement* Parser::DeclareNative(const AstRawString* name, int pos, bool* ok) {
1526   // Make sure that the function containing the native declaration
1527   // isn't lazily compiled. The extension structures are only
1528   // accessible while parsing the first time not when reparsing
1529   // because of lazy compilation.
1530   GetClosureScope()->ForceEagerCompilation();
1531 
1532   // TODO(1240846): It's weird that native function declarations are
1533   // introduced dynamically when we meet their declarations, whereas
1534   // other functions are set up when entering the surrounding scope.
1535   Declaration* decl = DeclareVariable(name, VAR, pos, CHECK_OK);
1536   NativeFunctionLiteral* lit =
1537       factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition);
1538   return factory()->NewExpressionStatement(
1539       factory()->NewAssignment(Token::INIT, decl->proxy(), lit,
1540                                kNoSourcePosition),
1541       pos);
1542 }
1543 
DeclareLabel(ZoneList<const AstRawString * > * labels,VariableProxy * var,bool * ok)1544 ZoneList<const AstRawString*>* Parser::DeclareLabel(
1545     ZoneList<const AstRawString*>* labels, VariableProxy* var, bool* ok) {
1546   DCHECK(IsIdentifier(var));
1547   const AstRawString* label = var->raw_name();
1548   // TODO(1240780): We don't check for redeclaration of labels
1549   // during preparsing since keeping track of the set of active
1550   // labels requires nontrivial changes to the way scopes are
1551   // structured.  However, these are probably changes we want to
1552   // make later anyway so we should go back and fix this then.
1553   if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
1554     ReportMessage(MessageTemplate::kLabelRedeclaration, label);
1555     *ok = false;
1556     return nullptr;
1557   }
1558   if (labels == nullptr) {
1559     labels = new (zone()) ZoneList<const AstRawString*>(1, zone());
1560   }
1561   labels->Add(label, zone());
1562   // Remove the "ghost" variable that turned out to be a label
1563   // from the top scope. This way, we don't try to resolve it
1564   // during the scope processing.
1565   scope()->RemoveUnresolved(var);
1566   return labels;
1567 }
1568 
ContainsLabel(ZoneList<const AstRawString * > * labels,const AstRawString * label)1569 bool Parser::ContainsLabel(ZoneList<const AstRawString*>* labels,
1570                            const AstRawString* label) {
1571   DCHECK_NOT_NULL(label);
1572   if (labels != nullptr) {
1573     for (int i = labels->length(); i-- > 0;) {
1574       if (labels->at(i) == label) return true;
1575     }
1576   }
1577   return false;
1578 }
1579 
RewriteReturn(Expression * return_value,int pos)1580 Expression* Parser::RewriteReturn(Expression* return_value, int pos) {
1581   if (IsDerivedConstructor(function_state_->kind())) {
1582     // For subclass constructors we need to return this in case of undefined
1583     // return a Smi (transformed into an exception in the ConstructStub)
1584     // for a non object.
1585     //
1586     //   return expr;
1587     //
1588     // Is rewritten as:
1589     //
1590     //   return (temp = expr) === undefined ? this :
1591     //       %_IsJSReceiver(temp) ? temp : 1;
1592 
1593     // temp = expr
1594     Variable* temp = NewTemporary(ast_value_factory()->empty_string());
1595     Assignment* assign = factory()->NewAssignment(
1596         Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos);
1597 
1598     // %_IsJSReceiver(temp)
1599     ZoneList<Expression*>* is_spec_object_args =
1600         new (zone()) ZoneList<Expression*>(1, zone());
1601     is_spec_object_args->Add(factory()->NewVariableProxy(temp), zone());
1602     Expression* is_spec_object_call = factory()->NewCallRuntime(
1603         Runtime::kInlineIsJSReceiver, is_spec_object_args, pos);
1604 
1605     // %_IsJSReceiver(temp) ? temp : 1;
1606     Expression* is_object_conditional = factory()->NewConditional(
1607         is_spec_object_call, factory()->NewVariableProxy(temp),
1608         factory()->NewSmiLiteral(1, pos), pos);
1609 
1610     // temp === undefined
1611     Expression* is_undefined = factory()->NewCompareOperation(
1612         Token::EQ_STRICT, assign,
1613         factory()->NewUndefinedLiteral(kNoSourcePosition), pos);
1614 
1615     // is_undefined ? this : is_object_conditional
1616     return_value = factory()->NewConditional(is_undefined, ThisExpression(pos),
1617                                              is_object_conditional, pos);
1618   }
1619   if (is_generator()) {
1620     return_value = BuildIteratorResult(return_value, true);
1621   }
1622   return return_value;
1623 }
1624 
RewriteDoExpression(Block * body,int pos,bool * ok)1625 Expression* Parser::RewriteDoExpression(Block* body, int pos, bool* ok) {
1626   Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
1627   DoExpression* expr = factory()->NewDoExpression(body, result, pos);
1628   if (!Rewriter::Rewrite(this, GetClosureScope(), expr, ast_value_factory())) {
1629     *ok = false;
1630     return nullptr;
1631   }
1632   return expr;
1633 }
1634 
RewriteSwitchStatement(Expression * tag,SwitchStatement * switch_statement,ZoneList<CaseClause * > * cases,Scope * scope)1635 Statement* Parser::RewriteSwitchStatement(Expression* tag,
1636                                           SwitchStatement* switch_statement,
1637                                           ZoneList<CaseClause*>* cases,
1638                                           Scope* scope) {
1639   // In order to get the CaseClauses to execute in their own lexical scope,
1640   // but without requiring downstream code to have special scope handling
1641   // code for switch statements, desugar into blocks as follows:
1642   // {  // To group the statements--harmless to evaluate Expression in scope
1643   //   .tag_variable = Expression;
1644   //   {  // To give CaseClauses a scope
1645   //     switch (.tag_variable) { CaseClause* }
1646   //   }
1647   // }
1648 
1649   Block* switch_block = factory()->NewBlock(NULL, 2, false, kNoSourcePosition);
1650 
1651   Variable* tag_variable =
1652       NewTemporary(ast_value_factory()->dot_switch_tag_string());
1653   Assignment* tag_assign = factory()->NewAssignment(
1654       Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag,
1655       tag->position());
1656   Statement* tag_statement =
1657       factory()->NewExpressionStatement(tag_assign, kNoSourcePosition);
1658   switch_block->statements()->Add(tag_statement, zone());
1659 
1660   // make statement: undefined;
1661   // This is needed so the tag isn't returned as the value, in case the switch
1662   // statements don't have a value.
1663   switch_block->statements()->Add(
1664       factory()->NewExpressionStatement(
1665           factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
1666       zone());
1667 
1668   Expression* tag_read = factory()->NewVariableProxy(tag_variable);
1669   switch_statement->Initialize(tag_read, cases);
1670   Block* cases_block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition);
1671   cases_block->statements()->Add(switch_statement, zone());
1672   cases_block->set_scope(scope);
1673   DCHECK_IMPLIES(scope != nullptr,
1674                  switch_statement->position() >= scope->start_position());
1675   DCHECK_IMPLIES(scope != nullptr,
1676                  switch_statement->position() < scope->end_position());
1677   switch_block->statements()->Add(cases_block, zone());
1678   return switch_block;
1679 }
1680 
RewriteCatchPattern(CatchInfo * catch_info,bool * ok)1681 void Parser::RewriteCatchPattern(CatchInfo* catch_info, bool* ok) {
1682   if (catch_info->name == nullptr) {
1683     DCHECK_NOT_NULL(catch_info->pattern);
1684     catch_info->name = ast_value_factory()->dot_catch_string();
1685   }
1686   catch_info->variable = catch_info->scope->DeclareLocal(catch_info->name, VAR);
1687   if (catch_info->pattern != nullptr) {
1688     DeclarationDescriptor descriptor;
1689     descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
1690     descriptor.scope = scope();
1691     descriptor.mode = LET;
1692     descriptor.declaration_pos = catch_info->pattern->position();
1693     descriptor.initialization_pos = catch_info->pattern->position();
1694 
1695     // Initializer position for variables declared by the pattern.
1696     const int initializer_position = position();
1697 
1698     DeclarationParsingResult::Declaration decl(
1699         catch_info->pattern, initializer_position,
1700         factory()->NewVariableProxy(catch_info->variable));
1701 
1702     catch_info->init_block =
1703         factory()->NewBlock(nullptr, 8, true, kNoSourcePosition);
1704     PatternRewriter::DeclareAndInitializeVariables(
1705         this, catch_info->init_block, &descriptor, &decl,
1706         &catch_info->bound_names, ok);
1707   } else {
1708     catch_info->bound_names.Add(catch_info->name, zone());
1709   }
1710 }
1711 
ValidateCatchBlock(const CatchInfo & catch_info,bool * ok)1712 void Parser::ValidateCatchBlock(const CatchInfo& catch_info, bool* ok) {
1713   // Check for `catch(e) { let e; }` and similar errors.
1714   Scope* inner_block_scope = catch_info.inner_block->scope();
1715   if (inner_block_scope != nullptr) {
1716     Declaration* decl = inner_block_scope->CheckLexDeclarationsConflictingWith(
1717         catch_info.bound_names);
1718     if (decl != nullptr) {
1719       const AstRawString* name = decl->proxy()->raw_name();
1720       int position = decl->proxy()->position();
1721       Scanner::Location location =
1722           position == kNoSourcePosition
1723               ? Scanner::Location::invalid()
1724               : Scanner::Location(position, position + 1);
1725       ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
1726       *ok = false;
1727     }
1728   }
1729 }
1730 
RewriteTryStatement(Block * try_block,Block * catch_block,Block * finally_block,const CatchInfo & catch_info,int pos)1731 Statement* Parser::RewriteTryStatement(Block* try_block, Block* catch_block,
1732                                        Block* finally_block,
1733                                        const CatchInfo& catch_info, int pos) {
1734   // Simplify the AST nodes by converting:
1735   //   'try B0 catch B1 finally B2'
1736   // to:
1737   //   'try { try B0 catch B1 } finally B2'
1738 
1739   if (catch_block != nullptr && finally_block != nullptr) {
1740     // If we have both, create an inner try/catch.
1741     DCHECK_NOT_NULL(catch_info.scope);
1742     DCHECK_NOT_NULL(catch_info.variable);
1743     TryCatchStatement* statement;
1744     statement = factory()->NewTryCatchStatement(try_block, catch_info.scope,
1745                                                 catch_info.variable,
1746                                                 catch_block, kNoSourcePosition);
1747 
1748     try_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
1749     try_block->statements()->Add(statement, zone());
1750     catch_block = nullptr;  // Clear to indicate it's been handled.
1751   }
1752 
1753   if (catch_block != nullptr) {
1754     // For a try-catch construct append return expressions from the catch block
1755     // to the list of return expressions.
1756     function_state_->tail_call_expressions().Append(
1757         catch_info.tail_call_expressions);
1758 
1759     DCHECK_NULL(finally_block);
1760     DCHECK_NOT_NULL(catch_info.scope);
1761     DCHECK_NOT_NULL(catch_info.variable);
1762     return factory()->NewTryCatchStatement(
1763         try_block, catch_info.scope, catch_info.variable, catch_block, pos);
1764   } else {
1765     DCHECK_NOT_NULL(finally_block);
1766     return factory()->NewTryFinallyStatement(try_block, finally_block, pos);
1767   }
1768 }
1769 
ParseAndRewriteGeneratorFunctionBody(int pos,FunctionKind kind,ZoneList<Statement * > * body,bool * ok)1770 void Parser::ParseAndRewriteGeneratorFunctionBody(int pos, FunctionKind kind,
1771                                                   ZoneList<Statement*>* body,
1772                                                   bool* ok) {
1773   // We produce:
1774   //
1775   // try { InitialYield; ...body...; return {value: undefined, done: true} }
1776   // finally { %_GeneratorClose(generator) }
1777   //
1778   // - InitialYield yields the actual generator object.
1779   // - Any return statement inside the body will have its argument wrapped
1780   //   in a "done" iterator result object.
1781   // - If the generator terminates for whatever reason, we must close it.
1782   //   Hence the finally clause.
1783 
1784   Block* try_block = factory()->NewBlock(nullptr, 3, false, kNoSourcePosition);
1785   Expression* initial_yield = BuildInitialYield(pos, kind);
1786   try_block->statements()->Add(
1787       factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
1788       zone());
1789   ParseStatementList(try_block->statements(), Token::RBRACE, ok);
1790   if (!*ok) return;
1791 
1792   Statement* final_return = factory()->NewReturnStatement(
1793       BuildIteratorResult(nullptr, true), kNoSourcePosition);
1794   try_block->statements()->Add(final_return, zone());
1795 
1796   Block* finally_block =
1797       factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
1798   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
1799   VariableProxy* call_proxy =
1800       factory()->NewVariableProxy(function_state_->generator_object_variable());
1801   args->Add(call_proxy, zone());
1802   Expression* call = factory()->NewCallRuntime(Runtime::kInlineGeneratorClose,
1803                                                args, kNoSourcePosition);
1804   finally_block->statements()->Add(
1805       factory()->NewExpressionStatement(call, kNoSourcePosition), zone());
1806 
1807   body->Add(factory()->NewTryFinallyStatement(try_block, finally_block,
1808                                               kNoSourcePosition),
1809             zone());
1810 }
1811 
CreateFunctionNameAssignment(const AstRawString * function_name,int pos,FunctionLiteral::FunctionType function_type,DeclarationScope * function_scope,ZoneList<Statement * > * result,int index)1812 void Parser::CreateFunctionNameAssignment(
1813     const AstRawString* function_name, int pos,
1814     FunctionLiteral::FunctionType function_type,
1815     DeclarationScope* function_scope, ZoneList<Statement*>* result, int index) {
1816   if (function_type == FunctionLiteral::kNamedExpression) {
1817     StatementT statement = factory()->NewEmptyStatement(kNoSourcePosition);
1818     if (function_scope->LookupLocal(function_name) == nullptr) {
1819       // Now that we know the language mode, we can create the const assignment
1820       // in the previously reserved spot.
1821       DCHECK_EQ(function_scope, scope());
1822       Variable* fvar = function_scope->DeclareFunctionVar(function_name);
1823       VariableProxy* fproxy = factory()->NewVariableProxy(fvar);
1824       statement = factory()->NewExpressionStatement(
1825           factory()->NewAssignment(Token::INIT, fproxy,
1826                                    factory()->NewThisFunction(pos),
1827                                    kNoSourcePosition),
1828           kNoSourcePosition);
1829     }
1830     result->Set(index, statement);
1831   }
1832 }
1833 
1834 // [if (IteratorType == kNormal)]
1835 //     !%_IsJSReceiver(result = iterator.next()) &&
1836 //         %ThrowIteratorResultNotAnObject(result)
1837 // [else if (IteratorType == kAsync)]
1838 //     !%_IsJSReceiver(result = Await(iterator.next())) &&
1839 //         %ThrowIteratorResultNotAnObject(result)
1840 // [endif]
BuildIteratorNextResult(Expression * iterator,Variable * result,IteratorType type,int pos)1841 Expression* Parser::BuildIteratorNextResult(Expression* iterator,
1842                                             Variable* result, IteratorType type,
1843                                             int pos) {
1844   Expression* next_literal = factory()->NewStringLiteral(
1845       ast_value_factory()->next_string(), kNoSourcePosition);
1846   Expression* next_property =
1847       factory()->NewProperty(iterator, next_literal, kNoSourcePosition);
1848   ZoneList<Expression*>* next_arguments =
1849       new (zone()) ZoneList<Expression*>(0, zone());
1850   Expression* next_call =
1851       factory()->NewCall(next_property, next_arguments, pos);
1852   if (type == IteratorType::kAsync) {
1853     next_call = RewriteAwaitExpression(next_call, pos);
1854   }
1855   Expression* result_proxy = factory()->NewVariableProxy(result);
1856   Expression* left =
1857       factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos);
1858 
1859   // %_IsJSReceiver(...)
1860   ZoneList<Expression*>* is_spec_object_args =
1861       new (zone()) ZoneList<Expression*>(1, zone());
1862   is_spec_object_args->Add(left, zone());
1863   Expression* is_spec_object_call = factory()->NewCallRuntime(
1864       Runtime::kInlineIsJSReceiver, is_spec_object_args, pos);
1865 
1866   // %ThrowIteratorResultNotAnObject(result)
1867   Expression* result_proxy_again = factory()->NewVariableProxy(result);
1868   ZoneList<Expression*>* throw_arguments =
1869       new (zone()) ZoneList<Expression*>(1, zone());
1870   throw_arguments->Add(result_proxy_again, zone());
1871   Expression* throw_call = factory()->NewCallRuntime(
1872       Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos);
1873 
1874   return factory()->NewBinaryOperation(
1875       Token::AND,
1876       factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos),
1877       throw_call, pos);
1878 }
1879 
InitializeForEachStatement(ForEachStatement * stmt,Expression * each,Expression * subject,Statement * body,int each_keyword_pos)1880 Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt,
1881                                               Expression* each,
1882                                               Expression* subject,
1883                                               Statement* body,
1884                                               int each_keyword_pos) {
1885   ForOfStatement* for_of = stmt->AsForOfStatement();
1886   if (for_of != NULL) {
1887     const bool finalize = true;
1888     return InitializeForOfStatement(for_of, each, subject, body, finalize,
1889                                     IteratorType::kNormal, each_keyword_pos);
1890   } else {
1891     if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
1892       Variable* temp = NewTemporary(ast_value_factory()->empty_string());
1893       VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
1894       Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment(
1895           this, factory()->NewAssignment(Token::ASSIGN, each, temp_proxy,
1896                                          kNoSourcePosition),
1897           scope());
1898       auto block = factory()->NewBlock(nullptr, 2, false, kNoSourcePosition);
1899       block->statements()->Add(
1900           factory()->NewExpressionStatement(assign_each, kNoSourcePosition),
1901           zone());
1902       block->statements()->Add(body, zone());
1903       body = block;
1904       each = factory()->NewVariableProxy(temp);
1905     }
1906     MarkExpressionAsAssigned(each);
1907     stmt->AsForInStatement()->Initialize(each, subject, body);
1908   }
1909   return stmt;
1910 }
1911 
1912 // Special case for legacy for
1913 //
1914 //    for (var x = initializer in enumerable) body
1915 //
1916 // An initialization block of the form
1917 //
1918 //    {
1919 //      x = initializer;
1920 //    }
1921 //
1922 // is returned in this case.  It has reserved space for two statements,
1923 // so that (later on during parsing), the equivalent of
1924 //
1925 //   for (x in enumerable) body
1926 //
1927 // is added as a second statement to it.
RewriteForVarInLegacy(const ForInfo & for_info)1928 Block* Parser::RewriteForVarInLegacy(const ForInfo& for_info) {
1929   const DeclarationParsingResult::Declaration& decl =
1930       for_info.parsing_result.declarations[0];
1931   if (!IsLexicalVariableMode(for_info.parsing_result.descriptor.mode) &&
1932       decl.pattern->IsVariableProxy() && decl.initializer != nullptr) {
1933     ++use_counts_[v8::Isolate::kForInInitializer];
1934     const AstRawString* name = decl.pattern->AsVariableProxy()->raw_name();
1935     VariableProxy* single_var = NewUnresolved(name);
1936     Block* init_block = factory()->NewBlock(
1937         nullptr, 2, true, for_info.parsing_result.descriptor.declaration_pos);
1938     init_block->statements()->Add(
1939         factory()->NewExpressionStatement(
1940             factory()->NewAssignment(Token::ASSIGN, single_var,
1941                                      decl.initializer, kNoSourcePosition),
1942             kNoSourcePosition),
1943         zone());
1944     return init_block;
1945   }
1946   return nullptr;
1947 }
1948 
1949 // Rewrite a for-in/of statement of the form
1950 //
1951 //   for (let/const/var x in/of e) b
1952 //
1953 // into
1954 //
1955 //   {
1956 //     <let x' be a temporary variable>
1957 //     for (x' in/of e) {
1958 //       let/const/var x;
1959 //       x = x';
1960 //       b;
1961 //     }
1962 //     let x;  // for TDZ
1963 //   }
DesugarBindingInForEachStatement(ForInfo * for_info,Block ** body_block,Expression ** each_variable,bool * ok)1964 void Parser::DesugarBindingInForEachStatement(ForInfo* for_info,
1965                                               Block** body_block,
1966                                               Expression** each_variable,
1967                                               bool* ok) {
1968   DCHECK(for_info->parsing_result.declarations.length() == 1);
1969   DeclarationParsingResult::Declaration& decl =
1970       for_info->parsing_result.declarations[0];
1971   Variable* temp = NewTemporary(ast_value_factory()->dot_for_string());
1972   auto each_initialization_block =
1973       factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
1974   {
1975     auto descriptor = for_info->parsing_result.descriptor;
1976     descriptor.declaration_pos = kNoSourcePosition;
1977     descriptor.initialization_pos = kNoSourcePosition;
1978     decl.initializer = factory()->NewVariableProxy(temp);
1979 
1980     bool is_for_var_of =
1981         for_info->mode == ForEachStatement::ITERATE &&
1982         for_info->parsing_result.descriptor.mode == VariableMode::VAR;
1983     bool collect_names =
1984         IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) ||
1985         is_for_var_of;
1986 
1987     PatternRewriter::DeclareAndInitializeVariables(
1988         this, each_initialization_block, &descriptor, &decl,
1989         collect_names ? &for_info->bound_names : nullptr, CHECK_OK_VOID);
1990 
1991     // Annex B.3.5 prohibits the form
1992     // `try {} catch(e) { for (var e of {}); }`
1993     // So if we are parsing a statement like `for (var ... of ...)`
1994     // we need to walk up the scope chain and look for catch scopes
1995     // which have a simple binding, then compare their binding against
1996     // all of the names declared in the init of the for-of we're
1997     // parsing.
1998     if (is_for_var_of) {
1999       Scope* catch_scope = scope();
2000       while (catch_scope != nullptr && !catch_scope->is_declaration_scope()) {
2001         if (catch_scope->is_catch_scope()) {
2002           auto name = catch_scope->catch_variable_name();
2003           // If it's a simple binding and the name is declared in the for loop.
2004           if (name != ast_value_factory()->dot_catch_string() &&
2005               for_info->bound_names.Contains(name)) {
2006             ReportMessageAt(for_info->parsing_result.bindings_loc,
2007                             MessageTemplate::kVarRedeclaration, name);
2008             *ok = false;
2009             return;
2010           }
2011         }
2012         catch_scope = catch_scope->outer_scope();
2013       }
2014     }
2015   }
2016 
2017   *body_block = factory()->NewBlock(nullptr, 3, false, kNoSourcePosition);
2018   (*body_block)->statements()->Add(each_initialization_block, zone());
2019   *each_variable = factory()->NewVariableProxy(temp, for_info->position);
2020 }
2021 
2022 // Create a TDZ for any lexically-bound names in for in/of statements.
CreateForEachStatementTDZ(Block * init_block,const ForInfo & for_info,bool * ok)2023 Block* Parser::CreateForEachStatementTDZ(Block* init_block,
2024                                          const ForInfo& for_info, bool* ok) {
2025   if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) {
2026     DCHECK_NULL(init_block);
2027 
2028     init_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
2029 
2030     for (int i = 0; i < for_info.bound_names.length(); ++i) {
2031       // TODO(adamk): This needs to be some sort of special
2032       // INTERNAL variable that's invisible to the debugger
2033       // but visible to everything else.
2034       Declaration* tdz_decl = DeclareVariable(for_info.bound_names[i], LET,
2035                                               kNoSourcePosition, CHECK_OK);
2036       tdz_decl->proxy()->var()->set_initializer_position(position());
2037     }
2038   }
2039   return init_block;
2040 }
2041 
InitializeForOfStatement(ForOfStatement * for_of,Expression * each,Expression * iterable,Statement * body,bool finalize,IteratorType type,int next_result_pos)2042 Statement* Parser::InitializeForOfStatement(
2043     ForOfStatement* for_of, Expression* each, Expression* iterable,
2044     Statement* body, bool finalize, IteratorType type, int next_result_pos) {
2045   // Create the auxiliary expressions needed for iterating over the iterable,
2046   // and initialize the given ForOfStatement with them.
2047   // If finalize is true, also instrument the loop with code that performs the
2048   // proper ES6 iterator finalization.  In that case, the result is not
2049   // immediately a ForOfStatement.
2050   const int nopos = kNoSourcePosition;
2051   auto avfactory = ast_value_factory();
2052 
2053   Variable* iterator = NewTemporary(avfactory->dot_iterator_string());
2054   Variable* result = NewTemporary(avfactory->dot_result_string());
2055   Variable* completion = NewTemporary(avfactory->empty_string());
2056 
2057   // iterator = GetIterator(iterable, type)
2058   Expression* assign_iterator;
2059   {
2060     assign_iterator = factory()->NewAssignment(
2061         Token::ASSIGN, factory()->NewVariableProxy(iterator),
2062         factory()->NewGetIterator(iterable, type, iterable->position()),
2063         iterable->position());
2064   }
2065 
2066   // [if (IteratorType == kNormal)]
2067   //     !%_IsJSReceiver(result = iterator.next()) &&
2068   //         %ThrowIteratorResultNotAnObject(result)
2069   // [else if (IteratorType == kAsync)]
2070   //     !%_IsJSReceiver(result = Await(iterator.next())) &&
2071   //         %ThrowIteratorResultNotAnObject(result)
2072   // [endif]
2073   Expression* next_result;
2074   {
2075     Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
2076     next_result =
2077         BuildIteratorNextResult(iterator_proxy, result, type, next_result_pos);
2078   }
2079 
2080   // result.done
2081   Expression* result_done;
2082   {
2083     Expression* done_literal = factory()->NewStringLiteral(
2084         ast_value_factory()->done_string(), kNoSourcePosition);
2085     Expression* result_proxy = factory()->NewVariableProxy(result);
2086     result_done =
2087         factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition);
2088   }
2089 
2090   // result.value
2091   Expression* result_value;
2092   {
2093     Expression* value_literal =
2094         factory()->NewStringLiteral(avfactory->value_string(), nopos);
2095     Expression* result_proxy = factory()->NewVariableProxy(result);
2096     result_value = factory()->NewProperty(result_proxy, value_literal, nopos);
2097   }
2098 
2099   // {{completion = kAbruptCompletion;}}
2100   Statement* set_completion_abrupt;
2101   if (finalize) {
2102     Expression* proxy = factory()->NewVariableProxy(completion);
2103     Expression* assignment = factory()->NewAssignment(
2104         Token::ASSIGN, proxy,
2105         factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
2106 
2107     Block* block = factory()->NewBlock(nullptr, 1, true, nopos);
2108     block->statements()->Add(
2109         factory()->NewExpressionStatement(assignment, nopos), zone());
2110     set_completion_abrupt = block;
2111   }
2112 
2113   // do { let tmp = #result_value; #set_completion_abrupt; tmp }
2114   // Expression* result_value (gets overwritten)
2115   if (finalize) {
2116     Variable* var_tmp = NewTemporary(avfactory->empty_string());
2117     Expression* tmp = factory()->NewVariableProxy(var_tmp);
2118     Expression* assignment =
2119         factory()->NewAssignment(Token::ASSIGN, tmp, result_value, nopos);
2120 
2121     Block* block = factory()->NewBlock(nullptr, 2, false, nopos);
2122     block->statements()->Add(
2123         factory()->NewExpressionStatement(assignment, nopos), zone());
2124     block->statements()->Add(set_completion_abrupt, zone());
2125 
2126     result_value = factory()->NewDoExpression(block, var_tmp, nopos);
2127   }
2128 
2129   // each = #result_value;
2130   Expression* assign_each;
2131   {
2132     assign_each =
2133         factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos);
2134     if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
2135       assign_each = PatternRewriter::RewriteDestructuringAssignment(
2136           this, assign_each->AsAssignment(), scope());
2137     }
2138   }
2139 
2140   // {{completion = kNormalCompletion;}}
2141   Statement* set_completion_normal;
2142   if (finalize) {
2143     Expression* proxy = factory()->NewVariableProxy(completion);
2144     Expression* assignment = factory()->NewAssignment(
2145         Token::ASSIGN, proxy,
2146         factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
2147 
2148     Block* block = factory()->NewBlock(nullptr, 1, true, nopos);
2149     block->statements()->Add(
2150         factory()->NewExpressionStatement(assignment, nopos), zone());
2151     set_completion_normal = block;
2152   }
2153 
2154   // { #loop-body; #set_completion_normal }
2155   // Statement* body (gets overwritten)
2156   if (finalize) {
2157     Block* block = factory()->NewBlock(nullptr, 2, false, nopos);
2158     block->statements()->Add(body, zone());
2159     block->statements()->Add(set_completion_normal, zone());
2160     body = block;
2161   }
2162 
2163   for_of->Initialize(body, iterator, assign_iterator, next_result, result_done,
2164                      assign_each);
2165   return finalize ? FinalizeForOfStatement(for_of, completion, type, nopos)
2166                   : for_of;
2167 }
2168 
DesugarLexicalBindingsInForStatement(ForStatement * loop,Statement * init,Expression * cond,Statement * next,Statement * body,Scope * inner_scope,const ForInfo & for_info,bool * ok)2169 Statement* Parser::DesugarLexicalBindingsInForStatement(
2170     ForStatement* loop, Statement* init, Expression* cond, Statement* next,
2171     Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) {
2172   // ES6 13.7.4.8 specifies that on each loop iteration the let variables are
2173   // copied into a new environment.  Moreover, the "next" statement must be
2174   // evaluated not in the environment of the just completed iteration but in
2175   // that of the upcoming one.  We achieve this with the following desugaring.
2176   // Extra care is needed to preserve the completion value of the original loop.
2177   //
2178   // We are given a for statement of the form
2179   //
2180   //  labels: for (let/const x = i; cond; next) body
2181   //
2182   // and rewrite it as follows.  Here we write {{ ... }} for init-blocks, ie.,
2183   // blocks whose ignore_completion_value_ flag is set.
2184   //
2185   //  {
2186   //    let/const x = i;
2187   //    temp_x = x;
2188   //    first = 1;
2189   //    undefined;
2190   //    outer: for (;;) {
2191   //      let/const x = temp_x;
2192   //      {{ if (first == 1) {
2193   //           first = 0;
2194   //         } else {
2195   //           next;
2196   //         }
2197   //         flag = 1;
2198   //         if (!cond) break;
2199   //      }}
2200   //      labels: for (; flag == 1; flag = 0, temp_x = x) {
2201   //        body
2202   //      }
2203   //      {{ if (flag == 1)  // Body used break.
2204   //           break;
2205   //      }}
2206   //    }
2207   //  }
2208 
2209   DCHECK(for_info.bound_names.length() > 0);
2210   ZoneList<Variable*> temps(for_info.bound_names.length(), zone());
2211 
2212   Block* outer_block = factory()->NewBlock(
2213       nullptr, for_info.bound_names.length() + 4, false, kNoSourcePosition);
2214 
2215   // Add statement: let/const x = i.
2216   outer_block->statements()->Add(init, zone());
2217 
2218   const AstRawString* temp_name = ast_value_factory()->dot_for_string();
2219 
2220   // For each lexical variable x:
2221   //   make statement: temp_x = x.
2222   for (int i = 0; i < for_info.bound_names.length(); i++) {
2223     VariableProxy* proxy = NewUnresolved(for_info.bound_names[i]);
2224     Variable* temp = NewTemporary(temp_name);
2225     VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
2226     Assignment* assignment = factory()->NewAssignment(Token::ASSIGN, temp_proxy,
2227                                                       proxy, kNoSourcePosition);
2228     Statement* assignment_statement =
2229         factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2230     outer_block->statements()->Add(assignment_statement, zone());
2231     temps.Add(temp, zone());
2232   }
2233 
2234   Variable* first = NULL;
2235   // Make statement: first = 1.
2236   if (next) {
2237     first = NewTemporary(temp_name);
2238     VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2239     Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2240     Assignment* assignment = factory()->NewAssignment(
2241         Token::ASSIGN, first_proxy, const1, kNoSourcePosition);
2242     Statement* assignment_statement =
2243         factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2244     outer_block->statements()->Add(assignment_statement, zone());
2245   }
2246 
2247   // make statement: undefined;
2248   outer_block->statements()->Add(
2249       factory()->NewExpressionStatement(
2250           factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
2251       zone());
2252 
2253   // Make statement: outer: for (;;)
2254   // Note that we don't actually create the label, or set this loop up as an
2255   // explicit break target, instead handing it directly to those nodes that
2256   // need to know about it. This should be safe because we don't run any code
2257   // in this function that looks up break targets.
2258   ForStatement* outer_loop =
2259       factory()->NewForStatement(NULL, kNoSourcePosition);
2260   outer_block->statements()->Add(outer_loop, zone());
2261   outer_block->set_scope(scope());
2262 
2263   Block* inner_block = factory()->NewBlock(NULL, 3, false, kNoSourcePosition);
2264   {
2265     BlockState block_state(&scope_, inner_scope);
2266 
2267     Block* ignore_completion_block = factory()->NewBlock(
2268         nullptr, for_info.bound_names.length() + 3, true, kNoSourcePosition);
2269     ZoneList<Variable*> inner_vars(for_info.bound_names.length(), zone());
2270     // For each let variable x:
2271     //    make statement: let/const x = temp_x.
2272     for (int i = 0; i < for_info.bound_names.length(); i++) {
2273       Declaration* decl = DeclareVariable(
2274           for_info.bound_names[i], for_info.parsing_result.descriptor.mode,
2275           kNoSourcePosition, CHECK_OK);
2276       inner_vars.Add(decl->proxy()->var(), zone());
2277       VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
2278       Assignment* assignment = factory()->NewAssignment(
2279           Token::INIT, decl->proxy(), temp_proxy, kNoSourcePosition);
2280       Statement* assignment_statement =
2281           factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2282       DCHECK(init->position() != kNoSourcePosition);
2283       decl->proxy()->var()->set_initializer_position(init->position());
2284       ignore_completion_block->statements()->Add(assignment_statement, zone());
2285     }
2286 
2287     // Make statement: if (first == 1) { first = 0; } else { next; }
2288     if (next) {
2289       DCHECK(first);
2290       Expression* compare = NULL;
2291       // Make compare expression: first == 1.
2292       {
2293         Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2294         VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2295         compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1,
2296                                                  kNoSourcePosition);
2297       }
2298       Statement* clear_first = NULL;
2299       // Make statement: first = 0.
2300       {
2301         VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2302         Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
2303         Assignment* assignment = factory()->NewAssignment(
2304             Token::ASSIGN, first_proxy, const0, kNoSourcePosition);
2305         clear_first =
2306             factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2307       }
2308       Statement* clear_first_or_next = factory()->NewIfStatement(
2309           compare, clear_first, next, kNoSourcePosition);
2310       ignore_completion_block->statements()->Add(clear_first_or_next, zone());
2311     }
2312 
2313     Variable* flag = NewTemporary(temp_name);
2314     // Make statement: flag = 1.
2315     {
2316       VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2317       Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2318       Assignment* assignment = factory()->NewAssignment(
2319           Token::ASSIGN, flag_proxy, const1, kNoSourcePosition);
2320       Statement* assignment_statement =
2321           factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2322       ignore_completion_block->statements()->Add(assignment_statement, zone());
2323     }
2324 
2325     // Make statement: if (!cond) break.
2326     if (cond) {
2327       Statement* stop =
2328           factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
2329       Statement* noop = factory()->NewEmptyStatement(kNoSourcePosition);
2330       ignore_completion_block->statements()->Add(
2331           factory()->NewIfStatement(cond, noop, stop, cond->position()),
2332           zone());
2333     }
2334 
2335     inner_block->statements()->Add(ignore_completion_block, zone());
2336     // Make cond expression for main loop: flag == 1.
2337     Expression* flag_cond = NULL;
2338     {
2339       Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2340       VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2341       flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
2342                                                  kNoSourcePosition);
2343     }
2344 
2345     // Create chain of expressions "flag = 0, temp_x = x, ..."
2346     Statement* compound_next_statement = NULL;
2347     {
2348       Expression* compound_next = NULL;
2349       // Make expression: flag = 0.
2350       {
2351         VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2352         Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
2353         compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy,
2354                                                  const0, kNoSourcePosition);
2355       }
2356 
2357       // Make the comma-separated list of temp_x = x assignments.
2358       int inner_var_proxy_pos = scanner()->location().beg_pos;
2359       for (int i = 0; i < for_info.bound_names.length(); i++) {
2360         VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
2361         VariableProxy* proxy =
2362             factory()->NewVariableProxy(inner_vars.at(i), inner_var_proxy_pos);
2363         Assignment* assignment = factory()->NewAssignment(
2364             Token::ASSIGN, temp_proxy, proxy, kNoSourcePosition);
2365         compound_next = factory()->NewBinaryOperation(
2366             Token::COMMA, compound_next, assignment, kNoSourcePosition);
2367       }
2368 
2369       compound_next_statement =
2370           factory()->NewExpressionStatement(compound_next, kNoSourcePosition);
2371     }
2372 
2373     // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
2374     // Note that we re-use the original loop node, which retains its labels
2375     // and ensures that any break or continue statements in body point to
2376     // the right place.
2377     loop->Initialize(NULL, flag_cond, compound_next_statement, body);
2378     inner_block->statements()->Add(loop, zone());
2379 
2380     // Make statement: {{if (flag == 1) break;}}
2381     {
2382       Expression* compare = NULL;
2383       // Make compare expresion: flag == 1.
2384       {
2385         Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2386         VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2387         compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
2388                                                  kNoSourcePosition);
2389       }
2390       Statement* stop =
2391           factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
2392       Statement* empty = factory()->NewEmptyStatement(kNoSourcePosition);
2393       Statement* if_flag_break =
2394           factory()->NewIfStatement(compare, stop, empty, kNoSourcePosition);
2395       Block* ignore_completion_block =
2396           factory()->NewBlock(NULL, 1, true, kNoSourcePosition);
2397       ignore_completion_block->statements()->Add(if_flag_break, zone());
2398       inner_block->statements()->Add(ignore_completion_block, zone());
2399     }
2400 
2401     inner_block->set_scope(inner_scope);
2402   }
2403 
2404   outer_loop->Initialize(NULL, NULL, NULL, inner_block);
2405   return outer_block;
2406 }
2407 
AddArrowFunctionFormalParameters(ParserFormalParameters * parameters,Expression * expr,int end_pos,bool * ok)2408 void Parser::AddArrowFunctionFormalParameters(
2409     ParserFormalParameters* parameters, Expression* expr, int end_pos,
2410     bool* ok) {
2411   // ArrowFunctionFormals ::
2412   //    Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail)
2413   //    Tail
2414   // NonTailArrowFunctionFormals ::
2415   //    Binary(Token::COMMA, NonTailArrowFunctionFormals, VariableProxy)
2416   //    VariableProxy
2417   // Tail ::
2418   //    VariableProxy
2419   //    Spread(VariableProxy)
2420   //
2421   // As we need to visit the parameters in left-to-right order, we recurse on
2422   // the left-hand side of comma expressions.
2423   //
2424   if (expr->IsBinaryOperation()) {
2425     BinaryOperation* binop = expr->AsBinaryOperation();
2426     // The classifier has already run, so we know that the expression is a valid
2427     // arrow function formals production.
2428     DCHECK_EQ(binop->op(), Token::COMMA);
2429     Expression* left = binop->left();
2430     Expression* right = binop->right();
2431     int comma_pos = binop->position();
2432     AddArrowFunctionFormalParameters(parameters, left, comma_pos,
2433                                      CHECK_OK_VOID);
2434     // LHS of comma expression should be unparenthesized.
2435     expr = right;
2436   }
2437 
2438   // Only the right-most expression may be a rest parameter.
2439   DCHECK(!parameters->has_rest);
2440 
2441   bool is_rest = expr->IsSpread();
2442   if (is_rest) {
2443     expr = expr->AsSpread()->expression();
2444     parameters->has_rest = true;
2445   }
2446   if (parameters->is_simple) {
2447     parameters->is_simple = !is_rest && expr->IsVariableProxy();
2448   }
2449 
2450   Expression* initializer = nullptr;
2451   if (expr->IsAssignment()) {
2452     Assignment* assignment = expr->AsAssignment();
2453     DCHECK(!assignment->is_compound());
2454     initializer = assignment->value();
2455     expr = assignment->target();
2456   }
2457 
2458   AddFormalParameter(parameters, expr, initializer,
2459                      end_pos, is_rest);
2460 }
2461 
DeclareArrowFunctionFormalParameters(ParserFormalParameters * parameters,Expression * expr,const Scanner::Location & params_loc,Scanner::Location * duplicate_loc,bool * ok)2462 void Parser::DeclareArrowFunctionFormalParameters(
2463     ParserFormalParameters* parameters, Expression* expr,
2464     const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
2465     bool* ok) {
2466   if (expr->IsEmptyParentheses()) return;
2467 
2468   AddArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos,
2469                                    CHECK_OK_VOID);
2470 
2471   if (parameters->arity > Code::kMaxArguments) {
2472     ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
2473     *ok = false;
2474     return;
2475   }
2476 
2477   ExpressionClassifier classifier(this);
2478   if (!parameters->is_simple) {
2479     this->classifier()->RecordNonSimpleParameter();
2480   }
2481   DeclareFormalParameters(parameters->scope, parameters->params);
2482   if (!this->classifier()
2483            ->is_valid_formal_parameter_list_without_duplicates()) {
2484     *duplicate_loc =
2485         this->classifier()->duplicate_formal_parameter_error().location;
2486   }
2487   DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters());
2488 }
2489 
PrepareGeneratorVariables()2490 void Parser::PrepareGeneratorVariables() {
2491   // For generators, allocating variables in contexts is currently a win because
2492   // it minimizes the work needed to suspend and resume an activation.  The
2493   // code produced for generators relies on this forced context allocation (it
2494   // does not restore the frame's parameters upon resume).
2495   function_state_->scope()->ForceContextAllocation();
2496 
2497   // Calling a generator returns a generator object.  That object is stored
2498   // in a temporary variable, a definition that is used by "yield"
2499   // expressions.
2500   function_state_->scope()->DeclareGeneratorObjectVar(
2501       ast_value_factory()->dot_generator_object_string());
2502 }
2503 
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,bool * ok)2504 FunctionLiteral* Parser::ParseFunctionLiteral(
2505     const AstRawString* function_name, Scanner::Location function_name_location,
2506     FunctionNameValidity function_name_validity, FunctionKind kind,
2507     int function_token_pos, FunctionLiteral::FunctionType function_type,
2508     LanguageMode language_mode, bool* ok) {
2509   // Function ::
2510   //   '(' FormalParameterList? ')' '{' FunctionBody '}'
2511   //
2512   // Getter ::
2513   //   '(' ')' '{' FunctionBody '}'
2514   //
2515   // Setter ::
2516   //   '(' PropertySetParameterList ')' '{' FunctionBody '}'
2517 
2518   int pos = function_token_pos == kNoSourcePosition ? peek_position()
2519                                                     : function_token_pos;
2520 
2521   // Anonymous functions were passed either the empty symbol or a null
2522   // handle as the function name.  Remember if we were passed a non-empty
2523   // handle to decide whether to invoke function name inference.
2524   bool should_infer_name = function_name == NULL;
2525 
2526   // We want a non-null handle as the function name.
2527   if (should_infer_name) {
2528     function_name = ast_value_factory()->empty_string();
2529   }
2530 
2531   FunctionLiteral::EagerCompileHint eager_compile_hint =
2532       function_state_->next_function_is_likely_called()
2533           ? FunctionLiteral::kShouldEagerCompile
2534           : default_eager_compile_hint();
2535 
2536   // Determine if the function can be parsed lazily. Lazy parsing is
2537   // different from lazy compilation; we need to parse more eagerly than we
2538   // compile.
2539 
2540   // We can only parse lazily if we also compile lazily. The heuristics for lazy
2541   // compilation are:
2542   // - It must not have been prohibited by the caller to Parse (some callers
2543   //   need a full AST).
2544   // - The outer scope must allow lazy compilation of inner functions.
2545   // - The function mustn't be a function expression with an open parenthesis
2546   //   before; we consider that a hint that the function will be called
2547   //   immediately, and it would be a waste of time to make it lazily
2548   //   compiled.
2549   // These are all things we can know at this point, without looking at the
2550   // function itself.
2551 
2552   // We separate between lazy parsing top level functions and lazy parsing inner
2553   // functions, because the latter needs to do more work. In particular, we need
2554   // to track unresolved variables to distinguish between these cases:
2555   // (function foo() {
2556   //   bar = function() { return 1; }
2557   //  })();
2558   // and
2559   // (function foo() {
2560   //   var a = 1;
2561   //   bar = function() { return a; }
2562   //  })();
2563 
2564   // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
2565   // parenthesis before the function means that it will be called
2566   // immediately). bar can be parsed lazily, but we need to parse it in a mode
2567   // that tracks unresolved variables.
2568   DCHECK_IMPLIES(parse_lazily(), FLAG_lazy);
2569   DCHECK_IMPLIES(parse_lazily(), allow_lazy_);
2570   DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr);
2571 
2572   bool can_preparse = parse_lazily() &&
2573                       eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
2574 
2575   bool is_lazy_top_level_function =
2576       can_preparse && impl()->AllowsLazyParsingWithoutUnresolvedVariables();
2577 
2578   RuntimeCallTimerScope runtime_timer(
2579       runtime_call_stats_,
2580       parsing_on_main_thread_
2581           ? &RuntimeCallStats::ParseFunctionLiteral
2582           : &RuntimeCallStats::ParseBackgroundFunctionLiteral);
2583 
2584   // Determine whether we can still lazy parse the inner function.
2585   // The preconditions are:
2586   // - Lazy compilation has to be enabled.
2587   // - Neither V8 natives nor native function declarations can be allowed,
2588   //   since parsing one would retroactively force the function to be
2589   //   eagerly compiled.
2590   // - The invoker of this parser can't depend on the AST being eagerly
2591   //   built (either because the function is about to be compiled, or
2592   //   because the AST is going to be inspected for some reason).
2593   // - Because of the above, we can't be attempting to parse a
2594   //   FunctionExpression; even without enclosing parentheses it might be
2595   //   immediately invoked.
2596   // - The function literal shouldn't be hinted to eagerly compile.
2597 
2598   // Inner functions will be parsed using a temporary Zone. After parsing, we
2599   // will migrate unresolved variable into a Scope in the main Zone.
2600   // TODO(marja): Refactor parsing modes: simplify this.
2601   bool use_temp_zone =
2602       (FLAG_aggressive_lazy_inner_functions
2603            ? can_preparse
2604            : (is_lazy_top_level_function ||
2605               (parse_lazily() &&
2606                function_type == FunctionLiteral::kDeclaration &&
2607                eager_compile_hint == FunctionLiteral::kShouldLazyCompile)));
2608 
2609   DCHECK_IMPLIES(
2610       (is_lazy_top_level_function ||
2611        (parse_lazily() && function_type == FunctionLiteral::kDeclaration &&
2612         eager_compile_hint == FunctionLiteral::kShouldLazyCompile)),
2613       can_preparse);
2614   bool is_lazy_inner_function =
2615       use_temp_zone && FLAG_lazy_inner_functions && !is_lazy_top_level_function;
2616 
2617   ZoneList<Statement*>* body = nullptr;
2618   int expected_property_count = -1;
2619   bool should_be_used_once_hint = false;
2620   int num_parameters = -1;
2621   int function_length = -1;
2622   bool has_duplicate_parameters = false;
2623   int function_literal_id = GetNextFunctionLiteralId();
2624 
2625   Zone* outer_zone = zone();
2626   DeclarationScope* scope;
2627 
2628   {
2629     // Temporary zones can nest. When we migrate free variables (see below), we
2630     // need to recreate them in the previous Zone.
2631     AstNodeFactory previous_zone_ast_node_factory(ast_value_factory());
2632     previous_zone_ast_node_factory.set_zone(zone());
2633 
2634     // Open a new zone scope, which sets our AstNodeFactory to allocate in the
2635     // new temporary zone if the preconditions are satisfied, and ensures that
2636     // the previous zone is always restored after parsing the body. To be able
2637     // to do scope analysis correctly after full parsing, we migrate needed
2638     // information when the function is parsed.
2639     Zone temp_zone(zone()->allocator(), ZONE_NAME);
2640     DiscardableZoneScope zone_scope(this, &temp_zone, use_temp_zone);
2641 
2642     // This Scope lives in the main zone. We'll migrate data into that zone
2643     // later.
2644     scope = NewFunctionScope(kind, outer_zone);
2645     SetLanguageMode(scope, language_mode);
2646 #ifdef DEBUG
2647     scope->SetScopeName(function_name);
2648     if (use_temp_zone) scope->set_needs_migration();
2649 #endif
2650 
2651     Expect(Token::LPAREN, CHECK_OK);
2652     scope->set_start_position(scanner()->location().beg_pos);
2653 
2654     // Eager or lazy parse? If is_lazy_top_level_function, we'll parse
2655     // lazily. We'll call SkipFunction, which may decide to
2656     // abort lazy parsing if it suspects that wasn't a good idea. If so (in
2657     // which case the parser is expected to have backtracked), or if we didn't
2658     // try to lazy parse in the first place, we'll have to parse eagerly.
2659     if (is_lazy_top_level_function || is_lazy_inner_function) {
2660       Scanner::BookmarkScope bookmark(scanner());
2661       bookmark.Set();
2662       LazyParsingResult result = SkipFunction(
2663           kind, scope, &num_parameters, &function_length,
2664           &has_duplicate_parameters, &expected_property_count,
2665           is_lazy_inner_function, is_lazy_top_level_function, CHECK_OK);
2666 
2667       if (result == kLazyParsingAborted) {
2668         DCHECK(is_lazy_top_level_function);
2669         bookmark.Apply();
2670         // Trigger eager (re-)parsing, just below this block.
2671         is_lazy_top_level_function = false;
2672 
2673         // This is probably an initialization function. Inform the compiler it
2674         // should also eager-compile this function, and that we expect it to be
2675         // used once.
2676         eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
2677         should_be_used_once_hint = true;
2678         scope->ResetAfterPreparsing(ast_value_factory(), true);
2679         zone_scope.Reset();
2680         use_temp_zone = false;
2681       }
2682     }
2683 
2684     if (!is_lazy_top_level_function && !is_lazy_inner_function) {
2685       body = ParseFunction(function_name, pos, kind, function_type, scope,
2686                            &num_parameters, &function_length,
2687                            &has_duplicate_parameters, &expected_property_count,
2688                            CHECK_OK);
2689     }
2690 
2691     DCHECK(use_temp_zone || !is_lazy_top_level_function);
2692     if (use_temp_zone) {
2693       // If the preconditions are correct the function body should never be
2694       // accessed, but do this anyway for better behaviour if they're wrong.
2695       body = nullptr;
2696       scope->AnalyzePartially(&previous_zone_ast_node_factory,
2697                               preparsed_scope_data_);
2698     }
2699 
2700     DCHECK_IMPLIES(use_temp_zone, temp_zoned_);
2701     if (FLAG_trace_preparse) {
2702       PrintF("  [%s]: %i-%i %.*s\n",
2703              is_lazy_top_level_function
2704                  ? "Preparse no-resolution"
2705                  : (temp_zoned_ ? "Preparse resolution" : "Full parse"),
2706              scope->start_position(), scope->end_position(),
2707              function_name->byte_length(), function_name->raw_data());
2708     }
2709     if (V8_UNLIKELY(FLAG_runtime_stats)) {
2710       if (is_lazy_top_level_function) {
2711         RuntimeCallStats::CorrectCurrentCounterId(
2712             runtime_call_stats_,
2713             parsing_on_main_thread_
2714                 ? &RuntimeCallStats::PreParseNoVariableResolution
2715                 : &RuntimeCallStats::PreParseBackgroundNoVariableResolution);
2716       } else if (temp_zoned_) {
2717         RuntimeCallStats::CorrectCurrentCounterId(
2718             runtime_call_stats_,
2719             parsing_on_main_thread_
2720                 ? &RuntimeCallStats::PreParseWithVariableResolution
2721                 : &RuntimeCallStats::PreParseBackgroundWithVariableResolution);
2722       }
2723     }
2724 
2725     // Validate function name. We can do this only after parsing the function,
2726     // since the function can declare itself strict.
2727     language_mode = scope->language_mode();
2728     CheckFunctionName(language_mode, function_name, function_name_validity,
2729                       function_name_location, CHECK_OK);
2730 
2731     if (is_strict(language_mode)) {
2732       CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
2733                               CHECK_OK);
2734     }
2735     CheckConflictingVarDeclarations(scope, CHECK_OK);
2736   }  // DiscardableZoneScope goes out of scope.
2737 
2738   FunctionLiteral::ParameterFlag duplicate_parameters =
2739       has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
2740                                : FunctionLiteral::kNoDuplicateParameters;
2741 
2742   // Note that the FunctionLiteral needs to be created in the main Zone again.
2743   FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
2744       function_name, scope, body, expected_property_count, num_parameters,
2745       function_length, duplicate_parameters, function_type, eager_compile_hint,
2746       pos, true, function_literal_id);
2747   function_literal->set_function_token_position(function_token_pos);
2748   if (should_be_used_once_hint)
2749     function_literal->set_should_be_used_once_hint();
2750 
2751   if (should_infer_name) {
2752     DCHECK_NOT_NULL(fni_);
2753     fni_->AddFunction(function_literal);
2754   }
2755   return function_literal;
2756 }
2757 
SkipFunction(FunctionKind kind,DeclarationScope * function_scope,int * num_parameters,int * function_length,bool * has_duplicate_parameters,int * expected_property_count,bool is_inner_function,bool may_abort,bool * ok)2758 Parser::LazyParsingResult Parser::SkipFunction(
2759     FunctionKind kind, DeclarationScope* function_scope, int* num_parameters,
2760     int* function_length, bool* has_duplicate_parameters,
2761     int* expected_property_count, bool is_inner_function, bool may_abort,
2762     bool* ok) {
2763   DCHECK_NE(kNoSourcePosition, function_scope->start_position());
2764   DCHECK_EQ(kNoSourcePosition, parameters_end_pos_);
2765   if (produce_cached_parse_data()) CHECK(log_);
2766 
2767   DCHECK_IMPLIES(IsArrowFunction(kind),
2768                  scanner()->current_token() == Token::ARROW);
2769 
2770   // Inner functions are not part of the cached data.
2771   if (!is_inner_function && consume_cached_parse_data() &&
2772       !cached_parse_data_->rejected()) {
2773     // If we have cached data, we use it to skip parsing the function. The data
2774     // contains the information we need to construct the lazy function.
2775     FunctionEntry entry =
2776         cached_parse_data_->GetFunctionEntry(function_scope->start_position());
2777     // Check that cached data is valid. If not, mark it as invalid (the embedder
2778     // handles it). Note that end position greater than end of stream is safe,
2779     // and hard to check.
2780     if (entry.is_valid() &&
2781         entry.end_pos() > function_scope->start_position()) {
2782       total_preparse_skipped_ += entry.end_pos() - position();
2783       function_scope->set_end_position(entry.end_pos());
2784       scanner()->SeekForward(entry.end_pos() - 1);
2785       Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
2786       *num_parameters = entry.num_parameters();
2787       *function_length = entry.function_length();
2788       *has_duplicate_parameters = entry.has_duplicate_parameters();
2789       *expected_property_count = entry.property_count();
2790       SetLanguageMode(function_scope, entry.language_mode());
2791       if (entry.uses_super_property())
2792         function_scope->RecordSuperPropertyUsage();
2793       if (entry.calls_eval()) function_scope->RecordEvalCall();
2794       SkipFunctionLiterals(entry.num_inner_functions());
2795       return kLazyParsingComplete;
2796     }
2797     cached_parse_data_->Reject();
2798   }
2799 
2800   // With no cached data, we partially parse the function, without building an
2801   // AST. This gathers the data needed to build a lazy function.
2802   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse");
2803 
2804   if (reusable_preparser_ == NULL) {
2805     reusable_preparser_ = new PreParser(
2806         zone(), &scanner_, stack_limit_, ast_value_factory(),
2807         &pending_error_handler_, runtime_call_stats_, parsing_on_main_thread_);
2808 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name());
2809     SET_ALLOW(natives);
2810     SET_ALLOW(harmony_do_expressions);
2811     SET_ALLOW(harmony_function_sent);
2812     SET_ALLOW(harmony_trailing_commas);
2813     SET_ALLOW(harmony_class_fields);
2814     SET_ALLOW(harmony_object_rest_spread);
2815     SET_ALLOW(harmony_dynamic_import);
2816     SET_ALLOW(harmony_async_iteration);
2817 #undef SET_ALLOW
2818   }
2819   // Aborting inner function preparsing would leave scopes in an inconsistent
2820   // state; we don't parse inner functions in the abortable mode anyway.
2821   DCHECK(!is_inner_function || !may_abort);
2822 
2823   PreParser::PreParseResult result = reusable_preparser_->PreParseFunction(
2824       kind, function_scope, parsing_module_, is_inner_function, may_abort,
2825       use_counts_);
2826 
2827   // Return immediately if pre-parser decided to abort parsing.
2828   if (result == PreParser::kPreParseAbort) return kLazyParsingAborted;
2829   if (result == PreParser::kPreParseStackOverflow) {
2830     // Propagate stack overflow.
2831     set_stack_overflow();
2832     *ok = false;
2833     return kLazyParsingComplete;
2834   }
2835   if (pending_error_handler_.has_pending_error()) {
2836     *ok = false;
2837     return kLazyParsingComplete;
2838   }
2839   PreParserLogger* logger = reusable_preparser_->logger();
2840   function_scope->set_end_position(logger->end());
2841   Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
2842   total_preparse_skipped_ +=
2843       function_scope->end_position() - function_scope->start_position();
2844   *num_parameters = logger->num_parameters();
2845   *function_length = logger->function_length();
2846   *has_duplicate_parameters = logger->has_duplicate_parameters();
2847   *expected_property_count = logger->properties();
2848   SkipFunctionLiterals(logger->num_inner_functions());
2849   if (!is_inner_function && produce_cached_parse_data()) {
2850     DCHECK(log_);
2851     log_->LogFunction(
2852         function_scope->start_position(), function_scope->end_position(),
2853         *num_parameters, *function_length, *has_duplicate_parameters,
2854         *expected_property_count, language_mode(),
2855         function_scope->uses_super_property(), function_scope->calls_eval(),
2856         logger->num_inner_functions());
2857   }
2858   return kLazyParsingComplete;
2859 }
2860 
2861 
BuildAssertIsCoercible(Variable * var)2862 Statement* Parser::BuildAssertIsCoercible(Variable* var) {
2863   // if (var === null || var === undefined)
2864   //     throw /* type error kNonCoercible) */;
2865 
2866   Expression* condition = factory()->NewBinaryOperation(
2867       Token::OR,
2868       factory()->NewCompareOperation(
2869           Token::EQ_STRICT, factory()->NewVariableProxy(var),
2870           factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
2871       factory()->NewCompareOperation(
2872           Token::EQ_STRICT, factory()->NewVariableProxy(var),
2873           factory()->NewNullLiteral(kNoSourcePosition), kNoSourcePosition),
2874       kNoSourcePosition);
2875   Expression* throw_type_error =
2876       NewThrowTypeError(MessageTemplate::kNonCoercible,
2877                         ast_value_factory()->empty_string(), kNoSourcePosition);
2878   IfStatement* if_statement = factory()->NewIfStatement(
2879       condition,
2880       factory()->NewExpressionStatement(throw_type_error, kNoSourcePosition),
2881       factory()->NewEmptyStatement(kNoSourcePosition), kNoSourcePosition);
2882   return if_statement;
2883 }
2884 
2885 
2886 class InitializerRewriter final
2887     : public AstTraversalVisitor<InitializerRewriter> {
2888  public:
InitializerRewriter(uintptr_t stack_limit,Expression * root,Parser * parser,Scope * scope)2889   InitializerRewriter(uintptr_t stack_limit, Expression* root, Parser* parser,
2890                       Scope* scope)
2891       : AstTraversalVisitor(stack_limit, root),
2892         parser_(parser),
2893         scope_(scope) {}
2894 
2895  private:
2896   // This is required so that the overriden Visit* methods can be
2897   // called by the base class (template).
2898   friend class AstTraversalVisitor<InitializerRewriter>;
2899 
2900   // Just rewrite destructuring assignments wrapped in RewritableExpressions.
VisitRewritableExpression(RewritableExpression * to_rewrite)2901   void VisitRewritableExpression(RewritableExpression* to_rewrite) {
2902     if (to_rewrite->is_rewritten()) return;
2903     Parser::PatternRewriter::RewriteDestructuringAssignment(parser_, to_rewrite,
2904                                                             scope_);
2905     AstTraversalVisitor::VisitRewritableExpression(to_rewrite);
2906   }
2907 
2908   // Code in function literals does not need to be eagerly rewritten, it will be
2909   // rewritten when scheduled.
VisitFunctionLiteral(FunctionLiteral * expr)2910   void VisitFunctionLiteral(FunctionLiteral* expr) {}
2911 
2912   Parser* parser_;
2913   Scope* scope_;
2914 };
2915 
2916 
RewriteParameterInitializer(Expression * expr,Scope * scope)2917 void Parser::RewriteParameterInitializer(Expression* expr, Scope* scope) {
2918   InitializerRewriter rewriter(stack_limit_, expr, this, scope);
2919   rewriter.Run();
2920 }
2921 
2922 
BuildParameterInitializationBlock(const ParserFormalParameters & parameters,bool * ok)2923 Block* Parser::BuildParameterInitializationBlock(
2924     const ParserFormalParameters& parameters, bool* ok) {
2925   DCHECK(!parameters.is_simple);
2926   DCHECK(scope()->is_function_scope());
2927   Block* init_block = factory()->NewBlock(NULL, 1, true, kNoSourcePosition);
2928   int index = 0;
2929   for (auto parameter : parameters.params) {
2930     if (parameter->is_nondestructuring_rest()) break;
2931     DeclarationDescriptor descriptor;
2932     descriptor.declaration_kind = DeclarationDescriptor::PARAMETER;
2933     descriptor.scope = scope();
2934     descriptor.mode = LET;
2935     descriptor.declaration_pos = parameter->pattern->position();
2936     // The position that will be used by the AssignmentExpression
2937     // which copies from the temp parameter to the pattern.
2938     //
2939     // TODO(adamk): Should this be kNoSourcePosition, since
2940     // it's just copying from a temp var to the real param var?
2941     descriptor.initialization_pos = parameter->pattern->position();
2942     Expression* initial_value =
2943         factory()->NewVariableProxy(parameters.scope->parameter(index));
2944     if (parameter->initializer != nullptr) {
2945       // IS_UNDEFINED($param) ? initializer : $param
2946 
2947       // Ensure initializer is rewritten
2948       RewriteParameterInitializer(parameter->initializer, scope());
2949 
2950       auto condition = factory()->NewCompareOperation(
2951           Token::EQ_STRICT,
2952           factory()->NewVariableProxy(parameters.scope->parameter(index)),
2953           factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
2954       initial_value = factory()->NewConditional(
2955           condition, parameter->initializer, initial_value, kNoSourcePosition);
2956       descriptor.initialization_pos = parameter->initializer->position();
2957     }
2958 
2959     Scope* param_scope = scope();
2960     Block* param_block = init_block;
2961     if (!parameter->is_simple() && scope()->calls_sloppy_eval()) {
2962       param_scope = NewVarblockScope();
2963       param_scope->set_start_position(descriptor.initialization_pos);
2964       param_scope->set_end_position(parameter->initializer_end_position);
2965       param_scope->RecordEvalCall();
2966       param_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition);
2967       param_block->set_scope(param_scope);
2968       // Pass the appropriate scope in so that PatternRewriter can appropriately
2969       // rewrite inner initializers of the pattern to param_scope
2970       descriptor.scope = param_scope;
2971       // Rewrite the outer initializer to point to param_scope
2972       ReparentParameterExpressionScope(stack_limit(), initial_value,
2973                                        param_scope);
2974     }
2975 
2976     BlockState block_state(&scope_, param_scope);
2977     DeclarationParsingResult::Declaration decl(
2978         parameter->pattern, parameter->initializer_end_position, initial_value);
2979     PatternRewriter::DeclareAndInitializeVariables(
2980         this, param_block, &descriptor, &decl, nullptr, CHECK_OK);
2981 
2982     if (param_block != init_block) {
2983       param_scope = param_scope->FinalizeBlockScope();
2984       if (param_scope != nullptr) {
2985         CheckConflictingVarDeclarations(param_scope, CHECK_OK);
2986       }
2987       init_block->statements()->Add(param_block, zone());
2988     }
2989     ++index;
2990   }
2991   return init_block;
2992 }
2993 
BuildRejectPromiseOnException(Block * inner_block)2994 Block* Parser::BuildRejectPromiseOnException(Block* inner_block) {
2995   // .promise = %AsyncFunctionPromiseCreate();
2996   // try {
2997   //   <inner_block>
2998   // } catch (.catch) {
2999   //   %RejectPromise(.promise, .catch);
3000   //   return .promise;
3001   // } finally {
3002   //   %AsyncFunctionPromiseRelease(.promise);
3003   // }
3004   Block* result = factory()->NewBlock(nullptr, 2, true, kNoSourcePosition);
3005 
3006   // .promise = %AsyncFunctionPromiseCreate();
3007   Statement* set_promise;
3008   {
3009     Expression* create_promise = factory()->NewCallRuntime(
3010         Context::ASYNC_FUNCTION_PROMISE_CREATE_INDEX,
3011         new (zone()) ZoneList<Expression*>(0, zone()), kNoSourcePosition);
3012     Assignment* assign_promise = factory()->NewAssignment(
3013         Token::ASSIGN, factory()->NewVariableProxy(PromiseVariable()),
3014         create_promise, kNoSourcePosition);
3015     set_promise =
3016         factory()->NewExpressionStatement(assign_promise, kNoSourcePosition);
3017   }
3018   result->statements()->Add(set_promise, zone());
3019 
3020   // catch (.catch) { return %RejectPromise(.promise, .catch), .promise }
3021   Scope* catch_scope = NewScope(CATCH_SCOPE);
3022   catch_scope->set_is_hidden();
3023   Variable* catch_variable =
3024       catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR);
3025   Block* catch_block = factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
3026 
3027   Expression* promise_reject = BuildRejectPromise(
3028       factory()->NewVariableProxy(catch_variable), kNoSourcePosition);
3029   ReturnStatement* return_promise_reject =
3030       factory()->NewReturnStatement(promise_reject, kNoSourcePosition);
3031   catch_block->statements()->Add(return_promise_reject, zone());
3032 
3033   TryStatement* try_catch_statement =
3034       factory()->NewTryCatchStatementForAsyncAwait(inner_block, catch_scope,
3035                                                    catch_variable, catch_block,
3036                                                    kNoSourcePosition);
3037 
3038   // There is no TryCatchFinally node, so wrap it in an outer try/finally
3039   Block* outer_try_block =
3040       factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
3041   outer_try_block->statements()->Add(try_catch_statement, zone());
3042 
3043   // finally { %AsyncFunctionPromiseRelease(.promise) }
3044   Block* finally_block =
3045       factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
3046   {
3047     ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
3048     args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
3049     Expression* call_promise_release = factory()->NewCallRuntime(
3050         Context::ASYNC_FUNCTION_PROMISE_RELEASE_INDEX, args, kNoSourcePosition);
3051     Statement* promise_release = factory()->NewExpressionStatement(
3052         call_promise_release, kNoSourcePosition);
3053     finally_block->statements()->Add(promise_release, zone());
3054   }
3055 
3056   Statement* try_finally_statement = factory()->NewTryFinallyStatement(
3057       outer_try_block, finally_block, kNoSourcePosition);
3058 
3059   result->statements()->Add(try_finally_statement, zone());
3060   return result;
3061 }
3062 
BuildCreateJSGeneratorObject(int pos,FunctionKind kind)3063 Assignment* Parser::BuildCreateJSGeneratorObject(int pos, FunctionKind kind) {
3064   // .generator = %CreateJSGeneratorObject(...);
3065   DCHECK_NOT_NULL(function_state_->generator_object_variable());
3066   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
3067   args->Add(factory()->NewThisFunction(pos), zone());
3068   args->Add(IsArrowFunction(kind) ? GetLiteralUndefined(pos)
3069                                   : ThisExpression(kNoSourcePosition),
3070             zone());
3071   Expression* allocation =
3072       factory()->NewCallRuntime(Runtime::kCreateJSGeneratorObject, args, pos);
3073   VariableProxy* proxy =
3074       factory()->NewVariableProxy(function_state_->generator_object_variable());
3075   return factory()->NewAssignment(Token::INIT, proxy, allocation,
3076                                   kNoSourcePosition);
3077 }
3078 
BuildResolvePromise(Expression * value,int pos)3079 Expression* Parser::BuildResolvePromise(Expression* value, int pos) {
3080   // %ResolvePromise(.promise, value), .promise
3081   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
3082   args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
3083   args->Add(value, zone());
3084   Expression* call_runtime =
3085       factory()->NewCallRuntime(Context::PROMISE_RESOLVE_INDEX, args, pos);
3086   return factory()->NewBinaryOperation(
3087       Token::COMMA, call_runtime,
3088       factory()->NewVariableProxy(PromiseVariable()), pos);
3089 }
3090 
BuildRejectPromise(Expression * value,int pos)3091 Expression* Parser::BuildRejectPromise(Expression* value, int pos) {
3092   // %promise_internal_reject(.promise, value, false), .promise
3093   // Disables the additional debug event for the rejection since a debug event
3094   // already happened for the exception that got us here.
3095   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(3, zone());
3096   args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
3097   args->Add(value, zone());
3098   args->Add(factory()->NewBooleanLiteral(false, pos), zone());
3099   Expression* call_runtime = factory()->NewCallRuntime(
3100       Context::PROMISE_INTERNAL_REJECT_INDEX, args, pos);
3101   return factory()->NewBinaryOperation(
3102       Token::COMMA, call_runtime,
3103       factory()->NewVariableProxy(PromiseVariable()), pos);
3104 }
3105 
PromiseVariable()3106 Variable* Parser::PromiseVariable() {
3107   // Based on the various compilation paths, there are many different code
3108   // paths which may be the first to access the Promise temporary. Whichever
3109   // comes first should create it and stash it in the FunctionState.
3110   Variable* promise = function_state_->promise_variable();
3111   if (function_state_->promise_variable() == nullptr) {
3112     promise = function_state_->scope()->DeclarePromiseVar(
3113         ast_value_factory()->empty_string());
3114   }
3115   return promise;
3116 }
3117 
BuildInitialYield(int pos,FunctionKind kind)3118 Expression* Parser::BuildInitialYield(int pos, FunctionKind kind) {
3119   Assignment* assignment = BuildCreateJSGeneratorObject(pos, kind);
3120   VariableProxy* generator =
3121       factory()->NewVariableProxy(function_state_->generator_object_variable());
3122   // The position of the yield is important for reporting the exception
3123   // caused by calling the .throw method on a generator suspended at the
3124   // initial yield (i.e. right after generator instantiation).
3125   return factory()->NewYield(generator, assignment, scope()->start_position(),
3126                              Yield::kOnExceptionThrow);
3127 }
3128 
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,bool * ok)3129 ZoneList<Statement*>* Parser::ParseFunction(
3130     const AstRawString* function_name, int pos, FunctionKind kind,
3131     FunctionLiteral::FunctionType function_type,
3132     DeclarationScope* function_scope, int* num_parameters, int* function_length,
3133     bool* has_duplicate_parameters, int* expected_property_count, bool* ok) {
3134   ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
3135 
3136   FunctionState function_state(&function_state_, &scope_, function_scope);
3137 
3138   DuplicateFinder duplicate_finder;
3139   ExpressionClassifier formals_classifier(this, &duplicate_finder);
3140 
3141   if (IsResumableFunction(kind)) PrepareGeneratorVariables();
3142 
3143   int expected_parameters_end_pos = parameters_end_pos_;
3144   if (expected_parameters_end_pos != kNoSourcePosition) {
3145     // This is the first function encountered in a CreateDynamicFunction eval.
3146     parameters_end_pos_ = kNoSourcePosition;
3147     // The function name should have been ignored, giving us the empty string
3148     // here.
3149     DCHECK_EQ(function_name, ast_value_factory()->empty_string());
3150   }
3151 
3152   ParserFormalParameters formals(function_scope);
3153   ParseFormalParameterList(&formals, CHECK_OK);
3154   if (expected_parameters_end_pos != kNoSourcePosition) {
3155     // Check for '(' or ')' shenanigans in the parameter string for dynamic
3156     // functions.
3157     int position = peek_position();
3158     if (position < expected_parameters_end_pos) {
3159       ReportMessageAt(Scanner::Location(position, position + 1),
3160                       MessageTemplate::kArgStringTerminatesParametersEarly);
3161       *ok = false;
3162       return nullptr;
3163     } else if (position > expected_parameters_end_pos) {
3164       ReportMessageAt(Scanner::Location(expected_parameters_end_pos - 2,
3165                                         expected_parameters_end_pos),
3166                       MessageTemplate::kUnexpectedEndOfArgString);
3167       *ok = false;
3168       return nullptr;
3169     }
3170   }
3171   Expect(Token::RPAREN, CHECK_OK);
3172   int formals_end_position = scanner()->location().end_pos;
3173   *num_parameters = formals.num_parameters();
3174   *function_length = formals.function_length;
3175 
3176   CheckArityRestrictions(formals.arity, kind, formals.has_rest,
3177                          function_scope->start_position(), formals_end_position,
3178                          CHECK_OK);
3179   Expect(Token::LBRACE, CHECK_OK);
3180 
3181   ZoneList<Statement*>* body = new (zone()) ZoneList<Statement*>(8, zone());
3182   ParseFunctionBody(body, function_name, pos, formals, kind, function_type, ok);
3183 
3184   // Validate parameter names. We can do this only after parsing the function,
3185   // since the function can declare itself strict.
3186   const bool allow_duplicate_parameters =
3187       is_sloppy(function_scope->language_mode()) && formals.is_simple &&
3188       !IsConciseMethod(kind);
3189   ValidateFormalParameters(function_scope->language_mode(),
3190                            allow_duplicate_parameters, CHECK_OK);
3191 
3192   RewriteDestructuringAssignments();
3193 
3194   *has_duplicate_parameters =
3195       !classifier()->is_valid_formal_parameter_list_without_duplicates();
3196 
3197   *expected_property_count = function_state.expected_property_count();
3198   return body;
3199 }
3200 
DeclareClassVariable(const AstRawString * name,ClassInfo * class_info,int class_token_pos,bool * ok)3201 void Parser::DeclareClassVariable(const AstRawString* name,
3202                                   ClassInfo* class_info, int class_token_pos,
3203                                   bool* ok) {
3204 #ifdef DEBUG
3205   scope()->SetScopeName(name);
3206 #endif
3207 
3208   if (name != nullptr) {
3209     class_info->proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE);
3210     Declaration* declaration = factory()->NewVariableDeclaration(
3211         class_info->proxy, scope(), class_token_pos);
3212     Declare(declaration, DeclarationDescriptor::NORMAL, CONST,
3213             Variable::DefaultInitializationFlag(CONST), ok);
3214   }
3215 }
3216 
3217 // This method declares a property of the given class.  It updates the
3218 // following fields of class_info, as appropriate:
3219 //   - constructor
3220 //   - properties
DeclareClassProperty(const AstRawString * class_name,ClassLiteralProperty * property,ClassLiteralProperty::Kind kind,bool is_static,bool is_constructor,ClassInfo * class_info,bool * ok)3221 void Parser::DeclareClassProperty(const AstRawString* class_name,
3222                                   ClassLiteralProperty* property,
3223                                   ClassLiteralProperty::Kind kind,
3224                                   bool is_static, bool is_constructor,
3225                                   ClassInfo* class_info, bool* ok) {
3226   if (is_constructor) {
3227     DCHECK(!class_info->constructor);
3228     class_info->constructor = GetPropertyValue(property)->AsFunctionLiteral();
3229     DCHECK_NOT_NULL(class_info->constructor);
3230     class_info->constructor->set_raw_name(
3231         class_name != nullptr ? class_name
3232                               : ast_value_factory()->empty_string());
3233     return;
3234   }
3235 
3236   if (property->kind() == ClassLiteralProperty::FIELD) {
3237     DCHECK(allow_harmony_class_fields());
3238     // TODO(littledan): Implement class fields
3239   }
3240   class_info->properties->Add(property, zone());
3241 }
3242 
3243 // This method rewrites a class literal into a do-expression.
3244 // It uses the following fields of class_info:
3245 //   - constructor (if missing, it updates it with a default constructor)
3246 //   - proxy
3247 //   - extends
3248 //   - properties
3249 //   - has_name_static_property
3250 //   - has_static_computed_names
RewriteClassLiteral(const AstRawString * name,ClassInfo * class_info,int pos,bool * ok)3251 Expression* Parser::RewriteClassLiteral(const AstRawString* name,
3252                                         ClassInfo* class_info, int pos,
3253                                         bool* ok) {
3254   int end_pos = scanner()->location().end_pos;
3255   Block* do_block = factory()->NewBlock(nullptr, 1, false, pos);
3256   Variable* result_var = NewTemporary(ast_value_factory()->empty_string());
3257   DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos);
3258 
3259   bool has_extends = class_info->extends != nullptr;
3260   bool has_default_constructor = class_info->constructor == nullptr;
3261   if (has_default_constructor) {
3262     class_info->constructor =
3263         DefaultConstructor(name, has_extends, pos, end_pos);
3264   }
3265 
3266   scope()->set_end_position(end_pos);
3267 
3268   if (name != nullptr) {
3269     DCHECK_NOT_NULL(class_info->proxy);
3270     class_info->proxy->var()->set_initializer_position(end_pos);
3271   }
3272 
3273   ClassLiteral* class_literal = factory()->NewClassLiteral(
3274       class_info->proxy, class_info->extends, class_info->constructor,
3275       class_info->properties, pos, end_pos,
3276       class_info->has_name_static_property,
3277       class_info->has_static_computed_names);
3278 
3279   do_block->statements()->Add(
3280       factory()->NewExpressionStatement(
3281           factory()->NewAssignment(Token::ASSIGN,
3282                                    factory()->NewVariableProxy(result_var),
3283                                    class_literal, kNoSourcePosition),
3284           pos),
3285       zone());
3286   do_block->set_scope(scope()->FinalizeBlockScope());
3287   do_expr->set_represented_function(class_info->constructor);
3288   AddFunctionForNameInference(class_info->constructor);
3289 
3290   return do_expr;
3291 }
3292 
GetLiteralUndefined(int position)3293 Literal* Parser::GetLiteralUndefined(int position) {
3294   return factory()->NewUndefinedLiteral(position);
3295 }
3296 
3297 
CheckConflictingVarDeclarations(Scope * scope,bool * ok)3298 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
3299   Declaration* decl = scope->CheckConflictingVarDeclarations();
3300   if (decl != NULL) {
3301     // In ES6, conflicting variable bindings are early errors.
3302     const AstRawString* name = decl->proxy()->raw_name();
3303     int position = decl->proxy()->position();
3304     Scanner::Location location =
3305         position == kNoSourcePosition
3306             ? Scanner::Location::invalid()
3307             : Scanner::Location(position, position + 1);
3308     ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
3309     *ok = false;
3310   }
3311 }
3312 
3313 
InsertShadowingVarBindingInitializers(Block * inner_block)3314 void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) {
3315   // For each var-binding that shadows a parameter, insert an assignment
3316   // initializing the variable with the parameter.
3317   Scope* inner_scope = inner_block->scope();
3318   DCHECK(inner_scope->is_declaration_scope());
3319   Scope* function_scope = inner_scope->outer_scope();
3320   DCHECK(function_scope->is_function_scope());
3321   BlockState block_state(&scope_, inner_scope);
3322   for (Declaration* decl : *inner_scope->declarations()) {
3323     if (decl->proxy()->var()->mode() != VAR || !decl->IsVariableDeclaration()) {
3324       continue;
3325     }
3326     const AstRawString* name = decl->proxy()->raw_name();
3327     Variable* parameter = function_scope->LookupLocal(name);
3328     if (parameter == nullptr) continue;
3329     VariableProxy* to = NewUnresolved(name);
3330     VariableProxy* from = factory()->NewVariableProxy(parameter);
3331     Expression* assignment =
3332         factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition);
3333     Statement* statement =
3334         factory()->NewExpressionStatement(assignment, kNoSourcePosition);
3335     inner_block->statements()->InsertAt(0, statement, zone());
3336   }
3337 }
3338 
InsertSloppyBlockFunctionVarBindings(DeclarationScope * scope)3339 void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope) {
3340   // For the outermost eval scope, we cannot hoist during parsing: let
3341   // declarations in the surrounding scope may prevent hoisting, but the
3342   // information is unaccessible during parsing. In this case, we hoist later in
3343   // DeclarationScope::Analyze.
3344   if (scope->is_eval_scope() && scope->outer_scope() == original_scope_) {
3345     return;
3346   }
3347   scope->HoistSloppyBlockFunctions(factory());
3348 }
3349 
3350 // ----------------------------------------------------------------------------
3351 // Parser support
3352 
TargetStackContainsLabel(const AstRawString * label)3353 bool Parser::TargetStackContainsLabel(const AstRawString* label) {
3354   for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) {
3355     if (ContainsLabel(t->statement()->labels(), label)) return true;
3356   }
3357   return false;
3358 }
3359 
3360 
LookupBreakTarget(const AstRawString * label,bool * ok)3361 BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label,
3362                                               bool* ok) {
3363   bool anonymous = label == NULL;
3364   for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) {
3365     BreakableStatement* stat = t->statement();
3366     if ((anonymous && stat->is_target_for_anonymous()) ||
3367         (!anonymous && ContainsLabel(stat->labels(), label))) {
3368       return stat;
3369     }
3370   }
3371   return NULL;
3372 }
3373 
3374 
LookupContinueTarget(const AstRawString * label,bool * ok)3375 IterationStatement* Parser::LookupContinueTarget(const AstRawString* label,
3376                                                  bool* ok) {
3377   bool anonymous = label == NULL;
3378   for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) {
3379     IterationStatement* stat = t->statement()->AsIterationStatement();
3380     if (stat == NULL) continue;
3381 
3382     DCHECK(stat->is_target_for_anonymous());
3383     if (anonymous || ContainsLabel(stat->labels(), label)) {
3384       return stat;
3385     }
3386   }
3387   return NULL;
3388 }
3389 
3390 
HandleSourceURLComments(Isolate * isolate,Handle<Script> script)3391 void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) {
3392   Handle<String> source_url = scanner_.SourceUrl(isolate);
3393   if (!source_url.is_null()) {
3394     script->set_source_url(*source_url);
3395   }
3396   Handle<String> source_mapping_url = scanner_.SourceMappingUrl(isolate);
3397   if (!source_mapping_url.is_null()) {
3398     script->set_source_mapping_url(*source_mapping_url);
3399   }
3400 }
3401 
ReportErrors(Isolate * isolate,Handle<Script> script)3402 void Parser::ReportErrors(Isolate* isolate, Handle<Script> script) {
3403   if (stack_overflow()) {
3404     isolate->StackOverflow();
3405   } else {
3406     DCHECK(pending_error_handler_.has_pending_error());
3407     // Internalize ast values for throwing the pending error.
3408     ast_value_factory()->Internalize(isolate);
3409     pending_error_handler_.ThrowPendingError(isolate, script);
3410   }
3411 }
3412 
UpdateStatistics(Isolate * isolate,Handle<Script> script)3413 void Parser::UpdateStatistics(Isolate* isolate, Handle<Script> script) {
3414   // Move statistics to Isolate.
3415   for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
3416        ++feature) {
3417     if (use_counts_[feature] > 0) {
3418       isolate->CountUsage(v8::Isolate::UseCounterFeature(feature));
3419     }
3420   }
3421   if (scanner_.FoundHtmlComment()) {
3422     isolate->CountUsage(v8::Isolate::kHtmlComment);
3423     if (script->line_offset() == 0 && script->column_offset() == 0) {
3424       isolate->CountUsage(v8::Isolate::kHtmlCommentInExternalScript);
3425     }
3426   }
3427   isolate->counters()->total_preparse_skipped()->Increment(
3428       total_preparse_skipped_);
3429   if (!parsing_on_main_thread_ &&
3430       FLAG_runtime_stats ==
3431           v8::tracing::TracingCategoryObserver::ENABLED_BY_NATIVE) {
3432     // Copy over the counters from the background thread to the main counters on
3433     // the isolate.
3434     isolate->counters()->runtime_call_stats()->Add(runtime_call_stats_);
3435   }
3436 }
3437 
ParseOnBackground(ParseInfo * info)3438 void Parser::ParseOnBackground(ParseInfo* info) {
3439   parsing_on_main_thread_ = false;
3440 
3441   DCHECK(info->literal() == NULL);
3442   FunctionLiteral* result = NULL;
3443 
3444   ParserLogger logger;
3445   if (produce_cached_parse_data()) {
3446     if (allow_lazy_) {
3447       log_ = &logger;
3448     } else {
3449       compile_options_ = ScriptCompiler::kNoCompileOptions;
3450     }
3451   }
3452   if (FLAG_runtime_stats) {
3453     // Create separate runtime stats for background parsing.
3454     runtime_call_stats_ = new (zone()) RuntimeCallStats();
3455   }
3456 
3457   std::unique_ptr<Utf16CharacterStream> stream;
3458   Utf16CharacterStream* stream_ptr;
3459   if (info->character_stream()) {
3460     DCHECK(info->source_stream() == nullptr);
3461     stream_ptr = info->character_stream();
3462   } else {
3463     DCHECK(info->character_stream() == nullptr);
3464     stream.reset(ScannerStream::For(info->source_stream(),
3465                                     info->source_stream_encoding(),
3466                                     runtime_call_stats_));
3467     stream_ptr = stream.get();
3468   }
3469   DCHECK(info->maybe_outer_scope_info().is_null());
3470 
3471   DCHECK(original_scope_);
3472 
3473   // When streaming, we don't know the length of the source until we have parsed
3474   // it. The raw data can be UTF-8, so we wouldn't know the source length until
3475   // we have decoded it anyway even if we knew the raw data length (which we
3476   // don't). We work around this by storing all the scopes which need their end
3477   // position set at the end of the script (the top scope and possible eval
3478   // scopes) and set their end position after we know the script length.
3479   if (info->is_toplevel()) {
3480     fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
3481     scanner_.Initialize(stream_ptr);
3482     result = DoParseProgram(info);
3483   } else {
3484     result = DoParseFunction(info, info->function_name(), stream_ptr);
3485   }
3486 
3487   info->set_literal(result);
3488 
3489   // We cannot internalize on a background thread; a foreground task will take
3490   // care of calling Parser::Internalize just before compilation.
3491 
3492   if (produce_cached_parse_data()) {
3493     if (result != NULL) *info->cached_data() = logger.GetScriptData();
3494     log_ = NULL;
3495   }
3496   if (FLAG_runtime_stats &
3497       v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING) {
3498     auto value = v8::tracing::TracedValue::Create();
3499     runtime_call_stats_->Dump(value.get());
3500     TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("v8.runtime_stats"),
3501                          "V8.RuntimeStats", TRACE_EVENT_SCOPE_THREAD,
3502                          "runtime-call-stats", std::move(value));
3503   }
3504 }
3505 
OpenTemplateLiteral(int pos)3506 Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
3507   return new (zone()) TemplateLiteral(zone(), pos);
3508 }
3509 
AddTemplateSpan(TemplateLiteralState * state,bool should_cook,bool tail)3510 void Parser::AddTemplateSpan(TemplateLiteralState* state, bool should_cook,
3511                              bool tail) {
3512   DCHECK(should_cook || allow_harmony_template_escapes());
3513   int pos = scanner()->location().beg_pos;
3514   int end = scanner()->location().end_pos - (tail ? 1 : 2);
3515   const AstRawString* trv = scanner()->CurrentRawSymbol(ast_value_factory());
3516   Literal* raw = factory()->NewStringLiteral(trv, pos);
3517   if (should_cook) {
3518     const AstRawString* tv = scanner()->CurrentSymbol(ast_value_factory());
3519     Literal* cooked = factory()->NewStringLiteral(tv, pos);
3520     (*state)->AddTemplateSpan(cooked, raw, end, zone());
3521   } else {
3522     (*state)->AddTemplateSpan(GetLiteralUndefined(pos), raw, end, zone());
3523   }
3524 }
3525 
3526 
AddTemplateExpression(TemplateLiteralState * state,Expression * expression)3527 void Parser::AddTemplateExpression(TemplateLiteralState* state,
3528                                    Expression* expression) {
3529   (*state)->AddExpression(expression, zone());
3530 }
3531 
3532 
CloseTemplateLiteral(TemplateLiteralState * state,int start,Expression * tag)3533 Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
3534                                          Expression* tag) {
3535   TemplateLiteral* lit = *state;
3536   int pos = lit->position();
3537   const ZoneList<Expression*>* cooked_strings = lit->cooked();
3538   const ZoneList<Expression*>* raw_strings = lit->raw();
3539   const ZoneList<Expression*>* expressions = lit->expressions();
3540   DCHECK_EQ(cooked_strings->length(), raw_strings->length());
3541   DCHECK_EQ(cooked_strings->length(), expressions->length() + 1);
3542 
3543   if (!tag) {
3544     // Build tree of BinaryOps to simplify code-generation
3545     Expression* expr = cooked_strings->at(0);
3546     int i = 0;
3547     while (i < expressions->length()) {
3548       Expression* sub = expressions->at(i++);
3549       Expression* cooked_str = cooked_strings->at(i);
3550 
3551       // Let middle be ToString(sub).
3552       ZoneList<Expression*>* args =
3553           new (zone()) ZoneList<Expression*>(1, zone());
3554       args->Add(sub, zone());
3555       Expression* middle = factory()->NewCallRuntime(Runtime::kInlineToString,
3556                                                      args, sub->position());
3557 
3558       expr = factory()->NewBinaryOperation(
3559           Token::ADD, factory()->NewBinaryOperation(
3560                           Token::ADD, expr, middle, expr->position()),
3561           cooked_str, sub->position());
3562     }
3563     return expr;
3564   } else {
3565     uint32_t hash = ComputeTemplateLiteralHash(lit);
3566 
3567     // $getTemplateCallSite
3568     ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone());
3569     args->Add(factory()->NewArrayLiteral(
3570                   const_cast<ZoneList<Expression*>*>(cooked_strings), pos),
3571               zone());
3572     args->Add(factory()->NewArrayLiteral(
3573                   const_cast<ZoneList<Expression*>*>(raw_strings), pos),
3574               zone());
3575 
3576     // Truncate hash to Smi-range.
3577     Smi* hash_obj = Smi::cast(Internals::IntToSmi(static_cast<int>(hash)));
3578     args->Add(factory()->NewNumberLiteral(hash_obj->value(), pos), zone());
3579 
3580     Expression* call_site = factory()->NewCallRuntime(
3581         Context::GET_TEMPLATE_CALL_SITE_INDEX, args, start);
3582 
3583     // Call TagFn
3584     ZoneList<Expression*>* call_args =
3585         new (zone()) ZoneList<Expression*>(expressions->length() + 1, zone());
3586     call_args->Add(call_site, zone());
3587     call_args->AddAll(*expressions, zone());
3588     return factory()->NewCall(tag, call_args, pos);
3589   }
3590 }
3591 
3592 
ComputeTemplateLiteralHash(const TemplateLiteral * lit)3593 uint32_t Parser::ComputeTemplateLiteralHash(const TemplateLiteral* lit) {
3594   const ZoneList<Expression*>* raw_strings = lit->raw();
3595   int total = raw_strings->length();
3596   DCHECK(total);
3597 
3598   uint32_t running_hash = 0;
3599 
3600   for (int index = 0; index < total; ++index) {
3601     if (index) {
3602       running_hash = StringHasher::ComputeRunningHashOneByte(
3603           running_hash, "${}", 3);
3604     }
3605 
3606     const AstRawString* raw_string =
3607         raw_strings->at(index)->AsLiteral()->raw_value()->AsString();
3608     if (raw_string->is_one_byte()) {
3609       const char* data = reinterpret_cast<const char*>(raw_string->raw_data());
3610       running_hash = StringHasher::ComputeRunningHashOneByte(
3611           running_hash, data, raw_string->length());
3612     } else {
3613       const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data());
3614       running_hash = StringHasher::ComputeRunningHash(running_hash, data,
3615                                                       raw_string->length());
3616     }
3617   }
3618 
3619   return running_hash;
3620 }
3621 
3622 namespace {
3623 
OnlyLastArgIsSpread(ZoneList<Expression * > * args)3624 bool OnlyLastArgIsSpread(ZoneList<Expression*>* args) {
3625   for (int i = 0; i < args->length() - 1; i++) {
3626     if (args->at(i)->IsSpread()) {
3627       return false;
3628     }
3629   }
3630   return args->at(args->length() - 1)->IsSpread();
3631 }
3632 
3633 }  // namespace
3634 
PrepareSpreadArguments(ZoneList<Expression * > * list)3635 ZoneList<Expression*>* Parser::PrepareSpreadArguments(
3636     ZoneList<Expression*>* list) {
3637   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
3638   if (list->length() == 1) {
3639     // Spread-call with single spread argument produces an InternalArray
3640     // containing the values from the array.
3641     //
3642     // Function is called or constructed with the produced array of arguments
3643     //
3644     // EG: Apply(Func, Spread(spread0))
3645     ZoneList<Expression*>* spread_list =
3646         new (zone()) ZoneList<Expression*>(0, zone());
3647     spread_list->Add(list->at(0)->AsSpread()->expression(), zone());
3648     args->Add(factory()->NewCallRuntime(Runtime::kSpreadIterablePrepare,
3649                                         spread_list, kNoSourcePosition),
3650               zone());
3651     return args;
3652   } else {
3653     // Spread-call with multiple arguments produces array literals for each
3654     // sequences of unspread arguments, and converts each spread iterable to
3655     // an Internal array. Finally, all of these produced arrays are flattened
3656     // into a single InternalArray, containing the arguments for the call.
3657     //
3658     // EG: Apply(Func, Flatten([unspread0, unspread1], Spread(spread0),
3659     //                         Spread(spread1), [unspread2, unspread3]))
3660     int i = 0;
3661     int n = list->length();
3662     while (i < n) {
3663       if (!list->at(i)->IsSpread()) {
3664         ZoneList<Expression*>* unspread =
3665             new (zone()) ZoneList<Expression*>(1, zone());
3666 
3667         // Push array of unspread parameters
3668         while (i < n && !list->at(i)->IsSpread()) {
3669           unspread->Add(list->at(i++), zone());
3670         }
3671         args->Add(factory()->NewArrayLiteral(unspread, kNoSourcePosition),
3672                   zone());
3673 
3674         if (i == n) break;
3675       }
3676 
3677       // Push eagerly spread argument
3678       ZoneList<Expression*>* spread_list =
3679           new (zone()) ZoneList<Expression*>(1, zone());
3680       spread_list->Add(list->at(i++)->AsSpread()->expression(), zone());
3681       args->Add(factory()->NewCallRuntime(Context::SPREAD_ITERABLE_INDEX,
3682                                           spread_list, kNoSourcePosition),
3683                 zone());
3684     }
3685 
3686     list = new (zone()) ZoneList<Expression*>(1, zone());
3687     list->Add(factory()->NewCallRuntime(Context::SPREAD_ARGUMENTS_INDEX, args,
3688                                         kNoSourcePosition),
3689               zone());
3690     return list;
3691   }
3692   UNREACHABLE();
3693 }
3694 
SpreadCall(Expression * function,ZoneList<Expression * > * args,int pos,Call::PossiblyEval is_possibly_eval)3695 Expression* Parser::SpreadCall(Expression* function,
3696                                ZoneList<Expression*>* args, int pos,
3697                                Call::PossiblyEval is_possibly_eval) {
3698   // Handle these cases in BytecodeGenerator.
3699   // [Call,New]WithSpread bytecodes aren't used with tailcalls - see
3700   // https://crbug.com/v8/5867
3701   if (!allow_tailcalls() && OnlyLastArgIsSpread(args)) {
3702     return factory()->NewCall(function, args, pos);
3703   }
3704 
3705   if (function->IsSuperCallReference()) {
3706     // Super calls
3707     // $super_constructor = %_GetSuperConstructor(<this-function>)
3708     // %reflect_construct($super_constructor, args, new.target)
3709 
3710     args = PrepareSpreadArguments(args);
3711     ZoneList<Expression*>* tmp = new (zone()) ZoneList<Expression*>(1, zone());
3712     tmp->Add(function->AsSuperCallReference()->this_function_var(), zone());
3713     Expression* super_constructor = factory()->NewCallRuntime(
3714         Runtime::kInlineGetSuperConstructor, tmp, pos);
3715     args->InsertAt(0, super_constructor, zone());
3716     args->Add(function->AsSuperCallReference()->new_target_var(), zone());
3717     return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args,
3718                                      pos);
3719   } else {
3720     args = PrepareSpreadArguments(args);
3721     if (function->IsProperty()) {
3722       // Method calls
3723       if (function->AsProperty()->IsSuperAccess()) {
3724         Expression* home = ThisExpression(kNoSourcePosition);
3725         args->InsertAt(0, function, zone());
3726         args->InsertAt(1, home, zone());
3727       } else {
3728         Variable* temp = NewTemporary(ast_value_factory()->empty_string());
3729         VariableProxy* obj = factory()->NewVariableProxy(temp);
3730         Assignment* assign_obj = factory()->NewAssignment(
3731             Token::ASSIGN, obj, function->AsProperty()->obj(),
3732             kNoSourcePosition);
3733         function = factory()->NewProperty(
3734             assign_obj, function->AsProperty()->key(), kNoSourcePosition);
3735         args->InsertAt(0, function, zone());
3736         obj = factory()->NewVariableProxy(temp);
3737         args->InsertAt(1, obj, zone());
3738       }
3739     } else {
3740       // Non-method calls
3741       args->InsertAt(0, function, zone());
3742       args->InsertAt(1, factory()->NewUndefinedLiteral(kNoSourcePosition),
3743                      zone());
3744     }
3745     return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos);
3746   }
3747 }
3748 
SpreadCallNew(Expression * function,ZoneList<Expression * > * args,int pos)3749 Expression* Parser::SpreadCallNew(Expression* function,
3750                                   ZoneList<Expression*>* args, int pos) {
3751   if (OnlyLastArgIsSpread(args)) {
3752     // Handle in BytecodeGenerator.
3753     return factory()->NewCallNew(function, args, pos);
3754   }
3755   args = PrepareSpreadArguments(args);
3756   args->InsertAt(0, function, zone());
3757 
3758   return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos);
3759 }
3760 
3761 
SetLanguageMode(Scope * scope,LanguageMode mode)3762 void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) {
3763   v8::Isolate::UseCounterFeature feature;
3764   if (is_sloppy(mode))
3765     feature = v8::Isolate::kSloppyMode;
3766   else if (is_strict(mode))
3767     feature = v8::Isolate::kStrictMode;
3768   else
3769     UNREACHABLE();
3770   ++use_counts_[feature];
3771   scope->SetLanguageMode(mode);
3772 }
3773 
SetAsmModule()3774 void Parser::SetAsmModule() {
3775   // Store the usage count; The actual use counter on the isolate is
3776   // incremented after parsing is done.
3777   ++use_counts_[v8::Isolate::kUseAsm];
3778   DCHECK(scope()->is_declaration_scope());
3779   scope()->AsDeclarationScope()->set_asm_module();
3780 }
3781 
MarkCollectedTailCallExpressions()3782 void Parser::MarkCollectedTailCallExpressions() {
3783   const ZoneList<Expression*>& tail_call_expressions =
3784       function_state_->tail_call_expressions().expressions();
3785   for (int i = 0; i < tail_call_expressions.length(); ++i) {
3786     MarkTailPosition(tail_call_expressions[i]);
3787   }
3788 }
3789 
ExpressionListToExpression(ZoneList<Expression * > * args)3790 Expression* Parser::ExpressionListToExpression(ZoneList<Expression*>* args) {
3791   Expression* expr = args->at(0);
3792   for (int i = 1; i < args->length(); ++i) {
3793     expr = factory()->NewBinaryOperation(Token::COMMA, expr, args->at(i),
3794                                          expr->position());
3795   }
3796   return expr;
3797 }
3798 
3799 // This method intoduces the line initializing the generator object
3800 // when desugaring the body of async_function.
PrepareAsyncFunctionBody(ZoneList<Statement * > * body,FunctionKind kind,int pos)3801 void Parser::PrepareAsyncFunctionBody(ZoneList<Statement*>* body,
3802                                       FunctionKind kind, int pos) {
3803   // When parsing an async arrow function, we get here without having called
3804   // PrepareGeneratorVariables yet, so do it now.
3805   if (function_state_->generator_object_variable() == nullptr) {
3806     PrepareGeneratorVariables();
3807   }
3808   body->Add(factory()->NewExpressionStatement(
3809                 BuildCreateJSGeneratorObject(pos, kind), kNoSourcePosition),
3810             zone());
3811 }
3812 
3813 // This method completes the desugaring of the body of async_function.
RewriteAsyncFunctionBody(ZoneList<Statement * > * body,Block * block,Expression * return_value,bool * ok)3814 void Parser::RewriteAsyncFunctionBody(ZoneList<Statement*>* body, Block* block,
3815                                       Expression* return_value, bool* ok) {
3816   // function async_function() {
3817   //   .generator_object = %CreateJSGeneratorObject();
3818   //   BuildRejectPromiseOnException({
3819   //     ... block ...
3820   //     return %ResolvePromise(.promise, expr), .promise;
3821   //   })
3822   // }
3823 
3824   return_value = BuildResolvePromise(return_value, return_value->position());
3825   block->statements()->Add(
3826       factory()->NewReturnStatement(return_value, return_value->position()),
3827       zone());
3828   block = BuildRejectPromiseOnException(block);
3829   body->Add(block, zone());
3830 }
3831 
RewriteAwaitExpression(Expression * value,int await_pos)3832 Expression* Parser::RewriteAwaitExpression(Expression* value, int await_pos) {
3833   // yield do {
3834   //   tmp = <operand>;
3835   //   %AsyncFunctionAwait(.generator_object, tmp, .promise);
3836   //   .promise
3837   // }
3838   // The value of the expression is returned to the caller of the async
3839   // function for the first yield statement; for this, .promise is the
3840   // appropriate return value, being a Promise that will be fulfilled or
3841   // rejected with the appropriate value by the desugaring. Subsequent yield
3842   // occurrences will return to the AsyncFunctionNext call within the
3843   // implemementation of the intermediate throwaway Promise's then handler.
3844   // This handler has nothing useful to do with the value, as the Promise is
3845   // ignored. If we yielded the value of the throwawayPromise that
3846   // AsyncFunctionAwait creates as an intermediate, it would create a memory
3847   // leak; we must return .promise instead;
3848   // The operand needs to be evaluated on a separate statement in order to get
3849   // a break location, and the .promise needs to be read earlier so that it
3850   // doesn't insert a false location.
3851   // TODO(littledan): investigate why this ordering is needed in more detail.
3852   Variable* generator_object_variable =
3853       function_state_->generator_object_variable();
3854   DCHECK_NOT_NULL(generator_object_variable);
3855 
3856   const int nopos = kNoSourcePosition;
3857 
3858   Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos);
3859 
3860   Variable* promise = PromiseVariable();
3861 
3862   // Wrap value evaluation to provide a break location.
3863   Variable* temp_var = NewTemporary(ast_value_factory()->empty_string());
3864   Expression* value_assignment = factory()->NewAssignment(
3865       Token::ASSIGN, factory()->NewVariableProxy(temp_var), value, nopos);
3866   do_block->statements()->Add(
3867       factory()->NewExpressionStatement(value_assignment, value->position()),
3868       zone());
3869 
3870   ZoneList<Expression*>* async_function_await_args =
3871       new (zone()) ZoneList<Expression*>(3, zone());
3872   Expression* generator_object =
3873       factory()->NewVariableProxy(generator_object_variable);
3874   async_function_await_args->Add(generator_object, zone());
3875   async_function_await_args->Add(factory()->NewVariableProxy(temp_var), zone());
3876   async_function_await_args->Add(factory()->NewVariableProxy(promise), zone());
3877 
3878   // The parser emits calls to AsyncFunctionAwaitCaught, but the
3879   // AstNumberingVisitor will rewrite this to AsyncFunctionAwaitUncaught
3880   // if there is no local enclosing try/catch block.
3881   Expression* async_function_await =
3882       factory()->NewCallRuntime(Context::ASYNC_FUNCTION_AWAIT_CAUGHT_INDEX,
3883                                 async_function_await_args, nopos);
3884   do_block->statements()->Add(
3885       factory()->NewExpressionStatement(async_function_await, await_pos),
3886       zone());
3887 
3888   // Wrap await to provide a break location between value evaluation and yield.
3889   Expression* do_expr = factory()->NewDoExpression(do_block, promise, nopos);
3890 
3891   generator_object = factory()->NewVariableProxy(generator_object_variable);
3892   return factory()->NewYield(generator_object, do_expr, nopos,
3893                              Yield::kOnExceptionRethrow);
3894 }
3895 
3896 class NonPatternRewriter : public AstExpressionRewriter {
3897  public:
NonPatternRewriter(uintptr_t stack_limit,Parser * parser)3898   NonPatternRewriter(uintptr_t stack_limit, Parser* parser)
3899       : AstExpressionRewriter(stack_limit), parser_(parser) {}
~NonPatternRewriter()3900   ~NonPatternRewriter() override {}
3901 
3902  private:
RewriteExpression(Expression * expr)3903   bool RewriteExpression(Expression* expr) override {
3904     if (expr->IsRewritableExpression()) return true;
3905     // Rewrite only what could have been a pattern but is not.
3906     if (expr->IsArrayLiteral()) {
3907       // Spread rewriting in array literals.
3908       ArrayLiteral* lit = expr->AsArrayLiteral();
3909       VisitExpressions(lit->values());
3910       replacement_ = parser_->RewriteSpreads(lit);
3911       return false;
3912     }
3913     if (expr->IsObjectLiteral()) {
3914       return true;
3915     }
3916     if (expr->IsBinaryOperation() &&
3917         expr->AsBinaryOperation()->op() == Token::COMMA) {
3918       return true;
3919     }
3920     // Everything else does not need rewriting.
3921     return false;
3922   }
3923 
VisitLiteralProperty(LiteralProperty * property)3924   void VisitLiteralProperty(LiteralProperty* property) override {
3925     if (property == nullptr) return;
3926     // Do not rewrite (computed) key expressions
3927     AST_REWRITE_PROPERTY(Expression, property, value);
3928   }
3929 
3930   Parser* parser_;
3931 };
3932 
RewriteNonPattern(bool * ok)3933 void Parser::RewriteNonPattern(bool* ok) {
3934   ValidateExpression(CHECK_OK_VOID);
3935   auto non_patterns_to_rewrite = function_state_->non_patterns_to_rewrite();
3936   int begin = classifier()->GetNonPatternBegin();
3937   int end = non_patterns_to_rewrite->length();
3938   if (begin < end) {
3939     NonPatternRewriter rewriter(stack_limit_, this);
3940     for (int i = begin; i < end; i++) {
3941       DCHECK(non_patterns_to_rewrite->at(i)->IsRewritableExpression());
3942       rewriter.Rewrite(non_patterns_to_rewrite->at(i));
3943     }
3944     non_patterns_to_rewrite->Rewind(begin);
3945   }
3946 }
3947 
3948 
RewriteDestructuringAssignments()3949 void Parser::RewriteDestructuringAssignments() {
3950   const auto& assignments =
3951       function_state_->destructuring_assignments_to_rewrite();
3952   for (int i = assignments.length() - 1; i >= 0; --i) {
3953     // Rewrite list in reverse, so that nested assignment patterns are rewritten
3954     // correctly.
3955     const DestructuringAssignment& pair = assignments.at(i);
3956     RewritableExpression* to_rewrite =
3957         pair.assignment->AsRewritableExpression();
3958     DCHECK_NOT_NULL(to_rewrite);
3959     if (!to_rewrite->is_rewritten()) {
3960       // Since this function is called at the end of parsing the program,
3961       // pair.scope may already have been removed by FinalizeBlockScope in the
3962       // meantime.
3963       Scope* scope = pair.scope->GetUnremovedScope();
3964       PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite, scope);
3965     }
3966   }
3967 }
3968 
RewriteExponentiation(Expression * left,Expression * right,int pos)3969 Expression* Parser::RewriteExponentiation(Expression* left, Expression* right,
3970                                           int pos) {
3971   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
3972   args->Add(left, zone());
3973   args->Add(right, zone());
3974   return factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos);
3975 }
3976 
RewriteAssignExponentiation(Expression * left,Expression * right,int pos)3977 Expression* Parser::RewriteAssignExponentiation(Expression* left,
3978                                                 Expression* right, int pos) {
3979   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
3980   if (left->IsVariableProxy()) {
3981     VariableProxy* lhs = left->AsVariableProxy();
3982 
3983     Expression* result;
3984     DCHECK_NOT_NULL(lhs->raw_name());
3985     result = ExpressionFromIdentifier(lhs->raw_name(), lhs->position());
3986     args->Add(left, zone());
3987     args->Add(right, zone());
3988     Expression* call =
3989         factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos);
3990     return factory()->NewAssignment(Token::ASSIGN, result, call, pos);
3991   } else if (left->IsProperty()) {
3992     Property* prop = left->AsProperty();
3993     auto temp_obj = NewTemporary(ast_value_factory()->empty_string());
3994     auto temp_key = NewTemporary(ast_value_factory()->empty_string());
3995     Expression* assign_obj = factory()->NewAssignment(
3996         Token::ASSIGN, factory()->NewVariableProxy(temp_obj), prop->obj(),
3997         kNoSourcePosition);
3998     Expression* assign_key = factory()->NewAssignment(
3999         Token::ASSIGN, factory()->NewVariableProxy(temp_key), prop->key(),
4000         kNoSourcePosition);
4001     args->Add(factory()->NewProperty(factory()->NewVariableProxy(temp_obj),
4002                                      factory()->NewVariableProxy(temp_key),
4003                                      left->position()),
4004               zone());
4005     args->Add(right, zone());
4006     Expression* call =
4007         factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos);
4008     Expression* target = factory()->NewProperty(
4009         factory()->NewVariableProxy(temp_obj),
4010         factory()->NewVariableProxy(temp_key), kNoSourcePosition);
4011     Expression* assign =
4012         factory()->NewAssignment(Token::ASSIGN, target, call, pos);
4013     return factory()->NewBinaryOperation(
4014         Token::COMMA, assign_obj,
4015         factory()->NewBinaryOperation(Token::COMMA, assign_key, assign, pos),
4016         pos);
4017   }
4018   UNREACHABLE();
4019   return nullptr;
4020 }
4021 
RewriteSpreads(ArrayLiteral * lit)4022 Expression* Parser::RewriteSpreads(ArrayLiteral* lit) {
4023   // Array literals containing spreads are rewritten using do expressions, e.g.
4024   //    [1, 2, 3, ...x, 4, ...y, 5]
4025   // is roughly rewritten as:
4026   //    do {
4027   //      $R = [1, 2, 3];
4028   //      for ($i of x) %AppendElement($R, $i);
4029   //      %AppendElement($R, 4);
4030   //      for ($j of y) %AppendElement($R, $j);
4031   //      %AppendElement($R, 5);
4032   //      $R
4033   //    }
4034   // where $R, $i and $j are fresh temporary variables.
4035   ZoneList<Expression*>::iterator s = lit->FirstSpread();
4036   if (s == lit->EndValue()) return nullptr;  // no spread, no rewriting...
4037   Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
4038   // NOTE: The value assigned to R is the whole original array literal,
4039   // spreads included. This will be fixed before the rewritten AST is returned.
4040   // $R = lit
4041   Expression* init_result = factory()->NewAssignment(
4042       Token::INIT, factory()->NewVariableProxy(result), lit, kNoSourcePosition);
4043   Block* do_block = factory()->NewBlock(nullptr, 16, false, kNoSourcePosition);
4044   do_block->statements()->Add(
4045       factory()->NewExpressionStatement(init_result, kNoSourcePosition),
4046       zone());
4047   // Traverse the array literal starting from the first spread.
4048   while (s != lit->EndValue()) {
4049     Expression* value = *s++;
4050     Spread* spread = value->AsSpread();
4051     if (spread == nullptr) {
4052       // If the element is not a spread, we're adding a single:
4053       // %AppendElement($R, value)
4054       // or, in case of a hole,
4055       // ++($R.length)
4056       if (!value->IsLiteral() ||
4057           !value->AsLiteral()->raw_value()->IsTheHole()) {
4058         ZoneList<Expression*>* append_element_args = NewExpressionList(2);
4059         append_element_args->Add(factory()->NewVariableProxy(result), zone());
4060         append_element_args->Add(value, zone());
4061         do_block->statements()->Add(
4062             factory()->NewExpressionStatement(
4063                 factory()->NewCallRuntime(Runtime::kAppendElement,
4064                                           append_element_args,
4065                                           kNoSourcePosition),
4066                 kNoSourcePosition),
4067             zone());
4068       } else {
4069         Property* length_property = factory()->NewProperty(
4070             factory()->NewVariableProxy(result),
4071             factory()->NewStringLiteral(ast_value_factory()->length_string(),
4072                                         kNoSourcePosition),
4073             kNoSourcePosition);
4074         CountOperation* count_op = factory()->NewCountOperation(
4075             Token::INC, true /* prefix */, length_property, kNoSourcePosition);
4076         do_block->statements()->Add(
4077             factory()->NewExpressionStatement(count_op, kNoSourcePosition),
4078             zone());
4079       }
4080     } else {
4081       // If it's a spread, we're adding a for/of loop iterating through it.
4082       Variable* each = NewTemporary(ast_value_factory()->dot_for_string());
4083       Expression* subject = spread->expression();
4084       // %AppendElement($R, each)
4085       Statement* append_body;
4086       {
4087         ZoneList<Expression*>* append_element_args = NewExpressionList(2);
4088         append_element_args->Add(factory()->NewVariableProxy(result), zone());
4089         append_element_args->Add(factory()->NewVariableProxy(each), zone());
4090         append_body = factory()->NewExpressionStatement(
4091             factory()->NewCallRuntime(Runtime::kAppendElement,
4092                                       append_element_args, kNoSourcePosition),
4093             kNoSourcePosition);
4094       }
4095       // for (each of spread) %AppendElement($R, each)
4096       ForOfStatement* loop =
4097           factory()->NewForOfStatement(nullptr, kNoSourcePosition);
4098       const bool finalize = false;
4099       InitializeForOfStatement(loop, factory()->NewVariableProxy(each), subject,
4100                                append_body, finalize, IteratorType::kNormal);
4101       do_block->statements()->Add(loop, zone());
4102     }
4103   }
4104   // Now, rewind the original array literal to truncate everything from the
4105   // first spread (included) until the end. This fixes $R's initialization.
4106   lit->RewindSpreads();
4107   return factory()->NewDoExpression(do_block, result, lit->position());
4108 }
4109 
QueueDestructuringAssignmentForRewriting(Expression * expr)4110 void Parser::QueueDestructuringAssignmentForRewriting(Expression* expr) {
4111   DCHECK(expr->IsRewritableExpression());
4112   function_state_->AddDestructuringAssignment(
4113       DestructuringAssignment(expr, scope()));
4114 }
4115 
QueueNonPatternForRewriting(Expression * expr,bool * ok)4116 void Parser::QueueNonPatternForRewriting(Expression* expr, bool* ok) {
4117   DCHECK(expr->IsRewritableExpression());
4118   function_state_->AddNonPatternForRewriting(expr, ok);
4119 }
4120 
AddAccessorPrefixToFunctionName(bool is_get,FunctionLiteral * function,const AstRawString * name)4121 void Parser::AddAccessorPrefixToFunctionName(bool is_get,
4122                                              FunctionLiteral* function,
4123                                              const AstRawString* name) {
4124   DCHECK_NOT_NULL(name);
4125   const AstRawString* prefix = is_get ? ast_value_factory()->get_space_string()
4126                                       : ast_value_factory()->set_space_string();
4127   function->set_raw_name(ast_value_factory()->NewConsString(prefix, name));
4128 }
4129 
SetFunctionNameFromPropertyName(ObjectLiteralProperty * property,const AstRawString * name)4130 void Parser::SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
4131                                              const AstRawString* name) {
4132   DCHECK(property->kind() != ObjectLiteralProperty::GETTER);
4133   DCHECK(property->kind() != ObjectLiteralProperty::SETTER);
4134 
4135   // Computed name setting must happen at runtime.
4136   DCHECK(!property->is_computed_name());
4137 
4138   // Ignore "__proto__" as a name when it's being used to set the [[Prototype]]
4139   // of an object literal.
4140   if (property->kind() == ObjectLiteralProperty::PROTOTYPE) return;
4141 
4142   Expression* value = property->value();
4143 
4144   DCHECK(!value->IsAnonymousFunctionDefinition() ||
4145          property->kind() == ObjectLiteralProperty::COMPUTED);
4146   SetFunctionName(value, name);
4147 }
4148 
SetFunctionNameFromIdentifierRef(Expression * value,Expression * identifier)4149 void Parser::SetFunctionNameFromIdentifierRef(Expression* value,
4150                                               Expression* identifier) {
4151   if (!identifier->IsVariableProxy()) return;
4152   SetFunctionName(value, identifier->AsVariableProxy()->raw_name());
4153 }
4154 
SetFunctionName(Expression * value,const AstRawString * name)4155 void Parser::SetFunctionName(Expression* value, const AstRawString* name) {
4156   DCHECK_NOT_NULL(name);
4157   if (!value->IsAnonymousFunctionDefinition()) return;
4158   auto function = value->AsFunctionLiteral();
4159   if (function != nullptr) {
4160     function->set_raw_name(name);
4161   } else {
4162     DCHECK(value->IsDoExpression());
4163     value->AsDoExpression()->represented_function()->set_raw_name(name);
4164   }
4165 }
4166 
4167 
4168 // Desugaring of yield*
4169 // ====================
4170 //
4171 // With the help of do-expressions and function.sent, we desugar yield* into a
4172 // loop containing a "raw" yield (a yield that doesn't wrap an iterator result
4173 // object around its argument).  Concretely, "yield* iterable" turns into
4174 // roughly the following code:
4175 //
4176 //   do {
4177 //     const kNext = 0;
4178 //     const kReturn = 1;
4179 //     const kThrow = 2;
4180 //
4181 //     let input = undefined;
4182 //     let mode = kNext;
4183 //     let output = undefined;
4184 //
4185 //     let iterator = GetIterator(iterable);
4186 //
4187 //     while (true) {
4188 //       // From the generator to the iterator:
4189 //       // Forward input according to resume mode and obtain output.
4190 //       switch (mode) {
4191 //         case kNext:
4192 //           output = iterator.next(input);
4193 //           if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
4194 //           break;
4195 //         case kReturn:
4196 //           IteratorClose(iterator, input, output);  // See below.
4197 //           break;
4198 //         case kThrow:
4199 //           let iteratorThrow = iterator.throw;
4200 //           if (IS_NULL_OR_UNDEFINED(iteratorThrow)) {
4201 //             IteratorClose(iterator);  // See below.
4202 //             throw MakeTypeError(kThrowMethodMissing);
4203 //           }
4204 //           output = %_Call(iteratorThrow, iterator, input);
4205 //           if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
4206 //           break;
4207 //       }
4208 //       if (output.done) break;
4209 //
4210 //       // From the generator to its user:
4211 //       // Forward output, receive new input, and determine resume mode.
4212 //       mode = kReturn;
4213 //       try {
4214 //         try {
4215 //           RawYield(output);  // See explanation above.
4216 //           mode = kNext;
4217 //         } catch (error) {
4218 //           mode = kThrow;
4219 //         }
4220 //       } finally {
4221 //         input = function.sent;
4222 //         continue;
4223 //       }
4224 //     }
4225 //
4226 //     if (mode === kReturn) {
4227 //       return {value: output.value, done: true};
4228 //     }
4229 //     output.value
4230 //   }
4231 //
4232 // IteratorClose(iterator) expands to the following:
4233 //
4234 //   let iteratorReturn = iterator.return;
4235 //   if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
4236 //     let output = %_Call(iteratorReturn, iterator);
4237 //     if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
4238 //   }
4239 //
4240 // IteratorClose(iterator, input, output) expands to the following:
4241 //
4242 //   let iteratorReturn = iterator.return;
4243 //   if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return input;
4244 //   output = %_Call(iteratorReturn, iterator, input);
4245 //   if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
4246 
RewriteYieldStar(Expression * generator,Expression * iterable,int pos)4247 Expression* Parser::RewriteYieldStar(Expression* generator,
4248                                      Expression* iterable, int pos) {
4249   const int nopos = kNoSourcePosition;
4250 
4251   // Forward definition for break/continue statements.
4252   WhileStatement* loop = factory()->NewWhileStatement(nullptr, nopos);
4253 
4254   // let input = undefined;
4255   Variable* var_input = NewTemporary(ast_value_factory()->empty_string());
4256   Statement* initialize_input;
4257   {
4258     Expression* input_proxy = factory()->NewVariableProxy(var_input);
4259     Expression* assignment =
4260         factory()->NewAssignment(Token::ASSIGN, input_proxy,
4261                                  factory()->NewUndefinedLiteral(nopos), nopos);
4262     initialize_input = factory()->NewExpressionStatement(assignment, nopos);
4263   }
4264 
4265   // let mode = kNext;
4266   Variable* var_mode = NewTemporary(ast_value_factory()->empty_string());
4267   Statement* initialize_mode;
4268   {
4269     Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
4270     Expression* knext =
4271         factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos);
4272     Expression* assignment =
4273         factory()->NewAssignment(Token::ASSIGN, mode_proxy, knext, nopos);
4274     initialize_mode = factory()->NewExpressionStatement(assignment, nopos);
4275   }
4276 
4277   // let output = undefined;
4278   Variable* var_output = NewTemporary(ast_value_factory()->empty_string());
4279   Statement* initialize_output;
4280   {
4281     Expression* output_proxy = factory()->NewVariableProxy(var_output);
4282     Expression* assignment =
4283         factory()->NewAssignment(Token::ASSIGN, output_proxy,
4284                                  factory()->NewUndefinedLiteral(nopos), nopos);
4285     initialize_output = factory()->NewExpressionStatement(assignment, nopos);
4286   }
4287 
4288   // let iterator = GetIterator(iterable);
4289   Variable* var_iterator = NewTemporary(ast_value_factory()->empty_string());
4290   Statement* get_iterator;
4291   {
4292     Expression* iterator =
4293         factory()->NewGetIterator(iterable, IteratorType::kNormal, nopos);
4294     Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator);
4295     Expression* assignment = factory()->NewAssignment(
4296         Token::ASSIGN, iterator_proxy, iterator, nopos);
4297     get_iterator = factory()->NewExpressionStatement(assignment, nopos);
4298   }
4299 
4300   // output = iterator.next(input);
4301   Statement* call_next;
4302   {
4303     Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator);
4304     Expression* literal =
4305         factory()->NewStringLiteral(ast_value_factory()->next_string(), nopos);
4306     Expression* next_property =
4307         factory()->NewProperty(iterator_proxy, literal, nopos);
4308     Expression* input_proxy = factory()->NewVariableProxy(var_input);
4309     auto args = new (zone()) ZoneList<Expression*>(1, zone());
4310     args->Add(input_proxy, zone());
4311     Expression* call = factory()->NewCall(next_property, args, nopos);
4312     Expression* output_proxy = factory()->NewVariableProxy(var_output);
4313     Expression* assignment =
4314         factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
4315     call_next = factory()->NewExpressionStatement(assignment, nopos);
4316   }
4317 
4318   // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
4319   Statement* validate_next_output;
4320   {
4321     Expression* is_receiver_call;
4322     {
4323       auto args = new (zone()) ZoneList<Expression*>(1, zone());
4324       args->Add(factory()->NewVariableProxy(var_output), zone());
4325       is_receiver_call =
4326           factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
4327     }
4328 
4329     Statement* throw_call;
4330     {
4331       auto args = new (zone()) ZoneList<Expression*>(1, zone());
4332       args->Add(factory()->NewVariableProxy(var_output), zone());
4333       Expression* call = factory()->NewCallRuntime(
4334           Runtime::kThrowIteratorResultNotAnObject, args, nopos);
4335       throw_call = factory()->NewExpressionStatement(call, nopos);
4336     }
4337 
4338     validate_next_output = factory()->NewIfStatement(
4339         is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
4340         nopos);
4341   }
4342 
4343   // let iteratorThrow = iterator.throw;
4344   Variable* var_throw = NewTemporary(ast_value_factory()->empty_string());
4345   Statement* get_throw;
4346   {
4347     Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator);
4348     Expression* literal =
4349         factory()->NewStringLiteral(ast_value_factory()->throw_string(), nopos);
4350     Expression* property =
4351         factory()->NewProperty(iterator_proxy, literal, nopos);
4352     Expression* throw_proxy = factory()->NewVariableProxy(var_throw);
4353     Expression* assignment =
4354         factory()->NewAssignment(Token::ASSIGN, throw_proxy, property, nopos);
4355     get_throw = factory()->NewExpressionStatement(assignment, nopos);
4356   }
4357 
4358   // if (IS_NULL_OR_UNDEFINED(iteratorThrow) {
4359   //   IteratorClose(iterator);
4360   //   throw MakeTypeError(kThrowMethodMissing);
4361   // }
4362   Statement* check_throw;
4363   {
4364     Expression* condition = factory()->NewCompareOperation(
4365         Token::EQ, factory()->NewVariableProxy(var_throw),
4366         factory()->NewNullLiteral(nopos), nopos);
4367     Expression* call =
4368         NewThrowTypeError(MessageTemplate::kThrowMethodMissing,
4369                           ast_value_factory()->empty_string(), nopos);
4370     Statement* throw_call = factory()->NewExpressionStatement(call, nopos);
4371 
4372     Block* then = factory()->NewBlock(nullptr, 4 + 1, false, nopos);
4373     BuildIteratorCloseForCompletion(
4374         scope(), then->statements(), var_iterator,
4375         factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos),
4376         IteratorType::kNormal);
4377     then->statements()->Add(throw_call, zone());
4378     check_throw = factory()->NewIfStatement(
4379         condition, then, factory()->NewEmptyStatement(nopos), nopos);
4380   }
4381 
4382   // output = %_Call(iteratorThrow, iterator, input);
4383   Statement* call_throw;
4384   {
4385     auto args = new (zone()) ZoneList<Expression*>(3, zone());
4386     args->Add(factory()->NewVariableProxy(var_throw), zone());
4387     args->Add(factory()->NewVariableProxy(var_iterator), zone());
4388     args->Add(factory()->NewVariableProxy(var_input), zone());
4389     Expression* call =
4390         factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
4391     Expression* assignment = factory()->NewAssignment(
4392         Token::ASSIGN, factory()->NewVariableProxy(var_output), call, nopos);
4393     call_throw = factory()->NewExpressionStatement(assignment, nopos);
4394   }
4395 
4396   // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
4397   Statement* validate_throw_output;
4398   {
4399     Expression* is_receiver_call;
4400     {
4401       auto args = new (zone()) ZoneList<Expression*>(1, zone());
4402       args->Add(factory()->NewVariableProxy(var_output), zone());
4403       is_receiver_call =
4404           factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
4405     }
4406 
4407     Statement* throw_call;
4408     {
4409       auto args = new (zone()) ZoneList<Expression*>(1, zone());
4410       args->Add(factory()->NewVariableProxy(var_output), zone());
4411       Expression* call = factory()->NewCallRuntime(
4412           Runtime::kThrowIteratorResultNotAnObject, args, nopos);
4413       throw_call = factory()->NewExpressionStatement(call, nopos);
4414     }
4415 
4416     validate_throw_output = factory()->NewIfStatement(
4417         is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
4418         nopos);
4419   }
4420 
4421   // if (output.done) break;
4422   Statement* if_done;
4423   {
4424     Expression* output_proxy = factory()->NewVariableProxy(var_output);
4425     Expression* literal =
4426         factory()->NewStringLiteral(ast_value_factory()->done_string(), nopos);
4427     Expression* property = factory()->NewProperty(output_proxy, literal, nopos);
4428     BreakStatement* break_loop = factory()->NewBreakStatement(loop, nopos);
4429     if_done = factory()->NewIfStatement(
4430         property, break_loop, factory()->NewEmptyStatement(nopos), nopos);
4431   }
4432 
4433 
4434   // mode = kReturn;
4435   Statement* set_mode_return;
4436   {
4437     Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
4438     Expression* kreturn =
4439         factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos);
4440     Expression* assignment =
4441         factory()->NewAssignment(Token::ASSIGN, mode_proxy, kreturn, nopos);
4442     set_mode_return = factory()->NewExpressionStatement(assignment, nopos);
4443   }
4444 
4445   // Yield(output);
4446   Statement* yield_output;
4447   {
4448     Expression* output_proxy = factory()->NewVariableProxy(var_output);
4449     Yield* yield = factory()->NewYield(generator, output_proxy, nopos,
4450                                        Yield::kOnExceptionThrow);
4451     yield_output = factory()->NewExpressionStatement(yield, nopos);
4452   }
4453 
4454   // mode = kNext;
4455   Statement* set_mode_next;
4456   {
4457     Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
4458     Expression* knext =
4459         factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos);
4460     Expression* assignment =
4461         factory()->NewAssignment(Token::ASSIGN, mode_proxy, knext, nopos);
4462     set_mode_next = factory()->NewExpressionStatement(assignment, nopos);
4463   }
4464 
4465   // mode = kThrow;
4466   Statement* set_mode_throw;
4467   {
4468     Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
4469     Expression* kthrow =
4470         factory()->NewSmiLiteral(JSGeneratorObject::kThrow, nopos);
4471     Expression* assignment =
4472         factory()->NewAssignment(Token::ASSIGN, mode_proxy, kthrow, nopos);
4473     set_mode_throw = factory()->NewExpressionStatement(assignment, nopos);
4474   }
4475 
4476   // input = function.sent;
4477   Statement* get_input;
4478   {
4479     Expression* function_sent = FunctionSentExpression(nopos);
4480     Expression* input_proxy = factory()->NewVariableProxy(var_input);
4481     Expression* assignment = factory()->NewAssignment(
4482         Token::ASSIGN, input_proxy, function_sent, nopos);
4483     get_input = factory()->NewExpressionStatement(assignment, nopos);
4484   }
4485 
4486   // if (mode === kReturn) {
4487   //   return {value: output.value, done: true};
4488   // }
4489   Statement* maybe_return_value;
4490   {
4491     Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
4492     Expression* kreturn =
4493         factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos);
4494     Expression* condition = factory()->NewCompareOperation(
4495         Token::EQ_STRICT, mode_proxy, kreturn, nopos);
4496 
4497     Expression* output_proxy = factory()->NewVariableProxy(var_output);
4498     Expression* literal =
4499         factory()->NewStringLiteral(ast_value_factory()->value_string(), nopos);
4500     Expression* property = factory()->NewProperty(output_proxy, literal, nopos);
4501     Statement* return_value = factory()->NewReturnStatement(
4502         BuildIteratorResult(property, true), nopos);
4503 
4504     maybe_return_value = factory()->NewIfStatement(
4505         condition, return_value, factory()->NewEmptyStatement(nopos), nopos);
4506   }
4507 
4508   // output.value
4509   Statement* get_value;
4510   {
4511     Expression* output_proxy = factory()->NewVariableProxy(var_output);
4512     Expression* literal =
4513         factory()->NewStringLiteral(ast_value_factory()->value_string(), nopos);
4514     Expression* property = factory()->NewProperty(output_proxy, literal, nopos);
4515     get_value = factory()->NewExpressionStatement(property, nopos);
4516   }
4517 
4518   // Now put things together.
4519 
4520   // try { ... } catch(e) { ... }
4521   Statement* try_catch;
4522   {
4523     Block* try_block = factory()->NewBlock(nullptr, 2, false, nopos);
4524     try_block->statements()->Add(yield_output, zone());
4525     try_block->statements()->Add(set_mode_next, zone());
4526 
4527     Block* catch_block = factory()->NewBlock(nullptr, 1, false, nopos);
4528     catch_block->statements()->Add(set_mode_throw, zone());
4529 
4530     Scope* catch_scope = NewScope(CATCH_SCOPE);
4531     catch_scope->set_is_hidden();
4532     const AstRawString* name = ast_value_factory()->dot_catch_string();
4533     Variable* catch_variable = catch_scope->DeclareLocal(name, VAR);
4534 
4535     try_catch = factory()->NewTryCatchStatementForDesugaring(
4536         try_block, catch_scope, catch_variable, catch_block, nopos);
4537   }
4538 
4539   // try { ... } finally { ... }
4540   Statement* try_finally;
4541   {
4542     Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
4543     try_block->statements()->Add(try_catch, zone());
4544 
4545     Block* finally = factory()->NewBlock(nullptr, 2, false, nopos);
4546     finally->statements()->Add(get_input, zone());
4547     finally->statements()->Add(factory()->NewContinueStatement(loop, nopos),
4548                                zone());
4549 
4550     try_finally = factory()->NewTryFinallyStatement(try_block, finally, nopos);
4551   }
4552 
4553   // switch (mode) { ... }
4554   SwitchStatement* switch_mode = factory()->NewSwitchStatement(nullptr, nopos);
4555   {
4556     auto case_next = new (zone()) ZoneList<Statement*>(3, zone());
4557     case_next->Add(call_next, zone());
4558     case_next->Add(validate_next_output, zone());
4559     case_next->Add(factory()->NewBreakStatement(switch_mode, nopos), zone());
4560 
4561     auto case_return = new (zone()) ZoneList<Statement*>(5, zone());
4562     BuildIteratorClose(case_return, var_iterator, var_input, var_output);
4563     case_return->Add(factory()->NewBreakStatement(switch_mode, nopos), zone());
4564 
4565     auto case_throw = new (zone()) ZoneList<Statement*>(5, zone());
4566     case_throw->Add(get_throw, zone());
4567     case_throw->Add(check_throw, zone());
4568     case_throw->Add(call_throw, zone());
4569     case_throw->Add(validate_throw_output, zone());
4570     case_throw->Add(factory()->NewBreakStatement(switch_mode, nopos), zone());
4571 
4572     auto cases = new (zone()) ZoneList<CaseClause*>(3, zone());
4573     Expression* knext =
4574         factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos);
4575     Expression* kreturn =
4576         factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos);
4577     Expression* kthrow =
4578         factory()->NewSmiLiteral(JSGeneratorObject::kThrow, nopos);
4579     cases->Add(factory()->NewCaseClause(knext, case_next, nopos), zone());
4580     cases->Add(factory()->NewCaseClause(kreturn, case_return, nopos), zone());
4581     cases->Add(factory()->NewCaseClause(kthrow, case_throw, nopos), zone());
4582 
4583     switch_mode->Initialize(factory()->NewVariableProxy(var_mode), cases);
4584   }
4585 
4586   // while (true) { ... }
4587   // Already defined earlier: WhileStatement* loop = ...
4588   {
4589     Block* loop_body = factory()->NewBlock(nullptr, 4, false, nopos);
4590     loop_body->statements()->Add(switch_mode, zone());
4591     loop_body->statements()->Add(if_done, zone());
4592     loop_body->statements()->Add(set_mode_return, zone());
4593     loop_body->statements()->Add(try_finally, zone());
4594 
4595     loop->Initialize(factory()->NewBooleanLiteral(true, nopos), loop_body);
4596   }
4597 
4598   // do { ... }
4599   DoExpression* yield_star;
4600   {
4601     // The rewriter needs to process the get_value statement only, hence we
4602     // put the preceding statements into an init block.
4603 
4604     Block* do_block_ = factory()->NewBlock(nullptr, 6, true, nopos);
4605     do_block_->statements()->Add(initialize_input, zone());
4606     do_block_->statements()->Add(initialize_mode, zone());
4607     do_block_->statements()->Add(initialize_output, zone());
4608     do_block_->statements()->Add(get_iterator, zone());
4609     do_block_->statements()->Add(loop, zone());
4610     do_block_->statements()->Add(maybe_return_value, zone());
4611 
4612     Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos);
4613     do_block->statements()->Add(do_block_, zone());
4614     do_block->statements()->Add(get_value, zone());
4615 
4616     Variable* dot_result =
4617         NewTemporary(ast_value_factory()->dot_result_string());
4618     yield_star = factory()->NewDoExpression(do_block, dot_result, nopos);
4619     Rewriter::Rewrite(this, GetClosureScope(), yield_star, ast_value_factory());
4620   }
4621 
4622   return yield_star;
4623 }
4624 
CheckCallable(Variable * var,Expression * error,int pos)4625 Statement* Parser::CheckCallable(Variable* var, Expression* error, int pos) {
4626   const int nopos = kNoSourcePosition;
4627   Statement* validate_var;
4628   {
4629     Expression* type_of = factory()->NewUnaryOperation(
4630         Token::TYPEOF, factory()->NewVariableProxy(var), nopos);
4631     Expression* function_literal = factory()->NewStringLiteral(
4632         ast_value_factory()->function_string(), nopos);
4633     Expression* condition = factory()->NewCompareOperation(
4634         Token::EQ_STRICT, type_of, function_literal, nopos);
4635 
4636     Statement* throw_call = factory()->NewExpressionStatement(error, pos);
4637 
4638     validate_var = factory()->NewIfStatement(
4639         condition, factory()->NewEmptyStatement(nopos), throw_call, nopos);
4640   }
4641   return validate_var;
4642 }
4643 
BuildIteratorClose(ZoneList<Statement * > * statements,Variable * iterator,Variable * input,Variable * var_output)4644 void Parser::BuildIteratorClose(ZoneList<Statement*>* statements,
4645                                 Variable* iterator, Variable* input,
4646                                 Variable* var_output) {
4647   //
4648   // This function adds four statements to [statements], corresponding to the
4649   // following code:
4650   //
4651   //   let iteratorReturn = iterator.return;
4652   //   if (IS_NULL_OR_UNDEFINED(iteratorReturn) {
4653   //     return {value: input, done: true};
4654   //   }
4655   //   output = %_Call(iteratorReturn, iterator, input);
4656   //   if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
4657   //
4658 
4659   const int nopos = kNoSourcePosition;
4660 
4661   // let iteratorReturn = iterator.return;
4662   Variable* var_return = var_output;  // Reusing the output variable.
4663   Statement* get_return;
4664   {
4665     Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
4666     Expression* literal = factory()->NewStringLiteral(
4667         ast_value_factory()->return_string(), nopos);
4668     Expression* property =
4669         factory()->NewProperty(iterator_proxy, literal, nopos);
4670     Expression* return_proxy = factory()->NewVariableProxy(var_return);
4671     Expression* assignment =
4672         factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos);
4673     get_return = factory()->NewExpressionStatement(assignment, nopos);
4674   }
4675 
4676   // if (IS_NULL_OR_UNDEFINED(iteratorReturn) {
4677   //   return {value: input, done: true};
4678   // }
4679   Statement* check_return;
4680   {
4681     Expression* condition = factory()->NewCompareOperation(
4682         Token::EQ, factory()->NewVariableProxy(var_return),
4683         factory()->NewNullLiteral(nopos), nopos);
4684 
4685     Expression* value = factory()->NewVariableProxy(input);
4686 
4687     Statement* return_input =
4688         factory()->NewReturnStatement(BuildIteratorResult(value, true), nopos);
4689 
4690     check_return = factory()->NewIfStatement(
4691         condition, return_input, factory()->NewEmptyStatement(nopos), nopos);
4692   }
4693 
4694   // output = %_Call(iteratorReturn, iterator, input);
4695   Statement* call_return;
4696   {
4697     auto args = new (zone()) ZoneList<Expression*>(3, zone());
4698     args->Add(factory()->NewVariableProxy(var_return), zone());
4699     args->Add(factory()->NewVariableProxy(iterator), zone());
4700     args->Add(factory()->NewVariableProxy(input), zone());
4701 
4702     Expression* call =
4703         factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
4704     Expression* output_proxy = factory()->NewVariableProxy(var_output);
4705     Expression* assignment =
4706         factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
4707     call_return = factory()->NewExpressionStatement(assignment, nopos);
4708   }
4709 
4710   // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output);
4711   Statement* validate_output;
4712   {
4713     Expression* is_receiver_call;
4714     {
4715       auto args = new (zone()) ZoneList<Expression*>(1, zone());
4716       args->Add(factory()->NewVariableProxy(var_output), zone());
4717       is_receiver_call =
4718           factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
4719     }
4720 
4721     Statement* throw_call;
4722     {
4723       auto args = new (zone()) ZoneList<Expression*>(1, zone());
4724       args->Add(factory()->NewVariableProxy(var_output), zone());
4725       Expression* call = factory()->NewCallRuntime(
4726           Runtime::kThrowIteratorResultNotAnObject, args, nopos);
4727       throw_call = factory()->NewExpressionStatement(call, nopos);
4728     }
4729 
4730     validate_output = factory()->NewIfStatement(
4731         is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
4732         nopos);
4733   }
4734 
4735   statements->Add(get_return, zone());
4736   statements->Add(check_return, zone());
4737   statements->Add(call_return, zone());
4738   statements->Add(validate_output, zone());
4739 }
4740 
FinalizeIteratorUse(Scope * use_scope,Variable * completion,Expression * condition,Variable * iter,Block * iterator_use,Block * target,IteratorType type)4741 void Parser::FinalizeIteratorUse(Scope* use_scope, Variable* completion,
4742                                  Expression* condition, Variable* iter,
4743                                  Block* iterator_use, Block* target,
4744                                  IteratorType type) {
4745   //
4746   // This function adds two statements to [target], corresponding to the
4747   // following code:
4748   //
4749   //   completion = kNormalCompletion;
4750   //   try {
4751   //     try {
4752   //       iterator_use
4753   //     } catch(e) {
4754   //       if (completion === kAbruptCompletion) completion = kThrowCompletion;
4755   //       %ReThrow(e);
4756   //     }
4757   //   } finally {
4758   //     if (condition) {
4759   //       #BuildIteratorCloseForCompletion(iter, completion)
4760   //     }
4761   //   }
4762   //
4763 
4764   const int nopos = kNoSourcePosition;
4765 
4766   // completion = kNormalCompletion;
4767   Statement* initialize_completion;
4768   {
4769     Expression* proxy = factory()->NewVariableProxy(completion);
4770     Expression* assignment = factory()->NewAssignment(
4771         Token::ASSIGN, proxy,
4772         factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
4773     initialize_completion =
4774         factory()->NewExpressionStatement(assignment, nopos);
4775   }
4776 
4777   // if (completion === kAbruptCompletion) completion = kThrowCompletion;
4778   Statement* set_completion_throw;
4779   {
4780     Expression* condition = factory()->NewCompareOperation(
4781         Token::EQ_STRICT, factory()->NewVariableProxy(completion),
4782         factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
4783 
4784     Expression* proxy = factory()->NewVariableProxy(completion);
4785     Expression* assignment = factory()->NewAssignment(
4786         Token::ASSIGN, proxy,
4787         factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos);
4788     Statement* statement = factory()->NewExpressionStatement(assignment, nopos);
4789     set_completion_throw = factory()->NewIfStatement(
4790         condition, statement, factory()->NewEmptyStatement(nopos), nopos);
4791   }
4792 
4793   // if (condition) {
4794   //   #BuildIteratorCloseForCompletion(iter, completion)
4795   // }
4796   Block* maybe_close;
4797   {
4798     Block* block = factory()->NewBlock(nullptr, 2, true, nopos);
4799     Expression* proxy = factory()->NewVariableProxy(completion);
4800     BuildIteratorCloseForCompletion(use_scope, block->statements(), iter, proxy,
4801                                     type);
4802     DCHECK(block->statements()->length() == 2);
4803 
4804     maybe_close = factory()->NewBlock(nullptr, 1, true, nopos);
4805     maybe_close->statements()->Add(
4806         factory()->NewIfStatement(condition, block,
4807                                   factory()->NewEmptyStatement(nopos), nopos),
4808         zone());
4809   }
4810 
4811   // try { #try_block }
4812   // catch(e) {
4813   //   #set_completion_throw;
4814   //   %ReThrow(e);
4815   // }
4816   Statement* try_catch;
4817   {
4818     Scope* catch_scope = NewScopeWithParent(use_scope, CATCH_SCOPE);
4819     Variable* catch_variable =
4820         catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR);
4821     catch_scope->set_is_hidden();
4822 
4823     Statement* rethrow;
4824     // We use %ReThrow rather than the ordinary throw because we want to
4825     // preserve the original exception message.  This is also why we create a
4826     // TryCatchStatementForReThrow below (which does not clear the pending
4827     // message), rather than a TryCatchStatement.
4828     {
4829       auto args = new (zone()) ZoneList<Expression*>(1, zone());
4830       args->Add(factory()->NewVariableProxy(catch_variable), zone());
4831       rethrow = factory()->NewExpressionStatement(
4832           factory()->NewCallRuntime(Runtime::kReThrow, args, nopos), nopos);
4833     }
4834 
4835     Block* catch_block = factory()->NewBlock(nullptr, 2, false, nopos);
4836     catch_block->statements()->Add(set_completion_throw, zone());
4837     catch_block->statements()->Add(rethrow, zone());
4838 
4839     try_catch = factory()->NewTryCatchStatementForReThrow(
4840         iterator_use, catch_scope, catch_variable, catch_block, nopos);
4841   }
4842 
4843   // try { #try_catch } finally { #maybe_close }
4844   Statement* try_finally;
4845   {
4846     Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
4847     try_block->statements()->Add(try_catch, zone());
4848 
4849     try_finally =
4850         factory()->NewTryFinallyStatement(try_block, maybe_close, nopos);
4851   }
4852 
4853   target->statements()->Add(initialize_completion, zone());
4854   target->statements()->Add(try_finally, zone());
4855 }
4856 
BuildIteratorCloseForCompletion(Scope * scope,ZoneList<Statement * > * statements,Variable * iterator,Expression * completion,IteratorType type)4857 void Parser::BuildIteratorCloseForCompletion(Scope* scope,
4858                                              ZoneList<Statement*>* statements,
4859                                              Variable* iterator,
4860                                              Expression* completion,
4861                                              IteratorType type) {
4862   //
4863   // This function adds two statements to [statements], corresponding to the
4864   // following code:
4865   //
4866   //   let iteratorReturn = iterator.return;
4867   //   if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
4868   //     if (completion === kThrowCompletion) {
4869   //       if (!IS_CALLABLE(iteratorReturn)) {
4870   //         throw MakeTypeError(kReturnMethodNotCallable);
4871   //       }
4872   //       [if (IteratorType == kAsync)]
4873   //           try { Await(%_Call(iteratorReturn, iterator) } catch (_) { }
4874   //       [else]
4875   //           try { %_Call(iteratorReturn, iterator) } catch (_) { }
4876   //       [endif]
4877   //     } else {
4878   //       [if (IteratorType == kAsync)]
4879   //           let output = Await(%_Call(iteratorReturn, iterator));
4880   //       [else]
4881   //           let output = %_Call(iteratorReturn, iterator);
4882   //       [endif]
4883   //       if (!IS_RECEIVER(output)) {
4884   //         %ThrowIterResultNotAnObject(output);
4885   //       }
4886   //     }
4887   //   }
4888   //
4889 
4890   const int nopos = kNoSourcePosition;
4891   // let iteratorReturn = iterator.return;
4892   Variable* var_return = NewTemporary(ast_value_factory()->empty_string());
4893   Statement* get_return;
4894   {
4895     Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
4896     Expression* literal = factory()->NewStringLiteral(
4897         ast_value_factory()->return_string(), nopos);
4898     Expression* property =
4899         factory()->NewProperty(iterator_proxy, literal, nopos);
4900     Expression* return_proxy = factory()->NewVariableProxy(var_return);
4901     Expression* assignment =
4902         factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos);
4903     get_return = factory()->NewExpressionStatement(assignment, nopos);
4904   }
4905 
4906   // if (!IS_CALLABLE(iteratorReturn)) {
4907   //   throw MakeTypeError(kReturnMethodNotCallable);
4908   // }
4909   Statement* check_return_callable;
4910   {
4911     Expression* throw_expr =
4912         NewThrowTypeError(MessageTemplate::kReturnMethodNotCallable,
4913                           ast_value_factory()->empty_string(), nopos);
4914     check_return_callable = CheckCallable(var_return, throw_expr, nopos);
4915   }
4916 
4917   // try { %_Call(iteratorReturn, iterator) } catch (_) { }
4918   Statement* try_call_return;
4919   {
4920     auto args = new (zone()) ZoneList<Expression*>(2, zone());
4921     args->Add(factory()->NewVariableProxy(var_return), zone());
4922     args->Add(factory()->NewVariableProxy(iterator), zone());
4923 
4924     Expression* call =
4925         factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
4926 
4927     if (type == IteratorType::kAsync) {
4928       call = RewriteAwaitExpression(call, nopos);
4929     }
4930 
4931     Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
4932     try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos),
4933                                  zone());
4934 
4935     Block* catch_block = factory()->NewBlock(nullptr, 0, false, nopos);
4936 
4937     Scope* catch_scope = NewScopeWithParent(scope, CATCH_SCOPE);
4938     Variable* catch_variable =
4939         catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR);
4940     catch_scope->set_is_hidden();
4941 
4942     try_call_return = factory()->NewTryCatchStatement(
4943         try_block, catch_scope, catch_variable, catch_block, nopos);
4944   }
4945 
4946   // let output = %_Call(iteratorReturn, iterator);
4947   // if (!IS_RECEIVER(output)) {
4948   //   %ThrowIteratorResultNotAnObject(output);
4949   // }
4950   Block* validate_return;
4951   {
4952     Variable* var_output = NewTemporary(ast_value_factory()->empty_string());
4953     Statement* call_return;
4954     {
4955       auto args = new (zone()) ZoneList<Expression*>(2, zone());
4956       args->Add(factory()->NewVariableProxy(var_return), zone());
4957       args->Add(factory()->NewVariableProxy(iterator), zone());
4958       Expression* call =
4959           factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
4960       if (type == IteratorType::kAsync) {
4961         call = RewriteAwaitExpression(call, nopos);
4962       }
4963 
4964       Expression* output_proxy = factory()->NewVariableProxy(var_output);
4965       Expression* assignment =
4966           factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
4967       call_return = factory()->NewExpressionStatement(assignment, nopos);
4968     }
4969 
4970     Expression* is_receiver_call;
4971     {
4972       auto args = new (zone()) ZoneList<Expression*>(1, zone());
4973       args->Add(factory()->NewVariableProxy(var_output), zone());
4974       is_receiver_call =
4975           factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
4976     }
4977 
4978     Statement* throw_call;
4979     {
4980       auto args = new (zone()) ZoneList<Expression*>(1, zone());
4981       args->Add(factory()->NewVariableProxy(var_output), zone());
4982       Expression* call = factory()->NewCallRuntime(
4983           Runtime::kThrowIteratorResultNotAnObject, args, nopos);
4984       throw_call = factory()->NewExpressionStatement(call, nopos);
4985     }
4986 
4987     Statement* check_return = factory()->NewIfStatement(
4988         is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
4989         nopos);
4990 
4991     validate_return = factory()->NewBlock(nullptr, 2, false, nopos);
4992     validate_return->statements()->Add(call_return, zone());
4993     validate_return->statements()->Add(check_return, zone());
4994   }
4995 
4996   // if (completion === kThrowCompletion) {
4997   //   #check_return_callable;
4998   //   #try_call_return;
4999   // } else {
5000   //   #validate_return;
5001   // }
5002   Statement* call_return_carefully;
5003   {
5004     Expression* condition = factory()->NewCompareOperation(
5005         Token::EQ_STRICT, completion,
5006         factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos);
5007 
5008     Block* then_block = factory()->NewBlock(nullptr, 2, false, nopos);
5009     then_block->statements()->Add(check_return_callable, zone());
5010     then_block->statements()->Add(try_call_return, zone());
5011 
5012     call_return_carefully = factory()->NewIfStatement(condition, then_block,
5013                                                       validate_return, nopos);
5014   }
5015 
5016   // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... }
5017   Statement* maybe_call_return;
5018   {
5019     Expression* condition = factory()->NewCompareOperation(
5020         Token::EQ, factory()->NewVariableProxy(var_return),
5021         factory()->NewNullLiteral(nopos), nopos);
5022 
5023     maybe_call_return = factory()->NewIfStatement(
5024         condition, factory()->NewEmptyStatement(nopos), call_return_carefully,
5025         nopos);
5026   }
5027 
5028   statements->Add(get_return, zone());
5029   statements->Add(maybe_call_return, zone());
5030 }
5031 
FinalizeForOfStatement(ForOfStatement * loop,Variable * var_completion,IteratorType type,int pos)5032 Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop,
5033                                           Variable* var_completion,
5034                                           IteratorType type, int pos) {
5035   //
5036   // This function replaces the loop with the following wrapping:
5037   //
5038   //   completion = kNormalCompletion;
5039   //   try {
5040   //     try {
5041   //       #loop;
5042   //     } catch(e) {
5043   //       if (completion === kAbruptCompletion) completion = kThrowCompletion;
5044   //       %ReThrow(e);
5045   //     }
5046   //   } finally {
5047   //     if (!(completion === kNormalCompletion)) {
5048   //       #BuildIteratorCloseForCompletion(#iterator, completion)
5049   //     }
5050   //   }
5051   //
5052   // Note that the loop's body and its assign_each already contain appropriate
5053   // assignments to completion (see InitializeForOfStatement).
5054   //
5055 
5056   const int nopos = kNoSourcePosition;
5057 
5058   // !(completion === kNormalCompletion)
5059   Expression* closing_condition;
5060   {
5061     Expression* cmp = factory()->NewCompareOperation(
5062         Token::EQ_STRICT, factory()->NewVariableProxy(var_completion),
5063         factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
5064     closing_condition = factory()->NewUnaryOperation(Token::NOT, cmp, nopos);
5065   }
5066 
5067   Block* final_loop = factory()->NewBlock(nullptr, 2, false, nopos);
5068   {
5069     Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
5070     try_block->statements()->Add(loop, zone());
5071 
5072     // The scope in which the parser creates this loop.
5073     Scope* loop_scope = scope()->outer_scope();
5074     DCHECK_EQ(loop_scope->scope_type(), BLOCK_SCOPE);
5075     DCHECK_EQ(scope()->scope_type(), BLOCK_SCOPE);
5076 
5077     FinalizeIteratorUse(loop_scope, var_completion, closing_condition,
5078                         loop->iterator(), try_block, final_loop, type);
5079   }
5080 
5081   return final_loop;
5082 }
5083 
5084 #undef CHECK_OK
5085 #undef CHECK_OK_VOID
5086 #undef CHECK_FAILED
5087 
5088 }  // namespace internal
5089 }  // namespace v8
5090