parser.cc 211 KB
Newer Older
1
// Copyright 2012 the V8 project authors. All rights reserved.
2 3
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4

5
#include "src/parsing/parser.h"
6

7 8
#include <memory>

9
#include "src/api.h"
nikolaos's avatar
nikolaos committed
10
#include "src/ast/ast-expression-rewriter.h"
11
#include "src/ast/ast-literal-reindexer.h"
12
#include "src/ast/ast-traversal-visitor.h"
13
#include "src/ast/ast.h"
14
#include "src/bailout-reason.h"
15
#include "src/base/platform/platform.h"
16 17
#include "src/char-predicates-inl.h"
#include "src/messages.h"
18
#include "src/parsing/duplicate-finder.h"
19
#include "src/parsing/parameter-initializer-rewriter.h"
20
#include "src/parsing/parse-info.h"
21 22
#include "src/parsing/rewriter.h"
#include "src/parsing/scanner-character-streams.h"
23
#include "src/runtime/runtime.h"
24
#include "src/string-stream.h"
25
#include "src/tracing/trace-event.h"
26

27 28
namespace v8 {
namespace internal {
29

30 31 32 33 34 35 36 37 38 39 40
ScriptData::ScriptData(const byte* data, int length)
    : owns_data_(false), rejected_(false), data_(data), length_(length) {
  if (!IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)) {
    byte* copy = NewArray<byte>(length);
    DCHECK(IsAligned(reinterpret_cast<intptr_t>(copy), kPointerAlignment));
    CopyBytes(copy, data, length);
    data_ = copy;
    AcquireDataOwnership();
  }
}

41
FunctionEntry ParseData::GetFunctionEntry(int start) {
42 43
  // The current pre-data entry must be a FunctionEntry with the given
  // start position.
44 45
  if ((function_index_ + FunctionEntry::kSize <= Length()) &&
      (static_cast<int>(Data()[function_index_]) == start)) {
46 47
    int index = function_index_;
    function_index_ += FunctionEntry::kSize;
48 49
    Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize);
    return FunctionEntry(subvector);
50 51 52 53 54
  }
  return FunctionEntry();
}


55 56 57 58 59
int ParseData::FunctionCount() {
  int functions_size = FunctionsSize();
  if (functions_size < 0) return 0;
  if (functions_size % FunctionEntry::kSize != 0) return 0;
  return functions_size / FunctionEntry::kSize;
60 61 62
}


63
bool ParseData::IsSane() {
64
  if (!IsAligned(script_data_->length(), sizeof(unsigned))) return false;
65 66
  // Check that the header data is valid and doesn't specify
  // point to positions outside the store.
67 68 69 70 71
  int data_length = Length();
  if (data_length < PreparseDataConstants::kHeaderSize) return false;
  if (Magic() != PreparseDataConstants::kMagicNumber) return false;
  if (Version() != PreparseDataConstants::kCurrentVersion) return false;
  if (HasError()) return false;
72
  // Check that the space allocated for function entries is sane.
73
  int functions_size = FunctionsSize();
74 75
  if (functions_size < 0) return false;
  if (functions_size % FunctionEntry::kSize != 0) return false;
76
  // Check that the total size has room for header and function entries.
77
  int minimum_size =
78
      PreparseDataConstants::kHeaderSize + functions_size;
79
  if (data_length < minimum_size) return false;
80 81 82 83
  return true;
}


84 85 86 87 88
void ParseData::Initialize() {
  // Prepares state for use.
  int data_length = Length();
  if (data_length >= PreparseDataConstants::kHeaderSize) {
    function_index_ = PreparseDataConstants::kHeaderSize;
89
  }
90 91 92
}


93 94
bool ParseData::HasError() {
  return Data()[PreparseDataConstants::kHasErrorOffset];
95 96 97
}


98 99
unsigned ParseData::Magic() {
  return Data()[PreparseDataConstants::kMagicOffset];
100 101 102
}


103 104
unsigned ParseData::Version() {
  return Data()[PreparseDataConstants::kVersionOffset];
105 106 107
}


108 109
int ParseData::FunctionsSize() {
  return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]);
110 111
}

112 113 114 115 116 117 118 119
// Helper for putting parts of the parse results into a temporary zone when
// parsing inner function bodies.
class DiscardableZoneScope {
 public:
  DiscardableZoneScope(Parser* parser, Zone* temp_zone, bool use_temp_zone)
      : ast_node_factory_scope_(parser->factory(), temp_zone, use_temp_zone),
        fni_(parser->ast_value_factory_, temp_zone),
        parser_(parser),
120 121
        prev_fni_(parser->fni_),
        prev_zone_(parser->zone_) {
122 123
    if (use_temp_zone) {
      parser_->fni_ = &fni_;
124
      parser_->zone_ = temp_zone;
125 126
      if (parser_->reusable_preparser_ != nullptr) {
        parser_->reusable_preparser_->zone_ = temp_zone;
127
        parser_->reusable_preparser_->factory()->set_zone(temp_zone);
128
      }
129 130
    }
  }
131
  void Reset() {
132 133
    parser_->fni_ = prev_fni_;
    parser_->zone_ = prev_zone_;
134 135
    if (parser_->reusable_preparser_ != nullptr) {
      parser_->reusable_preparser_->zone_ = prev_zone_;
136
      parser_->reusable_preparser_->factory()->set_zone(prev_zone_);
137
    }
138
    ast_node_factory_scope_.Reset();
139
  }
140
  ~DiscardableZoneScope() { Reset(); }
141 142 143 144 145 146

 private:
  AstNodeFactory::BodyScope ast_node_factory_scope_;
  FuncNameInferrer fni_;
  Parser* parser_;
  FuncNameInferrer* prev_fni_;
147 148 149
  Zone* prev_zone_;

  DISALLOW_COPY_AND_ASSIGN(DiscardableZoneScope);
150
};
151

152
void Parser::SetCachedData(ParseInfo* info) {
153 154 155 156 157
  DCHECK_NULL(cached_parse_data_);
  if (consume_cached_parse_data()) {
    cached_parse_data_ = ParseData::FromCachedData(*info->cached_data());
    if (cached_parse_data_ == nullptr) {
      compile_options_ = ScriptCompiler::kNoCompileOptions;
158 159
    }
  }
160 161
}

162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
Expression* Parser::CallClassFieldInitializer(Scope* scope,
                                              Expression* this_expr) {
  // This produces the expression
  // `.class_field_intializer(this_expr)`, where '.class_field_intializer' is
  // the name
  // of a synthetic variable.
  // 'this_expr' will be 'this' in a base constructor and the result of calling
  // 'super' in a derived one.
  const AstRawString* init_fn_name =
      ast_value_factory()->dot_class_field_init_string();
  VariableProxy* init_fn_proxy = scope->NewUnresolved(factory(), init_fn_name);
  ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
  args->Add(init_fn_proxy, zone());
  args->Add(this_expr, zone());
  return factory()->NewCallRuntime(Runtime::kInlineCall, args,
                                   kNoSourcePosition);
}

Expression* Parser::RewriteSuperCall(Expression* super_call) {
  // TODO(bakkot) find a way to avoid this for classes without fields.
  if (!allow_harmony_class_fields()) {
    return super_call;
  }
  // This turns a super call `super()` into a do expression of the form
  // do {
  //   tmp x = super();
  //   if (.class-field-init)
  //     .class-field-init(x)
  //   x; // This isn't actually present; our do-expression representation
  // allows specifying that the expression returns x directly.
  // }
  Variable* var_tmp =
      scope()->NewTemporary(ast_value_factory()->empty_string());
  Block* block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
  Assignment* assignment = factory()->NewAssignment(
      Token::ASSIGN, factory()->NewVariableProxy(var_tmp), super_call,
      kNoSourcePosition);
  block->statements()->Add(
      factory()->NewExpressionStatement(assignment, kNoSourcePosition), zone());
  const AstRawString* init_fn_name =
      ast_value_factory()->dot_class_field_init_string();
  VariableProxy* init_fn_proxy =
      scope()->NewUnresolved(factory(), init_fn_name);
  Expression* condition = init_fn_proxy;
  Statement* initialize = factory()->NewExpressionStatement(
      CallClassFieldInitializer(scope(), factory()->NewVariableProxy(var_tmp)),
      kNoSourcePosition);
  IfStatement* if_statement = factory()->NewIfStatement(
      condition, initialize, factory()->NewEmptyStatement(kNoSourcePosition),
      kNoSourcePosition);
  block->statements()->Add(if_statement, zone());
  return factory()->NewDoExpression(block, var_tmp, kNoSourcePosition);
}

216
FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name,
217 218 219
                                            bool call_super,
                                            bool requires_class_field_init,
                                            int pos, int end_pos,
220
                                            LanguageMode language_mode) {
221 222
  int materialized_literal_count = -1;
  int expected_property_count = -1;
223
  const int parameter_count = 0;
224
  if (name == nullptr) name = ast_value_factory()->empty_string();
225

226 227
  FunctionKind kind = call_super ? FunctionKind::kDefaultSubclassConstructor
                                 : FunctionKind::kDefaultBaseConstructor;
228
  DeclarationScope* function_scope = NewFunctionScope(kind);
229 230
  SetLanguageMode(function_scope,
                  static_cast<LanguageMode>(language_mode | STRICT));
231 232 233 234 235 236
  // Set start and end position to the same value
  function_scope->set_start_position(pos);
  function_scope->set_end_position(pos);
  ZoneList<Statement*>* body = NULL;

  {
237
    FunctionState function_state(&function_state_, &scope_state_,
238
                                 function_scope);
239

240
    body = new (zone()) ZoneList<Statement*>(call_super ? 2 : 1, zone());
241
    if (call_super) {
242
      // $super_constructor = %_GetSuperConstructor(<this-function>)
243 244 245 246 247 248
      // %reflect_construct(
      //     $super_constructor, InternalArray(...args), new.target)
      auto constructor_args_name = ast_value_factory()->empty_string();
      bool is_duplicate;
      bool is_rest = true;
      bool is_optional = false;
249 250 251
      Variable* constructor_args = function_scope->DeclareParameter(
          constructor_args_name, TEMPORARY, is_optional, is_rest, &is_duplicate,
          ast_value_factory());
252

253
      ZoneList<Expression*>* args =
254
          new (zone()) ZoneList<Expression*>(2, zone());
255 256
      VariableProxy* this_function_proxy =
          NewUnresolved(ast_value_factory()->this_function_string(), pos);
257 258 259
      ZoneList<Expression*>* tmp =
          new (zone()) ZoneList<Expression*>(1, zone());
      tmp->Add(this_function_proxy, zone());
260 261 262
      Expression* super_constructor = factory()->NewCallRuntime(
          Runtime::kInlineGetSuperConstructor, tmp, pos);
      args->Add(super_constructor, zone());
263 264 265 266 267 268
      Spread* spread_args = factory()->NewSpread(
          factory()->NewVariableProxy(constructor_args), pos, pos);
      ZoneList<Expression*>* spread_args_expr =
          new (zone()) ZoneList<Expression*>(1, zone());
      spread_args_expr->Add(spread_args, zone());
      args->AddAll(*PrepareSpreadArguments(spread_args_expr), zone());
269 270
      VariableProxy* new_target_proxy =
          NewUnresolved(ast_value_factory()->new_target_string(), pos);
271
      args->Add(new_target_proxy, zone());
272
      Expression* call = factory()->NewCallRuntime(
273
          Context::REFLECT_CONSTRUCT_INDEX, args, pos);
274 275 276
      if (requires_class_field_init) {
        call = CallClassFieldInitializer(scope(), call);
      }
277
      body->Add(factory()->NewReturnStatement(call, pos), zone());
278 279 280 281 282 283 284
    }

    materialized_literal_count = function_state.materialized_literal_count();
    expected_property_count = function_state.expected_property_count();
  }

  FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
285
      name, function_scope, body, materialized_literal_count,
286
      expected_property_count, parameter_count, parameter_count,
287
      FunctionLiteral::kNoDuplicateParameters,
288 289
      FunctionLiteral::kAnonymousExpression, default_eager_compile_hint(), pos,
      true);
290

291 292
  function_literal->set_requires_class_field_init(requires_class_field_init);

293 294 295
  return function_literal;
}

296 297 298 299 300 301 302 303
// ----------------------------------------------------------------------------
// The CHECK_OK macro is a convenient macro to enforce error
// handling for functions that may fail (by returning !*ok).
//
// CAUTION: This macro appends extra statements after a call,
// thus it must never be used where only a single statement
// is correct (e.g. an if statement branch w/o braces)!

304 305
#define CHECK_OK_VALUE(x) ok); \
  if (!*ok) return x;          \
306 307 308 309
  ((void)0
#define DUMMY )  // to make indentation work
#undef DUMMY

310 311
#define CHECK_OK CHECK_OK_VALUE(nullptr)
#define CHECK_OK_VOID CHECK_OK_VALUE(this->Void())
312 313

#define CHECK_FAILED /**/); \
neis's avatar
neis committed
314
  if (failed_) return nullptr;  \
315 316 317
  ((void)0
#define DUMMY )  // to make indentation work
#undef DUMMY
318 319 320 321

// ----------------------------------------------------------------------------
// Implementation of Parser

322 323 324
bool Parser::ShortcutNumericLiteralBinaryExpression(Expression** x,
                                                    Expression* y,
                                                    Token::Value op, int pos) {
325 326 327 328
  if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() &&
      y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) {
    double x_val = (*x)->AsLiteral()->raw_value()->AsNumber();
    double y_val = y->AsLiteral()->raw_value()->AsNumber();
329 330 331
    bool x_has_dot = (*x)->AsLiteral()->raw_value()->ContainsDot();
    bool y_has_dot = y->AsLiteral()->raw_value()->ContainsDot();
    bool has_dot = x_has_dot || y_has_dot;
332 333
    switch (op) {
      case Token::ADD:
334
        *x = factory()->NewNumberLiteral(x_val + y_val, pos, has_dot);
335 336
        return true;
      case Token::SUB:
337
        *x = factory()->NewNumberLiteral(x_val - y_val, pos, has_dot);
338 339
        return true;
      case Token::MUL:
340
        *x = factory()->NewNumberLiteral(x_val * y_val, pos, has_dot);
341 342
        return true;
      case Token::DIV:
343
        *x = factory()->NewNumberLiteral(x_val / y_val, pos, has_dot);
344 345 346
        return true;
      case Token::BIT_OR: {
        int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
347
        *x = factory()->NewNumberLiteral(value, pos, has_dot);
348 349 350 351
        return true;
      }
      case Token::BIT_AND: {
        int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
352
        *x = factory()->NewNumberLiteral(value, pos, has_dot);
353 354 355 356
        return true;
      }
      case Token::BIT_XOR: {
        int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
357
        *x = factory()->NewNumberLiteral(value, pos, has_dot);
358 359 360 361
        return true;
      }
      case Token::SHL: {
        int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
362
        *x = factory()->NewNumberLiteral(value, pos, has_dot);
363 364 365 366 367
        return true;
      }
      case Token::SHR: {
        uint32_t shift = DoubleToInt32(y_val) & 0x1f;
        uint32_t value = DoubleToUint32(x_val) >> shift;
368
        *x = factory()->NewNumberLiteral(value, pos, has_dot);
369 370 371 372 373
        return true;
      }
      case Token::SAR: {
        uint32_t shift = DoubleToInt32(y_val) & 0x1f;
        int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
374
        *x = factory()->NewNumberLiteral(value, pos, has_dot);
375 376
        return true;
      }
377
      case Token::EXP: {
378
        double value = Pow(x_val, y_val);
379
        int int_value = static_cast<int>(value);
380
        *x = factory()->NewNumberLiteral(
381 382 383 384
            int_value == value && value != -0.0 ? int_value : value, pos,
            has_dot);
        return true;
      }
385 386 387 388 389 390 391
      default:
        break;
    }
  }
  return false;
}

392 393
Expression* Parser::BuildUnaryExpression(Expression* expression,
                                         Token::Value op, int pos) {
394
  DCHECK(expression != NULL);
395
  if (expression->IsLiteral()) {
396
    const AstValue* literal = expression->AsLiteral()->raw_value();
397 398 399
    if (op == Token::NOT) {
      // Convert the literal to a boolean condition and negate it.
      bool condition = literal->BooleanValue();
400
      return factory()->NewBooleanLiteral(!condition, pos);
401 402
    } else if (literal->IsNumber()) {
      // Compute some expressions involving only number literals.
403
      double value = literal->AsNumber();
404
      bool has_dot = literal->ContainsDot();
405 406 407 408
      switch (op) {
        case Token::ADD:
          return expression;
        case Token::SUB:
409
          return factory()->NewNumberLiteral(-value, pos, has_dot);
410
        case Token::BIT_NOT:
411 412
          return factory()->NewNumberLiteral(~DoubleToInt32(value), pos,
                                             has_dot);
413 414 415 416 417 418 419
        default:
          break;
      }
    }
  }
  // Desugar '+foo' => 'foo*1'
  if (op == Token::ADD) {
420 421
    return factory()->NewBinaryOperation(
        Token::MUL, expression, factory()->NewNumberLiteral(1, pos, true), pos);
422 423 424
  }
  // The same idea for '-foo' => 'foo*(-1)'.
  if (op == Token::SUB) {
425 426
    return factory()->NewBinaryOperation(
        Token::MUL, expression, factory()->NewNumberLiteral(-1, pos), pos);
427 428 429
  }
  // ...and one more time for '~foo' => 'foo^(~0)'.
  if (op == Token::BIT_NOT) {
430 431
    return factory()->NewBinaryOperation(
        Token::BIT_XOR, expression, factory()->NewNumberLiteral(~0, pos), pos);
432
  }
433
  return factory()->NewUnaryOperation(op, expression, pos);
434 435
}

436
Expression* Parser::BuildIteratorResult(Expression* value, bool done) {
yangguo's avatar
yangguo committed
437
  int pos = kNoSourcePosition;
438

439
  if (value == nullptr) value = factory()->NewUndefinedLiteral(pos);
440

441 442 443
  auto args = new (zone()) ZoneList<Expression*>(2, zone());
  args->Add(value, zone());
  args->Add(factory()->NewBooleanLiteral(done, pos), zone());
444

445 446
  return factory()->NewCallRuntime(Runtime::kInlineCreateIterResultObject, args,
                                   pos);
447 448
}

449 450 451 452 453 454 455 456
Expression* Parser::NewThrowError(Runtime::FunctionId id,
                                  MessageTemplate::Template message,
                                  const AstRawString* arg, int pos) {
  ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
  args->Add(factory()->NewSmiLiteral(message, pos), zone());
  args->Add(factory()->NewStringLiteral(arg, pos), zone());
  CallRuntime* call_constructor = factory()->NewCallRuntime(id, args, pos);
  return factory()->NewThrow(call_constructor, pos);
457 458
}

459
Expression* Parser::NewSuperPropertyReference(int pos) {
460
  // this_function[home_object_symbol]
461 462
  VariableProxy* this_function_proxy =
      NewUnresolved(ast_value_factory()->this_function_string(), pos);
463
  Expression* home_object_symbol_literal =
464 465
      factory()->NewSymbolLiteral("home_object_symbol", kNoSourcePosition);
  Expression* home_object = factory()->NewProperty(
466
      this_function_proxy, home_object_symbol_literal, pos);
467
  return factory()->NewSuperPropertyReference(
468
      ThisExpression(pos)->AsVariableProxy(), home_object, pos);
469
}
470

471 472 473 474 475 476 477 478
Expression* Parser::NewSuperCallReference(int pos) {
  VariableProxy* new_target_proxy =
      NewUnresolved(ast_value_factory()->new_target_string(), pos);
  VariableProxy* this_function_proxy =
      NewUnresolved(ast_value_factory()->this_function_string(), pos);
  return factory()->NewSuperCallReference(
      ThisExpression(pos)->AsVariableProxy(), new_target_proxy,
      this_function_proxy, pos);
479 480
}

481
Expression* Parser::NewTargetExpression(int pos) {
482
  auto proxy = NewUnresolved(ast_value_factory()->new_target_string(), pos);
483 484
  proxy->set_is_new_target();
  return proxy;
485 486
}

487
Expression* Parser::FunctionSentExpression(int pos) {
488
  // We desugar function.sent into %_GeneratorGetInputOrDebugPos(generator).
489 490 491 492 493 494 495 496 497
  ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
  VariableProxy* generator =
      factory()->NewVariableProxy(function_state_->generator_object_variable());
  args->Add(generator, zone());
  return factory()->NewCallRuntime(Runtime::kInlineGeneratorGetInputOrDebugPos,
                                   args, pos);
}

Literal* Parser::ExpressionFromLiteral(Token::Value token, int pos) {
498 499
  switch (token) {
    case Token::NULL_LITERAL:
500
      return factory()->NewNullLiteral(pos);
501
    case Token::TRUE_LITERAL:
502
      return factory()->NewBooleanLiteral(true, pos);
503
    case Token::FALSE_LITERAL:
504
      return factory()->NewBooleanLiteral(false, pos);
verwaest's avatar
verwaest committed
505
    case Token::SMI: {
heimbuef's avatar
heimbuef committed
506
      uint32_t value = scanner()->smi_value();
507
      return factory()->NewSmiLiteral(value, pos);
verwaest's avatar
verwaest committed
508
    }
509
    case Token::NUMBER: {
510 511 512
      bool has_dot = scanner()->ContainsDot();
      double value = scanner()->DoubleValue();
      return factory()->NewNumberLiteral(value, pos, has_dot);
513 514
    }
    default:
515
      DCHECK(false);
516 517 518 519
  }
  return NULL;
}

520
Expression* Parser::GetIterator(Expression* iterable, int pos) {
521
  Expression* iterator_symbol_literal =
522
      factory()->NewSymbolLiteral("iterator_symbol", kNoSourcePosition);
523
  Expression* prop =
524 525 526
      factory()->NewProperty(iterable, iterator_symbol_literal, pos);
  ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(0, zone());
  return factory()->NewCall(prop, args, pos);
527 528
}

529
void Parser::MarkTailPosition(Expression* expression) {
530 531
  expression->MarkTail();
}
532

533 534 535 536 537 538 539 540 541
Expression* Parser::NewV8Intrinsic(const AstRawString* name,
                                   ZoneList<Expression*>* args, int pos,
                                   bool* ok) {
  if (extension_ != nullptr) {
    // The extension structures are only accessible while parsing the
    // very first time, not when reparsing because of lazy compilation.
    GetClosureScope()->ForceEagerCompilation();
  }

542 543 544
  DCHECK(name->is_one_byte());
  const Runtime::Function* function =
      Runtime::FunctionForName(name->raw_data(), name->length());
545 546 547 548

  if (function != nullptr) {
    // Check for possible name clash.
    DCHECK_EQ(Context::kNotFound,
549
              Context::IntrinsicIndexForName(name->raw_data(), name->length()));
550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574
    // Check for built-in IS_VAR macro.
    if (function->function_id == Runtime::kIS_VAR) {
      DCHECK_EQ(Runtime::RUNTIME, function->intrinsic_type);
      // %IS_VAR(x) evaluates to x if x is a variable,
      // leads to a parse error otherwise.  Could be implemented as an
      // inline function %_IS_VAR(x) to eliminate this special case.
      if (args->length() == 1 && args->at(0)->AsVariableProxy() != nullptr) {
        return args->at(0);
      } else {
        ReportMessage(MessageTemplate::kNotIsvar);
        *ok = false;
        return nullptr;
      }
    }

    // Check that the expected number of arguments are being passed.
    if (function->nargs != -1 && function->nargs != args->length()) {
      ReportMessage(MessageTemplate::kRuntimeWrongNumArgs);
      *ok = false;
      return nullptr;
    }

    return factory()->NewCallRuntime(function, args, pos);
  }

575 576
  int context_index =
      Context::IntrinsicIndexForName(name->raw_data(), name->length());
577 578 579 580 581 582 583 584 585 586 587

  // Check that the function is defined.
  if (context_index == Context::kNotFound) {
    ReportMessage(MessageTemplate::kNotDefined, name);
    *ok = false;
    return nullptr;
  }

  return factory()->NewCallRuntime(context_index, args, pos);
}

588
Parser::Parser(ParseInfo* info)
589
    : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(),
590
                         info->extension(), info->ast_value_factory()),
591
      scanner_(info->unicode_cache()),
592 593
      reusable_preparser_(nullptr),
      original_scope_(nullptr),
594
      mode_(PARSE_EAGERLY),  // Lazy mode must be set explicitly.
595
      target_stack_(nullptr),
596
      compile_options_(info->compile_options()),
597
      cached_parse_data_(nullptr),
598
      total_preparse_skipped_(0),
599 600
      parsing_on_main_thread_(true),
      log_(nullptr) {
601
  // Even though we were passed ParseInfo, we should not store it in
602
  // Parser - this makes sure that Isolate is not accidentally accessed via
603
  // ParseInfo during background parsing.
604 605
  DCHECK(!info->script().is_null() || info->source_stream() != nullptr ||
         info->character_stream() != nullptr);
606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622
  // Determine if functions can be lazily compiled. This is necessary to
  // allow some of our builtin JS files to be lazily compiled. These
  // builtins cannot be handled lazily by the parser, since we have to know
  // if a function uses the special natives syntax, which is something the
  // parser records.
  // If the debugger requests compilation for break points, we cannot be
  // aggressive about lazy compilation, because it might trigger compilation
  // of functions without an outer context when setting a breakpoint through
  // Debug::FindSharedFunctionInfoInScript
  bool can_compile_lazily = FLAG_lazy && !info->is_debug();

  // Consider compiling eagerly when targeting the code cache.
  can_compile_lazily &= !(FLAG_serialize_eager && info->will_serialize());

  set_default_eager_compile_hint(can_compile_lazily
                                     ? FunctionLiteral::kShouldLazyCompile
                                     : FunctionLiteral::kShouldEagerCompile);
623
  set_allow_lazy(FLAG_lazy && info->allow_lazy_parsing() &&
624 625
                 !info->is_native() && info->extension() == nullptr &&
                 can_compile_lazily);
626
  set_allow_natives(FLAG_allow_natives_syntax || info->is_native());
627 628
  set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() &&
                      info->isolate()->is_tail_call_elimination_enabled());
629
  set_allow_harmony_do_expressions(FLAG_harmony_do_expressions);
630
  set_allow_harmony_function_sent(FLAG_harmony_function_sent);
631
  set_allow_harmony_async_await(FLAG_harmony_async_await);
632
  set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators);
633
  set_allow_harmony_trailing_commas(FLAG_harmony_trailing_commas);
634
  set_allow_harmony_class_fields(FLAG_harmony_class_fields);
635 636 637 638
  for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
       ++feature) {
    use_counts_[feature] = 0;
  }
639 640
  if (info->ast_value_factory() == NULL) {
    // info takes ownership of AstValueFactory.
641 642
    info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed()));
    info->set_ast_value_factory_owned();
643
    ast_value_factory_ = info->ast_value_factory();
644
    ast_node_factory_.set_ast_value_factory(ast_value_factory_);
645
  }
646 647
}

648 649
void Parser::DeserializeScopeChain(
    ParseInfo* info, MaybeHandle<ScopeInfo> maybe_outer_scope_info) {
650
  DCHECK(ThreadId::Current().Equals(info->isolate()->thread_id()));
651 652
  // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native
  // context, which will have the "this" binding for script scopes.
653 654 655
  DeclarationScope* script_scope = NewScriptScope();
  info->set_script_scope(script_scope);
  Scope* scope = script_scope;
656 657
  Handle<ScopeInfo> outer_scope_info;
  if (maybe_outer_scope_info.ToHandle(&outer_scope_info)) {
658
    scope = Scope::DeserializeScopeChain(
659 660
        info->isolate(), zone(), *outer_scope_info, script_scope,
        ast_value_factory(), Scope::DeserializationMode::kScopesOnly);
661
    DCHECK(!info->is_module() || scope->is_module_scope());
662 663 664
  }
  original_scope_ = scope;
}
665

666
FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
667 668
  // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
  // see comment for HistogramTimerScope class.
669

670 671 672 673
  // It's OK to use the Isolate & counters here, since this function is only
  // called in the main thread.
  DCHECK(parsing_on_main_thread_);

674 675
  RuntimeCallTimerScope runtime_timer(isolate, &RuntimeCallStats::ParseProgram);
  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram");
676 677
  Handle<String> source(String::cast(info->script()->source()));
  isolate->counters()->total_parse_size()->Increment(source->length());
678
  base::ElapsedTimer timer;
679 680 681
  if (FLAG_trace_parse) {
    timer.Start();
  }
682
  fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
683 684

  // Initialize parser state.
685
  ParserLogger logger;
686

687
  if (produce_cached_parse_data()) {
688
    log_ = &logger;
689
  } else if (consume_cached_parse_data()) {
690
    cached_parse_data_->Initialize();
691 692
  }

693
  DeserializeScopeChain(info, info->maybe_outer_scope_info());
694

695
  source = String::Flatten(source);
696
  FunctionLiteral* result;
697

698
  {
699
    std::unique_ptr<Utf16CharacterStream> stream(ScannerStream::For(source));
700
    scanner_.Initialize(stream.get());
wingo's avatar
wingo committed
701
    result = DoParseProgram(info);
702
  }
wingo's avatar
wingo committed
703 704
  if (result != NULL) {
    DCHECK_EQ(scanner_.peek_location().beg_pos, source->length());
705
  }
706
  HandleSourceURLComments(isolate, info->script());
707

708
  if (FLAG_trace_parse && result != nullptr) {
709
    double ms = timer.Elapsed().InMillisecondsF();
710
    if (info->is_eval()) {
711
      PrintF("[parsing eval");
712 713
    } else if (info->script()->name()->IsString()) {
      String* name = String::cast(info->script()->name());
714
      std::unique_ptr<char[]> name_chars = name->ToCString();
715
      PrintF("[parsing script: %s", name_chars.get());
716 717 718 719 720
    } else {
      PrintF("[parsing script");
    }
    PrintF(" - took %0.3f ms]\n", ms);
  }
721 722
  if (produce_cached_parse_data() && result != nullptr) {
    *info->cached_data() = logger.GetScriptData();
723
  }
724
  log_ = nullptr;
725
  return result;
726 727 728
}


wingo's avatar
wingo committed
729
FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
730 731
  // Note that this function can be called from the main thread or from a
  // background thread. We should not access anything Isolate / heap dependent
732
  // via ParseInfo, and also not pass it forward.
733 734
  DCHECK_NULL(scope_state_);
  DCHECK_NULL(target_stack_);
735

736
  ParsingModeScope mode(this, allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY);
737

738
  FunctionLiteral* result = NULL;
739
  {
740
    Scope* outer = original_scope_;
741
    DCHECK_NOT_NULL(outer);
742
    parsing_module_ = info->is_module();
743
    if (info->is_eval()) {
744
      outer = NewEvalScope(outer);
745
    } else if (parsing_module_) {
746 747
      DCHECK_EQ(outer, info->script_scope());
      outer = NewModuleScope(info->script_scope());
748
    }
wingo's avatar
wingo committed
749

750 751
    DeclarationScope* scope = outer->AsDeclarationScope();

wingo's avatar
wingo committed
752
    scope->set_start_position(0);
753

754
    FunctionState function_state(&function_state_, &scope_state_, scope);
755

756
    ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
757
    bool ok = true;
758
    int beg_pos = scanner()->location().beg_pos;
759
    if (parsing_module_) {
760 761 762 763 764 765 766 767 768 769
      // Declare the special module parameter.
      auto name = ast_value_factory()->empty_string();
      bool is_duplicate;
      bool is_rest = false;
      bool is_optional = false;
      auto var = scope->DeclareParameter(name, VAR, is_optional, is_rest,
                                         &is_duplicate, ast_value_factory());
      DCHECK(!is_duplicate);
      var->AllocateTo(VariableLocation::PARAMETER, 0);

770 771 772 773 774 775 776
      PrepareGeneratorVariables(&function_state);
      Expression* initial_yield =
          BuildInitialYield(kNoSourcePosition, kGeneratorFunction);
      body->Add(
          factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
          zone());

777
      ParseModuleItemList(body, &ok);
778
      ok = ok &&
779
           module()->Validate(this->scope()->AsModuleScope(),
780
                              &pending_error_handler_, zone());
781
    } else {
782 783
      // Don't count the mode in the use counters--give the program a chance
      // to enable script-wide strict mode below.
784
      this->scope()->SetLanguageMode(info->language_mode());
785
      ParseStatementList(body, Token::EOS, &ok);
786
    }
787

wingo's avatar
wingo committed
788 789 790 791
    // The parser will peek but not consume EOS.  Our scope logically goes all
    // the way to the EOS, though.
    scope->set_end_position(scanner()->peek_location().beg_pos);

792
    if (ok && is_strict(language_mode())) {
793
      CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
794
      CheckDecimalLiteralWithLeadingZero(beg_pos,
795
                                         scanner()->location().end_pos);
796
    }
797
    if (ok && is_sloppy(language_mode())) {
798 799 800 801
      // TODO(littledan): Function bindings on the global object that modify
      // pre-existing bindings should be made writable, enumerable and
      // nonconfigurable if possible, whereas this code will leave attributes
      // unchanged if the property already exists.
802
      InsertSloppyBlockFunctionVarBindings(scope);
803
    }
804
    if (ok) {
805
      CheckConflictingVarDeclarations(scope, &ok);
806 807
    }

808 809 810 811 812
    if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
      if (body->length() != 1 ||
          !body->at(0)->IsExpressionStatement() ||
          !body->at(0)->AsExpressionStatement()->
              expression()->IsFunctionLiteral()) {
813
        ReportMessage(MessageTemplate::kSingleFunctionLiteral);
814 815 816 817
        ok = false;
      }
    }

818
    if (ok) {
819
      RewriteDestructuringAssignments();
820
      int parameter_count = parsing_module_ ? 1 : 0;
821
      result = factory()->NewScriptOrEvalFunctionLiteral(
822
          scope, body, function_state.materialized_literal_count(),
823
          function_state.expected_property_count(), parameter_count);
824 825 826 827
    }
  }

  // Make sure the target stack is empty.
828
  DCHECK(target_stack_ == NULL);
829 830 831 832

  return result;
}

833
FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info) {
834 835 836
  // It's OK to use the Isolate & counters here, since this function is only
  // called in the main thread.
  DCHECK(parsing_on_main_thread_);
837 838 839
  RuntimeCallTimerScope runtime_timer(isolate,
                                      &RuntimeCallStats::ParseFunction);
  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseFunction");
840
  Handle<String> source(String::cast(info->script()->source()));
841
  isolate->counters()->total_parse_size()->Increment(source->length());
842
  base::ElapsedTimer timer;
843 844 845
  if (FLAG_trace_parse) {
    timer.Start();
  }
846
  Handle<SharedFunctionInfo> shared_info = info->shared_info();
847
  DeserializeScopeChain(info, info->maybe_outer_scope_info());
848

849
  // Initialize parser state.
850
  source = String::Flatten(source);
851
  FunctionLiteral* result;
852
  {
853 854
    std::unique_ptr<Utf16CharacterStream> stream(ScannerStream::For(
        source, shared_info->start_position(), shared_info->end_position()));
855
    Handle<String> name(String::cast(shared_info->name()));
856 857
    result = DoParseFunction(info, ast_value_factory()->GetString(name),
                             stream.get());
858 859 860 861
    if (result != nullptr) {
      Handle<String> inferred_name(shared_info->inferred_name());
      result->set_inferred_name(inferred_name);
    }
862
  }
863 864

  if (FLAG_trace_parse && result != NULL) {
865
    double ms = timer.Elapsed().InMillisecondsF();
866 867
    // We need to make sure that the debug-name is available.
    ast_value_factory()->Internalize(isolate);
868
    std::unique_ptr<char[]> name_chars = result->debug_name()->ToCString();
869
    PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms);
870 871
  }
  return result;
872 873
}

874 875
static FunctionLiteral::FunctionType ComputeFunctionType(ParseInfo* info) {
  if (info->is_declaration()) {
876
    return FunctionLiteral::kDeclaration;
877
  } else if (info->is_named_expression()) {
878
    return FunctionLiteral::kNamedExpression;
879 880
  } else if (IsConciseMethod(info->function_kind()) ||
             IsAccessorFunction(info->function_kind())) {
881 882 883 884
    return FunctionLiteral::kAccessorOrMethod;
  }
  return FunctionLiteral::kAnonymousExpression;
}
885

886 887 888
FunctionLiteral* Parser::DoParseFunction(ParseInfo* info,
                                         const AstRawString* raw_name,
                                         Utf16CharacterStream* source) {
889
  scanner_.Initialize(source);
890 891
  DCHECK_NULL(scope_state_);
  DCHECK_NULL(target_stack_);
892

893 894
  DCHECK(ast_value_factory());
  fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
895
  fni_->PushEnclosingName(raw_name);
896

897
  ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
898 899

  // Place holder for the result.
900
  FunctionLiteral* result = nullptr;
901 902 903

  {
    // Parse the function literal.
904
    Scope* outer = original_scope_;
905
    DeclarationScope* outer_function = outer->GetClosureScope();
906
    DCHECK(outer);
907
    FunctionState function_state(&function_state_, &scope_state_,
908
                                 outer_function);
909
    BlockState block_state(&scope_state_, outer);
910
    DCHECK(is_sloppy(outer->language_mode()) ||
911
           is_strict(info->language_mode()));
912
    FunctionLiteral::FunctionType function_type = ComputeFunctionType(info);
913
    FunctionKind kind = info->function_kind();
914
    bool ok = true;
915

916 917
    if (IsArrowFunction(kind)) {
      if (allow_harmony_async_await() && IsAsyncFunction(kind)) {
918
        DCHECK(!scanner()->HasAnyLineTerminatorAfterNext());
919 920 921 922 923 924 925 926
        if (!Check(Token::ASYNC)) {
          CHECK(stack_overflow());
          return nullptr;
        }
        if (!(peek_any_identifier() || peek() == Token::LPAREN)) {
          CHECK(stack_overflow());
          return nullptr;
        }
927 928
      }

929
      // TODO(adamk): We should construct this scope from the ScopeInfo.
930
      DeclarationScope* scope = NewFunctionScope(kind);
931 932 933 934 935

      // These two bits only need to be explicitly set because we're
      // not passing the ScopeInfo to the Scope constructor.
      // TODO(adamk): Remove these calls once the above NewScope call
      // passes the ScopeInfo.
936
      if (info->calls_eval()) {
937 938
        scope->RecordEvalCall();
      }
939
      SetLanguageMode(scope, info->language_mode());
940

941
      scope->set_start_position(info->start_position());
942
      ExpressionClassifier formals_classifier(this);
943
      ParserFormalParameters formals(scope);
944
      Checkpoint checkpoint(this);
945 946 947 948
      {
        // Parsing patterns as variable reference expression creates
        // NewUnresolved references in current scope. Entrer arrow function
        // scope for formal parameter parsing.
949
        BlockState block_state(&scope_state_, scope);
950 951
        if (Check(Token::LPAREN)) {
          // '(' StrictFormalParameters ')'
952
          ParseFormalParameterList(&formals, &ok);
953 954 955
          if (ok) ok = Check(Token::RPAREN);
        } else {
          // BindingIdentifier
956 957
          ParseFormalParameter(&formals, &ok);
          if (ok) DeclareFormalParameter(formals.scope, formals.at(0));
958
        }
959 960
      }

961
      if (ok) {
962
        checkpoint.Restore(&formals.materialized_literals_count);
963 964
        // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should
        // not be observable, or else the preparser would have failed.
965
        Expression* expression = ParseArrowFunctionLiteral(true, formals, &ok);
966 967 968 969 970 971 972
        if (ok) {
          // Scanning must end at the same position that was recorded
          // previously. If not, parsing has been interrupted due to a stack
          // overflow, at which point the partially parsed arrow function
          // concise body happens to be a valid expression. This is a problem
          // only for arrow functions with single expression bodies, since there
          // is no end token such as "}" for normal functions.
973
          if (scanner()->location().end_pos == info->end_position()) {
974 975 976 977 978 979 980
            // The pre-parser saw an arrow function here, so the full parser
            // must produce a FunctionLiteral.
            DCHECK(expression->IsFunctionLiteral());
            result = expression->AsFunctionLiteral();
          } else {
            ok = false;
          }
981 982
        }
      }
983
    } else if (IsDefaultConstructor(kind)) {
984
      DCHECK_EQ(scope(), outer);
985
      bool is_subclass_constructor = IsSubclassConstructor(kind);
986
      result = DefaultConstructor(
987 988 989 990 991 992 993 994 995 996 997 998 999 1000
          raw_name, is_subclass_constructor, info->requires_class_field_init(),
          info->start_position(), info->end_position(), info->language_mode());
      if (!is_subclass_constructor && info->requires_class_field_init()) {
        result = InsertClassFieldInitializer(result);
      }
    } else if (info->is_class_field_initializer()) {
      Handle<SharedFunctionInfo> shared_info = info->shared_info();
      DCHECK(!shared_info.is_null());
      if (shared_info->length() == 0) {
        result = ParseClassFieldForInitializer(
            info->start_position() != info->end_position(), &ok);
      } else {
        result = SynthesizeClassFieldInitializer(shared_info->length());
      }
1001
    } else {
1002 1003 1004
      result = ParseFunctionLiteral(
          raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind,
          kNoSourcePosition, function_type, info->language_mode(), &ok);
1005 1006 1007
      if (info->requires_class_field_init()) {
        result = InsertClassFieldInitializer(result);
      }
1008
    }
1009
    // Make sure the results agree.
1010
    DCHECK(ok == (result != nullptr));
1011 1012 1013
  }

  // Make sure the target stack is empty.
1014
  DCHECK_NULL(target_stack_);
1015 1016 1017
  return result;
}

1018
Statement* Parser::ParseModuleItem(bool* ok) {
1019
  // ecma262/#prod-ModuleItem
1020 1021 1022 1023
  // ModuleItem :
  //    ImportDeclaration
  //    ExportDeclaration
  //    StatementListItem
1024 1025

  switch (peek()) {
1026
    case Token::IMPORT:
1027 1028
      ParseImportDeclaration(CHECK_OK);
      return factory()->NewEmptyStatement(kNoSourcePosition);
1029 1030 1031 1032
    case Token::EXPORT:
      return ParseExportDeclaration(ok);
    default:
      return ParseStatementListItem(ok);
1033 1034 1035 1036
  }
}


neis's avatar
neis committed
1037
void Parser::ParseModuleItemList(ZoneList<Statement*>* body, bool* ok) {
1038
  // ecma262/#prod-Module
1039 1040 1041
  // Module :
  //    ModuleBody?
  //
1042
  // ecma262/#prod-ModuleItemList
1043 1044
  // ModuleBody :
  //    ModuleItem*
1045

1046
  DCHECK(scope()->is_module_scope());
1047
  while (peek() != Token::EOS) {
neis's avatar
neis committed
1048
    Statement* stat = ParseModuleItem(CHECK_OK_VOID);
1049 1050
    if (stat && !stat->IsEmpty()) {
      body->Add(stat, zone());
1051 1052 1053 1054 1055
    }
  }
}


1056
const AstRawString* Parser::ParseModuleSpecifier(bool* ok) {
1057 1058
  // ModuleSpecifier :
  //    StringLiteral
1059 1060

  Expect(Token::STRING, CHECK_OK);
1061
  return GetSymbol();
1062 1063 1064
}


neis's avatar
neis committed
1065 1066 1067 1068
void Parser::ParseExportClause(ZoneList<const AstRawString*>* export_names,
                               ZoneList<Scanner::Location>* export_locations,
                               ZoneList<const AstRawString*>* local_names,
                               Scanner::Location* reserved_loc, bool* ok) {
1069
  // ExportClause :
1070
  //   '{' '}'
1071 1072
  //   '{' ExportsList '}'
  //   '{' ExportsList ',' '}'
1073
  //
1074 1075 1076
  // ExportsList :
  //   ExportSpecifier
  //   ExportsList ',' ExportSpecifier
1077
  //
1078
  // ExportSpecifier :
1079 1080 1081
  //   IdentifierName
  //   IdentifierName 'as' IdentifierName

neis's avatar
neis committed
1082
  Expect(Token::LBRACE, CHECK_OK_VOID);
1083

1084 1085 1086 1087 1088
  Token::Value name_tok;
  while ((name_tok = peek()) != Token::RBRACE) {
    // Keep track of the first reserved word encountered in case our
    // caller needs to report an error.
    if (!reserved_loc->IsValid() &&
1089
        !Token::IsIdentifier(name_tok, STRICT, false, parsing_module_)) {
1090 1091
      *reserved_loc = scanner()->location();
    }
neis's avatar
neis committed
1092
    const AstRawString* local_name = ParseIdentifierName(CHECK_OK_VOID);
1093
    const AstRawString* export_name = NULL;
1094
    Scanner::Location location = scanner()->location();
1095
    if (CheckContextualKeyword(CStrVector("as"))) {
neis's avatar
neis committed
1096
      export_name = ParseIdentifierName(CHECK_OK_VOID);
1097 1098 1099
      // Set the location to the whole "a as b" string, so that it makes sense
      // both for errors due to "a" and for errors due to "b".
      location.end_pos = scanner()->location().end_pos;
1100
    }
1101 1102 1103 1104 1105
    if (export_name == NULL) {
      export_name = local_name;
    }
    export_names->Add(export_name, zone());
    local_names->Add(local_name, zone());
1106
    export_locations->Add(location, zone());
1107
    if (peek() == Token::RBRACE) break;
neis's avatar
neis committed
1108
    Expect(Token::COMMA, CHECK_OK_VOID);
1109 1110
  }

neis's avatar
neis committed
1111
  Expect(Token::RBRACE, CHECK_OK_VOID);
1112 1113 1114
}


1115 1116
ZoneList<const Parser::NamedImport*>* Parser::ParseNamedImports(
    int pos, bool* ok) {
1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131
  // NamedImports :
  //   '{' '}'
  //   '{' ImportsList '}'
  //   '{' ImportsList ',' '}'
  //
  // ImportsList :
  //   ImportSpecifier
  //   ImportsList ',' ImportSpecifier
  //
  // ImportSpecifier :
  //   BindingIdentifier
  //   IdentifierName 'as' BindingIdentifier

  Expect(Token::LBRACE, CHECK_OK);

1132
  auto result = new (zone()) ZoneList<const NamedImport*>(1, zone());
1133 1134 1135
  while (peek() != Token::RBRACE) {
    const AstRawString* import_name = ParseIdentifierName(CHECK_OK);
    const AstRawString* local_name = import_name;
1136
    Scanner::Location location = scanner()->location();
1137 1138
    // In the presence of 'as', the left-side of the 'as' can
    // be any IdentifierName. But without 'as', it must be a valid
1139
    // BindingIdentifier.
1140
    if (CheckContextualKeyword(CStrVector("as"))) {
1141 1142
      local_name = ParseIdentifierName(CHECK_OK);
    }
1143 1144
    if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false,
                             parsing_module_)) {
1145
      *ok = false;
1146
      ReportMessage(MessageTemplate::kUnexpectedReserved);
1147
      return nullptr;
1148
    } else if (IsEvalOrArguments(local_name)) {
1149
      *ok = false;
1150
      ReportMessage(MessageTemplate::kStrictEvalArguments);
1151
      return nullptr;
1152
    }
1153

1154 1155
    DeclareVariable(local_name, CONST, kNeedsInitialization, position(),
                    CHECK_OK);
1156

1157 1158
    NamedImport* import =
        new (zone()) NamedImport(import_name, local_name, location);
1159 1160
    result->Add(import, zone());

1161 1162 1163 1164 1165
    if (peek() == Token::RBRACE) break;
    Expect(Token::COMMA, CHECK_OK);
  }

  Expect(Token::RBRACE, CHECK_OK);
1166
  return result;
1167 1168 1169
}


neis's avatar
neis committed
1170
void Parser::ParseImportDeclaration(bool* ok) {
1171 1172 1173
  // ImportDeclaration :
  //   'import' ImportClause 'from' ModuleSpecifier ';'
  //   'import' ModuleSpecifier ';'
1174
  //
1175
  // ImportClause :
1176
  //   ImportedDefaultBinding
1177 1178 1179 1180 1181 1182 1183
  //   NameSpaceImport
  //   NamedImports
  //   ImportedDefaultBinding ',' NameSpaceImport
  //   ImportedDefaultBinding ',' NamedImports
  //
  // NameSpaceImport :
  //   '*' 'as' ImportedBinding
1184

1185
  int pos = peek_position();
neis's avatar
neis committed
1186
  Expect(Token::IMPORT, CHECK_OK_VOID);
1187 1188 1189 1190 1191

  Token::Value tok = peek();

  // 'import' ModuleSpecifier ';'
  if (tok == Token::STRING) {
neis's avatar
neis committed
1192 1193
    const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID);
    ExpectSemicolon(CHECK_OK_VOID);
1194
    module()->AddEmptyImport(module_specifier);
neis's avatar
neis committed
1195
    return;
1196 1197 1198
  }

  // Parse ImportedDefaultBinding if present.
1199 1200
  const AstRawString* import_default_binding = nullptr;
  Scanner::Location import_default_binding_loc;
1201
  if (tok != Token::MUL && tok != Token::LBRACE) {
1202
    import_default_binding =
neis's avatar
neis committed
1203
        ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK_VOID);
1204
    import_default_binding_loc = scanner()->location();
1205 1206
    DeclareVariable(import_default_binding, CONST, kNeedsInitialization, pos,
                    CHECK_OK_VOID);
1207 1208
  }

1209 1210 1211 1212 1213
  // Parse NameSpaceImport or NamedImports if present.
  const AstRawString* module_namespace_binding = nullptr;
  Scanner::Location module_namespace_binding_loc;
  const ZoneList<const NamedImport*>* named_imports = nullptr;
  if (import_default_binding == nullptr || Check(Token::COMMA)) {
1214 1215 1216
    switch (peek()) {
      case Token::MUL: {
        Consume(Token::MUL);
neis's avatar
neis committed
1217
        ExpectContextualKeyword(CStrVector("as"), CHECK_OK_VOID);
1218
        module_namespace_binding =
neis's avatar
neis committed
1219
            ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK_VOID);
1220
        module_namespace_binding_loc = scanner()->location();
1221 1222
        DeclareVariable(module_namespace_binding, CONST, kCreatedInitialized,
                        pos, CHECK_OK_VOID);
1223 1224
        break;
      }
1225

1226
      case Token::LBRACE:
neis's avatar
neis committed
1227
        named_imports = ParseNamedImports(pos, CHECK_OK_VOID);
1228 1229 1230 1231 1232
        break;

      default:
        *ok = false;
        ReportUnexpectedToken(scanner()->current_token());
neis's avatar
neis committed
1233
        return;
1234
    }
1235 1236
  }

neis's avatar
neis committed
1237 1238 1239
  ExpectContextualKeyword(CStrVector("from"), CHECK_OK_VOID);
  const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID);
  ExpectSemicolon(CHECK_OK_VOID);
1240

1241 1242 1243
  // Now that we have all the information, we can make the appropriate
  // declarations.

1244 1245 1246 1247
  // TODO(neis): Would prefer to call DeclareVariable for each case below rather
  // than above and in ParseNamedImports, but then a possible error message
  // would point to the wrong location.  Maybe have a DeclareAt version of
  // Declare that takes a location?
1248

1249 1250 1251 1252 1253
  if (module_namespace_binding != nullptr) {
    module()->AddStarImport(module_namespace_binding, module_specifier,
                            module_namespace_binding_loc, zone());
  }

1254
  if (import_default_binding != nullptr) {
1255 1256 1257
    module()->AddImport(ast_value_factory()->default_string(),
                        import_default_binding, module_specifier,
                        import_default_binding_loc, zone());
1258
  }
1259

1260 1261
  if (named_imports != nullptr) {
    if (named_imports->length() == 0) {
1262
      module()->AddEmptyImport(module_specifier);
1263 1264 1265
    } else {
      for (int i = 0; i < named_imports->length(); ++i) {
        const NamedImport* import = named_imports->at(i);
1266 1267
        module()->AddImport(import->import_name, import->local_name,
                            module_specifier, import->location, zone());
1268
      }
1269
    }
1270
  }
1271 1272 1273
}


1274 1275
Statement* Parser::ParseExportDefault(bool* ok) {
  //  Supports the following productions, starting after the 'default' token:
1276
  //    'export' 'default' HoistableDeclaration
1277 1278 1279
  //    'export' 'default' ClassDeclaration
  //    'export' 'default' AssignmentExpression[In] ';'

1280 1281 1282
  Expect(Token::DEFAULT, CHECK_OK);
  Scanner::Location default_loc = scanner()->location();

1283
  ZoneList<const AstRawString*> local_names(1, zone());
1284
  Statement* result = nullptr;
1285
  switch (peek()) {
1286
    case Token::FUNCTION:
1287
      result = ParseHoistableDeclaration(&local_names, true, CHECK_OK);
1288 1289 1290
      break;

    case Token::CLASS:
1291
      Consume(Token::CLASS);
1292
      result = ParseClassDeclaration(&local_names, true, CHECK_OK);
1293 1294
      break;

1295 1296 1297 1298
    case Token::ASYNC:
      if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION &&
          !scanner()->HasAnyLineTerminatorAfterNext()) {
        Consume(Token::ASYNC);
1299
        result = ParseAsyncFunctionDeclaration(&local_names, true, CHECK_OK);
1300 1301 1302 1303
        break;
      }
    /* falls through */

1304
    default: {
1305
      int pos = position();
1306
      ExpressionClassifier classifier(this);
1307 1308
      Expression* value = ParseAssignmentExpression(true, CHECK_OK);
      RewriteNonPattern(CHECK_OK);
1309 1310 1311 1312 1313 1314 1315 1316
      SetFunctionName(value, ast_value_factory()->default_string());

      const AstRawString* local_name =
          ast_value_factory()->star_default_star_string();
      local_names.Add(local_name, zone());

      // It's fine to declare this as CONST because the user has no way of
      // writing to it.
1317 1318
      Declaration* decl = DeclareVariable(local_name, CONST, pos, CHECK_OK);
      decl->proxy()->var()->set_initializer_position(position());
1319 1320

      Assignment* assignment = factory()->NewAssignment(
1321
          Token::INIT, decl->proxy(), value, kNoSourcePosition);
1322
      result = factory()->NewExpressionStatement(assignment, kNoSourcePosition);
1323

1324 1325 1326 1327 1328
      ExpectSemicolon(CHECK_OK);
      break;
    }
  }

1329
  DCHECK_EQ(local_names.length(), 1);
1330 1331 1332
  module()->AddExport(local_names.first(),
                      ast_value_factory()->default_string(), default_loc,
                      zone());
1333

1334
  DCHECK_NOT_NULL(result);
1335 1336 1337
  return result;
}

1338 1339
Statement* Parser::ParseExportDeclaration(bool* ok) {
  // ExportDeclaration:
1340 1341 1342 1343 1344
  //    'export' '*' 'from' ModuleSpecifier ';'
  //    'export' ExportClause ('from' ModuleSpecifier)? ';'
  //    'export' VariableStatement
  //    'export' Declaration
  //    'export' 'default' ... (handled in ParseExportDefault)
1345 1346

  Expect(Token::EXPORT, CHECK_OK);
1347
  int pos = position();
1348

1349
  Statement* result = nullptr;
1350
  ZoneList<const AstRawString*> names(1, zone());
1351
  Scanner::Location loc = scanner()->peek_location();
1352
  switch (peek()) {
1353 1354 1355 1356 1357
    case Token::DEFAULT:
      return ParseExportDefault(ok);

    case Token::MUL: {
      Consume(Token::MUL);
1358
      loc = scanner()->location();
1359
      ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1360
      const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1361
      ExpectSemicolon(CHECK_OK);
1362
      module()->AddStarExport(module_specifier, loc, zone());
1363
      return factory()->NewEmptyStatement(pos);
1364 1365
    }

1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378
    case Token::LBRACE: {
      // There are two cases here:
      //
      // 'export' ExportClause ';'
      // and
      // 'export' ExportClause FromClause ';'
      //
      // In the first case, the exported identifiers in ExportClause must
      // not be reserved words, while in the latter they may be. We
      // pass in a location that gets filled with the first reserved word
      // encountered, and then throw a SyntaxError if we are in the
      // non-FromClause case.
      Scanner::Location reserved_loc = Scanner::Location::invalid();
1379 1380
      ZoneList<const AstRawString*> export_names(1, zone());
      ZoneList<Scanner::Location> export_locations(1, zone());
1381 1382
      ZoneList<const AstRawString*> original_names(1, zone());
      ParseExportClause(&export_names, &export_locations, &original_names,
1383
                        &reserved_loc, CHECK_OK);
1384
      const AstRawString* module_specifier = nullptr;
1385
      if (CheckContextualKeyword(CStrVector("from"))) {
1386
        module_specifier = ParseModuleSpecifier(CHECK_OK);
1387 1388 1389
      } else if (reserved_loc.IsValid()) {
        // No FromClause, so reserved words are invalid in ExportClause.
        *ok = false;
1390
        ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved);
1391
        return nullptr;
1392 1393
      }
      ExpectSemicolon(CHECK_OK);
1394
      const int length = export_names.length();
1395
      DCHECK_EQ(length, original_names.length());
1396
      DCHECK_EQ(length, export_locations.length());
1397
      if (module_specifier == nullptr) {
1398
        for (int i = 0; i < length; ++i) {
1399 1400
          module()->AddExport(original_names[i], export_names[i],
                              export_locations[i], zone());
1401
        }
1402
      } else if (length == 0) {
1403
        module()->AddEmptyImport(module_specifier);
1404 1405
      } else {
        for (int i = 0; i < length; ++i) {
1406 1407
          module()->AddExport(original_names[i], export_names[i],
                              module_specifier, export_locations[i], zone());
1408 1409 1410
        }
      }
      return factory()->NewEmptyStatement(pos);
1411
    }
1412

1413
    case Token::FUNCTION:
1414
      result = ParseHoistableDeclaration(&names, false, CHECK_OK);
1415 1416
      break;

arv@chromium.org's avatar
arv@chromium.org committed
1417
    case Token::CLASS:
1418
      Consume(Token::CLASS);
1419
      result = ParseClassDeclaration(&names, false, CHECK_OK);
arv@chromium.org's avatar
arv@chromium.org committed
1420 1421
      break;

1422 1423 1424
    case Token::VAR:
    case Token::LET:
    case Token::CONST:
1425
      result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK);
1426 1427
      break;

1428 1429
    case Token::ASYNC:
      if (allow_harmony_async_await()) {
1430 1431
        // TODO(neis): Why don't we have the same check here as in
        // ParseStatementListItem?
1432
        Consume(Token::ASYNC);
1433
        result = ParseAsyncFunctionDeclaration(&names, false, CHECK_OK);
1434 1435 1436 1437
        break;
      }
    /* falls through */

1438 1439
    default:
      *ok = false;
1440
      ReportUnexpectedToken(scanner()->current_token());
1441
      return nullptr;
1442
  }
1443
  loc.end_pos = scanner()->location().end_pos;
1444

1445
  ModuleDescriptor* descriptor = module();
1446
  for (int i = 0; i < names.length(); ++i) {
1447
    descriptor->AddExport(names[i], names[i], loc, zone());
1448 1449
  }

1450
  DCHECK_NOT_NULL(result);
1451
  return result;
1452 1453
}

1454
VariableProxy* Parser::NewUnresolved(const AstRawString* name, int begin_pos,
1455 1456
                                     VariableKind kind) {
  return scope()->NewUnresolved(factory(), name, begin_pos, kind);
1457
}
1458

1459
VariableProxy* Parser::NewUnresolved(const AstRawString* name) {
1460
  return scope()->NewUnresolved(factory(), name, scanner()->location().beg_pos);
1461 1462
}

1463 1464
Declaration* Parser::DeclareVariable(const AstRawString* name,
                                     VariableMode mode, int pos, bool* ok) {
1465 1466
  return DeclareVariable(name, mode, Variable::DefaultInitializationFlag(mode),
                         pos, ok);
1467 1468 1469 1470 1471
}

Declaration* Parser::DeclareVariable(const AstRawString* name,
                                     VariableMode mode, InitializationFlag init,
                                     int pos, bool* ok) {
1472
  DCHECK_NOT_NULL(name);
1473
  VariableProxy* proxy = factory()->NewVariableProxy(
1474
      name, NORMAL_VARIABLE, scanner()->location().beg_pos);
1475
  Declaration* declaration =
1476
      factory()->NewVariableDeclaration(proxy, this->scope(), pos);
1477 1478 1479
  Declare(declaration, DeclarationDescriptor::NORMAL, mode, init, ok, nullptr,
          scanner()->location().end_pos);
  if (!*ok) return nullptr;
1480
  return declaration;
1481 1482
}

1483 1484
Variable* Parser::Declare(Declaration* declaration,
                          DeclarationDescriptor::Kind declaration_kind,
1485
                          VariableMode mode, InitializationFlag init, bool* ok,
1486
                          Scope* scope, int var_end_pos) {
marja's avatar
marja committed
1487 1488 1489 1490 1491 1492 1493 1494
  if (scope == nullptr) {
    scope = this->scope();
  }
  bool sloppy_mode_block_scope_function_redefinition = false;
  Variable* variable = scope->DeclareVariable(
      declaration, mode, init, allow_harmony_restrictive_generators(),
      &sloppy_mode_block_scope_function_redefinition, ok);
  if (!*ok) {
1495 1496 1497 1498 1499 1500 1501
    // If we only have the start position of a proxy, we can't highlight the
    // whole variable name.  Pretend its length is 1 so that we highlight at
    // least the first character.
    Scanner::Location loc(declaration->proxy()->position(),
                          var_end_pos != kNoSourcePosition
                              ? var_end_pos
                              : declaration->proxy()->position() + 1);
marja's avatar
marja committed
1502
    if (declaration_kind == DeclarationDescriptor::NORMAL) {
1503 1504
      ReportMessageAt(loc, MessageTemplate::kVarRedeclaration,
                      declaration->proxy()->raw_name());
marja's avatar
marja committed
1505
    } else {
1506
      ReportMessageAt(loc, MessageTemplate::kParamDupe);
1507
    }
1508
    return nullptr;
1509
  }
marja's avatar
marja committed
1510 1511 1512 1513
  if (sloppy_mode_block_scope_function_redefinition) {
    ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition];
  }
  return variable;
1514 1515
}

1516 1517
Block* Parser::BuildInitializationBlock(
    DeclarationParsingResult* parsing_result,
1518
    ZoneList<const AstRawString*>* names, bool* ok) {
1519 1520 1521
  Block* result = factory()->NewBlock(
      NULL, 1, true, parsing_result->descriptor.declaration_pos);
  for (auto declaration : parsing_result->declarations) {
1522
    PatternRewriter::DeclareAndInitializeVariables(
1523 1524
        this, result, &(parsing_result->descriptor), &declaration, names,
        CHECK_OK);
1525 1526 1527 1528
  }
  return result;
}

1529 1530 1531 1532 1533 1534 1535 1536
void Parser::DeclareAndInitializeVariables(
    Block* block, const DeclarationDescriptor* declaration_descriptor,
    const DeclarationParsingResult::Declaration* declaration,
    ZoneList<const AstRawString*>* names, bool* ok) {
  DCHECK_NOT_NULL(block);
  PatternRewriter::DeclareAndInitializeVariables(
      this, block, declaration_descriptor, declaration, names, ok);
}
1537

1538 1539 1540 1541 1542 1543 1544 1545 1546 1547
Statement* Parser::DeclareFunction(const AstRawString* variable_name,
                                   FunctionLiteral* function, int pos,
                                   bool is_generator, bool is_async,
                                   ZoneList<const AstRawString*>* names,
                                   bool* ok) {
  // In ES6, a function behaves as a lexical binding, except in
  // a script scope, or the initial scope of eval or another function.
  VariableMode mode =
      (!scope()->is_declaration_scope() || scope()->is_module_scope()) ? LET
                                                                       : VAR;
1548 1549
  VariableProxy* proxy =
      factory()->NewVariableProxy(variable_name, NORMAL_VARIABLE);
1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570
  Declaration* declaration =
      factory()->NewFunctionDeclaration(proxy, function, scope(), pos);
  Declare(declaration, DeclarationDescriptor::NORMAL, mode, kCreatedInitialized,
          CHECK_OK);
  if (names) names->Add(variable_name, zone());
  // Async functions don't undergo sloppy mode block scoped hoisting, and don't
  // allow duplicates in a block. Both are represented by the
  // sloppy_block_function_map. Don't add them to the map for async functions.
  // Generators are also supposed to be prohibited; currently doing this behind
  // a flag and UseCounting violations to assess web compatibility.
  if (is_sloppy(language_mode()) && !scope()->is_declaration_scope() &&
      !is_async && !(allow_harmony_restrictive_generators() && is_generator)) {
    SloppyBlockFunctionStatement* delegate =
        factory()->NewSloppyBlockFunctionStatement(scope());
    DeclarationScope* target_scope = GetDeclarationScope();
    target_scope->DeclareSloppyBlockFunction(variable_name, delegate);
    return delegate;
  }
  return factory()->NewEmptyStatement(kNoSourcePosition);
}

1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604
Statement* Parser::DeclareClass(const AstRawString* variable_name,
                                Expression* value,
                                ZoneList<const AstRawString*>* names,
                                int class_token_pos, int end_pos, bool* ok) {
  Declaration* decl =
      DeclareVariable(variable_name, LET, class_token_pos, CHECK_OK);
  decl->proxy()->var()->set_initializer_position(end_pos);
  Assignment* assignment = factory()->NewAssignment(Token::INIT, decl->proxy(),
                                                    value, class_token_pos);
  Statement* assignment_statement =
      factory()->NewExpressionStatement(assignment, kNoSourcePosition);
  if (names) names->Add(variable_name, zone());
  return assignment_statement;
}

Statement* Parser::DeclareNative(const AstRawString* name, int pos, bool* ok) {
  // Make sure that the function containing the native declaration
  // isn't lazily compiled. The extension structures are only
  // accessible while parsing the first time not when reparsing
  // because of lazy compilation.
  GetClosureScope()->ForceEagerCompilation();

  // TODO(1240846): It's weird that native function declarations are
  // introduced dynamically when we meet their declarations, whereas
  // other functions are set up when entering the surrounding scope.
  Declaration* decl = DeclareVariable(name, VAR, pos, CHECK_OK);
  NativeFunctionLiteral* lit =
      factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition);
  return factory()->NewExpressionStatement(
      factory()->NewAssignment(Token::INIT, decl->proxy(), lit,
                               kNoSourcePosition),
      pos);
}

1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634
ZoneList<const AstRawString*>* Parser::DeclareLabel(
    ZoneList<const AstRawString*>* labels, VariableProxy* var, bool* ok) {
  const AstRawString* label = var->raw_name();
  // TODO(1240780): We don't check for redeclaration of labels
  // during preparsing since keeping track of the set of active
  // labels requires nontrivial changes to the way scopes are
  // structured.  However, these are probably changes we want to
  // make later anyway so we should go back and fix this then.
  if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
    ReportMessage(MessageTemplate::kLabelRedeclaration, label);
    *ok = false;
    return nullptr;
  }
  if (labels == nullptr) {
    labels = new (zone()) ZoneList<const AstRawString*>(1, zone());
  }
  labels->Add(label, zone());
  // Remove the "ghost" variable that turned out to be a label
  // from the top scope. This way, we don't try to resolve it
  // during the scope processing.
  scope()->RemoveUnresolved(var);
  return labels;
}

bool Parser::ContainsLabel(ZoneList<const AstRawString*>* labels,
                           const AstRawString* label) {
  DCHECK_NOT_NULL(label);
  if (labels != nullptr) {
    for (int i = labels->length(); i-- > 0;) {
      if (labels->at(i) == label) return true;
1635 1636
    }
  }
1637 1638 1639
  return false;
}

1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686
Expression* Parser::RewriteReturn(Expression* return_value, int pos) {
  if (IsSubclassConstructor(function_state_->kind())) {
    // For subclass constructors we need to return this in case of undefined
    // return a Smi (transformed into an exception in the ConstructStub)
    // for a non object.
    //
    //   return expr;
    //
    // Is rewritten as:
    //
    //   return (temp = expr) === undefined ? this :
    //       %_IsJSReceiver(temp) ? temp : 1;

    // temp = expr
    Variable* temp = NewTemporary(ast_value_factory()->empty_string());
    Assignment* assign = factory()->NewAssignment(
        Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos);

    // %_IsJSReceiver(temp)
    ZoneList<Expression*>* is_spec_object_args =
        new (zone()) ZoneList<Expression*>(1, zone());
    is_spec_object_args->Add(factory()->NewVariableProxy(temp), zone());
    Expression* is_spec_object_call = factory()->NewCallRuntime(
        Runtime::kInlineIsJSReceiver, is_spec_object_args, pos);

    // %_IsJSReceiver(temp) ? temp : 1;
    Expression* is_object_conditional = factory()->NewConditional(
        is_spec_object_call, factory()->NewVariableProxy(temp),
        factory()->NewSmiLiteral(1, pos), pos);

    // temp === undefined
    Expression* is_undefined = factory()->NewCompareOperation(
        Token::EQ_STRICT, assign,
        factory()->NewUndefinedLiteral(kNoSourcePosition), pos);

    // is_undefined ? this : is_object_conditional
    return_value = factory()->NewConditional(is_undefined, ThisExpression(pos),
                                             is_object_conditional, pos);
  }
  if (is_generator()) {
    return_value = BuildIteratorResult(return_value, true);
  } else if (is_async_function()) {
    return_value = BuildResolvePromise(return_value, return_value->position());
  }
  return return_value;
}

1687 1688 1689 1690 1691 1692 1693 1694 1695 1696
Expression* Parser::RewriteDoExpression(Block* body, int pos, bool* ok) {
  Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
  DoExpression* expr = factory()->NewDoExpression(body, result, pos);
  if (!Rewriter::Rewrite(this, GetClosureScope(), expr, ast_value_factory())) {
    *ok = false;
    return nullptr;
  }
  return expr;
}

1697 1698 1699 1700
Statement* Parser::RewriteSwitchStatement(Expression* tag,
                                          SwitchStatement* switch_statement,
                                          ZoneList<CaseClause*>* cases,
                                          Scope* scope) {
1701 1702 1703 1704 1705 1706 1707 1708 1709
  // In order to get the CaseClauses to execute in their own lexical scope,
  // but without requiring downstream code to have special scope handling
  // code for switch statements, desugar into blocks as follows:
  // {  // To group the statements--harmless to evaluate Expression in scope
  //   .tag_variable = Expression;
  //   {  // To give CaseClauses a scope
  //     switch (.tag_variable) { CaseClause* }
  //   }
  // }
1710

yangguo's avatar
yangguo committed
1711
  Block* switch_block = factory()->NewBlock(NULL, 2, false, kNoSourcePosition);
1712

1713
  Variable* tag_variable =
1714
      NewTemporary(ast_value_factory()->dot_switch_tag_string());
1715 1716 1717 1718
  Assignment* tag_assign = factory()->NewAssignment(
      Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag,
      tag->position());
  Statement* tag_statement =
yangguo's avatar
yangguo committed
1719
      factory()->NewExpressionStatement(tag_assign, kNoSourcePosition);
neis's avatar
neis committed
1720
  switch_block->statements()->Add(tag_statement, zone());
1721

1722 1723 1724
  // make statement: undefined;
  // This is needed so the tag isn't returned as the value, in case the switch
  // statements don't have a value.
neis's avatar
neis committed
1725
  switch_block->statements()->Add(
1726
      factory()->NewExpressionStatement(
yangguo's avatar
yangguo committed
1727
          factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
1728 1729
      zone());

1730 1731
  Expression* tag_read = factory()->NewVariableProxy(tag_variable);
  switch_statement->Initialize(tag_read, cases);
yangguo's avatar
yangguo committed
1732
  Block* cases_block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition);
1733 1734
  cases_block->statements()->Add(switch_statement, zone());
  cases_block->set_scope(scope);
neis's avatar
neis committed
1735
  switch_block->statements()->Add(cases_block, zone());
1736
  return switch_block;
1737 1738
}

1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768
void Parser::RewriteCatchPattern(CatchInfo* catch_info, bool* ok) {
  if (catch_info->name == nullptr) {
    DCHECK_NOT_NULL(catch_info->pattern);
    catch_info->name = ast_value_factory()->dot_catch_string();
  }
  catch_info->variable = catch_info->scope->DeclareLocal(
      catch_info->name, VAR, kCreatedInitialized, NORMAL_VARIABLE);
  if (catch_info->pattern != nullptr) {
    DeclarationDescriptor descriptor;
    descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
    descriptor.scope = scope();
    descriptor.hoist_scope = nullptr;
    descriptor.mode = LET;
    descriptor.declaration_pos = catch_info->pattern->position();
    descriptor.initialization_pos = catch_info->pattern->position();

    // Initializer position for variables declared by the pattern.
    const int initializer_position = position();

    DeclarationParsingResult::Declaration decl(
        catch_info->pattern, initializer_position,
        factory()->NewVariableProxy(catch_info->variable));

    catch_info->init_block =
        factory()->NewBlock(nullptr, 8, true, kNoSourcePosition);
    PatternRewriter::DeclareAndInitializeVariables(
        this, catch_info->init_block, &descriptor, &decl,
        &catch_info->bound_names, ok);
  } else {
    catch_info->bound_names.Add(catch_info->name, zone());
1769
  }
1770
}
1771

1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786
void Parser::ValidateCatchBlock(const CatchInfo& catch_info, bool* ok) {
  // Check for `catch(e) { let e; }` and similar errors.
  Scope* inner_block_scope = catch_info.inner_block->scope();
  if (inner_block_scope != nullptr) {
    Declaration* decl = inner_block_scope->CheckLexDeclarationsConflictingWith(
        catch_info.bound_names);
    if (decl != nullptr) {
      const AstRawString* name = decl->proxy()->raw_name();
      int position = decl->proxy()->position();
      Scanner::Location location =
          position == kNoSourcePosition
              ? Scanner::Location::invalid()
              : Scanner::Location(position, position + 1);
      ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
      *ok = false;
1787
    }
1788
  }
1789
}
1790

1791 1792 1793
Statement* Parser::RewriteTryStatement(Block* try_block, Block* catch_block,
                                       Block* finally_block,
                                       const CatchInfo& catch_info, int pos) {
1794
  // Simplify the AST nodes by converting:
1795
  //   'try B0 catch B1 finally B2'
1796
  // to:
1797
  //   'try { try B0 catch B1 } finally B2'
1798

1799
  if (catch_block != nullptr && finally_block != nullptr) {
1800
    // If we have both, create an inner try/catch.
1801 1802
    DCHECK_NOT_NULL(catch_info.scope);
    DCHECK_NOT_NULL(catch_info.variable);
1803
    TryCatchStatement* statement;
1804
    if (catch_info.for_promise_reject) {
1805
      statement = factory()->NewTryCatchStatementForPromiseReject(
1806
          try_block, catch_info.scope, catch_info.variable, catch_block,
1807 1808
          kNoSourcePosition);
    } else {
1809 1810 1811
      statement = factory()->NewTryCatchStatement(
          try_block, catch_info.scope, catch_info.variable, catch_block,
          kNoSourcePosition);
1812 1813
    }

1814
    try_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
neis's avatar
neis committed
1815
    try_block->statements()->Add(statement, zone());
1816
    catch_block = nullptr;  // Clear to indicate it's been handled.
1817 1818
  }

1819
  if (catch_block != nullptr) {
1820 1821
    // For a try-catch construct append return expressions from the catch block
    // to the list of return expressions.
1822
    function_state_->tail_call_expressions().Append(
1823
        catch_info.tail_call_expressions);
1824

1825 1826 1827 1828 1829
    DCHECK_NULL(finally_block);
    DCHECK_NOT_NULL(catch_info.scope);
    DCHECK_NOT_NULL(catch_info.variable);
    return factory()->NewTryCatchStatement(
        try_block, catch_info.scope, catch_info.variable, catch_block, pos);
1830
  } else {
1831 1832
    DCHECK_NOT_NULL(finally_block);
    return factory()->NewTryFinallyStatement(try_block, finally_block, pos);
1833 1834 1835
  }
}

1836
// !%_IsJSReceiver(result = iterator.next()) &&
1837 1838 1839 1840
//     %ThrowIteratorResultNotAnObject(result)
Expression* Parser::BuildIteratorNextResult(Expression* iterator,
                                            Variable* result, int pos) {
  Expression* next_literal = factory()->NewStringLiteral(
yangguo's avatar
yangguo committed
1841
      ast_value_factory()->next_string(), kNoSourcePosition);
1842
  Expression* next_property =
yangguo's avatar
yangguo committed
1843
      factory()->NewProperty(iterator, next_literal, kNoSourcePosition);
1844 1845 1846 1847 1848 1849 1850 1851
  ZoneList<Expression*>* next_arguments =
      new (zone()) ZoneList<Expression*>(0, zone());
  Expression* next_call =
      factory()->NewCall(next_property, next_arguments, pos);
  Expression* result_proxy = factory()->NewVariableProxy(result);
  Expression* left =
      factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos);

1852
  // %_IsJSReceiver(...)
1853 1854 1855 1856
  ZoneList<Expression*>* is_spec_object_args =
      new (zone()) ZoneList<Expression*>(1, zone());
  is_spec_object_args->Add(left, zone());
  Expression* is_spec_object_call = factory()->NewCallRuntime(
1857
      Runtime::kInlineIsJSReceiver, is_spec_object_args, pos);
1858 1859 1860 1861 1862 1863 1864

  // %ThrowIteratorResultNotAnObject(result)
  Expression* result_proxy_again = factory()->NewVariableProxy(result);
  ZoneList<Expression*>* throw_arguments =
      new (zone()) ZoneList<Expression*>(1, zone());
  throw_arguments->Add(result_proxy_again, zone());
  Expression* throw_call = factory()->NewCallRuntime(
1865
      Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos);
1866 1867 1868 1869 1870 1871 1872

  return factory()->NewBinaryOperation(
      Token::AND,
      factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos),
      throw_call, pos);
}

1873 1874 1875 1876 1877
Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt,
                                              Expression* each,
                                              Expression* subject,
                                              Statement* body,
                                              int each_keyword_pos) {
1878 1879
  ForOfStatement* for_of = stmt->AsForOfStatement();
  if (for_of != NULL) {
1880 1881 1882
    const bool finalize = true;
    return InitializeForOfStatement(for_of, each, subject, body, finalize,
                                    each_keyword_pos);
1883
  } else {
1884
    if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
1885
      Variable* temp = NewTemporary(ast_value_factory()->empty_string());
1886 1887 1888
      VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
      Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment(
          this, factory()->NewAssignment(Token::ASSIGN, each, temp_proxy,
yangguo's avatar
yangguo committed
1889
                                         kNoSourcePosition),
1890
          scope());
yangguo's avatar
yangguo committed
1891 1892 1893 1894
      auto block = factory()->NewBlock(nullptr, 2, false, kNoSourcePosition);
      block->statements()->Add(
          factory()->NewExpressionStatement(assign_each, kNoSourcePosition),
          zone());
1895 1896 1897 1898
      block->statements()->Add(body, zone());
      body = block;
      each = factory()->NewVariableProxy(temp);
    }
1899
    stmt->AsForInStatement()->Initialize(each, subject, body);
1900
  }
1901
  return stmt;
1902 1903
}

1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010
// Special case for legacy for
//
//    for (var x = initializer in enumerable) body
//
// An initialization block of the form
//
//    {
//      x = initializer;
//    }
//
// is returned in this case.  It has reserved space for two statements,
// so that (later on during parsing), the equivalent of
//
//   for (x in enumerable) body
//
// is added as a second statement to it.
Block* Parser::RewriteForVarInLegacy(const ForInfo& for_info) {
  const DeclarationParsingResult::Declaration& decl =
      for_info.parsing_result.declarations[0];
  if (!IsLexicalVariableMode(for_info.parsing_result.descriptor.mode) &&
      decl.pattern->IsVariableProxy() && decl.initializer != nullptr) {
    ++use_counts_[v8::Isolate::kForInInitializer];
    const AstRawString* name = decl.pattern->AsVariableProxy()->raw_name();
    VariableProxy* single_var = NewUnresolved(name);
    Block* init_block = factory()->NewBlock(
        nullptr, 2, true, for_info.parsing_result.descriptor.declaration_pos);
    init_block->statements()->Add(
        factory()->NewExpressionStatement(
            factory()->NewAssignment(Token::ASSIGN, single_var,
                                     decl.initializer, kNoSourcePosition),
            kNoSourcePosition),
        zone());
    return init_block;
  }
  return nullptr;
}

// Rewrite a for-in/of statement of the form
//
//   for (let/const/var x in/of e) b
//
// into
//
//   {
//     <let x' be a temporary variable>
//     for (x' in/of e) {
//       let/const/var x;
//       x = x';
//       b;
//     }
//     let x;  // for TDZ
//   }
void Parser::DesugarBindingInForEachStatement(ForInfo* for_info,
                                              Block** body_block,
                                              Expression** each_variable,
                                              bool* ok) {
  DeclarationParsingResult::Declaration& decl =
      for_info->parsing_result.declarations[0];
  Variable* temp = NewTemporary(ast_value_factory()->dot_for_string());
  auto each_initialization_block =
      factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
  {
    auto descriptor = for_info->parsing_result.descriptor;
    descriptor.declaration_pos = kNoSourcePosition;
    descriptor.initialization_pos = kNoSourcePosition;
    decl.initializer = factory()->NewVariableProxy(temp);

    bool is_for_var_of =
        for_info->mode == ForEachStatement::ITERATE &&
        for_info->parsing_result.descriptor.mode == VariableMode::VAR;

    PatternRewriter::DeclareAndInitializeVariables(
        this, each_initialization_block, &descriptor, &decl,
        (IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) ||
         is_for_var_of)
            ? &for_info->bound_names
            : nullptr,
        CHECK_OK_VOID);

    // Annex B.3.5 prohibits the form
    // `try {} catch(e) { for (var e of {}); }`
    // So if we are parsing a statement like `for (var ... of ...)`
    // we need to walk up the scope chain and look for catch scopes
    // which have a simple binding, then compare their binding against
    // all of the names declared in the init of the for-of we're
    // parsing.
    if (is_for_var_of) {
      Scope* catch_scope = scope();
      while (catch_scope != nullptr && !catch_scope->is_declaration_scope()) {
        if (catch_scope->is_catch_scope()) {
          auto name = catch_scope->catch_variable_name();
          // If it's a simple binding and the name is declared in the for loop.
          if (name != ast_value_factory()->dot_catch_string() &&
              for_info->bound_names.Contains(name)) {
            ReportMessageAt(for_info->parsing_result.bindings_loc,
                            MessageTemplate::kVarRedeclaration, name);
            *ok = false;
            return;
          }
        }
        catch_scope = catch_scope->outer_scope();
      }
    }
  }

  *body_block = factory()->NewBlock(nullptr, 3, false, kNoSourcePosition);
  (*body_block)->statements()->Add(each_initialization_block, zone());
2011
  *each_variable = factory()->NewVariableProxy(temp, for_info->position);
2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033
}

// Create a TDZ for any lexically-bound names in for in/of statements.
Block* Parser::CreateForEachStatementTDZ(Block* init_block,
                                         const ForInfo& for_info, bool* ok) {
  if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) {
    DCHECK_NULL(init_block);

    init_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);

    for (int i = 0; i < for_info.bound_names.length(); ++i) {
      // TODO(adamk): This needs to be some sort of special
      // INTERNAL variable that's invisible to the debugger
      // but visible to everything else.
      Declaration* tdz_decl = DeclareVariable(for_info.bound_names[i], LET,
                                              kNoSourcePosition, CHECK_OK);
      tdz_decl->proxy()->var()->set_initializer_position(position());
    }
  }
  return init_block;
}

2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047
Statement* Parser::InitializeForOfStatement(ForOfStatement* for_of,
                                            Expression* each,
                                            Expression* iterable,
                                            Statement* body, bool finalize,
                                            int next_result_pos) {
  // Create the auxiliary expressions needed for iterating over the iterable,
  // and initialize the given ForOfStatement with them.
  // If finalize is true, also instrument the loop with code that performs the
  // proper ES6 iterator finalization.  In that case, the result is not
  // immediately a ForOfStatement.

  const int nopos = kNoSourcePosition;
  auto avfactory = ast_value_factory();

2048 2049 2050
  Variable* iterator = NewTemporary(ast_value_factory()->dot_iterator_string());
  Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
  Variable* completion = NewTemporary(avfactory->empty_string());
2051 2052

  // iterator = iterable[Symbol.iterator]()
2053 2054 2055 2056
  Expression* assign_iterator;
  {
    assign_iterator = factory()->NewAssignment(
        Token::ASSIGN, factory()->NewVariableProxy(iterator),
2057
        GetIterator(iterable, iterable->position()), iterable->position());
2058
  }
2059 2060 2061

  // !%_IsJSReceiver(result = iterator.next()) &&
  //     %ThrowIteratorResultNotAnObject(result)
2062
  Expression* next_result;
2063 2064 2065 2066 2067 2068 2069
  {
    Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
    next_result =
        BuildIteratorNextResult(iterator_proxy, result, next_result_pos);
  }

  // result.done
2070
  Expression* result_done;
2071 2072
  {
    Expression* done_literal = factory()->NewStringLiteral(
yangguo's avatar
yangguo committed
2073
        ast_value_factory()->done_string(), kNoSourcePosition);
2074
    Expression* result_proxy = factory()->NewVariableProxy(result);
yangguo's avatar
yangguo committed
2075 2076
    result_done =
        factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition);
2077 2078
  }

2079 2080
  // result.value
  Expression* result_value;
2081
  {
2082 2083
    Expression* value_literal =
        factory()->NewStringLiteral(avfactory->value_string(), nopos);
2084
    Expression* result_proxy = factory()->NewVariableProxy(result);
2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104
    result_value = factory()->NewProperty(result_proxy, value_literal, nopos);
  }

  // {{completion = kAbruptCompletion;}}
  Statement* set_completion_abrupt;
  if (finalize) {
    Expression* proxy = factory()->NewVariableProxy(completion);
    Expression* assignment = factory()->NewAssignment(
        Token::ASSIGN, proxy,
        factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);

    Block* block = factory()->NewBlock(nullptr, 1, true, nopos);
    block->statements()->Add(
        factory()->NewExpressionStatement(assignment, nopos), zone());
    set_completion_abrupt = block;
  }

  // do { let tmp = #result_value; #set_completion_abrupt; tmp }
  // Expression* result_value (gets overwritten)
  if (finalize) {
2105
    Variable* var_tmp = NewTemporary(avfactory->empty_string());
2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122
    Expression* tmp = factory()->NewVariableProxy(var_tmp);
    Expression* assignment =
        factory()->NewAssignment(Token::ASSIGN, tmp, result_value, nopos);

    Block* block = factory()->NewBlock(nullptr, 2, false, nopos);
    block->statements()->Add(
        factory()->NewExpressionStatement(assignment, nopos), zone());
    block->statements()->Add(set_completion_abrupt, zone());

    result_value = factory()->NewDoExpression(block, var_tmp, nopos);
  }

  // each = #result_value;
  Expression* assign_each;
  {
    assign_each =
        factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos);
2123 2124
    if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
      assign_each = PatternRewriter::RewriteDestructuringAssignment(
2125
          this, assign_each->AsAssignment(), scope());
2126 2127 2128
    }
  }

2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151
  // {{completion = kNormalCompletion;}}
  Statement* set_completion_normal;
  if (finalize) {
    Expression* proxy = factory()->NewVariableProxy(completion);
    Expression* assignment = factory()->NewAssignment(
        Token::ASSIGN, proxy,
        factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);

    Block* block = factory()->NewBlock(nullptr, 1, true, nopos);
    block->statements()->Add(
        factory()->NewExpressionStatement(assignment, nopos), zone());
    set_completion_normal = block;
  }

  // { #loop-body; #set_completion_normal }
  // Statement* body (gets overwritten)
  if (finalize) {
    Block* block = factory()->NewBlock(nullptr, 2, false, nopos);
    block->statements()->Add(body, zone());
    block->statements()->Add(set_completion_normal, zone());
    body = block;
  }

2152 2153
  for_of->Initialize(body, iterator, assign_iterator, next_result, result_done,
                     assign_each);
2154
  return finalize ? FinalizeForOfStatement(for_of, completion, nopos) : for_of;
2155 2156
}

rossberg's avatar
rossberg committed
2157
Statement* Parser::DesugarLexicalBindingsInForStatement(
2158
    ForStatement* loop, Statement* init, Expression* cond, Statement* next,
2159
    Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) {
2160 2161 2162 2163 2164
  // ES6 13.7.4.8 specifies that on each loop iteration the let variables are
  // copied into a new environment.  Moreover, the "next" statement must be
  // evaluated not in the environment of the just completed iteration but in
  // that of the upcoming one.  We achieve this with the following desugaring.
  // Extra care is needed to preserve the completion value of the original loop.
2165
  //
2166
  // We are given a for statement of the form
2167
  //
rossberg's avatar
rossberg committed
2168
  //  labels: for (let/const x = i; cond; next) body
2169
  //
2170 2171
  // and rewrite it as follows.  Here we write {{ ... }} for init-blocks, ie.,
  // blocks whose ignore_completion_value_ flag is set.
2172 2173
  //
  //  {
rossberg's avatar
rossberg committed
2174
  //    let/const x = i;
2175 2176
  //    temp_x = x;
  //    first = 1;
2177
  //    undefined;
2178
  //    outer: for (;;) {
2179 2180 2181 2182 2183 2184 2185 2186 2187
  //      let/const x = temp_x;
  //      {{ if (first == 1) {
  //           first = 0;
  //         } else {
  //           next;
  //         }
  //         flag = 1;
  //         if (!cond) break;
  //      }}
2188
  //      labels: for (; flag == 1; flag = 0, temp_x = x) {
2189
  //        body
2190
  //      }
2191 2192 2193
  //      {{ if (flag == 1)  // Body used break.
  //           break;
  //      }}
2194
  //    }
2195 2196
  //  }

2197 2198
  DCHECK(for_info.bound_names.length() > 0);
  ZoneList<Variable*> temps(for_info.bound_names.length(), zone());
2199

2200 2201
  Block* outer_block = factory()->NewBlock(
      nullptr, for_info.bound_names.length() + 4, false, kNoSourcePosition);
2202

rossberg's avatar
rossberg committed
2203
  // Add statement: let/const x = i.
neis's avatar
neis committed
2204
  outer_block->statements()->Add(init, zone());
2205

2206
  const AstRawString* temp_name = ast_value_factory()->dot_for_string();
2207

rossberg's avatar
rossberg committed
2208
  // For each lexical variable x:
2209
  //   make statement: temp_x = x.
2210 2211
  for (int i = 0; i < for_info.bound_names.length(); i++) {
    VariableProxy* proxy = NewUnresolved(for_info.bound_names[i]);
2212
    Variable* temp = NewTemporary(temp_name);
2213
    VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
yangguo's avatar
yangguo committed
2214 2215 2216 2217
    Assignment* assignment = factory()->NewAssignment(Token::ASSIGN, temp_proxy,
                                                      proxy, kNoSourcePosition);
    Statement* assignment_statement =
        factory()->NewExpressionStatement(assignment, kNoSourcePosition);
neis's avatar
neis committed
2218
    outer_block->statements()->Add(assignment_statement, zone());
2219 2220 2221
    temps.Add(temp, zone());
  }

2222 2223 2224
  Variable* first = NULL;
  // Make statement: first = 1.
  if (next) {
2225
    first = NewTemporary(temp_name);
2226
    VariableProxy* first_proxy = factory()->NewVariableProxy(first);
yangguo's avatar
yangguo committed
2227
    Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2228
    Assignment* assignment = factory()->NewAssignment(
yangguo's avatar
yangguo committed
2229
        Token::ASSIGN, first_proxy, const1, kNoSourcePosition);
2230
    Statement* assignment_statement =
yangguo's avatar
yangguo committed
2231
        factory()->NewExpressionStatement(assignment, kNoSourcePosition);
neis's avatar
neis committed
2232
    outer_block->statements()->Add(assignment_statement, zone());
2233 2234
  }

2235
  // make statement: undefined;
neis's avatar
neis committed
2236
  outer_block->statements()->Add(
2237
      factory()->NewExpressionStatement(
yangguo's avatar
yangguo committed
2238
          factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
2239 2240
      zone());

2241 2242 2243 2244 2245 2246
  // Make statement: outer: for (;;)
  // Note that we don't actually create the label, or set this loop up as an
  // explicit break target, instead handing it directly to those nodes that
  // need to know about it. This should be safe because we don't run any code
  // in this function that looks up break targets.
  ForStatement* outer_loop =
yangguo's avatar
yangguo committed
2247
      factory()->NewForStatement(NULL, kNoSourcePosition);
neis's avatar
neis committed
2248
  outer_block->statements()->Add(outer_loop, zone());
2249
  outer_block->set_scope(scope());
2250

yangguo's avatar
yangguo committed
2251
  Block* inner_block = factory()->NewBlock(NULL, 3, false, kNoSourcePosition);
2252
  {
2253
    BlockState block_state(&scope_state_, inner_scope);
2254

2255 2256 2257
    Block* ignore_completion_block = factory()->NewBlock(
        nullptr, for_info.bound_names.length() + 3, true, kNoSourcePosition);
    ZoneList<Variable*> inner_vars(for_info.bound_names.length(), zone());
2258 2259
    // For each let variable x:
    //    make statement: let/const x = temp_x.
2260 2261 2262 2263
    for (int i = 0; i < for_info.bound_names.length(); i++) {
      Declaration* decl = DeclareVariable(
          for_info.bound_names[i], for_info.parsing_result.descriptor.mode,
          kNoSourcePosition, CHECK_OK);
2264
      inner_vars.Add(decl->proxy()->var(), zone());
2265 2266
      VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
      Assignment* assignment = factory()->NewAssignment(
2267
          Token::INIT, decl->proxy(), temp_proxy, kNoSourcePosition);
2268
      Statement* assignment_statement =
yangguo's avatar
yangguo committed
2269 2270
          factory()->NewExpressionStatement(assignment, kNoSourcePosition);
      DCHECK(init->position() != kNoSourcePosition);
2271
      decl->proxy()->var()->set_initializer_position(init->position());
2272 2273
      ignore_completion_block->statements()->Add(assignment_statement, zone());
    }
2274

2275 2276 2277 2278 2279 2280
    // Make statement: if (first == 1) { first = 0; } else { next; }
    if (next) {
      DCHECK(first);
      Expression* compare = NULL;
      // Make compare expression: first == 1.
      {
yangguo's avatar
yangguo committed
2281
        Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2282 2283
        VariableProxy* first_proxy = factory()->NewVariableProxy(first);
        compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1,
yangguo's avatar
yangguo committed
2284
                                                 kNoSourcePosition);
2285 2286 2287 2288 2289
      }
      Statement* clear_first = NULL;
      // Make statement: first = 0.
      {
        VariableProxy* first_proxy = factory()->NewVariableProxy(first);
yangguo's avatar
yangguo committed
2290
        Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
2291
        Assignment* assignment = factory()->NewAssignment(
yangguo's avatar
yangguo committed
2292 2293 2294
            Token::ASSIGN, first_proxy, const0, kNoSourcePosition);
        clear_first =
            factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2295 2296
      }
      Statement* clear_first_or_next = factory()->NewIfStatement(
yangguo's avatar
yangguo committed
2297
          compare, clear_first, next, kNoSourcePosition);
2298
      ignore_completion_block->statements()->Add(clear_first_or_next, zone());
2299
    }
2300

2301
    Variable* flag = NewTemporary(temp_name);
2302
    // Make statement: flag = 1.
2303
    {
2304
      VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
yangguo's avatar
yangguo committed
2305
      Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2306
      Assignment* assignment = factory()->NewAssignment(
yangguo's avatar
yangguo committed
2307
          Token::ASSIGN, flag_proxy, const1, kNoSourcePosition);
2308
      Statement* assignment_statement =
yangguo's avatar
yangguo committed
2309
          factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2310
      ignore_completion_block->statements()->Add(assignment_statement, zone());
2311
    }
2312

2313 2314 2315
    // Make statement: if (!cond) break.
    if (cond) {
      Statement* stop =
yangguo's avatar
yangguo committed
2316 2317
          factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
      Statement* noop = factory()->NewEmptyStatement(kNoSourcePosition);
2318 2319 2320 2321
      ignore_completion_block->statements()->Add(
          factory()->NewIfStatement(cond, noop, stop, cond->position()),
          zone());
    }
2322

2323 2324 2325
    inner_block->statements()->Add(ignore_completion_block, zone());
    // Make cond expression for main loop: flag == 1.
    Expression* flag_cond = NULL;
2326
    {
yangguo's avatar
yangguo committed
2327
      Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2328
      VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2329
      flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
yangguo's avatar
yangguo committed
2330
                                                 kNoSourcePosition);
2331
    }
2332

2333 2334 2335 2336 2337 2338 2339
    // Create chain of expressions "flag = 0, temp_x = x, ..."
    Statement* compound_next_statement = NULL;
    {
      Expression* compound_next = NULL;
      // Make expression: flag = 0.
      {
        VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
yangguo's avatar
yangguo committed
2340 2341 2342
        Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
        compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy,
                                                 const0, kNoSourcePosition);
2343
      }
2344

2345 2346
      // Make the comma-separated list of temp_x = x assignments.
      int inner_var_proxy_pos = scanner()->location().beg_pos;
2347
      for (int i = 0; i < for_info.bound_names.length(); i++) {
2348 2349 2350 2351
        VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
        VariableProxy* proxy =
            factory()->NewVariableProxy(inner_vars.at(i), inner_var_proxy_pos);
        Assignment* assignment = factory()->NewAssignment(
yangguo's avatar
yangguo committed
2352
            Token::ASSIGN, temp_proxy, proxy, kNoSourcePosition);
2353
        compound_next = factory()->NewBinaryOperation(
yangguo's avatar
yangguo committed
2354
            Token::COMMA, compound_next, assignment, kNoSourcePosition);
2355
      }
2356

yangguo's avatar
yangguo committed
2357 2358
      compound_next_statement =
          factory()->NewExpressionStatement(compound_next, kNoSourcePosition);
2359
    }
2360

2361 2362 2363 2364 2365 2366 2367 2368
    // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
    // Note that we re-use the original loop node, which retains its labels
    // and ensures that any break or continue statements in body point to
    // the right place.
    loop->Initialize(NULL, flag_cond, compound_next_statement, body);
    inner_block->statements()->Add(loop, zone());

    // Make statement: {{if (flag == 1) break;}}
2369
    {
2370 2371 2372
      Expression* compare = NULL;
      // Make compare expresion: flag == 1.
      {
yangguo's avatar
yangguo committed
2373
        Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2374 2375
        VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
        compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
yangguo's avatar
yangguo committed
2376
                                                 kNoSourcePosition);
2377 2378
      }
      Statement* stop =
yangguo's avatar
yangguo committed
2379 2380 2381 2382
          factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
      Statement* empty = factory()->NewEmptyStatement(kNoSourcePosition);
      Statement* if_flag_break =
          factory()->NewIfStatement(compare, stop, empty, kNoSourcePosition);
2383
      Block* ignore_completion_block =
yangguo's avatar
yangguo committed
2384
          factory()->NewBlock(NULL, 1, true, kNoSourcePosition);
2385 2386 2387
      ignore_completion_block->statements()->Add(if_flag_break, zone());
      inner_block->statements()->Add(ignore_completion_block, zone());
    }
2388

2389 2390 2391
    inner_scope->set_end_position(scanner()->location().end_pos);
    inner_block->set_scope(inner_scope);
  }
2392

2393
  outer_loop->Initialize(NULL, NULL, NULL, inner_block);
2394 2395 2396
  return outer_block;
}

2397
void Parser::AddArrowFunctionFormalParameters(
2398 2399
    ParserFormalParameters* parameters, Expression* expr, int end_pos,
    bool* ok) {
2400
  // ArrowFunctionFormals ::
2401 2402 2403 2404 2405 2406
  //    Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail)
  //    Tail
  // NonTailArrowFunctionFormals ::
  //    Binary(Token::COMMA, NonTailArrowFunctionFormals, VariableProxy)
  //    VariableProxy
  // Tail ::
2407
  //    VariableProxy
2408
  //    Spread(VariableProxy)
2409 2410 2411 2412 2413 2414
  //
  // As we need to visit the parameters in left-to-right order, we recurse on
  // the left-hand side of comma expressions.
  //
  if (expr->IsBinaryOperation()) {
    BinaryOperation* binop = expr->AsBinaryOperation();
2415 2416 2417
    // The classifier has already run, so we know that the expression is a valid
    // arrow function formals production.
    DCHECK_EQ(binop->op(), Token::COMMA);
2418 2419
    Expression* left = binop->left();
    Expression* right = binop->right();
2420
    int comma_pos = binop->position();
2421 2422
    AddArrowFunctionFormalParameters(parameters, left, comma_pos,
                                     CHECK_OK_VOID);
2423 2424 2425
    // LHS of comma expression should be unparenthesized.
    expr = right;
  }
2426

2427
  // Only the right-most expression may be a rest parameter.
2428
  DCHECK(!parameters->has_rest);
2429

2430
  bool is_rest = expr->IsSpread();
2431 2432 2433 2434 2435 2436 2437
  if (is_rest) {
    expr = expr->AsSpread()->expression();
    parameters->has_rest = true;
  }
  if (parameters->is_simple) {
    parameters->is_simple = !is_rest && expr->IsVariableProxy();
  }
2438

2439
  Expression* initializer = nullptr;
2440
  if (expr->IsAssignment()) {
2441 2442 2443 2444
    Assignment* assignment = expr->AsAssignment();
    DCHECK(!assignment->is_compound());
    initializer = assignment->value();
    expr = assignment->target();
2445 2446
  }

2447
  AddFormalParameter(parameters, expr, initializer, end_pos, is_rest);
2448 2449
}

2450
void Parser::DeclareArrowFunctionFormalParameters(
2451
    ParserFormalParameters* parameters, Expression* expr,
2452
    const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
2453
    bool* ok) {
2454 2455
  if (expr->IsEmptyParentheses()) return;

2456 2457
  AddArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos,
                                   CHECK_OK_VOID);
2458

2459
  if (parameters->arity > Code::kMaxArguments) {
2460
    ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
2461 2462 2463 2464
    *ok = false;
    return;
  }

2465
  ExpressionClassifier classifier(this);
2466
  if (!parameters->is_simple) {
2467
    this->classifier()->RecordNonSimpleParameter();
2468
  }
2469
  for (int i = 0; i < parameters->arity; ++i) {
2470
    auto parameter = parameters->at(i);
2471
    DeclareFormalParameter(parameters->scope, parameter);
2472 2473 2474
    if (!this->classifier()
             ->is_valid_formal_parameter_list_without_duplicates() &&
        !duplicate_loc->IsValid()) {
2475 2476
      *duplicate_loc =
          this->classifier()->duplicate_formal_parameter_error().location;
2477
    }
2478
  }
2479
  DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters());
2480 2481
}

2482 2483
void Parser::ReindexLiterals(const ParserFormalParameters& parameters) {
  if (function_state_->materialized_literal_count() > 0) {
2484 2485
    AstLiteralReindexer reindexer;

2486
    for (const auto p : parameters.params) {
2487
      if (p.pattern != nullptr) reindexer.Reindex(p.pattern);
2488
      if (p.initializer != nullptr) reindexer.Reindex(p.initializer);
2489
    }
2490

2491
    DCHECK(reindexer.count() <= function_state_->materialized_literal_count());
2492 2493 2494
  }
}

2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508
void Parser::PrepareGeneratorVariables(FunctionState* function_state) {
  // For generators, allocating variables in contexts is currently a win
  // because it minimizes the work needed to suspend and resume an
  // activation.  The machine code produced for generators (by full-codegen)
  // relies on this forced context allocation, but not in an essential way.
  scope()->ForceContextAllocation();

  // Calling a generator returns a generator object.  That object is stored
  // in a temporary variable, a definition that is used by "yield"
  // expressions.
  Variable* temp =
      NewTemporary(ast_value_factory()->dot_generator_object_string());
  function_state->set_generator_object_variable(temp);
}
2509

2510
FunctionLiteral* Parser::ParseFunctionLiteral(
2511
    const AstRawString* function_name, Scanner::Location function_name_location,
2512 2513
    FunctionNameValidity function_name_validity, FunctionKind kind,
    int function_token_pos, FunctionLiteral::FunctionType function_type,
2514
    LanguageMode language_mode, bool* ok) {
2515 2516
  // Function ::
  //   '(' FormalParameterList? ')' '{' FunctionBody '}'
2517 2518 2519 2520 2521 2522
  //
  // Getter ::
  //   '(' ')' '{' FunctionBody '}'
  //
  // Setter ::
  //   '(' PropertySetParameterList ')' '{' FunctionBody '}'
2523

yangguo's avatar
yangguo committed
2524 2525
  int pos = function_token_pos == kNoSourcePosition ? peek_position()
                                                    : function_token_pos;
2526

2527 2528 2529
  // Anonymous functions were passed either the empty symbol or a null
  // handle as the function name.  Remember if we were passed a non-empty
  // handle to decide whether to invoke function name inference.
2530
  bool should_infer_name = function_name == NULL;
2531 2532 2533

  // We want a non-null handle as the function name.
  if (should_infer_name) {
2534
    function_name = ast_value_factory()->empty_string();
2535 2536
  }

2537 2538 2539
  FunctionLiteral::EagerCompileHint eager_compile_hint =
      function_state_->next_function_is_parenthesized()
          ? FunctionLiteral::kShouldEagerCompile
2540
          : default_eager_compile_hint();
2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557

  // Determine if the function can be parsed lazily. Lazy parsing is
  // different from lazy compilation; we need to parse more eagerly than we
  // compile.

  // We can only parse lazily if we also compile lazily. The heuristics for lazy
  // compilation are:
  // - It must not have been prohibited by the caller to Parse (some callers
  //   need a full AST).
  // - The outer scope must allow lazy compilation of inner functions.
  // - The function mustn't be a function expression with an open parenthesis
  //   before; we consider that a hint that the function will be called
  //   immediately, and it would be a waste of time to make it lazily
  //   compiled.
  // These are all things we can know at this point, without looking at the
  // function itself.

2558 2559 2560
  // We separate between lazy parsing top level functions and lazy parsing inner
  // functions, because the latter needs to do more work. In particular, we need
  // to track unresolved variables to distinguish between these cases:
2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571
  // (function foo() {
  //   bar = function() { return 1; }
  //  })();
  // and
  // (function foo() {
  //   var a = 1;
  //   bar = function() { return a; }
  //  })();

  // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
  // parenthesis before the function means that it will be called
2572 2573
  // immediately). bar can be parsed lazily, but we need to parse it in a mode
  // that tracks unresolved variables.
2574 2575 2576
  DCHECK_IMPLIES(parse_lazily(), FLAG_lazy);
  DCHECK_IMPLIES(parse_lazily(), allow_lazy());
  DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr);
2577

2578
  bool can_preparse = parse_lazily() &&
2579 2580
                      eager_compile_hint == FunctionLiteral::kShouldLazyCompile;

2581
  bool is_lazy_top_level_function =
2582
      can_preparse && impl()->AllowsLazyParsingWithoutUnresolvedVariables();
2583 2584

  // Determine whether we can still lazy parse the inner function.
2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598
  // The preconditions are:
  // - Lazy compilation has to be enabled.
  // - Neither V8 natives nor native function declarations can be allowed,
  //   since parsing one would retroactively force the function to be
  //   eagerly compiled.
  // - The invoker of this parser can't depend on the AST being eagerly
  //   built (either because the function is about to be compiled, or
  //   because the AST is going to be inspected for some reason).
  // - Because of the above, we can't be attempting to parse a
  //   FunctionExpression; even without enclosing parentheses it might be
  //   immediately invoked.
  // - The function literal shouldn't be hinted to eagerly compile.
  // - For asm.js functions the body needs to be available when module
  //   validation is active, because we examine the entire module at once.
2599 2600 2601 2602

  // Inner functions will be parsed using a temporary Zone. After parsing, we
  // will migrate unresolved variable into a Scope in the main Zone.
  // TODO(marja): Refactor parsing modes: simplify this.
2603
  bool use_temp_zone =
2604 2605
      (FLAG_lazy_inner_functions
           ? can_preparse
2606 2607 2608
           : (is_lazy_top_level_function ||
              (allow_lazy() && function_type == FunctionLiteral::kDeclaration &&
               eager_compile_hint == FunctionLiteral::kShouldLazyCompile))) &&
2609
      !(FLAG_validate_asm && scope()->IsAsmModule());
2610 2611
  bool is_lazy_inner_function =
      use_temp_zone && FLAG_lazy_inner_functions && !is_lazy_top_level_function;
2612

2613 2614 2615
  // This Scope lives in the main zone. We'll migrate data into that zone later.
  DeclarationScope* scope = NewFunctionScope(kind);
  SetLanguageMode(scope, language_mode);
2616 2617 2618
#ifdef DEBUG
  scope->SetScopeName(function_name);
#endif
2619 2620

  ZoneList<Statement*>* body = nullptr;
2621 2622
  int materialized_literal_count = -1;
  int expected_property_count = -1;
2623
  bool should_be_used_once_hint = false;
2624 2625 2626
  int num_parameters = -1;
  int function_length = -1;
  bool has_duplicate_parameters = false;
2627 2628

  Expect(Token::LPAREN, CHECK_OK);
2629
  scope->set_start_position(scanner()->location().beg_pos);
2630

2631
  {
2632 2633 2634 2635 2636 2637 2638 2639 2640
    // Temporary zones can nest. When we migrate free variables (see below), we
    // need to recreate them in the previous Zone.
    AstNodeFactory previous_zone_ast_node_factory(ast_value_factory());
    previous_zone_ast_node_factory.set_zone(zone());

    // Open a new zone scope, which sets our AstNodeFactory to allocate in the
    // new temporary zone if the preconditions are satisfied, and ensures that
    // the previous zone is always restored after parsing the body. To be able
    // to do scope analysis correctly after full parsing, we migrate needed
2641
    // information when the function is parsed.
2642
    Zone temp_zone(zone()->allocator(), ZONE_NAME);
2643
    DiscardableZoneScope zone_scope(this, &temp_zone, use_temp_zone);
2644
#ifdef DEBUG
2645
    if (use_temp_zone) scope->set_needs_migration();
2646
#endif
2647

2648
    // Eager or lazy parse? If is_lazy_top_level_function, we'll parse
2649 2650 2651 2652
    // lazily. We'll call SkipFunction, which may decide to
    // abort lazy parsing if it suspects that wasn't a good idea. If so (in
    // which case the parser is expected to have backtracked), or if we didn't
    // try to lazy parse in the first place, we'll have to parse eagerly.
2653
    if (is_lazy_top_level_function || is_lazy_inner_function) {
2654
      Scanner::BookmarkScope bookmark(scanner());
2655
      bookmark.Set();
2656 2657 2658 2659 2660
      LazyParsingResult result =
          SkipFunction(kind, scope, &num_parameters, &function_length,
                       &has_duplicate_parameters, &materialized_literal_count,
                       &expected_property_count, is_lazy_inner_function,
                       is_lazy_top_level_function, CHECK_OK);
2661

2662
      if (result == kLazyParsingAborted) {
2663
        DCHECK(is_lazy_top_level_function);
2664
        bookmark.Apply();
2665
        // Trigger eager (re-)parsing, just below this block.
2666
        is_lazy_top_level_function = false;
2667 2668 2669 2670 2671 2672

        // This is probably an initialization function. Inform the compiler it
        // should also eager-compile this function, and that we expect it to be
        // used once.
        eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
        should_be_used_once_hint = true;
2673
        scope->ResetAfterPreparsing(ast_value_factory(), true);
2674 2675
        zone_scope.Reset();
        use_temp_zone = false;
2676 2677
      }
    }
2678

2679
    if (!is_lazy_top_level_function && !is_lazy_inner_function) {
2680 2681 2682 2683
      body = ParseFunction(
          function_name, pos, kind, function_type, scope, &num_parameters,
          &function_length, &has_duplicate_parameters,
          &materialized_literal_count, &expected_property_count, CHECK_OK);
2684 2685
    }

2686 2687
    DCHECK(use_temp_zone || !is_lazy_top_level_function);
    if (use_temp_zone) {
2688 2689 2690 2691
      // If the preconditions are correct the function body should never be
      // accessed, but do this anyway for better behaviour if they're wrong.
      body = nullptr;
      scope->AnalyzePartially(&previous_zone_ast_node_factory);
2692
    }
2693

2694 2695 2696 2697 2698 2699 2700 2701 2702
    if (FLAG_trace_preparse) {
      PrintF("  [%s]: %i-%i %.*s\n",
             is_lazy_top_level_function
                 ? "Preparse no-resolution"
                 : (use_temp_zone ? "Preparse resolution" : "Full parse"),
             scope->start_position(), scope->end_position(),
             function_name->byte_length(), function_name->raw_data());
    }

2703 2704
    // Validate function name. We can do this only after parsing the function,
    // since the function can declare itself strict.
2705 2706
    language_mode = scope->language_mode();
    CheckFunctionName(language_mode, function_name, function_name_validity,
2707
                      function_name_location, CHECK_OK);
2708

2709
    if (is_strict(language_mode)) {
2710 2711
      CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
                              CHECK_OK);
2712
      CheckDecimalLiteralWithLeadingZero(scope->start_position(),
2713
                                         scope->end_position());
2714
    }
2715
    CheckConflictingVarDeclarations(scope, CHECK_OK);
2716
  }  // DiscardableZoneScope goes out of scope.
2717

2718
  FunctionLiteral::ParameterFlag duplicate_parameters =
2719 2720
      has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
                               : FunctionLiteral::kNoDuplicateParameters;
2721

2722
  // Note that the FunctionLiteral needs to be created in the main Zone again.
2723
  FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
2724
      function_name, scope, body, materialized_literal_count,
2725
      expected_property_count, num_parameters, function_length,
2726
      duplicate_parameters, function_type, eager_compile_hint, pos, true);
2727
  function_literal->set_function_token_position(function_token_pos);
2728 2729
  if (should_be_used_once_hint)
    function_literal->set_should_be_used_once_hint();
2730

2731 2732 2733 2734
  if (should_infer_name) {
    DCHECK_NOT_NULL(fni_);
    fni_->AddFunction(function_literal);
  }
2735
  return function_literal;
2736 2737
}

2738 2739 2740
Parser::LazyParsingResult Parser::SkipFunction(
    FunctionKind kind, DeclarationScope* function_scope, int* num_parameters,
    int* function_length, bool* has_duplicate_parameters,
2741
    int* materialized_literal_count, int* expected_property_count,
2742
    bool is_inner_function, bool may_abort, bool* ok) {
2743
  DCHECK_NE(kNoSourcePosition, function_scope->start_position());
2744
  if (produce_cached_parse_data()) CHECK(log_);
2745

2746 2747 2748
  DCHECK_IMPLIES(IsArrowFunction(kind),
                 scanner()->current_token() == Token::ARROW);

2749 2750 2751
  // Inner functions are not part of the cached data.
  if (!is_inner_function && consume_cached_parse_data() &&
      !cached_parse_data_->rejected()) {
2752 2753
    // If we have cached data, we use it to skip parsing the function. The data
    // contains the information we need to construct the lazy function.
2754
    FunctionEntry entry =
2755
        cached_parse_data_->GetFunctionEntry(function_scope->start_position());
2756 2757 2758
    // Check that cached data is valid. If not, mark it as invalid (the embedder
    // handles it). Note that end position greater than end of stream is safe,
    // and hard to check.
2759 2760 2761 2762
    if (entry.is_valid() &&
        entry.end_pos() > function_scope->start_position()) {
      total_preparse_skipped_ += entry.end_pos() - position();
      function_scope->set_end_position(entry.end_pos());
2763
      scanner()->SeekForward(entry.end_pos() - 1);
2764
      Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
2765 2766 2767
      *num_parameters = entry.num_parameters();
      *function_length = entry.function_length();
      *has_duplicate_parameters = entry.has_duplicate_parameters();
2768 2769
      *materialized_literal_count = entry.literal_count();
      *expected_property_count = entry.property_count();
2770 2771 2772 2773
      SetLanguageMode(function_scope, entry.language_mode());
      if (entry.uses_super_property())
        function_scope->RecordSuperPropertyUsage();
      if (entry.calls_eval()) function_scope->RecordEvalCall();
2774
      return kLazyParsingComplete;
2775
    }
2776 2777 2778 2779
    cached_parse_data_->Reject();
  }
  // With no cached data, we partially parse the function, without building an
  // AST. This gathers the data needed to build a lazy function.
2780
  PreParser::PreParseResult result = ParseFunctionWithPreParser(
2781
      kind, function_scope, is_inner_function, may_abort);
2782

2783
  // Return immediately if pre-parser decided to abort parsing.
2784
  if (result == PreParser::kPreParseAbort) return kLazyParsingAborted;
2785 2786 2787 2788
  if (result == PreParser::kPreParseStackOverflow) {
    // Propagate stack overflow.
    set_stack_overflow();
    *ok = false;
2789
    return kLazyParsingComplete;
2790
  }
2791 2792 2793 2794 2795
  PreParserLogger* logger = reusable_preparser_->logger();
  if (logger->has_error()) {
    ReportMessageAt(Scanner::Location(logger->start(), logger->end()),
                    logger->message(), logger->argument_opt(),
                    logger->error_type());
2796
    *ok = false;
2797
    return kLazyParsingComplete;
2798
  }
2799
  function_scope->set_end_position(logger->end());
2800
  Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
2801 2802
  total_preparse_skipped_ +=
      function_scope->end_position() - function_scope->start_position();
2803 2804 2805 2806 2807
  *num_parameters = logger->num_parameters();
  *function_length = logger->function_length();
  *has_duplicate_parameters = logger->has_duplicate_parameters();
  *materialized_literal_count = logger->literals();
  *expected_property_count = logger->properties();
2808
  if (!is_inner_function && produce_cached_parse_data()) {
2809
    DCHECK(log_);
2810 2811 2812 2813 2814
    log_->LogFunction(
        function_scope->start_position(), function_scope->end_position(),
        *num_parameters, *function_length, *has_duplicate_parameters,
        *materialized_literal_count, *expected_property_count, language_mode(),
        function_scope->uses_super_property(), function_scope->calls_eval());
2815
  }
2816
  return kLazyParsingComplete;
2817 2818 2819
}


2820 2821 2822 2823 2824
Statement* Parser::BuildAssertIsCoercible(Variable* var) {
  // if (var === null || var === undefined)
  //     throw /* type error kNonCoercible) */;

  Expression* condition = factory()->NewBinaryOperation(
yangguo's avatar
yangguo committed
2825
      Token::OR,
2826 2827
      factory()->NewCompareOperation(
          Token::EQ_STRICT, factory()->NewVariableProxy(var),
yangguo's avatar
yangguo committed
2828 2829 2830 2831 2832
          factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
      factory()->NewCompareOperation(
          Token::EQ_STRICT, factory()->NewVariableProxy(var),
          factory()->NewNullLiteral(kNoSourcePosition), kNoSourcePosition),
      kNoSourcePosition);
2833 2834 2835
  Expression* throw_type_error =
      NewThrowTypeError(MessageTemplate::kNonCoercible,
                        ast_value_factory()->empty_string(), kNoSourcePosition);
2836
  IfStatement* if_statement = factory()->NewIfStatement(
yangguo's avatar
yangguo committed
2837 2838 2839
      condition,
      factory()->NewExpressionStatement(throw_type_error, kNoSourcePosition),
      factory()->NewEmptyStatement(kNoSourcePosition), kNoSourcePosition);
2840 2841 2842 2843
  return if_statement;
}


2844 2845
class InitializerRewriter final
    : public AstTraversalVisitor<InitializerRewriter> {
2846 2847 2848
 public:
  InitializerRewriter(uintptr_t stack_limit, Expression* root, Parser* parser,
                      Scope* scope)
2849
      : AstTraversalVisitor(stack_limit, root),
2850 2851 2852 2853
        parser_(parser),
        scope_(scope) {}

 private:
2854 2855 2856
  // This is required so that the overriden Visit* methods can be
  // called by the base class (template).
  friend class AstTraversalVisitor<InitializerRewriter>;
2857

2858 2859 2860
  // Just rewrite destructuring assignments wrapped in RewritableExpressions.
  void VisitRewritableExpression(RewritableExpression* to_rewrite) {
    if (to_rewrite->is_rewritten()) return;
2861
    Parser::PatternRewriter::RewriteDestructuringAssignment(parser_, to_rewrite,
2862
                                                            scope_);
2863 2864
  }

2865 2866
  // Code in function literals does not need to be eagerly rewritten, it will be
  // rewritten when scheduled.
2867
  void VisitFunctionLiteral(FunctionLiteral* expr) {}
2868

2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879
  Parser* parser_;
  Scope* scope_;
};


void Parser::RewriteParameterInitializer(Expression* expr, Scope* scope) {
  InitializerRewriter rewriter(stack_limit_, expr, this, scope);
  rewriter.Run();
}


2880
Block* Parser::BuildParameterInitializationBlock(
2881
    const ParserFormalParameters& parameters, bool* ok) {
2882
  DCHECK(!parameters.is_simple);
2883
  DCHECK(scope()->is_function_scope());
yangguo's avatar
yangguo committed
2884
  Block* init_block = factory()->NewBlock(NULL, 1, true, kNoSourcePosition);
2885 2886
  for (int i = 0; i < parameters.params.length(); ++i) {
    auto parameter = parameters.params[i];
2887
    if (parameter.is_rest && parameter.pattern->IsVariableProxy()) break;
2888 2889
    DeclarationDescriptor descriptor;
    descriptor.declaration_kind = DeclarationDescriptor::PARAMETER;
2890
    descriptor.scope = scope();
2891
    descriptor.hoist_scope = nullptr;
2892 2893
    descriptor.mode = LET;
    descriptor.declaration_pos = parameter.pattern->position();
2894 2895 2896
    // The position that will be used by the AssignmentExpression
    // which copies from the temp parameter to the pattern.
    //
yangguo's avatar
yangguo committed
2897
    // TODO(adamk): Should this be kNoSourcePosition, since
2898
    // it's just copying from a temp var to the real param var?
2899
    descriptor.initialization_pos = parameter.pattern->position();
2900 2901 2902 2903
    Expression* initial_value =
        factory()->NewVariableProxy(parameters.scope->parameter(i));
    if (parameter.initializer != nullptr) {
      // IS_UNDEFINED($param) ? initializer : $param
2904 2905

      // Ensure initializer is rewritten
2906
      RewriteParameterInitializer(parameter.initializer, scope());
2907

2908 2909 2910
      auto condition = factory()->NewCompareOperation(
          Token::EQ_STRICT,
          factory()->NewVariableProxy(parameters.scope->parameter(i)),
yangguo's avatar
yangguo committed
2911
          factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
2912
      initial_value = factory()->NewConditional(
yangguo's avatar
yangguo committed
2913
          condition, parameter.initializer, initial_value, kNoSourcePosition);
2914 2915
      descriptor.initialization_pos = parameter.initializer->position();
    }
2916

2917
    Scope* param_scope = scope();
2918
    Block* param_block = init_block;
2919
    if (!parameter.is_simple() && scope()->calls_sloppy_eval()) {
2920
      param_scope = NewVarblockScope();
2921 2922
      param_scope->set_start_position(descriptor.initialization_pos);
      param_scope->set_end_position(parameter.initializer_end_position);
2923
      param_scope->RecordEvalCall();
yangguo's avatar
yangguo committed
2924
      param_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition);
2925
      param_block->set_scope(param_scope);
2926
      descriptor.hoist_scope = scope();
2927 2928 2929 2930
      // Pass the appropriate scope in so that PatternRewriter can appropriately
      // rewrite inner initializers of the pattern to param_scope
      descriptor.scope = param_scope;
      // Rewrite the outer initializer to point to param_scope
2931
      ReparentParameterExpressionScope(stack_limit(), initial_value,
2932
                                       param_scope);
2933 2934
    }

2935 2936
    BlockState block_state(&scope_state_, param_scope);
    DeclarationParsingResult::Declaration decl(
2937
        parameter.pattern, parameter.initializer_end_position, initial_value);
2938 2939
    PatternRewriter::DeclareAndInitializeVariables(
        this, param_block, &descriptor, &decl, nullptr, CHECK_OK);
2940 2941 2942

    if (param_block != init_block) {
      param_scope = block_state.FinalizedBlockScope();
2943 2944 2945
      if (param_scope != nullptr) {
        CheckConflictingVarDeclarations(param_scope, CHECK_OK);
      }
neis's avatar
neis committed
2946
      init_block->statements()->Add(param_block, zone());
2947
    }
2948 2949 2950 2951
  }
  return init_block;
}

2952
Block* Parser::BuildRejectPromiseOnException(Block* inner_block, bool* ok) {
2953
  // .promise = %AsyncFunctionPromiseCreate();
2954 2955 2956 2957 2958 2959
  // try {
  //   <inner_block>
  // } catch (.catch) {
  //   %RejectPromise(.promise, .catch);
  //   return .promise;
  // } finally {
2960
  //   %AsyncFunctionPromiseRelease(.promise);
2961
  // }
2962
  Block* result = factory()->NewBlock(nullptr, 2, true, kNoSourcePosition);
2963

2964
  // .promise = %AsyncFunctionPromiseCreate();
2965 2966 2967
  Statement* set_promise;
  {
    Expression* create_promise = factory()->NewCallRuntime(
2968
        Context::ASYNC_FUNCTION_PROMISE_CREATE_INDEX,
2969 2970
        new (zone()) ZoneList<Expression*>(0, zone()), kNoSourcePosition);
    Assignment* assign_promise = factory()->NewAssignment(
2971 2972
        Token::INIT, factory()->NewVariableProxy(PromiseVariable()),
        create_promise, kNoSourcePosition);
2973 2974 2975 2976 2977 2978
    set_promise =
        factory()->NewExpressionStatement(assign_promise, kNoSourcePosition);
  }
  result->statements()->Add(set_promise, zone());

  // catch (.catch) { return %RejectPromise(.promise, .catch), .promise }
2979
  Scope* catch_scope = NewScope(CATCH_SCOPE);
2980 2981 2982
  catch_scope->set_is_hidden();
  Variable* catch_variable =
      catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR,
2983
                                kCreatedInitialized, NORMAL_VARIABLE);
yangguo's avatar
yangguo committed
2984
  Block* catch_block = factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
2985

2986
  Expression* promise_reject = BuildRejectPromise(
yangguo's avatar
yangguo committed
2987
      factory()->NewVariableProxy(catch_variable), kNoSourcePosition);
2988
  ReturnStatement* return_promise_reject =
yangguo's avatar
yangguo committed
2989
      factory()->NewReturnStatement(promise_reject, kNoSourcePosition);
2990
  catch_block->statements()->Add(return_promise_reject, zone());
2991

2992 2993 2994 2995
  TryStatement* try_catch_statement =
      factory()->NewTryCatchStatementForAsyncAwait(inner_block, catch_scope,
                                                   catch_variable, catch_block,
                                                   kNoSourcePosition);
2996 2997 2998 2999 3000 3001

  // There is no TryCatchFinally node, so wrap it in an outer try/finally
  Block* outer_try_block =
      factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
  outer_try_block->statements()->Add(try_catch_statement, zone());

3002
  // finally { %AsyncFunctionPromiseRelease(.promise) }
3003 3004 3005
  Block* finally_block =
      factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
  {
3006 3007 3008 3009 3010 3011 3012
    ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
    args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
    Expression* call_promise_release = factory()->NewCallRuntime(
        Context::ASYNC_FUNCTION_PROMISE_RELEASE_INDEX, args, kNoSourcePosition);
    Statement* promise_release = factory()->NewExpressionStatement(
        call_promise_release, kNoSourcePosition);
    finally_block->statements()->Add(promise_release, zone());
3013
  }
3014

3015 3016 3017 3018 3019
  Statement* try_finally_statement = factory()->NewTryFinallyStatement(
      outer_try_block, finally_block, kNoSourcePosition);

  result->statements()->Add(try_finally_statement, zone());
  return result;
3020 3021
}

3022
Expression* Parser::BuildCreateJSGeneratorObject(int pos, FunctionKind kind) {
3023 3024 3025
  DCHECK_NOT_NULL(function_state_->generator_object_variable());
  ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
  args->Add(factory()->NewThisFunction(pos), zone());
3026 3027
  args->Add(IsArrowFunction(kind) ? GetLiteralUndefined(pos)
                                  : ThisExpression(kNoSourcePosition),
3028
            zone());
3029 3030 3031 3032
  return factory()->NewCallRuntime(Runtime::kCreateJSGeneratorObject, args,
                                   pos);
}

3033 3034 3035
Expression* Parser::BuildResolvePromise(Expression* value, int pos) {
  // %ResolvePromise(.promise, value), .promise
  ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
3036
  args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
3037
  args->Add(value, zone());
3038 3039
  Expression* call_runtime =
      factory()->NewCallRuntime(Context::PROMISE_RESOLVE_INDEX, args, pos);
3040 3041 3042
  return factory()->NewBinaryOperation(
      Token::COMMA, call_runtime,
      factory()->NewVariableProxy(PromiseVariable()), pos);
3043 3044
}

3045 3046 3047 3048 3049 3050
Expression* Parser::BuildRejectPromise(Expression* value, int pos) {
  // %RejectPromiseNoDebugEvent(.promise, value, true), .promise
  // The NoDebugEvent variant disables the additional debug event for the
  // rejection since a debug event already happened for the exception that got
  // us here.
  ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
3051
  args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
3052
  args->Add(value, zone());
3053 3054
  Expression* call_runtime = factory()->NewCallRuntime(
      Context::REJECT_PROMISE_NO_DEBUG_EVENT_INDEX, args, pos);
3055 3056 3057
  return factory()->NewBinaryOperation(
      Token::COMMA, call_runtime,
      factory()->NewVariableProxy(PromiseVariable()), pos);
3058 3059
}

3060 3061 3062 3063 3064 3065 3066 3067 3068 3069
Variable* Parser::PromiseVariable() {
  // Based on the various compilation paths, there are many different code
  // paths which may be the first to access the Promise temporary. Whichever
  // comes first should create it and stash it in the FunctionState.
  Variable* promise = function_state_->promise_variable();
  if (function_state_->promise_variable() == nullptr) {
    promise = scope()->NewTemporary(ast_value_factory()->empty_string());
    function_state_->set_promise_variable(promise);
  }
  return promise;
3070
}
3071

3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086
Expression* Parser::BuildInitialYield(int pos, FunctionKind kind) {
  Expression* allocation = BuildCreateJSGeneratorObject(pos, kind);
  VariableProxy* init_proxy =
      factory()->NewVariableProxy(function_state_->generator_object_variable());
  Assignment* assignment = factory()->NewAssignment(
      Token::INIT, init_proxy, allocation, kNoSourcePosition);
  VariableProxy* get_proxy =
      factory()->NewVariableProxy(function_state_->generator_object_variable());
  // The position of the yield is important for reporting the exception
  // caused by calling the .throw method on a generator suspended at the
  // initial yield (i.e. right after generator instantiation).
  return factory()->NewYield(get_proxy, assignment, scope()->start_position(),
                             Yield::kOnExceptionThrow);
}

3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132
ZoneList<Statement*>* Parser::ParseFunction(
    const AstRawString* function_name, int pos, FunctionKind kind,
    FunctionLiteral::FunctionType function_type,
    DeclarationScope* function_scope, int* num_parameters, int* function_length,
    bool* has_duplicate_parameters, int* materialized_literal_count,
    int* expected_property_count, bool* ok) {
  FunctionState function_state(&function_state_, &scope_state_, function_scope);

  DuplicateFinder duplicate_finder(scanner()->unicode_cache());
  ExpressionClassifier formals_classifier(this, &duplicate_finder);

  if (IsGeneratorFunction(kind)) PrepareGeneratorVariables(&function_state);

  ParserFormalParameters formals(function_scope);
  ParseFormalParameterList(&formals, CHECK_OK);
  Expect(Token::RPAREN, CHECK_OK);
  int formals_end_position = scanner()->location().end_pos;
  *num_parameters = formals.num_parameters();
  *function_length = formals.function_length;

  CheckArityRestrictions(formals.arity, kind, formals.has_rest,
                         function_scope->start_position(), formals_end_position,
                         CHECK_OK);
  Expect(Token::LBRACE, CHECK_OK);

  ZoneList<Statement*>* body = ParseEagerFunctionBody(
      function_name, pos, formals, kind, function_type, ok);

  // Validate parameter names. We can do this only after parsing the function,
  // since the function can declare itself strict.
  const bool allow_duplicate_parameters =
      is_sloppy(function_scope->language_mode()) && formals.is_simple &&
      !IsConciseMethod(kind);
  ValidateFormalParameters(function_scope->language_mode(),
                           allow_duplicate_parameters, CHECK_OK);

  RewriteDestructuringAssignments();

  *has_duplicate_parameters =
      !classifier()->is_valid_formal_parameter_list_without_duplicates();

  *materialized_literal_count = function_state.materialized_literal_count();
  *expected_property_count = function_state.expected_property_count();
  return body;
}

3133
ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
3134
    const AstRawString* function_name, int pos,
3135 3136
    const ParserFormalParameters& parameters, FunctionKind kind,
    FunctionLiteral::FunctionType function_type, bool* ok) {
3137
  ParsingModeScope mode(this, allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY);
3138
  ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone());
3139

3140
  static const int kFunctionNameAssignmentIndex = 0;
3141
  if (function_type == FunctionLiteral::kNamedExpression) {
3142 3143 3144 3145 3146 3147 3148 3149 3150
    DCHECK(function_name != NULL);
    // If we have a named function expression, we add a local variable
    // declaration to the body of the function with the name of the
    // function and let it refer to the function itself (closure).
    // Not having parsed the function body, the language mode may still change,
    // so we reserve a spot and create the actual const assignment later.
    DCHECK_EQ(kFunctionNameAssignmentIndex, result->length());
    result->Add(NULL, zone());
  }
3151

3152
  ZoneList<Statement*>* body = result;
3153 3154
  DeclarationScope* function_scope = scope()->AsDeclarationScope();
  DeclarationScope* inner_scope = function_scope;
3155
  Block* inner_block = nullptr;
3156
  if (!parameters.is_simple) {
3157
    inner_scope = NewVarblockScope();
3158
    inner_scope->set_start_position(scanner()->location().beg_pos);
yangguo's avatar
yangguo committed
3159
    inner_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition);
3160 3161
    inner_block->set_scope(inner_scope);
    body = inner_block->statements();
3162 3163
  }

3164
  {
3165
    BlockState block_state(&scope_state_, inner_scope);
3166

3167
    if (IsGeneratorFunction(kind)) {
3168 3169
      // We produce:
      //
3170
      // try { InitialYield; ...body...; return {value: undefined, done: true} }
3171
      // finally { %_GeneratorClose(generator) }
3172 3173
      //
      // - InitialYield yields the actual generator object.
3174 3175
      // - Any return statement inside the body will have its argument wrapped
      //   in a "done" iterator result object.
3176 3177 3178 3179
      // - If the generator terminates for whatever reason, we must close it.
      //   Hence the finally clause.

      Block* try_block =
yangguo's avatar
yangguo committed
3180
          factory()->NewBlock(nullptr, 3, false, kNoSourcePosition);
3181 3182 3183 3184
      Expression* initial_yield = BuildInitialYield(pos, kind);
      try_block->statements()->Add(
          factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
          zone());
3185
      ParseStatementList(try_block->statements(), Token::RBRACE, CHECK_OK);
3186

3187
      Statement* final_return = factory()->NewReturnStatement(
yangguo's avatar
yangguo committed
3188
          BuildIteratorResult(nullptr, true), kNoSourcePosition);
3189
      try_block->statements()->Add(final_return, zone());
3190 3191

      Block* finally_block =
yangguo's avatar
yangguo committed
3192
          factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
3193 3194 3195 3196 3197 3198
      ZoneList<Expression*>* args =
          new (zone()) ZoneList<Expression*>(1, zone());
      VariableProxy* call_proxy = factory()->NewVariableProxy(
          function_state_->generator_object_variable());
      args->Add(call_proxy, zone());
      Expression* call = factory()->NewCallRuntime(
yangguo's avatar
yangguo committed
3199
          Runtime::kInlineGeneratorClose, args, kNoSourcePosition);
3200
      finally_block->statements()->Add(
yangguo's avatar
yangguo committed
3201
          factory()->NewExpressionStatement(call, kNoSourcePosition), zone());
3202 3203

      body->Add(factory()->NewTryFinallyStatement(try_block, finally_block,
yangguo's avatar
yangguo committed
3204
                                                  kNoSourcePosition),
3205
                zone());
3206 3207
    } else if (IsAsyncFunction(kind)) {
      const bool accept_IN = true;
3208 3209
      ParseAsyncFunctionBody(inner_scope, body, kind, FunctionBodyType::kNormal,
                             accept_IN, pos, CHECK_OK);
3210 3211
    } else {
      ParseStatementList(body, Token::RBRACE, CHECK_OK);
3212
    }
3213

3214
    if (IsSubclassConstructor(kind)) {
3215 3216
      body->Add(factory()->NewReturnStatement(ThisExpression(kNoSourcePosition),
                                              kNoSourcePosition),
yangguo's avatar
yangguo committed
3217
                zone());
3218
    }
3219 3220
  }

3221
  Expect(Token::RBRACE, CHECK_OK);
3222
  scope()->set_end_position(scanner()->location().end_pos);
3223

3224
  if (!parameters.is_simple) {
3225
    DCHECK_NOT_NULL(inner_scope);
3226 3227
    DCHECK_EQ(function_scope, scope());
    DCHECK_EQ(function_scope, inner_scope->outer_scope());
3228
    DCHECK_EQ(body, inner_block->statements());
3229
    SetLanguageMode(function_scope, inner_scope->language_mode());
3230
    Block* init_block = BuildParameterInitializationBlock(parameters, CHECK_OK);
3231

3232
    if (is_sloppy(inner_scope->language_mode())) {
3233
      InsertSloppyBlockFunctionVarBindings(inner_scope);
3234 3235
    }

3236
    // TODO(littledan): Merge the two rejection blocks into one
3237
    if (IsAsyncFunction(kind)) {
3238
      init_block = BuildRejectPromiseOnException(init_block, CHECK_OK);
3239 3240
    }

3241 3242
    DCHECK_NOT_NULL(init_block);

3243
    inner_scope->set_end_position(scanner()->location().end_pos);
3244
    if (inner_scope->FinalizeBlockScope() != nullptr) {
3245
      CheckConflictingVarDeclarations(inner_scope, CHECK_OK);
3246
      InsertShadowingVarBindingInitializers(inner_block);
3247
    }
3248
    inner_scope = nullptr;
3249 3250 3251

    result->Add(init_block, zone());
    result->Add(inner_block, zone());
3252
  } else {
3253 3254
    DCHECK_EQ(inner_scope, function_scope);
    if (is_sloppy(function_scope->language_mode())) {
3255
      InsertSloppyBlockFunctionVarBindings(function_scope);
3256
    }
3257
  }
3258

3259 3260 3261 3262 3263 3264 3265
  if (!IsArrowFunction(kind)) {
    // Declare arguments after parsing the function since lexical 'arguments'
    // masks the arguments object. Declare arguments before declaring the
    // function var since the arguments object masks 'function arguments'.
    function_scope->DeclareArguments(ast_value_factory());
  }

3266
  if (function_type == FunctionLiteral::kNamedExpression) {
3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282
    Statement* statement;
    if (function_scope->LookupLocal(function_name) == nullptr) {
      // Now that we know the language mode, we can create the const assignment
      // in the previously reserved spot.
      DCHECK_EQ(function_scope, scope());
      Variable* fvar = function_scope->DeclareFunctionVar(function_name);
      VariableProxy* fproxy = factory()->NewVariableProxy(fvar);
      statement = factory()->NewExpressionStatement(
          factory()->NewAssignment(Token::INIT, fproxy,
                                   factory()->NewThisFunction(pos),
                                   kNoSourcePosition),
          kNoSourcePosition);
    } else {
      statement = factory()->NewEmptyStatement(kNoSourcePosition);
    }
    result->Set(kFunctionNameAssignmentIndex, statement);
3283 3284
  }

3285
  MarkCollectedTailCallExpressions();
3286
  return result;
3287 3288
}

3289
PreParser::PreParseResult Parser::ParseFunctionWithPreParser(
3290 3291
    FunctionKind kind, DeclarationScope* function_scope, bool is_inner_function,
    bool may_abort) {
3292
  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse");
3293

3294
  if (reusable_preparser_ == NULL) {
3295 3296
    reusable_preparser_ =
        new PreParser(zone(), &scanner_, ast_value_factory(), stack_limit_);
3297
    reusable_preparser_->set_allow_lazy(true);
3298 3299
#define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name());
    SET_ALLOW(natives);
3300
    SET_ALLOW(harmony_do_expressions);
3301
    SET_ALLOW(harmony_function_sent);
3302
    SET_ALLOW(harmony_async_await);
3303
    SET_ALLOW(harmony_trailing_commas);
3304
    SET_ALLOW(harmony_class_fields);
3305
#undef SET_ALLOW
3306
  }
3307 3308 3309 3310
  // Aborting inner function preparsing would leave scopes in an inconsistent
  // state; we don't parse inner functions in the abortable mode anyway.
  DCHECK(!is_inner_function || !may_abort);

3311
  PreParser::PreParseResult result = reusable_preparser_->PreParseFunction(
3312 3313
      kind, function_scope, parsing_module_, is_inner_function, may_abort,
      use_counts_);
3314 3315 3316
  return result;
}

3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373
Expression* Parser::InstallHomeObject(Expression* function_literal,
                                      Expression* home_object) {
  Block* do_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
  Variable* result_var =
      scope()->NewTemporary(ast_value_factory()->empty_string());
  DoExpression* do_expr =
      factory()->NewDoExpression(do_block, result_var, kNoSourcePosition);
  Assignment* init = factory()->NewAssignment(
      Token::ASSIGN, factory()->NewVariableProxy(result_var), function_literal,
      kNoSourcePosition);
  do_block->statements()->Add(
      factory()->NewExpressionStatement(init, kNoSourcePosition), zone());
  Property* home_object_property = factory()->NewProperty(
      factory()->NewVariableProxy(result_var),
      factory()->NewSymbolLiteral("home_object_symbol", kNoSourcePosition),
      kNoSourcePosition);
  Assignment* assignment = factory()->NewAssignment(
      Token::ASSIGN, home_object_property, home_object, kNoSourcePosition);
  do_block->statements()->Add(
      factory()->NewExpressionStatement(assignment, kNoSourcePosition), zone());
  return do_expr;
}

const AstRawString* ClassFieldVariableName(bool is_name,
                                           AstValueFactory* ast_value_factory,
                                           int index) {
  std::string name =
      ".class-field-" + std::to_string(index) + (is_name ? "-name" : "-func");
  return ast_value_factory->GetOneByteString(name.c_str());
}

FunctionLiteral* Parser::SynthesizeClassFieldInitializer(int count) {
  DCHECK(count > 0);
  // Makes a function which reads the names and initializers for each class
  // field out of deterministically named local variables and sets each property
  // to the result of evaluating its corresponding initializer in turn.

  // This produces a function which looks like
  // function () {
  //   this[.class-field-0-name] = .class-field-0-func();
  //   this[.class-field-1-name] = .class-field-1-func();
  //   [...]
  //   this[.class-field-n-name] = .class-field-n-func();
  //   return this;
  // }
  // except that it performs defineProperty, so that instead of '=' it has
  // %DefineDataPropertyInLiteral(this, .class-field-0-name,
  // .class-field-0-func(),
  //   DONT_ENUM, false)

  RaiseLanguageMode(STRICT);
  FunctionKind kind = FunctionKind::kConciseMethod;
  DeclarationScope* initializer_scope = NewFunctionScope(kind);
  SetLanguageMode(initializer_scope, language_mode());
  initializer_scope->set_start_position(scanner()->location().end_pos);
  initializer_scope->set_end_position(scanner()->location().end_pos);
  FunctionState initializer_state(&function_state_, &scope_state_,
3374
                                  initializer_scope);
3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416
  ZoneList<Statement*>* body = new (zone()) ZoneList<Statement*>(count, zone());
  for (int i = 0; i < count; ++i) {
    const AstRawString* name =
        ClassFieldVariableName(true, ast_value_factory(), i);
    VariableProxy* name_proxy = scope()->NewUnresolved(factory(), name);
    const AstRawString* function_name =
        ClassFieldVariableName(false, ast_value_factory(), i);
    VariableProxy* function_proxy =
        scope()->NewUnresolved(factory(), function_name);
    ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
    args->Add(function_proxy, zone());
    args->Add(ThisExpression(kNoSourcePosition), zone());
    Expression* call = factory()->NewCallRuntime(Runtime::kInlineCall, args,
                                                 kNoSourcePosition);
    ZoneList<Expression*>* define_property_args =
        new (zone()) ZoneList<Expression*>(5, zone());
    define_property_args->Add(ThisExpression(kNoSourcePosition), zone());
    define_property_args->Add(name_proxy, zone());
    define_property_args->Add(call, zone());
    define_property_args->Add(
        factory()->NewNumberLiteral(DONT_ENUM, kNoSourcePosition), zone());
    define_property_args->Add(
        factory()->NewNumberLiteral(
            false,  // TODO(bakkot) function name inference a la class { x =
                    // function(){}; static y = function(){}; }
            kNoSourcePosition),
        zone());
    body->Add(factory()->NewExpressionStatement(
                  factory()->NewCallRuntime(
                      Runtime::kDefineDataProperty,
                      define_property_args,  // TODO(bakkot) verify that this is
                      // the same as object_define_property
                      kNoSourcePosition),
                  kNoSourcePosition),
              zone());
  }
  body->Add(factory()->NewReturnStatement(ThisExpression(kNoSourcePosition),
                                          kNoSourcePosition),
            zone());
  FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
      ast_value_factory()->empty_string(), initializer_scope, body,
      initializer_state.materialized_literal_count(),
3417
      initializer_state.expected_property_count(), 0, count,
3418 3419
      FunctionLiteral::kNoDuplicateParameters,
      FunctionLiteral::kAnonymousExpression,
3420 3421
      FunctionLiteral::kShouldLazyCompile, initializer_scope->start_position(),
      true);
3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432
  function_literal->set_is_class_field_initializer(true);
  return function_literal;
}

FunctionLiteral* Parser::InsertClassFieldInitializer(
    FunctionLiteral* constructor) {
  Statement* call_initializer = factory()->NewExpressionStatement(
      CallClassFieldInitializer(
          constructor->scope(),
          constructor->scope()->NewUnresolved(
              factory(), ast_value_factory()->this_string(), kNoSourcePosition,
3433
              THIS_VARIABLE)),
3434 3435 3436 3437 3438
      kNoSourcePosition);
  constructor->body()->InsertAt(0, call_initializer, zone());
  return constructor;
}

3439 3440 3441 3442 3443
// If a class name is specified, this method declares the class variable
// and sets class_info->proxy to point to that name.
void Parser::DeclareClassVariable(const AstRawString* name, Scope* block_scope,
                                  ClassInfo* class_info, int class_token_pos,
                                  bool* ok) {
3444
#ifdef DEBUG
3445
  scope()->SetScopeName(name);
3446
#endif
3447

3448
  if (name != nullptr) {
3449 3450 3451
    class_info->proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE);
    Declaration* declaration = factory()->NewVariableDeclaration(
        class_info->proxy, block_scope, class_token_pos);
3452
    Declare(declaration, DeclarationDescriptor::NORMAL, CONST,
3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472
            Variable::DefaultInitializationFlag(CONST), ok);
  }
}

// This method declares a property of the given class.  It updates the
// following fields of class_info, as appropriate:
//   - constructor
//   - static_initializer_var
//   - instance_field_initializers
//   - properties
void Parser::DeclareClassProperty(const AstRawString* class_name,
                                  ClassLiteralProperty* property,
                                  ClassInfo* class_info, bool* ok) {
  if (class_info->has_seen_constructor && class_info->constructor == nullptr) {
    class_info->constructor = GetPropertyValue(property)->AsFunctionLiteral();
    DCHECK_NOT_NULL(class_info->constructor);
    class_info->constructor->set_raw_name(
        class_name != nullptr ? class_name
                              : ast_value_factory()->empty_string());
    return;
3473 3474
  }

3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533
  if (property->kind() == ClassLiteralProperty::FIELD) {
    DCHECK(allow_harmony_class_fields());
    if (property->is_static()) {
      if (class_info->static_initializer_var == nullptr) {
        class_info->static_initializer_var =
            NewTemporary(ast_value_factory()->empty_string());
      }
      // TODO(bakkot) only do this conditionally
      Expression* function = InstallHomeObject(
          property->value(),
          factory()->NewVariableProxy(class_info->static_initializer_var));
      ZoneList<Expression*>* args =
          new (zone()) ZoneList<Expression*>(2, zone());
      args->Add(function, zone());
      args->Add(factory()->NewVariableProxy(class_info->static_initializer_var),
                zone());
      Expression* call = factory()->NewCallRuntime(Runtime::kInlineCall, args,
                                                   kNoSourcePosition);
      property->set_value(call);
    } else {
      // if (is_computed_name) { // TODO(bakkot) figure out why this is
      // necessary for non-computed names in full-codegen
      ZoneList<Expression*>* to_name_args =
          new (zone()) ZoneList<Expression*>(1, zone());
      to_name_args->Add(property->key(), zone());
      property->set_key(factory()->NewCallRuntime(
          Runtime::kToName, to_name_args, kNoSourcePosition));
      //}
      const AstRawString* name = ClassFieldVariableName(
          true, ast_value_factory(),
          class_info->instance_field_initializers->length());
      VariableProxy* name_proxy =
          factory()->NewVariableProxy(name, NORMAL_VARIABLE);
      Declaration* name_declaration = factory()->NewVariableDeclaration(
          name_proxy, scope(), kNoSourcePosition);
      Variable* name_var =
          Declare(name_declaration, DeclarationDescriptor::NORMAL, CONST,
                  kNeedsInitialization, ok, scope());
      DCHECK(*ok);
      if (!*ok) return;
      class_info->instance_field_initializers->Add(property->value(), zone());
      property->set_value(factory()->NewVariableProxy(name_var));
    }
  }
  class_info->properties->Add(property, zone());
}

// This method rewrites a class literal into a do-expression.
// It uses the following fields of class_info:
//   - constructor (if missing, it updates it with a default constructor)
//   - proxy
//   - extends
//   - static_initializer_var
//   - instance_field_initializers
//   - properties
Expression* Parser::RewriteClassLiteral(const AstRawString* name,
                                        ClassInfo* class_info, int pos,
                                        bool* ok) {
  int end_pos = scanner()->location().end_pos;
3534 3535 3536
  Block* do_block = factory()->NewBlock(nullptr, 1, false, pos);
  Variable* result_var = NewTemporary(ast_value_factory()->empty_string());
  DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos);
3537

3538 3539 3540
  bool has_extends = class_info->extends != nullptr;
  bool has_instance_fields =
      class_info->instance_field_initializers->length() > 0;
3541
  DCHECK(!has_instance_fields || allow_harmony_class_fields());
3542
  bool has_default_constructor = class_info->constructor == nullptr;
3543
  if (has_default_constructor) {
3544 3545 3546
    class_info->constructor =
        DefaultConstructor(name, has_extends, has_instance_fields, pos, end_pos,
                           scope()->language_mode());
3547 3548
  }

3549 3550 3551 3552
  if (has_instance_fields && !has_extends) {
    class_info->constructor =
        InsertClassFieldInitializer(class_info->constructor);
    class_info->constructor->set_requires_class_field_init(true);
3553 3554
  }  // The derived case is handled by rewriting super calls.

3555
  scope()->set_end_position(end_pos);
3556

3557
  if (name != nullptr) {
3558 3559
    DCHECK_NOT_NULL(class_info->proxy);
    class_info->proxy->var()->set_initializer_position(end_pos);
3560 3561
  }

3562
  ClassLiteral* class_literal = factory()->NewClassLiteral(
3563 3564
      class_info->proxy, class_info->extends, class_info->constructor,
      class_info->properties, pos, end_pos);
3565

3566
  if (class_info->static_initializer_var != nullptr) {
3567
    class_literal->set_static_initializer_proxy(
3568
        factory()->NewVariableProxy(class_info->static_initializer_var));
3569 3570
  }

3571
  do_block->statements()->Add(
3572 3573 3574 3575 3576 3577
      factory()->NewExpressionStatement(
          factory()->NewAssignment(Token::ASSIGN,
                                   factory()->NewVariableProxy(result_var),
                                   class_literal, kNoSourcePosition),
          pos),
      zone());
3578
  if (allow_harmony_class_fields() &&
3579
      (has_instance_fields || (has_extends && !has_default_constructor))) {
3580 3581 3582 3583 3584 3585 3586 3587 3588
    // Default constructors for derived classes without fields will not try to
    // read this variable, so there's no need to create it.
    const AstRawString* init_fn_name =
        ast_value_factory()->dot_class_field_init_string();
    Variable* init_fn_var = scope()->DeclareLocal(
        init_fn_name, CONST, kCreatedInitialized, NORMAL_VARIABLE);
    Expression* initializer =
        has_instance_fields
            ? static_cast<Expression*>(SynthesizeClassFieldInitializer(
3589
                  class_info->instance_field_initializers->length()))
3590 3591 3592 3593 3594 3595 3596 3597
            : factory()->NewBooleanLiteral(false, kNoSourcePosition);
    Assignment* assignment = factory()->NewAssignment(
        Token::INIT, factory()->NewVariableProxy(init_fn_var), initializer,
        kNoSourcePosition);
    do_block->statements()->Add(
        factory()->NewExpressionStatement(assignment, kNoSourcePosition),
        zone());
  }
3598
  for (int i = 0; i < class_info->instance_field_initializers->length(); ++i) {
3599 3600
    const AstRawString* function_name =
        ClassFieldVariableName(false, ast_value_factory(), i);
3601 3602
    VariableProxy* function_proxy =
        factory()->NewVariableProxy(function_name, NORMAL_VARIABLE);
3603 3604 3605 3606 3607
    Declaration* function_declaration = factory()->NewVariableDeclaration(
        function_proxy, scope(), kNoSourcePosition);
    Variable* function_var =
        Declare(function_declaration, DeclarationDescriptor::NORMAL, CONST,
                kNeedsInitialization, ok, scope());
3608
    if (!*ok) return nullptr;
3609 3610 3611 3612 3613 3614
    Property* prototype_property = factory()->NewProperty(
        factory()->NewVariableProxy(result_var),
        factory()->NewStringLiteral(ast_value_factory()->prototype_string(),
                                    kNoSourcePosition),
        kNoSourcePosition);
    Expression* function_value = InstallHomeObject(
3615
        class_info->instance_field_initializers->at(i),
3616 3617 3618 3619 3620 3621 3622 3623 3624
        prototype_property);  // TODO(bakkot) ideally this would be conditional,
                              // especially in trivial cases
    Assignment* function_assignment = factory()->NewAssignment(
        Token::INIT, factory()->NewVariableProxy(function_var), function_value,
        kNoSourcePosition);
    do_block->statements()->Add(factory()->NewExpressionStatement(
                                    function_assignment, kNoSourcePosition),
                                zone());
  }
3625 3626
  do_block->set_scope(scope()->FinalizeBlockScope());
  do_expr->set_represented_function(class_info->constructor);
3627 3628

  return do_expr;
3629 3630
}

3631
Literal* Parser::GetLiteralUndefined(int position) {
3632
  return factory()->NewUndefinedLiteral(position);
3633 3634 3635
}


3636 3637 3638
void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
  Declaration* decl = scope->CheckConflictingVarDeclarations();
  if (decl != NULL) {
3639
    // In ES6, conflicting variable bindings are early errors.
3640
    const AstRawString* name = decl->proxy()->raw_name();
3641
    int position = decl->proxy()->position();
yangguo's avatar
yangguo committed
3642 3643 3644 3645
    Scanner::Location location =
        position == kNoSourcePosition
            ? Scanner::Location::invalid()
            : Scanner::Location(position, position + 1);
3646
    ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
3647 3648 3649 3650 3651
    *ok = false;
  }
}


3652 3653 3654 3655 3656 3657 3658
void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) {
  // For each var-binding that shadows a parameter, insert an assignment
  // initializing the variable with the parameter.
  Scope* inner_scope = inner_block->scope();
  DCHECK(inner_scope->is_declaration_scope());
  Scope* function_scope = inner_scope->outer_scope();
  DCHECK(function_scope->is_function_scope());
3659
  BlockState block_state(&scope_state_, inner_scope);
3660
  for (Declaration* decl : *inner_scope->declarations()) {
3661 3662 3663
    if (decl->proxy()->var()->mode() != VAR || !decl->IsVariableDeclaration()) {
      continue;
    }
3664 3665 3666
    const AstRawString* name = decl->proxy()->raw_name();
    Variable* parameter = function_scope->LookupLocal(name);
    if (parameter == nullptr) continue;
3667
    VariableProxy* to = NewUnresolved(name);
3668
    VariableProxy* from = factory()->NewVariableProxy(parameter);
yangguo's avatar
yangguo committed
3669 3670 3671 3672
    Expression* assignment =
        factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition);
    Statement* statement =
        factory()->NewExpressionStatement(assignment, kNoSourcePosition);
3673 3674 3675 3676
    inner_block->statements()->InsertAt(0, statement, zone());
  }
}

3677 3678 3679 3680 3681 3682 3683
void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope) {
  // For the outermost eval scope, we cannot hoist during parsing: let
  // declarations in the surrounding scope may prevent hoisting, but the
  // information is unaccessible during parsing. In this case, we hoist later in
  // DeclarationScope::Analyze.
  if (scope->is_eval_scope() && scope->outer_scope() == original_scope_) {
    return;
3684
  }
3685
  scope->HoistSloppyBlockFunctions(factory());
3686 3687
}

3688 3689 3690
// ----------------------------------------------------------------------------
// Parser support

3691
bool Parser::TargetStackContainsLabel(const AstRawString* label) {
3692
  for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) {
3693
    if (ContainsLabel(t->statement()->labels(), label)) return true;
3694 3695 3696 3697 3698
  }
  return false;
}


3699 3700 3701
BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label,
                                              bool* ok) {
  bool anonymous = label == NULL;
3702
  for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) {
3703
    BreakableStatement* stat = t->statement();
3704 3705 3706 3707 3708 3709 3710 3711 3712
    if ((anonymous && stat->is_target_for_anonymous()) ||
        (!anonymous && ContainsLabel(stat->labels(), label))) {
      return stat;
    }
  }
  return NULL;
}


3713
IterationStatement* Parser::LookupContinueTarget(const AstRawString* label,
3714
                                                 bool* ok) {
3715
  bool anonymous = label == NULL;
3716
  for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) {
3717
    IterationStatement* stat = t->statement()->AsIterationStatement();
3718 3719
    if (stat == NULL) continue;

3720
    DCHECK(stat->is_target_for_anonymous());
3721 3722 3723 3724 3725 3726 3727 3728
    if (anonymous || ContainsLabel(stat->labels(), label)) {
      return stat;
    }
  }
  return NULL;
}


3729
void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) {
3730 3731
  Handle<String> source_url = scanner_.SourceUrl(isolate);
  if (!source_url.is_null()) {
3732
    script->set_source_url(*source_url);
3733
  }
3734 3735
  Handle<String> source_mapping_url = scanner_.SourceMappingUrl(isolate);
  if (!source_mapping_url.is_null()) {
3736
    script->set_source_mapping_url(*source_mapping_url);
3737 3738 3739 3740
  }
}


3741
void Parser::Internalize(Isolate* isolate, Handle<Script> script, bool error) {
3742
  // Internalize strings and values.
3743
  ast_value_factory()->Internalize(isolate);
3744 3745

  // Error processing.
3746
  if (error) {
3747
    if (stack_overflow()) {
3748
      isolate->StackOverflow();
3749
    } else {
3750 3751
      DCHECK(pending_error_handler_.has_pending_error());
      pending_error_handler_.ThrowPendingError(isolate, script);
3752 3753 3754 3755
    }
  }

  // Move statistics to Isolate.
3756 3757
  for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
       ++feature) {
3758
    if (use_counts_[feature] > 0) {
3759
      isolate->CountUsage(v8::Isolate::UseCounterFeature(feature));
3760 3761
    }
  }
3762 3763 3764 3765 3766 3767
  if (scanner_.FoundHtmlComment()) {
    isolate->CountUsage(v8::Isolate::kHtmlComment);
    if (script->line_offset() == 0 && script->column_offset() == 0) {
      isolate->CountUsage(v8::Isolate::kHtmlCommentInExternalScript);
    }
  }
3768
  isolate->counters()->total_preparse_skipped()->Increment(
3769
      total_preparse_skipped_);
3770 3771 3772
}


3773 3774 3775
// ----------------------------------------------------------------------------
// The Parser interface.

3776

3777 3778
bool Parser::ParseStatic(ParseInfo* info) {
  Parser parser(info);
3779
  if (parser.Parse(info)) {
3780
    info->set_language_mode(info->literal()->language_mode());
3781 3782 3783 3784 3785 3786
    return true;
  }
  return false;
}


3787
bool Parser::Parse(ParseInfo* info) {
3788
  DCHECK(info->literal() == NULL);
3789
  FunctionLiteral* result = NULL;
3790 3791 3792
  // Ok to use Isolate here; this function is only called in the main thread.
  DCHECK(parsing_on_main_thread_);
  Isolate* isolate = info->isolate();
3793

3794
  if (info->is_toplevel()) {
3795
    SetCachedData(info);
3796
    result = ParseProgram(isolate, info);
3797
  } else {
3798
    result = ParseFunction(isolate, info);
3799
  }
3800
  info->set_literal(result);
3801

3802
  Internalize(isolate, info->script(), result == NULL);
3803
  return (result != NULL);
3804 3805
}

3806

3807
void Parser::ParseOnBackground(ParseInfo* info) {
3808 3809
  parsing_on_main_thread_ = false;

3810
  DCHECK(info->literal() == NULL);
3811 3812
  FunctionLiteral* result = NULL;

3813 3814
  ParserLogger logger;
  if (produce_cached_parse_data()) log_ = &logger;
3815

3816 3817 3818 3819 3820 3821 3822
  std::unique_ptr<Utf16CharacterStream> stream;
  Utf16CharacterStream* stream_ptr;
  if (info->character_stream()) {
    DCHECK(info->source_stream() == nullptr);
    stream_ptr = info->character_stream();
  } else {
    DCHECK(info->character_stream() == nullptr);
3823 3824
    stream.reset(ScannerStream::For(info->source_stream(),
                                    info->source_stream_encoding()));
3825 3826
    stream_ptr = stream.get();
  }
3827
  DCHECK(info->maybe_outer_scope_info().is_null());
3828

3829 3830
  DCHECK(original_scope_);

3831 3832 3833 3834 3835 3836
  // When streaming, we don't know the length of the source until we have parsed
  // it. The raw data can be UTF-8, so we wouldn't know the source length until
  // we have decoded it anyway even if we knew the raw data length (which we
  // don't). We work around this by storing all the scopes which need their end
  // position set at the end of the script (the top scope and possible eval
  // scopes) and set their end position after we know the script length.
verwaest's avatar
verwaest committed
3837
  if (info->is_toplevel()) {
3838 3839 3840
    fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
    scanner_.Initialize(stream_ptr);
    result = DoParseProgram(info);
verwaest's avatar
verwaest committed
3841
  } else {
3842
    result = DoParseFunction(info, info->function_name(), stream_ptr);
3843
  }
3844

3845
  info->set_literal(result);
3846 3847 3848 3849

  // We cannot internalize on a background thread; a foreground task will take
  // care of calling Parser::Internalize just before compilation.

3850
  if (produce_cached_parse_data()) {
3851
    if (result != NULL) *info->cached_data() = logger.GetScriptData();
3852 3853 3854
    log_ = NULL;
  }
}
3855

3856 3857
Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
  return new (zone()) TemplateLiteral(zone(), pos);
3858 3859 3860 3861 3862 3863 3864
}


void Parser::AddTemplateSpan(TemplateLiteralState* state, bool tail) {
  int pos = scanner()->location().beg_pos;
  int end = scanner()->location().end_pos - (tail ? 1 : 2);
  const AstRawString* tv = scanner()->CurrentSymbol(ast_value_factory());
3865
  const AstRawString* trv = scanner()->CurrentRawSymbol(ast_value_factory());
3866
  Literal* cooked = factory()->NewStringLiteral(tv, pos);
3867 3868
  Literal* raw = factory()->NewStringLiteral(trv, pos);
  (*state)->AddTemplateSpan(cooked, raw, end, zone());
3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882
}


void Parser::AddTemplateExpression(TemplateLiteralState* state,
                                   Expression* expression) {
  (*state)->AddExpression(expression, zone());
}


Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
                                         Expression* tag) {
  TemplateLiteral* lit = *state;
  int pos = lit->position();
  const ZoneList<Expression*>* cooked_strings = lit->cooked();
3883
  const ZoneList<Expression*>* raw_strings = lit->raw();
3884
  const ZoneList<Expression*>* expressions = lit->expressions();
3885 3886
  DCHECK_EQ(cooked_strings->length(), raw_strings->length());
  DCHECK_EQ(cooked_strings->length(), expressions->length() + 1);
3887 3888 3889

  if (!tag) {
    // Build tree of BinaryOps to simplify code-generation
3890 3891 3892 3893 3894 3895 3896 3897 3898 3899
    Expression* expr = cooked_strings->at(0);
    int i = 0;
    while (i < expressions->length()) {
      Expression* sub = expressions->at(i++);
      Expression* cooked_str = cooked_strings->at(i);

      // Let middle be ToString(sub).
      ZoneList<Expression*>* args =
          new (zone()) ZoneList<Expression*>(1, zone());
      args->Add(sub, zone());
3900 3901
      Expression* middle = factory()->NewCallRuntime(Runtime::kInlineToString,
                                                     args, sub->position());
3902 3903

      expr = factory()->NewBinaryOperation(
3904 3905 3906
          Token::ADD, factory()->NewBinaryOperation(
                          Token::ADD, expr, middle, expr->position()),
          cooked_str, sub->position());
3907 3908 3909
    }
    return expr;
  } else {
3910
    uint32_t hash = ComputeTemplateLiteralHash(lit);
3911 3912 3913 3914

    int cooked_idx = function_state_->NextMaterializedLiteralIndex();
    int raw_idx = function_state_->NextMaterializedLiteralIndex();

3915
    // $getTemplateCallSite
3916 3917 3918
    ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone());
    args->Add(factory()->NewArrayLiteral(
                  const_cast<ZoneList<Expression*>*>(cooked_strings),
3919
                  cooked_idx, pos),
3920 3921 3922
              zone());
    args->Add(
        factory()->NewArrayLiteral(
3923
            const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx, pos),
3924
        zone());
3925

heimbuef's avatar
heimbuef committed
3926
    // Truncate hash to Smi-range.
3927
    Smi* hash_obj = Smi::cast(Internals::IntToSmi(static_cast<int>(hash)));
heimbuef's avatar
heimbuef committed
3928
    args->Add(factory()->NewNumberLiteral(hash_obj->value(), pos), zone());
3929

3930
    Expression* call_site = factory()->NewCallRuntime(
3931
        Context::GET_TEMPLATE_CALL_SITE_INDEX, args, start);
3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942

    // Call TagFn
    ZoneList<Expression*>* call_args =
        new (zone()) ZoneList<Expression*>(expressions->length() + 1, zone());
    call_args->Add(call_site, zone());
    call_args->AddAll(*expressions, zone());
    return factory()->NewCall(tag, call_args, pos);
  }
}


3943 3944 3945
uint32_t Parser::ComputeTemplateLiteralHash(const TemplateLiteral* lit) {
  const ZoneList<Expression*>* raw_strings = lit->raw();
  int total = raw_strings->length();
3946 3947
  DCHECK(total);

3948
  uint32_t running_hash = 0;
3949

3950
  for (int index = 0; index < total; ++index) {
3951
    if (index) {
3952 3953
      running_hash = StringHasher::ComputeRunningHashOneByte(
          running_hash, "${}", 3);
3954 3955
    }

3956 3957 3958 3959 3960 3961
    const AstRawString* raw_string =
        raw_strings->at(index)->AsLiteral()->raw_value()->AsString();
    if (raw_string->is_one_byte()) {
      const char* data = reinterpret_cast<const char*>(raw_string->raw_data());
      running_hash = StringHasher::ComputeRunningHashOneByte(
          running_hash, data, raw_string->length());
3962
    } else {
3963 3964 3965
      const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data());
      running_hash = StringHasher::ComputeRunningHash(running_hash, data,
                                                      raw_string->length());
3966
    }
3967 3968
  }

3969
  return running_hash;
3970
}
3971

3972 3973 3974
ZoneList<Expression*>* Parser::PrepareSpreadArguments(
    ZoneList<Expression*>* list) {
  ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
3975 3976 3977 3978 3979 3980 3981 3982 3983 3984
  if (list->length() == 1) {
    // Spread-call with single spread argument produces an InternalArray
    // containing the values from the array.
    //
    // Function is called or constructed with the produced array of arguments
    //
    // EG: Apply(Func, Spread(spread0))
    ZoneList<Expression*>* spread_list =
        new (zone()) ZoneList<Expression*>(0, zone());
    spread_list->Add(list->at(0)->AsSpread()->expression(), zone());
3985
    args->Add(factory()->NewCallRuntime(Context::SPREAD_ITERABLE_INDEX,
yangguo's avatar
yangguo committed
3986
                                        spread_list, kNoSourcePosition),
3987
              zone());
3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000
    return args;
  } else {
    // Spread-call with multiple arguments produces array literals for each
    // sequences of unspread arguments, and converts each spread iterable to
    // an Internal array. Finally, all of these produced arrays are flattened
    // into a single InternalArray, containing the arguments for the call.
    //
    // EG: Apply(Func, Flatten([unspread0, unspread1], Spread(spread0),
    //                         Spread(spread1), [unspread2, unspread3]))
    int i = 0;
    int n = list->length();
    while (i < n) {
      if (!list->at(i)->IsSpread()) {
4001 4002
        ZoneList<Expression*>* unspread =
            new (zone()) ZoneList<Expression*>(1, zone());
4003 4004 4005 4006 4007 4008 4009

        // Push array of unspread parameters
        while (i < n && !list->at(i)->IsSpread()) {
          unspread->Add(list->at(i++), zone());
        }
        int literal_index = function_state_->NextMaterializedLiteralIndex();
        args->Add(factory()->NewArrayLiteral(unspread, literal_index,
yangguo's avatar
yangguo committed
4010
                                             kNoSourcePosition),
4011 4012 4013 4014 4015 4016
                  zone());

        if (i == n) break;
      }

      // Push eagerly spread argument
4017 4018
      ZoneList<Expression*>* spread_list =
          new (zone()) ZoneList<Expression*>(1, zone());
4019
      spread_list->Add(list->at(i++)->AsSpread()->expression(), zone());
4020
      args->Add(factory()->NewCallRuntime(Context::SPREAD_ITERABLE_INDEX,
yangguo's avatar
yangguo committed
4021
                                          spread_list, kNoSourcePosition),
4022 4023 4024
                zone());
    }

4025
    list = new (zone()) ZoneList<Expression*>(1, zone());
4026
    list->Add(factory()->NewCallRuntime(Context::SPREAD_ARGUMENTS_INDEX, args,
yangguo's avatar
yangguo committed
4027
                                        kNoSourcePosition),
4028 4029 4030 4031 4032 4033 4034
              zone());
    return list;
  }
  UNREACHABLE();
}

Expression* Parser::SpreadCall(Expression* function,
4035
                               ZoneList<Expression*>* args, int pos) {
4036
  if (function->IsSuperCallReference()) {
4037
    // Super calls
4038 4039
    // $super_constructor = %_GetSuperConstructor(<this-function>)
    // %reflect_construct($super_constructor, args, new.target)
4040 4041
    ZoneList<Expression*>* tmp = new (zone()) ZoneList<Expression*>(1, zone());
    tmp->Add(function->AsSuperCallReference()->this_function_var(), zone());
4042 4043 4044
    Expression* super_constructor = factory()->NewCallRuntime(
        Runtime::kInlineGetSuperConstructor, tmp, pos);
    args->InsertAt(0, super_constructor, zone());
4045
    args->Add(function->AsSuperCallReference()->new_target_var(), zone());
4046 4047
    return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args,
                                     pos);
4048 4049 4050
  } else {
    if (function->IsProperty()) {
      // Method calls
4051
      if (function->AsProperty()->IsSuperAccess()) {
4052
        Expression* home = ThisExpression(kNoSourcePosition);
4053 4054 4055
        args->InsertAt(0, function, zone());
        args->InsertAt(1, home, zone());
      } else {
4056
        Variable* temp = NewTemporary(ast_value_factory()->empty_string());
4057 4058 4059
        VariableProxy* obj = factory()->NewVariableProxy(temp);
        Assignment* assign_obj = factory()->NewAssignment(
            Token::ASSIGN, obj, function->AsProperty()->obj(),
yangguo's avatar
yangguo committed
4060
            kNoSourcePosition);
4061
        function = factory()->NewProperty(
yangguo's avatar
yangguo committed
4062
            assign_obj, function->AsProperty()->key(), kNoSourcePosition);
4063 4064 4065 4066
        args->InsertAt(0, function, zone());
        obj = factory()->NewVariableProxy(temp);
        args->InsertAt(1, obj, zone());
      }
4067 4068 4069
    } else {
      // Non-method calls
      args->InsertAt(0, function, zone());
yangguo's avatar
yangguo committed
4070
      args->InsertAt(1, factory()->NewUndefinedLiteral(kNoSourcePosition),
4071 4072
                     zone());
    }
4073
    return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos);
4074 4075 4076 4077
  }
}

Expression* Parser::SpreadCallNew(Expression* function,
4078
                                  ZoneList<Expression*>* args, int pos) {
4079 4080
  args->InsertAt(0, function, zone());

4081
  return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos);
4082
}
4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096


void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) {
  v8::Isolate::UseCounterFeature feature;
  if (is_sloppy(mode))
    feature = v8::Isolate::kSloppyMode;
  else if (is_strict(mode))
    feature = v8::Isolate::kStrictMode;
  else
    UNREACHABLE();
  ++use_counts_[feature];
  scope->SetLanguageMode(mode);
}

4097 4098 4099 4100 4101 4102
void Parser::SetAsmModule() {
  // Store the usage count; The actual use counter on the isolate is
  // incremented after parsing is done.
  ++use_counts_[v8::Isolate::kUseAsm];
  DCHECK(scope()->is_declaration_scope());
  scope()->AsDeclarationScope()->set_asm_module();
4103 4104
}

4105 4106 4107 4108
void Parser::MarkCollectedTailCallExpressions() {
  const ZoneList<Expression*>& tail_call_expressions =
      function_state_->tail_call_expressions().expressions();
  for (int i = 0; i < tail_call_expressions.length(); ++i) {
4109
    MarkTailPosition(tail_call_expressions[i]);
4110 4111
  }
}
4112

4113
Expression* Parser::ExpressionListToExpression(ZoneList<Expression*>* args) {
4114 4115
  Expression* expr = args->at(0);
  for (int i = 1; i < args->length(); ++i) {
4116 4117
    expr = factory()->NewBinaryOperation(Token::COMMA, expr, args->at(i),
                                         expr->position());
4118 4119 4120 4121
  }
  return expr;
}

4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164
// This method intoduces the line initializing the generator object
// when desugaring the body of async_function.
void Parser::PrepareAsyncFunctionBody(ZoneList<Statement*>* body,
                                      FunctionKind kind, int pos) {
  // function async_function() {
  //   .generator_object = %CreateGeneratorObject();
  //   BuildRejectPromiseOnException({
  //     ... block ...
  //     return %ResolvePromise(.promise, expr), .promise;
  //   })
  // }

  Variable* temp =
      NewTemporary(ast_value_factory()->dot_generator_object_string());
  function_state_->set_generator_object_variable(temp);

  Expression* init_generator_variable = factory()->NewAssignment(
      Token::INIT, factory()->NewVariableProxy(temp),
      BuildCreateJSGeneratorObject(pos, kind), kNoSourcePosition);
  body->Add(factory()->NewExpressionStatement(init_generator_variable,
                                              kNoSourcePosition),
            zone());
}

// This method completes the desugaring of the body of async_function.
void Parser::RewriteAsyncFunctionBody(ZoneList<Statement*>* body, Block* block,
                                      Expression* return_value, bool* ok) {
  // function async_function() {
  //   .generator_object = %CreateGeneratorObject();
  //   BuildRejectPromiseOnException({
  //     ... block ...
  //     return %ResolvePromise(.promise, expr), .promise;
  //   })
  // }

  return_value = BuildResolvePromise(return_value, return_value->position());
  block->statements()->Add(
      factory()->NewReturnStatement(return_value, return_value->position()),
      zone());
  block = BuildRejectPromiseOnException(block, CHECK_OK_VOID);
  body->Add(block, zone());
}

4165
Expression* Parser::RewriteAwaitExpression(Expression* value, int await_pos) {
4166 4167
  // yield do {
  //   tmp = <operand>;
4168 4169
  //   %AsyncFunctionAwait(.generator_object, tmp, .promise);
  //   .promise
4170
  // }
4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184
  // The value of the expression is returned to the caller of the async
  // function for the first yield statement; for this, .promise is the
  // appropriate return value, being a Promise that will be fulfilled or
  // rejected with the appropriate value by the desugaring. Subsequent yield
  // occurrences will return to the AsyncFunctionNext call within the
  // implemementation of the intermediate throwaway Promise's then handler.
  // This handler has nothing useful to do with the value, as the Promise is
  // ignored. If we yielded the value of the throwawayPromise that
  // AsyncFunctionAwait creates as an intermediate, it would create a memory
  // leak; we must return .promise instead;
  // The operand needs to be evaluated on a separate statement in order to get
  // a break location, and the .promise needs to be read earlier so that it
  // doesn't insert a false location.
  // TODO(littledan): investigate why this ordering is needed in more detail.
4185
  Variable* generator_object_variable =
4186
      function_state_->generator_object_variable();
4187 4188

  // If generator_object_variable is null,
4189
  // TODO(littledan): Is this necessary?
4190 4191
  if (!generator_object_variable) return value;

yangguo's avatar
yangguo committed
4192
  const int nopos = kNoSourcePosition;
4193

4194
  Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos);
4195

4196
  Variable* promise = PromiseVariable();
4197 4198

  // Wrap value evaluation to provide a break location.
4199
  Variable* temp_var = NewTemporary(ast_value_factory()->empty_string());
4200 4201
  Expression* value_assignment = factory()->NewAssignment(
      Token::ASSIGN, factory()->NewVariableProxy(temp_var), value, nopos);
4202
  do_block->statements()->Add(
4203
      factory()->NewExpressionStatement(value_assignment, value->position()),
4204
      zone());
4205 4206

  ZoneList<Expression*>* async_function_await_args =
4207
      new (zone()) ZoneList<Expression*>(3, zone());
4208
  Expression* generator_object =
4209
      factory()->NewVariableProxy(generator_object_variable);
4210
  async_function_await_args->Add(generator_object, zone());
4211
  async_function_await_args->Add(factory()->NewVariableProxy(temp_var), zone());
4212
  async_function_await_args->Add(factory()->NewVariableProxy(promise), zone());
4213 4214 4215 4216 4217 4218 4219

  // The parser emits calls to AsyncFunctionAwaitCaught, but the
  // AstNumberingVisitor will rewrite this to AsyncFunctionAwaitUncaught
  // if there is no local enclosing try/catch block.
  Expression* async_function_await =
      factory()->NewCallRuntime(Context::ASYNC_FUNCTION_AWAIT_CAUGHT_INDEX,
                                async_function_await_args, nopos);
4220 4221 4222
  do_block->statements()->Add(
      factory()->NewExpressionStatement(async_function_await, await_pos),
      zone());
4223

4224
  // Wrap await to provide a break location between value evaluation and yield.
4225
  Expression* do_expr = factory()->NewDoExpression(do_block, promise, nopos);
4226

4227 4228 4229
  generator_object = factory()->NewVariableProxy(generator_object_variable);
  return factory()->NewYield(generator_object, do_expr, nopos,
                             Yield::kOnExceptionRethrow);
4230 4231
}

nikolaos's avatar
nikolaos committed
4232 4233 4234 4235 4236 4237 4238 4239
class NonPatternRewriter : public AstExpressionRewriter {
 public:
  NonPatternRewriter(uintptr_t stack_limit, Parser* parser)
      : AstExpressionRewriter(stack_limit), parser_(parser) {}
  ~NonPatternRewriter() override {}

 private:
  bool RewriteExpression(Expression* expr) override {
4240
    if (expr->IsRewritableExpression()) return true;
nikolaos's avatar
nikolaos committed
4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259
    // Rewrite only what could have been a pattern but is not.
    if (expr->IsArrayLiteral()) {
      // Spread rewriting in array literals.
      ArrayLiteral* lit = expr->AsArrayLiteral();
      VisitExpressions(lit->values());
      replacement_ = parser_->RewriteSpreads(lit);
      return false;
    }
    if (expr->IsObjectLiteral()) {
      return true;
    }
    if (expr->IsBinaryOperation() &&
        expr->AsBinaryOperation()->op() == Token::COMMA) {
      return true;
    }
    // Everything else does not need rewriting.
    return false;
  }

4260
  void VisitLiteralProperty(LiteralProperty* property) override {
4261 4262 4263 4264 4265
    if (property == nullptr) return;
    // Do not rewrite (computed) key expressions
    AST_REWRITE_PROPERTY(Expression, property, value);
  }

nikolaos's avatar
nikolaos committed
4266 4267 4268
  Parser* parser_;
};

4269 4270
void Parser::RewriteNonPattern(bool* ok) {
  ValidateExpression(CHECK_OK_VOID);
4271
  auto non_patterns_to_rewrite = function_state_->non_patterns_to_rewrite();
4272
  int begin = classifier()->GetNonPatternBegin();
4273 4274 4275 4276 4277 4278 4279 4280
  int end = non_patterns_to_rewrite->length();
  if (begin < end) {
    NonPatternRewriter rewriter(stack_limit_, this);
    for (int i = begin; i < end; i++) {
      DCHECK(non_patterns_to_rewrite->at(i)->IsRewritableExpression());
      rewriter.Rewrite(non_patterns_to_rewrite->at(i));
    }
    non_patterns_to_rewrite->Rewind(begin);
nikolaos's avatar
nikolaos committed
4281 4282 4283 4284
  }
}


4285
void Parser::RewriteDestructuringAssignments() {
4286 4287
  const auto& assignments =
      function_state_->destructuring_assignments_to_rewrite();
4288 4289 4290
  for (int i = assignments.length() - 1; i >= 0; --i) {
    // Rewrite list in reverse, so that nested assignment patterns are rewritten
    // correctly.
4291 4292 4293
    const DestructuringAssignment& pair = assignments.at(i);
    RewritableExpression* to_rewrite =
        pair.assignment->AsRewritableExpression();
4294 4295
    DCHECK_NOT_NULL(to_rewrite);
    if (!to_rewrite->is_rewritten()) {
4296 4297
      PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite,
                                                      pair.scope);
4298 4299 4300 4301
    }
  }
}

4302 4303 4304 4305 4306
Expression* Parser::RewriteExponentiation(Expression* left, Expression* right,
                                          int pos) {
  ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
  args->Add(left, zone());
  args->Add(right, zone());
4307
  return factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos);
4308 4309 4310 4311 4312 4313 4314 4315 4316 4317
}

Expression* Parser::RewriteAssignExponentiation(Expression* left,
                                                Expression* right, int pos) {
  ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
  if (left->IsVariableProxy()) {
    VariableProxy* lhs = left->AsVariableProxy();

    Expression* result;
    DCHECK_NOT_NULL(lhs->raw_name());
4318
    result = ExpressionFromIdentifier(lhs->raw_name(), lhs->position());
4319 4320 4321
    args->Add(left, zone());
    args->Add(right, zone());
    Expression* call =
4322
        factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos);
4323 4324 4325
    return factory()->NewAssignment(Token::ASSIGN, result, call, pos);
  } else if (left->IsProperty()) {
    Property* prop = left->AsProperty();
4326 4327
    auto temp_obj = NewTemporary(ast_value_factory()->empty_string());
    auto temp_key = NewTemporary(ast_value_factory()->empty_string());
4328 4329
    Expression* assign_obj = factory()->NewAssignment(
        Token::ASSIGN, factory()->NewVariableProxy(temp_obj), prop->obj(),
yangguo's avatar
yangguo committed
4330
        kNoSourcePosition);
4331 4332
    Expression* assign_key = factory()->NewAssignment(
        Token::ASSIGN, factory()->NewVariableProxy(temp_key), prop->key(),
yangguo's avatar
yangguo committed
4333
        kNoSourcePosition);
4334 4335 4336 4337 4338 4339
    args->Add(factory()->NewProperty(factory()->NewVariableProxy(temp_obj),
                                     factory()->NewVariableProxy(temp_key),
                                     left->position()),
              zone());
    args->Add(right, zone());
    Expression* call =
4340
        factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos);
4341 4342
    Expression* target = factory()->NewProperty(
        factory()->NewVariableProxy(temp_obj),
yangguo's avatar
yangguo committed
4343
        factory()->NewVariableProxy(temp_key), kNoSourcePosition);
4344 4345 4346 4347 4348 4349 4350 4351 4352 4353
    Expression* assign =
        factory()->NewAssignment(Token::ASSIGN, target, call, pos);
    return factory()->NewBinaryOperation(
        Token::COMMA, assign_obj,
        factory()->NewBinaryOperation(Token::COMMA, assign_key, assign, pos),
        pos);
  }
  UNREACHABLE();
  return nullptr;
}
4354

nikolaos's avatar
nikolaos committed
4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369
Expression* Parser::RewriteSpreads(ArrayLiteral* lit) {
  // Array literals containing spreads are rewritten using do expressions, e.g.
  //    [1, 2, 3, ...x, 4, ...y, 5]
  // is roughly rewritten as:
  //    do {
  //      $R = [1, 2, 3];
  //      for ($i of x) %AppendElement($R, $i);
  //      %AppendElement($R, 4);
  //      for ($j of y) %AppendElement($R, $j);
  //      %AppendElement($R, 5);
  //      $R
  //    }
  // where $R, $i and $j are fresh temporary variables.
  ZoneList<Expression*>::iterator s = lit->FirstSpread();
  if (s == lit->EndValue()) return nullptr;  // no spread, no rewriting...
4370
  Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
nikolaos's avatar
nikolaos committed
4371 4372 4373
  // NOTE: The value assigned to R is the whole original array literal,
  // spreads included. This will be fixed before the rewritten AST is returned.
  // $R = lit
yangguo's avatar
yangguo committed
4374 4375 4376
  Expression* init_result = factory()->NewAssignment(
      Token::INIT, factory()->NewVariableProxy(result), lit, kNoSourcePosition);
  Block* do_block = factory()->NewBlock(nullptr, 16, false, kNoSourcePosition);
nikolaos's avatar
nikolaos committed
4377
  do_block->statements()->Add(
yangguo's avatar
yangguo committed
4378
      factory()->NewExpressionStatement(init_result, kNoSourcePosition),
nikolaos's avatar
nikolaos committed
4379 4380 4381 4382 4383 4384 4385 4386
      zone());
  // Traverse the array literal starting from the first spread.
  while (s != lit->EndValue()) {
    Expression* value = *s++;
    Spread* spread = value->AsSpread();
    if (spread == nullptr) {
      // If the element is not a spread, we're adding a single:
      // %AppendElement($R, value)
4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412
      // or, in case of a hole,
      // ++($R.length)
      if (!value->IsLiteral() ||
          !value->AsLiteral()->raw_value()->IsTheHole()) {
        ZoneList<Expression*>* append_element_args = NewExpressionList(2);
        append_element_args->Add(factory()->NewVariableProxy(result), zone());
        append_element_args->Add(value, zone());
        do_block->statements()->Add(
            factory()->NewExpressionStatement(
                factory()->NewCallRuntime(Runtime::kAppendElement,
                                          append_element_args,
                                          kNoSourcePosition),
                kNoSourcePosition),
            zone());
      } else {
        Property* length_property = factory()->NewProperty(
            factory()->NewVariableProxy(result),
            factory()->NewStringLiteral(ast_value_factory()->length_string(),
                                        kNoSourcePosition),
            kNoSourcePosition);
        CountOperation* count_op = factory()->NewCountOperation(
            Token::INC, true /* prefix */, length_property, kNoSourcePosition);
        do_block->statements()->Add(
            factory()->NewExpressionStatement(count_op, kNoSourcePosition),
            zone());
      }
nikolaos's avatar
nikolaos committed
4413 4414
    } else {
      // If it's a spread, we're adding a for/of loop iterating through it.
4415
      Variable* each = NewTemporary(ast_value_factory()->dot_for_string());
nikolaos's avatar
nikolaos committed
4416 4417 4418 4419
      Expression* subject = spread->expression();
      // %AppendElement($R, each)
      Statement* append_body;
      {
4420
        ZoneList<Expression*>* append_element_args = NewExpressionList(2);
nikolaos's avatar
nikolaos committed
4421 4422 4423 4424
        append_element_args->Add(factory()->NewVariableProxy(result), zone());
        append_element_args->Add(factory()->NewVariableProxy(each), zone());
        append_body = factory()->NewExpressionStatement(
            factory()->NewCallRuntime(Runtime::kAppendElement,
yangguo's avatar
yangguo committed
4425 4426
                                      append_element_args, kNoSourcePosition),
            kNoSourcePosition);
nikolaos's avatar
nikolaos committed
4427 4428 4429
      }
      // for (each of spread) %AppendElement($R, each)
      ForEachStatement* loop = factory()->NewForEachStatement(
yangguo's avatar
yangguo committed
4430
          ForEachStatement::ITERATE, nullptr, kNoSourcePosition);
4431
      const bool finalize = false;
4432 4433
      InitializeForOfStatement(loop->AsForOfStatement(),
                               factory()->NewVariableProxy(each), subject,
4434
                               append_body, finalize);
4435
      do_block->statements()->Add(loop, zone());
nikolaos's avatar
nikolaos committed
4436 4437 4438 4439 4440 4441 4442 4443
    }
  }
  // Now, rewind the original array literal to truncate everything from the
  // first spread (included) until the end. This fixes $R's initialization.
  lit->RewindSpreads();
  return factory()->NewDoExpression(do_block, result, lit->position());
}

4444
void Parser::QueueDestructuringAssignmentForRewriting(Expression* expr) {
4445
  DCHECK(expr->IsRewritableExpression());
4446
  function_state_->AddDestructuringAssignment(
4447
      DestructuringAssignment(expr, scope()));
4448 4449
}

4450
void Parser::QueueNonPatternForRewriting(Expression* expr, bool* ok) {
4451
  DCHECK(expr->IsRewritableExpression());
4452
  function_state_->AddNonPatternForRewriting(expr, ok);
4453 4454
}

4455 4456 4457 4458 4459 4460 4461 4462 4463
void Parser::AddAccessorPrefixToFunctionName(bool is_get,
                                             FunctionLiteral* function,
                                             const AstRawString* name) {
  DCHECK_NOT_NULL(name);
  const AstRawString* prefix = is_get ? ast_value_factory()->get_space_string()
                                      : ast_value_factory()->set_space_string();
  function->set_raw_name(ast_value_factory()->NewConsString(prefix, name));
}

4464 4465
void Parser::SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
                                             const AstRawString* name) {
4466 4467
  DCHECK(property->kind() != ObjectLiteralProperty::GETTER);
  DCHECK(property->kind() != ObjectLiteralProperty::SETTER);
4468

4469
  // Computed name setting must happen at runtime.
4470
  DCHECK(!property->is_computed_name());
4471

4472 4473 4474 4475
  // Ignore "__proto__" as a name when it's being used to set the [[Prototype]]
  // of an object literal.
  if (property->kind() == ObjectLiteralProperty::PROTOTYPE) return;

4476 4477
  Expression* value = property->value();

4478 4479
  DCHECK(!value->IsAnonymousFunctionDefinition() ||
         property->kind() == ObjectLiteralProperty::COMPUTED);
4480 4481 4482
  SetFunctionName(value, name);
}

4483 4484
void Parser::SetFunctionNameFromIdentifierRef(Expression* value,
                                              Expression* identifier) {
4485
  if (!identifier->IsVariableProxy()) return;
4486
  SetFunctionName(value, identifier->AsVariableProxy()->raw_name());
4487
}
4488

4489
void Parser::SetFunctionName(Expression* value, const AstRawString* name) {
4490 4491
  DCHECK_NOT_NULL(name);
  if (!value->IsAnonymousFunctionDefinition()) return;
4492 4493 4494
  auto function = value->AsFunctionLiteral();
  if (function != nullptr) {
    function->set_raw_name(name);
4495
  } else {
4496 4497
    DCHECK(value->IsDoExpression());
    value->AsDoExpression()->represented_function()->set_raw_name(name);
4498 4499 4500 4501
  }
}


neis's avatar
neis committed
4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530
// Desugaring of yield*
// ====================
//
// With the help of do-expressions and function.sent, we desugar yield* into a
// loop containing a "raw" yield (a yield that doesn't wrap an iterator result
// object around its argument).  Concretely, "yield* iterable" turns into
// roughly the following code:
//
//   do {
//     const kNext = 0;
//     const kReturn = 1;
//     const kThrow = 2;
//
//     let input = function.sent;
//     let mode = kNext;
//     let output = undefined;
//
//     let iterator = iterable[Symbol.iterator]();
//     if (!IS_RECEIVER(iterator)) throw MakeTypeError(kSymbolIteratorInvalid);
//
//     while (true) {
//       // From the generator to the iterator:
//       // Forward input according to resume mode and obtain output.
//       switch (mode) {
//         case kNext:
//           output = iterator.next(input);
//           if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
//           break;
//         case kReturn:
4531
//           IteratorClose(iterator, input, output);  // See below.
neis's avatar
neis committed
4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560
//           break;
//         case kThrow:
//           let iteratorThrow = iterator.throw;
//           if (IS_NULL_OR_UNDEFINED(iteratorThrow)) {
//             IteratorClose(iterator);  // See below.
//             throw MakeTypeError(kThrowMethodMissing);
//           }
//           output = %_Call(iteratorThrow, iterator, input);
//           if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
//           break;
//       }
//       if (output.done) break;
//
//       // From the generator to its user:
//       // Forward output, receive new input, and determine resume mode.
//       mode = kReturn;
//       try {
//         try {
//           RawYield(output);  // See explanation above.
//           mode = kNext;
//         } catch (error) {
//           mode = kThrow;
//         }
//       } finally {
//         input = function.sent;
//         continue;
//       }
//     }
//
4561 4562 4563 4564
//     if (mode === kReturn) {
//       return {value: output.value, done: true};
//     }
//     output.value
neis's avatar
neis committed
4565 4566 4567 4568 4569
//   }
//
// IteratorClose(iterator) expands to the following:
//
//   let iteratorReturn = iterator.return;
4570 4571 4572 4573
//   if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
//     let output = %_Call(iteratorReturn, iterator);
//     if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
//   }
neis's avatar
neis committed
4574
//
4575
// IteratorClose(iterator, input, output) expands to the following:
neis's avatar
neis committed
4576 4577 4578
//
//   let iteratorReturn = iterator.return;
//   if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return input;
4579 4580
//   output = %_Call(iteratorReturn, iterator, input);
//   if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
neis's avatar
neis committed
4581

4582 4583
Expression* Parser::RewriteYieldStar(Expression* generator,
                                     Expression* iterable, int pos) {
yangguo's avatar
yangguo committed
4584
  const int nopos = kNoSourcePosition;
neis's avatar
neis committed
4585 4586

  // Forward definition for break/continue statements.
4587
  WhileStatement* loop = factory()->NewWhileStatement(nullptr, nopos);
neis's avatar
neis committed
4588 4589

  // let input = undefined;
4590
  Variable* var_input = NewTemporary(ast_value_factory()->empty_string());
neis's avatar
neis committed
4591 4592
  Statement* initialize_input;
  {
4593 4594 4595 4596 4597
    Expression* input_proxy = factory()->NewVariableProxy(var_input);
    Expression* assignment =
        factory()->NewAssignment(Token::ASSIGN, input_proxy,
                                 factory()->NewUndefinedLiteral(nopos), nopos);
    initialize_input = factory()->NewExpressionStatement(assignment, nopos);
neis's avatar
neis committed
4598 4599 4600
  }

  // let mode = kNext;
4601
  Variable* var_mode = NewTemporary(ast_value_factory()->empty_string());
neis's avatar
neis committed
4602 4603
  Statement* initialize_mode;
  {
4604 4605 4606
    Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
    Expression* knext =
        factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos);
neis's avatar
neis committed
4607
    Expression* assignment =
4608 4609
        factory()->NewAssignment(Token::ASSIGN, mode_proxy, knext, nopos);
    initialize_mode = factory()->NewExpressionStatement(assignment, nopos);
neis's avatar
neis committed
4610 4611 4612
  }

  // let output = undefined;
4613
  Variable* var_output = NewTemporary(ast_value_factory()->empty_string());
neis's avatar
neis committed
4614 4615
  Statement* initialize_output;
  {
4616 4617 4618 4619 4620
    Expression* output_proxy = factory()->NewVariableProxy(var_output);
    Expression* assignment =
        factory()->NewAssignment(Token::ASSIGN, output_proxy,
                                 factory()->NewUndefinedLiteral(nopos), nopos);
    initialize_output = factory()->NewExpressionStatement(assignment, nopos);
neis's avatar
neis committed
4621 4622 4623
  }

  // let iterator = iterable[Symbol.iterator];
4624
  Variable* var_iterator = NewTemporary(ast_value_factory()->empty_string());
neis's avatar
neis committed
4625 4626
  Statement* get_iterator;
  {
4627
    Expression* iterator = GetIterator(iterable, nopos);
4628 4629
    Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator);
    Expression* assignment = factory()->NewAssignment(
neis's avatar
neis committed
4630
        Token::ASSIGN, iterator_proxy, iterator, nopos);
4631
    get_iterator = factory()->NewExpressionStatement(assignment, nopos);
neis's avatar
neis committed
4632 4633 4634 4635 4636 4637 4638
  }

  // if (!IS_RECEIVER(iterator)) throw MakeTypeError(kSymbolIteratorInvalid);
  Statement* validate_iterator;
  {
    Expression* is_receiver_call;
    {
4639 4640
      auto args = new (zone()) ZoneList<Expression*>(1, zone());
      args->Add(factory()->NewVariableProxy(var_iterator), zone());
neis's avatar
neis committed
4641
      is_receiver_call =
4642
          factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
neis's avatar
neis committed
4643 4644 4645 4646
    }

    Statement* throw_call;
    {
4647 4648 4649 4650
      Expression* call =
          NewThrowTypeError(MessageTemplate::kSymbolIteratorInvalid,
                            ast_value_factory()->empty_string(), nopos);
      throw_call = factory()->NewExpressionStatement(call, nopos);
neis's avatar
neis committed
4651 4652
    }

4653 4654 4655
    validate_iterator = factory()->NewIfStatement(
        is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
        nopos);
neis's avatar
neis committed
4656 4657 4658 4659 4660
  }

  // output = iterator.next(input);
  Statement* call_next;
  {
4661
    Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator);
neis's avatar
neis committed
4662
    Expression* literal =
4663
        factory()->NewStringLiteral(ast_value_factory()->next_string(), nopos);
neis's avatar
neis committed
4664
    Expression* next_property =
4665 4666 4667 4668 4669 4670
        factory()->NewProperty(iterator_proxy, literal, nopos);
    Expression* input_proxy = factory()->NewVariableProxy(var_input);
    auto args = new (zone()) ZoneList<Expression*>(1, zone());
    args->Add(input_proxy, zone());
    Expression* call = factory()->NewCall(next_property, args, nopos);
    Expression* output_proxy = factory()->NewVariableProxy(var_output);
neis's avatar
neis committed
4671
    Expression* assignment =
4672 4673
        factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
    call_next = factory()->NewExpressionStatement(assignment, nopos);
neis's avatar
neis committed
4674 4675 4676 4677 4678 4679 4680
  }

  // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
  Statement* validate_next_output;
  {
    Expression* is_receiver_call;
    {
4681 4682
      auto args = new (zone()) ZoneList<Expression*>(1, zone());
      args->Add(factory()->NewVariableProxy(var_output), zone());
neis's avatar
neis committed
4683
      is_receiver_call =
4684
          factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
neis's avatar
neis committed
4685 4686 4687 4688
    }

    Statement* throw_call;
    {
4689 4690 4691
      auto args = new (zone()) ZoneList<Expression*>(1, zone());
      args->Add(factory()->NewVariableProxy(var_output), zone());
      Expression* call = factory()->NewCallRuntime(
neis's avatar
neis committed
4692
          Runtime::kThrowIteratorResultNotAnObject, args, nopos);
4693
      throw_call = factory()->NewExpressionStatement(call, nopos);
neis's avatar
neis committed
4694 4695
    }

4696 4697 4698
    validate_next_output = factory()->NewIfStatement(
        is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
        nopos);
neis's avatar
neis committed
4699 4700 4701
  }

  // let iteratorThrow = iterator.throw;
4702
  Variable* var_throw = NewTemporary(ast_value_factory()->empty_string());
neis's avatar
neis committed
4703 4704
  Statement* get_throw;
  {
4705
    Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator);
neis's avatar
neis committed
4706
    Expression* literal =
4707
        factory()->NewStringLiteral(ast_value_factory()->throw_string(), nopos);
neis's avatar
neis committed
4708
    Expression* property =
4709 4710 4711 4712 4713
        factory()->NewProperty(iterator_proxy, literal, nopos);
    Expression* throw_proxy = factory()->NewVariableProxy(var_throw);
    Expression* assignment =
        factory()->NewAssignment(Token::ASSIGN, throw_proxy, property, nopos);
    get_throw = factory()->NewExpressionStatement(assignment, nopos);
neis's avatar
neis committed
4714 4715 4716 4717 4718 4719 4720 4721
  }

  // if (IS_NULL_OR_UNDEFINED(iteratorThrow) {
  //   IteratorClose(iterator);
  //   throw MakeTypeError(kThrowMethodMissing);
  // }
  Statement* check_throw;
  {
4722 4723 4724 4725 4726 4727 4728
    Expression* condition = factory()->NewCompareOperation(
        Token::EQ, factory()->NewVariableProxy(var_throw),
        factory()->NewNullLiteral(nopos), nopos);
    Expression* call =
        NewThrowTypeError(MessageTemplate::kThrowMethodMissing,
                          ast_value_factory()->empty_string(), nopos);
    Statement* throw_call = factory()->NewExpressionStatement(call, nopos);
neis's avatar
neis committed
4729

4730 4731
    Block* then = factory()->NewBlock(nullptr, 4 + 1, false, nopos);
    BuildIteratorCloseForCompletion(
4732
        then->statements(), var_iterator,
4733 4734 4735 4736
        factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos));
    then->statements()->Add(throw_call, zone());
    check_throw = factory()->NewIfStatement(
        condition, then, factory()->NewEmptyStatement(nopos), nopos);
neis's avatar
neis committed
4737 4738 4739 4740 4741
  }

  // output = %_Call(iteratorThrow, iterator, input);
  Statement* call_throw;
  {
4742 4743 4744 4745
    auto args = new (zone()) ZoneList<Expression*>(3, zone());
    args->Add(factory()->NewVariableProxy(var_throw), zone());
    args->Add(factory()->NewVariableProxy(var_iterator), zone());
    args->Add(factory()->NewVariableProxy(var_input), zone());
neis's avatar
neis committed
4746
    Expression* call =
4747 4748 4749 4750
        factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
    Expression* assignment = factory()->NewAssignment(
        Token::ASSIGN, factory()->NewVariableProxy(var_output), call, nopos);
    call_throw = factory()->NewExpressionStatement(assignment, nopos);
neis's avatar
neis committed
4751 4752 4753 4754 4755 4756 4757
  }

  // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
  Statement* validate_throw_output;
  {
    Expression* is_receiver_call;
    {
4758 4759
      auto args = new (zone()) ZoneList<Expression*>(1, zone());
      args->Add(factory()->NewVariableProxy(var_output), zone());
neis's avatar
neis committed
4760
      is_receiver_call =
4761
          factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
neis's avatar
neis committed
4762 4763 4764 4765
    }

    Statement* throw_call;
    {
4766 4767 4768
      auto args = new (zone()) ZoneList<Expression*>(1, zone());
      args->Add(factory()->NewVariableProxy(var_output), zone());
      Expression* call = factory()->NewCallRuntime(
neis's avatar
neis committed
4769
          Runtime::kThrowIteratorResultNotAnObject, args, nopos);
4770
      throw_call = factory()->NewExpressionStatement(call, nopos);
neis's avatar
neis committed
4771 4772
    }

4773 4774 4775
    validate_throw_output = factory()->NewIfStatement(
        is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
        nopos);
neis's avatar
neis committed
4776 4777 4778 4779 4780
  }

  // if (output.done) break;
  Statement* if_done;
  {
4781
    Expression* output_proxy = factory()->NewVariableProxy(var_output);
neis's avatar
neis committed
4782
    Expression* literal =
4783 4784 4785 4786 4787
        factory()->NewStringLiteral(ast_value_factory()->done_string(), nopos);
    Expression* property = factory()->NewProperty(output_proxy, literal, nopos);
    BreakStatement* break_loop = factory()->NewBreakStatement(loop, nopos);
    if_done = factory()->NewIfStatement(
        property, break_loop, factory()->NewEmptyStatement(nopos), nopos);
neis's avatar
neis committed
4788 4789 4790 4791 4792 4793
  }


  // mode = kReturn;
  Statement* set_mode_return;
  {
4794
    Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
4795
    Expression* kreturn =
4796
        factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos);
neis's avatar
neis committed
4797
    Expression* assignment =
4798 4799
        factory()->NewAssignment(Token::ASSIGN, mode_proxy, kreturn, nopos);
    set_mode_return = factory()->NewExpressionStatement(assignment, nopos);
neis's avatar
neis committed
4800 4801
  }

4802
  // Yield(output);
neis's avatar
neis committed
4803 4804
  Statement* yield_output;
  {
4805 4806 4807 4808
    Expression* output_proxy = factory()->NewVariableProxy(var_output);
    Yield* yield = factory()->NewYield(generator, output_proxy, nopos,
                                       Yield::kOnExceptionThrow);
    yield_output = factory()->NewExpressionStatement(yield, nopos);
neis's avatar
neis committed
4809 4810 4811 4812 4813
  }

  // mode = kNext;
  Statement* set_mode_next;
  {
4814 4815 4816
    Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
    Expression* knext =
        factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos);
neis's avatar
neis committed
4817
    Expression* assignment =
4818 4819
        factory()->NewAssignment(Token::ASSIGN, mode_proxy, knext, nopos);
    set_mode_next = factory()->NewExpressionStatement(assignment, nopos);
neis's avatar
neis committed
4820 4821 4822 4823 4824
  }

  // mode = kThrow;
  Statement* set_mode_throw;
  {
4825
    Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
4826
    Expression* kthrow =
4827
        factory()->NewSmiLiteral(JSGeneratorObject::kThrow, nopos);
neis's avatar
neis committed
4828
    Expression* assignment =
4829 4830
        factory()->NewAssignment(Token::ASSIGN, mode_proxy, kthrow, nopos);
    set_mode_throw = factory()->NewExpressionStatement(assignment, nopos);
neis's avatar
neis committed
4831 4832 4833 4834 4835
  }

  // input = function.sent;
  Statement* get_input;
  {
4836
    Expression* function_sent = FunctionSentExpression(nopos);
4837 4838
    Expression* input_proxy = factory()->NewVariableProxy(var_input);
    Expression* assignment = factory()->NewAssignment(
neis's avatar
neis committed
4839
        Token::ASSIGN, input_proxy, function_sent, nopos);
4840
    get_input = factory()->NewExpressionStatement(assignment, nopos);
neis's avatar
neis committed
4841 4842
  }

4843 4844 4845 4846 4847
  // if (mode === kReturn) {
  //   return {value: output.value, done: true};
  // }
  Statement* maybe_return_value;
  {
4848
    Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
4849
    Expression* kreturn =
4850 4851
        factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos);
    Expression* condition = factory()->NewCompareOperation(
4852 4853
        Token::EQ_STRICT, mode_proxy, kreturn, nopos);

4854
    Expression* output_proxy = factory()->NewVariableProxy(var_output);
4855
    Expression* literal =
4856 4857 4858 4859
        factory()->NewStringLiteral(ast_value_factory()->value_string(), nopos);
    Expression* property = factory()->NewProperty(output_proxy, literal, nopos);
    Statement* return_value = factory()->NewReturnStatement(
        BuildIteratorResult(property, true), nopos);
4860

4861 4862
    maybe_return_value = factory()->NewIfStatement(
        condition, return_value, factory()->NewEmptyStatement(nopos), nopos);
4863 4864 4865
  }

  // output.value
neis's avatar
neis committed
4866 4867
  Statement* get_value;
  {
4868
    Expression* output_proxy = factory()->NewVariableProxy(var_output);
neis's avatar
neis committed
4869
    Expression* literal =
4870 4871 4872
        factory()->NewStringLiteral(ast_value_factory()->value_string(), nopos);
    Expression* property = factory()->NewProperty(output_proxy, literal, nopos);
    get_value = factory()->NewExpressionStatement(property, nopos);
neis's avatar
neis committed
4873 4874 4875 4876 4877 4878 4879
  }

  // Now put things together.

  // try { ... } catch(e) { ... }
  Statement* try_catch;
  {
4880 4881 4882
    Block* try_block = factory()->NewBlock(nullptr, 2, false, nopos);
    try_block->statements()->Add(yield_output, zone());
    try_block->statements()->Add(set_mode_next, zone());
neis's avatar
neis committed
4883

4884 4885
    Block* catch_block = factory()->NewBlock(nullptr, 1, false, nopos);
    catch_block->statements()->Add(set_mode_throw, zone());
neis's avatar
neis committed
4886

4887
    Scope* catch_scope = NewScope(CATCH_SCOPE);
4888
    catch_scope->set_is_hidden();
4889
    const AstRawString* name = ast_value_factory()->dot_catch_string();
4890 4891
    Variable* catch_variable = catch_scope->DeclareLocal(
        name, VAR, kCreatedInitialized, NORMAL_VARIABLE);
neis's avatar
neis committed
4892

4893
    try_catch = factory()->NewTryCatchStatementForDesugaring(
neis's avatar
neis committed
4894 4895 4896 4897 4898 4899
        try_block, catch_scope, catch_variable, catch_block, nopos);
  }

  // try { ... } finally { ... }
  Statement* try_finally;
  {
4900 4901
    Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
    try_block->statements()->Add(try_catch, zone());
neis's avatar
neis committed
4902

4903 4904 4905 4906
    Block* finally = factory()->NewBlock(nullptr, 2, false, nopos);
    finally->statements()->Add(get_input, zone());
    finally->statements()->Add(factory()->NewContinueStatement(loop, nopos),
                               zone());
neis's avatar
neis committed
4907

4908
    try_finally = factory()->NewTryFinallyStatement(try_block, finally, nopos);
neis's avatar
neis committed
4909 4910 4911
  }

  // switch (mode) { ... }
4912
  SwitchStatement* switch_mode = factory()->NewSwitchStatement(nullptr, nopos);
neis's avatar
neis committed
4913
  {
4914 4915 4916 4917
    auto case_next = new (zone()) ZoneList<Statement*>(3, zone());
    case_next->Add(call_next, zone());
    case_next->Add(validate_next_output, zone());
    case_next->Add(factory()->NewBreakStatement(switch_mode, nopos), zone());
neis's avatar
neis committed
4918

4919
    auto case_return = new (zone()) ZoneList<Statement*>(5, zone());
4920
    BuildIteratorClose(case_return, var_iterator, var_input, var_output);
4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932
    case_return->Add(factory()->NewBreakStatement(switch_mode, nopos), zone());

    auto case_throw = new (zone()) ZoneList<Statement*>(5, zone());
    case_throw->Add(get_throw, zone());
    case_throw->Add(check_throw, zone());
    case_throw->Add(call_throw, zone());
    case_throw->Add(validate_throw_output, zone());
    case_throw->Add(factory()->NewBreakStatement(switch_mode, nopos), zone());

    auto cases = new (zone()) ZoneList<CaseClause*>(3, zone());
    Expression* knext =
        factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos);
4933
    Expression* kreturn =
4934
        factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos);
4935
    Expression* kthrow =
4936 4937 4938 4939
        factory()->NewSmiLiteral(JSGeneratorObject::kThrow, nopos);
    cases->Add(factory()->NewCaseClause(knext, case_next, nopos), zone());
    cases->Add(factory()->NewCaseClause(kreturn, case_return, nopos), zone());
    cases->Add(factory()->NewCaseClause(kthrow, case_throw, nopos), zone());
neis's avatar
neis committed
4940

4941
    switch_mode->Initialize(factory()->NewVariableProxy(var_mode), cases);
neis's avatar
neis committed
4942 4943 4944 4945 4946
  }

  // while (true) { ... }
  // Already defined earlier: WhileStatement* loop = ...
  {
4947 4948 4949 4950 4951
    Block* loop_body = factory()->NewBlock(nullptr, 4, false, nopos);
    loop_body->statements()->Add(switch_mode, zone());
    loop_body->statements()->Add(if_done, zone());
    loop_body->statements()->Add(set_mode_return, zone());
    loop_body->statements()->Add(try_finally, zone());
neis's avatar
neis committed
4952

4953
    loop->Initialize(factory()->NewBooleanLiteral(true, nopos), loop_body);
neis's avatar
neis committed
4954 4955 4956 4957 4958 4959 4960 4961
  }

  // do { ... }
  DoExpression* yield_star;
  {
    // The rewriter needs to process the get_value statement only, hence we
    // put the preceding statements into an init block.

4962 4963 4964 4965 4966 4967 4968 4969
    Block* do_block_ = factory()->NewBlock(nullptr, 7, true, nopos);
    do_block_->statements()->Add(initialize_input, zone());
    do_block_->statements()->Add(initialize_mode, zone());
    do_block_->statements()->Add(initialize_output, zone());
    do_block_->statements()->Add(get_iterator, zone());
    do_block_->statements()->Add(validate_iterator, zone());
    do_block_->statements()->Add(loop, zone());
    do_block_->statements()->Add(maybe_return_value, zone());
neis's avatar
neis committed
4970

4971 4972 4973
    Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos);
    do_block->statements()->Add(do_block_, zone());
    do_block->statements()->Add(get_value, zone());
neis's avatar
neis committed
4974

4975
    Variable* dot_result =
4976 4977 4978
        NewTemporary(ast_value_factory()->dot_result_string());
    yield_star = factory()->NewDoExpression(do_block, dot_result, nopos);
    Rewriter::Rewrite(this, GetClosureScope(), yield_star, ast_value_factory());
neis's avatar
neis committed
4979 4980 4981 4982 4983
  }

  return yield_star;
}

4984
Statement* Parser::CheckCallable(Variable* var, Expression* error, int pos) {
yangguo's avatar
yangguo committed
4985
  const int nopos = kNoSourcePosition;
4986 4987
  Statement* validate_var;
  {
4988 4989 4990 4991 4992
    Expression* type_of = factory()->NewUnaryOperation(
        Token::TYPEOF, factory()->NewVariableProxy(var), nopos);
    Expression* function_literal = factory()->NewStringLiteral(
        ast_value_factory()->function_string(), nopos);
    Expression* condition = factory()->NewCompareOperation(
4993 4994
        Token::EQ_STRICT, type_of, function_literal, nopos);

4995
    Statement* throw_call = factory()->NewExpressionStatement(error, pos);
4996

4997 4998
    validate_var = factory()->NewIfStatement(
        condition, factory()->NewEmptyStatement(nopos), throw_call, nopos);
4999 5000 5001
  }
  return validate_var;
}
neis's avatar
neis committed
5002

5003 5004 5005
void Parser::BuildIteratorClose(ZoneList<Statement*>* statements,
                                Variable* iterator, Variable* input,
                                Variable* var_output) {
5006 5007 5008 5009 5010
  //
  // This function adds four statements to [statements], corresponding to the
  // following code:
  //
  //   let iteratorReturn = iterator.return;
neis's avatar
neis committed
5011 5012 5013 5014
  //   if (IS_NULL_OR_UNDEFINED(iteratorReturn) {
  //     return {value: input, done: true};
  //   }
  //   output = %_Call(iteratorReturn, iterator, input);
5015 5016 5017
  //   if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
  //

yangguo's avatar
yangguo committed
5018
  const int nopos = kNoSourcePosition;
neis's avatar
neis committed
5019 5020

  // let iteratorReturn = iterator.return;
5021
  Variable* var_return = var_output;  // Reusing the output variable.
neis's avatar
neis committed
5022 5023
  Statement* get_return;
  {
5024 5025 5026
    Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
    Expression* literal = factory()->NewStringLiteral(
        ast_value_factory()->return_string(), nopos);
neis's avatar
neis committed
5027
    Expression* property =
5028 5029 5030 5031 5032
        factory()->NewProperty(iterator_proxy, literal, nopos);
    Expression* return_proxy = factory()->NewVariableProxy(var_return);
    Expression* assignment =
        factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos);
    get_return = factory()->NewExpressionStatement(assignment, nopos);
neis's avatar
neis committed
5033 5034
  }

neis's avatar
neis committed
5035 5036 5037
  // if (IS_NULL_OR_UNDEFINED(iteratorReturn) {
  //   return {value: input, done: true};
  // }
neis's avatar
neis committed
5038 5039
  Statement* check_return;
  {
5040 5041 5042
    Expression* condition = factory()->NewCompareOperation(
        Token::EQ, factory()->NewVariableProxy(var_return),
        factory()->NewNullLiteral(nopos), nopos);
neis's avatar
neis committed
5043

5044
    Expression* value = factory()->NewVariableProxy(input);
5045

neis's avatar
neis committed
5046
    Statement* return_input =
5047
        factory()->NewReturnStatement(BuildIteratorResult(value, true), nopos);
neis's avatar
neis committed
5048

5049 5050
    check_return = factory()->NewIfStatement(
        condition, return_input, factory()->NewEmptyStatement(nopos), nopos);
neis's avatar
neis committed
5051 5052
  }

neis's avatar
neis committed
5053
  // output = %_Call(iteratorReturn, iterator, input);
neis's avatar
neis committed
5054 5055
  Statement* call_return;
  {
5056 5057 5058 5059
    auto args = new (zone()) ZoneList<Expression*>(3, zone());
    args->Add(factory()->NewVariableProxy(var_return), zone());
    args->Add(factory()->NewVariableProxy(iterator), zone());
    args->Add(factory()->NewVariableProxy(input), zone());
neis's avatar
neis committed
5060 5061

    Expression* call =
5062 5063 5064 5065 5066
        factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
    Expression* output_proxy = factory()->NewVariableProxy(var_output);
    Expression* assignment =
        factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
    call_return = factory()->NewExpressionStatement(assignment, nopos);
neis's avatar
neis committed
5067 5068
  }

5069
  // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output);
5070
  Statement* validate_output;
neis's avatar
neis committed
5071 5072 5073
  {
    Expression* is_receiver_call;
    {
5074 5075
      auto args = new (zone()) ZoneList<Expression*>(1, zone());
      args->Add(factory()->NewVariableProxy(var_output), zone());
neis's avatar
neis committed
5076
      is_receiver_call =
5077
          factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
neis's avatar
neis committed
5078 5079 5080 5081
    }

    Statement* throw_call;
    {
5082 5083 5084
      auto args = new (zone()) ZoneList<Expression*>(1, zone());
      args->Add(factory()->NewVariableProxy(var_output), zone());
      Expression* call = factory()->NewCallRuntime(
neis's avatar
neis committed
5085
          Runtime::kThrowIteratorResultNotAnObject, args, nopos);
5086
      throw_call = factory()->NewExpressionStatement(call, nopos);
neis's avatar
neis committed
5087 5088
    }

5089 5090 5091
    validate_output = factory()->NewIfStatement(
        is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
        nopos);
neis's avatar
neis committed
5092 5093
  }

5094 5095 5096 5097
  statements->Add(get_return, zone());
  statements->Add(check_return, zone());
  statements->Add(call_return, zone());
  statements->Add(validate_output, zone());
neis's avatar
neis committed
5098 5099
}

5100 5101 5102
void Parser::FinalizeIteratorUse(Variable* completion, Expression* condition,
                                 Variable* iter, Block* iterator_use,
                                 Block* target) {
5103 5104 5105 5106 5107 5108 5109 5110 5111 5112
  //
  // This function adds two statements to [target], corresponding to the
  // following code:
  //
  //   completion = kNormalCompletion;
  //   try {
  //     try {
  //       iterator_use
  //     } catch(e) {
  //       if (completion === kAbruptCompletion) completion = kThrowCompletion;
5113
  //       %ReThrow(e);
5114 5115 5116 5117 5118 5119 5120 5121
  //     }
  //   } finally {
  //     if (condition) {
  //       #BuildIteratorCloseForCompletion(iter, completion)
  //     }
  //   }
  //

yangguo's avatar
yangguo committed
5122
  const int nopos = kNoSourcePosition;
5123 5124 5125 5126

  // completion = kNormalCompletion;
  Statement* initialize_completion;
  {
5127 5128
    Expression* proxy = factory()->NewVariableProxy(completion);
    Expression* assignment = factory()->NewAssignment(
5129
        Token::ASSIGN, proxy,
5130 5131 5132
        factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
    initialize_completion =
        factory()->NewExpressionStatement(assignment, nopos);
5133 5134 5135 5136 5137
  }

  // if (completion === kAbruptCompletion) completion = kThrowCompletion;
  Statement* set_completion_throw;
  {
5138 5139 5140
    Expression* condition = factory()->NewCompareOperation(
        Token::EQ_STRICT, factory()->NewVariableProxy(completion),
        factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
5141

5142 5143
    Expression* proxy = factory()->NewVariableProxy(completion);
    Expression* assignment = factory()->NewAssignment(
5144
        Token::ASSIGN, proxy,
5145 5146 5147 5148
        factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos);
    Statement* statement = factory()->NewExpressionStatement(assignment, nopos);
    set_completion_throw = factory()->NewIfStatement(
        condition, statement, factory()->NewEmptyStatement(nopos), nopos);
5149 5150 5151 5152 5153 5154 5155
  }

  // if (condition) {
  //   #BuildIteratorCloseForCompletion(iter, completion)
  // }
  Block* maybe_close;
  {
5156 5157 5158
    Block* block = factory()->NewBlock(nullptr, 2, true, nopos);
    Expression* proxy = factory()->NewVariableProxy(completion);
    BuildIteratorCloseForCompletion(block->statements(), iter, proxy);
5159 5160
    DCHECK(block->statements()->length() == 2);

5161
    maybe_close = factory()->NewBlock(nullptr, 1, true, nopos);
5162
    maybe_close->statements()->Add(
5163 5164 5165
        factory()->NewIfStatement(condition, block,
                                  factory()->NewEmptyStatement(nopos), nopos),
        zone());
5166 5167 5168 5169 5170
  }

  // try { #try_block }
  // catch(e) {
  //   #set_completion_throw;
5171
  //   %ReThrow(e);
5172 5173 5174
  // }
  Statement* try_catch;
  {
5175
    Scope* catch_scope = NewScopeWithParent(scope(), CATCH_SCOPE);
5176
    Variable* catch_variable =
5177
        catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR,
5178
                                  kCreatedInitialized, NORMAL_VARIABLE);
5179
    catch_scope->set_is_hidden();
5180 5181

    Statement* rethrow;
5182 5183 5184 5185
    // We use %ReThrow rather than the ordinary throw because we want to
    // preserve the original exception message.  This is also why we create a
    // TryCatchStatementForReThrow below (which does not clear the pending
    // message), rather than a TryCatchStatement.
5186
    {
5187 5188 5189 5190
      auto args = new (zone()) ZoneList<Expression*>(1, zone());
      args->Add(factory()->NewVariableProxy(catch_variable), zone());
      rethrow = factory()->NewExpressionStatement(
          factory()->NewCallRuntime(Runtime::kReThrow, args, nopos), nopos);
5191 5192
    }

5193 5194 5195
    Block* catch_block = factory()->NewBlock(nullptr, 2, false, nopos);
    catch_block->statements()->Add(set_completion_throw, zone());
    catch_block->statements()->Add(rethrow, zone());
5196

5197
    try_catch = factory()->NewTryCatchStatementForReThrow(
5198 5199 5200 5201 5202 5203
        iterator_use, catch_scope, catch_variable, catch_block, nopos);
  }

  // try { #try_catch } finally { #maybe_close }
  Statement* try_finally;
  {
5204 5205
    Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
    try_block->statements()->Add(try_catch, zone());
5206 5207

    try_finally =
5208
        factory()->NewTryFinallyStatement(try_block, maybe_close, nopos);
5209 5210
  }

5211 5212
  target->statements()->Add(initialize_completion, zone());
  target->statements()->Add(try_finally, zone());
5213
}
5214

5215 5216 5217
void Parser::BuildIteratorCloseForCompletion(ZoneList<Statement*>* statements,
                                             Variable* iterator,
                                             Expression* completion) {
5218 5219 5220 5221 5222 5223
  //
  // This function adds two statements to [statements], corresponding to the
  // following code:
  //
  //   let iteratorReturn = iterator.return;
  //   if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
5224
  //     if (completion === kThrowCompletion) {
5225 5226 5227
  //       if (!IS_CALLABLE(iteratorReturn)) {
  //         throw MakeTypeError(kReturnMethodNotCallable);
  //       }
5228
  //       try { %_Call(iteratorReturn, iterator) } catch (_) { }
5229
  //     } else {
5230 5231 5232 5233
  //       let output = %_Call(iteratorReturn, iterator);
  //       if (!IS_RECEIVER(output)) {
  //         %ThrowIterResultNotAnObject(output);
  //       }
5234 5235 5236 5237
  //     }
  //   }
  //

yangguo's avatar
yangguo committed
5238
  const int nopos = kNoSourcePosition;
5239
  // let iteratorReturn = iterator.return;
5240
  Variable* var_return = NewTemporary(ast_value_factory()->empty_string());
5241 5242
  Statement* get_return;
  {
5243 5244 5245
    Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
    Expression* literal = factory()->NewStringLiteral(
        ast_value_factory()->return_string(), nopos);
5246
    Expression* property =
5247 5248 5249 5250 5251
        factory()->NewProperty(iterator_proxy, literal, nopos);
    Expression* return_proxy = factory()->NewVariableProxy(var_return);
    Expression* assignment =
        factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos);
    get_return = factory()->NewExpressionStatement(assignment, nopos);
5252 5253 5254 5255 5256 5257 5258
  }

  // if (!IS_CALLABLE(iteratorReturn)) {
  //   throw MakeTypeError(kReturnMethodNotCallable);
  // }
  Statement* check_return_callable;
  {
5259 5260 5261
    Expression* throw_expr =
        NewThrowTypeError(MessageTemplate::kReturnMethodNotCallable,
                          ast_value_factory()->empty_string(), nopos);
5262
    check_return_callable = CheckCallable(var_return, throw_expr, nopos);
5263 5264
  }

5265
  // try { %_Call(iteratorReturn, iterator) } catch (_) { }
5266 5267
  Statement* try_call_return;
  {
5268 5269 5270
    auto args = new (zone()) ZoneList<Expression*>(2, zone());
    args->Add(factory()->NewVariableProxy(var_return), zone());
    args->Add(factory()->NewVariableProxy(iterator), zone());
5271 5272

    Expression* call =
5273
        factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
5274

5275 5276 5277
    Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
    try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos),
                                 zone());
5278

5279
    Block* catch_block = factory()->NewBlock(nullptr, 0, false, nopos);
5280

5281
    Scope* catch_scope = NewScope(CATCH_SCOPE);
5282 5283
    Variable* catch_variable =
        catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR,
5284
                                  kCreatedInitialized, NORMAL_VARIABLE);
5285
    catch_scope->set_is_hidden();
5286

5287
    try_call_return = factory()->NewTryCatchStatement(
5288 5289 5290
        try_block, catch_scope, catch_variable, catch_block, nopos);
  }

5291 5292 5293
  // let output = %_Call(iteratorReturn, iterator);
  // if (!IS_RECEIVER(output)) {
  //   %ThrowIteratorResultNotAnObject(output);
5294
  // }
5295
  Block* validate_return;
5296
  {
5297
    Variable* var_output = NewTemporary(ast_value_factory()->empty_string());
5298 5299
    Statement* call_return;
    {
5300 5301 5302
      auto args = new (zone()) ZoneList<Expression*>(2, zone());
      args->Add(factory()->NewVariableProxy(var_return), zone());
      args->Add(factory()->NewVariableProxy(iterator), zone());
5303
      Expression* call =
5304
          factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
5305

5306
      Expression* output_proxy = factory()->NewVariableProxy(var_output);
5307
      Expression* assignment =
5308 5309
          factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
      call_return = factory()->NewExpressionStatement(assignment, nopos);
5310
    }
5311 5312 5313

    Expression* is_receiver_call;
    {
5314 5315
      auto args = new (zone()) ZoneList<Expression*>(1, zone());
      args->Add(factory()->NewVariableProxy(var_output), zone());
5316
      is_receiver_call =
5317
          factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
5318 5319 5320 5321
    }

    Statement* throw_call;
    {
5322 5323 5324
      auto args = new (zone()) ZoneList<Expression*>(1, zone());
      args->Add(factory()->NewVariableProxy(var_output), zone());
      Expression* call = factory()->NewCallRuntime(
5325
          Runtime::kThrowIteratorResultNotAnObject, args, nopos);
5326
      throw_call = factory()->NewExpressionStatement(call, nopos);
5327 5328
    }

5329 5330 5331
    Statement* check_return = factory()->NewIfStatement(
        is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
        nopos);
5332

5333 5334 5335
    validate_return = factory()->NewBlock(nullptr, 2, false, nopos);
    validate_return->statements()->Add(call_return, zone());
    validate_return->statements()->Add(check_return, zone());
5336 5337
  }

5338
  // if (completion === kThrowCompletion) {
5339 5340 5341 5342 5343 5344 5345
  //   #check_return_callable;
  //   #try_call_return;
  // } else {
  //   #validate_return;
  // }
  Statement* call_return_carefully;
  {
5346
    Expression* condition = factory()->NewCompareOperation(
5347
        Token::EQ_STRICT, completion,
5348
        factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos);
5349

5350 5351 5352
    Block* then_block = factory()->NewBlock(nullptr, 2, false, nopos);
    then_block->statements()->Add(check_return_callable, zone());
    then_block->statements()->Add(try_call_return, zone());
5353

5354 5355
    call_return_carefully = factory()->NewIfStatement(condition, then_block,
                                                      validate_return, nopos);
5356 5357 5358 5359 5360
  }

  // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... }
  Statement* maybe_call_return;
  {
5361 5362 5363
    Expression* condition = factory()->NewCompareOperation(
        Token::EQ, factory()->NewVariableProxy(var_return),
        factory()->NewNullLiteral(nopos), nopos);
5364

5365 5366 5367
    maybe_call_return = factory()->NewIfStatement(
        condition, factory()->NewEmptyStatement(nopos), call_return_carefully,
        nopos);
5368 5369
  }

5370 5371
  statements->Add(get_return, zone());
  statements->Add(maybe_call_return, zone());
5372 5373
}

5374 5375
Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop,
                                          Variable* var_completion, int pos) {
5376 5377 5378
  //
  // This function replaces the loop with the following wrapping:
  //
5379
  //   completion = kNormalCompletion;
5380
  //   try {
5381 5382 5383 5384
  //     try {
  //       #loop;
  //     } catch(e) {
  //       if (completion === kAbruptCompletion) completion = kThrowCompletion;
5385
  //       %ReThrow(e);
5386
  //     }
5387
  //   } finally {
5388
  //     if (!(completion === kNormalCompletion || IS_UNDEFINED(#iterator))) {
5389
  //       #BuildIteratorCloseForCompletion(#iterator, completion)
5390 5391 5392
  //     }
  //   }
  //
5393 5394
  // Note that the loop's body and its assign_each already contain appropriate
  // assignments to completion (see InitializeForOfStatement).
5395
  //
5396

yangguo's avatar
yangguo committed
5397
  const int nopos = kNoSourcePosition;
5398

5399 5400
  // !(completion === kNormalCompletion || IS_UNDEFINED(#iterator))
  Expression* closing_condition;
5401
  {
5402 5403 5404 5405 5406 5407 5408 5409
    Expression* lhs = factory()->NewCompareOperation(
        Token::EQ_STRICT, factory()->NewVariableProxy(var_completion),
        factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
    Expression* rhs = factory()->NewCompareOperation(
        Token::EQ_STRICT, factory()->NewVariableProxy(loop->iterator()),
        factory()->NewUndefinedLiteral(nopos), nopos);
    closing_condition = factory()->NewUnaryOperation(
        Token::NOT, factory()->NewBinaryOperation(Token::OR, lhs, rhs, nopos),
5410
        nopos);
5411 5412
  }

5413
  Block* final_loop = factory()->NewBlock(nullptr, 2, false, nopos);
5414
  {
5415 5416
    Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
    try_block->statements()->Add(loop, zone());
5417 5418

    FinalizeIteratorUse(var_completion, closing_condition, loop->iterator(),
5419
                        try_block, final_loop);
5420
  }
5421

5422 5423 5424
  return final_loop;
}

5425
#undef CHECK_OK
neis's avatar
neis committed
5426
#undef CHECK_OK_VOID
5427 5428
#undef CHECK_FAILED

5429 5430
}  // namespace internal
}  // namespace v8