242df3a2ed
The plain "wasm fuzzer" (which takes the fuzzer input as the wasm wire bytes) was already running both the interpreter and compiled code, but it did not compare the results of both. This CL fixes this by reusing some logic that was already present in the fuzzers based on the {WasmCompileFuzzer} class. R=ahaas@chromium.org Bug: chromium:1113681, chromium:1112099 Change-Id: I9d407f66dfcba0eec90f050630b028edd5fae1d1 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2339624 Commit-Queue: Clemens Backes <clemensb@chromium.org> Reviewed-by: Andreas Haas <ahaas@chromium.org> Cr-Commit-Position: refs/heads/master@{#69310}
116 lines
3.9 KiB
C++
116 lines
3.9 KiB
C++
// 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:
|
|
// 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_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(WasmInterpreter);
|
|
};
|
|
|
|
} // namespace wasm
|
|
} // namespace internal
|
|
} // namespace v8
|
|
|
|
#endif // V8_WASM_WASM_INTERPRETER_H_
|