X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/9567837688897dd742899612a9701fc590f54326..498c3570ae00dea1f54fb067e1d2c27435863e90:/ObjectiveC/Library.mm?ds=sidebyside diff --git a/ObjectiveC/Library.mm b/ObjectiveC/Library.mm index 83e4776..de56719 100644 --- a/ObjectiveC/Library.mm +++ b/ObjectiveC/Library.mm @@ -1,5 +1,7 @@ -#ifdef __APPLE__ +#if defined(__APPLE__) && defined(__arm__) #include +#else +#include #endif #include "ObjectiveC/Internal.hpp" @@ -18,7 +20,6 @@ #ifdef __APPLE__ #include -#include #include #include #endif @@ -73,13 +74,17 @@ #define method_getTypeEncoding(method) ((method)->method_types) #define method_setImplementation(method, imp) ((void) ((method)->method_imp = (imp))) +#undef objc_getClass +#define objc_getClass GSClassFromName + #define objc_getProtocol GSProtocolFromName #define object_getClass GSObjCClass #define object_getInstanceVariable(object, name, value) ({ \ objc_ivar *ivar(class_getInstanceVariable(object_getClass(object), name)); \ - GSObjCGetVariable(object, ivar_getOffset(ivar), sizeof(void *), value); \ + if (ivar != NULL) \ + GSObjCGetVariable(object, ivar_getOffset(ivar), sizeof(void *), value); \ ivar; \ }) @@ -188,6 +193,8 @@ CYUTF8String CYCastUTF8String(NSString *value) { } /* }}} */ +JSValueRef CYCastJSValue(JSContextRef context, NSObject *value); + void CYThrow(JSContextRef context, NSException *error, JSValueRef *exception) { if (exception == NULL) throw error; @@ -217,13 +224,13 @@ static JSClassRef ObjectiveC_Image_Classes_; static JSClassRef ObjectiveC_Images_; #endif -static JSObjectRef Instance_prototype_; - #ifdef __APPLE__ static Class NSCFBoolean_; static Class NSCFType_; static Class NSMessageBuilder_; static Class NSZombie_; +#else +static Class NSBoolNumber_; #endif static Class NSArray_; @@ -244,7 +251,7 @@ Type_privateData *Selector_privateData::GetType() const { // XXX: trick this out with associated objects! JSValueRef CYGetClassPrototype(JSContextRef context, id self) { if (self == nil) - return Instance_prototype_; + return CYGetCachedObject(context, CYJSString("Instance_prototype")); // XXX: I need to think through multi-context typedef std::map CacheMap; @@ -258,9 +265,9 @@ JSValueRef CYGetClassPrototype(JSContextRef context, id self) { JSValueRef prototype; if (self == NSArray_) - prototype = Array_prototype_; + prototype = CYGetCachedObject(context, CYJSString("Array_prototype")); else if (self == NSDictionary_) - prototype = Object_prototype_; + prototype = CYGetCachedObject(context, CYJSString("Object_prototype")); else prototype = CYGetClassPrototype(context, class_getSuperclass(self)); @@ -547,8 +554,9 @@ NSObject *NSCFType$cy$toJSON(id self, SEL sel, NSString *key) { /* }}} */ NSObject *CYCastNSObject_(apr_pool_t *pool, JSContextRef context, JSObjectRef object) { + JSObjectRef Array(CYGetCachedObject(context, Array_s)); JSValueRef exception(NULL); - bool array(JSValueIsInstanceOfConstructor(context, object, Array_, &exception)); + bool array(JSValueIsInstanceOfConstructor(context, object, Array, &exception)); CYThrow(context, exception); id value(array ? [CYJSArray alloc] : [CYJSObject alloc]); return CYPoolRelease(pool, [value initWithJSObject:object inContext:context]); @@ -567,6 +575,12 @@ NSNumber *CYCopyNSNumber(JSContextRef context, JSValueRef value) { return [[NSNumber alloc] initWithDouble:CYCastDouble(context, value)]; } +#ifndef __APPLE__ +@interface NSBoolNumber : NSNumber { +} +@end +#endif + id CYNSObject(apr_pool_t *pool, JSContextRef context, JSValueRef value, bool cast) { id object; bool copy; @@ -586,7 +600,7 @@ id CYNSObject(apr_pool_t *pool, JSContextRef context, JSValueRef value, bool cas object = (id) (CYCastBool(context, value) ? kCFBooleanTrue : kCFBooleanFalse); copy = false; #else - object = [[NSNumber alloc] initWithBool:CYCastBool(context, value)]; + object = [[NSBoolNumber alloc] initWithBool:CYCastBool(context, value)]; copy = true; #endif break; @@ -701,6 +715,29 @@ NSObject *CYCopyNSObject(apr_pool_t *pool, JSContextRef context, JSValueRef valu @end /* }}} */ +/* Bridge: NSBoolNumber {{{ */ +#ifndef __APPLE__ +@implementation NSBoolNumber (Cycript) + +- (JSType) cy$JSType { + return kJSTypeBoolean; +} + +- (NSObject *) cy$toJSON:(NSString *)key { + return self; +} + +- (NSString *) cy$toCYON { + return [self boolValue] ? @"true" : @"false"; +} + +- (JSValueRef) cy$JSValueInContext:(JSContextRef)context { CYObjectiveTry_(context) { + return CYCastJSValue(context, (bool) [self boolValue]); +} CYObjectiveCatch } + +@end +#endif +/* }}} */ /* Bridge: NSDictionary {{{ */ @implementation NSDictionary (Cycript) @@ -710,10 +747,10 @@ NSObject *CYCopyNSObject(apr_pool_t *pool, JSContextRef context, JSValueRef valu bool comma(false); #ifdef __APPLE__ - for (id key in self) { + for (NSObject *key in self) { #else NSEnumerator *keys([self keyEnumerator]); - while (id key = [keys nextObject]) { + while (NSObject *key = [keys nextObject]) { #endif if (comma) [json appendString:@","]; @@ -741,10 +778,10 @@ NSObject *CYCopyNSObject(apr_pool_t *pool, JSContextRef context, JSValueRef valu [super cy$getPropertyNames:names inContext:context]; #ifdef __APPLE__ - for (NSString *key in self) { + for (NSObject *key in self) { #else NSEnumerator *keys([self keyEnumerator]); - while (NSString *key = [keys nextObject]) { + while (NSObject *key = [keys nextObject]) { #endif JSPropertyNameAccumulatorAddName(names, CYJSString(context, key)); } @@ -1001,32 +1038,34 @@ NSArray *CYCastNSArray(JSContextRef context, JSPropertyNameArrayRef names) { return array; } -JSValueRef CYCastJSValue(JSContextRef context, id value) { CYPoolTry { +JSValueRef CYCastJSValue(JSContextRef context, NSObject *value) { CYPoolTry { if (value == nil) return CYJSNull(context); else if ([value respondsToSelector:@selector(cy$JSValueInContext:)]) return [value cy$JSValueInContext:context]; else return CYMakeInstance(context, value, false); -} CYPoolCatch(NULL) } +} CYPoolCatch(NULL) return /*XXX*/ NULL; } @implementation CYJSObject - (id) initWithJSObject:(JSObjectRef)object inContext:(JSContextRef)context { CYObjectiveTry { if ((self = [super init]) != nil) { object_ = object; - context_ = context; + context_ = CYGetJSContext(context); + //XXX:JSGlobalContextRetain(context_); JSValueProtect(context_, object_); } return self; } CYObjectiveCatch } - (void) dealloc { CYObjectiveTry { JSValueUnprotect(context_, object_); + //XXX:JSGlobalContextRelease(context_); [super dealloc]; } CYObjectiveCatch } - (NSObject *) cy$toJSON:(NSString *)key { CYObjectiveTry { - JSValueRef toJSON(CYGetProperty(context_, object_, toJSON_)); + JSValueRef toJSON(CYGetProperty(context_, object_, toJSON_s)); if (!CYIsCallable(context_, toJSON)) return [super cy$toJSON:key]; else { @@ -1056,8 +1095,7 @@ JSValueRef CYCastJSValue(JSContextRef context, id value) { CYPoolTry { } CYObjectiveCatch } - (id) objectForKey:(id)key { CYObjectiveTry { - // XXX: are NSDictionary keys always NSString *? - JSValueRef value(CYGetProperty(context_, object_, CYJSString(context_, (NSString *) key))); + JSValueRef value(CYGetProperty(context_, object_, CYJSString(context_, (NSObject *) key))); if (JSValueIsUndefined(context_, value)) return nil; return CYCastNSObject(NULL, context_, value) ?: [NSNull null]; @@ -1071,14 +1109,12 @@ JSValueRef CYCastJSValue(JSContextRef context, id value) { CYPoolTry { } CYObjectiveCatch } - (void) setObject:(id)object forKey:(id)key { CYObjectiveTry { - // XXX: are NSDictionary keys always NSString *? - CYSetProperty(context_, object_, CYJSString(context_, (NSString *) key), CYCastJSValue(context_, object)); + CYSetProperty(context_, object_, CYJSString(context_, (NSObject *) key), CYCastJSValue(context_, (NSString *) object)); } CYObjectiveCatch } - (void) removeObjectForKey:(id)key { CYObjectiveTry { JSValueRef exception(NULL); - // XXX: are NSDictionary keys always NSString *? - (void) JSObjectDeleteProperty(context_, object_, CYJSString(context_, (NSString *) key), &exception); + (void) JSObjectDeleteProperty(context_, object_, CYJSString(context_, (NSObject *) key), &exception); CYThrow(context_, exception); } CYObjectiveCatch } @@ -1089,18 +1125,20 @@ JSValueRef CYCastJSValue(JSContextRef context, id value) { CYPoolTry { - (id) initWithJSObject:(JSObjectRef)object inContext:(JSContextRef)context { CYObjectiveTry { if ((self = [super init]) != nil) { object_ = object; - context_ = context; + context_ = CYGetJSContext(context); + //XXX:JSGlobalContextRetain(context_); JSValueProtect(context_, object_); } return self; } CYObjectiveCatch } - (void) dealloc { CYObjectiveTry { JSValueUnprotect(context_, object_); + //XXX:JSGlobalContextRelease(context_); [super dealloc]; } CYObjectiveCatch } - (NSUInteger) count { CYObjectiveTry { - return CYCastDouble(context_, CYGetProperty(context_, object_, length_)); + return CYCastDouble(context_, CYGetProperty(context_, object_, length_s)); } CYObjectiveCatch } - (id) objectAtIndex:(NSUInteger)index { CYObjectiveTry { @@ -1116,8 +1154,9 @@ JSValueRef CYCastJSValue(JSContextRef context, id value) { CYPoolTry { - (void) addObject:(id)object { CYObjectiveTry { JSValueRef exception(NULL); JSValueRef arguments[1]; - arguments[0] = CYCastJSValue(context_, object); - JSObjectCallAsFunction(context_, Array_push_, object_, 1, arguments, &exception); + arguments[0] = CYCastJSValue(context_, (NSObject *) object); + JSObjectRef Array(CYGetCachedObject(context_, Array_s)); + JSObjectCallAsFunction(context_, CYCastJSObject(context_, CYGetProperty(context_, Array, push_s)), object_, 1, arguments, &exception); CYThrow(context_, exception); } CYObjectiveCatch } @@ -1129,14 +1168,16 @@ JSValueRef CYCastJSValue(JSContextRef context, id value) { CYPoolTry { JSValueRef arguments[3]; arguments[0] = CYCastJSValue(context_, index); arguments[1] = CYCastJSValue(context_, 0); - arguments[2] = CYCastJSValue(context_, object); - JSObjectCallAsFunction(context_, Array_splice_, object_, 3, arguments, &exception); + arguments[2] = CYCastJSValue(context_, (NSObject *) object); + JSObjectRef Array(CYGetCachedObject(context_, Array_s)); + JSObjectCallAsFunction(context_, CYCastJSObject(context_, CYGetProperty(context_, Array, splice_s)), object_, 3, arguments, &exception); CYThrow(context_, exception); } CYObjectiveCatch } - (void) removeLastObject { CYObjectiveTry { JSValueRef exception(NULL); - JSObjectCallAsFunction(context_, Array_pop_, object_, 0, NULL, &exception); + JSObjectRef Array(CYGetCachedObject(context_, Array_s)); + JSObjectCallAsFunction(context_, CYCastJSObject(context_, CYGetProperty(context_, Array, pop_s)), object_, 0, NULL, &exception); CYThrow(context_, exception); } CYObjectiveCatch } @@ -1148,7 +1189,8 @@ JSValueRef CYCastJSValue(JSContextRef context, id value) { CYPoolTry { JSValueRef arguments[2]; arguments[0] = CYCastJSValue(context_, index); arguments[1] = CYCastJSValue(context_, 1); - JSObjectCallAsFunction(context_, Array_splice_, object_, 2, arguments, &exception); + JSObjectRef Array(CYGetCachedObject(context_, Array_s)); + JSObjectCallAsFunction(context_, CYCastJSObject(context_, CYGetProperty(context_, Array, splice_s)), object_, 2, arguments, &exception); CYThrow(context_, exception); } CYObjectiveCatch } @@ -1156,7 +1198,7 @@ JSValueRef CYCastJSValue(JSContextRef context, id value) { CYPoolTry { size_t bounds([self count]); if (index >= bounds) @throw [NSException exceptionWithName:NSRangeException reason:[NSString stringWithFormat:@"*** -[CYJSArray replaceObjectAtIndex:withObject:]: index (%zu) beyond bounds (%zu)", index, bounds] userInfo:nil]; - CYSetProperty(context_, object_, index, CYCastJSValue(context_, object)); + CYSetProperty(context_, object_, index, CYCastJSValue(context_, (NSObject *) object)); } CYObjectiveCatch } @end @@ -1241,19 +1283,21 @@ void CYObjectiveC_ExecuteEnd(JSContextRef context, void *handle) { return [(NSAutoreleasePool *) handle release]; } -JSValueRef CYObjectiveC_RuntimeProperty(JSContextRef context, CYUTF8String name) { CYObjectiveTry_(context) { +JSValueRef CYObjectiveC_RuntimeProperty(JSContextRef context, CYUTF8String name) { CYPoolTry { if (name == "nil") return Instance::Make(context, nil); if (Class _class = objc_getClass(name.data)) return CYMakeInstance(context, _class, true); return NULL; -} CYObjectiveCatch } +} CYPoolCatch(NULL) return /*XXX*/ NULL; } -static void CYObjectiveC_CallFunction(JSContextRef context, ffi_cif *cif, void (*function)(), uint8_t *value, void **values) { CYObjectiveTry_(context) { +static void CYObjectiveC_CallFunction(JSContextRef context, ffi_cif *cif, void (*function)(), uint8_t *value, void **values) { @try { ffi_call(cif, function, value, values); -} CYObjectiveCatch } +} @catch (NSException *error ) { + throw CYJSError(context, CYCastJSValue(context, error)); +} } -static bool CYObjectiveC_PoolFFI(apr_pool_t *pool, JSContextRef context, sig::Type *type, ffi_type *ffi, void *data, JSValueRef value) { CYObjectiveTry_(context) { +static bool CYObjectiveC_PoolFFI(apr_pool_t *pool, JSContextRef context, sig::Type *type, ffi_type *ffi, void *data, JSValueRef value) { CYPoolTry { switch (type->primitive) { case sig::object_P: case sig::typename_P: @@ -1269,12 +1313,12 @@ static bool CYObjectiveC_PoolFFI(apr_pool_t *pool, JSContextRef context, sig::Ty } return true; -} CYObjectiveCatch } +} CYPoolCatch(false) return /*XXX*/ NULL; } -static JSValueRef CYObjectiveC_FromFFI(JSContextRef context, sig::Type *type, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) { CYObjectiveTry_(context) { +static JSValueRef CYObjectiveC_FromFFI(JSContextRef context, sig::Type *type, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) { CYPoolTry { switch (type->primitive) { case sig::object_P: - if (id object = *reinterpret_cast(data)) { + if (NSObject *object = *reinterpret_cast(data)) { JSValueRef value(CYCastJSValue(context, object)); if (initialize) [object release]; @@ -1294,13 +1338,13 @@ static JSValueRef CYObjectiveC_FromFFI(JSContextRef context, sig::Type *type, ff default: return NULL; } -} CYObjectiveCatch } +} CYPoolCatch(NULL) return /*XXX*/ NULL; } static bool CYImplements(id object, Class _class, SEL selector, bool devoid) { if (objc_method *method = class_getInstanceMethod(_class, selector)) { if (!devoid) return true; -#ifdef __OBJC2__ +#if OBJC_API_VERSION >= 2 char type[16]; method_getReturnType(method, type, sizeof(type)); #else @@ -1447,7 +1491,7 @@ static bool Messages_setProperty(JSContextRef context, JSObjectRef object, JSStr return true; } -#if 0 && !__OBJC2__ +#if 0 && OBJC_API_VERSION < 2 static bool Messages_deleteProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { Messages *internal(reinterpret_cast(JSObjectGetPrivate(object))); Class _class(internal->GetValue()); @@ -1470,7 +1514,7 @@ static void Messages_getPropertyNames(JSContextRef context, JSObjectRef object, Messages *internal(reinterpret_cast(JSObjectGetPrivate(object))); Class _class(internal->GetValue()); -#ifdef __OBJC2__ +#if OBJC_API_VERSION >= 2 unsigned int size; objc_method **data(class_copyMethodList(_class, &size)); for (size_t i(0); i != size; ++i) @@ -1624,7 +1668,7 @@ static bool Instance_deleteProperty(JSContextRef context, JSObjectRef object, JS NSString *name(CYCastNSString(NULL, context, property)); return [self cy$deleteProperty:name]; } CYPoolCatch(NULL) -} CYCatch } +} CYCatch return /*XXX*/ NULL; } static void Instance_getPropertyNames(JSContextRef context, JSObjectRef object, JSPropertyNameAccumulatorRef names) { Instance *internal(reinterpret_cast(JSObjectGetPrivate(object))); @@ -1693,6 +1737,7 @@ static JSValueRef Internal_getProperty(JSContextRef context, JSObjectRef object, if (objc_ivar *ivar = object_getInstanceVariable(self, name, NULL)) { Type_privateData type(pool, ivar_getTypeEncoding(ivar)); + // XXX: if this fails and throws an exception the person we are throwing it to gets the wrong exception return CYFromFFI(context, type.type_, type.GetFFI(), reinterpret_cast(self) + ivar_getOffset(ivar)); } @@ -1719,7 +1764,7 @@ static void Internal_getPropertyNames_(Class _class, JSPropertyNameAccumulatorRe if (Class super = class_getSuperclass(_class)) Internal_getPropertyNames_(super, names); -#ifdef __OBJC2__ +#if OBJC_API_VERSION >= 2 unsigned int size; objc_ivar **data(class_copyIvarList(_class, &size)); for (size_t i(0); i != size; ++i) @@ -1782,7 +1827,7 @@ static void ObjectiveC_Classes_getPropertyNames(JSContextRef context, JSObjectRe #endif } -#ifdef __OBJC2__ +#if OBJC_API_VERSION >= 2 static JSValueRef ObjectiveC_Image_Classes_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry { const char *internal(reinterpret_cast(JSObjectGetPrivate(object))); @@ -1852,7 +1897,7 @@ static JSValueRef ObjectiveC_Protocols_getProperty(JSContextRef context, JSObjec } CYCatch } static void ObjectiveC_Protocols_getPropertyNames(JSContextRef context, JSObjectRef object, JSPropertyNameAccumulatorRef names) { -#ifdef __OBJC2__ +#if OBJC_API_VERSION >= 2 unsigned int size; Protocol **data(objc_copyProtocolList(&size)); for (size_t i(0); i != size; ++i) @@ -1959,7 +2004,7 @@ static JSValueRef $objc_msgSend(JSContextRef context, JSObjectRef object, JSObje } CYCatch } /* Hook: objc_registerClassPair {{{ */ -#ifdef __OBJC2__ +#if defined(__APPLE__) && defined(__arm__) // XXX: replace this with associated objects MSHook(void, CYDealloc, id self, SEL sel) { @@ -2060,7 +2105,7 @@ static JSValueRef CYValue_callAsFunction_$cya(JSContextRef context, JSObjectRef ffi = typical->ffi_; } - return CYMakePointer(context, &internal->value_, type, ffi, object); + return CYMakePointer(context, &internal->value_, _not(size_t), type, ffi, object); } static JSValueRef Instance_getProperty_constructor(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { @@ -2107,7 +2152,7 @@ static JSValueRef Instance_callAsFunction_toJSON(JSContextRef context, JSObjectR // XXX: check for support of cy$toJSON? return CYCastJSValue(context, CYJSString(context, [internal->GetValue() cy$toJSON:key])); } CYPoolCatch(NULL) -} CYCatch } +} CYCatch return /*XXX*/ NULL; } static JSValueRef Instance_callAsFunction_toString(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { if (!JSValueIsObjectOfClass(context, _this, Instance_)) @@ -2119,7 +2164,7 @@ static JSValueRef Instance_callAsFunction_toString(JSContextRef context, JSObjec // XXX: this seems like a stupid implementation; what if it crashes? why not use the CYONifier backend? return CYCastJSValue(context, CYJSString(context, [internal->GetValue() description])); } CYPoolCatch(NULL) -} CYCatch } +} CYCatch return /*XXX*/ NULL; } static JSValueRef Selector_callAsFunction_toString(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { Selector_privateData *internal(reinterpret_cast(JSObjectGetPrivate(_this))); @@ -2138,7 +2183,7 @@ static JSValueRef Selector_callAsFunction_toCYON(JSContextRef context, JSObjectR NSString *string([NSString stringWithFormat:@"@selector(%s)", name]); return CYCastJSValue(context, CYJSString(context, string)); } CYPoolCatch(NULL) -} CYCatch } +} CYCatch return /*XXX*/ NULL; } static JSValueRef Selector_callAsFunction_type(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { if (count != 1) @@ -2194,18 +2239,19 @@ static JSStaticFunction Selector_staticFunctions[5] = { {NULL, NULL, 0} }; -void CYObjectiveC_SetupContext(JSContextRef context) { - JSObjectRef global(CYGetGlobalObject(context)); +void CYObjectiveC_Initialize() { /*XXX*/ JSContextRef context(NULL); CYPoolTry { apr_pool_t *pool(CYGetGlobalPool()); - Object_type = new(pool) Type_privateData(pool, "@"); - Selector_type = new(pool) Type_privateData(pool, ":"); + Object_type = new(pool) Type_privateData("@"); + Selector_type = new(pool) Type_privateData(":"); #ifdef __APPLE__ NSCFBoolean_ = objc_getClass("NSCFBoolean"); NSCFType_ = objc_getClass("NSCFType"); NSMessageBuilder_ = objc_getClass("NSMessageBuilder"); NSZombie_ = objc_getClass("_NSZombie_"); +#else + NSBoolNumber_ = objc_getClass("NSBoolNumber"); #endif NSArray_ = objc_getClass("NSArray"); @@ -2250,7 +2296,7 @@ void CYObjectiveC_SetupContext(JSContextRef context) { definition.hasProperty = &Messages_hasProperty; definition.getProperty = &Messages_getProperty; definition.setProperty = &Messages_setProperty; -#if 0 && !__OBJC2__ +#if 0 && OBJC_API_VERSION < 2 definition.deleteProperty = &Messages_deleteProperty; #endif definition.getPropertyNames = &Messages_getPropertyNames; @@ -2277,19 +2323,7 @@ void CYObjectiveC_SetupContext(JSContextRef context) { definition.getPropertyNames = &ObjectiveC_Classes_getPropertyNames; ObjectiveC_Classes_ = JSClassCreate(&definition); - definition = kJSClassDefinitionEmpty; - definition.className = "ObjectiveC::Protocols"; - definition.getProperty = &ObjectiveC_Protocols_getProperty; - definition.getPropertyNames = &ObjectiveC_Protocols_getPropertyNames; - ObjectiveC_Protocols_ = JSClassCreate(&definition); - - JSObjectRef ObjectiveC(JSObjectMake(context, NULL, NULL)); - CYSetProperty(context, global, CYJSString("ObjectiveC"), ObjectiveC); - - CYSetProperty(context, ObjectiveC, CYJSString("classes"), JSObjectMake(context, ObjectiveC_Classes_, NULL)); - CYSetProperty(context, ObjectiveC, CYJSString("protocols"), JSObjectMake(context, ObjectiveC_Protocols_, NULL)); - -#ifdef __OBJC2__ +#if OBJC_API_VERSION >= 2 definition = kJSClassDefinitionEmpty; definition.className = "ObjectiveC::Images"; definition.getProperty = &ObjectiveC_Images_getProperty; @@ -2301,7 +2335,34 @@ void CYObjectiveC_SetupContext(JSContextRef context) { definition.getProperty = &ObjectiveC_Image_Classes_getProperty; definition.getPropertyNames = &ObjectiveC_Image_Classes_getPropertyNames; ObjectiveC_Image_Classes_ = JSClassCreate(&definition); +#endif + + definition = kJSClassDefinitionEmpty; + definition.className = "ObjectiveC::Protocols"; + definition.getProperty = &ObjectiveC_Protocols_getProperty; + definition.getPropertyNames = &ObjectiveC_Protocols_getPropertyNames; + ObjectiveC_Protocols_ = JSClassCreate(&definition); + +#if defined(__APPLE__) && defined(__arm__) + MSHookFunction(&objc_registerClassPair, MSHake(objc_registerClassPair)); +#endif + +#ifdef __APPLE__ + class_addMethod(NSCFType_, @selector(cy$toJSON:), reinterpret_cast(&NSCFType$cy$toJSON), "@12@0:4@8"); +#endif +} CYPoolCatch() } + +void CYObjectiveC_SetupContext(JSContextRef context) { CYPoolTry { + JSObjectRef global(CYGetGlobalObject(context)); + JSObjectRef cy(CYCastJSObject(context, CYGetProperty(context, global, cy_s))); + + JSObjectRef ObjectiveC(JSObjectMake(context, NULL, NULL)); + CYSetProperty(context, global, CYJSString("ObjectiveC"), ObjectiveC); + CYSetProperty(context, ObjectiveC, CYJSString("classes"), JSObjectMake(context, ObjectiveC_Classes_, NULL)); + CYSetProperty(context, ObjectiveC, CYJSString("protocols"), JSObjectMake(context, ObjectiveC_Protocols_, NULL)); + +#if OBJC_API_VERSION >= 2 CYSetProperty(context, ObjectiveC, CYJSString("images"), JSObjectMake(context, ObjectiveC_Images_, NULL)); #endif @@ -2310,33 +2371,30 @@ void CYObjectiveC_SetupContext(JSContextRef context) { JSObjectRef Selector(JSObjectMakeConstructor(context, Selector_, &Selector_new)); JSObjectRef Super(JSObjectMakeConstructor(context, Super_, &Super_new)); - Instance_prototype_ = (JSObjectRef) CYGetProperty(context, Instance, prototype_); - JSValueProtect(context, Instance_prototype_); + JSObjectRef Instance_prototype(CYCastJSObject(context, CYGetProperty(context, Instance, prototype_s))); + CYSetProperty(context, cy, CYJSString("Instance_prototype"), Instance_prototype); CYSetProperty(context, global, CYJSString("Instance"), Instance); CYSetProperty(context, global, CYJSString("Selector"), Selector); CYSetProperty(context, global, CYJSString("Super"), Super); -#ifdef __OBJC2__ +#if defined(__APPLE__) && defined(__arm__) CYSetProperty(context, global, CYJSString("objc_registerClassPair"), JSObjectMakeFunctionWithCallback(context, CYJSString("objc_registerClassPair"), &objc_registerClassPair_)); - MSHookFunction(&objc_registerClassPair, MSHake(objc_registerClassPair)); #endif CYSetProperty(context, global, CYJSString("objc_msgSend"), JSObjectMakeFunctionWithCallback(context, CYJSString("objc_msgSend"), &$objc_msgSend)); - JSObjectSetPrototype(context, (JSObjectRef) CYGetProperty(context, Message, prototype_), Function_prototype_); - JSObjectSetPrototype(context, (JSObjectRef) CYGetProperty(context, Selector, prototype_), Function_prototype_); - -#ifdef __APPLE__ - class_addMethod(NSCFType_, @selector(cy$toJSON:), reinterpret_cast(&NSCFType$cy$toJSON), "@12@0:4@8"); -#endif -} + JSObjectRef Function_prototype(CYGetCachedObject(context, CYJSString("Function_prototype"))); + JSObjectSetPrototype(context, CYCastJSObject(context, CYGetProperty(context, Message, prototype_s)), Function_prototype); + JSObjectSetPrototype(context, CYCastJSObject(context, CYGetProperty(context, Selector, prototype_s)), Function_prototype); +} CYPoolCatch() } static CYHooks CYObjectiveCHooks = { &CYObjectiveC_ExecuteStart, &CYObjectiveC_ExecuteEnd, &CYObjectiveC_RuntimeProperty, &CYObjectiveC_CallFunction, + &CYObjectiveC_Initialize, &CYObjectiveC_SetupContext, &CYObjectiveC_PoolFFI, &CYObjectiveC_FromFFI,