// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/asmjs/asm-parser.h"

#include <math.h>
#include <string.h>

#include <algorithm>

#include "src/asmjs/asm-js.h"
#include "src/asmjs/asm-types.h"
#include "src/base/optional.h"
#include "src/base/overflowing-math.h"
#include "src/flags/flags.h"
#include "src/numbers/conversions-inl.h"
#include "src/parsing/scanner.h"
#include "src/wasm/wasm-limits.h"
#include "src/wasm/wasm-opcodes.h"

namespace v8 {
namespace internal {
namespace wasm {

#ifdef DEBUG
#define FAIL_AND_RETURN(ret, msg)                                        \
  failed_ = true;                                                        \
  failure_message_ = msg;                                                \
  failure_location_ = static_cast<int>(scanner_.Position());             \
  if (FLAG_trace_asm_parser) {                                           \
    PrintF("[asm.js failure: %s, token: '%s', see: %s:%d]\n", msg,       \
           scanner_.Name(scanner_.Token()).c_str(), __FILE__, __LINE__); \
  }                                                                      \
  return ret;
#else
#define FAIL_AND_RETURN(ret, msg)                            \
  failed_ = true;                                            \
  failure_message_ = msg;                                    \
  failure_location_ = static_cast<int>(scanner_.Position()); \
  return ret;
#endif

#define FAIL(msg) FAIL_AND_RETURN(, msg)
#define FAILn(msg) FAIL_AND_RETURN(nullptr, msg)

#define EXPECT_TOKEN_OR_RETURN(ret, token)      \
  do {                                          \
    if (scanner_.Token() != token) {            \
      FAIL_AND_RETURN(ret, "Unexpected token"); \
    }                                           \
    scanner_.Next();                            \
  } while (false)

#define EXPECT_TOKEN(token) EXPECT_TOKEN_OR_RETURN(, token)
#define EXPECT_TOKENn(token) EXPECT_TOKEN_OR_RETURN(nullptr, token)

#define RECURSE_OR_RETURN(ret, call)                                       \
  do {                                                                     \
    DCHECK(!failed_);                                                      \
    if (GetCurrentStackPosition() < stack_limit_) {                        \
      FAIL_AND_RETURN(ret, "Stack overflow while parsing asm.js module."); \
    }                                                                      \
    call;                                                                  \
    if (failed_) return ret;                                               \
  } while (false)

#define RECURSE(call) RECURSE_OR_RETURN(, call)
#define RECURSEn(call) RECURSE_OR_RETURN(nullptr, call)

#define TOK(name) AsmJsScanner::kToken_##name

AsmJsParser::AsmJsParser(Zone* zone, uintptr_t stack_limit,
                         Utf16CharacterStream* stream)
    : zone_(zone),
      scanner_(stream),
      module_builder_(new (zone) WasmModuleBuilder(zone)),
      return_type_(nullptr),
      stack_limit_(stack_limit),
      global_var_info_(zone),
      local_var_info_(zone),
      failed_(false),
      failure_location_(kNoSourcePosition),
      stdlib_name_(kTokenNone),
      foreign_name_(kTokenNone),
      heap_name_(kTokenNone),
      inside_heap_assignment_(false),
      heap_access_type_(nullptr),
      block_stack_(zone),
      call_coercion_(nullptr),
      call_coercion_deferred_(nullptr),
      pending_label_(0),
      global_imports_(zone) {
  module_builder_->SetMinMemorySize(0);
  InitializeStdlibTypes();
}

void AsmJsParser::InitializeStdlibTypes() {
  auto* d = AsmType::Double();
  auto* dq = AsmType::DoubleQ();
  stdlib_dq2d_ = AsmType::Function(zone(), d);
  stdlib_dq2d_->AsFunctionType()->AddArgument(dq);

  stdlib_dqdq2d_ = AsmType::Function(zone(), d);
  stdlib_dqdq2d_->AsFunctionType()->AddArgument(dq);
  stdlib_dqdq2d_->AsFunctionType()->AddArgument(dq);

  auto* f = AsmType::Float();
  auto* fh = AsmType::Floatish();
  auto* fq = AsmType::FloatQ();
  auto* fq2fh = AsmType::Function(zone(), fh);
  fq2fh->AsFunctionType()->AddArgument(fq);

  auto* s = AsmType::Signed();
  auto* u = AsmType::Unsigned();
  auto* s2u = AsmType::Function(zone(), u);
  s2u->AsFunctionType()->AddArgument(s);

  auto* i = AsmType::Int();
  stdlib_i2s_ = AsmType::Function(zone_, s);
  stdlib_i2s_->AsFunctionType()->AddArgument(i);

  stdlib_ii2s_ = AsmType::Function(zone(), s);
  stdlib_ii2s_->AsFunctionType()->AddArgument(i);
  stdlib_ii2s_->AsFunctionType()->AddArgument(i);

  // The signatures in "9 Standard Library" of the spec draft are outdated and
  // have been superseded with the following by an errata:
  //  - Math.min/max : (signed, signed...) -> signed
  //                   (double, double...) -> double
  //                   (float, float...) -> float
  auto* minmax_d = AsmType::MinMaxType(zone(), d, d);
  auto* minmax_f = AsmType::MinMaxType(zone(), f, f);
  auto* minmax_s = AsmType::MinMaxType(zone(), s, s);
  stdlib_minmax_ = AsmType::OverloadedFunction(zone());
  stdlib_minmax_->AsOverloadedFunctionType()->AddOverload(minmax_s);
  stdlib_minmax_->AsOverloadedFunctionType()->AddOverload(minmax_f);
  stdlib_minmax_->AsOverloadedFunctionType()->AddOverload(minmax_d);

  // The signatures in "9 Standard Library" of the spec draft are outdated and
  // have been superseded with the following by an errata:
  //  - Math.abs : (signed) -> unsigned
  //               (double?) -> double
  //               (float?) -> floatish
  stdlib_abs_ = AsmType::OverloadedFunction(zone());
  stdlib_abs_->AsOverloadedFunctionType()->AddOverload(s2u);
  stdlib_abs_->AsOverloadedFunctionType()->AddOverload(stdlib_dq2d_);
  stdlib_abs_->AsOverloadedFunctionType()->AddOverload(fq2fh);

  // The signatures in "9 Standard Library" of the spec draft are outdated and
  // have been superseded with the following by an errata:
  //  - Math.ceil/floor/sqrt : (double?) -> double
  //                           (float?) -> floatish
  stdlib_ceil_like_ = AsmType::OverloadedFunction(zone());
  stdlib_ceil_like_->AsOverloadedFunctionType()->AddOverload(stdlib_dq2d_);
  stdlib_ceil_like_->AsOverloadedFunctionType()->AddOverload(fq2fh);

  stdlib_fround_ = AsmType::FroundType(zone());
}

FunctionSig* AsmJsParser::ConvertSignature(AsmType* return_type,
                                           const ZoneVector<AsmType*>& params) {
  FunctionSig::Builder sig_builder(
      zone(), !return_type->IsA(AsmType::Void()) ? 1 : 0, params.size());
  for (auto param : params) {
    if (param->IsA(AsmType::Double())) {
      sig_builder.AddParam(kWasmF64);
    } else if (param->IsA(AsmType::Float())) {
      sig_builder.AddParam(kWasmF32);
    } else if (param->IsA(AsmType::Int())) {
      sig_builder.AddParam(kWasmI32);
    } else {
      UNREACHABLE();
    }
  }
  if (!return_type->IsA(AsmType::Void())) {
    if (return_type->IsA(AsmType::Double())) {
      sig_builder.AddReturn(kWasmF64);
    } else if (return_type->IsA(AsmType::Float())) {
      sig_builder.AddReturn(kWasmF32);
    } else if (return_type->IsA(AsmType::Signed())) {
      sig_builder.AddReturn(kWasmI32);
    } else {
      UNREACHABLE();
    }
  }
  return sig_builder.Build();
}

bool AsmJsParser::Run() {
  ValidateModule();
  return !failed_;
}

class AsmJsParser::TemporaryVariableScope {
 public:
  explicit TemporaryVariableScope(AsmJsParser* parser) : parser_(parser) {
    local_depth_ = parser_->function_temp_locals_depth_;
    parser_->function_temp_locals_depth_++;
  }
  ~TemporaryVariableScope() {
    DCHECK_EQ(local_depth_, parser_->function_temp_locals_depth_ - 1);
    parser_->function_temp_locals_depth_--;
  }
  uint32_t get() const { return parser_->TempVariable(local_depth_); }

 private:
  AsmJsParser* parser_;
  int local_depth_;
};

wasm::AsmJsParser::VarInfo* AsmJsParser::GetVarInfo(
    AsmJsScanner::token_t token) {
  if (AsmJsScanner::IsGlobal(token)) {
    size_t old = global_var_info_.size();
    size_t index = AsmJsScanner::GlobalIndex(token);
    size_t sz = std::max(old, index + 1);
    if (sz != old) {
      global_var_info_.resize(sz);
    }
    return &global_var_info_[index];
  } else if (AsmJsScanner::IsLocal(token)) {
    size_t old = local_var_info_.size();
    size_t index = AsmJsScanner::LocalIndex(token);
    size_t sz = std::max(old, index + 1);
    if (sz != old) {
      local_var_info_.resize(sz);
    }
    return &local_var_info_[index];
  }
  UNREACHABLE();
}

uint32_t AsmJsParser::VarIndex(VarInfo* info) {
  DCHECK_EQ(info->kind, VarKind::kGlobal);
  return info->index + static_cast<uint32_t>(global_imports_.size());
}

void AsmJsParser::AddGlobalImport(Vector<const char> name, AsmType* type,
                                  ValueType vtype, bool mutable_variable,
                                  VarInfo* info) {
  // Allocate a separate variable for the import.
  // TODO(mstarzinger): Consider using the imported global directly instead of
  // allocating a separate global variable for immutable (i.e. const) imports.
  DeclareGlobal(info, mutable_variable, type, vtype);

  // Record the need to initialize the global from the import.
  global_imports_.push_back({name, vtype, info});
}

void AsmJsParser::DeclareGlobal(VarInfo* info, bool mutable_variable,
                                AsmType* type, ValueType vtype,
                                const WasmInitExpr& init) {
  info->kind = VarKind::kGlobal;
  info->type = type;
  info->index = module_builder_->AddGlobal(vtype, true, init);
  info->mutable_variable = mutable_variable;
}

void AsmJsParser::DeclareStdlibFunc(VarInfo* info, VarKind kind,
                                    AsmType* type) {
  info->kind = kind;
  info->type = type;
  info->index = 0;  // unused
  info->mutable_variable = false;
}

uint32_t AsmJsParser::TempVariable(int index) {
  if (index + 1 > function_temp_locals_used_) {
    function_temp_locals_used_ = index + 1;
  }
  return function_temp_locals_offset_ + index;
}

Vector<const char> AsmJsParser::CopyCurrentIdentifierString() {
  const std::string& str = scanner_.GetIdentifierString();
  char* buffer = zone()->NewArray<char>(str.size());
  str.copy(buffer, str.size());
  return Vector<const char>(buffer, static_cast<int>(str.size()));
}

void AsmJsParser::SkipSemicolon() {
  if (Check(';')) {
    // Had a semicolon.
  } else if (!Peek('}') && !scanner_.IsPrecededByNewline()) {
    FAIL("Expected ;");
  }
}

void AsmJsParser::Begin(AsmJsScanner::token_t label) {
  BareBegin(BlockKind::kRegular, label);
  current_function_builder_->EmitWithU8(kExprBlock, kLocalVoid);
}

void AsmJsParser::Loop(AsmJsScanner::token_t label) {
  BareBegin(BlockKind::kLoop, label);
  size_t position = scanner_.Position();
  current_function_builder_->AddAsmWasmOffset(position, position);
  current_function_builder_->EmitWithU8(kExprLoop, kLocalVoid);
}

void AsmJsParser::End() {
  BareEnd();
  current_function_builder_->Emit(kExprEnd);
}

void AsmJsParser::BareBegin(BlockKind kind, AsmJsScanner::token_t label) {
  BlockInfo info;
  info.kind = kind;
  info.label = label;
  block_stack_.push_back(info);
}

void AsmJsParser::BareEnd() {
  DCHECK_GT(block_stack_.size(), 0);
  block_stack_.pop_back();
}

int AsmJsParser::FindContinueLabelDepth(AsmJsScanner::token_t label) {
  int count = 0;
  for (auto it = block_stack_.rbegin(); it != block_stack_.rend();
       ++it, ++count) {
    // A 'continue' statement targets ...
    //  - The innermost {kLoop} block if no label is given.
    //  - The matching {kLoop} block (when a label is provided).
    if (it->kind == BlockKind::kLoop &&
        (label == kTokenNone || it->label == label)) {
      return count;
    }
  }
  return -1;
}

int AsmJsParser::FindBreakLabelDepth(AsmJsScanner::token_t label) {
  int count = 0;
  for (auto it = block_stack_.rbegin(); it != block_stack_.rend();
       ++it, ++count) {
    // A 'break' statement targets ...
    //  - The innermost {kRegular} block if no label is given.
    //  - The matching {kRegular} or {kNamed} block (when a label is provided).
    if ((it->kind == BlockKind::kRegular &&
         (label == kTokenNone || it->label == label)) ||
        (it->kind == BlockKind::kNamed && it->label == label)) {
      return count;
    }
  }
  return -1;
}

// 6.1 ValidateModule
void AsmJsParser::ValidateModule() {
  RECURSE(ValidateModuleParameters());
  EXPECT_TOKEN('{');
  EXPECT_TOKEN(TOK(UseAsm));
  RECURSE(SkipSemicolon());
  RECURSE(ValidateModuleVars());
  while (Peek(TOK(function))) {
    RECURSE(ValidateFunction());
  }
  while (Peek(TOK(var))) {
    RECURSE(ValidateFunctionTable());
  }
  RECURSE(ValidateExport());
  RECURSE(SkipSemicolon());
  EXPECT_TOKEN('}');

  // Check that all functions were eventually defined.
  for (auto& info : global_var_info_) {
    if (info.kind == VarKind::kFunction && !info.function_defined) {
      FAIL("Undefined function");
    }
    if (info.kind == VarKind::kTable && !info.function_defined) {
      FAIL("Undefined function table");
    }
    if (info.kind == VarKind::kImportedFunction && !info.function_defined) {
      // For imported functions without a single call site, we insert a dummy
      // import here to preserve the fact that there actually was an import.
      FunctionSig* void_void_sig = FunctionSig::Builder(zone(), 0, 0).Build();
      module_builder_->AddImport(info.import->function_name, void_void_sig);
    }
  }

  // Add start function to initialize things.
  WasmFunctionBuilder* start = module_builder_->AddFunction();
  module_builder_->MarkStartFunction(start);
  for (auto& global_import : global_imports_) {
    uint32_t import_index = module_builder_->AddGlobalImport(
        global_import.import_name, global_import.value_type,
        false /* mutability */);
    start->EmitWithI32V(kExprGetGlobal, import_index);
    start->EmitWithI32V(kExprSetGlobal, VarIndex(global_import.var_info));
  }
  start->Emit(kExprEnd);
  FunctionSig::Builder b(zone(), 0, 0);
  start->SetSignature(b.Build());
}

// 6.1 ValidateModule - parameters
void AsmJsParser::ValidateModuleParameters() {
  EXPECT_TOKEN('(');
  stdlib_name_ = 0;
  foreign_name_ = 0;
  heap_name_ = 0;
  if (!Peek(')')) {
    if (!scanner_.IsGlobal()) {
      FAIL("Expected stdlib parameter");
    }
    stdlib_name_ = Consume();
    if (!Peek(')')) {
      EXPECT_TOKEN(',');
      if (!scanner_.IsGlobal()) {
        FAIL("Expected foreign parameter");
      }
      foreign_name_ = Consume();
      if (!Peek(')')) {
        EXPECT_TOKEN(',');
        if (!scanner_.IsGlobal()) {
          FAIL("Expected heap parameter");
        }
        heap_name_ = Consume();
      }
    }
  }
  EXPECT_TOKEN(')');
}

// 6.1 ValidateModule - variables
void AsmJsParser::ValidateModuleVars() {
  while (Peek(TOK(var)) || Peek(TOK(const))) {
    bool mutable_variable = true;
    if (Check(TOK(var))) {
      // Had a var.
    } else {
      EXPECT_TOKEN(TOK(const));
      mutable_variable = false;
    }
    for (;;) {
      RECURSE(ValidateModuleVar(mutable_variable));
      if (Check(',')) {
        continue;
      }
      break;
    }
    SkipSemicolon();
  }
}

// 6.1 ValidateModule - one variable
void AsmJsParser::ValidateModuleVar(bool mutable_variable) {
  if (!scanner_.IsGlobal()) {
    FAIL("Expected identifier");
  }
  VarInfo* info = GetVarInfo(Consume());
  if (info->kind != VarKind::kUnused) {
    FAIL("Redefinition of variable");
  }
  EXPECT_TOKEN('=');
  double dvalue = 0.0;
  uint32_t uvalue = 0;
  if (CheckForDouble(&dvalue)) {
    DeclareGlobal(info, mutable_variable, AsmType::Double(), kWasmF64,
                  WasmInitExpr(dvalue));
  } else if (CheckForUnsigned(&uvalue)) {
    if (uvalue > 0x7FFFFFFF) {
      FAIL("Numeric literal out of range");
    }
    DeclareGlobal(info, mutable_variable,
                  mutable_variable ? AsmType::Int() : AsmType::Signed(),
                  kWasmI32, WasmInitExpr(static_cast<int32_t>(uvalue)));
  } else if (Check('-')) {
    if (CheckForDouble(&dvalue)) {
      DeclareGlobal(info, mutable_variable, AsmType::Double(), kWasmF64,
                    WasmInitExpr(-dvalue));
    } else if (CheckForUnsigned(&uvalue)) {
      if (uvalue > 0x7FFFFFFF) {
        FAIL("Numeric literal out of range");
      }
      DeclareGlobal(info, mutable_variable,
                    mutable_variable ? AsmType::Int() : AsmType::Signed(),
                    kWasmI32, WasmInitExpr(-static_cast<int32_t>(uvalue)));
    } else {
      FAIL("Expected numeric literal");
    }
  } else if (Check(TOK(new))) {
    RECURSE(ValidateModuleVarNewStdlib(info));
  } else if (Check(stdlib_name_)) {
    EXPECT_TOKEN('.');
    RECURSE(ValidateModuleVarStdlib(info));
  } else if (Peek(foreign_name_) || Peek('+')) {
    RECURSE(ValidateModuleVarImport(info, mutable_variable));
  } else if (scanner_.IsGlobal()) {
    RECURSE(ValidateModuleVarFromGlobal(info, mutable_variable));
  } else {
    FAIL("Bad variable declaration");
  }
}

// 6.1 ValidateModule - global float declaration
void AsmJsParser::ValidateModuleVarFromGlobal(VarInfo* info,
                                              bool mutable_variable) {
  VarInfo* src_info = GetVarInfo(Consume());
  if (!src_info->type->IsA(stdlib_fround_)) {
    if (src_info->mutable_variable) {
      FAIL("Can only use immutable variables in global definition");
    }
    if (mutable_variable) {
      FAIL("Can only define immutable variables with other immutables");
    }
    if (!src_info->type->IsA(AsmType::Int()) &&
        !src_info->type->IsA(AsmType::Float()) &&
        !src_info->type->IsA(AsmType::Double())) {
      FAIL("Expected int, float, double, or fround for global definition");
    }
    info->kind = VarKind::kGlobal;
    info->type = src_info->type;
    info->index = src_info->index;
    info->mutable_variable = false;
    return;
  }
  EXPECT_TOKEN('(');
  bool negate = false;
  if (Check('-')) {
    negate = true;
  }
  double dvalue = 0.0;
  uint32_t uvalue = 0;
  if (CheckForDouble(&dvalue)) {
    if (negate) {
      dvalue = -dvalue;
    }
    DeclareGlobal(info, mutable_variable, AsmType::Float(), kWasmF32,
                  WasmInitExpr(DoubleToFloat32(dvalue)));
  } else if (CheckForUnsigned(&uvalue)) {
    dvalue = uvalue;
    if (negate) {
      dvalue = -dvalue;
    }
    DeclareGlobal(info, mutable_variable, AsmType::Float(), kWasmF32,
                  WasmInitExpr(static_cast<float>(dvalue)));
  } else {
    FAIL("Expected numeric literal");
  }
  EXPECT_TOKEN(')');
}

// 6.1 ValidateModule - foreign imports
void AsmJsParser::ValidateModuleVarImport(VarInfo* info,
                                          bool mutable_variable) {
  if (Check('+')) {
    EXPECT_TOKEN(foreign_name_);
    EXPECT_TOKEN('.');
    Vector<const char> name = CopyCurrentIdentifierString();
    AddGlobalImport(name, AsmType::Double(), kWasmF64, mutable_variable, info);
    scanner_.Next();
  } else {
    EXPECT_TOKEN(foreign_name_);
    EXPECT_TOKEN('.');
    Vector<const char> name = CopyCurrentIdentifierString();
    scanner_.Next();
    if (Check('|')) {
      if (!CheckForZero()) {
        FAIL("Expected |0 type annotation for foreign integer import");
      }
      AddGlobalImport(name, AsmType::Int(), kWasmI32, mutable_variable, info);
    } else {
      info->kind = VarKind::kImportedFunction;
      info->import = new (zone()->New(sizeof(FunctionImportInfo)))
          FunctionImportInfo(name, zone());
      info->mutable_variable = false;
    }
  }
}

// 6.1 ValidateModule - one variable
// 9 - Standard Library - heap types
void AsmJsParser::ValidateModuleVarNewStdlib(VarInfo* info) {
  EXPECT_TOKEN(stdlib_name_);
  EXPECT_TOKEN('.');
  switch (Consume()) {
#define V(name, _junk1, _junk2, _junk3)                          \
  case TOK(name):                                                \
    DeclareStdlibFunc(info, VarKind::kSpecial, AsmType::name()); \
    stdlib_uses_.Add(StandardMember::k##name);                   \
    break;
    STDLIB_ARRAY_TYPE_LIST(V)
#undef V
    default:
      FAIL("Expected ArrayBuffer view");
      break;
  }
  EXPECT_TOKEN('(');
  EXPECT_TOKEN(heap_name_);
  EXPECT_TOKEN(')');
}

// 6.1 ValidateModule - one variable
// 9 - Standard Library
void AsmJsParser::ValidateModuleVarStdlib(VarInfo* info) {
  if (Check(TOK(Math))) {
    EXPECT_TOKEN('.');
    switch (Consume()) {
#define V(name, const_value)                                \
  case TOK(name):                                           \
    DeclareGlobal(info, false, AsmType::Double(), kWasmF64, \
                  WasmInitExpr(const_value));               \
    stdlib_uses_.Add(StandardMember::kMath##name);          \
    break;
      STDLIB_MATH_VALUE_LIST(V)
#undef V
#define V(name, Name, op, sig)                                      \
  case TOK(name):                                                   \
    DeclareStdlibFunc(info, VarKind::kMath##Name, stdlib_##sig##_); \
    stdlib_uses_.Add(StandardMember::kMath##Name);                  \
    break;
      STDLIB_MATH_FUNCTION_LIST(V)
#undef V
      default:
        FAIL("Invalid member of stdlib.Math");
    }
  } else if (Check(TOK(Infinity))) {
    DeclareGlobal(info, false, AsmType::Double(), kWasmF64,
                  WasmInitExpr(std::numeric_limits<double>::infinity()));
    stdlib_uses_.Add(StandardMember::kInfinity);
  } else if (Check(TOK(NaN))) {
    DeclareGlobal(info, false, AsmType::Double(), kWasmF64,
                  WasmInitExpr(std::numeric_limits<double>::quiet_NaN()));
    stdlib_uses_.Add(StandardMember::kNaN);
  } else {
    FAIL("Invalid member of stdlib");
  }
}

// 6.2 ValidateExport
void AsmJsParser::ValidateExport() {
  // clang-format off
  EXPECT_TOKEN(TOK(return));
  // clang-format on
  if (Check('{')) {
    for (;;) {
      Vector<const char> name = CopyCurrentIdentifierString();
      if (!scanner_.IsGlobal() && !scanner_.IsLocal()) {
        FAIL("Illegal export name");
      }
      Consume();
      EXPECT_TOKEN(':');
      if (!scanner_.IsGlobal()) {
        FAIL("Expected function name");
      }
      VarInfo* info = GetVarInfo(Consume());
      if (info->kind != VarKind::kFunction) {
        FAIL("Expected function");
      }
      module_builder_->AddExport(name, info->function_builder);
      if (Check(',')) {
        if (!Peek('}')) {
          continue;
        }
      }
      break;
    }
    EXPECT_TOKEN('}');
  } else {
    if (!scanner_.IsGlobal()) {
      FAIL("Single function export must be a function name");
    }
    VarInfo* info = GetVarInfo(Consume());
    if (info->kind != VarKind::kFunction) {
      FAIL("Single function export must be a function");
    }
    module_builder_->AddExport(CStrVector(AsmJs::kSingleFunctionName),
                               info->function_builder);
  }
}

// 6.3 ValidateFunctionTable
void AsmJsParser::ValidateFunctionTable() {
  EXPECT_TOKEN(TOK(var));
  if (!scanner_.IsGlobal()) {
    FAIL("Expected table name");
  }
  VarInfo* table_info = GetVarInfo(Consume());
  if (table_info->kind == VarKind::kTable) {
    if (table_info->function_defined) {
      FAIL("Function table redefined");
    }
    table_info->function_defined = true;
  } else if (table_info->kind != VarKind::kUnused) {
    FAIL("Function table name collides");
  }
  EXPECT_TOKEN('=');
  EXPECT_TOKEN('[');
  uint64_t count = 0;
  for (;;) {
    if (!scanner_.IsGlobal()) {
      FAIL("Expected function name");
    }
    VarInfo* info = GetVarInfo(Consume());
    if (info->kind != VarKind::kFunction) {
      FAIL("Expected function");
    }
    // Only store the function into a table if we used the table somewhere
    // (i.e. tables are first seen at their use sites and allocated there).
    if (table_info->kind == VarKind::kTable) {
      if (count >= static_cast<uint64_t>(table_info->mask) + 1) {
        FAIL("Exceeded function table size");
      }
      if (!info->type->IsA(table_info->type)) {
        FAIL("Function table definition doesn't match use");
      }
      module_builder_->SetIndirectFunction(
          static_cast<uint32_t>(table_info->index + count), info->index);
    }
    ++count;
    if (Check(',')) {
      if (!Peek(']')) {
        continue;
      }
    }
    break;
  }
  EXPECT_TOKEN(']');
  if (table_info->kind == VarKind::kTable &&
      count != static_cast<uint64_t>(table_info->mask) + 1) {
    FAIL("Function table size does not match uses");
  }
  SkipSemicolon();
}

// 6.4 ValidateFunction
void AsmJsParser::ValidateFunction() {
  EXPECT_TOKEN(TOK(function));
  if (!scanner_.IsGlobal()) {
    FAIL("Expected function name");
  }

  Vector<const char> function_name_str = CopyCurrentIdentifierString();
  AsmJsScanner::token_t function_name = Consume();
  VarInfo* function_info = GetVarInfo(function_name);
  if (function_info->kind == VarKind::kUnused) {
    function_info->kind = VarKind::kFunction;
    function_info->function_builder = module_builder_->AddFunction();
    function_info->index = function_info->function_builder->func_index();
    function_info->mutable_variable = false;
  } else if (function_info->kind != VarKind::kFunction) {
    FAIL("Function name collides with variable");
  } else if (function_info->function_defined) {
    FAIL("Function redefined");
  }

  function_info->function_defined = true;
  function_info->function_builder->SetName(function_name_str);
  current_function_builder_ = function_info->function_builder;
  return_type_ = nullptr;

  // Record start of the function, used as position for the stack check.
  current_function_builder_->SetAsmFunctionStartPosition(scanner_.Position());

  CachedVector<AsmType*> params(&cached_asm_type_p_vectors_);
  ValidateFunctionParams(&params);

  // Check against limit on number of parameters.
  if (params.size() >= kV8MaxWasmFunctionParams) {
    FAIL("Number of parameters exceeds internal limit");
  }

  CachedVector<ValueType> locals(&cached_valuetype_vectors_);
  ValidateFunctionLocals(params.size(), &locals);

  function_temp_locals_offset_ = static_cast<uint32_t>(
      params.size() + locals.size());
  function_temp_locals_used_ = 0;
  function_temp_locals_depth_ = 0;

  bool last_statement_is_return = false;
  while (!failed_ && !Peek('}')) {
    // clang-format off
    last_statement_is_return = Peek(TOK(return));
    // clang-format on
    RECURSE(ValidateStatement());
  }
  EXPECT_TOKEN('}');

  if (!last_statement_is_return) {
    if (return_type_ == nullptr) {
      return_type_ = AsmType::Void();
    } else if (!return_type_->IsA(AsmType::Void())) {
      FAIL("Expected return at end of non-void function");
    }
  }
  DCHECK_NOT_NULL(return_type_);

  // TODO(bradnelson): WasmModuleBuilder can't take this in the right order.
  //                   We should fix that so we can use it instead.
  FunctionSig* sig = ConvertSignature(return_type_, params);
  current_function_builder_->SetSignature(sig);
  for (auto local : locals) {
    current_function_builder_->AddLocal(local);
  }
  // Add bonus temps.
  for (int i = 0; i < function_temp_locals_used_; ++i) {
    current_function_builder_->AddLocal(kWasmI32);
  }

  // Check against limit on number of local variables.
  if (locals.size() + function_temp_locals_used_ > kV8MaxWasmFunctionLocals) {
    FAIL("Number of local variables exceeds internal limit");
  }

  // End function
  current_function_builder_->Emit(kExprEnd);

  if (current_function_builder_->GetPosition() > kV8MaxWasmFunctionSize) {
    FAIL("Size of function body exceeds internal limit");
  }
  // Record (or validate) function type.
  AsmType* function_type = AsmType::Function(zone(), return_type_);
  for (auto t : params) {
    function_type->AsFunctionType()->AddArgument(t);
  }
  function_info = GetVarInfo(function_name);
  if (function_info->type->IsA(AsmType::None())) {
    DCHECK_EQ(function_info->kind, VarKind::kFunction);
    function_info->type = function_type;
  } else if (!function_type->IsA(function_info->type)) {
    // TODO(bradnelson): Should IsExactly be used here?
    FAIL("Function definition doesn't match use");
  }

  scanner_.ResetLocals();
  local_var_info_.clear();
}

// 6.4 ValidateFunction
void AsmJsParser::ValidateFunctionParams(ZoneVector<AsmType*>* params) {
  // TODO(bradnelson): Do this differently so that the scanner doesn't need to
  // have a state transition that needs knowledge of how the scanner works
  // inside.
  scanner_.EnterLocalScope();
  EXPECT_TOKEN('(');
  CachedVector<AsmJsScanner::token_t> function_parameters(
      &cached_token_t_vectors_);
  while (!failed_ && !Peek(')')) {
    if (!scanner_.IsLocal()) {
      FAIL("Expected parameter name");
    }
    function_parameters.push_back(Consume());
    if (!Peek(')')) {
      EXPECT_TOKEN(',');
    }
  }
  EXPECT_TOKEN(')');
  scanner_.EnterGlobalScope();
  EXPECT_TOKEN('{');
  // 5.1 Parameter Type Annotations
  for (auto p : function_parameters) {
    EXPECT_TOKEN(p);
    EXPECT_TOKEN('=');
    VarInfo* info = GetVarInfo(p);
    if (info->kind != VarKind::kUnused) {
      FAIL("Duplicate parameter name");
    }
    if (Check(p)) {
      EXPECT_TOKEN('|');
      if (!CheckForZero()) {
        FAIL("Bad integer parameter annotation.");
      }
      info->kind = VarKind::kLocal;
      info->type = AsmType::Int();
      info->index = static_cast<uint32_t>(params->size());
      params->push_back(AsmType::Int());
    } else if (Check('+')) {
      EXPECT_TOKEN(p);
      info->kind = VarKind::kLocal;
      info->type = AsmType::Double();
      info->index = static_cast<uint32_t>(params->size());
      params->push_back(AsmType::Double());
    } else {
      if (!scanner_.IsGlobal() ||
          !GetVarInfo(Consume())->type->IsA(stdlib_fround_)) {
        FAIL("Expected fround");
      }
      EXPECT_TOKEN('(');
      EXPECT_TOKEN(p);
      EXPECT_TOKEN(')');
      info->kind = VarKind::kLocal;
      info->type = AsmType::Float();
      info->index = static_cast<uint32_t>(params->size());
      params->push_back(AsmType::Float());
    }
    SkipSemicolon();
  }
}

// 6.4 ValidateFunction - locals
void AsmJsParser::ValidateFunctionLocals(size_t param_count,
                                         ZoneVector<ValueType>* locals) {
  DCHECK(locals->empty());
  // Local Variables.
  while (Peek(TOK(var))) {
    scanner_.EnterLocalScope();
    EXPECT_TOKEN(TOK(var));
    scanner_.EnterGlobalScope();
    for (;;) {
      if (!scanner_.IsLocal()) {
        FAIL("Expected local variable identifier");
      }
      VarInfo* info = GetVarInfo(Consume());
      if (info->kind != VarKind::kUnused) {
        FAIL("Duplicate local variable name");
      }
      // Store types.
      EXPECT_TOKEN('=');
      double dvalue = 0.0;
      uint32_t uvalue = 0;
      if (Check('-')) {
        if (CheckForDouble(&dvalue)) {
          info->kind = VarKind::kLocal;
          info->type = AsmType::Double();
          info->index = static_cast<uint32_t>(param_count + locals->size());
          locals->push_back(kWasmF64);
          current_function_builder_->EmitF64Const(-dvalue);
          current_function_builder_->EmitSetLocal(info->index);
        } else if (CheckForUnsigned(&uvalue)) {
          if (uvalue > 0x7FFFFFFF) {
            FAIL("Numeric literal out of range");
          }
          info->kind = VarKind::kLocal;
          info->type = AsmType::Int();
          info->index = static_cast<uint32_t>(param_count + locals->size());
          locals->push_back(kWasmI32);
          int32_t value = -static_cast<int32_t>(uvalue);
          current_function_builder_->EmitI32Const(value);
          current_function_builder_->EmitSetLocal(info->index);
        } else {
          FAIL("Expected variable initial value");
        }
      } else if (scanner_.IsGlobal()) {
        VarInfo* sinfo = GetVarInfo(Consume());
        if (sinfo->kind == VarKind::kGlobal) {
          if (sinfo->mutable_variable) {
            FAIL("Initializing from global requires const variable");
          }
          info->kind = VarKind::kLocal;
          info->type = sinfo->type;
          info->index = static_cast<uint32_t>(param_count + locals->size());
          if (sinfo->type->IsA(AsmType::Int())) {
            locals->push_back(kWasmI32);
          } else if (sinfo->type->IsA(AsmType::Float())) {
            locals->push_back(kWasmF32);
          } else if (sinfo->type->IsA(AsmType::Double())) {
            locals->push_back(kWasmF64);
          } else {
            FAIL("Bad local variable definition");
          }
          current_function_builder_->EmitWithI32V(kExprGetGlobal,
                                                    VarIndex(sinfo));
          current_function_builder_->EmitSetLocal(info->index);
        } else if (sinfo->type->IsA(stdlib_fround_)) {
          EXPECT_TOKEN('(');
          bool negate = false;
          if (Check('-')) {
            negate = true;
          }
          double dvalue = 0.0;
          if (CheckForDouble(&dvalue)) {
            info->kind = VarKind::kLocal;
            info->type = AsmType::Float();
            info->index = static_cast<uint32_t>(param_count + locals->size());
            locals->push_back(kWasmF32);
            if (negate) {
              dvalue = -dvalue;
            }
            float fvalue = DoubleToFloat32(dvalue);
            current_function_builder_->EmitF32Const(fvalue);
            current_function_builder_->EmitSetLocal(info->index);
          } else if (CheckForUnsigned(&uvalue)) {
            if (uvalue > 0x7FFFFFFF) {
              FAIL("Numeric literal out of range");
            }
            info->kind = VarKind::kLocal;
            info->type = AsmType::Float();
            info->index = static_cast<uint32_t>(param_count + locals->size());
            locals->push_back(kWasmF32);
            int32_t value = static_cast<int32_t>(uvalue);
            if (negate) {
              value = -value;
            }
            float fvalue = static_cast<float>(value);
            current_function_builder_->EmitF32Const(fvalue);
            current_function_builder_->EmitSetLocal(info->index);
          } else {
            FAIL("Expected variable initial value");
          }
          EXPECT_TOKEN(')');
        } else {
          FAIL("expected fround or const global");
        }
      } else if (CheckForDouble(&dvalue)) {
        info->kind = VarKind::kLocal;
        info->type = AsmType::Double();
        info->index = static_cast<uint32_t>(param_count + locals->size());
        locals->push_back(kWasmF64);
        current_function_builder_->EmitF64Const(dvalue);
        current_function_builder_->EmitSetLocal(info->index);
      } else if (CheckForUnsigned(&uvalue)) {
        info->kind = VarKind::kLocal;
        info->type = AsmType::Int();
        info->index = static_cast<uint32_t>(param_count + locals->size());
        locals->push_back(kWasmI32);
        int32_t value = static_cast<int32_t>(uvalue);
        current_function_builder_->EmitI32Const(value);
        current_function_builder_->EmitSetLocal(info->index);
      } else {
        FAIL("Expected variable initial value");
      }
      if (!Peek(',')) {
        break;
      }
      scanner_.EnterLocalScope();
      EXPECT_TOKEN(',');
      scanner_.EnterGlobalScope();
    }
    SkipSemicolon();
  }
}

// 6.5 ValidateStatement
void AsmJsParser::ValidateStatement() {
  call_coercion_ = nullptr;
  if (Peek('{')) {
    RECURSE(Block());
  } else if (Peek(';')) {
    RECURSE(EmptyStatement());
  } else if (Peek(TOK(if))) {
    RECURSE(IfStatement());
    // clang-format off
  } else if (Peek(TOK(return))) {
    // clang-format on
    RECURSE(ReturnStatement());
  } else if (IterationStatement()) {
    // Handled in IterationStatement.
  } else if (Peek(TOK(break))) {
    RECURSE(BreakStatement());
  } else if (Peek(TOK(continue))) {
    RECURSE(ContinueStatement());
  } else if (Peek(TOK(switch))) {
    RECURSE(SwitchStatement());
  } else {
    RECURSE(ExpressionStatement());
  }
}

// 6.5.1 Block
void AsmJsParser::Block() {
  bool can_break_to_block = pending_label_ != 0;
  if (can_break_to_block) {
    BareBegin(BlockKind::kNamed, pending_label_);
    current_function_builder_->EmitWithU8(kExprBlock, kLocalVoid);
  }
  pending_label_ = 0;
  EXPECT_TOKEN('{');
  while (!failed_ && !Peek('}')) {
    RECURSE(ValidateStatement());
  }
  EXPECT_TOKEN('}');
  if (can_break_to_block) {
    End();
  }
}

// 6.5.2 ExpressionStatement
void AsmJsParser::ExpressionStatement() {
  if (scanner_.IsGlobal() || scanner_.IsLocal()) {
    // NOTE: Both global or local identifiers can also be used as labels.
    scanner_.Next();
    if (Peek(':')) {
      scanner_.Rewind();
      RECURSE(LabelledStatement());
      return;
    }
    scanner_.Rewind();
  }
  AsmType* ret;
  RECURSE(ret = ValidateExpression());
  if (!ret->IsA(AsmType::Void())) {
    current_function_builder_->Emit(kExprDrop);
  }
  SkipSemicolon();
}

// 6.5.3 EmptyStatement
void AsmJsParser::EmptyStatement() { EXPECT_TOKEN(';'); }

// 6.5.4 IfStatement
void AsmJsParser::IfStatement() {
  EXPECT_TOKEN(TOK(if));
  EXPECT_TOKEN('(');
  RECURSE(Expression(AsmType::Int()));
  EXPECT_TOKEN(')');
  BareBegin(BlockKind::kOther);
  current_function_builder_->EmitWithU8(kExprIf, kLocalVoid);
  RECURSE(ValidateStatement());
  if (Check(TOK(else))) {
    current_function_builder_->Emit(kExprElse);
    RECURSE(ValidateStatement());
  }
  current_function_builder_->Emit(kExprEnd);
  BareEnd();
}

// 6.5.5 ReturnStatement
void AsmJsParser::ReturnStatement() {
  // clang-format off
  EXPECT_TOKEN(TOK(return));
  // clang-format on
  if (!Peek(';') && !Peek('}')) {
    // TODO(bradnelson): See if this can be factored out.
    AsmType* ret;
    RECURSE(ret = Expression(return_type_));
    if (ret->IsA(AsmType::Double())) {
      return_type_ = AsmType::Double();
    } else if (ret->IsA(AsmType::Float())) {
      return_type_ = AsmType::Float();
    } else if (ret->IsA(AsmType::Signed())) {
      return_type_ = AsmType::Signed();
    } else {
      FAIL("Invalid return type");
    }
  } else if (return_type_ == nullptr) {
    return_type_ = AsmType::Void();
  } else if (!return_type_->IsA(AsmType::Void())) {
    FAIL("Invalid void return type");
  }
  current_function_builder_->Emit(kExprReturn);
  SkipSemicolon();
}

// 6.5.6 IterationStatement
bool AsmJsParser::IterationStatement() {
  if (Peek(TOK(while))) {
    WhileStatement();
  } else if (Peek(TOK(do))) {
    DoStatement();
  } else if (Peek(TOK(for))) {
    ForStatement();
  } else {
    return false;
  }
  return true;
}

// 6.5.6 IterationStatement - while
void AsmJsParser::WhileStatement() {
  // a: block {
  Begin(pending_label_);
  //   b: loop {
  Loop(pending_label_);
  pending_label_ = 0;
  EXPECT_TOKEN(TOK(while));
  EXPECT_TOKEN('(');
  RECURSE(Expression(AsmType::Int()));
  EXPECT_TOKEN(')');
  //     if (!CONDITION) break a;
  current_function_builder_->Emit(kExprI32Eqz);
  current_function_builder_->EmitWithU8(kExprBrIf, 1);
  //     BODY
  RECURSE(ValidateStatement());
  //     continue b;
  current_function_builder_->EmitWithU8(kExprBr, 0);
  End();
  //   }
  // }
  End();
}

// 6.5.6 IterationStatement - do
void AsmJsParser::DoStatement() {
  // a: block {
  Begin(pending_label_);
  //   b: loop {
  Loop();
  //     c: block {  // but treated like loop so continue works
  BareBegin(BlockKind::kLoop, pending_label_);
  current_function_builder_->EmitWithU8(kExprBlock, kLocalVoid);
  pending_label_ = 0;
  EXPECT_TOKEN(TOK(do));
  //       BODY
  RECURSE(ValidateStatement());
  EXPECT_TOKEN(TOK(while));
  End();
  //     }  // end c
  EXPECT_TOKEN('(');
  RECURSE(Expression(AsmType::Int()));
  //     if (!CONDITION) break a;
  current_function_builder_->Emit(kExprI32Eqz);
  current_function_builder_->EmitWithU8(kExprBrIf, 1);
  //     continue b;
  current_function_builder_->EmitWithU8(kExprBr, 0);
  EXPECT_TOKEN(')');
  //   }  // end b
  End();
  // }  // end a
  End();
  SkipSemicolon();
}

// 6.5.6 IterationStatement - for
void AsmJsParser::ForStatement() {
  EXPECT_TOKEN(TOK(for));
  EXPECT_TOKEN('(');
  if (!Peek(';')) {
    AsmType* ret;
    RECURSE(ret = Expression(nullptr));
    if (!ret->IsA(AsmType::Void())) {
      current_function_builder_->Emit(kExprDrop);
    }
  }
  EXPECT_TOKEN(';');
  // a: block {
  Begin(pending_label_);
  //   b: loop {
  Loop();
  //     c: block {  // but treated like loop so continue works
  BareBegin(BlockKind::kLoop, pending_label_);
  current_function_builder_->EmitWithU8(kExprBlock, kLocalVoid);
  pending_label_ = 0;
  if (!Peek(';')) {
    //       if (!CONDITION) break a;
    RECURSE(Expression(AsmType::Int()));
    current_function_builder_->Emit(kExprI32Eqz);
    current_function_builder_->EmitWithU8(kExprBrIf, 2);
  }
  EXPECT_TOKEN(';');
  // Race past INCREMENT
  size_t increment_position = scanner_.Position();
  ScanToClosingParenthesis();
  EXPECT_TOKEN(')');
  //       BODY
  RECURSE(ValidateStatement());
  //     }  // end c
  End();
  //     INCREMENT
  size_t end_position = scanner_.Position();
  scanner_.Seek(increment_position);
  if (!Peek(')')) {
    RECURSE(Expression(nullptr));
    // NOTE: No explicit drop because below break is an implicit drop.
  }
  //     continue b;
  current_function_builder_->EmitWithU8(kExprBr, 0);
  scanner_.Seek(end_position);
  //   }  // end b
  End();
  // }  // end a
  End();
}

// 6.5.7 BreakStatement
void AsmJsParser::BreakStatement() {
  EXPECT_TOKEN(TOK(break));
  AsmJsScanner::token_t label_name = kTokenNone;
  if (scanner_.IsGlobal() || scanner_.IsLocal()) {
    // NOTE: Currently using globals/locals for labels too.
    label_name = Consume();
  }
  int depth = FindBreakLabelDepth(label_name);
  if (depth < 0) {
    FAIL("Illegal break");
  }
  current_function_builder_->Emit(kExprBr);
  current_function_builder_->EmitI32V(depth);
  SkipSemicolon();
}

// 6.5.8 ContinueStatement
void AsmJsParser::ContinueStatement() {
  EXPECT_TOKEN(TOK(continue));
  AsmJsScanner::token_t label_name = kTokenNone;
  if (scanner_.IsGlobal() || scanner_.IsLocal()) {
    // NOTE: Currently using globals/locals for labels too.
    label_name = Consume();
  }
  int depth = FindContinueLabelDepth(label_name);
  if (depth < 0) {
    FAIL("Illegal continue");
  }
  current_function_builder_->EmitWithI32V(kExprBr, depth);
  SkipSemicolon();
}

// 6.5.9 LabelledStatement
void AsmJsParser::LabelledStatement() {
  DCHECK(scanner_.IsGlobal() || scanner_.IsLocal());
  // NOTE: Currently using globals/locals for labels too.
  if (pending_label_ != 0) {
    FAIL("Double label unsupported");
  }
  pending_label_ = scanner_.Token();
  scanner_.Next();
  EXPECT_TOKEN(':');
  RECURSE(ValidateStatement());
}

// 6.5.10 SwitchStatement
void AsmJsParser::SwitchStatement() {
  EXPECT_TOKEN(TOK(switch));
  EXPECT_TOKEN('(');
  AsmType* test;
  RECURSE(test = Expression(nullptr));
  if (!test->IsA(AsmType::Signed())) {
    FAIL("Expected signed for switch value");
  }
  EXPECT_TOKEN(')');
  uint32_t tmp = TempVariable(0);
  current_function_builder_->EmitSetLocal(tmp);
  Begin(pending_label_);
  pending_label_ = 0;
  // TODO(bradnelson): Make less weird.
  CachedVector<int32_t> cases(&cached_int_vectors_);
  GatherCases(&cases);
  EXPECT_TOKEN('{');
  size_t count = cases.size() + 1;
  for (size_t i = 0; i < count; ++i) {
    BareBegin(BlockKind::kOther);
    current_function_builder_->EmitWithU8(kExprBlock, kLocalVoid);
  }
  int table_pos = 0;
  for (auto c : cases) {
    current_function_builder_->EmitGetLocal(tmp);
    current_function_builder_->EmitI32Const(c);
    current_function_builder_->Emit(kExprI32Eq);
    current_function_builder_->EmitWithI32V(kExprBrIf, table_pos++);
  }
  current_function_builder_->EmitWithI32V(kExprBr, table_pos++);
  while (!failed_ && Peek(TOK(case))) {
    current_function_builder_->Emit(kExprEnd);
    BareEnd();
    RECURSE(ValidateCase());
  }
  current_function_builder_->Emit(kExprEnd);
  BareEnd();
  if (Peek(TOK(default))) {
    RECURSE(ValidateDefault());
  }
  EXPECT_TOKEN('}');
  End();
}

// 6.6. ValidateCase
void AsmJsParser::ValidateCase() {
  EXPECT_TOKEN(TOK(case));
  bool negate = false;
  if (Check('-')) {
    negate = true;
  }
  uint32_t uvalue;
  if (!CheckForUnsigned(&uvalue)) {
    FAIL("Expected numeric literal");
  }
  // TODO(bradnelson): Share negation plumbing.
  if ((negate && uvalue > 0x80000000) || (!negate && uvalue > 0x7FFFFFFF)) {
    FAIL("Numeric literal out of range");
  }
  int32_t value = static_cast<int32_t>(uvalue);
  DCHECK_IMPLIES(negate && uvalue == 0x80000000, value == kMinInt);
  if (negate && value != kMinInt) {
    value = -value;
  }
  EXPECT_TOKEN(':');
  while (!failed_ && !Peek('}') && !Peek(TOK(case)) && !Peek(TOK(default))) {
    RECURSE(ValidateStatement());
  }
}

// 6.7 ValidateDefault
void AsmJsParser::ValidateDefault() {
  EXPECT_TOKEN(TOK(default));
  EXPECT_TOKEN(':');
  while (!failed_ && !Peek('}')) {
    RECURSE(ValidateStatement());
  }
}

// 6.8 ValidateExpression
AsmType* AsmJsParser::ValidateExpression() {
  AsmType* ret;
  RECURSEn(ret = Expression(nullptr));
  return ret;
}

// 6.8.1 Expression
AsmType* AsmJsParser::Expression(AsmType* expected) {
  AsmType* a;
  for (;;) {
    RECURSEn(a = AssignmentExpression());
    if (Peek(',')) {
      if (a->IsA(AsmType::None())) {
        FAILn("Expected actual type");
      }
      if (!a->IsA(AsmType::Void())) {
        current_function_builder_->Emit(kExprDrop);
      }
      EXPECT_TOKENn(',');
      continue;
    }
    break;
  }
  if (expected != nullptr && !a->IsA(expected)) {
    FAILn("Unexpected type");
  }
  return a;
}

// 6.8.2 NumericLiteral
AsmType* AsmJsParser::NumericLiteral() {
  call_coercion_ = nullptr;
  double dvalue = 0.0;
  uint32_t uvalue = 0;
  if (CheckForDouble(&dvalue)) {
    current_function_builder_->EmitF64Const(dvalue);
    return AsmType::Double();
  } else if (CheckForUnsigned(&uvalue)) {
    if (uvalue <= 0x7FFFFFFF) {
      current_function_builder_->EmitI32Const(static_cast<int32_t>(uvalue));
      return AsmType::FixNum();
    } else {
      current_function_builder_->EmitI32Const(static_cast<int32_t>(uvalue));
      return AsmType::Unsigned();
    }
  } else {
    FAILn("Expected numeric literal.");
  }
}

// 6.8.3 Identifier
AsmType* AsmJsParser::Identifier() {
  call_coercion_ = nullptr;
  if (scanner_.IsLocal()) {
    VarInfo* info = GetVarInfo(Consume());
    if (info->kind != VarKind::kLocal) {
      FAILn("Undefined local variable");
    }
    current_function_builder_->EmitGetLocal(info->index);
    return info->type;
  } else if (scanner_.IsGlobal()) {
    VarInfo* info = GetVarInfo(Consume());
    if (info->kind != VarKind::kGlobal) {
      FAILn("Undefined global variable");
    }
    current_function_builder_->EmitWithI32V(kExprGetGlobal, VarIndex(info));
    return info->type;
  }
  UNREACHABLE();
}

// 6.8.4 CallExpression
AsmType* AsmJsParser::CallExpression() {
  AsmType* ret;
  if (scanner_.IsGlobal() &&
      GetVarInfo(scanner_.Token())->type->IsA(stdlib_fround_)) {
    ValidateFloatCoercion();
    return AsmType::Float();
  } else if (scanner_.IsGlobal() &&
             GetVarInfo(scanner_.Token())->type->IsA(AsmType::Heap())) {
    RECURSEn(ret = MemberExpression());
  } else if (Peek('(')) {
    RECURSEn(ret = ParenthesizedExpression());
  } else if (PeekCall()) {
    RECURSEn(ret = ValidateCall());
  } else if (scanner_.IsLocal() || scanner_.IsGlobal()) {
    RECURSEn(ret = Identifier());
  } else {
    RECURSEn(ret = NumericLiteral());
  }
  return ret;
}

// 6.8.5 MemberExpression
AsmType* AsmJsParser::MemberExpression() {
  call_coercion_ = nullptr;
  RECURSEn(ValidateHeapAccess());
  DCHECK_NOT_NULL(heap_access_type_);
  if (Peek('=')) {
    inside_heap_assignment_ = true;
    return heap_access_type_->StoreType();
  } else {
#define V(array_type, wasmload, wasmstore, type)                       \
  if (heap_access_type_->IsA(AsmType::array_type())) {                 \
    current_function_builder_->Emit(kExpr##type##AsmjsLoad##wasmload); \
    return heap_access_type_->LoadType();                              \
  }
    STDLIB_ARRAY_TYPE_LIST(V)
#undef V
    FAILn("Expected valid heap load");
  }
}

// 6.8.6 AssignmentExpression
AsmType* AsmJsParser::AssignmentExpression() {
  AsmType* ret;
  if (scanner_.IsGlobal() &&
      GetVarInfo(scanner_.Token())->type->IsA(AsmType::Heap())) {
    RECURSEn(ret = ConditionalExpression());
    if (Peek('=')) {
      if (!inside_heap_assignment_) {
        FAILn("Invalid assignment target");
      }
      inside_heap_assignment_ = false;
      DCHECK_NOT_NULL(heap_access_type_);
      AsmType* heap_type = heap_access_type_;
      EXPECT_TOKENn('=');
      AsmType* value;
      RECURSEn(value = AssignmentExpression());
      if (!value->IsA(ret)) {
        FAILn("Illegal type stored to heap view");
      }
      if (heap_type->IsA(AsmType::Float32Array()) &&
          value->IsA(AsmType::DoubleQ())) {
        // Assignment to a float32 heap can be used to convert doubles.
        current_function_builder_->Emit(kExprF32ConvertF64);
      }
      if (heap_type->IsA(AsmType::Float64Array()) &&
          value->IsA(AsmType::FloatQ())) {
        // Assignment to a float64 heap can be used to convert floats.
        current_function_builder_->Emit(kExprF64ConvertF32);
      }
      ret = value;
#define V(array_type, wasmload, wasmstore, type)                         \
  if (heap_type->IsA(AsmType::array_type())) {                           \
    current_function_builder_->Emit(kExpr##type##AsmjsStore##wasmstore); \
    return ret;                                                          \
  }
      STDLIB_ARRAY_TYPE_LIST(V)
#undef V
    }
  } else if (scanner_.IsLocal() || scanner_.IsGlobal()) {
    bool is_local = scanner_.IsLocal();
    VarInfo* info = GetVarInfo(scanner_.Token());
    USE(is_local);
    ret = info->type;
    scanner_.Next();
    if (Check('=')) {
      // NOTE: Before this point, this might have been VarKind::kUnused even in
      // valid code, as it might be a label.
      if (info->kind == VarKind::kUnused) {
        FAILn("Undeclared assignment target");
      }
      if (!info->mutable_variable) {
        FAILn("Expected mutable variable in assignment");
      }
      DCHECK(is_local ? info->kind == VarKind::kLocal
                      : info->kind == VarKind::kGlobal);
      AsmType* value;
      RECURSEn(value = AssignmentExpression());
      if (!value->IsA(ret)) {
        FAILn("Type mismatch in assignment");
      }
      if (info->kind == VarKind::kLocal) {
        current_function_builder_->EmitTeeLocal(info->index);
      } else if (info->kind == VarKind::kGlobal) {
        current_function_builder_->EmitWithU32V(kExprSetGlobal, VarIndex(info));
        current_function_builder_->EmitWithU32V(kExprGetGlobal, VarIndex(info));
      } else {
        UNREACHABLE();
      }
      return ret;
    }
    scanner_.Rewind();
    RECURSEn(ret = ConditionalExpression());
  } else {
    RECURSEn(ret = ConditionalExpression());
  }
  return ret;
}

// 6.8.7 UnaryExpression
AsmType* AsmJsParser::UnaryExpression() {
  AsmType* ret;
  if (Check('-')) {
    uint32_t uvalue;
    if (CheckForUnsigned(&uvalue)) {
      // TODO(bradnelson): was supposed to be 0x7FFFFFFF, check errata.
      if (uvalue <= 0x80000000) {
        current_function_builder_->EmitI32Const(
            base::NegateWithWraparound(static_cast<int32_t>(uvalue)));
      } else {
        FAILn("Integer numeric literal out of range.");
      }
      ret = AsmType::Signed();
    } else {
      RECURSEn(ret = UnaryExpression());
      if (ret->IsA(AsmType::Int())) {
        TemporaryVariableScope tmp(this);
        current_function_builder_->EmitSetLocal(tmp.get());
        current_function_builder_->EmitI32Const(0);
        current_function_builder_->EmitGetLocal(tmp.get());
        current_function_builder_->Emit(kExprI32Sub);
        ret = AsmType::Intish();
      } else if (ret->IsA(AsmType::DoubleQ())) {
        current_function_builder_->Emit(kExprF64Neg);
        ret = AsmType::Double();
      } else if (ret->IsA(AsmType::FloatQ())) {
        current_function_builder_->Emit(kExprF32Neg);
        ret = AsmType::Floatish();
      } else {
        FAILn("expected int/double?/float?");
      }
    }
  } else if (Peek('+')) {
    call_coercion_ = AsmType::Double();
    call_coercion_position_ = scanner_.Position();
    scanner_.Next();  // Done late for correct position.
    RECURSEn(ret = UnaryExpression());
    // TODO(bradnelson): Generalize.
    if (ret->IsA(AsmType::Signed())) {
      current_function_builder_->Emit(kExprF64SConvertI32);
      ret = AsmType::Double();
    } else if (ret->IsA(AsmType::Unsigned())) {
      current_function_builder_->Emit(kExprF64UConvertI32);
      ret = AsmType::Double();
    } else if (ret->IsA(AsmType::DoubleQ())) {
      ret = AsmType::Double();
    } else if (ret->IsA(AsmType::FloatQ())) {
      current_function_builder_->Emit(kExprF64ConvertF32);
      ret = AsmType::Double();
    } else {
      FAILn("expected signed/unsigned/double?/float?");
    }
  } else if (Check('!')) {
    RECURSEn(ret = UnaryExpression());
    if (!ret->IsA(AsmType::Int())) {
      FAILn("expected int");
    }
    current_function_builder_->Emit(kExprI32Eqz);
  } else if (Check('~')) {
    if (Check('~')) {
      RECURSEn(ret = UnaryExpression());
      if (ret->IsA(AsmType::Double())) {
        current_function_builder_->Emit(kExprI32AsmjsSConvertF64);
      } else if (ret->IsA(AsmType::FloatQ())) {
        current_function_builder_->Emit(kExprI32AsmjsSConvertF32);
      } else {
        FAILn("expected double or float?");
      }
      ret = AsmType::Signed();
    } else {
      RECURSEn(ret = UnaryExpression());
      if (!ret->IsA(AsmType::Intish())) {
        FAILn("operator ~ expects intish");
      }
      current_function_builder_->EmitI32Const(0xFFFFFFFF);
      current_function_builder_->Emit(kExprI32Xor);
      ret = AsmType::Signed();
    }
  } else {
    RECURSEn(ret = CallExpression());
  }
  return ret;
}

// 6.8.8 MultiplicativeExpression
AsmType* AsmJsParser::MultiplicativeExpression() {
  AsmType* a;
  uint32_t uvalue;
  if (CheckForUnsignedBelow(0x100000, &uvalue)) {
    if (Check('*')) {
      AsmType* a;
      RECURSEn(a = UnaryExpression());
      if (!a->IsA(AsmType::Int())) {
        FAILn("Expected int");
      }
      int32_t value = static_cast<int32_t>(uvalue);
      current_function_builder_->EmitI32Const(value);
      current_function_builder_->Emit(kExprI32Mul);
      return AsmType::Intish();
    } else {
      scanner_.Rewind();
      RECURSEn(a = UnaryExpression());
    }
  } else if (Check('-')) {
    if (CheckForUnsignedBelow(0x100000, &uvalue)) {
      int32_t value = -static_cast<int32_t>(uvalue);
      current_function_builder_->EmitI32Const(value);
      if (Check('*')) {
        AsmType* a;
        RECURSEn(a = UnaryExpression());
        if (!a->IsA(AsmType::Int())) {
          FAILn("Expected int");
        }
        current_function_builder_->Emit(kExprI32Mul);
        return AsmType::Intish();
      }
      a = AsmType::Signed();
    } else {
      scanner_.Rewind();
      RECURSEn(a = UnaryExpression());
    }
  } else {
    RECURSEn(a = UnaryExpression());
  }
  for (;;) {
    if (Check('*')) {
      uint32_t uvalue;
      if (Check('-')) {
        if (CheckForUnsigned(&uvalue)) {
          if (uvalue >= 0x100000) {
            FAILn("Constant multiple out of range");
          }
          if (!a->IsA(AsmType::Int())) {
            FAILn("Integer multiply of expects int");
          }
          int32_t value = -static_cast<int32_t>(uvalue);
          current_function_builder_->EmitI32Const(value);
          current_function_builder_->Emit(kExprI32Mul);
          return AsmType::Intish();
        }
        scanner_.Rewind();
      } else if (CheckForUnsigned(&uvalue)) {
        if (uvalue >= 0x100000) {
          FAILn("Constant multiple out of range");
        }
        if (!a->IsA(AsmType::Int())) {
          FAILn("Integer multiply of expects int");
        }
        int32_t value = static_cast<int32_t>(uvalue);
        current_function_builder_->EmitI32Const(value);
        current_function_builder_->Emit(kExprI32Mul);
        return AsmType::Intish();
      }
      AsmType* b;
      RECURSEn(b = UnaryExpression());
      if (a->IsA(AsmType::DoubleQ()) && b->IsA(AsmType::DoubleQ())) {
        current_function_builder_->Emit(kExprF64Mul);
        a = AsmType::Double();
      } else if (a->IsA(AsmType::FloatQ()) && b->IsA(AsmType::FloatQ())) {
        current_function_builder_->Emit(kExprF32Mul);
        a = AsmType::Floatish();
      } else {
        FAILn("expected doubles or floats");
      }
    } else if (Check('/')) {
      AsmType* b;
      RECURSEn(b = UnaryExpression());
      if (a->IsA(AsmType::DoubleQ()) && b->IsA(AsmType::DoubleQ())) {
        current_function_builder_->Emit(kExprF64Div);
        a = AsmType::Double();
      } else if (a->IsA(AsmType::FloatQ()) && b->IsA(AsmType::FloatQ())) {
        current_function_builder_->Emit(kExprF32Div);
        a = AsmType::Floatish();
      } else if (a->IsA(AsmType::Signed()) && b->IsA(AsmType::Signed())) {
        current_function_builder_->Emit(kExprI32AsmjsDivS);
        a = AsmType::Intish();
      } else if (a->IsA(AsmType::Unsigned()) && b->IsA(AsmType::Unsigned())) {
        current_function_builder_->Emit(kExprI32AsmjsDivU);
        a = AsmType::Intish();
      } else {
        FAILn("expected doubles or floats");
      }
    } else if (Check('%')) {
      AsmType* b;
      RECURSEn(b = UnaryExpression());
      if (a->IsA(AsmType::DoubleQ()) && b->IsA(AsmType::DoubleQ())) {
        current_function_builder_->Emit(kExprF64Mod);
        a = AsmType::Double();
      } else if (a->IsA(AsmType::Signed()) && b->IsA(AsmType::Signed())) {
        current_function_builder_->Emit(kExprI32AsmjsRemS);
        a = AsmType::Intish();
      } else if (a->IsA(AsmType::Unsigned()) && b->IsA(AsmType::Unsigned())) {
        current_function_builder_->Emit(kExprI32AsmjsRemU);
        a = AsmType::Intish();
      } else {
        FAILn("expected doubles or floats");
      }
    } else {
      break;
    }
  }
  return a;
}

// 6.8.9 AdditiveExpression
AsmType* AsmJsParser::AdditiveExpression() {
  AsmType* a;
  RECURSEn(a = MultiplicativeExpression());
  int n = 0;
  for (;;) {
    if (Check('+')) {
      AsmType* b;
      RECURSEn(b = MultiplicativeExpression());
      if (a->IsA(AsmType::Double()) && b->IsA(AsmType::Double())) {
        current_function_builder_->Emit(kExprF64Add);
        a = AsmType::Double();
      } else if (a->IsA(AsmType::FloatQ()) && b->IsA(AsmType::FloatQ())) {
        current_function_builder_->Emit(kExprF32Add);
        a = AsmType::Floatish();
      } else if (a->IsA(AsmType::Int()) && b->IsA(AsmType::Int())) {
        current_function_builder_->Emit(kExprI32Add);
        a = AsmType::Intish();
        n = 2;
      } else if (a->IsA(AsmType::Intish()) && b->IsA(AsmType::Intish())) {
        // TODO(bradnelson): b should really only be Int.
        // specialize intish to capture count.
        ++n;
        if (n > (1 << 20)) {
          FAILn("more than 2^20 additive values");
        }
        current_function_builder_->Emit(kExprI32Add);
      } else {
        FAILn("illegal types for +");
      }
    } else if (Check('-')) {
      AsmType* b;
      RECURSEn(b = MultiplicativeExpression());
      if (a->IsA(AsmType::Double()) && b->IsA(AsmType::Double())) {
        current_function_builder_->Emit(kExprF64Sub);
        a = AsmType::Double();
      } else if (a->IsA(AsmType::FloatQ()) && b->IsA(AsmType::FloatQ())) {
        current_function_builder_->Emit(kExprF32Sub);
        a = AsmType::Floatish();
      } else if (a->IsA(AsmType::Int()) && b->IsA(AsmType::Int())) {
        current_function_builder_->Emit(kExprI32Sub);
        a = AsmType::Intish();
        n = 2;
      } else if (a->IsA(AsmType::Intish()) && b->IsA(AsmType::Intish())) {
        // TODO(bradnelson): b should really only be Int.
        // specialize intish to capture count.
        ++n;
        if (n > (1 << 20)) {
          FAILn("more than 2^20 additive values");
        }
        current_function_builder_->Emit(kExprI32Sub);
      } else {
        FAILn("illegal types for +");
      }
    } else {
      break;
    }
  }
  return a;
}

// 6.8.10 ShiftExpression
AsmType* AsmJsParser::ShiftExpression() {
  AsmType* a = nullptr;
  RECURSEn(a = AdditiveExpression());
  heap_access_shift_position_ = kNoHeapAccessShift;
  // TODO(bradnelson): Implement backtracking to avoid emitting code
  // for the x >>> 0 case (similar to what's there for |0).
  for (;;) {
    switch (scanner_.Token()) {
      case TOK(SAR): {
        EXPECT_TOKENn(TOK(SAR));
        heap_access_shift_position_ = kNoHeapAccessShift;
        // Remember position allowing this shift-expression to be used as part
        // of a heap access operation expecting `a >> n:NumericLiteral`.
        bool imm = false;
        size_t old_pos;
        size_t old_code;
        uint32_t shift_imm;
        if (a->IsA(AsmType::Intish()) && CheckForUnsigned(&shift_imm)) {
          old_pos = scanner_.Position();
          old_code = current_function_builder_->GetPosition();
          scanner_.Rewind();
          imm = true;
        }
        AsmType* b = nullptr;
        RECURSEn(b = AdditiveExpression());
        // Check for `a >> n:NumericLiteral` pattern.
        if (imm && old_pos == scanner_.Position()) {
          heap_access_shift_position_ = old_code;
          heap_access_shift_value_ = shift_imm;
        }
        if (!(a->IsA(AsmType::Intish()) && b->IsA(AsmType::Intish()))) {
          FAILn("Expected intish for operator >>.");
        }
        current_function_builder_->Emit(kExprI32ShrS);
        a = AsmType::Signed();
        continue;
      }
#define HANDLE_CASE(op, opcode, name, result)                        \
  case TOK(op): {                                                    \
    EXPECT_TOKENn(TOK(op));                                          \
    heap_access_shift_position_ = kNoHeapAccessShift;                \
    AsmType* b = nullptr;                                            \
    RECURSEn(b = AdditiveExpression());                              \
    if (!(a->IsA(AsmType::Intish()) && b->IsA(AsmType::Intish()))) { \
      FAILn("Expected intish for operator " #name ".");              \
    }                                                                \
    current_function_builder_->Emit(kExpr##opcode);                  \
    a = AsmType::result();                                           \
    continue;                                                        \
  }
        HANDLE_CASE(SHL, I32Shl, "<<", Signed);
        HANDLE_CASE(SHR, I32ShrU, ">>>", Unsigned);
#undef HANDLE_CASE
      default:
        return a;
    }
  }
}

// 6.8.11 RelationalExpression
AsmType* AsmJsParser::RelationalExpression() {
  AsmType* a = nullptr;
  RECURSEn(a = ShiftExpression());
  for (;;) {
    switch (scanner_.Token()) {
#define HANDLE_CASE(op, sop, uop, dop, fop, name)                             \
  case op: {                                                                  \
    EXPECT_TOKENn(op);                                                        \
    AsmType* b = nullptr;                                                     \
    RECURSEn(b = ShiftExpression());                                          \
    if (a->IsA(AsmType::Signed()) && b->IsA(AsmType::Signed())) {             \
      current_function_builder_->Emit(kExpr##sop);                            \
    } else if (a->IsA(AsmType::Unsigned()) && b->IsA(AsmType::Unsigned())) {  \
      current_function_builder_->Emit(kExpr##uop);                            \
    } else if (a->IsA(AsmType::Double()) && b->IsA(AsmType::Double())) {      \
      current_function_builder_->Emit(kExpr##dop);                            \
    } else if (a->IsA(AsmType::Float()) && b->IsA(AsmType::Float())) {        \
      current_function_builder_->Emit(kExpr##fop);                            \
    } else {                                                                  \
      FAILn("Expected signed, unsigned, double, or float for operator " #name \
            ".");                                                             \
    }                                                                         \
    a = AsmType::Int();                                                       \
    continue;                                                                 \
  }
      HANDLE_CASE('<', I32LtS, I32LtU, F64Lt, F32Lt, "<");
      HANDLE_CASE(TOK(LE), I32LeS, I32LeU, F64Le, F32Le, "<=");
      HANDLE_CASE('>', I32GtS, I32GtU, F64Gt, F32Gt, ">");
      HANDLE_CASE(TOK(GE), I32GeS, I32GeU, F64Ge, F32Ge, ">=");
#undef HANDLE_CASE
      default:
        return a;
    }
  }
}

// 6.8.12 EqualityExpression
AsmType* AsmJsParser::EqualityExpression() {
  AsmType* a = nullptr;
  RECURSEn(a = RelationalExpression());
  for (;;) {
    switch (scanner_.Token()) {
#define HANDLE_CASE(op, sop, uop, dop, fop, name)                             \
  case op: {                                                                  \
    EXPECT_TOKENn(op);                                                        \
    AsmType* b = nullptr;                                                     \
    RECURSEn(b = RelationalExpression());                                     \
    if (a->IsA(AsmType::Signed()) && b->IsA(AsmType::Signed())) {             \
      current_function_builder_->Emit(kExpr##sop);                            \
    } else if (a->IsA(AsmType::Unsigned()) && b->IsA(AsmType::Unsigned())) {  \
      current_function_builder_->Emit(kExpr##uop);                            \
    } else if (a->IsA(AsmType::Double()) && b->IsA(AsmType::Double())) {      \
      current_function_builder_->Emit(kExpr##dop);                            \
    } else if (a->IsA(AsmType::Float()) && b->IsA(AsmType::Float())) {        \
      current_function_builder_->Emit(kExpr##fop);                            \
    } else {                                                                  \
      FAILn("Expected signed, unsigned, double, or float for operator " #name \
            ".");                                                             \
    }                                                                         \
    a = AsmType::Int();                                                       \
    continue;                                                                 \
  }
      HANDLE_CASE(TOK(EQ), I32Eq, I32Eq, F64Eq, F32Eq, "==");
      HANDLE_CASE(TOK(NE), I32Ne, I32Ne, F64Ne, F32Ne, "!=");
#undef HANDLE_CASE
      default:
        return a;
    }
  }
}

// 6.8.13 BitwiseANDExpression
AsmType* AsmJsParser::BitwiseANDExpression() {
  AsmType* a = nullptr;
  RECURSEn(a = EqualityExpression());
  while (Check('&')) {
    AsmType* b = nullptr;
    RECURSEn(b = EqualityExpression());
    if (a->IsA(AsmType::Intish()) && b->IsA(AsmType::Intish())) {
      current_function_builder_->Emit(kExprI32And);
      a = AsmType::Signed();
    } else {
      FAILn("Expected intish for operator &.");
    }
  }
  return a;
}

// 6.8.14 BitwiseXORExpression
AsmType* AsmJsParser::BitwiseXORExpression() {
  AsmType* a = nullptr;
  RECURSEn(a = BitwiseANDExpression());
  while (Check('^')) {
    AsmType* b = nullptr;
    RECURSEn(b = BitwiseANDExpression());
    if (a->IsA(AsmType::Intish()) && b->IsA(AsmType::Intish())) {
      current_function_builder_->Emit(kExprI32Xor);
      a = AsmType::Signed();
    } else {
      FAILn("Expected intish for operator &.");
    }
  }
  return a;
}

// 6.8.15 BitwiseORExpression
AsmType* AsmJsParser::BitwiseORExpression() {
  AsmType* a = nullptr;
  call_coercion_deferred_position_ = scanner_.Position();
  RECURSEn(a = BitwiseXORExpression());
  while (Check('|')) {
    AsmType* b = nullptr;
    // Remember whether the first operand to this OR-expression has requested
    // deferred validation of the |0 annotation.
    // NOTE: This has to happen here to work recursively.
    bool requires_zero =
        AsmType::IsExactly(call_coercion_deferred_, AsmType::Signed());
    call_coercion_deferred_ = nullptr;
    // TODO(bradnelson): Make it prettier.
    bool zero = false;
    size_t old_pos;
    size_t old_code;
    if (a->IsA(AsmType::Intish()) && CheckForZero()) {
      old_pos = scanner_.Position();
      old_code = current_function_builder_->GetPosition();
      scanner_.Rewind();
      zero = true;
    }
    RECURSEn(b = BitwiseXORExpression());
    // Handle |0 specially.
    if (zero && old_pos == scanner_.Position()) {
      current_function_builder_->DeleteCodeAfter(old_code);
      a = AsmType::Signed();
      continue;
    }
    // Anything not matching |0 breaks the lookahead in {ValidateCall}.
    if (requires_zero) {
      FAILn("Expected |0 type annotation for call");
    }
    if (a->IsA(AsmType::Intish()) && b->IsA(AsmType::Intish())) {
      current_function_builder_->Emit(kExprI32Ior);
      a = AsmType::Signed();
    } else {
      FAILn("Expected intish for operator |.");
    }
  }
  DCHECK_NULL(call_coercion_deferred_);
  return a;
}

// 6.8.16 ConditionalExpression
AsmType* AsmJsParser::ConditionalExpression() {
  AsmType* test = nullptr;
  RECURSEn(test = BitwiseORExpression());
  if (Check('?')) {
    if (!test->IsA(AsmType::Int())) {
      FAILn("Expected int in condition of ternary operator.");
    }
    current_function_builder_->EmitWithU8(kExprIf, kLocalI32);
    size_t fixup = current_function_builder_->GetPosition() -
                   1;  // Assumes encoding knowledge.
    AsmType* cons = nullptr;
    RECURSEn(cons = AssignmentExpression());
    current_function_builder_->Emit(kExprElse);
    EXPECT_TOKENn(':');
    AsmType* alt = nullptr;
    RECURSEn(alt = AssignmentExpression());
    current_function_builder_->Emit(kExprEnd);
    if (cons->IsA(AsmType::Int()) && alt->IsA(AsmType::Int())) {
      current_function_builder_->FixupByte(fixup, kLocalI32);
      return AsmType::Int();
    } else if (cons->IsA(AsmType::Double()) && alt->IsA(AsmType::Double())) {
      current_function_builder_->FixupByte(fixup, kLocalF64);
      return AsmType::Double();
    } else if (cons->IsA(AsmType::Float()) && alt->IsA(AsmType::Float())) {
      current_function_builder_->FixupByte(fixup, kLocalF32);
      return AsmType::Float();
    } else {
      FAILn("Type mismatch in ternary operator.");
    }
  } else {
    return test;
  }
}

// 6.8.17 ParenthesiedExpression
AsmType* AsmJsParser::ParenthesizedExpression() {
  call_coercion_ = nullptr;
  AsmType* ret;
  EXPECT_TOKENn('(');
  RECURSEn(ret = Expression(nullptr));
  EXPECT_TOKENn(')');
  return ret;
}

// 6.9 ValidateCall
AsmType* AsmJsParser::ValidateCall() {
  AsmType* return_type = call_coercion_;
  call_coercion_ = nullptr;
  size_t call_pos = scanner_.Position();
  size_t to_number_pos = call_coercion_position_;
  bool allow_peek = (call_coercion_deferred_position_ == scanner_.Position());
  AsmJsScanner::token_t function_name = Consume();

  // Distinguish between ordinary function calls and function table calls. In
  // both cases we might be seeing the {function_name} for the first time and
  // hence allocate a {VarInfo} here, all subsequent uses of the same name then
  // need to match the information stored at this point.
  base::Optional<TemporaryVariableScope> tmp;
  if (Check('[')) {
    AsmType* index = nullptr;
    RECURSEn(index = EqualityExpression());
    if (!index->IsA(AsmType::Intish())) {
      FAILn("Expected intish index");
    }
    EXPECT_TOKENn('&');
    uint32_t mask = 0;
    if (!CheckForUnsigned(&mask)) {
      FAILn("Expected mask literal");
    }
    if (!base::bits::IsPowerOfTwo(mask + 1)) {
      FAILn("Expected power of 2 mask");
    }
    current_function_builder_->EmitI32Const(mask);
    current_function_builder_->Emit(kExprI32And);
    EXPECT_TOKENn(']');
    VarInfo* function_info = GetVarInfo(function_name);
    if (function_info->kind == VarKind::kUnused) {
      uint32_t index = module_builder_->AllocateIndirectFunctions(mask + 1);
      if (index == std::numeric_limits<uint32_t>::max()) {
        FAILn("Exceeded maximum function table size");
      }
      function_info->kind = VarKind::kTable;
      function_info->mask = mask;
      function_info->index = index;
      function_info->mutable_variable = false;
    } else {
      if (function_info->kind != VarKind::kTable) {
        FAILn("Expected call table");
      }
      if (function_info->mask != mask) {
        FAILn("Mask size mismatch");
      }
    }
    current_function_builder_->EmitI32Const(function_info->index);
    current_function_builder_->Emit(kExprI32Add);
    // We have to use a temporary for the correct order of evaluation.
    tmp.emplace(this);
    current_function_builder_->EmitSetLocal(tmp->get());
    // The position of function table calls is after the table lookup.
    call_pos = scanner_.Position();
  } else {
    VarInfo* function_info = GetVarInfo(function_name);
    if (function_info->kind == VarKind::kUnused) {
      function_info->kind = VarKind::kFunction;
      function_info->function_builder = module_builder_->AddFunction();
      function_info->index = function_info->function_builder->func_index();
      function_info->mutable_variable = false;
    } else {
      if (function_info->kind != VarKind::kFunction &&
          function_info->kind < VarKind::kImportedFunction) {
        FAILn("Expected function as call target");
      }
    }
  }

  // Parse argument list and gather types.
  CachedVector<AsmType*> param_types(&cached_asm_type_p_vectors_);
  CachedVector<AsmType*> param_specific_types(&cached_asm_type_p_vectors_);
  EXPECT_TOKENn('(');
  while (!failed_ && !Peek(')')) {
    AsmType* t;
    RECURSEn(t = AssignmentExpression());
    param_specific_types.push_back(t);
    if (t->IsA(AsmType::Int())) {
      param_types.push_back(AsmType::Int());
    } else if (t->IsA(AsmType::Float())) {
      param_types.push_back(AsmType::Float());
    } else if (t->IsA(AsmType::Double())) {
      param_types.push_back(AsmType::Double());
    } else {
      FAILn("Bad function argument type");
    }
    if (!Peek(')')) {
      EXPECT_TOKENn(',');
    }
  }
  EXPECT_TOKENn(')');

  // Reload {VarInfo} after parsing arguments as table might have grown.
  VarInfo* function_info = GetVarInfo(function_name);

  // We potentially use lookahead in order to determine the return type in case
  // it is not yet clear from the call context. Special care has to be taken to
  // ensure the non-contextual lookahead is valid. The following restrictions
  // substantiate the validity of the lookahead implemented below:
  //  - All calls (except stdlib calls) require some sort of type annotation.
  //  - The coercion to "signed" is part of the {BitwiseORExpression}, any
  //    intermittent expressions like parenthesis in `(callsite(..))|0` are
  //    syntactically not considered coercions.
  //  - The coercion to "double" as part of the {UnaryExpression} has higher
  //    precedence and wins in `+callsite(..)|0` cases. Only "float" return
  //    types are overridden in `fround(callsite(..)|0)` expressions.
  //  - Expected coercions to "signed" are flagged via {call_coercion_deferred}
  //    and later on validated as part of {BitwiseORExpression} to ensure they
  //    indeed apply to the current call expression.
  //  - The deferred validation is only allowed if {BitwiseORExpression} did
  //    promise to fulfill the request via {call_coercion_deferred_position}.
  if (allow_peek && Peek('|') &&
      function_info->kind <= VarKind::kImportedFunction &&
      (return_type == nullptr || return_type->IsA(AsmType::Float()))) {
    DCHECK_NULL(call_coercion_deferred_);
    call_coercion_deferred_ = AsmType::Signed();
    to_number_pos = scanner_.Position();
    return_type = AsmType::Signed();
  } else if (return_type == nullptr) {
    to_number_pos = call_pos;  // No conversion.
    return_type = AsmType::Void();
  }

  // Compute function type and signature based on gathered types.
  AsmType* function_type = AsmType::Function(zone(), return_type);
  for (auto t : param_types) {
    function_type->AsFunctionType()->AddArgument(t);
  }
  FunctionSig* sig = ConvertSignature(return_type, param_types);
  uint32_t signature_index = module_builder_->AddSignature(sig);

  // Emit actual function invocation depending on the kind. At this point we
  // also determined the complete function type and can perform checking against
  // the expected type or update the expected type in case of first occurrence.
  if (function_info->kind == VarKind::kImportedFunction) {
    for (auto t : param_specific_types) {
      if (!t->IsA(AsmType::Extern())) {
        FAILn("Imported function args must be type extern");
      }
    }
    if (return_type->IsA(AsmType::Float())) {
      FAILn("Imported function can't be called as float");
    }
    DCHECK_NOT_NULL(function_info->import);
    // TODO(bradnelson): Factor out.
    uint32_t index;
    auto it = function_info->import->cache.find(*sig);
    if (it != function_info->import->cache.end()) {
      index = it->second;
      DCHECK(function_info->function_defined);
    } else {
      index =
          module_builder_->AddImport(function_info->import->function_name, sig);
      function_info->import->cache[*sig] = index;
      function_info->function_defined = true;
    }
    current_function_builder_->AddAsmWasmOffset(call_pos, to_number_pos);
    current_function_builder_->EmitWithU32V(kExprCallFunction, index);
  } else if (function_info->kind > VarKind::kImportedFunction) {
    AsmCallableType* callable = function_info->type->AsCallableType();
    if (!callable) {
      FAILn("Expected callable function");
    }
    // TODO(bradnelson): Refactor AsmType to not need this.
    if (callable->CanBeInvokedWith(return_type, param_specific_types)) {
      // Return type ok.
    } else if (callable->CanBeInvokedWith(AsmType::Float(),
                                          param_specific_types)) {
      return_type = AsmType::Float();
    } else if (callable->CanBeInvokedWith(AsmType::Floatish(),
                                          param_specific_types)) {
      return_type = AsmType::Floatish();
    } else if (callable->CanBeInvokedWith(AsmType::Double(),
                                          param_specific_types)) {
      return_type = AsmType::Double();
    } else if (callable->CanBeInvokedWith(AsmType::Signed(),
                                          param_specific_types)) {
      return_type = AsmType::Signed();
    } else if (callable->CanBeInvokedWith(AsmType::Unsigned(),
                                          param_specific_types)) {
      return_type = AsmType::Unsigned();
    } else {
      FAILn("Function use doesn't match definition");
    }
    switch (function_info->kind) {
#define V(name, Name, op, sig)           \
  case VarKind::kMath##Name:             \
    current_function_builder_->Emit(op); \
    break;
      STDLIB_MATH_FUNCTION_MONOMORPHIC_LIST(V)
#undef V
#define V(name, Name, op, sig)                                    \
  case VarKind::kMath##Name:                                      \
    if (param_specific_types[0]->IsA(AsmType::DoubleQ())) {       \
      current_function_builder_->Emit(kExprF64##Name);            \
    } else if (param_specific_types[0]->IsA(AsmType::FloatQ())) { \
      current_function_builder_->Emit(kExprF32##Name);            \
    } else {                                                      \
      UNREACHABLE();                                              \
    }                                                             \
    break;
      STDLIB_MATH_FUNCTION_CEIL_LIKE_LIST(V)
#undef V
      case VarKind::kMathMin:
      case VarKind::kMathMax:
        if (param_specific_types[0]->IsA(AsmType::Double())) {
          for (size_t i = 1; i < param_specific_types.size(); ++i) {
            if (function_info->kind == VarKind::kMathMin) {
              current_function_builder_->Emit(kExprF64Min);
            } else {
              current_function_builder_->Emit(kExprF64Max);
            }
          }
        } else if (param_specific_types[0]->IsA(AsmType::Float())) {
          // NOTE: Not technically part of the asm.js spec, but Firefox
          // accepts it.
          for (size_t i = 1; i < param_specific_types.size(); ++i) {
            if (function_info->kind == VarKind::kMathMin) {
              current_function_builder_->Emit(kExprF32Min);
            } else {
              current_function_builder_->Emit(kExprF32Max);
            }
          }
        } else if (param_specific_types[0]->IsA(AsmType::Signed())) {
          TemporaryVariableScope tmp_x(this);
          TemporaryVariableScope tmp_y(this);
          for (size_t i = 1; i < param_specific_types.size(); ++i) {
            current_function_builder_->EmitSetLocal(tmp_x.get());
            current_function_builder_->EmitTeeLocal(tmp_y.get());
            current_function_builder_->EmitGetLocal(tmp_x.get());
            if (function_info->kind == VarKind::kMathMin) {
              current_function_builder_->Emit(kExprI32GeS);
            } else {
              current_function_builder_->Emit(kExprI32LeS);
            }
            current_function_builder_->EmitWithU8(kExprIf, kLocalI32);
            current_function_builder_->EmitGetLocal(tmp_x.get());
            current_function_builder_->Emit(kExprElse);
            current_function_builder_->EmitGetLocal(tmp_y.get());
            current_function_builder_->Emit(kExprEnd);
          }
        } else {
          UNREACHABLE();
        }
        break;

      case VarKind::kMathAbs:
        if (param_specific_types[0]->IsA(AsmType::Signed())) {
          TemporaryVariableScope tmp(this);
          current_function_builder_->EmitTeeLocal(tmp.get());
          current_function_builder_->EmitGetLocal(tmp.get());
          current_function_builder_->EmitI32Const(31);
          current_function_builder_->Emit(kExprI32ShrS);
          current_function_builder_->EmitTeeLocal(tmp.get());
          current_function_builder_->Emit(kExprI32Xor);
          current_function_builder_->EmitGetLocal(tmp.get());
          current_function_builder_->Emit(kExprI32Sub);
        } else if (param_specific_types[0]->IsA(AsmType::DoubleQ())) {
          current_function_builder_->Emit(kExprF64Abs);
        } else if (param_specific_types[0]->IsA(AsmType::FloatQ())) {
          current_function_builder_->Emit(kExprF32Abs);
        } else {
          UNREACHABLE();
        }
        break;

      case VarKind::kMathFround:
        // NOTE: Handled in {AsmJsParser::CallExpression} specially and treated
        // as a coercion to "float" type. Cannot be reached as a call here.
        UNREACHABLE();

      default:
        UNREACHABLE();
    }
  } else {
    DCHECK(function_info->kind == VarKind::kFunction ||
           function_info->kind == VarKind::kTable);
    if (function_info->type->IsA(AsmType::None())) {
      function_info->type = function_type;
    } else {
      AsmCallableType* callable = function_info->type->AsCallableType();
      if (!callable ||
          !callable->CanBeInvokedWith(return_type, param_specific_types)) {
        FAILn("Function use doesn't match definition");
      }
    }
    if (function_info->kind == VarKind::kTable) {
      current_function_builder_->EmitGetLocal(tmp->get());
      current_function_builder_->AddAsmWasmOffset(call_pos, to_number_pos);
      current_function_builder_->Emit(kExprCallIndirect);
      current_function_builder_->EmitU32V(signature_index);
      current_function_builder_->EmitU32V(0);  // table index
    } else {
      current_function_builder_->AddAsmWasmOffset(call_pos, to_number_pos);
      current_function_builder_->Emit(kExprCallFunction);
      current_function_builder_->EmitDirectCallIndex(function_info->index);
    }
  }

  return return_type;
}

// 6.9 ValidateCall - helper
bool AsmJsParser::PeekCall() {
  if (!scanner_.IsGlobal()) {
    return false;
  }
  if (GetVarInfo(scanner_.Token())->kind == VarKind::kFunction) {
    return true;
  }
  if (GetVarInfo(scanner_.Token())->kind >= VarKind::kImportedFunction) {
    return true;
  }
  if (GetVarInfo(scanner_.Token())->kind == VarKind::kUnused ||
      GetVarInfo(scanner_.Token())->kind == VarKind::kTable) {
    scanner_.Next();
    if (Peek('(') || Peek('[')) {
      scanner_.Rewind();
      return true;
    }
    scanner_.Rewind();
  }
  return false;
}

// 6.10 ValidateHeapAccess
void AsmJsParser::ValidateHeapAccess() {
  VarInfo* info = GetVarInfo(Consume());
  int32_t size = info->type->ElementSizeInBytes();
  EXPECT_TOKEN('[');
  uint32_t offset;
  if (CheckForUnsigned(&offset)) {
    // TODO(bradnelson): Check more things.
    // TODO(mstarzinger): Clarify and explain where this limit is coming from,
    // as it is not mandated by the spec directly.
    if (offset > 0x7FFFFFFF ||
        static_cast<uint64_t>(offset) * static_cast<uint64_t>(size) >
            0x7FFFFFFF) {
      FAIL("Heap access out of range");
    }
    if (Check(']')) {
      current_function_builder_->EmitI32Const(
          static_cast<uint32_t>(offset * size));
      // NOTE: This has to happen here to work recursively.
      heap_access_type_ = info->type;
      return;
    } else {
      scanner_.Rewind();
    }
  }
  AsmType* index_type;
  if (info->type->IsA(AsmType::Int8Array()) ||
      info->type->IsA(AsmType::Uint8Array())) {
    RECURSE(index_type = Expression(nullptr));
  } else {
    RECURSE(index_type = ShiftExpression());
    if (heap_access_shift_position_ == kNoHeapAccessShift) {
      FAIL("Expected shift of word size");
    }
    if (heap_access_shift_value_ > 3) {
      FAIL("Expected valid heap access shift");
    }
    if ((1 << heap_access_shift_value_) != size) {
      FAIL("Expected heap access shift to match heap view");
    }
    // Delete the code of the actual shift operation.
    current_function_builder_->DeleteCodeAfter(heap_access_shift_position_);
    // Mask bottom bits to match asm.js behavior.
    current_function_builder_->EmitI32Const(~(size - 1));
    current_function_builder_->Emit(kExprI32And);
  }
  if (!index_type->IsA(AsmType::Intish())) {
    FAIL("Expected intish index");
  }
  EXPECT_TOKEN(']');
  // NOTE: This has to happen here to work recursively.
  heap_access_type_ = info->type;
}

// 6.11 ValidateFloatCoercion
void AsmJsParser::ValidateFloatCoercion() {
  if (!scanner_.IsGlobal() ||
      !GetVarInfo(scanner_.Token())->type->IsA(stdlib_fround_)) {
    FAIL("Expected fround");
  }
  scanner_.Next();
  EXPECT_TOKEN('(');
  call_coercion_ = AsmType::Float();
  // NOTE: The coercion position to float is not observable from JavaScript,
  // because imported functions are not allowed to have float return type.
  call_coercion_position_ = scanner_.Position();
  AsmType* ret;
  RECURSE(ret = ValidateExpression());
  if (ret->IsA(AsmType::Floatish())) {
    // Do nothing, as already a float.
  } else if (ret->IsA(AsmType::DoubleQ())) {
    current_function_builder_->Emit(kExprF32ConvertF64);
  } else if (ret->IsA(AsmType::Signed())) {
    current_function_builder_->Emit(kExprF32SConvertI32);
  } else if (ret->IsA(AsmType::Unsigned())) {
    current_function_builder_->Emit(kExprF32UConvertI32);
  } else {
    FAIL("Illegal conversion to float");
  }
  EXPECT_TOKEN(')');
}

void AsmJsParser::ScanToClosingParenthesis() {
  int depth = 0;
  for (;;) {
    if (Peek('(')) {
      ++depth;
    } else if (Peek(')')) {
      --depth;
      if (depth < 0) {
        break;
      }
    } else if (Peek(AsmJsScanner::kEndOfInput)) {
      break;
    }
    scanner_.Next();
  }
}

void AsmJsParser::GatherCases(ZoneVector<int32_t>* cases) {
  size_t start = scanner_.Position();
  int depth = 0;
  for (;;) {
    if (Peek('{')) {
      ++depth;
    } else if (Peek('}')) {
      --depth;
      if (depth <= 0) {
        break;
      }
    } else if (depth == 1 && Peek(TOK(case))) {
      scanner_.Next();
      uint32_t uvalue;
      bool negate = false;
      if (Check('-')) negate = true;
      if (!CheckForUnsigned(&uvalue)) {
        break;
      }
      int32_t value = static_cast<int32_t>(uvalue);
      DCHECK_IMPLIES(negate && uvalue == 0x80000000, value == kMinInt);
      if (negate && value != kMinInt) {
        value = -value;
      }
      cases->push_back(value);
    } else if (Peek(AsmJsScanner::kEndOfInput) ||
               Peek(AsmJsScanner::kParseError)) {
      break;
    }
    scanner_.Next();
  }
  scanner_.Seek(start);
}

}  // namespace wasm
}  // namespace internal
}  // namespace v8

#undef RECURSE
