Skip to content

Commit 5f1afa5

Browse files
authored
wasm-emscripten-finalize: Emit illegal dynCalls, and legalize them (#1890)
Before this, we just did not emit illegal dynCalls. This was wrong as we do need them (e.g. if a function with a setjmp call calls a function with an i64 param - we'll have an invoke with that signature there). We just need to legalize them. This fixes that by first emitting them, and second by running legalization late, after dynCalls have been generated, so it legalizes them too.
1 parent 5bfb98b commit 5f1afa5

File tree

5 files changed

+191
-64
lines changed

5 files changed

+191
-64
lines changed

src/tools/wasm-emscripten-finalize.cpp

+15-12
Original file line numberDiff line numberDiff line change
@@ -173,17 +173,6 @@ int main(int argc, const char *argv[]) {
173173
EmscriptenGlueGenerator generator(wasm);
174174
generator.fixInvokeFunctionNames();
175175

176-
{
177-
PassRunner passRunner(&wasm);
178-
passRunner.setDebug(options.debug);
179-
passRunner.setDebugInfo(debugInfo);
180-
passRunner.add(ABI::getLegalizationPass(
181-
legalizeJavaScriptFFI ? ABI::LegalizationLevel::Full
182-
: ABI::LegalizationLevel::Minimal
183-
));
184-
passRunner.run();
185-
}
186-
187176
std::vector<Name> initializerFunctions;
188177

189178
// The names of standard imports/exports used by lld doesn't quite match that
@@ -215,12 +204,26 @@ int main(int argc, const char *argv[]) {
215204

216205
generator.generateDynCallThunks();
217206
generator.generateJSCallThunks(numReservedFunctionPointers);
218-
std::string metadata = generator.generateEmscriptenMetadata(dataSize, initializerFunctions, numReservedFunctionPointers);
219207
if (!dataSegmentFile.empty()) {
220208
Output memInitFile(dataSegmentFile, Flags::Binary, Flags::Release);
221209
generator.separateDataSegments(&memInitFile);
222210
}
223211

212+
// Finally, legalize the wasm.
213+
{
214+
PassRunner passRunner(&wasm);
215+
passRunner.setDebug(options.debug);
216+
passRunner.setDebugInfo(debugInfo);
217+
passRunner.add(ABI::getLegalizationPass(
218+
legalizeJavaScriptFFI ? ABI::LegalizationLevel::Full
219+
: ABI::LegalizationLevel::Minimal
220+
));
221+
passRunner.run();
222+
}
223+
224+
// All changes to the wasm are done, create the metadata.
225+
std::string metadata = generator.generateEmscriptenMetadata(dataSize, initializerFunctions, numReservedFunctionPointers);
226+
224227
if (options.debug) {
225228
std::cerr << "Module after:\n";
226229
WasmPrinter::printModule(&wasm, std::cerr);

src/wasm/wasm-emscripten.cpp

-9
Original file line numberDiff line numberDiff line change
@@ -161,14 +161,6 @@ void EmscriptenGlueGenerator::generateStackInitialization(Address addr) {
161161
stackPointer->init->cast<Const>()->value = Literal(int32_t(addr));
162162
}
163163

164-
static bool hasI64ResultOrParam(FunctionType* ft) {
165-
if (ft->result == i64) return true;
166-
for (auto ty : ft->params) {
167-
if (ty == i64) return true;
168-
}
169-
return false;
170-
}
171-
172164
inline void exportFunction(Module& wasm, Name name, bool must_export) {
173165
if (!wasm.getFunctionOrNull(name)) {
174166
assert(!must_export);
@@ -194,7 +186,6 @@ void EmscriptenGlueGenerator::generateDynCallThunks() {
194186
}
195187
std::string sig = getSig(wasm.getFunction(indirectFunc));
196188
auto* funcType = ensureFunctionType(sig, &wasm);
197-
if (hasI64ResultOrParam(funcType)) continue; // Can't export i64s on the web.
198189
if (!sigs.insert(sig).second) continue; // Sig is already in the set
199190
std::vector<NameType> params;
200191
params.emplace_back("fptr", i32); // function pointer param

test/lld/duplicate_imports.wast.out

+31-31
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,35 @@
3939
(func $__wasm_call_ctors (; 5 ;) (type $2)
4040
(nop)
4141
)
42-
(func $legalfunc$puts2 (; 6 ;) (param $0 i64) (result i32)
42+
(func $stackSave (; 6 ;) (result i32)
43+
(global.get $global$0)
44+
)
45+
(func $stackAlloc (; 7 ;) (param $0 i32) (result i32)
46+
(local $1 i32)
47+
(global.set $global$0
48+
(local.tee $1
49+
(i32.and
50+
(i32.sub
51+
(global.get $global$0)
52+
(local.get $0)
53+
)
54+
(i32.const -16)
55+
)
56+
)
57+
)
58+
(local.get $1)
59+
)
60+
(func $stackRestore (; 8 ;) (param $0 i32)
61+
(global.set $global$0
62+
(local.get $0)
63+
)
64+
)
65+
(func $__growWasmMemory (; 9 ;) (param $newSize i32) (result i32)
66+
(grow_memory
67+
(local.get $newSize)
68+
)
69+
)
70+
(func $legalfunc$puts2 (; 10 ;) (param $0 i64) (result i32)
4371
(call $legalimport$puts2
4472
(i32.wrap_i64
4573
(local.get $0)
@@ -52,7 +80,7 @@
5280
)
5381
)
5482
)
55-
(func $legalfunc$invoke_ffd (; 7 ;) (param $0 i32) (param $1 f32) (param $2 f64) (result f32)
83+
(func $legalfunc$invoke_ffd (; 11 ;) (param $0 i32) (param $1 f32) (param $2 f64) (result f32)
5684
(f32.demote_f64
5785
(call $legalimport$invoke_ffd
5886
(local.get $0)
@@ -63,7 +91,7 @@
6391
)
6492
)
6593
)
66-
(func $legalfunc$invoke_ffd2 (; 8 ;) (param $0 i32) (param $1 f64) (param $2 f64) (result f32)
94+
(func $legalfunc$invoke_ffd2 (; 12 ;) (param $0 i32) (param $1 f64) (param $2 f64) (result f32)
6795
(f32.demote_f64
6896
(call $legalimport$invoke_ffd2
6997
(local.get $0)
@@ -72,34 +100,6 @@
72100
)
73101
)
74102
)
75-
(func $stackSave (; 9 ;) (result i32)
76-
(global.get $global$0)
77-
)
78-
(func $stackAlloc (; 10 ;) (param $0 i32) (result i32)
79-
(local $1 i32)
80-
(global.set $global$0
81-
(local.tee $1
82-
(i32.and
83-
(i32.sub
84-
(global.get $global$0)
85-
(local.get $0)
86-
)
87-
(i32.const -16)
88-
)
89-
)
90-
)
91-
(local.get $1)
92-
)
93-
(func $stackRestore (; 11 ;) (param $0 i32)
94-
(global.set $global$0
95-
(local.get $0)
96-
)
97-
)
98-
(func $__growWasmMemory (; 12 ;) (param $newSize i32) (result i32)
99-
(grow_memory
100-
(local.get $newSize)
101-
)
102-
)
103103
)
104104
(;
105105
--BEGIN METADATA --

test/lld/reserved_func_ptr.wast.jscall.out

+19-4
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@
1818
(type $FUNCSIG$v (func))
1919
(type $FUNCSIG$vii (func (param i32 i32)))
2020
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
21+
(type $legaltype$jsCall_fffi (func (param i32 f64 f64 i32) (result f64)))
2122
(import "env" "_Z4atoiPKc" (func $_Z4atoiPKc (param i32) (result i32)))
2223
(import "env" "jsCall_ddi" (func $jsCall_ddi (param i32 f64 i32) (result f64)))
23-
(import "env" "jsCall_fffi" (func $jsCall_fffi (param i32 f32 f32 i32) (result f32)))
2424
(import "env" "jsCall_iii" (func $jsCall_iii (param i32 i32 i32) (result i32)))
2525
(import "env" "jsCall_v" (func $jsCall_v (param i32)))
2626
(import "env" "jsCall_vi" (func $jsCall_vi (param i32 i32)))
2727
(import "env" "jsCall_viii" (func $jsCall_viii (param i32 i32 i32 i32)))
28+
(import "env" "jsCall_fffi" (func $legalimport$jsCall_fffi (param i32 f64 f64 i32) (result f64)))
2829
(memory $0 2)
2930
(table $0 21 21 funcref)
3031
(elem (i32.const 1) $_Z18address_taken_funciii $_Z19address_taken_func2iii $jsCall_ddi_0 $jsCall_ddi_1 $jsCall_ddi_2 $jsCall_fffi_0 $jsCall_fffi_1 $jsCall_fffi_2 $jsCall_iii_0 $jsCall_iii_1 $jsCall_iii_2 $jsCall_v_0 $jsCall_v_1 $jsCall_v_2 $jsCall_vi_0 $jsCall_vi_1 $jsCall_vi_2 $jsCall_viii_0 $jsCall_viii_1 $jsCall_viii_2)
@@ -192,23 +193,23 @@
192193
)
193194
)
194195
(func $jsCall_fffi_0 (; 19 ;) (param $0 f32) (param $1 f32) (param $2 i32) (result f32)
195-
(call $jsCall_fffi
196+
(call $legalfunc$jsCall_fffi
196197
(i32.const 0)
197198
(local.get $0)
198199
(local.get $1)
199200
(local.get $2)
200201
)
201202
)
202203
(func $jsCall_fffi_1 (; 20 ;) (param $0 f32) (param $1 f32) (param $2 i32) (result f32)
203-
(call $jsCall_fffi
204+
(call $legalfunc$jsCall_fffi
204205
(i32.const 1)
205206
(local.get $0)
206207
(local.get $1)
207208
(local.get $2)
208209
)
209210
)
210211
(func $jsCall_fffi_2 (; 21 ;) (param $0 f32) (param $1 f32) (param $2 i32) (result f32)
211-
(call $jsCall_fffi
212+
(call $legalfunc$jsCall_fffi
212213
(i32.const 2)
213214
(local.get $0)
214215
(local.get $1)
@@ -293,6 +294,20 @@
293294
(local.get $2)
294295
)
295296
)
297+
(func $legalfunc$jsCall_fffi (; 34 ;) (param $0 i32) (param $1 f32) (param $2 f32) (param $3 i32) (result f32)
298+
(f32.demote_f64
299+
(call $legalimport$jsCall_fffi
300+
(local.get $0)
301+
(f64.promote_f32
302+
(local.get $1)
303+
)
304+
(f64.promote_f32
305+
(local.get $2)
306+
)
307+
(local.get $3)
308+
)
309+
)
310+
)
296311
)
297312
(;
298313
--BEGIN METADATA --

0 commit comments

Comments
 (0)