From: Jay Freeman (saurik) Date: Fri, 24 Jan 2014 16:25:26 +0000 (-0800) Subject: Split CYBlockEncoding out for NSBlock.type usage. X-Git-Tag: v0.9.501~17 X-Git-Url: https://git.saurik.com/cycript.git/commitdiff_plain/f073482c223ba7e1f29c2c208b2f957a6453b273?ds=inline Split CYBlockEncoding out for NSBlock.type usage. --- diff --git a/ObjectiveC/Library.mm b/ObjectiveC/Library.mm index 00ea5df..34a0f10 100644 --- a/ObjectiveC/Library.mm +++ b/ObjectiveC/Library.mm @@ -1944,6 +1944,18 @@ static JSObjectRef Instance_callAsConstructor(JSContextRef context, JSObjectRef return value; } CYCatch(NULL) } +static const char *CYBlockEncoding(NSBlock *self) { + BlockLiteral *literal(reinterpret_cast(self)); + if ((literal->flags & BLOCK_HAS_SIGNATURE) == 0) + return NULL; + uint8_t *descriptor(reinterpret_cast(literal->descriptor)); + descriptor += sizeof(BlockDescriptor1); + if ((literal->flags & BLOCK_HAS_COPY_DISPOSE) != 0) + descriptor += sizeof(BlockDescriptor2); + BlockDescriptor3 *descriptor3(reinterpret_cast(descriptor)); + return descriptor3->signature; +} + static JSValueRef Instance_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { Instance *internal(reinterpret_cast(JSObjectGetPrivate(object))); id self(internal->GetValue()); @@ -1956,30 +1968,21 @@ static JSValueRef Instance_callAsFunction(JSContextRef context, JSObjectRef obje // to do /that/, generalize the various "is exactly Instance_" checks // then, move Instance_callAsFunction to only be on FunctionInstance - BlockLiteral *literal(reinterpret_cast(self)); + if (const char *encoding = CYBlockEncoding(self)) { + CYPool pool; - if ((literal->flags & BLOCK_HAS_SIGNATURE) != 0) { - uint8_t *descriptor(reinterpret_cast(literal->descriptor)); - descriptor += sizeof(BlockDescriptor1); - if ((literal->flags & BLOCK_HAS_COPY_DISPOSE) != 0) - descriptor += sizeof(BlockDescriptor2); - BlockDescriptor3 *descriptor3(reinterpret_cast(descriptor)); + void *setup[1]; + setup[0] = &self; - if (const char *type = descriptor3->signature) { - CYPool pool; + sig::Signature signature; + sig::Parse(pool, &signature, encoding, &Structor_); - void *setup[1]; - setup[0] = &self; + ffi_cif cif; + sig::sig_ffi_cif(pool, &sig::ObjectiveC, &signature, &cif); - sig::Signature signature; - sig::Parse(pool, &signature, type, &Structor_); - - ffi_cif cif; - sig::sig_ffi_cif(pool, &sig::ObjectiveC, &signature, &cif); - - void (*function)() = reinterpret_cast(literal->invoke); - return CYCallFunction(pool, context, 1, setup, count, arguments, false, &signature, &cif, function); - } + BlockLiteral *literal(reinterpret_cast(self)); + void (*function)() = reinterpret_cast(literal->invoke); + return CYCallFunction(pool, context, 1, setup, count, arguments, false, &signature, &cif, function); } if (count != 0)