86 lines
3.4 KiB
C
86 lines
3.4 KiB
C
// 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);
|
|
|
|
// 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);
|
|
} DOBJC_Context;
|
|
FFI_EXPORT DOBJC_Context* DOBJC_fillContext(DOBJC_Context* context);
|
|
|
|
#endif // OBJECTIVE_C_SRC_OBJECTIVE_C_H_
|