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

#ifndef V8_COMPILER_WASM_COMPILER_H_
#define V8_COMPILER_WASM_COMPILER_H_

// Clients of this interface shouldn't depend on lots of compiler internals.
// Do not include anything from src/compiler here!
#include "src/wasm/wasm-opcodes.h"
#include "src/zone.h"

namespace v8 {
namespace internal {

namespace compiler {
// Forward declarations for some compiler data structures.
class Node;
class JSGraph;
class Graph;
}

namespace wasm {
// Forward declarations for some WASM data structures.
struct ModuleEnv;
struct WasmFunction;
class ErrorThrower;

// Expose {Node} and {Graph} opaquely as {wasm::TFNode} and {wasm::TFGraph}.
typedef compiler::Node TFNode;
typedef compiler::JSGraph TFGraph;
}

namespace compiler {
// Compiles a single function, producing a code object.
Handle<Code> CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate,
                                 wasm::ModuleEnv* module_env,
                                 const wasm::WasmFunction& function);

// Wraps a JS function, producing a code object that can be called from WASM.
Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, wasm::ModuleEnv* module,
                                    Handle<JSFunction> function,
                                    wasm::FunctionSig* sig, const char* name);

// Wraps a given wasm code object, producing a JSFunction that can be called
// from JavaScript.
Handle<JSFunction> CompileJSToWasmWrapper(
    Isolate* isolate, wasm::ModuleEnv* module, Handle<String> name,
    Handle<Code> wasm_code, Handle<JSObject> module_object, uint32_t index);

// Abstracts details of building TurboFan graph nodes for WASM to separate
// the WASM decoder from the internal details of TurboFan.
class WasmTrapHelper;
class WasmGraphBuilder {
 public:
  WasmGraphBuilder(Zone* z, JSGraph* g, wasm::FunctionSig* function_signature);

  Node** Buffer(size_t count) {
    if (count > cur_bufsize_) {
      size_t new_size = count + cur_bufsize_ + 5;
      cur_buffer_ =
          reinterpret_cast<Node**>(zone_->New(new_size * sizeof(Node*)));
      cur_bufsize_ = new_size;
    }
    return cur_buffer_;
  }

  //-----------------------------------------------------------------------
  // Operations independent of {control} or {effect}.
  //-----------------------------------------------------------------------
  Node* Error();
  Node* Start(unsigned params);
  Node* Param(unsigned index, wasm::LocalType type);
  Node* Loop(Node* entry);
  Node* Terminate(Node* effect, Node* control);
  Node* Merge(unsigned count, Node** controls);
  Node* Phi(wasm::LocalType type, unsigned count, Node** vals, Node* control);
  Node* EffectPhi(unsigned count, Node** effects, Node* control);
  Node* Int32Constant(int32_t value);
  Node* Int64Constant(int64_t value);
  Node* Float32Constant(float value);
  Node* Float64Constant(double value);
  Node* Constant(Handle<Object> value);
  Node* Binop(wasm::WasmOpcode opcode, Node* left, Node* right);
  Node* Unop(wasm::WasmOpcode opcode, Node* input);
  unsigned InputCount(Node* node);
  bool IsPhiWithMerge(Node* phi, Node* merge);
  void AppendToMerge(Node* merge, Node* from);
  void AppendToPhi(Node* merge, Node* phi, Node* from);

  //-----------------------------------------------------------------------
  // Operations that read and/or write {control} and {effect}.
  //-----------------------------------------------------------------------
  Node* Branch(Node* cond, Node** true_node, Node** false_node);
  Node* Switch(unsigned count, Node* key);
  Node* IfValue(int32_t value, Node* sw);
  Node* IfDefault(Node* sw);
  Node* Return(unsigned count, Node** vals);
  Node* ReturnVoid();
  Node* Unreachable();

  Node* CallDirect(uint32_t index, Node** args);
  Node* CallImport(uint32_t index, Node** args);
  Node* CallIndirect(uint32_t index, Node** args);
  void BuildJSToWasmWrapper(Handle<Code> wasm_code, wasm::FunctionSig* sig);
  void BuildWasmToJSWrapper(Handle<JSFunction> function,
                            wasm::FunctionSig* sig);
  Node* ToJS(Node* node, Node* context, wasm::LocalType type);
  Node* FromJS(Node* node, Node* context, wasm::LocalType type);
  Node* Invert(Node* node);
  Node* FunctionTable();

  //-----------------------------------------------------------------------
  // Operations that concern the linear memory.
  //-----------------------------------------------------------------------
  Node* MemSize(uint32_t offset);
  Node* LoadGlobal(uint32_t index);
  Node* StoreGlobal(uint32_t index, Node* val);
  Node* LoadMem(wasm::LocalType type, MachineType memtype, Node* index,
                uint32_t offset);
  Node* StoreMem(MachineType type, Node* index, uint32_t offset, Node* val);

  static void PrintDebugName(Node* node);

  Node* Control() { return *control_; }
  Node* Effect() { return *effect_; }

  void set_module(wasm::ModuleEnv* module) { this->module_ = module; }

  void set_control_ptr(Node** control) { this->control_ = control; }

  void set_effect_ptr(Node** effect) { this->effect_ = effect; }

  wasm::FunctionSig* GetFunctionSignature() { return function_signature_; }

  void Int64LoweringForTesting();

 private:
  static const int kDefaultBufferSize = 16;
  friend class WasmTrapHelper;

  Zone* zone_;
  JSGraph* jsgraph_;
  wasm::ModuleEnv* module_;
  Node* mem_buffer_;
  Node* mem_size_;
  Node* function_table_;
  Node** control_;
  Node** effect_;
  Node** cur_buffer_;
  size_t cur_bufsize_;
  Node* def_buffer_[kDefaultBufferSize];

  WasmTrapHelper* trap_;
  wasm::FunctionSig* function_signature_;

  // Internal helper methods.
  JSGraph* jsgraph() { return jsgraph_; }
  Graph* graph();

  Node* String(const char* string);
  Node* MemBuffer(uint32_t offset);
  void BoundsCheckMem(MachineType memtype, Node* index, uint32_t offset);

  Node* BuildCCall(MachineSignature* sig, Node** args);
  Node* BuildWasmCall(wasm::FunctionSig* sig, Node** args);
  Node* BuildF32Neg(Node* input);
  Node* BuildF64Neg(Node* input);
  Node* BuildF32CopySign(Node* left, Node* right);
  Node* BuildF64CopySign(Node* left, Node* right);
  Node* BuildF32Min(Node* left, Node* right);
  Node* BuildF32Max(Node* left, Node* right);
  Node* BuildF64Min(Node* left, Node* right);
  Node* BuildF64Max(Node* left, Node* right);
  Node* BuildI32SConvertF32(Node* input);
  Node* BuildI32SConvertF64(Node* input);
  Node* BuildI32UConvertF32(Node* input);
  Node* BuildI32UConvertF64(Node* input);
  Node* BuildI32Ctz(Node* input);
  Node* BuildI32Popcnt(Node* input);
  Node* BuildI64Ctz(Node* input);
  Node* BuildI64Popcnt(Node* input);
  Node* BuildRoundingInstruction(Node* input, ExternalReference ref,
                                 MachineType type);
  Node* BuildF32Trunc(Node* input);
  Node* BuildF32Floor(Node* input);
  Node* BuildF32Ceil(Node* input);
  Node* BuildF32NearestInt(Node* input);
  Node* BuildF64Trunc(Node* input);
  Node* BuildF64Floor(Node* input);
  Node* BuildF64Ceil(Node* input);
  Node* BuildF64NearestInt(Node* input);

  Node** Realloc(Node** buffer, size_t count) {
    Node** buf = Buffer(count);
    if (buf != buffer) memcpy(buf, buffer, count * sizeof(Node*));
    return buf;
  }
};
}  // namespace compiler
}  // namespace internal
}  // namespace v8

#endif  // V8_COMPILER_WASM_COMPILER_H_
