Files
not-python/src/obj/fun.rs

133 lines
2.8 KiB
Rust
Raw Normal View History

use crate::{obj::{reserved::*, prelude::*}, vm::{inst::Inst, Vm}};
use once_cell::sync::Lazy;
use shredder::{GcSafeWrapper, Scan};
use std::fmt::{Debug, Formatter, self};
#[derive(Debug, Scan)]
pub struct Method {
vtable: Vtable,
attrs: Attrs,
}
impl Method {
pub fn new(this: ObjRef, func: ObjRef) -> Self {
Self {
vtable: Default::default(),
attrs: attrs! {
SELF_MEMBER_NAME.sym => this,
FUNC_MEMBER_NAME.sym => func,
}
}
}
}
impl_obj!(Method);
pub static CALL_METHOD_WRAPPER_FUN: Lazy<ObjRef<NativeFun>> = Lazy::new(|| {
NativeFun::new_obj(Box::new(|_vm, _fun, _args| {
todo!("__call__ function")
}))
});
//
// struct UserFun
//
pub type UserFunRef = ObjRef<UserFun>;
#[derive(Scan)]
pub struct UserFun {
vtable: Vtable,
attrs: Attrs,
// Safe because Vec<Inst> doesn't need to be scanned
#[shredder(unsafe_skip)]
code: Vec<Inst>,
// Safe because this is just an interner that points to symbols, which aren't GC'd
#[shredder(unsafe_skip)]
locals: Names,
}
impl UserFun {
pub fn code(&self) -> &Vec<Inst> {
&self.code
}
pub fn locals(&self) -> &Names {
&self.locals
}
}
impl_obj!(UserFun);
impl Debug for UserFun {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
fmt.debug_struct("UserFun")
.field("attrs", &self.attrs)
.field("code", &self.code)
.field("locals", &self.locals)
.finish()
}
}
//
// struct NativeFun
//
pub type NativeFunPtr = Box<dyn Fn(&mut Vm, ObjRef, Vec<ObjRef>) + Send + Sync>;
#[derive(Scan)]
pub struct NativeFun {
vtable: Vtable,
attrs: Attrs,
#[shredder(skip)]
fun: GcSafeWrapper<NativeFunPtr>,
}
//
// impl NativeFun
//
impl NativeFun {
pub fn new_obj(fun: NativeFunPtr) -> ObjRef<Self> {
ObjRef::new(Self {
// TODO : vtable for NativeFun
vtable: Default::default(),
attrs: Default::default(),
fun: GcSafeWrapper::new(fun),
})
}
}
//
// impl Debug for NativeFun
//
impl Debug for NativeFun {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
fmt.debug_struct("NativeFun")
.field("fun", &format!("(function at {:x})", &self.fun as *const _ as usize))
.field("attrs", &self.attrs)
.finish()
}
}
impl_obj!(NativeFun);
//
// Native function defs
//
// __access__ is what the "dot" operator calls
// __get_attr__ *should* always bypass the __access__ function and get an attribute directly
pub static GET_ATTR_MEMBER_FUN: Lazy<ObjRef<NativeFun>> = Lazy::new(|| {
NativeFun::new_obj(Box::new(|_vm, _fun, _args| {
/*
let sym_ref = vm.pop();
let obj_ref = vm.pop();
obj_ref.access()
*/
todo!("__get_attr__ function")
}))
});