Exemplo n.º 1
0
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);
}
Exemplo n.º 2
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;
}