void _VMClass_set_instance_invokable(void* _self, int64_t idx, pVMObject value) { pVMClass self = (pVMClass)_self; // set this class as the holder of the given invokable TSEND(VMInvokable, value, set_holder, self); // set the instance method with the given index to the given value pVMArray arr = SEND(self, get_instance_invokables); SEND(arr, set_indexable_field, idx, value); }
void _Object_perform_inSuperclass_(pVMObject object, pVMFrame frame) { pVMClass class = (pVMClass) SEND(frame, pop); pVMSymbol selector = (pVMSymbol)SEND(frame, pop); pVMObject invokable = SEND(class, lookup_invokable, selector); TSEND(VMInvokable, invokable, invoke, frame); }
void _Object_perform_(pVMObject object, pVMFrame frame) { pVMSymbol selector = (pVMSymbol)SEND(frame, pop); pVMObject self = SEND(frame, get_stack_element, 0); pVMClass class = SEND(self, get_class); pVMObject invokable = SEND(class, lookup_invokable, selector); TSEND(VMInvokable, invokable, invoke, frame); }
void _VMClass_add_instance_primitive(void* _self, pVMPrimitive value, bool warn) { pVMClass self = (pVMClass)_self; if(SEND(self, add_instance_invokable, (pVMObject)value) && warn) { pVMSymbol sym = TSEND(VMInvokable, value, get_signature); debug_warn("Primitive %s is not in class definition for class %s.\n", sym->chars, self->name->chars); } }
bool _VMClass_add_instance_invokable(void* _self, pVMObject value) { pVMClass self = (pVMClass)_self; // add the given invokable to the array of instance invokables for(int i = 0; i < SEND(self, get_number_of_instance_invokables); i++) { // get the next invokable in the instance invokable array pVMObject invokable = SEND(self, get_instance_invokable, i); // replace the invokable with the given one if the signature matches if(TSEND(VMInvokable, invokable, get_signature) == TSEND(VMInvokable, value, get_signature)) { SEND(self, set_instance_invokable, i, value); return false; } } // append the given method to the array of instance methods self->instance_invokables = SEND(self->instance_invokables, copy_and_extend_with, value); return true; }
bool _VMClass_has_primitives(void* _self) { pVMClass self = (pVMClass)_self; // lookup invokable with given signature in array of instance invokables for(int i = 0; i < SEND(self, get_number_of_instance_invokables); i++) { // get the next invokable in the instance invokable array pVMObject inv = SEND(self, get_instance_invokable, i); if(TSEND(VMInvokable, inv, is_primitive)) return true; } return false; }
void _VMClass_set_instance_invokables(void* _self, pVMArray value) { pVMClass self = (pVMClass)_self; // set the instance invokables self->instance_invokables = value; // make sure this class is the holder of all invokables in the array for(int i = 0; i < SEND(self, get_number_of_instance_invokables); i++) { pVMObject inv = SEND(self, get_instance_invokable, i); TSEND(VMInvokable, inv, set_holder, self); } }
void _VMMethod_set_holder_all(void* _self, pVMClass value) { pVMMethod self = (pVMMethod)_self; // Make sure all nested invokables have the same holder for(size_t i = 0; i < SEND(self, get_number_of_indexable_fields); i++) { pVMObject o = SEND(self, get_indexable_field, i); if(SUPPORTS(o, VMInvokable)) TSEND(VMInvokable, o, set_holder, value); } }
void _Object_perform_withArguments_inSuperclass_(pVMObject object, pVMFrame frame) { pVMClass class = (pVMClass) SEND(frame, pop); pVMArray args = (pVMArray) SEND(frame, pop); pVMSymbol selector = (pVMSymbol)SEND(frame, pop); size_t num_args = SEND(args, get_number_of_indexable_fields); for (size_t i = 0; i < num_args; i++) { pVMObject arg = SEND(args, get_indexable_field, i); SEND(frame, push, arg); } pVMObject invokable = SEND(class, lookup_invokable, selector); TSEND(VMInvokable, invokable, invoke, frame); }
pVMObject _VMClass_lookup_invokable(void* _self, pVMSymbol signature) { pVMClass self = (pVMClass)_self; pVMObject invokable = NULL; // lookup invokable with given signature in array of instance invokables for(int i = 0; i < SEND(self, get_number_of_instance_invokables); i++) { // get the next invokable in the instance invokable array invokable = SEND(self, get_instance_invokable, i); // return the invokable if the signature matches if(TSEND(VMInvokable, invokable, get_signature) == signature) return invokable; } // traverse the super class chain by calling lookup on the super class if(SEND(self, has_super_class)) { invokable = SEND(self->super_class, lookup_invokable, signature); if(invokable) return invokable; } // invokable not found return NULL; }
debug_print("%d", SEND((pVMInteger)o, get_embedded_integer)); else if(c == symbol_class) { debug_print("#%s", SEND((pVMSymbol)o, get_chars)); } else debug_print("address: %p", (void*)o); } } /** * Dump a class and all subsequent methods. */ void Disassembler_dump(pVMClass class) { for(int i = 0; i < SEND(class, get_number_of_instance_invokables); i++) { pVMObject inv = SEND(class, get_instance_invokable, i); // output header and skip if the Invokable is a Primitive pVMSymbol sig = TSEND(VMInvokable, inv, get_signature); const char* sig_s = SEND(sig, get_chars); pVMSymbol cname = SEND(class, get_name); const char* cname_s = SEND(cname, get_chars); debug_dump("%s>>%s = ", cname_s, sig_s); if(TSEND(VMInvokable, inv, is_primitive)) { debug_print("<primitive>\n"); continue; } // output actual method Disassembler_dump_method((pVMMethod)inv, "\t"); } } /**