summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2019-01-29 12:39:02 -0800
committerGitHub <noreply@github.com>2019-01-29 12:39:02 -0800
commit5f1afa58d22dce1088c63eff690283d8c615feee (patch)
tree6c59a39af79f789f1c65d00c72a960f222b9f845
parent5bfb98b97c18342d851d2e0841a3091ae671f88c (diff)
downloadbinaryen-5f1afa58d22dce1088c63eff690283d8c615feee.tar.gz
binaryen-5f1afa58d22dce1088c63eff690283d8c615feee.tar.bz2
binaryen-5f1afa58d22dce1088c63eff690283d8c615feee.zip
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.
-rw-r--r--src/tools/wasm-emscripten-finalize.cpp27
-rw-r--r--src/wasm/wasm-emscripten.cpp9
-rw-r--r--test/lld/duplicate_imports.wast.out62
-rw-r--r--test/lld/reserved_func_ptr.wast.jscall.out23
-rw-r--r--test/passes/fpcast-emu.txt134
5 files changed, 191 insertions, 64 deletions
diff --git a/src/tools/wasm-emscripten-finalize.cpp b/src/tools/wasm-emscripten-finalize.cpp
index 5c2e37ac3..d0b664c0c 100644
--- a/src/tools/wasm-emscripten-finalize.cpp
+++ b/src/tools/wasm-emscripten-finalize.cpp
@@ -173,17 +173,6 @@ int main(int argc, const char *argv[]) {
EmscriptenGlueGenerator generator(wasm);
generator.fixInvokeFunctionNames();
- {
- PassRunner passRunner(&wasm);
- passRunner.setDebug(options.debug);
- passRunner.setDebugInfo(debugInfo);
- passRunner.add(ABI::getLegalizationPass(
- legalizeJavaScriptFFI ? ABI::LegalizationLevel::Full
- : ABI::LegalizationLevel::Minimal
- ));
- passRunner.run();
- }
-
std::vector<Name> initializerFunctions;
// 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[]) {
generator.generateDynCallThunks();
generator.generateJSCallThunks(numReservedFunctionPointers);
- std::string metadata = generator.generateEmscriptenMetadata(dataSize, initializerFunctions, numReservedFunctionPointers);
if (!dataSegmentFile.empty()) {
Output memInitFile(dataSegmentFile, Flags::Binary, Flags::Release);
generator.separateDataSegments(&memInitFile);
}
+ // Finally, legalize the wasm.
+ {
+ PassRunner passRunner(&wasm);
+ passRunner.setDebug(options.debug);
+ passRunner.setDebugInfo(debugInfo);
+ passRunner.add(ABI::getLegalizationPass(
+ legalizeJavaScriptFFI ? ABI::LegalizationLevel::Full
+ : ABI::LegalizationLevel::Minimal
+ ));
+ passRunner.run();
+ }
+
+ // All changes to the wasm are done, create the metadata.
+ std::string metadata = generator.generateEmscriptenMetadata(dataSize, initializerFunctions, numReservedFunctionPointers);
+
if (options.debug) {
std::cerr << "Module after:\n";
WasmPrinter::printModule(&wasm, std::cerr);
diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp
index 3dee642b1..e09ad98d2 100644
--- a/src/wasm/wasm-emscripten.cpp
+++ b/src/wasm/wasm-emscripten.cpp
@@ -161,14 +161,6 @@ void EmscriptenGlueGenerator::generateStackInitialization(Address addr) {
stackPointer->init->cast<Const>()->value = Literal(int32_t(addr));
}
-static bool hasI64ResultOrParam(FunctionType* ft) {
- if (ft->result == i64) return true;
- for (auto ty : ft->params) {
- if (ty == i64) return true;
- }
- return false;
-}
-
inline void exportFunction(Module& wasm, Name name, bool must_export) {
if (!wasm.getFunctionOrNull(name)) {
assert(!must_export);
@@ -194,7 +186,6 @@ void EmscriptenGlueGenerator::generateDynCallThunks() {
}
std::string sig = getSig(wasm.getFunction(indirectFunc));
auto* funcType = ensureFunctionType(sig, &wasm);
- if (hasI64ResultOrParam(funcType)) continue; // Can't export i64s on the web.
if (!sigs.insert(sig).second) continue; // Sig is already in the set
std::vector<NameType> params;
params.emplace_back("fptr", i32); // function pointer param
diff --git a/test/lld/duplicate_imports.wast.out b/test/lld/duplicate_imports.wast.out
index 58f5846e6..3a9fa2474 100644
--- a/test/lld/duplicate_imports.wast.out
+++ b/test/lld/duplicate_imports.wast.out
@@ -39,7 +39,35 @@
(func $__wasm_call_ctors (; 5 ;) (type $2)
(nop)
)
- (func $legalfunc$puts2 (; 6 ;) (param $0 i64) (result i32)
+ (func $stackSave (; 6 ;) (result i32)
+ (global.get $global$0)
+ )
+ (func $stackAlloc (; 7 ;) (param $0 i32) (result i32)
+ (local $1 i32)
+ (global.set $global$0
+ (local.tee $1
+ (i32.and
+ (i32.sub
+ (global.get $global$0)
+ (local.get $0)
+ )
+ (i32.const -16)
+ )
+ )
+ )
+ (local.get $1)
+ )
+ (func $stackRestore (; 8 ;) (param $0 i32)
+ (global.set $global$0
+ (local.get $0)
+ )
+ )
+ (func $__growWasmMemory (; 9 ;) (param $newSize i32) (result i32)
+ (grow_memory
+ (local.get $newSize)
+ )
+ )
+ (func $legalfunc$puts2 (; 10 ;) (param $0 i64) (result i32)
(call $legalimport$puts2
(i32.wrap_i64
(local.get $0)
@@ -52,7 +80,7 @@
)
)
)
- (func $legalfunc$invoke_ffd (; 7 ;) (param $0 i32) (param $1 f32) (param $2 f64) (result f32)
+ (func $legalfunc$invoke_ffd (; 11 ;) (param $0 i32) (param $1 f32) (param $2 f64) (result f32)
(f32.demote_f64
(call $legalimport$invoke_ffd
(local.get $0)
@@ -63,7 +91,7 @@
)
)
)
- (func $legalfunc$invoke_ffd2 (; 8 ;) (param $0 i32) (param $1 f64) (param $2 f64) (result f32)
+ (func $legalfunc$invoke_ffd2 (; 12 ;) (param $0 i32) (param $1 f64) (param $2 f64) (result f32)
(f32.demote_f64
(call $legalimport$invoke_ffd2
(local.get $0)
@@ -72,34 +100,6 @@
)
)
)
- (func $stackSave (; 9 ;) (result i32)
- (global.get $global$0)
- )
- (func $stackAlloc (; 10 ;) (param $0 i32) (result i32)
- (local $1 i32)
- (global.set $global$0
- (local.tee $1
- (i32.and
- (i32.sub
- (global.get $global$0)
- (local.get $0)
- )
- (i32.const -16)
- )
- )
- )
- (local.get $1)
- )
- (func $stackRestore (; 11 ;) (param $0 i32)
- (global.set $global$0
- (local.get $0)
- )
- )
- (func $__growWasmMemory (; 12 ;) (param $newSize i32) (result i32)
- (grow_memory
- (local.get $newSize)
- )
- )
)
(;
--BEGIN METADATA --
diff --git a/test/lld/reserved_func_ptr.wast.jscall.out b/test/lld/reserved_func_ptr.wast.jscall.out
index bc9b677d6..e176ba231 100644
--- a/test/lld/reserved_func_ptr.wast.jscall.out
+++ b/test/lld/reserved_func_ptr.wast.jscall.out
@@ -18,13 +18,14 @@
(type $FUNCSIG$v (func))
(type $FUNCSIG$vii (func (param i32 i32)))
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
+ (type $legaltype$jsCall_fffi (func (param i32 f64 f64 i32) (result f64)))
(import "env" "_Z4atoiPKc" (func $_Z4atoiPKc (param i32) (result i32)))
(import "env" "jsCall_ddi" (func $jsCall_ddi (param i32 f64 i32) (result f64)))
- (import "env" "jsCall_fffi" (func $jsCall_fffi (param i32 f32 f32 i32) (result f32)))
(import "env" "jsCall_iii" (func $jsCall_iii (param i32 i32 i32) (result i32)))
(import "env" "jsCall_v" (func $jsCall_v (param i32)))
(import "env" "jsCall_vi" (func $jsCall_vi (param i32 i32)))
(import "env" "jsCall_viii" (func $jsCall_viii (param i32 i32 i32 i32)))
+ (import "env" "jsCall_fffi" (func $legalimport$jsCall_fffi (param i32 f64 f64 i32) (result f64)))
(memory $0 2)
(table $0 21 21 funcref)
(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,7 +193,7 @@
)
)
(func $jsCall_fffi_0 (; 19 ;) (param $0 f32) (param $1 f32) (param $2 i32) (result f32)
- (call $jsCall_fffi
+ (call $legalfunc$jsCall_fffi
(i32.const 0)
(local.get $0)
(local.get $1)
@@ -200,7 +201,7 @@
)
)
(func $jsCall_fffi_1 (; 20 ;) (param $0 f32) (param $1 f32) (param $2 i32) (result f32)
- (call $jsCall_fffi
+ (call $legalfunc$jsCall_fffi
(i32.const 1)
(local.get $0)
(local.get $1)
@@ -208,7 +209,7 @@
)
)
(func $jsCall_fffi_2 (; 21 ;) (param $0 f32) (param $1 f32) (param $2 i32) (result f32)
- (call $jsCall_fffi
+ (call $legalfunc$jsCall_fffi
(i32.const 2)
(local.get $0)
(local.get $1)
@@ -293,6 +294,20 @@
(local.get $2)
)
)
+ (func $legalfunc$jsCall_fffi (; 34 ;) (param $0 i32) (param $1 f32) (param $2 f32) (param $3 i32) (result f32)
+ (f32.demote_f64
+ (call $legalimport$jsCall_fffi
+ (local.get $0)
+ (f64.promote_f32
+ (local.get $1)
+ )
+ (f64.promote_f32
+ (local.get $2)
+ )
+ (local.get $3)
+ )
+ )
+ )
)
(;
--BEGIN METADATA --
diff --git a/test/passes/fpcast-emu.txt b/test/passes/fpcast-emu.txt
index a4e79a85a..c1a76b1d3 100644
--- a/test/passes/fpcast-emu.txt
+++ b/test/passes/fpcast-emu.txt
@@ -14,8 +14,12 @@
(import "env" "imported_func" (func $imported-func (param i32 i64 f32 f64) (result f32)))
(table $0 10 10 funcref)
(elem (i32.const 0) $byn$fpcast-emu$a $byn$fpcast-emu$b $byn$fpcast-emu$c $byn$fpcast-emu$d $byn$fpcast-emu$e $byn$fpcast-emu$e $byn$fpcast-emu$imported-func)
+ (export "dynCall_vijfd" (func $dynCall_vijfd))
+ (export "dynCall_jii" (func $dynCall_jii))
+ (export "dynCall_fjj" (func $dynCall_fjj))
(export "dynCall_dff" (func $dynCall_dff))
(export "dynCall_idd" (func $dynCall_idd))
+ (export "dynCall_fijfd" (func $dynCall_fijfd))
(func $a (; 1 ;) (type $vijfd) (param $x i32) (param $y i64) (param $z f32) (param $w f64)
(drop
(call_indirect (type $FUNCSIG$jjjjjjjjjjjjjjjjj)
@@ -155,7 +159,88 @@
)
)
)
- (func $dynCall_dff (; 6 ;) (param $fptr i32) (param $0 f32) (param $1 f32) (result f64)
+ (func $dynCall_vijfd (; 6 ;) (param $fptr i32) (param $0 i32) (param $1 i64) (param $2 f32) (param $3 f64)
+ (drop
+ (call_indirect (type $FUNCSIG$jjjjjjjjjjjjjjjjj)
+ (i64.extend_i32_u
+ (local.get $0)
+ )
+ (local.get $1)
+ (i64.extend_i32_u
+ (i32.reinterpret_f32
+ (local.get $2)
+ )
+ )
+ (i64.reinterpret_f64
+ (local.get $3)
+ )
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (local.get $fptr)
+ )
+ )
+ )
+ (func $dynCall_jii (; 7 ;) (param $fptr i32) (param $0 i32) (param $1 i32) (result i64)
+ (call_indirect (type $FUNCSIG$jjjjjjjjjjjjjjjjj)
+ (i64.extend_i32_u
+ (local.get $0)
+ )
+ (i64.extend_i32_u
+ (local.get $1)
+ )
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (local.get $fptr)
+ )
+ )
+ (func $dynCall_fjj (; 8 ;) (param $fptr i32) (param $0 i64) (param $1 i64) (result f32)
+ (f32.reinterpret_i32
+ (i32.wrap_i64
+ (call_indirect (type $FUNCSIG$jjjjjjjjjjjjjjjjj)
+ (local.get $0)
+ (local.get $1)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (local.get $fptr)
+ )
+ )
+ )
+ )
+ (func $dynCall_dff (; 9 ;) (param $fptr i32) (param $0 f32) (param $1 f32) (result f64)
(f64.reinterpret_i64
(call_indirect (type $FUNCSIG$jjjjjjjjjjjjjjjjj)
(i64.extend_i32_u
@@ -186,7 +271,7 @@
)
)
)
- (func $dynCall_idd (; 7 ;) (param $fptr i32) (param $0 f64) (param $1 f64) (result i32)
+ (func $dynCall_idd (; 10 ;) (param $fptr i32) (param $0 f64) (param $1 f64) (result i32)
(i32.wrap_i64
(call_indirect (type $FUNCSIG$jjjjjjjjjjjjjjjjj)
(i64.reinterpret_f64
@@ -213,7 +298,40 @@
)
)
)
- (func $byn$fpcast-emu$a (; 8 ;) (type $FUNCSIG$jjjjjjjjjjjjjjjjj) (param $0 i64) (param $1 i64) (param $2 i64) (param $3 i64) (param $4 i64) (param $5 i64) (param $6 i64) (param $7 i64) (param $8 i64) (param $9 i64) (param $10 i64) (param $11 i64) (param $12 i64) (param $13 i64) (param $14 i64) (param $15 i64) (result i64)
+ (func $dynCall_fijfd (; 11 ;) (param $fptr i32) (param $0 i32) (param $1 i64) (param $2 f32) (param $3 f64) (result f32)
+ (f32.reinterpret_i32
+ (i32.wrap_i64
+ (call_indirect (type $FUNCSIG$jjjjjjjjjjjjjjjjj)
+ (i64.extend_i32_u
+ (local.get $0)
+ )
+ (local.get $1)
+ (i64.extend_i32_u
+ (i32.reinterpret_f32
+ (local.get $2)
+ )
+ )
+ (i64.reinterpret_f64
+ (local.get $3)
+ )
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ (local.get $fptr)
+ )
+ )
+ )
+ )
+ (func $byn$fpcast-emu$a (; 12 ;) (type $FUNCSIG$jjjjjjjjjjjjjjjjj) (param $0 i64) (param $1 i64) (param $2 i64) (param $3 i64) (param $4 i64) (param $5 i64) (param $6 i64) (param $7 i64) (param $8 i64) (param $9 i64) (param $10 i64) (param $11 i64) (param $12 i64) (param $13 i64) (param $14 i64) (param $15 i64) (result i64)
(call $a
(i32.wrap_i64
(local.get $0)
@@ -230,7 +348,7 @@
)
(i64.const 0)
)
- (func $byn$fpcast-emu$b (; 9 ;) (type $FUNCSIG$jjjjjjjjjjjjjjjjj) (param $0 i64) (param $1 i64) (param $2 i64) (param $3 i64) (param $4 i64) (param $5 i64) (param $6 i64) (param $7 i64) (param $8 i64) (param $9 i64) (param $10 i64) (param $11 i64) (param $12 i64) (param $13 i64) (param $14 i64) (param $15 i64) (result i64)
+ (func $byn$fpcast-emu$b (; 13 ;) (type $FUNCSIG$jjjjjjjjjjjjjjjjj) (param $0 i64) (param $1 i64) (param $2 i64) (param $3 i64) (param $4 i64) (param $5 i64) (param $6 i64) (param $7 i64) (param $8 i64) (param $9 i64) (param $10 i64) (param $11 i64) (param $12 i64) (param $13 i64) (param $14 i64) (param $15 i64) (result i64)
(call $b
(i32.wrap_i64
(local.get $0)
@@ -240,7 +358,7 @@
)
)
)
- (func $byn$fpcast-emu$c (; 10 ;) (type $FUNCSIG$jjjjjjjjjjjjjjjjj) (param $0 i64) (param $1 i64) (param $2 i64) (param $3 i64) (param $4 i64) (param $5 i64) (param $6 i64) (param $7 i64) (param $8 i64) (param $9 i64) (param $10 i64) (param $11 i64) (param $12 i64) (param $13 i64) (param $14 i64) (param $15 i64) (result i64)
+ (func $byn$fpcast-emu$c (; 14 ;) (type $FUNCSIG$jjjjjjjjjjjjjjjjj) (param $0 i64) (param $1 i64) (param $2 i64) (param $3 i64) (param $4 i64) (param $5 i64) (param $6 i64) (param $7 i64) (param $8 i64) (param $9 i64) (param $10 i64) (param $11 i64) (param $12 i64) (param $13 i64) (param $14 i64) (param $15 i64) (result i64)
(i64.extend_i32_u
(i32.reinterpret_f32
(call $c
@@ -250,7 +368,7 @@
)
)
)
- (func $byn$fpcast-emu$d (; 11 ;) (type $FUNCSIG$jjjjjjjjjjjjjjjjj) (param $0 i64) (param $1 i64) (param $2 i64) (param $3 i64) (param $4 i64) (param $5 i64) (param $6 i64) (param $7 i64) (param $8 i64) (param $9 i64) (param $10 i64) (param $11 i64) (param $12 i64) (param $13 i64) (param $14 i64) (param $15 i64) (result i64)
+ (func $byn$fpcast-emu$d (; 15 ;) (type $FUNCSIG$jjjjjjjjjjjjjjjjj) (param $0 i64) (param $1 i64) (param $2 i64) (param $3 i64) (param $4 i64) (param $5 i64) (param $6 i64) (param $7 i64) (param $8 i64) (param $9 i64) (param $10 i64) (param $11 i64) (param $12 i64) (param $13 i64) (param $14 i64) (param $15 i64) (result i64)
(i64.reinterpret_f64
(call $d
(f32.reinterpret_i32
@@ -266,7 +384,7 @@
)
)
)
- (func $byn$fpcast-emu$e (; 12 ;) (type $FUNCSIG$jjjjjjjjjjjjjjjjj) (param $0 i64) (param $1 i64) (param $2 i64) (param $3 i64) (param $4 i64) (param $5 i64) (param $6 i64) (param $7 i64) (param $8 i64) (param $9 i64) (param $10 i64) (param $11 i64) (param $12 i64) (param $13 i64) (param $14 i64) (param $15 i64) (result i64)
+ (func $byn$fpcast-emu$e (; 16 ;) (type $FUNCSIG$jjjjjjjjjjjjjjjjj) (param $0 i64) (param $1 i64) (param $2 i64) (param $3 i64) (param $4 i64) (param $5 i64) (param $6 i64) (param $7 i64) (param $8 i64) (param $9 i64) (param $10 i64) (param $11 i64) (param $12 i64) (param $13 i64) (param $14 i64) (param $15 i64) (result i64)
(i64.extend_i32_u
(call $e
(f64.reinterpret_i64
@@ -278,7 +396,7 @@
)
)
)
- (func $byn$fpcast-emu$imported-func (; 13 ;) (type $FUNCSIG$jjjjjjjjjjjjjjjjj) (param $0 i64) (param $1 i64) (param $2 i64) (param $3 i64) (param $4 i64) (param $5 i64) (param $6 i64) (param $7 i64) (param $8 i64) (param $9 i64) (param $10 i64) (param $11 i64) (param $12 i64) (param $13 i64) (param $14 i64) (param $15 i64) (result i64)
+ (func $byn$fpcast-emu$imported-func (; 17 ;) (type $FUNCSIG$jjjjjjjjjjjjjjjjj) (param $0 i64) (param $1 i64) (param $2 i64) (param $3 i64) (param $4 i64) (param $5 i64) (param $6 i64) (param $7 i64) (param $8 i64) (param $9 i64) (param $10 i64) (param $11 i64) (param $12 i64) (param $13 i64) (param $14 i64) (param $15 i64) (result i64)
(i64.extend_i32_u
(i32.reinterpret_f32
(call $imported-func