diff --git a/crates/cli-support/src/js/binding.rs b/crates/cli-support/src/js/binding.rs index 611c0508ecc..fdb0a0b01f9 100644 --- a/crates/cli-support/src/js/binding.rs +++ b/crates/cli-support/src/js/binding.rs @@ -548,15 +548,17 @@ fn instruction(js: &mut JsBuilder, instr: &Instruction, log_error: &mut bool) -> | Instruction::CallExport(_) | Instruction::CallAdapter(_) | Instruction::CallTableElement(_) - | Instruction::DeferCallCore(_) => { + | Instruction::DeferFree { .. } => { let invoc = Invocation::from(instr, js.cx.module)?; let (mut params, results) = invoc.params_results(js.cx); let mut args = Vec::new(); let tmp = js.tmp(); if invoc.defer() { - // substract alignment - params -= 1; + if let Instruction::DeferFree { .. } = instr { + // substract alignment + params -= 1; + } // If the call is deferred, the arguments to the function still need to be // accessible in the `finally` block, so we declare variables to hold the args // outside of the try-finally block and then set those to the args. @@ -566,8 +568,10 @@ fn instruction(js: &mut JsBuilder, instr: &Instruction, log_error: &mut bool) -> writeln!(js.prelude, "{name} = {arg};").unwrap(); args.push(name); } - // add alignment - args.push(String::from("4")); + if let Instruction::DeferFree { align, .. } = instr { + // add alignment + args.push(align.to_string()); + } } else { // Otherwise, pop off the number of parameters for the function we're calling. for _ in 0..params { @@ -1194,8 +1198,8 @@ impl Invocation { defer: false, }, - DeferCallCore(f) => Invocation::Core { - id: *f, + DeferFree { free, .. } => Invocation::Core { + id: *free, defer: true, }, diff --git a/crates/cli-support/src/wit/outgoing.rs b/crates/cli-support/src/wit/outgoing.rs index 890b79b2fb0..506d34d92fd 100644 --- a/crates/cli-support/src/wit/outgoing.rs +++ b/crates/cli-support/src/wit/outgoing.rs @@ -105,7 +105,7 @@ impl InstructionBuilder<'_, '_> { // ... then defer a call to `free` to happen later let free = self.cx.free()?; self.instructions.push(InstructionData { - instr: Instruction::DeferCallCore(free), + instr: Instruction::DeferFree { free, align: 4 }, stack_change: StackChange::Modified { popped: 2, pushed: 2, @@ -389,7 +389,7 @@ impl InstructionBuilder<'_, '_> { // special case it. assert!(!self.instructions[len..] .iter() - .any(|idata| matches!(idata.instr, Instruction::DeferCallCore(_)))); + .any(|idata| matches!(idata.instr, Instruction::DeferFree { .. }))); // Finally, we add the two inputs to UnwrapResult, and everything checks out // @@ -429,7 +429,7 @@ impl InstructionBuilder<'_, '_> { // implementation. let free = self.cx.free()?; self.instructions.push(InstructionData { - instr: Instruction::DeferCallCore(free), + instr: Instruction::DeferFree { free, align: 4 }, stack_change: StackChange::Modified { popped: 2, pushed: 2, diff --git a/crates/cli-support/src/wit/standard.rs b/crates/cli-support/src/wit/standard.rs index 953fbfa5688..ba29a75e417 100644 --- a/crates/cli-support/src/wit/standard.rs +++ b/crates/cli-support/src/wit/standard.rs @@ -95,7 +95,10 @@ pub enum Instruction { CallCore(walrus::FunctionId), /// Schedules a function to be called after the whole lift/lower cycle is /// finished, e.g. to deallocate a string or something. - DeferCallCore(walrus::FunctionId), + DeferFree { + free: walrus::FunctionId, + align: usize, + }, /// A call to one of our own defined adapters, similar to the standard /// call-adapter instruction CallAdapter(AdapterId), @@ -423,7 +426,7 @@ impl walrus::CustomSection for NonstandardWitSection { }; for instr in instrs { match instr.instr { - DeferCallCore(f) | CallCore(f) => { + DeferFree { free: f, .. } | CallCore(f) => { roots.push_func(f); } StoreRetptr { mem, .. }