|
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