mirror of
https://github.com/darlinghq/darling-cocotron.git
synced 2025-02-17 10:08:46 +00:00
Support for The Stupidest Idea Ever Introduced To The GNU Objective-C Runtime AKA Typed Selectors, which somehow got carried over to clang too.
This commit is contained in:
parent
bd1ef43a46
commit
97e0ea5eb8
@ -247,14 +247,14 @@ static OBJCArray *OBJCModuleQueue(){
|
||||
|
||||
|
||||
static void OBJCSymbolTableRegisterSelectors(OBJCSymbolTable *symbolTable){
|
||||
SEL *selectorReferences=symbolTable->selectorReferences;
|
||||
|
||||
if(selectorReferences!=NULL){
|
||||
while(*selectorReferences!=NULL){
|
||||
*selectorReferences=(SEL)sel_registerNameNoCopy((const char *)*selectorReferences);
|
||||
selectorReferences++;
|
||||
objc_selector_internal *selectorReferences=symbolTable->selectorReferences;
|
||||
|
||||
if(selectorReferences!=NULL){
|
||||
while(objc_getSelectorReferenceName(selectorReferences)!=NULL){
|
||||
objc_setSelectorReferenceName(&selectorReferences,sel_registerNameNoCopy(objc_getSelectorReferenceName(selectorReferences)));
|
||||
selectorReferences++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OBJCAddToUnResolvedClasses(Class class) {
|
||||
@ -471,47 +471,47 @@ static void OBJCSymbolTableRegisterCategories(OBJCSymbolTable *symbolTable){
|
||||
|
||||
// GNU style for now
|
||||
static void OBJCSymbolTableRegisterStringsIfNeeded(OBJCSymbolTable *symbolTable){
|
||||
static OBJCArray *unlinkedObjects=NULL;
|
||||
|
||||
unsigned long offset=symbolTable->classCount+symbolTable->categoryCount;
|
||||
OBJCStaticInstanceList **listOfLists=symbolTable->definitions[offset];
|
||||
|
||||
if(unlinkedObjects!=NULL){
|
||||
int count=unlinkedObjects->count;
|
||||
|
||||
while(--count>=0){
|
||||
OBJCStaticInstanceList *staticInstances=OBJCArrayItemAtIndex(unlinkedObjects,count);
|
||||
Class class=objc_lookUpClass(staticInstances->name);
|
||||
|
||||
if(class!=Nil){
|
||||
unsigned i;
|
||||
|
||||
for(i=0;staticInstances->instances[i]!= nil;i++)
|
||||
staticInstances->instances[i]->isa = class;
|
||||
|
||||
OBJCArrayRemoveItemAtIndex(unlinkedObjects,count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(listOfLists!=NULL){
|
||||
for (;*listOfLists != NULL;listOfLists++) {
|
||||
OBJCStaticInstanceList *staticInstances=*listOfLists;
|
||||
Class class=objc_lookUpClass(staticInstances->name);
|
||||
unsigned i;
|
||||
|
||||
if(class!=Nil){
|
||||
for(i=0;staticInstances->instances[i]!= nil;i++)
|
||||
staticInstances->instances[i]->isa = class;
|
||||
}
|
||||
else {
|
||||
if(unlinkedObjects==NULL)
|
||||
unlinkedObjects=OBJCArrayNew();
|
||||
|
||||
OBJCArrayAdd(unlinkedObjects,staticInstances);
|
||||
}
|
||||
static OBJCArray *unlinkedObjects=NULL;
|
||||
|
||||
unsigned long offset=symbolTable->classCount+symbolTable->categoryCount;
|
||||
OBJCStaticInstanceList **listOfLists=symbolTable->definitions[offset];
|
||||
|
||||
if(unlinkedObjects!=NULL){
|
||||
int count=unlinkedObjects->count;
|
||||
|
||||
while(--count>=0){
|
||||
OBJCStaticInstanceList *staticInstances=OBJCArrayItemAtIndex(unlinkedObjects,count);
|
||||
Class class=objc_lookUpClass(staticInstances->name);
|
||||
|
||||
if(class!=Nil) {
|
||||
unsigned i;
|
||||
|
||||
for(i=0;staticInstances->instances[i]!= nil;i++)
|
||||
staticInstances->instances[i]->isa = class;
|
||||
|
||||
OBJCArrayRemoveItemAtIndex(unlinkedObjects,count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(listOfLists!=NULL){
|
||||
for (;*listOfLists != NULL;listOfLists++) {
|
||||
OBJCStaticInstanceList *staticInstances=*listOfLists;
|
||||
Class class=objc_lookUpClass(staticInstances->name);
|
||||
unsigned i;
|
||||
|
||||
if(class!=Nil){
|
||||
for(i=0;staticInstances->instances[i]!= nil;i++)
|
||||
staticInstances->instances[i]->isa = class;
|
||||
}
|
||||
else {
|
||||
if(unlinkedObjects==NULL)
|
||||
unlinkedObjects=OBJCArrayNew();
|
||||
|
||||
OBJCArrayAdd(unlinkedObjects,staticInstances);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void OBJCSymbolTableRegisterProtocolsIfNeeded(OBJCSymbolTable *symbolTable){
|
||||
|
@ -59,7 +59,7 @@ void OBJCRegisterProtocol(OBJCProtocolTemplate *template) {
|
||||
|
||||
if(instanceMethods!=NULL)
|
||||
for(i=0;i<instanceMethods->count;i++)
|
||||
if(instanceMethods->list[i].name==selector)
|
||||
if(instanceMethods->list[i].name==sel_getSelector(selector))
|
||||
return &instanceMethods->list[i];
|
||||
|
||||
list=childProtocols;
|
||||
@ -70,7 +70,7 @@ void OBJCRegisterProtocol(OBJCProtocolTemplate *template) {
|
||||
unsigned k;
|
||||
|
||||
for(k=0;k<list->list[j]->instanceMethods->count;k++)
|
||||
if(list->list[j]->instanceMethods->list[k].name==selector)
|
||||
if(list->list[j]->instanceMethods->list[k].name==sel_getSelector(selector))
|
||||
return &list->list[j]->instanceMethods->list[k];
|
||||
}
|
||||
list=list->next;
|
||||
@ -85,7 +85,7 @@ void OBJCRegisterProtocol(OBJCProtocolTemplate *template) {
|
||||
|
||||
if(classMethods!=NULL)
|
||||
for(i=0;i<classMethods->count;i++)
|
||||
if(classMethods->list[i].name==selector)
|
||||
if(classMethods->list[i].name==sel_getSelector(selector))
|
||||
return &classMethods->list[i];
|
||||
|
||||
list=childProtocols;
|
||||
@ -96,7 +96,7 @@ void OBJCRegisterProtocol(OBJCProtocolTemplate *template) {
|
||||
unsigned k;
|
||||
|
||||
for (k=0;k<list->list[j]->classMethods->count;k++)
|
||||
if(list->list[j]->classMethods->list[k].name==selector)
|
||||
if(list->list[j]->classMethods->list[k].name==sel_getSelector(selector))
|
||||
return &list->list[j]->classMethods->list[k];
|
||||
}
|
||||
list=list->next;
|
||||
|
@ -58,6 +58,10 @@ id objc_lookUpClass(const char *className) {
|
||||
return result;
|
||||
}
|
||||
|
||||
id objc_lookup_class(const char *className) {
|
||||
return objc_lookUpClass(className);
|
||||
}
|
||||
|
||||
id objc_getClass(const char *name) {
|
||||
id result;
|
||||
|
||||
@ -240,9 +244,9 @@ Ivar class_getClassVariable(Class cls,const char *name) {
|
||||
|
||||
static inline struct objc_method *OBJCLookupUniqueIdInMethodList(struct objc_method_list *list,SEL uniqueId){
|
||||
int i;
|
||||
|
||||
|
||||
for(i=0;i<list->method_count;i++){
|
||||
if(((SEL)list->method_list[i].method_name)==uniqueId)
|
||||
if(((SEL)list->method_list[i].method_name)==sel_getSelector(uniqueId))
|
||||
return list->method_list+i;
|
||||
}
|
||||
|
||||
@ -769,7 +773,7 @@ static void OBJCCreateCacheForClass(Class class){
|
||||
}
|
||||
|
||||
void OBJCRegisterClass(Class class) {
|
||||
|
||||
|
||||
{
|
||||
struct objc_class* futureClass=OBJCHashValueForKey(OBJCFutureClassTable(), class->name);
|
||||
|
||||
@ -778,7 +782,7 @@ void OBJCRegisterClass(Class class) {
|
||||
class=futureClass;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pthread_mutex_lock(&classTableLock);
|
||||
OBJCHashInsertValueForKey(OBJCClassTable(), class->name, class);
|
||||
pthread_mutex_unlock(&classTableLock);
|
||||
@ -836,18 +840,18 @@ void OBJCRegisterCategoryInClass(Category category,Class class) {
|
||||
}
|
||||
|
||||
static void OBJCLinkClass(Class class) {
|
||||
if(!(class->info&CLASS_INFO_LINKED)){
|
||||
Class superClass=objc_lookUpClass((const char *)class->super_class);
|
||||
Class metaRoot=objc_lookUpClass((const char *)class->isa->isa);
|
||||
|
||||
if(superClass!=NULL && metaRoot!= NULL){
|
||||
class->super_class=superClass;
|
||||
class->info|=CLASS_INFO_LINKED;
|
||||
class->isa->super_class=class->super_class->isa;
|
||||
class->isa->info|=CLASS_INFO_LINKED;
|
||||
class->isa->isa=metaRoot->isa;
|
||||
}
|
||||
}
|
||||
if(!(class->info&CLASS_INFO_LINKED)){
|
||||
Class superClass=(class->super_class==NULL)?NULL:objc_lookUpClass((const char *)class->super_class);
|
||||
Class metaRoot=(class->isa->isa==NULL)?NULL:objc_lookUpClass((const char *)class->isa->isa);
|
||||
|
||||
if(superClass!=NULL){
|
||||
class->super_class=superClass;
|
||||
class->info|=CLASS_INFO_LINKED;
|
||||
class->isa->super_class=class->super_class->isa;
|
||||
class->isa->info|=CLASS_INFO_LINKED;
|
||||
class->isa->isa=(metaRoot==NULL)?NULL:metaRoot->isa;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OBJCLinkClassTable(void) {
|
||||
@ -910,10 +914,10 @@ IMP OBJCInitializeLookupAndCacheUniqueIdForObject(id object,SEL selector){
|
||||
Class checkInit=(class->info&CLASS_INFO_META)?(Class)object:class;
|
||||
OBJCInitializeClass(checkInit);
|
||||
}
|
||||
|
||||
IMP result=class_getMethodImplementation(class,selector);
|
||||
|
||||
if(result==NULL){
|
||||
|
||||
IMP result=class_getMethodImplementation(class,selector);
|
||||
|
||||
if(result==NULL){
|
||||
result=objc_forwardHandler;
|
||||
}
|
||||
return result;
|
||||
|
@ -27,8 +27,8 @@ IMP objc_msg_lookup(id object,SEL selector) {
|
||||
|
||||
do{
|
||||
struct objc_method *check=checkEntry->method;
|
||||
|
||||
if(((SEL)check->method_name)==selector)
|
||||
|
||||
if(((SEL)check->method_name)==sel_getSelector(selector))
|
||||
return check->method_imp;
|
||||
|
||||
checkEntry=((void *)checkEntry)+checkEntry->offsetToNextEntry;
|
||||
@ -45,7 +45,7 @@ IMP objc_msg_lookup_super(struct objc_super *super,SEL selector) {
|
||||
do{
|
||||
struct objc_method *check=checkEntry->method;
|
||||
|
||||
if(((SEL)check->method_name)==selector)
|
||||
if(((SEL)check->method_name)==sel_getSelector(selector))
|
||||
return check->method_imp;
|
||||
|
||||
checkEntry=((void *)checkEntry)+checkEntry->offsetToNextEntry;
|
||||
|
@ -9,5 +9,50 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
#import <objc/objc.h>
|
||||
#import <objc/objc-class.h>
|
||||
|
||||
OBJC_EXPORT SEL sel_registerNameNoCopy(const char *name);
|
||||
OBJC_EXPORT const char *sel_registerNameNoCopy(const char *name);
|
||||
|
||||
OBJC_EXPORT SEL sel_registerSelectorNoCopyName(const char *name);
|
||||
|
||||
#ifdef OBJC_TYPED_SELECTORS
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
const char *types;
|
||||
} objc_selector_internal;
|
||||
|
||||
static inline const char *objc_getSelectorReferenceName(objc_selector_internal *ref) {
|
||||
return ref->name;
|
||||
}
|
||||
|
||||
static inline void objc_setSelectorReferenceName(objc_selector_internal **ref,const char *name) {
|
||||
(*ref)->name=name;
|
||||
}
|
||||
|
||||
static inline SEL sel_getSelector(SEL selector) {
|
||||
if(selector==NULL)
|
||||
return selector;
|
||||
|
||||
struct {
|
||||
SEL selector;
|
||||
} *typed=(void *)selector;
|
||||
|
||||
return typed->selector;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
typedef SEL objc_selector_internal;
|
||||
|
||||
static inline const char *objc_getSelectorReferenceName(objc_selector_internal *ref) {
|
||||
return *ref;
|
||||
}
|
||||
|
||||
static inline void objc_setSelectorReferenceName(objc_selector_internal **ref,const char *name) {
|
||||
**ref=name;
|
||||
}
|
||||
|
||||
static inline SEL sel_getSelector(SEL selector) {
|
||||
return selector;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -15,20 +15,45 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
#define INITIAL_SELECTOR_TABLE_SIZE 4096 // Big System has about 3700 selectors
|
||||
|
||||
static OBJCHashTable *nameToNumber=NULL;
|
||||
static OBJCHashTable *nameToSelector=NULL;
|
||||
|
||||
SEL sel_registerNameNoCopy(const char *name){
|
||||
const char *sel_registerNameNoCopy(const char *name) {
|
||||
const char *result;
|
||||
|
||||
if(nameToNumber==NULL)
|
||||
nameToNumber=OBJCCreateHashTable(INITIAL_SELECTOR_TABLE_SIZE);
|
||||
|
||||
result=OBJCHashValueForKey(nameToNumber,name);
|
||||
|
||||
if(result==NULL){
|
||||
result=OBJCHashInsertValueForKey(nameToNumber,name,name);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SEL sel_registerSelectorNoCopyName(const char *name){
|
||||
#ifndef OBJC_TYPED_SELECTORS
|
||||
return sel_registerNameNoCopy(name);
|
||||
#else
|
||||
SEL result;
|
||||
|
||||
if(nameToNumber==NULL)
|
||||
nameToNumber=OBJCCreateHashTable(INITIAL_SELECTOR_TABLE_SIZE);
|
||||
if(nameToSelector==NULL)
|
||||
nameToSelector=OBJCCreateHashTable(INITIAL_SELECTOR_TABLE_SIZE);
|
||||
|
||||
result=(SEL)OBJCHashValueForKey(nameToNumber,name);
|
||||
result=(SEL)OBJCHashValueForKey(nameToSelector,name);
|
||||
|
||||
if(result==NULL){
|
||||
result=(SEL)OBJCHashInsertValueForKey(nameToNumber,name, (char*)name);
|
||||
objc_selector_internal *ughp;
|
||||
|
||||
ughp=objc_malloc(sizeof(objc_selector_internal));
|
||||
ughp->name=sel_registerNameNoCopy(name);
|
||||
|
||||
result=(SEL)OBJCHashInsertValueForKey(nameToSelector,(char*)name,ughp);
|
||||
}
|
||||
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -38,30 +63,50 @@ const char *sel_getName(SEL selector) {
|
||||
|
||||
if(nameToNumber==NULL)
|
||||
return NULL;
|
||||
|
||||
|
||||
selector=sel_getSelector(selector);
|
||||
|
||||
return (const char*)OBJCHashValueForKey(nameToNumber, selector);
|
||||
}
|
||||
|
||||
SEL sel_getUid(const char *selectorName) {
|
||||
SEL result;
|
||||
SEL result;
|
||||
|
||||
if(nameToNumber==NULL)
|
||||
#ifndef OBJC_TYPED_SELECTORS
|
||||
if(nameToNumber==NULL)
|
||||
result=NULL;
|
||||
else
|
||||
result=(SEL)OBJCHashValueForKey(nameToNumber,selectorName);
|
||||
|
||||
if(result==NULL){
|
||||
char *copy=objc_malloc(sizeof(char)*(strlen(selectorName)+1));
|
||||
|
||||
strcpy(copy,selectorName);
|
||||
result=(SEL)sel_registerNameNoCopy(copy);
|
||||
}
|
||||
#else
|
||||
if(nameToSelector==NULL)
|
||||
result=NULL;
|
||||
else
|
||||
result=(SEL)OBJCHashValueForKey(nameToNumber,selectorName);
|
||||
result=(SEL)OBJCHashValueForKey(nameToSelector,selectorName);
|
||||
|
||||
if(result==NULL){
|
||||
if(result==NULL){
|
||||
char *copy=objc_malloc(sizeof(char)*(strlen(selectorName)+1));
|
||||
|
||||
strcpy(copy,selectorName);
|
||||
result=(SEL)sel_registerNameNoCopy(copy);
|
||||
|
||||
result=sel_registerSelectorNoCopyName(copy);
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL sel_isEqual(SEL selector,SEL other) {
|
||||
return (selector==other)?YES:NO;
|
||||
selector=sel_getSelector(selector);
|
||||
other=sel_getSelector(other);
|
||||
|
||||
return (selector==other)?YES:NO;
|
||||
}
|
||||
|
||||
SEL sel_registerName(const char *cString){
|
||||
|
Loading…
x
Reference in New Issue
Block a user