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

@@ -1,4 +1,3 @@
use std::collections::HashMap;
use std::rc::Rc;
use crate::obj::function::*;
@@ -93,19 +92,13 @@ pub struct Vm {
globals: Vec<ObjP>,
stack: Vec<ObjP>,
frames: Vec<Frame>,
builtins: HashMap<String, ObjP>,
}
impl Vm {
/// Create a new virtual machine with the given chunk, constants, and global names.
pub fn new(
chunk: Rc<Chunk>,
constants: Vec<ObjP>,
global_names: Vec<String>,
builtins: HashMap<String, ObjP>,
) -> Self {
pub fn new(chunk: Rc<Chunk>, constants: Vec<ObjP>, global_names: Vec<String>) -> Self {
// set up globals
let nil = builtins.create_nil();
let nil = NilInst::create();
let mut globals: Vec<_> = global_names.iter().map(|_| ObjP::clone(&nil)).collect();
let mut register_global = |name: &str, value: ObjP| {
@@ -116,9 +109,11 @@ impl Vm {
globals[index] = value;
};
for (name, builtin) in builtins.iter() {
register_global(&name, ObjP::clone(&builtin));
}
BUILTINS.with_borrow(|builtins| {
for (name, builtin) in builtins.iter() {
register_global(&name, builtin.clone());
}
});
// stack and frames
let stack = Vec::new();
@@ -134,7 +129,6 @@ impl Vm {
globals,
stack,
frames,
builtins,
}
}
@@ -261,9 +255,6 @@ impl Vm {
}
pub fn run(&mut self) {
// Cached pointers that we just always want to have on hand
let method_type = self.builtins().get("Method").unwrap().clone();
loop {
let op = self.dispatch();
@@ -301,10 +292,7 @@ impl Vm {
let name =
with_obj_downcast(name_obj, |name: &StrInst| Rc::clone(&name.str_value()));
let owner = self.pop();
let value =
owner
.borrow_mut()
.get_attr_lazy(owner.clone(), method_type.clone(), &name);
let value = owner.borrow_mut().get_vtable_attr(owner.clone(), &name);
if let Some(value) = value {
self.push(value);
} else {
@@ -410,9 +398,3 @@ impl Vm {
}
}
}
impl ObjFactory for Vm {
fn builtins(&self) -> &HashMap<String, ObjP> {
&self.builtins
}
}