wip storage integration

This commit is contained in:
Andrew Morris
2023-10-30 17:39:36 +11:00
parent 6fbca5ac59
commit 8bdccba57e
12 changed files with 244 additions and 8 deletions

1
Cargo.lock generated
View File

@@ -2386,6 +2386,7 @@ version = "0.1.0"
dependencies = [
"num-bigint",
"num-traits",
"storage",
"valuescript_common",
]

View File

@@ -136,8 +136,6 @@ impl StorageEntity for DemoVal {
}
fn from_storage_entry<E, Tx: StorageOps<E>>(tx: &mut Tx, entry: StorageEntry) -> Result<Self, E> {
let mut reader = StorageEntryReader::new(&entry);
Self::read_from_entry(tx, &mut reader)
Self::read_from_entry(tx, &mut StorageEntryReader::new(&entry))
}
}

View File

@@ -17,5 +17,7 @@ pub use self::storage::Storage;
pub use self::storage_backend::StorageBackend;
pub use memory_backend::MemoryBackend;
pub use sled_backend::SledBackend;
pub use storage_entity::StorageEntity;
pub use storage_entry::{StorageEntry, StorageEntryReader};
pub use storage_ptr::{storage_head_ptr, StoragePtr};
pub use storage_ops::StorageOps;
pub use storage_ptr::{storage_head_ptr, StorageEntryPtr, StorageHeadPtr, StoragePtr};

View File

@@ -5,8 +5,8 @@ use crate::storage_ptr::StorageEntryPtr;
#[derive(Serialize, Deserialize)]
pub struct StorageEntry {
pub(crate) ref_count: u64,
pub(crate) refs: Vec<StorageEntryPtr>,
pub(crate) data: Vec<u8>,
pub refs: Vec<StorageEntryPtr>,
pub data: Vec<u8>,
}
pub struct StorageEntryReader<'a> {

View File

@@ -62,6 +62,7 @@ impl TryToKal for Val {
| Val::Static(..)
| Val::Dynamic(..)
| Val::CopyCounter(..) => return None,
Val::StoragePtr(ptr) => return ptr.get().try_to_kal(),
})
}
}

View File

@@ -9,3 +9,4 @@ edition = "2021"
num-bigint = "0.4"
num-traits = "0.2"
valuescript_common = { path = "../valuescript_common" }
storage = { path = "../storage" }

View File

@@ -55,15 +55,19 @@ static IS_ARRAY: NativeFunction = native_fn(|_this, params| {
});
static FROM: NativeFunction = native_fn(|_this, params| {
let first_param = match params.get(0) {
let mut first_param = match params.get(0) {
None => return Err("undefined is not iterable".to_type_error()),
Some(p) => p,
Some(p) => p.clone(),
};
if params.len() > 1 {
return Err("TODO: Using Array.from with a map function".to_internal_error());
}
if let Val::StoragePtr(ptr) = first_param {
first_param = ptr.get();
}
Ok(match first_param {
Val::Array(arr) => Val::Array(arr.clone()),
Val::String(s) => s.chars().map(|c| c.to_val()).collect::<Vec<Val>>().to_val(),
@@ -104,6 +108,9 @@ static FROM: NativeFunction = native_fn(|_this, params| {
VsArray::from(arr).to_val()
}
Val::StoragePtr(_) => {
panic!("Shouldn't be possible") // prevented this just above the match
}
})
});

View File

@@ -19,11 +19,13 @@ pub mod operations;
mod stack_frame;
mod string_methods;
mod todo_fn;
mod val_storage;
mod virtual_machine;
pub mod vs_array;
pub mod vs_class;
mod vs_function;
pub mod vs_object;
mod vs_storage_ptr;
mod vs_symbol;
pub mod vs_value;

View File

@@ -636,6 +636,7 @@ pub fn op_sub(left: &mut Val, right: &Val) -> Result<Val, Val> {
"count" => (*cc.count.borrow() as f64).to_val(),
_ => Val::Undefined,
}),
Val::StoragePtr(ptr) => ptr.get().sub(right),
}
}
@@ -692,6 +693,13 @@ pub fn op_submov(target: &mut Val, subscript: &Val, value: Val) -> Result<(), Va
Val::Static(_) => Err("Cannot assign to subscript of static value".to_type_error()),
Val::Dynamic(_) => Err("TODO: Assign to subscript of dynamic value".to_type_error()),
Val::CopyCounter(_) => Err("Cannot assign to subscript of CopyCounter".to_type_error()),
Val::StoragePtr(ptr) => {
let mut val = ptr.get();
val.submov(subscript, value)?;
*target = val;
Ok(())
}
}
}

View File

@@ -0,0 +1,176 @@
use storage::{StorageEntity, StorageEntry, StorageEntryReader, StorageOps};
use crate::vs_value::Val;
enum Tag {
Void,
Undefined,
Null,
Bool,
Number,
BigInt,
Symbol,
String,
Array,
Object,
Function,
Class,
Static,
Dynamic,
CopyCounter,
}
impl Tag {
fn to_byte(&self) -> u8 {
match self {
Tag::Void => 0,
Tag::Undefined => 1,
Tag::Null => 2,
Tag::Bool => 3,
Tag::Number => 4,
Tag::BigInt => 5,
Tag::Symbol => 6,
Tag::String => 7,
Tag::Array => 8,
Tag::Object => 9,
Tag::Function => 10,
Tag::Class => 11,
Tag::Static => 12,
Tag::Dynamic => 13,
Tag::CopyCounter => 14,
}
}
fn from_byte(byte: u8) -> Self {
match byte {
0 => Tag::Void,
1 => Tag::Undefined,
2 => Tag::Null,
3 => Tag::Bool,
4 => Tag::Number,
5 => Tag::BigInt,
6 => Tag::Symbol,
7 => Tag::String,
8 => Tag::Array,
9 => Tag::Object,
10 => Tag::Function,
11 => Tag::Class,
12 => Tag::Static,
13 => Tag::Dynamic,
14 => Tag::CopyCounter,
_ => panic!("Invalid tag byte: {}", byte),
}
}
}
impl StorageEntity for Val {
fn from_storage_entry<E, Tx: StorageOps<E>>(tx: &mut Tx, entry: StorageEntry) -> Result<Self, E> {
read_from_entry(tx, &mut StorageEntryReader::new(&entry))
// TODO: assert that we've read the whole entry
}
fn to_storage_entry<E, Tx: StorageOps<E>>(&self, tx: &mut Tx) -> Result<StorageEntry, E> {
todo!()
}
}
fn write_to_entry<E, SO: StorageOps<E>>(
val: &Val,
tx: &mut SO,
entry: &mut StorageEntry,
) -> Result<(), E> {
match val {
Val::Void => {
entry.data.push(Tag::Void.to_byte());
}
Val::Undefined => {
entry.data.push(Tag::Undefined.to_byte());
}
Val::Null => {
entry.data.push(Tag::Null.to_byte());
}
Val::Bool(b) => {
entry.data.push(Tag::Bool.to_byte());
entry.data.push(if *b { 1 } else { 0 });
}
Val::Number(n) => {
entry.data.push(Tag::Number.to_byte());
entry.data.extend_from_slice(&n.to_le_bytes());
}
Val::BigInt(b) => {
entry.data.push(Tag::BigInt.to_byte());
todo!()
}
Val::Symbol(s) => {
entry.data.push(Tag::Symbol.to_byte());
todo!()
}
Val::String(s) => {
entry.data.push(Tag::String.to_byte());
todo!()
}
Val::Array(a) => {
entry.data.push(Tag::Array.to_byte());
todo!()
}
Val::Object(o) => {
entry.data.push(Tag::Object.to_byte());
todo!()
}
Val::Function(f) => {
entry.data.push(Tag::Function.to_byte());
todo!()
}
Val::Class(c) => {
entry.data.push(Tag::Class.to_byte());
todo!()
}
Val::Static(s) => {
entry.data.push(Tag::Static.to_byte());
todo!()
}
Val::Dynamic(d) => {
entry.data.push(Tag::Dynamic.to_byte());
todo!()
}
Val::CopyCounter(cc) => {
entry.data.push(Tag::CopyCounter.to_byte());
todo!()
}
Val::StoragePtr(ptr) => {
entry.data.push(Tag::CopyCounter.to_byte());
todo!()
}
};
Ok(())
}
fn read_from_entry<E, SO: StorageOps<E>>(
_tx: &mut SO,
reader: &mut StorageEntryReader,
) -> Result<Val, E> {
let tag = Tag::from_byte(reader.read_u8().unwrap());
Ok(match tag {
Tag::Void => Val::Void,
Tag::Undefined => Val::Undefined,
Tag::Null => Val::Null,
Tag::Bool => Val::Bool(match reader.read_u8().unwrap() {
0 => false,
1 => true,
_ => panic!("Invalid bool byte"),
}),
Tag::Number => todo!(),
Tag::BigInt => todo!(),
Tag::Symbol => todo!(),
Tag::String => todo!(),
Tag::Array => todo!(),
Tag::Object => todo!(),
Tag::Function => todo!(),
Tag::Class => todo!(),
Tag::Static => todo!(),
Tag::Dynamic => todo!(),
Tag::CopyCounter => todo!(),
})
}

View File

@@ -0,0 +1,27 @@
use std::{cell::RefCell, fmt::Debug};
use storage::StorageEntryPtr;
use crate::vs_value::Val;
#[derive(Debug)]
pub struct VsStoragePtr {
ptr: StorageEntryPtr,
cache: RefCell<Option<Val>>,
}
impl VsStoragePtr {
pub fn get(&self) -> Val {
#[allow(unused_mut)] // Used in commented code
let mut cache = self.cache.borrow_mut();
if let Some(val) = &*cache {
return val.clone();
}
todo!()
// let val = /* TODO */;
// *cache = Some(val.clone());
// val
}
}

View File

@@ -16,6 +16,7 @@ use crate::vs_array::VsArray;
use crate::vs_class::VsClass;
use crate::vs_function::VsFunction;
use crate::vs_object::VsObject;
use crate::vs_storage_ptr::VsStoragePtr;
use crate::vs_symbol::{symbol_to_name, VsSymbol};
#[derive(Clone, Debug, Default)]
@@ -36,6 +37,7 @@ pub enum Val {
Static(&'static dyn ValTrait),
Dynamic(Rc<dyn DynValTrait>),
CopyCounter(Box<CopyCounter>),
StoragePtr(Rc<VsStoragePtr>),
}
#[derive(PartialEq, Debug)]
@@ -185,6 +187,7 @@ impl ValTrait for Val {
Static(val) => val.typeof_(),
Dynamic(val) => val.typeof_(),
CopyCounter(_) => VsType::Object,
StoragePtr(ptr) => ptr.get().typeof_(),
}
}
@@ -211,6 +214,7 @@ impl ValTrait for Val {
Static(val) => val.to_number(),
Dynamic(val) => val.to_number(),
CopyCounter(_) => f64::NAN,
StoragePtr(ptr) => ptr.get().to_number(),
}
}
@@ -236,6 +240,7 @@ impl ValTrait for Val {
Static(val) => val.to_index(),
Dynamic(val) => val.to_index(),
CopyCounter(_) => None,
StoragePtr(ptr) => ptr.get().to_index(),
}
}
@@ -258,6 +263,7 @@ impl ValTrait for Val {
Static(val) => val.is_primitive(), // TODO: false?
Dynamic(val) => val.is_primitive(),
CopyCounter(_) => false,
StoragePtr(ptr) => ptr.get().is_primitive(),
}
}
@@ -280,6 +286,7 @@ impl ValTrait for Val {
Static(val) => val.is_truthy(), // TODO: true?
Dynamic(val) => val.is_truthy(),
CopyCounter(_) => true,
StoragePtr(ptr) => ptr.get().is_truthy(),
}
}
@@ -302,6 +309,7 @@ impl ValTrait for Val {
Static(_) => false,
Dynamic(val) => val.is_nullish(),
CopyCounter(_) => false,
StoragePtr(ptr) => ptr.get().is_nullish(),
}
}
@@ -454,6 +462,7 @@ impl ValTrait for Val {
Val::Static(static_) => static_.has(key),
Val::Dynamic(dynamic) => dynamic.has(key),
Val::CopyCounter(_) => Some(matches!(key.to_string().as_str(), "tag" | "count")),
Val::StoragePtr(ptr) => ptr.get().has(key),
}
}
@@ -540,6 +549,7 @@ impl ValTrait for Val {
cc.tag.codify(),
cc.count.borrow()
),
Val::StoragePtr(_) => todo!(),
}
}
}
@@ -601,6 +611,7 @@ impl fmt::Display for Val {
cc.tag,
(*cc.count.borrow() as f64).to_val()
),
StoragePtr(ptr) => ptr.get().fmt(f),
}
}
}
@@ -771,6 +782,8 @@ impl<'a> std::fmt::Display for PrettyVal<'a> {
cc.tag.pretty(),
(*cc.count.borrow() as f64).to_val().pretty()
),
Val::StoragePtr(ptr) => ptr.get().pretty_fmt(f),
}
}
}