]> git.saurik.com Git - cycript.git/blobdiff - ObjectiveC/Library.mm
Factor common code out of FFI closure adapters.
[cycript.git] / ObjectiveC / Library.mm
index 44eb0570c8f09fcdc907082cbb85c707ec59f01d..5863e9583e543b8e548261533a35317736536d93 100644 (file)
@@ -245,8 +245,8 @@ static JSClassRef ArrayInstance_;
 static JSClassRef FunctionInstance_;
 static JSClassRef ObjectInstance_;
 static JSClassRef StringInstance_;
-static JSClassRef TypeInstance_;
 
+static JSClassRef Class_;
 static JSClassRef Internal_;
 static JSClassRef Message_;
 static JSClassRef Messages_;
@@ -295,7 +295,7 @@ JSValueRef CYGetClassPrototype(JSContextRef context, Class self, bool meta) {
     if (self == nil)
         return CYGetCachedObject(context, CYJSString("Instance_prototype"));
     else if (meta && !class_isMetaClass(self))
-        return CYGetCachedObject(context, CYJSString("TypeInstance_prototype"));
+        return CYGetCachedObject(context, CYJSString("Class_prototype"));
 
     JSObjectRef global(CYGetGlobalObject(context));
     JSObjectRef cy(CYCastJSObject(context, CYGetProperty(context, global, cy_s)));
@@ -1485,21 +1485,13 @@ static const char *CYPoolTypeEncoding(apr_pool_t *pool, JSContextRef context, SE
     return NULL;
 }
 
-static void MessageClosure_(ffi_cif *cif, void *result, void **arguments, void *arg) {
-    Closure_privateData *internal(reinterpret_cast<Closure_privateData *>(arg));
-
-    JSContextRef context(internal->context_);
-
-    size_t count(internal->cif_.nargs);
-    JSValueRef values[count];
-
-    for (size_t index(0); index != count; ++index)
-        values[index] = CYFromFFI(context, internal->signature_.elements[1 + index].type, internal->cif_.arg_types[index], arguments[index]);
-
+static JSValueRef MessageAdapter_(JSContextRef context, size_t count, JSValueRef values[], JSObjectRef function) {
     JSObjectRef _this(CYCastJSObject(context, values[0]));
+    return CYCallAsFunction(context, function, _this, count - 2, values + 2);
+}
 
-    JSValueRef value(CYCallAsFunction(context, internal->function_, _this, count - 2, values + 2));
-    CYPoolFFI(NULL, context, internal->signature_.elements[0].type, internal->cif_.rtype, result, value);
+static void MessageClosure_(ffi_cif *cif, void *result, void **arguments, void *arg) {
+    CYExecuteClosure(cif, result, arguments, arg, &MessageAdapter_);
 }
 
 static JSObjectRef CYMakeMessage(JSContextRef context, SEL sel, IMP imp, const char *type) {
@@ -2406,15 +2398,34 @@ static JSValueRef Instance_callAsFunction_toString(JSContextRef context, JSObjec
     Instance *internal(reinterpret_cast<Instance *>(JSObjectGetPrivate(_this)));
     id value(internal->GetValue());
 
-    if (value == nil)
-        return CYCastJSValue(context, "nil");
-
     CYPoolTry {
         // XXX: this seems like a stupid implementation; what if it crashes? why not use the CYONifier backend?
         return CYCastJSValue(context, CYJSString(context, [value description]));
     } CYPoolCatch(NULL)
 } CYCatch return /*XXX*/ NULL; }
 
+static JSValueRef Class_callAsFunction_pointerTo(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
+    if (!CYJSValueIsNSObject(context, _this))
+        return NULL;
+
+    Instance *internal(reinterpret_cast<Instance *>(JSObjectGetPrivate(_this)));
+    id value(internal->GetValue());
+
+    if (!CYIsClass(value))
+        CYThrow("non-Class object cannot be used as Type");
+
+    // XXX: this is a very silly implementation
+
+    std::ostringstream type;
+    type << "@\"";
+    type << class_getName(value);
+    type << "\"";
+
+    CYPoolTry {
+        return CYMakeType(context, type.str().c_str());
+    } CYPoolCatch(NULL)
+} 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<Selector_privateData *>(JSObjectGetPrivate(_this)));
     return CYCastJSValue(context, sel_getName(internal->GetValue()));
@@ -2477,6 +2488,11 @@ static JSStaticFunction Instance_staticFunctions[7] = {
     {NULL, NULL, 0}
 };
 
+static JSStaticFunction Class_staticFunctions[2] = {
+    {"pointerTo", &Class_callAsFunction_pointerTo, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
+    {NULL, NULL, 0}
+};
+
 static JSStaticFunction Internal_staticFunctions[2] = {
     {"$cya", &Internal_callAsFunction_$cya, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
     {NULL, NULL, 0}
@@ -2546,17 +2562,19 @@ void CYObjectiveC_Initialize() { /*XXX*/ JSContextRef context(NULL); CYPoolTry {
     definition.className = "ArrayInstance";
     ArrayInstance_ = JSClassCreate(&definition);
 
+    definition.className = "FunctionInstance";
+    FunctionInstance_ = JSClassCreate(&definition);
+
     definition.className = "ObjectInstance";
     ObjectInstance_ = JSClassCreate(&definition);
 
     definition.className = "StringInstance";
     StringInstance_ = JSClassCreate(&definition);
 
-    definition.className = "TypeInstance";
-    TypeInstance_ = JSClassCreate(&definition);
-
-    definition.className = "FunctionInstance";
-    FunctionInstance_ = JSClassCreate(&definition);
+    definition = kJSClassDefinitionEmpty;
+    definition.className = "Class";
+    definition.staticFunctions = Class_staticFunctions;
+    Class_ = JSClassCreate(&definition);
 
     definition = kJSClassDefinitionEmpty;
     definition.className = "Internal";
@@ -2664,6 +2682,7 @@ void CYObjectiveC_SetupContext(JSContextRef context) { CYPoolTry {
     CYSetProperty(context, ObjectiveC, CYJSString("images"), JSObjectMake(context, ObjectiveC_Images_, NULL));
 #endif
 
+    JSObjectRef Class(JSObjectMakeConstructor(context, Class_, NULL));
     JSObjectRef Instance(JSObjectMakeConstructor(context, Instance_, &Instance_new));
     JSObjectRef Message(JSObjectMakeConstructor(context, Message_, NULL));
     JSObjectRef Selector(JSObjectMakeConstructor(context, Selector_, &Selector_new));
@@ -2696,11 +2715,9 @@ void CYObjectiveC_SetupContext(JSContextRef context) { CYPoolTry {
     JSObjectRef String_prototype(CYGetCachedObject(context, CYJSString("String_prototype")));
     JSObjectSetPrototype(context, StringInstance_prototype, String_prototype);
 
-    JSObjectRef TypeInstance(JSObjectMakeConstructor(context, TypeInstance_, NULL));
-    JSObjectRef TypeInstance_prototype(CYCastJSObject(context, CYGetProperty(context, TypeInstance, prototype_s)));
-    CYSetProperty(context, cy, CYJSString("TypeInstance_prototype"), TypeInstance_prototype);
-    JSObjectRef Type_prototype(CYGetCachedObject(context, CYJSString("Type_prototype")));
-    JSObjectSetPrototype(context, TypeInstance_prototype, Type_prototype);
+    JSObjectRef Class_prototype(CYCastJSObject(context, CYGetProperty(context, Class, prototype_s)));
+    CYSetProperty(context, cy, CYJSString("Class_prototype"), Class_prototype);
+    JSObjectSetPrototype(context, Class_prototype, Instance_prototype);
 
     CYSetProperty(context, cycript, CYJSString("Instance"), Instance);
     CYSetProperty(context, cycript, CYJSString("Selector"), Selector);