Conversation
…on params and result + fix [ci skip]
kripken
added a commit
to emscripten-core/emscripten
that referenced
this pull request
Mar 15, 2018
This reworks how function cast emulation works in wasm: it uses the new binaryen pass for that (WebAssembly/binaryen#1468), which converts all indirect calls to use a simple ABI with a fixed number of arguments and i64s for all types. This lets stuff like Python work, which casts away extra arguments, making them technically invalid as wasm indirect calls without emulation. This fixes #6309 (dynamic linking + wasm + function cast emulation in asm2wasm, which did not work) and also gets function cast emulation working in the wasm backend, enabling the test there. This should also get Python working in the wasm backend (however the test there can't be enabled as it's not compiling from source - I think we just bundled the bitcode because python was just huge). To get asm2wasm dynamic linking working with function cast emulation, the way we get function pointers is changed: we used to get the exported function and use addFunction to add it to the table dynamically. This can't work with function cast emulation since the export is callable from JS, while function pointers need to use the i64 ABI, so we'd need to convert those at runtime, which is not practical. Instead, asm2wasm provides metadata from the backend about the function pointer for each export, and uses those directly. This is better anyhow because it's simpler and likely closer to what proper wasm dynamic linking will use eventually; also, using addFunction is tricky here since we don't know the type, so that couldn't have worked in the wasm backend anyhow.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This adds a pass that implements "function pointer cast emulation" - allows indirect calls to go through even if the number of arguments or their types is incorrect. That is undefined behavior in C/C++ but in practice somehow works in native archs. It is even relied upon in e.g. Python.
Emscripten already has such emulation for asm.js, which also worked for asm2wasm. This implements something like it in binaryen which also allows the wasm backend to use it. As a result, Python should now be portable using the wasm backend.
The mechanism used for the emulation is to make all indirect calls use a fixed number of arguments, all of type i64, and a return type of also i64. Thunks are then placed in the table which translate the arguments properly for the target, basically by reinterpreting to i64 and back. As a result, receiving an i64 when an i32 is sent will have the upper bits all zero, and the reverse would truncate the upper bits, etc. (Note that this is different than emscripten's existing emulation, which converts (as signed) to a double. That makes sense for JS where double's can contain all numeric values, but in wasm we have i64s. Also, bitwise conversion may be more like what native archs do anyhow. It is enough for Python.)
Also adds validation for a function's type matching the function's actual params and result (surprised we didn't have that before, but we didn't, and there was even a place in the test suite where that was wrong).
Also simplifies the build script by moving two cpp files into the
wasm/subdir, so they can be built once and shared between the various tools.