Fixed LuaJ fallback.

Fixed boot address not being saved.
This commit is contained in:
Florian Nücke 2014-06-03 17:36:21 +02:00
parent 9991f4a5fc
commit 7cc239ebe3
8 changed files with 41 additions and 5 deletions

View File

@ -186,6 +186,11 @@ opencomputers {
# always be erased when the computer is completely powered off, even if # always be erased when the computer is completely powered off, even if
# it crashed. This setting is purely for software-triggered reboots. # it crashed. This setting is purely for software-triggered reboots.
eraseTmpOnReboot: false eraseTmpOnReboot: false
# Forces the use of the LuaJ fallback instead of the native libraries.
# Use this if you have (unfounded) concerns using native libraries or
# experience issues with the native library. Also used for debugging.
forceLuaJ: false
} }
# Robot related settings, what they may do and general balancing. # Robot related settings, what they may do and general balancing.

View File

@ -59,6 +59,7 @@ class Settings(config: Config) {
val allowBytecode = config.getBoolean("computer.allowBytecode") val allowBytecode = config.getBoolean("computer.allowBytecode")
val logLuaCallbackErrors = config.getBoolean("computer.logCallbackErrors") val logLuaCallbackErrors = config.getBoolean("computer.logCallbackErrors")
val eraseTmpOnReboot = config.getBoolean("computer.eraseTmpOnReboot") val eraseTmpOnReboot = config.getBoolean("computer.eraseTmpOnReboot")
val forceLuaJ = config.getBoolean("computer.forceLuaJ")
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
// robot // robot

View File

@ -44,7 +44,7 @@ class Proxy {
api.Items.instance = Items api.Items.instance = Items
api.Machine.instance = machine.Machine api.Machine.instance = machine.Machine
api.Machine.LuaArchitecture = api.Machine.LuaArchitecture =
if (LuaStateFactory.isAvailable) classOf[NativeLuaArchitecture] if (LuaStateFactory.isAvailable && !Settings.get.forceLuaJ) classOf[NativeLuaArchitecture]
else classOf[LuaJLuaArchitecture] else classOf[LuaJLuaArchitecture]
api.Network.instance = network.Network api.Network.instance = network.Network

View File

@ -25,11 +25,14 @@ class LuaJLuaArchitecture(val machine: api.machine.Machine) extends Architecture
private[machine] var memory = 0 private[machine] var memory = 0
private[machine] var bootAddress = ""
private val apis = Array( private val apis = Array(
new ComponentAPI(this), new ComponentAPI(this),
new ComputerAPI(this), new ComputerAPI(this),
new OSAPI(this), new OSAPI(this),
new SystemAPI(this), new SystemAPI(this),
new UnicodeAPI(this),
new UserdataAPI(this)) new UserdataAPI(this))
private[machine] def invoke(f: () => Array[AnyRef]): Varargs = try { private[machine] def invoke(f: () => Array[AnyRef]): Varargs = try {
@ -158,16 +161,18 @@ class LuaJLuaArchitecture(val machine: api.machine.Machine) extends Architecture
// The kernel thread returned. If it threw we'd be in the catch below. // The kernel thread returned. If it threw we'd be in the catch below.
else { else {
// We're expecting the result of a pcall, if anything, so boolean + (result | string). // We're expecting the result of a pcall, if anything, so boolean + (result | string).
if (results.`type`(2) != LuaValue.TBOOLEAN || !(results.isstring(3) || results.isnil(3))) { if (results.`type`(2) != LuaValue.TBOOLEAN || !(results.isstring(3) || results.isnoneornil(3))) {
OpenComputers.log.warning("Kernel returned unexpected results.") OpenComputers.log.warning("Kernel returned unexpected results.")
} }
// The pcall *should* never return normally... but check for it nonetheless. // The pcall *should* never return normally... but check for it nonetheless.
if (results.toboolean(1)) { if (results.toboolean(2)) {
OpenComputers.log.warning("Kernel stopped unexpectedly.") OpenComputers.log.warning("Kernel stopped unexpectedly.")
new ExecutionResult.Shutdown(false) new ExecutionResult.Shutdown(false)
} }
else { else {
val error = results.tojstring(3) val error =
if (results.isuserdata(3)) results.touserdata(3).toString
else results.tojstring(3)
if (error != null) new ExecutionResult.Error(error) if (error != null) new ExecutionResult.Error(error)
else new ExecutionResult.Error("unknown error") else new ExecutionResult.Error("unknown error")
} }
@ -219,6 +224,8 @@ class LuaJLuaArchitecture(val machine: api.machine.Machine) extends Architecture
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
override def load(nbt: NBTTagCompound) { override def load(nbt: NBTTagCompound) {
bootAddress = nbt.getString("bootAddress")
if (machine.isRunning) { if (machine.isRunning) {
machine.stop() machine.stop()
machine.start() machine.start()
@ -226,5 +233,8 @@ class LuaJLuaArchitecture(val machine: api.machine.Machine) extends Architecture
} }
override def save(nbt: NBTTagCompound) { override def save(nbt: NBTTagCompound) {
if (bootAddress != null) {
nbt.setString("bootAddress", bootAddress)
}
} }
} }

View File

@ -316,6 +316,8 @@ class NativeLuaArchitecture(val machine: api.machine.Machine) extends Architectu
private def state = machine.asInstanceOf[Machine].state private def state = machine.asInstanceOf[Machine].state
override def load(nbt: NBTTagCompound) { override def load(nbt: NBTTagCompound) {
bootAddress = nbt.getString("bootAddress")
// Unlimit memory use while unpersisting. // Unlimit memory use while unpersisting.
lua.setTotalMemory(Integer.MAX_VALUE) lua.setTotalMemory(Integer.MAX_VALUE)
@ -366,6 +368,10 @@ class NativeLuaArchitecture(val machine: api.machine.Machine) extends Architectu
} }
override def save(nbt: NBTTagCompound) { override def save(nbt: NBTTagCompound) {
if (bootAddress != null) {
nbt.setString("bootAddress", bootAddress)
}
// Unlimit memory while persisting. // Unlimit memory while persisting.
lua.setTotalMemory(Integer.MAX_VALUE) lua.setTotalMemory(Integer.MAX_VALUE)

View File

@ -27,6 +27,18 @@ class ComputerAPI(owner: LuaJLuaArchitecture) extends LuaJAPI(owner) {
case _ => LuaValue.NIL case _ => LuaValue.NIL
}) })
// Get/set address of boot device.
computer.set("getBootAddress", (_: Varargs) => owner.bootAddress match {
case "" => LuaValue.NIL
case address => LuaValue.valueOf(address)
})
computer.set("setBootAddress", (args: Varargs) => {
if (args.isnoneornil(1)) owner.bootAddress = ""
else owner.bootAddress = args.checkjstring(1)
LuaValue.NIL
})
computer.set("freeMemory", (_: Varargs) => LuaValue.valueOf(owner.memory / 2)) computer.set("freeMemory", (_: Varargs) => LuaValue.valueOf(owner.memory / 2))
computer.set("totalMemory", (_: Varargs) => LuaValue.valueOf(owner.memory)) computer.set("totalMemory", (_: Varargs) => LuaValue.valueOf(owner.memory))

View File

@ -13,7 +13,7 @@ class SystemAPI(owner: LuaJLuaArchitecture) extends LuaJAPI(owner) {
system.set("allowBytecode", (_: Varargs) => LuaValue.valueOf(Settings.get.allowBytecode)) system.set("allowBytecode", (_: Varargs) => LuaValue.valueOf(Settings.get.allowBytecode))
// How long programs may run without yielding before we stop them. // How long programs may run without yielding before we stop them.
system.set("timeout", LuaValue.valueOf(Settings.get.timeout)) system.set("timeout", (_: Varargs) => LuaValue.valueOf(Settings.get.timeout))
lua.set("system", system) lua.set("system", system)
} }

View File

@ -8,6 +8,7 @@ import scala.collection.mutable
import scala.language.implicitConversions import scala.language.implicitConversions
import scala.math.ScalaNumber import scala.math.ScalaNumber
import scala.runtime.BoxedUnit import scala.runtime.BoxedUnit
import li.cil.oc.api.machine.Value
class ScalaClosure(val f: (Varargs) => Varargs) extends VarArgFunction { class ScalaClosure(val f: (Varargs) => Varargs) extends VarArgFunction {
override def invoke(args: Varargs) = f(args) override def invoke(args: Varargs) = f(args)
@ -41,6 +42,7 @@ object ScalaClosure {
case value: java.lang.String => LuaValue.valueOf(value) case value: java.lang.String => LuaValue.valueOf(value)
case value: Array[Byte] => LuaValue.valueOf(value) case value: Array[Byte] => LuaValue.valueOf(value)
case value: Array[_] => toLuaList(value) case value: Array[_] => toLuaList(value)
case value: Value => LuaValue.userdataOf(value)
case value: Product => toLuaList(value.productIterator.toIterable) case value: Product => toLuaList(value.productIterator.toIterable)
case value: Seq[_] => toLuaList(value) case value: Seq[_] => toLuaList(value)
case value: java.util.Map[_, _] => toLuaTable(value.toMap) case value: java.util.Map[_, _] => toLuaTable(value.toMap)