Chromium Code Reviews| 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 a1ea4d133fba3e97d5153f8ef536d4bfbf2f68ad..e76b463a6cb364d64796014a82e65d4278c64d60 100644 |
| --- a/test/cctest/wasm/wasm-run-utils.h |
| +++ b/test/cctest/wasm/wasm-run-utils.h |
| @@ -14,6 +14,8 @@ |
| #include "src/compiler/graph-visualizer.h" |
| #include "src/compiler/int64-lowering.h" |
| #include "src/compiler/js-graph.h" |
| +#include "src/compiler/node.h" |
| +#include "src/compiler/pipeline.h" |
| #include "src/compiler/wasm-compiler.h" |
| #include "src/wasm/ast-decoder.h" |
| @@ -21,8 +23,10 @@ |
| #include "src/wasm/wasm-module.h" |
| #include "src/wasm/wasm-opcodes.h" |
| +#include "src/zone.h" |
| + |
| #include "test/cctest/cctest.h" |
| -#include "test/cctest/compiler/codegen-tester.h" |
| +#include "test/cctest/compiler/call-tester.h" |
| #include "test/cctest/compiler/graph-builder-tester.h" |
| // TODO(titzer): pull WASM_64 up to a common header. |
| @@ -246,6 +250,126 @@ inline void TestBuildingGraph(Zone* zone, JSGraph* jsgraph, FunctionEnv* env, |
| } |
| } |
| +template <typename ReturnType> |
| +class WasmFunctionWrapper : public HandleAndZoneScope, |
| + private GraphAndBuilders { |
| + public: |
| + WasmFunctionWrapper() |
| + : GraphAndBuilders(main_zone()), |
| + inner_code_node_(nullptr), |
| + signature_(nullptr) { |
| + Signature<MachineType>::Builder sig_builder(zone(), 1, 5); |
| + |
| + sig_builder.AddReturn(MachineType::Int32()); |
| + for (int i = 0; i < 5; i++) { |
| + sig_builder.AddParam(MachineType::Pointer()); |
| + } |
| + signature_ = sig_builder.Build(); |
| + } |
| + |
| + void Init(CallDescriptor* descriptor, MachineType p0 = MachineType::None(), |
| + MachineType p1 = MachineType::None(), |
| + MachineType p2 = MachineType::None(), |
| + MachineType p3 = MachineType::None()) { |
| + // Create the TF graph for the wrapper. The wrapper always takes four |
| + // pointers as parameters, but may not pass the values of all pointers to |
| + // the actual test function. |
| + |
| + // Function, effect, and control. |
| + Node** parameters = zone()->template NewArray<Node*>(4 + 3); |
| + graph()->SetStart(graph()->NewNode(common()->Start(6))); |
| + Node* effect = graph()->start(); |
| + int parameter_count = 0; |
| + |
| + // Dummy node which gets replaced in SetInnerCode. |
| + inner_code_node_ = graph()->NewNode(common()->Int32Constant(0)); |
| + parameters[parameter_count++] = inner_code_node_; |
| + |
| + if (p0 != MachineType::None()) { |
| + parameters[parameter_count] = graph()->NewNode( |
| + machine()->Load(p0), |
| + graph()->NewNode(common()->Parameter(0), graph()->start()), |
| + graph()->NewNode(common()->Int32Constant(0)), effect, |
| + graph()->start()); |
| + effect = parameters[parameter_count++]; |
| + } |
| + if (p1 != MachineType::None()) { |
| + parameters[parameter_count] = graph()->NewNode( |
| + machine()->Load(p0), |
| + graph()->NewNode(common()->Parameter(1), graph()->start()), |
| + graph()->NewNode(common()->Int32Constant(0)), effect, |
| + graph()->start()); |
| + effect = parameters[parameter_count++]; |
| + } |
| + if (p2 != MachineType::None()) { |
| + parameters[parameter_count] = graph()->NewNode( |
| + machine()->Load(p0), |
| + graph()->NewNode(common()->Parameter(2), graph()->start()), |
| + graph()->NewNode(common()->Int32Constant(0)), effect, |
| + graph()->start()); |
| + effect = parameters[parameter_count++]; |
| + } |
| + if (p3 != MachineType::None()) { |
| + parameters[parameter_count] = graph()->NewNode( |
| + machine()->Load(p0), |
| + graph()->NewNode(common()->Parameter(3), graph()->start()), |
| + graph()->NewNode(common()->Int32Constant(0)), effect, |
| + graph()->start()); |
| + effect = parameters[parameter_count++]; |
| + } |
| + |
| + parameters[parameter_count++] = effect; |
| + parameters[parameter_count++] = graph()->start(); |
| + Node* call = graph()->NewNode(common()->Call(descriptor), parameter_count, |
| + parameters); |
| + |
| + effect = graph()->NewNode( |
| + machine()->Store( |
| + StoreRepresentation(MachineTypeForC<ReturnType>().representation(), |
| + WriteBarrierKind::kNoWriteBarrier)), |
| + graph()->NewNode(common()->Parameter(4), graph()->start()), |
| + graph()->NewNode(common()->Int32Constant(0)), call, effect, |
| + graph()->start()); |
| + Node* r = graph()->NewNode(common()->Return(), |
| + graph()->NewNode(common()->Int32Constant(7654)), |
| + effect, graph()->start()); |
| + graph()->SetEnd(graph()->NewNode(common()->End(2), r, graph()->start())); |
| + } |
| + |
| + void SetInnerCode(Handle<Code> code_handle) { |
| + NodeProperties::ChangeOp(inner_code_node_, |
| + common()->HeapConstant(code_handle)); |
| + } |
| + |
| + Handle<Code> GetWrapperCode() { |
| + if (code_.is_null()) { |
| + Isolate* isolate = CcTest::InitIsolateOnce(); |
| + |
| + CallDescriptor* descriptor = |
| + Linkage::GetSimplifiedCDescriptor(zone(), signature_, true); |
| + |
| + CompilationInfo info("testing", isolate, graph()->zone()); |
| + code_ = |
| + Pipeline::GenerateCodeForTesting(&info, descriptor, graph(), nullptr); |
| + CHECK(!code_.is_null()); |
| +#ifdef ENABLE_DISASSEMBLER |
| + if (FLAG_print_opt_code) { |
| + OFStream os(stdout); |
| + code_->Disassemble("wasm wrapper", os); |
| + } |
| +#endif |
| + } |
| + |
| + return code_; |
| + } |
| + |
| + Signature<MachineType>* signature() const { return signature_; } |
| + |
| + private: |
| + Node* inner_code_node_; |
| + Handle<Code> code_; |
| + Signature<MachineType>* signature_; |
| +}; |
| // A helper for compiling functions that are only internally callable WASM code. |
| class WasmFunctionCompiler : public HandleAndZoneScope, |
| @@ -270,6 +394,11 @@ class WasmFunctionCompiler : public HandleAndZoneScope, |
| Zone* zone() const { return graph()->zone(); } |
| CommonOperatorBuilder* common() { return &main_common_; } |
| MachineOperatorBuilder* machine() { return &main_machine_; } |
| + void InitializeDescriptor() { |
| + if (descriptor_ == nullptr) { |
| + descriptor_ = env.module->GetWasmCallDescriptor(main_zone(), env.sig); |
| + } |
| + } |
| CallDescriptor* descriptor() { return descriptor_; } |
| void Build(const byte* start, const byte* end) { |
| @@ -285,7 +414,7 @@ class WasmFunctionCompiler : public HandleAndZoneScope, |
| } |
| Handle<Code> Compile(ModuleEnv* module) { |
| - descriptor_ = module->GetWasmCallDescriptor(this->zone(), env.sig); |
| + InitializeDescriptor(); |
| CompilationInfo info("wasm compile", this->isolate(), this->zone()); |
| Handle<Code> result = |
| Pipeline::GenerateCodeForTesting(&info, descriptor_, this->graph()); |
| @@ -323,7 +452,6 @@ class WasmRunner { |
| : signature_(MachineTypeForC<ReturnType>() == MachineType::None() ? 0 : 1, |
| GetParameterCount(p0, p1, p2, p3), storage_), |
| compiler_(&signature_), |
| - call_wrapper_(p0, p1, p2, p3), |
| compilation_done_(false) { |
| int index = 0; |
| MachineType ret = MachineTypeForC<ReturnType>(); |
| @@ -338,6 +466,9 @@ class WasmRunner { |
| storage_[index++] = WasmOpcodes::LocalTypeFor(p2); |
| if (p3 != MachineType::None()) |
| storage_[index++] = WasmOpcodes::LocalTypeFor(p3); |
| + |
| + compiler_.InitializeDescriptor(); |
| + wrapper_.Init(compiler_.descriptor(), p0, p1, p2, p3); |
| } |
| @@ -355,39 +486,35 @@ class WasmRunner { |
| // Generate code. |
| Handle<Code> code = compiler_.Compile(env()->module); |
| - // Construct the call wrapper. |
| - Node* inputs[5]; |
| - int input_count = 0; |
| - inputs[input_count++] = call_wrapper_.HeapConstant(code); |
| - for (size_t i = 0; i < signature_.parameter_count(); i++) { |
| - inputs[input_count++] = call_wrapper_.Parameter(i); |
| - } |
| - |
| - call_wrapper_.Return(call_wrapper_.AddNode( |
| - call_wrapper_.common()->Call(compiler_.descriptor()), input_count, |
| - inputs)); |
| + wrapper_.SetInnerCode(code); |
| } |
| - ReturnType Call() { return call_wrapper_.Call(); } |
| + ReturnType Call() { return Call(nullptr, nullptr, nullptr, nullptr); } |
| template <typename P0> |
| ReturnType Call(P0 p0) { |
| - return call_wrapper_.Call(p0); |
| + return Call(p0, nullptr, nullptr, nullptr); |
| } |
| template <typename P0, typename P1> |
| ReturnType Call(P0 p0, P1 p1) { |
| - return call_wrapper_.Call(p0, p1); |
| + return Call(p0, p1, nullptr, nullptr); |
| } |
| template <typename P0, typename P1, typename P2> |
| ReturnType Call(P0 p0, P1 p1, P2 p2) { |
| - return call_wrapper_.Call(p0, p1, p2); |
| + return Call(p0, p1, p2, nullptr); |
| } |
| template <typename P0, typename P1, typename P2, typename P3> |
| ReturnType Call(P0 p0, P1 p1, P2 p2, P3 p3) { |
| - return call_wrapper_.Call(p0, p1, p2, 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(7654, result); |
|
titzer
2016/02/18 08:18:49
Pull this constant out somewhere.
ahaas
2016/02/18 09:10:57
Done.
|
| + return return_value; |
| } |
| byte AllocateLocal(LocalType type) { |
| @@ -402,7 +529,7 @@ class WasmRunner { |
| LocalType storage_[5]; |
| FunctionSig signature_; |
| WasmFunctionCompiler compiler_; |
| - BufferedRawMachineAssemblerTester<ReturnType> call_wrapper_; |
| + WasmFunctionWrapper<ReturnType> wrapper_; |
| bool compilation_done_; |
| static size_t GetParameterCount(MachineType p0, MachineType p1, |