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; } } }