Revert "Revert "Upgrade to 5.0.71.48"" DO NOT MERGE

This reverts commit f2e3994fa5148cc3d9946666f0b0596290192b0e,
and updates the x64 makefile properly so it doesn't break that
build.

FPIIM-449

Change-Id: Ib83e35bfbae6af627451c926a9650ec57c045605
(cherry picked from commit 109988c7ccb6f3fd1a58574fa3dfb88beaef6632)
diff --git a/test/cctest/wasm/wasm-run-utils.h b/test/cctest/wasm/wasm-run-utils.h
index cc23b46..7ee3981 100644
--- a/test/cctest/wasm/wasm-run-utils.h
+++ b/test/cctest/wasm/wasm-run-utils.h
@@ -12,7 +12,10 @@
 #include "src/base/utils/random-number-generator.h"
 
 #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"
@@ -20,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.
@@ -31,6 +36,8 @@
 #define WASM_64 0
 #endif
 
+static const uint32_t kMaxFunctions = 10;
+
 // TODO(titzer): check traps more robustly in tests.
 // Currently, in tests, we just return 0xdeadbeef from the function in which
 // the trap occurs if the runtime context is not available to throw a JavaScript
@@ -41,6 +48,9 @@
   CHECK_EQ(0xdeadbeefdeadbeef, (bit_cast<uint64_t>(x)) & 0xFFFFFFFFFFFFFFFF)
 #define CHECK_TRAP(x) CHECK_TRAP32(x)
 
+#define WASM_RUNNER_MAX_NUM_PARAMETERS 4
+#define WASM_WRAPPER_RETURN_VALUE 8754
+
 namespace {
 using namespace v8::base;
 using namespace v8::internal;
@@ -50,47 +60,51 @@
 inline void init_env(FunctionEnv* env, FunctionSig* sig) {
   env->module = nullptr;
   env->sig = sig;
-  env->local_int32_count = 0;
-  env->local_int64_count = 0;
-  env->local_float32_count = 0;
-  env->local_float64_count = 0;
+  env->local_i32_count = 0;
+  env->local_i64_count = 0;
+  env->local_f32_count = 0;
+  env->local_f64_count = 0;
   env->SumLocals();
 }
 
 const uint32_t kMaxGlobalsSize = 128;
 
 // A helper for module environments that adds the ability to allocate memory
-// and global variables.
+// and global variables. Contains a built-in {WasmModule} and
+// {WasmModuleInstance}.
 class TestingModule : public ModuleEnv {
  public:
-  TestingModule() : mem_size(0), global_offset(0) {
-    globals_area = 0;
-    mem_start = 0;
-    mem_end = 0;
-    module = nullptr;
+  TestingModule() : instance_(&module_), global_offset(0) {
+    module_.shared_isolate = CcTest::InitIsolateOnce();
+    module = &module_;
+    instance = &instance_;
+    instance->module = &module_;
+    instance->globals_start = global_data;
+    instance->globals_size = kMaxGlobalsSize;
+    instance->mem_start = nullptr;
+    instance->mem_size = 0;
+    instance->function_code = nullptr;
     linker = nullptr;
-    function_code = nullptr;
     asm_js = false;
     memset(global_data, 0, sizeof(global_data));
   }
 
   ~TestingModule() {
-    if (mem_start) {
-      free(raw_mem_start<byte>());
+    if (instance->mem_start) {
+      free(instance->mem_start);
     }
-    if (function_code) delete function_code;
-    if (module) delete module;
+    if (instance->function_code) {
+      delete instance->function_code;
+    }
   }
 
   byte* AddMemory(size_t size) {
-    CHECK_EQ(0, mem_start);
-    CHECK_EQ(0, mem_size);
-    mem_start = reinterpret_cast<uintptr_t>(malloc(size));
-    CHECK(mem_start);
-    byte* raw = raw_mem_start<byte>();
-    memset(raw, 0, size);
-    mem_end = mem_start + size;
-    mem_size = size;
+    CHECK_NULL(instance->mem_start);
+    CHECK_EQ(0, instance->mem_size);
+    instance->mem_start = reinterpret_cast<byte*>(malloc(size));
+    CHECK(instance->mem_start);
+    memset(instance->mem_start, 0, size);
+    instance->mem_size = size;
     return raw_mem_start<byte>();
   }
 
@@ -103,11 +117,10 @@
   template <typename T>
   T* AddGlobal(MachineType mem_type) {
     WasmGlobal* global = AddGlobal(mem_type);
-    return reinterpret_cast<T*>(globals_area + global->offset);
+    return reinterpret_cast<T*>(instance->globals_start + global->offset);
   }
 
   byte AddSignature(FunctionSig* sig) {
-    AllocModule();
     if (!module->signatures) {
       module->signatures = new std::vector<FunctionSig*>();
     }
@@ -119,33 +132,33 @@
 
   template <typename T>
   T* raw_mem_start() {
-    DCHECK(mem_start);
-    return reinterpret_cast<T*>(mem_start);
+    DCHECK(instance->mem_start);
+    return reinterpret_cast<T*>(instance->mem_start);
   }
 
   template <typename T>
   T* raw_mem_end() {
-    DCHECK(mem_end);
-    return reinterpret_cast<T*>(mem_end);
+    DCHECK(instance->mem_start);
+    return reinterpret_cast<T*>(instance->mem_start + instance->mem_size);
   }
 
   template <typename T>
   T raw_mem_at(int i) {
-    DCHECK(mem_start);
-    return reinterpret_cast<T*>(mem_start)[i];
+    DCHECK(instance->mem_start);
+    return reinterpret_cast<T*>(instance->mem_start)[i];
   }
 
   template <typename T>
   T raw_val_at(int i) {
     T val;
-    memcpy(&val, reinterpret_cast<void*>(mem_start + i), sizeof(T));
+    memcpy(&val, reinterpret_cast<void*>(instance->mem_start + i), sizeof(T));
     return val;
   }
 
   // Zero-initialize the memory.
   void BlankMemory() {
     byte* raw = raw_mem_start<byte>();
-    memset(raw, 0, mem_size);
+    memset(raw, 0, instance->mem_size);
   }
 
   // Pseudo-randomly intialize the memory.
@@ -157,26 +170,57 @@
     rng.NextBytes(raw, end - raw);
   }
 
-  WasmFunction* AddFunction(FunctionSig* sig, Handle<Code> code) {
-    AllocModule();
+  int AddFunction(FunctionSig* sig, Handle<Code> code) {
     if (module->functions == nullptr) {
       module->functions = new std::vector<WasmFunction>();
-      function_code = new std::vector<Handle<Code>>();
+      // TODO(titzer): Reserving space here to avoid the underlying WasmFunction
+      // structs from moving.
+      module->functions->reserve(kMaxFunctions);
+      instance->function_code = new std::vector<Handle<Code>>();
     }
-    module->functions->push_back({sig, 0, 0, 0, 0, 0, 0, 0, false, false});
-    function_code->push_back(code);
-    return &module->functions->back();
+    uint32_t index = static_cast<uint32_t>(module->functions->size());
+    module->functions->push_back(
+        {sig, index, 0, 0, 0, 0, 0, 0, 0, false, false});
+    instance->function_code->push_back(code);
+    DCHECK_LT(index, kMaxFunctions);  // limited for testing.
+    return index;
+  }
+
+  void SetFunctionCode(uint32_t index, Handle<Code> code) {
+    instance->function_code->at(index) = code;
+  }
+
+  void AddIndirectFunctionTable(int* functions, int table_size) {
+    Isolate* isolate = module->shared_isolate;
+    Handle<FixedArray> fixed =
+        isolate->factory()->NewFixedArray(2 * table_size);
+    instance->function_table = fixed;
+    module->function_table = new std::vector<uint16_t>();
+    for (int i = 0; i < table_size; i++) {
+      module->function_table->push_back(functions[i]);
+    }
+  }
+
+  void PopulateIndirectFunctionTable() {
+    if (instance->function_table.is_null()) return;
+    int table_size = static_cast<int>(module->function_table->size());
+    for (int i = 0; i < table_size; i++) {
+      int function_index = module->function_table->at(i);
+      WasmFunction* function = &module->functions->at(function_index);
+      instance->function_table->set(i, Smi::FromInt(function->sig_index));
+      instance->function_table->set(
+          i + table_size, *instance->function_code->at(function_index));
+    }
   }
 
  private:
-  size_t mem_size;
+  WasmModule module_;
+  WasmModuleInstance instance_;
   uint32_t global_offset;
-  byte global_data[kMaxGlobalsSize];
+  V8_ALIGNED(8) byte global_data[kMaxGlobalsSize];  // preallocated global data.
 
   WasmGlobal* AddGlobal(MachineType mem_type) {
-    AllocModule();
-    if (globals_area == 0) {
-      globals_area = reinterpret_cast<uintptr_t>(global_data);
+    if (!module->globals) {
       module->globals = new std::vector<WasmGlobal>();
     }
     byte size = WasmOpcodes::MemSize(mem_type);
@@ -187,15 +231,6 @@
     CHECK_LT(global_offset, kMaxGlobalsSize);
     return &module->globals->back();
   }
-  void AllocModule() {
-    if (module == nullptr) {
-      module = new WasmModule();
-      module->shared_isolate = CcTest::InitIsolateOnce();
-      module->globals = nullptr;
-      module->functions = nullptr;
-      module->data_segments = nullptr;
-    }
-  }
 };
 
 
@@ -212,39 +247,212 @@
     str << ", msg = " << result.error_msg.get();
     FATAL(str.str().c_str());
   }
+  builder.Int64LoweringForTesting();
   if (FLAG_trace_turbo_graph) {
     OFStream os(stdout);
     os << AsRPO(*jsgraph->graph());
   }
 }
 
+template <typename ReturnType>
+class WasmFunctionWrapper : public HandleAndZoneScope,
+                            private GraphAndBuilders {
+ public:
+  WasmFunctionWrapper()
+      : GraphAndBuilders(main_zone()),
+        inner_code_node_(nullptr),
+        signature_(nullptr) {
+    // One additional parameter for the pointer to the return value memory.
+    Signature<MachineType>::Builder sig_builder(
+        zone(), 1, WASM_RUNNER_MAX_NUM_PARAMETERS + 1);
 
-// A helper for compiling functions that are only internally callable WASM code.
+    sig_builder.AddReturn(MachineType::Int32());
+    for (int i = 0; i < WASM_RUNNER_MAX_NUM_PARAMETERS + 1; 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*>(WASM_RUNNER_MAX_NUM_PARAMETERS + 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(WASM_RUNNER_MAX_NUM_PARAMETERS),
+                         graph()->start()),
+        graph()->NewNode(common()->Int32Constant(0)), call, effect,
+        graph()->start());
+    Node* r = graph()->NewNode(
+        common()->Return(),
+        graph()->NewNode(common()->Int32Constant(WASM_WRAPPER_RETURN_VALUE)),
+        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);
+
+      if (kPointerSize == 4) {
+        // One additional parameter for the pointer of the return value.
+        Signature<MachineRepresentation>::Builder rep_builder(
+            zone(), 1, WASM_RUNNER_MAX_NUM_PARAMETERS + 1);
+
+        rep_builder.AddReturn(MachineRepresentation::kWord32);
+        for (int i = 0; i < WASM_RUNNER_MAX_NUM_PARAMETERS + 1; i++) {
+          rep_builder.AddParam(MachineRepresentation::kWord32);
+        }
+        Int64Lowering r(graph(), machine(), common(), zone(),
+                        rep_builder.Build());
+        r.LowerGraph();
+      }
+
+      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 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.
 class WasmFunctionCompiler : public HandleAndZoneScope,
                              private GraphAndBuilders {
  public:
-  explicit WasmFunctionCompiler(FunctionSig* sig, ModuleEnv* module = nullptr)
+  explicit WasmFunctionCompiler(FunctionSig* sig, TestingModule* module)
       : GraphAndBuilders(main_zone()),
         jsgraph(this->isolate(), this->graph(), this->common(), nullptr,
                 nullptr, this->machine()),
-        descriptor_(nullptr) {
+        descriptor_(nullptr),
+        testing_module_(module) {
     init_env(&env, sig);
     env.module = module;
+    if (module) {
+      // Get a new function from the testing module.
+      function_ = nullptr;
+      function_index_ = module->AddFunction(sig, Handle<Code>::null());
+    } else {
+      // Create our own function.
+      function_ = new WasmFunction();
+      function_->sig = sig;
+      function_index_ = 0;
+    }
+  }
+
+  ~WasmFunctionCompiler() {
+    if (function_) delete function_;
   }
 
   JSGraph jsgraph;
   FunctionEnv env;
   // The call descriptor is initialized when the function is compiled.
   CallDescriptor* descriptor_;
+  TestingModule* testing_module_;
+  WasmFunction* function_;
+  int function_index_;
 
   Isolate* isolate() { return main_isolate(); }
   Graph* graph() const { return main_graph_; }
   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) {
+    // Transfer local counts before compiling.
+    function()->local_i32_count = env.local_i32_count;
+    function()->local_i64_count = env.local_i64_count;
+    function()->local_f32_count = env.local_f32_count;
+    function()->local_f64_count = env.local_f64_count;
+
+    // Build the TurboFan graph.
     TestBuildingGraph(main_zone(), &jsgraph, &env, start, end);
   }
 
@@ -256,11 +464,16 @@
     return b;
   }
 
-  Handle<Code> Compile(ModuleEnv* module) {
-    descriptor_ = module->GetWasmCallDescriptor(this->zone(), env.sig);
+  // TODO(titzer): remove me.
+  Handle<Code> Compile() {
+    InitializeDescriptor();
+    CallDescriptor* desc = descriptor_;
+    if (kPointerSize == 4) {
+      desc = testing_module_->GetI32WasmCallDescriptor(this->zone(), desc);
+    }
     CompilationInfo info("wasm compile", this->isolate(), this->zone());
     Handle<Code> result =
-        Pipeline::GenerateCodeForTesting(&info, descriptor_, this->graph());
+        Pipeline::GenerateCodeForTesting(&info, desc, this->graph());
 #ifdef ENABLE_DISASSEMBLER
     if (!result.is_null() && FLAG_print_opt_code) {
       OFStream os(stdout);
@@ -271,17 +484,21 @@
     return result;
   }
 
-  uint32_t CompileAndAdd(TestingModule* module) {
-    uint32_t index = 0;
-    if (module->module && module->module->functions) {
-      index = static_cast<uint32_t>(module->module->functions->size());
-    }
-    module->AddFunction(env.sig, Compile(module));
-    return index;
+  // TODO(titzer): remove me.
+  uint32_t CompileAndAdd(uint16_t sig_index = 0) {
+    CHECK(testing_module_);
+    function()->sig_index = sig_index;
+    Handle<Code> code = Compile();
+    testing_module_->SetFunctionCode(function_index_, code);
+    return static_cast<uint32_t>(function_index_);
+  }
+
+  WasmFunction* function() {
+    if (function_) return function_;
+    return &testing_module_->module->functions->at(function_index_);
   }
 };
 
-
 // A helper class to build graphs from Wasm bytecode, generate machine
 // code, and run that code.
 template <typename ReturnType>
@@ -291,11 +508,28 @@
              MachineType p1 = MachineType::None(),
              MachineType p2 = MachineType::None(),
              MachineType p3 = MachineType::None())
-      : signature_(MachineTypeForC<ReturnType>() == MachineType::None() ? 0 : 1,
+      : compiled_(false),
+
+        signature_(MachineTypeForC<ReturnType>() == MachineType::None() ? 0 : 1,
                    GetParameterCount(p0, p1, p2, p3), storage_),
-        compiler_(&signature_),
-        call_wrapper_(p0, p1, p2, p3),
-        compilation_done_(false) {
+        compiler_(&signature_, nullptr) {
+    InitSigStorage(p0, p1, p2, p3);
+  }
+
+  WasmRunner(TestingModule* module, MachineType p0 = MachineType::None(),
+             MachineType p1 = MachineType::None(),
+             MachineType p2 = MachineType::None(),
+             MachineType p3 = MachineType::None())
+      : compiled_(false),
+        signature_(MachineTypeForC<ReturnType>() == MachineType::None() ? 0 : 1,
+                   GetParameterCount(p0, p1, p2, p3), storage_),
+        compiler_(&signature_, module) {
+    DCHECK(module);
+    InitSigStorage(p0, p1, p2, p3);
+  }
+
+  void InitSigStorage(MachineType p0, MachineType p1, MachineType p2,
+                      MachineType p3) {
     int index = 0;
     MachineType ret = MachineTypeForC<ReturnType>();
     if (ret != MachineType::None()) {
@@ -309,56 +543,60 @@
       storage_[index++] = WasmOpcodes::LocalTypeFor(p2);
     if (p3 != MachineType::None())
       storage_[index++] = WasmOpcodes::LocalTypeFor(p3);
-  }
 
+    compiler_.InitializeDescriptor();
+    wrapper_.Init(compiler_.descriptor(), p0, p1, p2, p3);
+  }
 
   FunctionEnv* env() { return &compiler_.env; }
 
-
-  // Builds a graph from the given Wasm code, and generates the machine
+  // Builds a graph from the given Wasm code and generates the machine
   // code and call wrapper for that graph. This method must not be called
   // more than once.
   void Build(const byte* start, const byte* end) {
-    DCHECK(!compilation_done_);
-    compilation_done_ = true;
-    // Build the TF graph.
+    CHECK(!compiled_);
+    compiled_ = true;
+
+    // Build the TF graph within the compiler.
     compiler_.Build(start, end);
     // Generate code.
-    Handle<Code> code = compiler_.Compile(env()->module);
+    Handle<Code> code = compiler_.Compile();
 
-    // 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);
+    if (compiler_.testing_module_) {
+      // Update the table of function code in the module.
+      compiler_.testing_module_->SetFunctionCode(compiler_.function_index_,
+                                                 code);
     }
 
-    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(0, 0, 0, 0); }
 
   template <typename P0>
   ReturnType Call(P0 p0) {
-    return call_wrapper_.Call(p0);
+    return Call(p0, 0, 0, 0);
   }
 
   template <typename P0, typename P1>
   ReturnType Call(P0 p0, P1 p1) {
-    return call_wrapper_.Call(p0, p1);
+    return Call(p0, p1, 0, 0);
   }
 
   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, 0);
   }
 
   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(WASM_WRAPPER_RETURN_VALUE, result);
+    return return_value;
   }
 
   byte AllocateLocal(LocalType type) {
@@ -369,12 +607,13 @@
     return b;
   }
 
- private:
-  LocalType storage_[5];
+ protected:
+  Zone zone;
+  bool compiled_;
+  LocalType storage_[WASM_RUNNER_MAX_NUM_PARAMETERS];
   FunctionSig signature_;
   WasmFunctionCompiler compiler_;
-  BufferedRawMachineAssemblerTester<ReturnType> call_wrapper_;
-  bool compilation_done_;
+  WasmFunctionWrapper<ReturnType> wrapper_;
 
   static size_t GetParameterCount(MachineType p0, MachineType p1,
                                   MachineType p2, MachineType p3) {