2016-05-25 08:32:37 +00:00
|
|
|
// 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.
|
|
|
|
|
2018-02-02 12:05:19 +00:00
|
|
|
#ifndef V8_WASM_WASM_INTERPRETER_H_
|
|
|
|
#define V8_WASM_WASM_INTERPRETER_H_
|
2016-05-25 08:32:37 +00:00
|
|
|
|
2019-09-13 16:11:40 +00:00
|
|
|
#include <memory>
|
|
|
|
|
2016-05-25 08:32:37 +00:00
|
|
|
#include "src/wasm/wasm-opcodes.h"
|
2017-07-14 13:49:01 +00:00
|
|
|
#include "src/wasm/wasm-value.h"
|
2016-09-20 16:07:25 +00:00
|
|
|
#include "src/zone/zone-containers.h"
|
2016-05-25 08:32:37 +00:00
|
|
|
|
|
|
|
namespace v8 {
|
|
|
|
|
|
|
|
namespace internal {
|
2017-03-23 09:46:16 +00:00
|
|
|
class WasmInstanceObject;
|
|
|
|
|
2016-05-25 08:32:37 +00:00
|
|
|
namespace wasm {
|
|
|
|
|
2019-03-12 11:00:28 +00:00
|
|
|
// Forward declarations.
|
2017-08-07 17:17:06 +00:00
|
|
|
struct ModuleWireBytes;
|
2016-05-25 08:32:37 +00:00
|
|
|
struct WasmFunction;
|
2017-04-25 09:43:39 +00:00
|
|
|
struct WasmModule;
|
2016-05-25 08:32:37 +00:00
|
|
|
class WasmInterpreterInternals;
|
|
|
|
|
2017-04-25 09:43:39 +00:00
|
|
|
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;
|
|
|
|
};
|
2016-05-30 10:02:34 +00:00
|
|
|
|
2017-04-25 09:43:39 +00:00
|
|
|
using ControlTransferMap = ZoneMap<pc_t, ControlTransferEntry>;
|
2016-05-25 08:32:37 +00:00
|
|
|
|
2017-06-09 12:21:52 +00:00
|
|
|
// An interpreter capable of executing WebAssembly.
|
2020-06-23 07:48:53 +00:00
|
|
|
class WasmInterpreter {
|
2016-05-25 08:32:37 +00:00
|
|
|
public:
|
2020-06-05 11:05:04 +00:00
|
|
|
// State machine for the interpreter:
|
2019-02-07 10:02:06 +00:00
|
|
|
// +----------------------------------------------------------+
|
|
|
|
// | +--------Run()/Step()---------+ |
|
|
|
|
// V V | |
|
|
|
|
// STOPPED ---Run()--> RUNNING ------Pause()-----+-> PAUSED <--+
|
2020-06-25 09:39:59 +00:00
|
|
|
// ^ | | | | /
|
|
|
|
// +--- Exception ---+ | | +--- Breakpoint ---+
|
|
|
|
// | +---------- Trap --------------> TRAPPED
|
2017-03-20 12:53:01 +00:00
|
|
|
// +----------- Finish -------------> FINISHED
|
2016-05-25 08:32:37 +00:00
|
|
|
enum State { STOPPED, RUNNING, PAUSED, FINISHED, TRAPPED };
|
|
|
|
|
2020-06-05 11:05:04 +00:00
|
|
|
enum ExceptionHandlingResult { HANDLED, UNWOUND };
|
2016-05-25 08:32:37 +00:00
|
|
|
|
2017-08-07 17:17:06 +00:00
|
|
|
WasmInterpreter(Isolate* isolate, const WasmModule* module,
|
2018-04-06 10:18:18 +00:00
|
|
|
const ModuleWireBytes& wire_bytes,
|
|
|
|
Handle<WasmInstanceObject> instance);
|
2019-09-17 12:31:28 +00:00
|
|
|
|
2016-05-25 08:32:37 +00:00
|
|
|
~WasmInterpreter();
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
// Execution controls.
|
|
|
|
//==========================================================================
|
2020-06-05 11:05:04 +00:00
|
|
|
State state();
|
|
|
|
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); }
|
2016-05-25 08:32:37 +00:00
|
|
|
void Pause();
|
2020-06-05 11:05:04 +00:00
|
|
|
void Reset();
|
2016-05-25 08:32:37 +00:00
|
|
|
|
2020-06-05 11:05:04 +00:00
|
|
|
// Stack inspection and modification.
|
|
|
|
WasmValue GetReturnValue(int index = 0);
|
|
|
|
TrapReason GetTrapReason();
|
|
|
|
|
|
|
|
// 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();
|
|
|
|
|
|
|
|
// Returns the number of calls / function frames executed on this thread.
|
|
|
|
uint64_t NumInterpretedCalls();
|
2016-05-25 08:32:37 +00:00
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
// Testing functionality.
|
|
|
|
//==========================================================================
|
2017-03-14 15:54:43 +00:00
|
|
|
// 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);
|
2016-05-25 08:32:37 +00:00
|
|
|
// Manually adds code to the interpreter for the given function.
|
2017-03-14 15:54:43 +00:00
|
|
|
void SetFunctionCodeForTesting(const WasmFunction* function,
|
2016-05-25 08:32:37 +00:00
|
|
|
const byte* start, const byte* end);
|
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
// Computes the control transfers for the given bytecode. Used internally in
|
|
|
|
// the interpreter, but exposed for testing.
|
2017-04-25 09:43:39 +00:00
|
|
|
static ControlTransferMap ComputeControlTransfersForTesting(
|
|
|
|
Zone* zone, const WasmModule* module, const byte* start, const byte* end);
|
2016-05-25 08:32:37 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
Zone zone_;
|
2019-09-17 12:31:28 +00:00
|
|
|
std::unique_ptr<WasmInterpreterInternals> internals_;
|
2019-10-21 13:09:19 +00:00
|
|
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(WasmInterpreter);
|
2016-05-25 08:32:37 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace wasm
|
|
|
|
} // namespace internal
|
|
|
|
} // namespace v8
|
|
|
|
|
2018-02-02 12:05:19 +00:00
|
|
|
#endif // V8_WASM_WASM_INTERPRETER_H_
|