Merge pull request #8 from JetBrains/callbacks-strike-back
Fix bugs after supporting callbacks in Interop
This commit is contained in:
@@ -3570,7 +3570,7 @@ enum class CXIndexOptFlags(val value: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
object NativeFunctionType1 : NativeFunctionType<(CXCursor, CXCursor, NativePtr?) -> CXChildVisitResult>(UInt32, Struct(UInt32, SInt32, Pointer), Struct(UInt32, SInt32, Pointer), Pointer) {
|
||||
object NativeFunctionType1 : NativeFunctionType<(CXCursor, CXCursor, NativePtr?) -> CXChildVisitResult>(UInt32, Struct(UInt32, SInt32, Struct(Pointer, Pointer, Pointer)), Struct(UInt32, SInt32, Struct(Pointer, Pointer, Pointer)), Pointer) {
|
||||
override fun invoke(function: (CXCursor, CXCursor, NativePtr?) -> CXChildVisitResult, args: NativeArray<NativePtrBox>, ret: NativePtr) {
|
||||
val res = function(args[0].value.asRef(CXCursor)!!, args[1].value.asRef(CXCursor)!!, args[2].value.asRef(NativePtrBox)!!.value)
|
||||
CXChildVisitResult.ref.byPtr(ret).value = res
|
||||
@@ -3589,14 +3589,14 @@ object NativeFunctionType3 : NativeFunctionType<(NativePtr?, CXSourceLocation?,
|
||||
}
|
||||
}
|
||||
|
||||
object NativeFunctionType4 : NativeFunctionType<(CXCursor, NativePtr?) -> CXVisitorResult>(UInt32, Struct(UInt32, SInt32, Pointer), Pointer) {
|
||||
object NativeFunctionType4 : NativeFunctionType<(CXCursor, NativePtr?) -> CXVisitorResult>(UInt32, Struct(UInt32, SInt32, Struct(Pointer, Pointer, Pointer)), Pointer) {
|
||||
override fun invoke(function: (CXCursor, NativePtr?) -> CXVisitorResult, args: NativeArray<NativePtrBox>, ret: NativePtr) {
|
||||
val res = function(args[0].value.asRef(CXCursor)!!, args[1].value.asRef(NativePtrBox)!!.value)
|
||||
CXVisitorResult.ref.byPtr(ret).value = res
|
||||
}
|
||||
}
|
||||
|
||||
object NativeFunctionType5 : NativeFunctionType<(NativePtr?, CXCursor, CXSourceRange) -> CXVisitorResult>(UInt32, Pointer, Struct(UInt32, SInt32, Pointer), Struct(Pointer, UInt32, UInt32)) {
|
||||
object NativeFunctionType5 : NativeFunctionType<(NativePtr?, CXCursor, CXSourceRange) -> CXVisitorResult>(UInt32, Pointer, Struct(UInt32, SInt32, Struct(Pointer, Pointer, Pointer)), Struct(Struct(Pointer, Pointer), UInt32, UInt32)) {
|
||||
override fun invoke(function: (NativePtr?, CXCursor, CXSourceRange) -> CXVisitorResult, args: NativeArray<NativePtrBox>, ret: NativePtr) {
|
||||
val res = function(args[0].value.asRef(NativePtrBox)!!.value, args[1].value.asRef(CXCursor)!!, args[2].value.asRef(CXSourceRange)!!)
|
||||
CXVisitorResult.ref.byPtr(ret).value = res
|
||||
|
||||
+21
-9
@@ -98,16 +98,27 @@ private class NativeIndexImpl : NativeIndex() {
|
||||
* Computes [StructDef.hasNaturalLayout] property.
|
||||
*/
|
||||
fun structHasNaturalLayout(structDefCursor: CXCursor): Boolean {
|
||||
val hasAttributes = malloc(Int32Box)
|
||||
hasAttributes.value = 0
|
||||
clang_visitChildren(structDefCursor, { cursor, parent, clientData ->
|
||||
if (clang_isAttribute(cursor.kind.value) != 0) {
|
||||
clientData.asRef(Int32Box)!!.value = 1
|
||||
}
|
||||
CXChildVisitResult.CXChildVisit_Continue
|
||||
}, hasAttributes.ptr)
|
||||
val defKind = structDefCursor.kind.value
|
||||
|
||||
return hasAttributes.value == 0
|
||||
when (defKind) {
|
||||
|
||||
CXCursorKind.CXCursor_UnionDecl -> return false
|
||||
|
||||
CXCursorKind.CXCursor_StructDecl -> {
|
||||
val hasAttributes = arena.alloc(Int32Box)
|
||||
hasAttributes.value = 0
|
||||
clang_visitChildren(structDefCursor, { cursor, parent, clientData ->
|
||||
if (clang_isAttribute(cursor.kind.value) != 0) {
|
||||
clientData.asRef(Int32Box)!!.value = 1
|
||||
}
|
||||
CXChildVisitResult.CXChildVisit_Continue
|
||||
}, hasAttributes.ptr)
|
||||
|
||||
return hasAttributes.value == 0
|
||||
}
|
||||
|
||||
else -> throw IllegalArgumentException(defKind.toString())
|
||||
}
|
||||
}
|
||||
|
||||
fun convertType(type: CXType): Type {
|
||||
@@ -253,6 +264,7 @@ fun CXString.convertAndDispose(): String {
|
||||
}
|
||||
|
||||
fun buildNativeIndexImpl(headerFile: File, args: List<String>): NativeIndex {
|
||||
// TODO: dispose all allocated memory and resources
|
||||
val args1 = args.map { CString.fromString(it)!!.asCharPtr() }.toTypedArray()
|
||||
|
||||
val index = clang_createIndex(0, 0)
|
||||
|
||||
@@ -101,6 +101,8 @@ JNIEXPORT jlong JNICALL Java_kotlin_1native_interop_CallbacksKt_ffiTypePointer(J
|
||||
JNIEXPORT jlong JNICALL Java_kotlin_1native_interop_CallbacksKt_ffiTypeStruct0(JNIEnv *env, jclass cls, jlong elements) {
|
||||
ffi_type* res = malloc(sizeof(ffi_type));
|
||||
if (res != NULL) {
|
||||
res->size = 0;
|
||||
res->alignment = 0;
|
||||
res->elements = (ffi_type**) elements;
|
||||
res->type = FFI_TYPE_STRUCT;
|
||||
}
|
||||
@@ -164,7 +166,11 @@ static void ffi_fun(ffi_cif *cif, void *ret, void **args, void *user_data) {
|
||||
static jmethodID ffiFunImpl0 = NULL;
|
||||
static jclass cls = NULL;
|
||||
if (ffiFunImpl0 == NULL) {
|
||||
cls = (*env)->FindClass(env, "kotlin_native/interop/CallbacksKt");
|
||||
jclass clsLocal = (*env)->FindClass(env, "kotlin_native/interop/CallbacksKt");
|
||||
checkException(env);
|
||||
assert(clsLocal != NULL);
|
||||
|
||||
cls = (jclass) (*env)->NewGlobalRef(env, clsLocal);
|
||||
checkException(env);
|
||||
assert(cls != NULL);
|
||||
|
||||
|
||||
+33
-9
@@ -374,7 +374,7 @@ class StubGenerator(
|
||||
|
||||
is RecordType -> {
|
||||
val refType = getKotlinTypeForRefTo(type)
|
||||
InValueBinding(
|
||||
return InValueBinding(
|
||||
kotlinJniBridgeType = "Long",
|
||||
conv = { "NativePtr.byValue($it).asRef(${refType.typeExpr})!!" },
|
||||
kotlinType = refType.typeName
|
||||
@@ -386,6 +386,16 @@ class StubGenerator(
|
||||
}
|
||||
|
||||
fun getCallbackParamBinding(type: Type): InValueBinding {
|
||||
when (type) {
|
||||
is RecordType -> {
|
||||
val refType = getKotlinTypeForRefTo(type)
|
||||
return InValueBinding(
|
||||
kotlinJniBridgeType = "Long",
|
||||
conv = { throw UnsupportedOperationException() },
|
||||
kotlinType = refType.typeName
|
||||
)
|
||||
}
|
||||
}
|
||||
return getInValueBinding(type)
|
||||
}
|
||||
|
||||
@@ -578,6 +588,11 @@ class StubGenerator(
|
||||
out("}")
|
||||
}
|
||||
|
||||
private fun getFfiStructType(elementTypes: List<Type>) =
|
||||
"Struct(" +
|
||||
elementTypes.map { getFfiType(it) }.joinToString(", ") +
|
||||
")"
|
||||
|
||||
private fun getFfiType(type: Type): String {
|
||||
return when(type) {
|
||||
is VoidType -> "Void"
|
||||
@@ -588,29 +603,38 @@ class StubGenerator(
|
||||
is Int32Type -> "SInt32"
|
||||
is UInt32Type -> "UInt32"
|
||||
is IntPtrType, is UIntPtrType, // TODO
|
||||
is PointerType, is ArrayType -> "Pointer"
|
||||
is PointerType -> "Pointer"
|
||||
is ConstArrayType -> getFfiStructType(
|
||||
Array(type.length.toInt(), { type.elemType }).toList()
|
||||
)
|
||||
is EnumType -> getFfiType(type.def.baseType)
|
||||
is RecordType -> {
|
||||
val def = type.decl.def!!
|
||||
if (!def.hasNaturalLayout) {
|
||||
throw NotImplementedError() // TODO: represent pointer to function as NativePtr instead
|
||||
}
|
||||
"Struct(" + def.fields.map {
|
||||
getFfiType(it.type)
|
||||
}.joinToString(", ") + ")"
|
||||
getFfiStructType(def.fields.map { it.type })
|
||||
}
|
||||
else -> throw NotImplementedError(type.toString())
|
||||
}
|
||||
}
|
||||
|
||||
private fun getArgFfiType(type: Type) = when (type) {
|
||||
is ArrayType -> "Pointer"
|
||||
else -> getFfiType(type)
|
||||
}
|
||||
|
||||
private fun getRetValFfiType(type: Type) = getArgFfiType(type)
|
||||
|
||||
private fun generateFunctionType(type: FunctionType, name: String) {
|
||||
val kotlinFunctionType = getKotlinFunctionType(type)
|
||||
|
||||
val constructorArgs = listOf(type.returnType, *type.parameterTypes.toTypedArray()).map {
|
||||
getFfiType(it)
|
||||
}.joinToString(", ")
|
||||
val constructorArgs = listOf(getRetValFfiType(type.returnType)) +
|
||||
type.parameterTypes.map { getArgFfiType(it) }
|
||||
|
||||
out("object $name : NativeFunctionType<$kotlinFunctionType>($constructorArgs) {")
|
||||
val constructorArgsStr = constructorArgs.joinToString(", ")
|
||||
|
||||
out("object $name : NativeFunctionType<$kotlinFunctionType>($constructorArgsStr) {")
|
||||
indent {
|
||||
out("override fun invoke(function: $kotlinFunctionType, args: NativeArray<NativePtrBox>, ret: NativePtr) {")
|
||||
indent {
|
||||
|
||||
Reference in New Issue
Block a user