mirror of
https://github.com/GayPizzaSpecifications/pork.git
synced 2025-08-02 21:00:56 +00:00
ffi: migrate to java.lang.foreign and require Java 21
This commit is contained in:
parent
c340cfb86d
commit
e31566f0d6
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -6,10 +6,10 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Checkout Repository
|
- name: Checkout Repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 21
|
||||||
uses: actions/setup-java@v3
|
uses: actions/setup-java@v3
|
||||||
with:
|
with:
|
||||||
java-version: '17'
|
java-version: '21'
|
||||||
distribution: 'temurin'
|
distribution: 'temurin'
|
||||||
- name: Build with Gradle
|
- name: Build with Gradle
|
||||||
uses: gradle/gradle-build-action@v2
|
uses: gradle/gradle-build-action@v2
|
||||||
|
6
.github/workflows/graal.yml
vendored
6
.github/workflows/graal.yml
vendored
@ -9,7 +9,7 @@ jobs:
|
|||||||
- name: Set up GraalVM
|
- name: Set up GraalVM
|
||||||
uses: graalvm/setup-graalvm@v1
|
uses: graalvm/setup-graalvm@v1
|
||||||
with:
|
with:
|
||||||
java-version: '17'
|
java-version: '21'
|
||||||
distribution: 'graalvm'
|
distribution: 'graalvm'
|
||||||
- name: Build with Gradle
|
- name: Build with Gradle
|
||||||
uses: gradle/gradle-build-action@v2
|
uses: gradle/gradle-build-action@v2
|
||||||
@ -33,7 +33,7 @@ jobs:
|
|||||||
- name: Set up GraalVM
|
- name: Set up GraalVM
|
||||||
uses: graalvm/setup-graalvm@v1
|
uses: graalvm/setup-graalvm@v1
|
||||||
with:
|
with:
|
||||||
java-version: '17'
|
java-version: '21'
|
||||||
distribution: 'graalvm'
|
distribution: 'graalvm'
|
||||||
- name: Build with Gradle
|
- name: Build with Gradle
|
||||||
uses: gradle/gradle-build-action@v2
|
uses: gradle/gradle-build-action@v2
|
||||||
@ -57,7 +57,7 @@ jobs:
|
|||||||
- name: Set up GraalVM
|
- name: Set up GraalVM
|
||||||
uses: graalvm/setup-graalvm@v1
|
uses: graalvm/setup-graalvm@v1
|
||||||
with:
|
with:
|
||||||
java-version: '17'
|
java-version: '21'
|
||||||
distribution: 'graalvm'
|
distribution: 'graalvm'
|
||||||
- name: Build with Gradle
|
- name: Build with Gradle
|
||||||
uses: gradle/gradle-build-action@v2
|
uses: gradle/gradle-build-action@v2
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm") version "1.9.10" apply false
|
id("gay.pizza.pork.root")
|
||||||
kotlin("plugin.serialization") version "1.9.10" apply false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<Wrapper> {
|
tasks.withType<Wrapper> {
|
||||||
gradleVersion = "8.3"
|
gradleVersion = "8.4-rc-1"
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
@file:Suppress("UnstableApiUsage")
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
`kotlin-dsl`
|
`kotlin-dsl`
|
||||||
embeddedKotlin("plugin.serialization")
|
embeddedKotlin("plugin.serialization")
|
||||||
@ -10,14 +11,31 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.10")
|
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.20-Beta2")
|
||||||
implementation("org.jetbrains.kotlin:kotlin-serialization:1.9.10")
|
implementation("org.jetbrains.kotlin:kotlin-serialization:1.9.20-Beta2")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
|
||||||
implementation("com.charleskorn.kaml:kaml:0.55.0")
|
implementation("com.charleskorn.kaml:kaml:0.55.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_20
|
||||||
|
targetCompatibility = JavaVersion.VERSION_20
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<KotlinCompile> {
|
||||||
|
kotlinOptions.jvmTarget = "20"
|
||||||
|
}
|
||||||
|
|
||||||
gradlePlugin {
|
gradlePlugin {
|
||||||
plugins {
|
plugins {
|
||||||
|
create("pork_root") {
|
||||||
|
id = "gay.pizza.pork.root"
|
||||||
|
implementationClass = "gay.pizza.pork.buildext.PorkRootPlugin"
|
||||||
|
|
||||||
|
displayName = "Pork Root"
|
||||||
|
description = "Root convention for pork"
|
||||||
|
}
|
||||||
|
|
||||||
create("pork_ast") {
|
create("pork_ast") {
|
||||||
id = "gay.pizza.pork.ast"
|
id = "gay.pizza.pork.ast"
|
||||||
implementationClass = "gay.pizza.pork.buildext.PorkAstPlugin"
|
implementationClass = "gay.pizza.pork.buildext.PorkAstPlugin"
|
||||||
|
@ -5,6 +5,7 @@ import org.gradle.api.Plugin
|
|||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.plugins.JavaPluginExtension
|
import org.gradle.api.plugins.JavaPluginExtension
|
||||||
import org.gradle.kotlin.dsl.*
|
import org.gradle.kotlin.dsl.*
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
|
|
||||||
open class PorkModulePlugin : Plugin<Project> {
|
open class PorkModulePlugin : Plugin<Project> {
|
||||||
@ -16,13 +17,17 @@ open class PorkModulePlugin : Plugin<Project> {
|
|||||||
target.repositories.maven(url = "https://gitlab.com/api/v4/projects/49101454/packages/maven")
|
target.repositories.maven(url = "https://gitlab.com/api/v4/projects/49101454/packages/maven")
|
||||||
|
|
||||||
target.extensions.getByType<JavaPluginExtension>().apply {
|
target.extensions.getByType<JavaPluginExtension>().apply {
|
||||||
val javaVersion = JavaVersion.toVersion(17)
|
val javaVersion = JavaVersion.toVersion(21)
|
||||||
sourceCompatibility = javaVersion
|
sourceCompatibility = javaVersion
|
||||||
targetCompatibility = javaVersion
|
targetCompatibility = javaVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
target.tasks.withType<KotlinCompile> {
|
target.tasks.withType<KotlinCompile> {
|
||||||
kotlinOptions.jvmTarget = "17"
|
kotlinOptions.jvmTarget = "21"
|
||||||
|
}
|
||||||
|
|
||||||
|
target.extensions.getByType<KotlinJvmProjectExtension>().apply {
|
||||||
|
jvmToolchain(21)
|
||||||
}
|
}
|
||||||
|
|
||||||
target.dependencies {
|
target.dependencies {
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
package gay.pizza.pork.buildext
|
||||||
|
|
||||||
|
import org.gradle.api.Plugin
|
||||||
|
import org.gradle.api.Project
|
||||||
|
|
||||||
|
class PorkRootPlugin : Plugin<Project> {
|
||||||
|
override fun apply(target: Project) {}
|
||||||
|
}
|
@ -7,5 +7,4 @@ dependencies {
|
|||||||
api(project(":evaluator"))
|
api(project(":evaluator"))
|
||||||
|
|
||||||
implementation(project(":common"))
|
implementation(project(":common"))
|
||||||
implementation("net.java.dev.jna:jna:5.13.0")
|
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,10 @@ class FfiFunctionDefinition(
|
|||||||
library,
|
library,
|
||||||
functionName,
|
functionName,
|
||||||
returnType,
|
returnType,
|
||||||
parameterString.split(",").map { it.trim() }
|
parameterString.splitToSequence(",")
|
||||||
|
.map { it.trim() }
|
||||||
|
.filter { it.isNotEmpty() }
|
||||||
|
.toList()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
46
ffi/src/main/kotlin/gay/pizza/pork/ffi/FfiLibraryCache.kt
Normal file
46
ffi/src/main/kotlin/gay/pizza/pork/ffi/FfiLibraryCache.kt
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package gay.pizza.pork.ffi
|
||||||
|
|
||||||
|
import java.lang.foreign.*
|
||||||
|
|
||||||
|
object FfiLibraryCache {
|
||||||
|
private val dlopenFunctionDescriptor = FunctionDescriptor.of(ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.JAVA_INT)
|
||||||
|
private val dlsymFunctionDescriptor = FunctionDescriptor.of(ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS)
|
||||||
|
|
||||||
|
private val dlopenMemorySegment = Linker.nativeLinker().defaultLookup().find("dlopen").orElseThrow()
|
||||||
|
private val dlsymMemorySegment = Linker.nativeLinker().defaultLookup().find("dlsym").orElseThrow()
|
||||||
|
|
||||||
|
private val dlopen = Linker.nativeLinker().downcallHandle(
|
||||||
|
dlopenMemorySegment,
|
||||||
|
dlopenFunctionDescriptor
|
||||||
|
)
|
||||||
|
|
||||||
|
private val dlsym = Linker.nativeLinker().downcallHandle(
|
||||||
|
dlsymMemorySegment,
|
||||||
|
dlsymFunctionDescriptor
|
||||||
|
)
|
||||||
|
|
||||||
|
private val libraryHandles = mutableMapOf<String, MemorySegment>()
|
||||||
|
|
||||||
|
private fun dlopen(name: String): MemorySegment {
|
||||||
|
var handle = libraryHandles[name]
|
||||||
|
if (handle != null) {
|
||||||
|
return handle
|
||||||
|
}
|
||||||
|
return Arena.ofConfined().use { arena ->
|
||||||
|
val nameStringPointer = arena.allocateUtf8String(name)
|
||||||
|
handle = dlopen.invokeExact(nameStringPointer, 0) as MemorySegment
|
||||||
|
if (handle == MemorySegment.NULL) {
|
||||||
|
throw RuntimeException("Unable to dlopen library: $name")
|
||||||
|
}
|
||||||
|
handle!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun dlsym(name: String, symbol: String): MemorySegment {
|
||||||
|
val libraryHandle = dlopen(name)
|
||||||
|
return Arena.ofConfined().use { arena ->
|
||||||
|
val symbolStringPointer = arena.allocateUtf8String(symbol)
|
||||||
|
dlsym.invokeExact(libraryHandle, symbolStringPointer) as MemorySegment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
ffi/src/main/kotlin/gay/pizza/pork/ffi/FfiMacPlatform.kt
Normal file
25
ffi/src/main/kotlin/gay/pizza/pork/ffi/FfiMacPlatform.kt
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package gay.pizza.pork.ffi
|
||||||
|
|
||||||
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.*
|
||||||
|
|
||||||
|
object FfiMacPlatform : FfiPlatform {
|
||||||
|
private val frameworksDirectories = listOf(
|
||||||
|
"/Library/Frameworks"
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun findLibrary(name: String): Path? {
|
||||||
|
val frameworksToCheck = frameworksDirectories.map { frameworkDirectory ->
|
||||||
|
Path("$frameworkDirectory/$name.framework/$name")
|
||||||
|
}
|
||||||
|
for (framework in frameworksToCheck) {
|
||||||
|
if (!framework.exists()) continue
|
||||||
|
return if (framework.isSymbolicLink()) {
|
||||||
|
return framework.parent.resolve(framework.readSymbolicLink()).absolute()
|
||||||
|
} else {
|
||||||
|
framework.absolute()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
79
ffi/src/main/kotlin/gay/pizza/pork/ffi/FfiNativeProvider.kt
Normal file
79
ffi/src/main/kotlin/gay/pizza/pork/ffi/FfiNativeProvider.kt
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
package gay.pizza.pork.ffi
|
||||||
|
|
||||||
|
import gay.pizza.pork.ast.ArgumentSpec
|
||||||
|
import gay.pizza.pork.evaluator.CallableFunction
|
||||||
|
import gay.pizza.pork.evaluator.NativeProvider
|
||||||
|
import gay.pizza.pork.evaluator.None
|
||||||
|
import java.lang.foreign.*
|
||||||
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.Path
|
||||||
|
import kotlin.io.path.absolutePathString
|
||||||
|
import kotlin.io.path.exists
|
||||||
|
|
||||||
|
class FfiNativeProvider : NativeProvider {
|
||||||
|
private val ffiTypeRegistry = FfiTypeRegistry()
|
||||||
|
|
||||||
|
override fun provideNativeFunction(definitions: List<String>, arguments: List<ArgumentSpec>): CallableFunction {
|
||||||
|
val functionDefinition = FfiFunctionDefinition.parse(definitions[0], definitions[1])
|
||||||
|
val linker = Linker.nativeLinker()
|
||||||
|
val functionAddress = lookupSymbol(functionDefinition)
|
||||||
|
|
||||||
|
val parameters = functionDefinition.parameters.map { id ->
|
||||||
|
ffiTypeRegistry.lookup(id) ?: throw RuntimeException("Unknown ffi type: $id")
|
||||||
|
}
|
||||||
|
|
||||||
|
val returnTypeId = functionDefinition.returnType
|
||||||
|
val returnType = ffiTypeRegistry.lookup(returnTypeId) ?:
|
||||||
|
throw RuntimeException("Unknown ffi return type: $returnTypeId")
|
||||||
|
val parameterArray = parameters.map { typeAsLayout(it) }.toTypedArray()
|
||||||
|
val descriptor = if (returnType == FfiPrimitiveType.Void)
|
||||||
|
FunctionDescriptor.ofVoid(*parameterArray)
|
||||||
|
else FunctionDescriptor.of(typeAsLayout(returnType), *parameterArray)
|
||||||
|
val handle = linker.downcallHandle(functionAddress, descriptor)
|
||||||
|
return CallableFunction { functionArguments, _ ->
|
||||||
|
Arena.ofConfined().use { arena ->
|
||||||
|
handle.invokeWithArguments(functionArguments.map { valueAsFfi(it, arena) }) ?: None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun lookupSymbol(functionDefinition: FfiFunctionDefinition): MemorySegment {
|
||||||
|
if (functionDefinition.library == "c") {
|
||||||
|
return SymbolLookup.loaderLookup().find(functionDefinition.function).orElseThrow {
|
||||||
|
RuntimeException("Unknown function: ${functionDefinition.function}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val actualLibraryPath = findLibraryPath(functionDefinition.library)
|
||||||
|
val functionAddress = FfiLibraryCache.dlsym(actualLibraryPath.absolutePathString(), functionDefinition.function)
|
||||||
|
if (functionAddress.address() == 0L) {
|
||||||
|
throw RuntimeException("Unknown function: ${functionDefinition.function} in library $actualLibraryPath")
|
||||||
|
}
|
||||||
|
return functionAddress
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun typeAsLayout(type: FfiType): MemoryLayout = when (type) {
|
||||||
|
FfiPrimitiveType.UnsignedByte, FfiPrimitiveType.Byte -> ValueLayout.JAVA_BYTE
|
||||||
|
FfiPrimitiveType.UnsignedInt, FfiPrimitiveType.Int -> ValueLayout.JAVA_INT
|
||||||
|
FfiPrimitiveType.UnsignedShort, FfiPrimitiveType.Short -> ValueLayout.JAVA_SHORT
|
||||||
|
FfiPrimitiveType.UnsignedLong, FfiPrimitiveType.Long -> ValueLayout.JAVA_LONG
|
||||||
|
FfiPrimitiveType.String -> ValueLayout.ADDRESS
|
||||||
|
FfiPrimitiveType.Pointer -> ValueLayout.ADDRESS
|
||||||
|
FfiPrimitiveType.Void -> MemoryLayout.sequenceLayout(0, ValueLayout.JAVA_INT)
|
||||||
|
else -> throw RuntimeException("Unknown ffi type to convert to memory layout: $type")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun valueAsFfi(value: Any, allocator: SegmentAllocator): Any = when (value) {
|
||||||
|
is String -> allocator.allocateUtf8String(value)
|
||||||
|
None -> MemorySegment.NULL
|
||||||
|
else -> value
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findLibraryPath(name: String): Path {
|
||||||
|
val initialPath = Path(name)
|
||||||
|
if (initialPath.exists()) {
|
||||||
|
return initialPath
|
||||||
|
}
|
||||||
|
return FfiPlatforms.current.platform.findLibrary(name)
|
||||||
|
?: throw RuntimeException("Unable to find library: $name")
|
||||||
|
}
|
||||||
|
}
|
24
ffi/src/main/kotlin/gay/pizza/pork/ffi/FfiPlatform.kt
Normal file
24
ffi/src/main/kotlin/gay/pizza/pork/ffi/FfiPlatform.kt
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package gay.pizza.pork.ffi
|
||||||
|
|
||||||
|
import java.nio.file.Path
|
||||||
|
|
||||||
|
enum class FfiPlatforms(val id: String, val platform: FfiPlatform) {
|
||||||
|
Mac("macOS", FfiMacPlatform),
|
||||||
|
Windows("Windows", FfiWindowsPlatform),
|
||||||
|
Unix("Unix", FfiUnixPlatform);
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val current by lazy {
|
||||||
|
val operatingSystemName = System.getProperty("os.name").lowercase()
|
||||||
|
when {
|
||||||
|
operatingSystemName.contains("win") -> Windows
|
||||||
|
operatingSystemName.contains("mac") -> Mac
|
||||||
|
else -> Unix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FfiPlatform {
|
||||||
|
fun findLibrary(name: String): Path?
|
||||||
|
}
|
@ -1,10 +1,11 @@
|
|||||||
package gay.pizza.pork.ffi
|
package gay.pizza.pork.ffi
|
||||||
|
|
||||||
import gay.pizza.pork.evaluator.None
|
import gay.pizza.pork.evaluator.None
|
||||||
|
import java.lang.foreign.MemorySegment
|
||||||
|
|
||||||
enum class FfiPrimitiveType(
|
enum class FfiPrimitiveType(
|
||||||
val id: kotlin.String,
|
val id: kotlin.String,
|
||||||
override val size: kotlin.Int,
|
override val size: kotlin.Long,
|
||||||
val numberConvert: (Number.() -> Number)? = null,
|
val numberConvert: (Number.() -> Number)? = null,
|
||||||
val nullableConversion: (Any?.() -> Any)? = null,
|
val nullableConversion: (Any?.() -> Any)? = null,
|
||||||
val notNullConversion: (Any.() -> Any)? = null
|
val notNullConversion: (Any.() -> Any)? = null
|
||||||
@ -22,9 +23,10 @@ enum class FfiPrimitiveType(
|
|||||||
String("char*", 8, nullableConversion = { toString() }),
|
String("char*", 8, nullableConversion = { toString() }),
|
||||||
Pointer("void*", 8, nullableConversion = {
|
Pointer("void*", 8, nullableConversion = {
|
||||||
if (this is kotlin.Long) {
|
if (this is kotlin.Long) {
|
||||||
com.sun.jna.Pointer(this)
|
MemorySegment.ofAddress(this)
|
||||||
} else if (this == None) {
|
} else if (this == None) {
|
||||||
com.sun.jna.Pointer.NULL
|
MemorySegment.NULL
|
||||||
} else this as com.sun.jna.Pointer
|
} else this as MemorySegment
|
||||||
})
|
}),
|
||||||
|
Void("void", 0)
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,6 @@ class FfiStruct : FfiType {
|
|||||||
fields.add(FfiStructField(field, type))
|
fields.add(FfiStructField(field, type))
|
||||||
}
|
}
|
||||||
|
|
||||||
override val size: Int
|
override val size: Long
|
||||||
get() = fields.sumOf { it.type.size }
|
get() = fields.sumOf { it.type.size }
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
package gay.pizza.pork.ffi
|
package gay.pizza.pork.ffi
|
||||||
|
|
||||||
interface FfiType {
|
interface FfiType {
|
||||||
val size: Int
|
val size: Long
|
||||||
}
|
}
|
||||||
|
18
ffi/src/main/kotlin/gay/pizza/pork/ffi/FfiTypeRegistry.kt
Normal file
18
ffi/src/main/kotlin/gay/pizza/pork/ffi/FfiTypeRegistry.kt
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package gay.pizza.pork.ffi
|
||||||
|
|
||||||
|
class FfiTypeRegistry {
|
||||||
|
private val types = mutableMapOf<String, FfiType>()
|
||||||
|
|
||||||
|
init {
|
||||||
|
for (type in FfiPrimitiveType.entries) {
|
||||||
|
add(type.id, type)
|
||||||
|
}
|
||||||
|
add("size_t", FfiPrimitiveType.Long)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun add(name: String, type: FfiType) {
|
||||||
|
types[name] = type
|
||||||
|
}
|
||||||
|
|
||||||
|
fun lookup(name: String): FfiType? = types[name]
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package gay.pizza.pork.ffi
|
||||||
|
|
||||||
|
import java.nio.file.Path
|
||||||
|
|
||||||
|
object FfiUnixPlatform : FfiPlatform {
|
||||||
|
override fun findLibrary(name: String): Path? = null
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package gay.pizza.pork.ffi
|
||||||
|
|
||||||
|
import java.nio.file.Path
|
||||||
|
|
||||||
|
object FfiWindowsPlatform : FfiPlatform {
|
||||||
|
override fun findLibrary(name: String): Path? = null
|
||||||
|
}
|
@ -1,93 +0,0 @@
|
|||||||
package gay.pizza.pork.ffi
|
|
||||||
|
|
||||||
import com.sun.jna.Function
|
|
||||||
import com.sun.jna.NativeLibrary
|
|
||||||
import gay.pizza.pork.ast.ArgumentSpec
|
|
||||||
import gay.pizza.pork.evaluator.CallableFunction
|
|
||||||
import gay.pizza.pork.evaluator.NativeProvider
|
|
||||||
import gay.pizza.pork.evaluator.None
|
|
||||||
|
|
||||||
class JnaNativeProvider : NativeProvider {
|
|
||||||
override fun provideNativeFunction(definitions: List<String>, arguments: List<ArgumentSpec>): CallableFunction {
|
|
||||||
val functionDefinition = FfiFunctionDefinition.parse(definitions[0], definitions[1])
|
|
||||||
val library = NativeLibrary.getInstance(functionDefinition.library)
|
|
||||||
val function = library.getFunction(functionDefinition.function)
|
|
||||||
?: throw RuntimeException("Failed to find function ${functionDefinition.function} in library ${functionDefinition.library}")
|
|
||||||
return CallableFunction { functionArgs, _ ->
|
|
||||||
val ffiArgs = mutableListOf<Any?>()
|
|
||||||
for ((index, spec) in arguments.withIndex()) {
|
|
||||||
val ffiType = functionDefinition.parameters[index]
|
|
||||||
if (spec.multiple) {
|
|
||||||
val variableArguments = functionArgs
|
|
||||||
.subList(index, functionArgs.size)
|
|
||||||
ffiArgs.addAll(variableArguments)
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
val converted = convert(ffiType, functionArgs[index])
|
|
||||||
ffiArgs.add(converted)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
invoke(function, ffiArgs.toTypedArray(), functionDefinition.returnType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun invoke(function: Function, values: Array<Any?>, type: String): Any = when (rewriteType(type)) {
|
|
||||||
"void*" -> function.invokePointer(values)
|
|
||||||
"int" -> function.invokeInt(values)
|
|
||||||
"long" -> function.invokeLong(values)
|
|
||||||
"float" -> function.invokeFloat(values)
|
|
||||||
"double" -> function.invokeDouble(values)
|
|
||||||
"void" -> function.invokeVoid(values)
|
|
||||||
"char*" -> function.invokeString(values, false)
|
|
||||||
else -> throw RuntimeException("Unsupported ffi return type: $type")
|
|
||||||
} ?: None
|
|
||||||
|
|
||||||
private fun rewriteType(type: String): String = when (type) {
|
|
||||||
"size_t" -> "long"
|
|
||||||
else -> type
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
|
||||||
if (value == null) {
|
|
||||||
throw RuntimeException("Null values cannot be used for converting to type $type")
|
|
||||||
}
|
|
||||||
return into(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun <T> nullableConvert(value: Any?, into: Any.() -> T): T? {
|
|
||||||
if (value == null || value == None) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
return into(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun <T> numberConvert(type: String, value: Any?, into: Number.() -> T): T {
|
|
||||||
if (value == null || value == None) {
|
|
||||||
throw RuntimeException("Null values cannot be used for converting to numeric type $type")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value !is Number) {
|
|
||||||
throw RuntimeException("Cannot convert value '$value' into type $type")
|
|
||||||
}
|
|
||||||
return into(value)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,653 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"name": "[Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "com.sun.jna.Callback"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "com.sun.jna.CallbackReference",
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "getCallback",
|
|
||||||
"parameterTypes": [
|
|
||||||
"java.lang.Class",
|
|
||||||
"com.sun.jna.Pointer",
|
|
||||||
"boolean"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "getFunctionPointer",
|
|
||||||
"parameterTypes": [
|
|
||||||
"com.sun.jna.Callback",
|
|
||||||
"boolean"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "getNativeString",
|
|
||||||
"parameterTypes": [
|
|
||||||
"java.lang.Object",
|
|
||||||
"boolean"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "initializeThread",
|
|
||||||
"parameterTypes": [
|
|
||||||
"com.sun.jna.Callback",
|
|
||||||
"com.sun.jna.CallbackReference$AttachOptions"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "com.sun.jna.CallbackReference$AttachOptions"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "com.sun.jna.FromNativeConverter",
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "nativeType",
|
|
||||||
"parameterTypes": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "com.sun.jna.IntegerType",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"name": "value"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "com.sun.jna.JNIEnv"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "com.sun.jna.Native",
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "dispose",
|
|
||||||
"parameterTypes": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "fromNative",
|
|
||||||
"parameterTypes": [
|
|
||||||
"com.sun.jna.FromNativeConverter",
|
|
||||||
"java.lang.Object",
|
|
||||||
"java.lang.reflect.Method"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "fromNative",
|
|
||||||
"parameterTypes": [
|
|
||||||
"java.lang.Class",
|
|
||||||
"java.lang.Object"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "fromNative",
|
|
||||||
"parameterTypes": [
|
|
||||||
"java.lang.reflect.Method",
|
|
||||||
"java.lang.Object"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "nativeType",
|
|
||||||
"parameterTypes": [
|
|
||||||
"java.lang.Class"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "toNative",
|
|
||||||
"parameterTypes": [
|
|
||||||
"com.sun.jna.ToNativeConverter",
|
|
||||||
"java.lang.Object"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "com.sun.jna.Native$ffi_callback",
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "invoke",
|
|
||||||
"parameterTypes": [
|
|
||||||
"long",
|
|
||||||
"long",
|
|
||||||
"long"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "com.sun.jna.NativeMapped",
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "toNative",
|
|
||||||
"parameterTypes": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "com.sun.jna.Pointer",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"name": "peer"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "<init>",
|
|
||||||
"parameterTypes": [
|
|
||||||
"long"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "com.sun.jna.PointerType",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"name": "pointer"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "com.sun.jna.Structure",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"name": "memory"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "typeInfo"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "autoRead",
|
|
||||||
"parameterTypes": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "autoWrite",
|
|
||||||
"parameterTypes": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "getTypeInfo",
|
|
||||||
"parameterTypes": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "newInstance",
|
|
||||||
"parameterTypes": [
|
|
||||||
"java.lang.Class",
|
|
||||||
"long"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "com.sun.jna.Structure$ByValue"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "com.sun.jna.Structure$FFIType$FFITypes",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"name": "ffi_type_double"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ffi_type_float"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ffi_type_longdouble"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ffi_type_pointer"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ffi_type_sint16"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ffi_type_sint32"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ffi_type_sint64"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ffi_type_sint8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ffi_type_uint16"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ffi_type_uint32"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ffi_type_uint64"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ffi_type_uint8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ffi_type_void"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "com.sun.jna.WString",
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "<init>",
|
|
||||||
"parameterTypes": [
|
|
||||||
"java.lang.String"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "java.lang.Boolean",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"name": "TYPE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "value"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "<init>",
|
|
||||||
"parameterTypes": [
|
|
||||||
"boolean"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "getBoolean",
|
|
||||||
"parameterTypes": [
|
|
||||||
"java.lang.String"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "java.lang.Byte",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"name": "TYPE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "value"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "<init>",
|
|
||||||
"parameterTypes": [
|
|
||||||
"byte"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "java.lang.Character",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"name": "TYPE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "value"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "<init>",
|
|
||||||
"parameterTypes": [
|
|
||||||
"char"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "java.lang.Class",
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "getComponentType",
|
|
||||||
"parameterTypes": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "java.lang.Double",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"name": "TYPE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "value"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "<init>",
|
|
||||||
"parameterTypes": [
|
|
||||||
"double"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "java.lang.Float",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"name": "TYPE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "value"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "<init>",
|
|
||||||
"parameterTypes": [
|
|
||||||
"float"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "java.lang.Integer",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"name": "TYPE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "value"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "<init>",
|
|
||||||
"parameterTypes": [
|
|
||||||
"int"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "java.lang.Long",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"name": "TYPE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "value"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "<init>",
|
|
||||||
"parameterTypes": [
|
|
||||||
"long"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "java.lang.Object",
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "toString",
|
|
||||||
"parameterTypes": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "java.lang.Short",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"name": "TYPE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "value"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "<init>",
|
|
||||||
"parameterTypes": [
|
|
||||||
"short"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "java.lang.String",
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "<init>",
|
|
||||||
"parameterTypes": [
|
|
||||||
"byte[]"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "<init>",
|
|
||||||
"parameterTypes": [
|
|
||||||
"byte[]",
|
|
||||||
"java.lang.String"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "getBytes",
|
|
||||||
"parameterTypes": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "getBytes",
|
|
||||||
"parameterTypes": [
|
|
||||||
"java.lang.String"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "lastIndexOf",
|
|
||||||
"parameterTypes": [
|
|
||||||
"int"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "substring",
|
|
||||||
"parameterTypes": [
|
|
||||||
"int"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "toCharArray",
|
|
||||||
"parameterTypes": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "java.lang.System",
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "getProperty",
|
|
||||||
"parameterTypes": [
|
|
||||||
"java.lang.String"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "setProperty",
|
|
||||||
"parameterTypes": [
|
|
||||||
"java.lang.String",
|
|
||||||
"java.lang.String"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "java.lang.Throwable",
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "toString",
|
|
||||||
"parameterTypes": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "java.lang.UnsatisfiedLinkError",
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "<init>",
|
|
||||||
"parameterTypes": [
|
|
||||||
"java.lang.String"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "java.lang.Void",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"name": "TYPE"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "java.lang.reflect.Method",
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "getParameterTypes",
|
|
||||||
"parameterTypes": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "getReturnType",
|
|
||||||
"parameterTypes": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "java.nio.Buffer",
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "position",
|
|
||||||
"parameterTypes": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "java.nio.ByteBuffer",
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "array",
|
|
||||||
"parameterTypes": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "arrayOffset",
|
|
||||||
"parameterTypes": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "java.nio.CharBuffer",
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "array",
|
|
||||||
"parameterTypes": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "arrayOffset",
|
|
||||||
"parameterTypes": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "java.nio.DoubleBuffer",
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "array",
|
|
||||||
"parameterTypes": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "arrayOffset",
|
|
||||||
"parameterTypes": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "java.nio.FloatBuffer",
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "array",
|
|
||||||
"parameterTypes": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "arrayOffset",
|
|
||||||
"parameterTypes": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "java.nio.IntBuffer",
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "array",
|
|
||||||
"parameterTypes": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "arrayOffset",
|
|
||||||
"parameterTypes": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "java.nio.LongBuffer",
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "array",
|
|
||||||
"parameterTypes": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "arrayOffset",
|
|
||||||
"parameterTypes": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "java.nio.ShortBuffer",
|
|
||||||
"methods": [
|
|
||||||
{
|
|
||||||
"name": "array",
|
|
||||||
"parameterTypes": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "arrayOffset",
|
|
||||||
"parameterTypes": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "sun.management.VMManagementImpl",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"name": "compTimeMonitoringSupport"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "currentThreadCpuTimeSupport"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "objectMonitorUsageSupport"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "otherThreadCpuTimeSupport"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "remoteDiagnosticCommandsSupport"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "synchronizerUsageSupport"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "threadAllocatedMemorySupport"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "threadContentionMonitoringSupport"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
@ -1,25 +0,0 @@
|
|||||||
{
|
|
||||||
"resources": {
|
|
||||||
"includes": [
|
|
||||||
{
|
|
||||||
"pattern": "\\Qcom/sun/jna/darwin-x86-64/libjnidispatch.jnilib\\E"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"pattern": "\\Qcom/sun/jna/linux-x86-64/libjnidispatch.so\\E"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"pattern": "\\Qcom/sun/jna/win32-x86-64/jnidispatch.dll\\E"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"pattern": "\\Qcom/sun/jna/darwin-aarch64/libjnidispatch.jnilib\\E"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"pattern": "\\Qcom/sun/jna/linux-aarch64/libjnidispatch.so\\E"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"pattern": "\\Qcom/sun/jna/win32-aarch64/jnidispatch.dll\\E"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"bundles": []
|
|
||||||
}
|
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-rc-1-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
@ -18,6 +18,8 @@ dependencies {
|
|||||||
application {
|
application {
|
||||||
applicationName = "pork-rt"
|
applicationName = "pork-rt"
|
||||||
mainClass.set("gay.pizza.pork.minimal.MainKt")
|
mainClass.set("gay.pizza.pork.minimal.MainKt")
|
||||||
|
applicationDefaultJvmArgs += "-XstartOnFirstThread"
|
||||||
|
applicationDefaultJvmArgs += "--enable-native-access=ALL-UNNAMED"
|
||||||
}
|
}
|
||||||
|
|
||||||
for (task in arrayOf(tasks.shadowDistTar, tasks.shadowDistZip, tasks.shadowJar)) {
|
for (task in arrayOf(tasks.shadowDistTar, tasks.shadowDistZip, tasks.shadowJar)) {
|
||||||
|
@ -4,9 +4,9 @@ import gay.pizza.pork.ast.CompilationUnit
|
|||||||
import gay.pizza.pork.ast.NodeVisitor
|
import gay.pizza.pork.ast.NodeVisitor
|
||||||
import gay.pizza.pork.ast.visit
|
import gay.pizza.pork.ast.visit
|
||||||
import gay.pizza.pork.evaluator.*
|
import gay.pizza.pork.evaluator.*
|
||||||
|
import gay.pizza.pork.ffi.FfiNativeProvider
|
||||||
import gay.pizza.pork.ffi.JavaAutogenContentSource
|
import gay.pizza.pork.ffi.JavaAutogenContentSource
|
||||||
import gay.pizza.pork.ffi.JavaNativeProvider
|
import gay.pizza.pork.ffi.JavaNativeProvider
|
||||||
import gay.pizza.pork.ffi.JnaNativeProvider
|
|
||||||
import gay.pizza.pork.frontend.ContentSource
|
import gay.pizza.pork.frontend.ContentSource
|
||||||
import gay.pizza.pork.frontend.ImportLocator
|
import gay.pizza.pork.frontend.ImportLocator
|
||||||
import gay.pizza.pork.frontend.DynamicImportSource
|
import gay.pizza.pork.frontend.DynamicImportSource
|
||||||
@ -55,7 +55,7 @@ abstract class Tool {
|
|||||||
fun run(scope: Scope, quiet: Boolean = false) {
|
fun run(scope: Scope, quiet: Boolean = false) {
|
||||||
val main = loadMainFunction(scope, setupEvaluator = {
|
val main = loadMainFunction(scope, setupEvaluator = {
|
||||||
addNativeProvider("internal", InternalNativeProvider(quiet = quiet))
|
addNativeProvider("internal", InternalNativeProvider(quiet = quiet))
|
||||||
addNativeProvider("ffi", JnaNativeProvider())
|
addNativeProvider("ffi", FfiNativeProvider())
|
||||||
addNativeProvider("java", JavaNativeProvider())
|
addNativeProvider("java", JavaNativeProvider())
|
||||||
})
|
})
|
||||||
main.call(emptyList(), CallStack())
|
main.call(emptyList(), CallStack())
|
||||||
|
@ -14,6 +14,7 @@ application {
|
|||||||
applicationName = "pork"
|
applicationName = "pork"
|
||||||
mainClass.set("gay.pizza.pork.tool.MainKt")
|
mainClass.set("gay.pizza.pork.tool.MainKt")
|
||||||
applicationDefaultJvmArgs += "-XstartOnFirstThread"
|
applicationDefaultJvmArgs += "-XstartOnFirstThread"
|
||||||
|
applicationDefaultJvmArgs += "--enable-native-access=ALL-UNNAMED"
|
||||||
}
|
}
|
||||||
|
|
||||||
for (task in arrayOf(tasks.shadowDistTar, tasks.shadowDistZip, tasks.shadowJar)) {
|
for (task in arrayOf(tasks.shadowDistTar, tasks.shadowDistZip, tasks.shadowJar)) {
|
||||||
|
@ -3,9 +3,7 @@ package gay.pizza.pork.tool
|
|||||||
import com.github.ajalt.clikt.core.CliktCommand
|
import com.github.ajalt.clikt.core.CliktCommand
|
||||||
import com.github.ajalt.clikt.parameters.arguments.argument
|
import com.github.ajalt.clikt.parameters.arguments.argument
|
||||||
import gay.pizza.dough.fs.PlatformFsProvider
|
import gay.pizza.dough.fs.PlatformFsProvider
|
||||||
import gay.pizza.pork.ast.Node
|
|
||||||
import gay.pizza.pork.ast.NodeCoalescer
|
import gay.pizza.pork.ast.NodeCoalescer
|
||||||
import gay.pizza.pork.ast.data
|
|
||||||
import gay.pizza.pork.ast.visit
|
import gay.pizza.pork.ast.visit
|
||||||
import gay.pizza.pork.minimal.FileTool
|
import gay.pizza.pork.minimal.FileTool
|
||||||
import gay.pizza.pork.parser.ParserAttributes
|
import gay.pizza.pork.parser.ParserAttributes
|
||||||
|
@ -6,8 +6,8 @@ import com.github.ajalt.clikt.parameters.options.flag
|
|||||||
import com.github.ajalt.clikt.parameters.options.option
|
import com.github.ajalt.clikt.parameters.options.option
|
||||||
import gay.pizza.dough.fs.PlatformFsProvider
|
import gay.pizza.dough.fs.PlatformFsProvider
|
||||||
import gay.pizza.pork.evaluator.*
|
import gay.pizza.pork.evaluator.*
|
||||||
|
import gay.pizza.pork.ffi.FfiNativeProvider
|
||||||
import gay.pizza.pork.ffi.JavaNativeProvider
|
import gay.pizza.pork.ffi.JavaNativeProvider
|
||||||
import gay.pizza.pork.ffi.JnaNativeProvider
|
|
||||||
import gay.pizza.pork.minimal.FileTool
|
import gay.pizza.pork.minimal.FileTool
|
||||||
|
|
||||||
class RunCommand : CliktCommand(help = "Run Program", name = "run") {
|
class RunCommand : CliktCommand(help = "Run Program", name = "run") {
|
||||||
@ -22,7 +22,7 @@ class RunCommand : CliktCommand(help = "Run Program", name = "run") {
|
|||||||
val scope = Scope.root()
|
val scope = Scope.root()
|
||||||
val main = tool.loadMainFunction(scope, setupEvaluator = {
|
val main = tool.loadMainFunction(scope, setupEvaluator = {
|
||||||
addNativeProvider("internal", InternalNativeProvider(quiet = quiet))
|
addNativeProvider("internal", InternalNativeProvider(quiet = quiet))
|
||||||
addNativeProvider("ffi", JnaNativeProvider())
|
addNativeProvider("ffi", FfiNativeProvider())
|
||||||
addNativeProvider("java", JavaNativeProvider())
|
addNativeProvider("java", JavaNativeProvider())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user