2020-09-01 17:32:48 -07:00
|
|
|
#[macro_use]
|
|
|
|
|
mod macros;
|
|
|
|
|
|
|
|
|
|
pub mod attrs;
|
|
|
|
|
pub mod fun;
|
|
|
|
|
pub mod int;
|
|
|
|
|
pub mod intern;
|
|
|
|
|
pub mod names;
|
|
|
|
|
pub mod str;
|
|
|
|
|
pub mod sym;
|
2020-09-14 14:09:29 -07:00
|
|
|
#[cfg(test)]
|
|
|
|
|
mod test;
|
2020-09-01 17:32:48 -07:00
|
|
|
pub mod ty;
|
|
|
|
|
|
|
|
|
|
pub mod prelude {
|
|
|
|
|
pub use crate::obj::{attrs::*, fun::*, int::*, intern::*, str::*, sym::*, ty::*, Obj, ObjRef};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
use shredder::{Gc, Scan};
|
|
|
|
|
use std::{
|
|
|
|
|
marker::Unsize,
|
2020-09-14 14:09:29 -07:00
|
|
|
ops::{CoerceUnsized, Deref, DerefMut},
|
2020-09-01 17:32:48 -07:00
|
|
|
sync::RwLock,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
use attrs::*;
|
|
|
|
|
use sym::Sym;
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// trait Obj
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
pub trait Obj: Scan + std::fmt::Debug {
|
2020-09-14 14:09:29 -07:00
|
|
|
fn vtable(&self) -> &Vtable;
|
2020-09-01 17:32:48 -07:00
|
|
|
fn attrs(&self) -> &Attrs;
|
|
|
|
|
fn attrs_mut(&mut self) -> Option<&mut Attrs>;
|
|
|
|
|
|
2020-09-14 14:09:29 -07:00
|
|
|
fn get_attr(&self, sym: &Sym) -> Option<ObjRef> {
|
|
|
|
|
self.attrs()
|
|
|
|
|
.get(&sym)
|
|
|
|
|
.cloned()
|
|
|
|
|
.or_else(|| {
|
|
|
|
|
let vtable = self.vtable().get();
|
|
|
|
|
vtable.get(&sym).cloned()
|
|
|
|
|
})
|
2020-09-01 17:32:48 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn set_attr(&mut self, sym: Sym, value: ObjRef) -> Option<ObjRef> {
|
|
|
|
|
self.attrs_mut()?.insert(sym, value)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// struct ObjRef
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Scan)]
|
2020-09-14 14:09:29 -07:00
|
|
|
pub struct ObjRef<T = (dyn Obj + Send + Sync + 'static)>
|
|
|
|
|
where
|
|
|
|
|
T: Obj + ?Sized + Send + Sync,
|
|
|
|
|
{
|
2020-09-01 17:32:48 -07:00
|
|
|
gc: Gc<RwLock<T>>,
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-14 14:09:29 -07:00
|
|
|
impl<T> Clone for ObjRef<T>
|
|
|
|
|
where
|
|
|
|
|
T: Obj + ?Sized + Send + Sync,
|
|
|
|
|
{
|
2020-09-01 17:32:48 -07:00
|
|
|
fn clone(&self) -> Self {
|
2020-09-14 14:09:29 -07:00
|
|
|
ObjRef {
|
|
|
|
|
gc: self.gc.clone(),
|
|
|
|
|
}
|
2020-09-01 17:32:48 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// impl ObjRef
|
|
|
|
|
//
|
|
|
|
|
|
2020-09-14 14:09:29 -07:00
|
|
|
impl<T> ObjRef<T>
|
|
|
|
|
where
|
|
|
|
|
T: Obj + ?Sized + Send + Sync,
|
|
|
|
|
{
|
2020-09-01 17:32:48 -07:00
|
|
|
/// Check object reference equality.
|
|
|
|
|
pub fn ref_eq(&self, other: &Self) -> bool {
|
|
|
|
|
let lhs: &RwLock<T> = &*self.gc.get();
|
|
|
|
|
let rhs: &RwLock<T> = &*other.get();
|
|
|
|
|
std::ptr::eq::<RwLock<T>>(lhs, rhs)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-14 14:09:29 -07:00
|
|
|
impl<T> ObjRef<T>
|
|
|
|
|
where
|
|
|
|
|
T: Obj + Send + Sync + 'static,
|
|
|
|
|
{
|
2020-09-01 17:32:48 -07:00
|
|
|
pub fn new(obj: T) -> Self {
|
|
|
|
|
ObjRef {
|
|
|
|
|
gc: Gc::new(RwLock::new(obj)),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<T, U> CoerceUnsized<ObjRef<U>> for ObjRef<T>
|
|
|
|
|
where
|
|
|
|
|
T: Obj + Send + Sync + ?Sized + Unsize<U>,
|
|
|
|
|
U: Obj + Send + Sync + ?Sized,
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// impl Deref for ObjRef
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
impl<T: Obj + ?Sized + Send + Sync> Deref for ObjRef<T> {
|
|
|
|
|
type Target = Gc<RwLock<T>>;
|
|
|
|
|
|
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
|
|
|
&self.gc
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// impl DerefMut for ObjRef
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
impl<T: Obj + ?Sized + Send + Sync> DerefMut for ObjRef<T> {
|
|
|
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
|
|
|
&mut self.gc
|
|
|
|
|
}
|
|
|
|
|
}
|