Exemple #1
0
OBJCRT_EXPORT Class objc_allocateClassPair(Class super, const char* name, size_t extraBytes) {
    // Per API contract: If the class name already exists,
    // the runtime refuses to create a new one.
    if (objc_classname_to_class(name) != Nil) {
        return Nil;
    }
    // allocate the metaclass and the class, back-to-back.
    size_t size = sizeof(struct objc_class) + // Metaclass
                  OBJC_ID_PADDED(sizeof(struct objc_class)) + // Class + Alignment Padding
                  extraBytes;
    Class newClasses = calloc(1, size);

    newClasses[0].name = newClasses[1].name = _strdup(name);
    newClasses[0].dtable = newClasses[1].dtable = empty_dtable;
    newClasses[0].info |= OBJC_CLASS_INFO_METACLASS | OBJC_CLASS_INFO_CREATED_RUNTIME;
    newClasses[1].info |= OBJC_CLASS_INFO_CLASS | OBJC_CLASS_INFO_CREATED_RUNTIME;
    newClasses[1].superclass = super;
    _object_setClass((id)&newClasses[1], &newClasses[0]);
    return &newClasses[1];
}
void
objc_init_static_instances(struct objc_abi_symtab *symtab)
{
    struct objc_abi_static_instances **si;
    size_t i;

    /* Check if the class for a static instance became available */
    for (i = 0; i < static_instances_cnt; i++) {
        Class cls = objc_lookup_class(static_instances[i]->class_name);

        if (cls != Nil) {
            id *instances;

            for (instances = static_instances[i]->instances;
                *instances != nil; instances++)
                _object_setClass(*instances, cls);

            static_instances_cnt--;

            if (static_instances_cnt == 0) {
                free(static_instances);
                static_instances = NULL;
                continue;
            }

            static_instances[i] =
                static_instances[static_instances_cnt];

            static_instances = realloc(static_instances,
                sizeof(struct objc_abi_static_instances*) *
                static_instances_cnt);

            if (static_instances == NULL)
                OBJC_ERROR("Not enough memory for list of "
                    "static instances!");
        }
    }

    si = (struct objc_abi_static_instances**)
        symtab->defs[symtab->cls_def_cnt + symtab->cat_def_cnt];

    if (si == NULL)
        return;

    for (; *si != NULL; si++) {
        Class cls = objc_lookup_class((*si)->class_name);

        if (cls != Nil) {
            id *instances;

            for (instances = (*si)->instances; *instances != nil;
                instances++)
                _object_setClass(*instances, cls);
        } else {
            if (static_instances == NULL)
                static_instances = malloc(sizeof(
                    struct objc_abi_static_instances*));
            else
                static_instances = realloc(static_instances,
                    sizeof(struct objc_abi_static_instances*) *
                    (static_instances_cnt + 1));

            if (static_instances == NULL)
                OBJC_ERROR("Not enough memory for list of "
                    "static instances!");

            static_instances[static_instances_cnt++] = *si;
        }
    }
}