Checkpoint more work on new ABI.
We're now using a new class and category structure and auto-upgrading the old ones. Other changes: - The Ivar structure now points to the ivar offset variable, so we can more easily find it. - Categories can now add properties.main
parent
09dda1837f
commit
f91fb2e745
@ -0,0 +1,93 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "objc/runtime.h"
|
||||
#include "objc/encoding.h"
|
||||
#include "ivar.h"
|
||||
#include "class.h"
|
||||
#include "loader.h"
|
||||
|
||||
static ivar_ownership ownershipForIvar(struct legacy_gnustep_objc_class *cls, int idx)
|
||||
{
|
||||
if (objc_get_class_version_legacy(cls) < 2)
|
||||
{
|
||||
return ownership_unsafe;
|
||||
}
|
||||
if (objc_bitfield_test(cls->strong_pointers, idx))
|
||||
{
|
||||
return ownership_strong;
|
||||
}
|
||||
if (objc_bitfield_test(cls->weak_pointers, idx))
|
||||
{
|
||||
return ownership_weak;
|
||||
}
|
||||
return ownership_unsafe;
|
||||
}
|
||||
|
||||
static struct objc_ivar_list *upgradeIvarList(struct legacy_gnustep_objc_class *cls)
|
||||
{
|
||||
struct objc_ivar_list_legacy *l = cls->ivars;
|
||||
if (l == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
struct objc_ivar_list *n = calloc(1, sizeof(struct objc_ivar_list) +
|
||||
l->count*sizeof(struct objc_ivar));
|
||||
n->size = sizeof(struct objc_ivar);
|
||||
n->count = l->count;
|
||||
for (int i=0 ; i<l->count ; i++)
|
||||
{
|
||||
n->ivar_list[i].name = l->ivar_list[i].name;
|
||||
n->ivar_list[i].type = l->ivar_list[i].type;
|
||||
if (objc_test_class_flag_legacy(cls, objc_class_flag_new_abi))
|
||||
{
|
||||
n->ivar_list[i].offset = cls->ivar_offsets[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
n->ivar_list[i].offset = &l->ivar_list[i].offset;
|
||||
}
|
||||
const char *type = l->ivar_list[i].type;
|
||||
n->ivar_list[i].align = ((type == NULL) || type[0] == 0) ? __alignof__(void*) : objc_alignof_type(type);
|
||||
ivarSetOwnership(&n->ivar_list[i], ownershipForIvar(cls, i));
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static int legacy_key;
|
||||
|
||||
PRIVATE struct legacy_gnustep_objc_class* objc_legacy_class_for_class(Class cls)
|
||||
{
|
||||
return (struct legacy_gnustep_objc_class*)objc_getAssociatedObject((id)cls, &legacy_key);
|
||||
}
|
||||
|
||||
PRIVATE Class objc_upgrade_class(struct legacy_gnustep_objc_class *oldClass)
|
||||
{
|
||||
Class cls = calloc(sizeof(struct objc_class), 1);
|
||||
cls->isa = oldClass->isa;
|
||||
cls->super_class = (struct objc_class*)oldClass->super_class;
|
||||
cls->name = oldClass->name;
|
||||
cls->version = oldClass->version;
|
||||
cls->info = oldClass->info;
|
||||
cls->instance_size = oldClass->instance_size;
|
||||
cls->ivars = upgradeIvarList(oldClass);
|
||||
cls->methods = oldClass->methods;
|
||||
cls->protocols = oldClass->protocols;
|
||||
cls->abi_version = oldClass->abi_version;
|
||||
cls->properties = oldClass->properties;
|
||||
objc_register_selectors_from_class(cls);
|
||||
if (!objc_test_class_flag(cls, objc_class_flag_meta))
|
||||
{
|
||||
cls->isa = objc_upgrade_class((struct legacy_gnustep_objc_class*)cls->isa);
|
||||
objc_setAssociatedObject((id)cls, &legacy_key, (id)oldClass, OBJC_ASSOCIATION_ASSIGN);
|
||||
}
|
||||
return cls;
|
||||
}
|
||||
|
||||
PRIVATE struct objc_category *objc_upgrade_category(struct objc_category_legacy *old)
|
||||
{
|
||||
struct objc_category *cat = calloc(1, sizeof(struct objc_category));
|
||||
memcpy(cat, old, sizeof(struct objc_category_legacy));
|
||||
return cat;
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include "visibility.h"
|
||||
#include "ivar.h"
|
||||
#include "class.h"
|
||||
#include "category.h"
|
||||
|
||||
PRIVATE Class objc_upgrade_class(struct legacy_gnustep_objc_class *oldClass);
|
||||
PRIVATE struct objc_category *objc_upgrade_category(struct objc_category_legacy *);
|
||||
|
||||
PRIVATE struct legacy_gnustep_objc_class* objc_legacy_class_for_class(Class);
|
||||
|
||||
Loading…
Reference in New Issue