Skip to content

Commit 6b6fd0f

Browse files
cabi_post_* and cabi_realloc
1 parent 2f9a7ff commit 6b6fd0f

2 files changed

Lines changed: 135 additions & 21 deletions

File tree

crates/d/src/lib.rs

Lines changed: 125 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,6 +1057,9 @@ impl<'a> DInterfaceGenerator<'a> {
10571057
_ => false,
10581058
};
10591059

1060+
res.post_return = self.direction == Some(Direction::Export)
1061+
&& abi::guest_export_needs_post_return(self.resolve, func);
1062+
10601063
res.result
10611064
.push_str(&(self.optional_type_name(func.result.as_ref(), self.fqn)));
10621065

@@ -1296,23 +1299,21 @@ impl<'a> DInterfaceGenerator<'a> {
12961299
}
12971300
}
12981301

1302+
let core_module_name = self.name.map(|s| self.resolve.name_world_key(s));
1303+
let export_name = func.legacy_core_export_name(core_module_name.as_deref());
1304+
12991305
self.src.push_str("/// ditto\n");
1300-
self.src.push_str(&format!(
1301-
"@wasmExport!(\"{}#{}\")\n",
1302-
self.wasm_import_module.unwrap(),
1303-
func.name
1304-
));
1306+
self.src
1307+
.push_str(&format!("@wasmExport!(\"{export_name}\")\n"));
13051308

13061309
self.src.push_str(&format!(
1307-
"pragma(mangle, \"__wit_export_{}__{}\")\n",
1308-
self.wasm_import_module
1309-
.unwrap()
1310+
"pragma(mangle, \"__wit_export_{}\")\n",
1311+
export_name
13101312
.replace("/", "__")
1311-
.replace("-", "_"),
1312-
func.name
13131313
.replace("-", "_")
13141314
.replace("[", ":")
13151315
.replace("]", ":")
1316+
.replace("#", "::")
13161317
));
13171318

13181319
if d_sig.implicit_self || d_sig.static_member {
@@ -1362,6 +1363,68 @@ impl<'a> DInterfaceGenerator<'a> {
13621363
self.src.push_str(&src.to_string());
13631364

13641365
self.src.push_str("}\n");
1366+
1367+
if abi::guest_export_needs_post_return(self.resolve, func) {
1368+
let mut param_data = Vec::new();
1369+
let mut params = Vec::<&str>::new();
1370+
1371+
for (arg, _ty) in wasm_sig.results.iter().enumerate() {
1372+
param_data.push(format!("arg{arg}"));
1373+
}
1374+
for param in &param_data {
1375+
params.push(&param);
1376+
}
1377+
1378+
self.src
1379+
.push_str(&format!("@wasmExport!(\"cabi_post_{export_name}\")\n"));
1380+
1381+
self.src.push_str(&format!(
1382+
"pragma(mangle, \"__wit_cabi_post_{}\")\n",
1383+
export_name
1384+
.replace("/", "__")
1385+
.replace("-", "_")
1386+
.replace("[", ":")
1387+
.replace("]", ":")
1388+
.replace("#", "::")
1389+
));
1390+
1391+
if d_sig.implicit_self || d_sig.static_member {
1392+
self.src.push_str("static ");
1393+
}
1394+
self.src.push_str(&format!(
1395+
"private extern(C) void __cabi_post_{}({}) {{\n",
1396+
d_sig.name,
1397+
wasm_sig
1398+
.results
1399+
.iter()
1400+
.zip(&params)
1401+
.map(|(ty, name)| format!("{} {name}", wasm_type(*ty)))
1402+
.collect::<Vec<String>>()
1403+
.join(", ")
1404+
));
1405+
1406+
let mut f = FunctionBindgen::new(self, &params);
1407+
abi::post_return(f.r#gen.resolve, func, &mut f);
1408+
1409+
let ret_area_decl = f.emit_ret_area_if_needed();
1410+
1411+
let FunctionBindgen {
1412+
src,
1413+
return_pointer_area_size,
1414+
return_pointer_area_align,
1415+
..
1416+
} = f;
1417+
self.return_pointer_area_size =
1418+
self.return_pointer_area_size.max(return_pointer_area_size);
1419+
self.return_pointer_area_align = self
1420+
.return_pointer_area_align
1421+
.max(return_pointer_area_align);
1422+
1423+
self.src.push_str(&ret_area_decl);
1424+
self.src.push_str(&src.to_string());
1425+
1426+
self.src.push_str("}\n");
1427+
}
13651428
}
13661429

13671430
fn emit_ret_area_if_needed(&self) -> String {
@@ -1615,10 +1678,10 @@ impl<'a> InterfaceGenerator<'a> for DInterfaceGenerator<'a> {
16151678

16161679
self.src.push_str(&format!(
16171680
"struct Borrow {{
1618-
package(wit) void* __ptr = null;
1681+
package(wit) uint __handle = 0;
16191682
1620-
package(wit) this(void* ptr) {{
1621-
__ptr = ptr;
1683+
package(wit) this(uint handle) {{
1684+
__handle = handle;
16221685
}}
16231686
16241687
@disable this();
@@ -2861,16 +2924,57 @@ impl<'a, 'b> Bindgen for FunctionBindgen<'a, 'b> {
28612924
self.push_str(&format!("free({});", operands[0]));
28622925
}
28632926
abi::Instruction::GuestDeallocateString { .. } => {
2864-
todo!("instr: GuestDeallocateString");
2865-
//self.push_str(&format!("if (({}) > 0) {{\n", operands[1]));
2866-
//self.push_str(&format!("free({});", operands[0]));
2867-
//self.push_str("}\n");
2927+
self.push_str(&format!("if ({} > 0) {{\n", operands[1]));
2928+
self.push_str(&format!("free({});\n", operands[0]));
2929+
self.push_str("}\n");
28682930
}
2869-
abi::Instruction::GuestDeallocateList { .. } => {
2870-
todo!("instr: GuestDeallocateList")
2931+
abi::Instruction::GuestDeallocateList { element } => {
2932+
let Block {
2933+
body,
2934+
results: block_results,
2935+
element: block_element,
2936+
base,
2937+
} = self.blocks.pop().unwrap();
2938+
let tmp = self.tmp();
2939+
let size = self.r#gen.sizes.size(element);
2940+
let size_str = size.format("size_t.sizeof");
2941+
2942+
let list = tempname("_list", tmp);
2943+
let list_len = tempname("_listLen", tmp);
2944+
let list_src = tempname("_listSrcPtr", tmp);
2945+
self.push_str(&format!("auto {list_src} = {};\n", operands[0]));
2946+
self.push_str(&format!("auto {list_len} = {};\n", operands[1]));
2947+
2948+
self.push_str(&format!(
2949+
"foreach ({block_element}_idx; 0..{list_len}) {{\n",
2950+
));
2951+
self.push_str(&format!(
2952+
"const auto {base} = {list_src} + {block_element}_idx * {size_str};\n"
2953+
));
2954+
self.push_str(&body);
2955+
self.push_str("\n}\n");
2956+
2957+
self.push_str(&format!("if ({} > 0) {{\n", operands[1]));
2958+
self.push_str(&format!("free({});\n", operands[0]));
2959+
self.push_str("}\n");
28712960
}
2872-
abi::Instruction::GuestDeallocateVariant { .. } => {
2873-
todo!("instr: GuestDeallocateVariant")
2961+
abi::Instruction::GuestDeallocateVariant {
2962+
blocks: block_count,
2963+
} => {
2964+
let blocks = self
2965+
.blocks
2966+
.drain(self.blocks.len() - block_count..)
2967+
.collect::<Vec<_>>();
2968+
2969+
self.push_str(&format!("switch ({}) {{\n", operands[0]));
2970+
for (i, block) in blocks.into_iter().enumerate() {
2971+
assert!(results.is_empty());
2972+
2973+
self.push_str(&format!("case {}: {{\n", i));
2974+
self.src.push_str(&block.body);
2975+
self.src.push_str("break;\n}\n");
2976+
}
2977+
self.src.push_str("default: break;\n}\n");
28742978
}
28752979
abi::Instruction::DropHandle { .. } => {
28762980
todo!("instr: DropHandle")

crates/d/src/wit_common.d

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,9 @@ package(wit):
234234

235235
extern(C) {
236236
void* malloc(size_t size);
237+
void* realloc(void* ptr, size_t newSIzew);
237238
void free(void* ptr);
239+
noreturn abort();
238240
}
239241

240242
// from numem.casting
@@ -335,3 +337,11 @@ template witExportsIn(T) {
335337
}
336338
}
337339
}
340+
341+
@wasmExport!("cabi_realloc")
342+
void* cabi_realloc(void *ptr, size_t oldSize, size_t alignment, size_t newSize) {
343+
if (newSize == 0) return cast(void*)alignment;
344+
void *ret = realloc(ptr, newSize);
345+
if (!ret) abort();
346+
return ret;
347+
}

0 commit comments

Comments
 (0)