blob: b61e092e23b691dedfd1e17adec13a06f21877a9 [file] [log] [blame]
Ben Murdoch13e2dad2016-09-16 13:49:30 +01001// Copyright 2016 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_WASM_INTERPRETER_H_
6#define V8_WASM_INTERPRETER_H_
7
8#include "src/wasm/wasm-opcodes.h"
Ben Murdochf3b273f2017-01-17 12:11:28 +00009#include "src/zone/zone-containers.h"
Ben Murdoch13e2dad2016-09-16 13:49:30 +010010
11namespace v8 {
12namespace base {
13class AccountingAllocator;
14}
15
16namespace internal {
17namespace wasm {
18
19// forward declarations.
20struct WasmFunction;
21struct WasmModuleInstance;
22class WasmInterpreterInternals;
23
24typedef size_t pc_t;
25typedef size_t sp_t;
26typedef int32_t pcdiff_t;
27typedef uint32_t spdiff_t;
28
29const pc_t kInvalidPc = 0x80000000;
30
Ben Murdochf3b273f2017-01-17 12:11:28 +000031typedef ZoneMap<pc_t, pcdiff_t> ControlTransferMap;
Ben Murdoch13e2dad2016-09-16 13:49:30 +010032
33// Macro for defining union members.
34#define FOREACH_UNION_MEMBER(V) \
35 V(i32, kAstI32, int32_t) \
36 V(u32, kAstI32, uint32_t) \
37 V(i64, kAstI64, int64_t) \
38 V(u64, kAstI64, uint64_t) \
39 V(f32, kAstF32, float) \
40 V(f64, kAstF64, double)
41
42// Representation of values within the interpreter.
43struct WasmVal {
44 LocalType type;
45 union {
46#define DECLARE_FIELD(field, localtype, ctype) ctype field;
47 FOREACH_UNION_MEMBER(DECLARE_FIELD)
48#undef DECLARE_FIELD
49 } val;
50
51 WasmVal() : type(kAstStmt) {}
52
53#define DECLARE_CONSTRUCTOR(field, localtype, ctype) \
54 explicit WasmVal(ctype v) : type(localtype) { val.field = v; }
55 FOREACH_UNION_MEMBER(DECLARE_CONSTRUCTOR)
56#undef DECLARE_CONSTRUCTOR
57
58 template <typename T>
59 T to() {
60 UNREACHABLE();
61 }
62};
63
64#define DECLARE_CAST(field, localtype, ctype) \
65 template <> \
66 inline ctype WasmVal::to() { \
67 CHECK_EQ(localtype, type); \
68 return val.field; \
69 }
70FOREACH_UNION_MEMBER(DECLARE_CAST)
71#undef DECLARE_CAST
72
73template <>
74inline void WasmVal::to() {
75 CHECK_EQ(kAstStmt, type);
76}
77
78// Representation of frames within the interpreter.
79class WasmFrame {
80 public:
81 const WasmFunction* function() const { return function_; }
82 int pc() const { return pc_; }
83
84 private:
85 friend class WasmInterpreter;
86
87 WasmFrame(const WasmFunction* function, int pc, int fp, int sp)
88 : function_(function), pc_(pc), fp_(fp), sp_(sp) {}
89
90 const WasmFunction* function_;
91 int pc_;
92 int fp_;
93 int sp_;
94};
95
96// An interpreter capable of executing WASM.
Ben Murdochf3b273f2017-01-17 12:11:28 +000097class V8_EXPORT_PRIVATE WasmInterpreter {
Ben Murdoch13e2dad2016-09-16 13:49:30 +010098 public:
99 // State machine for a Thread:
100 // +---------------Run()-----------+
101 // V |
102 // STOPPED ---Run()--> RUNNING ------Pause()-----+-> PAUSED <------+
103 // | | | / | |
104 // | | +---- Breakpoint ---+ +-- Step() --+
105 // | |
106 // | +------------ Trap --------------> TRAPPED
107 // +------------- Finish -------------> FINISHED
108 enum State { STOPPED, RUNNING, PAUSED, FINISHED, TRAPPED };
109
110 // Representation of a thread in the interpreter.
111 class Thread {
112 public:
113 // Execution control.
114 virtual State state() = 0;
115 virtual void PushFrame(const WasmFunction* function, WasmVal* args) = 0;
116 virtual State Run() = 0;
117 virtual State Step() = 0;
118 virtual void Pause() = 0;
119 virtual void Reset() = 0;
120 virtual ~Thread() {}
121
122 // Stack inspection and modification.
123 virtual pc_t GetBreakpointPc() = 0;
124 virtual int GetFrameCount() = 0;
125 virtual const WasmFrame* GetFrame(int index) = 0;
126 virtual WasmFrame* GetMutableFrame(int index) = 0;
Ben Murdochf3b273f2017-01-17 12:11:28 +0000127 virtual WasmVal GetReturnValue(int index = 0) = 0;
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100128
129 // Thread-specific breakpoints.
130 bool SetBreakpoint(const WasmFunction* function, int pc, bool enabled);
131 bool GetBreakpoint(const WasmFunction* function, int pc);
132 };
133
Ben Murdochf3b273f2017-01-17 12:11:28 +0000134 WasmInterpreter(WasmModuleInstance* instance, AccountingAllocator* allocator);
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100135 ~WasmInterpreter();
136
137 //==========================================================================
138 // Execution controls.
139 //==========================================================================
140 void Run();
141 void Pause();
142
143 // Set a breakpoint at {pc} in {function} to be {enabled}. Returns the
144 // previous state of the breakpoint at {pc}.
145 bool SetBreakpoint(const WasmFunction* function, pc_t pc, bool enabled);
146
147 // Gets the current state of the breakpoint at {function}.
148 bool GetBreakpoint(const WasmFunction* function, pc_t pc);
149
150 // Enable or disable tracing for {function}. Return the previous state.
151 bool SetTracing(const WasmFunction* function, bool enabled);
152
153 //==========================================================================
154 // Thread iteration and inspection.
155 //==========================================================================
156 int GetThreadCount();
157 Thread* GetThread(int id);
158
159 //==========================================================================
160 // Stack frame inspection.
161 //==========================================================================
162 WasmVal GetLocalVal(const WasmFrame* frame, int index);
163 WasmVal GetExprVal(const WasmFrame* frame, int pc);
164 void SetLocalVal(WasmFrame* frame, int index, WasmVal val);
165 void SetExprVal(WasmFrame* frame, int pc, WasmVal val);
166
167 //==========================================================================
168 // Memory access.
169 //==========================================================================
170 size_t GetMemorySize();
171 WasmVal ReadMemory(size_t offset);
172 void WriteMemory(size_t offset, WasmVal val);
173
174 //==========================================================================
175 // Testing functionality.
176 //==========================================================================
177 // Manually adds a function to this interpreter, returning the index of the
178 // function.
179 int AddFunctionForTesting(const WasmFunction* function);
180 // Manually adds code to the interpreter for the given function.
181 bool SetFunctionCodeForTesting(const WasmFunction* function,
182 const byte* start, const byte* end);
183
Ben Murdochf3b273f2017-01-17 12:11:28 +0000184 // Computes the control transfers for the given bytecode. Used internally in
185 // the interpreter, but exposed for testing.
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100186 static ControlTransferMap ComputeControlTransfersForTesting(Zone* zone,
187 const byte* start,
188 const byte* end);
189
190 private:
191 Zone zone_;
192 WasmInterpreterInternals* internals_;
193};
194
195} // namespace wasm
196} // namespace internal
197} // namespace v8
198
199#endif // V8_WASM_INTERPRETER_H_