mirror of
https://github.com/GayPizzaSpecifications/pork.git
synced 2025-08-02 12:50:55 +00:00
modify compiler to fix return values and add support for vm ffi
This commit is contained in:
parent
4100752f1c
commit
2f5ea4629d
@ -17,9 +17,6 @@ class IrStubOpEmitter(val irDefinition: IrDefinition, val code: CodeBuilder) : I
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun final() {
|
fun final() {
|
||||||
if (irDefinition.type == IrDefinitionType.CodeFunction) {
|
|
||||||
code.emit(Opcode.None)
|
|
||||||
}
|
|
||||||
code.emit(Opcode.Return)
|
code.emit(Opcode.Return)
|
||||||
code.emit(Opcode.End)
|
code.emit(Opcode.End)
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package gay.pizza.pork.ffi
|
|||||||
import com.kenai.jffi.*
|
import com.kenai.jffi.*
|
||||||
import com.kenai.jffi.Function
|
import com.kenai.jffi.Function
|
||||||
import gay.pizza.pork.ast.gen.ArgumentSpec
|
import gay.pizza.pork.ast.gen.ArgumentSpec
|
||||||
|
import gay.pizza.pork.ast.gen.Symbol
|
||||||
import gay.pizza.pork.evaluator.*
|
import gay.pizza.pork.evaluator.*
|
||||||
import gay.pizza.pork.execution.ArgumentList
|
import gay.pizza.pork.execution.ArgumentList
|
||||||
import gay.pizza.pork.execution.NativeFunction
|
import gay.pizza.pork.execution.NativeFunction
|
||||||
@ -26,14 +27,14 @@ class FfiNativeProvider : ExpandedNativeProvider, NativeProvider {
|
|||||||
rootTypeRegistry.registerPrimitiveTypes()
|
rootTypeRegistry.registerPrimitiveTypes()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun provideNativeFunction(
|
fun provideNativeFunctionGeneric(
|
||||||
definitions: List<String>,
|
definitions: List<String>,
|
||||||
arguments: List<ArgumentSpec>,
|
arguments: List<ArgumentSpec>? = null,
|
||||||
inside: SlabContext
|
inside: SlabContext? = null,
|
||||||
): CallableFunction {
|
): CallableFunction {
|
||||||
if (definitions[0] == "internal") {
|
if (definitions[0] == "internal") {
|
||||||
val internal = internalFunctions[definitions[1]] ?:
|
val internal =
|
||||||
throw RuntimeException("Unknown internal function: ${definitions[1]}")
|
internalFunctions[definitions[1]] ?: throw RuntimeException("Unknown internal function: ${definitions[1]}")
|
||||||
return CallableFunction { functionArguments, _ ->
|
return CallableFunction { functionArguments, _ ->
|
||||||
internal(functionArguments)
|
internal(functionArguments)
|
||||||
}
|
}
|
||||||
@ -77,7 +78,13 @@ class FfiNativeProvider : ExpandedNativeProvider, NativeProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addStructDefs(ffiTypeRegistry: FfiTypeRegistry, types: List<String>, inside: SlabContext) {
|
override fun provideNativeFunction(
|
||||||
|
definitions: List<String>,
|
||||||
|
arguments: List<ArgumentSpec>,
|
||||||
|
inside: SlabContext
|
||||||
|
): CallableFunction = provideNativeFunctionGeneric(definitions, arguments, inside)
|
||||||
|
|
||||||
|
private fun addStructDefs(ffiTypeRegistry: FfiTypeRegistry, types: List<String>, inside: SlabContext?) {
|
||||||
for (parameter in types) {
|
for (parameter in types) {
|
||||||
if (!parameter.startsWith("struct ")) {
|
if (!parameter.startsWith("struct ")) {
|
||||||
continue
|
continue
|
||||||
@ -87,7 +94,8 @@ class FfiNativeProvider : ExpandedNativeProvider, NativeProvider {
|
|||||||
if (structureName.endsWith("*")) {
|
if (structureName.endsWith("*")) {
|
||||||
structureName = structureName.substring(0, structureName.length - 1)
|
structureName = structureName.substring(0, structureName.length - 1)
|
||||||
}
|
}
|
||||||
val structureDefinitionValue = inside.internalScope.value(structureName)
|
val structureDefinitionValue =
|
||||||
|
inside?.internalScope?.value(structureName) ?: throw RuntimeException("Undefined structure: $structureName")
|
||||||
if (structureDefinitionValue !is FfiStructDefinition) {
|
if (structureDefinitionValue !is FfiStructDefinition) {
|
||||||
throw RuntimeException("Structure '${structureName}' was not an FfiStructDefinition.")
|
throw RuntimeException("Structure '${structureName}' was not an FfiStructDefinition.")
|
||||||
}
|
}
|
||||||
@ -101,16 +109,21 @@ class FfiNativeProvider : ExpandedNativeProvider, NativeProvider {
|
|||||||
|
|
||||||
private fun buildArgumentList(
|
private fun buildArgumentList(
|
||||||
context: CallContext,
|
context: CallContext,
|
||||||
functionArgumentSpecs: List<ArgumentSpec>,
|
functionArgumentSpecs: List<ArgumentSpec>?,
|
||||||
functionArguments: List<Any>,
|
functionArguments: List<Any>,
|
||||||
ffiTypeRegistry: FfiTypeRegistry,
|
ffiTypeRegistry: FfiTypeRegistry,
|
||||||
functionDefinition: FfiFunctionDefinition,
|
functionDefinition: FfiFunctionDefinition,
|
||||||
freeStringList: MutableList<FfiString>
|
freeStringList: MutableList<FfiString>
|
||||||
): HeapInvocationBuffer {
|
): HeapInvocationBuffer {
|
||||||
val buffer = HeapInvocationBuffer(context)
|
val buffer = HeapInvocationBuffer(context)
|
||||||
for ((index, spec) in functionArgumentSpecs.withIndex()) {
|
|
||||||
val ffiType = ffiTypeRegistry.lookup(functionDefinition.parameters[index]) ?:
|
val useFunctionArguments = functionArgumentSpecs ?: functionArguments.map {
|
||||||
throw RuntimeException("Unknown ffi type: ${functionDefinition.parameters[index]}")
|
ArgumentSpec(symbol = Symbol(""), multiple = false)
|
||||||
|
}
|
||||||
|
|
||||||
|
for ((index, spec) in useFunctionArguments.withIndex()) {
|
||||||
|
val ffiType = ffiTypeRegistry.lookup(functionDefinition.parameters[index])
|
||||||
|
?: throw RuntimeException("Unknown ffi type: ${functionDefinition.parameters[index]}")
|
||||||
if (spec.multiple) {
|
if (spec.multiple) {
|
||||||
val variableArguments = functionArguments
|
val variableArguments = functionArguments
|
||||||
.subList(index, functionArguments.size)
|
.subList(index, functionArguments.size)
|
||||||
@ -143,7 +156,8 @@ class FfiNativeProvider : ExpandedNativeProvider, NativeProvider {
|
|||||||
if (functionAddress == 0L) {
|
if (functionAddress == 0L) {
|
||||||
throw RuntimeException(
|
throw RuntimeException(
|
||||||
"Failed to find symbol ${functionDefinition.function} in " +
|
"Failed to find symbol ${functionDefinition.function} in " +
|
||||||
"library $actualLibraryPath")
|
"library $actualLibraryPath"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return functionAddress
|
return functionAddress
|
||||||
}
|
}
|
||||||
@ -156,16 +170,17 @@ class FfiNativeProvider : ExpandedNativeProvider, NativeProvider {
|
|||||||
return FfiPlatforms.current.platform.findLibrary(name) ?: name
|
return FfiPlatforms.current.platform.findLibrary(name) ?: name
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun invoke(invoker: Invoker, function: Function, buffer: HeapInvocationBuffer, type: FfiType): Any = when (type) {
|
private fun invoke(invoker: Invoker, function: Function, buffer: HeapInvocationBuffer, type: FfiType): Any =
|
||||||
FfiPrimitiveType.Pointer -> invoker.invokeAddress(function, buffer)
|
when (type) {
|
||||||
FfiPrimitiveType.UnsignedInt, FfiPrimitiveType.Int -> invoker.invokeInt(function, buffer)
|
FfiPrimitiveType.Pointer -> invoker.invokeAddress(function, buffer)
|
||||||
FfiPrimitiveType.Long -> invoker.invokeLong(function, buffer)
|
FfiPrimitiveType.UnsignedInt, FfiPrimitiveType.Int -> invoker.invokeInt(function, buffer)
|
||||||
FfiPrimitiveType.Void -> invoker.invokeStruct(function, buffer)
|
FfiPrimitiveType.Long -> invoker.invokeLong(function, buffer)
|
||||||
FfiPrimitiveType.Double -> invoker.invokeDouble(function, buffer)
|
FfiPrimitiveType.Void -> invoker.invokeStruct(function, buffer)
|
||||||
FfiPrimitiveType.Float -> invoker.invokeFloat(function, buffer)
|
FfiPrimitiveType.Double -> invoker.invokeDouble(function, buffer)
|
||||||
FfiPrimitiveType.String -> invoker.invokeAddress(function, buffer)
|
FfiPrimitiveType.Float -> invoker.invokeFloat(function, buffer)
|
||||||
else -> throw RuntimeException("Unsupported ffi return type: $type")
|
FfiPrimitiveType.String -> invoker.invokeAddress(function, buffer)
|
||||||
} ?: None
|
else -> throw RuntimeException("Unsupported ffi return type: $type")
|
||||||
|
} ?: None
|
||||||
|
|
||||||
private fun ffiStructDefine(arguments: ArgumentList): Any {
|
private fun ffiStructDefine(arguments: ArgumentList): Any {
|
||||||
val copy = arguments.toMutableList()
|
val copy = arguments.toMutableList()
|
||||||
@ -211,9 +226,11 @@ class FfiNativeProvider : ExpandedNativeProvider, NativeProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun provideNativeFunction(definitions: List<String>): NativeFunction {
|
override fun provideNativeFunction(definitions: List<String>): NativeFunction {
|
||||||
throw RuntimeException("Invalid Native Function Usage")
|
val callable = provideNativeFunctionGeneric(definitions, arguments = null, inside = null)
|
||||||
|
return NativeFunction { arguments ->
|
||||||
|
callable.call(arguments, CallStack())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun typeConversion(type: FfiType): Type = when (type) {
|
fun typeConversion(type: FfiType): Type = when (type) {
|
||||||
FfiPrimitiveType.UnsignedByte -> Type.UINT8
|
FfiPrimitiveType.UnsignedByte -> Type.UINT8
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
export func printf(format, arguments...)
|
export func printf(format, arguments...)
|
||||||
native ffi "c:printf:int:char*,..."
|
native ffi "c" "int printf(int argc, ...)"
|
||||||
|
Loading…
Reference in New Issue
Block a user