@@ -214,6 +214,7 @@ fn escape_d_identifier(name: &str) -> &str {
214214 "bits" => "bits_" , // part of WitFlags
215215 "borrow" => "borrow_" , // part of the expansion of `resource`
216216 "drop" => "drop_" , // part of the expansion of `resource`
217+ "rep" => "rep_" , // part of the expansion of `resource`
217218 "makeNew" => "makeNew_" , // part of the expansion of `resource`
218219 "constructor" => "constructor_" , // part of the expansion of `resource`
219220
@@ -625,6 +626,25 @@ impl WorldGenerator for D {
625626 }
626627 }
627628 }
629+
630+ r#gen. src . push_str ( & format ! (
631+ "\n @wasmExport!(\" {}#[dtor]{}\" )\n " ,
632+ wasm_import_module,
633+ ty. name. as_ref( ) . unwrap( )
634+ ) ) ;
635+ r#gen. src . push_str ( & format ! (
636+ "pragma(mangle, \" __wit_export_{}__:dtor:{}\" )\n " ,
637+ wasm_import_module. replace( "/" , "__" ) . replace( "-" , "_" ) ,
638+ ty. name. as_ref( ) . unwrap( ) . replace( "-" , "_" )
639+ ) ) ;
640+ r#gen. src . push_str (
641+ "static private extern(C) void __export_dtor(void* ptr) {
642+ (*cast(_Resource_Impl*)ptr).destroy!false;
643+ free(ptr);
644+ }
645+ " ,
646+ ) ;
647+
628648 r#gen. src . push_str ( "}\n " ) ;
629649
630650 if emit_exports_stubs {
@@ -1518,12 +1538,6 @@ impl<'a> InterfaceGenerator<'a> for DInterfaceGenerator<'a> {
15181538
15191539 @disable this();
15201540
1521- // TODO: make RAII? disable copy for the own
1522-
1523-
1524- auto borrow() => Borrow(__handle);
1525- alias borrow this;
1526-
15271541 "
15281542 ) ) ;
15291543
@@ -1569,17 +1583,12 @@ impl<'a> InterfaceGenerator<'a> for DInterfaceGenerator<'a> {
15691583 }
15701584
15711585 self . src
1572- . push_str ( "\n void drop() {\n __import__drop(__handle);\n }\n " ) ;
1573-
1586+ . push_str ( "\n void drop() {\n __import_drop(__handle);\n }\n " ) ;
15741587 self . src . push_str ( & format ! (
15751588 "@wasmImport!(\" {}\" , \" [resource-drop]{}\" )\n " ,
15761589 self . wasm_import_module. unwrap( ) ,
15771590 name
15781591 ) ) ;
1579-
1580- // The mangle is not important, as long as it won't conflict with other symbols
1581- // WebAssembly symbol identifiers are much more permissive than C (can be any UTF-8).
1582- // Yet, LDC before 1.42 doesn't allow full use of this fact. We make some substitutions.
15831592 self . src . push_str ( & format ! (
15841593 "pragma(mangle, \" __wit_import_{}__:resource_drop:{}\" )\n " ,
15851594 self . wasm_import_module
@@ -1589,18 +1598,22 @@ impl<'a> InterfaceGenerator<'a> for DInterfaceGenerator<'a> {
15891598 name. replace( "-" , "_" )
15901599 ) ) ;
15911600 self . src
1592- . push_str ( "static private extern(C) void __import__drop (uint);\n \n " ) ;
1601+ . push_str ( "static private extern(C) void __import_drop (uint);\n \n " ) ;
15931602
15941603 self . src . push_str ( & format ! (
1595- "struct Borrow {{
1604+ "// TODO: make RAII? disable copy for the own
1605+
1606+ auto borrow() => Borrow(__handle);
1607+ alias borrow this;
1608+
1609+ struct Borrow {{
15961610 package(wit) uint __handle = 0;
15971611
15981612 package(wit) this(uint handle) {{
15991613 __handle = handle;
16001614 }}
16011615
16021616 @disable this();
1603-
16041617 "
16051618 ) ) ;
16061619
@@ -1670,14 +1683,78 @@ impl<'a> InterfaceGenerator<'a> for DInterfaceGenerator<'a> {
16701683 }}
16711684
16721685 @disable this();
1686+ "
1687+ ) ) ;
16731688
1674- // TODO: make RAII? disable copy for the own
1689+ self . src . push_str ( & format ! (
1690+ "
1691+ static {escaped_name} makeNew(T)(scope void delegate(out T) dg) if (is(T == struct)) {{
1692+ auto ptr = cast(T*)malloc(T.sizeof);
1693+ if (ptr is null) return {escaped_name}.init;
1694+
1695+ dg(*ptr);
1696+ return {escaped_name}(__import_makeNew(ptr));
1697+ }}
1698+ " ,
1699+ ) ) ;
1700+ self . src . push_str ( & format ! (
1701+ "@wasmImport!(\" {}\" , \" [resource-new]{}\" )\n " ,
1702+ self . wasm_import_module. unwrap( ) ,
1703+ name
1704+ ) ) ;
1705+ self . src . push_str ( & format ! (
1706+ "pragma(mangle, \" __wit_import_{}__:resource_new:{}\" )\n " ,
1707+ self . wasm_import_module
1708+ . unwrap( )
1709+ . replace( "/" , "__" )
1710+ . replace( "-" , "_" ) ,
1711+ name. replace( "-" , "_" )
1712+ ) ) ;
1713+ self . src
1714+ . push_str ( "static private extern(C) uint __import_makeNew(void*);\n \n " ) ;
16751715
1676- "
1716+ self . src
1717+ . push_str ( "T* rep(T)() if (is(T == struct)) {\n return cast(T*)__import_rep(__handle);\n }\n " ) ;
1718+ self . src . push_str ( & format ! (
1719+ "@wasmImport!(\" {}\" , \" [resource-rep]{}\" )\n " ,
1720+ self . wasm_import_module. unwrap( ) ,
1721+ name
16771722 ) ) ;
1723+ self . src . push_str ( & format ! (
1724+ "pragma(mangle, \" __wit_import_{}__:resource_rep:{}\" )\n " ,
1725+ self . wasm_import_module
1726+ . unwrap( )
1727+ . replace( "/" , "__" )
1728+ . replace( "-" , "_" ) ,
1729+ name. replace( "-" , "_" )
1730+ ) ) ;
1731+ self . src
1732+ . push_str ( "static private extern(C) void __import_rep(uint);\n \n " ) ;
1733+
1734+ self . src
1735+ . push_str ( "void drop() {\n __import_drop(__handle);\n }\n " ) ;
1736+ self . src . push_str ( & format ! (
1737+ "@wasmImport!(\" {}\" , \" [resource-drop]{}\" )\n " ,
1738+ self . wasm_import_module. unwrap( ) ,
1739+ name
1740+ ) ) ;
1741+ self . src . push_str ( & format ! (
1742+ "pragma(mangle, \" __wit_import_{}__:resource_drop:{}\" )\n " ,
1743+ self . wasm_import_module
1744+ . unwrap( )
1745+ . replace( "/" , "__" )
1746+ . replace( "-" , "_" ) ,
1747+ name. replace( "-" , "_" )
1748+ ) ) ;
1749+ self . src
1750+ . push_str ( "static private extern(C) void __import_drop(uint);\n \n " ) ;
16781751
16791752 self . src . push_str ( & format ! (
1680- "struct Borrow {{
1753+ "// TODO: make RAII? disable copy for the own
1754+ auto borrow() => Borrow(__handle);
1755+ alias borrow this;
1756+
1757+ struct Borrow {{
16811758 package(wit) uint __handle = 0;
16821759
16831760 package(wit) this(uint handle) {{
0 commit comments