// 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_WASM_WASM_MODULE_BUILDER_H_
#define V8_WASM_WASM_MODULE_BUILDER_H_

#include "src/signature.h"
#include "src/zone/zone-containers.h"

#include "src/wasm/leb-helper.h"
#include "src/wasm/wasm-macro-gen.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-opcodes.h"
#include "src/wasm/wasm-result.h"

namespace v8 {
namespace internal {
namespace wasm {

class ZoneBuffer : public ZoneObject {
 public:
  static const uint32_t kInitialSize = 4096;
  explicit ZoneBuffer(Zone* zone, size_t initial = kInitialSize)
      : zone_(zone), buffer_(reinterpret_cast<byte*>(zone->New(initial))) {
    pos_ = buffer_;
    end_ = buffer_ + initial;
  }

  void write_u8(uint8_t x) {
    EnsureSpace(1);
    *(pos_++) = x;
  }

  void write_u16(uint16_t x) {
    EnsureSpace(2);
    WriteLittleEndianValue<uint16_t>(pos_, x);
    pos_ += 2;
  }

  void write_u32(uint32_t x) {
    EnsureSpace(4);
    WriteLittleEndianValue<uint32_t>(pos_, x);
    pos_ += 4;
  }

  void write_u32v(uint32_t val) {
    EnsureSpace(kMaxVarInt32Size);
    LEBHelper::write_u32v(&pos_, val);
  }

  void write_size(size_t val) {
    EnsureSpace(kMaxVarInt32Size);
    DCHECK_EQ(val, static_cast<uint32_t>(val));
    LEBHelper::write_u32v(&pos_, static_cast<uint32_t>(val));
  }

  void write(const byte* data, size_t size) {
    EnsureSpace(size);
    memcpy(pos_, data, size);
    pos_ += size;
  }

  size_t reserve_u32v() {
    size_t off = offset();
    EnsureSpace(kMaxVarInt32Size);
    pos_ += kMaxVarInt32Size;
    return off;
  }

  // Patch a (padded) u32v at the given offset to be the given value.
  void patch_u32v(size_t offset, uint32_t val) {
    byte* ptr = buffer_ + offset;
    for (size_t pos = 0; pos != kPaddedVarInt32Size; ++pos) {
      uint32_t next = val >> 7;
      byte out = static_cast<byte>(val & 0x7f);
      if (pos != kPaddedVarInt32Size - 1) {
        *(ptr++) = 0x80 | out;
        val = next;
      } else {
        *(ptr++) = out;
      }
    }
  }

  size_t offset() { return static_cast<size_t>(pos_ - buffer_); }
  size_t size() { return static_cast<size_t>(pos_ - buffer_); }
  const byte* begin() { return buffer_; }
  const byte* end() { return pos_; }

  void EnsureSpace(size_t size) {
    if ((pos_ + size) > end_) {
      size_t new_size = 4096 + size + (end_ - buffer_) * 3;
      byte* new_buffer = reinterpret_cast<byte*>(zone_->New(new_size));
      memcpy(new_buffer, buffer_, (pos_ - buffer_));
      pos_ = new_buffer + (pos_ - buffer_);
      buffer_ = new_buffer;
      end_ = new_buffer + new_size;
    }
    DCHECK(pos_ + size <= end_);
  }

  byte** pos_ptr() { return &pos_; }

 private:
  Zone* zone_;
  byte* buffer_;
  byte* pos_;
  byte* end_;
};

class WasmModuleBuilder;

class V8_EXPORT_PRIVATE WasmFunctionBuilder : public ZoneObject {
 public:
  // Building methods.
  void SetSignature(FunctionSig* sig);
  uint32_t AddLocal(LocalType type);
  void EmitVarInt(uint32_t val);
  void EmitCode(const byte* code, uint32_t code_size);
  void Emit(WasmOpcode opcode);
  void EmitGetLocal(uint32_t index);
  void EmitSetLocal(uint32_t index);
  void EmitTeeLocal(uint32_t index);
  void EmitI32Const(int32_t val);
  void EmitWithU8(WasmOpcode opcode, const byte immediate);
  void EmitWithU8U8(WasmOpcode opcode, const byte imm1, const byte imm2);
  void EmitWithVarInt(WasmOpcode opcode, uint32_t immediate);
  void EmitDirectCallIndex(uint32_t index);
  void SetExported();
  void SetName(const char* name, int name_length);

  void WriteSignature(ZoneBuffer& buffer) const;
  void WriteExport(ZoneBuffer& buffer) const;
  void WriteBody(ZoneBuffer& buffer) const;

  bool exported() { return exported_; }
  uint32_t func_index() { return func_index_; }
  FunctionSig* signature();

 private:
  explicit WasmFunctionBuilder(WasmModuleBuilder* builder);
  friend class WasmModuleBuilder;
  friend class WasmTemporary;

  struct DirectCallIndex {
    size_t offset;
    uint32_t direct_index;
  };

  WasmModuleBuilder* builder_;
  LocalDeclEncoder locals_;
  uint32_t signature_index_;
  bool exported_;
  uint32_t func_index_;
  ZoneVector<uint8_t> body_;
  ZoneVector<char> name_;
  ZoneVector<uint32_t> i32_temps_;
  ZoneVector<uint32_t> i64_temps_;
  ZoneVector<uint32_t> f32_temps_;
  ZoneVector<uint32_t> f64_temps_;
  ZoneVector<DirectCallIndex> direct_calls_;
};

class WasmTemporary {
 public:
  WasmTemporary(WasmFunctionBuilder* builder, LocalType type) {
    switch (type) {
      case kAstI32:
        temporary_ = &builder->i32_temps_;
        break;
      case kAstI64:
        temporary_ = &builder->i64_temps_;
        break;
      case kAstF32:
        temporary_ = &builder->f32_temps_;
        break;
      case kAstF64:
        temporary_ = &builder->f64_temps_;
        break;
      default:
        UNREACHABLE();
        temporary_ = nullptr;
    }
    if (temporary_->size() == 0) {
      // Allocate a new temporary.
      index_ = builder->AddLocal(type);
    } else {
      // Reuse a previous temporary.
      index_ = temporary_->back();
      temporary_->pop_back();
    }
  }
  ~WasmTemporary() {
    temporary_->push_back(index_);  // return the temporary to the list.
  }
  uint32_t index() { return index_; }

 private:
  ZoneVector<uint32_t>* temporary_;
  uint32_t index_;
};

class V8_EXPORT_PRIVATE WasmModuleBuilder : public ZoneObject {
 public:
  explicit WasmModuleBuilder(Zone* zone);

  // Building methods.
  uint32_t AddImport(const char* name, int name_length, FunctionSig* sig);
  void SetImportName(uint32_t index, const char* name, int name_length) {
    imports_[index].name = name;
    imports_[index].name_length = name_length;
  }
  WasmFunctionBuilder* AddFunction(FunctionSig* sig = nullptr);
  uint32_t AddGlobal(LocalType type, bool exported, bool mutability = true);
  void AddDataSegment(const byte* data, uint32_t size, uint32_t dest);
  uint32_t AddSignature(FunctionSig* sig);
  void AddIndirectFunction(uint32_t index);
  void MarkStartFunction(WasmFunctionBuilder* builder);

  // Writing methods.
  void WriteTo(ZoneBuffer& buffer) const;

  struct CompareFunctionSigs {
    bool operator()(FunctionSig* a, FunctionSig* b) const;
  };
  typedef ZoneMap<FunctionSig*, uint32_t, CompareFunctionSigs> SignatureMap;

  Zone* zone() { return zone_; }

  FunctionSig* GetSignature(uint32_t index) { return signatures_[index]; }

 private:
  struct WasmFunctionImport {
    uint32_t sig_index;
    const char* name;
    int name_length;
  };

  struct WasmGlobal {
    LocalType type;
    bool exported;
    bool mutability;
  };

  struct WasmDataSegment {
    ZoneVector<byte> data;
    uint32_t dest;
  };

  friend class WasmFunctionBuilder;
  Zone* zone_;
  ZoneVector<FunctionSig*> signatures_;
  ZoneVector<WasmFunctionImport> imports_;
  ZoneVector<WasmFunctionBuilder*> functions_;
  ZoneVector<WasmDataSegment> data_segments_;
  ZoneVector<uint32_t> indirect_functions_;
  ZoneVector<WasmGlobal> globals_;
  SignatureMap signature_map_;
  int start_function_index_;
};

inline FunctionSig* WasmFunctionBuilder::signature() {
  return builder_->signatures_[signature_index_];
}

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

#endif  // V8_WASM_WASM_MODULE_BUILDER_H_
