From 0d090df3e206dd909849fd05cd869416e4489f74 Mon Sep 17 00:00:00 2001 From: Hong Shin Date: Mon, 22 Jan 2024 14:16:26 -0800 Subject: [PATCH] Implement ProxiedWithRawVTable, ProxiedWithRawOptionalVTable, and ProxiedWithPresence for Messages Stage 2 of 3. Fleshed out the bodies required by the aforementioned contracts above. We create MessageVTable and utilize the `unsafe fns` directly in `message.cc` -- a departure from PrimitiveVTables. In the final followup CL, we will perform the field_entry swapover and update all unit tests. PiperOrigin-RevId: 600567890 --- rust/internal.rs | 4 +-- rust/vtable.rs | 22 +++++++----- src/google/protobuf/compiler/rust/message.cc | 38 ++++++++++++++------ 3 files changed, 44 insertions(+), 20 deletions(-) diff --git a/rust/internal.rs b/rust/internal.rs index e66e7b1630..ac7d67367b 100644 --- a/rust/internal.rs +++ b/rust/internal.rs @@ -11,8 +11,8 @@ pub use crate::r#enum::Enum; pub use crate::vtable::{ - new_vtable_field_entry, BytesMutVTable, BytesOptionalMutVTable, MessageOptionalVTable, - MessageVTable, PrimitiveOptionalMutVTable, PrimitiveVTable, PrimitiveWithRawVTable, + new_vtable_field_entry, BytesMutVTable, BytesOptionalMutVTable, MessageVTable, + PrimitiveOptionalMutVTable, PrimitiveVTable, PrimitiveWithRawVTable, ProxiedWithRawOptionalVTable, ProxiedWithRawVTable, RawVTableMutator, RawVTableOptionalMutatorData, }; diff --git a/rust/vtable.rs b/rust/vtable.rs index de44895907..f577f994fb 100644 --- a/rust/vtable.rs +++ b/rust/vtable.rs @@ -134,10 +134,14 @@ impl<'msg, T: ProxiedWithRawVTable + ?Sized> RawVTableMutator<'msg, T> { RawVTableMutator { msg_ref, vtable: NonNull::from(vtable).cast(), _phantom: PhantomData } } - fn vtable(self) -> &'static T::VTable { + pub fn vtable(self) -> &'static T::VTable { // SAFETY: This was cast from `&'static T::VTable`. unsafe { self.vtable.cast().as_ref() } } + + pub fn msg_ref(self) -> MutatorMessageRef<'msg> { + self.msg_ref + } } /// [`RawVTableMutator`], but also includes has/clear. @@ -197,7 +201,11 @@ impl<'msg, T: ProxiedWithRawOptionalVTable + ?Sized> RawVTableOptionalMutatorDat Self { msg_ref, optional_vtable: NonNull::from(vtable).cast(), _phantom: PhantomData } } - fn optional_vtable(self) -> &'static T::OptionalVTable { + pub fn msg_ref(self) -> MutatorMessageRef<'msg> { + self.msg_ref + } + + pub fn optional_vtable(self) -> &'static T::OptionalVTable { // SAFETY: This was cast from `&'static T::OptionalVTable` in `new`. unsafe { self.optional_vtable.cast().as_ref() } } @@ -507,10 +515,8 @@ impl<'msg, T: PrimitiveWithRawVTable> RawVTableOptionalMutatorData<'msg, T> { } #[derive(Debug)] -#[allow(unused)] -pub struct MessageOptionalVTable { - pub base: MessageVTable, +pub struct MessageVTable { + pub getter: unsafe extern "C" fn(msg: RawMessage) -> RawMessage, + pub mut_getter: unsafe extern "C" fn(msg: RawMessage) -> RawMessage, + pub clearer: unsafe extern "C" fn(msg: RawMessage), } - -#[derive(Debug)] -pub struct MessageVTable {} diff --git a/src/google/protobuf/compiler/rust/message.cc b/src/google/protobuf/compiler/rust/message.cc index 1c038935fa..2185babecc 100644 --- a/src/google/protobuf/compiler/rust/message.cc +++ b/src/google/protobuf/compiler/rust/message.cc @@ -586,25 +586,31 @@ void GenerateRs(Context& ctx, const Descriptor& msg) { type VTable = $pbi$::MessageVTable; fn make_view(_private: $pbi$::Private, - _mut_inner: $pbi$::RawVTableMutator<'_, Self>) + mut_inner: $pbi$::RawVTableMutator<'_, Self>) -> $pb$::View<'_, Self> { - todo!() + let msg = unsafe { + (mut_inner.vtable().getter)(mut_inner.msg_ref().msg()) + }; + $Msg$View::new($pbi$::Private, msg) } fn make_mut(_private: $pbi$::Private, - _inner: $pbi$::RawVTableMutator<'_, Self>) + inner: $pbi$::RawVTableMutator<'_, Self>) -> $pb$::Mut<'_, Self> { - todo!() + let raw_submsg = unsafe { + (inner.vtable().mut_getter)(inner.msg_ref().msg()) + }; + $Msg$Mut::from_parent($pbi$::Private, inner.msg_ref(), raw_submsg) } } impl $pbi$::ProxiedWithRawOptionalVTable for $Msg$ { - type OptionalVTable = $pbi$::MessageOptionalVTable; + type OptionalVTable = $pbi$::MessageVTable; fn upcast_vtable(_private: $pbi$::Private, optional_vtable: &'static Self::OptionalVTable) -> &'static Self::VTable { - &optional_vtable.base + &optional_vtable } } @@ -612,14 +618,26 @@ void GenerateRs(Context& ctx, const Descriptor& msg) { type PresentMutData<'a> = $pbr$::MessagePresentMutData<'a, $Msg$>; type AbsentMutData<'a> = $pbr$::MessageAbsentMutData<'a, $Msg$>; - fn clear_present_field(_present_mutator: Self::PresentMutData<'_>) + fn clear_present_field(present_mutator: Self::PresentMutData<'_>) -> Self::AbsentMutData<'_> { - todo!(); + // SAFETY: The raw ptr msg_ref is valid + unsafe { + (present_mutator.optional_vtable().clearer); + (present_mutator.msg_ref().msg()); + + $pbi$::RawVTableOptionalMutatorData::new($pbi$::Private, + present_mutator.msg_ref(), + present_mutator.optional_vtable()) + } } - fn set_absent_to_default(_absent_mutator: Self::AbsentMutData<'_>) + fn set_absent_to_default(absent_mutator: Self::AbsentMutData<'_>) -> Self::PresentMutData<'_> { - todo!(); + unsafe { + $pbi$::RawVTableOptionalMutatorData::new($pbi$::Private, + absent_mutator.msg_ref(), + absent_mutator.optional_vtable()) + } } }