Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
388 changes: 359 additions & 29 deletions Cargo.lock

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions crates/c/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1822,6 +1822,16 @@ impl<'a> wit_bindgen_core::AnonymousTypeGenerator<'a> for InterfaceGenerator<'a>
fn anonymous_type_type(&mut self, _id: TypeId, _ty: &Type, _docs: &Docs) {
todo!("print_anonymous_type for type");
}

fn anonymous_type_fixed_size_list(
&mut self,
_id: TypeId,
_ty: &Type,
_size: u32,
_docs: &Docs,
) {
todo!("print_anonymous_type for fixed size list");
}
}

pub enum CTypeNameInfo<'a> {
Expand Down
102 changes: 96 additions & 6 deletions crates/core/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,39 @@ def_instruction! {
ty: TypeId,
} : [2] => [1],

/// Pops all fields for a fixed list off the stack and then composes them
/// into an array.
FixedSizeListLift {
element: &'a Type,
size: u32,
id: TypeId,
} : [*size as usize] => [1],

/// Pops an array off the stack, decomposes the elements and then pushes them onto the stack.
FixedSizeListLower {
element: &'a Type,
size: u32,
id: TypeId,
} : [1] => [*size as usize],

/// Pops an array and an address off the stack, passes each element to a block storing it
FixedSizeListLowerToMemory {
element: &'a Type,
size: u32,
id: TypeId,
} : [2] => [0],

/// Pops base address, pushes an array
///
/// This will also pop a block from the block stack which is how to
/// read each individual element from the list.
FixedSizeListLiftFromMemory {
element: &'a Type,
size: u32,
id: TypeId,
} : [1] => [1],


/// Pushes an operand onto the stack representing the list item from
/// each iteration of the list.
///
Expand Down Expand Up @@ -840,7 +873,7 @@ fn needs_deallocate(resolve: &Resolve, ty: &Type, what: Deallocate) -> bool {
TypeDefKind::Flags(_) | TypeDefKind::Enum(_) => false,
TypeDefKind::Future(_) | TypeDefKind::Stream(_) => what.handles(),
TypeDefKind::Unknown => unreachable!(),
TypeDefKind::FixedSizeList(..) => todo!(),
TypeDefKind::FixedSizeList(t, _) => needs_deallocate(resolve, t, what),
},

Type::Bool
Expand Down Expand Up @@ -1552,7 +1585,21 @@ impl<'a, B: Bindgen> Generator<'a, B> {
});
}
TypeDefKind::Unknown => unreachable!(),
TypeDefKind::FixedSizeList(..) => todo!(),
TypeDefKind::FixedSizeList(ty, size) => {
self.emit(&FixedSizeListLower {
element: ty,
size: *size,
id,
});
let mut values = self
.stack
.drain(self.stack.len() - (*size as usize)..)
.collect::<Vec<_>>();
for value in values.drain(..) {
self.stack.push(value);
self.lower(ty);
}
}
},
}
}
Expand Down Expand Up @@ -1735,7 +1782,24 @@ impl<'a, B: Bindgen> Generator<'a, B> {
});
}
TypeDefKind::Unknown => unreachable!(),
TypeDefKind::FixedSizeList(..) => todo!(),
TypeDefKind::FixedSizeList(ty, size) => {
let temp = flat_types(self.resolve, ty, None).unwrap();
let flat_per_elem = temp.to_vec().len();
let flatsize = flat_per_elem * (*size as usize);
let mut lowered_args = self
.stack
.drain(self.stack.len() - flatsize..)
.collect::<Vec<_>>();
for _ in 0..*size {
self.stack.extend(lowered_args.drain(..flat_per_elem));
self.lift(ty);
}
self.emit(&FixedSizeListLift {
element: ty,
size: *size,
id,
});
}
},
}
}
Expand Down Expand Up @@ -1917,7 +1981,21 @@ impl<'a, B: Bindgen> Generator<'a, B> {
}

TypeDefKind::Unknown => unreachable!(),
TypeDefKind::FixedSizeList(..) => todo!(),
TypeDefKind::FixedSizeList(element, size) => {
// resembles write_list_to_memory
self.push_block();
self.emit(&IterElem { element });
self.emit(&IterBasePointer);
let elem_addr = self.stack.pop().unwrap();
self.write_to_memory(element, elem_addr, offset);
self.finish_block(0);
self.stack.push(addr);
self.emit(&FixedSizeListLowerToMemory {
element,
size: *size,
id,
});
}
},
}
}
Expand Down Expand Up @@ -2104,7 +2182,19 @@ impl<'a, B: Bindgen> Generator<'a, B> {
}

TypeDefKind::Unknown => unreachable!(),
TypeDefKind::FixedSizeList(..) => todo!(),
TypeDefKind::FixedSizeList(ty, size) => {
self.push_block();
self.emit(&IterBasePointer);
let elemaddr = self.stack.pop().unwrap();
self.read_from_memory(ty, elemaddr, offset);
self.finish_block(1);
self.stack.push(addr.clone());
self.emit(&FixedSizeListLiftFromMemory {
element: ty,
size: *size,
id,
});
}
},
}
}
Expand Down Expand Up @@ -2413,7 +2503,7 @@ impl<'a, B: Bindgen> Generator<'a, B> {
TypeDefKind::Future(_) => unreachable!(),
TypeDefKind::Stream(_) => unreachable!(),
TypeDefKind::Unknown => unreachable!(),
TypeDefKind::FixedSizeList(..) => todo!(),
TypeDefKind::FixedSizeList(_, _) => {}
},
}
}
Expand Down
5 changes: 4 additions & 1 deletion crates/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ pub trait AnonymousTypeGenerator<'a> {
fn anonymous_type_option(&mut self, id: TypeId, ty: &Type, docs: &Docs);
fn anonymous_type_result(&mut self, id: TypeId, ty: &Result_, docs: &Docs);
fn anonymous_type_list(&mut self, id: TypeId, ty: &Type, docs: &Docs);
fn anonymous_type_fixed_size_list(&mut self, id: TypeId, ty: &Type, size: u32, docs: &Docs);
fn anonymous_type_future(&mut self, id: TypeId, ty: &Option<Type>, docs: &Docs);
fn anonymous_type_stream(&mut self, id: TypeId, ty: &Option<Type>, docs: &Docs);
fn anonymous_type_type(&mut self, id: TypeId, ty: &Type, docs: &Docs);
Expand All @@ -217,7 +218,9 @@ pub trait AnonymousTypeGenerator<'a> {
TypeDefKind::Future(f) => self.anonymous_type_future(id, f, &ty.docs),
TypeDefKind::Stream(s) => self.anonymous_type_stream(id, s, &ty.docs),
TypeDefKind::Handle(handle) => self.anonymous_type_handle(id, handle, &ty.docs),
TypeDefKind::FixedSizeList(..) => todo!(),
TypeDefKind::FixedSizeList(t, size) => {
self.anonymous_type_fixed_size_list(id, t, *size, &ty.docs)
}
TypeDefKind::Unknown => unreachable!(),
}
}
Expand Down
4 changes: 3 additions & 1 deletion crates/core/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,9 @@ impl Types {
// should use the same ownership semantics as `own<T>`
info.has_own_handle = true;
}
TypeDefKind::FixedSizeList(..) => todo!(),
TypeDefKind::FixedSizeList(ty, _) => {
info = self.type_info(resolve, ty);
}
TypeDefKind::Unknown => unreachable!(),
}
let prev = self.type_info.insert(ty, info);
Expand Down
103 changes: 100 additions & 3 deletions crates/cpp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ struct Includes {
// needs wit types
needs_wit: bool,
needs_memory: bool,
needs_array: bool,
}

#[derive(Default)]
Expand Down Expand Up @@ -428,6 +429,9 @@ impl Cpp {
if self.dependencies.needs_memory {
self.include("<memory>");
}
if self.dependencies.needs_array {
self.include("<array>");
}
if self.dependencies.needs_bit {
self.include("<bit>");
}
Expand Down Expand Up @@ -1697,7 +1701,13 @@ impl CppInterfaceGenerator<'_> {
TypeDefKind::Future(_) => todo!(),
TypeDefKind::Stream(_) => todo!(),
TypeDefKind::Type(ty) => self.type_name(ty, from_namespace, flavor),
TypeDefKind::FixedSizeList(_, _) => todo!(),
TypeDefKind::FixedSizeList(ty, size) => {
self.r#gen.dependencies.needs_array = true;
format!(
"std::array<{}, {size}>",
self.type_name(ty, from_namespace, flavor)
)
}
TypeDefKind::Unknown => todo!(),
},
Type::ErrorContext => todo!(),
Expand Down Expand Up @@ -2646,7 +2656,94 @@ impl<'a, 'b> Bindgen for FunctionBindgen<'a, 'b> {
results.push(move_if_necessary(&result));
}
}
abi::Instruction::IterElem { .. } => results.push("IterElem".to_string()),
abi::Instruction::FixedSizeListLift {
element,
size,
id: _,
} => {
let tmp = self.tmp();
let result = format!("result{tmp}");
let typename = self
.r#gen
.type_name(element, &self.namespace, Flavor::InStruct);
self.push_str(&format!("std::array<{typename}, {size}> {result} = {{",));
for a in operands.drain(0..(*size as usize)) {
self.push_str(&a);
self.push_str(", ");
}
self.push_str("};\n");
results.push(result);
}
abi::Instruction::FixedSizeListLiftFromMemory {
element,
size: elemsize,
id: _,
} => {
let body = self.blocks.pop().unwrap();
let tmp = self.tmp();
let vec = format!("array{tmp}");
let source = operands[0].clone();
let size = self.r#gen.sizes.size(element);
let size_str = size.format(POINTER_SIZE_EXPRESSION);
let typename = self
.r#gen
.type_name(element, &self.namespace, Flavor::InStruct);
let ptr_type = self.r#gen.r#gen.opts.ptr_type();
self.push_str(&format!("std::array<{typename}, {elemsize}> {vec};\n"));
self.push_str(&format!(
"{{
{ptr_type} outer_base = {source};\n"
));
let source: String = "outer_base".into();
// let vec: String = "outer_vec".into();
self.push_str(&format!("for (unsigned i = 0; i<{elemsize}; ++i) {{\n",));
self.push_str(&format!("{ptr_type} base = {source} + i * {size_str};\n"));
self.push_str(&body.0);
self.push_str(&format!("{vec}[i] = {};", body.1[0]));
self.push_str("\n}\n}\n");
results.push(vec);
}
abi::Instruction::FixedSizeListLower {
element: _,
size,
id: _,
} => {
for i in 0..(*size as usize) {
results.push(format!("{}[{i}]", operands[0]));
}
}
abi::Instruction::FixedSizeListLowerToMemory {
element,
size: elemsize,
id: _,
} => {
let body = self.blocks.pop().unwrap();
let vec = operands[0].clone();
let target = operands[1].clone();
let size = self.r#gen.sizes.size(element);
let size_str = size.format(POINTER_SIZE_EXPRESSION);
let typename = self
.r#gen
.type_name(element, &self.namespace, Flavor::InStruct);
let ptr_type = self.r#gen.r#gen.opts.ptr_type();
self.push_str(&format!(
"{{
{ptr_type} outer_base = {target};\n"
));
let target: String = "outer_base".into();
self.push_str(&format!(
"std::array<{typename}, {elemsize}>& outer_vec = {vec};\n"
));
let vec: String = "outer_vec".into();
self.push_str(&format!("for (unsigned i = 0; i<{vec}.size(); ++i) {{\n",));
self.push_str(&format!(
"{ptr_type} base = {target} + i * {size_str};
{typename}& iter_elem = {vec}[i];\n"
));
self.push_str(&body.0);
self.push_str("\n}\n}\n");
}
abi::Instruction::IterElem { .. } => results.push("iter_elem".to_string()),
abi::Instruction::IterBasePointer => results.push("base".to_string()),
abi::Instruction::RecordLower { record, .. } => {
let op = &operands[0];
Expand Down Expand Up @@ -3252,7 +3349,7 @@ impl<'a, 'b> Bindgen for FunctionBindgen<'a, 'b> {
self.src.push_str(">(");
}
if *amt == 1 {
if operands[0].starts_with("std::move(") {
if operands[0].starts_with("std::move(") && !operands[0].contains('.') {
// remove the std::move due to return value optimization (and complex rules about when std::move harms)
self.src.push_str(&operands[0][9..]);
} else {
Expand Down
4 changes: 4 additions & 0 deletions crates/csharp/src/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1445,6 +1445,10 @@ impl Bindgen for FunctionBindgen<'_, '_> {
| Instruction::ErrorContextLower { .. }
| Instruction::ErrorContextLift { .. }
| Instruction::DropHandle { .. }
| Instruction::FixedSizeListLift { .. }
| Instruction::FixedSizeListLower { .. }
| Instruction::FixedSizeListLowerToMemory { .. }
| Instruction::FixedSizeListLiftFromMemory { .. }
=> {
dbg!(inst);
todo!()
Expand Down
4 changes: 4 additions & 0 deletions crates/moonbit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2696,6 +2696,10 @@ impl Bindgen for FunctionBindgen<'_, '_> {
Instruction::ErrorContextLower { .. }
| Instruction::ErrorContextLift { .. }
| Instruction::DropHandle { .. } => todo!(),
Instruction::FixedSizeListLift { .. } => todo!(),
Instruction::FixedSizeListLower { .. } => todo!(),
Instruction::FixedSizeListLowerToMemory { .. } => todo!(),
Instruction::FixedSizeListLiftFromMemory { .. } => todo!(),
}
}

Expand Down
Loading
Loading