V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
wasm-interpreter.h
1 // 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_WASM_INTERPRETER_H_
6 #define V8_WASM_WASM_INTERPRETER_H_
7 
8 #include "src/wasm/wasm-opcodes.h"
9 #include "src/wasm/wasm-value.h"
10 #include "src/zone/zone-containers.h"
11 
12 namespace v8 {
13 
14 namespace internal {
15 class WasmInstanceObject;
16 
17 namespace wasm {
18 
19 // forward declarations.
20 struct ModuleWireBytes;
21 struct WasmFunction;
22 struct WasmModule;
23 class WasmInterpreterInternals;
24 
25 using pc_t = size_t;
26 using sp_t = size_t;
27 using pcdiff_t = int32_t;
28 using spdiff_t = uint32_t;
29 
30 constexpr pc_t kInvalidPc = 0x80000000;
31 
33  // Distance from the instruction to the label to jump to (forward, but can be
34  // negative).
35  pcdiff_t pc_diff;
36  // Delta by which to decrease the stack height.
37  spdiff_t sp_diff;
38  // Arity of the block we jump to.
39  uint32_t target_arity;
40 };
41 
43 
44 // Representation of frames within the interpreter.
45 //
46 // Layout of a frame:
47 // -----------------
48 // stack slot #N ‾\.
49 // ... | stack entries: GetStackHeight(); GetStackValue()
50 // stack slot #0 _/·
51 // local #L ‾\.
52 // ... | locals: GetLocalCount(); GetLocalValue()
53 // local #P+1 |
54 // param #P | ‾\.
55 // ... | | parameters: GetParameterCount(); GetLocalValue()
56 // param #0 _/· _/·
57 // -----------------
58 //
60  public:
61  const WasmFunction* function() const;
62  int pc() const;
63 
64  int GetParameterCount() const;
65  int GetLocalCount() const;
66  int GetStackHeight() const;
67  WasmValue GetLocalValue(int index) const;
68  WasmValue GetStackValue(int index) const;
69 
70  private:
71  friend class WasmInterpreter;
72  // Don't instante InterpretedFrames; they will be allocated as
73  // InterpretedFrameImpl in the interpreter implementation.
74  InterpretedFrame() = delete;
75  DISALLOW_COPY_AND_ASSIGN(InterpretedFrame);
76 };
77 
78 // Deleter struct to delete the underlying InterpretedFrameImpl without
79 // violating language specifications.
81  void operator()(InterpretedFrame* ptr);
82 };
83 
84 // An interpreter capable of executing WebAssembly.
85 class V8_EXPORT_PRIVATE WasmInterpreter {
86  public:
87  // State machine for a Thread:
88  // +---------Run()/Step()--------+
89  // V |
90  // STOPPED ---Run()--> RUNNING ------Pause()-----+-> PAUSED
91  // ^ | | | | /
92  // +- HandleException -+ | | +--- Breakpoint ---+
93  // | |
94  // | +---------- Trap --------------> TRAPPED
95  // +----------- Finish -------------> FINISHED
96  enum State { STOPPED, RUNNING, PAUSED, FINISHED, TRAPPED };
97 
98  // Tells a thread to pause after certain instructions.
99  enum BreakFlag : uint8_t {
100  None = 0,
101  AfterReturn = 1 << 0,
102  AfterCall = 1 << 1
103  };
104 
105  using FramePtr = std::unique_ptr<InterpretedFrame, InterpretedFrameDeleter>;
106 
107  // Representation of a thread in the interpreter.
108  class V8_EXPORT_PRIVATE Thread {
109  // Don't instante Threads; they will be allocated as ThreadImpl in the
110  // interpreter implementation.
111  Thread() = delete;
112 
113  public:
114  enum ExceptionHandlingResult { HANDLED, UNWOUND };
115 
116  // Execution control.
117  State state();
118  void InitFrame(const WasmFunction* function, WasmValue* args);
119  // Pass -1 as num_steps to run till completion, pause or breakpoint.
120  State Run(int num_steps = -1);
121  State Step() { return Run(1); }
122  void Pause();
123  void Reset();
124  // Handle the pending exception in the passed isolate. Unwind the stack
125  // accordingly. Return whether the exception was handled inside wasm.
126  ExceptionHandlingResult HandleException(Isolate* isolate);
127 
128  // Stack inspection and modification.
129  pc_t GetBreakpointPc();
130  // TODO(clemensh): Make this uint32_t.
131  int GetFrameCount();
132  // The InterpretedFrame is only valid as long as the Thread is paused.
133  FramePtr GetFrame(int index);
134  WasmValue GetReturnValue(int index = 0);
135  TrapReason GetTrapReason();
136 
137  // Returns true if the thread executed an instruction which may produce
138  // nondeterministic results, e.g. float div, float sqrt, and float mul,
139  // where the sign bit of a NaN is nondeterministic.
140  bool PossibleNondeterminism();
141 
142  // Returns the number of calls / function frames executed on this thread.
143  uint64_t NumInterpretedCalls();
144 
145  // Thread-specific breakpoints.
146  // TODO(wasm): Implement this once we support multiple threads.
147  // bool SetBreakpoint(const WasmFunction* function, int pc, bool enabled);
148  // bool GetBreakpoint(const WasmFunction* function, int pc);
149 
150  void AddBreakFlags(uint8_t flags);
151  void ClearBreakFlags();
152 
153  // Each thread can have multiple activations, each represented by a portion
154  // of the stack frames of this thread. StartActivation returns the id
155  // (counting from 0 up) of the started activation.
156  // Activations must be properly stacked, i.e. if FinishActivation is called,
157  // the given id must the the latest activation on the stack.
158  uint32_t NumActivations();
159  uint32_t StartActivation();
160  void FinishActivation(uint32_t activation_id);
161  // Return the frame base of the given activation, i.e. the number of frames
162  // when this activation was started.
163  uint32_t ActivationFrameBase(uint32_t activation_id);
164  };
165 
166  WasmInterpreter(Isolate* isolate, const WasmModule* module,
167  const ModuleWireBytes& wire_bytes,
168  Handle<WasmInstanceObject> instance);
169  ~WasmInterpreter();
170 
171  //==========================================================================
172  // Execution controls.
173  //==========================================================================
174  void Run();
175  void Pause();
176 
177  // Set a breakpoint at {pc} in {function} to be {enabled}. Returns the
178  // previous state of the breakpoint at {pc}.
179  bool SetBreakpoint(const WasmFunction* function, pc_t pc, bool enabled);
180 
181  // Gets the current state of the breakpoint at {function}.
182  bool GetBreakpoint(const WasmFunction* function, pc_t pc);
183 
184  // Enable or disable tracing for {function}. Return the previous state.
185  bool SetTracing(const WasmFunction* function, bool enabled);
186 
187  //==========================================================================
188  // Thread iteration and inspection.
189  //==========================================================================
190  int GetThreadCount();
191  Thread* GetThread(int id);
192 
193  //==========================================================================
194  // Testing functionality.
195  //==========================================================================
196  // Manually adds a function to this interpreter. The func_index of the
197  // function must match the current number of functions.
198  void AddFunctionForTesting(const WasmFunction* function);
199  // Manually adds code to the interpreter for the given function.
200  void SetFunctionCodeForTesting(const WasmFunction* function,
201  const byte* start, const byte* end);
202  void SetCallIndirectTestMode();
203 
204  // Computes the control transfers for the given bytecode. Used internally in
205  // the interpreter, but exposed for testing.
206  static ControlTransferMap ComputeControlTransfersForTesting(
207  Zone* zone, const WasmModule* module, const byte* start, const byte* end);
208 
209  private:
210  Zone zone_;
211  WasmInterpreterInternals* internals_;
212 };
213 
214 } // namespace wasm
215 } // namespace internal
216 } // namespace v8
217 
218 #endif // V8_WASM_WASM_INTERPRETER_H_
Definition: libplatform.h:13
Definition: v8.h:3134