Skip to content
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

Support the Tail Call Proposal #4111

Merged
merged 1 commit into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

### Added

* Added support for the WebAssembly `Tail Call` proposal.
[#4111](https://github.com/rustwasm/wasm-bindgen/pull/4111)

* Add bindings for `RTCPeerConnection.setConfiguration(RTCConfiguration)` method.
[#4105](https://github.com/rustwasm/wasm-bindgen/pull/4105)

Expand Down Expand Up @@ -204,7 +207,7 @@ Released 2024-08-13

* Fix MDN links to static interface methods.
[#4010](https://github.com/rustwasm/wasm-bindgen/pull/4010)

* Fixed Deno support.
[#3990](https://github.com/rustwasm/wasm-bindgen/pull/3990)

Expand Down
2 changes: 1 addition & 1 deletion crates/cli-support/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tempfile = "3.0"
unicode-ident = "1.0.5"
walrus = "0.21"
walrus = "0.21.2"
wasm-bindgen-externref-xform = { path = '../externref-xform', version = '=0.2.93' }
wasm-bindgen-multi-value-xform = { path = '../multi-value-xform', version = '=0.2.93' }
wasm-bindgen-shared = { path = "../shared", version = '=0.2.93' }
Expand Down
12 changes: 12 additions & 0 deletions crates/cli-support/src/descriptors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,12 @@ impl WasmBindgenDescriptorsSection {
self.found = true;
}
}

fn visit_return_call(&mut self, instr: &walrus::ir::ReturnCall) {
if instr.func == self.wbindgen_describe_closure {
self.found = true;
}
}
}

struct UpdateDescribeClosure {
Expand All @@ -212,6 +218,12 @@ impl WasmBindgenDescriptorsSection {
call.func = self.replacement;
}
}

fn visit_return_call_mut(&mut self, instr: &mut walrus::ir::ReturnCall) {
if instr.func == self.wbindgen_describe_closure {
instr.func = self.replacement;
}
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ serde = { version = "1.0", features = ['derive'] }
serde_derive = "1.0"
serde_json = "1.0"
ureq = { version = "2.7", default-features = false, features = ["brotli", "gzip"] }
walrus = { version = "0.21", features = ['parallel'] }
walrus = { version = "0.21.2", features = ['parallel'] }
wasm-bindgen-cli-support = { path = "../cli-support", version = "=0.2.93" }
wasm-bindgen-shared = { path = "../shared", version = "=0.2.93" }

Expand Down
2 changes: 1 addition & 1 deletion crates/externref-xform/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ version = "0.2.93"

[dependencies]
anyhow = "1.0"
walrus = "0.21"
walrus = "0.21.2"
wasm-bindgen-wasm-conventions = { path = "../wasm-conventions", version = "=0.2.93" }

[dev-dependencies]
Expand Down
15 changes: 8 additions & 7 deletions crates/externref-xform/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -722,18 +722,19 @@ impl Transform<'_> {
impl VisitorMut for Rewrite<'_, '_> {
fn start_instr_seq_mut(&mut self, seq: &mut InstrSeq) {
for i in (0..seq.instrs.len()).rev() {
let call = match &mut seq.instrs[i].0 {
Instr::Call(call) => call,
let func = match &mut seq.instrs[i].0 {
Instr::Call(Call { func }) => func,
Instr::ReturnCall(ReturnCall { func }) => func,
_ => continue,
};
let intrinsic = match self.xform.intrinsic_map.get(&call.func) {
let intrinsic = match self.xform.intrinsic_map.get(func) {
Some(f) => f,
None => {
// If this wasn't a call of an intrinsic, but it was a
// call of one of our old import functions then we
// switch the functions we're calling here.
if let Some(f) = self.xform.import_map.get(&call.func) {
call.func = *f;
if let Some(f) = self.xform.import_map.get(func) {
*func = *f;
}
continue;
}
Expand Down Expand Up @@ -776,8 +777,8 @@ impl Transform<'_> {
seq.instrs
.insert(i, (RefNull { ty }.into(), InstrLocId::default()));
}
Intrinsic::DropRef => call.func = self.heap_dealloc,
Intrinsic::CloneRef => call.func = self.clone_ref,
Intrinsic::DropRef => *func = self.heap_dealloc,
Intrinsic::CloneRef => *func = self.clone_ref,
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/multi-value-xform/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ version = "0.2.93"

[dependencies]
anyhow = "1.0"
walrus = "0.21"
walrus = "0.21.2"
wasm-bindgen-wasm-conventions = { path = "../wasm-conventions", version = "=0.2.93" }

[dev-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion crates/threads-xform/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ version = "0.2.93"

[dependencies]
anyhow = "1.0"
walrus = "0.21"
walrus = "0.21.2"
wasm-bindgen-wasm-conventions = { path = "../wasm-conventions", version = "=0.2.93" }

[dev-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion crates/wasm-conventions/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ version = "0.2.93"

[dependencies]
leb128 = "0.2"
walrus = "0.21"
walrus = "0.21.2"
# Matching the version `walrus` depends on.
anyhow = "1.0"
log = "0.4"
Expand Down
2 changes: 1 addition & 1 deletion crates/wasm-interpreter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ version = "0.2.93"
[dependencies]
anyhow = "1.0"
log = "0.4"
walrus = "0.21"
walrus = "0.21.2"
wasm-bindgen-wasm-conventions = { path = "../wasm-conventions", version = "0.2.93" }

[dev-dependencies]
Expand Down
18 changes: 12 additions & 6 deletions crates/wasm-interpreter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,13 +338,14 @@ impl Frame<'_> {
stack.pop().unwrap();
}

Instr::Call(e) => {
Instr::Call(Call { func }) | Instr::ReturnCall(ReturnCall { func }) => {
let func = *func;
// If this function is calling the `__wbindgen_describe`
// function, which we've precomputed the id for, then
// it's telling us about the next `u32` element in the
// descriptor to return. We "call" the imported function
// here by directly inlining it.
if Some(e.func) == self.interp.describe_id {
if Some(func) == self.interp.describe_id {
let val = stack.pop().unwrap();
log::debug!("__wbindgen_describe({})", val);
self.interp.descriptor.push(val as u32);
Expand All @@ -354,7 +355,7 @@ impl Frame<'_> {
// slightly different signature. Note that we don't eval the
// previous arguments because they shouldn't have any side
// effects we're interested in.
} else if Some(e.func) == self.interp.describe_closure_id {
} else if Some(func) == self.interp.describe_closure_id {
let val = stack.pop().unwrap();
stack.pop();
stack.pop();
Expand All @@ -368,7 +369,7 @@ impl Frame<'_> {
if self
.module
.funcs
.get(e.func)
.get(func)
.name
.as_ref()
.is_some_and(|name| {
Expand All @@ -380,12 +381,17 @@ impl Frame<'_> {
return Ok(());
}

let ty = self.module.types.get(self.module.funcs.get(e.func).ty());
let ty = self.module.types.get(self.module.funcs.get(func).ty());
let args = (0..ty.params().len())
.map(|_| stack.pop().unwrap())
.collect::<Vec<_>>();

self.interp.call(e.func, self.module, &args);
self.interp.call(func, self.module, &args);
}

if let Instr::ReturnCall(_) = instr {
log::debug!("return_call");
self.done = true;
}
}

Expand Down