-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
feat: wasm text format and import support #5636
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains 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
This file contains 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
2 changes: 2 additions & 0 deletions
2
crates/turbopack-tests/tests/execution/turbopack/wasm/complex/input/README.md
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Adapted from webpack | ||
https://github.com/webpack/webpack/blob/6be4065ade1e252c1d8dcba4af0f43e32af1bdc1/examples/wasm-complex/README.md |
20 changes: 20 additions & 0 deletions
20
crates/turbopack-tests/tests/execution/turbopack/wasm/complex/input/index.js
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
describe("complex wasm", () => { | ||
it("should be possible to use imported memory", async () => { | ||
// magic.js is an async module, so we import it inside this function to make sure the entrypoint isn't async. | ||
const { get, set } = await import("./magic.js"); | ||
|
||
set(42); | ||
expect(get()).toEqual(42); | ||
set(123); | ||
expect(get()).toEqual(123); | ||
}); | ||
|
||
it("should be possible to use imported functions", async () => { | ||
// magic.js is an async module, so we import it inside this function to make sure the entrypoint isn't async. | ||
const { getNumber } = await import("./magic.js"); | ||
|
||
// random numbers | ||
expect(getNumber()).toBeGreaterThanOrEqual(0); | ||
expect(getNumber()).toBeGreaterThanOrEqual(0); | ||
}); | ||
}) |
7 changes: 7 additions & 0 deletions
7
crates/turbopack-tests/tests/execution/turbopack/wasm/complex/input/magic-number.js
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
export function getNumber() { | ||
return 42; | ||
} | ||
|
||
export function getRandomNumber() { | ||
return Math.floor(Math.random() * 256); | ||
} |
2 changes: 2 additions & 0 deletions
2
crates/turbopack-tests/tests/execution/turbopack/wasm/complex/input/magic.js
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
// reexporting | ||
export * from "./magic.wat"; |
15 changes: 15 additions & 0 deletions
15
crates/turbopack-tests/tests/execution/turbopack/wasm/complex/input/magic.wat
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
(module | ||
(type $t0 (func (result i32))) | ||
(type $t1 (func (param i32))) | ||
(import "./memory.js" "memory" (memory 1)) | ||
(import "./magic-number.js" "getRandomNumber" (func $getRandomNumber (type $t0))) | ||
(func $get (export "get") (type $t0) (result i32) | ||
(i32.load | ||
(i32.const 0))) | ||
(func $set (export "set") (type $t1) (param $p i32) | ||
(i32.store | ||
(i32.const 0) | ||
(get_local $p))) | ||
(func $getNumber (export "getNumber") (type $t0) (result i32) | ||
(call $getRandomNumber)) | ||
) |
7 changes: 7 additions & 0 deletions
7
crates/turbopack-tests/tests/execution/turbopack/wasm/complex/input/memory.js
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
async function getMemoryFromParentInWorker() { | ||
await new Promise(r => setTimeout(r, 200)); | ||
// fake | ||
return new WebAssembly.Memory({ initial: 1 }); | ||
} | ||
|
||
export const memory = await getMemoryFromParentInWorker(); |
2 changes: 1 addition & 1 deletion
2
crates/turbopack-tests/tests/execution/turbopack/wasm/simple/input/index.js
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
use std::collections::BTreeMap; | ||
|
||
use anyhow::Result; | ||
use turbo_tasks::Vc; | ||
use turbo_tasks_fs::FileContent; | ||
use turbopack_core::asset::Asset; | ||
use wasmparser::{Chunk, Parser, Payload}; | ||
|
||
use crate::source::WebAssemblySource; | ||
|
||
/// Imports and exports of a WebAssembly file. | ||
#[turbo_tasks::value] | ||
#[derive(Default)] | ||
pub(crate) struct WebAssemblyAnalysis { | ||
pub imports: BTreeMap<String, Vec<String>>, | ||
pub exports: Vec<String>, | ||
} | ||
|
||
/// Analyse a WebAssembly file. | ||
/// | ||
/// Extracts imports and exports. | ||
#[turbo_tasks::function] | ||
pub(crate) async fn analyze(source: Vc<WebAssemblySource>) -> Result<Vc<WebAssemblyAnalysis>> { | ||
let content = source.content().file_content().await?; | ||
|
||
let mut analysis = WebAssemblyAnalysis::default(); | ||
|
||
let FileContent::Content(file) = &*content else { | ||
return Ok(analysis.cell()); | ||
}; | ||
|
||
let mut bytes = &*file.content().to_bytes()?; | ||
|
||
let mut parser = Parser::new(0); | ||
loop { | ||
let payload = match parser.parse(bytes, true)? { | ||
Chunk::Parsed { consumed, payload } => { | ||
bytes = &bytes[consumed..]; | ||
payload | ||
} | ||
// this state isn't possible with `eof = true` | ||
Chunk::NeedMoreData(_) => unreachable!(), | ||
}; | ||
|
||
match payload { | ||
Payload::ImportSection(s) => { | ||
for import in s { | ||
let import = import?; | ||
|
||
analysis | ||
.imports | ||
.entry(import.module.to_string()) | ||
.or_default() | ||
.push(import.name.to_string()); | ||
} | ||
} | ||
Payload::ExportSection(s) => { | ||
for export in s { | ||
let export = export?; | ||
|
||
analysis.exports.push(export.name.to_string()); | ||
} | ||
} | ||
|
||
// skip over code sections | ||
Payload::CodeSectionStart { size, .. } => { | ||
parser.skip_section(); | ||
bytes = &bytes[size as usize..]; | ||
} | ||
|
||
Payload::End(_) => break, | ||
_ => {} | ||
} | ||
} | ||
|
||
Ok(analysis.cell()) | ||
} |
Oops, something went wrong.
Oops, something went wrong.
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.
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.
Does this double skip? We're already advancing
consumed
bytes, doesconsumed
not include the range of the code section?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.
No, because we tell the parser to skip the next section
weird API tbh, I would expect to give it the slice of bytes once, and have it keep a cursor internally