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 <memory> 9 10 #include "src/wasm/wasm-opcodes.h" 11 #include "src/wasm/wasm-value.h" 12 #include "src/zone/zone-containers.h" 13 14 namespace v8 { 15 16 namespace internal { 17 class WasmInstanceObject; 18 19 namespace wasm { 20 21 // Forward declarations. 22 struct ModuleWireBytes; 23 struct WasmFunction; 24 struct WasmModule; 25 class WasmInterpreterInternals; 26 27 using pc_t = size_t; 28 using sp_t = size_t; 29 using pcdiff_t = int32_t; 30 using spdiff_t = uint32_t; 31 32 struct ControlTransferEntry { 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 42 struct CatchControlTransferEntry : public ControlTransferEntry { 43 int tag_index; 44 int target_control_index; 45 }; 46 47 struct ControlTransferMap { ControlTransferMapControlTransferMap48 explicit ControlTransferMap(Zone* zone) : map(zone), catch_map(zone) {} 49 50 ZoneMap<pc_t, ControlTransferEntry> map; 51 ZoneMap<pc_t, ZoneVector<CatchControlTransferEntry>> catch_map; 52 }; 53 54 // An interpreter capable of executing WebAssembly. 55 class WasmInterpreter { 56 public: 57 WasmInterpreter(const WasmInterpreter&) = delete; 58 WasmInterpreter& operator=(const WasmInterpreter&) = delete; 59 60 // State machine for the interpreter: 61 // +----------------------------------------------------------+ 62 // | +--------Run()/Step()---------+ | 63 // V V | | 64 // STOPPED ---Run()--> RUNNING ------Pause()-----+-> PAUSED <--+ 65 // ^ | | | | / 66 // +--- Exception ---+ | | +--- Breakpoint ---+ 67 // | +---------- Trap --------------> TRAPPED 68 // +----------- Finish -------------> FINISHED 69 enum State { STOPPED, RUNNING, PAUSED, FINISHED, TRAPPED }; 70 71 enum ExceptionHandlingResult { HANDLED, UNWOUND }; 72 73 WasmInterpreter(Isolate* isolate, const WasmModule* module, 74 const ModuleWireBytes& wire_bytes, 75 Handle<WasmInstanceObject> instance); 76 77 ~WasmInterpreter(); 78 79 //========================================================================== 80 // Execution controls. 81 //========================================================================== 82 State state() const; 83 void InitFrame(const WasmFunction* function, WasmValue* args); 84 // Pass -1 as num_steps to run till completion, pause or breakpoint. 85 State Run(int num_steps = -1); Step()86 State Step() { return Run(1); } 87 void Pause(); 88 void Reset(); 89 90 // Stack inspection and modification. 91 WasmValue GetReturnValue(int index = 0) const; 92 TrapReason GetTrapReason() const; 93 94 // Returns true if the thread executed an instruction which may produce 95 // nondeterministic results, e.g. float div, float sqrt, and float mul, 96 // where the sign bit of a NaN is nondeterministic. 97 bool PossibleNondeterminism() const; 98 99 // Returns the number of calls / function frames executed on this thread. 100 uint64_t NumInterpretedCalls() const; 101 102 //========================================================================== 103 // Testing functionality. 104 //========================================================================== 105 // Manually adds a function to this interpreter. The func_index of the 106 // function must match the current number of functions. 107 void AddFunctionForTesting(const WasmFunction* function); 108 // Manually adds code to the interpreter for the given function. 109 void SetFunctionCodeForTesting(const WasmFunction* function, 110 const byte* start, const byte* end); 111 112 // Computes the control transfers for the given bytecode. Used internally in 113 // the interpreter, but exposed for testing. 114 static ControlTransferMap ComputeControlTransfersForTesting( 115 Zone* zone, const WasmModule* module, const byte* start, const byte* end); 116 117 private: 118 Zone zone_; 119 std::unique_ptr<WasmInterpreterInternals> internals_; 120 }; 121 122 } // namespace wasm 123 } // namespace internal 124 } // namespace v8 125 126 #endif // V8_WASM_WASM_INTERPRETER_H_ 127