]> git.saurik.com Git - cycript.git/blobdiff - ObjectiveC/Library.mm
Replace failed prototype trick with separate classes.
[cycript.git] / ObjectiveC / Library.mm
index f5fdb28a872a3ce07e7706e4d110394372427f3e..5b679cb86f5a0a238e0de75e8533cbc1f9c34e25 100644 (file)
@@ -234,6 +234,17 @@ bool CYGetOffset(apr_pool_t *pool, JSContextRef context, NSString *value, ssize_
 }
 
 static JSClassRef Instance_;
+static JSClassRef ArrayInstance_;
+static JSClassRef ObjectInstance_;
+static JSClassRef StringInstance_;
+
+static JSClassRef *Instances_[] = {
+    &Instance_,
+    &ArrayInstance_,
+    &ObjectInstance_,
+    &StringInstance_,
+};
+
 static JSClassRef Internal_;
 static JSClassRef Message_;
 static JSClassRef Messages_;
@@ -267,6 +278,13 @@ static Class Object_;
 static Type_privateData *Object_type;
 static Type_privateData *Selector_type;
 
+static bool CYValueIsObjectOfClassInstance(JSContextRef context, JSValueRef value) {
+    for (size_t i(0); i != sizeof(Instances_) / sizeof(Instances_[0]); ++i)
+        if (JSValueIsObjectOfClass(context, value, *Instances_[i]))
+            return true;
+    return false;
+}
+
 Type_privateData *Instance::GetType() const {
     return Object_type;
 }
@@ -598,7 +616,7 @@ NSObject *CYCastNSObject_(apr_pool_t *pool, JSContextRef context, JSObjectRef ob
 }
 
 NSObject *CYCastNSObject(apr_pool_t *pool, JSContextRef context, JSObjectRef object) {
-    if (!JSValueIsObjectOfClass(context, object, Instance_))
+    if (!CYValueIsObjectOfClassInstance(context, object))
         return CYCastNSObject_(pool, context, object);
     else {
         Instance *internal(reinterpret_cast<Instance *>(JSObjectGetPrivate(object)));
@@ -1834,7 +1852,7 @@ static bool Instance_hasInstance(JSContextRef context, JSObjectRef constructor,
     if (!CYIsClass(_class))
         return false;
 
-    if (JSValueIsObjectOfClass(context, instance, Instance_)) {
+    if (CYValueIsObjectOfClassInstance(context, instance)) {
         Instance *linternal(reinterpret_cast<Instance *>(JSObjectGetPrivate((JSObjectRef) instance)));
         // XXX: this isn't always safe
         return [linternal->GetValue() isKindOfClass:_class];
@@ -2152,7 +2170,7 @@ static JSValueRef $objc_msgSend(JSContextRef context, JSObjectRef object, JSObje
         self = internal->GetValue();
         _class = internal->class_;;
         uninitialized = false;
-    } else if (JSValueIsObjectOfClass(context, arguments[0], Instance_)) {
+    } else if (CYValueIsObjectOfClassInstance(context, arguments[0])) {
         Instance *internal(reinterpret_cast<Instance *>(JSObjectGetPrivate((JSObjectRef) arguments[0])));
         self = internal->GetValue();
         _class = nil;
@@ -2300,7 +2318,7 @@ static JSValueRef Instance_getProperty_messages(JSContextRef context, JSObjectRe
 }
 
 static JSValueRef Instance_callAsFunction_toCYON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
-    if (!JSValueIsObjectOfClass(context, _this, Instance_))
+    if (!CYValueIsObjectOfClassInstance(context, _this))
         return NULL;
 
     Instance *internal(reinterpret_cast<Instance *>(JSObjectGetPrivate(_this)));
@@ -2308,7 +2326,7 @@ static JSValueRef Instance_callAsFunction_toCYON(JSContextRef context, JSObjectR
 } CYCatch }
 
 static JSValueRef Instance_callAsFunction_toJSON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
-    if (!JSValueIsObjectOfClass(context, _this, Instance_))
+    if (!CYValueIsObjectOfClassInstance(context, _this))
         return NULL;
 
     Instance *internal(reinterpret_cast<Instance *>(JSObjectGetPrivate(_this)));
@@ -2325,7 +2343,7 @@ static JSValueRef Instance_callAsFunction_toJSON(JSContextRef context, JSObjectR
 } CYCatch return /*XXX*/ NULL; }
 
 static JSValueRef Instance_callAsFunction_valueOf(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
-    if (!JSValueIsObjectOfClass(context, _this, Instance_))
+    if (!CYValueIsObjectOfClassInstance(context, _this))
         return NULL;
 
     Instance *internal(reinterpret_cast<Instance *>(JSObjectGetPrivate(_this)));
@@ -2341,7 +2359,7 @@ static JSValueRef Instance_callAsFunction_valueOf(JSContextRef context, JSObject
 } CYCatch return /*XXX*/ NULL; }
 
 static JSValueRef Instance_callAsFunction_toPointer(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
-    if (!JSValueIsObjectOfClass(context, _this, Instance_))
+    if (!CYValueIsObjectOfClassInstance(context, _this))
         return NULL;
 
     Instance *internal(reinterpret_cast<Instance *>(JSObjectGetPrivate(_this)));
@@ -2350,7 +2368,7 @@ static JSValueRef Instance_callAsFunction_toPointer(JSContextRef context, JSObje
 } 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_))
+    if (!CYValueIsObjectOfClassInstance(context, _this))
         return NULL;
 
     Instance *internal(reinterpret_cast<Instance *>(JSObjectGetPrivate(_this)));
@@ -2477,6 +2495,15 @@ void CYObjectiveC_Initialize() { /*XXX*/ JSContextRef context(NULL); CYPoolTry {
     definition.finalize = &CYFinalize;
     Instance_ = JSClassCreate(&definition);
 
+    definition.className = "ArrayInstance";
+    ArrayInstance_ = JSClassCreate(&definition);
+
+    definition.className = "ObjectInstance";
+    ObjectInstance_ = JSClassCreate(&definition);
+
+    definition.className = "StringInstance";
+    StringInstance_ = JSClassCreate(&definition);
+
     definition = kJSClassDefinitionEmpty;
     definition.className = "Internal";
     definition.staticFunctions = Internal_staticFunctions;
@@ -2595,19 +2622,19 @@ void CYObjectiveC_SetupContext(JSContextRef context) { CYPoolTry {
     JSObjectRef Instance_prototype(CYCastJSObject(context, CYGetProperty(context, Instance, prototype_s)));
     CYSetProperty(context, cy, CYJSString("Instance_prototype"), Instance_prototype);
 
-    JSObjectRef ArrayInstance(JSObjectMakeConstructor(context, Instance_, NULL));
+    JSObjectRef ArrayInstance(JSObjectMakeConstructor(context, ArrayInstance_, NULL));
     JSObjectRef ArrayInstance_prototype(CYCastJSObject(context, CYGetProperty(context, ArrayInstance, prototype_s)));
     CYSetProperty(context, cy, CYJSString("ArrayInstance_prototype"), ArrayInstance_prototype);
     JSObjectRef Array_prototype(CYGetCachedObject(context, CYJSString("Array_prototype")));
     JSObjectSetPrototype(context, ArrayInstance_prototype, Array_prototype);
 
-    JSObjectRef ObjectInstance(JSObjectMakeConstructor(context, Instance_, NULL));
+    JSObjectRef ObjectInstance(JSObjectMakeConstructor(context, ObjectInstance_, NULL));
     JSObjectRef ObjectInstance_prototype(CYCastJSObject(context, CYGetProperty(context, ObjectInstance, prototype_s)));
     CYSetProperty(context, cy, CYJSString("ObjectInstance_prototype"), ObjectInstance_prototype);
     JSObjectRef Object_prototype(CYGetCachedObject(context, CYJSString("Object_prototype")));
     JSObjectSetPrototype(context, ObjectInstance_prototype, Object_prototype);
 
-    JSObjectRef StringInstance(JSObjectMakeConstructor(context, Instance_, NULL));
+    JSObjectRef StringInstance(JSObjectMakeConstructor(context, StringInstance_, NULL));
     JSObjectRef StringInstance_prototype(CYCastJSObject(context, CYGetProperty(context, StringInstance, prototype_s)));
     CYSetProperty(context, cy, CYJSString("StringInstance_prototype"), StringInstance_prototype);
     JSObjectRef String_prototype(CYGetCachedObject(context, CYJSString("String_prototype")));