parser.cc 126 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

31 32
namespace v8 {
namespace internal {
33

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

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

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

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

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

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

    expected_property_count = function_state.expected_property_count();
  }

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

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

145 146 147
// ----------------------------------------------------------------------------
// Implementation of Parser

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

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

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

223 224
    nary = factory()->NewNaryOperation(op, binop->left(), 2);
    nary->AddSubsequent(binop->right(), binop->position());
225
    ConvertBinaryToNaryOperationSourceRange(binop, nary);
226 227 228 229 230 231 232 233 234 235 236 237
    *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);
238
  nary->clear_parenthesized();
239 240
  AppendNaryOperationSourceRange(nary, range);

241 242 243
  return true;
}

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

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

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

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

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

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

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

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

349 350 351
  DCHECK(name->is_one_byte());
  const Runtime::Function* function =
      Runtime::FunctionForName(name->raw_data(), name->length());
352 353 354 355

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

    // Check that the expected number of arguments are being passed.
359
    if (function->nargs != -1 && function->nargs != args.length()) {
360
      ReportMessage(MessageTemplate::kRuntimeWrongNumArgs);
361
      return FailureExpression();
362 363 364 365 366
    }

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

367 368
  int context_index =
      Context::IntrinsicIndexForName(name->raw_data(), name->length());
369 370 371 372

  // Check that the function is defined.
  if (context_index == Context::kNotFound) {
    ReportMessage(MessageTemplate::kNotDefined, name);
373
    return FailureExpression();
374 375 376 377 378
  }

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

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

  set_default_eager_compile_hint(can_compile_lazily
                                     ? FunctionLiteral::kShouldLazyCompile
                                     : FunctionLiteral::kShouldEagerCompile);
416 417 418 419 420 421 422 423 424 425 426
  allow_lazy_ = info->allow_lazy_compile() && info->allow_lazy_parsing() &&
                !info->is_native() && info->extension() == nullptr &&
                can_compile_lazily;
  set_allow_natives(info->allow_natives_syntax() || info->is_native());
  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());
427 428 429 430
  for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
       ++feature) {
    use_counts_[feature] = 0;
  }
431 432
}

433 434 435
void Parser::InitializeEmptyScopeChain(ParseInfo* info) {
  DCHECK_NULL(original_scope_);
  DCHECK_NULL(info->script_scope());
436 437
  DeclarationScope* script_scope = NewScriptScope();
  info->set_script_scope(script_scope);
438 439 440 441 442
  original_scope_ = script_scope;
}

void Parser::DeserializeScopeChain(
    Isolate* isolate, ParseInfo* info,
443 444
    MaybeHandle<ScopeInfo> maybe_outer_scope_info,
    Scope::DeserializationMode mode) {
445
  InitializeEmptyScopeChain(info);
446 447
  Handle<ScopeInfo> outer_scope_info;
  if (maybe_outer_scope_info.ToHandle(&outer_scope_info)) {
448
    DCHECK(ThreadId::Current().Equals(isolate->thread_id()));
449 450
    original_scope_ = Scope::DeserializeScopeChain(
        isolate, zone(), *outer_scope_info, info->script_scope(),
451
        ast_value_factory(), mode);
452 453 454 455
    if (info->is_eval() || IsArrowFunction(info->function_kind())) {
      original_scope_->GetReceiverScope()->DeserializeReceiver(
          ast_value_factory());
    }
456 457
  }
}
458

459 460 461 462 463
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.
464 465 466
  if (info->contains_asm_module()) {
    if (FLAG_stress_validate_asm) return;
    if (literal != nullptr && literal->scope()->ContainsAsmModule()) return;
467
  }
468
  info->ResetCharacterStream();
469 470
}

471 472 473 474 475 476 477 478 479
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();
  }
}

480 481
}  // namespace

482
FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
483 484
  // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
  // see comment for HistogramTimerScope class.
485

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

  // Initialize parser state.
498 499
  DeserializeScopeChain(isolate, info, info->maybe_outer_scope_info(),
                        Scope::DeserializationMode::kIncludingVariables);
500

501
  scanner_.Initialize();
502 503 504
  if (FLAG_harmony_hashbang && !info->is_eval()) {
    scanner_.SkipHashBang();
  }
505
  FunctionLiteral* result = DoParseProgram(isolate, info);
506
  MaybeResetCharacterStream(info, result);
507
  MaybeProcessSourceRanges(info, result, stack_limit_);
508

509
  HandleSourceURLComments(isolate, info->script());
510

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

528
FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
529 530
  // Note that this function can be called from the main thread or from a
  // background thread. We should not access anything Isolate / heap dependent
531 532 533
  // 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);
534
  DCHECK_NULL(scope_);
535
  DCHECK_NULL(target_stack_);
536

537
  ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
538 539 540
  ResetFunctionLiteralId();
  DCHECK(info->function_literal_id() == FunctionLiteral::kIdTypeTopLevel ||
         info->function_literal_id() == FunctionLiteral::kIdTypeInvalid);
541

542
  FunctionLiteral* result = nullptr;
543
  {
544
    Scope* outer = original_scope_;
545
    DCHECK_NOT_NULL(outer);
546
    if (info->is_eval()) {
547
      outer = NewEvalScope(outer);
548
    } else if (parsing_module_) {
549 550
      DCHECK_EQ(outer, info->script_scope());
      outer = NewModuleScope(info->script_scope());
551
    }
wingo's avatar
wingo committed
552

553
    DeclarationScope* scope = outer->AsDeclarationScope();
wingo's avatar
wingo committed
554
    scope->set_start_position(0);
555

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

574
      PrepareGeneratorVariables();
575 576
      Expression* initial_yield =
          BuildInitialYield(kNoSourcePosition, kGeneratorFunction);
577 578
      body.Add(
          factory()->NewExpressionStatement(initial_yield, kNoSourcePosition));
579

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

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

599 600
    if (is_strict(language_mode())) {
      CheckStrictOctalLiteral(beg_pos, end_position());
601
    }
602
    if (is_sloppy(language_mode())) {
603 604 605 606
      // 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.
607
      InsertSloppyBlockFunctionVarBindings(scope);
608
    }
609 610 611 612 613 614
    // 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);
    }
615
    CheckConflictingVarDeclarations(scope);
616

617
    if (info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
618 619 620 621 622
      if (body.length() != 1 || !body.at(0)->IsExpressionStatement() ||
          !body.at(0)
               ->AsExpressionStatement()
               ->expression()
               ->IsFunctionLiteral()) {
623
        ReportMessage(MessageTemplate::kSingleFunctionLiteral);
624 625 626
      }
    }

627 628 629 630
    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());
631 632
  }

633 634
  info->set_max_function_literal_id(GetLastFunctionLiteralId());

635
  // Make sure the target stack is empty.
636
  DCHECK_NULL(target_stack_);
637

638
  if (has_error()) return nullptr;
639 640 641
  return result;
}

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

658
void Parser::ParseWrapped(Isolate* isolate, ParseInfo* info,
659
                          ScopedPtrList<Statement>* body,
660
                          DeclarationScope* outer_scope, Zone* zone) {
661
  DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr);
662 663 664 665 666 667 668 669 670 671
  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);

672
  ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
673
      PrepareWrappedArguments(isolate, info, zone);
674 675 676 677

  FunctionLiteral* function_literal = ParseFunctionLiteral(
      function_name, location, kSkipFunctionNameCheck, kNormalFunction,
      kNoSourcePosition, FunctionLiteral::kWrapped, LanguageMode::kSloppy,
678
      arguments_for_wrapped_function);
679 680 681

  Statement* return_statement = factory()->NewReturnStatement(
      function_literal, kNoSourcePosition, kNoSourcePosition);
682
  body->Add(return_statement);
683 684
}

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

696 697
  DeserializeScopeChain(isolate, info, info->maybe_outer_scope_info(),
                        Scope::DeserializationMode::kIncludingVariables);
698
  DCHECK_EQ(factory()->zone(), info->zone());
699

700
  // Initialize parser state.
701
  Handle<String> name(shared_info->Name(), isolate);
702
  info->set_function_name(ast_value_factory()->GetString(name));
703
  scanner_.Initialize();
704

705 706
  FunctionLiteral* result =
      DoParseFunction(isolate, info, info->function_name());
707
  MaybeResetCharacterStream(info, result);
708
  MaybeProcessSourceRanges(info, result, stack_limit_);
709
  if (result != nullptr) {
710
    Handle<String> inferred_name(shared_info->inferred_name(), isolate);
711
    result->set_inferred_name(inferred_name);
712
  }
713

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

729
static FunctionLiteral::FunctionType ComputeFunctionType(ParseInfo* info) {
730 731 732
  if (info->is_wrapped_as_function()) {
    return FunctionLiteral::kWrapped;
  } else if (info->is_declaration()) {
733
    return FunctionLiteral::kDeclaration;
734
  } else if (info->is_named_expression()) {
735
    return FunctionLiteral::kNamedExpression;
736 737
  } else if (IsConciseMethod(info->function_kind()) ||
             IsAccessorFunction(info->function_kind())) {
738 739 740 741
    return FunctionLiteral::kAccessorOrMethod;
  }
  return FunctionLiteral::kAnonymousExpression;
}
742

743
FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
744
                                         const AstRawString* raw_name) {
745
  DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr);
746
  DCHECK_NOT_NULL(raw_name);
747
  DCHECK_NULL(scope_);
748
  DCHECK_NULL(target_stack_);
749

750
  DCHECK(ast_value_factory());
751
  fni_.PushEnclosingName(raw_name);
752

753 754 755 756
  ResetFunctionLiteralId();
  DCHECK_LT(0, info->function_literal_id());
  SkipFunctionLiterals(info->function_literal_id() - 1);

757
  ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
758 759

  // Place holder for the result.
760
  FunctionLiteral* result = nullptr;
761 762 763

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

774
    if (IsArrowFunction(kind)) {
775
      if (IsAsyncFunction(kind)) {
776
        DCHECK(!scanner()->HasLineTerminatorAfterNext());
777 778 779 780 781 782 783 784
        if (!Check(Token::ASYNC)) {
          CHECK(stack_overflow());
          return nullptr;
        }
        if (!(peek_any_identifier() || peek() == Token::LPAREN)) {
          CHECK(stack_overflow());
          return nullptr;
        }
785 786
      }

787
      // TODO(adamk): We should construct this scope from the ScopeInfo.
788
      DeclarationScope* scope = NewFunctionScope(kind);
789
      scope->set_has_checked_syntax(true);
790

791
      // This bit only needs to be explicitly set because we're
792
      // not passing the ScopeInfo to the Scope constructor.
793
      SetLanguageMode(scope, info->language_mode());
794

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

816
      if (GetLastFunctionLiteralId() != info->function_literal_id() - 1) {
817
        if (has_error()) return nullptr;
818 819 820 821 822 823 824 825 826 827
        // 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());
828 829
          }
        }
830 831 832
        ResetFunctionLiteralId();
        SkipFunctionLiterals(info->function_literal_id() - 1);
      }
833

834
      Expression* expression = ParseArrowFunctionLiteral(formals);
835 836 837 838 839 840 841 842 843 844 845
      // 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();
846
      }
847
    } else if (IsDefaultConstructor(kind)) {
848
      DCHECK_EQ(scope(), outer);
849
      result = DefaultConstructor(raw_name, IsDerivedConstructor(kind),
850
                                  info->start_position(), info->end_position());
851
    } else {
852
      ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
853 854 855
          info->is_wrapped_as_function()
              ? PrepareWrappedArguments(isolate, info, zone())
              : nullptr;
856
      result = ParseFunctionLiteral(
857
          raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind,
858
          kNoSourcePosition, function_type, info->language_mode(),
859
          arguments_for_wrapped_function);
860 861
    }

862
    if (has_error()) return nullptr;
863 864
    result->set_requires_instance_members_initializer(
        info->requires_instance_members_initializer());
865 866
    if (info->is_oneshot_iife()) {
      result->mark_as_oneshot_iife();
867
    }
868 869 870
  }

  // Make sure the target stack is empty.
871
  DCHECK_NULL(target_stack_);
872 873
  DCHECK_IMPLIES(result,
                 info->function_literal_id() == result->function_literal_id());
874 875 876
  return result;
}

877
Statement* Parser::ParseModuleItem() {
878
  // ecma262/#prod-ModuleItem
879 880 881 882
  // ModuleItem :
  //    ImportDeclaration
  //    ExportDeclaration
  //    StatementListItem
883

884 885 886
  Token::Value next = peek();

  if (next == Token::EXPORT) {
887
    return ParseExportDeclaration();
888
  }
889

890 891 892 893 894 895
  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)) {
896
      ParseImportDeclaration();
897
      return factory()->EmptyStatement();
898
    }
899 900
  }

901
  return ParseStatementListItem();
902 903
}

904
void Parser::ParseModuleItemList(ScopedPtrList<Statement>* body) {
905
  // ecma262/#prod-Module
906 907 908
  // Module :
  //    ModuleBody?
  //
909
  // ecma262/#prod-ModuleItemList
910 911
  // ModuleBody :
  //    ModuleItem*
912

913
  DCHECK(scope()->is_module_scope());
914
  while (peek() != Token::EOS) {
915
    Statement* stat = ParseModuleItem();
916
    if (stat == nullptr) return;
917
    if (stat->IsEmptyStatement()) continue;
918
    body->Add(stat);
919 920 921
  }
}

922
const AstRawString* Parser::ParseModuleSpecifier() {
923 924
  // ModuleSpecifier :
  //    StringLiteral
925

926
  Expect(Token::STRING);
927
  return GetSymbol();
928 929
}

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

947
  Expect(Token::LBRACE);
948

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

978
  Expect(Token::RBRACE);
979
  return export_data;
980 981
}

982
ZonePtrList<const Parser::NamedImport>* Parser::ParseNamedImports(int pos) {
983 984 985 986 987 988 989 990 991 992 993 994 995
  // NamedImports :
  //   '{' '}'
  //   '{' ImportsList '}'
  //   '{' ImportsList ',' '}'
  //
  // ImportsList :
  //   ImportSpecifier
  //   ImportsList ',' ImportSpecifier
  //
  // ImportSpecifier :
  //   BindingIdentifier
  //   IdentifierName 'as' BindingIdentifier

996
  Expect(Token::LBRACE);
997

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

1019 1020
    DeclareUnboundVariable(local_name, VariableMode::kConst,
                           kNeedsInitialization, position());
1021

1022 1023
    NamedImport* import =
        new (zone()) NamedImport(import_name, local_name, location);
1024 1025
    result->Add(import, zone());

1026
    if (peek() == Token::RBRACE) break;
1027
    Expect(Token::COMMA);
1028 1029
  }

1030
  Expect(Token::RBRACE);
1031
  return result;
1032 1033
}

1034
void Parser::ParseImportDeclaration() {
1035 1036 1037
  // ImportDeclaration :
  //   'import' ImportClause 'from' ModuleSpecifier ';'
  //   'import' ModuleSpecifier ';'
1038
  //
1039
  // ImportClause :
1040
  //   ImportedDefaultBinding
1041 1042 1043 1044 1045 1046 1047
  //   NameSpaceImport
  //   NamedImports
  //   ImportedDefaultBinding ',' NameSpaceImport
  //   ImportedDefaultBinding ',' NamedImports
  //
  // NameSpaceImport :
  //   '*' 'as' ImportedBinding
1048

1049
  int pos = peek_position();
1050
  Expect(Token::IMPORT);
1051 1052 1053 1054 1055

  Token::Value tok = peek();

  // 'import' ModuleSpecifier ';'
  if (tok == Token::STRING) {
1056
    Scanner::Location specifier_loc = scanner()->peek_location();
1057 1058
    const AstRawString* module_specifier = ParseModuleSpecifier();
    ExpectSemicolon();
1059
    module()->AddEmptyImport(module_specifier, specifier_loc);
neis's avatar
neis committed
1060
    return;
1061 1062 1063
  }

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

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

1089
      case Token::LBRACE:
1090
        named_imports = ParseNamedImports(pos);
1091 1092 1093 1094
        break;

      default:
        ReportUnexpectedToken(scanner()->current_token());
neis's avatar
neis committed
1095
        return;
1096
    }
1097 1098
  }

1099
  ExpectContextualKeyword(ast_value_factory()->from_string());
1100
  Scanner::Location specifier_loc = scanner()->peek_location();
1101 1102
  const AstRawString* module_specifier = ParseModuleSpecifier();
  ExpectSemicolon();
1103

1104 1105 1106
  // Now that we have all the information, we can make the appropriate
  // declarations.

1107 1108 1109 1110
  // 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?
1111

1112 1113
  if (module_namespace_binding != nullptr) {
    module()->AddStarImport(module_namespace_binding, module_specifier,
1114 1115
                            module_namespace_binding_loc, specifier_loc,
                            zone());
1116 1117
  }

1118
  if (import_default_binding != nullptr) {
1119 1120
    module()->AddImport(ast_value_factory()->default_string(),
                        import_default_binding, module_specifier,
1121
                        import_default_binding_loc, specifier_loc, zone());
1122
  }
1123

1124 1125
  if (named_imports != nullptr) {
    if (named_imports->length() == 0) {
1126
      module()->AddEmptyImport(module_specifier, specifier_loc);
1127 1128 1129
    } else {
      for (int i = 0; i < named_imports->length(); ++i) {
        const NamedImport* import = named_imports->at(i);
1130
        module()->AddImport(import->import_name, import->local_name,
1131 1132
                            module_specifier, import->location, specifier_loc,
                            zone());
1133
      }
1134
    }
1135
  }
1136 1137
}

1138
Statement* Parser::ParseExportDefault() {
1139
  //  Supports the following productions, starting after the 'default' token:
1140
  //    'export' 'default' HoistableDeclaration
1141 1142 1143
  //    'export' 'default' ClassDeclaration
  //    'export' 'default' AssignmentExpression[In] ';'

1144
  Expect(Token::DEFAULT);
1145 1146
  Scanner::Location default_loc = scanner()->location();

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

    case Token::CLASS:
1155
      Consume(Token::CLASS);
1156
      result = ParseClassDeclaration(&local_names, true);
1157 1158
      break;

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

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

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

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

      Assignment* assignment = factory()->NewAssignment(
1185
          Token::INIT, proxy, value, kNoSourcePosition);
1186 1187
      result = IgnoreCompletion(
          factory()->NewExpressionStatement(assignment, kNoSourcePosition));
1188

1189
      ExpectSemicolon();
1190 1191 1192 1193
      break;
    }
  }

1194 1195 1196 1197 1198 1199
  if (result != nullptr) {
    DCHECK_EQ(local_names.length(), 1);
    module()->AddExport(local_names.first(),
                        ast_value_factory()->default_string(), default_loc,
                        zone());
  }
1200 1201 1202 1203

  return result;
}

1204 1205 1206 1207 1208 1209 1210
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());
}

1211
void Parser::ParseExportStar() {
1212 1213 1214
  int pos = position();
  Consume(Token::MUL);

1215 1216
  if (!FLAG_harmony_namespace_exports ||
      !PeekContextualKeyword(ast_value_factory()->as_string())) {
1217 1218
    // 'export' '*' 'from' ModuleSpecifier ';'
    Scanner::Location loc = scanner()->location();
1219
    ExpectContextualKeyword(ast_value_factory()->from_string());
1220
    Scanner::Location specifier_loc = scanner()->peek_location();
1221 1222
    const AstRawString* module_specifier = ParseModuleSpecifier();
    ExpectSemicolon();
1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234
    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};

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

1243
  ExpectContextualKeyword(ast_value_factory()->from_string());
1244
  Scanner::Location specifier_loc = scanner()->peek_location();
1245 1246
  const AstRawString* module_specifier = ParseModuleSpecifier();
  ExpectSemicolon();
1247 1248 1249 1250 1251 1252

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

1253
Statement* Parser::ParseExportDeclaration() {
1254
  // ExportDeclaration:
1255
  //    'export' '*' 'from' ModuleSpecifier ';'
1256
  //    'export' '*' 'as' IdentifierName 'from' ModuleSpecifier ';'
1257 1258 1259 1260
  //    'export' ExportClause ('from' ModuleSpecifier)? ';'
  //    'export' VariableStatement
  //    'export' Declaration
  //    'export' 'default' ... (handled in ParseExportDefault)
1261

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

1270
    case Token::MUL:
1271
      ParseExportStar();
1272
      return factory()->EmptyStatement();
1273

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

1317
    case Token::FUNCTION:
1318
      result = ParseHoistableDeclaration(&names, false);
1319 1320
      break;

arv@chromium.org's avatar
arv@chromium.org committed
1321
    case Token::CLASS:
1322
      Consume(Token::CLASS);
1323
      result = ParseClassDeclaration(&names, false);
arv@chromium.org's avatar
arv@chromium.org committed
1324 1325
      break;

1326 1327 1328
    case Token::VAR:
    case Token::LET:
    case Token::CONST:
1329
      result = ParseVariableStatement(kStatementListItem, &names);
1330 1331
      break;

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

1341
    default:
1342
      ReportUnexpectedToken(scanner()->current_token());
1343
      return nullptr;
1344
  }
1345
  loc.end_pos = scanner()->location().end_pos;
1346

1347
  ModuleDescriptor* descriptor = module();
1348
  for (int i = 0; i < names.length(); ++i) {
1349
    descriptor->AddExport(names[i], names[i], loc, zone());
1350 1351 1352
  }

  return result;
1353 1354
}

1355 1356 1357 1358 1359 1360 1361 1362
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);
1363 1364
}

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

1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390
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) {
1391
  Declaration* declaration;
1392 1393
  if (mode == VariableMode::kVar && !scope->is_declaration_scope()) {
    DCHECK(scope->is_block_scope() || scope->is_with_scope());
1394
    declaration = factory()->NewNestedVariableDeclaration(scope, begin);
1395
  } else {
1396
    declaration = factory()->NewVariableDeclaration(begin);
1397
  }
1398 1399
  Declare(declaration, name, kind, mode, init, scope, was_added, begin, end);
  return declaration->var();
1400 1401
}

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

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

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

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

1475 1476
  Assignment* assignment =
      factory()->NewAssignment(Token::INIT, proxy, value, class_token_pos);
1477 1478
  return IgnoreCompletion(
      factory()->NewExpressionStatement(assignment, kNoSourcePosition));
1479 1480
}

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

1499 1500
void Parser::DeclareLabel(ZonePtrList<const AstRawString>** labels,
                          ZonePtrList<const AstRawString>** own_labels,
1501
                          VariableProxy* var) {
1502
  DCHECK(IsIdentifier(var));
1503
  const AstRawString* label = var->raw_name();
1504

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

  // 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());
    }
1524
  }
1525 1526 1527
  (*labels)->Add(label, zone());
  (*own_labels)->Add(label, zone());

1528 1529 1530
  // 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.
1531
  scope()->DeleteUnresolved(var);
1532 1533
}

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

1545
Block* Parser::IgnoreCompletion(Statement* statement) {
1546
  Block* block = factory()->NewBlock(1, true);
1547 1548 1549 1550
  block->statements()->Add(statement, zone());
  return block;
}

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

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

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

1583
Statement* Parser::RewriteSwitchStatement(SwitchStatement* switch_statement,
1584
                                          Scope* scope) {
1585 1586 1587 1588 1589 1590 1591 1592 1593
  // 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* }
  //   }
  // }
1594 1595 1596 1597
  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());
1598

1599
  Block* switch_block = factory()->NewBlock(2, false);
1600

1601
  Expression* tag = switch_statement->tag();
1602
  Variable* tag_variable =
1603
      NewTemporary(ast_value_factory()->dot_switch_tag_string());
1604 1605 1606
  Assignment* tag_assign = factory()->NewAssignment(
      Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag,
      tag->position());
1607 1608 1609 1610
  // 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
1611
  switch_block->statements()->Add(tag_statement, zone());
1612

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

1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636
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));
}

1637 1638 1639 1640
Block* Parser::RewriteCatchPattern(CatchInfo* catch_info) {
  DCHECK_NOT_NULL(catch_info->pattern);

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

1643
  ScopedPtrList<Statement> init_statements(pointer_buffer());
1644
  InitializeVariables(&init_statements, NORMAL_VARIABLE, &decl);
1645
  return factory()->NewBlock(true, init_statements);
1646
}
1647

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

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

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

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

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

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

void Parser::ParseAndRewriteAsyncGeneratorFunctionBody(
1710
    int pos, FunctionKind kind, ScopedPtrList<Statement>* body) {
1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722
  // For ES2017 Async Generators, we produce:
  //
  // try {
  //   InitialYield;
  //   ...body...;
  //   return undefined; // See comment below
  // } catch (.catch) {
  //   %AsyncGeneratorReject(generator, .catch);
  // } finally {
  //   %_GeneratorClose(generator);
  // }
  //
1723 1724
  // - InitialYield yields the actual generator object.
  // - Any return statement inside the body will have its argument wrapped
1725
  //   in an iterator result object with a "done" property set to `true`.
1726 1727
  // - If the generator terminates for whatever reason, we must close it.
  //   Hence the finally clause.
1728 1729 1730
  // - 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.
1731
  DCHECK(IsAsyncGeneratorFunction(kind));
1732

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

1741 1742 1743 1744 1745 1746 1747 1748 1749 1750
    // 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);
  }
1751

1752
  // For AsyncGenerators, a top-level catch block will reject the Promise.
1753
  Scope* catch_scope = NewHiddenCatchScope();
1754

1755 1756 1757 1758 1759 1760
  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()));
1761

1762 1763 1764 1765 1766
    Expression* reject_call = factory()->NewCallRuntime(
        Runtime::kInlineAsyncGeneratorReject, reject_args, kNoSourcePosition);
    catch_block = IgnoreCompletion(
        factory()->NewReturnStatement(reject_call, kNoSourcePosition));
  }
1767

1768 1769 1770 1771 1772 1773 1774
  {
    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);
  }
1775

1776 1777 1778 1779 1780 1781 1782 1783 1784
  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);
  }
1785

1786 1787 1788 1789 1790 1791 1792
  Block* finally_block;
  {
    ScopedPtrList<Statement> statements(pointer_buffer());
    statements.Add(
        factory()->NewExpressionStatement(close_call, kNoSourcePosition));
    finally_block = factory()->NewBlock(false, statements);
  }
1793 1794

  body->Add(factory()->NewTryFinallyStatement(try_block, finally_block,
1795
                                              kNoSourcePosition));
1796 1797
}

1798 1799 1800 1801 1802 1803 1804
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);
1805 1806 1807
  }
}

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

1870
  *body_block = factory()->NewBlock(3, false);
1871 1872 1873
  (*body_block)
      ->statements()
      ->Add(factory()->NewBlock(true, each_initialization_statements), zone());
1874
  *each_variable = factory()->NewVariableProxy(temp, for_info->position);
1875 1876 1877 1878
}

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

1883
    init_block = factory()->NewBlock(1, false);
1884 1885 1886 1887 1888

    for (int i = 0; i < for_info.bound_names.length(); ++i) {
      // TODO(adamk): This needs to be some sort of special
      // INTERNAL variable that's invisible to the debugger
      // but visible to everything else.
1889
      VariableProxy* tdz_proxy = DeclareBoundVariable(
1890
          for_info.bound_names[i], VariableMode::kLet, kNoSourcePosition);
1891
      tdz_proxy->var()->set_initializer_position(position());
1892 1893 1894 1895 1896
    }
  }
  return init_block;
}

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

1937
  DCHECK_GT(for_info.bound_names.length(), 0);
1938
  ZonePtrList<Variable> temps(for_info.bound_names.length(), zone());
1939

1940 1941
  Block* outer_block =
      factory()->NewBlock(for_info.bound_names.length() + 4, false);
1942

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

1946
  const AstRawString* temp_name = ast_value_factory()->dot_for_string();
1947

rossberg's avatar
rossberg committed
1948
  // For each lexical variable x:
1949
  //   make statement: temp_x = x.
1950 1951
  for (int i = 0; i < for_info.bound_names.length(); i++) {
    VariableProxy* proxy = NewUnresolved(for_info.bound_names[i]);
1952
    Variable* temp = NewTemporary(temp_name);
1953
    VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
yangguo's avatar
yangguo committed
1954 1955 1956 1957
    Assignment* assignment = factory()->NewAssignment(Token::ASSIGN, temp_proxy,
                                                      proxy, kNoSourcePosition);
    Statement* assignment_statement =
        factory()->NewExpressionStatement(assignment, kNoSourcePosition);
neis's avatar
neis committed
1958
    outer_block->statements()->Add(assignment_statement, zone());
1959 1960 1961
    temps.Add(temp, zone());
  }

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

1975
  // make statement: undefined;
neis's avatar
neis committed
1976
  outer_block->statements()->Add(
1977
      factory()->NewExpressionStatement(
yangguo's avatar
yangguo committed
1978
          factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
1979 1980
      zone());

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

1991
  Block* inner_block = factory()->NewBlock(3, false);
1992
  {
1993
    BlockState block_state(&scope_, inner_scope);
1994

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

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

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

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

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

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

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

yangguo's avatar
yangguo committed
2098 2099
      compound_next_statement =
          factory()->NewExpressionStatement(compound_next, kNoSourcePosition);
2100
    }
2101

2102 2103 2104 2105
    // 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.
2106
    loop->Initialize(nullptr, flag_cond, compound_next_statement, body);
2107 2108 2109
    inner_block->statements()->Add(loop, zone());

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

2127 2128
    inner_block->set_scope(inner_scope);
  }
2129

2130
  outer_loop->Initialize(nullptr, nullptr, nullptr, inner_block);
2131

2132 2133 2134
  return outer_block;
}

2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145
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);
  }
}

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

  // 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) {
2173 2174
      AddArrowFunctionFormalParameters(parameters, next,
                                       nary->subsequent_op_position(i));
2175 2176
      next = nary->subsequent(i);
    }
2177
    AddArrowFunctionFormalParameters(parameters, next, end_pos);
2178 2179 2180 2181 2182
    return;
  }

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

2196
  // Only the right-most expression may be a rest parameter.
2197
  DCHECK(!parameters->has_rest);
2198

2199
  bool is_rest = expr->IsSpread();
2200 2201 2202 2203
  if (is_rest) {
    expr = expr->AsSpread()->expression();
    parameters->has_rest = true;
  }
2204 2205
  DCHECK_IMPLIES(parameters->is_simple, !is_rest);
  DCHECK_IMPLIES(parameters->is_simple, expr->IsVariableProxy());
2206

2207
  Expression* initializer = nullptr;
2208
  if (expr->IsAssignment()) {
2209
    Assignment* assignment = expr->AsAssignment();
2210
    DCHECK(!assignment->IsCompoundAssignment());
2211 2212
    initializer = assignment->value();
    expr = assignment->target();
2213 2214
  }

2215
  AddFormalParameter(parameters, expr, initializer, end_pos, is_rest);
2216 2217
}

2218
void Parser::DeclareArrowFunctionFormalParameters(
2219
    ParserFormalParameters* parameters, Expression* expr,
2220
    const Scanner::Location& params_loc) {
2221
  if (expr->IsEmptyParentheses() || has_error()) return;
2222

2223
  AddArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos);
2224

2225
  if (parameters->arity > Code::kMaxArguments) {
2226
    ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
2227 2228 2229
    return;
  }

2230
  DeclareFormalParameters(parameters);
2231 2232
  DCHECK_IMPLIES(parameters->is_simple,
                 parameters->scope->has_simple_parameters());
2233 2234
}

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

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

2258 2259 2260
  bool is_wrapped = function_type == FunctionLiteral::kWrapped;
  DCHECK_EQ(is_wrapped, arguments_for_wrapped_function != nullptr);

yangguo's avatar
yangguo committed
2261 2262
  int pos = function_token_pos == kNoSourcePosition ? peek_position()
                                                    : function_token_pos;
2263
  DCHECK_NE(kNoSourcePosition, pos);
2264

2265 2266 2267
  // 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.
2268
  bool should_infer_name = function_name == nullptr;
2269

2270 2271 2272 2273 2274 2275
  // 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();
  }

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

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

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

2317 2318
  const bool is_lazy =
      eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
2319
  const bool is_top_level = AllowsLazyParsingWithoutUnresolvedVariables();
2320
  const bool is_eager_top_level_function = !is_lazy && is_top_level;
2321 2322
  const bool is_lazy_top_level_function = is_lazy && is_top_level;
  const bool is_lazy_inner_function = is_lazy && !is_top_level;
2323

2324 2325 2326
  RuntimeCallTimerScope runtime_timer(
      runtime_call_stats_,
      parsing_on_main_thread_
2327 2328
          ? RuntimeCallCounterId::kParseFunctionLiteral
          : RuntimeCallCounterId::kParseBackgroundFunctionLiteral);
2329 2330
  base::ElapsedTimer timer;
  if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
2331

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

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

2349
  const bool should_preparse_inner = parse_lazily() && is_lazy_inner_function;
2350

2351 2352 2353 2354 2355 2356 2357 2358
  // 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();

2359
  // This may be modified later to reflect preparsing decision taken
2360 2361
  bool should_preparse = (parse_lazily() && is_lazy_top_level_function) ||
                         should_preparse_inner || should_post_parallel_task;
2362

2363
  ScopedPtrList<Statement> body(pointer_buffer());
2364
  int expected_property_count = -1;
2365
  int suspend_count = -1;
2366 2367 2368
  int num_parameters = -1;
  int function_length = -1;
  bool has_duplicate_parameters = false;
2369
  int function_literal_id = GetNextFunctionLiteralId();
2370
  ProducedPreparseData* produced_preparse_data = nullptr;
2371

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

2380 2381 2382
  if (!is_wrapped && V8_UNLIKELY(!Check(Token::LPAREN))) {
    ReportUnexpectedToken(Next());
    return nullptr;
2383
  }
2384
  scope->set_start_position(position());
2385 2386 2387 2388 2389 2390

  // 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.
2391
  bool did_preparse_successfully =
2392 2393
      should_preparse && SkipFunction(function_name, kind, function_type, scope,
                                      &num_parameters, &produced_preparse_data);
2394

2395
  if (!did_preparse_successfully) {
2396 2397 2398
    // If skipping aborted, it rewound the scanner until before the LPAREN.
    // Consume it in that case.
    if (should_preparse) Consume(Token::LPAREN);
2399
    should_post_parallel_task = false;
2400 2401 2402 2403
    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);
2404
  }
2405

2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417
  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());
  }
2418
  if (V8_UNLIKELY(FLAG_runtime_stats) && did_preparse_successfully) {
2419 2420 2421
    const RuntimeCallCounterId counters[2] = {
        RuntimeCallCounterId::kPreParseBackgroundWithVariableResolution,
        RuntimeCallCounterId::kPreParseWithVariableResolution};
2422 2423
    if (runtime_call_stats_) {
      runtime_call_stats_->CorrectCurrentCounterId(
2424
          counters[parsing_on_main_thread_]);
2425
    }
2426
  }
2427

2428 2429 2430 2431
  // 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,
2432
                    function_name_location);
2433

2434
  if (is_strict(language_mode)) {
2435
    CheckStrictOctalLiteral(scope->start_position(), scope->end_position());
2436
  }
2437

2438
  FunctionLiteral::ParameterFlag duplicate_parameters =
2439 2440
      has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
                               : FunctionLiteral::kNoDuplicateParameters;
2441

2442
  // Note that the FunctionLiteral needs to be created in the main Zone again.
2443
  FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
2444 2445
      function_name, scope, body, expected_property_count, num_parameters,
      function_length, duplicate_parameters, function_type, eager_compile_hint,
2446
      pos, true, function_literal_id, produced_preparse_data);
2447
  function_literal->set_function_token_position(function_token_pos);
2448
  function_literal->set_suspend_count(suspend_count);
2449

2450 2451 2452 2453 2454
  if (should_post_parallel_task) {
    // Start a parallel parse / compile task on the compiler dispatcher.
    info()->parallel_tasks()->Enqueue(info(), function_name, function_literal);
  }

2455
  if (should_infer_name) {
2456
    fni_.AddFunction(function_literal);
2457
  }
2458
  return function_literal;
2459 2460
}

2461 2462 2463 2464
bool Parser::SkipFunction(const AstRawString* function_name, FunctionKind kind,
                          FunctionLiteral::FunctionType function_type,
                          DeclarationScope* function_scope, int* num_parameters,
                          ProducedPreparseData** produced_preparse_data) {
2465
  FunctionState function_state(&function_state_, &scope_, function_scope);
2466
  function_scope->set_zone(&preparser_zone_);
2467

2468
  DCHECK_NE(kNoSourcePosition, function_scope->start_position());
2469
  DCHECK_EQ(kNoSourcePosition, parameters_end_pos_);
2470

2471 2472 2473
  DCHECK_IMPLIES(IsArrowFunction(kind),
                 scanner()->current_token() == Token::ARROW);

2474
  // FIXME(marja): There are 2 ways to skip functions now. Unify them.
2475
  if (consumed_preparse_data_) {
2476 2477 2478 2479
    int end_position;
    LanguageMode language_mode;
    int num_inner_functions;
    bool uses_super_property;
2480
    if (stack_overflow()) return true;
2481 2482
    *produced_preparse_data =
        consumed_preparse_data_->GetDataForSkippableFunction(
2483 2484 2485 2486
            main_zone(), function_scope->start_position(), &end_position,
            num_parameters, &num_inner_functions, &uses_super_property,
            &language_mode);

2487
    function_scope->outer_scope()->SetMustUsePreparseData();
2488 2489 2490
    function_scope->set_is_skipped_function(true);
    function_scope->set_end_position(end_position);
    scanner()->SeekForward(end_position - 1);
2491
    Expect(Token::RBRACE);
2492 2493 2494
    SetLanguageMode(function_scope, language_mode);
    if (uses_super_property) {
      function_scope->RecordSuperPropertyUsage();
2495
    }
2496
    SkipFunctionLiterals(num_inner_functions);
2497
    function_scope->ResetAfterPreparsing(ast_value_factory_, false);
2498
    return true;
2499 2500
  }

2501
  Scanner::BookmarkScope bookmark(scanner());
2502
  bookmark.Set(function_scope->start_position());
2503

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

2508
  PreParser::PreParseResult result = reusable_preparser()->PreParseFunction(
2509
      function_name, kind, function_type, function_scope, use_counts_,
2510
      produced_preparse_data, this->script_id());
2511

2512 2513 2514
  if (result == PreParser::kPreParseStackOverflow) {
    // Propagate stack overflow.
    set_stack_overflow();
2515
  } else if (pending_error_handler()->has_error_unidentifiable_by_preparser()) {
2516 2517 2518 2519
    // 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;
2520
    DCHECK(!pending_error_handler()->stack_overflow());
2521 2522 2523 2524 2525
    // 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();
    function_scope->ResetAfterPreparsing(ast_value_factory(), true);
2526
    pending_error_handler()->clear_unidentifiable_error();
2527
    return false;
2528
  } else if (pending_error_handler()->has_pending_error()) {
2529
    DCHECK(!pending_error_handler()->stack_overflow());
2530
    DCHECK(has_error());
2531
  } else {
2532
    DCHECK(!pending_error_handler()->stack_overflow());
2533
    set_allow_eval_cache(reusable_preparser()->allow_eval_cache());
2534

2535 2536
    PreParserLogger* logger = reusable_preparser()->logger();
    function_scope->set_end_position(logger->end());
2537
    Expect(Token::RBRACE);
2538 2539 2540 2541
    total_preparse_skipped_ +=
        function_scope->end_position() - function_scope->start_position();
    *num_parameters = logger->num_parameters();
    SkipFunctionLiterals(logger->num_inner_functions());
2542
    function_scope->AnalyzePartially(this, factory());
2543
  }
2544

2545
  return true;
2546 2547
}

2548
Block* Parser::BuildParameterInitializationBlock(
2549
    const ParserFormalParameters& parameters) {
2550
  DCHECK(!parameters.is_simple);
2551
  DCHECK(scope()->is_function_scope());
2552
  DCHECK_EQ(scope(), parameters.scope);
2553
  ScopedPtrList<Statement> init_statements(pointer_buffer());
2554 2555
  int index = 0;
  for (auto parameter : parameters.params) {
2556
    Expression* initial_value =
2557
        factory()->NewVariableProxy(parameters.scope->parameter(index));
2558
    if (parameter->initializer() != nullptr) {
2559
      // IS_UNDEFINED($param) ? initializer : $param
2560

2561 2562
      auto condition = factory()->NewCompareOperation(
          Token::EQ_STRICT,
2563
          factory()->NewVariableProxy(parameters.scope->parameter(index)),
yangguo's avatar
yangguo committed
2564
          factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
2565 2566 2567
      initial_value =
          factory()->NewConditional(condition, parameter->initializer(),
                                    initial_value, kNoSourcePosition);
2568
    }
2569

2570
    Scope* param_scope = scope();
2571 2572 2573
    ScopedPtrList<Statement>* param_init_statements = &init_statements;

    base::Optional<ScopedPtrList<Statement>> non_simple_param_init_statements;
2574 2575
    if (!parameter->is_simple() &&
        scope()->AsDeclarationScope()->calls_sloppy_eval()) {
2576
      param_scope = NewVarblockScope();
2577
      param_scope->set_start_position(parameter->pattern->position());
2578
      param_scope->set_end_position(parameter->initializer_end_position);
2579
      param_scope->RecordEvalCall();
2580 2581
      non_simple_param_init_statements.emplace(pointer_buffer());
      param_init_statements = &non_simple_param_init_statements.value();
2582
      // Rewrite the outer initializer to point to param_scope
2583
      ReparentExpressionScope(stack_limit(), parameter->pattern, param_scope);
2584
      ReparentExpressionScope(stack_limit(), initial_value, param_scope);
2585 2586
    }

2587
    BlockState block_state(&scope_, param_scope);
2588 2589
    DeclarationParsingResult::Declaration decl(parameter->pattern,
                                               initial_value);
2590

2591
    InitializeVariables(param_init_statements, PARAMETER_VARIABLE, &decl);
2592 2593 2594 2595 2596 2597 2598 2599

    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);
2600
      param_scope = param_scope->FinalizeBlockScope();
2601
      init_statements.Add(param_block);
2602
    }
2603
    ++index;
2604
  }
2605
  return factory()->NewBlock(true, init_statements);
2606 2607
}

2608 2609
Scope* Parser::NewHiddenCatchScope() {
  Scope* catch_scope = NewScopeWithParent(scope(), CATCH_SCOPE);
2610
  bool was_added;
2611
  catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(),
2612 2613
                            VariableMode::kVar, NORMAL_VARIABLE, &was_added);
  DCHECK(was_added);
2614 2615 2616 2617
  catch_scope->set_is_hidden();
  return catch_scope;
}

2618
Block* Parser::BuildRejectPromiseOnException(Block* inner_block) {
2619 2620 2621
  // try {
  //   <inner_block>
  // } catch (.catch) {
2622
  //   return %_AsyncFunctionReject(.generator_object, .catch, can_suspend);
2623
  // }
2624
  Block* result = factory()->NewBlock(1, true);
2625

2626
  // catch (.catch) {
2627
  //   return %_AsyncFunctionReject(.generator_object, .catch, can_suspend)
2628
  // }
2629
  Scope* catch_scope = NewHiddenCatchScope();
2630

2631
  Expression* reject_promise;
2632
  {
2633
    ScopedPtrList<Expression> args(pointer_buffer());
2634 2635 2636 2637 2638
    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));
2639 2640
    reject_promise = factory()->NewCallRuntime(
        Runtime::kInlineAsyncFunctionReject, args, kNoSourcePosition);
2641
  }
2642 2643
  Block* catch_block = IgnoreCompletion(
      factory()->NewReturnStatement(reject_promise, kNoSourcePosition));
2644

2645 2646 2647 2648
  TryStatement* try_catch_statement =
      factory()->NewTryCatchStatementForAsyncAwait(
          inner_block, catch_scope, catch_block, kNoSourcePosition);
  result->statements()->Add(try_catch_statement, zone());
2649
  return result;
2650 2651
}

2652
Expression* Parser::BuildInitialYield(int pos, FunctionKind kind) {
2653 2654
  Expression* yield_result = factory()->NewVariableProxy(
      function_state_->scope()->generator_object_var());
2655 2656 2657
  // 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).
2658
  function_state_->AddSuspend();
2659 2660
  return factory()->NewYield(yield_result, scope()->start_position(),
                             Suspend::kOnExceptionThrow);
2661 2662
}

2663 2664 2665
void Parser::ParseFunction(
    ScopedPtrList<Statement>* body, const AstRawString* function_name, int pos,
    FunctionKind kind, FunctionLiteral::FunctionType function_type,
2666
    DeclarationScope* function_scope, int* num_parameters, int* function_length,
2667
    bool* has_duplicate_parameters, int* expected_property_count,
2668
    int* suspend_count,
2669
    ZonePtrList<const AstRawString>* arguments_for_wrapped_function) {
2670 2671
  ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);

2672
  FunctionState function_state(&function_state_, &scope_, function_scope);
2673

2674 2675
  bool is_wrapped = function_type == FunctionLiteral::kWrapped;

2676 2677 2678 2679
  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;
2680
    // The function name should have been ignored, giving us the empty string
2681
    // here.
2682
    DCHECK_EQ(function_name, ast_value_factory()->empty_string());
2683 2684
  }

2685
  ParserFormalParameters formals(function_scope);
2686

2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699
  {
    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.
      int arguments_length = arguments_for_wrapped_function->length();
      for (int i = 0; i < arguments_length; i++) {
        const bool is_rest = false;
        Expression* argument = ExpressionFromIdentifier(
            arguments_for_wrapped_function->at(i), kNoSourcePosition);
        AddFormalParameter(&formals, argument, NullExpression(),
                           kNoSourcePosition, is_rest);
2700
      }
2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723
      DCHECK_EQ(arguments_length, formals.num_parameters());
      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;
2724

2725 2726 2727 2728 2729
      CheckArityRestrictions(formals.arity, kind, formals.has_rest,
                             function_scope->start_position(),
                             formals_end_position);
      Expect(Token::LBRACE);
    }
2730
    formals.duplicate_loc = formals_scope.duplicate_location();
2731
  }
2732

2733 2734 2735
  *num_parameters = formals.num_parameters();
  *function_length = formals.function_length;

2736
  AcceptINScope scope(this, true);
2737
  ParseFunctionBody(body, function_name, pos, formals, kind, function_type,
2738
                    FunctionBodyType::kBlock);
2739

2740
  *has_duplicate_parameters = formals.has_duplicate();
2741 2742

  *expected_property_count = function_state.expected_property_count();
2743
  *suspend_count = function_state.suspend_count();
2744 2745
}

2746
void Parser::DeclareClassVariable(const AstRawString* name,
2747
                                  ClassInfo* class_info, int class_token_pos) {
2748
#ifdef DEBUG
2749
  scope()->SetScopeName(name);
2750
#endif
2751

2752
  if (name != nullptr) {
2753
    VariableProxy* proxy =
2754
        DeclareBoundVariable(name, VariableMode::kConst, class_token_pos);
2755
    class_info->variable = proxy->var();
2756 2757 2758
  }
}

2759 2760 2761
// 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.
2762
Variable* Parser::CreateSyntheticContextVariable(const AstRawString* name) {
2763
  VariableProxy* proxy =
2764
      DeclareBoundVariable(name, VariableMode::kConst, kNoSourcePosition);
2765 2766
  proxy->var()->ForceContextAllocation();
  return proxy->var();
2767 2768
}

2769 2770 2771 2772
void Parser::DeclareClassField(ClassLiteralProperty* property,
                               const AstRawString* property_name,
                               bool is_static, bool is_computed_name,
                               bool is_private, ClassInfo* class_info) {
2773
  DCHECK(allow_harmony_public_fields() || allow_harmony_private_fields());
2774 2775

  if (is_static) {
2776 2777
    class_info->static_fields->Add(property, zone());
  } else {
2778 2779 2780
    class_info->instance_fields->Add(property, zone());
  }

2781
  DCHECK_IMPLIES(is_computed_name, !is_private);
2782
  if (is_computed_name) {
2783 2784
    // We create a synthetic variable name here so that scope
    // analysis doesn't dedupe the vars.
2785 2786 2787
    Variable* computed_name_var =
        CreateSyntheticContextVariable(ClassFieldVariableName(
            ast_value_factory(), class_info->computed_field_count));
2788
    property->set_computed_name_var(computed_name_var);
2789
    class_info->properties->Add(property, zone());
2790
  } else if (is_private) {
2791
    Variable* private_name_var = CreateSyntheticContextVariable(property_name);
2792
    private_name_var->set_initializer_position(property->value()->position());
2793
    property->set_private_name_var(private_name_var);
2794 2795
    class_info->properties->Add(property, zone());
  }
2796 2797
}

2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817
// This method declares a property of the given class.  It updates the
// following fields of class_info, as appropriate:
//   - constructor
//   - properties
void Parser::DeclareClassProperty(const AstRawString* class_name,
                                  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());
}

2818
FunctionLiteral* Parser::CreateInitializerFunction(
2819 2820
    const char* name, DeclarationScope* scope,
    ZonePtrList<ClassLiteral::Property>* fields) {
2821
  DCHECK_EQ(scope->function_kind(),
2822
            FunctionKind::kClassMembersInitializerFunction);
2823
  // function() { .. class fields initializer .. }
2824
  ScopedPtrList<Statement> statements(pointer_buffer());
2825 2826
  InitializeClassMembersStatement* static_fields =
      factory()->NewInitializeClassMembersStatement(fields, kNoSourcePosition);
2827
  statements.Add(static_fields);
2828
  return factory()->NewFunctionLiteral(
2829
      ast_value_factory()->GetOneByteString(name), scope, statements, 0, 0, 0,
2830 2831
      FunctionLiteral::kNoDuplicateParameters,
      FunctionLiteral::kAnonymousExpression,
2832
      FunctionLiteral::kShouldEagerCompile, scope->start_position(), false,
2833 2834 2835
      GetNextFunctionLiteralId());
}

2836
// This method generates a ClassLiteral AST node.
2837 2838 2839 2840 2841
// It uses the following fields of class_info:
//   - constructor (if missing, it updates it with a default constructor)
//   - proxy
//   - extends
//   - properties
2842 2843
//   - has_name_static_property
//   - has_static_computed_names
2844 2845
Expression* Parser::RewriteClassLiteral(Scope* block_scope,
                                        const AstRawString* name,
2846
                                        ClassInfo* class_info, int pos,
2847
                                        int end_pos) {
2848 2849
  DCHECK_NOT_NULL(block_scope);
  DCHECK_EQ(block_scope->scope_type(), BLOCK_SCOPE);
2850
  DCHECK_EQ(block_scope->language_mode(), LanguageMode::kStrict);
2851

2852 2853
  bool has_extends = class_info->extends != nullptr;
  bool has_default_constructor = class_info->constructor == nullptr;
2854
  if (has_default_constructor) {
2855 2856
    class_info->constructor =
        DefaultConstructor(name, has_extends, pos, end_pos);
2857 2858
  }

2859
  if (name != nullptr) {
2860 2861
    DCHECK_NOT_NULL(class_info->variable);
    class_info->variable->set_initializer_position(end_pos);
2862 2863
  }

2864 2865
  FunctionLiteral* static_fields_initializer = nullptr;
  if (class_info->has_static_class_fields) {
2866
    static_fields_initializer = CreateInitializerFunction(
2867 2868
        "<static_fields_initializer>", class_info->static_fields_scope,
        class_info->static_fields);
2869 2870
  }

2871 2872 2873 2874
  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,
2875
        class_info->instance_fields);
2876
    class_info->constructor->set_requires_instance_members_initializer(true);
2877 2878
  }

2879
  ClassLiteral* class_literal = factory()->NewClassLiteral(
2880
      block_scope, class_info->variable, class_info->extends,
2881
      class_info->constructor, class_info->properties,
2882
      static_fields_initializer, instance_members_initializer_function, pos,
2883
      end_pos, class_info->has_name_static_property,
2884
      class_info->has_static_computed_names, class_info->is_anonymous);
2885

2886
  AddFunctionForNameInference(class_info->constructor);
2887
  return class_literal;
2888 2889
}

2890 2891 2892 2893 2894 2895 2896
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();

2897
  return key->IsPrivateName();
2898
}
2899

2900 2901 2902 2903 2904 2905 2906
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());
2907
  BlockState block_state(&scope_, inner_scope);
2908
  for (Declaration* decl : *inner_scope->declarations()) {
2909
    if (decl->var()->mode() != VariableMode::kVar ||
2910
        !decl->IsVariableDeclaration()) {
2911 2912
      continue;
    }
2913
    const AstRawString* name = decl->var()->raw_name();
2914 2915
    Variable* parameter = function_scope->LookupLocal(name);
    if (parameter == nullptr) continue;
2916
    VariableProxy* to = NewUnresolved(name);
2917
    VariableProxy* from = factory()->NewVariableProxy(parameter);
yangguo's avatar
yangguo committed
2918 2919 2920 2921
    Expression* assignment =
        factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition);
    Statement* statement =
        factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2922 2923 2924 2925
    inner_block->statements()->InsertAt(0, statement, zone());
  }
}

2926 2927 2928 2929 2930 2931 2932
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;
2933
  }
2934
  scope->HoistSloppyBlockFunctions(factory());
2935 2936
}

2937 2938 2939
// ----------------------------------------------------------------------------
// Parser support

2940
bool Parser::TargetStackContainsLabel(const AstRawString* label) {
2941
  for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
2942
    if (ContainsLabel(t->statement()->labels(), label)) return true;
2943 2944 2945 2946
  }
  return false;
}

2947
BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label) {
2948 2949
  bool anonymous = label == nullptr;
  for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
2950
    BreakableStatement* stat = t->statement();
2951 2952 2953 2954 2955
    if ((anonymous && stat->is_target_for_anonymous()) ||
        (!anonymous && ContainsLabel(stat->labels(), label))) {
      return stat;
    }
  }
2956
  return nullptr;
2957 2958
}

2959
IterationStatement* Parser::LookupContinueTarget(const AstRawString* label) {
2960 2961
  bool anonymous = label == nullptr;
  for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
2962
    IterationStatement* stat = t->statement()->AsIterationStatement();
2963
    if (stat == nullptr) continue;
2964

2965
    DCHECK(stat->is_target_for_anonymous());
2966
    if (anonymous || ContainsLabel(stat->own_labels(), label)) {
2967 2968
      return stat;
    }
2969
    if (ContainsLabel(stat->labels(), label)) break;
2970
  }
2971
  return nullptr;
2972 2973
}

2974
void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) {
2975 2976
  Handle<String> source_url = scanner_.SourceUrl(isolate);
  if (!source_url.is_null()) {
2977
    script->set_source_url(*source_url);
2978
  }
2979 2980
  Handle<String> source_mapping_url = scanner_.SourceMappingUrl(isolate);
  if (!source_mapping_url.is_null()) {
2981
    script->set_source_mapping_url(*source_mapping_url);
2982 2983 2984
  }
}

2985
void Parser::UpdateStatistics(Isolate* isolate, Handle<Script> script) {
2986
  // Move statistics to Isolate.
2987 2988
  for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
       ++feature) {
2989
    if (use_counts_[feature] > 0) {
2990
      isolate->CountUsage(v8::Isolate::UseCounterFeature(feature));
2991 2992
    }
  }
2993 2994 2995 2996 2997 2998
  if (scanner_.FoundHtmlComment()) {
    isolate->CountUsage(v8::Isolate::kHtmlComment);
    if (script->line_offset() == 0 && script->column_offset() == 0) {
      isolate->CountUsage(v8::Isolate::kHtmlCommentInExternalScript);
    }
  }
2999
  isolate->counters()->total_preparse_skipped()->Increment(
3000
      total_preparse_skipped_);
3001 3002
}

3003
void Parser::ParseOnBackground(ParseInfo* info) {
3004 3005
  RuntimeCallTimerScope runtimeTimer(
      runtime_call_stats_, RuntimeCallCounterId::kParseBackgroundProgram);
3006
  parsing_on_main_thread_ = false;
3007
  set_script_id(info->script_id());
3008

3009
  DCHECK_NULL(info->literal());
3010
  FunctionLiteral* result = nullptr;
3011

3012
  scanner_.Initialize();
3013
  DCHECK(info->maybe_outer_scope_info().is_null());
3014

3015 3016
  DCHECK(original_scope_);

3017 3018 3019 3020 3021 3022
  // 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
3023
  if (info->is_toplevel()) {
3024
    result = DoParseProgram(/* isolate = */ nullptr, info);
verwaest's avatar
verwaest committed
3025
  } else {
3026 3027
    result =
        DoParseFunction(/* isolate = */ nullptr, info, info->function_name());
3028
  }
3029
  MaybeResetCharacterStream(info, result);
3030

3031
  info->set_literal(result);
3032 3033

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

3037 3038
Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
  return new (zone()) TemplateLiteral(zone(), pos);
3039 3040
}

3041 3042
void Parser::AddTemplateSpan(TemplateLiteralState* state, bool should_cook,
                             bool tail) {
3043
  int end = scanner()->location().end_pos - (tail ? 1 : 2);
3044
  const AstRawString* raw = scanner()->CurrentRawSymbol(ast_value_factory());
3045
  if (should_cook) {
3046
    const AstRawString* cooked = scanner()->CurrentSymbol(ast_value_factory());
3047 3048
    (*state)->AddTemplateSpan(cooked, raw, end, zone());
  } else {
3049
    (*state)->AddTemplateSpan(nullptr, raw, end, zone());
3050
  }
3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061
}

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();
3062 3063 3064
  const ZonePtrList<const AstRawString>* cooked_strings = lit->cooked();
  const ZonePtrList<const AstRawString>* raw_strings = lit->raw();
  const ZonePtrList<Expression>* expressions = lit->expressions();
3065 3066
  DCHECK_EQ(cooked_strings->length(), raw_strings->length());
  DCHECK_EQ(cooked_strings->length(), expressions->length() + 1);
3067 3068

  if (!tag) {
3069 3070
    if (cooked_strings->length() == 1) {
      return factory()->NewStringLiteral(cooked_strings->first(), pos);
3071
    }
3072
    return factory()->NewTemplateLiteral(cooked_strings, expressions, pos);
3073
  } else {
3074
    // GetTemplateObject
3075
    Expression* template_object =
3076
        factory()->NewGetTemplateObject(cooked_strings, raw_strings, pos);
3077 3078

    // Call TagFn
3079
    ScopedPtrList<Expression> call_args(pointer_buffer());
3080 3081
    call_args.Add(template_object);
    call_args.AddAll(*expressions);
3082
    return factory()->NewTaggedTemplate(tag, call_args, pos);
3083 3084 3085
  }
}

3086 3087
namespace {

3088 3089 3090
bool OnlyLastArgIsSpread(const ScopedPtrList<Expression>& args) {
  for (int i = 0; i < args.length() - 1; i++) {
    if (args.at(i)->IsSpread()) {
3091 3092 3093
      return false;
    }
  }
3094
  return args.at(args.length() - 1)->IsSpread();
3095 3096 3097 3098
}

}  // namespace

3099
ArrayLiteral* Parser::ArrayLiteralFromListWithSpread(
3100
    const ScopedPtrList<Expression>& list) {
3101 3102
  // If there's only a single spread argument, a fast path using CallWithSpread
  // is taken.
3103
  DCHECK_LT(1, list.length());
3104

3105 3106
  // The arguments of the spread call become a single ArrayLiteral.
  int first_spread = 0;
3107
  for (; first_spread < list.length() && !list.at(first_spread)->IsSpread();
3108
       ++first_spread) {
3109
  }
3110

3111
  DCHECK_LT(first_spread, list.length());
3112
  return factory()->NewArrayLiteral(list, first_spread, kNoSourcePosition);
3113 3114 3115
}

Expression* Parser::SpreadCall(Expression* function,
3116 3117
                               const ScopedPtrList<Expression>& args_list,
                               int pos, Call::PossiblyEval is_possibly_eval) {
3118
  // Handle this case in BytecodeGenerator.
3119
  if (OnlyLastArgIsSpread(args_list) || function->IsSuperCallReference()) {
3120
    return factory()->NewCall(function, args_list, pos);
3121 3122
  }

3123
  ScopedPtrList<Expression> args(pointer_buffer());
3124 3125 3126
  if (function->IsProperty()) {
    // Method calls
    if (function->AsProperty()->IsSuperAccess()) {
3127
      Expression* home = ThisExpression();
3128 3129
      args.Add(function);
      args.Add(home);
3130
    } else {
3131 3132 3133 3134 3135 3136
      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);
3137
      args.Add(function);
3138
      obj = factory()->NewVariableProxy(temp);
3139
      args.Add(obj);
3140
    }
3141 3142
  } else {
    // Non-method calls
3143 3144
    args.Add(function);
    args.Add(factory()->NewUndefinedLiteral(kNoSourcePosition));
3145
  }
3146
  args.Add(ArrayLiteralFromListWithSpread(args_list));
3147
  return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos);
3148 3149 3150
}

Expression* Parser::SpreadCallNew(Expression* function,
3151 3152
                                  const ScopedPtrList<Expression>& args_list,
                                  int pos) {
3153
  if (OnlyLastArgIsSpread(args_list)) {
3154
    // Handle in BytecodeGenerator.
3155
    return factory()->NewCallNew(function, args_list, pos);
3156
  }
3157
  ScopedPtrList<Expression> args(pointer_buffer());
3158 3159
  args.Add(function);
  args.Add(ArrayLiteralFromListWithSpread(args_list));
3160

3161
  return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos);
3162
}
3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175

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

3176 3177 3178 3179 3180
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());
3181 3182
  scope()->AsDeclarationScope()->set_is_asm_module();
  info_->set_contains_asm_module(true);
3183 3184
}

3185 3186 3187
Expression* Parser::ExpressionListToExpression(
    const ScopedPtrList<Expression>& args) {
  Expression* expr = args.at(0);
3188 3189 3190
  if (args.length() == 1) return expr;
  if (args.length() == 2) {
    return factory()->NewBinaryOperation(Token::COMMA, expr, args.at(1),
3191
                                         args.at(1)->position());
3192
  }
3193 3194 3195
  NaryOperation* result =
      factory()->NewNaryOperation(Token::COMMA, expr, args.length() - 1);
  for (int i = 1; i < args.length(); i++) {
3196
    result->AddSubsequent(args.at(i), args.at(i)->position());
3197 3198
  }
  return result;
3199 3200
}

3201
// This method completes the desugaring of the body of async_function.
3202
void Parser::RewriteAsyncFunctionBody(ScopedPtrList<Statement>* body,
3203
                                      Block* block, Expression* return_value) {
3204
  // function async_function() {
3205
  //   .generator_object = %_AsyncFunctionEnter();
3206 3207
  //   BuildRejectPromiseOnException({
  //     ... block ...
3208
  //     return %_AsyncFunctionResolve(.generator_object, expr);
3209 3210 3211
  //   })
  // }

3212 3213 3214
  block->statements()->Add(factory()->NewAsyncReturnStatement(
                               return_value, return_value->position()),
                           zone());
3215
  block = BuildRejectPromiseOnException(block);
3216
  body->Add(block);
3217 3218
}

3219 3220 3221
void Parser::SetFunctionNameFromPropertyName(LiteralProperty* property,
                                             const AstRawString* name,
                                             const AstRawString* prefix) {
3222
  if (has_error()) return;
3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239
  // 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);
3240 3241
}

3242
void Parser::SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
3243 3244
                                             const AstRawString* name,
                                             const AstRawString* prefix) {
3245 3246
  // Ignore "__proto__" as a name when it's being used to set the [[Prototype]]
  // of an object literal.
3247
  // See ES #sec-__proto__-property-names-in-object-initializers.
3248
  if (property->IsPrototype() || has_error()) return;
3249

3250
  DCHECK(!property->value()->IsAnonymousFunctionDefinition() ||
3251
         property->kind() == ObjectLiteralProperty::COMPUTED);
3252 3253 3254

  SetFunctionNameFromPropertyName(static_cast<LiteralProperty*>(property), name,
                                  prefix);
3255 3256
}

3257 3258
void Parser::SetFunctionNameFromIdentifierRef(Expression* value,
                                              Expression* identifier) {
3259
  if (!identifier->IsVariableProxy()) return;
3260
  SetFunctionName(value, identifier->AsVariableProxy()->raw_name());
3261
}
3262

3263 3264 3265 3266 3267 3268 3269
void Parser::SetFunctionName(Expression* value, const AstRawString* name,
                             const AstRawString* prefix) {
  if (!value->IsAnonymousFunctionDefinition() &&
      !value->IsConciseMethodDefinition() &&
      !value->IsAccessorFunctionDefinition()) {
    return;
  }
3270
  auto function = value->AsFunctionLiteral();
3271 3272 3273
  if (value->IsClassLiteral()) {
    function = value->AsClassLiteral()->constructor();
  }
3274
  if (function != nullptr) {
3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285
    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);
3286 3287 3288
  }
}

3289
Statement* Parser::CheckCallable(Variable* var, Expression* error, int pos) {
yangguo's avatar
yangguo committed
3290
  const int nopos = kNoSourcePosition;
3291 3292
  Statement* validate_var;
  {
3293 3294 3295 3296 3297
    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(
3298 3299
        Token::EQ_STRICT, type_of, function_literal, nopos);

3300
    Statement* throw_call = factory()->NewExpressionStatement(error, pos);
3301

3302
    validate_var = factory()->NewIfStatement(
3303
        condition, factory()->EmptyStatement(), throw_call, nopos);
3304 3305 3306
  }
  return validate_var;
}
neis's avatar
neis committed
3307

3308 3309
}  // namespace internal
}  // namespace v8