mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-01-09 21:48:12 -05:00
wip storage integration
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -2386,6 +2386,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
"storage",
|
||||
"valuescript_common",
|
||||
]
|
||||
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,3 +9,4 @@ edition = "2021"
|
||||
num-bigint = "0.4"
|
||||
num-traits = "0.2"
|
||||
valuescript_common = { path = "../valuescript_common" }
|
||||
storage = { path = "../storage" }
|
||||
|
||||
@@ -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
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
176
valuescript_vm/src/val_storage.rs
Normal file
176
valuescript_vm/src/val_storage.rs
Normal 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!(),
|
||||
})
|
||||
}
|
||||
27
valuescript_vm/src/vs_storage_ptr.rs
Normal file
27
valuescript_vm/src/vs_storage_ptr.rs
Normal 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
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user