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:
34
src/vm.rs
34
src/vm.rs
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user