parser.cc 128 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
#include <algorithm>
8 9
#include <memory>

10
#include "src/ast/ast-function-literal-id-reindexer.h"
11
#include "src/ast/ast-traversal-visitor.h"
12
#include "src/ast/ast.h"
13
#include "src/ast/source-range-ast-visitor.h"
14
#include "src/bailout-reason.h"
15
#include "src/base/ieee754.h"
16
#include "src/base/overflowing-math.h"
17
#include "src/base/platform/platform.h"
18
#include "src/char-predicates-inl.h"
19
#include "src/compiler-dispatcher/compiler-dispatcher.h"
20
#include "src/conversions-inl.h"
21
#include "src/log.h"
22
#include "src/message-template.h"
23
#include "src/objects/scope-info.h"
24
#include "src/parsing/expression-scope-reparenter.h"
25
#include "src/parsing/parse-info.h"
26
#include "src/parsing/rewriter.h"
27
#include "src/runtime/runtime.h"
28
#include "src/string-stream.h"
29
#include "src/tracing/trace-event.h"
30
#include "src/zone/zone-list-inl.h"
31

32 33
namespace v8 {
namespace internal {
34

35
FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name,
36 37
                                            bool call_super, int pos,
                                            int end_pos) {
38
  int expected_property_count = 0;
39
  const int parameter_count = 0;
40

41
  FunctionKind kind = call_super ? FunctionKind::kDefaultDerivedConstructor
42
                                 : FunctionKind::kDefaultBaseConstructor;
43
  DeclarationScope* function_scope = NewFunctionScope(kind);
44
  SetLanguageMode(function_scope, LanguageMode::kStrict);
45 46 47
  // Set start and end position to the same value
  function_scope->set_start_position(pos);
  function_scope->set_end_position(pos);
48
  ScopedPtrList<Statement> body(pointer_buffer());
49 50

  {
51
    FunctionState function_state(&function_state_, &scope_, function_scope);
52 53

    if (call_super) {
54
      // Create a SuperCallReference and handle in BytecodeGenerator.
55 56 57
      auto constructor_args_name = ast_value_factory()->empty_string();
      bool is_rest = true;
      bool is_optional = false;
58
      Variable* constructor_args = function_scope->DeclareParameter(
59
          constructor_args_name, VariableMode::kTemporary, is_optional, is_rest,
60
          ast_value_factory(), pos);
61

62 63 64 65 66
      Expression* call;
      {
        ScopedPtrList<Expression> args(pointer_buffer());
        Spread* spread_args = factory()->NewSpread(
            factory()->NewVariableProxy(constructor_args), pos, pos);
67

68 69 70 71 72
        args.Add(spread_args);
        Expression* super_call_ref = NewSuperCallReference(pos);
        call = factory()->NewCall(super_call_ref, args, pos);
      }
      body.Add(factory()->NewReturnStatement(call, pos));
73 74 75 76 77 78
    }

    expected_property_count = function_state.expected_property_count();
  }

  FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
79 80
      name, function_scope, body, expected_property_count, parameter_count,
      parameter_count, FunctionLiteral::kNoDuplicateParameters,
81
      FunctionLiteral::kAnonymousExpression, default_eager_compile_hint(), pos,
82
      true, GetNextFunctionLiteralId());
83 84 85
  return function_literal;
}

86 87 88 89
void Parser::ReportUnexpectedTokenAt(Scanner::Location location,
                                     Token::Value token,
                                     MessageTemplate message) {
  const char* arg = nullptr;
90 91
  switch (token) {
    case Token::EOS:
92
      message = MessageTemplate::kUnexpectedEOS;
93 94 95 96
      break;
    case Token::SMI:
    case Token::NUMBER:
    case Token::BIGINT:
97
      message = MessageTemplate::kUnexpectedTokenNumber;
98 99
      break;
    case Token::STRING:
100
      message = MessageTemplate::kUnexpectedTokenString;
101 102 103
      break;
    case Token::PRIVATE_NAME:
    case Token::IDENTIFIER:
104
      message = MessageTemplate::kUnexpectedTokenIdentifier;
105 106 107
      break;
    case Token::AWAIT:
    case Token::ENUM:
108
      message = MessageTemplate::kUnexpectedReserved;
109 110 111 112 113
      break;
    case Token::LET:
    case Token::STATIC:
    case Token::YIELD:
    case Token::FUTURE_STRICT_RESERVED_WORD:
114 115 116
      message = is_strict(language_mode())
                    ? MessageTemplate::kUnexpectedStrictReserved
                    : MessageTemplate::kUnexpectedTokenIdentifier;
117 118 119
      break;
    case Token::TEMPLATE_SPAN:
    case Token::TEMPLATE_TAIL:
120
      message = MessageTemplate::kUnexpectedTemplateString;
121 122 123
      break;
    case Token::ESCAPED_STRICT_RESERVED_WORD:
    case Token::ESCAPED_KEYWORD:
124
      message = MessageTemplate::kInvalidEscapedReservedWord;
125 126 127
      break;
    case Token::ILLEGAL:
      if (scanner()->has_error()) {
128 129
        message = scanner()->error();
        location = scanner()->error_location();
130
      } else {
131
        message = MessageTemplate::kInvalidOrUnexpectedToken;
132 133 134
      }
      break;
    case Token::REGEXP_LITERAL:
135
      message = MessageTemplate::kUnexpectedTokenRegExp;
136 137 138 139
      break;
    default:
      const char* name = Token::String(token);
      DCHECK_NOT_NULL(name);
140
      arg = name;
141 142
      break;
  }
143
  ReportMessageAt(location, message, arg);
144 145
}

146 147 148
// ----------------------------------------------------------------------------
// Implementation of Parser

149 150 151
bool Parser::ShortcutNumericLiteralBinaryExpression(Expression** x,
                                                    Expression* y,
                                                    Token::Value op, int pos) {
152 153 154
  if ((*x)->IsNumberLiteral() && y->IsNumberLiteral()) {
    double x_val = (*x)->AsLiteral()->AsNumber();
    double y_val = y->AsLiteral()->AsNumber();
155 156
    switch (op) {
      case Token::ADD:
157
        *x = factory()->NewNumberLiteral(x_val + y_val, pos);
158 159
        return true;
      case Token::SUB:
160
        *x = factory()->NewNumberLiteral(x_val - y_val, pos);
161 162
        return true;
      case Token::MUL:
163
        *x = factory()->NewNumberLiteral(x_val * y_val, pos);
164 165
        return true;
      case Token::DIV:
166
        *x = factory()->NewNumberLiteral(base::Divide(x_val, y_val), pos);
167 168 169
        return true;
      case Token::BIT_OR: {
        int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
170
        *x = factory()->NewNumberLiteral(value, pos);
171 172 173 174
        return true;
      }
      case Token::BIT_AND: {
        int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
175
        *x = factory()->NewNumberLiteral(value, pos);
176 177 178 179
        return true;
      }
      case Token::BIT_XOR: {
        int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
180
        *x = factory()->NewNumberLiteral(value, pos);
181 182 183
        return true;
      }
      case Token::SHL: {
184 185
        int value =
            base::ShlWithWraparound(DoubleToInt32(x_val), DoubleToInt32(y_val));
186
        *x = factory()->NewNumberLiteral(value, pos);
187 188 189
        return true;
      }
      case Token::SHR: {
190
        uint32_t shift = DoubleToInt32(y_val) & 0x1F;
191
        uint32_t value = DoubleToUint32(x_val) >> shift;
192
        *x = factory()->NewNumberLiteral(value, pos);
193 194 195
        return true;
      }
      case Token::SAR: {
196
        uint32_t shift = DoubleToInt32(y_val) & 0x1F;
197
        int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
198
        *x = factory()->NewNumberLiteral(value, pos);
199 200
        return true;
      }
201 202
      case Token::EXP:
        *x = factory()->NewNumberLiteral(base::ieee754::pow(x_val, y_val), pos);
203
        return true;
204 205 206 207 208 209 210
      default:
        break;
    }
  }
  return false;
}

211
bool Parser::CollapseNaryExpression(Expression** x, Expression* y,
212 213
                                    Token::Value op, int pos,
                                    const SourceRange& range) {
214
  // Filter out unsupported ops.
215
  if (!Token::IsBinaryOp(op) || op == Token::EXP) return false;
216 217 218 219 220 221 222 223

  // Convert *x into an nary operation with the given op, returning false if
  // this is not possible.
  NaryOperation* nary = nullptr;
  if ((*x)->IsBinaryOperation()) {
    BinaryOperation* binop = (*x)->AsBinaryOperation();
    if (binop->op() != op) return false;

224 225
    nary = factory()->NewNaryOperation(op, binop->left(), 2);
    nary->AddSubsequent(binop->right(), binop->position());
226
    ConvertBinaryToNaryOperationSourceRange(binop, nary);
227 228 229 230 231 232 233 234 235 236 237 238
    *x = nary;
  } else if ((*x)->IsNaryOperation()) {
    nary = (*x)->AsNaryOperation();
    if (nary->op() != op) return false;
  } else {
    return false;
  }

  // Append our current expression to the nary operation.
  // TODO(leszeks): Do some literal collapsing here if we're appending Smi or
  // String literals.
  nary->AddSubsequent(y, pos);
239
  nary->clear_parenthesized();
240 241
  AppendNaryOperationSourceRange(nary, range);

242 243 244
  return true;
}

245 246
Expression* Parser::BuildUnaryExpression(Expression* expression,
                                         Token::Value op, int pos) {
247
  DCHECK_NOT_NULL(expression);
248 249
  const Literal* literal = expression->AsLiteral();
  if (literal != nullptr) {
250 251
    if (op == Token::NOT) {
      // Convert the literal to a boolean condition and negate it.
252 253
      return factory()->NewBooleanLiteral(literal->ToBooleanIsFalse(), pos);
    } else if (literal->IsNumberLiteral()) {
254
      // Compute some expressions involving only number literals.
255
      double value = literal->AsNumber();
256 257 258 259
      switch (op) {
        case Token::ADD:
          return expression;
        case Token::SUB:
260
          return factory()->NewNumberLiteral(-value, pos);
261
        case Token::BIT_NOT:
262
          return factory()->NewNumberLiteral(~DoubleToInt32(value), pos);
263 264 265 266 267
        default:
          break;
      }
    }
  }
268
  return factory()->NewUnaryOperation(op, expression, pos);
269 270
}

271
Expression* Parser::NewThrowError(Runtime::FunctionId id,
272
                                  MessageTemplate message,
273
                                  const AstRawString* arg, int pos) {
274
  ScopedPtrList<Expression> args(pointer_buffer());
275 276
  args.Add(factory()->NewSmiLiteral(static_cast<int>(message), pos));
  args.Add(factory()->NewStringLiteral(arg, pos));
277 278
  CallRuntime* call_constructor = factory()->NewCallRuntime(id, args, pos);
  return factory()->NewThrow(call_constructor, pos);
279 280
}

281
Expression* Parser::NewSuperPropertyReference(int pos) {
282
  // this_function[home_object_symbol]
283 284
  VariableProxy* this_function_proxy =
      NewUnresolved(ast_value_factory()->this_function_string(), pos);
285 286
  Expression* home_object_symbol_literal = factory()->NewSymbolLiteral(
      AstSymbol::kHomeObjectSymbol, kNoSourcePosition);
287
  Expression* home_object = factory()->NewProperty(
288
      this_function_proxy, home_object_symbol_literal, pos);
289
  return factory()->NewSuperPropertyReference(home_object, pos);
290
}
291

292 293 294 295 296
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);
297 298
  return factory()->NewSuperCallReference(new_target_proxy, this_function_proxy,
                                          pos);
299 300
}

301
Expression* Parser::NewTargetExpression(int pos) {
302
  auto proxy = NewUnresolved(ast_value_factory()->new_target_string(), pos);
303 304
  proxy->set_is_new_target();
  return proxy;
305 306
}

307
Expression* Parser::ImportMetaExpression(int pos) {
308
  ScopedPtrList<Expression> args(pointer_buffer());
309 310
  return factory()->NewCallRuntime(Runtime::kInlineGetImportMetaObject, args,
                                   pos);
311 312
}

313
Expression* Parser::ExpressionFromLiteral(Token::Value token, int pos) {
314 315
  switch (token) {
    case Token::NULL_LITERAL:
316
      return factory()->NewNullLiteral(pos);
317
    case Token::TRUE_LITERAL:
318
      return factory()->NewBooleanLiteral(true, pos);
319
    case Token::FALSE_LITERAL:
320
      return factory()->NewBooleanLiteral(false, pos);
verwaest's avatar
verwaest committed
321
    case Token::SMI: {
heimbuef's avatar
heimbuef committed
322
      uint32_t value = scanner()->smi_value();
323
      return factory()->NewSmiLiteral(value, pos);
verwaest's avatar
verwaest committed
324
    }
325
    case Token::NUMBER: {
326
      double value = scanner()->DoubleValue();
327
      return factory()->NewNumberLiteral(value, pos);
328
    }
329 330
    case Token::BIGINT:
      return factory()->NewBigIntLiteral(
331
          AstBigInt(scanner()->CurrentLiteralAsCString(zone())), pos);
332
    case Token::STRING: {
333
      return factory()->NewStringLiteral(GetSymbol(), pos);
334
    }
335
    default:
336
      DCHECK(false);
337
  }
338
  return FailureExpression();
339 340
}

341
Expression* Parser::NewV8Intrinsic(const AstRawString* name,
342
                                   const ScopedPtrList<Expression>& args,
343
                                   int pos) {
344 345 346 347 348 349
  if (extension_ != nullptr) {
    // The extension structures are only accessible while parsing the
    // very first time, not when reparsing because of lazy compilation.
    GetClosureScope()->ForceEagerCompilation();
  }

350 351 352 353 354 355
  if (!name->is_one_byte()) {
    // There are no two-byte named intrinsics.
    ReportMessage(MessageTemplate::kNotDefined, name);
    return FailureExpression();
  }

356 357
  const Runtime::Function* function =
      Runtime::FunctionForName(name->raw_data(), name->length());
358 359 360 361

  if (function != nullptr) {
    // Check for possible name clash.
    DCHECK_EQ(Context::kNotFound,
362
              Context::IntrinsicIndexForName(name->raw_data(), name->length()));
363 364

    // Check that the expected number of arguments are being passed.
365
    if (function->nargs != -1 && function->nargs != args.length()) {
366
      ReportMessage(MessageTemplate::kRuntimeWrongNumArgs);
367
      return FailureExpression();
368 369 370 371 372
    }

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

373 374
  int context_index =
      Context::IntrinsicIndexForName(name->raw_data(), name->length());
375 376 377 378

  // Check that the function is defined.
  if (context_index == Context::kNotFound) {
    ReportMessage(MessageTemplate::kNotDefined, name);
379
    return FailureExpression();
380 381 382 383 384
  }

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

385
Parser::Parser(ParseInfo* info)
386
    : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(),
387
                         info->extension(), info->GetOrCreateAstValueFactory(),
388 389 390 391
                         info->pending_error_handler(),
                         info->runtime_call_stats(), info->logger(),
                         info->script().is_null() ? -1 : info->script()->id(),
                         info->is_module(), true),
392
      info_(info),
393
      scanner_(info->character_stream(), info->is_module()),
394
      preparser_zone_(info->zone()->allocator(), ZONE_NAME),
395
      reusable_preparser_(nullptr),
396
      mode_(PARSE_EAGERLY),  // Lazy mode must be set explicitly.
397
      source_range_map_(info->source_range_map()),
398
      target_stack_(nullptr),
399
      total_preparse_skipped_(0),
400
      consumed_preparse_data_(info->consumed_preparse_data()),
401
      preparse_data_buffer_(),
402
      parameters_end_pos_(info->parameters_end_pos()) {
403
  // Even though we were passed ParseInfo, we should not store it in
404
  // Parser - this makes sure that Isolate is not accidentally accessed via
405
  // ParseInfo during background parsing.
406
  DCHECK_NOT_NULL(info->character_stream());
407 408 409 410 411 412 413 414 415
  // 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
416
  // We also compile eagerly for kProduceExhaustiveCodeCache.
417
  bool can_compile_lazily = info->allow_lazy_compile() && !info->is_eager();
418 419 420 421

  set_default_eager_compile_hint(can_compile_lazily
                                     ? FunctionLiteral::kShouldLazyCompile
                                     : FunctionLiteral::kShouldEagerCompile);
422
  allow_lazy_ = info->allow_lazy_compile() && info->allow_lazy_parsing() &&
423 424
                info->extension() == nullptr && can_compile_lazily;
  set_allow_natives(info->allow_natives_syntax());
425 426 427 428 429 430 431
  set_allow_harmony_public_fields(info->allow_harmony_public_fields());
  set_allow_harmony_static_fields(info->allow_harmony_static_fields());
  set_allow_harmony_dynamic_import(info->allow_harmony_dynamic_import());
  set_allow_harmony_import_meta(info->allow_harmony_import_meta());
  set_allow_harmony_numeric_separator(info->allow_harmony_numeric_separator());
  set_allow_harmony_private_fields(info->allow_harmony_private_fields());
  set_allow_harmony_private_methods(info->allow_harmony_private_methods());
432 433 434 435
  for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
       ++feature) {
    use_counts_[feature] = 0;
  }
436 437
}

438 439 440
void Parser::InitializeEmptyScopeChain(ParseInfo* info) {
  DCHECK_NULL(original_scope_);
  DCHECK_NULL(info->script_scope());
441 442
  DeclarationScope* script_scope = NewScriptScope();
  info->set_script_scope(script_scope);
443 444 445 446 447
  original_scope_ = script_scope;
}

void Parser::DeserializeScopeChain(
    Isolate* isolate, ParseInfo* info,
448 449
    MaybeHandle<ScopeInfo> maybe_outer_scope_info,
    Scope::DeserializationMode mode) {
450
  InitializeEmptyScopeChain(info);
451 452
  Handle<ScopeInfo> outer_scope_info;
  if (maybe_outer_scope_info.ToHandle(&outer_scope_info)) {
Clemens Hammacher's avatar
Clemens Hammacher committed
453
    DCHECK_EQ(ThreadId::Current(), isolate->thread_id());
454 455
    original_scope_ = Scope::DeserializeScopeChain(
        isolate, zone(), *outer_scope_info, info->script_scope(),
456
        ast_value_factory(), mode);
457 458 459 460
    if (info->is_eval() || IsArrowFunction(info->function_kind())) {
      original_scope_->GetReceiverScope()->DeserializeReceiver(
          ast_value_factory());
    }
461 462
  }
}
463

464 465 466 467 468
namespace {

void MaybeResetCharacterStream(ParseInfo* info, FunctionLiteral* literal) {
  // Don't reset the character stream if there is an asm.js module since it will
  // be used again by the asm-parser.
469 470 471
  if (info->contains_asm_module()) {
    if (FLAG_stress_validate_asm) return;
    if (literal != nullptr && literal->scope()->ContainsAsmModule()) return;
472
  }
473
  info->ResetCharacterStream();
474 475
}

476 477 478 479 480 481 482 483 484
void MaybeProcessSourceRanges(ParseInfo* parse_info, Expression* root,
                              uintptr_t stack_limit_) {
  if (root != nullptr && parse_info->source_range_map() != nullptr) {
    SourceRangeAstVisitor visitor(stack_limit_, root,
                                  parse_info->source_range_map());
    visitor.Run();
  }
}

485 486
}  // namespace

487
FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
488 489
  // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
  // see comment for HistogramTimerScope class.
490

491 492 493
  // It's OK to use the Isolate & counters here, since this function is only
  // called in the main thread.
  DCHECK(parsing_on_main_thread_);
494
  RuntimeCallTimerScope runtime_timer(
495 496 497
      runtime_call_stats_, info->is_eval()
                               ? RuntimeCallCounterId::kParseEval
                               : RuntimeCallCounterId::kParseProgram);
498
  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram");
499
  base::ElapsedTimer timer;
500
  if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
501 502

  // Initialize parser state.
503 504
  DeserializeScopeChain(isolate, info, info->maybe_outer_scope_info(),
                        Scope::DeserializationMode::kIncludingVariables);
505

506
  scanner_.Initialize();
507
  if (FLAG_harmony_hashbang) {
508 509
    scanner_.SkipHashBang();
  }
510
  FunctionLiteral* result = DoParseProgram(isolate, info);
511
  MaybeResetCharacterStream(info, result);
512
  MaybeProcessSourceRanges(info, result, stack_limit_);
513

514
  HandleSourceURLComments(isolate, info->script());
515

516 517 518
  if (V8_UNLIKELY(FLAG_log_function_events) && result != nullptr) {
    double ms = timer.Elapsed().InMillisecondsF();
    const char* event_name = "parse-eval";
519
    Script script = *info->script();
520 521 522 523 524 525 526
    int start = -1;
    int end = -1;
    if (!info->is_eval()) {
      event_name = "parse-script";
      start = 0;
      end = String::cast(script->source())->length();
    }
527 528
    LOG(isolate,
        FunctionEvent(event_name, script->id(), ms, start, end, "", 0));
529
  }
530
  return result;
531 532
}

533
FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
534 535
  // Note that this function can be called from the main thread or from a
  // background thread. We should not access anything Isolate / heap dependent
536 537 538
  // via ParseInfo, and also not pass it forward. If not on the main thread
  // isolate will be nullptr.
  DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr);
539
  DCHECK_NULL(scope_);
540
  DCHECK_NULL(target_stack_);
541

542
  ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
543
  ResetFunctionLiteralId();
544 545
  DCHECK(info->function_literal_id() == kFunctionLiteralIdTopLevel ||
         info->function_literal_id() == kFunctionLiteralIdInvalid);
546

547
  FunctionLiteral* result = nullptr;
548
  {
549
    Scope* outer = original_scope_;
550
    DCHECK_NOT_NULL(outer);
551
    if (info->is_eval()) {
552
      outer = NewEvalScope(outer);
553
    } else if (parsing_module_) {
554 555
      DCHECK_EQ(outer, info->script_scope());
      outer = NewModuleScope(info->script_scope());
556
    }
wingo's avatar
wingo committed
557

558
    DeclarationScope* scope = outer->AsDeclarationScope();
wingo's avatar
wingo committed
559
    scope->set_start_position(0);
560

561
    FunctionState function_state(&function_state_, &scope_, scope);
562
    ScopedPtrList<Statement> body(pointer_buffer());
563
    int beg_pos = scanner()->location().beg_pos;
564
    if (parsing_module_) {
565
      DCHECK(info->is_module());
566 567 568 569
      // Declare the special module parameter.
      auto name = ast_value_factory()->empty_string();
      bool is_rest = false;
      bool is_optional = false;
570
      VariableMode mode = VariableMode::kVar;
571 572
      bool was_added;
      scope->DeclareLocal(name, mode, PARAMETER_VARIABLE, &was_added,
573
                          Variable::DefaultInitializationFlag(mode));
574
      DCHECK(was_added);
575
      auto var = scope->DeclareParameter(name, VariableMode::kVar, is_optional,
576
                                         is_rest, ast_value_factory(), beg_pos);
577 578
      var->AllocateTo(VariableLocation::PARAMETER, 0);

579
      PrepareGeneratorVariables();
580 581
      Expression* initial_yield =
          BuildInitialYield(kNoSourcePosition, kGeneratorFunction);
582 583
      body.Add(
          factory()->NewExpressionStatement(initial_yield, kNoSourcePosition));
584

585
      ParseModuleItemList(&body);
586 587
      if (!has_error() &&
          !module()->Validate(this->scope()->AsModuleScope(),
588 589 590
                              pending_error_handler(), zone())) {
        scanner()->set_parser_error();
      }
591
    } else if (info->is_wrapped_as_function()) {
592
      ParseWrapped(isolate, info, &body, scope, zone());
593
    } else {
594 595
      // Don't count the mode in the use counters--give the program a chance
      // to enable script-wide strict mode below.
596
      this->scope()->SetLanguageMode(info->language_mode());
597
      ParseStatementList(&body, Token::EOS);
598
    }
599

wingo's avatar
wingo committed
600 601
    // The parser will peek but not consume EOS.  Our scope logically goes all
    // the way to the EOS, though.
602
    scope->set_end_position(peek_position());
wingo's avatar
wingo committed
603

604 605
    if (is_strict(language_mode())) {
      CheckStrictOctalLiteral(beg_pos, end_position());
606
    }
607
    if (is_sloppy(language_mode())) {
608 609 610 611
      // 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.
612
      InsertSloppyBlockFunctionVarBindings(scope);
613
    }
614 615 616 617 618 619
    // Internalize the ast strings in the case of eval so we can check for
    // conflicting var declarations with outer scope-info-backed scopes.
    if (info->is_eval()) {
      DCHECK(parsing_on_main_thread_);
      info->ast_value_factory()->Internalize(isolate);
    }
620
    CheckConflictingVarDeclarations(scope);
621

622
    if (info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
623 624 625 626 627
      if (body.length() != 1 || !body.at(0)->IsExpressionStatement() ||
          !body.at(0)
               ->AsExpressionStatement()
               ->expression()
               ->IsFunctionLiteral()) {
628
        ReportMessage(MessageTemplate::kSingleFunctionLiteral);
629 630 631
      }
    }

632 633 634 635
    int parameter_count = parsing_module_ ? 1 : 0;
    result = factory()->NewScriptOrEvalFunctionLiteral(
        scope, body, function_state.expected_property_count(), parameter_count);
    result->set_suspend_count(function_state.suspend_count());
636 637
  }

638 639
  info->set_max_function_literal_id(GetLastFunctionLiteralId());

640
  // Make sure the target stack is empty.
641
  DCHECK_NULL(target_stack_);
642

643
  if (has_error()) return nullptr;
644 645 646
  return result;
}

647 648
ZonePtrList<const AstRawString>* Parser::PrepareWrappedArguments(
    Isolate* isolate, ParseInfo* info, Zone* zone) {
649
  DCHECK(parsing_on_main_thread_);
650 651
  DCHECK_NOT_NULL(isolate);
  Handle<FixedArray> arguments(info->script()->wrapped_arguments(), isolate);
652
  int arguments_length = arguments->length();
653 654
  ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
      new (zone) ZonePtrList<const AstRawString>(arguments_length, zone);
655 656
  for (int i = 0; i < arguments_length; i++) {
    const AstRawString* argument_string = ast_value_factory()->GetString(
657
        Handle<String>(String::cast(arguments->get(i)), isolate));
658 659 660 661 662
    arguments_for_wrapped_function->Add(argument_string, zone);
  }
  return arguments_for_wrapped_function;
}

663
void Parser::ParseWrapped(Isolate* isolate, ParseInfo* info,
664
                          ScopedPtrList<Statement>* body,
665
                          DeclarationScope* outer_scope, Zone* zone) {
666
  DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr);
667 668 669 670 671 672 673 674 675 676
  DCHECK(info->is_wrapped_as_function());
  ParsingModeScope parsing_mode(this, PARSE_EAGERLY);

  // Set function and block state for the outer eval scope.
  DCHECK(outer_scope->is_eval_scope());
  FunctionState function_state(&function_state_, &scope_, outer_scope);

  const AstRawString* function_name = nullptr;
  Scanner::Location location(0, 0);

677
  ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
678
      PrepareWrappedArguments(isolate, info, zone);
679 680 681 682

  FunctionLiteral* function_literal = ParseFunctionLiteral(
      function_name, location, kSkipFunctionNameCheck, kNormalFunction,
      kNoSourcePosition, FunctionLiteral::kWrapped, LanguageMode::kSloppy,
683
      arguments_for_wrapped_function);
684 685 686

  Statement* return_statement = factory()->NewReturnStatement(
      function_literal, kNoSourcePosition, kNoSourcePosition);
687
  body->Add(return_statement);
688 689
}

690 691
FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
                                       Handle<SharedFunctionInfo> shared_info) {
692 693 694
  // It's OK to use the Isolate & counters here, since this function is only
  // called in the main thread.
  DCHECK(parsing_on_main_thread_);
695
  RuntimeCallTimerScope runtime_timer(runtime_call_stats_,
696
                                      RuntimeCallCounterId::kParseFunction);
697
  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseFunction");
698
  base::ElapsedTimer timer;
699 700
  if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();

701 702
  DeserializeScopeChain(isolate, info, info->maybe_outer_scope_info(),
                        Scope::DeserializationMode::kIncludingVariables);
703
  DCHECK_EQ(factory()->zone(), info->zone());
704

705
  // Initialize parser state.
706
  Handle<String> name(shared_info->Name(), isolate);
707
  info->set_function_name(ast_value_factory()->GetString(name));
708
  scanner_.Initialize();
709

710 711
  FunctionLiteral* result =
      DoParseFunction(isolate, info, info->function_name());
712
  MaybeResetCharacterStream(info, result);
713
  MaybeProcessSourceRanges(info, result, stack_limit_);
714
  if (result != nullptr) {
715
    Handle<String> inferred_name(shared_info->inferred_name(), isolate);
716
    result->set_inferred_name(inferred_name);
717
  }
718

719
  if (V8_UNLIKELY(FLAG_log_function_events) && result != nullptr) {
720
    double ms = timer.Elapsed().InMillisecondsF();
721
    // We need to make sure that the debug-name is available.
722
    ast_value_factory()->Internalize(isolate);
723 724
    DeclarationScope* function_scope = result->scope();
    std::unique_ptr<char[]> function_name = result->GetDebugName();
725
    LOG(isolate,
726
        FunctionEvent("parse-function", info->script()->id(), ms,
727 728 729
                      function_scope->start_position(),
                      function_scope->end_position(), function_name.get(),
                      strlen(function_name.get())));
730 731
  }
  return result;
732 733
}

734
static FunctionLiteral::FunctionType ComputeFunctionType(ParseInfo* info) {
735 736 737
  if (info->is_wrapped_as_function()) {
    return FunctionLiteral::kWrapped;
  } else if (info->is_declaration()) {
738
    return FunctionLiteral::kDeclaration;
739
  } else if (info->is_named_expression()) {
740
    return FunctionLiteral::kNamedExpression;
741 742
  } else if (IsConciseMethod(info->function_kind()) ||
             IsAccessorFunction(info->function_kind())) {
743 744 745 746
    return FunctionLiteral::kAccessorOrMethod;
  }
  return FunctionLiteral::kAnonymousExpression;
}
747

748
FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
749
                                         const AstRawString* raw_name) {
750
  DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr);
751
  DCHECK_NOT_NULL(raw_name);
752
  DCHECK_NULL(scope_);
753
  DCHECK_NULL(target_stack_);
754

755
  DCHECK(ast_value_factory());
756
  fni_.PushEnclosingName(raw_name);
757

758 759 760 761
  ResetFunctionLiteralId();
  DCHECK_LT(0, info->function_literal_id());
  SkipFunctionLiterals(info->function_literal_id() - 1);

762
  ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
763 764

  // Place holder for the result.
765
  FunctionLiteral* result = nullptr;
766 767 768

  {
    // Parse the function literal.
769
    Scope* outer = original_scope_;
770
    DeclarationScope* outer_function = outer->GetClosureScope();
771
    DCHECK(outer);
772 773
    FunctionState function_state(&function_state_, &scope_, outer_function);
    BlockState block_state(&scope_, outer);
774
    DCHECK(is_sloppy(outer->language_mode()) ||
775
           is_strict(info->language_mode()));
776
    FunctionLiteral::FunctionType function_type = ComputeFunctionType(info);
777
    FunctionKind kind = info->function_kind();
778

779
    if (IsArrowFunction(kind)) {
780
      if (IsAsyncFunction(kind)) {
781
        DCHECK(!scanner()->HasLineTerminatorAfterNext());
782 783 784 785 786 787 788 789
        if (!Check(Token::ASYNC)) {
          CHECK(stack_overflow());
          return nullptr;
        }
        if (!(peek_any_identifier() || peek() == Token::LPAREN)) {
          CHECK(stack_overflow());
          return nullptr;
        }
790 791
      }

792
      // TODO(adamk): We should construct this scope from the ScopeInfo.
793
      DeclarationScope* scope = NewFunctionScope(kind);
794
      scope->set_has_checked_syntax(true);
795

796
      // This bit only needs to be explicitly set because we're
797
      // not passing the ScopeInfo to the Scope constructor.
798
      SetLanguageMode(scope, info->language_mode());
799

800
      scope->set_start_position(info->start_position());
801
      ParserFormalParameters formals(scope);
802
      {
803
        ParameterDeclarationParsingScope formals_scope(this);
804
        // Parsing patterns as variable reference expression creates
805
        // NewUnresolved references in current scope. Enter arrow function
806
        // scope for formal parameter parsing.
807
        BlockState block_state(&scope_, scope);
808 809
        if (Check(Token::LPAREN)) {
          // '(' StrictFormalParameters ')'
810
          ParseFormalParameterList(&formals);
811
          Expect(Token::RPAREN);
812 813
        } else {
          // BindingIdentifier
814
          ParameterParsingScope scope(impl(), &formals);
815
          ParseFormalParameter(&formals);
816
          DeclareFormalParameters(&formals);
817
        }
818
        formals.duplicate_loc = formals_scope.duplicate_location();
819 820
      }

821
      if (GetLastFunctionLiteralId() != info->function_literal_id() - 1) {
822
        if (has_error()) return nullptr;
823 824 825 826 827 828 829 830 831 832
        // If there were FunctionLiterals in the parameters, we need to
        // renumber them to shift down so the next function literal id for
        // the arrow function is the one requested.
        AstFunctionLiteralIdReindexer reindexer(
            stack_limit_,
            (info->function_literal_id() - 1) - GetLastFunctionLiteralId());
        for (auto p : formals.params) {
          if (p->pattern != nullptr) reindexer.Reindex(p->pattern);
          if (p->initializer() != nullptr) {
            reindexer.Reindex(p->initializer());
833 834
          }
        }
835 836 837
        ResetFunctionLiteralId();
        SkipFunctionLiterals(info->function_literal_id() - 1);
      }
838

839
      Expression* expression = ParseArrowFunctionLiteral(formals);
840 841 842 843 844 845 846 847 848 849 850
      // 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.
      if (scanner()->location().end_pos == info->end_position()) {
        // The pre-parser saw an arrow function here, so the full parser
        // must produce a FunctionLiteral.
        DCHECK(expression->IsFunctionLiteral());
        result = expression->AsFunctionLiteral();
851
      }
852
    } else if (IsDefaultConstructor(kind)) {
853
      DCHECK_EQ(scope(), outer);
854
      result = DefaultConstructor(raw_name, IsDerivedConstructor(kind),
855
                                  info->start_position(), info->end_position());
856
    } else {
857
      ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
858 859 860
          info->is_wrapped_as_function()
              ? PrepareWrappedArguments(isolate, info, zone())
              : nullptr;
861
      result = ParseFunctionLiteral(
862
          raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind,
863
          kNoSourcePosition, function_type, info->language_mode(),
864
          arguments_for_wrapped_function);
865 866
    }

867
    if (has_error()) return nullptr;
868 869
    result->set_requires_instance_members_initializer(
        info->requires_instance_members_initializer());
870 871
    if (info->is_oneshot_iife()) {
      result->mark_as_oneshot_iife();
872
    }
873 874 875
  }

  // Make sure the target stack is empty.
876
  DCHECK_NULL(target_stack_);
877 878
  DCHECK_IMPLIES(result,
                 info->function_literal_id() == result->function_literal_id());
879 880 881
  return result;
}

882
Statement* Parser::ParseModuleItem() {
883
  // ecma262/#prod-ModuleItem
884 885 886 887
  // ModuleItem :
  //    ImportDeclaration
  //    ExportDeclaration
  //    StatementListItem
888

889 890 891
  Token::Value next = peek();

  if (next == Token::EXPORT) {
892
    return ParseExportDeclaration();
893
  }
894

895 896 897 898 899 900
  if (next == Token::IMPORT) {
    // We must be careful not to parse a dynamic import expression as an import
    // declaration. Same for import.meta expressions.
    Token::Value peek_ahead = PeekAhead();
    if ((!allow_harmony_dynamic_import() || peek_ahead != Token::LPAREN) &&
        (!allow_harmony_import_meta() || peek_ahead != Token::PERIOD)) {
901
      ParseImportDeclaration();
902
      return factory()->EmptyStatement();
903
    }
904 905
  }

906
  return ParseStatementListItem();
907 908
}

909
void Parser::ParseModuleItemList(ScopedPtrList<Statement>* body) {
910
  // ecma262/#prod-Module
911 912 913
  // Module :
  //    ModuleBody?
  //
914
  // ecma262/#prod-ModuleItemList
915 916
  // ModuleBody :
  //    ModuleItem*
917

918
  DCHECK(scope()->is_module_scope());
919
  while (peek() != Token::EOS) {
920
    Statement* stat = ParseModuleItem();
921
    if (stat == nullptr) return;
922
    if (stat->IsEmptyStatement()) continue;
923
    body->Add(stat);
924 925 926
  }
}

927
const AstRawString* Parser::ParseModuleSpecifier() {
928 929
  // ModuleSpecifier :
  //    StringLiteral
930

931
  Expect(Token::STRING);
932
  return GetSymbol();
933 934
}

935
ZoneChunkList<Parser::ExportClauseData>* Parser::ParseExportClause(
936
    Scanner::Location* reserved_loc) {
937
  // ExportClause :
938
  //   '{' '}'
939 940
  //   '{' ExportsList '}'
  //   '{' ExportsList ',' '}'
941
  //
942 943 944
  // ExportsList :
  //   ExportSpecifier
  //   ExportsList ',' ExportSpecifier
945
  //
946
  // ExportSpecifier :
947 948
  //   IdentifierName
  //   IdentifierName 'as' IdentifierName
949 950
  ZoneChunkList<ExportClauseData>* export_data =
      new (zone()) ZoneChunkList<ExportClauseData>(zone());
951

952
  Expect(Token::LBRACE);
953

954 955 956 957 958
  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() &&
959 960
        !Token::IsValidIdentifier(name_tok, LanguageMode::kStrict, false,
                                  parsing_module_)) {
961 962
      *reserved_loc = scanner()->location();
    }
963
    const AstRawString* local_name = ParsePropertyName();
964
    const AstRawString* export_name = nullptr;
965
    Scanner::Location location = scanner()->location();
966
    if (CheckContextualKeyword(ast_value_factory()->as_string())) {
967
      export_name = ParsePropertyName();
968 969 970
      // 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;
971
    }
972
    if (export_name == nullptr) {
973 974
      export_name = local_name;
    }
975
    export_data->push_back({export_name, local_name, location});
976
    if (peek() == Token::RBRACE) break;
977 978 979 980
    if (V8_UNLIKELY(!Check(Token::COMMA))) {
      ReportUnexpectedToken(Next());
      break;
    }
981 982
  }

983
  Expect(Token::RBRACE);
984
  return export_data;
985 986
}

987
ZonePtrList<const Parser::NamedImport>* Parser::ParseNamedImports(int pos) {
988 989 990 991 992 993 994 995 996 997 998 999 1000
  // NamedImports :
  //   '{' '}'
  //   '{' ImportsList '}'
  //   '{' ImportsList ',' '}'
  //
  // ImportsList :
  //   ImportSpecifier
  //   ImportsList ',' ImportSpecifier
  //
  // ImportSpecifier :
  //   BindingIdentifier
  //   IdentifierName 'as' BindingIdentifier

1001
  Expect(Token::LBRACE);
1002

1003
  auto result = new (zone()) ZonePtrList<const NamedImport>(1, zone());
1004
  while (peek() != Token::RBRACE) {
1005
    const AstRawString* import_name = ParsePropertyName();
1006
    const AstRawString* local_name = import_name;
1007
    Scanner::Location location = scanner()->location();
1008 1009
    // In the presence of 'as', the left-side of the 'as' can
    // be any IdentifierName. But without 'as', it must be a valid
1010
    // BindingIdentifier.
1011
    if (CheckContextualKeyword(ast_value_factory()->as_string())) {
1012
      local_name = ParsePropertyName();
1013
    }
1014 1015 1016
    if (!Token::IsValidIdentifier(scanner()->current_token(),
                                  LanguageMode::kStrict, false,
                                  parsing_module_)) {
1017
      ReportMessage(MessageTemplate::kUnexpectedReserved);
1018
      return nullptr;
1019
    } else if (IsEvalOrArguments(local_name)) {
1020
      ReportMessage(MessageTemplate::kStrictEvalArguments);
1021
      return nullptr;
1022
    }
1023

1024 1025
    DeclareUnboundVariable(local_name, VariableMode::kConst,
                           kNeedsInitialization, position());
1026

1027 1028
    NamedImport* import =
        new (zone()) NamedImport(import_name, local_name, location);
1029 1030
    result->Add(import, zone());

1031
    if (peek() == Token::RBRACE) break;
1032
    Expect(Token::COMMA);
1033 1034
  }

1035
  Expect(Token::RBRACE);
1036
  return result;
1037 1038
}

1039
void Parser::ParseImportDeclaration() {
1040 1041 1042
  // ImportDeclaration :
  //   'import' ImportClause 'from' ModuleSpecifier ';'
  //   'import' ModuleSpecifier ';'
1043
  //
1044
  // ImportClause :
1045
  //   ImportedDefaultBinding
1046 1047 1048 1049 1050 1051 1052
  //   NameSpaceImport
  //   NamedImports
  //   ImportedDefaultBinding ',' NameSpaceImport
  //   ImportedDefaultBinding ',' NamedImports
  //
  // NameSpaceImport :
  //   '*' 'as' ImportedBinding
1053

1054
  int pos = peek_position();
1055
  Expect(Token::IMPORT);
1056 1057 1058 1059 1060

  Token::Value tok = peek();

  // 'import' ModuleSpecifier ';'
  if (tok == Token::STRING) {
1061
    Scanner::Location specifier_loc = scanner()->peek_location();
1062 1063
    const AstRawString* module_specifier = ParseModuleSpecifier();
    ExpectSemicolon();
1064
    module()->AddEmptyImport(module_specifier, specifier_loc);
neis's avatar
neis committed
1065
    return;
1066 1067 1068
  }

  // Parse ImportedDefaultBinding if present.
1069 1070
  const AstRawString* import_default_binding = nullptr;
  Scanner::Location import_default_binding_loc;
1071
  if (tok != Token::MUL && tok != Token::LBRACE) {
1072
    import_default_binding = ParseNonRestrictedIdentifier();
1073
    import_default_binding_loc = scanner()->location();
1074 1075
    DeclareUnboundVariable(import_default_binding, VariableMode::kConst,
                           kNeedsInitialization, pos);
1076 1077
  }

1078 1079 1080
  // Parse NameSpaceImport or NamedImports if present.
  const AstRawString* module_namespace_binding = nullptr;
  Scanner::Location module_namespace_binding_loc;
1081
  const ZonePtrList<const NamedImport>* named_imports = nullptr;
1082
  if (import_default_binding == nullptr || Check(Token::COMMA)) {
1083 1084 1085
    switch (peek()) {
      case Token::MUL: {
        Consume(Token::MUL);
1086
        ExpectContextualKeyword(ast_value_factory()->as_string());
1087
        module_namespace_binding = ParseNonRestrictedIdentifier();
1088
        module_namespace_binding_loc = scanner()->location();
1089 1090
        DeclareUnboundVariable(module_namespace_binding, VariableMode::kConst,
                               kCreatedInitialized, pos);
1091 1092
        break;
      }
1093

1094
      case Token::LBRACE:
1095
        named_imports = ParseNamedImports(pos);
1096 1097 1098 1099
        break;

      default:
        ReportUnexpectedToken(scanner()->current_token());
neis's avatar
neis committed
1100
        return;
1101
    }
1102 1103
  }

1104
  ExpectContextualKeyword(ast_value_factory()->from_string());
1105
  Scanner::Location specifier_loc = scanner()->peek_location();
1106 1107
  const AstRawString* module_specifier = ParseModuleSpecifier();
  ExpectSemicolon();
1108

1109 1110 1111
  // Now that we have all the information, we can make the appropriate
  // declarations.

1112 1113 1114 1115
  // 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?
1116

1117 1118
  if (module_namespace_binding != nullptr) {
    module()->AddStarImport(module_namespace_binding, module_specifier,
1119 1120
                            module_namespace_binding_loc, specifier_loc,
                            zone());
1121 1122
  }

1123
  if (import_default_binding != nullptr) {
1124 1125
    module()->AddImport(ast_value_factory()->default_string(),
                        import_default_binding, module_specifier,
1126
                        import_default_binding_loc, specifier_loc, zone());
1127
  }
1128

1129 1130
  if (named_imports != nullptr) {
    if (named_imports->length() == 0) {
1131
      module()->AddEmptyImport(module_specifier, specifier_loc);
1132
    } else {
1133
      for (const NamedImport* import : *named_imports) {
1134
        module()->AddImport(import->import_name, import->local_name,
1135 1136
                            module_specifier, import->location, specifier_loc,
                            zone());
1137
      }
1138
    }
1139
  }
1140 1141
}

1142
Statement* Parser::ParseExportDefault() {
1143
  //  Supports the following productions, starting after the 'default' token:
1144
  //    'export' 'default' HoistableDeclaration
1145 1146 1147
  //    'export' 'default' ClassDeclaration
  //    'export' 'default' AssignmentExpression[In] ';'

1148
  Expect(Token::DEFAULT);
1149 1150
  Scanner::Location default_loc = scanner()->location();

1151
  ZonePtrList<const AstRawString> local_names(1, zone());
1152
  Statement* result = nullptr;
1153
  switch (peek()) {
1154
    case Token::FUNCTION:
1155
      result = ParseHoistableDeclaration(&local_names, true);
1156 1157 1158
      break;

    case Token::CLASS:
1159
      Consume(Token::CLASS);
1160
      result = ParseClassDeclaration(&local_names, true);
1161 1162
      break;

1163
    case Token::ASYNC:
1164
      if (PeekAhead() == Token::FUNCTION &&
1165
          !scanner()->HasLineTerminatorAfterNext()) {
1166
        Consume(Token::ASYNC);
1167
        result = ParseAsyncFunctionDeclaration(&local_names, true);
1168 1169
        break;
      }
1170
      V8_FALLTHROUGH;
1171

1172
    default: {
1173
      int pos = position();
1174 1175
      AcceptINScope scope(this, true);
      Expression* value = ParseAssignmentExpression();
1176 1177 1178
      SetFunctionName(value, ast_value_factory()->default_string());

      const AstRawString* local_name =
1179
          ast_value_factory()->dot_default_string();
1180 1181
      local_names.Add(local_name, zone());

1182 1183
      // It's fine to declare this as VariableMode::kConst because the user has
      // no way of writing to it.
1184
      VariableProxy* proxy =
1185
          DeclareBoundVariable(local_name, VariableMode::kConst, pos);
1186
      proxy->var()->set_initializer_position(position());
1187 1188

      Assignment* assignment = factory()->NewAssignment(
1189
          Token::INIT, proxy, value, kNoSourcePosition);
1190 1191
      result = IgnoreCompletion(
          factory()->NewExpressionStatement(assignment, kNoSourcePosition));
1192

1193
      ExpectSemicolon();
1194 1195 1196 1197
      break;
    }
  }

1198 1199 1200 1201 1202 1203
  if (result != nullptr) {
    DCHECK_EQ(local_names.length(), 1);
    module()->AddExport(local_names.first(),
                        ast_value_factory()->default_string(), default_loc,
                        zone());
  }
1204 1205 1206 1207

  return result;
}

1208 1209 1210 1211 1212 1213 1214
const AstRawString* Parser::NextInternalNamespaceExportName() {
  const char* prefix = ".ns-export";
  std::string s(prefix);
  s.append(std::to_string(number_of_named_namespace_exports_++));
  return ast_value_factory()->GetOneByteString(s.c_str());
}

1215
void Parser::ParseExportStar() {
1216 1217 1218
  int pos = position();
  Consume(Token::MUL);

1219 1220
  if (!FLAG_harmony_namespace_exports ||
      !PeekContextualKeyword(ast_value_factory()->as_string())) {
1221 1222
    // 'export' '*' 'from' ModuleSpecifier ';'
    Scanner::Location loc = scanner()->location();
1223
    ExpectContextualKeyword(ast_value_factory()->from_string());
1224
    Scanner::Location specifier_loc = scanner()->peek_location();
1225 1226
    const AstRawString* module_specifier = ParseModuleSpecifier();
    ExpectSemicolon();
1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238
    module()->AddStarExport(module_specifier, loc, specifier_loc, zone());
    return;
  }
  if (!FLAG_harmony_namespace_exports) return;

  // 'export' '*' 'as' IdentifierName 'from' ModuleSpecifier ';'
  //
  // Desugaring:
  //   export * as x from "...";
  // ~>
  //   import * as .x from "..."; export {.x as x};

1239
  ExpectContextualKeyword(ast_value_factory()->as_string());
1240
  const AstRawString* export_name = ParsePropertyName();
1241 1242 1243
  Scanner::Location export_name_loc = scanner()->location();
  const AstRawString* local_name = NextInternalNamespaceExportName();
  Scanner::Location local_name_loc = Scanner::Location::invalid();
1244 1245
  DeclareUnboundVariable(local_name, VariableMode::kConst, kCreatedInitialized,
                         pos);
1246

1247
  ExpectContextualKeyword(ast_value_factory()->from_string());
1248
  Scanner::Location specifier_loc = scanner()->peek_location();
1249 1250
  const AstRawString* module_specifier = ParseModuleSpecifier();
  ExpectSemicolon();
1251 1252 1253 1254 1255 1256

  module()->AddStarImport(local_name, module_specifier, local_name_loc,
                          specifier_loc, zone());
  module()->AddExport(local_name, export_name, export_name_loc, zone());
}

1257
Statement* Parser::ParseExportDeclaration() {
1258
  // ExportDeclaration:
1259
  //    'export' '*' 'from' ModuleSpecifier ';'
1260
  //    'export' '*' 'as' IdentifierName 'from' ModuleSpecifier ';'
1261 1262 1263 1264
  //    'export' ExportClause ('from' ModuleSpecifier)? ';'
  //    'export' VariableStatement
  //    'export' Declaration
  //    'export' 'default' ... (handled in ParseExportDefault)
1265

1266
  Expect(Token::EXPORT);
1267
  Statement* result = nullptr;
1268
  ZonePtrList<const AstRawString> names(1, zone());
1269
  Scanner::Location loc = scanner()->peek_location();
1270
  switch (peek()) {
1271
    case Token::DEFAULT:
1272
      return ParseExportDefault();
1273

1274
    case Token::MUL:
1275
      ParseExportStar();
1276
      return factory()->EmptyStatement();
1277

1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290
    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();
1291
      ZoneChunkList<ExportClauseData>* export_data =
1292
          ParseExportClause(&reserved_loc);
1293
      const AstRawString* module_specifier = nullptr;
1294
      Scanner::Location specifier_loc;
1295
      if (CheckContextualKeyword(ast_value_factory()->from_string())) {
1296
        specifier_loc = scanner()->peek_location();
1297
        module_specifier = ParseModuleSpecifier();
1298 1299
      } else if (reserved_loc.IsValid()) {
        // No FromClause, so reserved words are invalid in ExportClause.
1300
        ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved);
1301
        return nullptr;
1302
      }
1303
      ExpectSemicolon();
1304
      if (module_specifier == nullptr) {
1305 1306 1307
        for (const ExportClauseData& data : *export_data) {
          module()->AddExport(data.local_name, data.export_name, data.location,
                              zone());
1308
        }
1309
      } else if (export_data->is_empty()) {
1310
        module()->AddEmptyImport(module_specifier, specifier_loc);
1311
      } else {
1312 1313 1314 1315
        for (const ExportClauseData& data : *export_data) {
          module()->AddExport(data.local_name, data.export_name,
                              module_specifier, data.location, specifier_loc,
                              zone());
1316 1317
        }
      }
1318
      return factory()->EmptyStatement();
1319
    }
1320

1321
    case Token::FUNCTION:
1322
      result = ParseHoistableDeclaration(&names, false);
1323 1324
      break;

arv@chromium.org's avatar
arv@chromium.org committed
1325
    case Token::CLASS:
1326
      Consume(Token::CLASS);
1327
      result = ParseClassDeclaration(&names, false);
arv@chromium.org's avatar
arv@chromium.org committed
1328 1329
      break;

1330 1331 1332
    case Token::VAR:
    case Token::LET:
    case Token::CONST:
1333
      result = ParseVariableStatement(kStatementListItem, &names);
1334 1335
      break;

1336
    case Token::ASYNC:
1337
      Consume(Token::ASYNC);
1338 1339
      if (peek() == Token::FUNCTION &&
          !scanner()->HasLineTerminatorBeforeNext()) {
1340
        result = ParseAsyncFunctionDeclaration(&names, false);
1341 1342 1343
        break;
      }
      V8_FALLTHROUGH;
1344

1345
    default:
1346
      ReportUnexpectedToken(scanner()->current_token());
1347
      return nullptr;
1348
  }
1349
  loc.end_pos = scanner()->location().end_pos;
1350

1351
  ModuleDescriptor* descriptor = module();
1352 1353
  for (const AstRawString* name : names) {
    descriptor->AddExport(name, name, loc, zone());
1354 1355 1356
  }

  return result;
1357 1358
}

1359 1360 1361 1362 1363 1364 1365 1366
void Parser::DeclareUnboundVariable(const AstRawString* name, VariableMode mode,
                                    InitializationFlag init, int pos) {
  bool was_added;
  Variable* var = DeclareVariable(name, NORMAL_VARIABLE, mode, init, scope(),
                                  &was_added, pos, end_position());
  // The variable will be added to the declarations list, but since we are not
  // binding it to anything, we can simply ignore it here.
  USE(var);
1367 1368
}

1369 1370
VariableProxy* Parser::DeclareBoundVariable(const AstRawString* name,
                                            VariableMode mode, int pos) {
1371
  DCHECK_NOT_NULL(name);
1372 1373
  VariableProxy* proxy =
      factory()->NewVariableProxy(name, NORMAL_VARIABLE, position());
1374
  bool was_added;
1375 1376 1377 1378
  Variable* var = DeclareVariable(name, NORMAL_VARIABLE, mode,
                                  Variable::DefaultInitializationFlag(mode),
                                  scope(), &was_added, pos, end_position());
  proxy->BindTo(var);
1379 1380 1381
  return proxy;
}

1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394
void Parser::DeclareAndBindVariable(VariableProxy* proxy, VariableKind kind,
                                    VariableMode mode, InitializationFlag init,
                                    Scope* scope, bool* was_added, int begin,
                                    int end) {
  Variable* var = DeclareVariable(proxy->raw_name(), kind, mode, init, scope,
                                  was_added, begin, end);
  proxy->BindTo(var);
}

Variable* Parser::DeclareVariable(const AstRawString* name, VariableKind kind,
                                  VariableMode mode, InitializationFlag init,
                                  Scope* scope, bool* was_added, int begin,
                                  int end) {
1395
  Declaration* declaration;
1396 1397
  if (mode == VariableMode::kVar && !scope->is_declaration_scope()) {
    DCHECK(scope->is_block_scope() || scope->is_with_scope());
1398
    declaration = factory()->NewNestedVariableDeclaration(scope, begin);
1399
  } else {
1400
    declaration = factory()->NewVariableDeclaration(begin);
1401
  }
1402 1403
  Declare(declaration, name, kind, mode, init, scope, was_added, begin, end);
  return declaration->var();
1404 1405
}

1406
void Parser::Declare(Declaration* declaration, const AstRawString* name,
1407
                     VariableKind variable_kind, VariableMode mode,
1408
                     InitializationFlag init, Scope* scope, bool* was_added,
1409
                     int var_begin_pos, int var_end_pos) {
1410
  bool local_ok = true;
marja's avatar
marja committed
1411
  bool sloppy_mode_block_scope_function_redefinition = false;
1412
  scope->DeclareVariable(
1413
      declaration, name, var_begin_pos, mode, variable_kind, init, was_added,
1414
      &sloppy_mode_block_scope_function_redefinition, &local_ok);
1415
  if (!local_ok) {
1416 1417 1418
    // 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.
1419 1420 1421
    Scanner::Location loc(var_begin_pos, var_end_pos != kNoSourcePosition
                                             ? var_end_pos
                                             : var_begin_pos + 1);
1422
    if (variable_kind == PARAMETER_VARIABLE) {
1423 1424
      ReportMessageAt(loc, MessageTemplate::kParamDupe);
    } else {
1425
      ReportMessageAt(loc, MessageTemplate::kVarRedeclaration,
1426
                      declaration->var()->raw_name());
1427
    }
1428
  } else if (sloppy_mode_block_scope_function_redefinition) {
marja's avatar
marja committed
1429 1430
    ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition];
  }
1431 1432
}

1433
Statement* Parser::BuildInitializationBlock(
1434
    DeclarationParsingResult* parsing_result) {
1435
  ScopedPtrList<Statement> statements(pointer_buffer());
1436
  for (const auto& declaration : parsing_result->declarations) {
1437
    if (!declaration.initializer) continue;
1438
    InitializeVariables(&statements, parsing_result->descriptor.kind,
1439
                        &declaration);
1440
  }
1441
  return factory()->NewBlock(true, statements);
1442 1443
}

1444
Statement* Parser::DeclareFunction(const AstRawString* variable_name,
1445
                                   FunctionLiteral* function, VariableMode mode,
1446
                                   VariableKind kind, int beg_pos, int end_pos,
1447
                                   ZonePtrList<const AstRawString>* names) {
1448 1449
  Declaration* declaration =
      factory()->NewFunctionDeclaration(function, beg_pos);
1450
  bool was_added;
1451 1452
  Declare(declaration, variable_name, kind, mode, kCreatedInitialized, scope(),
          &was_added, beg_pos);
1453
  if (info()->coverage_enabled()) {
1454 1455 1456 1457
    // Force the function to be allocated when collecting source coverage, so
    // that even dead functions get source coverage data.
    declaration->var()->set_is_used();
  }
1458
  if (names) names->Add(variable_name, zone());
1459 1460
  if (kind == SLOPPY_BLOCK_FUNCTION_VARIABLE) {
    Token::Value init = loop_nesting_depth() > 0 ? Token::ASSIGN : Token::INIT;
1461
    SloppyBlockFunctionStatement* statement =
1462 1463 1464
        factory()->NewSloppyBlockFunctionStatement(end_pos, declaration->var(),
                                                   init);
    GetDeclarationScope()->DeclareSloppyBlockFunction(statement);
1465
    return statement;
1466
  }
1467
  return factory()->EmptyStatement();
1468 1469
}

1470 1471
Statement* Parser::DeclareClass(const AstRawString* variable_name,
                                Expression* value,
1472
                                ZonePtrList<const AstRawString>* names,
1473
                                int class_token_pos, int end_pos) {
1474
  VariableProxy* proxy =
1475
      DeclareBoundVariable(variable_name, VariableMode::kLet, class_token_pos);
1476
  proxy->var()->set_initializer_position(end_pos);
1477 1478
  if (names) names->Add(variable_name, zone());

1479 1480
  Assignment* assignment =
      factory()->NewAssignment(Token::INIT, proxy, value, class_token_pos);
1481 1482
  return IgnoreCompletion(
      factory()->NewExpressionStatement(assignment, kNoSourcePosition));
1483 1484
}

1485
Statement* Parser::DeclareNative(const AstRawString* name, int pos) {
1486 1487 1488 1489 1490 1491 1492 1493 1494
  // 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.
1495
  VariableProxy* proxy = DeclareBoundVariable(name, VariableMode::kVar, pos);
1496 1497 1498
  NativeFunctionLiteral* lit =
      factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition);
  return factory()->NewExpressionStatement(
1499
      factory()->NewAssignment(Token::INIT, proxy, lit, kNoSourcePosition),
1500 1501 1502
      pos);
}

1503 1504
void Parser::DeclareLabel(ZonePtrList<const AstRawString>** labels,
                          ZonePtrList<const AstRawString>** own_labels,
1505
                          VariableProxy* var) {
1506
  DCHECK(IsIdentifier(var));
1507
  const AstRawString* label = var->raw_name();
1508

1509 1510 1511 1512 1513
  // 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.
1514
  if (ContainsLabel(*labels, label) || TargetStackContainsLabel(label)) {
1515
    ReportMessage(MessageTemplate::kLabelRedeclaration, label);
1516
    return;
1517
  }
1518 1519 1520 1521 1522 1523 1524 1525 1526 1527

  // Add {label} to both {labels} and {own_labels}.
  if (*labels == nullptr) {
    DCHECK_NULL(*own_labels);
    *labels = new (zone()) ZonePtrList<const AstRawString>(1, zone());
    *own_labels = new (zone()) ZonePtrList<const AstRawString>(1, zone());
  } else {
    if (*own_labels == nullptr) {
      *own_labels = new (zone()) ZonePtrList<const AstRawString>(1, zone());
    }
1528
  }
1529 1530 1531
  (*labels)->Add(label, zone());
  (*own_labels)->Add(label, zone());

1532 1533 1534
  // 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.
1535
  scope()->DeleteUnresolved(var);
1536 1537
}

1538
bool Parser::ContainsLabel(ZonePtrList<const AstRawString>* labels,
1539 1540 1541 1542 1543
                           const AstRawString* label) {
  DCHECK_NOT_NULL(label);
  if (labels != nullptr) {
    for (int i = labels->length(); i-- > 0;) {
      if (labels->at(i) == label) return true;
1544 1545
    }
  }
1546 1547 1548
  return false;
}

1549
Block* Parser::IgnoreCompletion(Statement* statement) {
1550
  Block* block = factory()->NewBlock(1, true);
1551 1552 1553 1554
  block->statements()->Add(statement, zone());
  return block;
}

1555
Expression* Parser::RewriteReturn(Expression* return_value, int pos) {
1556
  if (IsDerivedConstructor(function_state_->kind())) {
1557 1558
    // For subclass constructors we need to return this in case of undefined;
    // other primitive values trigger an exception in the ConstructStub.
1559 1560 1561 1562 1563
    //
    //   return expr;
    //
    // Is rewritten as:
    //
1564
    //   return (temp = expr) === undefined ? this : temp;
1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575

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

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

1576
    // is_undefined ? this : temp
1577 1578 1579
    // We don't need to call UseThis() since it's guaranteed to be called
    // for derived constructors after parsing the constructor in
    // ParseFunctionBody.
1580
    return_value =
1581
        factory()->NewConditional(is_undefined, factory()->ThisExpression(),
1582
                                  factory()->NewVariableProxy(temp), pos);
1583 1584 1585 1586
  }
  return return_value;
}

1587
Statement* Parser::RewriteSwitchStatement(SwitchStatement* switch_statement,
1588
                                          Scope* scope) {
1589 1590 1591 1592 1593 1594 1595 1596 1597
  // 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* }
  //   }
  // }
1598 1599 1600 1601
  DCHECK_NOT_NULL(scope);
  DCHECK(scope->is_block_scope());
  DCHECK_GE(switch_statement->position(), scope->start_position());
  DCHECK_LT(switch_statement->position(), scope->end_position());
1602

1603
  Block* switch_block = factory()->NewBlock(2, false);
1604

1605
  Expression* tag = switch_statement->tag();
1606
  Variable* tag_variable =
1607
      NewTemporary(ast_value_factory()->dot_switch_tag_string());
1608 1609 1610
  Assignment* tag_assign = factory()->NewAssignment(
      Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag,
      tag->position());
1611 1612 1613 1614
  // Wrap with IgnoreCompletion so the tag isn't returned as the completion
  // value, in case the switch statements don't have a value.
  Statement* tag_statement = IgnoreCompletion(
      factory()->NewExpressionStatement(tag_assign, kNoSourcePosition));
neis's avatar
neis committed
1615
  switch_block->statements()->Add(tag_statement, zone());
1616

1617
  switch_statement->set_tag(factory()->NewVariableProxy(tag_variable));
1618
  Block* cases_block = factory()->NewBlock(1, false);
1619 1620
  cases_block->statements()->Add(switch_statement, zone());
  cases_block->set_scope(scope);
neis's avatar
neis committed
1621
  switch_block->statements()->Add(cases_block, zone());
1622
  return switch_block;
1623 1624
}

1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640
void Parser::InitializeVariables(
    ScopedPtrList<Statement>* statements, VariableKind kind,
    const DeclarationParsingResult::Declaration* declaration) {
  if (has_error()) return;

  DCHECK_NOT_NULL(declaration->initializer);

  int pos = declaration->value_beg_pos;
  if (pos == kNoSourcePosition) {
    pos = declaration->initializer->position();
  }
  Assignment* assignment = factory()->NewAssignment(
      Token::INIT, declaration->pattern, declaration->initializer, pos);
  statements->Add(factory()->NewExpressionStatement(assignment, pos));
}

1641 1642 1643 1644
Block* Parser::RewriteCatchPattern(CatchInfo* catch_info) {
  DCHECK_NOT_NULL(catch_info->pattern);

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

1647
  ScopedPtrList<Statement> init_statements(pointer_buffer());
1648
  InitializeVariables(&init_statements, NORMAL_VARIABLE, &decl);
1649
  return factory()->NewBlock(true, init_statements);
1650
}
1651

1652
void Parser::ReportVarRedeclarationIn(const AstRawString* name, Scope* scope) {
1653
  for (Declaration* decl : *scope->declarations()) {
1654 1655
    if (decl->var()->raw_name() == name) {
      int position = decl->position();
1656 1657 1658
      Scanner::Location location =
          position == kNoSourcePosition
              ? Scanner::Location::invalid()
1659
              : Scanner::Location(position, position + name->length());
1660
      ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
1661
      return;
1662
    }
1663
  }
1664
  UNREACHABLE();
1665
}
1666

1667
Statement* Parser::RewriteTryStatement(Block* try_block, Block* catch_block,
1668
                                       const SourceRange& catch_range,
1669
                                       Block* finally_block,
1670
                                       const SourceRange& finally_range,
1671
                                       const CatchInfo& catch_info, int pos) {
1672
  // Simplify the AST nodes by converting:
1673
  //   'try B0 catch B1 finally B2'
1674
  // to:
1675
  //   'try { try B0 catch B1 } finally B2'
1676

1677
  if (catch_block != nullptr && finally_block != nullptr) {
1678
    // If we have both, create an inner try/catch.
1679
    TryCatchStatement* statement;
1680
    statement = factory()->NewTryCatchStatement(try_block, catch_info.scope,
1681 1682
                                                catch_block, kNoSourcePosition);
    RecordTryCatchStatementSourceRange(statement, catch_range);
1683

1684
    try_block = factory()->NewBlock(1, false);
neis's avatar
neis committed
1685
    try_block->statements()->Add(statement, zone());
1686
    catch_block = nullptr;  // Clear to indicate it's been handled.
1687 1688
  }

1689 1690
  if (catch_block != nullptr) {
    DCHECK_NULL(finally_block);
1691 1692 1693 1694
    TryCatchStatement* stmt = factory()->NewTryCatchStatement(
        try_block, catch_info.scope, catch_block, pos);
    RecordTryCatchStatementSourceRange(stmt, catch_range);
    return stmt;
1695
  } else {
1696
    DCHECK_NOT_NULL(finally_block);
1697 1698 1699 1700
    TryFinallyStatement* stmt =
        factory()->NewTryFinallyStatement(try_block, finally_block, pos);
    RecordTryFinallyStatementSourceRange(stmt, finally_range);
    return stmt;
1701 1702 1703
  }
}

1704
void Parser::ParseAndRewriteGeneratorFunctionBody(
1705
    int pos, FunctionKind kind, ScopedPtrList<Statement>* body) {
1706 1707
  // For ES6 Generators, we just prepend the initial yield.
  Expression* initial_yield = BuildInitialYield(pos, kind);
1708 1709
  body->Add(
      factory()->NewExpressionStatement(initial_yield, kNoSourcePosition));
1710
  ParseStatementList(body, Token::RBRACE);
1711 1712 1713
}

void Parser::ParseAndRewriteAsyncGeneratorFunctionBody(
1714
    int pos, FunctionKind kind, ScopedPtrList<Statement>* body) {
1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726
  // For ES2017 Async Generators, we produce:
  //
  // try {
  //   InitialYield;
  //   ...body...;
  //   return undefined; // See comment below
  // } catch (.catch) {
  //   %AsyncGeneratorReject(generator, .catch);
  // } finally {
  //   %_GeneratorClose(generator);
  // }
  //
1727 1728
  // - InitialYield yields the actual generator object.
  // - Any return statement inside the body will have its argument wrapped
1729
  //   in an iterator result object with a "done" property set to `true`.
1730 1731
  // - If the generator terminates for whatever reason, we must close it.
  //   Hence the finally clause.
1732 1733 1734
  // - BytecodeGenerator performs special handling for ReturnStatements in
  //   async generator functions, resolving the appropriate Promise with an
  //   "done" iterator result object containing a Promise-unwrapped value.
1735
  DCHECK(IsAsyncGeneratorFunction(kind));
1736

1737 1738 1739 1740 1741 1742
  Block* try_block;
  {
    ScopedPtrList<Statement> statements(pointer_buffer());
    Expression* initial_yield = BuildInitialYield(pos, kind);
    statements.Add(
        factory()->NewExpressionStatement(initial_yield, kNoSourcePosition));
1743
    ParseStatementList(&statements, Token::RBRACE);
1744

1745 1746 1747 1748 1749 1750 1751 1752 1753 1754
    // Don't create iterator result for async generators, as the resume methods
    // will create it.
    // TODO(leszeks): This will create another suspend point, which is
    // unnecessary if there is already an unconditional return in the body.
    Statement* final_return = BuildReturnStatement(
        factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
    statements.Add(final_return);

    try_block = factory()->NewBlock(false, statements);
  }
1755

1756
  // For AsyncGenerators, a top-level catch block will reject the Promise.
1757
  Scope* catch_scope = NewHiddenCatchScope();
1758

1759 1760 1761 1762 1763 1764
  Block* catch_block;
  {
    ScopedPtrList<Expression> reject_args(pointer_buffer());
    reject_args.Add(factory()->NewVariableProxy(
        function_state_->scope()->generator_object_var()));
    reject_args.Add(factory()->NewVariableProxy(catch_scope->catch_variable()));
1765

1766 1767 1768 1769 1770
    Expression* reject_call = factory()->NewCallRuntime(
        Runtime::kInlineAsyncGeneratorReject, reject_args, kNoSourcePosition);
    catch_block = IgnoreCompletion(
        factory()->NewReturnStatement(reject_call, kNoSourcePosition));
  }
1771

1772 1773 1774 1775 1776 1777 1778
  {
    ScopedPtrList<Statement> statements(pointer_buffer());
    TryStatement* try_catch = factory()->NewTryCatchStatementForAsyncAwait(
        try_block, catch_scope, catch_block, kNoSourcePosition);
    statements.Add(try_catch);
    try_block = factory()->NewBlock(false, statements);
  }
1779

1780 1781 1782 1783 1784 1785 1786 1787 1788
  Expression* close_call;
  {
    ScopedPtrList<Expression> close_args(pointer_buffer());
    VariableProxy* call_proxy = factory()->NewVariableProxy(
        function_state_->scope()->generator_object_var());
    close_args.Add(call_proxy);
    close_call = factory()->NewCallRuntime(Runtime::kInlineGeneratorClose,
                                           close_args, kNoSourcePosition);
  }
1789

1790 1791 1792 1793 1794 1795 1796
  Block* finally_block;
  {
    ScopedPtrList<Statement> statements(pointer_buffer());
    statements.Add(
        factory()->NewExpressionStatement(close_call, kNoSourcePosition));
    finally_block = factory()->NewBlock(false, statements);
  }
1797 1798

  body->Add(factory()->NewTryFinallyStatement(try_block, finally_block,
1799
                                              kNoSourcePosition));
1800 1801
}

1802 1803 1804 1805 1806 1807 1808
void Parser::DeclareFunctionNameVar(const AstRawString* function_name,
                                    FunctionLiteral::FunctionType function_type,
                                    DeclarationScope* function_scope) {
  if (function_type == FunctionLiteral::kNamedExpression &&
      function_scope->LookupLocal(function_name) == nullptr) {
    DCHECK_EQ(function_scope, scope());
    function_scope->DeclareFunctionVar(function_name);
1809 1810 1811
  }
}

1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831
// 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) &&
1832
      decl.initializer != nullptr && decl.pattern->IsVariableProxy()) {
1833 1834 1835
    ++use_counts_[v8::Isolate::kForInInitializer];
    const AstRawString* name = decl.pattern->AsVariableProxy()->raw_name();
    VariableProxy* single_var = NewUnresolved(name);
1836
    Block* init_block = factory()->NewBlock(2, true);
1837 1838 1839
    init_block->statements()->Add(
        factory()->NewExpressionStatement(
            factory()->NewAssignment(Token::ASSIGN, single_var,
1840
                                     decl.initializer, decl.value_beg_pos),
1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854
            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
//
//   {
1855 1856 1857
//     var temp;
//     for (temp in/of e) {
//       let/const/var x = temp;
1858 1859 1860 1861 1862 1863
//       b;
//     }
//     let x;  // for TDZ
//   }
void Parser::DesugarBindingInForEachStatement(ForInfo* for_info,
                                              Block** body_block,
1864
                                              Expression** each_variable) {
1865
  DCHECK_EQ(1, for_info->parsing_result.declarations.size());
1866 1867 1868
  DeclarationParsingResult::Declaration& decl =
      for_info->parsing_result.declarations[0];
  Variable* temp = NewTemporary(ast_value_factory()->dot_for_string());
1869
  ScopedPtrList<Statement> each_initialization_statements(pointer_buffer());
1870
  DCHECK_IMPLIES(!has_error(), decl.pattern != nullptr);
1871
  decl.initializer = factory()->NewVariableProxy(temp, for_info->position);
1872
  InitializeVariables(&each_initialization_statements, NORMAL_VARIABLE, &decl);
1873

1874
  *body_block = factory()->NewBlock(3, false);
1875 1876 1877
  (*body_block)
      ->statements()
      ->Add(factory()->NewBlock(true, each_initialization_statements), zone());
1878
  *each_variable = factory()->NewVariableProxy(temp, for_info->position);
1879 1880 1881 1882
}

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

1887
    init_block = factory()->NewBlock(1, false);
1888

1889
    for (const AstRawString* bound_name : for_info.bound_names) {
1890 1891 1892
      // TODO(adamk): This needs to be some sort of special
      // INTERNAL variable that's invisible to the debugger
      // but visible to everything else.
1893
      VariableProxy* tdz_proxy = DeclareBoundVariable(
1894
          bound_name, VariableMode::kLet, kNoSourcePosition);
1895
      tdz_proxy->var()->set_initializer_position(position());
1896 1897 1898 1899 1900
    }
  }
  return init_block;
}

rossberg's avatar
rossberg committed
1901
Statement* Parser::DesugarLexicalBindingsInForStatement(
1902
    ForStatement* loop, Statement* init, Expression* cond, Statement* next,
1903
    Statement* body, Scope* inner_scope, const ForInfo& for_info) {
1904 1905 1906 1907 1908
  // 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.
1909
  //
1910
  // We are given a for statement of the form
1911
  //
rossberg's avatar
rossberg committed
1912
  //  labels: for (let/const x = i; cond; next) body
1913
  //
1914 1915
  // and rewrite it as follows.  Here we write {{ ... }} for init-blocks, ie.,
  // blocks whose ignore_completion_value_ flag is set.
1916 1917
  //
  //  {
rossberg's avatar
rossberg committed
1918
  //    let/const x = i;
1919 1920
  //    temp_x = x;
  //    first = 1;
1921
  //    undefined;
1922
  //    outer: for (;;) {
1923 1924 1925 1926 1927 1928 1929 1930 1931
  //      let/const x = temp_x;
  //      {{ if (first == 1) {
  //           first = 0;
  //         } else {
  //           next;
  //         }
  //         flag = 1;
  //         if (!cond) break;
  //      }}
1932
  //      labels: for (; flag == 1; flag = 0, temp_x = x) {
1933
  //        body
1934
  //      }
1935 1936 1937
  //      {{ if (flag == 1)  // Body used break.
  //           break;
  //      }}
1938
  //    }
1939 1940
  //  }

1941
  DCHECK_GT(for_info.bound_names.length(), 0);
1942
  ScopedPtrList<Variable> temps(pointer_buffer());
1943

1944 1945
  Block* outer_block =
      factory()->NewBlock(for_info.bound_names.length() + 4, false);
1946

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

1950
  const AstRawString* temp_name = ast_value_factory()->dot_for_string();
1951

rossberg's avatar
rossberg committed
1952
  // For each lexical variable x:
1953
  //   make statement: temp_x = x.
1954 1955
  for (const AstRawString* bound_name : for_info.bound_names) {
    VariableProxy* proxy = NewUnresolved(bound_name);
1956
    Variable* temp = NewTemporary(temp_name);
1957
    VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
yangguo's avatar
yangguo committed
1958 1959 1960 1961
    Assignment* assignment = factory()->NewAssignment(Token::ASSIGN, temp_proxy,
                                                      proxy, kNoSourcePosition);
    Statement* assignment_statement =
        factory()->NewExpressionStatement(assignment, kNoSourcePosition);
neis's avatar
neis committed
1962
    outer_block->statements()->Add(assignment_statement, zone());
1963
    temps.Add(temp);
1964 1965
  }

1966
  Variable* first = nullptr;
1967 1968
  // Make statement: first = 1.
  if (next) {
1969
    first = NewTemporary(temp_name);
1970
    VariableProxy* first_proxy = factory()->NewVariableProxy(first);
yangguo's avatar
yangguo committed
1971
    Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
1972
    Assignment* assignment = factory()->NewAssignment(
yangguo's avatar
yangguo committed
1973
        Token::ASSIGN, first_proxy, const1, kNoSourcePosition);
1974
    Statement* assignment_statement =
yangguo's avatar
yangguo committed
1975
        factory()->NewExpressionStatement(assignment, kNoSourcePosition);
neis's avatar
neis committed
1976
    outer_block->statements()->Add(assignment_statement, zone());
1977 1978
  }

1979
  // make statement: undefined;
neis's avatar
neis committed
1980
  outer_block->statements()->Add(
1981
      factory()->NewExpressionStatement(
yangguo's avatar
yangguo committed
1982
          factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
1983 1984
      zone());

1985 1986 1987 1988 1989 1990
  // 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 =
1991
      factory()->NewForStatement(nullptr, nullptr, kNoSourcePosition);
neis's avatar
neis committed
1992
  outer_block->statements()->Add(outer_loop, zone());
1993
  outer_block->set_scope(scope());
1994

1995
  Block* inner_block = factory()->NewBlock(3, false);
1996
  {
1997
    BlockState block_state(&scope_, inner_scope);
1998

1999 2000
    Block* ignore_completion_block =
        factory()->NewBlock(for_info.bound_names.length() + 3, true);
2001
    ScopedPtrList<Variable> inner_vars(pointer_buffer());
2002 2003
    // For each let variable x:
    //    make statement: let/const x = temp_x.
2004
    for (int i = 0; i < for_info.bound_names.length(); i++) {
2005
      VariableProxy* proxy = DeclareBoundVariable(
2006
          for_info.bound_names[i], for_info.parsing_result.descriptor.mode,
2007
          kNoSourcePosition);
2008
      inner_vars.Add(proxy->var());
2009 2010
      VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
      Assignment* assignment = factory()->NewAssignment(
2011
          Token::INIT, proxy, temp_proxy, kNoSourcePosition);
2012
      Statement* assignment_statement =
yangguo's avatar
yangguo committed
2013
          factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2014
      int declaration_pos = for_info.parsing_result.descriptor.declaration_pos;
2015
      DCHECK_NE(declaration_pos, kNoSourcePosition);
2016
      proxy->var()->set_initializer_position(declaration_pos);
2017 2018
      ignore_completion_block->statements()->Add(assignment_statement, zone());
    }
2019

2020 2021 2022
    // Make statement: if (first == 1) { first = 0; } else { next; }
    if (next) {
      DCHECK(first);
2023
      Expression* compare = nullptr;
2024 2025
      // Make compare expression: first == 1.
      {
yangguo's avatar
yangguo committed
2026
        Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2027 2028
        VariableProxy* first_proxy = factory()->NewVariableProxy(first);
        compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1,
yangguo's avatar
yangguo committed
2029
                                                 kNoSourcePosition);
2030
      }
2031
      Statement* clear_first = nullptr;
2032 2033 2034
      // Make statement: first = 0.
      {
        VariableProxy* first_proxy = factory()->NewVariableProxy(first);
yangguo's avatar
yangguo committed
2035
        Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
2036
        Assignment* assignment = factory()->NewAssignment(
yangguo's avatar
yangguo committed
2037 2038 2039
            Token::ASSIGN, first_proxy, const0, kNoSourcePosition);
        clear_first =
            factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2040 2041
      }
      Statement* clear_first_or_next = factory()->NewIfStatement(
yangguo's avatar
yangguo committed
2042
          compare, clear_first, next, kNoSourcePosition);
2043
      ignore_completion_block->statements()->Add(clear_first_or_next, zone());
2044
    }
2045

2046
    Variable* flag = NewTemporary(temp_name);
2047
    // Make statement: flag = 1.
2048
    {
2049
      VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
yangguo's avatar
yangguo committed
2050
      Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2051
      Assignment* assignment = factory()->NewAssignment(
yangguo's avatar
yangguo committed
2052
          Token::ASSIGN, flag_proxy, const1, kNoSourcePosition);
2053
      Statement* assignment_statement =
yangguo's avatar
yangguo committed
2054
          factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2055
      ignore_completion_block->statements()->Add(assignment_statement, zone());
2056
    }
2057

2058 2059 2060
    // Make statement: if (!cond) break.
    if (cond) {
      Statement* stop =
yangguo's avatar
yangguo committed
2061
          factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
2062
      Statement* noop = factory()->EmptyStatement();
2063 2064 2065 2066
      ignore_completion_block->statements()->Add(
          factory()->NewIfStatement(cond, noop, stop, cond->position()),
          zone());
    }
2067

2068 2069
    inner_block->statements()->Add(ignore_completion_block, zone());
    // Make cond expression for main loop: flag == 1.
2070
    Expression* flag_cond = nullptr;
2071
    {
yangguo's avatar
yangguo committed
2072
      Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2073
      VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2074
      flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
yangguo's avatar
yangguo committed
2075
                                                 kNoSourcePosition);
2076
    }
2077

2078
    // Create chain of expressions "flag = 0, temp_x = x, ..."
2079
    Statement* compound_next_statement = nullptr;
2080
    {
2081
      Expression* compound_next = nullptr;
2082 2083 2084
      // Make expression: flag = 0.
      {
        VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
yangguo's avatar
yangguo committed
2085 2086 2087
        Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
        compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy,
                                                 const0, kNoSourcePosition);
2088
      }
2089

2090 2091
      // Make the comma-separated list of temp_x = x assignments.
      int inner_var_proxy_pos = scanner()->location().beg_pos;
2092
      for (int i = 0; i < for_info.bound_names.length(); i++) {
2093 2094 2095 2096
        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
2097
            Token::ASSIGN, temp_proxy, proxy, kNoSourcePosition);
2098
        compound_next = factory()->NewBinaryOperation(
yangguo's avatar
yangguo committed
2099
            Token::COMMA, compound_next, assignment, kNoSourcePosition);
2100
      }
2101

yangguo's avatar
yangguo committed
2102 2103
      compound_next_statement =
          factory()->NewExpressionStatement(compound_next, kNoSourcePosition);
2104
    }
2105

2106 2107 2108 2109
    // 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.
2110
    loop->Initialize(nullptr, flag_cond, compound_next_statement, body);
2111 2112 2113
    inner_block->statements()->Add(loop, zone());

    // Make statement: {{if (flag == 1) break;}}
2114
    {
2115
      Expression* compare = nullptr;
2116 2117
      // Make compare expresion: flag == 1.
      {
yangguo's avatar
yangguo committed
2118
        Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2119 2120
        VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
        compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
yangguo's avatar
yangguo committed
2121
                                                 kNoSourcePosition);
2122 2123
      }
      Statement* stop =
yangguo's avatar
yangguo committed
2124
          factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
2125
      Statement* empty = factory()->EmptyStatement();
yangguo's avatar
yangguo committed
2126 2127
      Statement* if_flag_break =
          factory()->NewIfStatement(compare, stop, empty, kNoSourcePosition);
2128
      inner_block->statements()->Add(IgnoreCompletion(if_flag_break), zone());
2129
    }
2130

2131 2132
    inner_block->set_scope(inner_scope);
  }
2133

2134
  outer_loop->Initialize(nullptr, nullptr, nullptr, inner_block);
2135

2136 2137 2138
  return outer_block;
}

2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149
void ParserFormalParameters::ValidateDuplicate(Parser* parser) const {
  if (has_duplicate()) {
    parser->ReportMessageAt(duplicate_loc, MessageTemplate::kParamDupe);
  }
}
void ParserFormalParameters::ValidateStrictMode(Parser* parser) const {
  if (strict_error_loc.IsValid()) {
    parser->ReportMessageAt(strict_error_loc, strict_error_message);
  }
}

2150
void Parser::AddArrowFunctionFormalParameters(
2151
    ParserFormalParameters* parameters, Expression* expr, int end_pos) {
2152
  // ArrowFunctionFormals ::
2153
  //    Nary(Token::COMMA, VariableProxy*, Tail)
2154 2155 2156 2157 2158 2159
  //    Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail)
  //    Tail
  // NonTailArrowFunctionFormals ::
  //    Binary(Token::COMMA, NonTailArrowFunctionFormals, VariableProxy)
  //    VariableProxy
  // Tail ::
2160
  //    VariableProxy
2161
  //    Spread(VariableProxy)
2162
  //
2163
  // We need to visit the parameters in left-to-right order
2164
  //
2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176

  // For the Nary case, we simply visit the parameters in a loop.
  if (expr->IsNaryOperation()) {
    NaryOperation* nary = expr->AsNaryOperation();
    // The classifier has already run, so we know that the expression is a valid
    // arrow function formals production.
    DCHECK_EQ(nary->op(), Token::COMMA);
    // Each op position is the end position of the *previous* expr, with the
    // second (i.e. first "subsequent") op position being the end position of
    // the first child expression.
    Expression* next = nary->first();
    for (size_t i = 0; i < nary->subsequent_length(); ++i) {
2177 2178
      AddArrowFunctionFormalParameters(parameters, next,
                                       nary->subsequent_op_position(i));
2179 2180
      next = nary->subsequent(i);
    }
2181
    AddArrowFunctionFormalParameters(parameters, next, end_pos);
2182 2183 2184 2185 2186
    return;
  }

  // For the binary case, we recurse on the left-hand side of binary comma
  // expressions.
2187 2188
  if (expr->IsBinaryOperation()) {
    BinaryOperation* binop = expr->AsBinaryOperation();
2189 2190 2191
    // The classifier has already run, so we know that the expression is a valid
    // arrow function formals production.
    DCHECK_EQ(binop->op(), Token::COMMA);
2192 2193
    Expression* left = binop->left();
    Expression* right = binop->right();
2194
    int comma_pos = binop->position();
2195
    AddArrowFunctionFormalParameters(parameters, left, comma_pos);
2196 2197 2198
    // LHS of comma expression should be unparenthesized.
    expr = right;
  }
2199

2200
  // Only the right-most expression may be a rest parameter.
2201
  DCHECK(!parameters->has_rest);
2202

2203
  bool is_rest = expr->IsSpread();
2204 2205 2206 2207
  if (is_rest) {
    expr = expr->AsSpread()->expression();
    parameters->has_rest = true;
  }
2208 2209
  DCHECK_IMPLIES(parameters->is_simple, !is_rest);
  DCHECK_IMPLIES(parameters->is_simple, expr->IsVariableProxy());
2210

2211
  Expression* initializer = nullptr;
2212
  if (expr->IsAssignment()) {
2213
    Assignment* assignment = expr->AsAssignment();
2214
    DCHECK(!assignment->IsCompoundAssignment());
2215 2216
    initializer = assignment->value();
    expr = assignment->target();
2217 2218
  }

2219
  AddFormalParameter(parameters, expr, initializer, end_pos, is_rest);
2220 2221
}

2222
void Parser::DeclareArrowFunctionFormalParameters(
2223
    ParserFormalParameters* parameters, Expression* expr,
2224
    const Scanner::Location& params_loc) {
2225
  if (expr->IsEmptyParentheses() || has_error()) return;
2226

2227
  AddArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos);
2228

2229
  if (parameters->arity > Code::kMaxArguments) {
2230
    ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
2231 2232 2233
    return;
  }

2234
  DeclareFormalParameters(parameters);
2235 2236
  DCHECK_IMPLIES(parameters->is_simple,
                 parameters->scope->has_simple_parameters());
2237 2238
}

2239
void Parser::PrepareGeneratorVariables() {
2240 2241 2242
  // Calling a generator returns a generator object.  That object is stored
  // in a temporary variable, a definition that is used by "yield"
  // expressions.
2243 2244
  function_state_->scope()->DeclareGeneratorObjectVar(
      ast_value_factory()->dot_generator_object_string());
2245
}
2246

2247
FunctionLiteral* Parser::ParseFunctionLiteral(
2248
    const AstRawString* function_name, Scanner::Location function_name_location,
2249 2250
    FunctionNameValidity function_name_validity, FunctionKind kind,
    int function_token_pos, FunctionLiteral::FunctionType function_type,
2251
    LanguageMode language_mode,
2252
    ZonePtrList<const AstRawString>* arguments_for_wrapped_function) {
2253 2254
  // Function ::
  //   '(' FormalParameterList? ')' '{' FunctionBody '}'
2255 2256 2257 2258 2259 2260
  //
  // Getter ::
  //   '(' ')' '{' FunctionBody '}'
  //
  // Setter ::
  //   '(' PropertySetParameterList ')' '{' FunctionBody '}'
2261

2262 2263 2264
  bool is_wrapped = function_type == FunctionLiteral::kWrapped;
  DCHECK_EQ(is_wrapped, arguments_for_wrapped_function != nullptr);

yangguo's avatar
yangguo committed
2265 2266
  int pos = function_token_pos == kNoSourcePosition ? peek_position()
                                                    : function_token_pos;
2267
  DCHECK_NE(kNoSourcePosition, pos);
2268

2269 2270 2271
  // 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.
2272
  bool should_infer_name = function_name == nullptr;
2273

2274 2275 2276 2277 2278 2279
  // We want a non-null handle as the function name by default. We will handle
  // the "function does not have a shared name" case later.
  if (should_infer_name) {
    function_name = ast_value_factory()->empty_string();
  }

2280
  FunctionLiteral::EagerCompileHint eager_compile_hint =
2281
      function_state_->next_function_is_likely_called() || is_wrapped
2282
          ? FunctionLiteral::kShouldEagerCompile
2283
          : default_eager_compile_hint();
2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300

  // 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.

2301 2302 2303
  // 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:
2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314
  // (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
2315 2316
  // immediately). bar can be parsed lazily, but we need to parse it in a mode
  // that tracks unresolved variables.
2317
  DCHECK_IMPLIES(parse_lazily(), info()->allow_lazy_compile());
2318
  DCHECK_IMPLIES(parse_lazily(), has_error() || allow_lazy_);
2319
  DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr);
2320

2321 2322
  const bool is_lazy =
      eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
2323
  const bool is_top_level = AllowsLazyParsingWithoutUnresolvedVariables();
2324
  const bool is_eager_top_level_function = !is_lazy && is_top_level;
2325 2326
  const bool is_lazy_top_level_function = is_lazy && is_top_level;
  const bool is_lazy_inner_function = is_lazy && !is_top_level;
2327

2328 2329 2330
  RuntimeCallTimerScope runtime_timer(
      runtime_call_stats_,
      parsing_on_main_thread_
2331 2332
          ? RuntimeCallCounterId::kParseFunctionLiteral
          : RuntimeCallCounterId::kParseBackgroundFunctionLiteral);
2333 2334
  base::ElapsedTimer timer;
  if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
2335

2336
  // Determine whether we can still lazy parse the inner function.
2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348
  // 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.
2349 2350 2351

  // Inner functions will be parsed using a temporary Zone. After parsing, we
  // will migrate unresolved variable into a Scope in the main Zone.
2352

2353
  const bool should_preparse_inner = parse_lazily() && is_lazy_inner_function;
2354

2355 2356 2357 2358 2359 2360 2361 2362
  // If parallel compile tasks are enabled, and the function is an eager
  // top level function, then we can pre-parse the function and parse / compile
  // in a parallel task on a worker thread.
  bool should_post_parallel_task =
      parse_lazily() && is_eager_top_level_function &&
      FLAG_parallel_compile_tasks && info()->parallel_tasks() &&
      scanner()->stream()->can_be_cloned_for_parallel_access();

2363
  // This may be modified later to reflect preparsing decision taken
2364 2365
  bool should_preparse = (parse_lazily() && is_lazy_top_level_function) ||
                         should_preparse_inner || should_post_parallel_task;
2366

2367
  ScopedPtrList<Statement> body(pointer_buffer());
2368
  int expected_property_count = 0;
2369
  int suspend_count = -1;
2370 2371 2372
  int num_parameters = -1;
  int function_length = -1;
  bool has_duplicate_parameters = false;
2373
  int function_literal_id = GetNextFunctionLiteralId();
2374
  ProducedPreparseData* produced_preparse_data = nullptr;
2375

2376
  // This Scope lives in the main zone. We'll migrate data into that zone later.
2377
  Zone* parse_zone = should_preparse ? &preparser_zone_ : zone();
2378
  DeclarationScope* scope = NewFunctionScope(kind, parse_zone);
2379
  SetLanguageMode(scope, language_mode);
2380
#ifdef DEBUG
2381
  scope->SetScopeName(function_name);
2382
#endif
2383

2384 2385 2386
  if (!is_wrapped && V8_UNLIKELY(!Check(Token::LPAREN))) {
    ReportUnexpectedToken(Next());
    return nullptr;
2387
  }
2388
  scope->set_start_position(position());
2389 2390 2391 2392 2393 2394

  // Eager or lazy parse? If is_lazy_top_level_function, we'll parse
  // 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.
2395
  bool did_preparse_successfully =
2396 2397 2398
      should_preparse &&
      SkipFunction(function_name, kind, function_type, scope, &num_parameters,
                   &function_length, &produced_preparse_data);
2399

2400
  if (!did_preparse_successfully) {
2401 2402 2403
    // If skipping aborted, it rewound the scanner until before the LPAREN.
    // Consume it in that case.
    if (should_preparse) Consume(Token::LPAREN);
2404
    should_post_parallel_task = false;
2405 2406 2407 2408
    ParseFunction(&body, function_name, pos, kind, function_type, scope,
                  &num_parameters, &function_length, &has_duplicate_parameters,
                  &expected_property_count, &suspend_count,
                  arguments_for_wrapped_function);
2409
  }
2410

2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422
  if (V8_UNLIKELY(FLAG_log_function_events)) {
    double ms = timer.Elapsed().InMillisecondsF();
    const char* event_name =
        should_preparse
            ? (is_top_level ? "preparse-no-resolution" : "preparse-resolution")
            : "full-parse";
    logger_->FunctionEvent(
        event_name, script_id(), ms, scope->start_position(),
        scope->end_position(),
        reinterpret_cast<const char*>(function_name->raw_data()),
        function_name->byte_length());
  }
2423 2424
  if (V8_UNLIKELY(TracingFlags::is_runtime_stats_enabled()) &&
      did_preparse_successfully) {
2425 2426 2427
    const RuntimeCallCounterId counters[2] = {
        RuntimeCallCounterId::kPreParseBackgroundWithVariableResolution,
        RuntimeCallCounterId::kPreParseWithVariableResolution};
2428 2429
    if (runtime_call_stats_) {
      runtime_call_stats_->CorrectCurrentCounterId(
2430
          counters[parsing_on_main_thread_]);
2431
    }
2432
  }
2433

2434 2435 2436 2437
  // Validate function name. We can do this only after parsing the function,
  // since the function can declare itself strict.
  language_mode = scope->language_mode();
  CheckFunctionName(language_mode, function_name, function_name_validity,
2438
                    function_name_location);
2439

2440
  if (is_strict(language_mode)) {
2441
    CheckStrictOctalLiteral(scope->start_position(), scope->end_position());
2442
  }
2443

2444
  FunctionLiteral::ParameterFlag duplicate_parameters =
2445 2446
      has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
                               : FunctionLiteral::kNoDuplicateParameters;
2447

2448
  // Note that the FunctionLiteral needs to be created in the main Zone again.
2449
  FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
2450 2451
      function_name, scope, body, expected_property_count, num_parameters,
      function_length, duplicate_parameters, function_type, eager_compile_hint,
2452
      pos, true, function_literal_id, produced_preparse_data);
2453
  function_literal->set_function_token_position(function_token_pos);
2454
  function_literal->set_suspend_count(suspend_count);
2455

2456 2457 2458 2459 2460
  if (should_post_parallel_task) {
    // Start a parallel parse / compile task on the compiler dispatcher.
    info()->parallel_tasks()->Enqueue(info(), function_name, function_literal);
  }

2461
  if (should_infer_name) {
2462
    fni_.AddFunction(function_literal);
2463
  }
2464
  return function_literal;
2465 2466
}

2467 2468 2469
bool Parser::SkipFunction(const AstRawString* function_name, FunctionKind kind,
                          FunctionLiteral::FunctionType function_type,
                          DeclarationScope* function_scope, int* num_parameters,
2470
                          int* function_length,
2471
                          ProducedPreparseData** produced_preparse_data) {
2472
  FunctionState function_state(&function_state_, &scope_, function_scope);
2473
  function_scope->set_zone(&preparser_zone_);
2474

2475
  DCHECK_NE(kNoSourcePosition, function_scope->start_position());
2476
  DCHECK_EQ(kNoSourcePosition, parameters_end_pos_);
2477

2478 2479 2480
  DCHECK_IMPLIES(IsArrowFunction(kind),
                 scanner()->current_token() == Token::ARROW);

2481
  // FIXME(marja): There are 2 ways to skip functions now. Unify them.
2482
  if (consumed_preparse_data_) {
2483 2484 2485 2486
    int end_position;
    LanguageMode language_mode;
    int num_inner_functions;
    bool uses_super_property;
2487
    if (stack_overflow()) return true;
2488 2489
    *produced_preparse_data =
        consumed_preparse_data_->GetDataForSkippableFunction(
2490
            main_zone(), function_scope->start_position(), &end_position,
2491 2492
            num_parameters, function_length, &num_inner_functions,
            &uses_super_property, &language_mode);
2493

2494
    function_scope->outer_scope()->SetMustUsePreparseData();
2495 2496 2497
    function_scope->set_is_skipped_function(true);
    function_scope->set_end_position(end_position);
    scanner()->SeekForward(end_position - 1);
2498
    Expect(Token::RBRACE);
2499 2500 2501
    SetLanguageMode(function_scope, language_mode);
    if (uses_super_property) {
      function_scope->RecordSuperPropertyUsage();
2502
    }
2503
    SkipFunctionLiterals(num_inner_functions);
2504
    function_scope->ResetAfterPreparsing(ast_value_factory_, false);
2505
    return true;
2506 2507
  }

2508
  Scanner::BookmarkScope bookmark(scanner());
2509
  bookmark.Set(function_scope->start_position());
2510

2511 2512 2513 2514 2515 2516 2517
  UnresolvedList::Iterator unresolved_private_tail;
  ClassScope* closest_class_scope = function_scope->GetClassScope();
  if (closest_class_scope != nullptr) {
    unresolved_private_tail =
        closest_class_scope->GetUnresolvedPrivateNameTail();
  }

2518 2519
  // With no cached data, we partially parse the function, without building an
  // AST. This gathers the data needed to build a lazy function.
2520 2521
  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse");

2522
  PreParser::PreParseResult result = reusable_preparser()->PreParseFunction(
2523
      function_name, kind, function_type, function_scope, use_counts_,
2524
      produced_preparse_data, this->script_id());
2525

2526 2527 2528
  if (result == PreParser::kPreParseStackOverflow) {
    // Propagate stack overflow.
    set_stack_overflow();
2529
  } else if (pending_error_handler()->has_error_unidentifiable_by_preparser()) {
2530 2531 2532 2533
    // Make sure we don't re-preparse inner functions of the aborted function.
    // The error might be in an inner function.
    allow_lazy_ = false;
    mode_ = PARSE_EAGERLY;
2534
    DCHECK(!pending_error_handler()->stack_overflow());
2535 2536 2537 2538
    // If we encounter an error that the preparser can not identify we reset to
    // the state before preparsing. The caller may then fully parse the function
    // to identify the actual error.
    bookmark.Apply();
2539 2540 2541 2542 2543
    if (closest_class_scope != nullptr) {
      closest_class_scope->ResetUnresolvedPrivateNameTail(
          unresolved_private_tail);
    }
    function_scope->ResetAfterPreparsing(ast_value_factory_, true);
2544
    pending_error_handler()->clear_unidentifiable_error();
2545
    return false;
2546
  } else if (pending_error_handler()->has_pending_error()) {
2547
    DCHECK(!pending_error_handler()->stack_overflow());
2548
    DCHECK(has_error());
2549
  } else {
2550
    DCHECK(!pending_error_handler()->stack_overflow());
2551
    set_allow_eval_cache(reusable_preparser()->allow_eval_cache());
2552

2553 2554
    PreParserLogger* logger = reusable_preparser()->logger();
    function_scope->set_end_position(logger->end());
2555
    Expect(Token::RBRACE);
2556 2557 2558
    total_preparse_skipped_ +=
        function_scope->end_position() - function_scope->start_position();
    *num_parameters = logger->num_parameters();
2559
    *function_length = logger->function_length();
2560
    SkipFunctionLiterals(logger->num_inner_functions());
2561 2562 2563 2564
    if (closest_class_scope != nullptr) {
      closest_class_scope->MigrateUnresolvedPrivateNameTail(
          factory(), unresolved_private_tail);
    }
2565
    function_scope->AnalyzePartially(this, factory());
2566
  }
2567

2568
  return true;
2569 2570
}

2571
Block* Parser::BuildParameterInitializationBlock(
2572
    const ParserFormalParameters& parameters) {
2573
  DCHECK(!parameters.is_simple);
2574
  DCHECK(scope()->is_function_scope());
2575
  DCHECK_EQ(scope(), parameters.scope);
2576
  ScopedPtrList<Statement> init_statements(pointer_buffer());
2577 2578
  int index = 0;
  for (auto parameter : parameters.params) {
2579
    Expression* initial_value =
2580
        factory()->NewVariableProxy(parameters.scope->parameter(index));
2581
    if (parameter->initializer() != nullptr) {
2582
      // IS_UNDEFINED($param) ? initializer : $param
2583

2584 2585
      auto condition = factory()->NewCompareOperation(
          Token::EQ_STRICT,
2586
          factory()->NewVariableProxy(parameters.scope->parameter(index)),
yangguo's avatar
yangguo committed
2587
          factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
2588 2589 2590
      initial_value =
          factory()->NewConditional(condition, parameter->initializer(),
                                    initial_value, kNoSourcePosition);
2591
    }
2592

2593
    Scope* param_scope = scope();
2594 2595 2596
    ScopedPtrList<Statement>* param_init_statements = &init_statements;

    base::Optional<ScopedPtrList<Statement>> non_simple_param_init_statements;
2597 2598
    if (!parameter->is_simple() &&
        scope()->AsDeclarationScope()->calls_sloppy_eval()) {
2599
      param_scope = NewVarblockScope();
2600
      param_scope->set_start_position(parameter->pattern->position());
2601
      param_scope->set_end_position(parameter->initializer_end_position);
2602
      param_scope->RecordEvalCall();
2603 2604
      non_simple_param_init_statements.emplace(pointer_buffer());
      param_init_statements = &non_simple_param_init_statements.value();
2605
      // Rewrite the outer initializer to point to param_scope
2606
      ReparentExpressionScope(stack_limit(), parameter->pattern, param_scope);
2607
      ReparentExpressionScope(stack_limit(), initial_value, param_scope);
2608 2609
    }

2610
    BlockState block_state(&scope_, param_scope);
2611 2612
    DeclarationParsingResult::Declaration decl(parameter->pattern,
                                               initial_value);
2613

2614
    InitializeVariables(param_init_statements, PARAMETER_VARIABLE, &decl);
2615 2616 2617 2618 2619 2620 2621 2622

    if (param_init_statements != &init_statements) {
      DCHECK_EQ(param_init_statements,
                &non_simple_param_init_statements.value());
      Block* param_block =
          factory()->NewBlock(true, *non_simple_param_init_statements);
      non_simple_param_init_statements.reset();
      param_block->set_scope(param_scope);
2623
      param_scope = param_scope->FinalizeBlockScope();
2624
      init_statements.Add(param_block);
2625
    }
2626
    ++index;
2627
  }
2628
  return factory()->NewBlock(true, init_statements);
2629 2630
}

2631 2632
Scope* Parser::NewHiddenCatchScope() {
  Scope* catch_scope = NewScopeWithParent(scope(), CATCH_SCOPE);
2633
  bool was_added;
2634
  catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(),
2635 2636
                            VariableMode::kVar, NORMAL_VARIABLE, &was_added);
  DCHECK(was_added);
2637 2638 2639 2640
  catch_scope->set_is_hidden();
  return catch_scope;
}

2641
Block* Parser::BuildRejectPromiseOnException(Block* inner_block) {
2642 2643 2644
  // try {
  //   <inner_block>
  // } catch (.catch) {
2645
  //   return %_AsyncFunctionReject(.generator_object, .catch, can_suspend);
2646
  // }
2647
  Block* result = factory()->NewBlock(1, true);
2648

2649
  // catch (.catch) {
2650
  //   return %_AsyncFunctionReject(.generator_object, .catch, can_suspend)
2651
  // }
2652
  Scope* catch_scope = NewHiddenCatchScope();
2653

2654
  Expression* reject_promise;
2655
  {
2656
    ScopedPtrList<Expression> args(pointer_buffer());
2657 2658 2659 2660 2661
    args.Add(factory()->NewVariableProxy(
        function_state_->scope()->generator_object_var()));
    args.Add(factory()->NewVariableProxy(catch_scope->catch_variable()));
    args.Add(factory()->NewBooleanLiteral(function_state_->CanSuspend(),
                                          kNoSourcePosition));
2662 2663
    reject_promise = factory()->NewCallRuntime(
        Runtime::kInlineAsyncFunctionReject, args, kNoSourcePosition);
2664
  }
2665 2666
  Block* catch_block = IgnoreCompletion(
      factory()->NewReturnStatement(reject_promise, kNoSourcePosition));
2667

2668 2669 2670 2671
  TryStatement* try_catch_statement =
      factory()->NewTryCatchStatementForAsyncAwait(
          inner_block, catch_scope, catch_block, kNoSourcePosition);
  result->statements()->Add(try_catch_statement, zone());
2672
  return result;
2673 2674
}

2675
Expression* Parser::BuildInitialYield(int pos, FunctionKind kind) {
2676 2677
  Expression* yield_result = factory()->NewVariableProxy(
      function_state_->scope()->generator_object_var());
2678 2679 2680
  // 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).
2681
  function_state_->AddSuspend();
2682 2683
  return factory()->NewYield(yield_result, scope()->start_position(),
                             Suspend::kOnExceptionThrow);
2684 2685
}

2686 2687 2688
void Parser::ParseFunction(
    ScopedPtrList<Statement>* body, const AstRawString* function_name, int pos,
    FunctionKind kind, FunctionLiteral::FunctionType function_type,
2689
    DeclarationScope* function_scope, int* num_parameters, int* function_length,
2690
    bool* has_duplicate_parameters, int* expected_property_count,
2691
    int* suspend_count,
2692
    ZonePtrList<const AstRawString>* arguments_for_wrapped_function) {
2693 2694
  ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);

2695
  FunctionState function_state(&function_state_, &scope_, function_scope);
2696

2697 2698
  bool is_wrapped = function_type == FunctionLiteral::kWrapped;

2699 2700 2701 2702
  int expected_parameters_end_pos = parameters_end_pos_;
  if (expected_parameters_end_pos != kNoSourcePosition) {
    // This is the first function encountered in a CreateDynamicFunction eval.
    parameters_end_pos_ = kNoSourcePosition;
2703
    // The function name should have been ignored, giving us the empty string
2704
    // here.
2705
    DCHECK_EQ(function_name, ast_value_factory()->empty_string());
2706 2707
  }

2708
  ParserFormalParameters formals(function_scope);
2709

2710 2711 2712 2713 2714 2715
  {
    ParameterDeclarationParsingScope formals_scope(this);
    if (is_wrapped) {
      // For a function implicitly wrapped in function header and footer, the
      // function arguments are provided separately to the source, and are
      // declared directly here.
2716
      for (const AstRawString* arg : *arguments_for_wrapped_function) {
2717
        const bool is_rest = false;
2718
        Expression* argument = ExpressionFromIdentifier(arg, kNoSourcePosition);
2719 2720
        AddFormalParameter(&formals, argument, NullExpression(),
                           kNoSourcePosition, is_rest);
2721
      }
2722 2723
      DCHECK_EQ(arguments_for_wrapped_function->length(),
                formals.num_parameters());
2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745
      DeclareFormalParameters(&formals);
    } else {
      // For a regular function, the function arguments are parsed from source.
      DCHECK_NULL(arguments_for_wrapped_function);
      ParseFormalParameterList(&formals);
      if (expected_parameters_end_pos != kNoSourcePosition) {
        // Check for '(' or ')' shenanigans in the parameter string for dynamic
        // functions.
        int position = peek_position();
        if (position < expected_parameters_end_pos) {
          ReportMessageAt(Scanner::Location(position, position + 1),
                          MessageTemplate::kArgStringTerminatesParametersEarly);
          return;
        } else if (position > expected_parameters_end_pos) {
          ReportMessageAt(Scanner::Location(expected_parameters_end_pos - 2,
                                            expected_parameters_end_pos),
                          MessageTemplate::kUnexpectedEndOfArgString);
          return;
        }
      }
      Expect(Token::RPAREN);
      int formals_end_position = scanner()->location().end_pos;
2746

2747 2748 2749 2750 2751
      CheckArityRestrictions(formals.arity, kind, formals.has_rest,
                             function_scope->start_position(),
                             formals_end_position);
      Expect(Token::LBRACE);
    }
2752
    formals.duplicate_loc = formals_scope.duplicate_location();
2753
  }
2754

2755 2756 2757
  *num_parameters = formals.num_parameters();
  *function_length = formals.function_length;

2758
  AcceptINScope scope(this, true);
2759
  ParseFunctionBody(body, function_name, pos, formals, kind, function_type,
2760
                    FunctionBodyType::kBlock);
2761

2762
  *has_duplicate_parameters = formals.has_duplicate();
2763 2764

  *expected_property_count = function_state.expected_property_count();
2765
  *suspend_count = function_state.suspend_count();
2766 2767
}

2768
void Parser::DeclareClassVariable(const AstRawString* name,
2769
                                  ClassInfo* class_info, int class_token_pos) {
2770
#ifdef DEBUG
2771
  scope()->SetScopeName(name);
2772
#endif
2773

2774
  if (name != nullptr) {
2775
    VariableProxy* proxy =
2776
        DeclareBoundVariable(name, VariableMode::kConst, class_token_pos);
2777
    class_info->variable = proxy->var();
2778 2779 2780
  }
}

2781 2782 2783
// TODO(gsathya): Ideally, this should just bypass scope analysis and
// allocate a slot directly on the context. We should just store this
// index in the AST, instead of storing the variable.
2784
Variable* Parser::CreateSyntheticContextVariable(const AstRawString* name) {
2785
  VariableProxy* proxy =
2786
      DeclareBoundVariable(name, VariableMode::kConst, kNoSourcePosition);
2787 2788
  proxy->var()->ForceContextAllocation();
  return proxy->var();
2789 2790
}

2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807
Variable* Parser::CreatePrivateNameVariable(ClassScope* scope,
                                            const AstRawString* name) {
  DCHECK_NOT_NULL(name);
  int begin = position();
  int end = end_position();
  bool was_added = false;
  Variable* var = scope->DeclarePrivateName(name, &was_added);
  if (!was_added) {
    Scanner::Location loc(begin, end);
    ReportMessageAt(loc, MessageTemplate::kVarRedeclaration, var->raw_name());
  }
  VariableProxy* proxy = factory()->NewVariableProxy(var, begin);
  return proxy->var();
}

void Parser::DeclareClassField(ClassScope* scope,
                               ClassLiteralProperty* property,
2808 2809 2810
                               const AstRawString* property_name,
                               bool is_static, bool is_computed_name,
                               bool is_private, ClassInfo* class_info) {
2811
  DCHECK(allow_harmony_public_fields() || allow_harmony_private_fields());
2812 2813

  if (is_static) {
2814 2815
    class_info->static_fields->Add(property, zone());
  } else {
2816 2817 2818
    class_info->instance_fields->Add(property, zone());
  }

2819
  DCHECK_IMPLIES(is_computed_name, !is_private);
2820
  if (is_computed_name) {
2821 2822
    // We create a synthetic variable name here so that scope
    // analysis doesn't dedupe the vars.
2823 2824 2825
    Variable* computed_name_var =
        CreateSyntheticContextVariable(ClassFieldVariableName(
            ast_value_factory(), class_info->computed_field_count));
2826
    property->set_computed_name_var(computed_name_var);
2827
    class_info->properties->Add(property, zone());
2828
  } else if (is_private) {
2829 2830 2831 2832 2833 2834 2835
    Variable* private_name_var =
        CreatePrivateNameVariable(scope, property_name);
    int pos = property->value()->position();
    if (pos == kNoSourcePosition) {
      pos = property->key()->position();
    }
    private_name_var->set_initializer_position(pos);
2836
    property->set_private_name_var(private_name_var);
2837 2838
    class_info->properties->Add(property, zone());
  }
2839 2840
}

2841 2842 2843 2844
// This method declares a property of the given class.  It updates the
// following fields of class_info, as appropriate:
//   - constructor
//   - properties
2845 2846
void Parser::DeclareClassProperty(ClassScope* scope,
                                  const AstRawString* class_name,
2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861
                                  ClassLiteralProperty* property,
                                  bool is_constructor, ClassInfo* class_info) {
  if (is_constructor) {
    DCHECK(!class_info->constructor);
    class_info->constructor = property->value()->AsFunctionLiteral();
    DCHECK_NOT_NULL(class_info->constructor);
    class_info->constructor->set_raw_name(
        class_name != nullptr ? ast_value_factory()->NewConsString(class_name)
                              : nullptr);
    return;
  }

  class_info->properties->Add(property, zone());
}

2862
FunctionLiteral* Parser::CreateInitializerFunction(
2863 2864
    const char* name, DeclarationScope* scope,
    ZonePtrList<ClassLiteral::Property>* fields) {
2865
  DCHECK_EQ(scope->function_kind(),
2866
            FunctionKind::kClassMembersInitializerFunction);
2867
  // function() { .. class fields initializer .. }
2868
  ScopedPtrList<Statement> statements(pointer_buffer());
2869 2870
  InitializeClassMembersStatement* static_fields =
      factory()->NewInitializeClassMembersStatement(fields, kNoSourcePosition);
2871
  statements.Add(static_fields);
2872
  return factory()->NewFunctionLiteral(
2873
      ast_value_factory()->GetOneByteString(name), scope, statements, 0, 0, 0,
2874 2875
      FunctionLiteral::kNoDuplicateParameters,
      FunctionLiteral::kAnonymousExpression,
2876
      FunctionLiteral::kShouldEagerCompile, scope->start_position(), false,
2877 2878 2879
      GetNextFunctionLiteralId());
}

2880
// This method generates a ClassLiteral AST node.
2881 2882 2883 2884 2885
// It uses the following fields of class_info:
//   - constructor (if missing, it updates it with a default constructor)
//   - proxy
//   - extends
//   - properties
2886 2887
//   - has_name_static_property
//   - has_static_computed_names
2888
Expression* Parser::RewriteClassLiteral(ClassScope* block_scope,
2889
                                        const AstRawString* name,
2890
                                        ClassInfo* class_info, int pos,
2891
                                        int end_pos) {
2892
  DCHECK_NOT_NULL(block_scope);
2893
  DCHECK_EQ(block_scope->scope_type(), CLASS_SCOPE);
2894
  DCHECK_EQ(block_scope->language_mode(), LanguageMode::kStrict);
2895

2896 2897
  bool has_extends = class_info->extends != nullptr;
  bool has_default_constructor = class_info->constructor == nullptr;
2898
  if (has_default_constructor) {
2899 2900
    class_info->constructor =
        DefaultConstructor(name, has_extends, pos, end_pos);
2901 2902
  }

2903
  if (name != nullptr) {
2904 2905
    DCHECK_NOT_NULL(class_info->variable);
    class_info->variable->set_initializer_position(end_pos);
2906 2907
  }

2908 2909
  FunctionLiteral* static_fields_initializer = nullptr;
  if (class_info->has_static_class_fields) {
2910
    static_fields_initializer = CreateInitializerFunction(
2911 2912
        "<static_fields_initializer>", class_info->static_fields_scope,
        class_info->static_fields);
2913 2914
  }

2915 2916 2917 2918
  FunctionLiteral* instance_members_initializer_function = nullptr;
  if (class_info->has_instance_members) {
    instance_members_initializer_function = CreateInitializerFunction(
        "<instance_members_initializer>", class_info->instance_members_scope,
2919
        class_info->instance_fields);
2920
    class_info->constructor->set_requires_instance_members_initializer(true);
2921 2922
    class_info->constructor->add_expected_properties(
        class_info->instance_fields->length());
2923 2924
  }

2925
  ClassLiteral* class_literal = factory()->NewClassLiteral(
2926
      block_scope, class_info->variable, class_info->extends,
2927
      class_info->constructor, class_info->properties,
2928
      static_fields_initializer, instance_members_initializer_function, pos,
2929
      end_pos, class_info->has_name_static_property,
2930
      class_info->has_static_computed_names, class_info->is_anonymous);
2931

2932
  AddFunctionForNameInference(class_info->constructor);
2933
  return class_literal;
2934 2935
}

2936 2937 2938 2939 2940 2941 2942
bool Parser::IsPropertyWithPrivateFieldKey(Expression* expression) {
  if (!expression->IsProperty()) return false;
  Property* property = expression->AsProperty();

  if (!property->key()->IsVariableProxy()) return false;
  VariableProxy* key = property->key()->AsVariableProxy();

2943
  return key->IsPrivateName();
2944
}
2945

2946 2947 2948 2949 2950 2951 2952
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());
2953
  BlockState block_state(&scope_, inner_scope);
2954
  for (Declaration* decl : *inner_scope->declarations()) {
2955
    if (decl->var()->mode() != VariableMode::kVar ||
2956
        !decl->IsVariableDeclaration()) {
2957 2958
      continue;
    }
2959
    const AstRawString* name = decl->var()->raw_name();
2960 2961
    Variable* parameter = function_scope->LookupLocal(name);
    if (parameter == nullptr) continue;
2962
    VariableProxy* to = NewUnresolved(name);
2963
    VariableProxy* from = factory()->NewVariableProxy(parameter);
yangguo's avatar
yangguo committed
2964 2965 2966 2967
    Expression* assignment =
        factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition);
    Statement* statement =
        factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2968 2969 2970 2971
    inner_block->statements()->InsertAt(0, statement, zone());
  }
}

2972 2973 2974 2975 2976 2977 2978
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;
2979
  }
2980
  scope->HoistSloppyBlockFunctions(factory());
2981 2982
}

2983 2984 2985
// ----------------------------------------------------------------------------
// Parser support

2986
bool Parser::TargetStackContainsLabel(const AstRawString* label) {
2987
  for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
2988
    if (ContainsLabel(t->statement()->labels(), label)) return true;
2989 2990 2991 2992
  }
  return false;
}

2993
BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label) {
2994 2995
  bool anonymous = label == nullptr;
  for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
2996
    BreakableStatement* stat = t->statement();
2997 2998 2999 3000 3001
    if ((anonymous && stat->is_target_for_anonymous()) ||
        (!anonymous && ContainsLabel(stat->labels(), label))) {
      return stat;
    }
  }
3002
  return nullptr;
3003 3004
}

3005
IterationStatement* Parser::LookupContinueTarget(const AstRawString* label) {
3006 3007
  bool anonymous = label == nullptr;
  for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
3008
    IterationStatement* stat = t->statement()->AsIterationStatement();
3009
    if (stat == nullptr) continue;
3010

3011
    DCHECK(stat->is_target_for_anonymous());
3012
    if (anonymous || ContainsLabel(stat->own_labels(), label)) {
3013 3014
      return stat;
    }
3015
    if (ContainsLabel(stat->labels(), label)) break;
3016
  }
3017
  return nullptr;
3018 3019
}

3020
void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) {
3021 3022
  Handle<String> source_url = scanner_.SourceUrl(isolate);
  if (!source_url.is_null()) {
3023
    script->set_source_url(*source_url);
3024
  }
3025 3026
  Handle<String> source_mapping_url = scanner_.SourceMappingUrl(isolate);
  if (!source_mapping_url.is_null()) {
3027
    script->set_source_mapping_url(*source_mapping_url);
3028 3029 3030
  }
}

3031
void Parser::UpdateStatistics(Isolate* isolate, Handle<Script> script) {
3032
  // Move statistics to Isolate.
3033 3034
  for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
       ++feature) {
3035
    if (use_counts_[feature] > 0) {
3036
      isolate->CountUsage(v8::Isolate::UseCounterFeature(feature));
3037 3038
    }
  }
3039 3040 3041 3042 3043 3044
  if (scanner_.FoundHtmlComment()) {
    isolate->CountUsage(v8::Isolate::kHtmlComment);
    if (script->line_offset() == 0 && script->column_offset() == 0) {
      isolate->CountUsage(v8::Isolate::kHtmlCommentInExternalScript);
    }
  }
3045
  isolate->counters()->total_preparse_skipped()->Increment(
3046
      total_preparse_skipped_);
3047 3048
}

3049
void Parser::ParseOnBackground(ParseInfo* info) {
3050 3051
  RuntimeCallTimerScope runtimeTimer(
      runtime_call_stats_, RuntimeCallCounterId::kParseBackgroundProgram);
3052
  parsing_on_main_thread_ = false;
3053
  set_script_id(info->script_id());
3054

3055
  DCHECK_NULL(info->literal());
3056
  FunctionLiteral* result = nullptr;
3057

3058
  scanner_.Initialize();
3059
  DCHECK(info->maybe_outer_scope_info().is_null());
3060

3061 3062
  DCHECK(original_scope_);

3063 3064 3065 3066 3067 3068
  // 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
3069
  if (info->is_toplevel()) {
3070
    result = DoParseProgram(/* isolate = */ nullptr, info);
verwaest's avatar
verwaest committed
3071
  } else {
3072 3073
    result =
        DoParseFunction(/* isolate = */ nullptr, info, info->function_name());
3074
  }
3075
  MaybeResetCharacterStream(info, result);
3076

3077
  info->set_literal(result);
3078 3079

  // We cannot internalize on a background thread; a foreground task will take
3080
  // care of calling AstValueFactory::Internalize just before compilation.
3081
}
3082

3083 3084
Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
  return new (zone()) TemplateLiteral(zone(), pos);
3085 3086
}

3087 3088
void Parser::AddTemplateSpan(TemplateLiteralState* state, bool should_cook,
                             bool tail) {
3089
  int end = scanner()->location().end_pos - (tail ? 1 : 2);
3090
  const AstRawString* raw = scanner()->CurrentRawSymbol(ast_value_factory());
3091
  if (should_cook) {
3092
    const AstRawString* cooked = scanner()->CurrentSymbol(ast_value_factory());
3093 3094
    (*state)->AddTemplateSpan(cooked, raw, end, zone());
  } else {
3095
    (*state)->AddTemplateSpan(nullptr, raw, end, zone());
3096
  }
3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107
}

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();
3108 3109 3110
  const ZonePtrList<const AstRawString>* cooked_strings = lit->cooked();
  const ZonePtrList<const AstRawString>* raw_strings = lit->raw();
  const ZonePtrList<Expression>* expressions = lit->expressions();
3111 3112
  DCHECK_EQ(cooked_strings->length(), raw_strings->length());
  DCHECK_EQ(cooked_strings->length(), expressions->length() + 1);
3113 3114

  if (!tag) {
3115 3116
    if (cooked_strings->length() == 1) {
      return factory()->NewStringLiteral(cooked_strings->first(), pos);
3117
    }
3118
    return factory()->NewTemplateLiteral(cooked_strings, expressions, pos);
3119
  } else {
3120
    // GetTemplateObject
3121
    Expression* template_object =
3122
        factory()->NewGetTemplateObject(cooked_strings, raw_strings, pos);
3123 3124

    // Call TagFn
3125
    ScopedPtrList<Expression> call_args(pointer_buffer());
3126 3127
    call_args.Add(template_object);
    call_args.AddAll(*expressions);
3128
    return factory()->NewTaggedTemplate(tag, call_args, pos);
3129 3130 3131
  }
}

3132 3133
namespace {

3134 3135 3136
bool OnlyLastArgIsSpread(const ScopedPtrList<Expression>& args) {
  for (int i = 0; i < args.length() - 1; i++) {
    if (args.at(i)->IsSpread()) {
3137 3138 3139
      return false;
    }
  }
3140
  return args.at(args.length() - 1)->IsSpread();
3141 3142 3143 3144
}

}  // namespace

3145
ArrayLiteral* Parser::ArrayLiteralFromListWithSpread(
3146
    const ScopedPtrList<Expression>& list) {
3147 3148
  // If there's only a single spread argument, a fast path using CallWithSpread
  // is taken.
3149
  DCHECK_LT(1, list.length());
3150

3151 3152
  // The arguments of the spread call become a single ArrayLiteral.
  int first_spread = 0;
3153
  for (; first_spread < list.length() && !list.at(first_spread)->IsSpread();
3154
       ++first_spread) {
3155
  }
3156

3157
  DCHECK_LT(first_spread, list.length());
3158
  return factory()->NewArrayLiteral(list, first_spread, kNoSourcePosition);
3159 3160 3161
}

Expression* Parser::SpreadCall(Expression* function,
3162 3163
                               const ScopedPtrList<Expression>& args_list,
                               int pos, Call::PossiblyEval is_possibly_eval) {
3164
  // Handle this case in BytecodeGenerator.
3165
  if (OnlyLastArgIsSpread(args_list) || function->IsSuperCallReference()) {
3166
    return factory()->NewCall(function, args_list, pos);
3167 3168
  }

3169
  ScopedPtrList<Expression> args(pointer_buffer());
3170 3171 3172
  if (function->IsProperty()) {
    // Method calls
    if (function->AsProperty()->IsSuperAccess()) {
3173
      Expression* home = ThisExpression();
3174 3175
      args.Add(function);
      args.Add(home);
3176
    } else {
3177 3178 3179 3180 3181 3182
      Variable* temp = NewTemporary(ast_value_factory()->empty_string());
      VariableProxy* obj = factory()->NewVariableProxy(temp);
      Assignment* assign_obj = factory()->NewAssignment(
          Token::ASSIGN, obj, function->AsProperty()->obj(), kNoSourcePosition);
      function = factory()->NewProperty(
          assign_obj, function->AsProperty()->key(), kNoSourcePosition);
3183
      args.Add(function);
3184
      obj = factory()->NewVariableProxy(temp);
3185
      args.Add(obj);
3186
    }
3187 3188
  } else {
    // Non-method calls
3189 3190
    args.Add(function);
    args.Add(factory()->NewUndefinedLiteral(kNoSourcePosition));
3191
  }
3192
  args.Add(ArrayLiteralFromListWithSpread(args_list));
3193
  return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos);
3194 3195 3196
}

Expression* Parser::SpreadCallNew(Expression* function,
3197 3198
                                  const ScopedPtrList<Expression>& args_list,
                                  int pos) {
3199
  if (OnlyLastArgIsSpread(args_list)) {
3200
    // Handle in BytecodeGenerator.
3201
    return factory()->NewCallNew(function, args_list, pos);
3202
  }
3203
  ScopedPtrList<Expression> args(pointer_buffer());
3204 3205
  args.Add(function);
  args.Add(ArrayLiteralFromListWithSpread(args_list));
3206

3207
  return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos);
3208
}
3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221

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);
}

3222 3223 3224 3225 3226
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());
3227 3228
  scope()->AsDeclarationScope()->set_is_asm_module();
  info_->set_contains_asm_module(true);
3229 3230
}

3231 3232 3233
Expression* Parser::ExpressionListToExpression(
    const ScopedPtrList<Expression>& args) {
  Expression* expr = args.at(0);
3234 3235 3236
  if (args.length() == 1) return expr;
  if (args.length() == 2) {
    return factory()->NewBinaryOperation(Token::COMMA, expr, args.at(1),
3237
                                         args.at(1)->position());
3238
  }
3239 3240 3241
  NaryOperation* result =
      factory()->NewNaryOperation(Token::COMMA, expr, args.length() - 1);
  for (int i = 1; i < args.length(); i++) {
3242
    result->AddSubsequent(args.at(i), args.at(i)->position());
3243 3244
  }
  return result;
3245 3246
}

3247
// This method completes the desugaring of the body of async_function.
3248
void Parser::RewriteAsyncFunctionBody(ScopedPtrList<Statement>* body,
3249
                                      Block* block, Expression* return_value) {
3250
  // function async_function() {
3251
  //   .generator_object = %_AsyncFunctionEnter();
3252 3253
  //   BuildRejectPromiseOnException({
  //     ... block ...
3254
  //     return %_AsyncFunctionResolve(.generator_object, expr);
3255 3256 3257
  //   })
  // }

3258 3259 3260
  block->statements()->Add(factory()->NewAsyncReturnStatement(
                               return_value, return_value->position()),
                           zone());
3261
  block = BuildRejectPromiseOnException(block);
3262
  body->Add(block);
3263 3264
}

3265 3266 3267
void Parser::SetFunctionNameFromPropertyName(LiteralProperty* property,
                                             const AstRawString* name,
                                             const AstRawString* prefix) {
3268
  if (has_error()) return;
3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285
  // Ensure that the function we are going to create has shared name iff
  // we are not going to set it later.
  if (property->NeedsSetFunctionName()) {
    name = nullptr;
    prefix = nullptr;
  } else {
    // If the property value is an anonymous function or an anonymous class or
    // a concise method or an accessor function which doesn't require the name
    // to be set then the shared name must be provided.
    DCHECK_IMPLIES(property->value()->IsAnonymousFunctionDefinition() ||
                       property->value()->IsConciseMethodDefinition() ||
                       property->value()->IsAccessorFunctionDefinition(),
                   name != nullptr);
  }

  Expression* value = property->value();
  SetFunctionName(value, name, prefix);
3286 3287
}

3288
void Parser::SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
3289 3290
                                             const AstRawString* name,
                                             const AstRawString* prefix) {
3291 3292
  // Ignore "__proto__" as a name when it's being used to set the [[Prototype]]
  // of an object literal.
3293
  // See ES #sec-__proto__-property-names-in-object-initializers.
3294
  if (property->IsPrototype() || has_error()) return;
3295

3296
  DCHECK(!property->value()->IsAnonymousFunctionDefinition() ||
3297
         property->kind() == ObjectLiteralProperty::COMPUTED);
3298 3299 3300

  SetFunctionNameFromPropertyName(static_cast<LiteralProperty*>(property), name,
                                  prefix);
3301 3302
}

3303 3304
void Parser::SetFunctionNameFromIdentifierRef(Expression* value,
                                              Expression* identifier) {
3305
  if (!identifier->IsVariableProxy()) return;
3306
  SetFunctionName(value, identifier->AsVariableProxy()->raw_name());
3307
}
3308

3309 3310 3311 3312 3313 3314 3315
void Parser::SetFunctionName(Expression* value, const AstRawString* name,
                             const AstRawString* prefix) {
  if (!value->IsAnonymousFunctionDefinition() &&
      !value->IsConciseMethodDefinition() &&
      !value->IsAccessorFunctionDefinition()) {
    return;
  }
3316
  auto function = value->AsFunctionLiteral();
3317 3318 3319
  if (value->IsClassLiteral()) {
    function = value->AsClassLiteral()->constructor();
  }
3320
  if (function != nullptr) {
3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331
    AstConsString* cons_name = nullptr;
    if (name != nullptr) {
      if (prefix != nullptr) {
        cons_name = ast_value_factory()->NewConsString(prefix, name);
      } else {
        cons_name = ast_value_factory()->NewConsString(name);
      }
    } else {
      DCHECK_NULL(prefix);
    }
    function->set_raw_name(cons_name);
3332 3333 3334
  }
}

3335
Statement* Parser::CheckCallable(Variable* var, Expression* error, int pos) {
yangguo's avatar
yangguo committed
3336
  const int nopos = kNoSourcePosition;
3337 3338
  Statement* validate_var;
  {
3339 3340 3341 3342 3343
    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(
3344 3345
        Token::EQ_STRICT, type_of, function_literal, nopos);

3346
    Statement* throw_call = factory()->NewExpressionStatement(error, pos);
3347

3348
    validate_var = factory()->NewIfStatement(
3349
        condition, factory()->EmptyStatement(), throw_call, nopos);
3350 3351 3352
  }
  return validate_var;
}
neis's avatar
neis committed
3353

3354 3355
}  // namespace internal
}  // namespace v8