feat: generalize Stack
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
mod builtins;
|
mod builtins;
|
||||||
mod bytecode;
|
mod bytecode;
|
||||||
mod ty;
|
mod ty;
|
||||||
|
mod stack;
|
||||||
|
|
||||||
pub mod compile;
|
pub mod compile;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
use std::mem::{MaybeUninit, replace, size_of, transmute};
|
use std::mem::{MaybeUninit, replace, transmute};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
use crate::error::*;
|
use crate::error::*;
|
||||||
use crate::ty::internal::Value;
|
|
||||||
|
|
||||||
pub const STACK_SIZE: usize = 8 * 1024 / size_of::<Value>();
|
pub struct Stack<T, const CAP: usize> {
|
||||||
|
|
||||||
pub struct Stack<'vm, const CAP: usize> {
|
|
||||||
// items: Box<[MaybeUninit<Value<'vm>>; CAP]>,
|
// items: Box<[MaybeUninit<Value<'vm>>; CAP]>,
|
||||||
items: [MaybeUninit<Value<'vm>>; CAP],
|
items: [MaybeUninit<T>; CAP],
|
||||||
top: usize,
|
top: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,7 +19,7 @@ macro_rules! into {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'vm, const CAP: usize> Stack<'vm, CAP> {
|
impl<T, const CAP: usize> Stack<T, CAP> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Stack {
|
Stack {
|
||||||
items: [const { MaybeUninit::uninit() }; CAP],
|
items: [const { MaybeUninit::uninit() }; CAP],
|
||||||
@@ -30,7 +27,7 @@ impl<'vm, const CAP: usize> Stack<'vm, CAP> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push(&mut self, item: Value<'vm>) -> Result<()> {
|
pub fn push(&mut self, item: T) -> Result<()> {
|
||||||
self.items
|
self.items
|
||||||
.get_mut(self.top)
|
.get_mut(self.top)
|
||||||
.map_or_else(
|
.map_or_else(
|
||||||
@@ -42,7 +39,7 @@ impl<'vm, const CAP: usize> Stack<'vm, CAP> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop(&mut self) -> Value<'vm> {
|
pub fn pop(&mut self) -> T {
|
||||||
self.top -= 1;
|
self.top -= 1;
|
||||||
let item = self.items.get_mut(self.top).unwrap();
|
let item = self.items.get_mut(self.top).unwrap();
|
||||||
|
|
||||||
@@ -52,7 +49,7 @@ impl<'vm, const CAP: usize> Stack<'vm, CAP> {
|
|||||||
unsafe { replace(item, MaybeUninit::uninit()).assume_init() }
|
unsafe { replace(item, MaybeUninit::uninit()).assume_init() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tos(&self) -> Result<&Value<'vm>> {
|
pub fn tos(&self) -> Result<&T> {
|
||||||
if self.top == 0 {
|
if self.top == 0 {
|
||||||
panic!("stack empty")
|
panic!("stack empty")
|
||||||
} else {
|
} else {
|
||||||
@@ -60,7 +57,7 @@ impl<'vm, const CAP: usize> Stack<'vm, CAP> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tos_mut(&mut self) -> Result<&mut Value<'vm>> {
|
pub fn tos_mut(&mut self) -> Result<&mut T> {
|
||||||
if self.top == 0 {
|
if self.top == 0 {
|
||||||
panic!("stack empty")
|
panic!("stack empty")
|
||||||
} else {
|
} else {
|
||||||
@@ -69,14 +66,14 @@ impl<'vm, const CAP: usize> Stack<'vm, CAP> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'vm, const CAP: usize> Deref for Stack<'vm, CAP> {
|
impl<T, const CAP: usize> Deref for Stack<T, CAP> {
|
||||||
type Target = [Value<'vm>];
|
type Target = [T];
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
into!(&self.items[0..self.top])
|
into!(&self.items[0..self.top])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const CAP: usize> Drop for Stack<'_, CAP> {
|
impl<T, const CAP: usize> Drop for Stack<T, CAP> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.items.as_mut_slice()[0..self.top]
|
self.items.as_mut_slice()[0..self.top]
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
@@ -7,18 +7,19 @@ use crate::ty::common::Symbol;
|
|||||||
use crate::ty::internal::*;
|
use crate::ty::internal::*;
|
||||||
use crate::ty::public as p;
|
use crate::ty::public as p;
|
||||||
|
|
||||||
use stack::{STACK_SIZE, Stack};
|
use crate::stack::Stack;
|
||||||
|
|
||||||
pub use env::Env;
|
pub use env::Env;
|
||||||
pub use jit::JITContext;
|
pub use jit::JITContext;
|
||||||
|
|
||||||
mod env;
|
mod env;
|
||||||
mod jit;
|
mod jit;
|
||||||
mod stack;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test;
|
mod test;
|
||||||
|
|
||||||
|
const STACK_SIZE: usize = 8 * 1024 / size_of::<Value>();
|
||||||
|
|
||||||
pub fn run(prog: Program, jit: JITContext<'_>) -> Result<p::Value> {
|
pub fn run(prog: Program, jit: JITContext<'_>) -> Result<p::Value> {
|
||||||
let vm = VM::new(
|
let vm = VM::new(
|
||||||
prog.thunks,
|
prog.thunks,
|
||||||
@@ -57,7 +58,7 @@ impl<'vm, 'jit: 'vm> VM<'jit> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn eval(&'vm self, opcodes: OpCodes, env: Rc<Env<'vm>>) -> Result<Value<'vm>> {
|
pub fn eval(&'vm self, opcodes: OpCodes, env: Rc<Env<'vm>>) -> Result<Value<'vm>> {
|
||||||
let mut stack = Stack::<STACK_SIZE>::new();
|
let mut stack = Stack::<_, STACK_SIZE>::new();
|
||||||
let mut iter = opcodes.into_iter();
|
let mut iter = opcodes.into_iter();
|
||||||
while let Some(opcode) = iter.next() {
|
while let Some(opcode) = iter.next() {
|
||||||
let jmp = self.single_op(opcode, &mut stack, &env)?;
|
let jmp = self.single_op(opcode, &mut stack, &env)?;
|
||||||
@@ -75,7 +76,7 @@ impl<'vm, 'jit: 'vm> VM<'jit> {
|
|||||||
fn single_op<'s, const CAP: usize>(
|
fn single_op<'s, const CAP: usize>(
|
||||||
&'vm self,
|
&'vm self,
|
||||||
opcode: OpCode,
|
opcode: OpCode,
|
||||||
stack: &'s mut Stack<'vm, CAP>,
|
stack: &'s mut Stack<Value<'vm>, CAP>,
|
||||||
env: &Rc<Env<'vm>>,
|
env: &Rc<Env<'vm>>,
|
||||||
) -> Result<usize> {
|
) -> Result<usize> {
|
||||||
match opcode {
|
match opcode {
|
||||||
|
|||||||
Reference in New Issue
Block a user