2020-09-01 17:32:48 -07:00
|
|
|
use crate::{obj::{names::*, prelude::*}, vm::{inst::Inst, Vm}};
|
|
|
|
|
use once_cell::sync::Lazy;
|
|
|
|
|
use shredder::{GcSafeWrapper, Scan};
|
|
|
|
|
use std::fmt::{Debug, Formatter, self};
|
|
|
|
|
|
2020-09-14 14:09:29 -07:00
|
|
|
#[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")
|
|
|
|
|
}))
|
|
|
|
|
});
|
|
|
|
|
|
2020-09-01 17:32:48 -07:00
|
|
|
//
|
|
|
|
|
// struct UserFun
|
|
|
|
|
//
|
|
|
|
|
#[derive(Scan)]
|
|
|
|
|
pub struct UserFun {
|
2020-09-14 14:09:29 -07:00
|
|
|
vtable: Vtable,
|
2020-09-01 17:32:48 -07:00
|
|
|
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: Locals,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl UserFun {
|
|
|
|
|
pub fn code(&self) -> &Vec<Inst> {
|
|
|
|
|
&self.code
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn locals(&self) -> &Locals {
|
|
|
|
|
&self.locals
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-14 14:09:29 -07:00
|
|
|
impl_obj!(UserFun);
|
2020-09-01 17:32:48 -07:00
|
|
|
|
|
|
|
|
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
|
|
|
|
|
//
|
|
|
|
|
|
2020-09-14 14:09:29 -07:00
|
|
|
pub type NativeFunPtr = Box<dyn Fn(&mut Vm, ObjRef, Vec<ObjRef>) + Send + Sync>;
|
|
|
|
|
|
2020-09-01 17:32:48 -07:00
|
|
|
#[derive(Scan)]
|
|
|
|
|
pub struct NativeFun {
|
2020-09-14 14:09:29 -07:00
|
|
|
vtable: Vtable,
|
2020-09-01 17:32:48 -07:00
|
|
|
attrs: Attrs,
|
2020-09-14 14:09:29 -07:00
|
|
|
#[shredder(skip)]
|
|
|
|
|
fun: GcSafeWrapper<NativeFunPtr>,
|
2020-09-01 17:32:48 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// impl NativeFun
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
impl NativeFun {
|
2020-09-14 14:09:29 -07:00
|
|
|
pub fn new_obj(fun: NativeFunPtr) -> ObjRef<Self> {
|
|
|
|
|
ObjRef::new(Self {
|
|
|
|
|
// TODO : vtable for NativeFun
|
|
|
|
|
vtable: Default::default(),
|
2020-09-01 17:32:48 -07:00
|
|
|
attrs: Default::default(),
|
2020-09-14 14:09:29 -07:00
|
|
|
fun: GcSafeWrapper::new(fun),
|
|
|
|
|
})
|
2020-09-01 17:32:48 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// 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()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-14 14:09:29 -07:00
|
|
|
impl_obj!(NativeFun);
|
2020-09-01 17:32:48 -07:00
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// 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(|| {
|
2020-09-14 14:09:29 -07:00
|
|
|
NativeFun::new_obj(Box::new(|_vm, _fun, _args| {
|
2020-09-01 17:32:48 -07:00
|
|
|
/*
|
|
|
|
|
let sym_ref = vm.pop();
|
|
|
|
|
let obj_ref = vm.pop();
|
|
|
|
|
obj_ref.access()
|
|
|
|
|
*/
|
|
|
|
|
todo!("__get_attr__ function")
|
|
|
|
|
}))
|
|
|
|
|
});
|