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

Unified Diff: test/cctest/wasm/wasm-run-utils.h

Issue 1972153002: [wasm] Implement an interpreter for WASM. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 7 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
Index: test/cctest/wasm/wasm-run-utils.h
diff --git a/test/cctest/wasm/wasm-run-utils.h b/test/cctest/wasm/wasm-run-utils.h
index d6dd893064d71627f332fa42393ae090e1545713..7c8bccafd99a36b4f23d0cf6eba74c634a20468b 100644
--- a/test/cctest/wasm/wasm-run-utils.h
+++ b/test/cctest/wasm/wasm-run-utils.h
@@ -9,6 +9,7 @@
#include <stdlib.h>
#include <string.h>
+#include "src/base/accounting-allocator.h"
#include "src/base/utils/random-number-generator.h"
#include "src/compiler/graph-visualizer.h"
@@ -20,6 +21,7 @@
#include "src/compiler/zone-pool.h"
#include "src/wasm/ast-decoder.h"
+#include "src/wasm/wasm-interpreter.h"
#include "src/wasm/wasm-js.h"
#include "src/wasm/wasm-macro-gen.h"
#include "src/wasm/wasm-module.h"
@@ -39,6 +41,7 @@
#endif
static const uint32_t kMaxFunctions = 10;
+#define WASM_INTERPRETER 1
// TODO(titzer): check traps more robustly in tests.
// Currently, in tests, we just return 0xdeadbeef from the function in which
@@ -72,7 +75,10 @@ const uint32_t kMaxGlobalsSize = 128;
// {WasmModuleInstance}.
class TestingModule : public ModuleEnv {
public:
- TestingModule() : instance_(&module_), global_offset(0) {
+ TestingModule()
+ : instance_(&module_),
+ global_offset(0),
+ interpreter_(&instance_, &allocator_) {
module_.shared_isolate = CcTest::InitIsolateOnce();
module = &module_;
instance = &instance_;
@@ -171,6 +177,9 @@ class TestingModule : public ModuleEnv {
module->functions.push_back(
{sig, index, 0, 0, 0, 0, 0, 0, 0, 0, 0, false, false});
instance->function_code.push_back(code);
+ WasmFunction* function = &module->functions.back();
+ int interpreter_index = interpreter_.AddFunctionForTesting(function);
+ DCHECK_EQ(index, static_cast<uint32_t>(interpreter_index));
DCHECK_LT(index, kMaxFunctions); // limited for testing.
return index;
}
@@ -226,11 +235,18 @@ class TestingModule : public ModuleEnv {
}
}
+ WasmInterpreter* GetInterpreter() { return &interpreter_; }
+
private:
WasmModule module_;
WasmModuleInstance instance_;
+ v8::base::AccountingAllocator allocator_;
uint32_t global_offset;
V8_ALIGNED(8) byte global_data[kMaxGlobalsSize]; // preallocated global data.
+ // TODO(titzer): This is ugly. Because the functions must be manually added
+ // to the interpreter for testing, it needs to be accessible to each creation
+ // of a WasmFunctionCompiler below.
+ WasmInterpreter interpreter_;
WasmGlobal* AddGlobal(MachineType mem_type) {
byte size = WasmOpcodes::MemSize(mem_type);
@@ -409,7 +425,7 @@ class WasmFunctionWrapper : public HandleAndZoneScope,
// A helper for compiling WASM functions for testing. This class can create a
// standalone function if {module} is NULL or a function within a
// {TestingModule}. It contains the internal state for compilation (i.e.
-// TurboFan graph) and, later, interpretation.
+// TurboFan graph) and interpretation (by adding to the interpreter manually).
class WasmFunctionCompiler : public HandleAndZoneScope,
private GraphAndBuilders {
public:
@@ -463,12 +479,25 @@ class WasmFunctionCompiler : public HandleAndZoneScope,
}
CallDescriptor* descriptor() { return descriptor_; }
- void Build(const byte* start, const byte* end) {
+ void Build(const byte* start, const byte* end,
+ WasmInterpreter* interpreter = nullptr) {
// Build the TurboFan graph.
local_decls.Prepend(&start, &end);
TestBuildingGraph(main_zone(), &jsgraph, testing_module_, sig,
&source_position_table_, start, end);
- delete[] start;
+#if WASM_INTERPRETER
+ // Build the interpreter code.
+ if (!testing_module_) {
+ // No module; the function was never added to the interpreter.
+ int index = interpreter->AddFunctionForTesting(function_);
+ CHECK_EQ(function_index_, index);
+ } else {
+ // Always use the interpreter from the module.
+ interpreter = testing_module_->GetInterpreter();
+ }
+ CHECK(interpreter->SetFunctionCodeForTesting(function(), start, end));
+// TODO(titzer): memory leak!!!! delete[] start;
Clemens Hammacher 2016/05/12 15:20:55 SetFunctionCodeForTesting could allocate memory fo
+#endif
}
byte AllocateLocal(LocalType type) {
@@ -551,7 +580,8 @@ class WasmRunner {
compiled_(false),
signature_(MachineTypeForC<ReturnType>() == MachineType::None() ? 0 : 1,
GetParameterCount(p0, p1, p2, p3), storage_),
- compiler_(&signature_, nullptr) {
+ compiler_(&signature_, nullptr),
+ interpreter_(new WasmInterpreter(nullptr, &allocator_)) {
InitSigStorage(p0, p1, p2, p3);
}
@@ -563,7 +593,8 @@ class WasmRunner {
compiled_(false),
signature_(MachineTypeForC<ReturnType>() == MachineType::None() ? 0 : 1,
GetParameterCount(p0, p1, p2, p3), storage_),
- compiler_(&signature_, module) {
+ compiler_(&signature_, module),
+ interpreter_(nullptr) {
DCHECK(module);
InitSigStorage(p0, p1, p2, p3);
}
@@ -595,50 +626,112 @@ class WasmRunner {
CHECK(!compiled_);
compiled_ = true;
- // Build the TF graph within the compiler.
- compiler_.Build(start, end);
- // Generate code.
- Handle<Code> code = compiler_.Compile();
+ if (WASM_INTERPRETER) {
+ // Build the interpreter code.
+ compiler_.Build(start, end, interpreter_);
+ } else {
+ // Build the TF graph within the compiler.
+ compiler_.Build(start, end);
+ // Generate code.
+ Handle<Code> code = compiler_.Compile();
+
+ if (compiler_.testing_module_) {
+ // Update the table of function code in the module.
+ compiler_.testing_module_->SetFunctionCode(compiler_.function_index_,
+ code);
+ }
- if (compiler_.testing_module_) {
- // Update the table of function code in the module.
- compiler_.testing_module_->SetFunctionCode(compiler_.function_index_,
- code);
+ wrapper_.SetInnerCode(code);
}
-
- wrapper_.SetInnerCode(code);
}
- ReturnType Call() { return Call(0, 0, 0, 0); }
+ ReturnType Call() {
+ if (WASM_INTERPRETER) {
+ return CallInterpreter(nullptr, 0);
+ } else {
+ return Call(0, 0, 0, 0);
+ }
+ }
template <typename P0>
ReturnType Call(P0 p0) {
- return Call(p0, 0, 0, 0);
+ if (WASM_INTERPRETER) {
+ WasmVal args[] = {WasmVal(p0)};
+ return CallInterpreter(args, 1);
+ } else {
+ return Call(p0, 0, 0, 0);
+ }
}
template <typename P0, typename P1>
ReturnType Call(P0 p0, P1 p1) {
- return Call(p0, p1, 0, 0);
+ if (WASM_INTERPRETER) {
+ WasmVal args[] = {WasmVal(p0), WasmVal(p1)};
+ return CallInterpreter(args, 2);
+ } else {
+ return Call(p0, p1, 0, 0);
+ }
}
template <typename P0, typename P1, typename P2>
ReturnType Call(P0 p0, P1 p1, P2 p2) {
- return Call(p0, p1, p2, 0);
+ if (WASM_INTERPRETER) {
+ WasmVal args[] = {WasmVal(p0), WasmVal(p1), WasmVal(p2)};
+ return CallInterpreter(args, 3);
+ } else {
+ return Call(p0, p1, p2, 0);
+ }
}
template <typename P0, typename P1, typename P2, typename P3>
ReturnType Call(P0 p0, P1 p1, P2 p2, P3 p3) {
- CodeRunner<int32_t> runner(CcTest::InitIsolateOnce(),
- wrapper_.GetWrapperCode(), wrapper_.signature());
- ReturnType return_value;
- int32_t result = runner.Call<void*, void*, void*, void*, void*>(
- &p0, &p1, &p2, &p3, &return_value);
- CHECK_EQ(WASM_WRAPPER_RETURN_VALUE, result);
- return return_value;
+ if (WASM_INTERPRETER) {
+ WasmVal args[] = {WasmVal(p0), WasmVal(p1), WasmVal(p2), WasmVal(p3)};
+ return CallInterpreter(args, 4);
+ } else {
+ CodeRunner<int32_t> runner(CcTest::InitIsolateOnce(),
+ wrapper_.GetWrapperCode(),
+ wrapper_.signature());
+ ReturnType return_value;
+ int32_t result = runner.Call<void*, void*, void*, void*, void*>(
+ &p0, &p1, &p2, &p3, &return_value);
+ CHECK_EQ(WASM_WRAPPER_RETURN_VALUE, result);
+ return return_value;
+ }
+ }
+
+ ReturnType CallInterpreter(WasmVal* args, int count) {
+ CHECK_EQ(count,
+ static_cast<int>(compiler_.function()->sig->parameter_count()));
+ WasmInterpreter* interpreter = GetInterpreter();
+
+ WasmInterpreter::Thread& thread = interpreter->GetThread(0);
+ thread.Reset();
+ thread.PushFrame(compiler_.function(), args);
+ if (thread.Run() == WasmInterpreter::FINISHED) {
+ WasmVal val = thread.GetReturnValue();
+ return val.to<ReturnType>();
+ } else if (thread.state() == WasmInterpreter::TRAPPED) {
+ // TODO(titzer): return the correct trap code
+ int64_t result = 0xdeadbeefdeadbeef;
+ return static_cast<ReturnType>(result);
+ } else {
ahaas 2016/05/13 12:18:55 if the program is more than 1000 (wasm-interpreter
+ // TODO(titzer): falling off end
+ ReturnType val = 0;
+ return val;
+ }
}
byte AllocateLocal(LocalType type) { return compiler_.AllocateLocal(type); }
+ WasmInterpreter* GetInterpreter() {
+ return compiler_.testing_module_
+ ? compiler_.testing_module_->GetInterpreter()
+ : interpreter_;
+ }
+
+ WasmFunction* function() { return compiler_.function(); }
+
protected:
v8::base::AccountingAllocator allocator_;
Zone zone;
@@ -647,6 +740,7 @@ class WasmRunner {
FunctionSig signature_;
WasmFunctionCompiler compiler_;
WasmFunctionWrapper<ReturnType> wrapper_;
+ WasmInterpreter* interpreter_;
static size_t GetParameterCount(MachineType p0, MachineType p1,
MachineType p2, MachineType p3) {

Powered by Google App Engine
This is Rietveld 408576698