X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/bc60fb46c3973f1c8d84994d9f98a6270f9ae803..498c3570ae00dea1f54fb067e1d2c27435863e90:/ObjectiveC/Library.mm diff --git a/ObjectiveC/Library.mm b/ObjectiveC/Library.mm index a3c1d66..de56719 100644 --- a/ObjectiveC/Library.mm +++ b/ObjectiveC/Library.mm @@ -224,8 +224,6 @@ static JSClassRef ObjectiveC_Image_Classes_; static JSClassRef ObjectiveC_Images_; #endif -static JSObjectRef Instance_prototype_; - #ifdef __APPLE__ static Class NSCFBoolean_; static Class NSCFType_; @@ -253,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; @@ -267,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)); @@ -556,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]); @@ -748,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:@","]; @@ -779,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)); } @@ -1066,7 +1065,7 @@ JSValueRef CYCastJSValue(JSContextRef context, NSObject *value) { CYPoolTry { } 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 { @@ -1096,8 +1095,7 @@ JSValueRef CYCastJSValue(JSContextRef context, NSObject *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]; @@ -1111,14 +1109,12 @@ JSValueRef CYCastJSValue(JSContextRef context, NSObject *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_, (NSString *) 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 } @@ -1142,7 +1138,7 @@ JSValueRef CYCastJSValue(JSContextRef context, NSObject *value) { CYPoolTry { } 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 { @@ -1159,7 +1155,8 @@ JSValueRef CYCastJSValue(JSContextRef context, NSObject *value) { CYPoolTry { JSValueRef exception(NULL); JSValueRef arguments[1]; arguments[0] = CYCastJSValue(context_, (NSObject *) object); - JSObjectCallAsFunction(context_, Array_push_, object_, 1, arguments, &exception); + JSObjectRef Array(CYGetCachedObject(context_, Array_s)); + JSObjectCallAsFunction(context_, CYCastJSObject(context_, CYGetProperty(context_, Array, push_s)), object_, 1, arguments, &exception); CYThrow(context_, exception); } CYObjectiveCatch } @@ -1172,13 +1169,15 @@ JSValueRef CYCastJSValue(JSContextRef context, NSObject *value) { CYPoolTry { arguments[0] = CYCastJSValue(context_, index); arguments[1] = CYCastJSValue(context_, 0); arguments[2] = CYCastJSValue(context_, (NSObject *) object); - JSObjectCallAsFunction(context_, Array_splice_, object_, 3, arguments, &exception); + 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 } @@ -1190,7 +1189,8 @@ JSValueRef CYCastJSValue(JSContextRef context, NSObject *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 } @@ -2239,8 +2239,7 @@ 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("@"); @@ -2324,18 +2323,6 @@ 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)); - #if OBJC_API_VERSION >= 2 definition = kJSClassDefinitionEmpty; definition.className = "ObjectiveC::Images"; @@ -2348,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 @@ -2357,8 +2371,8 @@ 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); @@ -2366,24 +2380,21 @@ void CYObjectiveC_SetupContext(JSContextRef context) { #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,