|
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 | 95 | return blockPointer;
|
|
125 | 135 | }
|
126 | 136 | }
|
127 | 137 |
|
| 138 | +bool Interop::isRefTypeEqual(const TypeEncoding* typeEncoding, const char* clazz){ |
| 139 | + std::string n(&typeEncoding->details.interfaceDeclarationReference.name.value()); |
| 140 | + return n.compare(clazz) == 0; |
| 141 | +} |
| 142 | + |
128 | 143 | void Interop::WriteValue(Local<Context> context, const TypeEncoding* typeEncoding, void* dest, Local<Value> arg) {
|
129 | 144 | Isolate* isolate = context->GetIsolate();
|
130 | 145 |
|
131 | 146 | if (arg.IsEmpty() || arg->IsNullOrUndefined()) {
|
132 | 147 | ffi_type* ffiType = FFICall::GetArgumentType(typeEncoding, true);
|
133 | 148 | size_t size = ffiType->size;
|
134 | 149 | memset(dest, 0, size);
|
| 150 | + } else if (tns::IsBool(arg) && typeEncoding->type == BinaryTypeEncodingType::InterfaceDeclarationReference && isRefTypeEqual(typeEncoding, "NSNumber")) { |
| 151 | + bool value = tns::ToBool(arg); |
| 152 | + NSNumber *num = [NSNumber numberWithBool: value]; |
| 153 | + Interop::SetValue(dest, num); |
135 | 154 | } else if (tns::IsBool(arg) && typeEncoding->type == BinaryTypeEncodingType::IdEncoding) {
|
136 | 155 | bool value = tns::ToBool(arg);
|
137 | 156 | NSObject* o = @(value);
|
|
286 | 305 | Local<Value> value = referenceWrapper->Value() != nullptr ? referenceWrapper->Value()->Get(isolate) : Local<Value>();
|
287 | 306 | ffi_type* ffiType = FFICall::GetArgumentType(innerType);
|
288 | 307 | data = calloc(1, ffiType->size);
|
289 |
| - referenceWrapper->SetData(data); |
| 308 | + |
| 309 | + referenceWrapper->SetData(data, true); |
290 | 310 | referenceWrapper->SetEncoding(innerType);
|
| 311 | + |
291 | 312 | // Initialize the ref/out parameter value before passing it to the function call
|
292 | 313 | if (!value.IsEmpty()) {
|
293 | 314 | Interop::WriteValue(context, innerType, data, value);
|
|
341 | 362 | BaseDataWrapper* baseWrapper = tns::GetValue(isolate, arg);
|
342 | 363 | if (baseWrapper != nullptr && baseWrapper->Type() == WrapperType::Block) {
|
343 | 364 | BlockWrapper* wrapper = static_cast<BlockWrapper*>(baseWrapper);
|
344 |
| - blockPtr = wrapper->Block(); |
| 365 | + blockPtr = Block_copy(wrapper->Block()); |
345 | 366 | } else {
|
346 | 367 | std::shared_ptr<Persistent<Value>> poCallback = std::make_shared<Persistent<Value>>(isolate, arg);
|
347 | 368 | MethodCallbackWrapper* userData = new MethodCallbackWrapper(isolate, poCallback, 1, argsCount, blockTypeEncoding);
|
|
503 | 524 | Local<ArrayBuffer> buffer = arg.As<ArrayBuffer>();
|
504 | 525 | NSDataAdapter* adapter = [[NSDataAdapter alloc] initWithJSObject:buffer isolate:isolate];
|
505 | 526 | Interop::SetValue(dest, adapter);
|
| 527 | + // CFAutorelease(adapter); |
506 | 528 | } else if (tns::IsArrayOrArrayLike(isolate, obj)) {
|
507 | 529 | Local<v8::Array> array = Interop::ToArray(obj);
|
508 | 530 | ArrayAdapter* adapter = [[ArrayAdapter alloc] initWithJSObject:array isolate:isolate];
|
509 | 531 | Interop::SetValue(dest, adapter);
|
| 532 | + // CFAutorelease(adapter); |
510 | 533 | } else {
|
511 | 534 | DictionaryAdapter* adapter = [[DictionaryAdapter alloc] initWithJSObject:obj isolate:isolate];
|
512 | 535 | Interop::SetValue(dest, adapter);
|
| 536 | + // CFAutorelease(adapter); |
513 | 537 | }
|
514 | 538 | } else {
|
515 | 539 | tns::Assert(false, isolate);
|
|
565 | 589 | } else {
|
566 | 590 | Local<Object> obj = arg.As<Object>();
|
567 | 591 | DictionaryAdapter* adapter = [[DictionaryAdapter alloc] initWithJSObject:obj isolate:isolate];
|
| 592 | + // CFAutorelease(adapter); |
568 | 593 | return adapter;
|
569 | 594 | }
|
570 | 595 | }
|
|
0 commit comments