-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Loader: support .wasm imports #3328
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
48b64fd
to
22e4670
Compare
Looks like test |
ee3fdfb
to
a8cd4ab
Compare
This actually also implies that |
bbad50e
to
e9a2763
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awseome 🎉 Just a couple of thoughts.
cli/js/compiler.ts
Outdated
sourceFileJson.filename | ||
); | ||
// Create declaration file on the fly. | ||
const _ = new SourceFile({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why even assign this to a variable? It is never read.
But good way of tackling the problem. The interesting thing will be if we can actually get the shape of the named exports of the WASM file, and actually pass into the compiler a dynamically generated set of source code.
cli/tests/051_wasm_import.ts
Outdated
@@ -0,0 +1,24 @@ | |||
import wasmExports from "./051_wasm_import/simple.wasm"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm, is this the proposed semantics for WASM imports, for all of the exports to go into the default export, instead of import * as wasmExports from "..."
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The standards seems to imply named exports. However we have problem collecting WASM imports and exports names since our current compiler does not support running some JS code. I don’t really know if there is a way I can directly get these info from Rust side other than either delegate this task to JS or using something like wasmer_runtime (which is too heavy ad it is a full runtime). Will investigate if there is some V8 APIs I could use instead...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I think I might be able to figure out export names with some extra tricks. Experimenting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean there are V8 APIs for WASM, which we would hook into at a lower-level...
https://github.com/v8/v8/blob/3c8c1c9d0a7d51cb8634dba2d829bd7d99d99163/include/v8.h#L1562-L1572
https://github.com/v8/v8/blob/3c8c1c9d0a7d51cb8634dba2d829bd7d99d99163/include/v8.h#L4648-L4668
https://github.com/v8/v8/blob/3c8c1c9d0a7d51cb8634dba2d829bd7d99d99163/include/v8.h#L4670-L4729
These APIs will be easier to access once we replace libdeno with rusty_v8
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ry I'm actually planning to do something similar to TsCompiler
to delegate discovery of imports/exports through a separate worker, and construct a script based on the message posted back. These V8 APIs seems lacking access to import/export details...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what you need exactly but I'm sure it's there somewhere. Check out GetModuleNamespace.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ry I believe that is from v8::internal
that is not public?
Anyways I am now able to get named exports working now by having a JS worker compile and get imports/exports for me before I construct the static scripts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cli/compilers/wasm_wrap.js
Outdated
@@ -0,0 +1,25 @@ | |||
function base64ToUint8Array(data) {{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this file is to have a .js filename extension, then it should be syntactically valid JS.
Rather than using format!
, which induces these double braces, it would be better to use a template of some sort. Maybe you can just do a substring replacement on BASE64_ENCODED_WASM
(or something)
cli/compilers/wasm_wrap.js
Outdated
|
||
const instance = new WebAssembly.Instance(compiled, importObject); | ||
|
||
export default instance.exports; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's cool about this is I think it would even work with deno bundle
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, actually that would simplify what I was going to do, there are consequences which I will detail in the related issue though.
Now supports named exports. Done through booting up a JS worker to extract imports/exports for us, sending back the info, and construct a static script based on it. Bonus point: now imports are all static, so |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM - very nice - I'm sure we'll need to iterate on this but I'm happy to land now that you've got the exports working.
* loader: support .wasm imports * http_server: true * Support named exports * Clippy
Imported WASM file can import from other JS files as follows
See
cli/compilers/wasm.rs
andcli/compilers/wasm_wrap.js
for details.Currently supporting only default exports since we currently have no access to Worker for running code from Compiler trait. (since also means currently we need--allow-read
to do dynamic imports (doable under top-level await)). This is different from Node.js, which implements named exports, since Node tries to compile WASM module first (as it can run JS code before module creation), extractingwasmModule.imports
andwasmModule.exports
, and build a dynamic script with static imports and explicit named exports and compile the script as a separate ES module. See https://github.com/nodejs/node/blob/35ec01097b2a397ad0a22aac536fe07514876e21/lib/internal/modules/esm/translators.js#L190-L210Named exports is implemented.
Usage of base64 encoding is debatable if we can accept failure of resolution given cases whereUsing string replacementsDeno
namespace is hidden. Braces inwasm_wrap.js
are double braces to avoid breakingformat!()
macro.