Commit 1d0a5824 authored by Andreas Haas's avatar Andreas Haas Committed by Commit Bot

[wasm][cleanup] Use the normal production pipeline for the fuzzers

This CL removes unnecessary code duplication in the fuzzer code. Instead
of having special testing functions to compile and instantiate a
WebAssembly module, we now just call SyncCompile and SyncInstantiate.

This also fixed a problem when the fuzzer generated a GrowMemory
instruction.

BUG=v8:6474
R=clemensh@chromium.org

Change-Id: I5f2f23349b5866ea67be20a0826271791e1a013e
Reviewed-on: https://chromium-review.googlesource.com/529210
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45851}
parent 07b7d720
......@@ -146,7 +146,7 @@ class WasmInstanceObject : public JSObject {
DECLARE_OPTIONAL_ACCESSORS(instance_wrapper, WasmInstanceWrapper);
WasmModuleObject* module_object();
wasm::WasmModule* module();
V8_EXPORT_PRIVATE wasm::WasmModule* module();
// Get the debug info associated with the given wasm object.
// If no debug info exists yet, it is created automatically.
......@@ -557,8 +557,8 @@ class WasmDebugInfo : public FixedArray {
// Returns a pointer to the interpreter instantiated inside this
// WasmDebugInfo.
// Use for testing only.
static wasm::WasmInterpreter* SetupForTesting(Handle<WasmInstanceObject>,
wasm::WasmInstance*);
V8_EXPORT_PRIVATE static wasm::WasmInterpreter* SetupForTesting(
Handle<WasmInstanceObject>, wasm::WasmInstance*);
static bool IsDebugInfo(Object*);
static WasmDebugInfo* cast(Object*);
......
......@@ -105,48 +105,23 @@ int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start,
}
return RunWasmModuleForTesting(isolate, instance, 0, nullptr, origin);
}
int32_t InterpretWasmModule(Isolate* isolate, ErrorThrower* thrower,
const WasmModule* module,
const ModuleWireBytes& wire_bytes,
int function_index, WasmVal* args,
bool* possible_nondeterminism) {
int32_t InterpretWasmModule(Isolate* isolate,
Handle<WasmInstanceObject> instance,
ErrorThrower* thrower, int32_t function_index,
WasmVal* args, bool* possible_nondeterminism) {
// Don't execute more than 16k steps.
constexpr int kMaxNumSteps = 16 * 1024;
DCHECK_NOT_NULL(module);
Zone zone(isolate->allocator(), ZONE_NAME);
v8::internal::HandleScope scope(isolate);
if (module->import_table.size() > 0) {
thrower->CompileError("Not supported: module has imports.");
}
if (module->export_table.size() == 0) {
thrower->CompileError("Not supported: module has no exports.");
}
if (thrower->error()) return -1;
// The code verifies, we create an instance to run it in the interpreter.
WasmInstance instance(module);
instance.context = isolate->native_context();
instance.mem_size = GetMinModuleMemSize(module);
// TODO(ahaas): Move memory allocation to wasm-module.cc for better
// encapsulation.
instance.mem_start =
static_cast<byte*>(calloc(GetMinModuleMemSize(module), 1));
instance.globals_start = nullptr;
ModuleBytesEnv env(module, &instance, wire_bytes);
WasmInterpreter interpreter(isolate, env);
WasmInterpreter::Thread* thread = interpreter.GetThread(0);
WasmInterpreter* interpreter =
WasmDebugInfo::SetupForTesting(instance, nullptr);
WasmInterpreter::Thread* thread = interpreter->GetThread(0);
thread->Reset();
thread->InitFrame(&(module->functions[function_index]), args);
thread->InitFrame(&(instance->module()->functions[function_index]), args);
WasmInterpreter::State interpreter_result = thread->Run(kMaxNumSteps);
if (instance.mem_start) {
free(instance.mem_start);
}
*possible_nondeterminism = thread->PossibleNondeterminism();
if (interpreter_result == WasmInterpreter::FINISHED) {
WasmVal val = thread->GetReturnValue();
......@@ -205,6 +180,7 @@ int32_t CallWasmFunctionForTesting(Isolate* isolate, Handle<JSObject> instance,
void SetupIsolateForWasmModule(Isolate* isolate) {
WasmJs::Install(isolate);
}
} // namespace testing
} // namespace wasm
} // namespace internal
......
......@@ -45,11 +45,10 @@ int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start,
// Interprets the given module, starting at the function specified by
// {function_index}. The return type of the function has to be int32. The module
// should not have any imports or exports
int32_t InterpretWasmModule(Isolate* isolate, ErrorThrower* thrower,
const WasmModule* module,
const ModuleWireBytes& wire_bytes,
int function_index, WasmVal* args,
bool* may_produced_nan);
int32_t InterpretWasmModule(Isolate* isolate,
Handle<WasmInstanceObject> instance,
ErrorThrower* thrower, int32_t function_index,
WasmVal* args, bool* possible_nondeterminism);
// Compiles WasmModule bytes and return an instance of the compiled module.
const Handle<WasmInstanceObject> CompileInstantiateWasmModuleForTesting(
......@@ -62,6 +61,7 @@ int32_t RunWasmModuleForTesting(Isolate* isolate, Handle<JSObject> instance,
ModuleOrigin origin);
// Install function map, module symbol for testing
void SetupIsolateForWasmModule(Isolate* isolate);
} // namespace testing
} // namespace wasm
} // namespace internal
......
......@@ -121,13 +121,13 @@ int WasmExecutionFuzzer::FuzzWasmModule(
v8::internal::wasm::testing::SetupIsolateForWasmModule(i_isolate);
ErrorThrower interpreter_thrower(i_isolate, "Interpreter");
std::unique_ptr<const WasmModule> module(testing::DecodeWasmModuleForTesting(
i_isolate, &interpreter_thrower, buffer.begin(), buffer.end(),
ModuleOrigin::kWasmOrigin, true));
ModuleWireBytes wire_bytes(buffer.begin(), buffer.end());
MaybeHandle<WasmModuleObject> compiled_module =
SyncCompile(i_isolate, &interpreter_thrower, wire_bytes);
// Clear the flag so that the WebAssembly code is not printed twice.
FLAG_wasm_code_fuzzer_gen_test = false;
if (module == nullptr) {
if (compiled_module.is_null()) {
if (generate_test) {
OFStream os(stdout);
os << " ])" << std::endl;
......@@ -147,30 +147,32 @@ int WasmExecutionFuzzer::FuzzWasmModule(
os << "})();" << std::endl;
}
ModuleWireBytes wire_bytes(buffer.begin(), buffer.end());
int32_t result_interpreted;
bool possible_nondeterminism = false;
{
MaybeHandle<WasmInstanceObject> interpreter_instance = SyncInstantiate(
i_isolate, &interpreter_thrower, compiled_module.ToHandleChecked(),
MaybeHandle<JSReceiver>(), MaybeHandle<JSArrayBuffer>());
if (interpreter_thrower.error()) {
return 0;
}
result_interpreted = testing::InterpretWasmModule(
i_isolate, &interpreter_thrower, module.get(), wire_bytes, 0,
interpreter_args.get(), &possible_nondeterminism);
i_isolate, interpreter_instance.ToHandleChecked(), &interpreter_thrower,
0, interpreter_args.get(), &possible_nondeterminism);
}
ErrorThrower compiler_thrower(i_isolate, "Compiler");
Handle<JSObject> instance = testing::InstantiateModuleForTesting(
i_isolate, &compiler_thrower, module.get(), wire_bytes);
// Restore the flag.
FLAG_wasm_code_fuzzer_gen_test = generate_test;
if (!interpreter_thrower.error()) {
CHECK(!instance.is_null());
} else {
return 0;
}
int32_t result_compiled;
{
ErrorThrower compiler_thrower(i_isolate, "Compiler");
MaybeHandle<WasmInstanceObject> compiled_instance = SyncInstantiate(
i_isolate, &compiler_thrower, compiled_module.ToHandleChecked(),
MaybeHandle<JSReceiver>(), MaybeHandle<JSArrayBuffer>());
DCHECK(!compiler_thrower.error());
result_compiled = testing::CallWasmFunctionForTesting(
i_isolate, instance, &compiler_thrower, "main", num_args,
compiler_args.get(), ModuleOrigin::kWasmOrigin);
i_isolate, compiled_instance.ToHandleChecked(), &compiler_thrower,
"main", num_args, compiler_args.get(), ModuleOrigin::kWasmOrigin);
}
// The WebAssembly spec allows the sign bit of NaN to be non-deterministic.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment