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
11 changes: 8 additions & 3 deletions cc_bindings_from_rs/generate_bindings/generate_function_thunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use arc_anyhow::{Context, Result};
use code_gen_utils::escape_non_identifier_chars;
use code_gen_utils::make_rs_ident;
use code_gen_utils::CcConstQualifier;
use crubit_abi_type::CrubitAbiTypeToRustTokens;
use crubit_abi_type::{CrubitAbiTypeToRustExprTokens, CrubitAbiTypeToRustTokens};
use database::code_snippet::{CcPrerequisites, CcSnippet, ExternCDecl};
use database::{AdtCoreBindings, BindingsGenerator, SugaredTy};
use error_report::{anyhow, bail, ensure};
Expand Down Expand Up @@ -223,9 +223,12 @@ fn convert_bridged_type_from_c_abi_to_rust<'tcx>(
}
BridgedType::Composable(composable) => {
let crubit_abi_type = CrubitAbiTypeToRustTokens(&composable.crubit_abi_type);
let crubit_abi_type_expr = CrubitAbiTypeToRustExprTokens(&composable.crubit_abi_type);
// SAFETY: The buffer is the correct size, as determined by Crubit.
Ok(quote! {
let #local_name = unsafe { ::bridge_rust::internal::decode::<#crubit_abi_type>(#local_name) };
let #local_name = unsafe {
::bridge_rust::decode_wrapper!(#crubit_abi_type_expr, #crubit_abi_type, #local_name)
};
})
}
}
Expand Down Expand Up @@ -413,10 +416,12 @@ fn write_rs_value_to_c_abi_ptr<'tcx>(
},
BridgedType::Composable(composable) => {
let crubit_abi_type = CrubitAbiTypeToRustTokens(&composable.crubit_abi_type);
let crubit_abi_type_expr =
CrubitAbiTypeToRustExprTokens(&composable.crubit_abi_type);
quote! {
// SAFETY: TODO(okabayashi)
unsafe {
::bridge_rust::internal::encode::<#crubit_abi_type>(
::bridge_rust::encode_wrapper!(#crubit_abi_type_expr, #crubit_abi_type,
// TODO(okabayashi): This ptr case can be removed once tuple bridging is supported,
// as it only is required in the tuple recursive case.
#c_ptr as *mut core::ffi::c_uchar,
Expand Down
18 changes: 9 additions & 9 deletions cc_bindings_from_rs/test/golden/composable_bridging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

use bridge_rust::{CrubitAbi, Decoder, Encoder};
use bridge_rust::{transmute_abi, CrubitAbi, Decoder, Encoder};
use std::mem;

pub fn returns_some_int() -> Option<i32> {
Expand Down Expand Up @@ -34,28 +34,28 @@ pub fn maybe_int_slice() -> Option<*const [i32]> {
Some(&[1, 2, 3][..] as *const [i32])
}

pub struct MyOptionRustAbi<T>(core::marker::PhantomData<T>);
pub struct MyOptionRustAbi<A>(pub A);

unsafe impl<A: CrubitAbi> CrubitAbi for MyOptionRustAbi<A> {
type Value = MyOptionRust<A::Value>;

const SIZE: usize = mem::size_of::<bool>() + A::SIZE;

fn encode(value: Self::Value, encoder: &mut Encoder) {
fn encode(self, value: Self::Value, encoder: &mut Encoder) {
if let Some(inner) = value.0 {
encoder.encode_transmute(true);
encoder.encode::<A>(inner);
transmute_abi().encode(true, encoder);
self.0.encode(inner, encoder);
} else {
encoder.encode_transmute(false);
transmute_abi().encode(false, encoder);
}
}

unsafe fn decode(decoder: &mut Decoder) -> Self::Value {
unsafe fn decode(self, decoder: &mut Decoder) -> Self::Value {
// SAFETY: the caller guarantees that the buffer contains a bool, and if the bool is true,
// that the buffer also contains the value.
unsafe {
if decoder.decode_transmute() {
MyOptionRust(Some(decoder.decode::<A>()))
if transmute_abi().decode(decoder) {
MyOptionRust(Some(self.0.decode(decoder)))
} else {
MyOptionRust(None)
}
Expand Down
47 changes: 33 additions & 14 deletions cc_bindings_from_rs/test/golden/composable_bridging_cc_api_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ unsafe extern "C" fn __crubit_thunk_returns_usome_uint(__ret_ptr: *mut core::ffi
unsafe {
let __rs_return_value = ::composable_bridging_rust_golden::returns_some_int();
unsafe {
::bridge_rust::internal::encode::<
::bridge_rust::encode_wrapper!(
::bridge_rust::OptionAbi(::bridge_rust::transmute_abi()),
::bridge_rust::OptionAbi<::bridge_rust::TransmuteAbi<i32>>,
>(__ret_ptr as *mut core::ffi::c_uchar, __rs_return_value);
__ret_ptr as *mut core::ffi::c_uchar,
__rs_return_value,
);
}
}
}
Expand All @@ -26,19 +29,24 @@ unsafe extern "C" fn __crubit_thunk_returns_uno_uint(__ret_ptr: *mut core::ffi::
unsafe {
let __rs_return_value = ::composable_bridging_rust_golden::returns_no_int();
unsafe {
::bridge_rust::internal::encode::<
::bridge_rust::encode_wrapper!(
::bridge_rust::OptionAbi(::bridge_rust::transmute_abi()),
::bridge_rust::OptionAbi<::bridge_rust::TransmuteAbi<i32>>,
>(__ret_ptr as *mut core::ffi::c_uchar, __rs_return_value);
__ret_ptr as *mut core::ffi::c_uchar,
__rs_return_value,
);
}
}
}
#[unsafe(no_mangle)]
unsafe extern "C" fn __crubit_thunk_unwrap_uor_uzero(x: *const core::ffi::c_uchar) -> i32 {
unsafe {
let x = unsafe {
::bridge_rust::internal::decode::<
::bridge_rust::decode_wrapper!(
::bridge_rust::OptionAbi(::bridge_rust::transmute_abi()),
::bridge_rust::OptionAbi<::bridge_rust::TransmuteAbi<i32>>,
>(x)
x
)
};
::composable_bridging_rust_golden::unwrap_or_zero(x)
}
Expand All @@ -50,15 +58,20 @@ unsafe extern "C" fn __crubit_thunk_option_uincrements(
) -> () {
unsafe {
let x = unsafe {
::bridge_rust::internal::decode::<
::bridge_rust::decode_wrapper!(
::bridge_rust::OptionAbi(::bridge_rust::transmute_abi()),
::bridge_rust::OptionAbi<::bridge_rust::TransmuteAbi<i32>>,
>(x)
x
)
};
let __rs_return_value = ::composable_bridging_rust_golden::option_increments(x);
unsafe {
::bridge_rust::internal::encode::<
::bridge_rust::encode_wrapper!(
::bridge_rust::OptionAbi(::bridge_rust::transmute_abi()),
::bridge_rust::OptionAbi<::bridge_rust::TransmuteAbi<i32>>,
>(__ret_ptr as *mut core::ffi::c_uchar, __rs_return_value);
__ret_ptr as *mut core::ffi::c_uchar,
__rs_return_value,
);
}
}
}
Expand All @@ -69,11 +82,14 @@ unsafe extern "C" fn __crubit_thunk_make_umy_uoption_urust(
unsafe {
let __rs_return_value = ::composable_bridging_rust_golden::make_my_option_rust();
unsafe {
::bridge_rust::internal::encode::<
::bridge_rust::encode_wrapper!(
::composable_bridging_rust_golden::MyOptionRustAbi(::bridge_rust::transmute_abi()),
::composable_bridging_rust_golden::MyOptionRustAbi<
::bridge_rust::TransmuteAbi<i32>,
>,
>(__ret_ptr as *mut core::ffi::c_uchar, __rs_return_value);
__ret_ptr as *mut core::ffi::c_uchar,
__rs_return_value,
);
}
}
}
Expand All @@ -82,9 +98,12 @@ unsafe extern "C" fn __crubit_thunk_maybe_uint_uslice(__ret_ptr: *mut core::ffi:
unsafe {
let __rs_return_value = ::composable_bridging_rust_golden::maybe_int_slice();
unsafe {
::bridge_rust::internal::encode::<
::bridge_rust::encode_wrapper!(
::bridge_rust::OptionAbi(::bridge_rust::transmute_abi()),
::bridge_rust::OptionAbi<::bridge_rust::TransmuteAbi<*const [i32]>>,
>(__ret_ptr as *mut core::ffi::c_uchar, __rs_return_value);
__ret_ptr as *mut core::ffi::c_uchar,
__rs_return_value,
);
}
}
}
18 changes: 9 additions & 9 deletions examples/types/bridging/either_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,26 @@ struct EitherAbi {
sizeof(bool) +
(LeftAbi::kSize > RightAbi::kSize ? LeftAbi::kSize : RightAbi::kSize);

static void Encode(Value value, crubit::Encoder& encoder) {
void Encode(Value value, crubit::Encoder& encoder) && {
if (value.is_left) {
encoder.EncodeTransmute(true);
encoder.Encode<LeftAbi>(std::move(value.left));
crubit::TransmuteAbi<bool>().Encode(true, encoder);
std::move(left_abi).Encode(std::move(value.left), encoder);
} else {
encoder.EncodeTransmute(false);
encoder.Encode<RightAbi>(std::move(value.right));
crubit::TransmuteAbi<bool>().Encode(false, encoder);
std::move(right_abi).Encode(std::move(value.right), encoder);
}
}

static Value Decode(crubit::Decoder& decoder) {
if (decoder.DecodeTransmute<bool>()) {
Value Decode(crubit::Decoder& decoder) && {
if (crubit::TransmuteAbi<bool>().Decode(decoder)) {
return {
.is_left = true,
.left = decoder.Decode<LeftAbi>(),
.left = std::move(left_abi).Decode(decoder),
};
} else {
return {
.is_left = false,
.right = decoder.Decode<RightAbi>(),
.right = std::move(right_abi).Decode(decoder),
};
}
}
Expand Down
16 changes: 8 additions & 8 deletions rs_bindings_from_cc/test/bridging/composable_bridging_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@ template <typename Abi>
struct Vec3Abi {
using Value = Vec3<typename Abi::Value>;
static constexpr size_t kSize = Abi::kSize * 3;
static void Encode(Value value, crubit::Encoder& encoder) {
encoder.Encode<Abi>(std::move(value.x));
encoder.Encode<Abi>(std::move(value.y));
encoder.Encode<Abi>(std::move(value.z));
void Encode(Value value, crubit::Encoder& encoder) && {
abi.Encode(std::move(value.x), encoder);
abi.Encode(std::move(value.y), encoder);
abi.Encode(std::move(value.z), encoder);
}
static Value Decode(crubit::Decoder& decoder) {
Value Decode(crubit::Decoder& decoder) && {
return {
.x = decoder.Decode<Abi>(),
.y = decoder.Decode<Abi>(),
.z = decoder.Decode<Abi>(),
.x = abi.Decode(decoder),
.y = abi.Decode(decoder),
.z = abi.Decode(decoder),
};
}

Expand Down
Loading