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

Unified Diff: src/compiler/wasm-compiler.cc

Issue 1899753004: [wasm] Wasm functions with int64 parameters can now be called from JS. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@to-tagged-from-tagged
Patch Set: Created 4 years, 8 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
« no previous file with comments | « src/compiler/int64-lowering.cc ('k') | test/mjsunit/wasm/calls.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
« no previous file with comments | « src/compiler/int64-lowering.cc ('k') | test/mjsunit/wasm/calls.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698