| #include <stdint.h> |
| #import <Foundation/Foundation.h> |
| #import <objc/message.h> |
| #import "block_annotation_test.h" |
| |
| #if !__has_feature(objc_arc) |
| #error "This file must be compiled with ARC enabled" |
| #endif |
| |
| #pragma clang diagnostic push |
| #pragma clang diagnostic ignored "-Wundeclared-selector" |
| |
| typedef struct { |
| int64_t version; |
| void* (*newWaiter)(void); |
| void (*awaitWaiter)(void*); |
| void* (*currentIsolate)(void); |
| void (*enterIsolate)(void*); |
| void (*exitIsolate)(void); |
| int64_t (*getMainPortId)(void); |
| bool (*getCurrentThreadOwnsIsolate)(int64_t); |
| } DOBJC_Context; |
| |
| id objc_retainBlock(id); |
| |
| #define BLOCKING_BLOCK_IMPL(ctx, BLOCK_SIG, INVOKE_DIRECT, INVOKE_LISTENER) \ |
| assert(ctx->version >= 1); \ |
| void* targetIsolate = ctx->currentIsolate(); \ |
| int64_t targetPort = ctx->getMainPortId == NULL ? 0 : ctx->getMainPortId(); \ |
| return BLOCK_SIG { \ |
| void* currentIsolate = ctx->currentIsolate(); \ |
| bool mayEnterIsolate = \ |
| currentIsolate == NULL && \ |
| ctx->getCurrentThreadOwnsIsolate != NULL && \ |
| ctx->getCurrentThreadOwnsIsolate(targetPort); \ |
| if (currentIsolate == targetIsolate || mayEnterIsolate) { \ |
| if (mayEnterIsolate) { \ |
| ctx->enterIsolate(targetIsolate); \ |
| } \ |
| INVOKE_DIRECT; \ |
| if (mayEnterIsolate) { \ |
| ctx->exitIsolate(); \ |
| } \ |
| } else { \ |
| void* waiter = ctx->newWaiter(); \ |
| INVOKE_LISTENER; \ |
| ctx->awaitWaiter(waiter); \ |
| } \ |
| }; |
| |
| |
| Protocol* _z0xonr_BlockAnnotationTestProtocol(void) { return @protocol(BlockAnnotationTestProtocol); } |
| |
| typedef id (^_ProtocolTrampoline)(void * sel); |
| __attribute__((visibility("default"))) __attribute__((used)) |
| id _z0xonr_protocolTrampoline_zb0vvk(id target, void * sel) { |
| return ((_ProtocolTrampoline)((id (*)(id, SEL, SEL))objc_msgSend)(target, @selector(getDOBJCDartProtocolMethodForSelector:), sel))(sel); |
| } |
| |
| typedef id (^_ProtocolTrampoline_1)(void * sel); |
| __attribute__((visibility("default"))) __attribute__((used)) |
| id _z0xonr_protocolTrampoline_1mbt9g9(id target, void * sel) { |
| return ((_ProtocolTrampoline_1)((id (*)(id, SEL, SEL))objc_msgSend)(target, @selector(getDOBJCDartProtocolMethodForSelector:), sel))(sel); |
| } |
| |
| typedef id (^_ProtocolTrampoline_2)(void * sel, id arg1); |
| __attribute__((visibility("default"))) __attribute__((used)) |
| id _z0xonr_protocolTrampoline_xr62hr(id target, void * sel, id arg1) { |
| return ((_ProtocolTrampoline_2)((id (*)(id, SEL, SEL))objc_msgSend)(target, @selector(getDOBJCDartProtocolMethodForSelector:), sel))(sel, arg1); |
| } |
| |
| typedef id (^_ProtocolTrampoline_3)(void * sel, id arg1 __attribute__((ns_consumed))); |
| __attribute__((visibility("default"))) __attribute__((used)) |
| id _z0xonr_protocolTrampoline_cww6wh(id target, void * sel, id arg1 __attribute__((ns_consumed))) { |
| return ((_ProtocolTrampoline_3)((id (*)(id, SEL, SEL))objc_msgSend)(target, @selector(getDOBJCDartProtocolMethodForSelector:), sel))(sel, arg1); |
| } |
| |
| typedef void (^_ListenerTrampoline)(void); |
| __attribute__((visibility("default"))) __attribute__((used)) |
| _ListenerTrampoline _z0xonr_wrapListenerBlock_1pl9qdv(_ListenerTrampoline block) NS_RETURNS_RETAINED { |
| return ^void() { |
| objc_retainBlock(block); |
| block(); |
| }; |
| } |
| |
| typedef void (^_BlockingTrampoline)(void * waiter); |
| __attribute__((visibility("default"))) __attribute__((used)) |
| _ListenerTrampoline _z0xonr_wrapBlockingBlock_1pl9qdv( |
| _BlockingTrampoline block, _BlockingTrampoline listenerBlock, |
| DOBJC_Context* ctx) NS_RETURNS_RETAINED { |
| BLOCKING_BLOCK_IMPL(ctx, ^void(), { |
| objc_retainBlock(block); |
| block(nil); |
| }, { |
| objc_retainBlock(listenerBlock); |
| listenerBlock(waiter); |
| }); |
| } |
| |
| typedef void (^_ListenerTrampoline_1)(void * arg0, id arg1); |
| __attribute__((visibility("default"))) __attribute__((used)) |
| _ListenerTrampoline_1 _z0xonr_wrapListenerBlock_18v1jvf(_ListenerTrampoline_1 block) NS_RETURNS_RETAINED { |
| return ^void(void * arg0, id arg1) { |
| objc_retainBlock(block); |
| block(arg0, (__bridge id)(__bridge_retained void*)(arg1)); |
| }; |
| } |
| |
| typedef void (^_BlockingTrampoline_1)(void * waiter, void * arg0, id arg1); |
| __attribute__((visibility("default"))) __attribute__((used)) |
| _ListenerTrampoline_1 _z0xonr_wrapBlockingBlock_18v1jvf( |
| _BlockingTrampoline_1 block, _BlockingTrampoline_1 listenerBlock, |
| DOBJC_Context* ctx) NS_RETURNS_RETAINED { |
| BLOCKING_BLOCK_IMPL(ctx, ^void(void * arg0, id arg1), { |
| objc_retainBlock(block); |
| block(nil, arg0, (__bridge id)(__bridge_retained void*)(arg1)); |
| }, { |
| objc_retainBlock(listenerBlock); |
| listenerBlock(waiter, arg0, (__bridge id)(__bridge_retained void*)(arg1)); |
| }); |
| } |
| |
| typedef void (^_ProtocolTrampoline_4)(void * sel, id arg1); |
| __attribute__((visibility("default"))) __attribute__((used)) |
| void _z0xonr_protocolTrampoline_18v1jvf(id target, void * sel, id arg1) { |
| return ((_ProtocolTrampoline_4)((id (*)(id, SEL, SEL))objc_msgSend)(target, @selector(getDOBJCDartProtocolMethodForSelector:), sel))(sel, arg1); |
| } |
| |
| typedef void (^_ListenerTrampoline_2)(void * arg0, id arg1 __attribute__((ns_consumed))); |
| __attribute__((visibility("default"))) __attribute__((used)) |
| _ListenerTrampoline_2 _z0xonr_wrapListenerBlock_6yc3kd(_ListenerTrampoline_2 block) NS_RETURNS_RETAINED { |
| return ^void(void * arg0, id arg1 __attribute__((ns_consumed))) { |
| objc_retainBlock(block); |
| block(arg0, (__bridge id)(__bridge_retained void*)(arg1)); |
| }; |
| } |
| |
| typedef void (^_BlockingTrampoline_2)(void * waiter, void * arg0, id arg1 __attribute__((ns_consumed))); |
| __attribute__((visibility("default"))) __attribute__((used)) |
| _ListenerTrampoline_2 _z0xonr_wrapBlockingBlock_6yc3kd( |
| _BlockingTrampoline_2 block, _BlockingTrampoline_2 listenerBlock, |
| DOBJC_Context* ctx) NS_RETURNS_RETAINED { |
| BLOCKING_BLOCK_IMPL(ctx, ^void(void * arg0, id arg1 __attribute__((ns_consumed))), { |
| objc_retainBlock(block); |
| block(nil, arg0, (__bridge id)(__bridge_retained void*)(arg1)); |
| }, { |
| objc_retainBlock(listenerBlock); |
| listenerBlock(waiter, arg0, (__bridge id)(__bridge_retained void*)(arg1)); |
| }); |
| } |
| |
| typedef void (^_ProtocolTrampoline_5)(void * sel, id arg1 __attribute__((ns_consumed))); |
| __attribute__((visibility("default"))) __attribute__((used)) |
| void _z0xonr_protocolTrampoline_6yc3kd(id target, void * sel, id arg1 __attribute__((ns_consumed))) { |
| return ((_ProtocolTrampoline_5)((id (*)(id, SEL, SEL))objc_msgSend)(target, @selector(getDOBJCDartProtocolMethodForSelector:), sel))(sel, arg1); |
| } |
| #undef BLOCKING_BLOCK_IMPL |
| |
| #pragma clang diagnostic pop |