From 47e239df1107c4cf9be1a7b522ae8820bbc10997 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 28 Aug 2020 00:32:04 -0700 Subject: [PATCH] Implement CxxVector --- src/cxx.cc | 3 ++- src/cxx_vector.rs | 29 +++++++++++++++++++---------- syntax/check.rs | 4 ++-- tests/ffi/lib.rs | 2 ++ tests/ffi/tests.cc | 11 +++++++++++ tests/ffi/tests.h | 3 +++ 6 files changed, 39 insertions(+), 13 deletions(-) diff --git a/src/cxx.cc b/src/cxx.cc index e00fd6ae6..2114598f6 100644 --- a/src/cxx.cc +++ b/src/cxx.cc @@ -276,7 +276,8 @@ void cxxbridge03$unique_ptr$std$string$drop( #define FOR_EACH_STD_VECTOR(MACRO) \ FOR_EACH_NUMERIC(MACRO) \ MACRO(usize, size_t) \ - MACRO(isize, rust::isize) + MACRO(isize, rust::isize) \ + MACRO(string, std::string) #define FOR_EACH_RUST_VEC(MACRO) \ FOR_EACH_NUMERIC(MACRO) \ diff --git a/src/cxx_vector.rs b/src/cxx_vector.rs index bfb4a4e37..10853a62d 100644 --- a/src/cxx_vector.rs +++ b/src/cxx_vector.rs @@ -1,3 +1,4 @@ +use crate::cxx_string::CxxString; use std::ffi::c_void; use std::fmt::{self, Display}; use std::marker::PhantomData; @@ -129,16 +130,16 @@ pub unsafe trait VectorElement: Sized { unsafe fn __unique_ptr_drop(repr: *mut c_void); } -macro_rules! impl_vector_element_for_primitive { - ($ty:ident) => { +macro_rules! impl_vector_element { + ($segment:expr, $name:expr, $ty:ty) => { const_assert_eq!(1, mem::align_of::>()); unsafe impl VectorElement for $ty { - const __NAME: &'static dyn Display = &stringify!($ty); + const __NAME: &'static dyn Display = &$name; fn __vector_size(v: &CxxVector<$ty>) -> usize { extern "C" { attr! { - #[link_name = concat!("cxxbridge03$std$vector$", stringify!($ty), "$size")] + #[link_name = concat!("cxxbridge03$std$vector$", $segment, "$size")] fn __vector_size(_: &CxxVector<$ty>) -> usize; } } @@ -147,7 +148,7 @@ macro_rules! impl_vector_element_for_primitive { unsafe fn __get_unchecked(v: &CxxVector<$ty>, pos: usize) -> &$ty { extern "C" { attr! { - #[link_name = concat!("cxxbridge03$std$vector$", stringify!($ty), "$get_unchecked")] + #[link_name = concat!("cxxbridge03$std$vector$", $segment, "$get_unchecked")] fn __get_unchecked(_: &CxxVector<$ty>, _: usize) -> *const $ty; } } @@ -156,7 +157,7 @@ macro_rules! impl_vector_element_for_primitive { fn __unique_ptr_null() -> *mut c_void { extern "C" { attr! { - #[link_name = concat!("cxxbridge03$unique_ptr$std$vector$", stringify!($ty), "$null")] + #[link_name = concat!("cxxbridge03$unique_ptr$std$vector$", $segment, "$null")] fn __unique_ptr_null(this: *mut *mut c_void); } } @@ -167,7 +168,7 @@ macro_rules! impl_vector_element_for_primitive { unsafe fn __unique_ptr_raw(raw: *mut CxxVector) -> *mut c_void { extern "C" { attr! { - #[link_name = concat!("cxxbridge03$unique_ptr$std$vector$", stringify!($ty), "$raw")] + #[link_name = concat!("cxxbridge03$unique_ptr$std$vector$", $segment, "$raw")] fn __unique_ptr_raw(this: *mut *mut c_void, raw: *mut CxxVector<$ty>); } } @@ -178,7 +179,7 @@ macro_rules! impl_vector_element_for_primitive { unsafe fn __unique_ptr_get(repr: *mut c_void) -> *const CxxVector { extern "C" { attr! { - #[link_name = concat!("cxxbridge03$unique_ptr$std$vector$", stringify!($ty), "$get")] + #[link_name = concat!("cxxbridge03$unique_ptr$std$vector$", $segment, "$get")] fn __unique_ptr_get(this: *const *mut c_void) -> *const CxxVector<$ty>; } } @@ -187,7 +188,7 @@ macro_rules! impl_vector_element_for_primitive { unsafe fn __unique_ptr_release(mut repr: *mut c_void) -> *mut CxxVector { extern "C" { attr! { - #[link_name = concat!("cxxbridge03$unique_ptr$std$vector$", stringify!($ty), "$release")] + #[link_name = concat!("cxxbridge03$unique_ptr$std$vector$", $segment, "$release")] fn __unique_ptr_release(this: *mut *mut c_void) -> *mut CxxVector<$ty>; } } @@ -196,7 +197,7 @@ macro_rules! impl_vector_element_for_primitive { unsafe fn __unique_ptr_drop(mut repr: *mut c_void) { extern "C" { attr! { - #[link_name = concat!("cxxbridge03$unique_ptr$std$vector$", stringify!($ty), "$drop")] + #[link_name = concat!("cxxbridge03$unique_ptr$std$vector$", $segment, "$drop")] fn __unique_ptr_drop(this: *mut *mut c_void); } } @@ -206,6 +207,12 @@ macro_rules! impl_vector_element_for_primitive { }; } +macro_rules! impl_vector_element_for_primitive { + ($ty:ident) => { + impl_vector_element!(stringify!($ty), stringify!($ty), $ty); + }; +} + impl_vector_element_for_primitive!(u8); impl_vector_element_for_primitive!(u16); impl_vector_element_for_primitive!(u32); @@ -218,3 +225,5 @@ impl_vector_element_for_primitive!(i64); impl_vector_element_for_primitive!(isize); impl_vector_element_for_primitive!(f32); impl_vector_element_for_primitive!(f64); + +impl_vector_element!("string", "CxxString", CxxString); diff --git a/syntax/check.rs b/syntax/check.rs index 71fab3b7a..4fbc6e22d 100644 --- a/syntax/check.rs +++ b/syntax/check.rs @@ -130,8 +130,8 @@ fn check_type_cxx_vector(cx: &mut Check, ptr: &Ty1) { match Atom::from(ident) { None | Some(U8) | Some(U16) | Some(U32) | Some(U64) | Some(Usize) | Some(I8) - | Some(I16) | Some(I32) | Some(I64) | Some(Isize) | Some(F32) | Some(F64) => return, - Some(CxxString) => { /* todo */ } + | Some(I16) | Some(I32) | Some(I64) | Some(Isize) | Some(F32) | Some(F64) + | Some(CxxString) => return, Some(Bool) | Some(RustString) => {} } } diff --git a/tests/ffi/lib.rs b/tests/ffi/lib.rs index cb688f319..8aaac75ba 100644 --- a/tests/ffi/lib.rs +++ b/tests/ffi/lib.rs @@ -39,6 +39,7 @@ pub mod ffi { fn c_return_unique_ptr_string() -> UniquePtr; fn c_return_unique_ptr_vector_u8() -> UniquePtr>; fn c_return_unique_ptr_vector_f64() -> UniquePtr>; + fn c_return_unique_ptr_vector_string() -> UniquePtr>; fn c_return_unique_ptr_vector_shared() -> UniquePtr>; fn c_return_unique_ptr_vector_opaque() -> UniquePtr>; fn c_return_ref_vector(c: &C) -> &CxxVector; @@ -62,6 +63,7 @@ pub mod ffi { fn c_take_unique_ptr_string(s: UniquePtr); fn c_take_unique_ptr_vector_u8(v: UniquePtr>); fn c_take_unique_ptr_vector_f64(v: UniquePtr>); + fn c_take_unique_ptr_vector_string(v: UniquePtr>); fn c_take_unique_ptr_vector_shared(v: UniquePtr>); fn c_take_ref_vector(v: &CxxVector); fn c_take_rust_vec(v: Vec); diff --git a/tests/ffi/tests.cc b/tests/ffi/tests.cc index b45e8aecc..d45d5d536 100644 --- a/tests/ffi/tests.cc +++ b/tests/ffi/tests.cc @@ -88,6 +88,11 @@ std::unique_ptr> c_return_unique_ptr_vector_f64() { return vec; } +std::unique_ptr> c_return_unique_ptr_vector_string() { + return std::unique_ptr>( + new std::vector()); +} + std::unique_ptr> c_return_unique_ptr_vector_shared() { auto vec = std::unique_ptr>(new std::vector()); vec->push_back(Shared{1010}); @@ -210,6 +215,12 @@ void c_take_unique_ptr_vector_f64(std::unique_ptr> v) { } } +void c_take_unique_ptr_vector_string( + std::unique_ptr> v) { + (void)v; + cxx_test_suite_set_correct(); +} + void c_take_unique_ptr_vector_shared(std::unique_ptr> v) { if (v->size() == 2) { cxx_test_suite_set_correct(); diff --git a/tests/ffi/tests.h b/tests/ffi/tests.h index 0efbd624d..f3bc2dd5f 100644 --- a/tests/ffi/tests.h +++ b/tests/ffi/tests.h @@ -43,6 +43,7 @@ rust::String c_return_rust_string(); std::unique_ptr c_return_unique_ptr_string(); std::unique_ptr> c_return_unique_ptr_vector_u8(); std::unique_ptr> c_return_unique_ptr_vector_f64(); +std::unique_ptr> c_return_unique_ptr_vector_string(); std::unique_ptr> c_return_unique_ptr_vector_shared(); std::unique_ptr> c_return_unique_ptr_vector_opaque(); const std::vector &c_return_ref_vector(const C &c); @@ -67,6 +68,8 @@ void c_take_rust_string(rust::String s); void c_take_unique_ptr_string(std::unique_ptr s); void c_take_unique_ptr_vector_u8(std::unique_ptr> v); void c_take_unique_ptr_vector_f64(std::unique_ptr> v); +void c_take_unique_ptr_vector_string( + std::unique_ptr> v); void c_take_unique_ptr_vector_shared(std::unique_ptr> v); void c_take_ref_vector(const std::vector &v); void c_take_rust_vec(rust::Vec v);