Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make PLBlockIMP drop in compatible on iOS 4 and 5 #2

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
*.mode1
*.mode1v3
*.mode2v3
*.perspective
*.perspectivev3
*.pbxuser
project.xcworkspace
xcuserdata
54 changes: 35 additions & 19 deletions Source/blockimp.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,41 @@

#include <stdio.h>
#include <Block.h>
#include <dispatch/dispatch.h>
#include <dlfcn.h>

// Convenience for falling through to the system implementation.
static BOOL fallthroughEnabled = YES;

#define NEXT(name, ...) do { \
static dispatch_once_t fptrOnce; \
static __typeof__(&name) fptr; \
dispatch_once(&fptrOnce, ^{ fptr = dlsym(RTLD_NEXT, #name); });\
if (fallthroughEnabled && fptr != NULL) \
return fptr(__VA_ARGS__); \
} while(0)

void PLBlockIMPSetFallthroughEnabled(BOOL enabled) {
fallthroughEnabled = enabled;
}

IMP imp_implementationWithBlock(PLObjectPtr block) {
NEXT(imp_implementationWithBlock, block);

return pl_imp_implementationWithBlock(block);
}

PLObjectPtr imp_getBlock(IMP anImp) {
NEXT(imp_getBlock, anImp);

return pl_imp_getBlock(anImp);
}

BOOL imp_removeBlock(IMP anImp) {
NEXT(imp_removeBlock, anImp);

return imp_removeBlock(anImp);
}

#pragma mark Trampolines

Expand All @@ -47,12 +82,6 @@ static pl_trampoline_table *blockimp_table = NULL;
*
*/
IMP pl_imp_implementationWithBlock (void *block) {
#if SUPPORT_APPLE_FALLBACK
/* Prefer Apple's implementation */
if (&imp_implementationWithBlock != NULL)
return imp_implementationWithBlock(block);
#endif

/* Allocate the appropriate trampoline type. */
pl_trampoline *tramp;
struct Block_layout *bl = block;
Expand All @@ -75,13 +104,6 @@ IMP pl_imp_implementationWithBlock (void *block) {
*
*/
void *pl_imp_getBlock(IMP anImp) {
#if SUPPORT_APPLE_FALLBACK
/* Prefer Apple's implementation */
if (&imp_getBlock != NULL) {
return imp_getBlock(anImp);
}
#endif

/* Fetch the config data and return the block reference. */
void **config = pl_trampoline_data_ptr(anImp);
return config[0];
Expand All @@ -91,12 +113,6 @@ void *pl_imp_getBlock(IMP anImp) {
*
*/
BOOL pl_imp_removeBlock(IMP anImp) {
#if SUPPORT_APPLE_FALLBACK
/* Prefer Apple's implementation */
if (&imp_removeBlock != NULL)
return imp_removeBlock(anImp);
#endif

/* Fetch the config data */
void **config = pl_trampoline_data_ptr(anImp);
struct Block_layout *bl = config[0];
Expand Down
15 changes: 12 additions & 3 deletions Source/blockimp.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,16 @@
*/

#include <objc/runtime.h>
#include <Availability.h>

extern IMP pl_imp_implementationWithBlock(void *block);
extern void *pl_imp_getBlock(IMP anImp);
extern BOOL pl_imp_removeBlock(IMP anImp);
#if defined (__MAC_10_8) || defined (__IPHONE_6_0)
typedef id PLObjectPtr;
#else
typedef void *PLObjectPtr;
#endif

OBJC_EXPORT IMP imp_implementationWithBlock(PLObjectPtr block);
OBJC_EXPORT PLObjectPtr imp_getBlock(IMP anImp);
OBJC_EXPORT BOOL imp_removeBlock(IMP anImp);

OBJC_EXPORT void PLBlockIMPSetFallthroughEnabled(BOOL enabled);
16 changes: 5 additions & 11 deletions Source/blockimp_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,6 @@
# error Unknown Architecture
#endif

#pragma mark Fallback Support

// if 1, we attempt to use Apple's official implementations
#define SUPPORT_APPLE_FALLBACK 0
#if SUPPORT_APPLE_FALLBACK
extern IMP imp_implementationWithBlock(void *block) WEAK_IMPORT_ATTRIBUTE;
extern void *imp_getBlock(IMP anImp) WEAK_IMPORT_ATTRIBUTE;
extern BOOL imp_removeBlock(IMP anImp) WEAK_IMPORT_ATTRIBUTE;
#endif

/*
* Block Flags
*/
Expand Down Expand Up @@ -132,4 +122,8 @@ struct Block_layout {
struct Block_descriptor *descriptor;

// imported variables
};
};

IMP pl_imp_implementationWithBlock(void *block);
void *pl_imp_getBlock(IMP anImp);
BOOL pl_imp_removeBlock(IMP anImp);
4 changes: 4 additions & 0 deletions Source/blockimp_tests.m
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
#import "GTMSenTestCase.h"
#import "blockimp.h"

IMP pl_imp_implementationWithBlock (void *block);
void *pl_imp_getBlock(IMP anImp);
BOOL pl_imp_removeBlock(IMP anImp);

@interface BlockIMPTests : SenTestCase @end

/**
Expand Down