Typesystem global instance churn, again

I don't know if I'm ever going to get this right.

It's a massive pain having to pass around the base "Method" type
everywhere. It really makes a lot more sense to have it already defined
someplace statically available. It makes doing like getting an attribute
or vtable entry a lot more ergonomic. Previously we'd have to pass in
the Method type every time, which was silly. Now we can just let the
MethodInst::instantiate() function query it directly. Like, this is
100000% better.

Also, I got rid of get_attr_lazy in favor of get_vtable_attr. I think
that I want to unify get_attr and get_vtable_attr, but that would
require a GC pointer to the "self" object on every object that you
create. That's a bit iffy.

But for now, things are feeling a little better and all the tests are
passing, so that's good at least.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2024-09-25 10:22:03 -07:00
parent 6c64697cde
commit 2203957ebb
7 changed files with 194 additions and 296 deletions

View File

@@ -125,7 +125,7 @@ impl Obj for BuiltinFunctionInst {
}
}
impl_base_obj!();
impl_base_obj!(BuiltinFunction);
}
////////////////////////////////////////////////////////////////////////////////
@@ -216,7 +216,7 @@ impl Obj for UserFunctionInst {
}
}
impl_base_obj!();
impl_base_obj!(UserFunction);
}
////////////////////////////////////////////////////////////////////////////////
@@ -249,9 +249,9 @@ impl MethodInst {
}
}
pub fn create(ty: ObjP, self_binding: ObjP, function: ObjP) -> ObjP {
pub fn create(self_binding: ObjP, function: ObjP) -> ObjP {
let ptr = make_ptr(Self::new(self_binding, function));
ptr.borrow_mut().instantiate(ty.clone());
ptr.borrow_mut().instantiate();
ptr
}
@@ -294,5 +294,5 @@ impl Obj for MethodInst {
}
}
impl_base_obj!();
impl_base_obj!(Method);
}

View File

@@ -1,7 +1,14 @@
macro_rules! impl_base_obj {
($base_name:ident) => {
fn instantiate(&mut self, ty: $crate::obj::ObjP) {
self.$base_name.instantiate(ty);
($base_name:ident, $type_name:ident) => {
fn instantiate(&mut self) {
let ty = $crate::obj::BUILTINS.with_borrow(|builtins| {
builtins
.get(stringify!($type_name))
.expect(concat!("no ", stringify!($type_name)))
.clone()
});
self.set_attr("__type__", ty);
self.$base_name.instantiate();
}
fn is_instantiated(&self) -> bool {
@@ -16,6 +23,10 @@ macro_rules! impl_base_obj {
self.$base_name.attrs_mut()
}
fn type_inst(&self) -> ObjP {
self.$base_name.type_inst()
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
@@ -24,16 +35,16 @@ macro_rules! impl_base_obj {
self
}
};
() => {
impl_base_obj! { base }
($type_name:ident) => {
impl_base_obj! { base, $type_name }
};
}
macro_rules! impl_create {
($($arg:ident : $ty:ty),* $(,)?) => {
pub fn create(ty: $crate::obj::ObjP $(, $arg : $ty )*) -> $crate::obj::ObjP {
pub fn create($($arg : $ty ),*) -> $crate::obj::ObjP {
let ptr = make_ptr(Self::new($($arg),*));
ptr.borrow_mut().instantiate(ty);
ptr.borrow_mut().instantiate();
ptr
}
}