Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(343)

Unified Diff: test/cctest/wasm/wasm-module-runner.cc

Issue 2321443002: [wasm] Call the wasm interpreter from the wasm-code-fuzzer. (Closed)
Patch Set: Address comments Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « test/cctest/wasm/wasm-module-runner.h ('k') | test/fuzzer/fuzzer.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/cctest/wasm/wasm-module-runner.cc
diff --git a/test/cctest/wasm/wasm-module-runner.cc b/test/cctest/wasm/wasm-module-runner.cc
new file mode 100644
index 0000000000000000000000000000000000000000..55bebede4eebf7747434ef721e79b6c17afc36a6
--- /dev/null
+++ b/test/cctest/wasm/wasm-module-runner.cc
@@ -0,0 +1,194 @@
+// 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.
+
+#include "test/cctest/wasm/wasm-module-runner.h"
+
+#include "src/handles.h"
+#include "src/isolate.h"
+#include "src/objects.h"
+#include "src/property-descriptor.h"
+#include "src/wasm/module-decoder.h"
+#include "src/wasm/wasm-interpreter.h"
+#include "src/wasm/wasm-module.h"
+#include "src/wasm/wasm-result.h"
+#include "src/zone.h"
+
+namespace v8 {
+namespace internal {
+namespace wasm {
+namespace testing {
+
+uint32_t GetMinModuleMemSize(const WasmModule* module) {
+ return WasmModule::kPageSize * module->min_mem_pages;
+}
+
+const WasmModule* DecodeWasmModuleForTesting(Isolate* isolate, Zone* zone,
+ ErrorThrower& thrower,
+ const byte* module_start,
+ const byte* module_end,
+ ModuleOrigin origin) {
+ // Decode the module, but don't verify function bodies, since we'll
+ // be compiling them anyway.
+ ModuleResult decoding_result =
+ DecodeWasmModule(isolate, zone, module_start, module_end, false, origin);
+
+ std::unique_ptr<const WasmModule> module(decoding_result.val);
+ if (decoding_result.failed()) {
+ // Module verification failed. throw.
+ thrower.Error("WASM.compileRun() failed: %s",
+ decoding_result.error_msg.get());
+ return nullptr;
+ }
+
+ if (thrower.error()) return nullptr;
+ return module.release();
+}
+
+const Handle<JSObject> InstantiateModuleForTesting(Isolate* isolate,
+ ErrorThrower& thrower,
+ const WasmModule* module) {
+ CHECK(module != nullptr);
+
+ if (module->import_table.size() > 0) {
+ thrower.Error("Not supported: module has imports.");
+ }
+ if (module->export_table.size() == 0) {
+ thrower.Error("Not supported: module has no exports.");
+ }
+
+ if (thrower.error()) return Handle<JSObject>::null();
+
+ MaybeHandle<FixedArray> compiled_module =
+ module->CompileFunctions(isolate, &thrower);
+
+ if (compiled_module.is_null()) return Handle<JSObject>::null();
+ return WasmModule::Instantiate(isolate, compiled_module.ToHandleChecked(),
+ Handle<JSReceiver>::null(),
+ Handle<JSArrayBuffer>::null())
+ .ToHandleChecked();
+}
+
+int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start,
+ const byte* module_end, bool asm_js) {
+ HandleScope scope(isolate);
+ Zone zone(isolate->allocator());
+
+ ErrorThrower thrower(isolate, "CompileAndRunWasmModule");
+ std::unique_ptr<const WasmModule> module(DecodeWasmModuleForTesting(
+ isolate, &zone, thrower, module_start, module_end,
+ asm_js ? kAsmJsOrigin : kWasmOrigin));
+
+ if (module == nullptr) {
+ return -1;
+ }
+ Handle<JSObject> instance =
+ InstantiateModuleForTesting(isolate, thrower, module.get());
+ if (instance.is_null()) {
+ return -1;
+ }
+ return CallWasmFunctionForTesting(isolate, instance, thrower,
+ asm_js ? "caller" : "main", 0, nullptr,
+ asm_js);
+}
+
+int32_t InterpretWasmModule(Isolate* isolate, ErrorThrower& thrower,
+ const WasmModule* module, int function_index,
+ WasmVal* args) {
+ CHECK(module != nullptr);
+
+ Zone zone(isolate->allocator());
+ v8::internal::HandleScope scope(isolate);
+
+ if (module->import_table.size() > 0) {
+ thrower.Error("Not supported: module has imports.");
+ }
+ if (module->export_table.size() == 0) {
+ thrower.Error("Not supported: module has no exports.");
+ }
+
+ if (thrower.error()) return -1;
+
+ WasmModuleInstance instance(module);
+ instance.context = isolate->native_context();
+ instance.mem_size = GetMinModuleMemSize(module);
+ instance.mem_start = nullptr;
+ instance.globals_start = nullptr;
+
+ ModuleEnv module_env;
+ module_env.module = module;
+ module_env.instance = &instance;
+ module_env.origin = module->origin;
+
+ const WasmFunction* function = &(module->functions[function_index]);
+
+ FunctionBody body = {&module_env, function->sig, module->module_start,
+ module->module_start + function->code_start_offset,
+ module->module_start + function->code_end_offset};
+ DecodeResult result = VerifyWasmCode(isolate->allocator(), body);
+ if (result.failed()) {
+ thrower.Error("Function did not verify");
+ return -1;
+ }
+
+ WasmInterpreter interpreter(&instance, isolate->allocator());
+
+ WasmInterpreter::Thread* thread = interpreter.GetThread(0);
+ thread->Reset();
+ thread->PushFrame(function, args);
+ if (thread->Run() == WasmInterpreter::FINISHED) {
+ WasmVal val = thread->GetReturnValue();
+ return val.to<int32_t>();
+ } else if (thread->state() == WasmInterpreter::TRAPPED) {
+ return 0xdeadbeef;
+ } else {
+ thrower.Error("Interpreter did not finish execution within its step bound");
+ return -1;
+ }
+}
+
+int32_t CallWasmFunctionForTesting(Isolate* isolate, Handle<JSObject> instance,
+ ErrorThrower& thrower, const char* name,
+ int argc, Handle<Object> argv[],
+ bool asm_js) {
+ Handle<JSObject> exports_object;
+ if (asm_js) {
+ exports_object = instance;
+ } else {
+ Handle<Name> exports = isolate->factory()->InternalizeUtf8String("exports");
+ exports_object = Handle<JSObject>::cast(
+ JSObject::GetProperty(instance, exports).ToHandleChecked());
+ }
+ Handle<Name> main_name = isolate->factory()->NewStringFromAsciiChecked(name);
+ PropertyDescriptor desc;
+ Maybe<bool> property_found = JSReceiver::GetOwnPropertyDescriptor(
+ isolate, exports_object, main_name, &desc);
+ if (!property_found.FromMaybe(false)) return -1;
+
+ Handle<JSFunction> main_export = Handle<JSFunction>::cast(desc.value());
+
+ // Call the JS function.
+ Handle<Object> undefined = isolate->factory()->undefined_value();
+ MaybeHandle<Object> retval =
+ Execution::Call(isolate, main_export, undefined, argc, argv);
+
+ // The result should be a number.
+ if (retval.is_null()) {
+ thrower.Error("WASM.compileRun() failed: Invocation was null");
+ return -1;
+ }
+ Handle<Object> result = retval.ToHandleChecked();
+ if (result->IsSmi()) {
+ return Smi::cast(*result)->value();
+ }
+ if (result->IsHeapNumber()) {
+ return static_cast<int32_t>(HeapNumber::cast(*result)->value());
+ }
+ thrower.Error("WASM.compileRun() failed: Return value should be number");
+ return -1;
+}
+
+} // namespace testing
+} // namespace wasm
+} // namespace internal
+} // namespace v8
« no previous file with comments | « test/cctest/wasm/wasm-module-runner.h ('k') | test/fuzzer/fuzzer.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698