From 077756a45fcee049b33e31dcb21575573768aef8 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Sat, 11 Jan 2014 22:34:04 -0800 Subject: [PATCH] Support casting any pointer to a function type. --- Execute.cpp | 11 +++++++++-- Internal.hpp | 19 ++++++++++++++++--- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/Execute.cpp b/Execute.cpp index eb1970e..f21d6da 100644 --- a/Execute.cpp +++ b/Execute.cpp @@ -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(JSObjectGetPrivate(object))); + if (internal->type_->primitive == sig::function_P) + return CYMakeFunctor(context, reinterpret_cast(static_cast(CYCastDouble(context, arguments[0]))), internal->type_->data.signature); + sig::Type *type(internal->type_); ffi_type *ffi(internal->GetFFI()); // XXX: alignment? diff --git a/Internal.hpp b/Internal.hpp index f7ad60d..ff45f13 100644 --- a/Internal.hpp +++ b/Internal.hpp @@ -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(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(value)) + { + sig::Parse(*pool_, &signature_, encoding, &Structor_); + set(); } void (*GetValue() const)() { -- 2.49.0