| // 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_WASM_INTERPRETER_H_ |
| #define V8_WASM_WASM_INTERPRETER_H_ |
| |
| #include <memory> |
| |
| #include "src/wasm/wasm-opcodes.h" |
| #include "src/wasm/wasm-value.h" |
| #include "src/zone/zone-containers.h" |
| |
| namespace v8 { |
| |
| namespace internal { |
| class WasmInstanceObject; |
| |
| namespace wasm { |
| |
| // Forward declarations. |
| struct ModuleWireBytes; |
| struct WasmFunction; |
| struct WasmModule; |
| class WasmInterpreterInternals; |
| |
| using pc_t = size_t; |
| using sp_t = size_t; |
| using pcdiff_t = int32_t; |
| using spdiff_t = uint32_t; |
| |
| struct ControlTransferEntry { |
| // Distance from the instruction to the label to jump to (forward, but can be |
| // negative). |
| pcdiff_t pc_diff; |
| // Delta by which to decrease the stack height. |
| spdiff_t sp_diff; |
| // Arity of the block we jump to. |
| uint32_t target_arity; |
| }; |
| |
| using ControlTransferMap = ZoneMap<pc_t, ControlTransferEntry>; |
| |
| // An interpreter capable of executing WebAssembly. |
| class WasmInterpreter { |
| public: |
| WasmInterpreter(const WasmInterpreter&) = delete; |
| WasmInterpreter& operator=(const WasmInterpreter&) = delete; |
| |
| // State machine for the interpreter: |
| // +----------------------------------------------------------+ |
| // | +--------Run()/Step()---------+ | |
| // V V | | |
| // STOPPED ---Run()--> RUNNING ------Pause()-----+-> PAUSED <--+ |
| // ^ | | | | / |
| // +--- Exception ---+ | | +--- Breakpoint ---+ |
| // | +---------- Trap --------------> TRAPPED |
| // +----------- Finish -------------> FINISHED |
| enum State { STOPPED, RUNNING, PAUSED, FINISHED, TRAPPED }; |
| |
| enum ExceptionHandlingResult { HANDLED, UNWOUND }; |
| |
| WasmInterpreter(Isolate* isolate, const WasmModule* module, |
| const ModuleWireBytes& wire_bytes, |
| Handle<WasmInstanceObject> instance); |
| |
| ~WasmInterpreter(); |
| |
| //========================================================================== |
| // Execution controls. |
| //========================================================================== |
| State state() const; |
| void InitFrame(const WasmFunction* function, WasmValue* args); |
| // Pass -1 as num_steps to run till completion, pause or breakpoint. |
| State Run(int num_steps = -1); |
| State Step() { return Run(1); } |
| void Pause(); |
| void Reset(); |
| |
| // Stack inspection and modification. |
| WasmValue GetReturnValue(int index = 0) const; |
| TrapReason GetTrapReason() const; |
| |
| // Returns true if the thread executed an instruction which may produce |
| // nondeterministic results, e.g. float div, float sqrt, and float mul, |
| // where the sign bit of a NaN is nondeterministic. |
| bool PossibleNondeterminism() const; |
| |
| // Returns the number of calls / function frames executed on this thread. |
| uint64_t NumInterpretedCalls() const; |
| |
| //========================================================================== |
| // Testing functionality. |
| //========================================================================== |
| // Manually adds a function to this interpreter. The func_index of the |
| // function must match the current number of functions. |
| void AddFunctionForTesting(const WasmFunction* function); |
| // Manually adds code to the interpreter for the given function. |
| void SetFunctionCodeForTesting(const WasmFunction* function, |
| const byte* start, const byte* end); |
| |
| // Computes the control transfers for the given bytecode. Used internally in |
| // the interpreter, but exposed for testing. |
| static ControlTransferMap ComputeControlTransfersForTesting( |
| Zone* zone, const WasmModule* module, const byte* start, const byte* end); |
| |
| private: |
| Zone zone_; |
| std::unique_ptr<WasmInterpreterInternals> internals_; |
| }; |
| |
| } // namespace wasm |
| } // namespace internal |
| } // namespace v8 |
| |
| #endif // V8_WASM_WASM_INTERPRETER_H_ |