| Index: src/wasm/wasm-interpreter.h
|
| diff --git a/src/wasm/wasm-interpreter.h b/src/wasm/wasm-interpreter.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..a3bb318c8f0059a93c58e104acaf4d73396d6b09
|
| --- /dev/null
|
| +++ b/src/wasm/wasm-interpreter.h
|
| @@ -0,0 +1,206 @@
|
| +// 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;
|
| +
|
| +// 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 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, int pc, bool enabled);
|
| +
|
| + // Gets the current state of the breakpoint at {function}.
|
| + bool GetBreakpoint(const WasmFunction* function, int 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_
|
|
|