bind/objc: remove a constructor and retain blocks
A framework generated with gomobile bind -target=ios has two global constructors: one initializing a data structure and another using it. These constructors are defined in different translation units, which (I believe, reasoning from C++ global constructors) means their order of initialization is undefined. A capturing block is stack allocated. Its memory is invalid after the function returns. Make a copy of the interface initializer blocks so they can be saved to the heap. Block implementation background: http://www.cocoawithlove.com/2009/10/how-blocks-are-implemented-and.html Updates golang/go#12590 Change-Id: Ia7ae9f4bbd8df6e6e79949de54b3e6c48148c700 Reviewed-on: https://go-review.googlesource.com/14549 Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
This commit is contained in:
Родитель
b10f681911
Коммит
7a70f37cf6
|
@ -88,15 +88,17 @@
|
|||
// registered by calling go_seq_register_proxy from a global contructor funcion.
|
||||
static goSeqDictionary *proxies = NULL;
|
||||
|
||||
__attribute__((constructor)) static void go_seq_very_init() {
|
||||
proxies = [[goSeqDictionary alloc] init];
|
||||
}
|
||||
|
||||
void go_seq_register_proxy(const char *descriptor,
|
||||
void (*fn)(id, int, GoSeq *, GoSeq *)) {
|
||||
[proxies put:^(id obj, int code, GoSeq *in, GoSeq *out) {
|
||||
if (proxies == NULL) {
|
||||
proxies = [[goSeqDictionary alloc] init];
|
||||
}
|
||||
// Copying moves the block to the heap.
|
||||
id block = [^(id obj, int code, GoSeq *in, GoSeq *out) {
|
||||
fn(obj, code, in, out);
|
||||
} withKey:[NSString stringWithUTF8String:descriptor]];
|
||||
} copy];
|
||||
|
||||
[proxies put:block withKey:[NSString stringWithUTF8String:descriptor]];
|
||||
}
|
||||
|
||||
// RefTracker encapsulates a map of objective-C objects passed to Go and
|
||||
|
@ -322,7 +324,10 @@ void go_seq_recv(int32_t refnum, const char *desc, int code, uint8_t *in_ptr,
|
|||
|
||||
NSString *k = [NSString stringWithUTF8String:desc];
|
||||
|
||||
proxyFn fn = [proxies get:k];
|
||||
proxyFn fn = NULL;
|
||||
if (proxies != NULL) {
|
||||
fn = [proxies get:k];
|
||||
}
|
||||
if (fn == NULL) {
|
||||
LOG_FATAL(@"cannot find a proxy function for %s", desc);
|
||||
return;
|
||||
|
|
Загрузка…
Ссылка в новой задаче