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; |
} |