Index: src/compiler/wasm-compiler.cc |
diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc |
index fd697f717cc38e2e6a24d6fa199578d97f63460c..8448f2ccf3dca8a5d91c3ea4173c708cee9fdd97 100644 |
--- a/src/compiler/wasm-compiler.cc |
+++ b/src/compiler/wasm-compiler.cc |
@@ -2203,8 +2203,12 @@ Node* WasmGraphBuilder::ToJS(Node* node, Node* context, wasm::LocalType type) { |
case wasm::kAstI64: |
// TODO(titzer): i64->JS has no good solution right now. Using lower 32 |
// bits. |
- node = |
- graph()->NewNode(jsgraph()->machine()->TruncateInt64ToInt32(), node); |
+ if (jsgraph()->machine()->Is64()) { |
+ // On 32 bit platforms we do not have to do the truncation because the |
+ // node we get in as a parameter only contains the low word anyways. |
+ node = graph()->NewNode(jsgraph()->machine()->TruncateInt64ToInt32(), |
+ node); |
+ } |
return BuildChangeInt32ToTagged(node); |
case wasm::kAstF32: |
node = graph()->NewNode(jsgraph()->machine()->ChangeFloat32ToFloat64(), |
@@ -2369,7 +2373,11 @@ Node* WasmGraphBuilder::FromJS(Node* node, Node* context, |
num = graph()->NewNode(jsgraph()->machine()->TruncateFloat64ToInt32( |
TruncationMode::kJavaScript), |
num); |
- num = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), num); |
+ if (jsgraph()->machine()->Is64()) { |
+ // We cannot change an int32 to an int64 on a 32 bit platform. Instead |
+ // we will split the parameter node later. |
+ num = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), num); |
+ } |
break; |
case wasm::kAstF32: |
num = graph()->NewNode(jsgraph()->machine()->TruncateFloat64ToFloat32(), |
@@ -2459,28 +2467,40 @@ Node* WasmGraphBuilder::BuildHeapNumberValueIndexConstant() { |
void WasmGraphBuilder::BuildJSToWasmWrapper(Handle<Code> wasm_code, |
wasm::FunctionSig* sig) { |
- int params = static_cast<int>(sig->parameter_count()); |
- int count = params + 3; |
+ int wasm_count = static_cast<int>(sig->parameter_count()); |
+ int param_count; |
+ if (jsgraph()->machine()->Is64()) { |
+ param_count = static_cast<int>(sig->parameter_count()); |
+ } else { |
+ param_count = Int64Lowering::GetParameterCountAfterLowering(sig); |
+ } |
+ int count = param_count + 3; |
Node** args = Buffer(count); |
// Build the start and the JS parameter nodes. |
- Node* start = Start(params + 5); |
+ Node* start = Start(param_count + 5); |
*control_ = start; |
*effect_ = start; |
// Create the context parameter |
Node* context = graph()->NewNode( |
jsgraph()->common()->Parameter( |
- Linkage::GetJSCallContextParamIndex(params + 1), "%context"), |
+ Linkage::GetJSCallContextParamIndex(wasm_count + 1), "%context"), |
graph()->start()); |
int pos = 0; |
args[pos++] = Constant(wasm_code); |
// Convert JS parameters to WASM numbers. |
- for (int i = 0; i < params; i++) { |
+ for (int i = 0; i < wasm_count; i++) { |
Node* param = |
graph()->NewNode(jsgraph()->common()->Parameter(i + 1), start); |
- args[pos++] = FromJS(param, context, sig->GetParam(i)); |
+ Node* wasm_param = FromJS(param, context, sig->GetParam(i)); |
+ args[pos++] = wasm_param; |
+ if (jsgraph()->machine()->Is32() && sig->GetParam(i) == wasm::kAstI64) { |
+ // We make up the high word with SAR to get the proper sign extension. |
+ args[pos++] = graph()->NewNode(jsgraph()->machine()->Word32Sar(), |
+ wasm_param, jsgraph()->Int32Constant(31)); |
+ } |
} |
args[pos++] = *effect_; |
@@ -2489,9 +2509,18 @@ void WasmGraphBuilder::BuildJSToWasmWrapper(Handle<Code> wasm_code, |
// Call the WASM code. |
CallDescriptor* desc = |
wasm::ModuleEnv::GetWasmCallDescriptor(jsgraph()->zone(), sig); |
+ if (jsgraph()->machine()->Is32()) { |
+ desc = wasm::ModuleEnv::GetI32WasmCallDescriptor(jsgraph()->zone(), desc); |
+ } |
Node* call = graph()->NewNode(jsgraph()->common()->Call(desc), count, args); |
+ Node* retval = call; |
+ if (jsgraph()->machine()->Is32() && sig->return_count() > 0 && |
+ sig->GetReturn(0) == wasm::kAstI64) { |
+ // The return values comes as two values, we pick the low word. |
+ retval = graph()->NewNode(jsgraph()->common()->Projection(0), retval); |
+ } |
Node* jsval = |
- ToJS(call, context, |
+ ToJS(retval, context, |
sig->return_count() == 0 ? wasm::kAstStmt : sig->GetReturn()); |
Node* ret = |
graph()->NewNode(jsgraph()->common()->Return(), jsval, call, start); |
@@ -2504,11 +2533,17 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSFunction> function, |
wasm::FunctionSig* sig) { |
int js_count = function->shared()->internal_formal_parameter_count(); |
int wasm_count = static_cast<int>(sig->parameter_count()); |
+ int param_count; |
+ if (jsgraph()->machine()->Is64()) { |
+ param_count = wasm_count; |
+ } else { |
+ param_count = Int64Lowering::GetParameterCountAfterLowering(sig); |
+ } |
// Build the start and the parameter nodes. |
Isolate* isolate = jsgraph()->isolate(); |
CallDescriptor* desc; |
- Node* start = Start(wasm_count + 3); |
+ Node* start = Start(param_count + 3); |
*effect_ = start; |
*control_ = start; |
// JS context is the last parameter. |
@@ -2544,9 +2579,15 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSFunction> function, |
args[pos++] = jsgraph()->Constant(global); |
// Convert WASM numbers to JS values. |
+ int param_index = 0; |
for (int i = 0; i < wasm_count; i++) { |
- Node* param = graph()->NewNode(jsgraph()->common()->Parameter(i), start); |
+ Node* param = |
+ graph()->NewNode(jsgraph()->common()->Parameter(param_index++), start); |
args[pos++] = ToJS(param, context, sig->GetParam(i)); |
+ if (jsgraph()->machine()->Is32() && sig->GetParam(i) == wasm::kAstI64) { |
+ // On 32 bit platforms we have to skip the high word of int64 parameters. |
+ param_index++; |
+ } |
} |
if (add_new_target_undefined) { |
@@ -2563,10 +2604,19 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSFunction> function, |
Node* call = graph()->NewNode(jsgraph()->common()->Call(desc), pos, args); |
// Convert the return value back. |
+ Node* ret; |
Node* val = |
FromJS(call, context, |
sig->return_count() == 0 ? wasm::kAstStmt : sig->GetReturn()); |
- Node* ret = graph()->NewNode(jsgraph()->common()->Return(), val, call, start); |
+ if (jsgraph()->machine()->Is32() && sig->return_count() > 0 && |
+ sig->GetReturn() == wasm::kAstI64) { |
+ ret = graph()->NewNode(jsgraph()->common()->Return(), val, |
+ graph()->NewNode(jsgraph()->machine()->Word32Sar(), |
+ val, jsgraph()->Int32Constant(31)), |
+ call, start); |
+ } else { |
+ ret = graph()->NewNode(jsgraph()->common()->Return(), val, call, start); |
+ } |
MergeControlToEnd(jsgraph(), ret); |
} |
@@ -2890,6 +2940,9 @@ Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, wasm::ModuleEnv* module, |
// Schedule and compile to machine code. |
CallDescriptor* incoming = |
wasm::ModuleEnv::GetWasmCallDescriptor(&zone, sig); |
+ if (machine.Is32()) { |
+ incoming = wasm::ModuleEnv::GetI32WasmCallDescriptor(&zone, incoming); |
+ } |
Code::Flags flags = Code::ComputeFlags(Code::WASM_TO_JS_FUNCTION); |
bool debugging = |
#if DEBUG |
@@ -2960,6 +3013,11 @@ Handle<Code> CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate, |
wasm::TreeResult result = |
wasm::BuildTFGraph(isolate->allocator(), &builder, body); |
+ if (machine.Is32()) { |
+ Int64Lowering r(&graph, &machine, &common, &zone, function.sig); |
+ r.LowerGraph(); |
+ } |
+ |
if (result.failed()) { |
if (FLAG_trace_wasm_compiler) { |
OFStream os(stdout); |