Skip to content

Commit 4433567

Browse files
authored
Use getTempRet0/setTempRet0 in LegalizeJSInterface.cpp (#1709)
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
1 parent 7ca9e24 commit 4433567

20 files changed

+326
-445
lines changed

src/passes/LegalizeJSInterface.cpp

Lines changed: 26 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,16 @@
2828

2929
#include "wasm.h"
3030
#include "pass.h"
31+
#include "asm_v_wasm.h"
32+
#include "asmjs/shared-constants.h"
3133
#include "wasm-builder.h"
3234
#include "ir/function-type-utils.h"
35+
#include "ir/import-utils.h"
3336
#include "ir/literal-utils.h"
3437
#include "ir/utils.h"
3538

3639
namespace wasm {
3740

38-
Name TEMP_RET_0("tempRet0");
3941
Name GET_TEMP_RET_0("getTempRet0");
4042
Name SET_TEMP_RET_0("setTempRet0");
4143

@@ -103,18 +105,12 @@ struct LegalizeJSInterface : public Pass {
103105
passRunner.add<FixImports>(&illegalImportsToLegal);
104106
passRunner.run();
105107
}
106-
107-
if (needTempRet0Helpers) {
108-
addTempRet0Helpers(module);
109-
}
110108
}
111109

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

116-
bool needTempRet0Helpers = false;
117-
118114
template<typename T>
119115
bool isIllegal(T* t) {
120116
for (auto param : t->params) {
@@ -124,6 +120,7 @@ struct LegalizeJSInterface : public Pass {
124120
return false;
125121
}
126122

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

151148
if (func->result == i64) {
149+
Function* f = getFunctionOrImport(module, SET_TEMP_RET_0, "vi");
152150
legal->result = i32;
153151
auto index = builder.addVar(legal, Name(), i64);
154152
auto* block = builder.makeBlock();
155153
block->list.push_back(builder.makeSetLocal(index, call));
156-
ensureTempRet0(module);
157-
block->list.push_back(builder.makeSetGlobal(
158-
TEMP_RET_0,
159-
I64Utilities::getI64High(builder, index)
160-
));
154+
block->list.push_back(builder.makeCall(f->name, {I64Utilities::getI64High(builder, index)}, none));
161155
block->list.push_back(I64Utilities::getI64Low(builder, index));
162156
block->finalize();
163157
legal->body = block;
@@ -211,10 +205,9 @@ struct LegalizeJSInterface : public Pass {
211205
}
212206

213207
if (imFunctionType->result == i64) {
208+
Function* f = getFunctionOrImport(module, GET_TEMP_RET_0, "i");
214209
call->type = i32;
215-
Expression* get;
216-
ensureTempRet0(module);
217-
get = builder.makeGetGlobal(TEMP_RET_0, i32);
210+
Expression* get = builder.makeCall(f->name, {}, call->type);
218211
func->body = I64Utilities::recreateI64(builder, call, get);
219212
type->result = i32;
220213
} else if (imFunctionType->result == f32) {
@@ -241,50 +234,26 @@ struct LegalizeJSInterface : public Pass {
241234
return func->name;
242235
}
243236

244-
void ensureTempRet0(Module* module) {
245-
if (!module->getGlobalOrNull(TEMP_RET_0)) {
246-
module->addGlobal(Builder::makeGlobal(
247-
TEMP_RET_0,
248-
i32,
249-
LiteralUtils::makeZero(i32, *module),
250-
Builder::Mutable
251-
));
252-
needTempRet0Helpers = true;
237+
static Function* getFunctionOrImport(Module* module, Name name, std::string sig) {
238+
// First look for the function by name
239+
if (Function* f = module->getFunctionOrNull(name)) {
240+
return f;
253241
}
254-
}
255-
256-
void addTempRet0Helpers(Module* module) {
257-
// We should also let JS access the tempRet0 global, which
258-
// is necessary to send/receive 64-bit return values.
259-
auto exportIt = [&](Function* func) {
260-
auto* export_ = new Export;
261-
export_->name = func->name;
262-
export_->value = func->name;
263-
export_->kind = ExternalKind::Function;
264-
module->addExport(export_);
265-
};
266-
if (!module->getExportOrNull(GET_TEMP_RET_0)) {
267-
Builder builder(*module);
268-
auto* func = new Function();
269-
func->name = GET_TEMP_RET_0;
270-
func->result = i32;
271-
func->body = builder.makeGetGlobal(TEMP_RET_0, i32);
272-
module->addFunction(func);
273-
exportIt(func);
274-
}
275-
if (!module->getExportOrNull(SET_TEMP_RET_0)) {
276-
Builder builder(*module);
277-
auto* func = new Function();
278-
func->name = SET_TEMP_RET_0;
279-
func->result = none;
280-
func->params.push_back(i32);
281-
func->body = builder.makeSetGlobal(
282-
TEMP_RET_0,
283-
builder.makeGetLocal(0, i32)
284-
);
285-
module->addFunction(func);
286-
exportIt(func);
242+
// Then see if its already imported
243+
ImportInfo info(*module);
244+
if (Function* f = info.getImportedFunction(ENV, name)) {
245+
return f;
287246
}
247+
// Failing that create a new function import.
248+
auto import = new Function;
249+
import->name = name;
250+
import->module = ENV;
251+
import->base = name;
252+
auto* functionType = ensureFunctionType(sig, module);
253+
import->type = functionType->name;
254+
FunctionTypeUtils::fillFunction(import, functionType);
255+
module->addFunction(import);
256+
return import;
288257
}
289258
};
290259

test/i64-setTempRet0.fromasm

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,31 @@
11
(module
2-
(type $legaltype$illegalImportResult (func (result i32)))
2+
(type $FUNCSIG$vi (func (param i32)))
3+
(type $FUNCSIG$i (func (result i32)))
34
(import "env" "memory" (memory $memory 256 256))
45
(data (get_global $__memory_base) "i64-setTempRet0.asm.js")
56
(import "env" "__memory_base" (global $__memory_base i32))
7+
(import "env" "setTempRet0" (func $setTempRet0 (param i32)))
8+
(import "env" "getTempRet0" (func $getTempRet0 (result i32)))
69
(import "env" "illegalImportResult" (func $legalimport$illegalImportResult (result i32)))
7-
(global $tempRet0 (mut i32) (i32.const 0))
810
(export "illegalResult" (func $legalstub$illegalResult))
911
(export "imports" (func $imports))
10-
(func $imports (; 1 ;) (; has Stack IR ;) (result i32)
12+
(func $imports (; 3 ;) (; has Stack IR ;) (result i32)
1113
(i32.wrap/i64
1214
(i64.or
1315
(i64.extend_u/i32
1416
(call $legalimport$illegalImportResult)
1517
)
1618
(i64.shl
1719
(i64.extend_u/i32
18-
(get_global $tempRet0)
20+
(call $getTempRet0)
1921
)
2022
(i64.const 32)
2123
)
2224
)
2325
)
2426
)
25-
(func $legalstub$illegalResult (; 2 ;) (; has Stack IR ;) (result i32)
26-
(set_global $tempRet0
27+
(func $legalstub$illegalResult (; 4 ;) (; has Stack IR ;) (result i32)
28+
(call $setTempRet0
2729
(i32.const 2)
2830
)
2931
(i32.const 1)

test/i64-setTempRet0.fromasm.clamp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,31 @@
11
(module
2-
(type $legaltype$illegalImportResult (func (result i32)))
2+
(type $FUNCSIG$vi (func (param i32)))
3+
(type $FUNCSIG$i (func (result i32)))
34
(import "env" "memory" (memory $memory 256 256))
45
(data (get_global $__memory_base) "i64-setTempRet0.asm.js")
56
(import "env" "__memory_base" (global $__memory_base i32))
7+
(import "env" "setTempRet0" (func $setTempRet0 (param i32)))
8+
(import "env" "getTempRet0" (func $getTempRet0 (result i32)))
69
(import "env" "illegalImportResult" (func $legalimport$illegalImportResult (result i32)))
7-
(global $tempRet0 (mut i32) (i32.const 0))
810
(export "illegalResult" (func $legalstub$illegalResult))
911
(export "imports" (func $imports))
10-
(func $imports (; 1 ;) (; has Stack IR ;) (result i32)
12+
(func $imports (; 3 ;) (; has Stack IR ;) (result i32)
1113
(i32.wrap/i64
1214
(i64.or
1315
(i64.extend_u/i32
1416
(call $legalimport$illegalImportResult)
1517
)
1618
(i64.shl
1719
(i64.extend_u/i32
18-
(get_global $tempRet0)
20+
(call $getTempRet0)
1921
)
2022
(i64.const 32)
2123
)
2224
)
2325
)
2426
)
25-
(func $legalstub$illegalResult (; 2 ;) (; has Stack IR ;) (result i32)
26-
(set_global $tempRet0
27+
(func $legalstub$illegalResult (; 4 ;) (; has Stack IR ;) (result i32)
28+
(call $setTempRet0
2729
(i32.const 2)
2830
)
2931
(i32.const 1)

test/i64-setTempRet0.fromasm.clamp.no-opts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,36 @@
11
(module
22
(type $FUNCSIG$j (func (result i64)))
3+
(type $FUNCSIG$vi (func (param i32)))
4+
(type $FUNCSIG$i (func (result i32)))
35
(type $legaltype$illegalImportResult (func (result i32)))
46
(import "env" "memory" (memory $memory 256 256))
57
(import "env" "table" (table $table 0 0 anyfunc))
68
(import "env" "__memory_base" (global $__memory_base i32))
79
(import "env" "__table_base" (global $__table_base i32))
10+
(import "env" "setTempRet0" (func $setTempRet0 (param i32)))
11+
(import "env" "getTempRet0" (func $getTempRet0 (result i32)))
812
(import "env" "illegalImportResult" (func $legalimport$illegalImportResult (result i32)))
913
(global $tempRet0 (mut i32) (i32.const 0))
1014
(export "illegalResult" (func $legalstub$illegalResult))
1115
(export "imports" (func $imports))
12-
(func $illegalResult (; 1 ;) (result i64)
16+
(func $illegalResult (; 3 ;) (result i64)
1317
(return
1418
(i64.const 8589934593)
1519
)
1620
)
17-
(func $imports (; 2 ;) (result i32)
21+
(func $imports (; 4 ;) (result i32)
1822
(return
1923
(i32.wrap/i64
2024
(call $legalfunc$illegalImportResult)
2125
)
2226
)
2327
)
24-
(func $legalstub$illegalResult (; 3 ;) (result i32)
28+
(func $legalstub$illegalResult (; 5 ;) (result i32)
2529
(local $0 i64)
2630
(set_local $0
2731
(call $illegalResult)
2832
)
29-
(set_global $tempRet0
33+
(call $setTempRet0
3034
(i32.wrap/i64
3135
(i64.shr_u
3236
(get_local $0)
@@ -38,14 +42,14 @@
3842
(get_local $0)
3943
)
4044
)
41-
(func $legalfunc$illegalImportResult (; 4 ;) (result i64)
45+
(func $legalfunc$illegalImportResult (; 6 ;) (result i64)
4246
(i64.or
4347
(i64.extend_u/i32
4448
(call $legalimport$illegalImportResult)
4549
)
4650
(i64.shl
4751
(i64.extend_u/i32
48-
(get_global $tempRet0)
52+
(call $getTempRet0)
4953
)
5054
(i64.const 32)
5155
)

test/i64-setTempRet0.fromasm.imprecise

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
11
(module
2-
(type $legaltype$illegalImportResult (func (result i32)))
2+
(type $FUNCSIG$vi (func (param i32)))
3+
(type $FUNCSIG$i (func (result i32)))
4+
(import "env" "setTempRet0" (func $setTempRet0 (param i32)))
5+
(import "env" "getTempRet0" (func $getTempRet0 (result i32)))
36
(import "env" "illegalImportResult" (func $legalimport$illegalImportResult (result i32)))
4-
(global $tempRet0 (mut i32) (i32.const 0))
57
(export "illegalResult" (func $legalstub$illegalResult))
68
(export "imports" (func $imports))
7-
(func $imports (; 1 ;) (; has Stack IR ;) (result i32)
9+
(func $imports (; 3 ;) (; has Stack IR ;) (result i32)
810
(i32.wrap/i64
911
(i64.or
1012
(i64.extend_u/i32
1113
(call $legalimport$illegalImportResult)
1214
)
1315
(i64.shl
1416
(i64.extend_u/i32
15-
(get_global $tempRet0)
17+
(call $getTempRet0)
1618
)
1719
(i64.const 32)
1820
)
1921
)
2022
)
2123
)
22-
(func $legalstub$illegalResult (; 2 ;) (; has Stack IR ;) (result i32)
23-
(set_global $tempRet0
24+
(func $legalstub$illegalResult (; 4 ;) (; has Stack IR ;) (result i32)
25+
(call $setTempRet0
2426
(i32.const 2)
2527
)
2628
(i32.const 1)

test/i64-setTempRet0.fromasm.imprecise.no-opts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,36 @@
11
(module
22
(type $FUNCSIG$j (func (result i64)))
3+
(type $FUNCSIG$vi (func (param i32)))
4+
(type $FUNCSIG$i (func (result i32)))
35
(type $legaltype$illegalImportResult (func (result i32)))
46
(import "env" "memory" (memory $memory 256 256))
57
(import "env" "table" (table $table 0 0 anyfunc))
68
(import "env" "__memory_base" (global $__memory_base i32))
79
(import "env" "__table_base" (global $__table_base i32))
10+
(import "env" "setTempRet0" (func $setTempRet0 (param i32)))
11+
(import "env" "getTempRet0" (func $getTempRet0 (result i32)))
812
(import "env" "illegalImportResult" (func $legalimport$illegalImportResult (result i32)))
913
(global $tempRet0 (mut i32) (i32.const 0))
1014
(export "illegalResult" (func $legalstub$illegalResult))
1115
(export "imports" (func $imports))
12-
(func $illegalResult (; 1 ;) (result i64)
16+
(func $illegalResult (; 3 ;) (result i64)
1317
(return
1418
(i64.const 8589934593)
1519
)
1620
)
17-
(func $imports (; 2 ;) (result i32)
21+
(func $imports (; 4 ;) (result i32)
1822
(return
1923
(i32.wrap/i64
2024
(call $legalfunc$illegalImportResult)
2125
)
2226
)
2327
)
24-
(func $legalstub$illegalResult (; 3 ;) (result i32)
28+
(func $legalstub$illegalResult (; 5 ;) (result i32)
2529
(local $0 i64)
2630
(set_local $0
2731
(call $illegalResult)
2832
)
29-
(set_global $tempRet0
33+
(call $setTempRet0
3034
(i32.wrap/i64
3135
(i64.shr_u
3236
(get_local $0)
@@ -38,14 +42,14 @@
3842
(get_local $0)
3943
)
4044
)
41-
(func $legalfunc$illegalImportResult (; 4 ;) (result i64)
45+
(func $legalfunc$illegalImportResult (; 6 ;) (result i64)
4246
(i64.or
4347
(i64.extend_u/i32
4448
(call $legalimport$illegalImportResult)
4549
)
4650
(i64.shl
4751
(i64.extend_u/i32
48-
(get_global $tempRet0)
52+
(call $getTempRet0)
4953
)
5054
(i64.const 32)
5155
)

0 commit comments

Comments
 (0)