0
0
Fork 0
mirror of https://github.com/denoland/rusty_v8.git synced 2025-01-11 16:42:32 -05:00
This commit is contained in:
Bert Belder 2019-10-22 14:52:43 -07:00
parent c3f0fbbeb4
commit 9a6e90be38
No known key found for this signature in database
GPG key ID: 7A77887B2E2ED461
11 changed files with 283 additions and 75 deletions

View file

@ -7,6 +7,7 @@ fn main() {
.debug(true) .debug(true)
.file("src/v8/inspector/channel.cpp") .file("src/v8/inspector/channel.cpp")
.file("src/v8/inspector/client.cpp") .file("src/v8/inspector/client.cpp")
.file("src/v8/platform/task.cpp")
.file("src/v8/string_buffer.cpp") .file("src/v8/string_buffer.cpp")
.compile("v8-bindings"); .compile("v8-bindings");

View file

@ -7,15 +7,16 @@ mod v8;
mod example { mod example {
use crate::support::UniquePtr; use crate::support::UniquePtr;
use crate::v8::inspector::channel::*; use crate::v8::inspector::channel::*;
use crate::v8::platform::task::*;
use crate::v8::*; use crate::v8::*;
pub struct Example { pub struct TestChannel {
a: i32, a: i32,
channel_base: ChannelBase, channel_base: ChannelBase,
b: i32, b: i32,
} }
impl ChannelImpl for Example { impl ChannelImpl for TestChannel {
fn base(&self) -> &ChannelBase { fn base(&self) -> &ChannelBase {
&self.channel_base &self.channel_base
} }
@ -37,7 +38,7 @@ mod example {
fn flushProtocolNotifications(&mut self) {} fn flushProtocolNotifications(&mut self) {}
} }
impl Example { impl TestChannel {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
channel_base: ChannelBase::new::<Self>(), channel_base: ChannelBase::new::<Self>(),
@ -46,16 +47,59 @@ mod example {
} }
} }
} }
pub struct TestTask {
a: i32,
base: TaskBase,
b: i32,
}
impl TaskImpl for TestTask {
fn base(&self) -> &TaskBase {
&self.base
}
fn base_mut(&mut self) -> &mut TaskBase {
&mut self.base
}
fn Run(&mut self) -> () {
println!("TestTask::Run {} {}", self.a, self.b);
}
}
impl TestTask {
pub fn new() -> Self {
Self {
base: TaskBase::new::<Self>(),
a: 2,
b: 3,
}
}
}
impl Drop for TestTask {
fn drop(&mut self) {
println!("TestTask::drop()");
}
}
} }
fn main() { fn main1() {
use crate::v8::inspector::channel::*; use crate::v8::inspector::channel::*;
use crate::v8::*; use crate::v8::*;
use example::*; use example::*;
let mut ex = Example::new(); let mut ex = TestChannel::new();
let chan = ex.as_channel_mut(); let chan = ex.as_channel_mut();
let message = b"hello"; let message = b"hello";
let message = StringView::from(&message[..]); let message = StringView::from(&message[..]);
let message = StringBuffer::create(&message); let message = StringBuffer::create(&message);
chan.sendResponse(3, message); chan.sendResponse(3, message);
} }
fn main() {
use crate::v8::platform::task::*;
use example::*;
let mut v = TestTask::new();
v.Run();
let b = Box::new(v);
b.into_unique_ptr();
}

View file

@ -1,6 +1,8 @@
use std::marker::PhantomData; use std::marker::PhantomData;
use std::mem::size_of; use std::mem::size_of;
use std::ops::{Deref, DerefMut}; use std::mem::transmute;
use std::ops::Deref;
use std::ops::DerefMut;
pub use std::os::raw::c_int as int; pub use std::os::raw::c_int as int;
@ -20,6 +22,23 @@ pub struct UniquePtr<T>(Option<&'static mut T>)
where where
T: Delete; T: Delete;
impl<T> UniquePtr<T>
where
T: Delete,
{
pub fn null() -> Self {
Self(None)
}
pub fn new(r: &'static mut T) -> Self {
Self(Some(r))
}
pub unsafe fn from_raw(p: *mut T) -> Self {
transmute(p)
}
}
impl<T> Deref for UniquePtr<T> impl<T> Deref for UniquePtr<T>
where where
T: Delete, T: Delete,
@ -48,42 +67,6 @@ where
} }
} }
/// Reference to object allocated on the C++ heap, similar to UniquePtr<T>,
/// but guaranteed to never contain a nullptr.
#[repr(transparent)]
pub struct UniqueRef<T>(&'static mut T)
where
T: Delete;
impl<T> Deref for UniqueRef<T>
where
T: Delete,
{
type Target = T;
fn deref(&self) -> &Self::Target {
self.0
}
}
impl<T> DerefMut for UniqueRef<T>
where
T: Delete,
{
fn deref_mut(&mut self) -> &mut Self::Target {
self.0
}
}
impl<T> Drop for UniqueRef<T>
where
T: Delete,
{
fn drop(&mut self) {
let ptr: &'static mut T = unsafe { std::mem::transmute_copy(self.0) };
ptr.delete();
}
}
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
#[repr(transparent)] #[repr(transparent)]
pub struct CxxVTable(pub *const Opaque); pub struct CxxVTable(pub *const Opaque);

View file

@ -19,28 +19,25 @@ void v8_inspector__V8Inspector__Channel__BASE__flushProtocolNotifications(
struct v8_inspector__V8Inspector__Channel__BASE : public V8Inspector::Channel { struct v8_inspector__V8Inspector__Channel__BASE : public V8Inspector::Channel {
using V8Inspector::Channel::Channel; using V8Inspector::Channel::Channel;
inline void sendResponse(int callId, void sendResponse(int callId,
std::unique_ptr<StringBuffer> message) override { std::unique_ptr<StringBuffer> message) override {
v8_inspector__V8Inspector__Channel__BASE__sendResponse(*this, callId, v8_inspector__V8Inspector__Channel__BASE__sendResponse(*this, callId,
message.release()); message.release());
} }
inline void sendNotification(std::unique_ptr<StringBuffer> message) override { void sendNotification(std::unique_ptr<StringBuffer> message) override {
v8_inspector__V8Inspector__Channel__BASE__sendNotification( v8_inspector__V8Inspector__Channel__BASE__sendNotification(
*this, message.release()); *this, message.release());
} }
inline void flushProtocolNotifications() override { void flushProtocolNotifications() override {
v8_inspector__V8Inspector__Channel__BASE__flushProtocolNotifications(*this); v8_inspector__V8Inspector__Channel__BASE__flushProtocolNotifications(*this);
} }
}; };
extern "C" { extern "C" {
void v8_inspector__V8Inspector__Channel__BASE__CTOR( void v8_inspector__V8Inspector__Channel__BASE__CONSTRUCT(
uninit_t<v8_inspector__V8Inspector__Channel__BASE>& buf) { uninit_t<v8_inspector__V8Inspector__Channel__BASE>& buf) {
construct_in_place<v8_inspector__V8Inspector__Channel__BASE>(buf); construct_in_place<v8_inspector__V8Inspector__Channel__BASE>(buf);
} }
void v8_inspector__V8Inspector__Channel__DTOR(V8Inspector::Channel& self) {
self.~Channel();
}
void v8_inspector__V8Inspector__Channel__sendResponse( void v8_inspector__V8Inspector__Channel__sendResponse(
V8Inspector::Channel& self, V8Inspector::Channel& self,

View file

@ -16,10 +16,9 @@ use crate::v8::StringBuffer;
// }; // };
extern "C" { extern "C" {
fn v8_inspector__V8Inspector__Channel__BASE__CTOR( fn v8_inspector__V8Inspector__Channel__BASE__CONSTRUCT(
buf: &mut std::mem::MaybeUninit<Channel>, buf: &mut std::mem::MaybeUninit<Channel>,
) -> (); ) -> ();
fn v8_inspector__V8Inspector__Channel__DTOR(this: &mut Channel) -> ();
fn v8_inspector__V8Inspector__Channel__sendResponse( fn v8_inspector__V8Inspector__Channel__sendResponse(
this: &mut Channel, this: &mut Channel,
@ -86,12 +85,6 @@ impl Channel {
} }
} }
impl Drop for Channel {
fn drop(&mut self) {
unsafe { v8_inspector__V8Inspector__Channel__DTOR(self) }
}
}
pub trait AsChannel { pub trait AsChannel {
fn as_channel(&self) -> &Channel; fn as_channel(&self) -> &Channel;
fn as_channel_mut(&mut self) -> &mut Channel; fn as_channel_mut(&mut self) -> &mut Channel;
@ -141,7 +134,7 @@ impl ChannelBase {
fn construct_cxx_base() -> 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__V8Inspector__Channel__BASE__CTOR(&mut buf); v8_inspector__V8Inspector__Channel__BASE__CONSTRUCT(&mut buf);
buf.assume_init() buf.assume_init()
} }
} }

View file

@ -18,27 +18,24 @@ void v8_inspector__V8InspectorClient__BASE__runIfWaitingForDebugger(
struct v8_inspector__V8InspectorClient__BASE : public V8InspectorClient { struct v8_inspector__V8InspectorClient__BASE : public V8InspectorClient {
using V8InspectorClient::V8InspectorClient; using V8InspectorClient::V8InspectorClient;
inline void runMessageLoopOnPause(int contextGroupId) override { void runMessageLoopOnPause(int contextGroupId) override {
v8_inspector__V8InspectorClient__BASE__runMessageLoopOnPause( v8_inspector__V8InspectorClient__BASE__runMessageLoopOnPause(
*this, contextGroupId); *this, contextGroupId);
} }
inline void quitMessageLoopOnPause() override { void quitMessageLoopOnPause() override {
v8_inspector__V8InspectorClient__BASE__quitMessageLoopOnPause(*this); v8_inspector__V8InspectorClient__BASE__quitMessageLoopOnPause(*this);
} }
inline void runIfWaitingForDebugger(int contextGroupId) override { void runIfWaitingForDebugger(int contextGroupId) override {
v8_inspector__V8InspectorClient__BASE__runIfWaitingForDebugger( v8_inspector__V8InspectorClient__BASE__runIfWaitingForDebugger(
*this, contextGroupId); *this, contextGroupId);
} }
}; };
extern "C" { extern "C" {
void v8_inspector__V8InspectorClient__BASE__CTOR( void v8_inspector__V8InspectorClient__BASE__CONSTRUCT(
uninit_t<v8_inspector__V8InspectorClient__BASE>& buf) { uninit_t<v8_inspector__V8InspectorClient__BASE>& buf) {
construct_in_place<v8_inspector__V8InspectorClient__BASE>(buf); construct_in_place<v8_inspector__V8InspectorClient__BASE>(buf);
} }
void v8_inspector__V8InspectorClient__DTOR(V8InspectorClient& self) {
self.~V8InspectorClient();
}
void v8_inspector__V8InspectorClient__runMessageLoopOnPause( void v8_inspector__V8InspectorClient__runMessageLoopOnPause(
V8InspectorClient& self, V8InspectorClient& self,

View file

@ -67,10 +67,9 @@ use crate::support::RustVTable;
// }; // };
extern "C" { extern "C" {
fn v8_inspector__V8InspectorClient__BASE__CTOR( fn v8_inspector__V8InspectorClient__BASE__CONSTRUCT(
buf: &mut std::mem::MaybeUninit<Client>, buf: &mut std::mem::MaybeUninit<Client>,
) -> (); ) -> ();
fn v8_inspector__V8InspectorClient__DTOR(this: &mut Client) -> ();
fn v8_inspector__V8InspectorClient__runMessageLoopOnPause( fn v8_inspector__V8InspectorClient__runMessageLoopOnPause(
this: &mut Client, this: &mut Client,
@ -135,12 +134,6 @@ impl Client {
} }
} }
impl Drop for Client {
fn drop(&mut self) {
unsafe { v8_inspector__V8InspectorClient__DTOR(self) }
}
}
pub trait AsClient { pub trait AsClient {
fn as_client(&self) -> &Client; fn as_client(&self) -> &Client;
fn as_client_mut(&mut self) -> &mut Client; fn as_client_mut(&mut self) -> &mut Client;
@ -187,7 +180,7 @@ impl ClientBase {
fn construct_cxx_base() -> 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__V8InspectorClient__BASE__CTOR(&mut buf); v8_inspector__V8InspectorClient__BASE__CONSTRUCT(&mut buf);
buf.assume_init() buf.assume_init()
} }
} }

View file

@ -1,4 +1,5 @@
pub mod inspector; pub mod inspector;
pub mod platform;
pub mod string_buffer; pub mod string_buffer;
pub mod string_view; pub mod string_view;

3
src/v8/platform/mod.rs Normal file
View file

@ -0,0 +1,3 @@
pub mod task;
pub use task::Task;

32
src/v8/platform/task.cpp Normal file
View file

@ -0,0 +1,32 @@
#include "../../../v8/include/v8-platform.h"
#include "../../support.h"
#include <iostream>
using namespace v8;
using namespace support;
extern "C" {
void v8__Task__BASE__DELETE(Task& self);
void v8__Task__BASE__Run(Task& self);
} // extern "C"
struct v8__Task__BASE : public Task {
using Task::Task;
void operator delete(void* ptr) noexcept {
v8__Task__BASE__DELETE(*reinterpret_cast<Task*>(ptr));
}
void Run() override { v8__Task__BASE__Run(*this); }
};
extern "C" {
void v8__Task__BASE__CONSTRUCT(uninit_t<v8__Task__BASE>& buf) {
construct_in_place<v8__Task__BASE>(buf);
}
void v8__Task__DELETE(Task& self) {
delete &self;
}
void v8__Task__Run(Task& self) {
self.Run();
}
} // extern "C"

164
src/v8/platform/task.rs Normal file
View file

@ -0,0 +1,164 @@
use std::mem::drop;
use std::mem::forget;
use crate::support::CxxVTable;
use crate::support::Delete;
use crate::support::FieldOffset;
use crate::support::Opaque;
use crate::support::RustVTable;
use crate::support::UniquePtr;
// class Task {
// public:
// virtual ~Task() = default;
// virtual void Run() = 0;
// };
extern "C" {
fn v8__Task__BASE__CONSTRUCT(buf: &mut std::mem::MaybeUninit<Task>) -> ();
fn v8__Task__DELETE(this: &'static mut Task) -> ();
fn v8__Task__Run(this: &mut Task) -> ();
}
#[no_mangle]
pub unsafe extern "C" fn v8__Task__BASE__DELETE(this: &mut Task) -> () {
println!("v8__Task__BASE__DELETE");
drop(TaskBase::dispatch_box(this))
}
#[no_mangle]
pub unsafe extern "C" fn v8__Task__BASE__Run(this: &mut Task) -> () {
TaskBase::dispatch_mut(this).Run()
}
#[repr(C)]
pub struct Task {
_cxx_vtable: CxxVTable,
}
impl Task {
pub fn Run(&mut self) -> () {
unsafe { v8__Task__Run(self) }
}
}
impl Delete for Task {
fn delete(&'static mut self) {
println!("Task::delete()");
unsafe { v8__Task__DELETE(self) }
}
}
pub trait AsTask {
fn as_task(&self) -> &Task;
fn as_task_mut(&mut self) -> &mut Task;
// TODO: this should be a trait in itself.
fn into_unique_ptr(mut self: Box<Self>) -> UniquePtr<Task>
where
Self: 'static,
{
let task = self.as_task_mut() as *mut Task;
forget(self);
unsafe { UniquePtr::from_raw(task) }
}
}
impl AsTask for Task {
fn as_task(&self) -> &Task {
self
}
fn as_task_mut(&mut self) -> &mut Task {
self
}
}
impl<T> AsTask for T
where
T: TaskImpl,
{
fn as_task(&self) -> &Task {
&self.base().cxx_base
}
fn as_task_mut(&mut self) -> &mut Task {
&mut self.base_mut().cxx_base
}
}
pub trait TaskImpl: AsTask {
fn base(&self) -> &TaskBase;
fn base_mut(&mut self) -> &mut TaskBase;
fn Run(&mut self) -> ();
}
pub struct TaskBase {
cxx_base: Task,
offset_within_embedder: FieldOffset<Self>,
rust_vtable: RustVTable<&'static dyn TaskImpl>,
}
impl TaskBase {
fn construct_cxx_base() -> Task {
unsafe {
let mut buf = std::mem::MaybeUninit::<Task>::uninit();
v8__Task__BASE__CONSTRUCT(&mut buf);
buf.assume_init()
}
}
fn get_cxx_base_offset() -> FieldOffset<Task> {
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
T: TaskImpl,
{
let buf = std::mem::MaybeUninit::<T>::uninit();
let embedder_ptr: *const T = buf.as_ptr();
let self_ptr: *const Self = unsafe { (*embedder_ptr).base() };
FieldOffset::from_ptrs(embedder_ptr, self_ptr)
}
fn get_rust_vtable<T>() -> RustVTable<&'static dyn TaskImpl>
where
T: TaskImpl,
{
let buf = std::mem::MaybeUninit::<T>::uninit();
let embedder_ptr = buf.as_ptr();
let trait_object: *const dyn TaskImpl = embedder_ptr;
let (data_ptr, vtable): (*const T, RustVTable<_>) =
unsafe { std::mem::transmute(trait_object) };
assert_eq!(data_ptr, embedder_ptr);
vtable
}
pub fn new<T>() -> Self
where
T: TaskImpl,
{
Self {
cxx_base: Self::construct_cxx_base(),
offset_within_embedder: Self::get_offset_within_embedder::<T>(),
rust_vtable: Self::get_rust_vtable::<T>(),
}
}
pub unsafe fn dispatch(task: &Task) -> &dyn TaskImpl {
let this = Self::get_cxx_base_offset().to_embedder::<Self>(task);
let embedder = this.offset_within_embedder.to_embedder::<Opaque>(this);
std::mem::transmute((embedder, this.rust_vtable))
}
pub unsafe fn dispatch_mut(task: &mut Task) -> &mut dyn TaskImpl {
let this = Self::get_cxx_base_offset().to_embedder_mut::<Self>(task);
let vtable = this.rust_vtable;
let embedder = this.offset_within_embedder.to_embedder_mut::<Opaque>(this);
std::mem::transmute((embedder, vtable))
}
pub unsafe fn dispatch_box(task: &mut Task) -> Box<dyn TaskImpl> {
std::mem::transmute(Self::dispatch_mut(task))
}
}