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_ |