From 44a85a401ab76ade9c9cf0c72f1dc3933b0fb40e Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Tue, 20 Mar 2018 17:41:17 +0000 Subject: [PATCH] Add size to the property list. It should now be possible to support newer ABIs. --- class.h | 2 +- legacy.c | 17 ++++++++++++++++- properties.h | 27 ++++++++++++++++++++++++++- properties.m | 1 + 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/class.h b/class.h index ef5962d..3d5e78e 100644 --- a/class.h +++ b/class.h @@ -244,7 +244,7 @@ struct legacy_gnustep_objc_class * List of declared properties on this class (NULL if none). This contains * the accessor methods for each property. */ - struct objc_property_list *properties; + struct objc_property_list_legacy *properties; /** * GC / ARC ABI: Fields below this point only exist if abi_version is >= 1. diff --git a/legacy.c b/legacy.c index 4ca16b1..64d3668 100644 --- a/legacy.c +++ b/legacy.c @@ -5,6 +5,7 @@ #include "objc/runtime.h" #include "objc/encoding.h" #include "ivar.h" +#include "properties.h" #include "class.h" #include "loader.h" @@ -82,6 +83,20 @@ static struct objc_method_list *upgradeMethodList(struct objc_method_list_legacy return l; } +static struct objc_property_list *upgradePropertyList(struct objc_property_list_legacy *l) +{ + if (l == NULL) + { + return NULL; + } + size_t data_size = l->count * sizeof(struct objc_property); + struct objc_property_list *n = calloc(1, sizeof(struct objc_property_list) + data_size); + n->count = l->count; + n->size = sizeof(struct objc_property); + memcpy(n->properties, l->properties, data_size); + return n; +} + static int legacy_key; PRIVATE struct legacy_gnustep_objc_class* objc_legacy_class_for_class(Class cls) @@ -102,7 +117,7 @@ PRIVATE Class objc_upgrade_class(struct legacy_gnustep_objc_class *oldClass) cls->methods = upgradeMethodList(oldClass->methods); cls->protocols = oldClass->protocols; cls->abi_version = oldClass->abi_version; - cls->properties = oldClass->properties; + cls->properties = upgradePropertyList(oldClass->properties); objc_register_selectors_from_class(cls); if (!objc_test_class_flag(cls, objc_class_flag_meta)) { diff --git a/properties.h b/properties.h index bb6cacf..b299b16 100644 --- a/properties.h +++ b/properties.h @@ -136,7 +136,7 @@ struct objc_property /** * List of property introspection data. */ -struct objc_property_list +struct objc_property_list_legacy { /** * Number of properties in this array. @@ -152,6 +152,31 @@ struct objc_property_list struct objc_property properties[]; }; +/** + * List of property introspection data. + */ +struct objc_property_list +{ + /** + * Number of properties in this array. + */ + int count; + /** + * Size of `struct objc_property`. This allows the runtime to + * transparently support newer ABIs with more fields in the property + * metadata. + */ + int size; + /* + * The next property in a linked list. + */ + struct objc_property_list *next; + /** + * List of properties. + */ + struct objc_property properties[]; +}; + /** * Constructs a property description from a list of attributes, returning the * instance variable name via the third parameter. diff --git a/properties.m b/properties.m index cbb8bdb..4b0e096 100644 --- a/properties.m +++ b/properties.m @@ -671,6 +671,7 @@ BOOL class_addProperty(Class cls, struct objc_property_list *l = calloc(1, sizeof(struct objc_property_list) + sizeof(struct objc_property)); l->count = 1; + l->size = sizeof(struct objc_property); memcpy(&l->properties, &p, sizeof(struct objc_property)); LOCK_RUNTIME_FOR_SCOPE(); l->next = cls->properties;