Implement vtables and method resolution
Types now can have vtable elements which are used by instances to bind themselves to methods. When Op::GetAttr is executed, it calls a new function, Obj::get_attr_lazy. This will search: * attributes on the object * vtable on the object's type * vtable on the object's type's type, * etc. This searches up the type tree for a named value. If it exists as an attribute, it will be returned immediately. If it exists in the type's vtable, then it will be inserted as an attribute. If the vtable value is a function, the object that it is being called on will be bound to that method as the `self` parameter. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
10
src/vm.rs
10
src/vm.rs
@@ -197,6 +197,9 @@ 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 {
|
||||
match self.next() {
|
||||
Op::Pop => {
|
||||
@@ -232,7 +235,10 @@ impl Vm {
|
||||
let name =
|
||||
with_obj_downcast(name_obj, |name: &StrInst| Rc::clone(&name.str_value()));
|
||||
let owner = self.pop();
|
||||
let value = owner.borrow().get_attr(&name);
|
||||
let value =
|
||||
owner
|
||||
.borrow_mut()
|
||||
.get_attr_lazy(owner.clone(), method_type.clone(), &name);
|
||||
if let Some(value) = value {
|
||||
self.push(value);
|
||||
} else {
|
||||
@@ -339,7 +345,7 @@ impl Vm {
|
||||
let stack_base = self.frames[frame_index].stack_base;
|
||||
let value = Ptr::clone(&self.stack[stack_base + (slot as usize)]);
|
||||
fun.push_capture(value);
|
||||
self.push(upcast_obj(make_ptr(fun)));
|
||||
self.push(make_ptr(fun));
|
||||
}
|
||||
Op::Halt => {
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user