// Copyright 2016 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-typer.h"

#include <algorithm>
#include <limits>
#include <memory>
#include <string>

#include "src/v8.h"

#include "src/asmjs/asm-types.h"
#include "src/ast/ast.h"
#include "src/ast/scopes.h"
#include "src/base/bits.h"
#include "src/codegen.h"
#include "src/globals.h"
#include "src/utils.h"

#define FAIL_LINE(line, msg)                                   \
  do {                                                         \
    base::OS::SNPrintF(error_message_, sizeof(error_message_), \
                       "asm: line %d: %s", (line) + 1, msg);   \
    return AsmType::None();                                    \
  } while (false)

#define FAIL(node, msg)                                        \
  do {                                                         \
    int line = node->position() == kNoSourcePosition           \
                   ? -1                                        \
                   : script_->GetLineNumber(node->position()); \
    FAIL_LINE(line, msg);                                      \
  } while (false)

#define RECURSE(call)                                             \
  do {                                                            \
    if (GetCurrentStackPosition() < stack_limit_) {               \
      stack_overflow_ = true;                                     \
      FAIL(root_, "Stack overflow while parsing asm.js module."); \
    }                                                             \
                                                                  \
    AsmType* result = (call);                                     \
    if (stack_overflow_) {                                        \
      return AsmType::None();                                     \
    }                                                             \
                                                                  \
    if (result == AsmType::None()) {                              \
      return AsmType::None();                                     \
    }                                                             \
  } while (false)

namespace v8 {
namespace internal {
namespace wasm {
namespace {
static const uint32_t LargestFixNum = std::numeric_limits<int32_t>::max();
}  // namespace

using v8::internal::AstNode;
using v8::internal::GetCurrentStackPosition;

// ----------------------------------------------------------------------------
// Implementation of AsmTyper::FlattenedStatements

AsmTyper::FlattenedStatements::FlattenedStatements(Zone* zone,
                                                   ZoneList<Statement*>* s)
    : context_stack_(zone) {
  context_stack_.emplace_back(Context(s));
}

Statement* AsmTyper::FlattenedStatements::Next() {
  for (;;) {
    if (context_stack_.empty()) {
      return nullptr;
    }

    Context* current = &context_stack_.back();

    if (current->statements_->length() <= current->next_index_) {
      context_stack_.pop_back();
      continue;
    }

    Statement* current_statement =
        current->statements_->at(current->next_index_++);
    if (current_statement->IsBlock()) {
      context_stack_.emplace_back(
          Context(current_statement->AsBlock()->statements()));
      continue;
    }

    return current_statement;
  }
}

// ----------------------------------------------------------------------------
// Implementation of AsmTyper::SourceLayoutTracker

bool AsmTyper::SourceLayoutTracker::IsValid() const {
  const Section* kAllSections[] = {&use_asm_, &globals_, &functions_, &tables_,
                                   &exports_};
  for (size_t ii = 0; ii < arraysize(kAllSections); ++ii) {
    const auto& curr_section = *kAllSections[ii];
    for (size_t jj = ii + 1; jj < arraysize(kAllSections); ++jj) {
      if (curr_section.IsPrecededBy(*kAllSections[jj])) {
        return false;
      }
    }
  }
  return true;
}

void AsmTyper::SourceLayoutTracker::Section::AddNewElement(
    const AstNode& node) {
  const int node_pos = node.position();
  if (start_ == kNoSourcePosition) {
    start_ = node_pos;
  } else {
    start_ = std::min(start_, node_pos);
  }
  if (end_ == kNoSourcePosition) {
    end_ = node_pos;
  } else {
    end_ = std::max(end_, node_pos);
  }
}

bool AsmTyper::SourceLayoutTracker::Section::IsPrecededBy(
    const Section& other) const {
  if (start_ == kNoSourcePosition) {
    DCHECK_EQ(end_, kNoSourcePosition);
    return false;
  }
  if (other.start_ == kNoSourcePosition) {
    DCHECK_EQ(other.end_, kNoSourcePosition);
    return false;
  }
  DCHECK_LE(start_, end_);
  DCHECK_LE(other.start_, other.end_);
  return other.start_ <= end_;
}

// ----------------------------------------------------------------------------
// Implementation of AsmTyper::VariableInfo

AsmTyper::VariableInfo* AsmTyper::VariableInfo::ForSpecialSymbol(
    Zone* zone, StandardMember standard_member) {
  DCHECK(standard_member == kStdlib || standard_member == kFFI ||
         standard_member == kHeap || standard_member == kModule);
  auto* new_var_info = new (zone) VariableInfo(AsmType::None());
  new_var_info->standard_member_ = standard_member;
  new_var_info->mutability_ = kImmutableGlobal;
  return new_var_info;
}

AsmTyper::VariableInfo* AsmTyper::VariableInfo::Clone(Zone* zone) const {
  CHECK(standard_member_ != kNone);
  CHECK(!type_->IsA(AsmType::None()));
  auto* new_var_info = new (zone) VariableInfo(type_);
  new_var_info->standard_member_ = standard_member_;
  new_var_info->mutability_ = mutability_;
  return new_var_info;
}

void AsmTyper::VariableInfo::SetFirstForwardUse(int source_location) {
  DCHECK(source_location_ == -1);
  missing_definition_ = true;
  source_location_ = source_location;
}

// ----------------------------------------------------------------------------
// Implementation of AsmTyper

AsmTyper::AsmTyper(Isolate* isolate, Zone* zone, Script* script,
                   FunctionLiteral* root)
    : isolate_(isolate),
      zone_(zone),
      script_(script),
      root_(root),
      forward_definitions_(zone),
      ffi_use_signatures_(zone),
      stdlib_types_(zone),
      stdlib_math_types_(zone),
      module_info_(VariableInfo::ForSpecialSymbol(zone_, kModule)),
      global_scope_(ZoneHashMap::kDefaultHashMapCapacity,
                    ZoneAllocationPolicy(zone)),
      local_scope_(ZoneHashMap::kDefaultHashMapCapacity,
                   ZoneAllocationPolicy(zone)),
      stack_limit_(isolate->stack_guard()->real_climit()),
      module_node_types_(zone_),
      function_node_types_(zone_),
      fround_type_(AsmType::FroundType(zone_)),
      ffi_type_(AsmType::FFIType(zone_)),
      function_pointer_tables_(zone_) {
  InitializeStdlib();
}

namespace {
bool ValidAsmIdentifier(Handle<String> name) {
  static const char* kInvalidAsmNames[] = {"eval", "arguments"};

  for (size_t ii = 0; ii < arraysize(kInvalidAsmNames); ++ii) {
    if (strcmp(name->ToCString().get(), kInvalidAsmNames[ii]) == 0) {
      return false;
    }
  }
  return true;
}
}  // namespace

void AsmTyper::InitializeStdlib() {
  auto* d = AsmType::Double();
  auto* dq = AsmType::DoubleQ();
  auto* dq2d = AsmType::Function(zone_, d);
  dq2d->AsFunctionType()->AddArgument(dq);

  auto* dqdq2d = AsmType::Function(zone_, d);
  dqdq2d->AsFunctionType()->AddArgument(dq);
  dqdq2d->AsFunctionType()->AddArgument(dq);

  auto* f = AsmType::Float();
  auto* fq = AsmType::FloatQ();
  auto* fq2f = AsmType::Function(zone_, f);
  fq2f->AsFunctionType()->AddArgument(fq);

  auto* s = AsmType::Signed();
  auto* s2s = AsmType::Function(zone_, s);
  s2s->AsFunctionType()->AddArgument(s);

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

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

  auto* minmax_d = AsmType::MinMaxType(zone_, d, d);
  // *VIOLATION* The float variant is not part of the spec, but firefox accepts
  // it.
  auto* minmax_f = AsmType::MinMaxType(zone_, f, f);
  auto* minmax_i = AsmType::MinMaxType(zone_, s, i);
  auto* minmax = AsmType::OverloadedFunction(zone_);
  minmax->AsOverloadedFunctionType()->AddOverload(minmax_i);
  minmax->AsOverloadedFunctionType()->AddOverload(minmax_f);
  minmax->AsOverloadedFunctionType()->AddOverload(minmax_d);

  auto* fround = fround_type_;

  auto* abs = AsmType::OverloadedFunction(zone_);
  abs->AsOverloadedFunctionType()->AddOverload(s2s);
  abs->AsOverloadedFunctionType()->AddOverload(dq2d);
  abs->AsOverloadedFunctionType()->AddOverload(fq2f);

  auto* ceil = AsmType::OverloadedFunction(zone_);
  ceil->AsOverloadedFunctionType()->AddOverload(dq2d);
  ceil->AsOverloadedFunctionType()->AddOverload(fq2f);

  auto* floor = ceil;
  auto* sqrt = ceil;

  struct StandardMemberInitializer {
    const char* name;
    StandardMember standard_member;
    AsmType* type;
  };

  const StandardMemberInitializer stdlib[] = {{"Infinity", kInfinity, d},
                                              {"NaN", kNaN, d},
#define ASM_TYPED_ARRAYS(V) \
  V(Uint8)                  \
  V(Int8)                   \
  V(Uint16)                 \
  V(Int16)                  \
  V(Uint32)                 \
  V(Int32)                  \
  V(Float32)                \
  V(Float64)

#define ASM_TYPED_ARRAY(TypeName) \
  {#TypeName "Array", kNone, AsmType::TypeName##Array()},
                                              ASM_TYPED_ARRAYS(ASM_TYPED_ARRAY)
#undef ASM_TYPED_ARRAY
  };
  for (size_t ii = 0; ii < arraysize(stdlib); ++ii) {
    stdlib_types_[stdlib[ii].name] = new (zone_) VariableInfo(stdlib[ii].type);
    stdlib_types_[stdlib[ii].name]->set_standard_member(
        stdlib[ii].standard_member);
    stdlib_types_[stdlib[ii].name]->set_mutability(
        VariableInfo::kImmutableGlobal);
  }

  const StandardMemberInitializer math[] = {
      {"PI", kMathPI, d},
      {"E", kMathE, d},
      {"LN2", kMathLN2, d},
      {"LN10", kMathLN10, d},
      {"LOG2E", kMathLOG2E, d},
      {"LOG10E", kMathLOG10E, d},
      {"SQRT2", kMathSQRT2, d},
      {"SQRT1_2", kMathSQRT1_2, d},
      {"imul", kMathImul, ii2s},
      {"abs", kMathAbs, abs},
      // NOTE: clz32 should return fixnum. The current typer can only return
      // Signed, Float, or Double, so it returns Signed in our version of
      // asm.js.
      {"clz32", kMathClz32, i2s},
      {"ceil", kMathCeil, ceil},
      {"floor", kMathFloor, floor},
      {"fround", kMathFround, fround},
      {"pow", kMathPow, dqdq2d},
      {"exp", kMathExp, dq2d},
      {"log", kMathLog, dq2d},
      {"min", kMathMin, minmax},
      {"max", kMathMax, minmax},
      {"sqrt", kMathSqrt, sqrt},
      {"cos", kMathCos, dq2d},
      {"sin", kMathSin, dq2d},
      {"tan", kMathTan, dq2d},
      {"acos", kMathAcos, dq2d},
      {"asin", kMathAsin, dq2d},
      {"atan", kMathAtan, dq2d},
      {"atan2", kMathAtan2, dqdq2d},
  };
  for (size_t ii = 0; ii < arraysize(math); ++ii) {
    stdlib_math_types_[math[ii].name] = new (zone_) VariableInfo(math[ii].type);
    stdlib_math_types_[math[ii].name]->set_standard_member(
        math[ii].standard_member);
    stdlib_math_types_[math[ii].name]->set_mutability(
        VariableInfo::kImmutableGlobal);
  }
}

// Used for 5.5 GlobalVariableTypeAnnotations
AsmTyper::VariableInfo* AsmTyper::ImportLookup(Property* import) {
  auto* obj = import->obj();
  auto* key = import->key()->AsLiteral();

  ObjectTypeMap* stdlib = &stdlib_types_;
  if (auto* obj_as_property = obj->AsProperty()) {
    // This can only be stdlib.Math
    auto* math_name = obj_as_property->key()->AsLiteral();
    if (math_name == nullptr || !math_name->IsPropertyName()) {
      return nullptr;
    }

    if (!math_name->AsPropertyName()->IsUtf8EqualTo(CStrVector("Math"))) {
      return nullptr;
    }

    auto* stdlib_var_proxy = obj_as_property->obj()->AsVariableProxy();
    if (stdlib_var_proxy == nullptr) {
      return nullptr;
    }
    obj = stdlib_var_proxy;
    stdlib = &stdlib_math_types_;
  }

  auto* obj_as_var_proxy = obj->AsVariableProxy();
  if (obj_as_var_proxy == nullptr) {
    return nullptr;
  }

  auto* obj_info = Lookup(obj_as_var_proxy->var());
  if (obj_info == nullptr) {
    return nullptr;
  }

  if (obj_info->IsFFI()) {
    // For FFI we can't validate import->key, so assume this is OK.
    return obj_info;
  }

  std::unique_ptr<char[]> aname = key->AsPropertyName()->ToCString();
  ObjectTypeMap::iterator i = stdlib->find(std::string(aname.get()));
  if (i == stdlib->end()) {
    return nullptr;
  }
  stdlib_uses_.insert(i->second->standard_member());
  return i->second;
}

AsmTyper::VariableInfo* AsmTyper::Lookup(Variable* variable) const {
  const ZoneHashMap* scope = in_function_ ? &local_scope_ : &global_scope_;
  ZoneHashMap::Entry* entry =
      scope->Lookup(variable, ComputePointerHash(variable));
  if (entry == nullptr && in_function_) {
    entry = global_scope_.Lookup(variable, ComputePointerHash(variable));
  }

  if (entry == nullptr && !module_name_.is_null() &&
      module_name_->Equals(*variable->name())) {
    return module_info_;
  }

  return entry ? reinterpret_cast<VariableInfo*>(entry->value) : nullptr;
}

void AsmTyper::AddForwardReference(VariableProxy* proxy, VariableInfo* info) {
  info->SetFirstForwardUse(proxy->position() == kNoSourcePosition
                               ? -1
                               : script_->GetLineNumber(proxy->position()));
  forward_definitions_.push_back(info);
}

bool AsmTyper::AddGlobal(Variable* variable, VariableInfo* info) {
  // We can't DCHECK(!in_function_) because function may actually install global
  // names (forward defined functions and function tables.)
  DCHECK(info->mutability() != VariableInfo::kInvalidMutability);
  DCHECK(info->IsGlobal());
  DCHECK(ValidAsmIdentifier(variable->name()));

  if (!module_name_.is_null() && module_name_->Equals(*variable->name())) {
    return false;
  }

  ZoneHashMap::Entry* entry = global_scope_.LookupOrInsert(
      variable, ComputePointerHash(variable), ZoneAllocationPolicy(zone_));

  if (entry->value != nullptr) {
    return false;
  }

  entry->value = info;
  return true;
}

bool AsmTyper::AddLocal(Variable* variable, VariableInfo* info) {
  DCHECK(in_function_);
  DCHECK(info->mutability() != VariableInfo::kInvalidMutability);
  DCHECK(!info->IsGlobal());
  DCHECK(ValidAsmIdentifier(variable->name()));

  ZoneHashMap::Entry* entry = local_scope_.LookupOrInsert(
      variable, ComputePointerHash(variable), ZoneAllocationPolicy(zone_));

  if (entry->value != nullptr) {
    return false;
  }

  entry->value = info;
  return true;
}

void AsmTyper::SetTypeOf(AstNode* node, AsmType* type) {
  DCHECK_NE(type, AsmType::None());
  if (in_function_) {
    DCHECK(function_node_types_.find(node) == function_node_types_.end());
    function_node_types_.insert(std::make_pair(node, type));
  } else {
    DCHECK(module_node_types_.find(node) == module_node_types_.end());
    module_node_types_.insert(std::make_pair(node, type));
  }
}

AsmType* AsmTyper::TypeOf(AstNode* node) const {
  auto node_type_iter = function_node_types_.find(node);
  if (node_type_iter != function_node_types_.end()) {
    return node_type_iter->second;
  }
  node_type_iter = module_node_types_.find(node);
  if (node_type_iter != module_node_types_.end()) {
    return node_type_iter->second;
  }

  // Sometimes literal nodes are not added to the node_type_ map simply because
  // their are not visited with ValidateExpression().
  if (auto* literal = node->AsLiteral()) {
    if (literal->raw_value()->ContainsDot()) {
      return AsmType::Double();
    }
    uint32_t u;
    if (literal->value()->ToUint32(&u)) {
      if (u > LargestFixNum) {
        return AsmType::Unsigned();
      }
      return AsmType::FixNum();
    }
    int32_t i;
    if (literal->value()->ToInt32(&i)) {
      return AsmType::Signed();
    }
  }

  return AsmType::None();
}

AsmType* AsmTyper::TypeOf(Variable* v) const { return Lookup(v)->type(); }

AsmTyper::StandardMember AsmTyper::VariableAsStandardMember(Variable* var) {
  auto* var_info = Lookup(var);
  if (var_info == nullptr) {
    return kNone;
  }
  StandardMember member = var_info->standard_member();
  return member;
}

bool AsmTyper::Validate() {
  return ValidateBeforeFunctionsPhase() &&
         !AsmType::None()->IsExactly(ValidateModuleFunctions(root_)) &&
         ValidateAfterFunctionsPhase();
}

bool AsmTyper::ValidateBeforeFunctionsPhase() {
  if (!AsmType::None()->IsExactly(ValidateModuleBeforeFunctionsPhase(root_))) {
    return true;
  }
  return false;
}

bool AsmTyper::ValidateInnerFunction(FunctionDeclaration* fun_decl) {
  if (!AsmType::None()->IsExactly(ValidateModuleFunction(fun_decl))) {
    return true;
  }
  return false;
}

bool AsmTyper::ValidateAfterFunctionsPhase() {
  if (!AsmType::None()->IsExactly(ValidateModuleAfterFunctionsPhase(root_))) {
    return true;
  }
  return false;
}

void AsmTyper::ClearFunctionNodeTypes() { function_node_types_.clear(); }

namespace {
bool IsUseAsmDirective(Statement* first_statement) {
  ExpressionStatement* use_asm = first_statement->AsExpressionStatement();
  if (use_asm == nullptr) {
    return false;
  }

  Literal* use_asm_literal = use_asm->expression()->AsLiteral();

  if (use_asm_literal == nullptr) {
    return false;
  }

  return use_asm_literal->raw_value()->AsString()->IsOneByteEqualTo("use asm");
}

Assignment* ExtractInitializerExpression(Statement* statement) {
  auto* expr_stmt = statement->AsExpressionStatement();
  if (expr_stmt == nullptr) {
    // Done with initializers.
    return nullptr;
  }
  auto* assign = expr_stmt->expression()->AsAssignment();
  if (assign == nullptr) {
    // Done with initializers.
    return nullptr;
  }
  if (assign->op() != Token::INIT) {
    // Done with initializers.
    return nullptr;
  }
  return assign;
}

}  // namespace

// 6.1 ValidateModule
AsmType* AsmTyper::ValidateModuleBeforeFunctionsPhase(FunctionLiteral* fun) {
  DeclarationScope* scope = fun->scope();
  if (!scope->is_function_scope()) FAIL(fun, "Not at function scope.");
  if (!ValidAsmIdentifier(fun->name()))
    FAIL(fun, "Invalid asm.js identifier in module name.");
  module_name_ = fun->name();

  // Allowed parameters: Stdlib, FFI, Mem
  static const int MaxModuleParameters = 3;
  if (scope->num_parameters() > MaxModuleParameters) {
    FAIL(fun, "asm.js modules may not have more than three parameters.");
  }

  struct {
    StandardMember standard_member;
  } kModuleParamInfo[3] = {
      {kStdlib}, {kFFI}, {kHeap},
  };

  for (int ii = 0; ii < scope->num_parameters(); ++ii) {
    Variable* param = scope->parameter(ii);
    DCHECK(param);

    if (!ValidAsmIdentifier(param->name())) {
      FAIL(fun, "Invalid asm.js identifier in module parameter.");
    }

    auto* param_info = VariableInfo::ForSpecialSymbol(
        zone_, kModuleParamInfo[ii].standard_member);

    if (!AddGlobal(param, param_info)) {
      FAIL(fun, "Redeclared identifier in module parameter.");
    }
  }

  FlattenedStatements iter(zone_, fun->body());
  auto* use_asm_directive = iter.Next();
  if (use_asm_directive == nullptr) {
    FAIL(fun, "Missing \"use asm\".");
  }
  // Check for extra assignment inserted by the parser when in this form:
  // (function Module(a, b, c) {... })
  ExpressionStatement* estatement = use_asm_directive->AsExpressionStatement();
  if (estatement != nullptr) {
    Assignment* assignment = estatement->expression()->AsAssignment();
    if (assignment != nullptr && assignment->target()->IsVariableProxy() &&
        assignment->target()
            ->AsVariableProxy()
            ->var()
            ->is_sloppy_function_name()) {
      use_asm_directive = iter.Next();
    }
  }
  if (!IsUseAsmDirective(use_asm_directive)) {
    FAIL(fun, "Missing \"use asm\".");
  }
  source_layout_.AddUseAsm(*use_asm_directive);
  module_return_ = nullptr;

  // *VIOLATION* The spec states that globals should be followed by function
  // declarations, which should be followed by function pointer tables, followed
  // by the module export (return) statement. Our AST might be rearraged by the
  // parser, so we can't rely on it being in source code order.
  while (Statement* current = iter.Next()) {
    if (auto* assign = ExtractInitializerExpression(current)) {
      if (assign->value()->IsArrayLiteral()) {
        // Save function tables for later validation.
        function_pointer_tables_.push_back(assign);
      } else {
        RECURSE(ValidateGlobalDeclaration(assign));
        source_layout_.AddGlobal(*assign);
      }
      continue;
    }

    if (auto* current_as_return = current->AsReturnStatement()) {
      if (module_return_ != nullptr) {
        FAIL(fun, "Multiple export statements.");
      }
      module_return_ = current_as_return;
      source_layout_.AddExport(*module_return_);
      continue;
    }

    FAIL(current, "Invalid top-level statement in asm.js module.");
  }

  return AsmType::Int();  // Any type that is not AsmType::None();
}

AsmType* AsmTyper::ValidateModuleFunction(FunctionDeclaration* fun_decl) {
  RECURSE(ValidateFunction(fun_decl));
  source_layout_.AddFunction(*fun_decl);

  return AsmType::Int();  // Any type that is not AsmType::None();
}

AsmType* AsmTyper::ValidateModuleFunctions(FunctionLiteral* fun) {
  DeclarationScope* scope = fun->scope();
  Declaration::List* decls = scope->declarations();
  for (Declaration* decl : *decls) {
    if (FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration()) {
      RECURSE(ValidateModuleFunction(fun_decl));
      continue;
    }
  }

  return AsmType::Int();  // Any type that is not AsmType::None();
}

AsmType* AsmTyper::ValidateModuleAfterFunctionsPhase(FunctionLiteral* fun) {
  for (auto* function_table : function_pointer_tables_) {
    RECURSE(ValidateFunctionTable(function_table));
    source_layout_.AddTable(*function_table);
  }

  DeclarationScope* scope = fun->scope();
  Declaration::List* decls = scope->declarations();
  for (Declaration* decl : *decls) {
    if (decl->IsFunctionDeclaration()) {
      continue;
    }

    VariableDeclaration* var_decl = decl->AsVariableDeclaration();
    if (var_decl == nullptr) {
      FAIL(decl, "Invalid asm.js declaration.");
    }

    auto* var_proxy = var_decl->proxy();
    if (var_proxy == nullptr) {
      FAIL(decl, "Invalid asm.js declaration.");
    }

    if (Lookup(var_proxy->var()) == nullptr) {
      FAIL(decl, "Global variable missing initializer in asm.js module.");
    }
  }

  // 6.2 ValidateExport
  if (module_return_ == nullptr) {
    FAIL(fun, "Missing asm.js module export.");
  }

  for (auto* forward_def : forward_definitions_) {
    if (forward_def->missing_definition()) {
      FAIL_LINE(forward_def->source_location(),
                "Missing definition for forward declared identifier.");
    }
  }

  RECURSE(ValidateExport(module_return_));

  if (!source_layout_.IsValid()) {
    FAIL(fun, "Invalid asm.js source code layout.");
  }

  return AsmType::Int();  // Any type that is not AsmType::None();
}

namespace {
bool IsDoubleAnnotation(BinaryOperation* binop) {
  // *VIOLATION* The parser replaces uses of +x with x*1.0.
  if (binop->op() != Token::MUL) {
    return false;
  }

  auto* right_as_literal = binop->right()->AsLiteral();
  if (right_as_literal == nullptr) {
    return false;
  }

  return right_as_literal->raw_value()->ContainsDot() &&
         right_as_literal->raw_value()->AsNumber() == 1.0;
}

bool IsIntAnnotation(BinaryOperation* binop) {
  if (binop->op() != Token::BIT_OR) {
    return false;
  }

  auto* right_as_literal = binop->right()->AsLiteral();
  if (right_as_literal == nullptr) {
    return false;
  }

  return !right_as_literal->raw_value()->ContainsDot() &&
         right_as_literal->raw_value()->AsNumber() == 0.0;
}
}  // namespace

AsmType* AsmTyper::ValidateGlobalDeclaration(Assignment* assign) {
  DCHECK(!assign->is_compound());
  if (assign->is_compound()) {
    FAIL(assign,
         "Compound assignment not supported when declaring global variables.");
  }

  auto* target = assign->target();
  if (!target->IsVariableProxy()) {
    FAIL(target, "Module assignments may only assign to globals.");
  }
  auto* target_variable = target->AsVariableProxy()->var();
  auto* target_info = Lookup(target_variable);

  if (target_info != nullptr) {
    FAIL(target, "Redefined global variable.");
  }

  auto* value = assign->value();
  // Not all types of assignment are allowed by asm.js. See
  // 5.5 Global Variable Type Annotations.
  bool global_variable = false;
  if (value->IsLiteral() || value->IsCall()) {
    AsmType* type = nullptr;
    VariableInfo::Mutability mutability;
    if (target_variable->mode() == CONST) {
      mutability = VariableInfo::kConstGlobal;
    } else {
      mutability = VariableInfo::kMutableGlobal;
    }
    RECURSE(type = VariableTypeAnnotations(value, mutability));
    target_info = new (zone_) VariableInfo(type);
    target_info->set_mutability(mutability);
    global_variable = true;
  } else if (value->IsProperty()) {
    target_info = ImportLookup(value->AsProperty());
    if (target_info == nullptr) {
      FAIL(assign, "Invalid import.");
    }
    CHECK(target_info->mutability() == VariableInfo::kImmutableGlobal);
    if (target_info->IsFFI()) {
      // create a new target info that represents a foreign variable.
      target_info = new (zone_) VariableInfo(ffi_type_);
      target_info->set_mutability(VariableInfo::kImmutableGlobal);
    } else if (target_info->type()->IsA(AsmType::Heap())) {
      FAIL(assign, "Heap view types can not be aliased.");
    } else {
      target_info = target_info->Clone(zone_);
    }
  } else if (value->IsBinaryOperation()) {
    // This should either be:
    //
    // var <> = ffi.<>|0
    //
    // or
    //
    // var <> = +ffi.<>
    auto* value_binop = value->AsBinaryOperation();
    auto* left = value_binop->left();
    AsmType* import_type = nullptr;

    if (IsDoubleAnnotation(value_binop)) {
      import_type = AsmType::Double();
    } else if (IsIntAnnotation(value_binop)) {
      import_type = AsmType::Int();
    } else {
      FAIL(value,
           "Invalid initializer for foreign import - unrecognized annotation.");
    }

    if (!left->IsProperty()) {
      FAIL(value,
           "Invalid initializer for foreign import - must import member.");
    }
    target_info = ImportLookup(left->AsProperty());
    if (target_info == nullptr) {
      // TODO(jpp): this error message is innacurate: this may fail if the
      // object lookup fails, or if the property lookup fails, or even if the
      // import is bogus like a().c.
      FAIL(value,
           "Invalid initializer for foreign import - object lookup failed.");
    }
    CHECK(target_info->mutability() == VariableInfo::kImmutableGlobal);
    if (!target_info->IsFFI()) {
      FAIL(value,
           "Invalid initializer for foreign import - object is not the ffi.");
    }

    // Create a new target info that represents the foreign import.
    target_info = new (zone_) VariableInfo(import_type);
    target_info->set_mutability(VariableInfo::kMutableGlobal);
  } else if (value->IsCallNew()) {
    AsmType* type = nullptr;
    RECURSE(type = NewHeapView(value->AsCallNew()));
    target_info = new (zone_) VariableInfo(type);
    target_info->set_mutability(VariableInfo::kImmutableGlobal);
  } else if (auto* proxy = value->AsVariableProxy()) {
    auto* var_info = Lookup(proxy->var());

    if (var_info == nullptr) {
      FAIL(value, "Undeclared identifier in global initializer");
    }

    if (var_info->mutability() != VariableInfo::kConstGlobal) {
      FAIL(value, "Identifier used to initialize a global must be a const");
    }

    target_info = new (zone_) VariableInfo(var_info->type());
    if (target_variable->mode() == CONST) {
      target_info->set_mutability(VariableInfo::kConstGlobal);
    } else {
      target_info->set_mutability(VariableInfo::kMutableGlobal);
    }
  }

  if (target_info == nullptr) {
    FAIL(assign, "Invalid global variable initializer.");
  }

  if (!ValidAsmIdentifier(target_variable->name())) {
    FAIL(target, "Invalid asm.js identifier in global variable.");
  }

  if (!AddGlobal(target_variable, target_info)) {
    FAIL(assign, "Redeclared global identifier.");
  }

  DCHECK(target_info->type() != AsmType::None());
  if (!global_variable) {
    // Global variables have their types set in VariableTypeAnnotations.
    SetTypeOf(value, target_info->type());
  }
  SetTypeOf(assign, target_info->type());
  SetTypeOf(target, target_info->type());
  return target_info->type();
}

// 6.2 ValidateExport
AsmType* AsmTyper::ExportType(VariableProxy* fun_export) {
  auto* fun_info = Lookup(fun_export->var());
  if (fun_info == nullptr) {
    FAIL(fun_export, "Undefined identifier in asm.js module export.");
  }

  if (fun_info->standard_member() != kNone) {
    FAIL(fun_export, "Module cannot export standard library functions.");
  }

  auto* type = fun_info->type();
  if (type->AsFFIType() != nullptr) {
    FAIL(fun_export, "Module cannot export foreign functions.");
  }

  if (type->AsFunctionTableType() != nullptr) {
    FAIL(fun_export, "Module cannot export function tables.");
  }

  if (fun_info->type()->AsFunctionType() == nullptr) {
    FAIL(fun_export, "Module export is not an asm.js function.");
  }

  return type;
}

AsmType* AsmTyper::ValidateExport(ReturnStatement* exports) {
  // asm.js modules can export single functions, or multiple functions in an
  // object literal.
  if (auto* fun_export = exports->expression()->AsVariableProxy()) {
    // Exporting single function.
    AsmType* export_type;
    RECURSE(export_type = ExportType(fun_export));
    return export_type;
  }

  if (auto* obj_export = exports->expression()->AsObjectLiteral()) {
    // Exporting object literal.
    for (auto* prop : *obj_export->properties()) {
      if (!prop->key()->IsLiteral()) {
        FAIL(prop->key(),
             "Only normal object properties may be used in the export object "
             "literal.");
      }

      auto* export_obj = prop->value()->AsVariableProxy();
      if (export_obj == nullptr) {
        FAIL(prop->value(), "Exported value must be an asm.js function name.");
      }

      RECURSE(ExportType(export_obj));
    }

    return AsmType::Int();
  }

  FAIL(exports, "Unrecognized expression in asm.js module export expression.");
}

// 6.3 ValidateFunctionTable
AsmType* AsmTyper::ValidateFunctionTable(Assignment* assign) {
  if (assign->is_compound()) {
    FAIL(assign,
         "Compound assignment not supported when declaring global variables.");
  }

  auto* target = assign->target();
  if (!target->IsVariableProxy()) {
    FAIL(target, "Module assignments may only assign to globals.");
  }
  auto* target_variable = target->AsVariableProxy()->var();

  auto* value = assign->value()->AsArrayLiteral();
  CHECK(value != nullptr);
  ZoneList<Expression*>* pointers = value->values();

  // The function table size must be n = 2 ** m, for m >= 0;
  // TODO(jpp): should this be capped?
  if (!base::bits::IsPowerOfTwo32(pointers->length())) {
    FAIL(assign, "Invalid length for function pointer table.");
  }

  AsmType* table_element_type = nullptr;
  for (auto* initializer : *pointers) {
    auto* var_proxy = initializer->AsVariableProxy();
    if (var_proxy == nullptr) {
      FAIL(initializer,
           "Function pointer table initializer must be a function name.");
    }

    auto* var_info = Lookup(var_proxy->var());
    if (var_info == nullptr) {
      FAIL(var_proxy,
           "Undefined identifier in function pointer table initializer.");
    }

    if (var_info->standard_member() != kNone) {
      FAIL(initializer,
           "Function pointer table must not be a member of the standard "
           "library.");
    }

    auto* initializer_type = var_info->type();
    if (initializer_type->AsFunctionType() == nullptr) {
      FAIL(initializer,
           "Function pointer table initializer must be an asm.js function.");
    }

    DCHECK(var_info->type()->AsFFIType() == nullptr);
    DCHECK(var_info->type()->AsFunctionTableType() == nullptr);

    if (table_element_type == nullptr) {
      table_element_type = initializer_type;
    } else if (!initializer_type->IsA(table_element_type)) {
      FAIL(initializer, "Type mismatch in function pointer table initializer.");
    }
  }

  auto* target_info = Lookup(target_variable);
  if (target_info == nullptr) {
    // Function pointer tables are the last entities to be validates, so this is
    // unlikely to happen: only unreferenced function tables will not already
    // have an entry in the global scope.
    target_info = new (zone_) VariableInfo(AsmType::FunctionTableType(
        zone_, pointers->length(), table_element_type));
    target_info->set_mutability(VariableInfo::kImmutableGlobal);
    if (!ValidAsmIdentifier(target_variable->name())) {
      FAIL(target, "Invalid asm.js identifier in function table name.");
    }
    if (!AddGlobal(target_variable, target_info)) {
      DCHECK(false);
      FAIL(assign, "Redeclared global identifier in function table name.");
    }
    SetTypeOf(value, target_info->type());
    return target_info->type();
  }

  auto* target_info_table = target_info->type()->AsFunctionTableType();
  if (target_info_table == nullptr) {
    FAIL(assign, "Identifier redefined as function pointer table.");
  }

  if (!target_info->missing_definition()) {
    FAIL(assign, "Identifier redefined (function table name).");
  }

  if (static_cast<int>(target_info_table->length()) != pointers->length()) {
    FAIL(assign, "Function table size mismatch.");
  }

  DCHECK(target_info_table->signature()->AsFunctionType());
  if (!table_element_type->IsA(target_info_table->signature())) {
    FAIL(assign, "Function table initializer does not match previous type.");
  }

  target_info->MarkDefined();
  DCHECK(target_info->type() != AsmType::None());
  SetTypeOf(value, target_info->type());

  return target_info->type();
}

// 6.4 ValidateFunction
AsmType* AsmTyper::ValidateFunction(FunctionDeclaration* fun_decl) {
  FunctionScope _(this);

  // Extract parameter types.
  auto* fun = fun_decl->fun();

  auto* fun_decl_proxy = fun_decl->proxy();
  if (fun_decl_proxy == nullptr) {
    FAIL(fun_decl, "Anonymous functions are not support in asm.js.");
  }

  Statement* current;
  FlattenedStatements iter(zone_, fun->body());

  size_t annotated_parameters = 0;

  // 5.3 Function type annotations
  //     * parameters
  ZoneVector<AsmType*> parameter_types(zone_);
  for (; (current = iter.Next()) != nullptr; ++annotated_parameters) {
    auto* stmt = current->AsExpressionStatement();
    if (stmt == nullptr) {
      // Done with parameters.
      break;
    }
    auto* expr = stmt->expression()->AsAssignment();
    if (expr == nullptr || expr->is_compound()) {
      // Done with parameters.
      break;
    }
    auto* proxy = expr->target()->AsVariableProxy();
    if (proxy == nullptr) {
      // Done with parameters.
      break;
    }
    auto* param = proxy->var();
    if (param->location() != VariableLocation::PARAMETER ||
        param->index() != static_cast<int>(annotated_parameters)) {
      // Done with parameters.
      break;
    }

    AsmType* type;
    RECURSE(type = ParameterTypeAnnotations(param, expr->value()));
    DCHECK(type->IsParameterType());
    auto* param_info = new (zone_) VariableInfo(type);
    param_info->set_mutability(VariableInfo::kLocal);
    if (!ValidAsmIdentifier(proxy->name())) {
      FAIL(proxy, "Invalid asm.js identifier in parameter name.");
    }

    if (!AddLocal(param, param_info)) {
      FAIL(proxy, "Redeclared parameter.");
    }
    parameter_types.push_back(type);
    SetTypeOf(proxy, type);
    SetTypeOf(expr, type);
  }

  if (static_cast<int>(annotated_parameters) != fun->parameter_count()) {
    FAIL(fun_decl, "Incorrect parameter type annotations.");
  }

  // 5.3 Function type annotations
  //     * locals
  for (; current; current = iter.Next()) {
    auto* initializer = ExtractInitializerExpression(current);
    if (initializer == nullptr) {
      // Done with locals.
      break;
    }

    auto* local = initializer->target()->AsVariableProxy();
    if (local == nullptr) {
      // Done with locals. It should never happen. Even if it does, the asm.js
      // code should not declare any other locals after this point, so we assume
      // this is OK. If any other variable declaration is found we report a
      // validation error.
      DCHECK(false);
      break;
    }

    AsmType* type;
    RECURSE(type = VariableTypeAnnotations(initializer->value()));
    auto* local_info = new (zone_) VariableInfo(type);
    local_info->set_mutability(VariableInfo::kLocal);
    if (!ValidAsmIdentifier(local->name())) {
      FAIL(local, "Invalid asm.js identifier in local variable.");
    }

    if (!AddLocal(local->var(), local_info)) {
      FAIL(initializer, "Redeclared local.");
    }

    SetTypeOf(local, type);
    SetTypeOf(initializer, type);
  }

  // 5.2 Return Type Annotations
  // *VIOLATION* we peel blocks to find the last statement in the asm module
  // because the parser may introduce synthetic blocks.
  ZoneList<Statement*>* statements = fun->body();

  do {
    if (statements->length() == 0) {
      return_type_ = AsmType::Void();
    } else {
      auto* last_statement = statements->last();
      auto* as_block = last_statement->AsBlock();
      if (as_block != nullptr) {
        statements = as_block->statements();
      } else {
        // We don't check whether AsReturnStatement() below returns non-null --
        // we leave that to the ReturnTypeAnnotations method.
        RECURSE(return_type_ =
                    ReturnTypeAnnotations(last_statement->AsReturnStatement()));
      }
    }
  } while (return_type_ == AsmType::None());

  DCHECK(return_type_->IsReturnType());

  for (Declaration* decl : *fun->scope()->declarations()) {
    auto* var_decl = decl->AsVariableDeclaration();
    if (var_decl == nullptr) {
      FAIL(decl, "Functions may only define inner variables.");
    }

    auto* var_proxy = var_decl->proxy();
    if (var_proxy == nullptr) {
      FAIL(decl, "Invalid local declaration declaration.");
    }

    auto* var_info = Lookup(var_proxy->var());
    if (var_info == nullptr || var_info->IsGlobal()) {
      FAIL(decl, "Local variable missing initializer in asm.js module.");
    }
  }

  for (; current; current = iter.Next()) {
    AsmType* current_type;
    RECURSE(current_type = ValidateStatement(current));
  }

  auto* fun_type = AsmType::Function(zone_, return_type_);
  auto* fun_type_as_function = fun_type->AsFunctionType();
  for (auto* param_type : parameter_types) {
    fun_type_as_function->AddArgument(param_type);
  }

  auto* fun_var = fun_decl_proxy->var();
  auto* fun_info = new (zone_) VariableInfo(fun_type);
  fun_info->set_mutability(VariableInfo::kImmutableGlobal);
  auto* old_fun_info = Lookup(fun_var);
  if (old_fun_info == nullptr) {
    if (!ValidAsmIdentifier(fun_var->name())) {
      FAIL(fun_decl_proxy, "Invalid asm.js identifier in function name.");
    }
    if (!AddGlobal(fun_var, fun_info)) {
      DCHECK(false);
      FAIL(fun_decl, "Redeclared global identifier.");
    }

    SetTypeOf(fun, fun_type);
    return fun_type;
  }

  // Not necessarily an error -- fun_decl might have been used before being
  // defined. If that's the case, then the type in the global environment must
  // be the same as the type inferred by the parameter/return type annotations.
  auto* old_fun_type = old_fun_info->type();
  if (old_fun_type->AsFunctionType() == nullptr) {
    FAIL(fun_decl, "Identifier redefined as function.");
  }

  if (!old_fun_info->missing_definition()) {
    FAIL(fun_decl, "Identifier redefined (function name).");
  }

  if (!fun_type->IsA(old_fun_type)) {
    FAIL(fun_decl, "Signature mismatch when defining function.");
  }

  old_fun_info->MarkDefined();
  SetTypeOf(fun, fun_type);

  return fun_type;
}

// 6.5 ValidateStatement
AsmType* AsmTyper::ValidateStatement(Statement* statement) {
  switch (statement->node_type()) {
    default:
      FAIL(statement, "Statement type invalid for asm.js.");
    case AstNode::kBlock:
      return ValidateBlockStatement(statement->AsBlock());
    case AstNode::kExpressionStatement:
      return ValidateExpressionStatement(statement->AsExpressionStatement());
    case AstNode::kEmptyStatement:
      return ValidateEmptyStatement(statement->AsEmptyStatement());
    case AstNode::kIfStatement:
      return ValidateIfStatement(statement->AsIfStatement());
    case AstNode::kReturnStatement:
      return ValidateReturnStatement(statement->AsReturnStatement());
    case AstNode::kWhileStatement:
      return ValidateWhileStatement(statement->AsWhileStatement());
    case AstNode::kDoWhileStatement:
      return ValidateDoWhileStatement(statement->AsDoWhileStatement());
    case AstNode::kForStatement:
      return ValidateForStatement(statement->AsForStatement());
    case AstNode::kBreakStatement:
      return ValidateBreakStatement(statement->AsBreakStatement());
    case AstNode::kContinueStatement:
      return ValidateContinueStatement(statement->AsContinueStatement());
    case AstNode::kSwitchStatement:
      return ValidateSwitchStatement(statement->AsSwitchStatement());
  }

  return AsmType::Void();
}

// 6.5.1 BlockStatement
AsmType* AsmTyper::ValidateBlockStatement(Block* block) {
  FlattenedStatements iter(zone_, block->statements());

  while (auto* current = iter.Next()) {
    RECURSE(ValidateStatement(current));
  }

  return AsmType::Void();
}

// 6.5.2 ExpressionStatement
AsmType* AsmTyper::ValidateExpressionStatement(ExpressionStatement* expr) {
  auto* expression = expr->expression();
  if (auto* call = expression->AsCall()) {
    RECURSE(ValidateCall(AsmType::Void(), call));
  } else {
    RECURSE(ValidateExpression(expression));
  }

  return AsmType::Void();
}

// 6.5.3 EmptyStatement
AsmType* AsmTyper::ValidateEmptyStatement(EmptyStatement* empty) {
  return AsmType::Void();
}

// 6.5.4 IfStatement
AsmType* AsmTyper::ValidateIfStatement(IfStatement* if_stmt) {
  AsmType* cond_type;
  RECURSE(cond_type = ValidateExpression(if_stmt->condition()));
  if (!cond_type->IsA(AsmType::Int())) {
    FAIL(if_stmt->condition(), "If condition must be type int.");
  }
  RECURSE(ValidateStatement(if_stmt->then_statement()));
  RECURSE(ValidateStatement(if_stmt->else_statement()));
  return AsmType::Void();
}

// 6.5.5 ReturnStatement
AsmType* AsmTyper::ValidateReturnStatement(ReturnStatement* ret_stmt) {
  AsmType* ret_expr_type = AsmType::Void();
  if (auto* ret_expr = ret_stmt->expression()) {
    RECURSE(ret_expr_type = ValidateExpression(ret_expr));
    if (ret_expr_type == AsmType::Void()) {
      // *VIOLATION* The parser modifies the source code so that expressionless
      // returns will return undefined, so we need to allow that.
      if (!ret_expr->IsUndefinedLiteral()) {
        FAIL(ret_stmt, "Return statement expression can't be void.");
      }
    }
  }

  if (!ret_expr_type->IsA(return_type_)) {
    FAIL(ret_stmt, "Type mismatch in return statement.");
  }

  return ret_expr_type;
}

// 6.5.6 IterationStatement
// 6.5.6.a WhileStatement
AsmType* AsmTyper::ValidateWhileStatement(WhileStatement* while_stmt) {
  AsmType* cond_type;
  RECURSE(cond_type = ValidateExpression(while_stmt->cond()));
  if (!cond_type->IsA(AsmType::Int())) {
    FAIL(while_stmt->cond(), "While condition must be type int.");
  }

  if (auto* body = while_stmt->body()) {
    RECURSE(ValidateStatement(body));
  }
  return AsmType::Void();
}

// 6.5.6.b DoWhileStatement
AsmType* AsmTyper::ValidateDoWhileStatement(DoWhileStatement* do_while) {
  AsmType* cond_type;
  RECURSE(cond_type = ValidateExpression(do_while->cond()));
  if (!cond_type->IsA(AsmType::Int())) {
    FAIL(do_while->cond(), "Do {} While condition must be type int.");
  }

  if (auto* body = do_while->body()) {
    RECURSE(ValidateStatement(body));
  }
  return AsmType::Void();
}

// 6.5.6.c ForStatement
AsmType* AsmTyper::ValidateForStatement(ForStatement* for_stmt) {
  if (auto* init = for_stmt->init()) {
    RECURSE(ValidateStatement(init));
  }

  if (auto* cond = for_stmt->cond()) {
    AsmType* cond_type;
    RECURSE(cond_type = ValidateExpression(cond));
    if (!cond_type->IsA(AsmType::Int())) {
      FAIL(cond, "For condition must be type int.");
    }
  }

  if (auto* next = for_stmt->next()) {
    RECURSE(ValidateStatement(next));
  }

  if (auto* body = for_stmt->body()) {
    RECURSE(ValidateStatement(body));
  }

  return AsmType::Void();
}

// 6.5.7 BreakStatement
AsmType* AsmTyper::ValidateBreakStatement(BreakStatement* brk_stmt) {
  return AsmType::Void();
}

// 6.5.8 ContinueStatement
AsmType* AsmTyper::ValidateContinueStatement(ContinueStatement* cont_stmt) {
  return AsmType::Void();
}

// 6.5.9 LabelledStatement
// No need to handle these here -- see the AsmTyper's definition.

// 6.5.10 SwitchStatement
AsmType* AsmTyper::ValidateSwitchStatement(SwitchStatement* stmt) {
  AsmType* cond_type;
  RECURSE(cond_type = ValidateExpression(stmt->tag()));
  if (!cond_type->IsA(AsmType::Signed())) {
    FAIL(stmt, "Switch tag must be signed.");
  }

  int default_pos = kNoSourcePosition;
  int last_case_pos = kNoSourcePosition;
  ZoneSet<int32_t> cases_seen(zone_);
  for (auto* a_case : *stmt->cases()) {
    if (a_case->is_default()) {
      CHECK(default_pos == kNoSourcePosition);
      RECURSE(ValidateDefault(a_case));
      default_pos = a_case->position();
      continue;
    }

    if (last_case_pos == kNoSourcePosition) {
      last_case_pos = a_case->position();
    } else {
      last_case_pos = std::max(last_case_pos, a_case->position());
    }

    int32_t case_lbl;
    RECURSE(ValidateCase(a_case, &case_lbl));
    auto case_lbl_pos = cases_seen.find(case_lbl);
    if (case_lbl_pos != cases_seen.end() && *case_lbl_pos == case_lbl) {
      FAIL(a_case, "Duplicated case label.");
    }
    cases_seen.insert(case_lbl);
  }

  if (!cases_seen.empty()) {
    const int64_t max_lbl = *cases_seen.rbegin();
    const int64_t min_lbl = *cases_seen.begin();
    if (max_lbl - min_lbl > std::numeric_limits<int32_t>::max()) {
      FAIL(stmt, "Out-of-bounds case label range.");
    }
  }

  if (last_case_pos != kNoSourcePosition && default_pos != kNoSourcePosition &&
      default_pos < last_case_pos) {
    FAIL(stmt, "Switch default must appear last.");
  }

  return AsmType::Void();
}

// 6.6 ValidateCase
namespace {
bool ExtractInt32CaseLabel(CaseClause* clause, int32_t* lbl) {
  auto* lbl_expr = clause->label()->AsLiteral();

  if (lbl_expr == nullptr) {
    return false;
  }

  if (lbl_expr->raw_value()->ContainsDot()) {
    return false;
  }

  return lbl_expr->value()->ToInt32(lbl);
}
}  // namespace

AsmType* AsmTyper::ValidateCase(CaseClause* label, int32_t* case_lbl) {
  if (!ExtractInt32CaseLabel(label, case_lbl)) {
    FAIL(label, "Case label must be a 32-bit signed integer.");
  }

  FlattenedStatements iter(zone_, label->statements());
  while (auto* current = iter.Next()) {
    RECURSE(ValidateStatement(current));
  }
  return AsmType::Void();
}

// 6.7 ValidateDefault
AsmType* AsmTyper::ValidateDefault(CaseClause* label) {
  FlattenedStatements iter(zone_, label->statements());
  while (auto* current = iter.Next()) {
    RECURSE(ValidateStatement(current));
  }
  return AsmType::Void();
}

// 6.8 ValidateExpression
AsmType* AsmTyper::ValidateExpression(Expression* expr) {
  AsmType* expr_ty = AsmType::None();

  switch (expr->node_type()) {
    default:
      FAIL(expr, "Invalid asm.js expression.");
    case AstNode::kLiteral:
      RECURSE(expr_ty = ValidateNumericLiteral(expr->AsLiteral()));
      break;
    case AstNode::kVariableProxy:
      RECURSE(expr_ty = ValidateIdentifier(expr->AsVariableProxy()));
      break;
    case AstNode::kCall:
      RECURSE(expr_ty = ValidateCallExpression(expr->AsCall()));
      break;
    case AstNode::kProperty:
      RECURSE(expr_ty = ValidateMemberExpression(expr->AsProperty()));
      break;
    case AstNode::kAssignment:
      RECURSE(expr_ty = ValidateAssignmentExpression(expr->AsAssignment()));
      break;
    case AstNode::kUnaryOperation:
      RECURSE(expr_ty = ValidateUnaryExpression(expr->AsUnaryOperation()));
      break;
    case AstNode::kConditional:
      RECURSE(expr_ty = ValidateConditionalExpression(expr->AsConditional()));
      break;
    case AstNode::kCompareOperation:
      RECURSE(expr_ty = ValidateCompareOperation(expr->AsCompareOperation()));
      break;
    case AstNode::kBinaryOperation:
      RECURSE(expr_ty = ValidateBinaryOperation(expr->AsBinaryOperation()));
      break;
  }

  SetTypeOf(expr, expr_ty);
  return expr_ty;
}

AsmType* AsmTyper::ValidateCompareOperation(CompareOperation* cmp) {
  switch (cmp->op()) {
    default:
      FAIL(cmp, "Invalid asm.js comparison operator.");
    case Token::LT:
    case Token::LTE:
    case Token::GT:
    case Token::GTE:
      return ValidateRelationalExpression(cmp);
    case Token::EQ:
    case Token::NE:
      return ValidateEqualityExpression(cmp);
  }

  UNREACHABLE();
}

namespace {
bool IsInvert(BinaryOperation* binop) {
  if (binop->op() != Token::BIT_XOR) {
    return false;
  }

  auto* right_as_literal = binop->right()->AsLiteral();
  if (right_as_literal == nullptr) {
    return false;
  }

  return !right_as_literal->raw_value()->ContainsDot() &&
         right_as_literal->raw_value()->AsNumber() == -1.0;
}

bool IsUnaryMinus(BinaryOperation* binop) {
  // *VIOLATION* The parser replaces uses of -x with x*-1.
  if (binop->op() != Token::MUL) {
    return false;
  }

  auto* right_as_literal = binop->right()->AsLiteral();
  if (right_as_literal == nullptr) {
    return false;
  }

  return !right_as_literal->raw_value()->ContainsDot() &&
         right_as_literal->raw_value()->AsNumber() == -1.0;
}
}  // namespace

AsmType* AsmTyper::ValidateBinaryOperation(BinaryOperation* expr) {
#define UNOP_OVERLOAD(Src, Dest)          \
  do {                                    \
    if (left_type->IsA(AsmType::Src())) { \
      return AsmType::Dest();             \
    }                                     \
  } while (0)

  switch (expr->op()) {
    default:
      FAIL(expr, "Invalid asm.js binary expression.");
    case Token::COMMA:
      return ValidateCommaExpression(expr);
    case Token::MUL:
      if (IsDoubleAnnotation(expr)) {
        // *VIOLATION* We can't be 100% sure this really IS a unary + in the asm
        // source so we have to be lenient, and treat this as a unary +.
        if (auto* Call = expr->left()->AsCall()) {
          return ValidateCall(AsmType::Double(), Call);
        }
        AsmType* left_type;
        RECURSE(left_type = ValidateExpression(expr->left()));
        SetTypeOf(expr->right(), AsmType::Double());
        UNOP_OVERLOAD(Signed, Double);
        UNOP_OVERLOAD(Unsigned, Double);
        UNOP_OVERLOAD(DoubleQ, Double);
        UNOP_OVERLOAD(FloatQ, Double);
        FAIL(expr, "Invalid type for conversion to double.");
      }

      if (IsUnaryMinus(expr)) {
        // *VIOLATION* the parser converts -x to x * -1.
        AsmType* left_type;
        RECURSE(left_type = ValidateExpression(expr->left()));
        SetTypeOf(expr->right(), left_type);
        UNOP_OVERLOAD(Int, Intish);
        UNOP_OVERLOAD(DoubleQ, Double);
        UNOP_OVERLOAD(FloatQ, Floatish);
        FAIL(expr, "Invalid type for unary -.");
      }
    // FALTHROUGH
    case Token::DIV:
    case Token::MOD:
      return ValidateMultiplicativeExpression(expr);
    case Token::ADD:
    case Token::SUB: {
      static const uint32_t kInitialIntishCount = 0;
      return ValidateAdditiveExpression(expr, kInitialIntishCount);
    }
    case Token::SAR:
    case Token::SHL:
    case Token::SHR:
      return ValidateShiftExpression(expr);
    case Token::BIT_AND:
      return ValidateBitwiseANDExpression(expr);
    case Token::BIT_XOR:
      if (IsInvert(expr)) {
        auto* left = expr->left();
        auto* left_as_binop = left->AsBinaryOperation();

        if (left_as_binop != nullptr && IsInvert(left_as_binop)) {
          // This is the special ~~ operator.
          AsmType* left_type;
          RECURSE(left_type = ValidateExpression(left_as_binop->left()));
          SetTypeOf(left_as_binop->right(), AsmType::FixNum());
          SetTypeOf(left_as_binop, AsmType::Signed());
          SetTypeOf(expr->right(), AsmType::FixNum());
          UNOP_OVERLOAD(Double, Signed);
          UNOP_OVERLOAD(FloatQ, Signed);
          FAIL(left_as_binop, "Invalid type for conversion to signed.");
        }

        AsmType* left_type;
        RECURSE(left_type = ValidateExpression(left));
        UNOP_OVERLOAD(Intish, Signed);
        FAIL(left, "Invalid type for ~.");
      }

      return ValidateBitwiseXORExpression(expr);
    case Token::BIT_OR:
      return ValidateBitwiseORExpression(expr);
  }
#undef UNOP_OVERLOAD
  UNREACHABLE();
}

// 6.8.1 Expression
AsmType* AsmTyper::ValidateCommaExpression(BinaryOperation* comma) {
  // The AST looks like:
  // (expr COMMA (expr COMMA (expr COMMA (... ))))

  auto* left = comma->left();
  if (auto* left_as_call = left->AsCall()) {
    RECURSE(ValidateCall(AsmType::Void(), left_as_call));
  } else {
    RECURSE(ValidateExpression(left));
  }

  auto* right = comma->right();
  AsmType* right_type = nullptr;
  if (auto* right_as_call = right->AsCall()) {
    RECURSE(right_type = ValidateFloatCoercion(right_as_call));
    if (right_type != AsmType::Float()) {
      // right_type == nullptr <-> right_as_call is not a call to fround.
      DCHECK(right_type == nullptr);
      RECURSE(right_type = ValidateCall(AsmType::Void(), right_as_call));
      // Unnanotated function call to something that's not fround must be a call
      // to a void function.
      DCHECK_EQ(right_type, AsmType::Void());
    }
  } else {
    RECURSE(right_type = ValidateExpression(right));
  }

  return right_type;
}

// 6.8.2 NumericLiteral
AsmType* AsmTyper::ValidateNumericLiteral(Literal* literal) {
  // *VIOLATION* asm.js does not allow the use of undefined, but our parser
  // inserts them, so we have to handle them.
  if (literal->IsUndefinedLiteral()) {
    return AsmType::Void();
  }

  if (literal->raw_value()->ContainsDot()) {
    return AsmType::Double();
  }

  // The parser collapses expressions like !0 and !123 to true/false.
  // We therefore need to permit these as alternate versions of 0 / 1.
  if (literal->raw_value()->IsTrue() || literal->raw_value()->IsFalse()) {
    return AsmType::Int();
  }

  uint32_t value;
  if (!literal->value()->ToUint32(&value)) {
    int32_t value;
    if (!literal->value()->ToInt32(&value)) {
      FAIL(literal, "Integer literal is out of range.");
    }
    // *VIOLATION* Not really a violation, but rather a difference in
    // validation. The spec handles -NumericLiteral in ValidateUnaryExpression,
    // but V8's AST represents the negative literals as Literals.
    return AsmType::Signed();
  }

  if (value <= LargestFixNum) {
    return AsmType::FixNum();
  }

  return AsmType::Unsigned();
}

// 6.8.3 Identifier
AsmType* AsmTyper::ValidateIdentifier(VariableProxy* proxy) {
  auto* proxy_info = Lookup(proxy->var());
  if (proxy_info == nullptr) {
    FAIL(proxy, "Undeclared identifier.");
  }
  auto* type = proxy_info->type();
  if (type->IsA(AsmType::None()) || type->AsCallableType() != nullptr) {
    FAIL(proxy, "Identifier may not be accessed by ordinary expressions.");
  }
  return type;
}

// 6.8.4 CallExpression
AsmType* AsmTyper::ValidateCallExpression(Call* call) {
  AsmType* return_type;
  RECURSE(return_type = ValidateFloatCoercion(call));
  if (return_type == nullptr) {
    FAIL(call, "Unanotated call to a function must be a call to fround.");
  }
  return return_type;
}

// 6.8.5 MemberExpression
AsmType* AsmTyper::ValidateMemberExpression(Property* prop) {
  AsmType* return_type;
  RECURSE(return_type = ValidateHeapAccess(prop, LoadFromHeap));
  return return_type;
}

// 6.8.6 AssignmentExpression
AsmType* AsmTyper::ValidateAssignmentExpression(Assignment* assignment) {
  AsmType* value_type;
  RECURSE(value_type = ValidateExpression(assignment->value()));

  if (assignment->op() == Token::INIT) {
    FAIL(assignment,
         "Local variable declaration must be at the top of the function.");
  }

  if (auto* target_as_proxy = assignment->target()->AsVariableProxy()) {
    auto* var = target_as_proxy->var();
    auto* target_info = Lookup(var);

    if (target_info == nullptr) {
      if (var->mode() != TEMPORARY) {
        FAIL(target_as_proxy, "Undeclared identifier.");
      }
      // Temporary variables are special: we add them to the local symbol table
      // as we see them, with the exact type of the variable's initializer. This
      // means that temporary variables might have nonsensical types (i.e.,
      // intish, float?, fixnum, and not just the "canonical" types.)
      auto* var_info = new (zone_) VariableInfo(value_type);
      var_info->set_mutability(VariableInfo::kLocal);
      if (!ValidAsmIdentifier(target_as_proxy->name())) {
        FAIL(target_as_proxy,
             "Invalid asm.js identifier in temporary variable.");
      }

      if (!AddLocal(var, var_info)) {
        FAIL(assignment, "Failed to add temporary variable to symbol table.");
      }
      return value_type;
    }

    if (!target_info->IsMutable()) {
      FAIL(assignment, "Can't assign to immutable symbol.");
    }

    DCHECK_NE(AsmType::None(), target_info->type());
    if (!value_type->IsA(target_info->type())) {
      FAIL(assignment, "Type mismatch in assignment.");
    }

    return value_type;
  }

  if (auto* target_as_property = assignment->target()->AsProperty()) {
    AsmType* allowed_store_types;
    RECURSE(allowed_store_types =
                ValidateHeapAccess(target_as_property, StoreToHeap));

    if (!value_type->IsA(allowed_store_types)) {
      FAIL(assignment, "Type mismatch in heap assignment.");
    }

    return value_type;
  }

  FAIL(assignment, "Invalid asm.js assignment.");
}

// 6.8.7 UnaryExpression
AsmType* AsmTyper::ValidateUnaryExpression(UnaryOperation* unop) {
  // *VIOLATION* -NumericLiteral is validated in ValidateLiteral.
  // *VIOLATION* +UnaryExpression is validated in ValidateBinaryOperation.
  // *VIOLATION* ~UnaryOperation is validated in ValidateBinaryOperation.
  // *VIOLATION* ~~UnaryOperation is validated in ValidateBinaryOperation.
  DCHECK(unop->op() != Token::BIT_NOT);
  DCHECK(unop->op() != Token::ADD);
  AsmType* exp_type;
  RECURSE(exp_type = ValidateExpression(unop->expression()));
#define UNOP_OVERLOAD(Src, Dest)         \
  do {                                   \
    if (exp_type->IsA(AsmType::Src())) { \
      return AsmType::Dest();            \
    }                                    \
  } while (0)

  // 8.1 Unary Operators
  switch (unop->op()) {
    default:
      FAIL(unop, "Invalid unary operator.");
    case Token::ADD:
      // We can't test this because of the +x -> x * 1.0 transformation.
      DCHECK(false);
      UNOP_OVERLOAD(Signed, Double);
      UNOP_OVERLOAD(Unsigned, Double);
      UNOP_OVERLOAD(DoubleQ, Double);
      UNOP_OVERLOAD(FloatQ, Double);
      FAIL(unop, "Invalid type for unary +.");
    case Token::SUB:
      // We can't test this because of the -x -> x * -1.0 transformation.
      DCHECK(false);
      UNOP_OVERLOAD(Int, Intish);
      UNOP_OVERLOAD(DoubleQ, Double);
      UNOP_OVERLOAD(FloatQ, Floatish);
      FAIL(unop, "Invalid type for unary -.");
    case Token::BIT_NOT:
      // We can't test this because of the ~x -> x ^ -1 transformation.
      DCHECK(false);
      UNOP_OVERLOAD(Intish, Signed);
      FAIL(unop, "Invalid type for ~.");
    case Token::NOT:
      UNOP_OVERLOAD(Int, Int);
      FAIL(unop, "Invalid type for !.");
  }

#undef UNOP_OVERLOAD

  UNREACHABLE();
}

// 6.8.8 MultiplicativeExpression
namespace {
bool IsIntishLiteralFactor(Expression* expr, int32_t* factor) {
  auto* literal = expr->AsLiteral();
  if (literal == nullptr) {
    return false;
  }

  if (literal->raw_value()->ContainsDot()) {
    return false;
  }

  if (!literal->value()->ToInt32(factor)) {
    return false;
  }
  static const int32_t kIntishBound = 1 << 20;
  return -kIntishBound < *factor && *factor < kIntishBound;
}
}  // namespace

AsmType* AsmTyper::ValidateMultiplicativeExpression(BinaryOperation* binop) {
  DCHECK(!IsDoubleAnnotation(binop));

  auto* left = binop->left();
  auto* right = binop->right();

  bool intish_mul_failed = false;
  if (binop->op() == Token::MUL) {
    int32_t factor;
    if (IsIntishLiteralFactor(left, &factor)) {
      AsmType* right_type;
      RECURSE(right_type = ValidateExpression(right));
      if (right_type->IsA(AsmType::Int())) {
        return AsmType::Intish();
      }
      // Can't fail here, because the rhs might contain a valid intish factor.
      //
      // The solution is to flag that there was an error, and later on -- when
      // both lhs and rhs are evaluated -- complain.
      intish_mul_failed = true;
    }

    if (IsIntishLiteralFactor(right, &factor)) {
      AsmType* left_type;
      RECURSE(left_type = ValidateExpression(left));
      if (left_type->IsA(AsmType::Int())) {
        // *VIOLATION* This will also (and correctly) handle -X, when X is an
        // integer. Therefore, we don't need to handle this case within the if
        // block below.
        return AsmType::Intish();
      }
      intish_mul_failed = true;

      if (factor == -1) {
        // *VIOLATION* The frontend transforms -x into x * -1 (not -1.0, because
        // consistency is overrated.)
        if (left_type->IsA(AsmType::DoubleQ())) {
          return AsmType::Double();
        } else if (left_type->IsA(AsmType::FloatQ())) {
          return AsmType::Floatish();
        }
      }
    }
  }

  if (intish_mul_failed) {
    FAIL(binop, "Invalid types for intish * (or unary -).");
  }

  AsmType* left_type;
  AsmType* right_type;
  RECURSE(left_type = ValidateExpression(left));
  RECURSE(right_type = ValidateExpression(right));

#define BINOP_OVERLOAD(Src0, Src1, Dest)                                       \
  do {                                                                         \
    if (left_type->IsA(AsmType::Src0()) && right_type->IsA(AsmType::Src1())) { \
      return AsmType::Dest();                                                  \
    }                                                                          \
  } while (0)
  switch (binop->op()) {
    default:
      FAIL(binop, "Invalid multiplicative expression.");
    case Token::MUL:
      BINOP_OVERLOAD(DoubleQ, DoubleQ, Double);
      BINOP_OVERLOAD(FloatQ, FloatQ, Floatish);
      FAIL(binop, "Invalid operands for *.");
    case Token::DIV:
      BINOP_OVERLOAD(Signed, Signed, Intish);
      BINOP_OVERLOAD(Unsigned, Unsigned, Intish);
      BINOP_OVERLOAD(DoubleQ, DoubleQ, Double);
      BINOP_OVERLOAD(FloatQ, FloatQ, Floatish);
      FAIL(binop, "Invalid operands for /.");
    case Token::MOD:
      BINOP_OVERLOAD(Signed, Signed, Intish);
      BINOP_OVERLOAD(Unsigned, Unsigned, Intish);
      BINOP_OVERLOAD(DoubleQ, DoubleQ, Double);
      FAIL(binop, "Invalid operands for %.");
  }
#undef BINOP_OVERLOAD

  UNREACHABLE();
}

// 6.8.9 AdditiveExpression
AsmType* AsmTyper::ValidateAdditiveExpression(BinaryOperation* binop,
                                              uint32_t intish_count) {
  static const uint32_t kMaxIntish = 1 << 20;

  auto* left = binop->left();
  auto* left_as_binop = left->AsBinaryOperation();
  AsmType* left_type;

  // TODO(jpp): maybe use an iterative approach instead of the recursion to
  // ValidateAdditiveExpression.
  if (left_as_binop != nullptr && (left_as_binop->op() == Token::ADD ||
                                   left_as_binop->op() == Token::SUB)) {
    RECURSE(left_type =
                ValidateAdditiveExpression(left_as_binop, intish_count + 1));
    SetTypeOf(left_as_binop, left_type);
  } else {
    RECURSE(left_type = ValidateExpression(left));
  }

  auto* right = binop->right();
  auto* right_as_binop = right->AsBinaryOperation();
  AsmType* right_type;

  if (right_as_binop != nullptr && (right_as_binop->op() == Token::ADD ||
                                    right_as_binop->op() == Token::SUB)) {
    RECURSE(right_type =
                ValidateAdditiveExpression(right_as_binop, intish_count + 1));
    SetTypeOf(right_as_binop, right_type);
  } else {
    RECURSE(right_type = ValidateExpression(right));
  }

  if (left_type->IsA(AsmType::FloatQ()) && right_type->IsA(AsmType::FloatQ())) {
    return AsmType::Floatish();
  }

  if (left_type->IsA(AsmType::Int()) && right_type->IsA(AsmType::Int())) {
    if (intish_count == 0) {
      return AsmType::Intish();
    }
    if (intish_count < kMaxIntish) {
      return AsmType::Int();
    }
    FAIL(binop, "Too many uncoerced integer additive expressions.");
  }

  if (left_type->IsA(AsmType::Double()) && right_type->IsA(AsmType::Double())) {
    return AsmType::Double();
  }

  if (binop->op() == Token::SUB) {
    if (left_type->IsA(AsmType::DoubleQ()) &&
        right_type->IsA(AsmType::DoubleQ())) {
      return AsmType::Double();
    }
  }

  FAIL(binop, "Invalid operands for additive expression.");
}

// 6.8.10 ShiftExpression
AsmType* AsmTyper::ValidateShiftExpression(BinaryOperation* binop) {
  auto* left = binop->left();
  auto* right = binop->right();

  AsmType* left_type;
  AsmType* right_type;
  RECURSE(left_type = ValidateExpression(left));
  RECURSE(right_type = ValidateExpression(right));

#define BINOP_OVERLOAD(Src0, Src1, Dest)                                       \
  do {                                                                         \
    if (left_type->IsA(AsmType::Src0()) && right_type->IsA(AsmType::Src1())) { \
      return AsmType::Dest();                                                  \
    }                                                                          \
  } while (0)
  switch (binop->op()) {
    default:
      FAIL(binop, "Invalid shift expression.");
    case Token::SHL:
      BINOP_OVERLOAD(Intish, Intish, Signed);
      FAIL(binop, "Invalid operands for <<.");
    case Token::SAR:
      BINOP_OVERLOAD(Intish, Intish, Signed);
      FAIL(binop, "Invalid operands for >>.");
    case Token::SHR:
      BINOP_OVERLOAD(Intish, Intish, Unsigned);
      FAIL(binop, "Invalid operands for >>>.");
  }
#undef BINOP_OVERLOAD

  UNREACHABLE();
}

// 6.8.11 RelationalExpression
AsmType* AsmTyper::ValidateRelationalExpression(CompareOperation* cmpop) {
  auto* left = cmpop->left();
  auto* right = cmpop->right();

  AsmType* left_type;
  AsmType* right_type;
  RECURSE(left_type = ValidateExpression(left));
  RECURSE(right_type = ValidateExpression(right));

#define CMPOP_OVERLOAD(Src0, Src1, Dest)                                       \
  do {                                                                         \
    if (left_type->IsA(AsmType::Src0()) && right_type->IsA(AsmType::Src1())) { \
      return AsmType::Dest();                                                  \
    }                                                                          \
  } while (0)
  switch (cmpop->op()) {
    default:
      FAIL(cmpop, "Invalid relational expression.");
    case Token::LT:
      CMPOP_OVERLOAD(Signed, Signed, Int);
      CMPOP_OVERLOAD(Unsigned, Unsigned, Int);
      CMPOP_OVERLOAD(Float, Float, Int);
      CMPOP_OVERLOAD(Double, Double, Int);
      FAIL(cmpop, "Invalid operands for <.");
    case Token::GT:
      CMPOP_OVERLOAD(Signed, Signed, Int);
      CMPOP_OVERLOAD(Unsigned, Unsigned, Int);
      CMPOP_OVERLOAD(Float, Float, Int);
      CMPOP_OVERLOAD(Double, Double, Int);
      FAIL(cmpop, "Invalid operands for >.");
    case Token::LTE:
      CMPOP_OVERLOAD(Signed, Signed, Int);
      CMPOP_OVERLOAD(Unsigned, Unsigned, Int);
      CMPOP_OVERLOAD(Float, Float, Int);
      CMPOP_OVERLOAD(Double, Double, Int);
      FAIL(cmpop, "Invalid operands for <=.");
    case Token::GTE:
      CMPOP_OVERLOAD(Signed, Signed, Int);
      CMPOP_OVERLOAD(Unsigned, Unsigned, Int);
      CMPOP_OVERLOAD(Float, Float, Int);
      CMPOP_OVERLOAD(Double, Double, Int);
      FAIL(cmpop, "Invalid operands for >=.");
  }
#undef CMPOP_OVERLOAD

  UNREACHABLE();
}

// 6.8.12 EqualityExpression
AsmType* AsmTyper::ValidateEqualityExpression(CompareOperation* cmpop) {
  auto* left = cmpop->left();
  auto* right = cmpop->right();

  AsmType* left_type;
  AsmType* right_type;
  RECURSE(left_type = ValidateExpression(left));
  RECURSE(right_type = ValidateExpression(right));

#define CMPOP_OVERLOAD(Src0, Src1, Dest)                                       \
  do {                                                                         \
    if (left_type->IsA(AsmType::Src0()) && right_type->IsA(AsmType::Src1())) { \
      return AsmType::Dest();                                                  \
    }                                                                          \
  } while (0)
  switch (cmpop->op()) {
    default:
      FAIL(cmpop, "Invalid equality expression.");
    case Token::EQ:
      CMPOP_OVERLOAD(Signed, Signed, Int);
      CMPOP_OVERLOAD(Unsigned, Unsigned, Int);
      CMPOP_OVERLOAD(Float, Float, Int);
      CMPOP_OVERLOAD(Double, Double, Int);
      FAIL(cmpop, "Invalid operands for ==.");
    case Token::NE:
      CMPOP_OVERLOAD(Signed, Signed, Int);
      CMPOP_OVERLOAD(Unsigned, Unsigned, Int);
      CMPOP_OVERLOAD(Float, Float, Int);
      CMPOP_OVERLOAD(Double, Double, Int);
      FAIL(cmpop, "Invalid operands for !=.");
  }
#undef CMPOP_OVERLOAD

  UNREACHABLE();
}

// 6.8.13 BitwiseANDExpression
AsmType* AsmTyper::ValidateBitwiseANDExpression(BinaryOperation* binop) {
  auto* left = binop->left();
  auto* right = binop->right();

  AsmType* left_type;
  AsmType* right_type;
  RECURSE(left_type = ValidateExpression(left));
  RECURSE(right_type = ValidateExpression(right));

  if (binop->op() != Token::BIT_AND) {
    FAIL(binop, "Invalid & expression.");
  }

#define BINOP_OVERLOAD(Src0, Src1, Dest)                                       \
  do {                                                                         \
    if (left_type->IsA(AsmType::Src0()) && right_type->IsA(AsmType::Src1())) { \
      return AsmType::Dest();                                                  \
    }                                                                          \
  } while (0)
  BINOP_OVERLOAD(Intish, Intish, Signed);
  FAIL(binop, "Invalid operands for &.");
#undef BINOP_OVERLOAD

  UNREACHABLE();
}

// 6.8.14 BitwiseXORExpression
AsmType* AsmTyper::ValidateBitwiseXORExpression(BinaryOperation* binop) {
  auto* left = binop->left();
  auto* right = binop->right();

  AsmType* left_type;
  AsmType* right_type;
  RECURSE(left_type = ValidateExpression(left));
  RECURSE(right_type = ValidateExpression(right));

  if (binop->op() != Token::BIT_XOR) {
    FAIL(binop, "Invalid ^ expression.");
  }

#define BINOP_OVERLOAD(Src0, Src1, Dest)                                       \
  do {                                                                         \
    if (left_type->IsA(AsmType::Src0()) && right_type->IsA(AsmType::Src1())) { \
      return AsmType::Dest();                                                  \
    }                                                                          \
  } while (0)
  BINOP_OVERLOAD(Intish, Intish, Signed);
  FAIL(binop, "Invalid operands for ^.");
#undef BINOP_OVERLOAD

  UNREACHABLE();
}

// 6.8.15 BitwiseORExpression
AsmType* AsmTyper::ValidateBitwiseORExpression(BinaryOperation* binop) {
  auto* left = binop->left();
  if (IsIntAnnotation(binop)) {
    if (auto* left_as_call = left->AsCall()) {
      AsmType* type;
      RECURSE(type = ValidateCall(AsmType::Signed(), left_as_call));
      return type;
    }

    // TODO(jpp): at this point we know that binop is expr|0. We could sinply
    //
    // RECURSE(t = ValidateExpression(left));
    // FAIL_IF(t->IsNotA(Intish));
    // return Signed;
  }

  auto* right = binop->right();
  AsmType* left_type;
  AsmType* right_type;
  RECURSE(left_type = ValidateExpression(left));
  RECURSE(right_type = ValidateExpression(right));

  if (binop->op() != Token::BIT_OR) {
    FAIL(binop, "Invalid | expression.");
  }

#define BINOP_OVERLOAD(Src0, Src1, Dest)                                       \
  do {                                                                         \
    if (left_type->IsA(AsmType::Src0()) && right_type->IsA(AsmType::Src1())) { \
      return AsmType::Dest();                                                  \
    }                                                                          \
  } while (0)
  BINOP_OVERLOAD(Intish, Intish, Signed);
  FAIL(binop, "Invalid operands for |.");
#undef BINOP_OVERLOAD

  UNREACHABLE();
}

// 6.8.16 ConditionalExpression
AsmType* AsmTyper::ValidateConditionalExpression(Conditional* cond) {
  AsmType* cond_type;
  RECURSE(cond_type = ValidateExpression(cond->condition()));
  if (!cond_type->IsA(AsmType::Int())) {
    FAIL(cond, "Ternary operation condition should be int.");
  }

  AsmType* then_type;
  RECURSE(then_type = ValidateExpression(cond->then_expression()));
  AsmType* else_type;
  RECURSE(else_type = ValidateExpression(cond->else_expression()));

#define SUCCEED_IF_BOTH_ARE(type)                                       \
  do {                                                                  \
    if (then_type->IsA(AsmType::type())) {                              \
      if (!else_type->IsA(AsmType::type())) {                           \
        FAIL(cond, "Type mismatch for ternary operation result type."); \
      }                                                                 \
      return AsmType::type();                                           \
    }                                                                   \
  } while (0)
  SUCCEED_IF_BOTH_ARE(Int);
  SUCCEED_IF_BOTH_ARE(Float);
  SUCCEED_IF_BOTH_ARE(Double);
#undef SUCCEED_IF_BOTH_ARE

  FAIL(cond, "Ternary operator must return int, float, or double.");
}

// 6.9 ValidateCall
namespace {
bool ExtractIndirectCallMask(Expression* expr, uint32_t* value) {
  auto* as_literal = expr->AsLiteral();
  if (as_literal == nullptr) {
    return false;
  }

  if (as_literal->raw_value()->ContainsDot()) {
    return false;
  }

  if (!as_literal->value()->ToUint32(value)) {
    return false;
  }

  return base::bits::IsPowerOfTwo32(1 + *value);
}
}  // namespace

AsmType* AsmTyper::ValidateCall(AsmType* return_type, Call* call) {
  AsmType* float_coercion_type;
  RECURSE(float_coercion_type = ValidateFloatCoercion(call));
  if (float_coercion_type == AsmType::Float()) {
    SetTypeOf(call, AsmType::Float());
    return return_type;
  }

  // TODO(jpp): we should be able to reuse the args vector's storage space.
  ZoneVector<AsmType*> args(zone_);
  args.reserve(call->arguments()->length());

  for (auto* arg : *call->arguments()) {
    AsmType* arg_type;
    RECURSE(arg_type = ValidateExpression(arg));
    args.emplace_back(arg_type);
  }

  auto* call_expr = call->expression();

  // identifier(Expression...)
  if (auto* call_var_proxy = call_expr->AsVariableProxy()) {
    auto* call_var_info = Lookup(call_var_proxy->var());

    if (call_var_info == nullptr) {
      // We can't fail here: the validator performs a single pass over the AST,
      // so it is possible for some calls to be currently unresolved. We eagerly
      // add the function to the table of globals.
      auto* call_type = AsmType::Function(zone_, return_type)->AsFunctionType();
      for (auto* arg : args) {
        call_type->AddArgument(arg->ToParameterType());
      }
      auto* fun_info =
          new (zone_) VariableInfo(reinterpret_cast<AsmType*>(call_type));
      fun_info->set_mutability(VariableInfo::kImmutableGlobal);
      AddForwardReference(call_var_proxy, fun_info);
      if (!ValidAsmIdentifier(call_var_proxy->name())) {
        FAIL(call_var_proxy,
             "Invalid asm.js identifier in (forward) function name.");
      }
      if (!AddGlobal(call_var_proxy->var(), fun_info)) {
        DCHECK(false);
        FAIL(call, "Redeclared global identifier.");
      }
      SetTypeOf(call_var_proxy, reinterpret_cast<AsmType*>(call_type));
      SetTypeOf(call, return_type);
      return return_type;
    }

    auto* callee_type = call_var_info->type()->AsCallableType();
    if (callee_type == nullptr) {
      FAIL(call, "Calling something that's not a function.");
    }

    if (callee_type->AsFFIType() != nullptr) {
      if (return_type == AsmType::Float()) {
        FAIL(call, "Foreign functions can't return float.");
      }
      // Record FFI use signature, since the asm->wasm translator must know
      // all uses up-front.
      ffi_use_signatures_.emplace_back(
          FFIUseSignature(call_var_proxy->var(), zone_));
      FFIUseSignature* sig = &ffi_use_signatures_.back();
      sig->return_type_ = return_type;
      sig->arg_types_.reserve(args.size());
      for (size_t i = 0; i < args.size(); ++i) {
        sig->arg_types_.emplace_back(args[i]);
      }
    }

    if (!callee_type->CanBeInvokedWith(return_type, args)) {
      FAIL(call, "Function invocation does not match function type.");
    }

    SetTypeOf(call_var_proxy, call_var_info->type());
    SetTypeOf(call, return_type);
    return return_type;
  }

  // identifier[expr & n](Expression...)
  if (auto* call_property = call_expr->AsProperty()) {
    auto* index = call_property->key()->AsBinaryOperation();
    if (index == nullptr || index->op() != Token::BIT_AND) {
      FAIL(call_property->key(),
           "Indirect call index must be in the expr & mask form.");
    }

    auto* left = index->left();
    auto* right = index->right();
    uint32_t mask;
    if (!ExtractIndirectCallMask(right, &mask)) {
      if (!ExtractIndirectCallMask(left, &mask)) {
        FAIL(right, "Invalid indirect call mask.");
      } else {
        left = right;
      }
    }
    const uint32_t table_length = mask + 1;

    AsmType* left_type;
    RECURSE(left_type = ValidateExpression(left));
    if (!left_type->IsA(AsmType::Intish())) {
      FAIL(left, "Indirect call index should be an intish.");
    }

    auto* name_var = call_property->obj()->AsVariableProxy();

    if (name_var == nullptr) {
      FAIL(call_property, "Invalid call.");
    }

    auto* name_info = Lookup(name_var->var());
    if (name_info == nullptr) {
      // We can't fail here -- just like above.
      auto* call_type = AsmType::Function(zone_, return_type)->AsFunctionType();
      for (auto* arg : args) {
        call_type->AddArgument(arg->ToParameterType());
      }
      auto* table_type = AsmType::FunctionTableType(
          zone_, table_length, reinterpret_cast<AsmType*>(call_type));
      auto* fun_info =
          new (zone_) VariableInfo(reinterpret_cast<AsmType*>(table_type));
      fun_info->set_mutability(VariableInfo::kImmutableGlobal);
      AddForwardReference(name_var, fun_info);
      if (!ValidAsmIdentifier(name_var->name())) {
        FAIL(name_var,
             "Invalid asm.js identifier in (forward) function table name.");
      }
      if (!AddGlobal(name_var->var(), fun_info)) {
        DCHECK(false);
        FAIL(call, "Redeclared global identifier.");
      }
      SetTypeOf(call_property, reinterpret_cast<AsmType*>(call_type));
      SetTypeOf(call, return_type);
      return return_type;
    }

    auto* previous_type = name_info->type()->AsFunctionTableType();
    if (previous_type == nullptr) {
      FAIL(call, "Identifier does not name a function table.");
    }

    if (table_length != previous_type->length()) {
      FAIL(call, "Function table size does not match expected size.");
    }

    auto* previous_type_signature =
        previous_type->signature()->AsFunctionType();
    DCHECK(previous_type_signature != nullptr);
    if (!previous_type_signature->CanBeInvokedWith(return_type, args)) {
      // TODO(jpp): better error messages.
      FAIL(call,
           "Function pointer table signature does not match previous "
           "signature.");
    }

    SetTypeOf(call_property, previous_type->signature());
    SetTypeOf(call, return_type);
    return return_type;
  }

  FAIL(call, "Invalid call.");
}

// 6.10 ValidateHeapAccess
namespace {
bool ExtractHeapAccessShift(Expression* expr, uint32_t* value) {
  auto* as_literal = expr->AsLiteral();
  if (as_literal == nullptr) {
    return false;
  }

  if (as_literal->raw_value()->ContainsDot()) {
    return false;
  }

  return as_literal->value()->ToUint32(value);
}

// Returns whether index is too large to access a heap with the given type.
bool LiteralIndexOutOfBounds(AsmType* obj_type, uint32_t index) {
  switch (obj_type->ElementSizeInBytes()) {
    case 1:
      return false;
    case 2:
      return (index & 0x80000000u) != 0;
    case 4:
      return (index & 0xC0000000u) != 0;
    case 8:
      return (index & 0xE0000000u) != 0;
  }
  UNREACHABLE();
  return true;
}

}  // namespace

AsmType* AsmTyper::ValidateHeapAccess(Property* heap,
                                      HeapAccessType access_type) {
  auto* obj = heap->obj()->AsVariableProxy();
  if (obj == nullptr) {
    FAIL(heap, "Invalid heap access.");
  }

  auto* obj_info = Lookup(obj->var());
  if (obj_info == nullptr) {
    FAIL(heap, "Undeclared identifier in heap access.");
  }

  auto* obj_type = obj_info->type();
  if (!obj_type->IsA(AsmType::Heap())) {
    FAIL(heap, "Identifier does not represent a heap view.");
  }
  SetTypeOf(obj, obj_type);

  if (auto* key_as_literal = heap->key()->AsLiteral()) {
    if (key_as_literal->raw_value()->ContainsDot()) {
      FAIL(key_as_literal, "Heap access index must be int.");
    }

    uint32_t index;
    if (!key_as_literal->value()->ToUint32(&index)) {
      FAIL(key_as_literal,
           "Heap access index must be a 32-bit unsigned integer.");
    }

    if (LiteralIndexOutOfBounds(obj_type, index)) {
      FAIL(key_as_literal, "Heap access index is out of bounds");
    }

    if (access_type == LoadFromHeap) {
      return obj_type->LoadType();
    }
    return obj_type->StoreType();
  }

  if (auto* key_as_binop = heap->key()->AsBinaryOperation()) {
    uint32_t shift;
    if (key_as_binop->op() == Token::SAR &&
        ExtractHeapAccessShift(key_as_binop->right(), &shift) &&
        (1 << shift) == obj_type->ElementSizeInBytes()) {
      AsmType* type;
      RECURSE(type = ValidateExpression(key_as_binop->left()));
      if (type->IsA(AsmType::Intish())) {
        if (access_type == LoadFromHeap) {
          return obj_type->LoadType();
        }
        return obj_type->StoreType();
      }
      FAIL(key_as_binop, "Invalid heap access index.");
    }
  }

  if (obj_type->ElementSizeInBytes() == 1) {
    // Leniency: if this is a byte array, we don't require the shift operation
    // to be present.
    AsmType* index_type;
    RECURSE(index_type = ValidateExpression(heap->key()));
    if (!index_type->IsA(AsmType::Int())) {
      FAIL(heap, "Invalid heap access index for byte array.");
    }
    if (access_type == LoadFromHeap) {
      return obj_type->LoadType();
    }
    return obj_type->StoreType();
  }

  FAIL(heap, "Invalid heap access index.");
}

// 6.11 ValidateFloatCoercion
bool AsmTyper::IsCallToFround(Call* call) {
  if (call->arguments()->length() != 1) {
    return false;
  }

  auto* call_var_proxy = call->expression()->AsVariableProxy();
  if (call_var_proxy == nullptr) {
    return false;
  }

  auto* call_var_info = Lookup(call_var_proxy->var());
  if (call_var_info == nullptr) {
    return false;
  }

  return call_var_info->standard_member() == kMathFround;
}

AsmType* AsmTyper::ValidateFloatCoercion(Call* call) {
  if (!IsCallToFround(call)) {
    return nullptr;
  }

  auto* arg = call->arguments()->at(0);
  // call is a fround() node. From now, there can be two possible outcomes:
  // 1. fround is used as a return type annotation.
  if (auto* arg_as_call = arg->AsCall()) {
    RECURSE(ValidateCall(AsmType::Float(), arg_as_call));
    return AsmType::Float();
  }

  // 2. fround is used for converting to float.
  AsmType* arg_type;
  RECURSE(arg_type = ValidateExpression(arg));
  if (arg_type->IsA(AsmType::Floatish()) || arg_type->IsA(AsmType::DoubleQ()) ||
      arg_type->IsA(AsmType::Signed()) || arg_type->IsA(AsmType::Unsigned())) {
    SetTypeOf(call->expression(), fround_type_);
    return AsmType::Float();
  }

  FAIL(call, "Invalid argument type to fround.");
}

// 5.1 ParameterTypeAnnotations
AsmType* AsmTyper::ParameterTypeAnnotations(Variable* parameter,
                                            Expression* annotation) {
  if (auto* binop = annotation->AsBinaryOperation()) {
    // Must be:
    //   * x|0
    //   * x*1 (*VIOLATION* i.e.,, +x)
    auto* left = binop->left()->AsVariableProxy();
    if (left == nullptr) {
      FAIL(
          binop->left(),
          "Invalid parameter type annotation - should annotate an identifier.");
    }
    if (left->var() != parameter) {
      FAIL(binop->left(),
           "Invalid parameter type annotation - should annotate a parameter.");
    }
    if (IsDoubleAnnotation(binop)) {
      SetTypeOf(left, AsmType::Double());
      return AsmType::Double();
    }
    if (IsIntAnnotation(binop)) {
      SetTypeOf(left, AsmType::Int());
      return AsmType::Int();
    }
    FAIL(binop, "Invalid parameter type annotation.");
  }

  auto* call = annotation->AsCall();
  if (call == nullptr) {
    FAIL(
        annotation,
        "Invalid float parameter type annotation - must be fround(parameter).");
  }

  if (!IsCallToFround(call)) {
    FAIL(annotation,
         "Invalid float parameter type annotation - must be call to fround.");
  }

  auto* src_expr = call->arguments()->at(0)->AsVariableProxy();
  if (src_expr == nullptr) {
    FAIL(annotation,
         "Invalid float parameter type annotation - argument to fround is not "
         "an identifier.");
  }

  if (src_expr->var() != parameter) {
    FAIL(annotation,
         "Invalid float parameter type annotation - argument to fround is not "
         "a parameter.");
  }

  SetTypeOf(src_expr, AsmType::Float());
  return AsmType::Float();
}

// 5.2 ReturnTypeAnnotations
AsmType* AsmTyper::ReturnTypeAnnotations(ReturnStatement* statement) {
  if (statement == nullptr) {
    return AsmType::Void();
  }

  auto* ret_expr = statement->expression();
  if (ret_expr == nullptr) {
    return AsmType::Void();
  }

  if (auto* binop = ret_expr->AsBinaryOperation()) {
    if (IsDoubleAnnotation(binop)) {
      return AsmType::Double();
    } else if (IsIntAnnotation(binop)) {
      return AsmType::Signed();
    }
    FAIL(statement, "Invalid return type annotation.");
  }

  if (auto* call = ret_expr->AsCall()) {
    if (IsCallToFround(call)) {
      return AsmType::Float();
    }
    FAIL(statement, "Invalid function call in return statement.");
  }

  if (auto* literal = ret_expr->AsLiteral()) {
    int32_t _;
    if (literal->raw_value()->ContainsDot()) {
      return AsmType::Double();
    } else if (literal->value()->ToInt32(&_)) {
      return AsmType::Signed();
    } else if (literal->IsUndefinedLiteral()) {
      // *VIOLATION* The parser changes
      //
      // return;
      //
      // into
      //
      // return undefined
      return AsmType::Void();
    }
    FAIL(statement, "Invalid literal in return statement.");
  }

  if (auto* proxy = ret_expr->AsVariableProxy()) {
    auto* var_info = Lookup(proxy->var());

    if (var_info == nullptr) {
      FAIL(statement, "Undeclared identifier in return statement.");
    }

    if (var_info->mutability() != VariableInfo::kConstGlobal) {
      FAIL(statement, "Identifier in return statement is not const.");
    }

    if (!var_info->type()->IsReturnType()) {
      FAIL(statement, "Constant in return must be signed, float, or double.");
    }

    return var_info->type();
  }

  FAIL(statement, "Invalid return type expression.");
}

// 5.4 VariableTypeAnnotations
// Also used for 5.5 GlobalVariableTypeAnnotations
AsmType* AsmTyper::VariableTypeAnnotations(
    Expression* initializer, VariableInfo::Mutability mutability_type) {
  if (auto* literal = initializer->AsLiteral()) {
    if (literal->raw_value()->ContainsDot()) {
      SetTypeOf(initializer, AsmType::Double());
      return AsmType::Double();
    }
    int32_t i32;
    uint32_t u32;

    AsmType* initializer_type = nullptr;
    if (literal->value()->ToUint32(&u32)) {
      if (u32 > LargestFixNum) {
        initializer_type = AsmType::Unsigned();
        SetTypeOf(initializer, initializer_type);
      } else {
        initializer_type = AsmType::FixNum();
        SetTypeOf(initializer, initializer_type);
        initializer_type = AsmType::Signed();
      }
    } else if (literal->value()->ToInt32(&i32)) {
      initializer_type = AsmType::Signed();
      SetTypeOf(initializer, initializer_type);
    } else {
      FAIL(initializer, "Invalid type annotation - forbidden literal.");
    }
    if (mutability_type != VariableInfo::kConstGlobal) {
      return AsmType::Int();
    }
    return initializer_type;
  }

  if (auto* proxy = initializer->AsVariableProxy()) {
    auto* var_info = Lookup(proxy->var());

    if (var_info == nullptr) {
      FAIL(initializer,
           "Undeclared identifier in variable declaration initializer.");
    }

    if (var_info->mutability() != VariableInfo::kConstGlobal) {
      FAIL(initializer,
           "Identifier in variable declaration initializer must be const.");
    }

    SetTypeOf(initializer, var_info->type());
    return var_info->type();
  }

  auto* call = initializer->AsCall();
  if (call == nullptr) {
    FAIL(initializer,
         "Invalid variable initialization - it should be a literal, const, or "
         "fround(literal).");
  }

  if (!IsCallToFround(call)) {
    FAIL(initializer,
         "Invalid float coercion - expected call fround(literal).");
  }

  auto* src_expr = call->arguments()->at(0)->AsLiteral();
  if (src_expr == nullptr) {
    FAIL(initializer,
         "Invalid float type annotation - expected literal argument for call "
         "to fround.");
  }

  // Float constants must contain dots in local, but not in globals.
  if (mutability_type == VariableInfo::kLocal) {
    if (!src_expr->raw_value()->ContainsDot()) {
      FAIL(initializer,
           "Invalid float type annotation - expected literal argument to be a "
           "floating point literal.");
    }
  }

  return AsmType::Float();
}

// 5.5 GlobalVariableTypeAnnotations
AsmType* AsmTyper::NewHeapView(CallNew* new_heap_view) {
  auto* heap_type = new_heap_view->expression()->AsProperty();
  if (heap_type == nullptr) {
    FAIL(new_heap_view, "Invalid type after new.");
  }
  auto* heap_view_info = ImportLookup(heap_type);

  if (heap_view_info == nullptr) {
    FAIL(new_heap_view, "Unknown stdlib member in heap view declaration.");
  }

  if (!heap_view_info->type()->IsA(AsmType::Heap())) {
    FAIL(new_heap_view, "Type is not a heap view type.");
  }

  if (new_heap_view->arguments()->length() != 1) {
    FAIL(new_heap_view, "Invalid number of arguments when creating heap view.");
  }

  auto* heap = new_heap_view->arguments()->at(0);
  auto* heap_var_proxy = heap->AsVariableProxy();

  if (heap_var_proxy == nullptr) {
    FAIL(heap,
         "Heap view creation parameter should be the module's heap parameter.");
  }

  auto* heap_var_info = Lookup(heap_var_proxy->var());

  if (heap_var_info == nullptr) {
    FAIL(heap, "Undeclared identifier instead of heap parameter.");
  }

  if (!heap_var_info->IsHeap()) {
    FAIL(heap,
         "Heap view creation parameter should be the module's heap parameter.");
  }

  DCHECK(heap_view_info->type()->IsA(AsmType::Heap()));
  return heap_view_info->type();
}

bool IsValidAsm(Isolate* isolate, Zone* zone, Script* script,
                FunctionLiteral* root, std::string* error_message) {
  error_message->clear();

  AsmTyper typer(isolate, zone, script, root);
  if (typer.Validate()) {
    return true;
  }

  *error_message = typer.error_message();
  return false;
}

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