Added property support functions, NSBlock base classes and uncaught exception handler.

main
theraven 16 years ago
parent 40da5b6b50
commit baed61c3e6

@ -5,12 +5,14 @@ LIBRARY_NAME = libobjc
libobjc_VERSION = 4
libobjc_OBJC_FILES = \
blocks_runtime.m\
linking.m\
mutation.m\
NSBlocks.m\
NXConstStr.m\
Object.m\
Protocol.m\
blocks_runtime.m\
linking.m\
mutation.m\
properties.m\
sync.m
@ -31,6 +33,7 @@ libobjc_C_FILES = \
selector.c\
sendmsg.c\
thr.c
libobjc_HEADER_FILES_DIR = objc
libobjc_HEADER_FILES_INSTALL_DIR = objc
libobjc_HEADER_FILES = \

@ -0,0 +1,56 @@
#import <Foundation/NSObject.h>
#import "objc/runtime.h"
#import "objc/blocks_runtime.h"
#include <assert.h>
struct objc_class _NSConcreteGlobalBlock;
struct objc_class _NSConcreteStackBlock;
@interface NSBlock : NSObject @end
void __objc_update_dispatch_table_for_class(Class);
extern struct sarray *__objc_uninstalled_dtable;
extern objc_mutex_t __objc_runtime_mutex;
static void createNSBlockSubclass(Class newClass, char *name)
{
Class superclass = [NSBlock class];
// Create the metaclass
Class metaClass = calloc(1, sizeof(struct objc_class));
// Initialize the metaclass
metaClass->class_pointer = superclass->class_pointer;
metaClass->super_class = superclass->class_pointer->super_class;
metaClass->info = _CLS_META;
metaClass->dtable = __objc_uninstalled_dtable;
// Set up the new class
newClass->class_pointer = metaClass;
newClass->super_class = superclass;
newClass->name = name;
newClass->info = _CLS_CLASS;
newClass->dtable = __objc_uninstalled_dtable;
// Initialize the dispatch table for the class and metaclass.
__objc_update_dispatch_table_for_class(metaClass);
__objc_update_dispatch_table_for_class(newClass);
CLS_SETINITIALIZED(metaClass);
CLS_SETINITIALIZED(newClass);
CLS_SETRESOLV(metaClass);
CLS_SETRESOLV(newClass);
// Add pointer from super class
objc_mutex_lock(__objc_runtime_mutex);
newClass->sibling_class = newClass->super_class->subclass_list;
newClass->super_class->subclass_list = newClass;
metaClass->sibling_class = metaClass->super_class->subclass_list;
metaClass->super_class->subclass_list = metaClass;
objc_mutex_unlock(__objc_runtime_mutex);
}
@implementation NSBlock
+ (void)load
{
createNSBlockSubclass(&_NSConcreteGlobalBlock, "_NSConcreteGlobalBlockPrivate");
createNSBlockSubclass(&_NSConcreteStackBlock, "_NSConcreteStackBlockPrivate");
}
@end

@ -27,6 +27,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
//#include <unwind.h>
#include "unwind-pe.h"
void (*__objc_unhandled_exception)(id) = 0;
__attribute__((weak)) int main(void);
#ifdef __ARM_EABI_UNWINDER__
@ -451,6 +455,13 @@ PERSONALITY_FUNCTION (int version,
install_context:
if (saw_cleanup == 0)
{
if (_Unwind_GetRegionStart(context) == (int)main)
{
if (__objc_unhandled_exception)
{
__objc_unhandled_exception(xh->value);
}
}
return_object = xh->value;
if (!(actions & _UA_SEARCH_PHASE))
_Unwind_DeleteException(&xh->base);

@ -315,6 +315,12 @@ id (*objc_proxy_lookup)(id receiver, SEL op) OBJC_NONPORTABLE;
*/
struct objc_slot *(*objc_msg_forward3)(id receiver, SEL op) OBJC_NONPORTABLE;
/**
* Runtime hook for unhandled exceptions. This is called if an exception is
* not caught.
*/
void (*__objc_unhandled_exception)(id);
// Global self so that self is a valid symbol everywhere. Will be replaced by
// a real self in an inner scope if there is one.
static const id self = nil;

@ -0,0 +1,47 @@
#include "objc/runtime.h"
// Subset of NSObject interface needed for properties.
@interface NSObject {}
- (id)retain;
- (id)copy;
- (id)autorelease;
- (void)release;
@end
id objc_getProperty(id obj, SEL _cmd, ptrdiff_t offset, BOOL isAtomic)
{
if (isAtomic)
{
@synchronized(obj) {
return objc_getProperty(obj, _cmd, offset, NO);
}
}
char *addr = (char*)obj;
addr += offset;
id ret = *(id*)addr;
return [[ret retain] autorelease];
}
void objc_setProperty(id obj, SEL _cmd, ptrdiff_t offset, id arg, BOOL isAtomic, BOOL isCopy)
{
if (isAtomic)
{
@synchronized(obj) {
objc_setProperty(obj, _cmd, offset, arg, NO, isCopy);
return;
}
}
if (isCopy)
{
arg = [arg copy];
}
else
{
arg = [arg retain];
}
char *addr = (char*)obj;
addr += offset;
id old = *(id*)addr;
*(id*)addr = arg;
[old release];
}

@ -606,7 +606,7 @@ static void merge_methods_from_superclass (Class class)
method_list = method_list->method_next;
}
}
while (super = super->super_class);
while ((super = super->super_class));
if (class->subclass_list) /* Traverse subclasses */
for (Class next = class->subclass_list; next; next = next->sibling_class)
merge_methods_from_superclass (next);

Loading…
Cancel
Save