|
46 | 46 | v8::Locker locker(isolate); |
47 | 47 | Isolate::Scope isolate_scope(isolate); |
48 | 48 | HandleScope handle_scope(isolate); |
| 49 | + BlockWrapper* blockWrapper = static_cast<BlockWrapper*>(tns::GetValue(isolate, callback)); |
49 | 50 | tns::DeleteValue(isolate, callback); |
50 | 51 | wrapper->callback_->Reset(); |
| 52 | + delete blockWrapper; |
51 | 53 | } |
52 | 54 | } |
53 | 55 | delete wrapper; |
| 56 | + ffi_closure_free(block->ffiClosure); |
54 | 57 | block->~JSBlock(); |
55 | 58 | } |
56 | 59 | } |
57 | 60 | }; |
58 | 61 |
|
59 | | -IMP Interop::CreateMethod(const uint8_t initialParamIndex, const uint8_t argsCount, const TypeEncoding* typeEncoding, FFIMethodCallback callback, void* userData) { |
| 62 | +std::pair<IMP, ffi_closure*> Interop::CreateMethodInternal(const uint8_t initialParamIndex, const uint8_t argsCount, const TypeEncoding* typeEncoding, FFIMethodCallback callback, void* userData) { |
60 | 63 | void* functionPointer; |
61 | 64 | ffi_closure* closure = static_cast<ffi_closure*>(ffi_closure_alloc(sizeof(ffi_closure), &functionPointer)); |
62 | 65 | ParametrizedCall* call = ParametrizedCall::Get(typeEncoding, initialParamIndex, initialParamIndex + argsCount); |
63 | 66 | ffi_status status = ffi_prep_closure_loc(closure, call->Cif, callback, userData, functionPointer); |
64 | 67 | tns::Assert(status == FFI_OK); |
65 | 68 |
|
66 | | - return (IMP)functionPointer; |
| 69 | + return std::make_pair((IMP)functionPointer, closure); |
| 70 | + |
| 71 | +} |
| 72 | + |
| 73 | +IMP Interop::CreateMethod(const uint8_t initialParamIndex, const uint8_t argsCount, const TypeEncoding* typeEncoding, FFIMethodCallback callback, void* userData) { |
| 74 | + std::pair<IMP, ffi_closure*> result = Interop::CreateMethodInternal(initialParamIndex, argsCount, typeEncoding, callback, userData); |
| 75 | + return result.first; |
67 | 76 | } |
68 | 77 |
|
69 | 78 | CFTypeRef Interop::CreateBlock(const uint8_t initialParamIndex, const uint8_t argsCount, const TypeEncoding* typeEncoding, FFIMethodCallback callback, void* userData) { |
70 | 79 | JSBlock* blockPointer = reinterpret_cast<JSBlock*>(malloc(sizeof(JSBlock))); |
71 | | - void* functionPointer = (void*)CreateMethod(initialParamIndex, argsCount, typeEncoding, callback, userData); |
| 80 | + |
| 81 | + std::pair<IMP, ffi_closure*> result = Interop::CreateMethodInternal(initialParamIndex, argsCount, typeEncoding, callback, userData); |
72 | 82 |
|
73 | 83 | *blockPointer = { |
74 | 84 | .isa = nullptr, |
75 | 85 | .flags = JSBlock::BLOCK_HAS_COPY_DISPOSE | JSBlock::BLOCK_NEEDS_FREE | (1 /* ref count */ << 1), |
76 | 86 | .reserved = 0, |
77 | | - .invoke = functionPointer, |
| 87 | + .invoke = (void*)result.first, |
78 | 88 | .descriptor = &JSBlock::kJSBlockDescriptor, |
| 89 | + .userData = userData, |
| 90 | + .ffiClosure = result.second, |
79 | 91 | }; |
80 | 92 |
|
81 | | - blockPointer->userData = userData; |
82 | | - |
83 | 93 | object_setClass((__bridge id)blockPointer, objc_getClass("__NSMallocBlock__")); |
84 | 94 |
|
85 | | - return blockPointer; |
| 95 | + return CFAutorelease(blockPointer); |
86 | 96 | } |
87 | 97 |
|
88 | 98 | Local<Value> Interop::CallFunction(CMethodCall& methodCall) { |
|
295 | 305 | Local<Value> value = referenceWrapper->Value() != nullptr ? referenceWrapper->Value()->Get(isolate) : Local<Value>(); |
296 | 306 | ffi_type* ffiType = FFICall::GetArgumentType(innerType); |
297 | 307 | data = calloc(1, ffiType->size); |
298 | | - referenceWrapper->SetData(data); |
| 308 | + |
| 309 | + referenceWrapper->SetData(data, true); |
299 | 310 | referenceWrapper->SetEncoding(innerType); |
| 311 | + |
300 | 312 | // Initialize the ref/out parameter value before passing it to the function call |
301 | 313 | if (!value.IsEmpty()) { |
302 | 314 | Interop::WriteValue(context, innerType, data, value); |
|
350 | 362 | BaseDataWrapper* baseWrapper = tns::GetValue(isolate, arg); |
351 | 363 | if (baseWrapper != nullptr && baseWrapper->Type() == WrapperType::Block) { |
352 | 364 | BlockWrapper* wrapper = static_cast<BlockWrapper*>(baseWrapper); |
353 | | - blockPtr = wrapper->Block(); |
| 365 | + blockPtr = Block_copy(wrapper->Block()); |
354 | 366 | } else { |
355 | 367 | std::shared_ptr<Persistent<Value>> poCallback = std::make_shared<Persistent<Value>>(isolate, arg); |
356 | 368 | MethodCallbackWrapper* userData = new MethodCallbackWrapper(isolate, poCallback, 1, argsCount, blockTypeEncoding); |
|
512 | 524 | Local<ArrayBuffer> buffer = arg.As<ArrayBuffer>(); |
513 | 525 | NSDataAdapter* adapter = [[NSDataAdapter alloc] initWithJSObject:buffer isolate:isolate]; |
514 | 526 | Interop::SetValue(dest, adapter); |
| 527 | + CFAutorelease(adapter); |
515 | 528 | } else if (tns::IsArrayOrArrayLike(isolate, obj)) { |
516 | 529 | Local<v8::Array> array = Interop::ToArray(obj); |
517 | 530 | ArrayAdapter* adapter = [[ArrayAdapter alloc] initWithJSObject:array isolate:isolate]; |
518 | 531 | Interop::SetValue(dest, adapter); |
| 532 | + CFAutorelease(adapter); |
519 | 533 | } else { |
520 | 534 | DictionaryAdapter* adapter = [[DictionaryAdapter alloc] initWithJSObject:obj isolate:isolate]; |
521 | 535 | Interop::SetValue(dest, adapter); |
| 536 | + CFAutorelease(adapter); |
522 | 537 | } |
523 | 538 | } else { |
524 | 539 | tns::Assert(false, isolate); |
|
574 | 589 | } else { |
575 | 590 | Local<Object> obj = arg.As<Object>(); |
576 | 591 | DictionaryAdapter* adapter = [[DictionaryAdapter alloc] initWithJSObject:obj isolate:isolate]; |
| 592 | + CFAutorelease(adapter); |
577 | 593 | return adapter; |
578 | 594 | } |
579 | 595 | } |
|
0 commit comments