static FileHandle* S_new_filehandle() { String *class_name = SSTR_WRAP_UTF8("TestFileHandle", 14); FileHandle *fh; Class *klass = Class_fetch_class(class_name); if (!klass) { klass = Class_singleton(class_name, FILEHANDLE); } Class_Override(klass, S_no_op_method, LUCY_FH_Close_OFFSET); fh = (FileHandle*)Class_Make_Obj(klass); return FH_do_open(fh, NULL, 0); }
Class* Class_singleton(String *class_name, Class *parent) { if (Class_registry == NULL) { Class_init_registry(); } Class *singleton = (Class*)LFReg_fetch(Class_registry, class_name); if (singleton == NULL) { Vector *fresh_host_methods; size_t num_fresh; if (parent == NULL) { String *parent_class = Class_find_parent_class(class_name); if (parent_class == NULL) { THROW(ERR, "Class '%o' doesn't descend from %o", class_name, OBJ->name); } else { parent = Class_singleton(parent_class, NULL); DECREF(parent_class); } } singleton = S_simple_subclass(parent, class_name); // Allow host methods to override. fresh_host_methods = Class_fresh_host_methods(class_name); num_fresh = Vec_Get_Size(fresh_host_methods); if (num_fresh) { Hash *meths = Hash_new(num_fresh); for (size_t i = 0; i < num_fresh; i++) { String *meth = (String*)Vec_Fetch(fresh_host_methods, i); Hash_Store(meths, meth, (Obj*)CFISH_TRUE); } for (Class *klass = parent; klass; klass = klass->parent) { for (size_t i = 0; klass->methods[i]; i++) { Method *method = klass->methods[i]; if (method->callback_func) { String *name = Method_Host_Name(method); if (Hash_Fetch(meths, name)) { Class_Override(singleton, method->callback_func, method->offset); } DECREF(name); } } } DECREF(meths); } DECREF(fresh_host_methods); // Register the new class, both locally and with host. if (Class_add_to_registry(singleton)) { // Doing this after registering is racy, but hard to fix. :( Class_register_with_host(singleton, parent); } else { DECREF(singleton); singleton = (Class*)LFReg_fetch(Class_registry, class_name); if (!singleton) { THROW(ERR, "Failed to either insert or fetch Class for '%o'", class_name); } } } return singleton; }