mirror of
https://github.com/MorizzG/rlox.git
synced 2025-12-06 04:12:42 +00:00
moved HeapedValue into environment
changed from UnsafeCell to RefCell to fix possible unsoundness
This commit is contained in:
parent
67bb5fe8fd
commit
6635929019
2 changed files with 40 additions and 55 deletions
|
|
@ -1,13 +1,42 @@
|
||||||
|
use std::cell::{Ref, RefCell, RefMut};
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use crate::error::RuntimeError;
|
use crate::error::RuntimeError;
|
||||||
|
|
||||||
use super::value::HeapedValue;
|
|
||||||
use super::{Runtime, Value};
|
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>;
|
pub type Scope = FxHashMap<Box<str>, HeapedValue>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -70,11 +99,17 @@ impl<'a> Environment<'a> {
|
||||||
self.scope_stack.last_mut().unwrap()
|
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.current_frame_mut().enter_scope();
|
||||||
// self.local_scopes.push(Scope::new());
|
// self.local_scopes.push(Scope::new());
|
||||||
|
|
||||||
|
if self.scope_stack.len() >= 255 {
|
||||||
|
return Err(RuntimeError::StackOverflow);
|
||||||
|
}
|
||||||
|
|
||||||
self.scope_stack.push(Scope::default());
|
self.scope_stack.push(Scope::default());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exit_scope(&mut self) {
|
pub fn exit_scope(&mut self) {
|
||||||
|
|
@ -95,19 +130,18 @@ impl<'a> Environment<'a> {
|
||||||
self.runtime.get_global(name)
|
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();
|
let len = self.scopes().len();
|
||||||
|
|
||||||
if level < len {
|
if level < len {
|
||||||
if let Some(heap_value) = self.scopes()[len - level - 1].get(name) {
|
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 {
|
Err(RuntimeError::NameNotDefined {
|
||||||
name: name.to_owned(),
|
name: name.to_owned(),
|
||||||
})
|
})
|
||||||
// self.runtime.get_global(name)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn define(&mut self, name: impl Into<Box<str>>, value: Value) {
|
pub fn define(&mut self, name: impl Into<Box<str>>, value: Value) {
|
||||||
|
|
@ -135,17 +169,8 @@ impl<'a> Environment<'a> {
|
||||||
Err(RuntimeError::NameNotDefined {
|
Err(RuntimeError::NameNotDefined {
|
||||||
name: name.to_owned(),
|
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 {
|
pub fn collect_closure(&self, closure_vars: &[(Box<str>, usize)]) -> Scope {
|
||||||
let mut closure_scope = Scope::default();
|
let mut closure_scope = Scope::default();
|
||||||
|
|
||||||
|
|
@ -182,7 +207,7 @@ impl Display for Environment<'_> {
|
||||||
write!(f, "\nScope {level}:")?;
|
write!(f, "\nScope {level}:")?;
|
||||||
|
|
||||||
for (name, value) in scope.iter() {
|
for (name, value) in scope.iter() {
|
||||||
write!(f, "\n\t{name} = {}", value.as_ref())?;
|
write!(f, "\n\t{name} = {}", value.borrow())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
use std::cell::UnsafeCell;
|
|
||||||
use std::fmt::{Debug, Display};
|
use std::fmt::{Debug, Display};
|
||||||
use std::rc::Rc;
|
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue