mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-14 23:16:06 +09:00
migration to graal
This commit is contained in:
@@ -39,10 +39,10 @@ class GraphicsJSR223Delegate(val vm: VM) {
|
||||
}
|
||||
}
|
||||
|
||||
fun plotPixel(x: Int, y: Int, color: Byte) {
|
||||
fun plotPixel(x: Int, y: Int, color: Int) {
|
||||
getFirstGPU()?.let {
|
||||
if (x in 0 until it.config.width && y in 0 until it.config.height) {
|
||||
it.poke(y.toLong() * it.config.width + x, color)
|
||||
it.poke(y.toLong() * it.config.width + x, color.toByte())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,12 +82,12 @@ class GraphicsJSR223Delegate(val vm: VM) {
|
||||
/**
|
||||
* prints a char as-is; won't interpret them as an escape sequence
|
||||
*/
|
||||
fun putSymbol(char: Byte) {
|
||||
fun putSymbol(c: Int) {
|
||||
getFirstGPU()?.let {
|
||||
val (cx, cy) = it.getCursorPos()
|
||||
|
||||
|
||||
it.putChar(cx, cy, char)
|
||||
it.putChar(cx, cy, c.toByte())
|
||||
it.setCursorPos(cx + 1, cy)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package net.torvald.tsvm
|
||||
|
||||
import net.torvald.UnsafeHelper
|
||||
import net.torvald.UnsafePtr
|
||||
import net.torvald.tsvm.firmware.Firmware
|
||||
import net.torvald.tsvm.peripheral.IOSpace
|
||||
import net.torvald.tsvm.peripheral.PeriBase
|
||||
import net.torvald.tsvm.peripheral.VMProgramRom
|
||||
@@ -21,6 +20,9 @@ class VM(
|
||||
val roms: Array<VMProgramRom?> // first ROM must contain the BIOS
|
||||
) {
|
||||
|
||||
class ErrorIllegalAccess(val addr: Long) : RuntimeException("Segmentation fault at 0x${addr.toString(16).padStart(8, '0')}")
|
||||
|
||||
|
||||
val id = java.util.Random().nextInt()
|
||||
|
||||
val memsize = minOf(USER_SPACE_SIZE, _memsize.toLong())
|
||||
@@ -115,10 +117,10 @@ class VM(
|
||||
internal fun poke(addr: Long, value: Byte) {
|
||||
val (memspace, offset) = translateAddr(addr)
|
||||
if (memspace == null)
|
||||
throw Firmware.ErrorIllegalAccess(addr)
|
||||
throw ErrorIllegalAccess(addr)
|
||||
else if (memspace is UnsafePtr) {
|
||||
if (addr >= memspace.size)
|
||||
throw Firmware.ErrorIllegalAccess(addr)
|
||||
throw ErrorIllegalAccess(addr)
|
||||
else
|
||||
memspace.set(offset, value)
|
||||
}
|
||||
@@ -132,7 +134,7 @@ class VM(
|
||||
null
|
||||
else if (memspace is UnsafePtr) {
|
||||
if (addr >= memspace.size)
|
||||
throw Firmware.ErrorIllegalAccess(addr)
|
||||
throw ErrorIllegalAccess(addr)
|
||||
else
|
||||
memspace.get(offset)
|
||||
}
|
||||
|
||||
@@ -38,15 +38,14 @@ class VMJSR223Delegate(val vm: VM) {
|
||||
return r
|
||||
}
|
||||
|
||||
fun print(s: String) {
|
||||
fun print(s: Any) {
|
||||
//System.out.print("[Nashorn] $s")
|
||||
vm.getPrintStream().write(s.toByteArray(VM.CHARSET))
|
||||
vm.getPrintStream().write("$s".toByteArray(VM.CHARSET))
|
||||
}
|
||||
fun println(s: String) {
|
||||
System.out.println("[Nashorn] $s")
|
||||
vm.getPrintStream().write((s + '\n').toByteArray(VM.CHARSET))
|
||||
fun println(s: Any = "") {
|
||||
System.out.println("[Graal] $s")
|
||||
vm.getPrintStream().write(("$s\n").toByteArray(VM.CHARSET))
|
||||
}
|
||||
fun println() = print('\n')
|
||||
|
||||
/**
|
||||
* @return key being hit, of which:
|
||||
@@ -112,7 +111,7 @@ class VMJSR223Delegate(val vm: VM) {
|
||||
}
|
||||
|
||||
class VMSerialDebugger(val vm: VM) {
|
||||
fun print(s: String) = System.out.print(s)
|
||||
fun println(s: String) = System.out.println(s)
|
||||
fun printerr(s: String) = System.err.println(s)
|
||||
fun print(s: Any) = System.out.print("$s")
|
||||
fun println(s: Any) = System.out.println("$s")
|
||||
fun printerr(s: Any) = System.err.println("$s")
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package net.torvald.tsvm
|
||||
|
||||
import net.torvald.tsvm.firmware.Firmware
|
||||
import org.luaj.vm2.LuaTable
|
||||
import org.luaj.vm2.LuaValue
|
||||
import org.luaj.vm2.lib.ZeroArgFunction
|
||||
import org.luaj.vm2.lib.jse.JsePlatform
|
||||
|
||||
class VMLuaAdapter(val vm: VM) {
|
||||
|
||||
val lua = JsePlatform.standardGlobals()
|
||||
|
||||
init {
|
||||
lua.load(Firmware(vm))
|
||||
lua.load("_G.int = function(n) if n > 0 then return math.floor(n) else return math.ceil(n) end end").call()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,20 +31,6 @@ object VMRunnerFactory {
|
||||
}
|
||||
|
||||
return when (extension) {
|
||||
"lua" -> {
|
||||
object : VMRunner(extension) {
|
||||
|
||||
private val vmLua = VMLuaAdapter(vm)
|
||||
|
||||
override suspend fun executeCommand(command: String) {
|
||||
vmLua.lua.load(command).call()
|
||||
}
|
||||
|
||||
override suspend fun evalGlobal(command: String) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
}
|
||||
"vt2" -> {
|
||||
object : VMRunner(extension) {
|
||||
|
||||
@@ -62,18 +48,13 @@ object VMRunnerFactory {
|
||||
}
|
||||
"js" -> {
|
||||
object : VMRunner(extension) {
|
||||
private val engine: ScriptEngine// = ScriptEngineManager().getEngineByExtension(extension)
|
||||
private val engine: ScriptEngine = ScriptEngineManager().getEngineByName("Graal.js")
|
||||
private val bind = engine.getBindings(ScriptContext.ENGINE_SCOPE)
|
||||
|
||||
init {
|
||||
val engineFactory = NashornScriptEngineFactory()
|
||||
engine = engineFactory.getScriptEngine("--no-java", "--no-syntax-extensions", "--language=es6")
|
||||
assertNotNull(engine, "Script engine for extension $extension not found")
|
||||
}
|
||||
// see https://github.com/graalvm/graaljs/blob/master/docs/user/ScriptEngine.md
|
||||
bind.put("polyglot.js.allowHostAccess", true)
|
||||
|
||||
private val context = SimpleScriptContext()
|
||||
private val bind = context.getBindings(ScriptContext.ENGINE_SCOPE)
|
||||
|
||||
init {
|
||||
bind.put("sys", VMJSR223Delegate(vm)) // TODO use delegator class to access peripheral (do not expose VM itself)
|
||||
bind.put("graphics", GraphicsJSR223Delegate(vm))
|
||||
bind.put("serial", VMSerialDebugger(vm))
|
||||
@@ -84,12 +65,12 @@ object VMRunnerFactory {
|
||||
val fr = FileReader("./assets/JS_INIT.js")
|
||||
val prg = fr.readText()
|
||||
fr.close()
|
||||
engine.eval(sanitiseJS(prg), context)
|
||||
engine.eval(sanitiseJS(prg))
|
||||
}
|
||||
|
||||
override suspend fun executeCommand(command: String) {
|
||||
try {
|
||||
engine.eval(encapsulateJS(sanitiseJS(command)), context)
|
||||
engine.eval(encapsulateJS(sanitiseJS(command)))
|
||||
}
|
||||
catch (e: javax.script.ScriptException) {
|
||||
System.err.println("ScriptException from the script:")
|
||||
@@ -99,7 +80,7 @@ object VMRunnerFactory {
|
||||
}
|
||||
|
||||
override suspend fun evalGlobal(command: String) {
|
||||
engine.eval("\"use strict\";" + sanitiseJS(command), context)
|
||||
engine.eval("\"use strict\";" + sanitiseJS(command))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
package net.torvald.tsvm.firmware
|
||||
|
||||
import net.torvald.tsvm.VM
|
||||
import net.torvald.tsvm.kB
|
||||
import org.luaj.vm2.LuaTable
|
||||
import org.luaj.vm2.LuaValue
|
||||
import org.luaj.vm2.lib.OneArgFunction
|
||||
import org.luaj.vm2.lib.TwoArgFunction
|
||||
import org.luaj.vm2.lib.ZeroArgFunction
|
||||
import java.lang.RuntimeException
|
||||
|
||||
internal class Firmware(val vm: VM) : TwoArgFunction() {
|
||||
|
||||
class ErrorIllegalAccess(val addr: Long) : RuntimeException("Segmentation fault at 0x${addr.toString(16).padStart(8, '0')}")
|
||||
|
||||
companion object {
|
||||
internal fun translateAddr(vm : VM, addr: LuaValue): Pair<Any?, Long> {
|
||||
val addr = addr.checklong()
|
||||
return when (addr) {
|
||||
// DO note that numbers in Lua are double precision floats (ignore Lua 5.3 for now)
|
||||
in 0..8192.kB() - 1 -> vm.usermem to addr
|
||||
in -1024.kB()..-1 -> vm.peripheralTable[0].peripheral to (-addr - 1)
|
||||
in -2048.kB()..-1024.kB() - 1 -> vm.peripheralTable[1].peripheral to (-addr - 1 - 1024.kB())
|
||||
in -3072.kB()..-2048.kB() - 1 -> vm.peripheralTable[2].peripheral to (-addr - 1 - 2048.kB())
|
||||
in -4096.kB()..-3072.kB() - 1 -> vm.peripheralTable[3].peripheral to (-addr - 1 - 3072.kB())
|
||||
in -5120.kB()..-4096.kB() - 1 -> vm.peripheralTable[4].peripheral to (-addr - 1 - 4096.kB())
|
||||
in -6144.kB()..-5120.kB() - 1 -> vm.peripheralTable[5].peripheral to (-addr - 1 - 5120.kB())
|
||||
in -7168.kB()..-6144.kB() - 1 -> vm.peripheralTable[6].peripheral to (-addr - 1 - 6144.kB())
|
||||
in -8192.kB()..-7168.kB() - 1 -> vm.peripheralTable[7].peripheral to (-addr - 1 - 7168.kB())
|
||||
else -> null to addr
|
||||
}
|
||||
}
|
||||
|
||||
fun Byte.toLuaValue() = LuaValue.valueOf(this.toInt())
|
||||
}
|
||||
|
||||
class Poke(private val vm: VM) : TwoArgFunction() {
|
||||
override fun call(addr: LuaValue, value: LuaValue): LuaValue {
|
||||
vm.poke(addr.checklong(), value.checkint().toByte())
|
||||
return LuaValue.NIL
|
||||
}
|
||||
}
|
||||
|
||||
class Peek(private val vm: VM) : OneArgFunction() {
|
||||
override fun call(addr: LuaValue): LuaValue {
|
||||
return vm.peek(addr.checklong())?.toLuaValue() ?: LuaValue.NIL
|
||||
}
|
||||
}
|
||||
|
||||
override fun call(modname: LuaValue, env: LuaValue): LuaValue {
|
||||
println("[Firmware] Loading package 'rawamem'")
|
||||
val t = LuaTable()
|
||||
t["poke"] = Poke(vm)
|
||||
t["peek"] = Peek(vm)
|
||||
t["nanoTime"] = object : ZeroArgFunction() {
|
||||
override fun call(): LuaValue {
|
||||
return LuaValue.valueOf(System.nanoTime().toDouble())
|
||||
}
|
||||
}
|
||||
if (!env["package"].isnil()) env["package"]["loaded"]["rawmem"] = t
|
||||
return t
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user