Skip to content

Commit

Permalink
Use getTempRet0/setTempRet0 in LegalizeJSInterface.cpp (#1709)
Browse files Browse the repository at this point in the history
Its simpler if we always import these functions from
the embedder rather then synthesizing them various
placed.

This is part of a 4 part change:
LLVM: https://reviews.llvm.org/D53240
fastcomp: emscripten-core/emscripten-fastcomp#237
emscripten: emscripten-core/emscripten#7358
binaryen: emscripten-core/emscripten#7358

Fixes: emscripten-core/emscripten#7273
Fixes: emscripten-core/emscripten#7304
  • Loading branch information
sbc100 authored Nov 20, 2018
1 parent 7ca9e24 commit 4433567
Show file tree
Hide file tree
Showing 20 changed files with 326 additions and 445 deletions.
83 changes: 26 additions & 57 deletions src/passes/LegalizeJSInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,16 @@

#include "wasm.h"
#include "pass.h"
#include "asm_v_wasm.h"
#include "asmjs/shared-constants.h"
#include "wasm-builder.h"
#include "ir/function-type-utils.h"
#include "ir/import-utils.h"
#include "ir/literal-utils.h"
#include "ir/utils.h"

namespace wasm {

Name TEMP_RET_0("tempRet0");
Name GET_TEMP_RET_0("getTempRet0");
Name SET_TEMP_RET_0("setTempRet0");

Expand Down Expand Up @@ -103,18 +105,12 @@ struct LegalizeJSInterface : public Pass {
passRunner.add<FixImports>(&illegalImportsToLegal);
passRunner.run();
}

if (needTempRet0Helpers) {
addTempRet0Helpers(module);
}
}

private:
// map of illegal to legal names for imports
std::map<Name, Name> illegalImportsToLegal;

bool needTempRet0Helpers = false;

template<typename T>
bool isIllegal(T* t) {
for (auto param : t->params) {
Expand All @@ -124,6 +120,7 @@ struct LegalizeJSInterface : public Pass {
return false;
}


// JS calls the export, so it must call a legal stub that calls the actual wasm function
Name makeLegalStub(Function* func, Module* module) {
Builder builder(*module);
Expand All @@ -149,15 +146,12 @@ struct LegalizeJSInterface : public Pass {
}

if (func->result == i64) {
Function* f = getFunctionOrImport(module, SET_TEMP_RET_0, "vi");
legal->result = i32;
auto index = builder.addVar(legal, Name(), i64);
auto* block = builder.makeBlock();
block->list.push_back(builder.makeSetLocal(index, call));
ensureTempRet0(module);
block->list.push_back(builder.makeSetGlobal(
TEMP_RET_0,
I64Utilities::getI64High(builder, index)
));
block->list.push_back(builder.makeCall(f->name, {I64Utilities::getI64High(builder, index)}, none));
block->list.push_back(I64Utilities::getI64Low(builder, index));
block->finalize();
legal->body = block;
Expand Down Expand Up @@ -211,10 +205,9 @@ struct LegalizeJSInterface : public Pass {
}

if (imFunctionType->result == i64) {
Function* f = getFunctionOrImport(module, GET_TEMP_RET_0, "i");
call->type = i32;
Expression* get;
ensureTempRet0(module);
get = builder.makeGetGlobal(TEMP_RET_0, i32);
Expression* get = builder.makeCall(f->name, {}, call->type);
func->body = I64Utilities::recreateI64(builder, call, get);
type->result = i32;
} else if (imFunctionType->result == f32) {
Expand All @@ -241,50 +234,26 @@ struct LegalizeJSInterface : public Pass {
return func->name;
}

void ensureTempRet0(Module* module) {
if (!module->getGlobalOrNull(TEMP_RET_0)) {
module->addGlobal(Builder::makeGlobal(
TEMP_RET_0,
i32,
LiteralUtils::makeZero(i32, *module),
Builder::Mutable
));
needTempRet0Helpers = true;
static Function* getFunctionOrImport(Module* module, Name name, std::string sig) {
// First look for the function by name
if (Function* f = module->getFunctionOrNull(name)) {
return f;
}
}

void addTempRet0Helpers(Module* module) {
// We should also let JS access the tempRet0 global, which
// is necessary to send/receive 64-bit return values.
auto exportIt = [&](Function* func) {
auto* export_ = new Export;
export_->name = func->name;
export_->value = func->name;
export_->kind = ExternalKind::Function;
module->addExport(export_);
};
if (!module->getExportOrNull(GET_TEMP_RET_0)) {
Builder builder(*module);
auto* func = new Function();
func->name = GET_TEMP_RET_0;
func->result = i32;
func->body = builder.makeGetGlobal(TEMP_RET_0, i32);
module->addFunction(func);
exportIt(func);
}
if (!module->getExportOrNull(SET_TEMP_RET_0)) {
Builder builder(*module);
auto* func = new Function();
func->name = SET_TEMP_RET_0;
func->result = none;
func->params.push_back(i32);
func->body = builder.makeSetGlobal(
TEMP_RET_0,
builder.makeGetLocal(0, i32)
);
module->addFunction(func);
exportIt(func);
// Then see if its already imported
ImportInfo info(*module);
if (Function* f = info.getImportedFunction(ENV, name)) {
return f;
}
// Failing that create a new function import.
auto import = new Function;
import->name = name;
import->module = ENV;
import->base = name;
auto* functionType = ensureFunctionType(sig, module);
import->type = functionType->name;
FunctionTypeUtils::fillFunction(import, functionType);
module->addFunction(import);
return import;
}
};

Expand Down
14 changes: 8 additions & 6 deletions test/i64-setTempRet0.fromasm
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
(module
(type $legaltype$illegalImportResult (func (result i32)))
(type $FUNCSIG$vi (func (param i32)))
(type $FUNCSIG$i (func (result i32)))
(import "env" "memory" (memory $memory 256 256))
(data (get_global $__memory_base) "i64-setTempRet0.asm.js")
(import "env" "__memory_base" (global $__memory_base i32))
(import "env" "setTempRet0" (func $setTempRet0 (param i32)))
(import "env" "getTempRet0" (func $getTempRet0 (result i32)))
(import "env" "illegalImportResult" (func $legalimport$illegalImportResult (result i32)))
(global $tempRet0 (mut i32) (i32.const 0))
(export "illegalResult" (func $legalstub$illegalResult))
(export "imports" (func $imports))
(func $imports (; 1 ;) (; has Stack IR ;) (result i32)
(func $imports (; 3 ;) (; has Stack IR ;) (result i32)
(i32.wrap/i64
(i64.or
(i64.extend_u/i32
(call $legalimport$illegalImportResult)
)
(i64.shl
(i64.extend_u/i32
(get_global $tempRet0)
(call $getTempRet0)
)
(i64.const 32)
)
)
)
)
(func $legalstub$illegalResult (; 2 ;) (; has Stack IR ;) (result i32)
(set_global $tempRet0
(func $legalstub$illegalResult (; 4 ;) (; has Stack IR ;) (result i32)
(call $setTempRet0
(i32.const 2)
)
(i32.const 1)
Expand Down
14 changes: 8 additions & 6 deletions test/i64-setTempRet0.fromasm.clamp
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
(module
(type $legaltype$illegalImportResult (func (result i32)))
(type $FUNCSIG$vi (func (param i32)))
(type $FUNCSIG$i (func (result i32)))
(import "env" "memory" (memory $memory 256 256))
(data (get_global $__memory_base) "i64-setTempRet0.asm.js")
(import "env" "__memory_base" (global $__memory_base i32))
(import "env" "setTempRet0" (func $setTempRet0 (param i32)))
(import "env" "getTempRet0" (func $getTempRet0 (result i32)))
(import "env" "illegalImportResult" (func $legalimport$illegalImportResult (result i32)))
(global $tempRet0 (mut i32) (i32.const 0))
(export "illegalResult" (func $legalstub$illegalResult))
(export "imports" (func $imports))
(func $imports (; 1 ;) (; has Stack IR ;) (result i32)
(func $imports (; 3 ;) (; has Stack IR ;) (result i32)
(i32.wrap/i64
(i64.or
(i64.extend_u/i32
(call $legalimport$illegalImportResult)
)
(i64.shl
(i64.extend_u/i32
(get_global $tempRet0)
(call $getTempRet0)
)
(i64.const 32)
)
)
)
)
(func $legalstub$illegalResult (; 2 ;) (; has Stack IR ;) (result i32)
(set_global $tempRet0
(func $legalstub$illegalResult (; 4 ;) (; has Stack IR ;) (result i32)
(call $setTempRet0
(i32.const 2)
)
(i32.const 1)
Expand Down
16 changes: 10 additions & 6 deletions test/i64-setTempRet0.fromasm.clamp.no-opts
Original file line number Diff line number Diff line change
@@ -1,32 +1,36 @@
(module
(type $FUNCSIG$j (func (result i64)))
(type $FUNCSIG$vi (func (param i32)))
(type $FUNCSIG$i (func (result i32)))
(type $legaltype$illegalImportResult (func (result i32)))
(import "env" "memory" (memory $memory 256 256))
(import "env" "table" (table $table 0 0 anyfunc))
(import "env" "__memory_base" (global $__memory_base i32))
(import "env" "__table_base" (global $__table_base i32))
(import "env" "setTempRet0" (func $setTempRet0 (param i32)))
(import "env" "getTempRet0" (func $getTempRet0 (result i32)))
(import "env" "illegalImportResult" (func $legalimport$illegalImportResult (result i32)))
(global $tempRet0 (mut i32) (i32.const 0))
(export "illegalResult" (func $legalstub$illegalResult))
(export "imports" (func $imports))
(func $illegalResult (; 1 ;) (result i64)
(func $illegalResult (; 3 ;) (result i64)
(return
(i64.const 8589934593)
)
)
(func $imports (; 2 ;) (result i32)
(func $imports (; 4 ;) (result i32)
(return
(i32.wrap/i64
(call $legalfunc$illegalImportResult)
)
)
)
(func $legalstub$illegalResult (; 3 ;) (result i32)
(func $legalstub$illegalResult (; 5 ;) (result i32)
(local $0 i64)
(set_local $0
(call $illegalResult)
)
(set_global $tempRet0
(call $setTempRet0
(i32.wrap/i64
(i64.shr_u
(get_local $0)
Expand All @@ -38,14 +42,14 @@
(get_local $0)
)
)
(func $legalfunc$illegalImportResult (; 4 ;) (result i64)
(func $legalfunc$illegalImportResult (; 6 ;) (result i64)
(i64.or
(i64.extend_u/i32
(call $legalimport$illegalImportResult)
)
(i64.shl
(i64.extend_u/i32
(get_global $tempRet0)
(call $getTempRet0)
)
(i64.const 32)
)
Expand Down
14 changes: 8 additions & 6 deletions test/i64-setTempRet0.fromasm.imprecise
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
(module
(type $legaltype$illegalImportResult (func (result i32)))
(type $FUNCSIG$vi (func (param i32)))
(type $FUNCSIG$i (func (result i32)))
(import "env" "setTempRet0" (func $setTempRet0 (param i32)))
(import "env" "getTempRet0" (func $getTempRet0 (result i32)))
(import "env" "illegalImportResult" (func $legalimport$illegalImportResult (result i32)))
(global $tempRet0 (mut i32) (i32.const 0))
(export "illegalResult" (func $legalstub$illegalResult))
(export "imports" (func $imports))
(func $imports (; 1 ;) (; has Stack IR ;) (result i32)
(func $imports (; 3 ;) (; has Stack IR ;) (result i32)
(i32.wrap/i64
(i64.or
(i64.extend_u/i32
(call $legalimport$illegalImportResult)
)
(i64.shl
(i64.extend_u/i32
(get_global $tempRet0)
(call $getTempRet0)
)
(i64.const 32)
)
)
)
)
(func $legalstub$illegalResult (; 2 ;) (; has Stack IR ;) (result i32)
(set_global $tempRet0
(func $legalstub$illegalResult (; 4 ;) (; has Stack IR ;) (result i32)
(call $setTempRet0
(i32.const 2)
)
(i32.const 1)
Expand Down
16 changes: 10 additions & 6 deletions test/i64-setTempRet0.fromasm.imprecise.no-opts
Original file line number Diff line number Diff line change
@@ -1,32 +1,36 @@
(module
(type $FUNCSIG$j (func (result i64)))
(type $FUNCSIG$vi (func (param i32)))
(type $FUNCSIG$i (func (result i32)))
(type $legaltype$illegalImportResult (func (result i32)))
(import "env" "memory" (memory $memory 256 256))
(import "env" "table" (table $table 0 0 anyfunc))
(import "env" "__memory_base" (global $__memory_base i32))
(import "env" "__table_base" (global $__table_base i32))
(import "env" "setTempRet0" (func $setTempRet0 (param i32)))
(import "env" "getTempRet0" (func $getTempRet0 (result i32)))
(import "env" "illegalImportResult" (func $legalimport$illegalImportResult (result i32)))
(global $tempRet0 (mut i32) (i32.const 0))
(export "illegalResult" (func $legalstub$illegalResult))
(export "imports" (func $imports))
(func $illegalResult (; 1 ;) (result i64)
(func $illegalResult (; 3 ;) (result i64)
(return
(i64.const 8589934593)
)
)
(func $imports (; 2 ;) (result i32)
(func $imports (; 4 ;) (result i32)
(return
(i32.wrap/i64
(call $legalfunc$illegalImportResult)
)
)
)
(func $legalstub$illegalResult (; 3 ;) (result i32)
(func $legalstub$illegalResult (; 5 ;) (result i32)
(local $0 i64)
(set_local $0
(call $illegalResult)
)
(set_global $tempRet0
(call $setTempRet0
(i32.wrap/i64
(i64.shr_u
(get_local $0)
Expand All @@ -38,14 +42,14 @@
(get_local $0)
)
)
(func $legalfunc$illegalImportResult (; 4 ;) (result i64)
(func $legalfunc$illegalImportResult (; 6 ;) (result i64)
(i64.or
(i64.extend_u/i32
(call $legalimport$illegalImportResult)
)
(i64.shl
(i64.extend_u/i32
(get_global $tempRet0)
(call $getTempRet0)
)
(i64.const 32)
)
Expand Down
Loading

0 comments on commit 4433567

Please sign in to comment.