Skip to content

Commit 73a7f68

Browse files
daxpeddaLiamolucko
andcommitted
Rework DeferCallCore to DeferFree
Co-Authored-By: Liam Murphy <[email protected]>
1 parent 8a88582 commit 73a7f68

File tree

3 files changed

+26
-55
lines changed

3 files changed

+26
-55
lines changed

crates/cli-support/src/js/binding.rs

+18-50
Original file line numberDiff line numberDiff line change
@@ -548,57 +548,32 @@ fn instruction(js: &mut JsBuilder, instr: &Instruction, log_error: &mut bool) ->
548548
| Instruction::CallExport(_)
549549
| Instruction::CallAdapter(_)
550550
| Instruction::CallTableElement(_)
551-
| Instruction::DeferCallCore(_) => {
551+
| Instruction::DeferFree { align, .. } => {
552552
let invoc = Invocation::from(instr, js.cx.module)?;
553553
let (mut params, results) = invoc.params_results(js.cx);
554+
assert_eq!(results, 0, "deferred calls must have no results");
555+
// substract alignment
556+
params -= 1;
554557

555558
let mut args = Vec::new();
556559
let tmp = js.tmp();
557-
if invoc.defer() {
558-
// substract alignment
559-
params -= 1;
560-
// If the call is deferred, the arguments to the function still need to be
561-
// accessible in the `finally` block, so we declare variables to hold the args
562-
// outside of the try-finally block and then set those to the args.
563-
for (i, arg) in js.stack[js.stack.len() - params..].iter().enumerate() {
564-
let name = format!("deferred{tmp}_{i}");
565-
writeln!(js.pre_try, "let {name};").unwrap();
566-
writeln!(js.prelude, "{name} = {arg};").unwrap();
567-
args.push(name);
568-
}
569-
// add alignment
570-
args.push(String::from("4"));
571-
} else {
572-
// Otherwise, pop off the number of parameters for the function we're calling.
573-
for _ in 0..params {
574-
args.push(js.pop());
575-
}
576-
args.reverse();
560+
561+
// If the call is deferred, the arguments to the function still need to be
562+
// accessible in the `finally` block, so we declare variables to hold the args
563+
// outside of the try-finally block and then set those to the args.
564+
for (i, arg) in js.stack[js.stack.len() - params..].iter().enumerate() {
565+
let name = format!("deferred{tmp}_{i}");
566+
writeln!(js.pre_try, "let {name};").unwrap();
567+
writeln!(js.prelude, "{name} = {arg};").unwrap();
568+
args.push(name);
577569
}
570+
// add alignment
571+
args.push(align.to_string());
578572

579573
// Call the function through an export of the underlying module.
580574
let call = invoc.invoke(js.cx, &args, &mut js.prelude, log_error)?;
581575

582-
// And then figure out how to actually handle where the call
583-
// happens. This is pretty conditional depending on the number of
584-
// return values of the function.
585-
match (invoc.defer(), results) {
586-
(true, 0) => {
587-
js.finally(&format!("{};", call));
588-
}
589-
(true, _) => panic!("deferred calls must have no results"),
590-
(false, 0) => js.prelude(&format!("{};", call)),
591-
(false, n) => {
592-
js.prelude(&format!("const ret = {};", call));
593-
if n == 1 {
594-
js.push("ret".to_string());
595-
} else {
596-
for i in 0..n {
597-
js.push(format!("ret[{}]", i));
598-
}
599-
}
600-
}
601-
}
576+
js.finally(&format!("{};", call));
602577
}
603578

604579
Instruction::IntToWasm { input, .. } => {
@@ -1194,8 +1169,8 @@ impl Invocation {
11941169
defer: false,
11951170
},
11961171

1197-
DeferCallCore(f) => Invocation::Core {
1198-
id: *f,
1172+
DeferFree { free, .. } => Invocation::Core {
1173+
id: *free,
11991174
defer: true,
12001175
},
12011176

@@ -1264,13 +1239,6 @@ impl Invocation {
12641239
}
12651240
}
12661241
}
1267-
1268-
fn defer(&self) -> bool {
1269-
match self {
1270-
Invocation::Core { defer, .. } => *defer,
1271-
_ => false,
1272-
}
1273-
}
12741242
}
12751243

12761244
fn adapter2ts(ty: &AdapterType, dst: &mut String) {

crates/cli-support/src/wit/outgoing.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ impl InstructionBuilder<'_, '_> {
105105
// ... then defer a call to `free` to happen later
106106
let free = self.cx.free()?;
107107
self.instructions.push(InstructionData {
108-
instr: Instruction::DeferCallCore(free),
108+
instr: Instruction::DeferFree { free, align: 1 },
109109
stack_change: StackChange::Modified {
110110
popped: 2,
111111
pushed: 2,
@@ -389,7 +389,7 @@ impl InstructionBuilder<'_, '_> {
389389
// special case it.
390390
assert!(!self.instructions[len..]
391391
.iter()
392-
.any(|idata| matches!(idata.instr, Instruction::DeferCallCore(_))));
392+
.any(|idata| matches!(idata.instr, Instruction::DeferFree { .. })));
393393

394394
// Finally, we add the two inputs to UnwrapResult, and everything checks out
395395
//
@@ -429,7 +429,7 @@ impl InstructionBuilder<'_, '_> {
429429
// implementation.
430430
let free = self.cx.free()?;
431431
self.instructions.push(InstructionData {
432-
instr: Instruction::DeferCallCore(free),
432+
instr: Instruction::DeferFree { free, align: 1 },
433433
stack_change: StackChange::Modified {
434434
popped: 2,
435435
pushed: 2,

crates/cli-support/src/wit/standard.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,10 @@ pub enum Instruction {
9595
CallCore(walrus::FunctionId),
9696
/// Schedules a function to be called after the whole lift/lower cycle is
9797
/// finished, e.g. to deallocate a string or something.
98-
DeferCallCore(walrus::FunctionId),
98+
DeferFree {
99+
free: walrus::FunctionId,
100+
align: usize,
101+
},
99102
/// A call to one of our own defined adapters, similar to the standard
100103
/// call-adapter instruction
101104
CallAdapter(AdapterId),
@@ -423,7 +426,7 @@ impl walrus::CustomSection for NonstandardWitSection {
423426
};
424427
for instr in instrs {
425428
match instr.instr {
426-
DeferCallCore(f) | CallCore(f) => {
429+
DeferFree { free: f, .. } | CallCore(f) => {
427430
roots.push_func(f);
428431
}
429432
StoreRetptr { mem, .. }

0 commit comments

Comments
 (0)