| // Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| #ifndef OBJECTIVE_C_SRC_OBJECTIVE_C_H_ | |
| #define OBJECTIVE_C_SRC_OBJECTIVE_C_H_ | |
| #include "ffi.h" | |
| #include "include/dart_api_dl.h" | |
| #include "objective_c_runtime.h" | |
| // See https://clang.llvm.org/docs/Block-ABI-Apple.html | |
| typedef struct _ObjCBlockDesc { | |
| unsigned long int reserved; | |
| unsigned long int size; // sizeof(ObjCBlockImpl) | |
| void (*copy_helper)(void *dst, void *src); | |
| void (*dispose_helper)(void *src); | |
| const char *signature; | |
| } ObjCBlockDesc; | |
| typedef struct _ObjCBlockImpl { | |
| void *isa; // _NSConcreteGlobalBlock | |
| int flags; | |
| int reserved; | |
| void *invoke; // RET (*invoke)(ObjCBlockImpl *, ARGS...); | |
| ObjCBlockDesc *descriptor; | |
| // Captured variables follow. These are specific to our use case. | |
| void *target; | |
| Dart_Port dispose_port; | |
| } ObjCBlockImpl; | |
| // Initialize the Dart API. | |
| FFI_EXPORT intptr_t DOBJC_initializeApi(void *data); | |
| // Dispose helper for ObjC blocks that wrap a Dart closure. | |
| FFI_EXPORT void DOBJC_disposeObjCBlockWithClosure(ObjCBlockImpl *block); | |
| // Returns whether the block is valid and live. The pointer must point to | |
| // readable memory, or be null. May (rarely) return false positives. | |
| FFI_EXPORT bool DOBJC_isValidBlock(ObjCBlockImpl *block); | |
| // Returns a new Dart_FinalizableHandle that will clean up the object when the | |
| // Dart owner is garbage collected. | |
| FFI_EXPORT Dart_FinalizableHandle | |
| DOBJC_newFinalizableHandle(Dart_Handle owner, ObjCObjectImpl *object); | |
| // Delete a finalizable handle. Doesn't run the finalization callback, so | |
| // doesn't clean up the assocated pointer. | |
| FFI_EXPORT void DOBJC_deleteFinalizableHandle(Dart_FinalizableHandle handle, | |
| Dart_Handle owner); | |
| // Returns a newly allocated bool* (initialized to false) that will be deleted | |
| // by a Dart_FinalizableHandle when the owner is garbage collected. | |
| FFI_EXPORT bool *DOBJC_newFinalizableBool(Dart_Handle owner); | |
| // Runs fn(arg) on the main thread. If runOnMainThread is already running on the | |
| // main thread, fn(arg) is invoked synchronously. Otherwise it is dispatched to | |
| // the main thread (ie dispatch_async(dispatch_get_main_queue(), ...)). | |
| FFI_EXPORT void DOBJC_runOnMainThread(void (*fn)(void *), void *arg); | |
| // Functions for creating a waiter, signaling it, and waiting for the signal. A | |
| // waiter is one-time-use, and the object that newWaiter creates will be | |
| // destroyed once signalWaiter and awaitWaiter are called exactly once. | |
| FFI_EXPORT void *DOBJC_newWaiter(void); | |
| FFI_EXPORT void DOBJC_signalWaiter(void *waiter); | |
| FFI_EXPORT void DOBJC_awaitWaiter(void *waiter); | |
| FFI_EXPORT void DOBJC_invokeListenerPortBlock(int64_t port, void* args); | |
| FFI_EXPORT void DOBJC_invokeBlockingPortBlock(int64_t port, void* args, | |
| void* waiter); | |
| FFI_EXPORT void DOBJC_attachPortBlockFinalizer(void *block, int64_t port); | |
| // Context object containing functions needed by the FFIgen bindings. Any | |
| // changes to this struct should bump the `version` field filled in by | |
| // package:objective_c, and checked by FFIgen. Never change or delete existing | |
| // fields. Keep in sync with the struct defined in FFIgen's writer.dart. | |
| typedef struct _DOBJC_Context { | |
| int64_t version; | |
| void* (*newWaiter)(void); | |
| void (*awaitWaiter)(void*); | |
| Dart_Isolate (*currentIsolate)(void); | |
| void (*enterIsolate)(Dart_Isolate); | |
| void (*exitIsolate)(void); | |
| int64_t (*getMainPortId)(void); | |
| bool (*getCurrentThreadOwnsIsolate)(int64_t); | |
| void (*invokeListenerPortBlock)(int64_t port, void*); | |
| void (*invokeBlockingPortBlock)(int64_t port, void*, void*); | |
| } DOBJC_Context; | |
| FFI_EXPORT DOBJC_Context* DOBJC_createContext(void); | |
| #endif // OBJECTIVE_C_SRC_OBJECTIVE_C_H_ |