Skip to content

Commit 84f362d

Browse files
committed
Support for CxxVector<*mut T> and CxxVector<*const T>
1 parent a7898a2 commit 84f362d

File tree

14 files changed

+680
-101
lines changed

14 files changed

+680
-101
lines changed

gen/src/write.rs

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::gen::nested::NamespaceEntries;
33
use crate::gen::out::OutFile;
44
use crate::gen::{builtin, include, Opt};
55
use crate::syntax::atom::Atom::{self, *};
6-
use crate::syntax::instantiate::{ImplKey, NamedImplKey};
6+
use crate::syntax::instantiate::{CxxVectorPayloadImplKey, ImplKey, NamedImplKey, PtrMutability};
77
use crate::syntax::map::UnorderedMap as Map;
88
use crate::syntax::set::UnorderedSet;
99
use crate::syntax::symbol::{self, Symbol};
@@ -1352,6 +1352,7 @@ fn write_space_after_type(out: &mut OutFile, ty: &Type) {
13521352
enum UniquePtr<'a> {
13531353
Ident(&'a Ident),
13541354
CxxVector(&'a Ident),
1355+
CxxVectorPtr(PtrMutability, &'a Ident),
13551356
}
13561357

13571358
trait ToTypename {
@@ -1371,6 +1372,17 @@ impl<'a> ToTypename for UniquePtr<'a> {
13711372
UniquePtr::CxxVector(element) => {
13721373
format!("::std::vector<{}>", element.to_typename(types))
13731374
}
1375+
UniquePtr::CxxVectorPtr(mutability, element) => {
1376+
let const_prefix = match mutability {
1377+
PtrMutability::Const => "const ",
1378+
PtrMutability::Mut => "",
1379+
};
1380+
format!(
1381+
"::std::vector<{}{}*>",
1382+
const_prefix,
1383+
element.to_typename(types)
1384+
)
1385+
}
13741386
}
13751387
}
13761388
}
@@ -1392,6 +1404,13 @@ impl<'a> ToMangled for UniquePtr<'a> {
13921404
UniquePtr::CxxVector(element) => {
13931405
symbol::join(&[&"std", &"vector", &element.to_mangled(types)])
13941406
}
1407+
UniquePtr::CxxVectorPtr(mutability, element) => {
1408+
let prefix = match mutability {
1409+
PtrMutability::Const => "ptrc",
1410+
PtrMutability::Mut => "ptrm",
1411+
};
1412+
symbol::join(&[&"std", &"vector", &prefix, &element.to_mangled(types)])
1413+
}
13951414
}
13961415
}
13971416
}
@@ -1412,7 +1431,7 @@ fn write_generic_instantiations(out: &mut OutFile) {
14121431
ImplKey::UniquePtr(ident) => write_unique_ptr(out, ident),
14131432
ImplKey::SharedPtr(ident) => write_shared_ptr(out, ident),
14141433
ImplKey::WeakPtr(ident) => write_weak_ptr(out, ident),
1415-
ImplKey::CxxVector(ident) => write_cxx_vector(out, ident),
1434+
ImplKey::CxxVector(payload) => write_cxx_vector(out, payload),
14161435
}
14171436
}
14181437
out.end_block(Block::ExternC);
@@ -1639,21 +1658,21 @@ fn write_unique_ptr_common(out: &mut OutFile, ty: UniquePtr) {
16391658
// bindings for a "new" method anyway. But the Rust code can't be called
16401659
// for Opaque types because the 'new' method is not implemented.
16411660
UniquePtr::Ident(ident) => out.types.is_maybe_trivial(ident),
1642-
UniquePtr::CxxVector(_) => false,
1661+
UniquePtr::CxxVector(_) | UniquePtr::CxxVectorPtr(..) => false,
16431662
};
16441663

16451664
let conditional_delete = match ty {
16461665
UniquePtr::Ident(ident) => {
16471666
!out.types.structs.contains_key(ident) && !out.types.enums.contains_key(ident)
16481667
}
1649-
UniquePtr::CxxVector(_) => false,
1668+
UniquePtr::CxxVector(_) | UniquePtr::CxxVectorPtr(..) => false,
16501669
};
16511670

16521671
if conditional_delete {
16531672
out.builtin.is_complete = true;
16541673
let definition = match ty {
16551674
UniquePtr::Ident(ty) => &out.types.resolve(ty).name.cxx,
1656-
UniquePtr::CxxVector(_) => unreachable!(),
1675+
UniquePtr::CxxVector(_) | UniquePtr::CxxVectorPtr(..) => unreachable!(),
16571676
};
16581677
writeln!(
16591678
out,
@@ -1895,7 +1914,17 @@ fn write_weak_ptr(out: &mut OutFile, key: NamedImplKey) {
18951914
writeln!(out, "}}");
18961915
}
18971916

1898-
fn write_cxx_vector(out: &mut OutFile, key: NamedImplKey) {
1917+
fn write_cxx_vector(out: &mut OutFile, payload: CxxVectorPayloadImplKey) {
1918+
let (key, ptr_prefix, unique_ptr_payload) = match payload {
1919+
CxxVectorPayloadImplKey::Named(id) => (id, "", UniquePtr::CxxVector(id.rust)),
1920+
CxxVectorPayloadImplKey::Ptr(id, mutability) => {
1921+
let prefix = match mutability {
1922+
PtrMutability::Const => "ptrc$",
1923+
PtrMutability::Mut => "ptrm$",
1924+
};
1925+
(id, prefix, UniquePtr::CxxVectorPtr(mutability, id.rust))
1926+
}
1927+
};
18991928
let element = key.rust;
19001929
let inner = element.to_typename(out.types);
19011930
let instance = element.to_mangled(out.types);
@@ -1907,26 +1936,26 @@ fn write_cxx_vector(out: &mut OutFile, key: NamedImplKey) {
19071936
begin_function_definition(out);
19081937
writeln!(
19091938
out,
1910-
"::std::vector<{}> *cxxbridge1$std$vector${}$new() noexcept {{",
1911-
inner, instance,
1939+
"::std::vector<{}> *cxxbridge1$std$vector${}{}$new() noexcept {{",
1940+
inner, ptr_prefix, instance,
19121941
);
19131942
writeln!(out, " return new ::std::vector<{}>();", inner);
19141943
writeln!(out, "}}");
19151944

19161945
begin_function_definition(out);
19171946
writeln!(
19181947
out,
1919-
"::std::size_t cxxbridge1$std$vector${}$size(::std::vector<{}> const &s) noexcept {{",
1920-
instance, inner,
1948+
"::std::size_t cxxbridge1$std$vector${}{}$size(const ::std::vector<{}> &s) noexcept {{",
1949+
ptr_prefix, instance, inner,
19211950
);
19221951
writeln!(out, " return s.size();");
19231952
writeln!(out, "}}");
19241953

19251954
begin_function_definition(out);
19261955
writeln!(
19271956
out,
1928-
"{} *cxxbridge1$std$vector${}$get_unchecked(::std::vector<{}> *s, ::std::size_t pos) noexcept {{",
1929-
inner, instance, inner,
1957+
"{} *cxxbridge1$std$vector${}{}$get_unchecked(::std::vector<{}> *s, ::std::size_t pos) noexcept {{",
1958+
inner, ptr_prefix, instance, inner,
19301959
);
19311960
writeln!(out, " return &(*s)[pos];");
19321961
writeln!(out, "}}");
@@ -1935,8 +1964,8 @@ fn write_cxx_vector(out: &mut OutFile, key: NamedImplKey) {
19351964
begin_function_definition(out);
19361965
writeln!(
19371966
out,
1938-
"void cxxbridge1$std$vector${}$push_back(::std::vector<{}> *v, {} *value) noexcept {{",
1939-
instance, inner, inner,
1967+
"void cxxbridge1$std$vector${}{}$push_back(::std::vector<{}> *v, {} *value) noexcept {{",
1968+
ptr_prefix, instance, inner, inner,
19401969
);
19411970
writeln!(out, " v->push_back(::std::move(*value));");
19421971
writeln!(out, " ::rust::destroy(value);");
@@ -1945,14 +1974,14 @@ fn write_cxx_vector(out: &mut OutFile, key: NamedImplKey) {
19451974
begin_function_definition(out);
19461975
writeln!(
19471976
out,
1948-
"void cxxbridge1$std$vector${}$pop_back(::std::vector<{}> *v, {} *out) noexcept {{",
1949-
instance, inner, inner,
1977+
"void cxxbridge1$std$vector${}{}$pop_back(::std::vector<{}> *v, {} *out) noexcept {{",
1978+
ptr_prefix, instance, inner, inner,
19501979
);
19511980
writeln!(out, " ::new (out) {}(::std::move(v->back()));", inner);
19521981
writeln!(out, " v->pop_back();");
19531982
writeln!(out, "}}");
19541983
}
19551984

19561985
out.include.memory = true;
1957-
write_unique_ptr_common(out, UniquePtr::CxxVector(element));
1986+
write_unique_ptr_common(out, unique_ptr_payload);
19581987
}

macro/src/expand.rs

Lines changed: 67 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::syntax::atom::Atom::*;
22
use crate::syntax::attrs::{self, OtherAttrs};
33
use crate::syntax::cfg::CfgExpr;
44
use crate::syntax::file::Module;
5-
use crate::syntax::instantiate::{ImplKey, NamedImplKey};
5+
use crate::syntax::instantiate::{CxxVectorPayloadImplKey, ImplKey, NamedImplKey, PtrMutability};
66
use crate::syntax::qualified::QualifiedName;
77
use crate::syntax::report::Errors;
88
use crate::syntax::symbol::Symbol;
@@ -108,8 +108,8 @@ fn expand(ffi: Module, doc: Doc, attrs: OtherAttrs, apis: &[Api], types: &Types)
108108
ImplKey::WeakPtr(ident) => {
109109
expanded.extend(expand_weak_ptr(ident, types, explicit_impl));
110110
}
111-
ImplKey::CxxVector(ident) => {
112-
expanded.extend(expand_cxx_vector(ident, explicit_impl, types));
111+
ImplKey::CxxVector(payload) => {
112+
expanded.extend(expand_cxx_vector(payload, explicit_impl, types));
113113
}
114114
}
115115
}
@@ -1670,21 +1670,31 @@ fn expand_weak_ptr(key: NamedImplKey, types: &Types, explicit_impl: Option<&Impl
16701670
}
16711671

16721672
fn expand_cxx_vector(
1673-
key: NamedImplKey,
1673+
payload: CxxVectorPayloadImplKey,
16741674
explicit_impl: Option<&Impl>,
16751675
types: &Types,
16761676
) -> TokenStream {
1677+
let (ptr_prefix, key, ty_prefix, elem_trait) = match payload {
1678+
CxxVectorPayloadImplKey::Named(id) => ("", id, quote! {}, quote!{ ::cxx::private::VectorElement }),
1679+
CxxVectorPayloadImplKey::Ptr(id, PtrMutability::Const) => ("ptrc$", id, quote! { *const }, quote!{ ::cxx::private::ConstPtrVectorElement }),
1680+
CxxVectorPayloadImplKey::Ptr(id, PtrMutability::Mut) => ("ptrm$", id, quote! { *mut }, quote!{ ::cxx::private::MutPtrVectorElement }),
1681+
};
16771682
let elem = key.rust;
16781683
let name = elem.to_string();
16791684
let resolve = types.resolve(elem);
1680-
let prefix = format!("cxxbridge1$std$vector${}$", resolve.name.to_symbol());
1685+
let prefix = format!(
1686+
"cxxbridge1$std$vector${}{}$",
1687+
ptr_prefix,
1688+
resolve.name.to_symbol()
1689+
);
16811690
let link_new = format!("{}new", prefix);
16821691
let link_size = format!("{}size", prefix);
16831692
let link_get_unchecked = format!("{}get_unchecked", prefix);
16841693
let link_push_back = format!("{}push_back", prefix);
16851694
let link_pop_back = format!("{}pop_back", prefix);
16861695
let unique_ptr_prefix = format!(
1687-
"cxxbridge1$unique_ptr$std$vector${}$",
1696+
"cxxbridge1$unique_ptr$std$vector${}{}$",
1697+
ptr_prefix,
16881698
resolve.name.to_symbol(),
16891699
);
16901700
let link_unique_ptr_null = format!("{}null", unique_ptr_prefix);
@@ -1694,6 +1704,7 @@ fn expand_cxx_vector(
16941704
let link_unique_ptr_drop = format!("{}drop", unique_ptr_prefix);
16951705

16961706
let (impl_generics, ty_generics) = generics::split_for_impl(key, explicit_impl, resolve);
1707+
let impl_target = quote! { #ty_prefix #elem #ty_generics };
16971708

16981709
let begin_span = explicit_impl.map_or(key.begin_span, |explicit| explicit.impl_token.span);
16991710
let end_span = explicit_impl.map_or(key.end_span, |explicit| explicit.brace_token.span.join());
@@ -1702,75 +1713,76 @@ fn expand_cxx_vector(
17021713
let can_pass_element_by_value = types.is_maybe_trivial(elem);
17031714
let by_value_methods = if can_pass_element_by_value {
17041715
Some(quote_spanned! {end_span=>
1705-
unsafe fn __push_back(
1706-
this: ::cxx::core::pin::Pin<&mut ::cxx::CxxVector<Self>>,
1707-
value: &mut ::cxx::core::mem::ManuallyDrop<Self>,
1708-
) {
1709-
extern "C" {
1710-
#[link_name = #link_push_back]
1711-
fn __push_back #impl_generics(
1712-
this: ::cxx::core::pin::Pin<&mut ::cxx::CxxVector<#elem #ty_generics>>,
1713-
value: *mut ::cxx::core::ffi::c_void,
1714-
);
1715-
}
1716-
unsafe {
1717-
__push_back(
1718-
this,
1719-
value as *mut ::cxx::core::mem::ManuallyDrop<Self> as *mut ::cxx::core::ffi::c_void,
1720-
);
1721-
}
1722-
}
1723-
unsafe fn __pop_back(
1724-
this: ::cxx::core::pin::Pin<&mut ::cxx::CxxVector<Self>>,
1725-
out: &mut ::cxx::core::mem::MaybeUninit<Self>,
1726-
) {
1727-
extern "C" {
1728-
#[link_name = #link_pop_back]
1729-
fn __pop_back #impl_generics(
1730-
this: ::cxx::core::pin::Pin<&mut ::cxx::CxxVector<#elem #ty_generics>>,
1731-
out: *mut ::cxx::core::ffi::c_void,
1732-
);
1716+
unsafe fn __push_back(
1717+
this: ::cxx::core::pin::Pin<&mut ::cxx::CxxVector<#ty_prefix Self>>,
1718+
value: &mut ::cxx::core::mem::ManuallyDrop<#ty_prefix Self>,
1719+
) {
1720+
extern "C" {
1721+
#[link_name = #link_push_back]
1722+
fn __push_back #impl_generics(
1723+
this: ::cxx::core::pin::Pin<&mut ::cxx::CxxVector<#impl_target>>,
1724+
value: *mut ::cxx::core::ffi::c_void,
1725+
);
1726+
}
1727+
unsafe {
1728+
__push_back(
1729+
this,
1730+
value as *mut ::cxx::core::mem::ManuallyDrop<#ty_prefix Self> as *mut ::cxx::core::ffi::c_void,
1731+
);
1732+
}
17331733
}
1734-
unsafe {
1735-
__pop_back(
1736-
this,
1737-
out as *mut ::cxx::core::mem::MaybeUninit<Self> as *mut ::cxx::core::ffi::c_void,
1738-
);
1734+
unsafe fn __pop_back(
1735+
this: ::cxx::core::pin::Pin<&mut ::cxx::CxxVector<#ty_prefix Self>>,
1736+
out: &mut ::cxx::core::mem::MaybeUninit<#ty_prefix Self>,
1737+
) {
1738+
extern "C" {
1739+
#[link_name = #link_pop_back]
1740+
fn __pop_back #impl_generics(
1741+
this: ::cxx::core::pin::Pin<&mut ::cxx::CxxVector<#impl_target>>,
1742+
out: *mut ::cxx::core::ffi::c_void,
1743+
);
1744+
}
1745+
unsafe {
1746+
__pop_back(
1747+
this,
1748+
out as *mut ::cxx::core::mem::MaybeUninit<#ty_prefix Self> as *mut ::cxx::core::ffi::c_void,
1749+
);
1750+
}
17391751
}
1740-
}
1741-
})
1752+
})
17421753
} else {
17431754
None
17441755
};
17451756

17461757
quote_spanned! {end_span=>
1747-
#unsafe_token impl #impl_generics ::cxx::private::VectorElement for #elem #ty_generics {
1758+
#unsafe_token impl #impl_generics #elem_trait for #elem #ty_generics {
1759+
#[doc(hidden)]
17481760
fn __typename(f: &mut ::cxx::core::fmt::Formatter<'_>) -> ::cxx::core::fmt::Result {
17491761
f.write_str(#name)
17501762
}
1751-
fn __vector_new() -> *mut ::cxx::CxxVector<Self> {
1763+
fn __vector_new() -> *mut ::cxx::CxxVector<#ty_prefix Self> {
17521764
extern "C" {
17531765
#[link_name = #link_new]
1754-
fn __vector_new #impl_generics() -> *mut ::cxx::CxxVector<#elem #ty_generics>;
1766+
fn __vector_new #impl_generics() -> *mut ::cxx::CxxVector<#impl_target>;
17551767
}
17561768
unsafe { __vector_new() }
17571769
}
1758-
fn __vector_size(v: &::cxx::CxxVector<Self>) -> usize {
1770+
fn __vector_size(v: &::cxx::CxxVector<#ty_prefix Self>) -> usize {
17591771
extern "C" {
17601772
#[link_name = #link_size]
1761-
fn __vector_size #impl_generics(_: &::cxx::CxxVector<#elem #ty_generics>) -> usize;
1773+
fn __vector_size #impl_generics(_: &::cxx::CxxVector<#impl_target>) -> usize;
17621774
}
17631775
unsafe { __vector_size(v) }
17641776
}
1765-
unsafe fn __get_unchecked(v: *mut ::cxx::CxxVector<Self>, pos: usize) -> *mut Self {
1777+
unsafe fn __get_unchecked(v: *mut ::cxx::CxxVector<#ty_prefix Self>, pos: usize) -> *mut #ty_prefix Self {
17661778
extern "C" {
17671779
#[link_name = #link_get_unchecked]
17681780
fn __get_unchecked #impl_generics(
1769-
v: *mut ::cxx::CxxVector<#elem #ty_generics>,
1781+
v: *mut ::cxx::CxxVector<#impl_target>,
17701782
pos: usize,
17711783
) -> *mut ::cxx::core::ffi::c_void;
17721784
}
1773-
unsafe { __get_unchecked(v, pos) as *mut Self }
1785+
unsafe { __get_unchecked(v, pos) as *mut #ty_prefix Self }
17741786
}
17751787
#by_value_methods
17761788
fn __unique_ptr_null() -> ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void> {
@@ -1784,28 +1796,28 @@ fn expand_cxx_vector(
17841796
}
17851797
repr
17861798
}
1787-
unsafe fn __unique_ptr_raw(raw: *mut ::cxx::CxxVector<Self>) -> ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void> {
1799+
unsafe fn __unique_ptr_raw(raw: *mut ::cxx::CxxVector<#ty_prefix Self>) -> ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void> {
17881800
extern "C" {
17891801
#[link_name = #link_unique_ptr_raw]
1790-
fn __unique_ptr_raw #impl_generics(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>, raw: *mut ::cxx::CxxVector<#elem #ty_generics>);
1802+
fn __unique_ptr_raw #impl_generics(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>, raw: *mut ::cxx::CxxVector<#impl_target>);
17911803
}
17921804
let mut repr = ::cxx::core::mem::MaybeUninit::uninit();
17931805
unsafe {
17941806
__unique_ptr_raw(&mut repr, raw);
17951807
}
17961808
repr
17971809
}
1798-
unsafe fn __unique_ptr_get(repr: ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *const ::cxx::CxxVector<Self> {
1810+
unsafe fn __unique_ptr_get(repr: ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *const ::cxx::CxxVector<#ty_prefix Self> {
17991811
extern "C" {
18001812
#[link_name = #link_unique_ptr_get]
1801-
fn __unique_ptr_get #impl_generics(this: *const ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *const ::cxx::CxxVector<#elem #ty_generics>;
1813+
fn __unique_ptr_get #impl_generics(this: *const ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *const ::cxx::CxxVector<#impl_target>;
18021814
}
18031815
unsafe { __unique_ptr_get(&repr) }
18041816
}
1805-
unsafe fn __unique_ptr_release(mut repr: ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *mut ::cxx::CxxVector<Self> {
1817+
unsafe fn __unique_ptr_release(mut repr: ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *mut ::cxx::CxxVector<#ty_prefix Self> {
18061818
extern "C" {
18071819
#[link_name = #link_unique_ptr_release]
1808-
fn __unique_ptr_release #impl_generics(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *mut ::cxx::CxxVector<#elem #ty_generics>;
1820+
fn __unique_ptr_release #impl_generics(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *mut ::cxx::CxxVector<#impl_target>;
18091821
}
18101822
unsafe { __unique_ptr_release(&mut repr) }
18111823
}

0 commit comments

Comments
 (0)