diff --git a/src/compiler/int64-lowering.cc b/src/compiler/int64-lowering.cc index c2952319be..c9c87b65d6 100644 --- a/src/compiler/int64-lowering.cc +++ b/src/compiler/int64-lowering.cc @@ -5,8 +5,12 @@ #include "src/compiler/int64-lowering.h" #include "src/compiler/common-operator.h" #include "src/compiler/graph.h" +#include "src/compiler/linkage.h" #include "src/compiler/machine-operator.h" +#include "src/compiler/node-properties.h" + #include "src/compiler/node.h" +#include "src/wasm/wasm-module.h" #include "src/zone.h" namespace v8 { @@ -14,17 +18,23 @@ namespace internal { namespace compiler { Int64Lowering::Int64Lowering(Graph* graph, MachineOperatorBuilder* machine, - CommonOperatorBuilder* common, Zone* zone) - : graph_(graph), + CommonOperatorBuilder* common, Zone* zone, + Signature* signature) + : zone_(zone), + graph_(graph), machine_(machine), common_(common), state_(graph, 4), stack_(zone), - replacements_(zone->NewArray(graph->NodeCount())) { + replacements_(zone->NewArray(graph->NodeCount())), + signature_(signature) { memset(replacements_, 0, sizeof(Replacement) * graph->NodeCount()); } -void Int64Lowering::ReduceGraph() { +void Int64Lowering::LowerGraph() { + if (4 != kPointerSize) { + return; + } stack_.push(graph()->end()); state_.Set(graph()->end(), State::kOnStack); @@ -34,7 +44,7 @@ void Int64Lowering::ReduceGraph() { stack_.pop(); state_.Set(top, State::kVisited); // All inputs of top have already been reduced, now reduce top. - ReduceNode(top); + LowerNode(top); } else { // Push all children onto the stack. for (Node* input : top->inputs()) { @@ -48,7 +58,35 @@ void Int64Lowering::ReduceGraph() { } } -void Int64Lowering::ReduceNode(Node* node) { +static int GetParameterIndexAfterLowering( + Signature* signature, int old_index) { + int result = old_index; + for (int i = 0; i < old_index; i++) { + if (signature->GetParam(i) == MachineRepresentation::kWord64) { + result++; + } + } + return result; +} + +static int GetParameterCountAfterLowering( + Signature* signature) { + return GetParameterIndexAfterLowering( + signature, static_cast(signature->parameter_count())); +} + +static int GetReturnCountAfterLowering( + Signature* signature) { + int result = static_cast(signature->return_count()); + for (int i = 0; i < static_cast(signature->return_count()); i++) { + if (signature->GetReturn(i) == MachineRepresentation::kWord64) { + result++; + } + } + return result; +} + +void Int64Lowering::LowerNode(Node* node) { switch (node->opcode()) { case IrOpcode::kInt64Constant: { int64_t value = OpParameter(node); @@ -56,48 +94,207 @@ void Int64Lowering::ReduceNode(Node* node) { common()->Int32Constant(static_cast(value & 0xFFFFFFFF))); Node* high_node = graph()->NewNode( common()->Int32Constant(static_cast(value >> 32))); - replacements_[node->id()].low = low_node; - replacements_[node->id()].high = high_node; + ReplaceNode(node, low_node, high_node); + break; + } + case IrOpcode::kLoad: { + LoadRepresentation load_rep = LoadRepresentationOf(node->op()); + + if (load_rep.representation() == MachineRepresentation::kWord64) { + Node* base = node->InputAt(0); + Node* index = node->InputAt(1); + Node* index_high = + graph()->NewNode(machine()->Int32Add(), index, + graph()->NewNode(common()->Int32Constant(4))); + + const Operator* load_op = machine()->Load(MachineType::Int32()); + Node* high_node; + if (node->InputCount() > 2) { + Node* effect_high = node->InputAt(2); + Node* control_high = node->InputAt(3); + high_node = graph()->NewNode(load_op, base, index_high, effect_high, + control_high); + // change the effect change from old_node --> old_effect to + // old_node --> high_node --> old_effect. + node->ReplaceInput(2, high_node); + } else { + high_node = graph()->NewNode(load_op, base, index_high); + } + NodeProperties::ChangeOp(node, load_op); + ReplaceNode(node, node, high_node); + } + break; + } + case IrOpcode::kStore: { + StoreRepresentation store_rep = StoreRepresentationOf(node->op()); + if (store_rep.representation() == MachineRepresentation::kWord64) { + // We change the original store node to store the low word, and create + // a new store node to store the high word. The effect and control edges + // are copied from the original store to the new store node, the effect + // edge of the original store is redirected to the new store. + WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); + + Node* base = node->InputAt(0); + Node* index = node->InputAt(1); + Node* index_high = + graph()->NewNode(machine()->Int32Add(), index, + graph()->NewNode(common()->Int32Constant(4))); + + Node* value = node->InputAt(2); + DCHECK(HasReplacementLow(value)); + DCHECK(HasReplacementHigh(value)); + + const Operator* store_op = machine()->Store(StoreRepresentation( + MachineRepresentation::kWord32, write_barrier_kind)); + + Node* high_node; + if (node->InputCount() > 3) { + Node* effect_high = node->InputAt(3); + Node* control_high = node->InputAt(4); + high_node = graph()->NewNode(store_op, base, index_high, + GetReplacementHigh(value), effect_high, + control_high); + node->ReplaceInput(3, high_node); + + } else { + high_node = graph()->NewNode(store_op, base, index_high, + GetReplacementHigh(value)); + } + + node->ReplaceInput(2, GetReplacementLow(value)); + NodeProperties::ChangeOp(node, store_op); + ReplaceNode(node, node, high_node); + } break; } case IrOpcode::kWord64And: { + DCHECK(node->InputCount() == 2); Node* left = node->InputAt(0); - DCHECK(replacements_[left->id()].low); - Node* left_low = replacements_[left->id()].low; - Node* left_high = replacements_[left->id()].high; - Node* right = node->InputAt(1); - DCHECK(replacements_[right->id()].low); - Node* right_low = replacements_[right->id()].low; - Node* right_high = replacements_[right->id()].high; - replacements_[node->id()].low = - graph()->NewNode(machine()->Word32And(), left_low, right_low); - replacements_[node->id()].high = - graph()->NewNode(machine()->Word32And(), left_high, right_high); + Node* low_node = + graph()->NewNode(machine()->Word32And(), GetReplacementLow(left), + GetReplacementLow(right)); + Node* high_node = + graph()->NewNode(machine()->Word32And(), GetReplacementHigh(left), + GetReplacementHigh(right)); + ReplaceNode(node, low_node, high_node); break; } case IrOpcode::kTruncateInt64ToInt32: { + DCHECK(node->InputCount() == 1); Node* input = node->InputAt(0); - DCHECK(replacements_[input->id()].low); - replacements_[node->id()].low = replacements_[input->id()].low; + ReplaceNode(node, GetReplacementLow(input), nullptr); + node->NullAllInputs(); break; } - default: { - // Also the inputs of nodes can change which do not expect int64 inputs. - for (int i = 0; i < node->InputCount(); i++) { - Node* input = node->InputAt(i); - // The input has changed altough it was not an int64 input. This can - // happen e.g. if the input node is IrOpcode::kTruncateInt64ToInt32. We - // use the low word replacement as the new input. - if (replacements_[input->id()].low) { - node->ReplaceInput(i, replacements_[input->id()].low); - } + case IrOpcode::kStart: { + int parameter_count = GetParameterCountAfterLowering(signature()); + // Only exchange the node if the parameter count actually changed. + if (parameter_count != signature()->parameter_count()) { + int delta = + parameter_count - static_cast(signature()->parameter_count()); + int new_output_count = node->op()->ValueOutputCount() + delta; + NodeProperties::ChangeOp(node, common()->Start(new_output_count)); } + break; } + case IrOpcode::kParameter: { + DCHECK(node->InputCount() == 1); + // Only exchange the node if the parameter count actually changed. We do + // not even have to do the default lowering because the the start node, + // the only input of a parameter node, only changes if the parameter count + // changes. + if (GetParameterCountAfterLowering(signature()) != + signature()->parameter_count()) { + int old_index = ParameterIndexOf(node->op()); + int new_index = GetParameterIndexAfterLowering(signature(), old_index); + Node* low_node = + graph()->NewNode(common()->Parameter(new_index), graph()->start()); + + Node* high_node = nullptr; + if (signature()->GetParam(old_index) == + MachineRepresentation::kWord64) { + high_node = graph()->NewNode(common()->Parameter(new_index + 1), + graph()->start()); + } + ReplaceNode(node, low_node, high_node); + } + break; + } + case IrOpcode::kReturn: { + DefaultLowering(node); + int new_return_count = GetReturnCountAfterLowering(signature()); + if (signature()->return_count() != new_return_count) { + NodeProperties::ChangeOp(node, common()->Return(new_return_count)); + } + break; + } + case IrOpcode::kCall: { + CallDescriptor* descriptor = OpParameter(node); + if (DefaultLowering(node) || + (descriptor->ReturnCount() == 1 && + descriptor->GetReturnType(0) == MachineType::Int64())) { + // We have to adjust the call descriptor. + const Operator* op = common()->Call( + wasm::ModuleEnv::GetI32WasmCallDescriptor(zone(), descriptor)); + NodeProperties::ChangeOp(node, op); + } + if (descriptor->ReturnCount() == 1 && + descriptor->GetReturnType(0) == MachineType::Int64()) { + // We access the additional return values through projections. + Node* low_node = graph()->NewNode(common()->Projection(0), node); + Node* high_node = graph()->NewNode(common()->Projection(1), node); + ReplaceNode(node, low_node, high_node); + } + break; + } + default: { DefaultLowering(node); } } } +bool Int64Lowering::DefaultLowering(Node* node) { + bool something_changed = false; + for (int i = NodeProperties::PastValueIndex(node) - 1; i >= 0; i--) { + Node* input = node->InputAt(i); + if (HasReplacementLow(input)) { + something_changed = true; + node->ReplaceInput(i, GetReplacementLow(input)); + } + if (HasReplacementHigh(input)) { + something_changed = true; + node->InsertInput(zone(), i + 1, GetReplacementHigh(input)); + } + } + return something_changed; +} + +void Int64Lowering::ReplaceNode(Node* old, Node* new_low, Node* new_high) { + // if new_low == nullptr, then also new_high == nullptr. + DCHECK(new_low != nullptr || new_high == nullptr); + replacements_[old->id()].low = new_low; + replacements_[old->id()].high = new_high; +} + +bool Int64Lowering::HasReplacementLow(Node* node) { + return replacements_[node->id()].low != nullptr; +} + +Node* Int64Lowering::GetReplacementLow(Node* node) { + Node* result = replacements_[node->id()].low; + DCHECK(result); + return result; +} + +bool Int64Lowering::HasReplacementHigh(Node* node) { + return replacements_[node->id()].high != nullptr; +} + +Node* Int64Lowering::GetReplacementHigh(Node* node) { + Node* result = replacements_[node->id()].high; + DCHECK(result); + return result; +} } // namespace compiler } // namespace internal } // namespace v8 diff --git a/src/compiler/int64-lowering.h b/src/compiler/int64-lowering.h index dcdeae243d..79a95dc195 100644 --- a/src/compiler/int64-lowering.h +++ b/src/compiler/int64-lowering.h @@ -18,12 +18,10 @@ namespace compiler { class Int64Lowering { public: Int64Lowering(Graph* graph, MachineOperatorBuilder* machine, - CommonOperatorBuilder* common, Zone* zone); + CommonOperatorBuilder* common, Zone* zone, + Signature* signature); - void ReduceGraph(); - Graph* graph() const { return graph_; } - MachineOperatorBuilder* machine() const { return machine_; } - CommonOperatorBuilder* common() const { return common_; } + void LowerGraph(); private: enum class State : uint8_t { kUnvisited, kOnStack, kInputsPushed, kVisited }; @@ -33,15 +31,29 @@ class Int64Lowering { Node* high; }; - void ReduceTop(); - void ReduceNode(Node* node); + Zone* zone() const { return zone_; } + Graph* graph() const { return graph_; } + MachineOperatorBuilder* machine() const { return machine_; } + CommonOperatorBuilder* common() const { return common_; } + Signature* signature() const { return signature_; } + void LowerNode(Node* node); + bool DefaultLowering(Node* node); + + void ReplaceNode(Node* old, Node* new_low, Node* new_high); + bool HasReplacementLow(Node* node); + Node* GetReplacementLow(Node* node); + bool HasReplacementHigh(Node* node); + Node* GetReplacementHigh(Node* node); + + Zone* zone_; Graph* const graph_; MachineOperatorBuilder* machine_; CommonOperatorBuilder* common_; NodeMarker state_; ZoneStack stack_; Replacement* replacements_; + Signature* signature_; }; } // namespace compiler diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc index 115f1962b1..109bfedd36 100644 --- a/src/compiler/wasm-compiler.cc +++ b/src/compiler/wasm-compiler.cc @@ -1484,8 +1484,9 @@ Node* WasmGraphBuilder::BuildWasmCall(wasm::FunctionSig* sig, Node** args) { args[params + 1] = *effect_; args[params + 2] = *control_; - const Operator* op = jsgraph()->common()->Call( - module_->GetWasmCallDescriptor(jsgraph()->zone(), sig)); + CallDescriptor* descriptor = + module_->GetWasmCallDescriptor(jsgraph()->zone(), sig); + const Operator* op = jsgraph()->common()->Call(descriptor); Node* call = graph()->NewNode(op, static_cast(count), args); *effect_ = call; @@ -1909,11 +1910,12 @@ Node* WasmGraphBuilder::String(const char* string) { Graph* WasmGraphBuilder::graph() { return jsgraph()->graph(); } void WasmGraphBuilder::Int64LoweringForTesting() { -#if !WASM_64 - Int64Lowering r(jsgraph()->graph(), jsgraph()->machine(), jsgraph()->common(), - jsgraph()->zone()); - r.ReduceGraph(); -#endif + if (kPointerSize == 4) { + Int64Lowering r(jsgraph()->graph(), jsgraph()->machine(), + jsgraph()->common(), jsgraph()->zone(), + function_signature_); + r.LowerGraph(); + } } static void RecordFunctionCompilation(Logger::LogEventsAndTags tag, @@ -2127,8 +2129,11 @@ Handle CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate, } // Run the compiler pipeline to generate machine code. - CallDescriptor* descriptor = const_cast( - module_env->GetWasmCallDescriptor(&zone, function.sig)); + CallDescriptor* descriptor = + module_env->GetWasmCallDescriptor(&zone, function.sig); + if (kPointerSize == 4) { + descriptor = module_env->GetI32WasmCallDescriptor(&zone, descriptor); + } Code::Flags flags = Code::ComputeFlags(Code::WASM_FUNCTION); // add flags here if a meaningful name is helpful for debugging. bool debugging = diff --git a/src/compiler/wasm-linkage.cc b/src/compiler/wasm-linkage.cc index 7dd36621e9..09a697ed8a 100644 --- a/src/compiler/wasm-linkage.cc +++ b/src/compiler/wasm-linkage.cc @@ -191,15 +191,7 @@ struct Allocator { }; } // namespace - -// General code uses the above configuration data. -CallDescriptor* ModuleEnv::GetWasmCallDescriptor(Zone* zone, - FunctionSig* fsig) { - MachineSignature::Builder msig(zone, fsig->return_count(), - fsig->parameter_count()); - LocationSignature::Builder locations(zone, fsig->return_count(), - fsig->parameter_count()); - +static Allocator GetReturnRegisters() { #ifdef GP_RETURN_REGISTERS static const Register kGPReturnRegisters[] = {GP_RETURN_REGISTERS}; static const int kGPReturnRegistersCount = @@ -221,14 +213,10 @@ CallDescriptor* ModuleEnv::GetWasmCallDescriptor(Zone* zone, Allocator rets(kGPReturnRegisters, kGPReturnRegistersCount, kFPReturnRegisters, kFPReturnRegistersCount); - // Add return location(s). - const int return_count = static_cast(locations.return_count_); - for (int i = 0; i < return_count; i++) { - LocalType ret = fsig->GetReturn(i); - msig.AddReturn(MachineTypeFor(ret)); - locations.AddReturn(rets.Next(ret)); - } + return rets; +} +static Allocator GetParameterRegisters() { #ifdef GP_PARAM_REGISTERS static const Register kGPParamRegisters[] = {GP_PARAM_REGISTERS}; static const int kGPParamRegistersCount = @@ -250,6 +238,29 @@ CallDescriptor* ModuleEnv::GetWasmCallDescriptor(Zone* zone, Allocator params(kGPParamRegisters, kGPParamRegistersCount, kFPParamRegisters, kFPParamRegistersCount); + return params; +} + +// General code uses the above configuration data. +CallDescriptor* ModuleEnv::GetWasmCallDescriptor(Zone* zone, + FunctionSig* fsig) { + MachineSignature::Builder msig(zone, fsig->return_count(), + fsig->parameter_count()); + LocationSignature::Builder locations(zone, fsig->return_count(), + fsig->parameter_count()); + + Allocator rets = GetReturnRegisters(); + + // Add return location(s). + const int return_count = static_cast(locations.return_count_); + for (int i = 0; i < return_count; i++) { + LocalType ret = fsig->GetReturn(i); + msig.AddReturn(MachineTypeFor(ret)); + locations.AddReturn(rets.Next(ret)); + } + + Allocator params = GetParameterRegisters(); + // Add register and/or stack parameter(s). const int parameter_count = static_cast(fsig->parameter_count()); for (int i = 0; i < parameter_count; i++) { @@ -276,8 +287,82 @@ CallDescriptor* ModuleEnv::GetWasmCallDescriptor(Zone* zone, kCalleeSaveRegisters, // callee-saved registers kCalleeSaveFPRegisters, // callee-saved fp regs CallDescriptor::kUseNativeStack, // flags - "c-call"); + "wasm-call"); } + +CallDescriptor* ModuleEnv::GetI32WasmCallDescriptor( + Zone* zone, CallDescriptor* descriptor) { + const MachineSignature* signature = descriptor->GetMachineSignature(); + size_t parameter_count = signature->parameter_count(); + size_t return_count = signature->return_count(); + for (size_t i = 0; i < signature->parameter_count(); i++) { + if (signature->GetParam(i) == MachineType::Int64()) { + // For each int64 input we get two int32 inputs. + parameter_count++; + } + } + for (size_t i = 0; i < signature->return_count(); i++) { + if (signature->GetReturn(i) == MachineType::Int64()) { + // For each int64 return we get two int32 returns. + return_count++; + } + } + if (parameter_count == signature->parameter_count() && + return_count == signature->return_count()) { + // If there is no int64 parameter or return value, we can just return the + // original descriptor. + return descriptor; + } + + MachineSignature::Builder msig(zone, return_count, parameter_count); + LocationSignature::Builder locations(zone, return_count, parameter_count); + + Allocator rets = GetReturnRegisters(); + + for (size_t i = 0; i < signature->return_count(); i++) { + if (signature->GetReturn(i) == MachineType::Int64()) { + // For each int64 return we get two int32 returns. + msig.AddReturn(MachineType::Int32()); + msig.AddReturn(MachineType::Int32()); + locations.AddReturn(rets.Next(MachineRepresentation::kWord32)); + locations.AddReturn(rets.Next(MachineRepresentation::kWord32)); + } else { + msig.AddReturn(signature->GetReturn(i)); + locations.AddReturn(rets.Next(signature->GetReturn(i).representation())); + } + } + + Allocator params = GetParameterRegisters(); + + for (size_t i = 0; i < signature->parameter_count(); i++) { + if (signature->GetParam(i) == MachineType::Int64()) { + // For each int64 input we get two int32 inputs. + msig.AddParam(MachineType::Int32()); + msig.AddParam(MachineType::Int32()); + locations.AddParam(params.Next(MachineRepresentation::kWord32)); + locations.AddParam(params.Next(MachineRepresentation::kWord32)); + } else { + msig.AddParam(signature->GetParam(i)); + locations.AddParam(params.Next(signature->GetParam(i).representation())); + } + } + + return new (zone) CallDescriptor( // -- + descriptor->kind(), // kind + descriptor->GetInputType(0), // target MachineType + descriptor->GetInputLocation(0), // target location + msig.Build(), // machine_sig + locations.Build(), // location_sig + params.stack_offset, // stack_parameter_count + descriptor->properties(), // properties + descriptor->CalleeSavedRegisters(), // callee-saved registers + descriptor->CalleeSavedFPRegisters(), // callee-saved fp regs + descriptor->flags(), // flags + descriptor->debug_name()); + + return descriptor; +} + } // namespace wasm } // namespace internal } // namespace v8 diff --git a/src/wasm/wasm-module.h b/src/wasm/wasm-module.h index cf9aebe7ba..8dc1abc222 100644 --- a/src/wasm/wasm-module.h +++ b/src/wasm/wasm-module.h @@ -191,6 +191,8 @@ struct ModuleEnv { Handle GetFunctionTable(); compiler::CallDescriptor* GetWasmCallDescriptor(Zone* zone, FunctionSig* sig); + static compiler::CallDescriptor* GetI32WasmCallDescriptor( + Zone* zone, compiler::CallDescriptor* descriptor); compiler::CallDescriptor* GetCallDescriptor(Zone* zone, uint32_t index); }; diff --git a/test/cctest/wasm/test-run-wasm.cc b/test/cctest/wasm/test-run-wasm.cc index e4f20dd8fc..448cf96507 100644 --- a/test/cctest/wasm/test-run-wasm.cc +++ b/test/cctest/wasm/test-run-wasm.cc @@ -2473,6 +2473,50 @@ TEST(Run_WasmCallF64StackParameter) { CHECK_EQ(256.5, result); } +TEST(Run_WasmCallI64Parameter) { + // Build the target function. + LocalType param_types[20]; + for (int i = 0; i < 20; i++) param_types[i] = kAstI64; + param_types[3] = kAstI32; + param_types[4] = kAstI32; + FunctionSig sig(1, 19, param_types); + for (int i = 0; i < 19; i++) { + TestingModule module; + WasmFunctionCompiler t(&sig); + if (i == 2 || i == 3) { + continue; + } else { + BUILD(t, WASM_GET_LOCAL(i)); + } + uint32_t index = t.CompileAndAdd(&module); + + // Build the calling function. + WasmRunner r; + r.env()->module = &module; + BUILD(r, + WASM_I32_CONVERT_I64(WASM_CALL_FUNCTION( + index, WASM_I64(0xbcd12340000000b), WASM_I64(0xbcd12340000000c), + WASM_I32(0xd), WASM_I32_CONVERT_I64(WASM_I64(0xbcd12340000000e)), + WASM_I64(0xbcd12340000000f), WASM_I64(0xbcd1234000000010), + WASM_I64(0xbcd1234000000011), WASM_I64(0xbcd1234000000012), + WASM_I64(0xbcd1234000000013), WASM_I64(0xbcd1234000000014), + WASM_I64(0xbcd1234000000015), WASM_I64(0xbcd1234000000016), + WASM_I64(0xbcd1234000000017), WASM_I64(0xbcd1234000000018), + WASM_I64(0xbcd1234000000019), WASM_I64(0xbcd123400000001a), + WASM_I64(0xbcd123400000001b), WASM_I64(0xbcd123400000001c), + WASM_I64(0xbcd123400000001d)))); + + CHECK_EQ(i + 0xb, r.Call()); + } +} + +TEST(Run_WasmI64And) { + WasmRunner r(MachineType::Int64(), MachineType::Int64()); + BUILD(r, WASM_I64_AND(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + FOR_INT64_INPUTS(i) { + FOR_INT64_INPUTS(j) { CHECK_EQ((*i) & (*j), r.Call(*i, *j)); } + } +} TEST(Run_WasmCallVoid) { const byte kMemOffset = 8; diff --git a/test/cctest/wasm/wasm-run-utils.h b/test/cctest/wasm/wasm-run-utils.h index 732516feb6..a90d9c6150 100644 --- a/test/cctest/wasm/wasm-run-utils.h +++ b/test/cctest/wasm/wasm-run-utils.h @@ -46,6 +46,7 @@ CHECK_EQ(0xdeadbeefdeadbeef, (bit_cast(x)) & 0xFFFFFFFFFFFFFFFF) #define CHECK_TRAP(x) CHECK_TRAP32(x) +#define WASM_RUNNER_MAX_NUM_PARAMETERS 4 #define WASM_WRAPPER_RETURN_VALUE 8754 namespace { @@ -260,10 +261,12 @@ class WasmFunctionWrapper : public HandleAndZoneScope, : GraphAndBuilders(main_zone()), inner_code_node_(nullptr), signature_(nullptr) { - Signature::Builder sig_builder(zone(), 1, 5); + // One additional parameter for the pointer to the return value memory. + Signature::Builder sig_builder( + zone(), 1, WASM_RUNNER_MAX_NUM_PARAMETERS + 1); sig_builder.AddReturn(MachineType::Int32()); - for (int i = 0; i < 5; i++) { + for (int i = 0; i < WASM_RUNNER_MAX_NUM_PARAMETERS + 1; i++) { sig_builder.AddParam(MachineType::Pointer()); } signature_ = sig_builder.Build(); @@ -278,7 +281,8 @@ class WasmFunctionWrapper : public HandleAndZoneScope, // the actual test function. // Function, effect, and control. - Node** parameters = zone()->template NewArray(4 + 3); + Node** parameters = + zone()->template NewArray(WASM_RUNNER_MAX_NUM_PARAMETERS + 3); graph()->SetStart(graph()->NewNode(common()->Start(6))); Node* effect = graph()->start(); int parameter_count = 0; @@ -329,7 +333,8 @@ class WasmFunctionWrapper : public HandleAndZoneScope, machine()->Store( StoreRepresentation(MachineTypeForC().representation(), WriteBarrierKind::kNoWriteBarrier)), - graph()->NewNode(common()->Parameter(4), graph()->start()), + graph()->NewNode(common()->Parameter(WASM_RUNNER_MAX_NUM_PARAMETERS), + graph()->start()), graph()->NewNode(common()->Int32Constant(0)), call, effect, graph()->start()); Node* r = graph()->NewNode( @@ -351,6 +356,20 @@ class WasmFunctionWrapper : public HandleAndZoneScope, CallDescriptor* descriptor = Linkage::GetSimplifiedCDescriptor(zone(), signature_, true); + if (kPointerSize == 4) { + // One additional parameter for the pointer of the return value. + Signature::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); @@ -418,9 +437,13 @@ class WasmFunctionCompiler : public HandleAndZoneScope, Handle Compile(ModuleEnv* module) { InitializeDescriptor(); + CallDescriptor* desc = descriptor_; + if (kPointerSize == 4) { + desc = module->GetI32WasmCallDescriptor(this->zone(), desc); + } CompilationInfo info("wasm compile", this->isolate(), this->zone()); Handle 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); @@ -529,7 +552,7 @@ class WasmRunner { } private: - LocalType storage_[5]; + LocalType storage_[WASM_RUNNER_MAX_NUM_PARAMETERS]; FunctionSig signature_; WasmFunctionCompiler compiler_; WasmFunctionWrapper wrapper_;