Skip to content

Commit 67f5e8d

Browse files
committed
Automatic adaption to 64bit architectures in guest code
1 parent 81ae4c0 commit 67f5e8d

File tree

8 files changed

+408
-282
lines changed

8 files changed

+408
-282
lines changed

crates/c/src/lib.rs

Lines changed: 47 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ struct C {
1818
opts: Opts,
1919
h_includes: Vec<String>,
2020
c_includes: Vec<String>,
21-
return_pointer_area_size: usize,
22-
return_pointer_area_align: usize,
21+
return_pointer_area_size: ArchitectureSize,
22+
return_pointer_area_align: Alignment,
2323
names: Ns,
2424
needs_string: bool,
2525
needs_union_int32_float: bool,
@@ -463,16 +463,18 @@ impl WorldGenerator for C {
463463
// Declare a statically-allocated return area, if needed. We only do
464464
// this for export bindings, because import bindings allocate their
465465
// return-area on the stack.
466-
if self.return_pointer_area_size > 0 {
466+
if !self.return_pointer_area_size.is_empty() {
467467
// Automatic indentation avoided due to `extern "C" {` declaration
468468
uwrite!(
469469
c_str,
470470
"
471471
__attribute__((__aligned__({})))
472472
static uint8_t RET_AREA[{}];
473473
",
474-
self.return_pointer_area_align,
475-
self.return_pointer_area_size,
474+
self.return_pointer_area_align
475+
.format(POINTER_SIZE_EXPRESSION),
476+
self.return_pointer_area_size
477+
.format(POINTER_SIZE_EXPRESSION),
476478
);
477479
}
478480
c_str.push_str(&self.src.c_adapters);
@@ -1788,12 +1790,14 @@ impl InterfaceGenerator<'_> {
17881790
..
17891791
} = f;
17901792

1791-
if import_return_pointer_area_size > 0 {
1793+
if !import_return_pointer_area_size.is_empty() {
17921794
self.src.c_adapters(&format!(
17931795
"\
1794-
__attribute__((__aligned__({import_return_pointer_area_align})))
1795-
uint8_t ret_area[{import_return_pointer_area_size}];
1796+
__attribute__((__aligned__({})))
1797+
uint8_t ret_area[{}];
17961798
",
1799+
import_return_pointer_area_align.format(POINTER_SIZE_EXPRESSION),
1800+
import_return_pointer_area_size.format(POINTER_SIZE_EXPRESSION),
17971801
));
17981802
}
17991803

@@ -2132,8 +2136,8 @@ struct FunctionBindgen<'a, 'b> {
21322136
params: Vec<String>,
21332137
wasm_return: Option<String>,
21342138
ret_store_cnt: usize,
2135-
import_return_pointer_area_size: usize,
2136-
import_return_pointer_area_align: usize,
2139+
import_return_pointer_area_size: ArchitectureSize,
2140+
import_return_pointer_area_align: Alignment,
21372141

21382142
/// Borrows observed during lifting an export, that will need to be dropped when the guest
21392143
/// function exits.
@@ -2161,8 +2165,8 @@ impl<'a, 'b> FunctionBindgen<'a, 'b> {
21612165
params: Vec::new(),
21622166
wasm_return: None,
21632167
ret_store_cnt: 0,
2164-
import_return_pointer_area_size: 0,
2165-
import_return_pointer_area_align: 0,
2168+
import_return_pointer_area_size: Default::default(),
2169+
import_return_pointer_area_align: Default::default(),
21662170
borrow_decls: Default::default(),
21672171
borrows: Vec::new(),
21682172
}
@@ -2175,23 +2179,40 @@ impl<'a, 'b> FunctionBindgen<'a, 'b> {
21752179
self.src.push_str(";\n");
21762180
}
21772181

2178-
fn load(&mut self, ty: &str, offset: i32, operands: &[String], results: &mut Vec<String>) {
2179-
results.push(format!("*(({}*) ({} + {}))", ty, operands[0], offset));
2182+
fn load(
2183+
&mut self,
2184+
ty: &str,
2185+
offset: ArchitectureSize,
2186+
operands: &[String],
2187+
results: &mut Vec<String>,
2188+
) {
2189+
results.push(format!(
2190+
"*(({}*) ({} + {}))",
2191+
ty,
2192+
operands[0],
2193+
offset.format(POINTER_SIZE_EXPRESSION)
2194+
));
21802195
}
21812196

2182-
fn load_ext(&mut self, ty: &str, offset: i32, operands: &[String], results: &mut Vec<String>) {
2197+
fn load_ext(
2198+
&mut self,
2199+
ty: &str,
2200+
offset: ArchitectureSize,
2201+
operands: &[String],
2202+
results: &mut Vec<String>,
2203+
) {
21832204
self.load(ty, offset, operands, results);
21842205
let result = results.pop().unwrap();
21852206
results.push(format!("(int32_t) {}", result));
21862207
}
21872208

2188-
fn store(&mut self, ty: &str, offset: i32, operands: &[String]) {
2209+
fn store(&mut self, ty: &str, offset: ArchitectureSize, operands: &[String]) {
21892210
uwriteln!(
21902211
self.src,
21912212
"*(({}*)({} + {})) = {};",
21922213
ty,
21932214
operands[1],
2194-
offset,
2215+
offset.format(POINTER_SIZE_EXPRESSION),
21952216
operands[0]
21962217
);
21972218
}
@@ -2241,7 +2262,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
22412262
self.blocks.push((src.into(), mem::take(operands)));
22422263
}
22432264

2244-
fn return_pointer(&mut self, size: usize, align: usize) -> String {
2265+
fn return_pointer(&mut self, size: ArchitectureSize, align: Alignment) -> String {
22452266
let ptr = self.locals.tmp("ptr");
22462267

22472268
// Use a stack-based return area for imports, because exports need
@@ -3045,8 +3066,12 @@ impl Bindgen for FunctionBindgen<'_, '_> {
30453066
uwriteln!(self.src, "uint8_t *{ptr} = {};", operands[0]);
30463067
let i = self.locals.tmp("i");
30473068
uwriteln!(self.src, "for (size_t {i} = 0; {i} < {len}; {i}++) {{");
3048-
let size = self.gen.gen.sizes.size(element).size_wasm32();
3049-
uwriteln!(self.src, "uint8_t *base = {ptr} + {i} * {size};");
3069+
let size = self.gen.gen.sizes.size(element);
3070+
uwriteln!(
3071+
self.src,
3072+
"uint8_t *base = {ptr} + {i} * {};",
3073+
size.format(POINTER_SIZE_EXPRESSION)
3074+
);
30503075
uwriteln!(self.src, "(void) base;");
30513076
uwrite!(self.src, "{body}");
30523077
uwriteln!(self.src, "}}");
@@ -3284,3 +3309,5 @@ pub fn to_c_ident(name: &str) -> String {
32843309
s => s.to_snake_case(),
32853310
}
32863311
}
3312+
3313+
const POINTER_SIZE_EXPRESSION: &str = "sizeof(void*)";

0 commit comments

Comments
 (0)