• 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 "src/api.h"
8 #include "src/ast/ast.h"
9 #include "src/ast/ast-expression-rewriter.h"
10 #include "src/ast/ast-expression-visitor.h"
11 #include "src/ast/ast-literal-reindexer.h"
12 #include "src/ast/scopeinfo.h"
13 #include "src/bailout-reason.h"
14 #include "src/base/platform/platform.h"
15 #include "src/bootstrapper.h"
16 #include "src/char-predicates-inl.h"
17 #include "src/codegen.h"
18 #include "src/compiler.h"
19 #include "src/messages.h"
20 #include "src/parsing/parameter-initializer-rewriter.h"
21 #include "src/parsing/parser-base.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 
ParseInfo(Zone * zone)42 ParseInfo::ParseInfo(Zone* zone)
43     : zone_(zone),
44       flags_(0),
45       source_stream_(nullptr),
46       source_stream_encoding_(ScriptCompiler::StreamedSource::ONE_BYTE),
47       extension_(nullptr),
48       compile_options_(ScriptCompiler::kNoCompileOptions),
49       script_scope_(nullptr),
50       unicode_cache_(nullptr),
51       stack_limit_(0),
52       hash_seed_(0),
53       isolate_(nullptr),
54       cached_data_(nullptr),
55       ast_value_factory_(nullptr),
56       literal_(nullptr),
57       scope_(nullptr) {}
58 
ParseInfo(Zone * zone,Handle<JSFunction> function)59 ParseInfo::ParseInfo(Zone* zone, Handle<JSFunction> function)
60     : ParseInfo(zone, Handle<SharedFunctionInfo>(function->shared())) {
61   set_context(Handle<Context>(function->context()));
62 }
63 
64 
ParseInfo(Zone * zone,Handle<SharedFunctionInfo> shared)65 ParseInfo::ParseInfo(Zone* zone, Handle<SharedFunctionInfo> shared)
66     : ParseInfo(zone) {
67   isolate_ = shared->GetIsolate();
68 
69   set_lazy();
70   set_hash_seed(isolate_->heap()->HashSeed());
71   set_stack_limit(isolate_->stack_guard()->real_climit());
72   set_unicode_cache(isolate_->unicode_cache());
73   set_language_mode(shared->language_mode());
74   set_shared_info(shared);
75 
76   Handle<Script> script(Script::cast(shared->script()));
77   set_script(script);
78   if (!script.is_null() && script->type() == Script::TYPE_NATIVE) {
79     set_native();
80   }
81 }
82 
83 
ParseInfo(Zone * zone,Handle<Script> script)84 ParseInfo::ParseInfo(Zone* zone, Handle<Script> script) : ParseInfo(zone) {
85   isolate_ = script->GetIsolate();
86 
87   set_hash_seed(isolate_->heap()->HashSeed());
88   set_stack_limit(isolate_->stack_guard()->real_climit());
89   set_unicode_cache(isolate_->unicode_cache());
90   set_script(script);
91 
92   if (script->type() == Script::TYPE_NATIVE) {
93     set_native();
94   }
95 }
96 
97 
GetFunctionEntry(int start)98 FunctionEntry ParseData::GetFunctionEntry(int start) {
99   // The current pre-data entry must be a FunctionEntry with the given
100   // start position.
101   if ((function_index_ + FunctionEntry::kSize <= Length()) &&
102       (static_cast<int>(Data()[function_index_]) == start)) {
103     int index = function_index_;
104     function_index_ += FunctionEntry::kSize;
105     Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize);
106     return FunctionEntry(subvector);
107   }
108   return FunctionEntry();
109 }
110 
111 
FunctionCount()112 int ParseData::FunctionCount() {
113   int functions_size = FunctionsSize();
114   if (functions_size < 0) return 0;
115   if (functions_size % FunctionEntry::kSize != 0) return 0;
116   return functions_size / FunctionEntry::kSize;
117 }
118 
119 
IsSane()120 bool ParseData::IsSane() {
121   if (!IsAligned(script_data_->length(), sizeof(unsigned))) return false;
122   // Check that the header data is valid and doesn't specify
123   // point to positions outside the store.
124   int data_length = Length();
125   if (data_length < PreparseDataConstants::kHeaderSize) return false;
126   if (Magic() != PreparseDataConstants::kMagicNumber) return false;
127   if (Version() != PreparseDataConstants::kCurrentVersion) return false;
128   if (HasError()) return false;
129   // Check that the space allocated for function entries is sane.
130   int functions_size = FunctionsSize();
131   if (functions_size < 0) return false;
132   if (functions_size % FunctionEntry::kSize != 0) return false;
133   // Check that the total size has room for header and function entries.
134   int minimum_size =
135       PreparseDataConstants::kHeaderSize + functions_size;
136   if (data_length < minimum_size) return false;
137   return true;
138 }
139 
140 
Initialize()141 void ParseData::Initialize() {
142   // Prepares state for use.
143   int data_length = Length();
144   if (data_length >= PreparseDataConstants::kHeaderSize) {
145     function_index_ = PreparseDataConstants::kHeaderSize;
146   }
147 }
148 
149 
HasError()150 bool ParseData::HasError() {
151   return Data()[PreparseDataConstants::kHasErrorOffset];
152 }
153 
154 
Magic()155 unsigned ParseData::Magic() {
156   return Data()[PreparseDataConstants::kMagicOffset];
157 }
158 
159 
Version()160 unsigned ParseData::Version() {
161   return Data()[PreparseDataConstants::kVersionOffset];
162 }
163 
164 
FunctionsSize()165 int ParseData::FunctionsSize() {
166   return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]);
167 }
168 
169 
SetCachedData(ParseInfo * info)170 void Parser::SetCachedData(ParseInfo* info) {
171   if (compile_options_ == ScriptCompiler::kNoCompileOptions) {
172     cached_parse_data_ = NULL;
173   } else {
174     DCHECK(info->cached_data() != NULL);
175     if (compile_options_ == ScriptCompiler::kConsumeParserCache) {
176       cached_parse_data_ = ParseData::FromCachedData(*info->cached_data());
177     }
178   }
179 }
180 
DefaultConstructor(const AstRawString * name,bool call_super,Scope * scope,int pos,int end_pos,LanguageMode language_mode)181 FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name,
182                                             bool call_super, Scope* scope,
183                                             int pos, int end_pos,
184                                             LanguageMode language_mode) {
185   int materialized_literal_count = -1;
186   int expected_property_count = -1;
187   int parameter_count = 0;
188   if (name == nullptr) name = ast_value_factory()->empty_string();
189 
190   FunctionKind kind = call_super ? FunctionKind::kDefaultSubclassConstructor
191                                  : FunctionKind::kDefaultBaseConstructor;
192   Scope* function_scope = NewScope(scope, FUNCTION_SCOPE, kind);
193   SetLanguageMode(function_scope,
194                   static_cast<LanguageMode>(language_mode | STRICT));
195   // Set start and end position to the same value
196   function_scope->set_start_position(pos);
197   function_scope->set_end_position(pos);
198   ZoneList<Statement*>* body = NULL;
199 
200   {
201     AstNodeFactory function_factory(ast_value_factory());
202     FunctionState function_state(&function_state_, &scope_, function_scope,
203                                  kind, &function_factory);
204 
205     body = new (zone()) ZoneList<Statement*>(call_super ? 2 : 1, zone());
206     if (call_super) {
207       // $super_constructor = %_GetSuperConstructor(<this-function>)
208       // %reflect_construct(
209       //     $super_constructor, InternalArray(...args), new.target)
210       auto constructor_args_name = ast_value_factory()->empty_string();
211       bool is_duplicate;
212       bool is_rest = true;
213       bool is_optional = false;
214       Variable* constructor_args =
215           function_scope->DeclareParameter(constructor_args_name, TEMPORARY,
216                                            is_optional, is_rest, &is_duplicate);
217 
218       ZoneList<Expression*>* args =
219           new (zone()) ZoneList<Expression*>(2, zone());
220       VariableProxy* this_function_proxy = scope_->NewUnresolved(
221           factory(), ast_value_factory()->this_function_string(),
222           Variable::NORMAL, pos);
223       ZoneList<Expression*>* tmp =
224           new (zone()) ZoneList<Expression*>(1, zone());
225       tmp->Add(this_function_proxy, zone());
226       Expression* super_constructor = factory()->NewCallRuntime(
227           Runtime::kInlineGetSuperConstructor, tmp, pos);
228       args->Add(super_constructor, zone());
229       Spread* spread_args = factory()->NewSpread(
230           factory()->NewVariableProxy(constructor_args), pos, pos);
231       ZoneList<Expression*>* spread_args_expr =
232           new (zone()) ZoneList<Expression*>(1, zone());
233       spread_args_expr->Add(spread_args, zone());
234       args->AddAll(*PrepareSpreadArguments(spread_args_expr), zone());
235       VariableProxy* new_target_proxy = scope_->NewUnresolved(
236           factory(), ast_value_factory()->new_target_string(), Variable::NORMAL,
237           pos);
238       args->Add(new_target_proxy, zone());
239       CallRuntime* call = factory()->NewCallRuntime(
240           Context::REFLECT_CONSTRUCT_INDEX, args, pos);
241       body->Add(factory()->NewReturnStatement(call, pos), zone());
242     }
243 
244     materialized_literal_count = function_state.materialized_literal_count();
245     expected_property_count = function_state.expected_property_count();
246   }
247 
248   FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
249       name, function_scope, body, materialized_literal_count,
250       expected_property_count, parameter_count,
251       FunctionLiteral::kNoDuplicateParameters,
252       FunctionLiteral::kAnonymousExpression,
253       FunctionLiteral::kShouldLazyCompile, kind, pos);
254 
255   return function_literal;
256 }
257 
258 
259 // ----------------------------------------------------------------------------
260 // Target is a support class to facilitate manipulation of the
261 // Parser's target_stack_ (the stack of potential 'break' and
262 // 'continue' statement targets). Upon construction, a new target is
263 // added; it is removed upon destruction.
264 
265 class Target BASE_EMBEDDED {
266  public:
Target(Target ** variable,BreakableStatement * statement)267   Target(Target** variable, BreakableStatement* statement)
268       : variable_(variable), statement_(statement), previous_(*variable) {
269     *variable = this;
270   }
271 
~Target()272   ~Target() {
273     *variable_ = previous_;
274   }
275 
previous()276   Target* previous() { return previous_; }
statement()277   BreakableStatement* statement() { return statement_; }
278 
279  private:
280   Target** variable_;
281   BreakableStatement* statement_;
282   Target* previous_;
283 };
284 
285 
286 class TargetScope BASE_EMBEDDED {
287  public:
TargetScope(Target ** variable)288   explicit TargetScope(Target** variable)
289       : variable_(variable), previous_(*variable) {
290     *variable = NULL;
291   }
292 
~TargetScope()293   ~TargetScope() {
294     *variable_ = previous_;
295   }
296 
297  private:
298   Target** variable_;
299   Target* previous_;
300 };
301 
302 
303 // ----------------------------------------------------------------------------
304 // The CHECK_OK macro is a convenient macro to enforce error
305 // handling for functions that may fail (by returning !*ok).
306 //
307 // CAUTION: This macro appends extra statements after a call,
308 // thus it must never be used where only a single statement
309 // is correct (e.g. an if statement branch w/o braces)!
310 
311 #define CHECK_OK  ok);   \
312   if (!*ok) return NULL; \
313   ((void)0
314 #define DUMMY )  // to make indentation work
315 #undef DUMMY
316 
317 #define CHECK_FAILED  /**/);   \
318   if (failed_) return NULL; \
319   ((void)0
320 #define DUMMY )  // to make indentation work
321 #undef DUMMY
322 
323 // ----------------------------------------------------------------------------
324 // Implementation of Parser
325 
IsEval(const AstRawString * identifier) const326 bool ParserTraits::IsEval(const AstRawString* identifier) const {
327   return identifier == parser_->ast_value_factory()->eval_string();
328 }
329 
330 
IsArguments(const AstRawString * identifier) const331 bool ParserTraits::IsArguments(const AstRawString* identifier) const {
332   return identifier == parser_->ast_value_factory()->arguments_string();
333 }
334 
335 
IsEvalOrArguments(const AstRawString * identifier) const336 bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const {
337   return IsEval(identifier) || IsArguments(identifier);
338 }
339 
IsUndefined(const AstRawString * identifier) const340 bool ParserTraits::IsUndefined(const AstRawString* identifier) const {
341   return identifier == parser_->ast_value_factory()->undefined_string();
342 }
343 
IsAwait(const AstRawString * identifier) const344 bool ParserTraits::IsAwait(const AstRawString* identifier) const {
345   return identifier == parser_->ast_value_factory()->await_string();
346 }
347 
IsPrototype(const AstRawString * identifier) const348 bool ParserTraits::IsPrototype(const AstRawString* identifier) const {
349   return identifier == parser_->ast_value_factory()->prototype_string();
350 }
351 
352 
IsConstructor(const AstRawString * identifier) const353 bool ParserTraits::IsConstructor(const AstRawString* identifier) const {
354   return identifier == parser_->ast_value_factory()->constructor_string();
355 }
356 
357 
IsThisProperty(Expression * expression)358 bool ParserTraits::IsThisProperty(Expression* expression) {
359   DCHECK(expression != NULL);
360   Property* property = expression->AsProperty();
361   return property != NULL && property->obj()->IsVariableProxy() &&
362          property->obj()->AsVariableProxy()->is_this();
363 }
364 
365 
IsIdentifier(Expression * expression)366 bool ParserTraits::IsIdentifier(Expression* expression) {
367   VariableProxy* operand = expression->AsVariableProxy();
368   return operand != NULL && !operand->is_this();
369 }
370 
371 
PushPropertyName(FuncNameInferrer * fni,Expression * expression)372 void ParserTraits::PushPropertyName(FuncNameInferrer* fni,
373                                     Expression* expression) {
374   if (expression->IsPropertyName()) {
375     fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName());
376   } else {
377     fni->PushLiteralName(
378         parser_->ast_value_factory()->anonymous_function_string());
379   }
380 }
381 
382 
CheckAssigningFunctionLiteralToProperty(Expression * left,Expression * right)383 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left,
384                                                            Expression* right) {
385   DCHECK(left != NULL);
386   if (left->IsProperty() && right->IsFunctionLiteral()) {
387     right->AsFunctionLiteral()->set_pretenure();
388   }
389 }
390 
391 
MarkExpressionAsAssigned(Expression * expression)392 Expression* ParserTraits::MarkExpressionAsAssigned(Expression* expression) {
393   VariableProxy* proxy =
394       expression != NULL ? expression->AsVariableProxy() : NULL;
395   if (proxy != NULL) proxy->set_is_assigned();
396   return expression;
397 }
398 
399 
ShortcutNumericLiteralBinaryExpression(Expression ** x,Expression * y,Token::Value op,int pos,AstNodeFactory * factory)400 bool ParserTraits::ShortcutNumericLiteralBinaryExpression(
401     Expression** x, Expression* y, Token::Value op, int pos,
402     AstNodeFactory* factory) {
403   if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() &&
404       y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) {
405     double x_val = (*x)->AsLiteral()->raw_value()->AsNumber();
406     double y_val = y->AsLiteral()->raw_value()->AsNumber();
407     bool x_has_dot = (*x)->AsLiteral()->raw_value()->ContainsDot();
408     bool y_has_dot = y->AsLiteral()->raw_value()->ContainsDot();
409     bool has_dot = x_has_dot || y_has_dot;
410     switch (op) {
411       case Token::ADD:
412         *x = factory->NewNumberLiteral(x_val + y_val, pos, has_dot);
413         return true;
414       case Token::SUB:
415         *x = factory->NewNumberLiteral(x_val - y_val, pos, has_dot);
416         return true;
417       case Token::MUL:
418         *x = factory->NewNumberLiteral(x_val * y_val, pos, has_dot);
419         return true;
420       case Token::DIV:
421         *x = factory->NewNumberLiteral(x_val / y_val, pos, has_dot);
422         return true;
423       case Token::BIT_OR: {
424         int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
425         *x = factory->NewNumberLiteral(value, pos, has_dot);
426         return true;
427       }
428       case Token::BIT_AND: {
429         int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
430         *x = factory->NewNumberLiteral(value, pos, has_dot);
431         return true;
432       }
433       case Token::BIT_XOR: {
434         int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
435         *x = factory->NewNumberLiteral(value, pos, has_dot);
436         return true;
437       }
438       case Token::SHL: {
439         int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
440         *x = factory->NewNumberLiteral(value, pos, has_dot);
441         return true;
442       }
443       case Token::SHR: {
444         uint32_t shift = DoubleToInt32(y_val) & 0x1f;
445         uint32_t value = DoubleToUint32(x_val) >> shift;
446         *x = factory->NewNumberLiteral(value, pos, has_dot);
447         return true;
448       }
449       case Token::SAR: {
450         uint32_t shift = DoubleToInt32(y_val) & 0x1f;
451         int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
452         *x = factory->NewNumberLiteral(value, pos, has_dot);
453         return true;
454       }
455       case Token::EXP: {
456         double value = Pow(x_val, y_val);
457         int int_value = static_cast<int>(value);
458         *x = factory->NewNumberLiteral(
459             int_value == value && value != -0.0 ? int_value : value, pos,
460             has_dot);
461         return true;
462       }
463       default:
464         break;
465     }
466   }
467   return false;
468 }
469 
470 
BuildUnaryExpression(Expression * expression,Token::Value op,int pos,AstNodeFactory * factory)471 Expression* ParserTraits::BuildUnaryExpression(Expression* expression,
472                                                Token::Value op, int pos,
473                                                AstNodeFactory* factory) {
474   DCHECK(expression != NULL);
475   if (expression->IsLiteral()) {
476     const AstValue* literal = expression->AsLiteral()->raw_value();
477     if (op == Token::NOT) {
478       // Convert the literal to a boolean condition and negate it.
479       bool condition = literal->BooleanValue();
480       return factory->NewBooleanLiteral(!condition, pos);
481     } else if (literal->IsNumber()) {
482       // Compute some expressions involving only number literals.
483       double value = literal->AsNumber();
484       bool has_dot = literal->ContainsDot();
485       switch (op) {
486         case Token::ADD:
487           return expression;
488         case Token::SUB:
489           return factory->NewNumberLiteral(-value, pos, has_dot);
490         case Token::BIT_NOT:
491           return factory->NewNumberLiteral(~DoubleToInt32(value), pos, has_dot);
492         default:
493           break;
494       }
495     }
496   }
497   // Desugar '+foo' => 'foo*1'
498   if (op == Token::ADD) {
499     return factory->NewBinaryOperation(
500         Token::MUL, expression, factory->NewNumberLiteral(1, pos, true), pos);
501   }
502   // The same idea for '-foo' => 'foo*(-1)'.
503   if (op == Token::SUB) {
504     return factory->NewBinaryOperation(
505         Token::MUL, expression, factory->NewNumberLiteral(-1, pos), pos);
506   }
507   // ...and one more time for '~foo' => 'foo^(~0)'.
508   if (op == Token::BIT_NOT) {
509     return factory->NewBinaryOperation(
510         Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos);
511   }
512   return factory->NewUnaryOperation(op, expression, pos);
513 }
514 
BuildIteratorResult(Expression * value,bool done)515 Expression* ParserTraits::BuildIteratorResult(Expression* value, bool done) {
516   int pos = RelocInfo::kNoPosition;
517   AstNodeFactory* factory = parser_->factory();
518   Zone* zone = parser_->zone();
519 
520   if (value == nullptr) value = factory->NewUndefinedLiteral(pos);
521 
522   auto args = new (zone) ZoneList<Expression*>(2, zone);
523   args->Add(value, zone);
524   args->Add(factory->NewBooleanLiteral(done, pos), zone);
525 
526   return factory->NewCallRuntime(Runtime::kInlineCreateIterResultObject, args,
527                                  pos);
528 }
529 
NewThrowReferenceError(MessageTemplate::Template message,int pos)530 Expression* ParserTraits::NewThrowReferenceError(
531     MessageTemplate::Template message, int pos) {
532   return NewThrowError(Runtime::kNewReferenceError, message,
533                        parser_->ast_value_factory()->empty_string(), pos);
534 }
535 
536 
NewThrowSyntaxError(MessageTemplate::Template message,const AstRawString * arg,int pos)537 Expression* ParserTraits::NewThrowSyntaxError(MessageTemplate::Template message,
538                                               const AstRawString* arg,
539                                               int pos) {
540   return NewThrowError(Runtime::kNewSyntaxError, message, arg, pos);
541 }
542 
543 
NewThrowTypeError(MessageTemplate::Template message,const AstRawString * arg,int pos)544 Expression* ParserTraits::NewThrowTypeError(MessageTemplate::Template message,
545                                             const AstRawString* arg, int pos) {
546   return NewThrowError(Runtime::kNewTypeError, message, arg, pos);
547 }
548 
549 
NewThrowError(Runtime::FunctionId id,MessageTemplate::Template message,const AstRawString * arg,int pos)550 Expression* ParserTraits::NewThrowError(Runtime::FunctionId id,
551                                         MessageTemplate::Template message,
552                                         const AstRawString* arg, int pos) {
553   Zone* zone = parser_->zone();
554   ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(2, zone);
555   args->Add(parser_->factory()->NewSmiLiteral(message, pos), zone);
556   args->Add(parser_->factory()->NewStringLiteral(arg, pos), zone);
557   CallRuntime* call_constructor =
558       parser_->factory()->NewCallRuntime(id, args, pos);
559   return parser_->factory()->NewThrow(call_constructor, pos);
560 }
561 
562 
ReportMessageAt(Scanner::Location source_location,MessageTemplate::Template message,const char * arg,ParseErrorType error_type)563 void ParserTraits::ReportMessageAt(Scanner::Location source_location,
564                                    MessageTemplate::Template message,
565                                    const char* arg, ParseErrorType error_type) {
566   if (parser_->stack_overflow()) {
567     // Suppress the error message (syntax error or such) in the presence of a
568     // stack overflow. The isolate allows only one pending exception at at time
569     // and we want to report the stack overflow later.
570     return;
571   }
572   parser_->pending_error_handler_.ReportMessageAt(source_location.beg_pos,
573                                                   source_location.end_pos,
574                                                   message, arg, error_type);
575 }
576 
577 
ReportMessage(MessageTemplate::Template message,const char * arg,ParseErrorType error_type)578 void ParserTraits::ReportMessage(MessageTemplate::Template message,
579                                  const char* arg, ParseErrorType error_type) {
580   Scanner::Location source_location = parser_->scanner()->location();
581   ReportMessageAt(source_location, message, arg, error_type);
582 }
583 
584 
ReportMessage(MessageTemplate::Template message,const AstRawString * arg,ParseErrorType error_type)585 void ParserTraits::ReportMessage(MessageTemplate::Template message,
586                                  const AstRawString* arg,
587                                  ParseErrorType error_type) {
588   Scanner::Location source_location = parser_->scanner()->location();
589   ReportMessageAt(source_location, message, arg, error_type);
590 }
591 
592 
ReportMessageAt(Scanner::Location source_location,MessageTemplate::Template message,const AstRawString * arg,ParseErrorType error_type)593 void ParserTraits::ReportMessageAt(Scanner::Location source_location,
594                                    MessageTemplate::Template message,
595                                    const AstRawString* arg,
596                                    ParseErrorType error_type) {
597   if (parser_->stack_overflow()) {
598     // Suppress the error message (syntax error or such) in the presence of a
599     // stack overflow. The isolate allows only one pending exception at at time
600     // and we want to report the stack overflow later.
601     return;
602   }
603   parser_->pending_error_handler_.ReportMessageAt(source_location.beg_pos,
604                                                   source_location.end_pos,
605                                                   message, arg, error_type);
606 }
607 
608 
GetSymbol(Scanner * scanner)609 const AstRawString* ParserTraits::GetSymbol(Scanner* scanner) {
610   const AstRawString* result =
611       parser_->scanner()->CurrentSymbol(parser_->ast_value_factory());
612   DCHECK(result != NULL);
613   return result;
614 }
615 
616 
GetNumberAsSymbol(Scanner * scanner)617 const AstRawString* ParserTraits::GetNumberAsSymbol(Scanner* scanner) {
618   double double_value = parser_->scanner()->DoubleValue();
619   char array[100];
620   const char* string = DoubleToCString(double_value, ArrayVector(array));
621   return parser_->ast_value_factory()->GetOneByteString(string);
622 }
623 
624 
GetNextSymbol(Scanner * scanner)625 const AstRawString* ParserTraits::GetNextSymbol(Scanner* scanner) {
626   return parser_->scanner()->NextSymbol(parser_->ast_value_factory());
627 }
628 
629 
ThisExpression(Scope * scope,AstNodeFactory * factory,int pos)630 Expression* ParserTraits::ThisExpression(Scope* scope, AstNodeFactory* factory,
631                                          int pos) {
632   return scope->NewUnresolved(factory,
633                               parser_->ast_value_factory()->this_string(),
634                               Variable::THIS, pos, pos + 4);
635 }
636 
637 
SuperPropertyReference(Scope * scope,AstNodeFactory * factory,int pos)638 Expression* ParserTraits::SuperPropertyReference(Scope* scope,
639                                                  AstNodeFactory* factory,
640                                                  int pos) {
641   // this_function[home_object_symbol]
642   VariableProxy* this_function_proxy = scope->NewUnresolved(
643       factory, parser_->ast_value_factory()->this_function_string(),
644       Variable::NORMAL, pos);
645   Expression* home_object_symbol_literal =
646       factory->NewSymbolLiteral("home_object_symbol", RelocInfo::kNoPosition);
647   Expression* home_object = factory->NewProperty(
648       this_function_proxy, home_object_symbol_literal, pos);
649   return factory->NewSuperPropertyReference(
650       ThisExpression(scope, factory, pos)->AsVariableProxy(), home_object, pos);
651 }
652 
653 
SuperCallReference(Scope * scope,AstNodeFactory * factory,int pos)654 Expression* ParserTraits::SuperCallReference(Scope* scope,
655                                              AstNodeFactory* factory, int pos) {
656   VariableProxy* new_target_proxy = scope->NewUnresolved(
657       factory, parser_->ast_value_factory()->new_target_string(),
658       Variable::NORMAL, pos);
659   VariableProxy* this_function_proxy = scope->NewUnresolved(
660       factory, parser_->ast_value_factory()->this_function_string(),
661       Variable::NORMAL, pos);
662   return factory->NewSuperCallReference(
663       ThisExpression(scope, factory, pos)->AsVariableProxy(), new_target_proxy,
664       this_function_proxy, pos);
665 }
666 
667 
NewTargetExpression(Scope * scope,AstNodeFactory * factory,int pos)668 Expression* ParserTraits::NewTargetExpression(Scope* scope,
669                                               AstNodeFactory* factory,
670                                               int pos) {
671   static const int kNewTargetStringLength = 10;
672   auto proxy = scope->NewUnresolved(
673       factory, parser_->ast_value_factory()->new_target_string(),
674       Variable::NORMAL, pos, pos + kNewTargetStringLength);
675   proxy->set_is_new_target();
676   return proxy;
677 }
678 
679 
FunctionSentExpression(Scope * scope,AstNodeFactory * factory,int pos)680 Expression* ParserTraits::FunctionSentExpression(Scope* scope,
681                                                  AstNodeFactory* factory,
682                                                  int pos) {
683   // We desugar function.sent into %_GeneratorGetInputOrDebugPos(generator).
684   Zone* zone = parser_->zone();
685   ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(1, zone);
686   VariableProxy* generator = factory->NewVariableProxy(
687       parser_->function_state_->generator_object_variable());
688   args->Add(generator, zone);
689   return factory->NewCallRuntime(Runtime::kInlineGeneratorGetInputOrDebugPos,
690                                  args, pos);
691 }
692 
693 
ExpressionFromLiteral(Token::Value token,int pos,Scanner * scanner,AstNodeFactory * factory)694 Literal* ParserTraits::ExpressionFromLiteral(Token::Value token, int pos,
695                                              Scanner* scanner,
696                                              AstNodeFactory* factory) {
697   switch (token) {
698     case Token::NULL_LITERAL:
699       return factory->NewNullLiteral(pos);
700     case Token::TRUE_LITERAL:
701       return factory->NewBooleanLiteral(true, pos);
702     case Token::FALSE_LITERAL:
703       return factory->NewBooleanLiteral(false, pos);
704     case Token::SMI: {
705       int value = scanner->smi_value();
706       return factory->NewSmiLiteral(value, pos);
707     }
708     case Token::NUMBER: {
709       bool has_dot = scanner->ContainsDot();
710       double value = scanner->DoubleValue();
711       return factory->NewNumberLiteral(value, pos, has_dot);
712     }
713     default:
714       DCHECK(false);
715   }
716   return NULL;
717 }
718 
719 
ExpressionFromIdentifier(const AstRawString * name,int start_position,int end_position,Scope * scope,AstNodeFactory * factory)720 Expression* ParserTraits::ExpressionFromIdentifier(const AstRawString* name,
721                                                    int start_position,
722                                                    int end_position,
723                                                    Scope* scope,
724                                                    AstNodeFactory* factory) {
725   if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name);
726   return scope->NewUnresolved(factory, name, Variable::NORMAL, start_position,
727                               end_position);
728 }
729 
730 
ExpressionFromString(int pos,Scanner * scanner,AstNodeFactory * factory)731 Expression* ParserTraits::ExpressionFromString(int pos, Scanner* scanner,
732                                                AstNodeFactory* factory) {
733   const AstRawString* symbol = GetSymbol(scanner);
734   if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol);
735   return factory->NewStringLiteral(symbol, pos);
736 }
737 
738 
GetIterator(Expression * iterable,AstNodeFactory * factory,int pos)739 Expression* ParserTraits::GetIterator(Expression* iterable,
740                                       AstNodeFactory* factory, int pos) {
741   Expression* iterator_symbol_literal =
742       factory->NewSymbolLiteral("iterator_symbol", RelocInfo::kNoPosition);
743   Expression* prop =
744       factory->NewProperty(iterable, iterator_symbol_literal, pos);
745   Zone* zone = parser_->zone();
746   ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(0, zone);
747   return factory->NewCall(prop, args, pos);
748 }
749 
750 
GetLiteralTheHole(int position,AstNodeFactory * factory)751 Literal* ParserTraits::GetLiteralTheHole(int position,
752                                          AstNodeFactory* factory) {
753   return factory->NewTheHoleLiteral(RelocInfo::kNoPosition);
754 }
755 
756 
ParseV8Intrinsic(bool * ok)757 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) {
758   return parser_->ParseV8Intrinsic(ok);
759 }
760 
761 
ParseFunctionLiteral(const AstRawString * name,Scanner::Location function_name_location,FunctionNameValidity function_name_validity,FunctionKind kind,int function_token_position,FunctionLiteral::FunctionType type,LanguageMode language_mode,bool * ok)762 FunctionLiteral* ParserTraits::ParseFunctionLiteral(
763     const AstRawString* name, Scanner::Location function_name_location,
764     FunctionNameValidity function_name_validity, FunctionKind kind,
765     int function_token_position, FunctionLiteral::FunctionType type,
766     LanguageMode language_mode, bool* ok) {
767   return parser_->ParseFunctionLiteral(
768       name, function_name_location, function_name_validity, kind,
769       function_token_position, type, language_mode, ok);
770 }
771 
ParseClassLiteral(Type::ExpressionClassifier * classifier,const AstRawString * name,Scanner::Location class_name_location,bool name_is_strict_reserved,int pos,bool * ok)772 ClassLiteral* ParserTraits::ParseClassLiteral(
773     Type::ExpressionClassifier* classifier, const AstRawString* name,
774     Scanner::Location class_name_location, bool name_is_strict_reserved,
775     int pos, bool* ok) {
776   return parser_->ParseClassLiteral(classifier, name, class_name_location,
777                                     name_is_strict_reserved, pos, ok);
778 }
779 
MarkTailPosition(Expression * expression)780 void ParserTraits::MarkTailPosition(Expression* expression) {
781   expression->MarkTail();
782 }
783 
MarkCollectedTailCallExpressions()784 void ParserTraits::MarkCollectedTailCallExpressions() {
785   parser_->MarkCollectedTailCallExpressions();
786 }
787 
Parser(ParseInfo * info)788 Parser::Parser(ParseInfo* info)
789     : ParserBase<ParserTraits>(info->zone(), &scanner_, info->stack_limit(),
790                                info->extension(), info->ast_value_factory(),
791                                NULL, this),
792       scanner_(info->unicode_cache()),
793       reusable_preparser_(NULL),
794       original_scope_(NULL),
795       target_stack_(NULL),
796       compile_options_(info->compile_options()),
797       cached_parse_data_(NULL),
798       total_preparse_skipped_(0),
799       pre_parse_timer_(NULL),
800       parsing_on_main_thread_(true) {
801   // Even though we were passed ParseInfo, we should not store it in
802   // Parser - this makes sure that Isolate is not accidentally accessed via
803   // ParseInfo during background parsing.
804   DCHECK(!info->script().is_null() || info->source_stream() != NULL);
805   set_allow_lazy(info->allow_lazy_parsing());
806   set_allow_natives(FLAG_allow_natives_syntax || info->is_native());
807   set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() &&
808                       info->isolate()->is_tail_call_elimination_enabled());
809   set_allow_harmony_do_expressions(FLAG_harmony_do_expressions);
810   set_allow_harmony_for_in(FLAG_harmony_for_in);
811   set_allow_harmony_function_sent(FLAG_harmony_function_sent);
812   set_allow_harmony_restrictive_declarations(
813       FLAG_harmony_restrictive_declarations);
814   set_allow_harmony_exponentiation_operator(
815       FLAG_harmony_exponentiation_operator);
816   set_allow_harmony_async_await(FLAG_harmony_async_await);
817   set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators);
818   for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
819        ++feature) {
820     use_counts_[feature] = 0;
821   }
822   if (info->ast_value_factory() == NULL) {
823     // info takes ownership of AstValueFactory.
824     info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed()));
825     info->set_ast_value_factory_owned();
826     ast_value_factory_ = info->ast_value_factory();
827   }
828 }
829 
830 
ParseProgram(Isolate * isolate,ParseInfo * info)831 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
832   // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
833   // see comment for HistogramTimerScope class.
834 
835   // It's OK to use the Isolate & counters here, since this function is only
836   // called in the main thread.
837   DCHECK(parsing_on_main_thread_);
838 
839   HistogramTimerScope timer_scope(isolate->counters()->parse(), true);
840   RuntimeCallTimerScope runtime_timer(isolate, &RuntimeCallStats::Parse);
841   TRACE_EVENT0("v8", "V8.Parse");
842   Handle<String> source(String::cast(info->script()->source()));
843   isolate->counters()->total_parse_size()->Increment(source->length());
844   base::ElapsedTimer timer;
845   if (FLAG_trace_parse) {
846     timer.Start();
847   }
848   fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
849 
850   // Initialize parser state.
851   CompleteParserRecorder recorder;
852 
853   if (produce_cached_parse_data()) {
854     log_ = &recorder;
855   } else if (consume_cached_parse_data()) {
856     cached_parse_data_->Initialize();
857   }
858 
859   source = String::Flatten(source);
860   FunctionLiteral* result;
861 
862   if (source->IsExternalTwoByteString()) {
863     // Notice that the stream is destroyed at the end of the branch block.
864     // The last line of the blocks can't be moved outside, even though they're
865     // identical calls.
866     ExternalTwoByteStringUtf16CharacterStream stream(
867         Handle<ExternalTwoByteString>::cast(source), 0, source->length());
868     scanner_.Initialize(&stream);
869     result = DoParseProgram(info);
870   } else {
871     GenericStringUtf16CharacterStream stream(source, 0, source->length());
872     scanner_.Initialize(&stream);
873     result = DoParseProgram(info);
874   }
875   if (result != NULL) {
876     DCHECK_EQ(scanner_.peek_location().beg_pos, source->length());
877   }
878   HandleSourceURLComments(isolate, info->script());
879 
880   if (FLAG_trace_parse && result != NULL) {
881     double ms = timer.Elapsed().InMillisecondsF();
882     if (info->is_eval()) {
883       PrintF("[parsing eval");
884     } else if (info->script()->name()->IsString()) {
885       String* name = String::cast(info->script()->name());
886       base::SmartArrayPointer<char> name_chars = name->ToCString();
887       PrintF("[parsing script: %s", name_chars.get());
888     } else {
889       PrintF("[parsing script");
890     }
891     PrintF(" - took %0.3f ms]\n", ms);
892   }
893   if (produce_cached_parse_data()) {
894     if (result != NULL) *info->cached_data() = recorder.GetScriptData();
895     log_ = NULL;
896   }
897   return result;
898 }
899 
900 
DoParseProgram(ParseInfo * info)901 FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
902   // Note that this function can be called from the main thread or from a
903   // background thread. We should not access anything Isolate / heap dependent
904   // via ParseInfo, and also not pass it forward.
905   DCHECK(scope_ == NULL);
906   DCHECK(target_stack_ == NULL);
907 
908   Mode parsing_mode = FLAG_lazy && allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY;
909   if (allow_natives() || extension_ != NULL) parsing_mode = PARSE_EAGERLY;
910 
911   FunctionLiteral* result = NULL;
912   {
913     // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native
914     // context, which will have the "this" binding for script scopes.
915     Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
916     info->set_script_scope(scope);
917     if (!info->context().is_null() && !info->context()->IsNativeContext()) {
918       scope = Scope::DeserializeScopeChain(info->isolate(), zone(),
919                                            *info->context(), scope);
920       // The Scope is backed up by ScopeInfo (which is in the V8 heap); this
921       // means the Parser cannot operate independent of the V8 heap. Tell the
922       // string table to internalize strings and values right after they're
923       // created. This kind of parsing can only be done in the main thread.
924       DCHECK(parsing_on_main_thread_);
925       ast_value_factory()->Internalize(info->isolate());
926     }
927     original_scope_ = scope;
928     if (info->is_eval()) {
929       if (!scope->is_script_scope() || is_strict(info->language_mode())) {
930         parsing_mode = PARSE_EAGERLY;
931       }
932       scope = NewScope(scope, EVAL_SCOPE);
933     } else if (info->is_module()) {
934       scope = NewScope(scope, MODULE_SCOPE);
935     }
936 
937     scope->set_start_position(0);
938 
939     // Enter 'scope' with the given parsing mode.
940     ParsingModeScope parsing_mode_scope(this, parsing_mode);
941     AstNodeFactory function_factory(ast_value_factory());
942     FunctionState function_state(&function_state_, &scope_, scope,
943                                  kNormalFunction, &function_factory);
944 
945     ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
946     bool ok = true;
947     int beg_pos = scanner()->location().beg_pos;
948     parsing_module_ = info->is_module();
949     if (parsing_module_) {
950       ParseModuleItemList(body, &ok);
951     } else {
952       // Don't count the mode in the use counters--give the program a chance
953       // to enable script-wide strict mode below.
954       scope_->SetLanguageMode(info->language_mode());
955       ParseStatementList(body, Token::EOS, &ok);
956     }
957 
958     // The parser will peek but not consume EOS.  Our scope logically goes all
959     // the way to the EOS, though.
960     scope->set_end_position(scanner()->peek_location().beg_pos);
961 
962     if (ok && is_strict(language_mode())) {
963       CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
964       CheckDecimalLiteralWithLeadingZero(use_counts_, beg_pos,
965                                          scanner()->location().end_pos);
966     }
967     if (ok && is_sloppy(language_mode())) {
968       // TODO(littledan): Function bindings on the global object that modify
969       // pre-existing bindings should be made writable, enumerable and
970       // nonconfigurable if possible, whereas this code will leave attributes
971       // unchanged if the property already exists.
972       InsertSloppyBlockFunctionVarBindings(scope, &ok);
973     }
974     if (ok) {
975       CheckConflictingVarDeclarations(scope_, &ok);
976     }
977 
978     if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
979       if (body->length() != 1 ||
980           !body->at(0)->IsExpressionStatement() ||
981           !body->at(0)->AsExpressionStatement()->
982               expression()->IsFunctionLiteral()) {
983         ReportMessage(MessageTemplate::kSingleFunctionLiteral);
984         ok = false;
985       }
986     }
987 
988     if (ok) {
989       ParserTraits::RewriteDestructuringAssignments();
990       result = factory()->NewScriptOrEvalFunctionLiteral(
991           scope_, body, function_state.materialized_literal_count(),
992           function_state.expected_property_count());
993     }
994   }
995 
996   // Make sure the target stack is empty.
997   DCHECK(target_stack_ == NULL);
998 
999   return result;
1000 }
1001 
1002 
ParseLazy(Isolate * isolate,ParseInfo * info)1003 FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info) {
1004   // It's OK to use the Isolate & counters here, since this function is only
1005   // called in the main thread.
1006   DCHECK(parsing_on_main_thread_);
1007   RuntimeCallTimerScope runtime_timer(isolate, &RuntimeCallStats::ParseLazy);
1008   HistogramTimerScope timer_scope(isolate->counters()->parse_lazy());
1009   TRACE_EVENT0("v8", "V8.ParseLazy");
1010   Handle<String> source(String::cast(info->script()->source()));
1011   isolate->counters()->total_parse_size()->Increment(source->length());
1012   base::ElapsedTimer timer;
1013   if (FLAG_trace_parse) {
1014     timer.Start();
1015   }
1016   Handle<SharedFunctionInfo> shared_info = info->shared_info();
1017 
1018   // Initialize parser state.
1019   source = String::Flatten(source);
1020   FunctionLiteral* result;
1021   if (source->IsExternalTwoByteString()) {
1022     ExternalTwoByteStringUtf16CharacterStream stream(
1023         Handle<ExternalTwoByteString>::cast(source),
1024         shared_info->start_position(),
1025         shared_info->end_position());
1026     result = ParseLazy(isolate, info, &stream);
1027   } else {
1028     GenericStringUtf16CharacterStream stream(source,
1029                                              shared_info->start_position(),
1030                                              shared_info->end_position());
1031     result = ParseLazy(isolate, info, &stream);
1032   }
1033 
1034   if (FLAG_trace_parse && result != NULL) {
1035     double ms = timer.Elapsed().InMillisecondsF();
1036     base::SmartArrayPointer<char> name_chars =
1037         result->debug_name()->ToCString();
1038     PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms);
1039   }
1040   return result;
1041 }
1042 
ComputeFunctionType(Handle<SharedFunctionInfo> shared_info)1043 static FunctionLiteral::FunctionType ComputeFunctionType(
1044     Handle<SharedFunctionInfo> shared_info) {
1045   if (shared_info->is_declaration()) {
1046     return FunctionLiteral::kDeclaration;
1047   } else if (shared_info->is_named_expression()) {
1048     return FunctionLiteral::kNamedExpression;
1049   } else if (IsConciseMethod(shared_info->kind()) ||
1050              IsAccessorFunction(shared_info->kind())) {
1051     return FunctionLiteral::kAccessorOrMethod;
1052   }
1053   return FunctionLiteral::kAnonymousExpression;
1054 }
1055 
ParseLazy(Isolate * isolate,ParseInfo * info,Utf16CharacterStream * source)1056 FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info,
1057                                    Utf16CharacterStream* source) {
1058   Handle<SharedFunctionInfo> shared_info = info->shared_info();
1059   scanner_.Initialize(source);
1060   DCHECK(scope_ == NULL);
1061   DCHECK(target_stack_ == NULL);
1062 
1063   Handle<String> name(String::cast(shared_info->name()));
1064   DCHECK(ast_value_factory());
1065   fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
1066   const AstRawString* raw_name = ast_value_factory()->GetString(name);
1067   fni_->PushEnclosingName(raw_name);
1068 
1069   ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1070 
1071   // Place holder for the result.
1072   FunctionLiteral* result = NULL;
1073 
1074   {
1075     // Parse the function literal.
1076     Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
1077     info->set_script_scope(scope);
1078     if (!info->context().is_null()) {
1079       // Ok to use Isolate here, since lazy function parsing is only done in the
1080       // main thread.
1081       DCHECK(parsing_on_main_thread_);
1082       scope = Scope::DeserializeScopeChain(isolate, zone(), *info->context(),
1083                                            scope);
1084     }
1085     original_scope_ = scope;
1086     AstNodeFactory function_factory(ast_value_factory());
1087     FunctionState function_state(&function_state_, &scope_, scope,
1088                                  shared_info->kind(), &function_factory);
1089     DCHECK(is_sloppy(scope->language_mode()) ||
1090            is_strict(info->language_mode()));
1091     DCHECK(info->language_mode() == shared_info->language_mode());
1092     FunctionLiteral::FunctionType function_type =
1093         ComputeFunctionType(shared_info);
1094     bool ok = true;
1095 
1096     if (shared_info->is_arrow()) {
1097       bool is_async = allow_harmony_async_await() && shared_info->is_async();
1098       if (is_async) {
1099         DCHECK(!scanner()->HasAnyLineTerminatorAfterNext());
1100         Consume(Token::ASYNC);
1101         DCHECK(peek_any_identifier() || peek() == Token::LPAREN);
1102       }
1103 
1104       // TODO(adamk): We should construct this scope from the ScopeInfo.
1105       Scope* scope =
1106           NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction);
1107 
1108       // These two bits only need to be explicitly set because we're
1109       // not passing the ScopeInfo to the Scope constructor.
1110       // TODO(adamk): Remove these calls once the above NewScope call
1111       // passes the ScopeInfo.
1112       if (shared_info->scope_info()->CallsEval()) {
1113         scope->RecordEvalCall();
1114       }
1115       SetLanguageMode(scope, shared_info->language_mode());
1116 
1117       scope->set_start_position(shared_info->start_position());
1118       ExpressionClassifier formals_classifier(this);
1119       ParserFormalParameters formals(scope);
1120       Checkpoint checkpoint(this);
1121       {
1122         // Parsing patterns as variable reference expression creates
1123         // NewUnresolved references in current scope. Entrer arrow function
1124         // scope for formal parameter parsing.
1125         BlockState block_state(&scope_, scope);
1126         if (Check(Token::LPAREN)) {
1127           // '(' StrictFormalParameters ')'
1128           ParseFormalParameterList(&formals, &formals_classifier, &ok);
1129           if (ok) ok = Check(Token::RPAREN);
1130         } else {
1131           // BindingIdentifier
1132           ParseFormalParameter(&formals, &formals_classifier, &ok);
1133           if (ok) {
1134             DeclareFormalParameter(formals.scope, formals.at(0),
1135                                    &formals_classifier);
1136           }
1137         }
1138       }
1139 
1140       if (ok) {
1141         checkpoint.Restore(&formals.materialized_literals_count);
1142         // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should
1143         // not be observable, or else the preparser would have failed.
1144         Expression* expression = ParseArrowFunctionLiteral(
1145             true, formals, is_async, formals_classifier, &ok);
1146         if (ok) {
1147           // Scanning must end at the same position that was recorded
1148           // previously. If not, parsing has been interrupted due to a stack
1149           // overflow, at which point the partially parsed arrow function
1150           // concise body happens to be a valid expression. This is a problem
1151           // only for arrow functions with single expression bodies, since there
1152           // is no end token such as "}" for normal functions.
1153           if (scanner()->location().end_pos == shared_info->end_position()) {
1154             // The pre-parser saw an arrow function here, so the full parser
1155             // must produce a FunctionLiteral.
1156             DCHECK(expression->IsFunctionLiteral());
1157             result = expression->AsFunctionLiteral();
1158           } else {
1159             ok = false;
1160           }
1161         }
1162       }
1163     } else if (shared_info->is_default_constructor()) {
1164       result = DefaultConstructor(
1165           raw_name, IsSubclassConstructor(shared_info->kind()), scope,
1166           shared_info->start_position(), shared_info->end_position(),
1167           shared_info->language_mode());
1168     } else {
1169       result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(),
1170                                     kSkipFunctionNameCheck, shared_info->kind(),
1171                                     RelocInfo::kNoPosition, function_type,
1172                                     shared_info->language_mode(), &ok);
1173     }
1174     // Make sure the results agree.
1175     DCHECK(ok == (result != NULL));
1176   }
1177 
1178   // Make sure the target stack is empty.
1179   DCHECK(target_stack_ == NULL);
1180 
1181   if (result != NULL) {
1182     Handle<String> inferred_name(shared_info->inferred_name());
1183     result->set_inferred_name(inferred_name);
1184   }
1185   return result;
1186 }
1187 
1188 
ParseStatementList(ZoneList<Statement * > * body,int end_token,bool * ok)1189 void* Parser::ParseStatementList(ZoneList<Statement*>* body, int end_token,
1190                                  bool* ok) {
1191   // StatementList ::
1192   //   (StatementListItem)* <end_token>
1193 
1194   // Allocate a target stack to use for this set of source
1195   // elements. This way, all scripts and functions get their own
1196   // target stack thus avoiding illegal breaks and continues across
1197   // functions.
1198   TargetScope scope(&this->target_stack_);
1199 
1200   DCHECK(body != NULL);
1201   bool directive_prologue = true;     // Parsing directive prologue.
1202 
1203   while (peek() != end_token) {
1204     if (directive_prologue && peek() != Token::STRING) {
1205       directive_prologue = false;
1206     }
1207 
1208     Scanner::Location token_loc = scanner()->peek_location();
1209     Statement* stat = ParseStatementListItem(CHECK_OK);
1210     if (stat == NULL || stat->IsEmpty()) {
1211       directive_prologue = false;   // End of directive prologue.
1212       continue;
1213     }
1214 
1215     if (directive_prologue) {
1216       // A shot at a directive.
1217       ExpressionStatement* e_stat;
1218       Literal* literal;
1219       // Still processing directive prologue?
1220       if ((e_stat = stat->AsExpressionStatement()) != NULL &&
1221           (literal = e_stat->expression()->AsLiteral()) != NULL &&
1222           literal->raw_value()->IsString()) {
1223         // Check "use strict" directive (ES5 14.1), "use asm" directive.
1224         bool use_strict_found =
1225             literal->raw_value()->AsString() ==
1226                 ast_value_factory()->use_strict_string() &&
1227             token_loc.end_pos - token_loc.beg_pos ==
1228                 ast_value_factory()->use_strict_string()->length() + 2;
1229         if (use_strict_found) {
1230           if (is_sloppy(scope_->language_mode())) {
1231             RaiseLanguageMode(STRICT);
1232           }
1233 
1234           if (!scope_->HasSimpleParameters()) {
1235             // TC39 deemed "use strict" directives to be an error when occurring
1236             // in the body of a function with non-simple parameter list, on
1237             // 29/7/2015. https://goo.gl/ueA7Ln
1238             const AstRawString* string = literal->raw_value()->AsString();
1239             ParserTraits::ReportMessageAt(
1240                 token_loc, MessageTemplate::kIllegalLanguageModeDirective,
1241                 string);
1242             *ok = false;
1243             return nullptr;
1244           }
1245           // Because declarations in strict eval code don't leak into the scope
1246           // of the eval call, it is likely that functions declared in strict
1247           // eval code will be used within the eval code, so lazy parsing is
1248           // probably not a win.
1249           if (scope_->is_eval_scope()) mode_ = PARSE_EAGERLY;
1250         } else if (literal->raw_value()->AsString() ==
1251                        ast_value_factory()->use_asm_string() &&
1252                    token_loc.end_pos - token_loc.beg_pos ==
1253                        ast_value_factory()->use_asm_string()->length() + 2) {
1254           // Store the usage count; The actual use counter on the isolate is
1255           // incremented after parsing is done.
1256           ++use_counts_[v8::Isolate::kUseAsm];
1257           scope_->SetAsmModule();
1258         } else {
1259           // Should not change mode, but will increment UseCounter
1260           // if appropriate. Ditto usages below.
1261           RaiseLanguageMode(SLOPPY);
1262         }
1263       } else {
1264         // End of the directive prologue.
1265         directive_prologue = false;
1266         RaiseLanguageMode(SLOPPY);
1267       }
1268     } else {
1269       RaiseLanguageMode(SLOPPY);
1270     }
1271 
1272     body->Add(stat, zone());
1273   }
1274 
1275   return 0;
1276 }
1277 
1278 
ParseStatementListItem(bool * ok)1279 Statement* Parser::ParseStatementListItem(bool* ok) {
1280   // (Ecma 262 6th Edition, 13.1):
1281   // StatementListItem:
1282   //    Statement
1283   //    Declaration
1284   const Token::Value peeked = peek();
1285   switch (peeked) {
1286     case Token::FUNCTION:
1287       return ParseHoistableDeclaration(NULL, ok);
1288     case Token::CLASS:
1289       Consume(Token::CLASS);
1290       return ParseClassDeclaration(NULL, ok);
1291     case Token::CONST:
1292       return ParseVariableStatement(kStatementListItem, NULL, ok);
1293     case Token::VAR:
1294       return ParseVariableStatement(kStatementListItem, NULL, ok);
1295     case Token::LET:
1296       if (IsNextLetKeyword()) {
1297         return ParseVariableStatement(kStatementListItem, NULL, ok);
1298       }
1299       break;
1300     case Token::ASYNC:
1301       if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION &&
1302           !scanner()->HasAnyLineTerminatorAfterNext()) {
1303         Consume(Token::ASYNC);
1304         return ParseAsyncFunctionDeclaration(NULL, ok);
1305       }
1306     /* falls through */
1307     default:
1308       break;
1309   }
1310   return ParseStatement(NULL, kAllowLabelledFunctionStatement, ok);
1311 }
1312 
1313 
ParseModuleItem(bool * ok)1314 Statement* Parser::ParseModuleItem(bool* ok) {
1315   // (Ecma 262 6th Edition, 15.2):
1316   // ModuleItem :
1317   //    ImportDeclaration
1318   //    ExportDeclaration
1319   //    StatementListItem
1320 
1321   switch (peek()) {
1322     case Token::IMPORT:
1323       return ParseImportDeclaration(ok);
1324     case Token::EXPORT:
1325       return ParseExportDeclaration(ok);
1326     default:
1327       return ParseStatementListItem(ok);
1328   }
1329 }
1330 
1331 
ParseModuleItemList(ZoneList<Statement * > * body,bool * ok)1332 void* Parser::ParseModuleItemList(ZoneList<Statement*>* body, bool* ok) {
1333   // (Ecma 262 6th Edition, 15.2):
1334   // Module :
1335   //    ModuleBody?
1336   //
1337   // ModuleBody :
1338   //    ModuleItem*
1339 
1340   DCHECK(scope_->is_module_scope());
1341 
1342   while (peek() != Token::EOS) {
1343     Statement* stat = ParseModuleItem(CHECK_OK);
1344     if (stat && !stat->IsEmpty()) {
1345       body->Add(stat, zone());
1346     }
1347   }
1348 
1349   // Check that all exports are bound.
1350   ModuleDescriptor* descriptor = scope_->module();
1351   for (ModuleDescriptor::Iterator it = descriptor->iterator(); !it.done();
1352        it.Advance()) {
1353     if (scope_->LookupLocal(it.local_name()) == NULL) {
1354       // TODO(adamk): Pass both local_name and export_name once ParserTraits
1355       // supports multiple arg error messages.
1356       // Also try to report this at a better location.
1357       ParserTraits::ReportMessage(MessageTemplate::kModuleExportUndefined,
1358                                   it.local_name());
1359       *ok = false;
1360       return NULL;
1361     }
1362   }
1363 
1364   return NULL;
1365 }
1366 
1367 
ParseModuleSpecifier(bool * ok)1368 const AstRawString* Parser::ParseModuleSpecifier(bool* ok) {
1369   // ModuleSpecifier :
1370   //    StringLiteral
1371 
1372   Expect(Token::STRING, CHECK_OK);
1373   return GetSymbol(scanner());
1374 }
1375 
1376 
ParseExportClause(ZoneList<const AstRawString * > * export_names,ZoneList<Scanner::Location> * export_locations,ZoneList<const AstRawString * > * local_names,Scanner::Location * reserved_loc,bool * ok)1377 void* Parser::ParseExportClause(ZoneList<const AstRawString*>* export_names,
1378                                 ZoneList<Scanner::Location>* export_locations,
1379                                 ZoneList<const AstRawString*>* local_names,
1380                                 Scanner::Location* reserved_loc, bool* ok) {
1381   // ExportClause :
1382   //   '{' '}'
1383   //   '{' ExportsList '}'
1384   //   '{' ExportsList ',' '}'
1385   //
1386   // ExportsList :
1387   //   ExportSpecifier
1388   //   ExportsList ',' ExportSpecifier
1389   //
1390   // ExportSpecifier :
1391   //   IdentifierName
1392   //   IdentifierName 'as' IdentifierName
1393 
1394   Expect(Token::LBRACE, CHECK_OK);
1395 
1396   Token::Value name_tok;
1397   while ((name_tok = peek()) != Token::RBRACE) {
1398     // Keep track of the first reserved word encountered in case our
1399     // caller needs to report an error.
1400     if (!reserved_loc->IsValid() &&
1401         !Token::IsIdentifier(name_tok, STRICT, false, parsing_module_)) {
1402       *reserved_loc = scanner()->location();
1403     }
1404     const AstRawString* local_name = ParseIdentifierName(CHECK_OK);
1405     const AstRawString* export_name = NULL;
1406     if (CheckContextualKeyword(CStrVector("as"))) {
1407       export_name = ParseIdentifierName(CHECK_OK);
1408     }
1409     if (export_name == NULL) {
1410       export_name = local_name;
1411     }
1412     export_names->Add(export_name, zone());
1413     local_names->Add(local_name, zone());
1414     export_locations->Add(scanner()->location(), zone());
1415     if (peek() == Token::RBRACE) break;
1416     Expect(Token::COMMA, CHECK_OK);
1417   }
1418 
1419   Expect(Token::RBRACE, CHECK_OK);
1420 
1421   return 0;
1422 }
1423 
1424 
ParseNamedImports(int pos,bool * ok)1425 ZoneList<ImportDeclaration*>* Parser::ParseNamedImports(int pos, bool* ok) {
1426   // NamedImports :
1427   //   '{' '}'
1428   //   '{' ImportsList '}'
1429   //   '{' ImportsList ',' '}'
1430   //
1431   // ImportsList :
1432   //   ImportSpecifier
1433   //   ImportsList ',' ImportSpecifier
1434   //
1435   // ImportSpecifier :
1436   //   BindingIdentifier
1437   //   IdentifierName 'as' BindingIdentifier
1438 
1439   Expect(Token::LBRACE, CHECK_OK);
1440 
1441   ZoneList<ImportDeclaration*>* result =
1442       new (zone()) ZoneList<ImportDeclaration*>(1, zone());
1443   while (peek() != Token::RBRACE) {
1444     const AstRawString* import_name = ParseIdentifierName(CHECK_OK);
1445     const AstRawString* local_name = import_name;
1446     // In the presence of 'as', the left-side of the 'as' can
1447     // be any IdentifierName. But without 'as', it must be a valid
1448     // BindingIdentifier.
1449     if (CheckContextualKeyword(CStrVector("as"))) {
1450       local_name = ParseIdentifierName(CHECK_OK);
1451     }
1452     if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false,
1453                              parsing_module_)) {
1454       *ok = false;
1455       ReportMessage(MessageTemplate::kUnexpectedReserved);
1456       return NULL;
1457     } else if (IsEvalOrArguments(local_name)) {
1458       *ok = false;
1459       ReportMessage(MessageTemplate::kStrictEvalArguments);
1460       return NULL;
1461     }
1462     VariableProxy* proxy = NewUnresolved(local_name, CONST);
1463     ImportDeclaration* declaration =
1464         factory()->NewImportDeclaration(proxy, import_name, NULL, scope_, pos);
1465     Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
1466     result->Add(declaration, zone());
1467     if (peek() == Token::RBRACE) break;
1468     Expect(Token::COMMA, CHECK_OK);
1469   }
1470 
1471   Expect(Token::RBRACE, CHECK_OK);
1472 
1473   return result;
1474 }
1475 
1476 
ParseImportDeclaration(bool * ok)1477 Statement* Parser::ParseImportDeclaration(bool* ok) {
1478   // ImportDeclaration :
1479   //   'import' ImportClause 'from' ModuleSpecifier ';'
1480   //   'import' ModuleSpecifier ';'
1481   //
1482   // ImportClause :
1483   //   NameSpaceImport
1484   //   NamedImports
1485   //   ImportedDefaultBinding
1486   //   ImportedDefaultBinding ',' NameSpaceImport
1487   //   ImportedDefaultBinding ',' NamedImports
1488   //
1489   // NameSpaceImport :
1490   //   '*' 'as' ImportedBinding
1491 
1492   int pos = peek_position();
1493   Expect(Token::IMPORT, CHECK_OK);
1494 
1495   Token::Value tok = peek();
1496 
1497   // 'import' ModuleSpecifier ';'
1498   if (tok == Token::STRING) {
1499     const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1500     scope_->module()->AddModuleRequest(module_specifier, zone());
1501     ExpectSemicolon(CHECK_OK);
1502     return factory()->NewEmptyStatement(pos);
1503   }
1504 
1505   // Parse ImportedDefaultBinding if present.
1506   ImportDeclaration* import_default_declaration = NULL;
1507   if (tok != Token::MUL && tok != Token::LBRACE) {
1508     const AstRawString* local_name =
1509         ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
1510     VariableProxy* proxy = NewUnresolved(local_name, CONST);
1511     import_default_declaration = factory()->NewImportDeclaration(
1512         proxy, ast_value_factory()->default_string(), NULL, scope_, pos);
1513     Declare(import_default_declaration, DeclarationDescriptor::NORMAL, true,
1514             CHECK_OK);
1515   }
1516 
1517   const AstRawString* module_instance_binding = NULL;
1518   ZoneList<ImportDeclaration*>* named_declarations = NULL;
1519   if (import_default_declaration == NULL || Check(Token::COMMA)) {
1520     switch (peek()) {
1521       case Token::MUL: {
1522         Consume(Token::MUL);
1523         ExpectContextualKeyword(CStrVector("as"), CHECK_OK);
1524         module_instance_binding =
1525             ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
1526         // TODO(ES6): Add an appropriate declaration.
1527         break;
1528       }
1529 
1530       case Token::LBRACE:
1531         named_declarations = ParseNamedImports(pos, CHECK_OK);
1532         break;
1533 
1534       default:
1535         *ok = false;
1536         ReportUnexpectedToken(scanner()->current_token());
1537         return NULL;
1538     }
1539   }
1540 
1541   ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1542   const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1543   scope_->module()->AddModuleRequest(module_specifier, zone());
1544 
1545   if (module_instance_binding != NULL) {
1546     // TODO(ES6): Set the module specifier for the module namespace binding.
1547   }
1548 
1549   if (import_default_declaration != NULL) {
1550     import_default_declaration->set_module_specifier(module_specifier);
1551   }
1552 
1553   if (named_declarations != NULL) {
1554     for (int i = 0; i < named_declarations->length(); ++i) {
1555       named_declarations->at(i)->set_module_specifier(module_specifier);
1556     }
1557   }
1558 
1559   ExpectSemicolon(CHECK_OK);
1560   return factory()->NewEmptyStatement(pos);
1561 }
1562 
1563 
ParseExportDefault(bool * ok)1564 Statement* Parser::ParseExportDefault(bool* ok) {
1565   //  Supports the following productions, starting after the 'default' token:
1566   //    'export' 'default' FunctionDeclaration
1567   //    'export' 'default' ClassDeclaration
1568   //    'export' 'default' AssignmentExpression[In] ';'
1569 
1570   Expect(Token::DEFAULT, CHECK_OK);
1571   Scanner::Location default_loc = scanner()->location();
1572 
1573   const AstRawString* default_string = ast_value_factory()->default_string();
1574   ZoneList<const AstRawString*> names(1, zone());
1575   Statement* result = nullptr;
1576   Expression* default_export = nullptr;
1577   switch (peek()) {
1578     case Token::FUNCTION: {
1579       Consume(Token::FUNCTION);
1580       int pos = position();
1581       bool is_generator = Check(Token::MUL);
1582       if (peek() == Token::LPAREN) {
1583         // FunctionDeclaration[+Default] ::
1584         //   'function' '(' FormalParameters ')' '{' FunctionBody '}'
1585         //
1586         // GeneratorDeclaration[+Default] ::
1587         //   'function' '*' '(' FormalParameters ')' '{' FunctionBody '}'
1588         default_export = ParseFunctionLiteral(
1589             default_string, Scanner::Location::invalid(),
1590             kSkipFunctionNameCheck,
1591             is_generator ? FunctionKind::kGeneratorFunction
1592                          : FunctionKind::kNormalFunction,
1593             pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK);
1594         result = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1595       } else {
1596         result = ParseHoistableDeclaration(
1597             pos, is_generator ? ParseFunctionFlags::kIsGenerator
1598                               : ParseFunctionFlags::kIsNormal,
1599             &names, CHECK_OK);
1600       }
1601       break;
1602     }
1603 
1604     case Token::CLASS:
1605       Consume(Token::CLASS);
1606       if (peek() == Token::EXTENDS || peek() == Token::LBRACE) {
1607         // ClassDeclaration[+Default] ::
1608         //   'class' ('extends' LeftHandExpression)? '{' ClassBody '}'
1609         default_export = ParseClassLiteral(nullptr, default_string,
1610                                            Scanner::Location::invalid(), false,
1611                                            position(), CHECK_OK);
1612         result = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1613       } else {
1614         result = ParseClassDeclaration(&names, CHECK_OK);
1615       }
1616       break;
1617 
1618     case Token::ASYNC:
1619       if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION &&
1620           !scanner()->HasAnyLineTerminatorAfterNext()) {
1621         Consume(Token::ASYNC);
1622         Consume(Token::FUNCTION);
1623         int pos = position();
1624         if (peek() == Token::LPAREN) {
1625           // AsyncFunctionDeclaration[+Default] ::
1626           //   async [no LineTerminator here] function ( FormalParameters ) {
1627           //      AsyncFunctionBody
1628           //   }
1629           default_export = ParseFunctionLiteral(
1630               default_string, Scanner::Location::invalid(),
1631               kSkipFunctionNameCheck, FunctionKind::kAsyncFunction, pos,
1632               FunctionLiteral::kDeclaration, language_mode(), CHECK_OK);
1633           result = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1634         } else {
1635           result = ParseHoistableDeclaration(pos, ParseFunctionFlags::kIsAsync,
1636                                              &names, CHECK_OK);
1637         }
1638         break;
1639       }
1640     /* falls through */
1641 
1642     default: {
1643       int pos = peek_position();
1644       ExpressionClassifier classifier(this);
1645       Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK);
1646       RewriteNonPattern(&classifier, CHECK_OK);
1647 
1648       ExpectSemicolon(CHECK_OK);
1649       result = factory()->NewExpressionStatement(expr, pos);
1650       break;
1651     }
1652   }
1653 
1654   DCHECK_LE(names.length(), 1);
1655   if (names.length() == 1) {
1656     scope_->module()->AddLocalExport(default_string, names.first(), zone(), ok);
1657     if (!*ok) {
1658       ParserTraits::ReportMessageAt(
1659           default_loc, MessageTemplate::kDuplicateExport, default_string);
1660       return nullptr;
1661     }
1662   } else {
1663     // TODO(ES6): Assign result to a const binding with the name "*default*"
1664     // and add an export entry with "*default*" as the local name.
1665     USE(default_export);
1666   }
1667 
1668   return result;
1669 }
1670 
1671 
ParseExportDeclaration(bool * ok)1672 Statement* Parser::ParseExportDeclaration(bool* ok) {
1673   // ExportDeclaration:
1674   //    'export' '*' 'from' ModuleSpecifier ';'
1675   //    'export' ExportClause ('from' ModuleSpecifier)? ';'
1676   //    'export' VariableStatement
1677   //    'export' Declaration
1678   //    'export' 'default' ... (handled in ParseExportDefault)
1679 
1680   int pos = peek_position();
1681   Expect(Token::EXPORT, CHECK_OK);
1682 
1683   Statement* result = NULL;
1684   ZoneList<const AstRawString*> names(1, zone());
1685   switch (peek()) {
1686     case Token::DEFAULT:
1687       return ParseExportDefault(ok);
1688 
1689     case Token::MUL: {
1690       Consume(Token::MUL);
1691       ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1692       const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1693       scope_->module()->AddModuleRequest(module_specifier, zone());
1694       // TODO(ES6): scope_->module()->AddStarExport(...)
1695       ExpectSemicolon(CHECK_OK);
1696       return factory()->NewEmptyStatement(pos);
1697     }
1698 
1699     case Token::LBRACE: {
1700       // There are two cases here:
1701       //
1702       // 'export' ExportClause ';'
1703       // and
1704       // 'export' ExportClause FromClause ';'
1705       //
1706       // In the first case, the exported identifiers in ExportClause must
1707       // not be reserved words, while in the latter they may be. We
1708       // pass in a location that gets filled with the first reserved word
1709       // encountered, and then throw a SyntaxError if we are in the
1710       // non-FromClause case.
1711       Scanner::Location reserved_loc = Scanner::Location::invalid();
1712       ZoneList<const AstRawString*> export_names(1, zone());
1713       ZoneList<Scanner::Location> export_locations(1, zone());
1714       ZoneList<const AstRawString*> local_names(1, zone());
1715       ParseExportClause(&export_names, &export_locations, &local_names,
1716                         &reserved_loc, CHECK_OK);
1717       const AstRawString* indirect_export_module_specifier = NULL;
1718       if (CheckContextualKeyword(CStrVector("from"))) {
1719         indirect_export_module_specifier = ParseModuleSpecifier(CHECK_OK);
1720       } else if (reserved_loc.IsValid()) {
1721         // No FromClause, so reserved words are invalid in ExportClause.
1722         *ok = false;
1723         ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved);
1724         return NULL;
1725       }
1726       ExpectSemicolon(CHECK_OK);
1727       const int length = export_names.length();
1728       DCHECK_EQ(length, local_names.length());
1729       DCHECK_EQ(length, export_locations.length());
1730       if (indirect_export_module_specifier == NULL) {
1731         for (int i = 0; i < length; ++i) {
1732           scope_->module()->AddLocalExport(export_names[i], local_names[i],
1733                                            zone(), ok);
1734           if (!*ok) {
1735             ParserTraits::ReportMessageAt(export_locations[i],
1736                                           MessageTemplate::kDuplicateExport,
1737                                           export_names[i]);
1738             return NULL;
1739           }
1740         }
1741       } else {
1742         scope_->module()->AddModuleRequest(indirect_export_module_specifier,
1743                                            zone());
1744         for (int i = 0; i < length; ++i) {
1745           // TODO(ES6): scope_->module()->AddIndirectExport(...);(
1746         }
1747       }
1748       return factory()->NewEmptyStatement(pos);
1749     }
1750 
1751     case Token::FUNCTION:
1752       result = ParseHoistableDeclaration(&names, CHECK_OK);
1753       break;
1754 
1755     case Token::CLASS:
1756       Consume(Token::CLASS);
1757       result = ParseClassDeclaration(&names, CHECK_OK);
1758       break;
1759 
1760     case Token::VAR:
1761     case Token::LET:
1762     case Token::CONST:
1763       result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK);
1764       break;
1765 
1766     case Token::ASYNC:
1767       if (allow_harmony_async_await()) {
1768         Consume(Token::ASYNC);
1769         result = ParseAsyncFunctionDeclaration(&names, CHECK_OK);
1770         break;
1771       }
1772     /* falls through */
1773 
1774     default:
1775       *ok = false;
1776       ReportUnexpectedToken(scanner()->current_token());
1777       return NULL;
1778   }
1779 
1780   // Extract declared names into export declarations.
1781   ModuleDescriptor* descriptor = scope_->module();
1782   for (int i = 0; i < names.length(); ++i) {
1783     descriptor->AddLocalExport(names[i], names[i], zone(), ok);
1784     if (!*ok) {
1785       // TODO(adamk): Possibly report this error at the right place.
1786       ParserTraits::ReportMessage(MessageTemplate::kDuplicateExport, names[i]);
1787       return NULL;
1788     }
1789   }
1790 
1791   DCHECK_NOT_NULL(result);
1792   return result;
1793 }
1794 
ParseStatement(ZoneList<const AstRawString * > * labels,AllowLabelledFunctionStatement allow_function,bool * ok)1795 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels,
1796                                   AllowLabelledFunctionStatement allow_function,
1797                                   bool* ok) {
1798   // Statement ::
1799   //   EmptyStatement
1800   //   ...
1801 
1802   if (peek() == Token::SEMICOLON) {
1803     Next();
1804     return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1805   }
1806   return ParseSubStatement(labels, allow_function, ok);
1807 }
1808 
ParseSubStatement(ZoneList<const AstRawString * > * labels,AllowLabelledFunctionStatement allow_function,bool * ok)1809 Statement* Parser::ParseSubStatement(
1810     ZoneList<const AstRawString*>* labels,
1811     AllowLabelledFunctionStatement allow_function, bool* ok) {
1812   // Statement ::
1813   //   Block
1814   //   VariableStatement
1815   //   EmptyStatement
1816   //   ExpressionStatement
1817   //   IfStatement
1818   //   IterationStatement
1819   //   ContinueStatement
1820   //   BreakStatement
1821   //   ReturnStatement
1822   //   WithStatement
1823   //   LabelledStatement
1824   //   SwitchStatement
1825   //   ThrowStatement
1826   //   TryStatement
1827   //   DebuggerStatement
1828 
1829   // Note: Since labels can only be used by 'break' and 'continue'
1830   // statements, which themselves are only valid within blocks,
1831   // iterations or 'switch' statements (i.e., BreakableStatements),
1832   // labels can be simply ignored in all other cases; except for
1833   // trivial labeled break statements 'label: break label' which is
1834   // parsed into an empty statement.
1835   switch (peek()) {
1836     case Token::LBRACE:
1837       return ParseBlock(labels, ok);
1838 
1839     case Token::SEMICOLON:
1840       Next();
1841       return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1842 
1843     case Token::IF:
1844       return ParseIfStatement(labels, ok);
1845 
1846     case Token::DO:
1847       return ParseDoWhileStatement(labels, ok);
1848 
1849     case Token::WHILE:
1850       return ParseWhileStatement(labels, ok);
1851 
1852     case Token::FOR:
1853       return ParseForStatement(labels, ok);
1854 
1855     case Token::CONTINUE:
1856     case Token::BREAK:
1857     case Token::RETURN:
1858     case Token::THROW:
1859     case Token::TRY: {
1860       // These statements must have their labels preserved in an enclosing
1861       // block
1862       if (labels == NULL) {
1863         return ParseStatementAsUnlabelled(labels, ok);
1864       } else {
1865         Block* result =
1866             factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition);
1867         Target target(&this->target_stack_, result);
1868         Statement* statement = ParseStatementAsUnlabelled(labels, CHECK_OK);
1869         if (result) result->statements()->Add(statement, zone());
1870         return result;
1871       }
1872     }
1873 
1874     case Token::WITH:
1875       return ParseWithStatement(labels, ok);
1876 
1877     case Token::SWITCH:
1878       return ParseSwitchStatement(labels, ok);
1879 
1880     case Token::FUNCTION:
1881       // FunctionDeclaration only allowed as a StatementListItem, not in
1882       // an arbitrary Statement position. Exceptions such as
1883       // ES#sec-functiondeclarations-in-ifstatement-statement-clauses
1884       // are handled by calling ParseScopedStatement rather than
1885       // ParseSubStatement directly.
1886       ReportMessageAt(scanner()->peek_location(),
1887                       is_strict(language_mode())
1888                           ? MessageTemplate::kStrictFunction
1889                           : MessageTemplate::kSloppyFunction);
1890       *ok = false;
1891       return nullptr;
1892 
1893     case Token::DEBUGGER:
1894       return ParseDebuggerStatement(ok);
1895 
1896     case Token::VAR:
1897       return ParseVariableStatement(kStatement, NULL, ok);
1898 
1899     default:
1900       return ParseExpressionOrLabelledStatement(labels, allow_function, ok);
1901   }
1902 }
1903 
ParseStatementAsUnlabelled(ZoneList<const AstRawString * > * labels,bool * ok)1904 Statement* Parser::ParseStatementAsUnlabelled(
1905     ZoneList<const AstRawString*>* labels, bool* ok) {
1906   switch (peek()) {
1907     case Token::CONTINUE:
1908       return ParseContinueStatement(ok);
1909 
1910     case Token::BREAK:
1911       return ParseBreakStatement(labels, ok);
1912 
1913     case Token::RETURN:
1914       return ParseReturnStatement(ok);
1915 
1916     case Token::THROW:
1917       return ParseThrowStatement(ok);
1918 
1919     case Token::TRY:
1920       return ParseTryStatement(ok);
1921 
1922     default:
1923       UNREACHABLE();
1924       return NULL;
1925   }
1926 }
1927 
1928 
NewUnresolved(const AstRawString * name,VariableMode mode)1929 VariableProxy* Parser::NewUnresolved(const AstRawString* name,
1930                                      VariableMode mode) {
1931   // If we are inside a function, a declaration of a var/const variable is a
1932   // truly local variable, and the scope of the variable is always the function
1933   // scope.
1934   // Let/const variables in harmony mode are always added to the immediately
1935   // enclosing scope.
1936   Scope* scope =
1937       IsLexicalVariableMode(mode) ? scope_ : scope_->DeclarationScope();
1938   return scope->NewUnresolved(factory(), name, Variable::NORMAL,
1939                               scanner()->location().beg_pos,
1940                               scanner()->location().end_pos);
1941 }
1942 
1943 
Declare(Declaration * declaration,DeclarationDescriptor::Kind declaration_kind,bool resolve,bool * ok,Scope * scope)1944 Variable* Parser::Declare(Declaration* declaration,
1945                           DeclarationDescriptor::Kind declaration_kind,
1946                           bool resolve, bool* ok, Scope* scope) {
1947   VariableProxy* proxy = declaration->proxy();
1948   DCHECK(proxy->raw_name() != NULL);
1949   const AstRawString* name = proxy->raw_name();
1950   VariableMode mode = declaration->mode();
1951   DCHECK(IsDeclaredVariableMode(mode) && mode != CONST_LEGACY);
1952   bool is_function_declaration = declaration->IsFunctionDeclaration();
1953   if (scope == nullptr) scope = scope_;
1954   Scope* declaration_scope =
1955       IsLexicalVariableMode(mode) ? scope : scope->DeclarationScope();
1956   Variable* var = NULL;
1957 
1958   // If a suitable scope exists, then we can statically declare this
1959   // variable and also set its mode. In any case, a Declaration node
1960   // will be added to the scope so that the declaration can be added
1961   // to the corresponding activation frame at runtime if necessary.
1962   // For instance, var declarations inside a sloppy eval scope need
1963   // to be added to the calling function context. Similarly, strict
1964   // mode eval scope and lexical eval bindings do not leak variable
1965   // declarations to the caller's scope so we declare all locals, too.
1966   if (declaration_scope->is_function_scope() ||
1967       declaration_scope->is_block_scope() ||
1968       declaration_scope->is_module_scope() ||
1969       declaration_scope->is_script_scope() ||
1970       (declaration_scope->is_eval_scope() &&
1971        (is_strict(declaration_scope->language_mode()) ||
1972         IsLexicalVariableMode(mode)))) {
1973     // Declare the variable in the declaration scope.
1974     var = declaration_scope->LookupLocal(name);
1975     if (var == NULL) {
1976       // Declare the name.
1977       Variable::Kind kind = Variable::NORMAL;
1978       if (is_function_declaration) {
1979         kind = Variable::FUNCTION;
1980       }
1981       var = declaration_scope->DeclareLocal(
1982           name, mode, declaration->initialization(), kind, kNotAssigned);
1983     } else if (IsLexicalVariableMode(mode) ||
1984                IsLexicalVariableMode(var->mode())) {
1985       // Allow duplicate function decls for web compat, see bug 4693.
1986       bool duplicate_allowed = false;
1987       if (is_sloppy(language_mode()) && is_function_declaration &&
1988           var->is_function()) {
1989         DCHECK(IsLexicalVariableMode(mode) &&
1990                IsLexicalVariableMode(var->mode()));
1991         // If the duplication is allowed, then the var will show up
1992         // in the SloppyBlockFunctionMap and the new FunctionKind
1993         // will be a permitted duplicate.
1994         FunctionKind function_kind =
1995             declaration->AsFunctionDeclaration()->fun()->kind();
1996         duplicate_allowed =
1997             scope->DeclarationScope()->sloppy_block_function_map()->Lookup(
1998                 const_cast<AstRawString*>(name), name->hash()) != nullptr &&
1999             !IsAsyncFunction(function_kind) &&
2000             !(allow_harmony_restrictive_generators() &&
2001               IsGeneratorFunction(function_kind));
2002       }
2003       if (duplicate_allowed) {
2004         ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition];
2005       } else {
2006         // The name was declared in this scope before; check for conflicting
2007         // re-declarations. We have a conflict if either of the declarations
2008         // is not a var (in script scope, we also have to ignore legacy const
2009         // for compatibility). There is similar code in runtime.cc in the
2010         // Declare functions. The function CheckConflictingVarDeclarations
2011         // checks for var and let bindings from different scopes whereas this
2012         // is a check for conflicting declarations within the same scope. This
2013         // check also covers the special case
2014         //
2015         // function () { let x; { var x; } }
2016         //
2017         // because the var declaration is hoisted to the function scope where
2018         // 'x' is already bound.
2019         DCHECK(IsDeclaredVariableMode(var->mode()));
2020         // In harmony we treat re-declarations as early errors. See
2021         // ES5 16 for a definition of early errors.
2022         if (declaration_kind == DeclarationDescriptor::NORMAL) {
2023           ParserTraits::ReportMessage(MessageTemplate::kVarRedeclaration, name);
2024         } else {
2025           ParserTraits::ReportMessage(MessageTemplate::kParamDupe);
2026         }
2027         *ok = false;
2028         return nullptr;
2029       }
2030     } else if (mode == VAR) {
2031       var->set_maybe_assigned();
2032     }
2033   } else if (declaration_scope->is_eval_scope() &&
2034              is_sloppy(declaration_scope->language_mode()) &&
2035              !IsLexicalVariableMode(mode)) {
2036     // In a var binding in a sloppy direct eval, pollute the enclosing scope
2037     // with this new binding by doing the following:
2038     // The proxy is bound to a lookup variable to force a dynamic declaration
2039     // using the DeclareEvalVar or DeclareEvalFunction runtime functions.
2040     Variable::Kind kind = Variable::NORMAL;
2041     // TODO(sigurds) figure out if kNotAssigned is OK here
2042     var = new (zone()) Variable(declaration_scope, name, mode, kind,
2043                                 declaration->initialization(), kNotAssigned);
2044     var->AllocateTo(VariableLocation::LOOKUP, -1);
2045     resolve = true;
2046   }
2047 
2048 
2049   // We add a declaration node for every declaration. The compiler
2050   // will only generate code if necessary. In particular, declarations
2051   // for inner local variables that do not represent functions won't
2052   // result in any generated code.
2053   //
2054   // Note that we always add an unresolved proxy even if it's not
2055   // used, simply because we don't know in this method (w/o extra
2056   // parameters) if the proxy is needed or not. The proxy will be
2057   // bound during variable resolution time unless it was pre-bound
2058   // below.
2059   //
2060   // WARNING: This will lead to multiple declaration nodes for the
2061   // same variable if it is declared several times. This is not a
2062   // semantic issue as long as we keep the source order, but it may be
2063   // a performance issue since it may lead to repeated
2064   // DeclareEvalVar or DeclareEvalFunction calls.
2065   declaration_scope->AddDeclaration(declaration);
2066 
2067   // If requested and we have a local variable, bind the proxy to the variable
2068   // at parse-time. This is used for functions (and consts) declared inside
2069   // statements: the corresponding function (or const) variable must be in the
2070   // function scope and not a statement-local scope, e.g. as provided with a
2071   // 'with' statement:
2072   //
2073   //   with (obj) {
2074   //     function f() {}
2075   //   }
2076   //
2077   // which is translated into:
2078   //
2079   //   with (obj) {
2080   //     // in this case this is not: 'var f; f = function () {};'
2081   //     var f = function () {};
2082   //   }
2083   //
2084   // Note that if 'f' is accessed from inside the 'with' statement, it
2085   // will be allocated in the context (because we must be able to look
2086   // it up dynamically) but it will also be accessed statically, i.e.,
2087   // with a context slot index and a context chain length for this
2088   // initialization code. Thus, inside the 'with' statement, we need
2089   // both access to the static and the dynamic context chain; the
2090   // runtime needs to provide both.
2091   if (resolve && var != NULL) {
2092     proxy->BindTo(var);
2093   }
2094   return var;
2095 }
2096 
2097 
2098 // Language extension which is only enabled for source files loaded
2099 // through the API's extension mechanism.  A native function
2100 // declaration is resolved by looking up the function through a
2101 // callback provided by the extension.
ParseNativeDeclaration(bool * ok)2102 Statement* Parser::ParseNativeDeclaration(bool* ok) {
2103   int pos = peek_position();
2104   Expect(Token::FUNCTION, CHECK_OK);
2105   // Allow "eval" or "arguments" for backward compatibility.
2106   const AstRawString* name =
2107       ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2108   Expect(Token::LPAREN, CHECK_OK);
2109   bool done = (peek() == Token::RPAREN);
2110   while (!done) {
2111     ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2112     done = (peek() == Token::RPAREN);
2113     if (!done) {
2114       Expect(Token::COMMA, CHECK_OK);
2115     }
2116   }
2117   Expect(Token::RPAREN, CHECK_OK);
2118   Expect(Token::SEMICOLON, CHECK_OK);
2119 
2120   // Make sure that the function containing the native declaration
2121   // isn't lazily compiled. The extension structures are only
2122   // accessible while parsing the first time not when reparsing
2123   // because of lazy compilation.
2124   // TODO(adamk): Should this be ClosureScope()?
2125   scope_->DeclarationScope()->ForceEagerCompilation();
2126 
2127   // TODO(1240846): It's weird that native function declarations are
2128   // introduced dynamically when we meet their declarations, whereas
2129   // other functions are set up when entering the surrounding scope.
2130   VariableProxy* proxy = NewUnresolved(name, VAR);
2131   Declaration* declaration =
2132       factory()->NewVariableDeclaration(proxy, VAR, scope_, pos);
2133   Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
2134   NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral(
2135       name, extension_, RelocInfo::kNoPosition);
2136   return factory()->NewExpressionStatement(
2137       factory()->NewAssignment(Token::INIT, proxy, lit, RelocInfo::kNoPosition),
2138       pos);
2139 }
2140 
2141 
ParseHoistableDeclaration(ZoneList<const AstRawString * > * names,bool * ok)2142 Statement* Parser::ParseHoistableDeclaration(
2143     ZoneList<const AstRawString*>* names, bool* ok) {
2144   Expect(Token::FUNCTION, CHECK_OK);
2145   int pos = position();
2146   ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal;
2147   if (Check(Token::MUL)) {
2148     flags |= ParseFunctionFlags::kIsGenerator;
2149   }
2150   return ParseHoistableDeclaration(pos, flags, names, ok);
2151 }
2152 
ParseAsyncFunctionDeclaration(ZoneList<const AstRawString * > * names,bool * ok)2153 Statement* Parser::ParseAsyncFunctionDeclaration(
2154     ZoneList<const AstRawString*>* names, bool* ok) {
2155   DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
2156   int pos = position();
2157   if (scanner()->HasAnyLineTerminatorBeforeNext()) {
2158     *ok = false;
2159     ReportUnexpectedToken(scanner()->current_token());
2160     return nullptr;
2161   }
2162   Expect(Token::FUNCTION, CHECK_OK);
2163   ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync;
2164   return ParseHoistableDeclaration(pos, flags, names, ok);
2165 }
2166 
ParseHoistableDeclaration(int pos,ParseFunctionFlags flags,ZoneList<const AstRawString * > * names,bool * ok)2167 Statement* Parser::ParseHoistableDeclaration(
2168     int pos, ParseFunctionFlags flags, ZoneList<const AstRawString*>* names,
2169     bool* ok) {
2170   // FunctionDeclaration ::
2171   //   'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
2172   // GeneratorDeclaration ::
2173   //   'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
2174   //
2175   // 'function' and '*' (if present) have been consumed by the caller.
2176   const bool is_generator = flags & ParseFunctionFlags::kIsGenerator;
2177   const bool is_async = flags & ParseFunctionFlags::kIsAsync;
2178   DCHECK(!is_generator || !is_async);
2179 
2180   bool is_strict_reserved = false;
2181   const AstRawString* name = ParseIdentifierOrStrictReservedWord(
2182       &is_strict_reserved, CHECK_OK);
2183 
2184   if (V8_UNLIKELY(is_async_function() && this->IsAwait(name))) {
2185     ReportMessageAt(scanner()->location(),
2186                     MessageTemplate::kAwaitBindingIdentifier);
2187     *ok = false;
2188     return nullptr;
2189   }
2190 
2191   FuncNameInferrer::State fni_state(fni_);
2192   if (fni_ != NULL) fni_->PushEnclosingName(name);
2193   FunctionLiteral* fun = ParseFunctionLiteral(
2194       name, scanner()->location(),
2195       is_strict_reserved ? kFunctionNameIsStrictReserved
2196                          : kFunctionNameValidityUnknown,
2197       is_generator ? FunctionKind::kGeneratorFunction
2198                    : is_async ? FunctionKind::kAsyncFunction
2199                               : FunctionKind::kNormalFunction,
2200       pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK);
2201 
2202   // Even if we're not at the top-level of the global or a function
2203   // scope, we treat it as such and introduce the function with its
2204   // initial value upon entering the corresponding scope.
2205   // In ES6, a function behaves as a lexical binding, except in
2206   // a script scope, or the initial scope of eval or another function.
2207   VariableMode mode =
2208       (!scope_->is_declaration_scope() || scope_->is_module_scope()) ? LET
2209                                                                      : VAR;
2210   VariableProxy* proxy = NewUnresolved(name, mode);
2211   Declaration* declaration =
2212       factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
2213   Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
2214   if (names) names->Add(name, zone());
2215   EmptyStatement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
2216   // Async functions don't undergo sloppy mode block scoped hoisting, and don't
2217   // allow duplicates in a block. Both are represented by the
2218   // sloppy_block_function_map. Don't add them to the map for async functions.
2219   // Generators are also supposed to be prohibited; currently doing this behind
2220   // a flag and UseCounting violations to assess web compatibility.
2221   if (is_sloppy(language_mode()) && !scope_->is_declaration_scope() &&
2222       !is_async && !(allow_harmony_restrictive_generators() && is_generator)) {
2223     SloppyBlockFunctionStatement* delegate =
2224         factory()->NewSloppyBlockFunctionStatement(empty, scope_);
2225     scope_->DeclarationScope()->sloppy_block_function_map()->Declare(name,
2226                                                                      delegate);
2227     return delegate;
2228   }
2229   return empty;
2230 }
2231 
2232 
ParseClassDeclaration(ZoneList<const AstRawString * > * names,bool * ok)2233 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
2234                                          bool* ok) {
2235   // ClassDeclaration ::
2236   //   'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
2237   //
2238   // 'class' is expected to be consumed by the caller.
2239   //
2240   // A ClassDeclaration
2241   //
2242   //   class C { ... }
2243   //
2244   // has the same semantics as:
2245   //
2246   //   let C = class C { ... };
2247   //
2248   // so rewrite it as such.
2249 
2250   int pos = position();
2251   bool is_strict_reserved = false;
2252   const AstRawString* name =
2253       ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
2254   ClassLiteral* value = ParseClassLiteral(nullptr, name, scanner()->location(),
2255                                           is_strict_reserved, pos, CHECK_OK);
2256 
2257   VariableProxy* proxy = NewUnresolved(name, LET);
2258   Declaration* declaration =
2259       factory()->NewVariableDeclaration(proxy, LET, scope_, pos);
2260   Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
2261   proxy->var()->set_initializer_position(position());
2262   Assignment* assignment =
2263       factory()->NewAssignment(Token::INIT, proxy, value, pos);
2264   Statement* assignment_statement =
2265       factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
2266   if (names) names->Add(name, zone());
2267   return assignment_statement;
2268 }
2269 
2270 
ParseBlock(ZoneList<const AstRawString * > * labels,bool finalize_block_scope,bool * ok)2271 Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels,
2272                           bool finalize_block_scope, bool* ok) {
2273   // The harmony mode uses block elements instead of statements.
2274   //
2275   // Block ::
2276   //   '{' StatementList '}'
2277 
2278   // Construct block expecting 16 statements.
2279   Block* body =
2280       factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
2281   Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
2282 
2283   // Parse the statements and collect escaping labels.
2284   Expect(Token::LBRACE, CHECK_OK);
2285   block_scope->set_start_position(scanner()->location().beg_pos);
2286   { BlockState block_state(&scope_, block_scope);
2287     Target target(&this->target_stack_, body);
2288 
2289     while (peek() != Token::RBRACE) {
2290       Statement* stat = ParseStatementListItem(CHECK_OK);
2291       if (stat && !stat->IsEmpty()) {
2292         body->statements()->Add(stat, zone());
2293       }
2294     }
2295   }
2296   Expect(Token::RBRACE, CHECK_OK);
2297   block_scope->set_end_position(scanner()->location().end_pos);
2298   if (finalize_block_scope) {
2299     block_scope = block_scope->FinalizeBlockScope();
2300   }
2301   body->set_scope(block_scope);
2302   return body;
2303 }
2304 
2305 
ParseBlock(ZoneList<const AstRawString * > * labels,bool * ok)2306 Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) {
2307   return ParseBlock(labels, true, ok);
2308 }
2309 
2310 
BuildInitializationBlock(ZoneList<const AstRawString * > * names,bool * ok)2311 Block* Parser::DeclarationParsingResult::BuildInitializationBlock(
2312     ZoneList<const AstRawString*>* names, bool* ok) {
2313   Block* result = descriptor.parser->factory()->NewBlock(
2314       NULL, 1, true, descriptor.declaration_pos);
2315   for (auto declaration : declarations) {
2316     PatternRewriter::DeclareAndInitializeVariables(
2317         result, &descriptor, &declaration, names, CHECK_OK);
2318   }
2319   return result;
2320 }
2321 
2322 
ParseVariableStatement(VariableDeclarationContext var_context,ZoneList<const AstRawString * > * names,bool * ok)2323 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
2324                                       ZoneList<const AstRawString*>* names,
2325                                       bool* ok) {
2326   // VariableStatement ::
2327   //   VariableDeclarations ';'
2328 
2329   // The scope of a var/const declared variable anywhere inside a function
2330   // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
2331   // transform a source-level var/const declaration into a (Function)
2332   // Scope declaration, and rewrite the source-level initialization into an
2333   // assignment statement. We use a block to collect multiple assignments.
2334   //
2335   // We mark the block as initializer block because we don't want the
2336   // rewriter to add a '.result' assignment to such a block (to get compliant
2337   // behavior for code such as print(eval('var x = 7')), and for cosmetic
2338   // reasons when pretty-printing. Also, unless an assignment (initialization)
2339   // is inside an initializer block, it is ignored.
2340 
2341   DeclarationParsingResult parsing_result;
2342   Block* result =
2343       ParseVariableDeclarations(var_context, &parsing_result, names, CHECK_OK);
2344   ExpectSemicolon(CHECK_OK);
2345   return result;
2346 }
2347 
ParseVariableDeclarations(VariableDeclarationContext var_context,DeclarationParsingResult * parsing_result,ZoneList<const AstRawString * > * names,bool * ok)2348 Block* Parser::ParseVariableDeclarations(
2349     VariableDeclarationContext var_context,
2350     DeclarationParsingResult* parsing_result,
2351     ZoneList<const AstRawString*>* names, bool* ok) {
2352   // VariableDeclarations ::
2353   //   ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
2354   //
2355   // The ES6 Draft Rev3 specifies the following grammar for const declarations
2356   //
2357   // ConstDeclaration ::
2358   //   const ConstBinding (',' ConstBinding)* ';'
2359   // ConstBinding ::
2360   //   Identifier '=' AssignmentExpression
2361   //
2362   // TODO(ES6):
2363   // ConstBinding ::
2364   //   BindingPattern '=' AssignmentExpression
2365 
2366   parsing_result->descriptor.parser = this;
2367   parsing_result->descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
2368   parsing_result->descriptor.declaration_pos = peek_position();
2369   parsing_result->descriptor.initialization_pos = peek_position();
2370   parsing_result->descriptor.mode = VAR;
2371 
2372   Block* init_block = nullptr;
2373   if (var_context != kForStatement) {
2374     init_block = factory()->NewBlock(
2375         NULL, 1, true, parsing_result->descriptor.declaration_pos);
2376   }
2377 
2378   if (peek() == Token::VAR) {
2379     Consume(Token::VAR);
2380   } else if (peek() == Token::CONST) {
2381     Consume(Token::CONST);
2382     DCHECK(var_context != kStatement);
2383     parsing_result->descriptor.mode = CONST;
2384   } else if (peek() == Token::LET) {
2385     Consume(Token::LET);
2386     DCHECK(var_context != kStatement);
2387     parsing_result->descriptor.mode = LET;
2388   } else {
2389     UNREACHABLE();  // by current callers
2390   }
2391 
2392   parsing_result->descriptor.scope = scope_;
2393   parsing_result->descriptor.hoist_scope = nullptr;
2394 
2395 
2396   bool first_declaration = true;
2397   int bindings_start = peek_position();
2398   do {
2399     FuncNameInferrer::State fni_state(fni_);
2400 
2401     // Parse name.
2402     if (!first_declaration) Consume(Token::COMMA);
2403 
2404     Expression* pattern;
2405     int decl_pos = peek_position();
2406     {
2407       ExpressionClassifier pattern_classifier(this);
2408       pattern = ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
2409       ValidateBindingPattern(&pattern_classifier, CHECK_OK);
2410       if (IsLexicalVariableMode(parsing_result->descriptor.mode)) {
2411         ValidateLetPattern(&pattern_classifier, CHECK_OK);
2412       }
2413     }
2414 
2415     Scanner::Location variable_loc = scanner()->location();
2416     const AstRawString* single_name =
2417         pattern->IsVariableProxy() ? pattern->AsVariableProxy()->raw_name()
2418                                    : nullptr;
2419     if (single_name != nullptr) {
2420       if (fni_ != NULL) fni_->PushVariableName(single_name);
2421     }
2422 
2423     Expression* value = NULL;
2424     int initializer_position = RelocInfo::kNoPosition;
2425     if (Check(Token::ASSIGN)) {
2426       ExpressionClassifier classifier(this);
2427       value = ParseAssignmentExpression(var_context != kForStatement,
2428                                         &classifier, CHECK_OK);
2429       RewriteNonPattern(&classifier, CHECK_OK);
2430       variable_loc.end_pos = scanner()->location().end_pos;
2431 
2432       if (!parsing_result->first_initializer_loc.IsValid()) {
2433         parsing_result->first_initializer_loc = variable_loc;
2434       }
2435 
2436       // Don't infer if it is "a = function(){...}();"-like expression.
2437       if (single_name) {
2438         if (fni_ != NULL && value->AsCall() == NULL &&
2439             value->AsCallNew() == NULL) {
2440           fni_->Infer();
2441         } else {
2442           fni_->RemoveLastFunction();
2443         }
2444       }
2445 
2446       ParserTraits::SetFunctionNameFromIdentifierRef(value, pattern);
2447 
2448       // End position of the initializer is after the assignment expression.
2449       initializer_position = scanner()->location().end_pos;
2450     } else {
2451       // Initializers may be either required or implied unless this is a
2452       // for-in/of iteration variable.
2453       if (var_context != kForStatement || !PeekInOrOf()) {
2454         // ES6 'const' and binding patterns require initializers.
2455         if (parsing_result->descriptor.mode == CONST ||
2456             !pattern->IsVariableProxy()) {
2457           ParserTraits::ReportMessageAt(
2458               Scanner::Location(decl_pos, scanner()->location().end_pos),
2459               MessageTemplate::kDeclarationMissingInitializer,
2460               !pattern->IsVariableProxy() ? "destructuring" : "const");
2461           *ok = false;
2462           return nullptr;
2463         }
2464 
2465         // 'let x' initializes 'x' to undefined.
2466         if (parsing_result->descriptor.mode == LET) {
2467           value = GetLiteralUndefined(position());
2468         }
2469       }
2470 
2471       // End position of the initializer is after the variable.
2472       initializer_position = position();
2473     }
2474 
2475     DeclarationParsingResult::Declaration decl(pattern, initializer_position,
2476                                                value);
2477     if (var_context == kForStatement) {
2478       // Save the declaration for further handling in ParseForStatement.
2479       parsing_result->declarations.Add(decl);
2480     } else {
2481       // Immediately declare the variable otherwise. This avoids O(N^2)
2482       // behavior (where N is the number of variables in a single
2483       // declaration) in the PatternRewriter having to do with removing
2484       // and adding VariableProxies to the Scope (see bug 4699).
2485       DCHECK_NOT_NULL(init_block);
2486       PatternRewriter::DeclareAndInitializeVariables(
2487           init_block, &parsing_result->descriptor, &decl, names, CHECK_OK);
2488     }
2489     first_declaration = false;
2490   } while (peek() == Token::COMMA);
2491 
2492   parsing_result->bindings_loc =
2493       Scanner::Location(bindings_start, scanner()->location().end_pos);
2494 
2495   DCHECK(*ok);
2496   return init_block;
2497 }
2498 
2499 
ContainsLabel(ZoneList<const AstRawString * > * labels,const AstRawString * label)2500 static bool ContainsLabel(ZoneList<const AstRawString*>* labels,
2501                           const AstRawString* label) {
2502   DCHECK(label != NULL);
2503   if (labels != NULL) {
2504     for (int i = labels->length(); i-- > 0; ) {
2505       if (labels->at(i) == label) {
2506         return true;
2507       }
2508     }
2509   }
2510   return false;
2511 }
2512 
ParseFunctionDeclaration(bool * ok)2513 Statement* Parser::ParseFunctionDeclaration(bool* ok) {
2514   Consume(Token::FUNCTION);
2515   int pos = position();
2516   ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal;
2517   if (Check(Token::MUL)) {
2518     flags |= ParseFunctionFlags::kIsGenerator;
2519     if (allow_harmony_restrictive_declarations()) {
2520       ParserTraits::ReportMessageAt(scanner()->location(),
2521                                     MessageTemplate::kGeneratorInLegacyContext);
2522       *ok = false;
2523       return nullptr;
2524     }
2525   }
2526 
2527   return ParseHoistableDeclaration(pos, flags, nullptr, CHECK_OK);
2528 }
2529 
ParseExpressionOrLabelledStatement(ZoneList<const AstRawString * > * labels,AllowLabelledFunctionStatement allow_function,bool * ok)2530 Statement* Parser::ParseExpressionOrLabelledStatement(
2531     ZoneList<const AstRawString*>* labels,
2532     AllowLabelledFunctionStatement allow_function, bool* ok) {
2533   // ExpressionStatement | LabelledStatement ::
2534   //   Expression ';'
2535   //   Identifier ':' Statement
2536   //
2537   // ExpressionStatement[Yield] :
2538   //   [lookahead ∉ {{, function, class, let [}] Expression[In, ?Yield] ;
2539 
2540   int pos = peek_position();
2541 
2542   switch (peek()) {
2543     case Token::FUNCTION:
2544     case Token::LBRACE:
2545       UNREACHABLE();  // Always handled by the callers.
2546     case Token::CLASS:
2547       ReportUnexpectedToken(Next());
2548       *ok = false;
2549       return nullptr;
2550     default:
2551       break;
2552   }
2553 
2554   bool starts_with_idenfifier = peek_any_identifier();
2555   Expression* expr = ParseExpression(true, CHECK_OK);
2556   if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL &&
2557       expr->AsVariableProxy() != NULL &&
2558       !expr->AsVariableProxy()->is_this()) {
2559     // Expression is a single identifier, and not, e.g., a parenthesized
2560     // identifier.
2561     VariableProxy* var = expr->AsVariableProxy();
2562     const AstRawString* label = var->raw_name();
2563     // TODO(1240780): We don't check for redeclaration of labels
2564     // during preparsing since keeping track of the set of active
2565     // labels requires nontrivial changes to the way scopes are
2566     // structured.  However, these are probably changes we want to
2567     // make later anyway so we should go back and fix this then.
2568     if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
2569       ParserTraits::ReportMessage(MessageTemplate::kLabelRedeclaration, label);
2570       *ok = false;
2571       return NULL;
2572     }
2573     if (labels == NULL) {
2574       labels = new(zone()) ZoneList<const AstRawString*>(4, zone());
2575     }
2576     labels->Add(label, zone());
2577     // Remove the "ghost" variable that turned out to be a label
2578     // from the top scope. This way, we don't try to resolve it
2579     // during the scope processing.
2580     scope_->RemoveUnresolved(var);
2581     Expect(Token::COLON, CHECK_OK);
2582     // ES#sec-labelled-function-declarations Labelled Function Declarations
2583     if (peek() == Token::FUNCTION && is_sloppy(language_mode())) {
2584       if (allow_function == kAllowLabelledFunctionStatement) {
2585         return ParseFunctionDeclaration(ok);
2586       } else {
2587         return ParseScopedStatement(labels, true, ok);
2588       }
2589     }
2590     return ParseStatement(labels, kDisallowLabelledFunctionStatement, ok);
2591   }
2592 
2593   // If we have an extension, we allow a native function declaration.
2594   // A native function declaration starts with "native function" with
2595   // no line-terminator between the two words.
2596   if (extension_ != NULL && peek() == Token::FUNCTION &&
2597       !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL &&
2598       expr->AsVariableProxy() != NULL &&
2599       expr->AsVariableProxy()->raw_name() ==
2600           ast_value_factory()->native_string() &&
2601       !scanner()->literal_contains_escapes()) {
2602     return ParseNativeDeclaration(ok);
2603   }
2604 
2605   // Parsed expression statement, followed by semicolon.
2606   ExpectSemicolon(CHECK_OK);
2607   return factory()->NewExpressionStatement(expr, pos);
2608 }
2609 
2610 
ParseIfStatement(ZoneList<const AstRawString * > * labels,bool * ok)2611 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels,
2612                                       bool* ok) {
2613   // IfStatement ::
2614   //   'if' '(' Expression ')' Statement ('else' Statement)?
2615 
2616   int pos = peek_position();
2617   Expect(Token::IF, CHECK_OK);
2618   Expect(Token::LPAREN, CHECK_OK);
2619   Expression* condition = ParseExpression(true, CHECK_OK);
2620   Expect(Token::RPAREN, CHECK_OK);
2621   Statement* then_statement = ParseScopedStatement(labels, false, CHECK_OK);
2622   Statement* else_statement = NULL;
2623   if (peek() == Token::ELSE) {
2624     Next();
2625     else_statement = ParseScopedStatement(labels, false, CHECK_OK);
2626   } else {
2627     else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
2628   }
2629   return factory()->NewIfStatement(
2630       condition, then_statement, else_statement, pos);
2631 }
2632 
2633 
ParseContinueStatement(bool * ok)2634 Statement* Parser::ParseContinueStatement(bool* ok) {
2635   // ContinueStatement ::
2636   //   'continue' Identifier? ';'
2637 
2638   int pos = peek_position();
2639   Expect(Token::CONTINUE, CHECK_OK);
2640   const AstRawString* label = NULL;
2641   Token::Value tok = peek();
2642   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2643       tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2644     // ECMA allows "eval" or "arguments" as labels even in strict mode.
2645     label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2646   }
2647   IterationStatement* target = LookupContinueTarget(label, CHECK_OK);
2648   if (target == NULL) {
2649     // Illegal continue statement.
2650     MessageTemplate::Template message = MessageTemplate::kIllegalContinue;
2651     if (label != NULL) {
2652       message = MessageTemplate::kUnknownLabel;
2653     }
2654     ParserTraits::ReportMessage(message, label);
2655     *ok = false;
2656     return NULL;
2657   }
2658   ExpectSemicolon(CHECK_OK);
2659   return factory()->NewContinueStatement(target, pos);
2660 }
2661 
2662 
ParseBreakStatement(ZoneList<const AstRawString * > * labels,bool * ok)2663 Statement* Parser::ParseBreakStatement(ZoneList<const AstRawString*>* labels,
2664                                        bool* ok) {
2665   // BreakStatement ::
2666   //   'break' Identifier? ';'
2667 
2668   int pos = peek_position();
2669   Expect(Token::BREAK, CHECK_OK);
2670   const AstRawString* label = NULL;
2671   Token::Value tok = peek();
2672   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2673       tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2674     // ECMA allows "eval" or "arguments" as labels even in strict mode.
2675     label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2676   }
2677   // Parse labeled break statements that target themselves into
2678   // empty statements, e.g. 'l1: l2: l3: break l2;'
2679   if (label != NULL && ContainsLabel(labels, label)) {
2680     ExpectSemicolon(CHECK_OK);
2681     return factory()->NewEmptyStatement(pos);
2682   }
2683   BreakableStatement* target = NULL;
2684   target = LookupBreakTarget(label, CHECK_OK);
2685   if (target == NULL) {
2686     // Illegal break statement.
2687     MessageTemplate::Template message = MessageTemplate::kIllegalBreak;
2688     if (label != NULL) {
2689       message = MessageTemplate::kUnknownLabel;
2690     }
2691     ParserTraits::ReportMessage(message, label);
2692     *ok = false;
2693     return NULL;
2694   }
2695   ExpectSemicolon(CHECK_OK);
2696   return factory()->NewBreakStatement(target, pos);
2697 }
2698 
2699 
ParseReturnStatement(bool * ok)2700 Statement* Parser::ParseReturnStatement(bool* ok) {
2701   // ReturnStatement ::
2702   //   'return' Expression? ';'
2703 
2704   // Consume the return token. It is necessary to do that before
2705   // reporting any errors on it, because of the way errors are
2706   // reported (underlining).
2707   Expect(Token::RETURN, CHECK_OK);
2708   Scanner::Location loc = scanner()->location();
2709   function_state_->set_return_location(loc);
2710 
2711   Token::Value tok = peek();
2712   Statement* result;
2713   Expression* return_value;
2714   if (scanner()->HasAnyLineTerminatorBeforeNext() ||
2715       tok == Token::SEMICOLON ||
2716       tok == Token::RBRACE ||
2717       tok == Token::EOS) {
2718     if (IsSubclassConstructor(function_state_->kind())) {
2719       return_value = ThisExpression(scope_, factory(), loc.beg_pos);
2720     } else {
2721       return_value = GetLiteralUndefined(position());
2722     }
2723   } else {
2724     int pos = peek_position();
2725 
2726     if (IsSubclassConstructor(function_state_->kind())) {
2727       // Because of the return code rewriting that happens in case of a subclass
2728       // constructor we don't want to accept tail calls, therefore we don't set
2729       // ReturnExprScope to kInsideValidReturnStatement here.
2730       return_value = ParseExpression(true, CHECK_OK);
2731 
2732       // For subclass constructors we need to return this in case of undefined
2733       // return a Smi (transformed into an exception in the ConstructStub)
2734       // for a non object.
2735       //
2736       //   return expr;
2737       //
2738       // Is rewritten as:
2739       //
2740       //   return (temp = expr) === undefined ? this :
2741       //       %_IsJSReceiver(temp) ? temp : 1;
2742 
2743       // temp = expr
2744       Variable* temp = scope_->NewTemporary(
2745           ast_value_factory()->empty_string());
2746       Assignment* assign = factory()->NewAssignment(
2747           Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos);
2748 
2749       // %_IsJSReceiver(temp)
2750       ZoneList<Expression*>* is_spec_object_args =
2751           new (zone()) ZoneList<Expression*>(1, zone());
2752       is_spec_object_args->Add(factory()->NewVariableProxy(temp), zone());
2753       Expression* is_spec_object_call = factory()->NewCallRuntime(
2754           Runtime::kInlineIsJSReceiver, is_spec_object_args, pos);
2755 
2756       // %_IsJSReceiver(temp) ? temp : 1;
2757       Expression* is_object_conditional = factory()->NewConditional(
2758           is_spec_object_call, factory()->NewVariableProxy(temp),
2759           factory()->NewSmiLiteral(1, pos), pos);
2760 
2761       // temp === undefined
2762       Expression* is_undefined = factory()->NewCompareOperation(
2763           Token::EQ_STRICT, assign,
2764           factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), pos);
2765 
2766       // is_undefined ? this : is_object_conditional
2767       return_value = factory()->NewConditional(
2768           is_undefined, ThisExpression(scope_, factory(), pos),
2769           is_object_conditional, pos);
2770     } else {
2771       ReturnExprScope maybe_allow_tail_calls(
2772           function_state_, ReturnExprContext::kInsideValidReturnStatement);
2773       return_value = ParseExpression(true, CHECK_OK);
2774 
2775       if (allow_tailcalls() && !is_sloppy(language_mode()) && !is_resumable()) {
2776         // ES6 14.6.1 Static Semantics: IsInTailPosition
2777         function_state_->AddImplicitTailCallExpression(return_value);
2778       }
2779     }
2780   }
2781   ExpectSemicolon(CHECK_OK);
2782 
2783   if (is_generator()) {
2784     return_value = BuildIteratorResult(return_value, true);
2785   } else if (is_async_function()) {
2786     return_value = BuildPromiseResolve(return_value, return_value->position());
2787   }
2788 
2789   result = factory()->NewReturnStatement(return_value, loc.beg_pos);
2790 
2791   Scope* decl_scope = scope_->DeclarationScope();
2792   if (decl_scope->is_script_scope() || decl_scope->is_eval_scope()) {
2793     ReportMessageAt(loc, MessageTemplate::kIllegalReturn);
2794     *ok = false;
2795     return NULL;
2796   }
2797   return result;
2798 }
2799 
2800 
ParseWithStatement(ZoneList<const AstRawString * > * labels,bool * ok)2801 Statement* Parser::ParseWithStatement(ZoneList<const AstRawString*>* labels,
2802                                       bool* ok) {
2803   // WithStatement ::
2804   //   'with' '(' Expression ')' Statement
2805 
2806   Expect(Token::WITH, CHECK_OK);
2807   int pos = position();
2808 
2809   if (is_strict(language_mode())) {
2810     ReportMessage(MessageTemplate::kStrictWith);
2811     *ok = false;
2812     return NULL;
2813   }
2814 
2815   Expect(Token::LPAREN, CHECK_OK);
2816   Expression* expr = ParseExpression(true, CHECK_OK);
2817   Expect(Token::RPAREN, CHECK_OK);
2818 
2819   Scope* with_scope = NewScope(scope_, WITH_SCOPE);
2820   Statement* body;
2821   { BlockState block_state(&scope_, with_scope);
2822     with_scope->set_start_position(scanner()->peek_location().beg_pos);
2823     body = ParseScopedStatement(labels, true, CHECK_OK);
2824     with_scope->set_end_position(scanner()->location().end_pos);
2825   }
2826   return factory()->NewWithStatement(with_scope, expr, body, pos);
2827 }
2828 
2829 
ParseCaseClause(bool * default_seen_ptr,bool * ok)2830 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
2831   // CaseClause ::
2832   //   'case' Expression ':' StatementList
2833   //   'default' ':' StatementList
2834 
2835   Expression* label = NULL;  // NULL expression indicates default case
2836   if (peek() == Token::CASE) {
2837     Expect(Token::CASE, CHECK_OK);
2838     label = ParseExpression(true, CHECK_OK);
2839   } else {
2840     Expect(Token::DEFAULT, CHECK_OK);
2841     if (*default_seen_ptr) {
2842       ReportMessage(MessageTemplate::kMultipleDefaultsInSwitch);
2843       *ok = false;
2844       return NULL;
2845     }
2846     *default_seen_ptr = true;
2847   }
2848   Expect(Token::COLON, CHECK_OK);
2849   int pos = position();
2850   ZoneList<Statement*>* statements =
2851       new(zone()) ZoneList<Statement*>(5, zone());
2852   Statement* stat = NULL;
2853   while (peek() != Token::CASE &&
2854          peek() != Token::DEFAULT &&
2855          peek() != Token::RBRACE) {
2856     stat = ParseStatementListItem(CHECK_OK);
2857     statements->Add(stat, zone());
2858   }
2859   return factory()->NewCaseClause(label, statements, pos);
2860 }
2861 
2862 
ParseSwitchStatement(ZoneList<const AstRawString * > * labels,bool * ok)2863 Statement* Parser::ParseSwitchStatement(ZoneList<const AstRawString*>* labels,
2864                                         bool* ok) {
2865   // SwitchStatement ::
2866   //   'switch' '(' Expression ')' '{' CaseClause* '}'
2867   // In order to get the CaseClauses to execute in their own lexical scope,
2868   // but without requiring downstream code to have special scope handling
2869   // code for switch statements, desugar into blocks as follows:
2870   // {  // To group the statements--harmless to evaluate Expression in scope
2871   //   .tag_variable = Expression;
2872   //   {  // To give CaseClauses a scope
2873   //     switch (.tag_variable) { CaseClause* }
2874   //   }
2875   // }
2876 
2877   Block* switch_block =
2878       factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
2879   int switch_pos = peek_position();
2880 
2881   Expect(Token::SWITCH, CHECK_OK);
2882   Expect(Token::LPAREN, CHECK_OK);
2883   Expression* tag = ParseExpression(true, CHECK_OK);
2884   Expect(Token::RPAREN, CHECK_OK);
2885 
2886   Variable* tag_variable =
2887       scope_->NewTemporary(ast_value_factory()->dot_switch_tag_string());
2888   Assignment* tag_assign = factory()->NewAssignment(
2889       Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag,
2890       tag->position());
2891   Statement* tag_statement =
2892       factory()->NewExpressionStatement(tag_assign, RelocInfo::kNoPosition);
2893   switch_block->statements()->Add(tag_statement, zone());
2894 
2895   // make statement: undefined;
2896   // This is needed so the tag isn't returned as the value, in case the switch
2897   // statements don't have a value.
2898   switch_block->statements()->Add(
2899       factory()->NewExpressionStatement(
2900           factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
2901           RelocInfo::kNoPosition),
2902       zone());
2903 
2904   Block* cases_block =
2905       factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
2906   Scope* cases_scope = NewScope(scope_, BLOCK_SCOPE);
2907   cases_scope->SetNonlinear();
2908 
2909   SwitchStatement* switch_statement =
2910       factory()->NewSwitchStatement(labels, switch_pos);
2911 
2912   cases_scope->set_start_position(scanner()->location().beg_pos);
2913   {
2914     BlockState cases_block_state(&scope_, cases_scope);
2915     Target target(&this->target_stack_, switch_statement);
2916 
2917     Expression* tag_read = factory()->NewVariableProxy(tag_variable);
2918 
2919     bool default_seen = false;
2920     ZoneList<CaseClause*>* cases =
2921         new (zone()) ZoneList<CaseClause*>(4, zone());
2922     Expect(Token::LBRACE, CHECK_OK);
2923     while (peek() != Token::RBRACE) {
2924       CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK);
2925       cases->Add(clause, zone());
2926     }
2927     switch_statement->Initialize(tag_read, cases);
2928     cases_block->statements()->Add(switch_statement, zone());
2929   }
2930   Expect(Token::RBRACE, CHECK_OK);
2931 
2932   cases_scope->set_end_position(scanner()->location().end_pos);
2933   cases_scope = cases_scope->FinalizeBlockScope();
2934   cases_block->set_scope(cases_scope);
2935 
2936   switch_block->statements()->Add(cases_block, zone());
2937 
2938   return switch_block;
2939 }
2940 
2941 
ParseThrowStatement(bool * ok)2942 Statement* Parser::ParseThrowStatement(bool* ok) {
2943   // ThrowStatement ::
2944   //   'throw' Expression ';'
2945 
2946   Expect(Token::THROW, CHECK_OK);
2947   int pos = position();
2948   if (scanner()->HasAnyLineTerminatorBeforeNext()) {
2949     ReportMessage(MessageTemplate::kNewlineAfterThrow);
2950     *ok = false;
2951     return NULL;
2952   }
2953   Expression* exception = ParseExpression(true, CHECK_OK);
2954   ExpectSemicolon(CHECK_OK);
2955 
2956   return factory()->NewExpressionStatement(
2957       factory()->NewThrow(exception, pos), pos);
2958 }
2959 
2960 
ParseTryStatement(bool * ok)2961 TryStatement* Parser::ParseTryStatement(bool* ok) {
2962   // TryStatement ::
2963   //   'try' Block Catch
2964   //   'try' Block Finally
2965   //   'try' Block Catch Finally
2966   //
2967   // Catch ::
2968   //   'catch' '(' Identifier ')' Block
2969   //
2970   // Finally ::
2971   //   'finally' Block
2972 
2973   Expect(Token::TRY, CHECK_OK);
2974   int pos = position();
2975 
2976   Block* try_block;
2977   {
2978     ReturnExprScope no_tail_calls(function_state_,
2979                                   ReturnExprContext::kInsideTryBlock);
2980     try_block = ParseBlock(NULL, CHECK_OK);
2981   }
2982 
2983   Token::Value tok = peek();
2984   if (tok != Token::CATCH && tok != Token::FINALLY) {
2985     ReportMessage(MessageTemplate::kNoCatchOrFinally);
2986     *ok = false;
2987     return NULL;
2988   }
2989 
2990   Scope* catch_scope = NULL;
2991   Variable* catch_variable = NULL;
2992   Block* catch_block = NULL;
2993   TailCallExpressionList tail_call_expressions_in_catch_block(zone());
2994   if (tok == Token::CATCH) {
2995     Consume(Token::CATCH);
2996 
2997     Expect(Token::LPAREN, CHECK_OK);
2998     catch_scope = NewScope(scope_, CATCH_SCOPE);
2999     catch_scope->set_start_position(scanner()->location().beg_pos);
3000 
3001     {
3002       CollectExpressionsInTailPositionToListScope
3003           collect_tail_call_expressions_scope(
3004               function_state_, &tail_call_expressions_in_catch_block);
3005       BlockState block_state(&scope_, catch_scope);
3006 
3007       catch_block =
3008           factory()->NewBlock(nullptr, 16, false, RelocInfo::kNoPosition);
3009 
3010       // Create a block scope to hold any lexical declarations created
3011       // as part of destructuring the catch parameter.
3012       Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
3013       block_scope->set_start_position(scanner()->location().beg_pos);
3014       {
3015         BlockState block_state(&scope_, block_scope);
3016         Target target(&this->target_stack_, catch_block);
3017 
3018         ExpressionClassifier pattern_classifier(this);
3019         Expression* pattern =
3020             ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
3021         ValidateBindingPattern(&pattern_classifier, CHECK_OK);
3022 
3023         const AstRawString* name = ast_value_factory()->dot_catch_string();
3024         bool is_simple = pattern->IsVariableProxy();
3025         if (is_simple) {
3026           auto proxy = pattern->AsVariableProxy();
3027           scope_->RemoveUnresolved(proxy);
3028           name = proxy->raw_name();
3029         }
3030         catch_variable = catch_scope->DeclareLocal(
3031             name, VAR, kCreatedInitialized, Variable::NORMAL);
3032 
3033         Expect(Token::RPAREN, CHECK_OK);
3034 
3035         if (!is_simple) {
3036           DeclarationDescriptor descriptor;
3037           descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
3038           descriptor.parser = this;
3039           descriptor.scope = scope_;
3040           descriptor.hoist_scope = nullptr;
3041           descriptor.mode = LET;
3042           descriptor.declaration_pos = pattern->position();
3043           descriptor.initialization_pos = pattern->position();
3044 
3045           // Initializer position for variables declared by the pattern.
3046           const int initializer_position = position();
3047 
3048           DeclarationParsingResult::Declaration decl(
3049               pattern, initializer_position,
3050               factory()->NewVariableProxy(catch_variable));
3051 
3052           Block* init_block =
3053               factory()->NewBlock(nullptr, 8, true, RelocInfo::kNoPosition);
3054           PatternRewriter::DeclareAndInitializeVariables(
3055               init_block, &descriptor, &decl, nullptr, CHECK_OK);
3056           catch_block->statements()->Add(init_block, zone());
3057         }
3058 
3059         // TODO(adamk): This should call ParseBlock in order to properly
3060         // add an additional block scope for the catch body.
3061         Expect(Token::LBRACE, CHECK_OK);
3062         while (peek() != Token::RBRACE) {
3063           Statement* stat = ParseStatementListItem(CHECK_OK);
3064           if (stat && !stat->IsEmpty()) {
3065             catch_block->statements()->Add(stat, zone());
3066           }
3067         }
3068         Consume(Token::RBRACE);
3069       }
3070       block_scope->set_end_position(scanner()->location().end_pos);
3071       block_scope = block_scope->FinalizeBlockScope();
3072       catch_block->set_scope(block_scope);
3073     }
3074 
3075     catch_scope->set_end_position(scanner()->location().end_pos);
3076     tok = peek();
3077   }
3078 
3079   Block* finally_block = NULL;
3080   DCHECK(tok == Token::FINALLY || catch_block != NULL);
3081   if (tok == Token::FINALLY) {
3082     Consume(Token::FINALLY);
3083     finally_block = ParseBlock(NULL, CHECK_OK);
3084   }
3085 
3086   // Simplify the AST nodes by converting:
3087   //   'try B0 catch B1 finally B2'
3088   // to:
3089   //   'try { try B0 catch B1 } finally B2'
3090 
3091   if (catch_block != NULL && finally_block != NULL) {
3092     // If we have both, create an inner try/catch.
3093     DCHECK(catch_scope != NULL && catch_variable != NULL);
3094     TryCatchStatement* statement =
3095         factory()->NewTryCatchStatement(try_block, catch_scope, catch_variable,
3096                                         catch_block, RelocInfo::kNoPosition);
3097     try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
3098     try_block->statements()->Add(statement, zone());
3099     catch_block = NULL;  // Clear to indicate it's been handled.
3100   }
3101 
3102   TryStatement* result = NULL;
3103   if (catch_block != NULL) {
3104     // For a try-catch construct append return expressions from the catch block
3105     // to the list of return expressions.
3106     function_state_->tail_call_expressions().Append(
3107         tail_call_expressions_in_catch_block);
3108 
3109     DCHECK(finally_block == NULL);
3110     DCHECK(catch_scope != NULL && catch_variable != NULL);
3111     result = factory()->NewTryCatchStatement(try_block, catch_scope,
3112                                              catch_variable, catch_block, pos);
3113   } else {
3114     if (FLAG_harmony_explicit_tailcalls &&
3115         tail_call_expressions_in_catch_block.has_explicit_tail_calls()) {
3116       // TODO(ishell): update chapter number.
3117       // ES8 XX.YY.ZZ
3118       ReportMessageAt(tail_call_expressions_in_catch_block.location(),
3119                       MessageTemplate::kUnexpectedTailCallInCatchBlock);
3120       *ok = false;
3121       return NULL;
3122     }
3123     DCHECK(finally_block != NULL);
3124     result = factory()->NewTryFinallyStatement(try_block, finally_block, pos);
3125   }
3126 
3127   return result;
3128 }
3129 
3130 
ParseDoWhileStatement(ZoneList<const AstRawString * > * labels,bool * ok)3131 DoWhileStatement* Parser::ParseDoWhileStatement(
3132     ZoneList<const AstRawString*>* labels, bool* ok) {
3133   // DoStatement ::
3134   //   'do' Statement 'while' '(' Expression ')' ';'
3135 
3136   DoWhileStatement* loop =
3137       factory()->NewDoWhileStatement(labels, peek_position());
3138   Target target(&this->target_stack_, loop);
3139 
3140   Expect(Token::DO, CHECK_OK);
3141   Statement* body = ParseScopedStatement(NULL, true, CHECK_OK);
3142   Expect(Token::WHILE, CHECK_OK);
3143   Expect(Token::LPAREN, CHECK_OK);
3144 
3145   Expression* cond = ParseExpression(true, CHECK_OK);
3146   Expect(Token::RPAREN, CHECK_OK);
3147 
3148   // Allow do-statements to be terminated with and without
3149   // semi-colons. This allows code such as 'do;while(0)return' to
3150   // parse, which would not be the case if we had used the
3151   // ExpectSemicolon() functionality here.
3152   if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
3153 
3154   if (loop != NULL) loop->Initialize(cond, body);
3155   return loop;
3156 }
3157 
3158 
ParseWhileStatement(ZoneList<const AstRawString * > * labels,bool * ok)3159 WhileStatement* Parser::ParseWhileStatement(
3160     ZoneList<const AstRawString*>* labels, bool* ok) {
3161   // WhileStatement ::
3162   //   'while' '(' Expression ')' Statement
3163 
3164   WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position());
3165   Target target(&this->target_stack_, loop);
3166 
3167   Expect(Token::WHILE, CHECK_OK);
3168   Expect(Token::LPAREN, CHECK_OK);
3169   Expression* cond = ParseExpression(true, CHECK_OK);
3170   Expect(Token::RPAREN, CHECK_OK);
3171   Statement* body = ParseScopedStatement(NULL, true, CHECK_OK);
3172 
3173   if (loop != NULL) loop->Initialize(cond, body);
3174   return loop;
3175 }
3176 
3177 
3178 // !%_IsJSReceiver(result = iterator.next()) &&
3179 //     %ThrowIteratorResultNotAnObject(result)
BuildIteratorNextResult(Expression * iterator,Variable * result,int pos)3180 Expression* Parser::BuildIteratorNextResult(Expression* iterator,
3181                                             Variable* result, int pos) {
3182   Expression* next_literal = factory()->NewStringLiteral(
3183       ast_value_factory()->next_string(), RelocInfo::kNoPosition);
3184   Expression* next_property =
3185       factory()->NewProperty(iterator, next_literal, RelocInfo::kNoPosition);
3186   ZoneList<Expression*>* next_arguments =
3187       new (zone()) ZoneList<Expression*>(0, zone());
3188   Expression* next_call =
3189       factory()->NewCall(next_property, next_arguments, pos);
3190   Expression* result_proxy = factory()->NewVariableProxy(result);
3191   Expression* left =
3192       factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos);
3193 
3194   // %_IsJSReceiver(...)
3195   ZoneList<Expression*>* is_spec_object_args =
3196       new (zone()) ZoneList<Expression*>(1, zone());
3197   is_spec_object_args->Add(left, zone());
3198   Expression* is_spec_object_call = factory()->NewCallRuntime(
3199       Runtime::kInlineIsJSReceiver, is_spec_object_args, pos);
3200 
3201   // %ThrowIteratorResultNotAnObject(result)
3202   Expression* result_proxy_again = factory()->NewVariableProxy(result);
3203   ZoneList<Expression*>* throw_arguments =
3204       new (zone()) ZoneList<Expression*>(1, zone());
3205   throw_arguments->Add(result_proxy_again, zone());
3206   Expression* throw_call = factory()->NewCallRuntime(
3207       Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos);
3208 
3209   return factory()->NewBinaryOperation(
3210       Token::AND,
3211       factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos),
3212       throw_call, pos);
3213 }
3214 
InitializeForEachStatement(ForEachStatement * stmt,Expression * each,Expression * subject,Statement * body,int each_keyword_pos)3215 void Parser::InitializeForEachStatement(ForEachStatement* stmt,
3216                                         Expression* each, Expression* subject,
3217                                         Statement* body, int each_keyword_pos) {
3218   ForOfStatement* for_of = stmt->AsForOfStatement();
3219   if (for_of != NULL) {
3220     InitializeForOfStatement(for_of, each, subject, body, each_keyword_pos);
3221   } else {
3222     if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
3223       Variable* temp =
3224           scope_->NewTemporary(ast_value_factory()->empty_string());
3225       VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
3226       Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment(
3227           this, factory()->NewAssignment(Token::ASSIGN, each, temp_proxy,
3228                                          RelocInfo::kNoPosition),
3229           scope_);
3230       auto block =
3231           factory()->NewBlock(nullptr, 2, false, RelocInfo::kNoPosition);
3232       block->statements()->Add(factory()->NewExpressionStatement(
3233                                    assign_each, RelocInfo::kNoPosition),
3234                                zone());
3235       block->statements()->Add(body, zone());
3236       body = block;
3237       each = factory()->NewVariableProxy(temp);
3238     }
3239     stmt->AsForInStatement()->Initialize(each, subject, body);
3240   }
3241 }
3242 
InitializeForOfStatement(ForOfStatement * for_of,Expression * each,Expression * iterable,Statement * body,int next_result_pos)3243 void Parser::InitializeForOfStatement(ForOfStatement* for_of, Expression* each,
3244                                       Expression* iterable, Statement* body,
3245                                       int next_result_pos) {
3246   Variable* iterator =
3247       scope_->NewTemporary(ast_value_factory()->dot_iterator_string());
3248   Variable* result =
3249       scope_->NewTemporary(ast_value_factory()->dot_result_string());
3250 
3251   Expression* assign_iterator;
3252   Expression* next_result;
3253   Expression* result_done;
3254   Expression* assign_each;
3255 
3256   int get_iterator_pos = iterable->position();
3257 
3258   // iterator = iterable[Symbol.iterator]()
3259   assign_iterator = factory()->NewAssignment(
3260       Token::ASSIGN, factory()->NewVariableProxy(iterator),
3261       GetIterator(iterable, factory(), get_iterator_pos), iterable->position());
3262 
3263   // !%_IsJSReceiver(result = iterator.next()) &&
3264   //     %ThrowIteratorResultNotAnObject(result)
3265   {
3266     // result = iterator.next()
3267     Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
3268     next_result =
3269         BuildIteratorNextResult(iterator_proxy, result, next_result_pos);
3270   }
3271 
3272   // result.done
3273   {
3274     Expression* done_literal = factory()->NewStringLiteral(
3275         ast_value_factory()->done_string(), RelocInfo::kNoPosition);
3276     Expression* result_proxy = factory()->NewVariableProxy(result);
3277     result_done = factory()->NewProperty(result_proxy, done_literal,
3278                                          RelocInfo::kNoPosition);
3279   }
3280 
3281   // each = result.value
3282   {
3283     Expression* value_literal = factory()->NewStringLiteral(
3284         ast_value_factory()->value_string(), RelocInfo::kNoPosition);
3285     Expression* result_proxy = factory()->NewVariableProxy(result);
3286     Expression* result_value = factory()->NewProperty(
3287         result_proxy, value_literal, RelocInfo::kNoPosition);
3288     assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value,
3289                                            RelocInfo::kNoPosition);
3290     if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
3291       assign_each = PatternRewriter::RewriteDestructuringAssignment(
3292           this, assign_each->AsAssignment(), scope_);
3293     }
3294   }
3295 
3296   for_of->Initialize(body, iterator, assign_iterator, next_result, result_done,
3297                      assign_each);
3298 }
3299 
DesugarLexicalBindingsInForStatement(Scope * inner_scope,VariableMode mode,ZoneList<const AstRawString * > * names,ForStatement * loop,Statement * init,Expression * cond,Statement * next,Statement * body,bool * ok)3300 Statement* Parser::DesugarLexicalBindingsInForStatement(
3301     Scope* inner_scope, VariableMode mode, ZoneList<const AstRawString*>* names,
3302     ForStatement* loop, Statement* init, Expression* cond, Statement* next,
3303     Statement* body, bool* ok) {
3304   // ES6 13.7.4.8 specifies that on each loop iteration the let variables are
3305   // copied into a new environment.  Moreover, the "next" statement must be
3306   // evaluated not in the environment of the just completed iteration but in
3307   // that of the upcoming one.  We achieve this with the following desugaring.
3308   // Extra care is needed to preserve the completion value of the original loop.
3309   //
3310   // We are given a for statement of the form
3311   //
3312   //  labels: for (let/const x = i; cond; next) body
3313   //
3314   // and rewrite it as follows.  Here we write {{ ... }} for init-blocks, ie.,
3315   // blocks whose ignore_completion_value_ flag is set.
3316   //
3317   //  {
3318   //    let/const x = i;
3319   //    temp_x = x;
3320   //    first = 1;
3321   //    undefined;
3322   //    outer: for (;;) {
3323   //      let/const x = temp_x;
3324   //      {{ if (first == 1) {
3325   //           first = 0;
3326   //         } else {
3327   //           next;
3328   //         }
3329   //         flag = 1;
3330   //         if (!cond) break;
3331   //      }}
3332   //      labels: for (; flag == 1; flag = 0, temp_x = x) {
3333   //        body
3334   //      }
3335   //      {{ if (flag == 1)  // Body used break.
3336   //           break;
3337   //      }}
3338   //    }
3339   //  }
3340 
3341   DCHECK(names->length() > 0);
3342   ZoneList<Variable*> temps(names->length(), zone());
3343 
3344   Block* outer_block = factory()->NewBlock(NULL, names->length() + 4, false,
3345                                            RelocInfo::kNoPosition);
3346 
3347   // Add statement: let/const x = i.
3348   outer_block->statements()->Add(init, zone());
3349 
3350   const AstRawString* temp_name = ast_value_factory()->dot_for_string();
3351 
3352   // For each lexical variable x:
3353   //   make statement: temp_x = x.
3354   for (int i = 0; i < names->length(); i++) {
3355     VariableProxy* proxy = NewUnresolved(names->at(i), LET);
3356     Variable* temp = scope_->NewTemporary(temp_name);
3357     VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
3358     Assignment* assignment = factory()->NewAssignment(
3359         Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
3360     Statement* assignment_statement = factory()->NewExpressionStatement(
3361         assignment, RelocInfo::kNoPosition);
3362     outer_block->statements()->Add(assignment_statement, zone());
3363     temps.Add(temp, zone());
3364   }
3365 
3366   Variable* first = NULL;
3367   // Make statement: first = 1.
3368   if (next) {
3369     first = scope_->NewTemporary(temp_name);
3370     VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3371     Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3372     Assignment* assignment = factory()->NewAssignment(
3373         Token::ASSIGN, first_proxy, const1, RelocInfo::kNoPosition);
3374     Statement* assignment_statement =
3375         factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3376     outer_block->statements()->Add(assignment_statement, zone());
3377   }
3378 
3379   // make statement: undefined;
3380   outer_block->statements()->Add(
3381       factory()->NewExpressionStatement(
3382           factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
3383           RelocInfo::kNoPosition),
3384       zone());
3385 
3386   // Make statement: outer: for (;;)
3387   // Note that we don't actually create the label, or set this loop up as an
3388   // explicit break target, instead handing it directly to those nodes that
3389   // need to know about it. This should be safe because we don't run any code
3390   // in this function that looks up break targets.
3391   ForStatement* outer_loop =
3392       factory()->NewForStatement(NULL, RelocInfo::kNoPosition);
3393   outer_block->statements()->Add(outer_loop, zone());
3394   outer_block->set_scope(scope_);
3395 
3396   Block* inner_block =
3397       factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3398   {
3399     BlockState block_state(&scope_, inner_scope);
3400 
3401     Block* ignore_completion_block = factory()->NewBlock(
3402         NULL, names->length() + 3, true, RelocInfo::kNoPosition);
3403     ZoneList<Variable*> inner_vars(names->length(), zone());
3404     // For each let variable x:
3405     //    make statement: let/const x = temp_x.
3406     for (int i = 0; i < names->length(); i++) {
3407       VariableProxy* proxy = NewUnresolved(names->at(i), mode);
3408       Declaration* declaration = factory()->NewVariableDeclaration(
3409           proxy, mode, scope_, RelocInfo::kNoPosition);
3410       Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
3411       inner_vars.Add(declaration->proxy()->var(), zone());
3412       VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3413       Assignment* assignment = factory()->NewAssignment(
3414           Token::INIT, proxy, temp_proxy, RelocInfo::kNoPosition);
3415       Statement* assignment_statement =
3416           factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3417       DCHECK(init->position() != RelocInfo::kNoPosition);
3418       proxy->var()->set_initializer_position(init->position());
3419       ignore_completion_block->statements()->Add(assignment_statement, zone());
3420     }
3421 
3422     // Make statement: if (first == 1) { first = 0; } else { next; }
3423     if (next) {
3424       DCHECK(first);
3425       Expression* compare = NULL;
3426       // Make compare expression: first == 1.
3427       {
3428         Expression* const1 =
3429             factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3430         VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3431         compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1,
3432                                                  RelocInfo::kNoPosition);
3433       }
3434       Statement* clear_first = NULL;
3435       // Make statement: first = 0.
3436       {
3437         VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3438         Expression* const0 =
3439             factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
3440         Assignment* assignment = factory()->NewAssignment(
3441             Token::ASSIGN, first_proxy, const0, RelocInfo::kNoPosition);
3442         clear_first = factory()->NewExpressionStatement(assignment,
3443                                                         RelocInfo::kNoPosition);
3444       }
3445       Statement* clear_first_or_next = factory()->NewIfStatement(
3446           compare, clear_first, next, RelocInfo::kNoPosition);
3447       ignore_completion_block->statements()->Add(clear_first_or_next, zone());
3448     }
3449 
3450     Variable* flag = scope_->NewTemporary(temp_name);
3451     // Make statement: flag = 1.
3452     {
3453       VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3454       Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3455       Assignment* assignment = factory()->NewAssignment(
3456           Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition);
3457       Statement* assignment_statement =
3458           factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3459       ignore_completion_block->statements()->Add(assignment_statement, zone());
3460     }
3461 
3462     // Make statement: if (!cond) break.
3463     if (cond) {
3464       Statement* stop =
3465           factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3466       Statement* noop = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
3467       ignore_completion_block->statements()->Add(
3468           factory()->NewIfStatement(cond, noop, stop, cond->position()),
3469           zone());
3470     }
3471 
3472     inner_block->statements()->Add(ignore_completion_block, zone());
3473     // Make cond expression for main loop: flag == 1.
3474     Expression* flag_cond = NULL;
3475     {
3476       Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3477       VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3478       flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
3479                                                  RelocInfo::kNoPosition);
3480     }
3481 
3482     // Create chain of expressions "flag = 0, temp_x = x, ..."
3483     Statement* compound_next_statement = NULL;
3484     {
3485       Expression* compound_next = NULL;
3486       // Make expression: flag = 0.
3487       {
3488         VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3489         Expression* const0 =
3490             factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
3491         compound_next = factory()->NewAssignment(
3492             Token::ASSIGN, flag_proxy, const0, RelocInfo::kNoPosition);
3493       }
3494 
3495       // Make the comma-separated list of temp_x = x assignments.
3496       int inner_var_proxy_pos = scanner()->location().beg_pos;
3497       for (int i = 0; i < names->length(); i++) {
3498         VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3499         VariableProxy* proxy =
3500             factory()->NewVariableProxy(inner_vars.at(i), inner_var_proxy_pos);
3501         Assignment* assignment = factory()->NewAssignment(
3502             Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
3503         compound_next = factory()->NewBinaryOperation(
3504             Token::COMMA, compound_next, assignment, RelocInfo::kNoPosition);
3505       }
3506 
3507       compound_next_statement = factory()->NewExpressionStatement(
3508           compound_next, RelocInfo::kNoPosition);
3509     }
3510 
3511     // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
3512     // Note that we re-use the original loop node, which retains its labels
3513     // and ensures that any break or continue statements in body point to
3514     // the right place.
3515     loop->Initialize(NULL, flag_cond, compound_next_statement, body);
3516     inner_block->statements()->Add(loop, zone());
3517 
3518     // Make statement: {{if (flag == 1) break;}}
3519     {
3520       Expression* compare = NULL;
3521       // Make compare expresion: flag == 1.
3522       {
3523         Expression* const1 =
3524             factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3525         VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3526         compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
3527                                                  RelocInfo::kNoPosition);
3528       }
3529       Statement* stop =
3530           factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3531       Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
3532       Statement* if_flag_break = factory()->NewIfStatement(
3533           compare, stop, empty, RelocInfo::kNoPosition);
3534       Block* ignore_completion_block =
3535           factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
3536       ignore_completion_block->statements()->Add(if_flag_break, zone());
3537       inner_block->statements()->Add(ignore_completion_block, zone());
3538     }
3539 
3540     inner_scope->set_end_position(scanner()->location().end_pos);
3541     inner_block->set_scope(inner_scope);
3542   }
3543 
3544   outer_loop->Initialize(NULL, NULL, NULL, inner_block);
3545   return outer_block;
3546 }
3547 
ParseScopedStatement(ZoneList<const AstRawString * > * labels,bool legacy,bool * ok)3548 Statement* Parser::ParseScopedStatement(ZoneList<const AstRawString*>* labels,
3549                                         bool legacy, bool* ok) {
3550   if (is_strict(language_mode()) || peek() != Token::FUNCTION ||
3551       (legacy && allow_harmony_restrictive_declarations())) {
3552     return ParseSubStatement(labels, kDisallowLabelledFunctionStatement, ok);
3553   } else {
3554     if (legacy) {
3555       ++use_counts_[v8::Isolate::kLegacyFunctionDeclaration];
3556     }
3557     // Make a block around the statement for a lexical binding
3558     // is introduced by a FunctionDeclaration.
3559     Scope* body_scope = NewScope(scope_, BLOCK_SCOPE);
3560     body_scope->set_start_position(scanner()->location().beg_pos);
3561     BlockState block_state(&scope_, body_scope);
3562     Block* block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
3563     Statement* body = ParseFunctionDeclaration(CHECK_OK);
3564     block->statements()->Add(body, zone());
3565     body_scope->set_end_position(scanner()->location().end_pos);
3566     body_scope = body_scope->FinalizeBlockScope();
3567     block->set_scope(body_scope);
3568     return block;
3569   }
3570 }
3571 
ParseForStatement(ZoneList<const AstRawString * > * labels,bool * ok)3572 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
3573                                      bool* ok) {
3574   int stmt_pos = peek_position();
3575   Statement* init = NULL;
3576   ZoneList<const AstRawString*> lexical_bindings(1, zone());
3577 
3578   // Create an in-between scope for let-bound iteration variables.
3579   Scope* for_scope = NewScope(scope_, BLOCK_SCOPE);
3580 
3581   BlockState block_state(&scope_, for_scope);
3582   Expect(Token::FOR, CHECK_OK);
3583   Expect(Token::LPAREN, CHECK_OK);
3584   for_scope->set_start_position(scanner()->location().beg_pos);
3585   for_scope->set_is_hidden();
3586   DeclarationParsingResult parsing_result;
3587   if (peek() != Token::SEMICOLON) {
3588     if (peek() == Token::VAR || peek() == Token::CONST ||
3589         (peek() == Token::LET && IsNextLetKeyword())) {
3590       ParseVariableDeclarations(kForStatement, &parsing_result, nullptr,
3591                                 CHECK_OK);
3592 
3593       ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE;
3594       int each_beg_pos = scanner()->location().beg_pos;
3595       int each_end_pos = scanner()->location().end_pos;
3596 
3597       if (CheckInOrOf(&mode, ok)) {
3598         if (!*ok) return nullptr;
3599         if (parsing_result.declarations.length() != 1) {
3600           ParserTraits::ReportMessageAt(
3601               parsing_result.bindings_loc,
3602               MessageTemplate::kForInOfLoopMultiBindings,
3603               ForEachStatement::VisitModeString(mode));
3604           *ok = false;
3605           return nullptr;
3606         }
3607         DeclarationParsingResult::Declaration& decl =
3608             parsing_result.declarations[0];
3609         if (parsing_result.first_initializer_loc.IsValid() &&
3610             (is_strict(language_mode()) || mode == ForEachStatement::ITERATE ||
3611              IsLexicalVariableMode(parsing_result.descriptor.mode) ||
3612              !decl.pattern->IsVariableProxy() || allow_harmony_for_in())) {
3613           // Only increment the use count if we would have let this through
3614           // without the flag.
3615           if (allow_harmony_for_in()) {
3616             ++use_counts_[v8::Isolate::kForInInitializer];
3617           }
3618           ParserTraits::ReportMessageAt(
3619               parsing_result.first_initializer_loc,
3620               MessageTemplate::kForInOfLoopInitializer,
3621               ForEachStatement::VisitModeString(mode));
3622           *ok = false;
3623           return nullptr;
3624         }
3625 
3626         Block* init_block = nullptr;
3627 
3628         // special case for legacy for (var/const x =.... in)
3629         if (!IsLexicalVariableMode(parsing_result.descriptor.mode) &&
3630             decl.pattern->IsVariableProxy() && decl.initializer != nullptr) {
3631           DCHECK(!allow_harmony_for_in());
3632           ++use_counts_[v8::Isolate::kForInInitializer];
3633           const AstRawString* name =
3634               decl.pattern->AsVariableProxy()->raw_name();
3635           VariableProxy* single_var = scope_->NewUnresolved(
3636               factory(), name, Variable::NORMAL, each_beg_pos, each_end_pos);
3637           init_block = factory()->NewBlock(
3638               nullptr, 2, true, parsing_result.descriptor.declaration_pos);
3639           init_block->statements()->Add(
3640               factory()->NewExpressionStatement(
3641                   factory()->NewAssignment(Token::ASSIGN, single_var,
3642                                            decl.initializer,
3643                                            RelocInfo::kNoPosition),
3644                   RelocInfo::kNoPosition),
3645               zone());
3646         }
3647 
3648         // Rewrite a for-in/of statement of the form
3649         //
3650         //   for (let/const/var x in/of e) b
3651         //
3652         // into
3653         //
3654         //   {
3655         //     <let x' be a temporary variable>
3656         //     for (x' in/of e) {
3657         //       let/const/var x;
3658         //       x = x';
3659         //       b;
3660         //     }
3661         //     let x;  // for TDZ
3662         //   }
3663 
3664         Variable* temp =
3665             scope_->NewTemporary(ast_value_factory()->dot_for_string());
3666         ForEachStatement* loop =
3667             factory()->NewForEachStatement(mode, labels, stmt_pos);
3668         Target target(&this->target_stack_, loop);
3669 
3670         int each_keyword_position = scanner()->location().beg_pos;
3671 
3672         Expression* enumerable;
3673         if (mode == ForEachStatement::ITERATE) {
3674           ExpressionClassifier classifier(this);
3675           enumerable = ParseAssignmentExpression(true, &classifier, CHECK_OK);
3676           RewriteNonPattern(&classifier, CHECK_OK);
3677         } else {
3678           enumerable = ParseExpression(true, CHECK_OK);
3679         }
3680 
3681         Expect(Token::RPAREN, CHECK_OK);
3682 
3683         Scope* body_scope = NewScope(scope_, BLOCK_SCOPE);
3684         body_scope->set_start_position(scanner()->location().beg_pos);
3685 
3686         Block* body_block =
3687             factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3688 
3689         {
3690           ReturnExprScope no_tail_calls(function_state_,
3691                                         ReturnExprContext::kInsideForInOfBody);
3692           BlockState block_state(&scope_, body_scope);
3693 
3694           Statement* body = ParseScopedStatement(NULL, true, CHECK_OK);
3695 
3696           auto each_initialization_block =
3697               factory()->NewBlock(nullptr, 1, true, RelocInfo::kNoPosition);
3698           {
3699             auto descriptor = parsing_result.descriptor;
3700             descriptor.declaration_pos = RelocInfo::kNoPosition;
3701             descriptor.initialization_pos = RelocInfo::kNoPosition;
3702             decl.initializer = factory()->NewVariableProxy(temp);
3703 
3704             PatternRewriter::DeclareAndInitializeVariables(
3705                 each_initialization_block, &descriptor, &decl,
3706                 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings
3707                                                        : nullptr,
3708                 CHECK_OK);
3709           }
3710 
3711           body_block->statements()->Add(each_initialization_block, zone());
3712           body_block->statements()->Add(body, zone());
3713           VariableProxy* temp_proxy =
3714               factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos);
3715           InitializeForEachStatement(loop, temp_proxy, enumerable, body_block,
3716                                      each_keyword_position);
3717         }
3718         body_scope->set_end_position(scanner()->location().end_pos);
3719         body_scope = body_scope->FinalizeBlockScope();
3720         body_block->set_scope(body_scope);
3721 
3722         // Create a TDZ for any lexically-bound names.
3723         if (IsLexicalVariableMode(parsing_result.descriptor.mode)) {
3724           DCHECK_NULL(init_block);
3725 
3726           init_block =
3727               factory()->NewBlock(nullptr, 1, false, RelocInfo::kNoPosition);
3728 
3729           for (int i = 0; i < lexical_bindings.length(); ++i) {
3730             // TODO(adamk): This needs to be some sort of special
3731             // INTERNAL variable that's invisible to the debugger
3732             // but visible to everything else.
3733             VariableProxy* tdz_proxy =
3734                 NewUnresolved(lexical_bindings[i], LET);
3735             Declaration* tdz_decl = factory()->NewVariableDeclaration(
3736                 tdz_proxy, LET, scope_, RelocInfo::kNoPosition);
3737             Variable* tdz_var = Declare(
3738                 tdz_decl, DeclarationDescriptor::NORMAL, true, CHECK_OK);
3739             tdz_var->set_initializer_position(position());
3740           }
3741         }
3742 
3743         Statement* final_loop = loop->IsForOfStatement()
3744             ? FinalizeForOfStatement(
3745                 loop->AsForOfStatement(), RelocInfo::kNoPosition)
3746             : loop;
3747 
3748         for_scope->set_end_position(scanner()->location().end_pos);
3749         for_scope = for_scope->FinalizeBlockScope();
3750         // Parsed for-in loop w/ variable declarations.
3751         if (init_block != nullptr) {
3752           init_block->statements()->Add(final_loop, zone());
3753           init_block->set_scope(for_scope);
3754           return init_block;
3755         } else {
3756           DCHECK_NULL(for_scope);
3757           return final_loop;
3758         }
3759       } else {
3760         init = parsing_result.BuildInitializationBlock(
3761             IsLexicalVariableMode(parsing_result.descriptor.mode)
3762                 ? &lexical_bindings
3763                 : nullptr,
3764             CHECK_OK);
3765       }
3766     } else {
3767       int lhs_beg_pos = peek_position();
3768       ExpressionClassifier classifier(this);
3769       Expression* expression = ParseExpression(false, &classifier, CHECK_OK);
3770       int lhs_end_pos = scanner()->location().end_pos;
3771       ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE;
3772 
3773       bool is_for_each = CheckInOrOf(&mode, ok);
3774       if (!*ok) return nullptr;
3775       bool is_destructuring = is_for_each && (expression->IsArrayLiteral() ||
3776                                               expression->IsObjectLiteral());
3777 
3778       if (is_destructuring) {
3779         ValidateAssignmentPattern(&classifier, CHECK_OK);
3780       } else {
3781         RewriteNonPattern(&classifier, CHECK_OK);
3782       }
3783 
3784       if (is_for_each) {
3785         if (!is_destructuring) {
3786           expression = this->CheckAndRewriteReferenceExpression(
3787               expression, lhs_beg_pos, lhs_end_pos,
3788               MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK);
3789         }
3790 
3791         ForEachStatement* loop =
3792             factory()->NewForEachStatement(mode, labels, stmt_pos);
3793         Target target(&this->target_stack_, loop);
3794 
3795         int each_keyword_position = scanner()->location().beg_pos;
3796 
3797         Expression* enumerable;
3798         if (mode == ForEachStatement::ITERATE) {
3799           ExpressionClassifier classifier(this);
3800           enumerable = ParseAssignmentExpression(true, &classifier, CHECK_OK);
3801           RewriteNonPattern(&classifier, CHECK_OK);
3802         } else {
3803           enumerable = ParseExpression(true, CHECK_OK);
3804         }
3805 
3806         Expect(Token::RPAREN, CHECK_OK);
3807 
3808         // For legacy compat reasons, give for loops similar treatment to
3809         // if statements in allowing a function declaration for a body
3810         Statement* body = ParseScopedStatement(NULL, true, CHECK_OK);
3811         InitializeForEachStatement(loop, expression, enumerable, body,
3812                                    each_keyword_position);
3813 
3814         Statement* final_loop = loop->IsForOfStatement()
3815             ? FinalizeForOfStatement(
3816                 loop->AsForOfStatement(), RelocInfo::kNoPosition)
3817             : loop;
3818 
3819         for_scope->set_end_position(scanner()->location().end_pos);
3820         for_scope = for_scope->FinalizeBlockScope();
3821         DCHECK(for_scope == nullptr);
3822         return final_loop;
3823 
3824       } else {
3825         init = factory()->NewExpressionStatement(expression, lhs_beg_pos);
3826       }
3827     }
3828   }
3829 
3830   // Standard 'for' loop
3831   ForStatement* loop = factory()->NewForStatement(labels, stmt_pos);
3832   Target target(&this->target_stack_, loop);
3833 
3834   // Parsed initializer at this point.
3835   Expect(Token::SEMICOLON, CHECK_OK);
3836 
3837   Expression* cond = NULL;
3838   Statement* next = NULL;
3839   Statement* body = NULL;
3840 
3841   // If there are let bindings, then condition and the next statement of the
3842   // for loop must be parsed in a new scope.
3843   Scope* inner_scope = scope_;
3844   if (lexical_bindings.length() > 0) {
3845     inner_scope = NewScope(for_scope, BLOCK_SCOPE);
3846     inner_scope->set_start_position(scanner()->location().beg_pos);
3847   }
3848   {
3849     BlockState block_state(&scope_, inner_scope);
3850 
3851     if (peek() != Token::SEMICOLON) {
3852       cond = ParseExpression(true, CHECK_OK);
3853     }
3854     Expect(Token::SEMICOLON, CHECK_OK);
3855 
3856     if (peek() != Token::RPAREN) {
3857       Expression* exp = ParseExpression(true, CHECK_OK);
3858       next = factory()->NewExpressionStatement(exp, exp->position());
3859     }
3860     Expect(Token::RPAREN, CHECK_OK);
3861 
3862     body = ParseScopedStatement(NULL, true, CHECK_OK);
3863   }
3864 
3865   Statement* result = NULL;
3866   if (lexical_bindings.length() > 0) {
3867     BlockState block_state(&scope_, for_scope);
3868     result = DesugarLexicalBindingsInForStatement(
3869         inner_scope, parsing_result.descriptor.mode, &lexical_bindings, loop,
3870         init, cond, next, body, CHECK_OK);
3871     for_scope->set_end_position(scanner()->location().end_pos);
3872   } else {
3873     for_scope->set_end_position(scanner()->location().end_pos);
3874     for_scope = for_scope->FinalizeBlockScope();
3875     if (for_scope) {
3876       // Rewrite a for statement of the form
3877       //   for (const x = i; c; n) b
3878       //
3879       // into
3880       //
3881       //   {
3882       //     const x = i;
3883       //     for (; c; n) b
3884       //   }
3885       //
3886       // or, desugar
3887       //   for (; c; n) b
3888       // into
3889       //   {
3890       //     for (; c; n) b
3891       //   }
3892       // just in case b introduces a lexical binding some other way, e.g., if b
3893       // is a FunctionDeclaration.
3894       Block* block =
3895           factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
3896       if (init != nullptr) {
3897         block->statements()->Add(init, zone());
3898       }
3899       block->statements()->Add(loop, zone());
3900       block->set_scope(for_scope);
3901       loop->Initialize(NULL, cond, next, body);
3902       result = block;
3903     } else {
3904       loop->Initialize(init, cond, next, body);
3905       result = loop;
3906     }
3907   }
3908   return result;
3909 }
3910 
3911 
ParseDebuggerStatement(bool * ok)3912 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
3913   // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
3914   // contexts this is used as a statement which invokes the debugger as i a
3915   // break point is present.
3916   // DebuggerStatement ::
3917   //   'debugger' ';'
3918 
3919   int pos = peek_position();
3920   Expect(Token::DEBUGGER, CHECK_OK);
3921   ExpectSemicolon(CHECK_OK);
3922   return factory()->NewDebuggerStatement(pos);
3923 }
3924 
3925 
IsCompileTimeValue(Expression * expression)3926 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) {
3927   if (expression->IsLiteral()) return true;
3928   MaterializedLiteral* lit = expression->AsMaterializedLiteral();
3929   return lit != NULL && lit->is_simple();
3930 }
3931 
3932 
GetValue(Isolate * isolate,Expression * expression)3933 Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate,
3934                                               Expression* expression) {
3935   Factory* factory = isolate->factory();
3936   DCHECK(IsCompileTimeValue(expression));
3937   Handle<FixedArray> result = factory->NewFixedArray(2, TENURED);
3938   ObjectLiteral* object_literal = expression->AsObjectLiteral();
3939   if (object_literal != NULL) {
3940     DCHECK(object_literal->is_simple());
3941     if (object_literal->fast_elements()) {
3942       result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS));
3943     } else {
3944       result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS));
3945     }
3946     result->set(kElementsSlot, *object_literal->constant_properties());
3947   } else {
3948     ArrayLiteral* array_literal = expression->AsArrayLiteral();
3949     DCHECK(array_literal != NULL && array_literal->is_simple());
3950     result->set(kLiteralTypeSlot, Smi::FromInt(ARRAY_LITERAL));
3951     result->set(kElementsSlot, *array_literal->constant_elements());
3952   }
3953   return result;
3954 }
3955 
3956 
GetLiteralType(Handle<FixedArray> value)3957 CompileTimeValue::LiteralType CompileTimeValue::GetLiteralType(
3958     Handle<FixedArray> value) {
3959   Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot));
3960   return static_cast<LiteralType>(literal_type->value());
3961 }
3962 
3963 
GetElements(Handle<FixedArray> value)3964 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) {
3965   return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot)));
3966 }
3967 
ParseArrowFunctionFormalParameters(ParserFormalParameters * parameters,Expression * expr,int end_pos,bool * ok)3968 void ParserTraits::ParseArrowFunctionFormalParameters(
3969     ParserFormalParameters* parameters, Expression* expr, int end_pos,
3970     bool* ok) {
3971   // ArrowFunctionFormals ::
3972   //    Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail)
3973   //    Tail
3974   // NonTailArrowFunctionFormals ::
3975   //    Binary(Token::COMMA, NonTailArrowFunctionFormals, VariableProxy)
3976   //    VariableProxy
3977   // Tail ::
3978   //    VariableProxy
3979   //    Spread(VariableProxy)
3980   //
3981   // As we need to visit the parameters in left-to-right order, we recurse on
3982   // the left-hand side of comma expressions.
3983   //
3984   if (expr->IsBinaryOperation()) {
3985     BinaryOperation* binop = expr->AsBinaryOperation();
3986     // The classifier has already run, so we know that the expression is a valid
3987     // arrow function formals production.
3988     DCHECK_EQ(binop->op(), Token::COMMA);
3989     Expression* left = binop->left();
3990     Expression* right = binop->right();
3991     int comma_pos = binop->position();
3992     ParseArrowFunctionFormalParameters(parameters, left, comma_pos, ok);
3993     if (!*ok) return;
3994     // LHS of comma expression should be unparenthesized.
3995     expr = right;
3996   }
3997 
3998   // Only the right-most expression may be a rest parameter.
3999   DCHECK(!parameters->has_rest);
4000 
4001   bool is_rest = expr->IsSpread();
4002   if (is_rest) {
4003     expr = expr->AsSpread()->expression();
4004     parameters->has_rest = true;
4005   }
4006   if (parameters->is_simple) {
4007     parameters->is_simple = !is_rest && expr->IsVariableProxy();
4008   }
4009 
4010   Expression* initializer = nullptr;
4011   if (expr->IsVariableProxy()) {
4012     // When the formal parameter was originally seen, it was parsed as a
4013     // VariableProxy and recorded as unresolved in the scope.  Here we undo that
4014     // parse-time side-effect for parameters that are single-names (not
4015     // patterns; for patterns that happens uniformly in
4016     // PatternRewriter::VisitVariableProxy).
4017     parser_->scope_->RemoveUnresolved(expr->AsVariableProxy());
4018   } else if (expr->IsAssignment()) {
4019     Assignment* assignment = expr->AsAssignment();
4020     DCHECK(!assignment->is_compound());
4021     initializer = assignment->value();
4022     expr = assignment->target();
4023 
4024     // TODO(adamk): Only call this if necessary.
4025     RewriteParameterInitializerScope(parser_->stack_limit(), initializer,
4026                                      parser_->scope_, parameters->scope);
4027   }
4028 
4029   AddFormalParameter(parameters, expr, initializer, end_pos, is_rest);
4030 }
4031 
ParseAsyncArrowSingleExpressionBody(ZoneList<Statement * > * body,bool accept_IN,Type::ExpressionClassifier * classifier,int pos,bool * ok)4032 void ParserTraits::ParseAsyncArrowSingleExpressionBody(
4033     ZoneList<Statement*>* body, bool accept_IN,
4034     Type::ExpressionClassifier* classifier, int pos, bool* ok) {
4035   parser_->DesugarAsyncFunctionBody(
4036       parser_->ast_value_factory()->empty_string(), parser_->scope_, body,
4037       classifier, kAsyncArrowFunction, FunctionBody::SingleExpression,
4038       accept_IN, pos, ok);
4039 }
4040 
DesugarAsyncFunctionBody(const AstRawString * function_name,Scope * scope,ZoneList<Statement * > * body,ExpressionClassifier * classifier,FunctionKind kind,FunctionBody body_type,bool accept_IN,int pos,bool * ok)4041 void Parser::DesugarAsyncFunctionBody(const AstRawString* function_name,
4042                                       Scope* scope, ZoneList<Statement*>* body,
4043                                       ExpressionClassifier* classifier,
4044                                       FunctionKind kind, FunctionBody body_type,
4045                                       bool accept_IN, int pos, bool* ok) {
4046   // function async_function() {
4047   //   try {
4048   //     .generator_object = %CreateGeneratorObject();
4049   //     ... function body ...
4050   //   } catch (e) {
4051   //     return Promise.reject(e);
4052   //   }
4053   // }
4054   scope->ForceContextAllocation();
4055   Variable* temp =
4056       scope_->NewTemporary(ast_value_factory()->dot_generator_object_string());
4057   function_state_->set_generator_object_variable(temp);
4058 
4059   Expression* init_generator_variable = factory()->NewAssignment(
4060       Token::INIT, factory()->NewVariableProxy(temp),
4061       BuildCreateJSGeneratorObject(pos, kind), RelocInfo::kNoPosition);
4062   body->Add(factory()->NewExpressionStatement(init_generator_variable,
4063                                               RelocInfo::kNoPosition),
4064             zone());
4065 
4066   Block* try_block = factory()->NewBlock(NULL, 8, true, RelocInfo::kNoPosition);
4067 
4068   ZoneList<Statement*>* inner_body = try_block->statements();
4069 
4070   Expression* return_value = nullptr;
4071   if (body_type == FunctionBody::Normal) {
4072     ParseStatementList(inner_body, Token::RBRACE, ok);
4073     if (!*ok) return;
4074     return_value = factory()->NewUndefinedLiteral(RelocInfo::kNoPosition);
4075   } else {
4076     return_value = ParseAssignmentExpression(accept_IN, classifier, ok);
4077     if (!*ok) return;
4078     ParserTraits::RewriteNonPattern(classifier, ok);
4079     if (!*ok) return;
4080   }
4081 
4082   return_value = BuildPromiseResolve(return_value, return_value->position());
4083   inner_body->Add(
4084       factory()->NewReturnStatement(return_value, return_value->position()),
4085       zone());
4086   body->Add(BuildRejectPromiseOnException(try_block), zone());
4087   scope->set_end_position(scanner()->location().end_pos);
4088 }
4089 
ParseDoExpression(bool * ok)4090 DoExpression* Parser::ParseDoExpression(bool* ok) {
4091   // AssignmentExpression ::
4092   //     do '{' StatementList '}'
4093   int pos = peek_position();
4094 
4095   Expect(Token::DO, CHECK_OK);
4096   Variable* result =
4097       scope_->NewTemporary(ast_value_factory()->dot_result_string());
4098   Block* block = ParseBlock(nullptr, false, CHECK_OK);
4099   DoExpression* expr = factory()->NewDoExpression(block, result, pos);
4100   if (!Rewriter::Rewrite(this, expr, ast_value_factory())) {
4101     *ok = false;
4102     return nullptr;
4103   }
4104   block->set_scope(block->scope()->FinalizeBlockScope());
4105   return expr;
4106 }
4107 
4108 
ParseArrowFunctionFormalParameterList(ParserFormalParameters * parameters,Expression * expr,const Scanner::Location & params_loc,Scanner::Location * duplicate_loc,bool * ok)4109 void ParserTraits::ParseArrowFunctionFormalParameterList(
4110     ParserFormalParameters* parameters, Expression* expr,
4111     const Scanner::Location& params_loc,
4112     Scanner::Location* duplicate_loc, bool* ok) {
4113   if (expr->IsEmptyParentheses()) return;
4114 
4115   ParseArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos, ok);
4116   if (!*ok) return;
4117 
4118   if (parameters->Arity() > Code::kMaxArguments) {
4119     ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
4120     *ok = false;
4121     return;
4122   }
4123 
4124   Type::ExpressionClassifier classifier(parser_);
4125   if (!parameters->is_simple) {
4126     classifier.RecordNonSimpleParameter();
4127   }
4128   for (int i = 0; i < parameters->Arity(); ++i) {
4129     auto parameter = parameters->at(i);
4130     DeclareFormalParameter(parameters->scope, parameter, &classifier);
4131     if (!duplicate_loc->IsValid()) {
4132       *duplicate_loc = classifier.duplicate_formal_parameter_error().location;
4133     }
4134   }
4135   DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters());
4136 }
4137 
4138 
ReindexLiterals(const ParserFormalParameters & parameters)4139 void ParserTraits::ReindexLiterals(const ParserFormalParameters& parameters) {
4140   if (parser_->function_state_->materialized_literal_count() > 0) {
4141     AstLiteralReindexer reindexer;
4142 
4143     for (const auto p : parameters.params) {
4144       if (p.pattern != nullptr) reindexer.Reindex(p.pattern);
4145       if (p.initializer != nullptr) reindexer.Reindex(p.initializer);
4146     }
4147 
4148     DCHECK(reindexer.count() <=
4149            parser_->function_state_->materialized_literal_count());
4150   }
4151 }
4152 
4153 
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)4154 FunctionLiteral* Parser::ParseFunctionLiteral(
4155     const AstRawString* function_name, Scanner::Location function_name_location,
4156     FunctionNameValidity function_name_validity, FunctionKind kind,
4157     int function_token_pos, FunctionLiteral::FunctionType function_type,
4158     LanguageMode language_mode, bool* ok) {
4159   // Function ::
4160   //   '(' FormalParameterList? ')' '{' FunctionBody '}'
4161   //
4162   // Getter ::
4163   //   '(' ')' '{' FunctionBody '}'
4164   //
4165   // Setter ::
4166   //   '(' PropertySetParameterList ')' '{' FunctionBody '}'
4167 
4168   int pos = function_token_pos == RelocInfo::kNoPosition
4169       ? peek_position() : function_token_pos;
4170 
4171   bool is_generator = IsGeneratorFunction(kind);
4172 
4173   // Anonymous functions were passed either the empty symbol or a null
4174   // handle as the function name.  Remember if we were passed a non-empty
4175   // handle to decide whether to invoke function name inference.
4176   bool should_infer_name = function_name == NULL;
4177 
4178   // We want a non-null handle as the function name.
4179   if (should_infer_name) {
4180     function_name = ast_value_factory()->empty_string();
4181   }
4182 
4183   Scope* scope = NewScope(scope_, FUNCTION_SCOPE, kind);
4184   SetLanguageMode(scope, language_mode);
4185   ZoneList<Statement*>* body = NULL;
4186   int arity = -1;
4187   int materialized_literal_count = -1;
4188   int expected_property_count = -1;
4189   DuplicateFinder duplicate_finder(scanner()->unicode_cache());
4190   bool should_be_used_once_hint = false;
4191   bool has_duplicate_parameters;
4192   FunctionLiteral::EagerCompileHint eager_compile_hint;
4193 
4194   // Parse function.
4195   {
4196     AstNodeFactory function_factory(ast_value_factory());
4197     FunctionState function_state(&function_state_, &scope_, scope, kind,
4198                                  &function_factory);
4199     scope_->SetScopeName(function_name);
4200     ExpressionClassifier formals_classifier(this, &duplicate_finder);
4201 
4202     eager_compile_hint = function_state_->this_function_is_parenthesized()
4203                              ? FunctionLiteral::kShouldEagerCompile
4204                              : FunctionLiteral::kShouldLazyCompile;
4205 
4206     if (is_generator) {
4207       // For generators, allocating variables in contexts is currently a win
4208       // because it minimizes the work needed to suspend and resume an
4209       // activation.  The machine code produced for generators (by full-codegen)
4210       // relies on this forced context allocation, but not in an essential way.
4211       scope_->ForceContextAllocation();
4212 
4213       // Calling a generator returns a generator object.  That object is stored
4214       // in a temporary variable, a definition that is used by "yield"
4215       // expressions. This also marks the FunctionState as a generator.
4216       Variable* temp = scope_->NewTemporary(
4217           ast_value_factory()->dot_generator_object_string());
4218       function_state.set_generator_object_variable(temp);
4219     }
4220 
4221     Expect(Token::LPAREN, CHECK_OK);
4222     int start_position = scanner()->location().beg_pos;
4223     scope_->set_start_position(start_position);
4224     ParserFormalParameters formals(scope);
4225     ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK);
4226     arity = formals.Arity();
4227     Expect(Token::RPAREN, CHECK_OK);
4228     int formals_end_position = scanner()->location().end_pos;
4229 
4230     CheckArityRestrictions(arity, kind, formals.has_rest, start_position,
4231                            formals_end_position, CHECK_OK);
4232     Expect(Token::LBRACE, CHECK_OK);
4233     // Don't include the rest parameter into the function's formal parameter
4234     // count (esp. the SharedFunctionInfo::internal_formal_parameter_count,
4235     // which says whether we need to create an arguments adaptor frame).
4236     if (formals.has_rest) arity--;
4237 
4238     // Determine if the function can be parsed lazily. Lazy parsing is different
4239     // from lazy compilation; we need to parse more eagerly than we compile.
4240 
4241     // We can only parse lazily if we also compile lazily. The heuristics for
4242     // lazy compilation are:
4243     // - It must not have been prohibited by the caller to Parse (some callers
4244     //   need a full AST).
4245     // - The outer scope must allow lazy compilation of inner functions.
4246     // - The function mustn't be a function expression with an open parenthesis
4247     //   before; we consider that a hint that the function will be called
4248     //   immediately, and it would be a waste of time to make it lazily
4249     //   compiled.
4250     // These are all things we can know at this point, without looking at the
4251     // function itself.
4252 
4253     // In addition, we need to distinguish between these cases:
4254     // (function foo() {
4255     //   bar = function() { return 1; }
4256     //  })();
4257     // and
4258     // (function foo() {
4259     //   var a = 1;
4260     //   bar = function() { return a; }
4261     //  })();
4262 
4263     // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
4264     // parenthesis before the function means that it will be called
4265     // immediately). The inner function *must* be parsed eagerly to resolve the
4266     // possible reference to the variable in foo's scope. However, it's possible
4267     // that it will be compiled lazily.
4268 
4269     // To make this additional case work, both Parser and PreParser implement a
4270     // logic where only top-level functions will be parsed lazily.
4271     bool is_lazily_parsed = mode() == PARSE_LAZILY &&
4272                             scope_->AllowsLazyParsing() &&
4273                             !function_state_->this_function_is_parenthesized();
4274 
4275     // Eager or lazy parse?
4276     // If is_lazily_parsed, we'll parse lazy. If we can set a bookmark, we'll
4277     // pass it to SkipLazyFunctionBody, which may use it to abort lazy
4278     // parsing if it suspect that wasn't a good idea. If so, or if we didn't
4279     // try to lazy parse in the first place, we'll have to parse eagerly.
4280     Scanner::BookmarkScope bookmark(scanner());
4281     if (is_lazily_parsed) {
4282       Scanner::BookmarkScope* maybe_bookmark =
4283           bookmark.Set() ? &bookmark : nullptr;
4284       SkipLazyFunctionBody(&materialized_literal_count,
4285                            &expected_property_count, /*CHECK_OK*/ ok,
4286                            maybe_bookmark);
4287 
4288       materialized_literal_count += formals.materialized_literals_count +
4289                                     function_state.materialized_literal_count();
4290 
4291       if (bookmark.HasBeenReset()) {
4292         // Trigger eager (re-)parsing, just below this block.
4293         is_lazily_parsed = false;
4294 
4295         // This is probably an initialization function. Inform the compiler it
4296         // should also eager-compile this function, and that we expect it to be
4297         // used once.
4298         eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
4299         should_be_used_once_hint = true;
4300       }
4301     }
4302     if (!is_lazily_parsed) {
4303       // Determine whether the function body can be discarded after parsing.
4304       // The preconditions are:
4305       // - Lazy compilation has to be enabled.
4306       // - Neither V8 natives nor native function declarations can be allowed,
4307       //   since parsing one would retroactively force the function to be
4308       //   eagerly compiled.
4309       // - The invoker of this parser can't depend on the AST being eagerly
4310       //   built (either because the function is about to be compiled, or
4311       //   because the AST is going to be inspected for some reason).
4312       // - Because of the above, we can't be attempting to parse a
4313       //   FunctionExpression; even without enclosing parentheses it might be
4314       //   immediately invoked.
4315       // - The function literal shouldn't be hinted to eagerly compile.
4316       // - For asm.js functions the body needs to be available when module
4317       //   validation is active, because we examine the entire module at once.
4318       bool use_temp_zone =
4319           FLAG_lazy && !allow_natives() && extension_ == NULL && allow_lazy() &&
4320           function_type == FunctionLiteral::kDeclaration &&
4321           eager_compile_hint != FunctionLiteral::kShouldEagerCompile &&
4322           !(FLAG_validate_asm && scope->asm_function());
4323       // Open a new BodyScope, which sets our AstNodeFactory to allocate in the
4324       // new temporary zone if the preconditions are satisfied, and ensures that
4325       // the previous zone is always restored after parsing the body.
4326       // For the purpose of scope analysis, some ZoneObjects allocated by the
4327       // factory must persist after the function body is thrown away and
4328       // temp_zone is deallocated. These objects are instead allocated in a
4329       // parser-persistent zone (see parser_zone_ in AstNodeFactory).
4330       {
4331         Zone temp_zone(zone()->allocator());
4332         AstNodeFactory::BodyScope inner(factory(), &temp_zone, use_temp_zone);
4333 
4334         body = ParseEagerFunctionBody(function_name, pos, formals, kind,
4335                                       function_type, CHECK_OK);
4336       }
4337       materialized_literal_count = function_state.materialized_literal_count();
4338       expected_property_count = function_state.expected_property_count();
4339       if (use_temp_zone) {
4340         // If the preconditions are correct the function body should never be
4341         // accessed, but do this anyway for better behaviour if they're wrong.
4342         body = NULL;
4343       }
4344     }
4345 
4346     // Parsing the body may change the language mode in our scope.
4347     language_mode = scope->language_mode();
4348 
4349     // Validate name and parameter names. We can do this only after parsing the
4350     // function, since the function can declare itself strict.
4351     CheckFunctionName(language_mode, function_name, function_name_validity,
4352                       function_name_location, CHECK_OK);
4353     const bool allow_duplicate_parameters =
4354         is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind);
4355     ValidateFormalParameters(&formals_classifier, language_mode,
4356                              allow_duplicate_parameters, CHECK_OK);
4357 
4358     if (is_strict(language_mode)) {
4359       CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
4360                               CHECK_OK);
4361       CheckDecimalLiteralWithLeadingZero(use_counts_, scope->start_position(),
4362                                          scope->end_position());
4363     }
4364     if (is_sloppy(language_mode)) {
4365       InsertSloppyBlockFunctionVarBindings(scope, CHECK_OK);
4366     }
4367     CheckConflictingVarDeclarations(scope, CHECK_OK);
4368 
4369     if (body) {
4370       // If body can be inspected, rewrite queued destructuring assignments
4371       ParserTraits::RewriteDestructuringAssignments();
4372     }
4373     has_duplicate_parameters =
4374       !formals_classifier.is_valid_formal_parameter_list_without_duplicates();
4375   }
4376 
4377   FunctionLiteral::ParameterFlag duplicate_parameters =
4378       has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
4379                                : FunctionLiteral::kNoDuplicateParameters;
4380 
4381   FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
4382       function_name, scope, body, materialized_literal_count,
4383       expected_property_count, arity, duplicate_parameters, function_type,
4384       eager_compile_hint, kind, pos);
4385   function_literal->set_function_token_position(function_token_pos);
4386   if (should_be_used_once_hint)
4387     function_literal->set_should_be_used_once_hint();
4388 
4389   if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
4390   return function_literal;
4391 }
4392 
ParseAsyncFunctionExpression(bool * ok)4393 Expression* Parser::ParseAsyncFunctionExpression(bool* ok) {
4394   // AsyncFunctionDeclaration ::
4395   //   async [no LineTerminator here] function ( FormalParameters[Await] )
4396   //       { AsyncFunctionBody }
4397   //
4398   //   async [no LineTerminator here] function BindingIdentifier[Await]
4399   //       ( FormalParameters[Await] ) { AsyncFunctionBody }
4400   DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
4401   int pos = position();
4402   Expect(Token::FUNCTION, CHECK_OK);
4403   bool is_strict_reserved = false;
4404   const AstRawString* name = nullptr;
4405   FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression;
4406 
4407   if (peek_any_identifier()) {
4408     type = FunctionLiteral::kNamedExpression;
4409     name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
4410     if (this->IsAwait(name)) {
4411       ReportMessageAt(scanner()->location(),
4412                       MessageTemplate::kAwaitBindingIdentifier);
4413       *ok = false;
4414       return nullptr;
4415     }
4416   }
4417   return ParseFunctionLiteral(name, scanner()->location(),
4418                               is_strict_reserved ? kFunctionNameIsStrictReserved
4419                                                  : kFunctionNameValidityUnknown,
4420                               FunctionKind::kAsyncFunction, pos, type,
4421                               language_mode(), CHECK_OK);
4422 }
4423 
SkipLazyFunctionBody(int * materialized_literal_count,int * expected_property_count,bool * ok,Scanner::BookmarkScope * bookmark)4424 void Parser::SkipLazyFunctionBody(int* materialized_literal_count,
4425                                   int* expected_property_count, bool* ok,
4426                                   Scanner::BookmarkScope* bookmark) {
4427   DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet());
4428   if (produce_cached_parse_data()) CHECK(log_);
4429 
4430   int function_block_pos = position();
4431   if (consume_cached_parse_data() && !cached_parse_data_->rejected()) {
4432     // If we have cached data, we use it to skip parsing the function body. The
4433     // data contains the information we need to construct the lazy function.
4434     FunctionEntry entry =
4435         cached_parse_data_->GetFunctionEntry(function_block_pos);
4436     // Check that cached data is valid. If not, mark it as invalid (the embedder
4437     // handles it). Note that end position greater than end of stream is safe,
4438     // and hard to check.
4439     if (entry.is_valid() && entry.end_pos() > function_block_pos) {
4440       scanner()->SeekForward(entry.end_pos() - 1);
4441 
4442       scope_->set_end_position(entry.end_pos());
4443       Expect(Token::RBRACE, ok);
4444       if (!*ok) {
4445         return;
4446       }
4447       total_preparse_skipped_ += scope_->end_position() - function_block_pos;
4448       *materialized_literal_count = entry.literal_count();
4449       *expected_property_count = entry.property_count();
4450       SetLanguageMode(scope_, entry.language_mode());
4451       if (entry.uses_super_property()) scope_->RecordSuperPropertyUsage();
4452       if (entry.calls_eval()) scope_->RecordEvalCall();
4453       return;
4454     }
4455     cached_parse_data_->Reject();
4456   }
4457   // With no cached data, we partially parse the function, without building an
4458   // AST. This gathers the data needed to build a lazy function.
4459   SingletonLogger logger;
4460   PreParser::PreParseResult result =
4461       ParseLazyFunctionBodyWithPreParser(&logger, bookmark);
4462   if (bookmark && bookmark->HasBeenReset()) {
4463     return;  // Return immediately if pre-parser devided to abort parsing.
4464   }
4465   if (result == PreParser::kPreParseStackOverflow) {
4466     // Propagate stack overflow.
4467     set_stack_overflow();
4468     *ok = false;
4469     return;
4470   }
4471   if (logger.has_error()) {
4472     ParserTraits::ReportMessageAt(
4473         Scanner::Location(logger.start(), logger.end()), logger.message(),
4474         logger.argument_opt(), logger.error_type());
4475     *ok = false;
4476     return;
4477   }
4478   scope_->set_end_position(logger.end());
4479   Expect(Token::RBRACE, ok);
4480   if (!*ok) {
4481     return;
4482   }
4483   total_preparse_skipped_ += scope_->end_position() - function_block_pos;
4484   *materialized_literal_count = logger.literals();
4485   *expected_property_count = logger.properties();
4486   SetLanguageMode(scope_, logger.language_mode());
4487   if (logger.uses_super_property()) {
4488     scope_->RecordSuperPropertyUsage();
4489   }
4490   if (logger.calls_eval()) {
4491     scope_->RecordEvalCall();
4492   }
4493   if (produce_cached_parse_data()) {
4494     DCHECK(log_);
4495     // Position right after terminal '}'.
4496     int body_end = scanner()->location().end_pos;
4497     log_->LogFunction(function_block_pos, body_end, *materialized_literal_count,
4498                       *expected_property_count, scope_->language_mode(),
4499                       scope_->uses_super_property(), scope_->calls_eval());
4500   }
4501 }
4502 
4503 
BuildAssertIsCoercible(Variable * var)4504 Statement* Parser::BuildAssertIsCoercible(Variable* var) {
4505   // if (var === null || var === undefined)
4506   //     throw /* type error kNonCoercible) */;
4507 
4508   Expression* condition = factory()->NewBinaryOperation(
4509       Token::OR, factory()->NewCompareOperation(
4510                      Token::EQ_STRICT, factory()->NewVariableProxy(var),
4511                      factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
4512                      RelocInfo::kNoPosition),
4513       factory()->NewCompareOperation(
4514           Token::EQ_STRICT, factory()->NewVariableProxy(var),
4515           factory()->NewNullLiteral(RelocInfo::kNoPosition),
4516           RelocInfo::kNoPosition),
4517       RelocInfo::kNoPosition);
4518   Expression* throw_type_error = this->NewThrowTypeError(
4519       MessageTemplate::kNonCoercible, ast_value_factory()->empty_string(),
4520       RelocInfo::kNoPosition);
4521   IfStatement* if_statement = factory()->NewIfStatement(
4522       condition, factory()->NewExpressionStatement(throw_type_error,
4523                                                    RelocInfo::kNoPosition),
4524       factory()->NewEmptyStatement(RelocInfo::kNoPosition),
4525       RelocInfo::kNoPosition);
4526   return if_statement;
4527 }
4528 
4529 
4530 class InitializerRewriter : public AstExpressionVisitor {
4531  public:
InitializerRewriter(uintptr_t stack_limit,Expression * root,Parser * parser,Scope * scope)4532   InitializerRewriter(uintptr_t stack_limit, Expression* root, Parser* parser,
4533                       Scope* scope)
4534       : AstExpressionVisitor(stack_limit, root),
4535         parser_(parser),
4536         scope_(scope) {}
4537 
4538  private:
VisitExpression(Expression * expr)4539   void VisitExpression(Expression* expr) override {
4540     RewritableExpression* to_rewrite = expr->AsRewritableExpression();
4541     if (to_rewrite == nullptr || to_rewrite->is_rewritten()) return;
4542 
4543     Parser::PatternRewriter::RewriteDestructuringAssignment(parser_, to_rewrite,
4544                                                             scope_);
4545   }
4546 
4547   // Code in function literals does not need to be eagerly rewritten, it will be
4548   // rewritten when scheduled.
VisitFunctionLiteral(FunctionLiteral * expr)4549   void VisitFunctionLiteral(FunctionLiteral* expr) override {}
4550 
4551  private:
4552   Parser* parser_;
4553   Scope* scope_;
4554 };
4555 
4556 
RewriteParameterInitializer(Expression * expr,Scope * scope)4557 void Parser::RewriteParameterInitializer(Expression* expr, Scope* scope) {
4558   InitializerRewriter rewriter(stack_limit_, expr, this, scope);
4559   rewriter.Run();
4560 }
4561 
4562 
BuildParameterInitializationBlock(const ParserFormalParameters & parameters,bool * ok)4563 Block* Parser::BuildParameterInitializationBlock(
4564     const ParserFormalParameters& parameters, bool* ok) {
4565   DCHECK(!parameters.is_simple);
4566   DCHECK(scope_->is_function_scope());
4567   Block* init_block =
4568       factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
4569   for (int i = 0; i < parameters.params.length(); ++i) {
4570     auto parameter = parameters.params[i];
4571     if (parameter.is_rest && parameter.pattern->IsVariableProxy()) break;
4572     DeclarationDescriptor descriptor;
4573     descriptor.declaration_kind = DeclarationDescriptor::PARAMETER;
4574     descriptor.parser = this;
4575     descriptor.scope = scope_;
4576     descriptor.hoist_scope = nullptr;
4577     descriptor.mode = LET;
4578     descriptor.declaration_pos = parameter.pattern->position();
4579     // The position that will be used by the AssignmentExpression
4580     // which copies from the temp parameter to the pattern.
4581     //
4582     // TODO(adamk): Should this be RelocInfo::kNoPosition, since
4583     // it's just copying from a temp var to the real param var?
4584     descriptor.initialization_pos = parameter.pattern->position();
4585     // The initializer position which will end up in,
4586     // Variable::initializer_position(), used for hole check elimination.
4587     int initializer_position = parameter.pattern->position();
4588     Expression* initial_value =
4589         factory()->NewVariableProxy(parameters.scope->parameter(i));
4590     if (parameter.initializer != nullptr) {
4591       // IS_UNDEFINED($param) ? initializer : $param
4592 
4593       // Ensure initializer is rewritten
4594       RewriteParameterInitializer(parameter.initializer, scope_);
4595 
4596       auto condition = factory()->NewCompareOperation(
4597           Token::EQ_STRICT,
4598           factory()->NewVariableProxy(parameters.scope->parameter(i)),
4599           factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
4600           RelocInfo::kNoPosition);
4601       initial_value = factory()->NewConditional(
4602           condition, parameter.initializer, initial_value,
4603           RelocInfo::kNoPosition);
4604       descriptor.initialization_pos = parameter.initializer->position();
4605       initializer_position = parameter.initializer_end_position;
4606     }
4607 
4608     Scope* param_scope = scope_;
4609     Block* param_block = init_block;
4610     if (!parameter.is_simple() && scope_->calls_sloppy_eval()) {
4611       param_scope = NewScope(scope_, BLOCK_SCOPE);
4612       param_scope->set_is_declaration_scope();
4613       param_scope->set_start_position(descriptor.initialization_pos);
4614       param_scope->set_end_position(parameter.initializer_end_position);
4615       param_scope->RecordEvalCall();
4616       param_block = factory()->NewBlock(NULL, 8, true, RelocInfo::kNoPosition);
4617       param_block->set_scope(param_scope);
4618       descriptor.hoist_scope = scope_;
4619       // Pass the appropriate scope in so that PatternRewriter can appropriately
4620       // rewrite inner initializers of the pattern to param_scope
4621       descriptor.scope = param_scope;
4622       // Rewrite the outer initializer to point to param_scope
4623       RewriteParameterInitializerScope(stack_limit(), initial_value, scope_,
4624                                        param_scope);
4625     }
4626 
4627     {
4628       BlockState block_state(&scope_, param_scope);
4629       DeclarationParsingResult::Declaration decl(
4630           parameter.pattern, initializer_position, initial_value);
4631       PatternRewriter::DeclareAndInitializeVariables(param_block, &descriptor,
4632                                                      &decl, nullptr, CHECK_OK);
4633     }
4634 
4635     if (!parameter.is_simple() && scope_->calls_sloppy_eval()) {
4636       param_scope = param_scope->FinalizeBlockScope();
4637       if (param_scope != nullptr) {
4638         CheckConflictingVarDeclarations(param_scope, CHECK_OK);
4639       }
4640       init_block->statements()->Add(param_block, zone());
4641     }
4642   }
4643   return init_block;
4644 }
4645 
BuildRejectPromiseOnException(Block * block)4646 Block* Parser::BuildRejectPromiseOnException(Block* block) {
4647   // try { <block> } catch (error) { return Promise.reject(error); }
4648   Block* try_block = block;
4649   Scope* catch_scope = NewScope(scope_, CATCH_SCOPE);
4650   catch_scope->set_is_hidden();
4651   Variable* catch_variable =
4652       catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR,
4653                                 kCreatedInitialized, Variable::NORMAL);
4654   Block* catch_block =
4655       factory()->NewBlock(nullptr, 1, true, RelocInfo::kNoPosition);
4656 
4657   Expression* promise_reject = BuildPromiseReject(
4658       factory()->NewVariableProxy(catch_variable), RelocInfo::kNoPosition);
4659 
4660   ReturnStatement* return_promise_reject =
4661       factory()->NewReturnStatement(promise_reject, RelocInfo::kNoPosition);
4662   catch_block->statements()->Add(return_promise_reject, zone());
4663   TryStatement* try_catch_statement =
4664       factory()->NewTryCatchStatement(try_block, catch_scope, catch_variable,
4665                                       catch_block, RelocInfo::kNoPosition);
4666 
4667   block = factory()->NewBlock(nullptr, 1, true, RelocInfo::kNoPosition);
4668   block->statements()->Add(try_catch_statement, zone());
4669   return block;
4670 }
4671 
BuildCreateJSGeneratorObject(int pos,FunctionKind kind)4672 Expression* Parser::BuildCreateJSGeneratorObject(int pos, FunctionKind kind) {
4673   DCHECK_NOT_NULL(function_state_->generator_object_variable());
4674   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
4675   args->Add(factory()->NewThisFunction(pos), zone());
4676   args->Add(IsArrowFunction(kind)
4677                 ? GetLiteralUndefined(pos)
4678                 : ThisExpression(scope_, factory(), RelocInfo::kNoPosition),
4679             zone());
4680   return factory()->NewCallRuntime(Runtime::kCreateJSGeneratorObject, args,
4681                                    pos);
4682 }
4683 
BuildPromiseResolve(Expression * value,int pos)4684 Expression* Parser::BuildPromiseResolve(Expression* value, int pos) {
4685   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
4686   args->Add(value, zone());
4687   return factory()->NewCallRuntime(Context::PROMISE_CREATE_RESOLVED_INDEX, args,
4688                                    pos);
4689 }
4690 
BuildPromiseReject(Expression * value,int pos)4691 Expression* Parser::BuildPromiseReject(Expression* value, int pos) {
4692   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
4693   args->Add(value, zone());
4694   return factory()->NewCallRuntime(Context::PROMISE_CREATE_REJECTED_INDEX, args,
4695                                    pos);
4696 }
4697 
ParseEagerFunctionBody(const AstRawString * function_name,int pos,const ParserFormalParameters & parameters,FunctionKind kind,FunctionLiteral::FunctionType function_type,bool * ok)4698 ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
4699     const AstRawString* function_name, int pos,
4700     const ParserFormalParameters& parameters, FunctionKind kind,
4701     FunctionLiteral::FunctionType function_type, bool* ok) {
4702   // Everything inside an eagerly parsed function will be parsed eagerly
4703   // (see comment above).
4704   ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
4705   ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone());
4706 
4707   static const int kFunctionNameAssignmentIndex = 0;
4708   if (function_type == FunctionLiteral::kNamedExpression) {
4709     DCHECK(function_name != NULL);
4710     // If we have a named function expression, we add a local variable
4711     // declaration to the body of the function with the name of the
4712     // function and let it refer to the function itself (closure).
4713     // Not having parsed the function body, the language mode may still change,
4714     // so we reserve a spot and create the actual const assignment later.
4715     DCHECK_EQ(kFunctionNameAssignmentIndex, result->length());
4716     result->Add(NULL, zone());
4717   }
4718 
4719   ZoneList<Statement*>* body = result;
4720   Scope* inner_scope = scope_;
4721   Block* inner_block = nullptr;
4722   if (!parameters.is_simple) {
4723     inner_scope = NewScope(scope_, BLOCK_SCOPE);
4724     inner_scope->set_is_declaration_scope();
4725     inner_scope->set_start_position(scanner()->location().beg_pos);
4726     inner_block = factory()->NewBlock(NULL, 8, true, RelocInfo::kNoPosition);
4727     inner_block->set_scope(inner_scope);
4728     body = inner_block->statements();
4729   }
4730 
4731   {
4732     BlockState block_state(&scope_, inner_scope);
4733 
4734     if (IsGeneratorFunction(kind)) {
4735       // We produce:
4736       //
4737       // try { InitialYield; ...body...; return {value: undefined, done: true} }
4738       // finally { %_GeneratorClose(generator) }
4739       //
4740       // - InitialYield yields the actual generator object.
4741       // - Any return statement inside the body will have its argument wrapped
4742       //   in a "done" iterator result object.
4743       // - If the generator terminates for whatever reason, we must close it.
4744       //   Hence the finally clause.
4745 
4746       Block* try_block =
4747           factory()->NewBlock(nullptr, 3, false, RelocInfo::kNoPosition);
4748 
4749       {
4750         Expression* allocation = BuildCreateJSGeneratorObject(pos, kind);
4751         VariableProxy* init_proxy = factory()->NewVariableProxy(
4752             function_state_->generator_object_variable());
4753         Assignment* assignment = factory()->NewAssignment(
4754             Token::INIT, init_proxy, allocation, RelocInfo::kNoPosition);
4755         VariableProxy* get_proxy = factory()->NewVariableProxy(
4756             function_state_->generator_object_variable());
4757         // The position of the yield is important for reporting the exception
4758         // caused by calling the .throw method on a generator suspended at the
4759         // initial yield (i.e. right after generator instantiation).
4760         Yield* yield = factory()->NewYield(get_proxy, assignment,
4761                                            scope_->start_position());
4762         try_block->statements()->Add(
4763             factory()->NewExpressionStatement(yield, RelocInfo::kNoPosition),
4764             zone());
4765       }
4766 
4767       ParseStatementList(try_block->statements(), Token::RBRACE, CHECK_OK);
4768 
4769       Statement* final_return = factory()->NewReturnStatement(
4770           BuildIteratorResult(nullptr, true), RelocInfo::kNoPosition);
4771       try_block->statements()->Add(final_return, zone());
4772 
4773       Block* finally_block =
4774           factory()->NewBlock(nullptr, 1, false, RelocInfo::kNoPosition);
4775       ZoneList<Expression*>* args =
4776           new (zone()) ZoneList<Expression*>(1, zone());
4777       VariableProxy* call_proxy = factory()->NewVariableProxy(
4778           function_state_->generator_object_variable());
4779       args->Add(call_proxy, zone());
4780       Expression* call = factory()->NewCallRuntime(
4781           Runtime::kInlineGeneratorClose, args, RelocInfo::kNoPosition);
4782       finally_block->statements()->Add(
4783           factory()->NewExpressionStatement(call, RelocInfo::kNoPosition),
4784           zone());
4785 
4786       body->Add(factory()->NewTryFinallyStatement(try_block, finally_block,
4787                                                   RelocInfo::kNoPosition),
4788                 zone());
4789     } else if (IsAsyncFunction(kind)) {
4790       const bool accept_IN = true;
4791       DesugarAsyncFunctionBody(function_name, inner_scope, body, nullptr, kind,
4792                                FunctionBody::Normal, accept_IN, pos, CHECK_OK);
4793     } else {
4794       ParseStatementList(body, Token::RBRACE, CHECK_OK);
4795     }
4796 
4797     if (IsSubclassConstructor(kind)) {
4798       body->Add(
4799           factory()->NewReturnStatement(
4800               this->ThisExpression(scope_, factory(), RelocInfo::kNoPosition),
4801               RelocInfo::kNoPosition),
4802               zone());
4803     }
4804   }
4805 
4806   Expect(Token::RBRACE, CHECK_OK);
4807   scope_->set_end_position(scanner()->location().end_pos);
4808 
4809   if (!parameters.is_simple) {
4810     DCHECK_NOT_NULL(inner_scope);
4811     DCHECK_EQ(body, inner_block->statements());
4812     SetLanguageMode(scope_, inner_scope->language_mode());
4813     Block* init_block = BuildParameterInitializationBlock(parameters, CHECK_OK);
4814 
4815     if (IsAsyncFunction(kind)) {
4816       init_block = BuildRejectPromiseOnException(init_block);
4817     }
4818 
4819     DCHECK_NOT_NULL(init_block);
4820 
4821     inner_scope->set_end_position(scanner()->location().end_pos);
4822     inner_scope = inner_scope->FinalizeBlockScope();
4823     if (inner_scope != nullptr) {
4824       CheckConflictingVarDeclarations(inner_scope, CHECK_OK);
4825       InsertShadowingVarBindingInitializers(inner_block);
4826     }
4827 
4828     result->Add(init_block, zone());
4829     result->Add(inner_block, zone());
4830   }
4831 
4832   if (function_type == FunctionLiteral::kNamedExpression) {
4833     // Now that we know the language mode, we can create the const assignment
4834     // in the previously reserved spot.
4835     // NOTE: We create a proxy and resolve it here so that in the
4836     // future we can change the AST to only refer to VariableProxies
4837     // instead of Variables and Proxies as is the case now.
4838     VariableMode fvar_mode = is_strict(language_mode()) ? CONST : CONST_LEGACY;
4839     Variable* fvar = new (zone())
4840         Variable(scope_, function_name, fvar_mode, Variable::NORMAL,
4841                  kCreatedInitialized, kNotAssigned);
4842     VariableProxy* proxy = factory()->NewVariableProxy(fvar);
4843     VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration(
4844         proxy, fvar_mode, scope_, RelocInfo::kNoPosition);
4845     scope_->DeclareFunctionVar(fvar_declaration);
4846 
4847     VariableProxy* fproxy = factory()->NewVariableProxy(fvar);
4848     result->Set(kFunctionNameAssignmentIndex,
4849                 factory()->NewExpressionStatement(
4850                     factory()->NewAssignment(Token::INIT, fproxy,
4851                                              factory()->NewThisFunction(pos),
4852                                              RelocInfo::kNoPosition),
4853                     RelocInfo::kNoPosition));
4854   }
4855 
4856   MarkCollectedTailCallExpressions();
4857   return result;
4858 }
4859 
4860 
ParseLazyFunctionBodyWithPreParser(SingletonLogger * logger,Scanner::BookmarkScope * bookmark)4861 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
4862     SingletonLogger* logger, Scanner::BookmarkScope* bookmark) {
4863   // This function may be called on a background thread too; record only the
4864   // main thread preparse times.
4865   if (pre_parse_timer_ != NULL) {
4866     pre_parse_timer_->Start();
4867   }
4868   TRACE_EVENT0("v8", "V8.PreParse");
4869 
4870   DCHECK_EQ(Token::LBRACE, scanner()->current_token());
4871 
4872   if (reusable_preparser_ == NULL) {
4873     reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(),
4874                                         NULL, stack_limit_);
4875     reusable_preparser_->set_allow_lazy(true);
4876 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name());
4877     SET_ALLOW(natives);
4878     SET_ALLOW(harmony_do_expressions);
4879     SET_ALLOW(harmony_for_in);
4880     SET_ALLOW(harmony_function_sent);
4881     SET_ALLOW(harmony_exponentiation_operator);
4882     SET_ALLOW(harmony_restrictive_declarations);
4883     SET_ALLOW(harmony_async_await);
4884 #undef SET_ALLOW
4885   }
4886   PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(
4887       language_mode(), function_state_->kind(), scope_->has_simple_parameters(),
4888       parsing_module_, logger, bookmark, use_counts_);
4889   if (pre_parse_timer_ != NULL) {
4890     pre_parse_timer_->Stop();
4891   }
4892   return result;
4893 }
4894 
ParseClassLiteral(ExpressionClassifier * classifier,const AstRawString * name,Scanner::Location class_name_location,bool name_is_strict_reserved,int pos,bool * ok)4895 ClassLiteral* Parser::ParseClassLiteral(ExpressionClassifier* classifier,
4896                                         const AstRawString* name,
4897                                         Scanner::Location class_name_location,
4898                                         bool name_is_strict_reserved, int pos,
4899                                         bool* ok) {
4900   // All parts of a ClassDeclaration and ClassExpression are strict code.
4901   if (name_is_strict_reserved) {
4902     ReportMessageAt(class_name_location,
4903                     MessageTemplate::kUnexpectedStrictReserved);
4904     *ok = false;
4905     return NULL;
4906   }
4907   if (IsEvalOrArguments(name)) {
4908     ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments);
4909     *ok = false;
4910     return NULL;
4911   }
4912 
4913   Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
4914   BlockState block_state(&scope_, block_scope);
4915   RaiseLanguageMode(STRICT);
4916   scope_->SetScopeName(name);
4917 
4918   VariableProxy* proxy = NULL;
4919   if (name != NULL) {
4920     proxy = NewUnresolved(name, CONST);
4921     Declaration* declaration =
4922         factory()->NewVariableDeclaration(proxy, CONST, block_scope, pos);
4923     Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
4924   }
4925 
4926   Expression* extends = NULL;
4927   if (Check(Token::EXTENDS)) {
4928     block_scope->set_start_position(scanner()->location().end_pos);
4929     ExpressionClassifier extends_classifier(this);
4930     extends = ParseLeftHandSideExpression(&extends_classifier, CHECK_OK);
4931     CheckNoTailCallExpressions(&extends_classifier, CHECK_OK);
4932     RewriteNonPattern(&extends_classifier, CHECK_OK);
4933     if (classifier != nullptr) {
4934       classifier->Accumulate(&extends_classifier,
4935                              ExpressionClassifier::ExpressionProductions);
4936     }
4937   } else {
4938     block_scope->set_start_position(scanner()->location().end_pos);
4939   }
4940 
4941 
4942   ClassLiteralChecker checker(this);
4943   ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone());
4944   FunctionLiteral* constructor = NULL;
4945   bool has_seen_constructor = false;
4946 
4947   Expect(Token::LBRACE, CHECK_OK);
4948 
4949   const bool has_extends = extends != nullptr;
4950   while (peek() != Token::RBRACE) {
4951     if (Check(Token::SEMICOLON)) continue;
4952     FuncNameInferrer::State fni_state(fni_);
4953     const bool in_class = true;
4954     bool is_computed_name = false;  // Classes do not care about computed
4955                                     // property names here.
4956     ExpressionClassifier property_classifier(this);
4957     const AstRawString* property_name = nullptr;
4958     ObjectLiteral::Property* property = ParsePropertyDefinition(
4959         &checker, in_class, has_extends, MethodKind::Normal, &is_computed_name,
4960         &has_seen_constructor, &property_classifier, &property_name, CHECK_OK);
4961     RewriteNonPattern(&property_classifier, CHECK_OK);
4962     if (classifier != nullptr) {
4963       classifier->Accumulate(&property_classifier,
4964                              ExpressionClassifier::ExpressionProductions);
4965     }
4966 
4967     if (has_seen_constructor && constructor == NULL) {
4968       constructor = GetPropertyValue(property)->AsFunctionLiteral();
4969       DCHECK_NOT_NULL(constructor);
4970       constructor->set_raw_name(
4971           name != nullptr ? name : ast_value_factory()->empty_string());
4972     } else {
4973       properties->Add(property, zone());
4974     }
4975 
4976     if (fni_ != NULL) fni_->Infer();
4977 
4978     if (property_name != ast_value_factory()->constructor_string()) {
4979       SetFunctionNameFromPropertyName(property, property_name);
4980     }
4981   }
4982 
4983   Expect(Token::RBRACE, CHECK_OK);
4984   int end_pos = scanner()->location().end_pos;
4985 
4986   if (constructor == NULL) {
4987     constructor = DefaultConstructor(name, has_extends, block_scope, pos,
4988                                      end_pos, block_scope->language_mode());
4989   }
4990 
4991   // Note that we do not finalize this block scope because it is
4992   // used as a sentinel value indicating an anonymous class.
4993   block_scope->set_end_position(end_pos);
4994 
4995   if (name != NULL) {
4996     DCHECK_NOT_NULL(proxy);
4997     proxy->var()->set_initializer_position(end_pos);
4998   }
4999 
5000   return factory()->NewClassLiteral(block_scope, proxy, extends, constructor,
5001                                     properties, pos, end_pos);
5002 }
5003 
5004 
ParseV8Intrinsic(bool * ok)5005 Expression* Parser::ParseV8Intrinsic(bool* ok) {
5006   // CallRuntime ::
5007   //   '%' Identifier Arguments
5008 
5009   int pos = peek_position();
5010   Expect(Token::MOD, CHECK_OK);
5011   // Allow "eval" or "arguments" for backward compatibility.
5012   const AstRawString* name = ParseIdentifier(kAllowRestrictedIdentifiers,
5013                                              CHECK_OK);
5014   Scanner::Location spread_pos;
5015   ExpressionClassifier classifier(this);
5016   ZoneList<Expression*>* args =
5017       ParseArguments(&spread_pos, &classifier, CHECK_OK);
5018 
5019   DCHECK(!spread_pos.IsValid());
5020 
5021   if (extension_ != NULL) {
5022     // The extension structures are only accessible while parsing the
5023     // very first time not when reparsing because of lazy compilation.
5024     scope_->DeclarationScope()->ForceEagerCompilation();
5025   }
5026 
5027   const Runtime::Function* function = Runtime::FunctionForName(name->string());
5028 
5029   if (function != NULL) {
5030     // Check for possible name clash.
5031     DCHECK_EQ(Context::kNotFound,
5032               Context::IntrinsicIndexForName(name->string()));
5033     // Check for built-in IS_VAR macro.
5034     if (function->function_id == Runtime::kIS_VAR) {
5035       DCHECK_EQ(Runtime::RUNTIME, function->intrinsic_type);
5036       // %IS_VAR(x) evaluates to x if x is a variable,
5037       // leads to a parse error otherwise.  Could be implemented as an
5038       // inline function %_IS_VAR(x) to eliminate this special case.
5039       if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
5040         return args->at(0);
5041       } else {
5042         ReportMessage(MessageTemplate::kNotIsvar);
5043         *ok = false;
5044         return NULL;
5045       }
5046     }
5047 
5048     // Check that the expected number of arguments are being passed.
5049     if (function->nargs != -1 && function->nargs != args->length()) {
5050       ReportMessage(MessageTemplate::kRuntimeWrongNumArgs);
5051       *ok = false;
5052       return NULL;
5053     }
5054 
5055     return factory()->NewCallRuntime(function, args, pos);
5056   }
5057 
5058   int context_index = Context::IntrinsicIndexForName(name->string());
5059 
5060   // Check that the function is defined.
5061   if (context_index == Context::kNotFound) {
5062     ParserTraits::ReportMessage(MessageTemplate::kNotDefined, name);
5063     *ok = false;
5064     return NULL;
5065   }
5066 
5067   return factory()->NewCallRuntime(context_index, args, pos);
5068 }
5069 
5070 
GetLiteralUndefined(int position)5071 Literal* Parser::GetLiteralUndefined(int position) {
5072   return factory()->NewUndefinedLiteral(position);
5073 }
5074 
5075 
CheckConflictingVarDeclarations(Scope * scope,bool * ok)5076 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
5077   Declaration* decl = scope->CheckConflictingVarDeclarations();
5078   if (decl != NULL) {
5079     // In ES6, conflicting variable bindings are early errors.
5080     const AstRawString* name = decl->proxy()->raw_name();
5081     int position = decl->proxy()->position();
5082     Scanner::Location location = position == RelocInfo::kNoPosition
5083         ? Scanner::Location::invalid()
5084         : Scanner::Location(position, position + 1);
5085     ParserTraits::ReportMessageAt(location, MessageTemplate::kVarRedeclaration,
5086                                   name);
5087     *ok = false;
5088   }
5089 }
5090 
5091 
InsertShadowingVarBindingInitializers(Block * inner_block)5092 void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) {
5093   // For each var-binding that shadows a parameter, insert an assignment
5094   // initializing the variable with the parameter.
5095   Scope* inner_scope = inner_block->scope();
5096   DCHECK(inner_scope->is_declaration_scope());
5097   Scope* function_scope = inner_scope->outer_scope();
5098   DCHECK(function_scope->is_function_scope());
5099   ZoneList<Declaration*>* decls = inner_scope->declarations();
5100   for (int i = 0; i < decls->length(); ++i) {
5101     Declaration* decl = decls->at(i);
5102     if (decl->mode() != VAR || !decl->IsVariableDeclaration()) continue;
5103     const AstRawString* name = decl->proxy()->raw_name();
5104     Variable* parameter = function_scope->LookupLocal(name);
5105     if (parameter == nullptr) continue;
5106     VariableProxy* to = inner_scope->NewUnresolved(factory(), name);
5107     VariableProxy* from = factory()->NewVariableProxy(parameter);
5108     Expression* assignment = factory()->NewAssignment(
5109         Token::ASSIGN, to, from, RelocInfo::kNoPosition);
5110     Statement* statement = factory()->NewExpressionStatement(
5111         assignment, RelocInfo::kNoPosition);
5112     inner_block->statements()->InsertAt(0, statement, zone());
5113   }
5114 }
5115 
5116 
InsertSloppyBlockFunctionVarBindings(Scope * scope,bool * ok)5117 void Parser::InsertSloppyBlockFunctionVarBindings(Scope* scope, bool* ok) {
5118   // For each variable which is used as a function declaration in a sloppy
5119   // block,
5120   DCHECK(scope->is_declaration_scope());
5121   SloppyBlockFunctionMap* map = scope->sloppy_block_function_map();
5122   for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
5123     AstRawString* name = static_cast<AstRawString*>(p->key);
5124     // If the variable wouldn't conflict with a lexical declaration,
5125     Variable* var = scope->LookupLocal(name);
5126     if (var == nullptr || !IsLexicalVariableMode(var->mode())) {
5127       // Declare a var-style binding for the function in the outer scope
5128       VariableProxy* proxy = scope->NewUnresolved(factory(), name);
5129       Declaration* declaration = factory()->NewVariableDeclaration(
5130           proxy, VAR, scope, RelocInfo::kNoPosition);
5131       Declare(declaration, DeclarationDescriptor::NORMAL, true, ok, scope);
5132       DCHECK(ok);  // Based on the preceding check, this should not fail
5133       if (!ok) return;
5134 
5135       // Write in assignments to var for each block-scoped function declaration
5136       auto delegates = static_cast<SloppyBlockFunctionMap::Vector*>(p->value);
5137       for (SloppyBlockFunctionStatement* delegate : *delegates) {
5138         // Read from the local lexical scope and write to the function scope
5139         VariableProxy* to = scope->NewUnresolved(factory(), name);
5140         VariableProxy* from = delegate->scope()->NewUnresolved(factory(), name);
5141         Expression* assignment = factory()->NewAssignment(
5142             Token::ASSIGN, to, from, RelocInfo::kNoPosition);
5143         Statement* statement = factory()->NewExpressionStatement(
5144             assignment, RelocInfo::kNoPosition);
5145         delegate->set_statement(statement);
5146       }
5147     }
5148   }
5149 }
5150 
5151 
5152 // ----------------------------------------------------------------------------
5153 // Parser support
5154 
TargetStackContainsLabel(const AstRawString * label)5155 bool Parser::TargetStackContainsLabel(const AstRawString* label) {
5156   for (Target* t = target_stack_; t != NULL; t = t->previous()) {
5157     if (ContainsLabel(t->statement()->labels(), label)) return true;
5158   }
5159   return false;
5160 }
5161 
5162 
LookupBreakTarget(const AstRawString * label,bool * ok)5163 BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label,
5164                                               bool* ok) {
5165   bool anonymous = label == NULL;
5166   for (Target* t = target_stack_; t != NULL; t = t->previous()) {
5167     BreakableStatement* stat = t->statement();
5168     if ((anonymous && stat->is_target_for_anonymous()) ||
5169         (!anonymous && ContainsLabel(stat->labels(), label))) {
5170       return stat;
5171     }
5172   }
5173   return NULL;
5174 }
5175 
5176 
LookupContinueTarget(const AstRawString * label,bool * ok)5177 IterationStatement* Parser::LookupContinueTarget(const AstRawString* label,
5178                                                  bool* ok) {
5179   bool anonymous = label == NULL;
5180   for (Target* t = target_stack_; t != NULL; t = t->previous()) {
5181     IterationStatement* stat = t->statement()->AsIterationStatement();
5182     if (stat == NULL) continue;
5183 
5184     DCHECK(stat->is_target_for_anonymous());
5185     if (anonymous || ContainsLabel(stat->labels(), label)) {
5186       return stat;
5187     }
5188   }
5189   return NULL;
5190 }
5191 
5192 
HandleSourceURLComments(Isolate * isolate,Handle<Script> script)5193 void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) {
5194   if (scanner_.source_url()->length() > 0) {
5195     Handle<String> source_url = scanner_.source_url()->Internalize(isolate);
5196     script->set_source_url(*source_url);
5197   }
5198   if (scanner_.source_mapping_url()->length() > 0) {
5199     Handle<String> source_mapping_url =
5200         scanner_.source_mapping_url()->Internalize(isolate);
5201     script->set_source_mapping_url(*source_mapping_url);
5202   }
5203 }
5204 
5205 
Internalize(Isolate * isolate,Handle<Script> script,bool error)5206 void Parser::Internalize(Isolate* isolate, Handle<Script> script, bool error) {
5207   // Internalize strings.
5208   ast_value_factory()->Internalize(isolate);
5209 
5210   // Error processing.
5211   if (error) {
5212     if (stack_overflow()) {
5213       isolate->StackOverflow();
5214     } else {
5215       DCHECK(pending_error_handler_.has_pending_error());
5216       pending_error_handler_.ThrowPendingError(isolate, script);
5217     }
5218   }
5219 
5220   // Move statistics to Isolate.
5221   for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
5222        ++feature) {
5223     if (use_counts_[feature] > 0) {
5224       isolate->CountUsage(v8::Isolate::UseCounterFeature(feature));
5225     }
5226   }
5227   if (scanner_.FoundHtmlComment()) {
5228     isolate->CountUsage(v8::Isolate::kHtmlComment);
5229     if (script->line_offset() == 0 && script->column_offset() == 0) {
5230       isolate->CountUsage(v8::Isolate::kHtmlCommentInExternalScript);
5231     }
5232   }
5233   isolate->counters()->total_preparse_skipped()->Increment(
5234       total_preparse_skipped_);
5235 }
5236 
5237 
5238 // ----------------------------------------------------------------------------
5239 // The Parser interface.
5240 
5241 
ParseStatic(ParseInfo * info)5242 bool Parser::ParseStatic(ParseInfo* info) {
5243   Parser parser(info);
5244   if (parser.Parse(info)) {
5245     info->set_language_mode(info->literal()->language_mode());
5246     return true;
5247   }
5248   return false;
5249 }
5250 
5251 
Parse(ParseInfo * info)5252 bool Parser::Parse(ParseInfo* info) {
5253   DCHECK(info->literal() == NULL);
5254   FunctionLiteral* result = NULL;
5255   // Ok to use Isolate here; this function is only called in the main thread.
5256   DCHECK(parsing_on_main_thread_);
5257   Isolate* isolate = info->isolate();
5258   pre_parse_timer_ = isolate->counters()->pre_parse();
5259   if (FLAG_trace_parse || allow_natives() || extension_ != NULL) {
5260     // If intrinsics are allowed, the Parser cannot operate independent of the
5261     // V8 heap because of Runtime. Tell the string table to internalize strings
5262     // and values right after they're created.
5263     ast_value_factory()->Internalize(isolate);
5264   }
5265 
5266   if (info->is_lazy()) {
5267     DCHECK(!info->is_eval());
5268     if (info->shared_info()->is_function()) {
5269       result = ParseLazy(isolate, info);
5270     } else {
5271       result = ParseProgram(isolate, info);
5272     }
5273   } else {
5274     SetCachedData(info);
5275     result = ParseProgram(isolate, info);
5276   }
5277   info->set_literal(result);
5278 
5279   Internalize(isolate, info->script(), result == NULL);
5280   DCHECK(ast_value_factory()->IsInternalized());
5281   return (result != NULL);
5282 }
5283 
5284 
ParseOnBackground(ParseInfo * info)5285 void Parser::ParseOnBackground(ParseInfo* info) {
5286   parsing_on_main_thread_ = false;
5287 
5288   DCHECK(info->literal() == NULL);
5289   FunctionLiteral* result = NULL;
5290   fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
5291 
5292   CompleteParserRecorder recorder;
5293   if (produce_cached_parse_data()) log_ = &recorder;
5294 
5295   DCHECK(info->source_stream() != NULL);
5296   ExternalStreamingStream stream(info->source_stream(),
5297                                  info->source_stream_encoding());
5298   scanner_.Initialize(&stream);
5299   DCHECK(info->context().is_null() || info->context()->IsNativeContext());
5300 
5301   // When streaming, we don't know the length of the source until we have parsed
5302   // it. The raw data can be UTF-8, so we wouldn't know the source length until
5303   // we have decoded it anyway even if we knew the raw data length (which we
5304   // don't). We work around this by storing all the scopes which need their end
5305   // position set at the end of the script (the top scope and possible eval
5306   // scopes) and set their end position after we know the script length.
5307   result = DoParseProgram(info);
5308 
5309   info->set_literal(result);
5310 
5311   // We cannot internalize on a background thread; a foreground task will take
5312   // care of calling Parser::Internalize just before compilation.
5313 
5314   if (produce_cached_parse_data()) {
5315     if (result != NULL) *info->cached_data() = recorder.GetScriptData();
5316     log_ = NULL;
5317   }
5318 }
5319 
5320 
OpenTemplateLiteral(int pos)5321 ParserTraits::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
5322   return new (zone()) ParserTraits::TemplateLiteral(zone(), pos);
5323 }
5324 
5325 
AddTemplateSpan(TemplateLiteralState * state,bool tail)5326 void Parser::AddTemplateSpan(TemplateLiteralState* state, bool tail) {
5327   int pos = scanner()->location().beg_pos;
5328   int end = scanner()->location().end_pos - (tail ? 1 : 2);
5329   const AstRawString* tv = scanner()->CurrentSymbol(ast_value_factory());
5330   const AstRawString* trv = scanner()->CurrentRawSymbol(ast_value_factory());
5331   Literal* cooked = factory()->NewStringLiteral(tv, pos);
5332   Literal* raw = factory()->NewStringLiteral(trv, pos);
5333   (*state)->AddTemplateSpan(cooked, raw, end, zone());
5334 }
5335 
5336 
AddTemplateExpression(TemplateLiteralState * state,Expression * expression)5337 void Parser::AddTemplateExpression(TemplateLiteralState* state,
5338                                    Expression* expression) {
5339   (*state)->AddExpression(expression, zone());
5340 }
5341 
5342 
CloseTemplateLiteral(TemplateLiteralState * state,int start,Expression * tag)5343 Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
5344                                          Expression* tag) {
5345   TemplateLiteral* lit = *state;
5346   int pos = lit->position();
5347   const ZoneList<Expression*>* cooked_strings = lit->cooked();
5348   const ZoneList<Expression*>* raw_strings = lit->raw();
5349   const ZoneList<Expression*>* expressions = lit->expressions();
5350   DCHECK_EQ(cooked_strings->length(), raw_strings->length());
5351   DCHECK_EQ(cooked_strings->length(), expressions->length() + 1);
5352 
5353   if (!tag) {
5354     // Build tree of BinaryOps to simplify code-generation
5355     Expression* expr = cooked_strings->at(0);
5356     int i = 0;
5357     while (i < expressions->length()) {
5358       Expression* sub = expressions->at(i++);
5359       Expression* cooked_str = cooked_strings->at(i);
5360 
5361       // Let middle be ToString(sub).
5362       ZoneList<Expression*>* args =
5363           new (zone()) ZoneList<Expression*>(1, zone());
5364       args->Add(sub, zone());
5365       Expression* middle = factory()->NewCallRuntime(Runtime::kInlineToString,
5366                                                      args, sub->position());
5367 
5368       expr = factory()->NewBinaryOperation(
5369           Token::ADD, factory()->NewBinaryOperation(
5370                           Token::ADD, expr, middle, expr->position()),
5371           cooked_str, sub->position());
5372     }
5373     return expr;
5374   } else {
5375     uint32_t hash = ComputeTemplateLiteralHash(lit);
5376 
5377     int cooked_idx = function_state_->NextMaterializedLiteralIndex();
5378     int raw_idx = function_state_->NextMaterializedLiteralIndex();
5379 
5380     // $getTemplateCallSite
5381     ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone());
5382     args->Add(factory()->NewArrayLiteral(
5383                   const_cast<ZoneList<Expression*>*>(cooked_strings),
5384                   cooked_idx, pos),
5385               zone());
5386     args->Add(
5387         factory()->NewArrayLiteral(
5388             const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx, pos),
5389         zone());
5390 
5391     // Ensure hash is suitable as a Smi value
5392     Smi* hash_obj = Smi::cast(Internals::IntToSmi(static_cast<int>(hash)));
5393     args->Add(factory()->NewSmiLiteral(hash_obj->value(), pos), zone());
5394 
5395     Expression* call_site = factory()->NewCallRuntime(
5396         Context::GET_TEMPLATE_CALL_SITE_INDEX, args, start);
5397 
5398     // Call TagFn
5399     ZoneList<Expression*>* call_args =
5400         new (zone()) ZoneList<Expression*>(expressions->length() + 1, zone());
5401     call_args->Add(call_site, zone());
5402     call_args->AddAll(*expressions, zone());
5403     return factory()->NewCall(tag, call_args, pos);
5404   }
5405 }
5406 
5407 
ComputeTemplateLiteralHash(const TemplateLiteral * lit)5408 uint32_t Parser::ComputeTemplateLiteralHash(const TemplateLiteral* lit) {
5409   const ZoneList<Expression*>* raw_strings = lit->raw();
5410   int total = raw_strings->length();
5411   DCHECK(total);
5412 
5413   uint32_t running_hash = 0;
5414 
5415   for (int index = 0; index < total; ++index) {
5416     if (index) {
5417       running_hash = StringHasher::ComputeRunningHashOneByte(
5418           running_hash, "${}", 3);
5419     }
5420 
5421     const AstRawString* raw_string =
5422         raw_strings->at(index)->AsLiteral()->raw_value()->AsString();
5423     if (raw_string->is_one_byte()) {
5424       const char* data = reinterpret_cast<const char*>(raw_string->raw_data());
5425       running_hash = StringHasher::ComputeRunningHashOneByte(
5426           running_hash, data, raw_string->length());
5427     } else {
5428       const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data());
5429       running_hash = StringHasher::ComputeRunningHash(running_hash, data,
5430                                                       raw_string->length());
5431     }
5432   }
5433 
5434   return running_hash;
5435 }
5436 
5437 
PrepareSpreadArguments(ZoneList<v8::internal::Expression * > * list)5438 ZoneList<v8::internal::Expression*>* Parser::PrepareSpreadArguments(
5439     ZoneList<v8::internal::Expression*>* list) {
5440   ZoneList<v8::internal::Expression*>* args =
5441       new (zone()) ZoneList<v8::internal::Expression*>(1, zone());
5442   if (list->length() == 1) {
5443     // Spread-call with single spread argument produces an InternalArray
5444     // containing the values from the array.
5445     //
5446     // Function is called or constructed with the produced array of arguments
5447     //
5448     // EG: Apply(Func, Spread(spread0))
5449     ZoneList<Expression*>* spread_list =
5450         new (zone()) ZoneList<Expression*>(0, zone());
5451     spread_list->Add(list->at(0)->AsSpread()->expression(), zone());
5452     args->Add(factory()->NewCallRuntime(Context::SPREAD_ITERABLE_INDEX,
5453                                         spread_list, RelocInfo::kNoPosition),
5454               zone());
5455     return args;
5456   } else {
5457     // Spread-call with multiple arguments produces array literals for each
5458     // sequences of unspread arguments, and converts each spread iterable to
5459     // an Internal array. Finally, all of these produced arrays are flattened
5460     // into a single InternalArray, containing the arguments for the call.
5461     //
5462     // EG: Apply(Func, Flatten([unspread0, unspread1], Spread(spread0),
5463     //                         Spread(spread1), [unspread2, unspread3]))
5464     int i = 0;
5465     int n = list->length();
5466     while (i < n) {
5467       if (!list->at(i)->IsSpread()) {
5468         ZoneList<v8::internal::Expression*>* unspread =
5469             new (zone()) ZoneList<v8::internal::Expression*>(1, zone());
5470 
5471         // Push array of unspread parameters
5472         while (i < n && !list->at(i)->IsSpread()) {
5473           unspread->Add(list->at(i++), zone());
5474         }
5475         int literal_index = function_state_->NextMaterializedLiteralIndex();
5476         args->Add(factory()->NewArrayLiteral(unspread, literal_index,
5477                                              RelocInfo::kNoPosition),
5478                   zone());
5479 
5480         if (i == n) break;
5481       }
5482 
5483       // Push eagerly spread argument
5484       ZoneList<v8::internal::Expression*>* spread_list =
5485           new (zone()) ZoneList<v8::internal::Expression*>(1, zone());
5486       spread_list->Add(list->at(i++)->AsSpread()->expression(), zone());
5487       args->Add(factory()->NewCallRuntime(Context::SPREAD_ITERABLE_INDEX,
5488                                           spread_list, RelocInfo::kNoPosition),
5489                 zone());
5490     }
5491 
5492     list = new (zone()) ZoneList<v8::internal::Expression*>(1, zone());
5493     list->Add(factory()->NewCallRuntime(Context::SPREAD_ARGUMENTS_INDEX, args,
5494                                         RelocInfo::kNoPosition),
5495               zone());
5496     return list;
5497   }
5498   UNREACHABLE();
5499 }
5500 
5501 
SpreadCall(Expression * function,ZoneList<v8::internal::Expression * > * args,int pos)5502 Expression* Parser::SpreadCall(Expression* function,
5503                                ZoneList<v8::internal::Expression*>* args,
5504                                int pos) {
5505   if (function->IsSuperCallReference()) {
5506     // Super calls
5507     // $super_constructor = %_GetSuperConstructor(<this-function>)
5508     // %reflect_construct($super_constructor, args, new.target)
5509     ZoneList<Expression*>* tmp = new (zone()) ZoneList<Expression*>(1, zone());
5510     tmp->Add(function->AsSuperCallReference()->this_function_var(), zone());
5511     Expression* super_constructor = factory()->NewCallRuntime(
5512         Runtime::kInlineGetSuperConstructor, tmp, pos);
5513     args->InsertAt(0, super_constructor, zone());
5514     args->Add(function->AsSuperCallReference()->new_target_var(), zone());
5515     return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args,
5516                                      pos);
5517   } else {
5518     if (function->IsProperty()) {
5519       // Method calls
5520       if (function->AsProperty()->IsSuperAccess()) {
5521         Expression* home =
5522             ThisExpression(scope_, factory(), RelocInfo::kNoPosition);
5523         args->InsertAt(0, function, zone());
5524         args->InsertAt(1, home, zone());
5525       } else {
5526         Variable* temp =
5527             scope_->NewTemporary(ast_value_factory()->empty_string());
5528         VariableProxy* obj = factory()->NewVariableProxy(temp);
5529         Assignment* assign_obj = factory()->NewAssignment(
5530             Token::ASSIGN, obj, function->AsProperty()->obj(),
5531             RelocInfo::kNoPosition);
5532         function = factory()->NewProperty(
5533             assign_obj, function->AsProperty()->key(), RelocInfo::kNoPosition);
5534         args->InsertAt(0, function, zone());
5535         obj = factory()->NewVariableProxy(temp);
5536         args->InsertAt(1, obj, zone());
5537       }
5538     } else {
5539       // Non-method calls
5540       args->InsertAt(0, function, zone());
5541       args->InsertAt(1, factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
5542                      zone());
5543     }
5544     return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos);
5545   }
5546 }
5547 
5548 
SpreadCallNew(Expression * function,ZoneList<v8::internal::Expression * > * args,int pos)5549 Expression* Parser::SpreadCallNew(Expression* function,
5550                                   ZoneList<v8::internal::Expression*>* args,
5551                                   int pos) {
5552   args->InsertAt(0, function, zone());
5553 
5554   return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos);
5555 }
5556 
5557 
SetLanguageMode(Scope * scope,LanguageMode mode)5558 void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) {
5559   v8::Isolate::UseCounterFeature feature;
5560   if (is_sloppy(mode))
5561     feature = v8::Isolate::kSloppyMode;
5562   else if (is_strict(mode))
5563     feature = v8::Isolate::kStrictMode;
5564   else
5565     UNREACHABLE();
5566   ++use_counts_[feature];
5567   scope->SetLanguageMode(mode);
5568 }
5569 
5570 
RaiseLanguageMode(LanguageMode mode)5571 void Parser::RaiseLanguageMode(LanguageMode mode) {
5572   LanguageMode old = scope_->language_mode();
5573   SetLanguageMode(scope_, old > mode ? old : mode);
5574 }
5575 
MarkCollectedTailCallExpressions()5576 void Parser::MarkCollectedTailCallExpressions() {
5577   const ZoneList<Expression*>& tail_call_expressions =
5578       function_state_->tail_call_expressions().expressions();
5579   for (int i = 0; i < tail_call_expressions.length(); ++i) {
5580     Expression* expression = tail_call_expressions[i];
5581     // If only FLAG_harmony_explicit_tailcalls is enabled then expression
5582     // must be a Call expression.
5583     DCHECK(FLAG_harmony_tailcalls || !FLAG_harmony_explicit_tailcalls ||
5584            expression->IsCall());
5585     MarkTailPosition(expression);
5586   }
5587 }
5588 
ExpressionListToExpression(ZoneList<Expression * > * args)5589 Expression* ParserTraits::ExpressionListToExpression(
5590     ZoneList<Expression*>* args) {
5591   AstNodeFactory* factory = parser_->factory();
5592   Expression* expr = args->at(0);
5593   for (int i = 1; i < args->length(); ++i) {
5594     expr = factory->NewBinaryOperation(Token::COMMA, expr, args->at(i),
5595                                        expr->position());
5596   }
5597   return expr;
5598 }
5599 
RewriteDestructuringAssignments()5600 void ParserTraits::RewriteDestructuringAssignments() {
5601   parser_->RewriteDestructuringAssignments();
5602 }
5603 
RewriteExponentiation(Expression * left,Expression * right,int pos)5604 Expression* ParserTraits::RewriteExponentiation(Expression* left,
5605                                                 Expression* right, int pos) {
5606   return parser_->RewriteExponentiation(left, right, pos);
5607 }
5608 
RewriteAssignExponentiation(Expression * left,Expression * right,int pos)5609 Expression* ParserTraits::RewriteAssignExponentiation(Expression* left,
5610                                                       Expression* right,
5611                                                       int pos) {
5612   return parser_->RewriteAssignExponentiation(left, right, pos);
5613 }
5614 
RewriteNonPattern(Type::ExpressionClassifier * classifier,bool * ok)5615 void ParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier,
5616                                      bool* ok) {
5617   parser_->RewriteNonPattern(classifier, ok);
5618 }
5619 
RewriteAwaitExpression(Expression * value,int await_pos)5620 Expression* ParserTraits::RewriteAwaitExpression(Expression* value,
5621                                                  int await_pos) {
5622   // yield %AsyncFunctionAwait(.generator_object, <operand>)
5623   Variable* generator_object_variable =
5624       parser_->function_state_->generator_object_variable();
5625 
5626   // If generator_object_variable is null,
5627   if (!generator_object_variable) return value;
5628 
5629   auto factory = parser_->factory();
5630   const int nopos = RelocInfo::kNoPosition;
5631 
5632   Variable* temp_var = parser_->scope_->NewTemporary(
5633       parser_->ast_value_factory()->empty_string());
5634   VariableProxy* temp_proxy = factory->NewVariableProxy(temp_var);
5635   Block* do_block = factory->NewBlock(nullptr, 2, false, nopos);
5636 
5637   // Wrap value evaluation to provide a break location.
5638   Expression* value_assignment =
5639       factory->NewAssignment(Token::ASSIGN, temp_proxy, value, nopos);
5640   do_block->statements()->Add(
5641       factory->NewExpressionStatement(value_assignment, value->position()),
5642       zone());
5643 
5644   ZoneList<Expression*>* async_function_await_args =
5645       new (zone()) ZoneList<Expression*>(2, zone());
5646   Expression* generator_object =
5647       factory->NewVariableProxy(generator_object_variable);
5648   async_function_await_args->Add(generator_object, zone());
5649   async_function_await_args->Add(temp_proxy, zone());
5650   Expression* async_function_await = parser_->factory()->NewCallRuntime(
5651       Context::ASYNC_FUNCTION_AWAIT_INDEX, async_function_await_args, nopos);
5652   // Wrap await to provide a break location between value evaluation and yield.
5653   Expression* await_assignment = factory->NewAssignment(
5654       Token::ASSIGN, temp_proxy, async_function_await, nopos);
5655   do_block->statements()->Add(
5656       factory->NewExpressionStatement(await_assignment, await_pos), zone());
5657   Expression* do_expr = factory->NewDoExpression(do_block, temp_var, nopos);
5658 
5659   generator_object = factory->NewVariableProxy(generator_object_variable);
5660   return factory->NewYield(generator_object, do_expr, nopos);
5661 }
5662 
GetNonPatternList() const5663 ZoneList<Expression*>* ParserTraits::GetNonPatternList() const {
5664   return parser_->function_state_->non_patterns_to_rewrite();
5665 }
5666 
5667 
5668 ZoneList<typename ParserTraits::Type::ExpressionClassifier::Error>*
GetReportedErrorList() const5669 ParserTraits::GetReportedErrorList() const {
5670   return parser_->function_state_->GetReportedErrorList();
5671 }
5672 
5673 
zone() const5674 Zone* ParserTraits::zone() const {
5675   return parser_->function_state_->scope()->zone();
5676 }
5677 
5678 
5679 class NonPatternRewriter : public AstExpressionRewriter {
5680  public:
NonPatternRewriter(uintptr_t stack_limit,Parser * parser)5681   NonPatternRewriter(uintptr_t stack_limit, Parser* parser)
5682       : AstExpressionRewriter(stack_limit), parser_(parser) {}
~NonPatternRewriter()5683   ~NonPatternRewriter() override {}
5684 
5685  private:
RewriteExpression(Expression * expr)5686   bool RewriteExpression(Expression* expr) override {
5687     if (expr->IsRewritableExpression()) return true;
5688     // Rewrite only what could have been a pattern but is not.
5689     if (expr->IsArrayLiteral()) {
5690       // Spread rewriting in array literals.
5691       ArrayLiteral* lit = expr->AsArrayLiteral();
5692       VisitExpressions(lit->values());
5693       replacement_ = parser_->RewriteSpreads(lit);
5694       return false;
5695     }
5696     if (expr->IsObjectLiteral()) {
5697       return true;
5698     }
5699     if (expr->IsBinaryOperation() &&
5700         expr->AsBinaryOperation()->op() == Token::COMMA) {
5701       return true;
5702     }
5703     // Everything else does not need rewriting.
5704     return false;
5705   }
5706 
VisitObjectLiteralProperty(ObjectLiteralProperty * property)5707   void VisitObjectLiteralProperty(ObjectLiteralProperty* property) override {
5708     if (property == nullptr) return;
5709     // Do not rewrite (computed) key expressions
5710     AST_REWRITE_PROPERTY(Expression, property, value);
5711   }
5712 
5713   Parser* parser_;
5714 };
5715 
5716 
RewriteNonPattern(ExpressionClassifier * classifier,bool * ok)5717 void Parser::RewriteNonPattern(ExpressionClassifier* classifier, bool* ok) {
5718   ValidateExpression(classifier, ok);
5719   if (!*ok) return;
5720   auto non_patterns_to_rewrite = function_state_->non_patterns_to_rewrite();
5721   int begin = classifier->GetNonPatternBegin();
5722   int end = non_patterns_to_rewrite->length();
5723   if (begin < end) {
5724     NonPatternRewriter rewriter(stack_limit_, this);
5725     for (int i = begin; i < end; i++) {
5726       DCHECK(non_patterns_to_rewrite->at(i)->IsRewritableExpression());
5727       rewriter.Rewrite(non_patterns_to_rewrite->at(i));
5728     }
5729     non_patterns_to_rewrite->Rewind(begin);
5730   }
5731 }
5732 
5733 
RewriteDestructuringAssignments()5734 void Parser::RewriteDestructuringAssignments() {
5735   const auto& assignments =
5736       function_state_->destructuring_assignments_to_rewrite();
5737   for (int i = assignments.length() - 1; i >= 0; --i) {
5738     // Rewrite list in reverse, so that nested assignment patterns are rewritten
5739     // correctly.
5740     const DestructuringAssignment& pair = assignments.at(i);
5741     RewritableExpression* to_rewrite =
5742         pair.assignment->AsRewritableExpression();
5743     DCHECK_NOT_NULL(to_rewrite);
5744     if (!to_rewrite->is_rewritten()) {
5745       PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite,
5746                                                       pair.scope);
5747     }
5748   }
5749 }
5750 
RewriteExponentiation(Expression * left,Expression * right,int pos)5751 Expression* Parser::RewriteExponentiation(Expression* left, Expression* right,
5752                                           int pos) {
5753   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
5754   args->Add(left, zone());
5755   args->Add(right, zone());
5756   return factory()->NewCallRuntime(Context::MATH_POW_METHOD_INDEX, args, pos);
5757 }
5758 
RewriteAssignExponentiation(Expression * left,Expression * right,int pos)5759 Expression* Parser::RewriteAssignExponentiation(Expression* left,
5760                                                 Expression* right, int pos) {
5761   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
5762   if (left->IsVariableProxy()) {
5763     VariableProxy* lhs = left->AsVariableProxy();
5764 
5765     Expression* result;
5766     DCHECK_NOT_NULL(lhs->raw_name());
5767     result =
5768         this->ExpressionFromIdentifier(lhs->raw_name(), lhs->position(),
5769                                        lhs->end_position(), scope_, factory());
5770     args->Add(left, zone());
5771     args->Add(right, zone());
5772     Expression* call =
5773         factory()->NewCallRuntime(Context::MATH_POW_METHOD_INDEX, args, pos);
5774     return factory()->NewAssignment(Token::ASSIGN, result, call, pos);
5775   } else if (left->IsProperty()) {
5776     Property* prop = left->AsProperty();
5777     auto temp_obj = scope_->NewTemporary(ast_value_factory()->empty_string());
5778     auto temp_key = scope_->NewTemporary(ast_value_factory()->empty_string());
5779     Expression* assign_obj = factory()->NewAssignment(
5780         Token::ASSIGN, factory()->NewVariableProxy(temp_obj), prop->obj(),
5781         RelocInfo::kNoPosition);
5782     Expression* assign_key = factory()->NewAssignment(
5783         Token::ASSIGN, factory()->NewVariableProxy(temp_key), prop->key(),
5784         RelocInfo::kNoPosition);
5785     args->Add(factory()->NewProperty(factory()->NewVariableProxy(temp_obj),
5786                                      factory()->NewVariableProxy(temp_key),
5787                                      left->position()),
5788               zone());
5789     args->Add(right, zone());
5790     Expression* call =
5791         factory()->NewCallRuntime(Context::MATH_POW_METHOD_INDEX, args, pos);
5792     Expression* target = factory()->NewProperty(
5793         factory()->NewVariableProxy(temp_obj),
5794         factory()->NewVariableProxy(temp_key), RelocInfo::kNoPosition);
5795     Expression* assign =
5796         factory()->NewAssignment(Token::ASSIGN, target, call, pos);
5797     return factory()->NewBinaryOperation(
5798         Token::COMMA, assign_obj,
5799         factory()->NewBinaryOperation(Token::COMMA, assign_key, assign, pos),
5800         pos);
5801   }
5802   UNREACHABLE();
5803   return nullptr;
5804 }
5805 
RewriteSpreads(ArrayLiteral * lit)5806 Expression* Parser::RewriteSpreads(ArrayLiteral* lit) {
5807   // Array literals containing spreads are rewritten using do expressions, e.g.
5808   //    [1, 2, 3, ...x, 4, ...y, 5]
5809   // is roughly rewritten as:
5810   //    do {
5811   //      $R = [1, 2, 3];
5812   //      for ($i of x) %AppendElement($R, $i);
5813   //      %AppendElement($R, 4);
5814   //      for ($j of y) %AppendElement($R, $j);
5815   //      %AppendElement($R, 5);
5816   //      $R
5817   //    }
5818   // where $R, $i and $j are fresh temporary variables.
5819   ZoneList<Expression*>::iterator s = lit->FirstSpread();
5820   if (s == lit->EndValue()) return nullptr;  // no spread, no rewriting...
5821   Variable* result =
5822       scope_->NewTemporary(ast_value_factory()->dot_result_string());
5823   // NOTE: The value assigned to R is the whole original array literal,
5824   // spreads included. This will be fixed before the rewritten AST is returned.
5825   // $R = lit
5826   Expression* init_result =
5827       factory()->NewAssignment(Token::INIT, factory()->NewVariableProxy(result),
5828                                lit, RelocInfo::kNoPosition);
5829   Block* do_block =
5830       factory()->NewBlock(nullptr, 16, false, RelocInfo::kNoPosition);
5831   do_block->statements()->Add(
5832       factory()->NewExpressionStatement(init_result, RelocInfo::kNoPosition),
5833       zone());
5834   // Traverse the array literal starting from the first spread.
5835   while (s != lit->EndValue()) {
5836     Expression* value = *s++;
5837     Spread* spread = value->AsSpread();
5838     if (spread == nullptr) {
5839       // If the element is not a spread, we're adding a single:
5840       // %AppendElement($R, value)
5841       ZoneList<Expression*>* append_element_args = NewExpressionList(2, zone());
5842       append_element_args->Add(factory()->NewVariableProxy(result), zone());
5843       append_element_args->Add(value, zone());
5844       do_block->statements()->Add(
5845           factory()->NewExpressionStatement(
5846               factory()->NewCallRuntime(Runtime::kAppendElement,
5847                                         append_element_args,
5848                                         RelocInfo::kNoPosition),
5849               RelocInfo::kNoPosition),
5850           zone());
5851     } else {
5852       // If it's a spread, we're adding a for/of loop iterating through it.
5853       Variable* each =
5854           scope_->NewTemporary(ast_value_factory()->dot_for_string());
5855       Expression* subject = spread->expression();
5856       // %AppendElement($R, each)
5857       Statement* append_body;
5858       {
5859         ZoneList<Expression*>* append_element_args =
5860             NewExpressionList(2, zone());
5861         append_element_args->Add(factory()->NewVariableProxy(result), zone());
5862         append_element_args->Add(factory()->NewVariableProxy(each), zone());
5863         append_body = factory()->NewExpressionStatement(
5864             factory()->NewCallRuntime(Runtime::kAppendElement,
5865                                       append_element_args,
5866                                       RelocInfo::kNoPosition),
5867             RelocInfo::kNoPosition);
5868       }
5869       // for (each of spread) %AppendElement($R, each)
5870       ForEachStatement* loop = factory()->NewForEachStatement(
5871           ForEachStatement::ITERATE, nullptr, RelocInfo::kNoPosition);
5872       InitializeForOfStatement(loop->AsForOfStatement(),
5873                                factory()->NewVariableProxy(each), subject,
5874                                append_body);
5875       do_block->statements()->Add(loop, zone());
5876     }
5877   }
5878   // Now, rewind the original array literal to truncate everything from the
5879   // first spread (included) until the end. This fixes $R's initialization.
5880   lit->RewindSpreads();
5881   return factory()->NewDoExpression(do_block, result, lit->position());
5882 }
5883 
5884 
QueueDestructuringAssignmentForRewriting(Expression * expr)5885 void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) {
5886   DCHECK(expr->IsRewritableExpression());
5887   parser_->function_state_->AddDestructuringAssignment(
5888       Parser::DestructuringAssignment(expr, parser_->scope_));
5889 }
5890 
5891 
QueueNonPatternForRewriting(Expression * expr,bool * ok)5892 void ParserTraits::QueueNonPatternForRewriting(Expression* expr, bool* ok) {
5893   DCHECK(expr->IsRewritableExpression());
5894   parser_->function_state_->AddNonPatternForRewriting(expr, ok);
5895 }
5896 
5897 
SetFunctionNameFromPropertyName(ObjectLiteralProperty * property,const AstRawString * name)5898 void ParserTraits::SetFunctionNameFromPropertyName(
5899     ObjectLiteralProperty* property, const AstRawString* name) {
5900   Expression* value = property->value();
5901 
5902   // Computed name setting must happen at runtime.
5903   if (property->is_computed_name()) return;
5904 
5905   // Getter and setter names are handled here because their names
5906   // change in ES2015, even though they are not anonymous.
5907   auto function = value->AsFunctionLiteral();
5908   if (function != nullptr) {
5909     bool is_getter = property->kind() == ObjectLiteralProperty::GETTER;
5910     bool is_setter = property->kind() == ObjectLiteralProperty::SETTER;
5911     if (is_getter || is_setter) {
5912       DCHECK_NOT_NULL(name);
5913       const AstRawString* prefix =
5914           is_getter ? parser_->ast_value_factory()->get_space_string()
5915                     : parser_->ast_value_factory()->set_space_string();
5916       function->set_raw_name(
5917           parser_->ast_value_factory()->NewConsString(prefix, name));
5918       return;
5919     }
5920   }
5921 
5922   if (!value->IsAnonymousFunctionDefinition()) return;
5923   DCHECK_NOT_NULL(name);
5924 
5925   // Ignore "__proto__" as a name when it's being used to set the [[Prototype]]
5926   // of an object literal.
5927   if (property->kind() == ObjectLiteralProperty::PROTOTYPE) return;
5928 
5929   if (function != nullptr) {
5930     function->set_raw_name(name);
5931     DCHECK_EQ(ObjectLiteralProperty::COMPUTED, property->kind());
5932   } else {
5933     DCHECK(value->IsClassLiteral());
5934     DCHECK_EQ(ObjectLiteralProperty::COMPUTED, property->kind());
5935     value->AsClassLiteral()->constructor()->set_raw_name(name);
5936   }
5937 }
5938 
5939 
SetFunctionNameFromIdentifierRef(Expression * value,Expression * identifier)5940 void ParserTraits::SetFunctionNameFromIdentifierRef(Expression* value,
5941                                                     Expression* identifier) {
5942   if (!value->IsAnonymousFunctionDefinition()) return;
5943   if (!identifier->IsVariableProxy()) return;
5944 
5945   auto name = identifier->AsVariableProxy()->raw_name();
5946   DCHECK_NOT_NULL(name);
5947 
5948   auto function = value->AsFunctionLiteral();
5949   if (function != nullptr) {
5950     function->set_raw_name(name);
5951   } else {
5952     DCHECK(value->IsClassLiteral());
5953     value->AsClassLiteral()->constructor()->set_raw_name(name);
5954   }
5955 }
5956 
5957 
5958 // Desugaring of yield*
5959 // ====================
5960 //
5961 // With the help of do-expressions and function.sent, we desugar yield* into a
5962 // loop containing a "raw" yield (a yield that doesn't wrap an iterator result
5963 // object around its argument).  Concretely, "yield* iterable" turns into
5964 // roughly the following code:
5965 //
5966 //   do {
5967 //     const kNext = 0;
5968 //     const kReturn = 1;
5969 //     const kThrow = 2;
5970 //
5971 //     let input = function.sent;
5972 //     let mode = kNext;
5973 //     let output = undefined;
5974 //
5975 //     let iterator = iterable[Symbol.iterator]();
5976 //     if (!IS_RECEIVER(iterator)) throw MakeTypeError(kSymbolIteratorInvalid);
5977 //
5978 //     while (true) {
5979 //       // From the generator to the iterator:
5980 //       // Forward input according to resume mode and obtain output.
5981 //       switch (mode) {
5982 //         case kNext:
5983 //           output = iterator.next(input);
5984 //           if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
5985 //           break;
5986 //         case kReturn:
5987 //           IteratorClose(iterator, input, output);  // See below.
5988 //           break;
5989 //         case kThrow:
5990 //           let iteratorThrow = iterator.throw;
5991 //           if (IS_NULL_OR_UNDEFINED(iteratorThrow)) {
5992 //             IteratorClose(iterator);  // See below.
5993 //             throw MakeTypeError(kThrowMethodMissing);
5994 //           }
5995 //           output = %_Call(iteratorThrow, iterator, input);
5996 //           if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
5997 //           break;
5998 //       }
5999 //       if (output.done) break;
6000 //
6001 //       // From the generator to its user:
6002 //       // Forward output, receive new input, and determine resume mode.
6003 //       mode = kReturn;
6004 //       try {
6005 //         try {
6006 //           RawYield(output);  // See explanation above.
6007 //           mode = kNext;
6008 //         } catch (error) {
6009 //           mode = kThrow;
6010 //         }
6011 //       } finally {
6012 //         input = function.sent;
6013 //         continue;
6014 //       }
6015 //     }
6016 //
6017 //     if (mode === kReturn) {
6018 //       return {value: output.value, done: true};
6019 //     }
6020 //     output.value
6021 //   }
6022 //
6023 // IteratorClose(iterator) expands to the following:
6024 //
6025 //   let iteratorReturn = iterator.return;
6026 //   if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
6027 //     let output = %_Call(iteratorReturn, iterator);
6028 //     if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
6029 //   }
6030 //
6031 // IteratorClose(iterator, input, output) expands to the following:
6032 //
6033 //   let iteratorReturn = iterator.return;
6034 //   if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return input;
6035 //   output = %_Call(iteratorReturn, iterator, input);
6036 //   if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
6037 
RewriteYieldStar(Expression * generator,Expression * iterable,int pos)6038 Expression* ParserTraits::RewriteYieldStar(
6039     Expression* generator, Expression* iterable, int pos) {
6040 
6041   const int nopos = RelocInfo::kNoPosition;
6042 
6043   auto factory = parser_->factory();
6044   auto avfactory = parser_->ast_value_factory();
6045   auto scope = parser_->scope_;
6046   auto zone = parser_->zone();
6047 
6048 
6049   // Forward definition for break/continue statements.
6050   WhileStatement* loop = factory->NewWhileStatement(nullptr, nopos);
6051 
6052 
6053   // let input = undefined;
6054   Variable* var_input = scope->NewTemporary(avfactory->empty_string());
6055   Statement* initialize_input;
6056   {
6057     Expression* input_proxy = factory->NewVariableProxy(var_input);
6058     Expression* assignment = factory->NewAssignment(
6059         Token::ASSIGN, input_proxy, factory->NewUndefinedLiteral(nopos), nopos);
6060     initialize_input = factory->NewExpressionStatement(assignment, nopos);
6061   }
6062 
6063 
6064   // let mode = kNext;
6065   Variable* var_mode = scope->NewTemporary(avfactory->empty_string());
6066   Statement* initialize_mode;
6067   {
6068     Expression* mode_proxy = factory->NewVariableProxy(var_mode);
6069     Expression* knext = factory->NewSmiLiteral(JSGeneratorObject::kNext, nopos);
6070     Expression* assignment =
6071         factory->NewAssignment(Token::ASSIGN, mode_proxy, knext, nopos);
6072     initialize_mode = factory->NewExpressionStatement(assignment, nopos);
6073   }
6074 
6075 
6076   // let output = undefined;
6077   Variable* var_output = scope->NewTemporary(avfactory->empty_string());
6078   Statement* initialize_output;
6079   {
6080     Expression* output_proxy = factory->NewVariableProxy(var_output);
6081     Expression* assignment = factory->NewAssignment(
6082         Token::ASSIGN, output_proxy, factory->NewUndefinedLiteral(nopos),
6083         nopos);
6084     initialize_output = factory->NewExpressionStatement(assignment, nopos);
6085   }
6086 
6087 
6088   // let iterator = iterable[Symbol.iterator];
6089   Variable* var_iterator = scope->NewTemporary(avfactory->empty_string());
6090   Statement* get_iterator;
6091   {
6092     Expression* iterator = GetIterator(iterable, factory, nopos);
6093     Expression* iterator_proxy = factory->NewVariableProxy(var_iterator);
6094     Expression* assignment = factory->NewAssignment(
6095         Token::ASSIGN, iterator_proxy, iterator, nopos);
6096     get_iterator = factory->NewExpressionStatement(assignment, nopos);
6097   }
6098 
6099 
6100   // if (!IS_RECEIVER(iterator)) throw MakeTypeError(kSymbolIteratorInvalid);
6101   Statement* validate_iterator;
6102   {
6103     Expression* is_receiver_call;
6104     {
6105       auto args = new (zone) ZoneList<Expression*>(1, zone);
6106       args->Add(factory->NewVariableProxy(var_iterator), zone);
6107       is_receiver_call =
6108           factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
6109     }
6110 
6111     Statement* throw_call;
6112     {
6113       Expression* call = NewThrowTypeError(
6114           MessageTemplate::kSymbolIteratorInvalid, avfactory->empty_string(),
6115           nopos);
6116       throw_call = factory->NewExpressionStatement(call, nopos);
6117     }
6118 
6119     validate_iterator = factory->NewIfStatement(
6120         is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos);
6121   }
6122 
6123 
6124   // output = iterator.next(input);
6125   Statement* call_next;
6126   {
6127     Expression* iterator_proxy = factory->NewVariableProxy(var_iterator);
6128     Expression* literal =
6129         factory->NewStringLiteral(avfactory->next_string(), nopos);
6130     Expression* next_property =
6131         factory->NewProperty(iterator_proxy, literal, nopos);
6132     Expression* input_proxy = factory->NewVariableProxy(var_input);
6133     auto args = new (zone) ZoneList<Expression*>(1, zone);
6134     args->Add(input_proxy, zone);
6135     Expression* call = factory->NewCall(next_property, args, nopos);
6136     Expression* output_proxy = factory->NewVariableProxy(var_output);
6137     Expression* assignment =
6138         factory->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
6139     call_next = factory->NewExpressionStatement(assignment, nopos);
6140   }
6141 
6142 
6143   // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
6144   Statement* validate_next_output;
6145   {
6146     Expression* is_receiver_call;
6147     {
6148       auto args = new (zone) ZoneList<Expression*>(1, zone);
6149       args->Add(factory->NewVariableProxy(var_output), zone);
6150       is_receiver_call =
6151           factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
6152     }
6153 
6154     Statement* throw_call;
6155     {
6156       auto args = new (zone) ZoneList<Expression*>(1, zone);
6157       args->Add(factory->NewVariableProxy(var_output), zone);
6158       Expression* call = factory->NewCallRuntime(
6159           Runtime::kThrowIteratorResultNotAnObject, args, nopos);
6160       throw_call = factory->NewExpressionStatement(call, nopos);
6161     }
6162 
6163     validate_next_output = factory->NewIfStatement(
6164         is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos);
6165   }
6166 
6167 
6168   // let iteratorThrow = iterator.throw;
6169   Variable* var_throw = scope->NewTemporary(avfactory->empty_string());
6170   Statement* get_throw;
6171   {
6172     Expression* iterator_proxy = factory->NewVariableProxy(var_iterator);
6173     Expression* literal =
6174         factory->NewStringLiteral(avfactory->throw_string(), nopos);
6175     Expression* property =
6176         factory->NewProperty(iterator_proxy, literal, nopos);
6177     Expression* throw_proxy = factory->NewVariableProxy(var_throw);
6178     Expression* assignment = factory->NewAssignment(
6179         Token::ASSIGN, throw_proxy, property, nopos);
6180     get_throw = factory->NewExpressionStatement(assignment, nopos);
6181   }
6182 
6183 
6184   // if (IS_NULL_OR_UNDEFINED(iteratorThrow) {
6185   //   IteratorClose(iterator);
6186   //   throw MakeTypeError(kThrowMethodMissing);
6187   // }
6188   Statement* check_throw;
6189   {
6190     Expression* condition = factory->NewCompareOperation(
6191         Token::EQ, factory->NewVariableProxy(var_throw),
6192         factory->NewNullLiteral(nopos), nopos);
6193 
6194     Expression* call = NewThrowTypeError(
6195         MessageTemplate::kThrowMethodMissing,
6196         avfactory->empty_string(), nopos);
6197     Statement* throw_call = factory->NewExpressionStatement(call, nopos);
6198 
6199     Block* then = factory->NewBlock(nullptr, 4+1, false, nopos);
6200     parser_->BuildIteratorCloseForCompletion(
6201         then->statements(), var_iterator,
6202         factory->NewSmiLiteral(Parser::kNormalCompletion, nopos));
6203     then->statements()->Add(throw_call, zone);
6204     check_throw = factory->NewIfStatement(
6205         condition, then, factory->NewEmptyStatement(nopos), nopos);
6206   }
6207 
6208 
6209   // output = %_Call(iteratorThrow, iterator, input);
6210   Statement* call_throw;
6211   {
6212     auto args = new (zone) ZoneList<Expression*>(3, zone);
6213     args->Add(factory->NewVariableProxy(var_throw), zone);
6214     args->Add(factory->NewVariableProxy(var_iterator), zone);
6215     args->Add(factory->NewVariableProxy(var_input), zone);
6216     Expression* call =
6217         factory->NewCallRuntime(Runtime::kInlineCall, args, nopos);
6218     Expression* assignment = factory->NewAssignment(
6219         Token::ASSIGN, factory->NewVariableProxy(var_output), call, nopos);
6220     call_throw = factory->NewExpressionStatement(assignment, nopos);
6221   }
6222 
6223 
6224   // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
6225   Statement* validate_throw_output;
6226   {
6227     Expression* is_receiver_call;
6228     {
6229       auto args = new (zone) ZoneList<Expression*>(1, zone);
6230       args->Add(factory->NewVariableProxy(var_output), zone);
6231       is_receiver_call =
6232           factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
6233     }
6234 
6235     Statement* throw_call;
6236     {
6237       auto args = new (zone) ZoneList<Expression*>(1, zone);
6238       args->Add(factory->NewVariableProxy(var_output), zone);
6239       Expression* call = factory->NewCallRuntime(
6240           Runtime::kThrowIteratorResultNotAnObject, args, nopos);
6241       throw_call = factory->NewExpressionStatement(call, nopos);
6242     }
6243 
6244     validate_throw_output = factory->NewIfStatement(
6245         is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos);
6246   }
6247 
6248 
6249   // if (output.done) break;
6250   Statement* if_done;
6251   {
6252     Expression* output_proxy = factory->NewVariableProxy(var_output);
6253     Expression* literal =
6254         factory->NewStringLiteral(avfactory->done_string(), nopos);
6255     Expression* property = factory->NewProperty(output_proxy, literal, nopos);
6256     BreakStatement* break_loop = factory->NewBreakStatement(loop, nopos);
6257     if_done = factory->NewIfStatement(
6258         property, break_loop, factory->NewEmptyStatement(nopos), nopos);
6259   }
6260 
6261 
6262   // mode = kReturn;
6263   Statement* set_mode_return;
6264   {
6265     Expression* mode_proxy = factory->NewVariableProxy(var_mode);
6266     Expression* kreturn =
6267         factory->NewSmiLiteral(JSGeneratorObject::kReturn, nopos);
6268     Expression* assignment =
6269         factory->NewAssignment(Token::ASSIGN, mode_proxy, kreturn, nopos);
6270     set_mode_return = factory->NewExpressionStatement(assignment, nopos);
6271   }
6272 
6273   // Yield(output);
6274   Statement* yield_output;
6275   {
6276     Expression* output_proxy = factory->NewVariableProxy(var_output);
6277     Yield* yield = factory->NewYield(generator, output_proxy, nopos);
6278     yield_output = factory->NewExpressionStatement(yield, nopos);
6279   }
6280 
6281 
6282   // mode = kNext;
6283   Statement* set_mode_next;
6284   {
6285     Expression* mode_proxy = factory->NewVariableProxy(var_mode);
6286     Expression* knext = factory->NewSmiLiteral(JSGeneratorObject::kNext, nopos);
6287     Expression* assignment =
6288         factory->NewAssignment(Token::ASSIGN, mode_proxy, knext, nopos);
6289     set_mode_next = factory->NewExpressionStatement(assignment, nopos);
6290   }
6291 
6292 
6293   // mode = kThrow;
6294   Statement* set_mode_throw;
6295   {
6296     Expression* mode_proxy = factory->NewVariableProxy(var_mode);
6297     Expression* kthrow =
6298         factory->NewSmiLiteral(JSGeneratorObject::kThrow, nopos);
6299     Expression* assignment =
6300         factory->NewAssignment(Token::ASSIGN, mode_proxy, kthrow, nopos);
6301     set_mode_throw = factory->NewExpressionStatement(assignment, nopos);
6302   }
6303 
6304 
6305   // input = function.sent;
6306   Statement* get_input;
6307   {
6308     Expression* function_sent = FunctionSentExpression(scope, factory, nopos);
6309     Expression* input_proxy = factory->NewVariableProxy(var_input);
6310     Expression* assignment = factory->NewAssignment(
6311         Token::ASSIGN, input_proxy, function_sent, nopos);
6312     get_input = factory->NewExpressionStatement(assignment, nopos);
6313   }
6314 
6315 
6316   // if (mode === kReturn) {
6317   //   return {value: output.value, done: true};
6318   // }
6319   Statement* maybe_return_value;
6320   {
6321     Expression* mode_proxy = factory->NewVariableProxy(var_mode);
6322     Expression* kreturn =
6323         factory->NewSmiLiteral(JSGeneratorObject::kReturn, nopos);
6324     Expression* condition = factory->NewCompareOperation(
6325         Token::EQ_STRICT, mode_proxy, kreturn, nopos);
6326 
6327     Expression* output_proxy = factory->NewVariableProxy(var_output);
6328     Expression* literal =
6329         factory->NewStringLiteral(avfactory->value_string(), nopos);
6330     Expression* property = factory->NewProperty(output_proxy, literal, nopos);
6331     Statement* return_value =
6332         factory->NewReturnStatement(BuildIteratorResult(property, true), nopos);
6333 
6334     maybe_return_value = factory->NewIfStatement(
6335         condition, return_value, factory->NewEmptyStatement(nopos), nopos);
6336   }
6337 
6338 
6339   // output.value
6340   Statement* get_value;
6341   {
6342     Expression* output_proxy = factory->NewVariableProxy(var_output);
6343     Expression* literal =
6344         factory->NewStringLiteral(avfactory->value_string(), nopos);
6345     Expression* property = factory->NewProperty(output_proxy, literal, nopos);
6346     get_value = factory->NewExpressionStatement(property, nopos);
6347   }
6348 
6349 
6350   // Now put things together.
6351 
6352 
6353   // try { ... } catch(e) { ... }
6354   Statement* try_catch;
6355   {
6356     Block* try_block = factory->NewBlock(nullptr, 2, false, nopos);
6357     try_block->statements()->Add(yield_output, zone);
6358     try_block->statements()->Add(set_mode_next, zone);
6359 
6360     Block* catch_block = factory->NewBlock(nullptr, 1, false, nopos);
6361     catch_block->statements()->Add(set_mode_throw, zone);
6362 
6363     Scope* catch_scope = NewScope(scope, CATCH_SCOPE);
6364     catch_scope->set_is_hidden();
6365     const AstRawString* name = avfactory->dot_catch_string();
6366     Variable* catch_variable =
6367         catch_scope->DeclareLocal(name, VAR, kCreatedInitialized,
6368                                                Variable::NORMAL);
6369 
6370     try_catch = factory->NewTryCatchStatement(
6371         try_block, catch_scope, catch_variable, catch_block, nopos);
6372   }
6373 
6374 
6375   // try { ... } finally { ... }
6376   Statement* try_finally;
6377   {
6378     Block* try_block = factory->NewBlock(nullptr, 1, false, nopos);
6379     try_block->statements()->Add(try_catch, zone);
6380 
6381     Block* finally = factory->NewBlock(nullptr, 2, false, nopos);
6382     finally->statements()->Add(get_input, zone);
6383     finally->statements()->Add(
6384         factory->NewContinueStatement(loop, nopos), zone);
6385 
6386     try_finally = factory->NewTryFinallyStatement(try_block, finally, nopos);
6387   }
6388 
6389 
6390   // switch (mode) { ... }
6391   SwitchStatement* switch_mode = factory->NewSwitchStatement(nullptr, nopos);
6392   {
6393     auto case_next = new (zone) ZoneList<Statement*>(3, zone);
6394     case_next->Add(call_next, zone);
6395     case_next->Add(validate_next_output, zone);
6396     case_next->Add(factory->NewBreakStatement(switch_mode, nopos), zone);
6397 
6398     auto case_return = new (zone) ZoneList<Statement*>(5, zone);
6399     BuildIteratorClose(case_return, var_iterator, var_input, var_output);
6400     case_return->Add(factory->NewBreakStatement(switch_mode, nopos), zone);
6401 
6402     auto case_throw = new (zone) ZoneList<Statement*>(5, zone);
6403     case_throw->Add(get_throw, zone);
6404     case_throw->Add(check_throw, zone);
6405     case_throw->Add(call_throw, zone);
6406     case_throw->Add(validate_throw_output, zone);
6407     case_throw->Add(factory->NewBreakStatement(switch_mode, nopos), zone);
6408 
6409     auto cases = new (zone) ZoneList<CaseClause*>(3, zone);
6410     Expression* knext = factory->NewSmiLiteral(JSGeneratorObject::kNext, nopos);
6411     Expression* kreturn =
6412         factory->NewSmiLiteral(JSGeneratorObject::kReturn, nopos);
6413     Expression* kthrow =
6414         factory->NewSmiLiteral(JSGeneratorObject::kThrow, nopos);
6415     cases->Add(factory->NewCaseClause(knext, case_next, nopos), zone);
6416     cases->Add(factory->NewCaseClause(kreturn, case_return, nopos), zone);
6417     cases->Add(factory->NewCaseClause(kthrow, case_throw, nopos), zone);
6418 
6419     switch_mode->Initialize(factory->NewVariableProxy(var_mode), cases);
6420   }
6421 
6422 
6423   // while (true) { ... }
6424   // Already defined earlier: WhileStatement* loop = ...
6425   {
6426     Block* loop_body = factory->NewBlock(nullptr, 4, false, nopos);
6427     loop_body->statements()->Add(switch_mode, zone);
6428     loop_body->statements()->Add(if_done, zone);
6429     loop_body->statements()->Add(set_mode_return, zone);
6430     loop_body->statements()->Add(try_finally, zone);
6431 
6432     loop->Initialize(factory->NewBooleanLiteral(true, nopos), loop_body);
6433   }
6434 
6435 
6436   // do { ... }
6437   DoExpression* yield_star;
6438   {
6439     // The rewriter needs to process the get_value statement only, hence we
6440     // put the preceding statements into an init block.
6441 
6442     Block* do_block_ = factory->NewBlock(nullptr, 7, true, nopos);
6443     do_block_->statements()->Add(initialize_input, zone);
6444     do_block_->statements()->Add(initialize_mode, zone);
6445     do_block_->statements()->Add(initialize_output, zone);
6446     do_block_->statements()->Add(get_iterator, zone);
6447     do_block_->statements()->Add(validate_iterator, zone);
6448     do_block_->statements()->Add(loop, zone);
6449     do_block_->statements()->Add(maybe_return_value, zone);
6450 
6451     Block* do_block = factory->NewBlock(nullptr, 2, false, nopos);
6452     do_block->statements()->Add(do_block_, zone);
6453     do_block->statements()->Add(get_value, zone);
6454 
6455     Variable* dot_result = scope->NewTemporary(avfactory->dot_result_string());
6456     yield_star = factory->NewDoExpression(do_block, dot_result, nopos);
6457     Rewriter::Rewrite(parser_, yield_star, avfactory);
6458   }
6459 
6460   return yield_star;
6461 }
6462 
CheckCallable(Variable * var,Expression * error,int pos)6463 Statement* ParserTraits::CheckCallable(Variable* var, Expression* error,
6464                                        int pos) {
6465   auto factory = parser_->factory();
6466   auto avfactory = parser_->ast_value_factory();
6467   const int nopos = RelocInfo::kNoPosition;
6468   Statement* validate_var;
6469   {
6470     Expression* type_of = factory->NewUnaryOperation(
6471         Token::TYPEOF, factory->NewVariableProxy(var), nopos);
6472     Expression* function_literal =
6473         factory->NewStringLiteral(avfactory->function_string(), nopos);
6474     Expression* condition = factory->NewCompareOperation(
6475         Token::EQ_STRICT, type_of, function_literal, nopos);
6476 
6477     Statement* throw_call = factory->NewExpressionStatement(error, pos);
6478 
6479     validate_var = factory->NewIfStatement(
6480         condition, factory->NewEmptyStatement(nopos), throw_call, nopos);
6481   }
6482   return validate_var;
6483 }
6484 
BuildIteratorClose(ZoneList<Statement * > * statements,Variable * iterator,Variable * input,Variable * var_output)6485 void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements,
6486                                       Variable* iterator, Variable* input,
6487                                       Variable* var_output) {
6488   //
6489   // This function adds four statements to [statements], corresponding to the
6490   // following code:
6491   //
6492   //   let iteratorReturn = iterator.return;
6493   //   if (IS_NULL_OR_UNDEFINED(iteratorReturn) {
6494   //     return {value: input, done: true};
6495   //   }
6496   //   output = %_Call(iteratorReturn, iterator, input);
6497   //   if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
6498   //
6499 
6500   const int nopos = RelocInfo::kNoPosition;
6501   auto factory = parser_->factory();
6502   auto avfactory = parser_->ast_value_factory();
6503   auto zone = parser_->zone();
6504 
6505   // let iteratorReturn = iterator.return;
6506   Variable* var_return = var_output;  // Reusing the output variable.
6507   Statement* get_return;
6508   {
6509     Expression* iterator_proxy = factory->NewVariableProxy(iterator);
6510     Expression* literal =
6511         factory->NewStringLiteral(avfactory->return_string(), nopos);
6512     Expression* property =
6513         factory->NewProperty(iterator_proxy, literal, nopos);
6514     Expression* return_proxy = factory->NewVariableProxy(var_return);
6515     Expression* assignment = factory->NewAssignment(
6516         Token::ASSIGN, return_proxy, property, nopos);
6517     get_return = factory->NewExpressionStatement(assignment, nopos);
6518   }
6519 
6520   // if (IS_NULL_OR_UNDEFINED(iteratorReturn) {
6521   //   return {value: input, done: true};
6522   // }
6523   Statement* check_return;
6524   {
6525     Expression* condition = factory->NewCompareOperation(
6526         Token::EQ, factory->NewVariableProxy(var_return),
6527         factory->NewNullLiteral(nopos), nopos);
6528 
6529     Expression* value = factory->NewVariableProxy(input);
6530 
6531     Statement* return_input =
6532         factory->NewReturnStatement(BuildIteratorResult(value, true), nopos);
6533 
6534     check_return = factory->NewIfStatement(
6535         condition, return_input, factory->NewEmptyStatement(nopos), nopos);
6536   }
6537 
6538   // output = %_Call(iteratorReturn, iterator, input);
6539   Statement* call_return;
6540   {
6541     auto args = new (zone) ZoneList<Expression*>(3, zone);
6542     args->Add(factory->NewVariableProxy(var_return), zone);
6543     args->Add(factory->NewVariableProxy(iterator), zone);
6544     args->Add(factory->NewVariableProxy(input), zone);
6545 
6546     Expression* call =
6547         factory->NewCallRuntime(Runtime::kInlineCall, args, nopos);
6548     Expression* output_proxy = factory->NewVariableProxy(var_output);
6549     Expression* assignment = factory->NewAssignment(
6550         Token::ASSIGN, output_proxy, call, nopos);
6551     call_return = factory->NewExpressionStatement(assignment, nopos);
6552   }
6553 
6554   // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output);
6555   Statement* validate_output;
6556   {
6557     Expression* is_receiver_call;
6558     {
6559       auto args = new (zone) ZoneList<Expression*>(1, zone);
6560       args->Add(factory->NewVariableProxy(var_output), zone);
6561       is_receiver_call =
6562           factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
6563     }
6564 
6565     Statement* throw_call;
6566     {
6567       auto args = new (zone) ZoneList<Expression*>(1, zone);
6568       args->Add(factory->NewVariableProxy(var_output), zone);
6569       Expression* call = factory->NewCallRuntime(
6570           Runtime::kThrowIteratorResultNotAnObject, args, nopos);
6571       throw_call = factory->NewExpressionStatement(call, nopos);
6572     }
6573 
6574     validate_output = factory->NewIfStatement(
6575         is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos);
6576   }
6577 
6578   statements->Add(get_return, zone);
6579   statements->Add(check_return, zone);
6580   statements->Add(call_return, zone);
6581   statements->Add(validate_output, zone);
6582 }
6583 
FinalizeIteratorUse(Variable * completion,Expression * condition,Variable * iter,Block * iterator_use,Block * target)6584 void ParserTraits::FinalizeIteratorUse(Variable* completion,
6585                                        Expression* condition, Variable* iter,
6586                                        Block* iterator_use, Block* target) {
6587   //
6588   // This function adds two statements to [target], corresponding to the
6589   // following code:
6590   //
6591   //   completion = kNormalCompletion;
6592   //   try {
6593   //     try {
6594   //       iterator_use
6595   //     } catch(e) {
6596   //       if (completion === kAbruptCompletion) completion = kThrowCompletion;
6597   //       %ReThrow(e);
6598   //     }
6599   //   } finally {
6600   //     if (condition) {
6601   //       #BuildIteratorCloseForCompletion(iter, completion)
6602   //     }
6603   //   }
6604   //
6605 
6606   const int nopos = RelocInfo::kNoPosition;
6607   auto factory = parser_->factory();
6608   auto avfactory = parser_->ast_value_factory();
6609   auto scope = parser_->scope_;
6610   auto zone = parser_->zone();
6611 
6612   // completion = kNormalCompletion;
6613   Statement* initialize_completion;
6614   {
6615     Expression* proxy = factory->NewVariableProxy(completion);
6616     Expression* assignment = factory->NewAssignment(
6617         Token::ASSIGN, proxy,
6618         factory->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
6619     initialize_completion = factory->NewExpressionStatement(assignment, nopos);
6620   }
6621 
6622   // if (completion === kAbruptCompletion) completion = kThrowCompletion;
6623   Statement* set_completion_throw;
6624   {
6625     Expression* condition = factory->NewCompareOperation(
6626         Token::EQ_STRICT, factory->NewVariableProxy(completion),
6627         factory->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
6628 
6629     Expression* proxy = factory->NewVariableProxy(completion);
6630     Expression* assignment = factory->NewAssignment(
6631         Token::ASSIGN, proxy,
6632         factory->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos);
6633     Statement* statement = factory->NewExpressionStatement(assignment, nopos);
6634     set_completion_throw = factory->NewIfStatement(
6635         condition, statement, factory->NewEmptyStatement(nopos), nopos);
6636   }
6637 
6638   // if (condition) {
6639   //   #BuildIteratorCloseForCompletion(iter, completion)
6640   // }
6641   Block* maybe_close;
6642   {
6643     Block* block = factory->NewBlock(nullptr, 2, true, nopos);
6644     Expression* proxy = factory->NewVariableProxy(completion);
6645     parser_->BuildIteratorCloseForCompletion(block->statements(), iter, proxy);
6646     DCHECK(block->statements()->length() == 2);
6647 
6648     maybe_close = factory->NewBlock(nullptr, 1, true, nopos);
6649     maybe_close->statements()->Add(
6650         factory->NewIfStatement(condition, block,
6651                                 factory->NewEmptyStatement(nopos), nopos),
6652         zone);
6653   }
6654 
6655   // try { #try_block }
6656   // catch(e) {
6657   //   #set_completion_throw;
6658   //   %ReThrow(e);
6659   // }
6660   Statement* try_catch;
6661   {
6662     Scope* catch_scope = parser_->NewScope(scope, CATCH_SCOPE);
6663     Variable* catch_variable =
6664         catch_scope->DeclareLocal(avfactory->dot_catch_string(), VAR,
6665                                   kCreatedInitialized, Variable::NORMAL);
6666     catch_scope->set_is_hidden();
6667 
6668     Statement* rethrow;
6669     // We use %ReThrow rather than the ordinary throw because we want to
6670     // preserve the original exception message.  This is also why we create a
6671     // TryCatchStatementForReThrow below (which does not clear the pending
6672     // message), rather than a TryCatchStatement.
6673     {
6674       auto args = new (zone) ZoneList<Expression*>(1, zone);
6675       args->Add(factory->NewVariableProxy(catch_variable), zone);
6676       rethrow = factory->NewExpressionStatement(
6677           factory->NewCallRuntime(Runtime::kReThrow, args, nopos), nopos);
6678     }
6679 
6680     Block* catch_block = factory->NewBlock(nullptr, 2, false, nopos);
6681     catch_block->statements()->Add(set_completion_throw, zone);
6682     catch_block->statements()->Add(rethrow, zone);
6683 
6684     try_catch = factory->NewTryCatchStatementForReThrow(
6685         iterator_use, catch_scope, catch_variable, catch_block, nopos);
6686   }
6687 
6688   // try { #try_catch } finally { #maybe_close }
6689   Statement* try_finally;
6690   {
6691     Block* try_block = factory->NewBlock(nullptr, 1, false, nopos);
6692     try_block->statements()->Add(try_catch, zone);
6693 
6694     try_finally =
6695         factory->NewTryFinallyStatement(try_block, maybe_close, nopos);
6696   }
6697 
6698   target->statements()->Add(initialize_completion, zone);
6699   target->statements()->Add(try_finally, zone);
6700 }
6701 
BuildIteratorCloseForCompletion(ZoneList<Statement * > * statements,Variable * iterator,Expression * completion)6702 void ParserTraits::BuildIteratorCloseForCompletion(
6703     ZoneList<Statement*>* statements, Variable* iterator,
6704     Expression* completion) {
6705   //
6706   // This function adds two statements to [statements], corresponding to the
6707   // following code:
6708   //
6709   //   let iteratorReturn = iterator.return;
6710   //   if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
6711   //     if (completion === kThrowCompletion) {
6712   //       if (!IS_CALLABLE(iteratorReturn)) {
6713   //         throw MakeTypeError(kReturnMethodNotCallable);
6714   //       }
6715   //       try { %_Call(iteratorReturn, iterator) } catch (_) { }
6716   //     } else {
6717   //       let output = %_Call(iteratorReturn, iterator);
6718   //       if (!IS_RECEIVER(output)) {
6719   //         %ThrowIterResultNotAnObject(output);
6720   //       }
6721   //     }
6722   //   }
6723   //
6724 
6725   const int nopos = RelocInfo::kNoPosition;
6726   auto factory = parser_->factory();
6727   auto avfactory = parser_->ast_value_factory();
6728   auto scope = parser_->scope_;
6729   auto zone = parser_->zone();
6730 
6731 
6732   // let iteratorReturn = iterator.return;
6733   Variable* var_return = scope->NewTemporary(avfactory->empty_string());
6734   Statement* get_return;
6735   {
6736     Expression* iterator_proxy = factory->NewVariableProxy(iterator);
6737     Expression* literal =
6738         factory->NewStringLiteral(avfactory->return_string(), nopos);
6739     Expression* property =
6740         factory->NewProperty(iterator_proxy, literal, nopos);
6741     Expression* return_proxy = factory->NewVariableProxy(var_return);
6742     Expression* assignment = factory->NewAssignment(
6743         Token::ASSIGN, return_proxy, property, nopos);
6744     get_return = factory->NewExpressionStatement(assignment, nopos);
6745   }
6746 
6747   // if (!IS_CALLABLE(iteratorReturn)) {
6748   //   throw MakeTypeError(kReturnMethodNotCallable);
6749   // }
6750   Statement* check_return_callable;
6751   {
6752     Expression* throw_expr = NewThrowTypeError(
6753         MessageTemplate::kReturnMethodNotCallable,
6754         avfactory->empty_string(), nopos);
6755     check_return_callable = CheckCallable(var_return, throw_expr, nopos);
6756   }
6757 
6758   // try { %_Call(iteratorReturn, iterator) } catch (_) { }
6759   Statement* try_call_return;
6760   {
6761     auto args = new (zone) ZoneList<Expression*>(2, zone);
6762     args->Add(factory->NewVariableProxy(var_return), zone);
6763     args->Add(factory->NewVariableProxy(iterator), zone);
6764 
6765     Expression* call =
6766         factory->NewCallRuntime(Runtime::kInlineCall, args, nopos);
6767 
6768     Block* try_block = factory->NewBlock(nullptr, 1, false, nopos);
6769     try_block->statements()->Add(factory->NewExpressionStatement(call, nopos),
6770                                  zone);
6771 
6772     Block* catch_block = factory->NewBlock(nullptr, 0, false, nopos);
6773 
6774     Scope* catch_scope = NewScope(scope, CATCH_SCOPE);
6775     Variable* catch_variable = catch_scope->DeclareLocal(
6776         avfactory->dot_catch_string(), VAR, kCreatedInitialized,
6777         Variable::NORMAL);
6778     catch_scope->set_is_hidden();
6779 
6780     try_call_return = factory->NewTryCatchStatement(
6781         try_block, catch_scope, catch_variable, catch_block, nopos);
6782   }
6783 
6784   // let output = %_Call(iteratorReturn, iterator);
6785   // if (!IS_RECEIVER(output)) {
6786   //   %ThrowIteratorResultNotAnObject(output);
6787   // }
6788   Block* validate_return;
6789   {
6790     Variable* var_output = scope->NewTemporary(avfactory->empty_string());
6791     Statement* call_return;
6792     {
6793       auto args = new (zone) ZoneList<Expression*>(2, zone);
6794       args->Add(factory->NewVariableProxy(var_return), zone);
6795       args->Add(factory->NewVariableProxy(iterator), zone);
6796       Expression* call =
6797           factory->NewCallRuntime(Runtime::kInlineCall, args, nopos);
6798 
6799       Expression* output_proxy = factory->NewVariableProxy(var_output);
6800       Expression* assignment =
6801           factory->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
6802       call_return = factory->NewExpressionStatement(assignment, nopos);
6803     }
6804 
6805     Expression* is_receiver_call;
6806     {
6807       auto args = new (zone) ZoneList<Expression*>(1, zone);
6808       args->Add(factory->NewVariableProxy(var_output), zone);
6809       is_receiver_call =
6810           factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
6811     }
6812 
6813     Statement* throw_call;
6814     {
6815       auto args = new (zone) ZoneList<Expression*>(1, zone);
6816       args->Add(factory->NewVariableProxy(var_output), zone);
6817       Expression* call = factory->NewCallRuntime(
6818           Runtime::kThrowIteratorResultNotAnObject, args, nopos);
6819       throw_call = factory->NewExpressionStatement(call, nopos);
6820     }
6821 
6822     Statement* check_return = factory->NewIfStatement(
6823         is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos);
6824 
6825     validate_return = factory->NewBlock(nullptr, 2, false, nopos);
6826     validate_return->statements()->Add(call_return, zone);
6827     validate_return->statements()->Add(check_return, zone);
6828   }
6829 
6830   // if (completion === kThrowCompletion) {
6831   //   #check_return_callable;
6832   //   #try_call_return;
6833   // } else {
6834   //   #validate_return;
6835   // }
6836   Statement* call_return_carefully;
6837   {
6838     Expression* condition = factory->NewCompareOperation(
6839         Token::EQ_STRICT, completion,
6840         factory->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos);
6841 
6842     Block* then_block = factory->NewBlock(nullptr, 2, false, nopos);
6843     then_block->statements()->Add(check_return_callable, zone);
6844     then_block->statements()->Add(try_call_return, zone);
6845 
6846     call_return_carefully =
6847         factory->NewIfStatement(condition, then_block, validate_return, nopos);
6848   }
6849 
6850   // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... }
6851   Statement* maybe_call_return;
6852   {
6853     Expression* condition = factory->NewCompareOperation(
6854         Token::EQ, factory->NewVariableProxy(var_return),
6855         factory->NewNullLiteral(nopos), nopos);
6856 
6857     maybe_call_return =
6858         factory->NewIfStatement(condition, factory->NewEmptyStatement(nopos),
6859                                 call_return_carefully, nopos);
6860   }
6861 
6862 
6863   statements->Add(get_return, zone);
6864   statements->Add(maybe_call_return, zone);
6865 }
6866 
6867 
FinalizeForOfStatement(ForOfStatement * loop,int pos)6868 Statement* ParserTraits::FinalizeForOfStatement(ForOfStatement* loop, int pos) {
6869   //
6870   // This function replaces the loop with the following wrapping:
6871   //
6872   //   let each;
6873   //   let completion = kNormalCompletion;
6874   //   try {
6875   //     try {
6876   //       #loop;
6877   //     } catch(e) {
6878   //       if (completion === kAbruptCompletion) completion = kThrowCompletion;
6879   //       %ReThrow(e);
6880   //     }
6881   //   } finally {
6882   //     if (!(completion === kNormalCompletion || IS_UNDEFINED(#iterator))) {
6883   //       #BuildIteratorCloseForCompletion(#iterator, completion)
6884   //     }
6885   //   }
6886   //
6887   // where the loop's body is wrapped as follows:
6888   //
6889   //   {
6890   //     #loop-body
6891   //     {{completion = kNormalCompletion;}}
6892   //   }
6893   //
6894   // and the loop's assign_each is wrapped as follows
6895   //
6896   //   do {
6897   //     {{completion = kAbruptCompletion;}}
6898   //     #assign-each
6899   //   }
6900   //
6901 
6902   const int nopos = RelocInfo::kNoPosition;
6903   auto factory = parser_->factory();
6904   auto avfactory = parser_->ast_value_factory();
6905   auto scope = parser_->scope_;
6906   auto zone = parser_->zone();
6907 
6908   Variable* var_completion = scope->NewTemporary(avfactory->empty_string());
6909 
6910   // let each;
6911   Variable* var_each = scope->NewTemporary(avfactory->empty_string());
6912   Statement* initialize_each;
6913   {
6914     Expression* proxy = factory->NewVariableProxy(var_each);
6915     Expression* assignment = factory->NewAssignment(
6916         Token::ASSIGN, proxy,
6917         factory->NewUndefinedLiteral(nopos), nopos);
6918     initialize_each =
6919         factory->NewExpressionStatement(assignment, nopos);
6920   }
6921 
6922   // !(completion === kNormalCompletion || IS_UNDEFINED(#iterator))
6923   Expression* closing_condition;
6924   {
6925     Expression* lhs = factory->NewCompareOperation(
6926         Token::EQ_STRICT, factory->NewVariableProxy(var_completion),
6927         factory->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
6928     Expression* rhs = factory->NewCompareOperation(
6929         Token::EQ_STRICT, factory->NewVariableProxy(loop->iterator()),
6930         factory->NewUndefinedLiteral(nopos), nopos);
6931     closing_condition = factory->NewUnaryOperation(
6932         Token::NOT, factory->NewBinaryOperation(Token::OR, lhs, rhs, nopos),
6933         nopos);
6934   }
6935 
6936   // {{completion = kNormalCompletion;}}
6937   Statement* set_completion_normal;
6938   {
6939     Expression* proxy = factory->NewVariableProxy(var_completion);
6940     Expression* assignment = factory->NewAssignment(
6941         Token::ASSIGN, proxy,
6942         factory->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
6943 
6944     Block* block = factory->NewBlock(nullptr, 1, true, nopos);
6945     block->statements()->Add(
6946         factory->NewExpressionStatement(assignment, nopos), zone);
6947     set_completion_normal = block;
6948   }
6949 
6950   // {{completion = kAbruptCompletion;}}
6951   Statement* set_completion_abrupt;
6952   {
6953     Expression* proxy = factory->NewVariableProxy(var_completion);
6954     Expression* assignment = factory->NewAssignment(
6955         Token::ASSIGN, proxy,
6956         factory->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
6957 
6958     Block* block = factory->NewBlock(nullptr, 1, true, nopos);
6959     block->statements()->Add(factory->NewExpressionStatement(assignment, nopos),
6960                              zone);
6961     set_completion_abrupt = block;
6962   }
6963 
6964   // { #loop-body; #set_completion_normal }
6965   Block* new_body = factory->NewBlock(nullptr, 2, false, nopos);
6966   {
6967     new_body->statements()->Add(loop->body(), zone);
6968     new_body->statements()->Add(set_completion_normal, zone);
6969   }
6970 
6971   // { #set_completion_abrupt; #assign-each }
6972   Block* new_assign_each = factory->NewBlock(nullptr, 2, false, nopos);
6973   {
6974     new_assign_each->statements()->Add(set_completion_abrupt, zone);
6975     new_assign_each->statements()->Add(
6976         factory->NewExpressionStatement(loop->assign_each(), nopos), zone);
6977   }
6978 
6979   // Now put things together.
6980 
6981   loop->set_body(new_body);
6982   loop->set_assign_each(
6983       factory->NewDoExpression(new_assign_each, var_each, nopos));
6984 
6985   Statement* final_loop;
6986   {
6987     Block* target = factory->NewBlock(nullptr, 3, false, nopos);
6988     target->statements()->Add(initialize_each, zone);
6989 
6990     Block* try_block = factory->NewBlock(nullptr, 1, false, nopos);
6991     try_block->statements()->Add(loop, zone);
6992 
6993     FinalizeIteratorUse(var_completion, closing_condition, loop->iterator(),
6994                         try_block, target);
6995     final_loop = target;
6996   }
6997 
6998   return final_loop;
6999 }
7000 
7001 
7002 }  // namespace internal
7003 }  // namespace v8
7004