From: Jay Freeman (saurik) Date: Sat, 15 Sep 2012 16:16:55 +0000 (-0700) Subject: Use new ^ syntax to bridge Blocks (with @ offset). X-Git-Tag: v0.9.460^0 X-Git-Url: https://git.saurik.com/cycript.git/commitdiff_plain/3f9ae37cb15f239389eeba110b3a7da0280a8381 Use new ^ syntax to bridge Blocks (with @ offset). --- diff --git a/Execute.cpp b/Execute.cpp index 018deb1..0afd098 100644 --- a/Execute.cpp +++ b/Execute.cpp @@ -131,7 +131,7 @@ size_t CYGetIndex(apr_pool_t *pool, JSContextRef context, JSStringRef value) { static JSClassRef All_; static JSClassRef Context_; -static JSClassRef Functor_; +JSClassRef Functor_; static JSClassRef Global_; static JSClassRef Pointer_; static JSClassRef Struct_; diff --git a/Internal.hpp b/Internal.hpp index 7f8563d..34ad257 100644 --- a/Internal.hpp +++ b/Internal.hpp @@ -38,6 +38,8 @@ void Structor_(apr_pool_t *pool, sig::Type *&type); JSObjectRef CYMakeType(JSContextRef context, const char *type); JSObjectRef CYMakeType(JSContextRef context, sig::Type *type); +extern JSClassRef Functor_; + struct Type_privateData : CYData { diff --git a/ObjectiveC/Library.mm b/ObjectiveC/Library.mm index 7b33245..77511f8 100644 --- a/ObjectiveC/Library.mm +++ b/ObjectiveC/Library.mm @@ -645,12 +645,45 @@ _finline bool CYJSValueIsInstanceOfCachedConstructor(JSContextRef context, JSVal return is; } +NSObject *CYMakeBlock(void (*invoke)(), sig::Signature &signature) { + BlockLiteral *literal(reinterpret_cast(malloc(sizeof(BlockLiteral)))); + + struct Descriptor { + struct { + BlockDescriptor1 one_; + BlockDescriptor2 two_; + BlockDescriptor3 three_; + } d_; + + CYPool pool_; + }; + + Descriptor *descriptor(new Descriptor); + memset(&descriptor->d_, 0, sizeof(descriptor->d_)); + + literal->isa = objc_getClass("__NSGlobalBlock__"); + literal->flags = BLOCK_HAS_SIGNATURE | BLOCK_HAS_COPY_DISPOSE | BLOCK_IS_GLOBAL; + literal->reserved = 0; + literal->invoke = reinterpret_cast(invoke); + literal->descriptor = descriptor; + + descriptor->d_.one_.size = sizeof(descriptor->d_); + descriptor->d_.three_.signature = sig::Unparse(descriptor->pool_, &signature); + + return reinterpret_cast(literal); +} + NSObject *CYCastNSObject(apr_pool_t *pool, JSContextRef context, JSObjectRef object) { if (CYJSValueIsNSObject(context, object)) { Instance *internal(reinterpret_cast(JSObjectGetPrivate(object))); return internal->GetValue(); } + if (JSValueIsObjectOfClass(context, object, Functor_)) { + cy::Functor *internal(reinterpret_cast(JSObjectGetPrivate(object))); + return CYMakeBlock(internal->GetValue(), internal->signature_); + } + bool array(CYJSValueIsInstanceOfCachedConstructor(context, object, Array_s)); id value(array ? [CYJSArray alloc] : [CYJSObject alloc]); return CYPoolRelease(pool, [value initWithJSObject:object inContext:context]); diff --git a/ObjectiveC/Replace.cpp b/ObjectiveC/Replace.cpp index 96f6663..1f6c118 100644 --- a/ObjectiveC/Replace.cpp +++ b/ObjectiveC/Replace.cpp @@ -167,7 +167,7 @@ CYExpression *CYBox::Replace(CYContext &context) { } CYExpression *CYObjCBlock::Replace(CYContext &context) { - return $N2($V("Functor"), $ CYFunctionExpression(NULL, parameters_->Parameters(context), statements_), parameters_->TypeSignature(context, type_->Replace(context))); + return $N2($V("Functor"), $ CYFunctionExpression(NULL, $ CYFunctionParameter($ CYDeclaration($ CYIdentifier("$cyt")), parameters_->Parameters(context)), statements_), parameters_->TypeSignature(context, $ CYAdd(type_->Replace(context), $ CYString("@")))); } CYStatement *CYProtocol::Replace(CYContext &context) const { $T(NULL)