mirror of
https://github.com/GayPizzaSpecifications/pork.git
synced 2025-08-02 12:50:55 +00:00
ffi: rework for future struct support
This commit is contained in:
parent
7cb3e02b21
commit
dacec08587
30
ffi/src/main/kotlin/gay/pizza/pork/ffi/FfiPrimitiveType.kt
Normal file
30
ffi/src/main/kotlin/gay/pizza/pork/ffi/FfiPrimitiveType.kt
Normal file
@ -0,0 +1,30 @@
|
||||
package gay.pizza.pork.ffi
|
||||
|
||||
import gay.pizza.pork.evaluator.None
|
||||
|
||||
enum class FfiPrimitiveType(
|
||||
val id: kotlin.String,
|
||||
override val size: kotlin.Int,
|
||||
val numberConvert: (Number.() -> Number)? = null,
|
||||
val nullableConversion: (Any?.() -> Any)? = null,
|
||||
val notNullConversion: (Any.() -> Any)? = null
|
||||
) : FfiType {
|
||||
Byte("byte", 1, numberConvert = { toByte() }),
|
||||
UnsignedByte("unsigned byte", 1, numberConvert = { toByte()}),
|
||||
Short("short", 2, numberConvert = { toShort() }),
|
||||
UnsignedShort("unsigned short", 2, numberConvert = { toShort() }),
|
||||
Int("int", 4, numberConvert = { toInt() }),
|
||||
UnsignedInt("unsigned int", 4, numberConvert = { toInt() }),
|
||||
Float("float", 4, numberConvert = { toFloat() }),
|
||||
Long("long", 8, numberConvert = { toLong() }),
|
||||
UnsignedLong("unsigned long", 8, numberConvert = { toLong() }),
|
||||
Double("double", 8, numberConvert = { toDouble() }),
|
||||
String("char*", 8, nullableConversion = { toString() }),
|
||||
Pointer("void*", 8, nullableConversion = {
|
||||
if (this is kotlin.Long) {
|
||||
com.sun.jna.Pointer(this)
|
||||
} else if (this == None) {
|
||||
com.sun.jna.Pointer.NULL
|
||||
} else this as com.sun.jna.Pointer
|
||||
})
|
||||
}
|
14
ffi/src/main/kotlin/gay/pizza/pork/ffi/FfiStruct.kt
Normal file
14
ffi/src/main/kotlin/gay/pizza/pork/ffi/FfiStruct.kt
Normal file
@ -0,0 +1,14 @@
|
||||
package gay.pizza.pork.ffi
|
||||
|
||||
class FfiStruct : FfiType {
|
||||
private val fields = mutableListOf<FfiStructField>()
|
||||
|
||||
data class FfiStructField(val name: String, val type: FfiType)
|
||||
|
||||
fun add(field: String, type: FfiType) {
|
||||
fields.add(FfiStructField(field, type))
|
||||
}
|
||||
|
||||
override val size: Int
|
||||
get() = fields.sumOf { it.type.size }
|
||||
}
|
5
ffi/src/main/kotlin/gay/pizza/pork/ffi/FfiType.kt
Normal file
5
ffi/src/main/kotlin/gay/pizza/pork/ffi/FfiType.kt
Normal file
@ -0,0 +1,5 @@
|
||||
package gay.pizza.pork.ffi
|
||||
|
||||
interface FfiType {
|
||||
val size: Int
|
||||
}
|
@ -2,7 +2,6 @@ package gay.pizza.pork.ffi
|
||||
|
||||
import com.sun.jna.Function
|
||||
import com.sun.jna.NativeLibrary
|
||||
import com.sun.jna.Pointer
|
||||
import gay.pizza.pork.ast.ArgumentSpec
|
||||
import gay.pizza.pork.evaluator.CallableFunction
|
||||
import gay.pizza.pork.evaluator.NativeProvider
|
||||
@ -48,24 +47,23 @@ class JnaNativeProvider : NativeProvider {
|
||||
else -> type
|
||||
}
|
||||
|
||||
private fun convert(type: String, value: Any?): Any? = when (rewriteType(type)) {
|
||||
"short" -> numberConvert(type, value) { toShort() }
|
||||
"unsigned short" -> numberConvert(type, value) { toShort() }
|
||||
"int" -> numberConvert(type, value) { toInt() }
|
||||
"unsigned int" -> numberConvert(type, value) { toInt() }
|
||||
"long" -> numberConvert(type, value) { toLong() }
|
||||
"unsigned long" -> numberConvert(type, value) { toLong() }
|
||||
"double" -> numberConvert(type, value) { toDouble() }
|
||||
"float" -> numberConvert(type, value) { toFloat() }
|
||||
"char*" -> notNullConvert(type, value) { toString() }
|
||||
"void*" -> nullableConvert(value) {
|
||||
if (value is Long) {
|
||||
Pointer(value)
|
||||
} else {
|
||||
value as Pointer
|
||||
}
|
||||
private fun convert(type: String, value: Any?): Any? {
|
||||
val rewritten = rewriteType(type)
|
||||
val primitive = FfiPrimitiveType.entries.firstOrNull { it.id == rewritten }
|
||||
?: throw RuntimeException("Unsupported ffi type: $type")
|
||||
if (primitive.numberConvert != null) {
|
||||
return numberConvert(type, value, primitive.numberConvert)
|
||||
}
|
||||
else -> throw RuntimeException("Unsupported ffi type: $type")
|
||||
|
||||
if (primitive.notNullConversion != null) {
|
||||
return notNullConvert(type, value, primitive.notNullConversion)
|
||||
}
|
||||
|
||||
if (primitive.nullableConversion != null) {
|
||||
return nullableConvert(value, primitive.nullableConversion)
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
private fun <T> notNullConvert(type: String, value: Any?, into: Any.() -> T): T {
|
||||
|
@ -1,2 +1,3 @@
|
||||
org.gradle.warning.mode=none
|
||||
kotlin.stdlib.default.dependency=false
|
||||
kotlin.experimental.tryK2=true
|
||||
|
Loading…
Reference in New Issue
Block a user