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 { ...@@ -146,7 +146,7 @@ class WasmInstanceObject : public JSObject {
DECLARE_OPTIONAL_ACCESSORS(instance_wrapper, WasmInstanceWrapper); DECLARE_OPTIONAL_ACCESSORS(instance_wrapper, WasmInstanceWrapper);
WasmModuleObject* module_object(); WasmModuleObject* module_object();
wasm::WasmModule* module(); V8_EXPORT_PRIVATE wasm::WasmModule* module();
// Get the debug info associated with the given wasm object. // Get the debug info associated with the given wasm object.
// If no debug info exists yet, it is created automatically. // If no debug info exists yet, it is created automatically.
...@@ -557,8 +557,8 @@ class WasmDebugInfo : public FixedArray { ...@@ -557,8 +557,8 @@ class WasmDebugInfo : public FixedArray {
// Returns a pointer to the interpreter instantiated inside this // Returns a pointer to the interpreter instantiated inside this
// WasmDebugInfo. // WasmDebugInfo.
// Use for testing only. // Use for testing only.
static wasm::WasmInterpreter* SetupForTesting(Handle<WasmInstanceObject>, V8_EXPORT_PRIVATE static wasm::WasmInterpreter* SetupForTesting(
wasm::WasmInstance*); Handle<WasmInstanceObject>, wasm::WasmInstance*);
static bool IsDebugInfo(Object*); static bool IsDebugInfo(Object*);
static WasmDebugInfo* cast(Object*); static WasmDebugInfo* cast(Object*);
......
...@@ -105,48 +105,23 @@ int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start, ...@@ -105,48 +105,23 @@ int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start,
} }
return RunWasmModuleForTesting(isolate, instance, 0, nullptr, origin); return RunWasmModuleForTesting(isolate, instance, 0, nullptr, origin);
} }
int32_t InterpretWasmModule(Isolate* isolate,
int32_t InterpretWasmModule(Isolate* isolate, ErrorThrower* thrower, Handle<WasmInstanceObject> instance,
const WasmModule* module, ErrorThrower* thrower, int32_t function_index,
const ModuleWireBytes& wire_bytes, WasmVal* args, bool* possible_nondeterminism) {
int function_index, WasmVal* args,
bool* possible_nondeterminism) {
// Don't execute more than 16k steps. // Don't execute more than 16k steps.
constexpr int kMaxNumSteps = 16 * 1024; constexpr int kMaxNumSteps = 16 * 1024;
DCHECK_NOT_NULL(module);
Zone zone(isolate->allocator(), ZONE_NAME); Zone zone(isolate->allocator(), ZONE_NAME);
v8::internal::HandleScope scope(isolate); v8::internal::HandleScope scope(isolate);
if (module->import_table.size() > 0) { WasmInterpreter* interpreter =
thrower->CompileError("Not supported: module has imports."); WasmDebugInfo::SetupForTesting(instance, nullptr);
} WasmInterpreter::Thread* thread = interpreter->GetThread(0);
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);
thread->Reset(); thread->Reset();
thread->InitFrame(&(module->functions[function_index]), args); thread->InitFrame(&(instance->module()->functions[function_index]), args);
WasmInterpreter::State interpreter_result = thread->Run(kMaxNumSteps); WasmInterpreter::State interpreter_result = thread->Run(kMaxNumSteps);
if (instance.mem_start) {
free(instance.mem_start);
}
*possible_nondeterminism = thread->PossibleNondeterminism(); *possible_nondeterminism = thread->PossibleNondeterminism();
if (interpreter_result == WasmInterpreter::FINISHED) { if (interpreter_result == WasmInterpreter::FINISHED) {
WasmVal val = thread->GetReturnValue(); WasmVal val = thread->GetReturnValue();
...@@ -205,6 +180,7 @@ int32_t CallWasmFunctionForTesting(Isolate* isolate, Handle<JSObject> instance, ...@@ -205,6 +180,7 @@ int32_t CallWasmFunctionForTesting(Isolate* isolate, Handle<JSObject> instance,
void SetupIsolateForWasmModule(Isolate* isolate) { void SetupIsolateForWasmModule(Isolate* isolate) {
WasmJs::Install(isolate); WasmJs::Install(isolate);
} }
} // namespace testing } // namespace testing
} // namespace wasm } // namespace wasm
} // namespace internal } // namespace internal
......
...@@ -45,11 +45,10 @@ int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start, ...@@ -45,11 +45,10 @@ int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start,
// Interprets the given module, starting at the function specified by // Interprets the given module, starting at the function specified by
// {function_index}. The return type of the function has to be int32. The module // {function_index}. The return type of the function has to be int32. The module
// should not have any imports or exports // should not have any imports or exports
int32_t InterpretWasmModule(Isolate* isolate, ErrorThrower* thrower, int32_t InterpretWasmModule(Isolate* isolate,
const WasmModule* module, Handle<WasmInstanceObject> instance,
const ModuleWireBytes& wire_bytes, ErrorThrower* thrower, int32_t function_index,
int function_index, WasmVal* args, WasmVal* args, bool* possible_nondeterminism);
bool* may_produced_nan);
// Compiles WasmModule bytes and return an instance of the compiled module. // Compiles WasmModule bytes and return an instance of the compiled module.
const Handle<WasmInstanceObject> CompileInstantiateWasmModuleForTesting( const Handle<WasmInstanceObject> CompileInstantiateWasmModuleForTesting(
...@@ -62,6 +61,7 @@ int32_t RunWasmModuleForTesting(Isolate* isolate, Handle<JSObject> instance, ...@@ -62,6 +61,7 @@ int32_t RunWasmModuleForTesting(Isolate* isolate, Handle<JSObject> instance,
ModuleOrigin origin); ModuleOrigin origin);
// Install function map, module symbol for testing // Install function map, module symbol for testing
void SetupIsolateForWasmModule(Isolate* isolate); void SetupIsolateForWasmModule(Isolate* isolate);
} // namespace testing } // namespace testing
} // namespace wasm } // namespace wasm
} // namespace internal } // namespace internal
......
...@@ -121,13 +121,13 @@ int WasmExecutionFuzzer::FuzzWasmModule( ...@@ -121,13 +121,13 @@ int WasmExecutionFuzzer::FuzzWasmModule(
v8::internal::wasm::testing::SetupIsolateForWasmModule(i_isolate); v8::internal::wasm::testing::SetupIsolateForWasmModule(i_isolate);
ErrorThrower interpreter_thrower(i_isolate, "Interpreter"); ErrorThrower interpreter_thrower(i_isolate, "Interpreter");
std::unique_ptr<const WasmModule> module(testing::DecodeWasmModuleForTesting( ModuleWireBytes wire_bytes(buffer.begin(), buffer.end());
i_isolate, &interpreter_thrower, buffer.begin(), buffer.end(),
ModuleOrigin::kWasmOrigin, true));
MaybeHandle<WasmModuleObject> compiled_module =
SyncCompile(i_isolate, &interpreter_thrower, wire_bytes);
// Clear the flag so that the WebAssembly code is not printed twice. // Clear the flag so that the WebAssembly code is not printed twice.
FLAG_wasm_code_fuzzer_gen_test = false; FLAG_wasm_code_fuzzer_gen_test = false;
if (module == nullptr) { if (compiled_module.is_null()) {
if (generate_test) { if (generate_test) {
OFStream os(stdout); OFStream os(stdout);
os << " ])" << std::endl; os << " ])" << std::endl;
...@@ -147,30 +147,32 @@ int WasmExecutionFuzzer::FuzzWasmModule( ...@@ -147,30 +147,32 @@ int WasmExecutionFuzzer::FuzzWasmModule(
os << "})();" << std::endl; os << "})();" << std::endl;
} }
ModuleWireBytes wire_bytes(buffer.begin(), buffer.end());
int32_t result_interpreted; int32_t result_interpreted;
bool possible_nondeterminism = false; bool possible_nondeterminism = false;
{ {
result_interpreted = testing::InterpretWasmModule( MaybeHandle<WasmInstanceObject> interpreter_instance = SyncInstantiate(
i_isolate, &interpreter_thrower, module.get(), wire_bytes, 0, i_isolate, &interpreter_thrower, compiled_module.ToHandleChecked(),
interpreter_args.get(), &possible_nondeterminism); MaybeHandle<JSReceiver>(), MaybeHandle<JSArrayBuffer>());
}
ErrorThrower compiler_thrower(i_isolate, "Compiler"); if (interpreter_thrower.error()) {
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; return 0;
} }
result_interpreted = testing::InterpretWasmModule(
i_isolate, interpreter_instance.ToHandleChecked(), &interpreter_thrower,
0, interpreter_args.get(), &possible_nondeterminism);
}
int32_t result_compiled; 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( result_compiled = testing::CallWasmFunctionForTesting(
i_isolate, instance, &compiler_thrower, "main", num_args, i_isolate, compiled_instance.ToHandleChecked(), &compiler_thrower,
compiler_args.get(), ModuleOrigin::kWasmOrigin); "main", num_args, compiler_args.get(), ModuleOrigin::kWasmOrigin);
} }
// The WebAssembly spec allows the sign bit of NaN to be non-deterministic. // 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