Skip to content

Commit

Permalink
Make tuples constructible
Browse files Browse the repository at this point in the history
  • Loading branch information
HKalbasi committed Oct 18, 2023
1 parent abb8b8f commit 7ece942
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 22 deletions.
24 changes: 12 additions & 12 deletions examples/memory_management/main.cpp
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
#include <cstdint>
#include <iostream>
#include <vector>

#include "./generated.h"

// Rust values are available in the `::rust` namespace from their absolute path
// in Rust
template <typename T> using Vec = rust::std::vec::Vec<T>;
template <typename T> using Option = rust::std::option::Option<T>;
template <typename T> using BoxDyn = rust::Box<rust::Dyn<T>>;
template <typename T> using RmDyn = rust::RefMut<rust::Dyn<T>>;
using rust::crate::consume_and_panic;
using rust::crate::consume_n_times;
using rust::crate::PrintOnDrop;
using rust::crate::PrintOnDropConsumer;
using rust::crate::PrintOnDropPair;
using namespace rust::crate;

class CppPrintOnDropHolder : public PrintOnDropConsumer {
rust::Unit consume(PrintOnDrop p) override {
Expand Down Expand Up @@ -139,8 +134,7 @@ int main() {
const char *elems[3] = {"elem1", "elem2", "elem3"};
int i = 0;
auto iter = rust::std::iter::from_fn(
::rust::Box<::rust::Dyn<::rust::Fn<::rust::std::option::Option<
::rust::crate::PrintOnDrop>>>>::make_box([&] {
rust::Box<rust::Dyn<rust::Fn<Option<PrintOnDrop>>>>::make_box([&] {
if (i == 3) {
return Option<PrintOnDrop>::None();
}
Expand All @@ -149,12 +143,18 @@ int main() {
}));
std::cout << "Checkpoint 41" << std::endl;
iter.for_each(
::rust::Box<
::rust::Dyn<::rust::Fn<::rust::crate::PrintOnDrop, rust::Unit>>>::
make_box([](PrintOnDrop p) -> rust::Unit {
rust::Box<rust::Dyn<rust::Fn<PrintOnDrop, rust::Unit>>>::make_box(
[](PrintOnDrop p) -> rust::Unit {
std::cout << "Checkpoint 42" << std::endl;
return {};
}));
}
std::cout << "Checkpoint 43" << std::endl;
{
auto tuple = rust::Tuple<PrintOnDrop, int32_t, PrintOnDrop>(
PrintOnDrop(rust::Str::from_char_star("field_0")), 5,
PrintOnDrop(rust::Str::from_char_star("field_2")));
std::cout << "Checkpoint 44" << std::endl;
}
std::cout << "Checkpoint 45" << std::endl;
}
5 changes: 2 additions & 3 deletions examples/memory_management/main.zng
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ type () {
wellknown_traits(Copy);
}

type (i32, u32) {
#layout(size = 8, align = 4);
wellknown_traits(Copy);
type (crate::PrintOnDrop, i32, crate::PrintOnDrop) {
#layout(size = 40, align = 8);
}

type bool {
Expand Down
21 changes: 14 additions & 7 deletions examples/memory_management/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ Checkpoint 20
Checkpoint 21
PrintOnDrop(A) has been dropped
Checkpoint 22
thread '<unnamed>' panicked at 'consume_and_panic executed with value B', examples/memory_management/src/lib.rs:29:9
thread '<unnamed>' panicked at examples/memory_management/src/lib.rs:29:9:
consume_and_panic executed with value B
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
PrintOnDrop(B) has been dropped
PrintOnDrop(A) has been dropped
Expand All @@ -58,15 +59,15 @@ Checkpoint 30
PrintOnDrop(elem1) has been dropped
PrintOnDrop(elem2) has been dropped
Checkpoint 31
[main.cpp:117] PrintOnDrop(rust::Str::from_char_star("dbg_A")) = PrintOnDrop(
[main.cpp:112] PrintOnDrop(rust::Str::from_char_star("dbg_A")) = PrintOnDrop(
"dbg_A",
)
Checkpoint 32
[main.cpp:119] std::move(p1) = PrintOnDrop(
[main.cpp:114] std::move(p1) = PrintOnDrop(
"dbg_A",
)
Checkpoint 33
[main.cpp:121] p2 = PrintOnDrop(
[main.cpp:116] p2 = PrintOnDrop(
"dbg_A",
)
Checkpoint 34
Expand All @@ -80,9 +81,15 @@ Checkpoint 39
PrintOnDrop(option_A) has been dropped
Checkpoint 40
Checkpoint 41
PrintOnDrop(iter_elem) has been dropped
PrintOnDrop(iter_elem) has been dropped
PrintOnDrop(iter_elem) has been dropped
Checkpoint 42
PrintOnDrop(elem1) has been dropped
Checkpoint 42
PrintOnDrop(elem2) has been dropped
Checkpoint 42
PrintOnDrop(elem3) has been dropped
Checkpoint 43
Checkpoint 44
PrintOnDrop(field_0) has been dropped
PrintOnDrop(field_2) has been dropped
Checkpoint 45
PrintOnDrop(C) has been dropped
10 changes: 10 additions & 0 deletions zngur-generator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,16 @@ impl ZngurGenerator {
}
}
}
if let RustType::Tuple(fields) = &ty_def.ty {
if !fields.is_empty() {
let rust_link_name = rust_file.add_tuple_constructor(&fields);
constructors.push(CppFnSig {
rust_link_name,
inputs: fields.iter().map(|x| x.into_cpp()).collect(),
output: ty_def.ty.into_cpp(),
});
}
}
for wellknown_trait in ty_def.wellknown_traits {
let data = rust_file.add_wellknown_trait(&ty_def.ty, wellknown_trait);
wellknown_traits.push(data);
Expand Down
24 changes: 24 additions & 0 deletions zngur-generator/src/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,30 @@ pub extern "C" fn {mangled_name}(
mangled_name
}

pub fn add_tuple_constructor(&mut self, fields: &[RustType]) -> String {
let constructor = mangle_name(&fields.iter().join("&"));
w!(
self,
r#"
#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn {constructor}("#
);
for name in 0..fields.len() {
w!(self, "f_{name}: *mut u8, ");
}
w!(
self,
r#"o: *mut u8) {{ unsafe {{
::std::ptr::write(o as *mut _, ("#
);
for (name, ty) in fields.iter().enumerate() {
w!(self, "::std::ptr::read(f_{name} as *mut {ty}), ");
}
wln!(self, ")) }} }}");
constructor
}

pub fn add_constructor(
&mut self,
rust_name: &str,
Expand Down

0 comments on commit 7ece942

Please sign in to comment.