Allow passing interop types to C API, refactoring.
This commit is contained in:
committed by
Nikolay Igotti
parent
76834dc7ce
commit
1599eddfe1
+27
-16
@@ -94,6 +94,13 @@ private val cnameAnnotation = FqName("konan.internal.CName")
|
|||||||
private fun org.jetbrains.kotlin.types.KotlinType.isGeneric() =
|
private fun org.jetbrains.kotlin.types.KotlinType.isGeneric() =
|
||||||
constructor.declarationDescriptor is TypeParameterDescriptor
|
constructor.declarationDescriptor is TypeParameterDescriptor
|
||||||
|
|
||||||
|
private val ClassDescriptor.isString
|
||||||
|
get() = fqNameSafe.asString() == "kotlin.String"
|
||||||
|
|
||||||
|
private val ClassDescriptor.isValueType
|
||||||
|
get() = this.defaultType.correspondingValueType != null
|
||||||
|
|
||||||
|
|
||||||
private fun isExportedFunction(descriptor: FunctionDescriptor): Boolean {
|
private fun isExportedFunction(descriptor: FunctionDescriptor): Boolean {
|
||||||
if (!descriptor.isEffectivelyPublicApi || !descriptor.kind.isReal)
|
if (!descriptor.isEffectivelyPublicApi || !descriptor.kind.isReal)
|
||||||
return false
|
return false
|
||||||
@@ -329,9 +336,8 @@ private class ExportedElement(val kind: ElementKind,
|
|||||||
|
|
||||||
private fun translateArgument(name: String, clazz: ClassDescriptor, direction: Direction,
|
private fun translateArgument(name: String, clazz: ClassDescriptor, direction: Direction,
|
||||||
builder: StringBuilder): String {
|
builder: StringBuilder): String {
|
||||||
val fqName = clazz.fqNameSafe.asString()
|
|
||||||
return when {
|
return when {
|
||||||
fqName == "kotlin.String" ->
|
clazz.isString ->
|
||||||
if (direction == Direction.C_TO_KOTLIN) {
|
if (direction == Direction.C_TO_KOTLIN) {
|
||||||
builder.append(" KObjHolder ${name}_holder;\n")
|
builder.append(" KObjHolder ${name}_holder;\n")
|
||||||
"CreateStringFromCString($name, ${name}_holder.slot())"
|
"CreateStringFromCString($name, ${name}_holder.slot())"
|
||||||
@@ -345,7 +351,10 @@ private class ExportedElement(val kind: ElementKind,
|
|||||||
} else {
|
} else {
|
||||||
"((${owner.translateType(clazz)}){ .pinned = CreateStablePointer(${name})})"
|
"((${owner.translateType(clazz)}){ .pinned = CreateStablePointer(${name})})"
|
||||||
}
|
}
|
||||||
else -> name
|
else -> {
|
||||||
|
assert(clazz.isValueType)
|
||||||
|
name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -830,23 +839,24 @@ internal class CAdapterGenerator(
|
|||||||
)
|
)
|
||||||
|
|
||||||
private val primitiveTypeMapping = mapOf(
|
private val primitiveTypeMapping = mapOf(
|
||||||
"kotlin.Byte" to "${prefix}_KByte",
|
ValueType.BOOLEAN to "${prefix}_KByte",
|
||||||
"kotlin.Short" to "${prefix}_KShort",
|
ValueType.SHORT to "${prefix}_KShort",
|
||||||
"kotlin.Int" to "${prefix}_KInt",
|
ValueType.INT to "${prefix}_KInt",
|
||||||
"kotlin.Long" to "${prefix}_KLong",
|
ValueType.LONG to "${prefix}_KLong",
|
||||||
"kotlin.Float" to "${prefix}_KFloat",
|
ValueType.FLOAT to "${prefix}_KFloat",
|
||||||
"kotlin.Double" to "${prefix}_KDouble",
|
ValueType.DOUBLE to "${prefix}_KDouble",
|
||||||
"kotlin.Boolean" to "${prefix}_KBoolean",
|
ValueType.CHAR to "${prefix}_KChar",
|
||||||
"kotlin.Char" to "${prefix}_KChar"
|
ValueType.C_POINTER to "void*",
|
||||||
|
ValueType.NATIVE_PTR to "void*",
|
||||||
|
ValueType.NATIVE_POINTED to "void*"
|
||||||
)
|
)
|
||||||
|
|
||||||
internal fun isMappedToString(descriptor: ClassDescriptor) =
|
internal fun isMappedToString(descriptor: ClassDescriptor) =
|
||||||
descriptor.fqNameSafe.asString() == "kotlin.String"
|
descriptor.fqNameSafe.asString() == "kotlin.String"
|
||||||
|
|
||||||
internal fun isMappedToReference(descriptor: ClassDescriptor): Boolean {
|
internal fun isMappedToReference(descriptor: ClassDescriptor) =
|
||||||
val name = descriptor.fqNameSafe.asString()
|
!descriptor.isUnit() && !isMappedToString(descriptor) &&
|
||||||
return !descriptor.isUnit() && name != "kotlin.String" && !primitiveTypeMapping.contains(name)
|
!primitiveTypeMapping.contains(descriptor.defaultType.correspondingValueType)
|
||||||
}
|
|
||||||
|
|
||||||
internal fun isMappedToVoid(descriptor: ClassDescriptor): Boolean {
|
internal fun isMappedToVoid(descriptor: ClassDescriptor): Boolean {
|
||||||
return descriptor.isUnit()
|
return descriptor.isUnit()
|
||||||
@@ -862,10 +872,11 @@ internal class CAdapterGenerator(
|
|||||||
|
|
||||||
private fun translateTypeFull(clazz: ClassDescriptor): Pair<String, String> {
|
private fun translateTypeFull(clazz: ClassDescriptor): Pair<String, String> {
|
||||||
val fqName = clazz.fqNameSafe.asString()
|
val fqName = clazz.fqNameSafe.asString()
|
||||||
|
val valueType = clazz.defaultType.correspondingValueType
|
||||||
return when {
|
return when {
|
||||||
clazz.isUnit() -> "void" to "void"
|
clazz.isUnit() -> "void" to "void"
|
||||||
fqName == "kotlin.String" -> "const char*" to "KObjHeader*"
|
fqName == "kotlin.String" -> "const char*" to "KObjHeader*"
|
||||||
primitiveTypeMapping.contains(fqName) -> primitiveTypeMapping[fqName]!! to primitiveTypeMapping[fqName]!!
|
valueType != null && primitiveTypeMapping.contains(valueType) -> primitiveTypeMapping[valueType]!! to primitiveTypeMapping[valueType]!!
|
||||||
else -> "${prefix}_kref_${translateTypeFqName(clazz.fqNameSafe.asString())}" to "KObjHeader*"
|
else -> "${prefix}_kref_${translateTypeFqName(clazz.fqNameSafe.asString())}" to "KObjHeader*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import kotlinx.cinterop.*
|
||||||
|
|
||||||
// Top level functions.
|
// Top level functions.
|
||||||
fun hello() {
|
fun hello() {
|
||||||
@@ -16,12 +17,14 @@ open class Base {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Top level functions.
|
||||||
@konan.internal.CName(fullName = "topLevelFunctionFromC", shortName = "topLevelFunctionFromCShort")
|
@konan.internal.CName(fullName = "topLevelFunctionFromC", shortName = "topLevelFunctionFromCShort")
|
||||||
fun topLevelFunction(x1: Int, x2: Int) = x1 - x2
|
fun topLevelFunction(x1: Int, x2: Int) = x1 - x2
|
||||||
|
|
||||||
@konan.internal.CName("topLevelFunctionVoidFromC")
|
@konan.internal.CName("topLevelFunctionVoidFromC")
|
||||||
fun topLevelFunctionVoid(x1: Int) {
|
fun topLevelFunctionVoid(x1: Int, pointer: COpaquePointer?) {
|
||||||
assert(x1 == 42)
|
assert(x1 == 42)
|
||||||
|
assert(pointer == null)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enum.
|
// Enum.
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ int main(void) {
|
|||||||
|
|
||||||
printf("object = %d\n", __ kotlin.root.Codeable.asCode(object1));
|
printf("object = %d\n", __ kotlin.root.Codeable.asCode(object1));
|
||||||
|
|
||||||
topLevelFunctionVoidFromC(42);
|
topLevelFunctionVoidFromC(42, 0);
|
||||||
__ kotlin.root.topLevelFunctionVoid(42);
|
__ kotlin.root.topLevelFunctionVoid(42, 0);
|
||||||
printf("topLevel = %d %d\n", topLevelFunctionFromC(780, 3), __ kotlin.root.topLevelFunctionFromCShort(5, 2));
|
printf("topLevel = %d %d\n", topLevelFunctionFromC(780, 3), __ kotlin.root.topLevelFunctionFromCShort(5, 2));
|
||||||
|
|
||||||
__ DisposeString(string);
|
__ DisposeString(string);
|
||||||
|
|||||||
Reference in New Issue
Block a user