]> git.saurik.com Git - cycript.git/commitdiff
Support casting any pointer to a function type.
authorJay Freeman (saurik) <saurik@saurik.com>
Sun, 12 Jan 2014 06:34:04 +0000 (22:34 -0800)
committerJay Freeman (saurik) <saurik@saurik.com>
Sun, 12 Jan 2014 06:34:04 +0000 (22:34 -0800)
Execute.cpp
Internal.hpp

index eb1970e89e7d38b6da286f3c9e8ace794d3341bb..f21d6da216d9881dd287d30074540b997518a581 100644 (file)
@@ -496,8 +496,12 @@ JSObjectRef CYMakePointer(JSContextRef context, void *pointer, size_t length, si
     return JSObjectMake(context, Pointer_, internal);
 }
 
-static JSObjectRef CYMakeFunctor(JSContextRef context, void (*function)(), const char *type) {
-    return JSObjectMake(context, Functor_, new cy::Functor(type, function));
+static JSObjectRef CYMakeFunctor(JSContextRef context, void (*function)(), const char *encoding) {
+    return JSObjectMake(context, Functor_, new cy::Functor(encoding, function));
+}
+
+static JSObjectRef CYMakeFunctor(JSContextRef context, void (*function)(), sig::Signature &signature) {
+    return JSObjectMake(context, Functor_, new cy::Functor(signature, function));
 }
 
 static JSObjectRef CYMakeFunctor(JSContextRef context, const char *symbol, const char *type, void **cache) {
@@ -1173,6 +1177,9 @@ static JSValueRef Type_callAsFunction(JSContextRef context, JSObjectRef object,
         throw CYJSError(context, "incorrect number of arguments to type cast function");
     Type_privateData *internal(reinterpret_cast<Type_privateData *>(JSObjectGetPrivate(object)));
 
+    if (internal->type_->primitive == sig::function_P)
+        return CYMakeFunctor(context, reinterpret_cast<void (*)()>(static_cast<uintptr_t>(CYCastDouble(context, arguments[0]))), internal->type_->data.signature);
+
     sig::Type *type(internal->type_);
     ffi_type *ffi(internal->GetFFI());
     // XXX: alignment?
index f7ad60ddb112c32008e029e22ec407e9dbd0801b..ff45f13b69479f070d19241ad3df17c045aace9e 100644 (file)
@@ -161,14 +161,27 @@ namespace cy {
 struct Functor :
     CYValue
 {
+  private:
+    void set() {
+        sig::sig_ffi_cif(*pool_, &sig::ObjectiveC, &signature_, &cif_);
+    }
+
+  public:
     sig::Signature signature_;
     ffi_cif cif_;
 
-    Functor(const char *type, void (*value)()) :
+    Functor(sig::Signature &signature, void (*value)()) :
         CYValue(reinterpret_cast<void *>(value))
     {
-        sig::Parse(*pool_, &signature_, type, &Structor_);
-        sig::sig_ffi_cif(*pool_, &sig::ObjectiveC, &signature_, &cif_);
+        sig::Copy(*pool_, signature_, signature);
+        set();
+    }
+
+    Functor(const char *encoding, void (*value)()) :
+        CYValue(reinterpret_cast<void *>(value))
+    {
+        sig::Parse(*pool_, &signature_, encoding, &Structor_);
+        set();
     }
 
     void (*GetValue() const)() {