-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
AssemblyScript transformer #5598
base: v2
Are you sure you want to change the base?
Conversation
|
ca9a304
to
2d99318
Compare
// TODO port Rollup improts | ||
code: ` | ||
import {compileStreaming} from "${SPECIAL_IMPORT}"; | ||
const wasmUrl = import.meta.ROLLUP_FILE_URL_${asset.id} |
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.
Not sure how to port this
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.
Conceptually, this should be the result of asset.addDependency()
which gets replaced with the correct url.
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.
This might work:
let wasmCode = asc.compile(/*...*/);
asset.type = "js";
asset.setCode(`
import wasmURL from "my-wasm";
export const modulePromise = /*@__PURE__*/(() => compileStreaming(fetch(wasmUrl)))();
export const instancePromise = /*@__PURE__*/(() => modulePromise.then(module => WebAssembly.instantiate(module, {})))();
export default wasmUrl;
`)
asset.addURLDependency('my-wasm');
return [asset, {type: 'wasm', uniqueKey: 'my-wasm', code: wasmCode}];
const MARKER = 'asc:'; | ||
const PREFIX_MATCHER = /^asc:(.+)$/; | ||
|
||
// This special import contains the `compileStreaming` polyfill. | ||
const SPECIAL_IMPORT = '__rollup-plugin-assemblyscript_compileStreaming'; | ||
|
||
const compileStreamingCode = ` | ||
export async function compileStreaming(respP) { | ||
if('compileStreaming' in WebAssembly) { | ||
return WebAssembly.compileStreaming(respP); | ||
} | ||
return respP | ||
.then(resp => resp.arrayBuffer()) | ||
.then(buffer => WebAssembly.compile(buffer)); | ||
} | ||
`; |
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.
Not sure how I can use these in Parcel
https://github.com/surma/rollup-plugin-assemblyscript/blob/da03273c4da0979e84d432cd0827a69e2443ecff/index.js#L86-L102
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.
To share code between transformer outputs, you can put this into a separate file inside the transformer package like here:
parcel/packages/transformers/js/src/visitors/modules.js
Lines 281 to 296 in e183e32
// Add a dependency so Parcel includes the helpers | |
let moduleRoot = path.resolve(__dirname, '..', '..'); | |
let helpersPath = path.resolve(__dirname, '..', 'esmodule-helpers.js'); | |
let helperSpecifier = `@parcel/transformer-js/${normalizeSeparators( | |
path.relative(moduleRoot, helpersPath), | |
)}`; | |
asset?.addDependency({ | |
moduleSpecifier: helperSpecifier, | |
resolveFrom: __filename, | |
env: { | |
includeNodeModules: { | |
'@parcel/transformer-js': true, | |
}, | |
}, | |
}); | |
https://github.com/parcel-bundler/parcel/blob/e183e32c811f066310fff0610aa856ca73a2fcb6/packages/transformers/js/src/esmodule-helpers.js
wasmFilePath, | ||
...(options.sourceMapURLPattern | ||
? [ | ||
`--sourceMap=${renderNamePattern(options.sourceMapURLPattern, { |
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.
Not sure how sourceMaps should be handled (renderNamePatter is a Rollup specific thing)
|
||
// wasm file | ||
asset.type = 'wasm'; | ||
asset.setCode(await fsp.readFile(wasmFilePath)); |
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.
Are there downsides to using this variant of the compiler instead? Would be cleaner than writing & reading from a tmpdir and would also work in the browser (from https://github.com/AssemblyScript/assemblyscript/tree/master/cli#api).
I'm a huge fan of AS, and this will definitely make using it more painless. However, I have a few concerns with this PR so far:
Overall though, this looks very promising! |
Is there a case where you need to pass an importObject with memory or imported functions to an AS wasm module? (e.g. can you |
Apparently so, AssemblyScript/assemblyscript#158... |
Also found it here: https://www.assemblyscript.org/exports-and-imports.html#imports So I guess we have to provide some why to pass them in. This is also what I dislike about the proposal for importing Wasm with ES imports. You only get the exports but there is no way to provide imports. So there's no standardized way.... |
The data to be imported from WASM could theoretically be provided via a config file, but I don't like the idea myself. At the same time, having different ways to import Rust WASM and AS WASM is just confusing and I'd rather sacrifice the ability to import from WASM than have to use both. The JS-WASM bridge is so slow that most WASM users probably don't need JS imports. A common strategy is to split logic between WASM and JS to avoid two passes across the bridge (the call and returning the value). |
The upstream package is updated: |
I tried to understand the Parcel API and mimic what the Rollup plugin does, but there are flaws in my implementation. Feel free to push to this branch. |
I think Rollup and Parcel differ enough that it makes more sense to reimplement the features instead of a 1:1 port. I've made a minimal version work (no automatic JS wrapper/runtime, the generated Wasm simply replaces the previous AS file) and added an example We probably also need a config file for the assemblyscript compiler options |
4385fe8
to
3a29196
Compare
|
||
let code = await asset.getCode(); | ||
const {binary} = asc.compileString(code, { | ||
// optimize: true, |
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 user should be able to modify the options here
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.
Yes, that's what I meant with
We probably also need a config file for the assemblyscript compiler options
As-bind is a killer feature and should be also implemented. |
Automatic wasm instantiation would be nice, but as seen in the Rollup plugin, it requires supporting a notion like
|
↪️ Pull Request
WIP. Traying to port the rollup plugin
https://github.com/surma/rollup-plugin-assemblyscript
💻 Examples
🚨 Test instructions
✔️ PR Todo