// 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 #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; }; struct CatchControlTransferEntry : public ControlTransferEntry { int tag_index; int target_control_index; }; struct ControlTransferMap { explicit ControlTransferMap(Zone* zone) : map(zone), catch_map(zone) {} ZoneMap map; ZoneMap> catch_map; }; // 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 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 byte* start, const byte* end); private: Zone zone_; std::unique_ptr internals_; }; } // namespace wasm } // namespace internal } // namespace v8 #endif // V8_WASM_WASM_INTERPRETER_H_