Use raw pointers

This commit is contained in:
Aleksey Kladov 2018-07-30 02:23:01 +03:00
parent b87291a8a4
commit 4e79073e38
3 changed files with 15 additions and 45 deletions

View File

@ -3,10 +3,6 @@ mod red;
mod syntax;
mod builder;
use std::{
sync::{Arc, Weak},
mem
};
pub(crate) use self::{
green::{GreenNode, GreenNodeBuilder},
red::RedNode,
@ -14,30 +10,3 @@ pub(crate) use self::{
builder::GreenBuilder,
};
pub use self::syntax::SyntaxNode;
// This could be just `*const T`, but we use `Weak` for additional checks
#[derive(Debug)]
pub(crate) struct Ptr<T>(Weak<T>);
impl<T> Clone for Ptr<T> {
fn clone(&self) -> Self {
Ptr(self.0.clone())
}
}
impl<T> Ptr<T> {
fn clone(self_: &Ptr<T>) -> Ptr<T> {
Ptr(Weak::clone(&self_.0))
}
fn new(arc: &Arc<T>) -> Ptr<T> {
Ptr(Arc::downgrade(arc))
}
unsafe fn get(&self) -> &T {
let t = self.0.upgrade()
.expect("caller must guarantee that Ptr is not null");
let t: &T = &*t;
mem::transmute(t)
}
}

View File

@ -1,7 +1,7 @@
use std::sync::{Arc, RwLock};
use {
TextUnit,
yellow::{Ptr, GreenNode},
yellow::GreenNode,
};
#[derive(Debug)]
@ -13,7 +13,7 @@ pub(crate) struct RedNode {
#[derive(Debug)]
struct ParentData {
parent: Ptr<RedNode>,
parent: *const RedNode,
start_offset: TextUnit,
index_in_parent: usize,
}
@ -27,7 +27,7 @@ impl RedNode {
fn new_child(
green: GreenNode,
parent: Ptr<RedNode>,
parent: *const RedNode,
start_offset: TextUnit,
index_in_parent: usize,
) -> RedNode {
@ -62,7 +62,7 @@ impl RedNode {
self.green.children().len()
}
pub(crate) fn nth_child(&self, me: Ptr<RedNode>, idx: usize) -> Arc<RedNode> {
pub(crate) fn nth_child(&self, idx: usize) -> Arc<RedNode> {
match &self.children.read().unwrap()[idx] {
Some(child) => return child.clone(),
None => (),
@ -72,7 +72,7 @@ impl RedNode {
let green_children = self.green.children();
let start_offset = self.start_offset()
+ green_children[..idx].iter().map(|x| x.text_len()).sum::<TextUnit>();
let child = RedNode::new_child(green_children[idx].clone(), me, start_offset, idx);
let child = RedNode::new_child(green_children[idx].clone(), self, start_offset, idx);
children[idx] = Some(Arc::new(child))
}
children[idx].as_ref().unwrap().clone()

View File

@ -1,18 +1,20 @@
use std::{
fmt,
sync::Arc,
ptr
};
use {
TextRange, TextUnit,
SyntaxKind::{self, *},
yellow::{Ptr, RedNode, GreenNode},
yellow::{RedNode, GreenNode},
};
#[derive(Clone)]
pub struct SyntaxNode {
pub(crate) root: SyntaxRoot,
red: Ptr<RedNode>,
// guaranteed to be alive bc SyntaxRoot holds a strong ref
red: ptr::NonNull<RedNode>,
}
#[derive(Clone)]
@ -29,10 +31,10 @@ pub(crate) struct SyntaxError {
impl SyntaxNode {
pub(crate) fn new(root: GreenNode, errors: Vec<SyntaxError>) -> SyntaxNode {
let root = Arc::new(RedNode::new_root(root));
let red = Ptr::new(&root);
let root = SyntaxRoot { red: root, errors: Arc::new(errors) };
SyntaxNode { root, red }
let red = Arc::new(RedNode::new_root(root));
let red_weak: ptr::NonNull<RedNode> = (&*red).into();
let root = SyntaxRoot { red, errors: Arc::new(errors) };
SyntaxNode { root, red: red_weak }
}
pub fn kind(&self) -> SyntaxKind {
@ -58,15 +60,14 @@ impl SyntaxNode {
for i in 0..n_children {
res.push(SyntaxNode {
root: self.root.clone(),
red: Ptr::new(&red.nth_child(Ptr::clone(&self.red), i)),
red: (&*red.nth_child(i)).into(),
});
}
res
}
fn red(&self) -> &RedNode {
// Safe b/c root ptr keeps red alive
unsafe { self.red.get() }
unsafe { self.red.as_ref() }
}
}