]> git.saurik.com Git - cycript.git/blobdiff - ObjectiveC/Library.mm
Removed all global cache objects, placing them in a object in the context.
[cycript.git] / ObjectiveC / Library.mm
index a3c1d66b9b784af87a6995630a59e016a231669c..de56719ebb52bbd373fe9a2ecdca4c34e82a4872 100644 (file)
@@ -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<id, JSValueRef> 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<IMP>(&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<IMP>(&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,