Skip to content

Commit 94ba156

Browse files
authored
Use Stackbased return pointer for imports (#1132)
Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
1 parent e566d45 commit 94ba156

File tree

1 file changed

+9
-20
lines changed

1 file changed

+9
-20
lines changed

crates/csharp/src/function.rs

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ pub(crate) struct FunctionBindgen<'a, 'b> {
2727
cleanup: Vec<Cleanup>,
2828
import_return_pointer_area_size: usize,
2929
import_return_pointer_area_align: usize,
30-
fixed: usize, // Number of `fixed` blocks that need to be closed.
3130
pub(crate) resource_drops: Vec<(String, String)>,
3231
}
3332

@@ -61,7 +60,6 @@ impl<'a, 'b> FunctionBindgen<'a, 'b> {
6160
cleanup: Vec::new(),
6261
import_return_pointer_area_size: 0,
6362
import_return_pointer_area_align: 0,
64-
fixed: 0,
6563
resource_drops: Vec::new(),
6664
}
6765
}
@@ -1016,10 +1014,6 @@ impl Bindgen for FunctionBindgen<'_, '_> {
10161014
uwriteln!(self.src, "return ({results});")
10171015
}
10181016
}
1019-
// Close all the fixed blocks.
1020-
for _ in 0..self.fixed {
1021-
uwriteln!(self.src, "}}");
1022-
}
10231017
}
10241018
}
10251019

@@ -1160,8 +1154,6 @@ impl Bindgen for FunctionBindgen<'_, '_> {
11601154
fn return_pointer(&mut self, size: usize, align: usize) -> String {
11611155
let ptr = self.locals.tmp("ptr");
11621156

1163-
// Use a stack-based return area for imports, because exports need
1164-
// their return area to be live until the post-return call.
11651157
match self.interface_gen.direction {
11661158
Direction::Import => {
11671159
self.import_return_pointer_area_size =
@@ -1173,25 +1165,22 @@ impl Bindgen for FunctionBindgen<'_, '_> {
11731165
self.import_return_pointer_area_align,
11741166
);
11751167
let ret_area = self.locals.tmp("retArea");
1176-
let ret_area_byte0 = self.locals.tmp("retAreaByte0");
1168+
// We can use the stack here to get a return pointer when importing.
1169+
// We do need to do a slight over-allocation since C# doesn't provide a way
1170+
// to align the allocation via the stackalloc command, unlike with a fixed array where the pointer will be aligned.
1171+
// We get the final ptr to pass to the wasm runtime by shifting to the
1172+
// correctly aligned pointer (sometimes it can be already aligned).
11771173
uwrite!(
11781174
self.src,
11791175
"
1180-
var {2} = new {0}[{1}];
1181-
fixed ({0}* {3} = &{2}[0])
1182-
{{
1183-
var {ptr} = (nint){3};
1184-
",
1185-
element_type,
1186-
array_size,
1187-
ret_area,
1188-
ret_area_byte0
1176+
var {ret_area} = stackalloc {element_type}[{array_size}+1];
1177+
var {ptr} = ((int){ret_area}) + ({align} - 1) & -{align};
1178+
"
11891179
);
1190-
self.fixed = self.fixed + 1;
1191-
11921180
format!("{ptr}")
11931181
}
11941182
Direction::Export => {
1183+
// exports need their return area to be live until the post-return call.
11951184
self.interface_gen.csharp_gen.return_area_size =
11961185
self.interface_gen.csharp_gen.return_area_size.max(size);
11971186
self.interface_gen.csharp_gen.return_area_align =

0 commit comments

Comments
 (0)