Chromium Code Reviews| Index: src/wasm/wasm-module.cc |
| diff --git a/src/wasm/wasm-module.cc b/src/wasm/wasm-module.cc |
| index 2470257735299c590511fb7e82f6d4f2b4152635..387adcd96a1a1c04cb391d741a0b6e5997ad8889 100644 |
| --- a/src/wasm/wasm-module.cc |
| +++ b/src/wasm/wasm-module.cc |
| @@ -18,6 +18,7 @@ |
| #include "src/wasm/module-decoder.h" |
| #include "src/wasm/wasm-debug.h" |
| #include "src/wasm/wasm-function-name-table.h" |
| +#include "src/wasm/wasm-interpreter.h" |
| #include "src/wasm/wasm-module.h" |
| #include "src/wasm/wasm-result.h" |
| @@ -1675,26 +1676,33 @@ MaybeHandle<JSObject> CreateModuleObjectFromBytes(Isolate* isolate, |
| namespace testing { |
| -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"); |
| - |
| +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, |
| - asm_js ? kAsmJsOrigin : kWasmOrigin); |
| + 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 -1; |
| + 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."); |
| } |
| @@ -1702,24 +1710,100 @@ int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start, |
| thrower.Error("Not supported: module has no exports."); |
| } |
| - if (thrower.error()) return -1; |
| + if (thrower.error()) return Handle<JSObject>::null(); |
| + |
| MaybeHandle<FixedArray> compiled_module = |
| module->CompileFunctions(isolate, &thrower); |
| - if (compiled_module.is_null()) return -1; |
| + 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, |
|
titzer
2016/09/09 08:58:59
I'm wondering if it's time to move this into the t
ahaas
2016/09/09 11:57:36
I created new files for this testing code in test/
|
| + 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 = |
| - WasmModule::Instantiate(isolate, compiled_module.ToHandleChecked(), |
| - Handle<JSReceiver>::null(), |
| - Handle<JSArrayBuffer>::null()) |
| - .ToHandleChecked(); |
| + 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; |
| - return CallFunction(isolate, instance, &thrower, asm_js ? "caller" : "main", |
| - 0, nullptr, asm_js); |
| + 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 CallFunction(Isolate* isolate, Handle<JSObject> instance, |
| - ErrorThrower* thrower, const char* name, int argc, |
| - Handle<Object> argv[], bool asm_js) { |
| +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; |
| @@ -1743,7 +1827,7 @@ int32_t CallFunction(Isolate* isolate, Handle<JSObject> instance, |
| // The result should be a number. |
| if (retval.is_null()) { |
| - thrower->Error("WASM.compileRun() failed: Invocation was null"); |
| + thrower.Error("WASM.compileRun() failed: Invocation was null"); |
| return -1; |
| } |
| Handle<Object> result = retval.ToHandleChecked(); |
| @@ -1753,7 +1837,7 @@ int32_t CallFunction(Isolate* isolate, Handle<JSObject> instance, |
| if (result->IsHeapNumber()) { |
| return static_cast<int32_t>(HeapNumber::cast(*result)->value()); |
| } |
| - thrower->Error("WASM.compileRun() failed: Return value should be number"); |
| + thrower.Error("WASM.compileRun() failed: Return value should be number"); |
| return -1; |
| } |