moved HeapedValue into environment

changed from UnsafeCell to RefCell to fix possible unsoundness
This commit is contained in:
Moritz Gmeiner 2024-09-01 20:46:24 +02:00
commit 6635929019
2 changed files with 40 additions and 55 deletions

View file

@ -1,13 +1,42 @@
use std::cell::{Ref, RefCell, RefMut};
use std::fmt::Display;
use std::io::{Read, Write};
use std::rc::Rc;
use rustc_hash::FxHashMap;
use crate::error::RuntimeError;
use super::value::HeapedValue;
use super::{Runtime, Value};
#[derive(Debug, Clone)]
pub struct HeapedValue {
inner: Rc<RefCell<Value>>,
}
impl HeapedValue {
pub fn new(value: Value) -> Self {
let inner = Rc::new(RefCell::new(value));
HeapedValue { inner }
}
pub fn replace(&mut self, value: Value) {
*self.inner.as_ref().borrow_mut() = value;
}
pub fn cloned(&self) -> Value {
self.inner.as_ref().borrow().clone()
}
pub fn borrow(&self) -> Ref<Value> {
self.inner.as_ref().borrow()
}
pub fn borrow_mut(&self) -> RefMut<Value> {
self.inner.as_ref().borrow_mut()
}
}
pub type Scope = FxHashMap<Box<str>, HeapedValue>;
#[derive(Debug)]
@ -70,11 +99,17 @@ impl<'a> Environment<'a> {
self.scope_stack.last_mut().unwrap()
}
pub fn enter_scope(&mut self) {
pub fn enter_scope(&mut self) -> Result<(), RuntimeError> {
// self.current_frame_mut().enter_scope();
// self.local_scopes.push(Scope::new());
if self.scope_stack.len() >= 255 {
return Err(RuntimeError::StackOverflow);
}
self.scope_stack.push(Scope::default());
Ok(())
}
pub fn exit_scope(&mut self) {
@ -95,19 +130,18 @@ impl<'a> Environment<'a> {
self.runtime.get_global(name)
}
pub fn get_local(&self, name: &str, level: usize) -> Result<Value, RuntimeError> {
pub fn get_local(&'a self, name: &str, level: usize) -> Result<Value, RuntimeError> {
let len = self.scopes().len();
if level < len {
if let Some(heap_value) = self.scopes()[len - level - 1].get(name) {
return Ok(heap_value.get_clone());
return Ok(heap_value.cloned());
}
}
Err(RuntimeError::NameNotDefined {
name: name.to_owned(),
})
// self.runtime.get_global(name)
}
pub fn define(&mut self, name: impl Into<Box<str>>, value: Value) {
@ -135,17 +169,8 @@ impl<'a> Environment<'a> {
Err(RuntimeError::NameNotDefined {
name: name.to_owned(),
})
// self.runtime.assign_global(name, value)
}
/* pub fn push_frame(&mut self, base_scope: Scope) {
self.frames.push(Frame::new(base_scope));
}
pub fn pop_frame(&mut self) {
self.frames.pop().expect("Tried to pop global frame");
} */
pub fn collect_closure(&self, closure_vars: &[(Box<str>, usize)]) -> Scope {
let mut closure_scope = Scope::default();
@ -182,7 +207,7 @@ impl Display for Environment<'_> {
write!(f, "\nScope {level}:")?;
for (name, value) in scope.iter() {
write!(f, "\n\t{name} = {}", value.as_ref())?;
write!(f, "\n\t{name} = {}", value.borrow())?;
}
}

View file

@ -1,4 +1,3 @@
use std::cell::UnsafeCell;
use std::fmt::{Debug, Display};
use std::rc::Rc;
@ -58,42 +57,3 @@ impl Display for Value {
}
}
}
/*====================================================================================================================*/
#[derive(Debug, Clone)]
pub struct HeapedValue {
inner: Rc<UnsafeCell<Value>>,
}
impl HeapedValue {
pub fn new(value: Value) -> Self {
let inner = Rc::new(UnsafeCell::new(value));
HeapedValue { inner }
}
pub fn get_clone(&self) -> Value {
unsafe {
let ptr = self.inner.get();
let value = &*ptr;
value.clone()
}
}
pub fn replace(&mut self, value: Value) {
let mut value = value;
unsafe {
let ptr_mut = self.inner.get();
std::ptr::swap(&mut value, ptr_mut);
}
}
}
impl AsRef<Value> for HeapedValue {
fn as_ref(&self) -> &Value {
unsafe {
let ptr = self.inner.get();
&*ptr
}
}
}