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

#ifndef V8_WASM_INTERPRETER_H_
#define V8_WASM_INTERPRETER_H_

#include "src/wasm/wasm-opcodes.h"
#include "src/zone-containers.h"

namespace v8 {
namespace base {
class AccountingAllocator;
}

namespace internal {
namespace wasm {

// forward declarations.
struct WasmFunction;
struct WasmModuleInstance;
class WasmInterpreterInternals;

typedef size_t pc_t;
typedef size_t sp_t;
typedef int32_t pcdiff_t;
typedef uint32_t spdiff_t;

const pc_t kInvalidPc = 0x80000000;

// Visible for testing. A {ControlTransfer} helps the interpreter figure out
// the target program counter and stack manipulations for a branch.
struct ControlTransfer {
  enum StackAction { kNoAction, kPopAndRepush, kPushVoid };
  pcdiff_t pcdiff;  // adjustment to the program counter (positive or negative).
  spdiff_t spdiff;  // number of elements to pop off the stack.
  StackAction action;  // action to perform on the stack.
};
typedef ZoneMap<pc_t, ControlTransfer> ControlTransferMap;

// Macro for defining union members.
#define FOREACH_UNION_MEMBER(V) \
  V(i32, kAstI32, int32_t)      \
  V(u32, kAstI32, uint32_t)     \
  V(i64, kAstI64, int64_t)      \
  V(u64, kAstI64, uint64_t)     \
  V(f32, kAstF32, float)        \
  V(f64, kAstF64, double)

// Representation of values within the interpreter.
struct WasmVal {
  LocalType type;
  union {
#define DECLARE_FIELD(field, localtype, ctype) ctype field;
    FOREACH_UNION_MEMBER(DECLARE_FIELD)
#undef DECLARE_FIELD
  } val;

  WasmVal() : type(kAstStmt) {}

#define DECLARE_CONSTRUCTOR(field, localtype, ctype) \
  explicit WasmVal(ctype v) : type(localtype) { val.field = v; }
  FOREACH_UNION_MEMBER(DECLARE_CONSTRUCTOR)
#undef DECLARE_CONSTRUCTOR

  template <typename T>
  T to() {
    UNREACHABLE();
  }
};

#define DECLARE_CAST(field, localtype, ctype) \
  template <>                                 \
  inline ctype WasmVal::to() {                \
    CHECK_EQ(localtype, type);                \
    return val.field;                         \
  }
FOREACH_UNION_MEMBER(DECLARE_CAST)
#undef DECLARE_CAST

template <>
inline void WasmVal::to() {
  CHECK_EQ(kAstStmt, type);
}

// Representation of frames within the interpreter.
class WasmFrame {
 public:
  const WasmFunction* function() const { return function_; }
  int pc() const { return pc_; }

 private:
  friend class WasmInterpreter;

  WasmFrame(const WasmFunction* function, int pc, int fp, int sp)
      : function_(function), pc_(pc), fp_(fp), sp_(sp) {}

  const WasmFunction* function_;
  int pc_;
  int fp_;
  int sp_;
};

// An interpreter capable of executing WASM.
class WasmInterpreter {
 public:
  // State machine for a Thread:
  //                       +---------------Run()-----------+
  //                       V                               |
  // STOPPED ---Run()-->  RUNNING  ------Pause()-----+-> PAUSED  <------+
  //                       | | |                    /      |            |
  //                       | | +---- Breakpoint ---+       +-- Step() --+
  //                       | |
  //                       | +------------ Trap --------------> TRAPPED
  //                       +------------- Finish -------------> FINISHED
  enum State { STOPPED, RUNNING, PAUSED, FINISHED, TRAPPED };

  // Representation of a thread in the interpreter.
  class Thread {
   public:
    // Execution control.
    virtual State state() = 0;
    virtual void PushFrame(const WasmFunction* function, WasmVal* args) = 0;
    virtual State Run() = 0;
    virtual State Step() = 0;
    virtual void Pause() = 0;
    virtual void Reset() = 0;
    virtual ~Thread() {}

    // Stack inspection and modification.
    virtual pc_t GetBreakpointPc() = 0;
    virtual int GetFrameCount() = 0;
    virtual const WasmFrame* GetFrame(int index) = 0;
    virtual WasmFrame* GetMutableFrame(int index) = 0;
    virtual WasmVal GetReturnValue() = 0;

    // Thread-specific breakpoints.
    bool SetBreakpoint(const WasmFunction* function, int pc, bool enabled);
    bool GetBreakpoint(const WasmFunction* function, int pc);
  };

  WasmInterpreter(WasmModuleInstance* instance,
                  base::AccountingAllocator* allocator);
  ~WasmInterpreter();

  //==========================================================================
  // Execution controls.
  //==========================================================================
  void Run();
  void Pause();

  // Set a breakpoint at {pc} in {function} to be {enabled}. Returns the
  // previous state of the breakpoint at {pc}.
  bool SetBreakpoint(const WasmFunction* function, pc_t pc, bool enabled);

  // Gets the current state of the breakpoint at {function}.
  bool GetBreakpoint(const WasmFunction* function, pc_t pc);

  // Enable or disable tracing for {function}. Return the previous state.
  bool SetTracing(const WasmFunction* function, bool enabled);

  //==========================================================================
  // Thread iteration and inspection.
  //==========================================================================
  int GetThreadCount();
  Thread* GetThread(int id);

  //==========================================================================
  // Stack frame inspection.
  //==========================================================================
  WasmVal GetLocalVal(const WasmFrame* frame, int index);
  WasmVal GetExprVal(const WasmFrame* frame, int pc);
  void SetLocalVal(WasmFrame* frame, int index, WasmVal val);
  void SetExprVal(WasmFrame* frame, int pc, WasmVal val);

  //==========================================================================
  // Memory access.
  //==========================================================================
  size_t GetMemorySize();
  WasmVal ReadMemory(size_t offset);
  void WriteMemory(size_t offset, WasmVal val);

  //==========================================================================
  // Testing functionality.
  //==========================================================================
  // Manually adds a function to this interpreter, returning the index of the
  // function.
  int AddFunctionForTesting(const WasmFunction* function);
  // Manually adds code to the interpreter for the given function.
  bool SetFunctionCodeForTesting(const WasmFunction* function,
                                 const byte* start, const byte* end);

  // Computes the control targets for the given bytecode as {pc offset, sp
  // offset}
  // pairs. Used internally in the interpreter, but exposed for testing.
  static ControlTransferMap ComputeControlTransfersForTesting(Zone* zone,
                                                              const byte* start,
                                                              const byte* end);

 private:
  Zone zone_;
  WasmInterpreterInternals* internals_;
};

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

#endif  // V8_WASM_INTERPRETER_H_
