0
0
Fork 0
mirror of https://github.com/denoland/rusty_v8.git synced 2025-02-01 12:15:46 -05:00
This commit is contained in:
Bert Belder 2019-10-20 14:22:18 -07:00
parent 7b8e882546
commit 1e3f137cc2
No known key found for this signature in database
GPG key ID: 7A77887B2E2ED461
5 changed files with 172 additions and 149 deletions

View file

@ -11,15 +11,15 @@ mod example {
pub struct Example { pub struct Example {
a: i32, a: i32,
channel_extender: ChannelExtender, channel_extender: ChannelBase,
b: i32, b: i32,
} }
impl ChannelOverrides for Example { impl ChannelImpl for Example {
fn extender(&self) -> &ChannelExtender { fn base(&self) -> &ChannelBase {
&self.channel_extender &self.channel_extender
} }
fn extender_mut(&mut self) -> &mut ChannelExtender { fn base_mut(&mut self) -> &mut ChannelBase {
&mut self.channel_extender &mut self.channel_extender
} }
fn sendResponse( fn sendResponse(
@ -40,7 +40,7 @@ mod example {
impl Example { impl Example {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
channel_extender: ChannelExtender::new::<Self>(), channel_extender: ChannelBase::new::<Self>(),
a: 2, a: 2,
b: 3, b: 3,
} }

View file

@ -2,56 +2,63 @@
#include <utility> #include <utility>
using namespace v8_inspector; using namespace v8_inspector;
using Channel = V8Inspector::Channel;
extern "C" { extern "C" {
void v8_inspector__Channel__EXTENDER__sendResponse(Channel& self, void v8_inspector__V8Inspector__Channel__BASE__sendResponse(
int callId, V8Inspector::Channel& self,
StringBuffer* message); int callId,
void v8_inspector__Channel__EXTENDER__sendNotification(Channel& self, StringBuffer* message);
StringBuffer* message); void v8_inspector__V8Inspector__Channel__BASE__sendNotification(
void v8_inspector__Channel__EXTENDER__flushProtocolNotifications(Channel& self); V8Inspector::Channel& self,
StringBuffer* message);
void v8_inspector__V8Inspector__Channel__BASE__flushProtocolNotifications(
V8Inspector::Channel& self);
} // extern "C" } // extern "C"
namespace v8_inspector { namespace v8_inspector {
struct Channel__EXTENDER : public Channel { struct V8Inspector__Channel__BASE : public V8Inspector::Channel {
using Channel::Channel; using V8Inspector::Channel::Channel;
static_assert(sizeof(std::unique_ptr<StringBuffer>) == sizeof(StringBuffer*), static_assert(sizeof(std::unique_ptr<StringBuffer>) == sizeof(StringBuffer*),
"sizeof(T*) != sizeof(unique_ptr<T>)"); "sizeof(T*) != sizeof(unique_ptr<T>)");
void sendResponse(int callId, void sendResponse(int callId,
std::unique_ptr<StringBuffer> message) override { std::unique_ptr<StringBuffer> message) override {
v8_inspector__Channel__EXTENDER__sendResponse(*this, callId, v8_inspector__V8Inspector__Channel__BASE__sendResponse(*this, callId,
message.release()); message.release());
} }
void sendNotification(std::unique_ptr<StringBuffer> message) override { void sendNotification(std::unique_ptr<StringBuffer> message) override {
v8_inspector__Channel__EXTENDER__sendNotification(*this, message.release()); v8_inspector__V8Inspector__Channel__BASE__sendNotification(
*this, message.release());
} }
void flushProtocolNotifications() override { void flushProtocolNotifications() override {
v8_inspector__Channel__EXTENDER__flushProtocolNotifications(*this); v8_inspector__V8Inspector__Channel__BASE__flushProtocolNotifications(*this);
} }
}; };
} // namespace v8_inspector } // namespace v8_inspector
extern "C" { extern "C" {
void v8_inspector__Channel__EXTENDER__CTOR(uninit_t<Channel__EXTENDER>& buf) { void v8_inspector__V8Inspector__Channel__BASE__CTOR(
new (launder(&buf)) Channel__EXTENDER(); uninit_t<V8Inspector__Channel__BASE>& buf) {
new (launder(&buf)) V8Inspector__Channel__BASE();
} }
void v8_inspector__Channel__DTOR(Channel& self) { void v8_inspector__V8Inspector__Channel__DTOR(V8Inspector::Channel& self) {
self.~Channel(); self.~Channel();
} }
void v8_inspector__Channel__sendResponse(Channel& self, void v8_inspector__V8Inspector__Channel__sendResponse(
int callId, V8Inspector::Channel& self,
StringBuffer* message) { int callId,
StringBuffer* message) {
self.sendResponse(callId, self.sendResponse(callId,
static_cast<std::unique_ptr<StringBuffer>>(message)); static_cast<std::unique_ptr<StringBuffer>>(message));
} }
void v8_inspector__Channel__sendNotification(Channel& self, void v8_inspector__V8Inspector__Channel__sendNotification(
StringBuffer* message) { V8Inspector::Channel& self,
StringBuffer* message) {
self.sendNotification(static_cast<std::unique_ptr<StringBuffer>>(message)); self.sendNotification(static_cast<std::unique_ptr<StringBuffer>>(message));
} }
void v8_inspector__Channel__flushProtocolNotifications(Channel& self) { void v8_inspector__V8Inspector__Channel__flushProtocolNotifications(
V8Inspector::Channel& self) {
self.flushProtocolNotifications(); self.flushProtocolNotifications();
} }
} // extern "C" } // extern "C"

View file

@ -17,47 +17,47 @@ use super::StringBuffer;
// }; // };
extern "C" { extern "C" {
fn v8_inspector__Channel__EXTENDER__CTOR( fn v8_inspector__V8Inspector__Channel__BASE__CTOR(
buf: &mut std::mem::MaybeUninit<Channel>, buf: &mut std::mem::MaybeUninit<Channel>,
) -> (); ) -> ();
fn v8_inspector__Channel__DTOR(this: &mut Channel) -> (); fn v8_inspector__V8Inspector__Channel__DTOR(this: &mut Channel) -> ();
fn v8_inspector__Channel__sendResponse( fn v8_inspector__V8Inspector__Channel__sendResponse(
this: &mut Channel, this: &mut Channel,
callId: int, callId: int,
message: UniquePtr<StringBuffer>, message: UniquePtr<StringBuffer>,
) -> (); ) -> ();
fn v8_inspector__Channel__sendNotification( fn v8_inspector__V8Inspector__Channel__sendNotification(
this: &mut Channel, this: &mut Channel,
message: UniquePtr<StringBuffer>, message: UniquePtr<StringBuffer>,
) -> (); ) -> ();
fn v8_inspector__Channel__flushProtocolNotifications( fn v8_inspector__V8Inspector__Channel__flushProtocolNotifications(
this: &mut Channel, this: &mut Channel,
) -> (); ) -> ();
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn v8_inspector__Channel__EXTENDER__sendResponse( pub unsafe extern "C" fn v8_inspector__V8Inspector__Channel__BASE__sendResponse(
this: &mut Channel, this: &mut Channel,
callId: int, callId: int,
message: UniquePtr<StringBuffer>, message: UniquePtr<StringBuffer>,
) -> () { ) -> () {
ChannelExtender::dispatch_mut(this).sendResponse(callId, message) ChannelBase::dispatch_mut(this).sendResponse(callId, message)
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn v8_inspector__Channel__EXTENDER__sendNotification( pub unsafe extern "C" fn v8_inspector__V8Inspector__Channel__BASE__sendNotification(
this: &mut Channel, this: &mut Channel,
message: UniquePtr<StringBuffer>, message: UniquePtr<StringBuffer>,
) -> () { ) -> () {
ChannelExtender::dispatch_mut(this).sendNotification(message) ChannelBase::dispatch_mut(this).sendNotification(message)
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn v8_inspector__Channel__EXTENDER__flushProtocolNotifications( pub unsafe extern "C" fn v8_inspector__V8Inspector__Channel__BASE__flushProtocolNotifications(
this: &mut Channel, this: &mut Channel,
) -> () { ) -> () {
ChannelExtender::dispatch_mut(this).flushProtocolNotifications() ChannelBase::dispatch_mut(this).flushProtocolNotifications()
} }
#[repr(C)] #[repr(C)]
@ -71,19 +71,25 @@ impl Channel {
callId: int, callId: int,
message: UniquePtr<StringBuffer>, message: UniquePtr<StringBuffer>,
) -> () { ) -> () {
unsafe { v8_inspector__Channel__sendResponse(self, callId, message) } unsafe {
v8_inspector__V8Inspector__Channel__sendResponse(self, callId, message)
}
} }
pub fn sendNotification(&mut self, message: UniquePtr<StringBuffer>) -> () { pub fn sendNotification(&mut self, message: UniquePtr<StringBuffer>) -> () {
unsafe { v8_inspector__Channel__sendNotification(self, message) } unsafe {
v8_inspector__V8Inspector__Channel__sendNotification(self, message)
}
} }
pub fn flushProtocolNotifications(&mut self) -> () { pub fn flushProtocolNotifications(&mut self) -> () {
unsafe { v8_inspector__Channel__flushProtocolNotifications(self) } unsafe {
v8_inspector__V8Inspector__Channel__flushProtocolNotifications(self)
}
} }
} }
impl Drop for Channel { impl Drop for Channel {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { v8_inspector__Channel__DTOR(self) } unsafe { v8_inspector__V8Inspector__Channel__DTOR(self) }
} }
} }
@ -103,19 +109,19 @@ impl AsChannel for Channel {
impl<T> AsChannel for T impl<T> AsChannel for T
where where
T: ChannelOverrides, T: ChannelImpl,
{ {
fn as_channel(&self) -> &Channel { fn as_channel(&self) -> &Channel {
&self.extender().cxx_channel &self.base().cxx_base
} }
fn as_channel_mut(&mut self) -> &mut Channel { fn as_channel_mut(&mut self) -> &mut Channel {
&mut self.extender_mut().cxx_channel &mut self.base_mut().cxx_base
} }
} }
pub trait ChannelOverrides: AsChannel { pub trait ChannelImpl: AsChannel {
fn extender(&self) -> &ChannelExtender; fn base(&self) -> &ChannelBase;
fn extender_mut(&mut self) -> &mut ChannelExtender; fn base_mut(&mut self) -> &mut ChannelBase;
fn sendResponse( fn sendResponse(
&mut self, &mut self,
@ -126,38 +132,43 @@ pub trait ChannelOverrides: AsChannel {
fn flushProtocolNotifications(&mut self) -> (); fn flushProtocolNotifications(&mut self) -> ();
} }
pub struct ChannelExtender { pub struct ChannelBase {
cxx_channel: Channel, cxx_base: Channel,
extender_offset: FieldOffset<Self>, offset_within_embedder: FieldOffset<Self>,
rust_vtable: RustVTable<&'static dyn ChannelOverrides>, rust_vtable: RustVTable<&'static dyn ChannelImpl>,
} }
impl ChannelExtender { impl ChannelBase {
fn construct_cxx_channel() -> Channel { fn construct_cxx_base() -> Channel {
unsafe { unsafe {
let mut buf = std::mem::MaybeUninit::<Channel>::uninit(); let mut buf = std::mem::MaybeUninit::<Channel>::uninit();
v8_inspector__Channel__EXTENDER__CTOR(&mut buf); v8_inspector__V8Inspector__Channel__BASE__CTOR(&mut buf);
buf.assume_init() buf.assume_init()
} }
} }
fn get_extender_offset<T>() -> FieldOffset<Self> fn get_cxx_base_offset() -> FieldOffset<Channel> {
let buf = std::mem::MaybeUninit::<Self>::uninit();
FieldOffset::from_ptrs(buf.as_ptr(), unsafe { &(*buf.as_ptr()).cxx_base })
}
fn get_offset_within_embedder<T>() -> FieldOffset<Self>
where where
T: ChannelOverrides, T: ChannelImpl,
{ {
let buf = std::mem::MaybeUninit::<T>::uninit(); let buf = std::mem::MaybeUninit::<T>::uninit();
let embedder_ptr: *const T = buf.as_ptr(); let embedder_ptr: *const T = buf.as_ptr();
let self_ptr: *const Self = unsafe { (*embedder_ptr).extender() }; let self_ptr: *const Self = unsafe { (*embedder_ptr).base() };
FieldOffset::from_ptrs(embedder_ptr, self_ptr) FieldOffset::from_ptrs(embedder_ptr, self_ptr)
} }
fn get_rust_vtable<T>() -> RustVTable<&'static dyn ChannelOverrides> fn get_rust_vtable<T>() -> RustVTable<&'static dyn ChannelImpl>
where where
T: ChannelOverrides, T: ChannelImpl,
{ {
let buf = std::mem::MaybeUninit::<T>::uninit(); let buf = std::mem::MaybeUninit::<T>::uninit();
let embedder_ptr = buf.as_ptr(); let embedder_ptr = buf.as_ptr();
let trait_object: *const dyn ChannelOverrides = embedder_ptr; let trait_object: *const dyn ChannelImpl = embedder_ptr;
let (data_ptr, vtable): (*const T, RustVTable<_>) = let (data_ptr, vtable): (*const T, RustVTable<_>) =
unsafe { std::mem::transmute(trait_object) }; unsafe { std::mem::transmute(trait_object) };
assert_eq!(data_ptr, embedder_ptr); assert_eq!(data_ptr, embedder_ptr);
@ -166,34 +177,25 @@ impl ChannelExtender {
pub fn new<T>() -> Self pub fn new<T>() -> Self
where where
T: ChannelOverrides, T: ChannelImpl,
{ {
Self { Self {
cxx_channel: Self::construct_cxx_channel(), cxx_base: Self::construct_cxx_base(),
extender_offset: Self::get_extender_offset::<T>(), offset_within_embedder: Self::get_offset_within_embedder::<T>(),
rust_vtable: Self::get_rust_vtable::<T>(), rust_vtable: Self::get_rust_vtable::<T>(),
} }
} }
fn get_channel_offset() -> FieldOffset<Channel> { pub unsafe fn dispatch(channel: &Channel) -> &dyn ChannelImpl {
let buf = std::mem::MaybeUninit::<Self>::uninit(); let this = Self::get_cxx_base_offset().to_embedder::<Self>(channel);
FieldOffset::from_ptrs(buf.as_ptr(), unsafe { let embedder = this.offset_within_embedder.to_embedder::<Opaque>(this);
&(*buf.as_ptr()).cxx_channel
})
}
pub unsafe fn dispatch(channel: &Channel) -> &dyn ChannelOverrides {
let this = Self::get_channel_offset().to_embedder::<Self>(channel);
let embedder = this.extender_offset.to_embedder::<Opaque>(this);
std::mem::transmute((embedder, this.rust_vtable)) std::mem::transmute((embedder, this.rust_vtable))
} }
pub unsafe fn dispatch_mut( pub unsafe fn dispatch_mut(channel: &mut Channel) -> &mut dyn ChannelImpl {
channel: &mut Channel, let this = Self::get_cxx_base_offset().to_embedder_mut::<Self>(channel);
) -> &mut dyn ChannelOverrides {
let this = Self::get_channel_offset().to_embedder_mut::<Self>(channel);
let vtable = this.rust_vtable; let vtable = this.rust_vtable;
let embedder = this.extender_offset.to_embedder_mut::<Opaque>(this); let embedder = this.offset_within_embedder.to_embedder_mut::<Opaque>(this);
std::mem::transmute((embedder, vtable)) std::mem::transmute((embedder, vtable))
} }
} }

View file

@ -2,53 +2,57 @@
#include <utility> #include <utility>
using namespace v8_inspector; using namespace v8_inspector;
using Client = V8InspectorClient;
extern "C" { extern "C" {
void v8_inspector__Client__EXTENDER__runMessageLoopOnPause(Client& self, void v8_inspector__V8InspectorClient__BASE__runMessageLoopOnPause(
int contextGroupId); V8InspectorClient& self,
void v8_inspector__Client__EXTENDER__quitMessageLoopOnPause(Client& self); int contextGroupId);
void v8_inspector__Client__EXTENDER__runIfWaitingForDebugger( void v8_inspector__V8InspectorClient__BASE__quitMessageLoopOnPause(
Client& self, V8InspectorClient& self);
void v8_inspector__V8InspectorClient__BASE__runIfWaitingForDebugger(
V8InspectorClient& self,
int contextGroupId); int contextGroupId);
} // extern "C" } // extern "C"
namespace v8_inspector { namespace v8_inspector {
struct Client__EXTENDER : public Client { struct Client__BASE : public V8InspectorClient {
using Client::Client; using V8InspectorClient::V8InspectorClient;
void runMessageLoopOnPause(int contextGroupId) override { void runMessageLoopOnPause(int contextGroupId) override {
v8_inspector__Client__EXTENDER__runMessageLoopOnPause(*this, v8_inspector__V8InspectorClient__BASE__runMessageLoopOnPause(
contextGroupId); *this, contextGroupId);
} }
void quitMessageLoopOnPause() override { void quitMessageLoopOnPause() override {
v8_inspector__Client__EXTENDER__quitMessageLoopOnPause(*this); v8_inspector__V8InspectorClient__BASE__quitMessageLoopOnPause(*this);
} }
void runIfWaitingForDebugger(int contextGroupId) override { void runIfWaitingForDebugger(int contextGroupId) override {
v8_inspector__Client__EXTENDER__runIfWaitingForDebugger(*this, v8_inspector__V8InspectorClient__BASE__runIfWaitingForDebugger(
contextGroupId); *this, contextGroupId);
} }
}; };
} // namespace v8_inspector } // namespace v8_inspector
extern "C" { extern "C" {
void v8_inspector__Client__EXTENDER__CTOR(uninit_t<Client__EXTENDER>& buf) { void v8_inspector__V8InspectorClient__BASE__CTOR(uninit_t<Client__BASE>& buf) {
new (launder(&buf)) Client__EXTENDER(); new (launder(&buf)) Client__BASE();
} }
void v8_inspector__Client__DTOR(Client& self) { void v8_inspector__V8InspectorClient__DTOR(V8InspectorClient& self) {
self.~Client(); self.~V8InspectorClient();
} }
void v8_inspector__Client__runMessageLoopOnPause(Client& self, void v8_inspector__V8InspectorClient__runMessageLoopOnPause(
int contextGroupId) { V8InspectorClient& self,
int contextGroupId) {
self.runMessageLoopOnPause(contextGroupId); self.runMessageLoopOnPause(contextGroupId);
} }
void v8_inspector__Client__quitMessageLoopOnPause(Client& self) { void v8_inspector__V8InspectorClient__quitMessageLoopOnPause(
V8InspectorClient& self) {
self.quitMessageLoopOnPause(); self.quitMessageLoopOnPause();
} }
void v8_inspector__Client__runIfWaitingForDebugger(Client& self, void v8_inspector__V8InspectorClient__runIfWaitingForDebugger(
int contextGroupId) { V8InspectorClient& self,
int contextGroupId) {
self.runIfWaitingForDebugger(contextGroupId); self.runIfWaitingForDebugger(contextGroupId);
} }
} // extern "C" } // extern "C"

View file

@ -67,43 +67,45 @@ use crate::cxx_util::RustVTable;
// }; // };
extern "C" { extern "C" {
fn v8_inspector__Client__EXTENDER__CTOR( fn v8_inspector__V8InspectorClient__BASE__CTOR(
buf: &mut std::mem::MaybeUninit<Client>, buf: &mut std::mem::MaybeUninit<Client>,
) -> (); ) -> ();
fn v8_inspector__Client__DTOR(this: &mut Client) -> (); fn v8_inspector__V8InspectorClient__DTOR(this: &mut Client) -> ();
fn v8_inspector__Client__runMessageLoopOnPause( fn v8_inspector__V8InspectorClient__runMessageLoopOnPause(
this: &mut Client, this: &mut Client,
contextGroupId: int, contextGroupId: int,
) -> (); ) -> ();
fn v8_inspector__Client__quitMessageLoopOnPause(this: &mut Client) -> (); fn v8_inspector__V8InspectorClient__quitMessageLoopOnPause(
fn v8_inspector__Client__runIfWaitingForDebugger( this: &mut Client,
) -> ();
fn v8_inspector__V8InspectorClient__runIfWaitingForDebugger(
this: &mut Client, this: &mut Client,
contextGroupId: int, contextGroupId: int,
) -> (); ) -> ();
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn v8_inspector__Client__EXTENDER__runMessageLoopOnPause( pub unsafe extern "C" fn v8_inspector__V8InspectorClient__BASE__runMessageLoopOnPause(
this: &mut Client, this: &mut Client,
contextGroupId: int, contextGroupId: int,
) -> () { ) -> () {
ClientExtender::dispatch_mut(this).runMessageLoopOnPause(contextGroupId) ClientBase::dispatch_mut(this).runMessageLoopOnPause(contextGroupId)
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn v8_inspector__Client__EXTENDER__quitMessageLoopOnPause( pub unsafe extern "C" fn v8_inspector__V8InspectorClient__BASE__quitMessageLoopOnPause(
this: &mut Client, this: &mut Client,
) -> () { ) -> () {
ClientExtender::dispatch_mut(this).quitMessageLoopOnPause() ClientBase::dispatch_mut(this).quitMessageLoopOnPause()
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn v8_inspector__Client__EXTENDER__runIfWaitingForDebugger( pub unsafe extern "C" fn v8_inspector__V8InspectorClient__BASE__runIfWaitingForDebugger(
this: &mut Client, this: &mut Client,
contextGroupId: int, contextGroupId: int,
) -> () { ) -> () {
ClientExtender::dispatch_mut(this).runIfWaitingForDebugger(contextGroupId) ClientBase::dispatch_mut(this).runIfWaitingForDebugger(contextGroupId)
} }
#[repr(C)] #[repr(C)]
@ -113,21 +115,29 @@ pub struct Client {
impl Client { impl Client {
pub fn runMessageLoopOnPause(&mut self, contextGroupId: int) -> () { pub fn runMessageLoopOnPause(&mut self, contextGroupId: int) -> () {
unsafe { v8_inspector__Client__runMessageLoopOnPause(self, contextGroupId) } unsafe {
v8_inspector__V8InspectorClient__runMessageLoopOnPause(
self,
contextGroupId,
)
}
} }
pub fn quitMessageLoopOnPause(&mut self) -> () { pub fn quitMessageLoopOnPause(&mut self) -> () {
unsafe { v8_inspector__Client__quitMessageLoopOnPause(self) } unsafe { v8_inspector__V8InspectorClient__quitMessageLoopOnPause(self) }
} }
pub fn runIfWaitingForDebugger(&mut self, contextGroupId: int) -> () { pub fn runIfWaitingForDebugger(&mut self, contextGroupId: int) -> () {
unsafe { unsafe {
v8_inspector__Client__runIfWaitingForDebugger(self, contextGroupId) v8_inspector__V8InspectorClient__runIfWaitingForDebugger(
self,
contextGroupId,
)
} }
} }
} }
impl Drop for Client { impl Drop for Client {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { v8_inspector__Client__DTOR(self) } unsafe { v8_inspector__V8InspectorClient__DTOR(self) }
} }
} }
@ -147,58 +157,63 @@ impl AsClient for Client {
impl<T> AsClient for T impl<T> AsClient for T
where where
T: ClientOverrides, T: ClientImpl,
{ {
fn as_client(&self) -> &Client { fn as_client(&self) -> &Client {
&self.extender().cxx_client &self.base().cxx_base
} }
fn as_client_mut(&mut self) -> &mut Client { fn as_client_mut(&mut self) -> &mut Client {
&mut self.extender_mut().cxx_client &mut self.base_mut().cxx_base
} }
} }
#[allow(unused_variables)] #[allow(unused_variables)]
pub trait ClientOverrides: AsClient { pub trait ClientImpl: AsClient {
fn extender(&self) -> &ClientExtender; fn base(&self) -> &ClientBase;
fn extender_mut(&mut self) -> &mut ClientExtender; fn base_mut(&mut self) -> &mut ClientBase;
fn runMessageLoopOnPause(&mut self, contextGroupId: int) -> () {} fn runMessageLoopOnPause(&mut self, contextGroupId: int) -> () {}
fn quitMessageLoopOnPause(&mut self) -> () {} fn quitMessageLoopOnPause(&mut self) -> () {}
fn runIfWaitingForDebugger(&mut self, contextGroupId: int) -> () {} fn runIfWaitingForDebugger(&mut self, contextGroupId: int) -> () {}
} }
pub struct ClientExtender { pub struct ClientBase {
cxx_client: Client, cxx_base: Client,
extender_offset: FieldOffset<Self>, offset_within_embedder: FieldOffset<Self>,
rust_vtable: RustVTable<&'static dyn ClientOverrides>, rust_vtable: RustVTable<&'static dyn ClientImpl>,
} }
impl ClientExtender { impl ClientBase {
fn construct_cxx_client() -> Client { fn construct_cxx_base() -> Client {
unsafe { unsafe {
let mut buf = std::mem::MaybeUninit::<Client>::uninit(); let mut buf = std::mem::MaybeUninit::<Client>::uninit();
v8_inspector__Client__EXTENDER__CTOR(&mut buf); v8_inspector__V8InspectorClient__BASE__CTOR(&mut buf);
buf.assume_init() buf.assume_init()
} }
} }
fn get_extender_offset<T>() -> FieldOffset<Self> fn get_cxx_base_offset() -> FieldOffset<Client> {
let buf = std::mem::MaybeUninit::<Self>::uninit();
FieldOffset::from_ptrs(buf.as_ptr(), unsafe { &(*buf.as_ptr()).cxx_base })
}
fn get_offset_within_embedder<T>() -> FieldOffset<Self>
where where
T: ClientOverrides, T: ClientImpl,
{ {
let buf = std::mem::MaybeUninit::<T>::uninit(); let buf = std::mem::MaybeUninit::<T>::uninit();
let embedder_ptr: *const T = buf.as_ptr(); let embedder_ptr: *const T = buf.as_ptr();
let self_ptr: *const Self = unsafe { (*embedder_ptr).extender() }; let self_ptr: *const Self = unsafe { (*embedder_ptr).base() };
FieldOffset::from_ptrs(embedder_ptr, self_ptr) FieldOffset::from_ptrs(embedder_ptr, self_ptr)
} }
fn get_rust_vtable<T>() -> RustVTable<&'static dyn ClientOverrides> fn get_rust_vtable<T>() -> RustVTable<&'static dyn ClientImpl>
where where
T: ClientOverrides, T: ClientImpl,
{ {
let buf = std::mem::MaybeUninit::<T>::uninit(); let buf = std::mem::MaybeUninit::<T>::uninit();
let embedder_ptr = buf.as_ptr(); let embedder_ptr = buf.as_ptr();
let trait_object: *const dyn ClientOverrides = embedder_ptr; let trait_object: *const dyn ClientImpl = embedder_ptr;
let (data_ptr, vtable): (*const T, RustVTable<_>) = let (data_ptr, vtable): (*const T, RustVTable<_>) =
unsafe { std::mem::transmute(trait_object) }; unsafe { std::mem::transmute(trait_object) };
assert_eq!(data_ptr, embedder_ptr); assert_eq!(data_ptr, embedder_ptr);
@ -207,30 +222,25 @@ impl ClientExtender {
pub fn new<T>() -> Self pub fn new<T>() -> Self
where where
T: ClientOverrides, T: ClientImpl,
{ {
Self { Self {
cxx_client: Self::construct_cxx_client(), cxx_base: Self::construct_cxx_base(),
extender_offset: Self::get_extender_offset::<T>(), offset_within_embedder: Self::get_offset_within_embedder::<T>(),
rust_vtable: Self::get_rust_vtable::<T>(), rust_vtable: Self::get_rust_vtable::<T>(),
} }
} }
fn get_client_offset() -> FieldOffset<Client> { pub unsafe fn dispatch(client: &Client) -> &dyn ClientImpl {
let buf = std::mem::MaybeUninit::<Self>::uninit(); let this = Self::get_cxx_base_offset().to_embedder::<Self>(client);
FieldOffset::from_ptrs(buf.as_ptr(), unsafe { &(*buf.as_ptr()).cxx_client }) let embedder = this.offset_within_embedder.to_embedder::<Opaque>(this);
}
pub unsafe fn dispatch(client: &Client) -> &dyn ClientOverrides {
let this = Self::get_client_offset().to_embedder::<Self>(client);
let embedder = this.extender_offset.to_embedder::<Opaque>(this);
std::mem::transmute((embedder, this.rust_vtable)) std::mem::transmute((embedder, this.rust_vtable))
} }
pub unsafe fn dispatch_mut(client: &mut Client) -> &mut dyn ClientOverrides { pub unsafe fn dispatch_mut(client: &mut Client) -> &mut dyn ClientImpl {
let this = Self::get_client_offset().to_embedder_mut::<Self>(client); let this = Self::get_cxx_base_offset().to_embedder_mut::<Self>(client);
let vtable = this.rust_vtable; let vtable = this.rust_vtable;
let embedder = this.extender_offset.to_embedder_mut::<Opaque>(this); let embedder = this.offset_within_embedder.to_embedder_mut::<Opaque>(this);
std::mem::transmute((embedder, vtable)) std::mem::transmute((embedder, vtable))
} }
} }