mirror of
https://github.com/denoland/rusty_v8.git
synced 2025-01-11 16:42:32 -05:00
Add Task
This commit is contained in:
parent
c3f0fbbeb4
commit
9a6e90be38
11 changed files with 283 additions and 75 deletions
1
build.rs
1
build.rs
|
@ -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");
|
||||||
|
|
||||||
|
|
54
src/main.rs
54
src/main.rs
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
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 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();
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
3
src/v8/platform/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
pub mod task;
|
||||||
|
|
||||||
|
pub use task::Task;
|
32
src/v8/platform/task.cpp
Normal file
32
src/v8/platform/task.cpp
Normal 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
164
src/v8/platform/task.rs
Normal 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))
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue