parent
11c6413251
commit
b2a90ddc2c
|
|
@ -19,5 +19,5 @@ opt-level = 3
|
||||||
[profile.dev.package.graphite-wasm]
|
[profile.dev.package.graphite-wasm]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
|
|
||||||
[profile.dev]
|
#[profile.dev]
|
||||||
opt-level = 3
|
#opt-level = 3
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
use std::{
|
use std::{
|
||||||
marker::PhantomData,
|
|
||||||
mem::MaybeUninit,
|
mem::MaybeUninit,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
sync::atomic::{AtomicUsize, Ordering},
|
sync::atomic::{AtomicUsize, Ordering},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait BorrowStack {
|
use dyn_any::StaticTypeSized;
|
||||||
type Item;
|
|
||||||
|
pub trait BorrowStack<T: StaticTypeSized> {
|
||||||
/// # Safety
|
/// # Safety
|
||||||
unsafe fn push(&self, value: Self::Item);
|
unsafe fn push(&self, value: T);
|
||||||
/// # Safety
|
/// # Safety
|
||||||
unsafe fn pop(&self);
|
unsafe fn pop(&self);
|
||||||
/// # Safety
|
/// # Safety
|
||||||
unsafe fn get(&self) -> &'static [Self::Item];
|
unsafe fn get<'a>(&self) -> &'a [<T as StaticTypeSized>::Static];
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -22,11 +22,11 @@ pub struct FixedSizeStack<T: dyn_any::StaticTypeSized> {
|
||||||
len: AtomicUsize,
|
len: AtomicUsize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'n, T: Unpin + 'n + dyn_any::StaticTypeSized> FixedSizeStack<T> {
|
impl<'n, T: 'n + dyn_any::StaticTypeSized> FixedSizeStack<T> {
|
||||||
pub fn new(capacity: usize) -> Self {
|
pub fn new(capacity: usize) -> Self {
|
||||||
let layout = std::alloc::Layout::array::<MaybeUninit<T>>(capacity).unwrap();
|
let layout = std::alloc::Layout::array::<MaybeUninit<T>>(capacity).unwrap();
|
||||||
let array = unsafe { std::alloc::alloc(layout) };
|
let array = unsafe { std::alloc::alloc(layout) };
|
||||||
let array = Pin::new(unsafe { Box::from_raw(std::slice::from_raw_parts_mut(array as *mut MaybeUninit<T>, capacity) as *mut [MaybeUninit<T>]) });
|
let array = Box::into_pin(unsafe { Box::from_raw(std::slice::from_raw_parts_mut(array as *mut MaybeUninit<T>, capacity) as *mut [MaybeUninit<T>]) });
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
data: array,
|
data: array,
|
||||||
|
|
@ -42,19 +42,20 @@ impl<'n, T: Unpin + 'n + dyn_any::StaticTypeSized> FixedSizeStack<T> {
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.len.load(Ordering::SeqCst) == 0
|
self.len.load(Ordering::SeqCst) == 0
|
||||||
}
|
}
|
||||||
pub fn push_fn(&self, f: impl FnOnce(&'static [T::Static]) -> T) {
|
pub fn push_fn<'a>(&self, f: impl FnOnce(&'a [T::Static]) -> T) {
|
||||||
unsafe { self.push(std::mem::transmute_copy(&f(self.get()))) }
|
assert_eq!(std::mem::size_of::<T>(), std::mem::size_of::<T::Static>());
|
||||||
|
unsafe { self.push(f(self.get())) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'n, T: 'n + dyn_any::StaticTypeSized> BorrowStack for FixedSizeStack<T> {
|
impl<T: dyn_any::StaticTypeSized> BorrowStack<T> for FixedSizeStack<T> {
|
||||||
type Item = T::Static;
|
unsafe fn push(&self, value: T) {
|
||||||
|
|
||||||
unsafe fn push(&self, value: Self::Item) {
|
|
||||||
let len = self.len.load(Ordering::SeqCst);
|
let len = self.len.load(Ordering::SeqCst);
|
||||||
assert!(len < self.capacity);
|
assert!(len < self.capacity);
|
||||||
let ptr = self.data[len].as_ptr();
|
let ptr = self.data[len].as_ptr();
|
||||||
(ptr as *mut T::Static).write(value);
|
let static_value = std::mem::transmute_copy(&value);
|
||||||
|
(ptr as *mut T::Static).write(static_value);
|
||||||
|
std::mem::forget(value);
|
||||||
self.len.fetch_add(1, Ordering::SeqCst);
|
self.len.fetch_add(1, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,7 +65,7 @@ impl<'n, T: 'n + dyn_any::StaticTypeSized> BorrowStack for FixedSizeStack<T> {
|
||||||
self.len.fetch_sub(1, Ordering::SeqCst);
|
self.len.fetch_sub(1, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn get(&self) -> &'static [Self::Item] {
|
unsafe fn get<'a>(&self) -> &'a [T::Static] {
|
||||||
std::slice::from_raw_parts(self.data.as_ptr() as *const T::Static, self.len.load(Ordering::SeqCst))
|
std::slice::from_raw_parts(self.data.as_ptr() as *const T::Static, self.len.load(Ordering::SeqCst))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ where
|
||||||
|
|
||||||
impl<'n, N: 'n, I> AsRefNode<'n, I> for N
|
impl<'n, N: 'n, I> AsRefNode<'n, I> for N
|
||||||
where
|
where
|
||||||
&'n N: Node<I, Output = N::Output>,
|
&'n N: Node<I>,
|
||||||
N: Node<I>,
|
N: Node<I>,
|
||||||
Self: 'n,
|
Self: 'n,
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
#![feature(trait_upcasting)]
|
||||||
pub mod node_registry;
|
pub mod node_registry;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
@ -17,7 +18,7 @@ mod tests {
|
||||||
fn borrow_stack() {
|
fn borrow_stack() {
|
||||||
let stack = borrow_stack::FixedSizeStack::new(256);
|
let stack = borrow_stack::FixedSizeStack::new(256);
|
||||||
unsafe {
|
unsafe {
|
||||||
let dynanynode: DynAnyNode<_, (), _, _> = DynAnyNode::new(ValueNode(2_u32));
|
let dynanynode: DynAnyNode<ValueNode<u32>, (), _, _> = DynAnyNode::new(ValueNode(2_u32));
|
||||||
stack.push(dynanynode.into_box());
|
stack.push(dynanynode.into_box());
|
||||||
}
|
}
|
||||||
stack.push_fn(|nodes| {
|
stack.push_fn(|nodes| {
|
||||||
|
|
@ -26,6 +27,7 @@ mod tests {
|
||||||
let dynanynode: DynAnyNode<ConsNode<_, Any<'_>>, u32, _, _> = DynAnyNode::new(ConsNode(downcast, PhantomData));
|
let dynanynode: DynAnyNode<ConsNode<_, Any<'_>>, u32, _, _> = DynAnyNode::new(ConsNode(downcast, PhantomData));
|
||||||
dynanynode.into_box()
|
dynanynode.into_box()
|
||||||
});
|
});
|
||||||
|
/*
|
||||||
stack.push_fn(|_| {
|
stack.push_fn(|_| {
|
||||||
let dynanynode: DynAnyNode<_, (u32, &u32), _, _> = DynAnyNode::new(AddNode);
|
let dynanynode: DynAnyNode<_, (u32, &u32), _, _> = DynAnyNode::new(AddNode);
|
||||||
dynanynode.into_box()
|
dynanynode.into_box()
|
||||||
|
|
@ -33,15 +35,18 @@ mod tests {
|
||||||
stack.push_fn(|nodes| {
|
stack.push_fn(|nodes| {
|
||||||
let compose_node = nodes[1].after(&nodes[2]);
|
let compose_node = nodes[1].after(&nodes[2]);
|
||||||
TypeErasedNode(Box::new(compose_node))
|
TypeErasedNode(Box::new(compose_node))
|
||||||
});
|
});}*/
|
||||||
|
|
||||||
|
let result = unsafe { &stack.get()[0] }.eval_ref(().into_dyn());
|
||||||
|
assert_eq!(*downcast::<&u32>(result).unwrap(), &2_u32);
|
||||||
let result = unsafe { &stack.get()[1] }.eval_ref(4_u32.into_dyn());
|
let result = unsafe { &stack.get()[1] }.eval_ref(4_u32.into_dyn());
|
||||||
assert_eq!(*downcast::<(u32, &u32)>(result).unwrap(), (4_u32, &2_u32));
|
assert_eq!(*downcast::<(u32, &u32)>(result).unwrap(), (4_u32, &2_u32));
|
||||||
|
/*
|
||||||
let result = unsafe { &stack.get()[1] }.eval_ref(4_u32.into_dyn());
|
let result = unsafe { &stack.get()[1] }.eval_ref(4_u32.into_dyn());
|
||||||
let add = unsafe { &stack.get()[2] }.eval_ref(result);
|
let add = unsafe { &stack.get()[2] }.eval_ref(result);
|
||||||
assert_eq!(*downcast::<u32>(add).unwrap(), 6_u32);
|
assert_eq!(*downcast::<u32>(add).unwrap(), 6_u32);
|
||||||
let add = unsafe { &stack.get()[3] }.eval_ref(4_u32.into_dyn());
|
let add = unsafe { &stack.get()[3] }.eval_ref(4_u32.into_dyn());
|
||||||
assert_eq!(*downcast::<u32>(add).unwrap(), 6_u32);
|
assert_eq!(*downcast::<u32>(add).unwrap(), 6_u32);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use borrow_stack::FixedSizeStack;
|
use borrow_stack::FixedSizeStack;
|
||||||
|
use dyn_clone::DynClone;
|
||||||
|
use graphene_core::generic::FnNode;
|
||||||
use graphene_core::ops::{AddNode, IdNode};
|
use graphene_core::ops::{AddNode, IdNode};
|
||||||
use graphene_core::structural::{ConsNode, Then};
|
use graphene_core::structural::{ConsNode, Then};
|
||||||
use graphene_core::{AsRefNode, Node};
|
use graphene_core::{AsRefNode, Node};
|
||||||
|
|
@ -14,40 +16,6 @@ struct NodeIdentifier {
|
||||||
types: &'static [&'static str],
|
types: &'static [&'static str],
|
||||||
}
|
}
|
||||||
|
|
||||||
const fn annotate<'n, 's: 'n, F>(f: F) -> F
|
|
||||||
where
|
|
||||||
F: Fn(ProtoNode, FixedSizeStack<TypeErasedNode<'n>>),
|
|
||||||
{
|
|
||||||
f
|
|
||||||
}
|
|
||||||
|
|
||||||
use borrow_stack::BorrowStack;
|
|
||||||
unsafe fn foo<'n>(proto_node: ProtoNode, stack: &'n FixedSizeStack<TypeErasedNode<'n>>) {
|
|
||||||
let node_id = proto_node.input.unwrap_node() as usize;
|
|
||||||
let nodes = stack.get();
|
|
||||||
let pre_node = nodes.get(node_id).unwrap();
|
|
||||||
let downcast: DowncastNode<_, &u32> = DowncastNode::new(pre_node);
|
|
||||||
let dynanynode: DynAnyNode<ConsNode<_, Any<'_>>, u32, _, _> = DynAnyNode::new(ConsNode(downcast, PhantomData));
|
|
||||||
stack.push(dynanynode.into_box());
|
|
||||||
}
|
|
||||||
fn borrow_stack() {
|
|
||||||
let stack = borrow_stack::FixedSizeStack::new(256);
|
|
||||||
unsafe {
|
|
||||||
{
|
|
||||||
let proto_node = ProtoNode::id();
|
|
||||||
foo(proto_node, &stack);
|
|
||||||
let proto_node = ProtoNode::id();
|
|
||||||
let stack = &stack;
|
|
||||||
let node_id = proto_node.input.unwrap_node() as usize;
|
|
||||||
let nodes = stack.get();
|
|
||||||
let pre_node = nodes.get(node_id).unwrap();
|
|
||||||
let downcast: DowncastNode<&TypeErasedNode, &u32> = DowncastNode::new(pre_node);
|
|
||||||
let dynanynode: DynAnyNode<ConsNode<_, Any<'_>>, u32, _, _> = DynAnyNode::new(ConsNode(downcast, PhantomData));
|
|
||||||
stack.push(dynanynode.into_box());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static NODE_REGISTRY: &[(NodeIdentifier, fn(ProtoNode, &FixedSizeStack<TypeErasedNode<'static>>))] = &[
|
static NODE_REGISTRY: &[(NodeIdentifier, fn(ProtoNode, &FixedSizeStack<TypeErasedNode<'static>>))] = &[
|
||||||
(
|
(
|
||||||
NodeIdentifier {
|
NodeIdentifier {
|
||||||
|
|
@ -77,7 +45,7 @@ static NODE_REGISTRY: &[(NodeIdentifier, fn(ProtoNode, &FixedSizeStack<TypeErase
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
/*(
|
(
|
||||||
NodeIdentifier {
|
NodeIdentifier {
|
||||||
name: "graphene_core::structural::ConsNode",
|
name: "graphene_core::structural::ConsNode",
|
||||||
types: &["&TypeErasedNode", "&u32", "u32"],
|
types: &["&TypeErasedNode", "&u32", "u32"],
|
||||||
|
|
@ -87,11 +55,11 @@ static NODE_REGISTRY: &[(NodeIdentifier, fn(ProtoNode, &FixedSizeStack<TypeErase
|
||||||
stack.push_fn(move |nodes| {
|
stack.push_fn(move |nodes| {
|
||||||
let pre_node = nodes.get(node_id).unwrap();
|
let pre_node = nodes.get(node_id).unwrap();
|
||||||
let downcast: DowncastNode<_, &u32> = DowncastNode::new(pre_node);
|
let downcast: DowncastNode<_, &u32> = DowncastNode::new(pre_node);
|
||||||
let dynanynode: DynAnyNode<ConsNode<_, Any<'_>>, u32, _, _> = DynAnyNode::new(ConsNode(downcast, PhantomData));
|
let dynanynode: DynAnyNode<_, u32, _, _> = DynAnyNode::new(ConsNode(downcast, PhantomData));
|
||||||
dynanynode.into_box()
|
dynanynode.into_box()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
),*/
|
),
|
||||||
(
|
(
|
||||||
NodeIdentifier {
|
NodeIdentifier {
|
||||||
name: "graphene_core::any::DowncastNode",
|
name: "graphene_core::any::DowncastNode",
|
||||||
|
|
@ -105,6 +73,22 @@ static NODE_REGISTRY: &[(NodeIdentifier, fn(ProtoNode, &FixedSizeStack<TypeErase
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
NodeIdentifier {
|
||||||
|
name: "graphene_core::value::ValueNode",
|
||||||
|
types: &["Any<'n>"],
|
||||||
|
},
|
||||||
|
|proto_node, stack| {
|
||||||
|
stack.push_fn(|nodes| {
|
||||||
|
if let ConstructionArgs::Value(value) = proto_node.construction_args {
|
||||||
|
let node = FnNode::new(move |_| value.clone() as Any<'static>);
|
||||||
|
node.into_type_erased()
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ use std::fmt::Display;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
use dyn_any::{DynAny, StaticType};
|
use dyn_any::{DynAny, StaticType};
|
||||||
|
use dyn_clone::DynClone;
|
||||||
use rand_chacha::{
|
use rand_chacha::{
|
||||||
rand_core::{RngCore, SeedableRng},
|
rand_core::{RngCore, SeedableRng},
|
||||||
ChaCha20Rng,
|
ChaCha20Rng,
|
||||||
|
|
@ -119,14 +120,14 @@ pub struct NodeNetwork {
|
||||||
pub nodes: HashMap<NodeId, DocumentNode>,
|
pub nodes: HashMap<NodeId, DocumentNode>,
|
||||||
}
|
}
|
||||||
pub type Value = Box<dyn ValueTrait>;
|
pub type Value = Box<dyn ValueTrait>;
|
||||||
pub trait ValueTrait: DynAny<'static> + std::fmt::Debug {}
|
pub trait ValueTrait: DynAny<'static> + std::fmt::Debug + DynClone {}
|
||||||
|
|
||||||
pub trait IntoValue: Sized + ValueTrait + 'static {
|
pub trait IntoValue: Sized + ValueTrait + 'static {
|
||||||
fn into_any(self) -> Value {
|
fn into_any(self) -> Value {
|
||||||
Box::new(self)
|
Box::new(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<T: 'static + StaticType + std::fmt::Debug + PartialEq> ValueTrait for T {}
|
impl<T: 'static + StaticType + std::fmt::Debug + PartialEq + Clone> ValueTrait for T {}
|
||||||
impl<T: 'static + ValueTrait> IntoValue for T {}
|
impl<T: 'static + ValueTrait> IntoValue for T {}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
|
@ -156,6 +157,20 @@ impl PartialEq for Box<dyn ValueTrait> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Clone for Value {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
let self_trait_object = unsafe { std::mem::transmute::<&dyn ValueTrait, TraitObject>(self.as_ref()) };
|
||||||
|
let size = self_trait_object.vtable.size;
|
||||||
|
let self_mem = unsafe { std::slice::from_raw_parts(self_trait_object.self_ptr, size) }.to_owned();
|
||||||
|
let ptr = Vec::leak(self_mem);
|
||||||
|
unsafe {
|
||||||
|
std::mem::transmute(TraitObject {
|
||||||
|
self_ptr: ptr as *mut [u8] as *mut u8,
|
||||||
|
vtable: self_trait_object.vtable,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub enum ConstructionArgs {
|
pub enum ConstructionArgs {
|
||||||
None,
|
None,
|
||||||
|
|
|
||||||
|
|
@ -111,8 +111,8 @@ impl<'a> IntoIterator for &'a Image {
|
||||||
|
|
||||||
pub fn file_node<'n, P: AsRef<Path> + 'n>() -> impl Node<P, Output = Result<Vec<u8>, Error>> {
|
pub fn file_node<'n, P: AsRef<Path> + 'n>() -> impl Node<P, Output = Result<Vec<u8>, Error>> {
|
||||||
let fs = ValueNode(StdFs).clone();
|
let fs = ValueNode(StdFs).clone();
|
||||||
let fs = ConsNode(fs, PhantomData);
|
let fs = ConsNode::new(fs);
|
||||||
let file: ComposeNode<_, _, P> = fs.then(FileNode(PhantomData));
|
let file = fs.then(FileNode(PhantomData));
|
||||||
|
|
||||||
file.then(FlatMapResultNode::new(BufferNode))
|
file.then(FlatMapResultNode::new(BufferNode))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue