mirror of
https://github.com/GayPizzaSpecifications/pork.git
synced 2025-08-03 13:11:32 +00:00
implement a new native call bytecode mechanism that can be optimized by the vm
This commit is contained in:
@ -6,9 +6,9 @@ import gay.pizza.pork.execution.NativeRegistry
|
||||
|
||||
class InternalMachine(val world: CompiledWorld, val nativeRegistry: NativeRegistry, val handlers: List<OpHandler>) {
|
||||
private val inlined = world.code.map { op ->
|
||||
val handler = handlers.firstOrNull { it.code == op.code } ?:
|
||||
throw VirtualMachineException("Opcode ${op.code.name} does not have a handler.")
|
||||
op to handler
|
||||
val handler = handlers.firstOrNull { it.code == op.code }
|
||||
?: throw VirtualMachineException("Opcode ${op.code.name} does not have a handler.")
|
||||
op to (handler.optimize(machine = this, op) ?: handler)
|
||||
}
|
||||
|
||||
private var inst: UInt = 0u
|
||||
|
@ -5,4 +5,6 @@ import gay.pizza.pork.bytecode.Opcode
|
||||
|
||||
abstract class OpHandler(val code: Opcode) {
|
||||
abstract fun handle(machine: InternalMachine, op: Op)
|
||||
|
||||
open fun optimize(machine: InternalMachine, op: Op): OpHandler? = null
|
||||
}
|
||||
|
@ -8,23 +8,15 @@ import gay.pizza.pork.vm.OpHandler
|
||||
|
||||
object NativeOpHandler : OpHandler(Opcode.Native) {
|
||||
override fun handle(machine: InternalMachine, op: Op) {
|
||||
val argumentCount = op.args[2]
|
||||
val arguments = mutableListOf<Any>()
|
||||
var x = argumentCount
|
||||
while (x > 0u) {
|
||||
x--
|
||||
arguments.add(machine.localAt(x))
|
||||
}
|
||||
val formConstant = machine.world.constantPool.read(op.args[0])
|
||||
val form = formConstant.readAsString()
|
||||
val handler = optimize(machine, op)
|
||||
handler.handle(machine, op)
|
||||
}
|
||||
|
||||
override fun optimize(machine: InternalMachine, op: Op): OpHandler {
|
||||
val nativeDefinition = machine.world.constantPool.read(op.args[0]).readAsNativeDefinition()
|
||||
val form = nativeDefinition[0]
|
||||
val provider = machine.nativeRegistry.of(form)
|
||||
val countOfNativeDefs = op.args[1].toInt()
|
||||
val defs = mutableListOf<String>()
|
||||
for (i in 0 until countOfNativeDefs) {
|
||||
defs.add(machine.pop())
|
||||
}
|
||||
val function = provider.provideNativeFunction(defs)
|
||||
val result = function.invoke(arguments)
|
||||
machine.push(if (result == Unit) None else result)
|
||||
val function = provider.provideNativeFunction(nativeDefinition.subList(1, nativeDefinition.size))
|
||||
return OptimizedNativeOpHandler(function)
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,22 @@
|
||||
package gay.pizza.pork.vm.ops
|
||||
|
||||
import gay.pizza.pork.bytecode.Op
|
||||
import gay.pizza.pork.bytecode.Opcode
|
||||
import gay.pizza.pork.execution.NativeFunction
|
||||
import gay.pizza.pork.execution.None
|
||||
import gay.pizza.pork.vm.InternalMachine
|
||||
import gay.pizza.pork.vm.OpHandler
|
||||
|
||||
class OptimizedNativeOpHandler(val function: NativeFunction) : OpHandler(Opcode.Native) {
|
||||
override fun handle(machine: InternalMachine, op: Op) {
|
||||
val argumentCount = op.args[1]
|
||||
val arguments = mutableListOf<Any>()
|
||||
var x = argumentCount
|
||||
while (x > 0u) {
|
||||
x--
|
||||
arguments.add(machine.localAt(x))
|
||||
}
|
||||
val result = function.invoke(arguments)
|
||||
machine.push(if (result == Unit) None else result)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user