Include some feedback from Luke.

This commit is contained in:
JF Bastien 2016-02-01 11:14:27 -08:00
parent ff04d7f6e7
commit 38b698553b

View File

@ -4,20 +4,25 @@ A [musl experiment][].
[musl experiment]: https://github.com/WebAssembly/musl/blob/landing-branch/README.md [musl experiment]: https://github.com/WebAssembly/musl/blob/landing-branch/README.md
The goal of this prototype was to get a WebAssembly libc off the ground. Dynamic The goal of this prototype was to get a WebAssembly libc off the ground. Limited
linking came out of it *for free* which is mighty convenient. We should: dynamic linking (no cross-module function pointers) came out of it *for free*
which is mighty convenient. We should:
1. Focus on the libc aspect. 1. Focus on the libc aspect, with static linking.
2. As a secondary goal use dynamic linking to inform WebAssembly's design. 2. As a secondary goal use limited dynamic linking to inform WebAssembly's
design.
**Note:** This experimental WebAssembly C library with dynamic linking is a **Note:** This experimental WebAssembly C library with limited dynamic linking
hack. Don't rely on it: it's meant to inform the design of WebAssembly. Things is a hack. Don't rely on it: it's meant to inform the design of
are changing rapidly, so mixing different parts of the toolchain may break from WebAssembly. Things are changing rapidly, so mixing different parts of the
time to time, try to keep them all in sync. toolchain may break from time to time, try to keep them all in sync. In
particular, the current WebAssembly design doesn't allow sharing heaps between
modules. It's a convenience API in the V8 implementation which may be removed in
the future.
In this experiment dynamic linking is entirely done through JavaScript, which is In this experiment, limited dynamic linking is entirely done through JavaScript,
acting as the dynamic linker / loader. This merely uses the WebAssembly object's which is acting as the dynamic linker / loader. This merely uses the WebAssembly
capabilities. object's capabilities as implemented today.
## Quick how-to ## Quick how-to
@ -95,6 +100,8 @@ Calls from one WebAssembly module to another trampoline through JavaScript, but
they should optimize well. We should figure out what we suggest developers use, they should optimize well. We should figure out what we suggest developers use,
so that the default pattern doesn't require gymnastics on the compiler's part. so that the default pattern doesn't require gymnastics on the compiler's part.
Indirect calls from one WebAssembly module to another do not work.
A WebAssembly module with un-met imports will throw. This can be handled, add A WebAssembly module with un-met imports will throw. This can be handled, add
the missing function as a stub to FFI, and then load again (loop until success) the missing function as a stub to FFI, and then load again (loop until success)
but it's silly. If WebAssembly modules were loadable, imports inspectable, and but it's silly. If WebAssembly modules were loadable, imports inspectable, and
@ -129,8 +136,9 @@ repository may not be the right one.
## Miscellaneous ## Miscellaneous
Dynamic linking isn't in WebAssembly's current MVP because we thought it would Dynamic linking and pointer-less dynamic linking aren't in WebAssembly's current
be hard. This repository shows that it's *possible*, we therefore may as well MVP because we thought it would be hard. This repository shows that it's
*possible* to expose limited but useful functionality, we therefore may as well
design it right from the start, or make it entirely impossible for the MVP. design it right from the start, or make it entirely impossible for the MVP.
That'll including figuring out calling convention and ABI. Exports currently That'll including figuring out calling convention and ABI. Exports currently
@ -173,7 +181,6 @@ and `-fdata-sections` but emit one `.wasm` file per section. This allows them to
lazy-load and lazy-compile each function as needed, and even unload them when lazy-load and lazy-compile each function as needed, and even unload them when
the program doesn't need them anymore. the program doesn't need them anymore.
## `<dlfcn.h>` example ## `<dlfcn.h>` example
This example doesn't use `musl.wasm`, it currently only uses `wasm.js`. musl This example doesn't use `musl.wasm`, it currently only uses `wasm.js`. musl
@ -240,9 +247,10 @@ Execute it:
Note that this currently doesn't work because the `dlsym` implementation returns Note that this currently doesn't work because the `dlsym` implementation returns
the function from another module, and the implementation puts the functions in the function from another module, and the implementation puts the functions in
different tables. `call_indirect` can only call functions from the same module, different tables (hence the "limited" nature of this hacky dynamic
whereas `call_import` can call functions from another module by trampolining linking). `call_indirect` can only call functions from the same module, whereas
through JavaScript. We could fix this by: `call_import` can call functions from another module by trampolining through
JavaScript. We could fix this by:
* Forcing developers to use a function such as `dlcall` and provide handles for * Forcing developers to use a function such as `dlcall` and provide handles for
the module and symbol. `dlcall` would trampoline through JavaScript. This the module and symbol. `dlcall` would trampoline through JavaScript. This
@ -252,3 +260,6 @@ through JavaScript. We could fix this by:
* Map functions from other modules into the current one when `dlsym` is invoked, * Map functions from other modules into the current one when `dlsym` is invoked,
e.g. adding new functions to the `_WASMEXP_` instance. This also requires e.g. adding new functions to the `_WASMEXP_` instance. This also requires
tracking `dlclose` properly. tracking `dlclose` properly.
This amounts to designing full dynamic linking correctly, which we may not want
to do for MVP.