Finish up function call implementation, it appears to be working
Functions are downcasted to a `Fun` trait, which will construct the appropriate stack frame. A few other things have been shifted around that affect internal APIs while things are still under construction. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
124
src/vm/frame.rs
124
src/vm/frame.rs
@@ -1,51 +1,107 @@
|
||||
use crate::obj::prelude::*;
|
||||
use shredder::{GcSafe, Scan, Scanner};
|
||||
use std::collections::BTreeMap;
|
||||
use crate::{obj::prelude::*, vm::inst::Inst};
|
||||
use std::{collections::BTreeMap, sync::Arc};
|
||||
use std::fmt::{self, Formatter, Debug};
|
||||
|
||||
/// A stack call frame.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum FrameKind {
|
||||
Native(NativeFunRef, Vec<ObjRef>),
|
||||
User {
|
||||
last_pc: usize,
|
||||
stack_base: usize,
|
||||
fun: UserFunRef,
|
||||
},
|
||||
pub type FrameBindings = BTreeMap<usize, ObjRef>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Frame {
|
||||
User(UserFrame),
|
||||
Native(NativeFrame),
|
||||
}
|
||||
|
||||
unsafe impl Scan for FrameKind {
|
||||
fn scan(&self, scanner: &mut Scanner<'_>) {
|
||||
match self {
|
||||
FrameKind::User { fun, .. } => scanner.scan(fun),
|
||||
_ => { /* no-op */ }
|
||||
impl Frame {
|
||||
pub fn user_frame(&self) -> Option<&UserFrame> {
|
||||
if let Frame::User(frame) = self {
|
||||
Some(frame)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn user_frame_mut(&mut self) -> Option<&mut UserFrame> {
|
||||
if let Frame::User(frame) = self {
|
||||
Some(frame)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn native_frame(&self) -> Option<&NativeFrame> {
|
||||
if let Frame::Native(frame) = self {
|
||||
Some(frame)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn native_frame_mut(&mut self) -> Option<&mut NativeFrame> {
|
||||
if let Frame::Native(frame) = self {
|
||||
Some(frame)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl GcSafe for FrameKind {}
|
||||
|
||||
#[derive(Scan, Debug, Clone)]
|
||||
pub struct Frame {
|
||||
locals: FrameLocals,
|
||||
kind: FrameKind,
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct UserFrame {
|
||||
callee: ObjRef,
|
||||
bindings: FrameBindings,
|
||||
last_pc: usize,
|
||||
code: Arc<Vec<Inst>>,
|
||||
}
|
||||
|
||||
impl Frame {
|
||||
pub fn new(locals: FrameLocals, kind: FrameKind) -> Self {
|
||||
Self { locals, kind, }
|
||||
impl UserFrame {
|
||||
pub fn new(callee: ObjRef, bindings: FrameBindings, last_pc: usize, code: Arc<Vec<Inst>>) -> Self {
|
||||
Self { callee, bindings, last_pc, code, }
|
||||
}
|
||||
|
||||
pub fn locals(&self) -> &FrameLocals {
|
||||
&self.locals
|
||||
pub fn bindings(&self) -> &FrameBindings {
|
||||
&self.bindings
|
||||
}
|
||||
|
||||
pub fn locals_mut(&mut self) -> &mut FrameLocals {
|
||||
&mut self.locals
|
||||
pub fn bindings_mut(&mut self) -> &mut FrameBindings {
|
||||
&mut self.bindings
|
||||
}
|
||||
|
||||
pub fn kind(&self) -> &FrameKind {
|
||||
&self.kind
|
||||
|
||||
pub fn last_pc(&self) -> usize {
|
||||
self.last_pc
|
||||
}
|
||||
|
||||
pub fn code(&self) -> &Arc<Vec<Inst>> {
|
||||
&self.code
|
||||
}
|
||||
|
||||
pub fn callee(&self) -> &ObjRef {
|
||||
&self.callee
|
||||
}
|
||||
}
|
||||
|
||||
pub type FrameLocals = BTreeMap<usize, ObjRef>;
|
||||
pub struct NativeFrame {
|
||||
callee: ObjRef,
|
||||
fun_ptr: NativeFunPtr,
|
||||
args: Vec<ObjRef>,
|
||||
}
|
||||
|
||||
impl NativeFrame {
|
||||
pub fn new(callee: ObjRef, fun_ptr: NativeFunPtr, args: Vec<ObjRef>) -> Self {
|
||||
Self { callee, fun_ptr, args }
|
||||
}
|
||||
|
||||
pub fn fun_ptr(&self) -> &NativeFunPtr {
|
||||
&self.fun_ptr
|
||||
}
|
||||
|
||||
pub fn callee(&self) -> &ObjRef {
|
||||
&self.callee
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for NativeFrame {
|
||||
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
|
||||
fmt.debug_struct("NativeFrame")
|
||||
.field("fun_ptr", &format!("{:#x}", &self.fun_ptr as *const _ as usize))
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user