Skip to content

Commit a955ee4

Browse files
authored
refactor(*): move anonymous type definition to core (#758)
* refactor(*): move anonymous type definition to core Signed-off-by: Jiaxiao Zhou (Mossaka) <[email protected]> * refactor(*): define a new trait for anonymous types Signed-off-by: Jiaxiao Zhou (Mossaka) <[email protected]> * fixed the rebase problem in gen-c Signed-off-by: Jiaxiao Zhou (Mossaka) <[email protected]> * removed comments Signed-off-by: Jiaxiao Zhou (Mossaka) <[email protected]> --------- Signed-off-by: Jiaxiao Zhou (Mossaka) <[email protected]>
1 parent b342747 commit a955ee4

File tree

3 files changed

+244
-178
lines changed

3 files changed

+244
-178
lines changed

crates/c/src/lib.rs

Lines changed: 105 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use std::fmt::Write;
77
use std::mem;
88
use wit_bindgen_core::abi::{self, AbiVariant, Bindgen, Bitcast, Instruction, LiftLower, WasmType};
99
use wit_bindgen_core::{
10-
dealias, uwrite, uwriteln, wit_parser::*, Direction, Files, InterfaceGenerator as _, Ns,
11-
WorldGenerator,
10+
dealias, uwrite, uwriteln, wit_parser::*, AnonymousTypeGenerator, Direction, Files,
11+
InterfaceGenerator as _, Ns, WorldGenerator,
1212
};
1313
use wit_component::StringEncoding;
1414

@@ -1341,6 +1341,98 @@ void __wasm_export_{ns}_{snake}_dtor({ns}_{snake}_t* arg) {{
13411341
}
13421342
}
13431343

1344+
impl<'a> wit_bindgen_core::AnonymousTypeGenerator<'a> for InterfaceGenerator<'a> {
1345+
fn resolve(&self) -> &'a Resolve {
1346+
self.resolve
1347+
}
1348+
1349+
fn anonymous_type_handle(&mut self, id: TypeId, handle: &Handle, docs: &Docs) {
1350+
self.src.h_defs("\ntypedef ");
1351+
let resource = match handle {
1352+
Handle::Borrow(id) | Handle::Own(id) => id,
1353+
};
1354+
let info = &self.gen.resources[&dealias(self.resolve, *resource)];
1355+
match handle {
1356+
Handle::Borrow(_) => self.src.h_defs(&info.borrow),
1357+
Handle::Own(_) => self.src.h_defs(&info.own),
1358+
}
1359+
self.src.h_defs(" ");
1360+
self.print_typedef_target(id);
1361+
}
1362+
1363+
fn anonymous_type_tuple(&mut self, id: TypeId, ty: &Tuple, docs: &Docs) {
1364+
self.src.h_defs("\ntypedef ");
1365+
self.src.h_defs("struct {\n");
1366+
for (i, t) in ty.types.iter().enumerate() {
1367+
let ty = self.gen.type_name(t);
1368+
uwriteln!(self.src.h_defs, "{ty} f{i};");
1369+
}
1370+
self.src.h_defs("}");
1371+
self.src.h_defs(" ");
1372+
self.print_typedef_target(id);
1373+
}
1374+
1375+
fn anonymous_type_option(&mut self, id: TypeId, ty: &Type, docs: &Docs) {
1376+
self.src.h_defs("\ntypedef ");
1377+
self.src.h_defs("struct {\n");
1378+
self.src.h_defs("bool is_some;\n");
1379+
let ty = self.gen.type_name(ty);
1380+
uwriteln!(self.src.h_defs, "{ty} val;");
1381+
self.src.h_defs("}");
1382+
self.src.h_defs(" ");
1383+
self.print_typedef_target(id);
1384+
}
1385+
1386+
fn anonymous_type_result(&mut self, id: TypeId, ty: &Result_, docs: &Docs) {
1387+
self.src.h_defs("\ntypedef ");
1388+
self.src.h_defs(
1389+
"struct {
1390+
bool is_err;
1391+
",
1392+
);
1393+
let ok_ty = ty.ok.as_ref();
1394+
let err_ty = ty.err.as_ref();
1395+
if ok_ty.is_some() || err_ty.is_some() {
1396+
self.src.h_defs("union {\n");
1397+
if let Some(ok) = ok_ty {
1398+
let ty = self.gen.type_name(ok);
1399+
uwriteln!(self.src.h_defs, "{ty} ok;");
1400+
}
1401+
if let Some(err) = err_ty {
1402+
let ty = self.gen.type_name(err);
1403+
uwriteln!(self.src.h_defs, "{ty} err;");
1404+
}
1405+
self.src.h_defs("} val;\n");
1406+
}
1407+
self.src.h_defs("}");
1408+
self.src.h_defs(" ");
1409+
self.print_typedef_target(id);
1410+
}
1411+
1412+
fn anonymous_type_list(&mut self, id: TypeId, ty: &Type, docs: &Docs) {
1413+
self.src.h_defs("\ntypedef ");
1414+
self.src.h_defs("struct {\n");
1415+
let ty = self.gen.type_name(ty);
1416+
uwriteln!(self.src.h_defs, "{ty} *ptr;");
1417+
self.src.h_defs("size_t len;\n");
1418+
self.src.h_defs("}");
1419+
self.src.h_defs(" ");
1420+
self.print_typedef_target(id);
1421+
}
1422+
1423+
fn anonymous_type_future(&mut self, id: TypeId, ty: &Option<Type>, docs: &Docs) {
1424+
todo!("print_anonymous_type for future");
1425+
}
1426+
1427+
fn anonymous_type_stream(&mut self, id: TypeId, ty: &Stream, docs: &Docs) {
1428+
todo!("print_anonymous_type for stream");
1429+
}
1430+
1431+
fn anonymous_typ_type(&mut self, id: TypeId, ty: &Type, docs: &Docs) {
1432+
todo!("print_anonymous_type for typ");
1433+
}
1434+
}
1435+
13441436
pub enum CTypeNameInfo<'a> {
13451437
Named { name: &'a str },
13461438
Anonymous { is_prim: bool },
@@ -1413,6 +1505,17 @@ impl InterfaceGenerator<'_> {
14131505
continue;
14141506
}
14151507

1508+
let kind = &self.resolve.types[ty].kind;
1509+
if let TypeDefKind::Handle(handle) = kind {
1510+
let resource = match handle {
1511+
Handle::Borrow(id) | Handle::Own(id) => id,
1512+
};
1513+
let origin = dealias(self.resolve, *resource);
1514+
if origin == *resource {
1515+
continue;
1516+
}
1517+
}
1518+
14161519
self.define_anonymous_type(ty)
14171520
}
14181521
}
@@ -1421,89 +1524,6 @@ impl InterfaceGenerator<'_> {
14211524
}
14221525
}
14231526

1424-
fn define_anonymous_type(&mut self, ty: TypeId) {
1425-
// skip `typedef handle_x handle_y` where `handle_x` is the same as `handle_y`
1426-
let kind = &self.resolve.types[ty].kind;
1427-
if let TypeDefKind::Handle(handle) = kind {
1428-
let resource = match handle {
1429-
Handle::Borrow(id) | Handle::Own(id) => id,
1430-
};
1431-
let origin = dealias(self.resolve, *resource);
1432-
if origin == *resource {
1433-
return;
1434-
}
1435-
}
1436-
1437-
self.src.h_defs("\ntypedef ");
1438-
let name = &self.gen.type_names[&ty];
1439-
match kind {
1440-
TypeDefKind::Type(_)
1441-
| TypeDefKind::Flags(_)
1442-
| TypeDefKind::Record(_)
1443-
| TypeDefKind::Resource
1444-
| TypeDefKind::Enum(_)
1445-
| TypeDefKind::Variant(_) => {
1446-
unreachable!()
1447-
}
1448-
TypeDefKind::Handle(handle) => {
1449-
let resource = match handle {
1450-
Handle::Borrow(id) | Handle::Own(id) => id,
1451-
};
1452-
let info = &self.gen.resources[&dealias(self.resolve, *resource)];
1453-
match handle {
1454-
Handle::Borrow(_) => self.src.h_defs(&info.borrow),
1455-
Handle::Own(_) => self.src.h_defs(&info.own),
1456-
}
1457-
}
1458-
TypeDefKind::Tuple(t) => {
1459-
self.src.h_defs(&format!("struct {name} {{\n"));
1460-
for (i, t) in t.types.iter().enumerate() {
1461-
let ty = self.gen.type_name(t);
1462-
uwriteln!(self.src.h_defs, "{ty} f{i};");
1463-
}
1464-
self.src.h_defs("}");
1465-
}
1466-
TypeDefKind::Option(t) => {
1467-
self.src.h_defs(&format!("struct {name} {{\n"));
1468-
self.src.h_defs("bool is_some;\n");
1469-
let ty = self.gen.type_name(t);
1470-
uwriteln!(self.src.h_defs, "{ty} val;");
1471-
self.src.h_defs("}");
1472-
}
1473-
TypeDefKind::Result(r) => {
1474-
self.src.h_defs(&format!("struct {name} {{\n"));
1475-
self.src.h_defs("bool is_err;\n");
1476-
let ok_ty = r.ok.as_ref();
1477-
let err_ty = r.err.as_ref();
1478-
if ok_ty.is_some() || err_ty.is_some() {
1479-
self.src.h_defs("union {\n");
1480-
if let Some(ok) = ok_ty {
1481-
let ty = self.gen.type_name(ok);
1482-
uwriteln!(self.src.h_defs, "{ty} ok;");
1483-
}
1484-
if let Some(err) = err_ty {
1485-
let ty = self.gen.type_name(err);
1486-
uwriteln!(self.src.h_defs, "{ty} err;");
1487-
}
1488-
self.src.h_defs("} val;\n");
1489-
}
1490-
self.src.h_defs("}");
1491-
}
1492-
TypeDefKind::List(t) => {
1493-
self.src.h_defs(&format!("struct {name} {{\n"));
1494-
let ty = self.gen.type_name(t);
1495-
uwriteln!(self.src.h_defs, "{ty} *ptr;");
1496-
self.src.h_defs("size_t len;\n");
1497-
self.src.h_defs("}");
1498-
}
1499-
TypeDefKind::Future(_) => todo!("print_anonymous_type for future"),
1500-
TypeDefKind::Stream(_) => todo!("print_anonymous_type for stream"),
1501-
TypeDefKind::Unknown => unreachable!(),
1502-
}
1503-
self.src.h_defs(" ");
1504-
self.print_typedef_target(ty);
1505-
}
1506-
15071527
fn define_dtor(&mut self, id: TypeId) {
15081528
let h_helpers_start = self.src.h_helpers.len();
15091529
let c_helpers_start = self.src.c_helpers.len();

crates/core/src/lib.rs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,6 @@ pub trait InterfaceGenerator<'a> {
152152
fn type_alias(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs);
153153
fn type_list(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs);
154154
fn type_builtin(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs);
155-
156155
fn types(&mut self, iface: InterfaceId) {
157156
let iface = &self.resolve().interfaces[iface];
158157
for (name, id) in iface.types.iter() {
@@ -181,6 +180,41 @@ pub trait InterfaceGenerator<'a> {
181180
}
182181
}
183182

183+
pub trait AnonymousTypeGenerator<'a> {
184+
fn resolve(&self) -> &'a Resolve;
185+
186+
fn anonymous_type_handle(&mut self, id: TypeId, handle: &Handle, docs: &Docs);
187+
fn anonymous_type_tuple(&mut self, id: TypeId, ty: &Tuple, docs: &Docs);
188+
fn anonymous_type_option(&mut self, id: TypeId, ty: &Type, docs: &Docs);
189+
fn anonymous_type_result(&mut self, id: TypeId, ty: &Result_, docs: &Docs);
190+
fn anonymous_type_list(&mut self, id: TypeId, ty: &Type, docs: &Docs);
191+
fn anonymous_type_future(&mut self, id: TypeId, ty: &Option<Type>, docs: &Docs);
192+
fn anonymous_type_stream(&mut self, id: TypeId, ty: &Stream, docs: &Docs);
193+
fn anonymous_typ_type(&mut self, id: TypeId, ty: &Type, docs: &Docs);
194+
195+
fn define_anonymous_type(&mut self, id: TypeId) {
196+
let ty = &self.resolve().types[id];
197+
match &ty.kind {
198+
TypeDefKind::Flags(_)
199+
| TypeDefKind::Record(_)
200+
| TypeDefKind::Resource
201+
| TypeDefKind::Enum(_)
202+
| TypeDefKind::Variant(_) => {
203+
unreachable!()
204+
}
205+
TypeDefKind::Type(t) => self.anonymous_typ_type(id, t, &ty.docs),
206+
TypeDefKind::Tuple(tuple) => self.anonymous_type_tuple(id, tuple, &ty.docs),
207+
TypeDefKind::Option(t) => self.anonymous_type_option(id, t, &ty.docs),
208+
TypeDefKind::Result(r) => self.anonymous_type_result(id, r, &ty.docs),
209+
TypeDefKind::List(t) => self.anonymous_type_list(id, t, &ty.docs),
210+
TypeDefKind::Future(f) => self.anonymous_type_future(id, f, &ty.docs),
211+
TypeDefKind::Stream(s) => self.anonymous_type_stream(id, s, &ty.docs),
212+
TypeDefKind::Handle(handle) => self.anonymous_type_handle(id, handle, &ty.docs),
213+
TypeDefKind::Unknown => unreachable!(),
214+
}
215+
}
216+
}
217+
184218
pub fn generated_preamble(src: &mut Source, version: &str) {
185219
uwriteln!(src, "// Generated by `wit-bindgen` {version}. DO NOT EDIT!")
186220
}

0 commit comments

Comments
 (0)