blob: 4df373df46b429e5d3d8d77f50cd740196297e99 [file] [log] [blame]
// 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_