Add Lua 5.4 support, update LuaJ, JNLua, fix everything, break everything.

To say that this has been a long time coming would be an understatement.

This commit changes the following:

 * Updates LuaJ to 3.0.2 with many third-party patches applied. Not that
   it doesn't have obvious breaking bugs still - however, it emulates
   Lua 5.2 that little bit better now.
 * Updates JNLua in every conceivable way:
   * Now compiled with actual optimizations - ~2x better performance!
   * Updates Lua 5.2 with gamax92's backported bugfixes.
   * Updates Lua 5.3 from 5.3.2 to 5.3.6.
   * Adds experimental Lua 5.4 support (Lua 5.4.4).
   * Adds proper support for 64-bit integers (longs) in LuaState.
   * Adds official support for AArch64 on Linux and macOS.
   * Drops support for all architectures on FreeBSD and x86 on macOS.
   * Further minor bugfixes here and there.
 * Adds a Lua 5.4 architecture (behind a config option for now).
 * Updates the Lua copyright date.

Thanks to everyone who has been patient enough to wait over four years
for this to finally get upstreamed.

( No joke! https://github.com/MightyPirates/OpenComputers/pull/2898 )

Let's hope this doesn't break the world. (It probably does, though.)
This commit is contained in:
Adrian Siekierka 2022-09-04 21:05:03 +02:00
parent 62887f81a7
commit ac4d93589a
37 changed files with 164 additions and 76 deletions

View File

@ -12,7 +12,7 @@ A few useful links:
* [Community Forums][forums]
### Experimental Builds
You can find experimental builds [on the build server][jenkins]. Expect these to be generally more unstable than builds marked as releases. Use these **at your own risk**, but - when using the latest one - please *do* report bugs you encounter using them. Thanks!
You can find experimental builds [on the build server][github-actions]. Expect these to be generally more unstable than builds marked as releases. Use these **at your own risk**, but - when using the latest one - please *do* report bugs you encounter using them. Thanks!
## License / Use in Modpacks
This mod is [licensed under the **MIT license**](https://github.com/MightyPirates/OpenComputers/blob/master-MC1.7.10/LICENSE). All **assets are public domain**, unless otherwise stated; all are free to be distributed as long as the license / source credits are kept. This means you can use this mod in any mod pack **as you please**. I'd be happy to hear about you using it, though, just out of curiosity.
@ -54,7 +54,7 @@ Also, and this should go without saying, your contributed code will also fall un
## Extending
### In your own mod
To use [the API][api] in your own mod, either get the API JAR from the [build server][jenkins], or if you're using [Gradle](http://gradle.org/), add a dependency to the maven repo:
To use [the API][api] in your own mod, either get the API JAR from the [build server][github-actions], or if you're using [Gradle](http://gradle.org/), add a dependency to the maven repo:
```groovy
repositories {
maven { url = "http://maven.cil.li/" }
@ -96,9 +96,9 @@ In the case you wish to use Eclipse rather than IntelliJ IDEA, the process is mo
[code conventions]: https://ocdoc.cil.li/lua_conventions
[dev-jar]: https://ci.cil.li/view/OpenComputers/job/OpenComputers-MC1.7.10/
[forums]: https://oc.cil.li/
[github-actions]: https://github.com/MightyPirates/OpenComputers/actions
[irc]: http://webchat.esper.net/?channels=#oc
[issues]: https://github.com/MightyPirates/OpenComputers/issues?state=open
[jenkins]: http://ci.cil.li/
[localizations]: https://github.com/MightyPirates/OpenComputers/tree/master-MC1.7.10/src/main/resources/assets/opencomputers/lang
[loot]: https://github.com/MightyPirates/OpenComputers/tree/master-MC1.7.10/src/main/resources/assets/opencomputers/loot
[manpages]: https://github.com/MightyPirates/OpenComputers/tree/master-MC1.7.10/src/main/resources/assets/opencomputers/loot/OpenOS/usr/man

View File

@ -157,7 +157,9 @@ dependencies {
compile 'com.google.code.findbugs:jsr305:1.3.9' // Annotations used by google libs.
embedded files('libs/OpenComputers-JNLua.jar', 'libs/OpenComputers-LuaJ.jar')
embedded name: 'OC-LuaJ', version: '20220904.0', ext: 'jar'
embedded name: 'OC-JNLua', version: '20220904.0', ext: 'jar'
embedded name: 'OC-JNLua-Natives', version: '20220904.0', ext: 'jar'
testCompile "org.mockito:mockito-all:1.10.19"
testCompile "org.scalactic:scalactic_2.11:2.2.6"

Binary file not shown.

Binary file not shown.

View File

@ -68,6 +68,19 @@ public interface Arguments extends Iterable<Object> {
*/
int checkInteger(int index);
/**
* Try to get a long value at the specified index.
* <br>
* Throws an error if there are too few arguments.
*
* @param index the index from which to get the argument.
* @return the long value at the specified index.
* @throws IllegalArgumentException if there is no argument at that index,
* or if the argument is not a number.
* @since OpenComputers 1.8.0
*/
long checkLong(int index);
/**
* Try to get a double value at the specified index.
* <br>
@ -188,6 +201,19 @@ public interface Arguments extends Iterable<Object> {
*/
int optInteger(int index, int def);
/**
* Try to get a long value at the specified index.
* <br>
* Return the specified default value if there is no such element, behaves
* like {@link #checkLong(int)} otherwise.
*
* @param index the index from which to get the argument.
* @return the long value at the specified index.
* @throws IllegalArgumentException if the argument exists but is not a number.
* @since OpenComputers 1.8.0
*/
long optLong(int index, long def);
/**
* Try to get a double value at the specified index.
* <br>
@ -273,6 +299,17 @@ public interface Arguments extends Iterable<Object> {
*/
boolean isInteger(int index);
/**
* Tests whether the argument at the specified index is a long value.
* <br>
* This will return false if there is <em>no</em> argument at the specified
* index, i.e. if there are too few arguments.
*
* @param index the index to check.
* @return true if the argument is a long; false otherwise.
*/
boolean isLong(int index);
/**
* Tests whether the argument at the specified index is a double value.
* <br>

View File

@ -231,6 +231,10 @@ opencomputers {
# If enabled, a crafted CPU will first be the Lua 5.3 architecture.
defaultLua53: true
# Whether to make the Lua 5.4 architecture available. If enabled, you
# can reconfigure any CPU to use the Lua 5.4 architecture.
enableLua54: false
# The sizes of the six levels of RAM, in kilobytes. This list must
# contain exactly six entries, or it will be ignored. Note that while
# there are six levels of RAM, they still fall into the three tiers of

View File

@ -86,7 +86,7 @@ local read_handler = {hint = function(line, index)
return hints
end}
io.write("\27[37m".._VERSION .. " Copyright (C) 1994-2017 Lua.org, PUC-Rio\n")
io.write("\27[37m".._VERSION .. " Copyright (C) 1994-2022 Lua.org, PUC-Rio\n")
io.write("\27[33mEnter a statement and hit enter to evaluate it.\n")
io.write("Prefix an expression with '=' to show its value.\n")
io.write("Press Ctrl+D to exit the interpreter.\n\27[37m")

View File

@ -792,7 +792,7 @@ sandbox = {
tonumber = tonumber,
tostring = tostring,
type = type,
_VERSION = _VERSION:match("Luaj") and "Luaj" or _VERSION:match("5.3") and "Lua 5.3" or "Lua 5.2",
_VERSION = _VERSION:match("Luaj") and "Luaj" or _VERSION:match("5.4") and "Lua 5.4" or _VERSION:match("5.3") and "Lua 5.3" or "Lua 5.2",
xpcall = function(f, msgh, ...)
local handled = false
checkArg(2, msgh, "function")

View File

@ -84,6 +84,7 @@ class Settings(val config: Config) {
val allowGC = config.getBoolean("computer.lua.allowGC")
val enableLua53 = config.getBoolean("computer.lua.enableLua53")
val defaultLua53 = config.getBoolean("computer.lua.defaultLua53")
val enableLua54 = config.getBoolean("computer.lua.enableLua54")
val ramSizes = Array(config.getIntList("computer.lua.ramSizes"): _*) match {
case Array(tier1, tier2, tier3, tier4, tier5, tier6) =>
Array(tier1: Int, tier2: Int, tier3: Int, tier4: Int, tier5: Int, tier6: Int)
@ -567,7 +568,7 @@ object Settings {
"misc.maxOpenPorts",
"computer.cpuComponentCount"
),
// Upgrading to version 1.8.0, changed meaning of limitFlightHeight value.
// Upgrading to version 1.8.0, changed meaning of limitFlightHeight value,
VersionRange.createFromVersionSpec("[0.0, 1.8.0)") -> Array(
"computer.robot.limitFlightHeight"
)

View File

@ -16,9 +16,7 @@ import li.cil.oc.common.item.traits.Delegate
import li.cil.oc.common.recipe.Recipes
import li.cil.oc.integration.Mods
import li.cil.oc.server._
import li.cil.oc.server.machine.luac.LuaStateFactory
import li.cil.oc.server.machine.luac.NativeLua52Architecture
import li.cil.oc.server.machine.luac.NativeLua53Architecture
import li.cil.oc.server.machine.luac.{LuaStateFactory, NativeLua52Architecture, NativeLua53Architecture, NativeLua54Architecture}
import li.cil.oc.server.machine.luaj.LuaJLuaArchitecture
import net.minecraft.item.Item
import net.minecraft.item.ItemStack
@ -73,20 +71,16 @@ class Proxy {
api.API.config = Settings.get.config
// Weird JNLua bug identified
// When loading JNLua (for either 5.2 or 5.3 lua state) there is a static section that the library loads
// being static, it loads once regardless of which lua state is loaded first
// static { REGISTRYINDEX = lua_registryindex(); }
// The problem is that lua_registryindex was removed in 5.3
// Thus, if we load JNLua from a lua5.3 state first, this static section fails
// We must load 5.2 first, AND we know 5.3 will likely fail to load if 5.2 failed
val include52: Boolean = LuaStateFactory.include52
// now that JNLua has been initialized from a lua52 state, we are safe to check 5.3
if (LuaStateFactory.include53) {
api.Machine.add(classOf[NativeLua53Architecture])
}
if (include52) {
api.Machine.add(classOf[NativeLua52Architecture])
if (LuaStateFactory.isAvailable) {
if (LuaStateFactory.include53) {
api.Machine.add(classOf[NativeLua53Architecture])
}
if (LuaStateFactory.include54) {
api.Machine.add(classOf[NativeLua54Architecture])
}
if (LuaStateFactory.include52) {
api.Machine.add(classOf[NativeLua52Architecture])
}
}
if (LuaStateFactory.includeLuaJ) {
api.Machine.add(classOf[LuaJLuaArchitecture])

View File

@ -185,7 +185,7 @@ private[oc] object Registry extends api.detail.DriverAPI {
case arg: java.lang.Long => arg
case arg: java.lang.Float => arg
case arg: java.lang.Double => arg
case arg: java.lang.Number => Double.box(arg.doubleValue())
case arg: java.lang.Number => Double.box(arg.doubleValue)
case arg: java.lang.String => arg
case arg: Array[Boolean] => arg

View File

@ -70,6 +70,19 @@ class ArgumentsImpl(val args: Seq[AnyRef]) extends Arguments {
else checkInteger(index)
}
def checkLong(index: Int) = {
checkIndex(index, "number")
args(index) match {
case value: java.lang.Number => value.longValue
case value => throw typeError(index, value, "number")
}
}
def optLong(index: Int, default: Long) = {
if (!isDefined(index)) default
else checkLong(index)
}
def checkString(index: Int) = {
checkIndex(index, "string")
args(index) match {
@ -159,6 +172,8 @@ class ArgumentsImpl(val args: Seq[AnyRef]) extends Arguments {
case _ => false
})
def isLong(index: Int) = isInteger(index)
def isString(index: Int) =
index >= 0 && index < count && (args(index) match {
case value: java.lang.String => true
@ -210,6 +225,10 @@ class ArgumentsImpl(val args: Seq[AnyRef]) extends Arguments {
private def typeName(value: AnyRef): String = value match {
case null | Unit | None => "nil"
case _: java.lang.Boolean => "boolean"
case _: java.lang.Byte => "integer"
case _: java.lang.Short => "integer"
case _: java.lang.Integer => "integer"
case _: java.lang.Long => "integer"
case _: java.lang.Number => "double"
case _: java.lang.String => "string"
case _: Array[Byte] => "string"

View File

@ -312,7 +312,10 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
def convertArg(param: Any): AnyRef = {
param match {
case arg: java.lang.Boolean => arg
case arg: java.lang.Character => Double.box(arg.toDouble)
case arg: java.lang.Character => Integer.valueOf(arg.toInt)
case arg: java.lang.Byte => arg
case arg: java.lang.Short => arg
case arg: java.lang.Integer => arg
case arg: java.lang.Long => arg
case arg: java.lang.Number => Double.box(arg.doubleValue)
case arg: java.lang.String => arg

View File

@ -15,7 +15,6 @@ import li.cil.oc.api.machine.Architecture
import li.cil.oc.server.machine.Machine
import li.cil.oc.util.ExtendedLuaState._
import li.cil.repack.com.naef.jnlua
import li.cil.repack.com.naef.jnlua.NativeSupport.Loader
import net.minecraft.item.ItemStack
import org.apache.commons.lang3.SystemUtils
@ -23,10 +22,11 @@ import scala.util.Random
object LuaStateFactory {
def isAvailable: Boolean = {
// Force initialization of both.
// Force initialization of all.
val lua52 = Lua52.isAvailable
val lua53 = Lua53.isAvailable
lua52 || lua53
val lua54 = Lua54.isAvailable
lua52 || lua53 || lua54
}
def luajRequested: Boolean = Settings.get.forceLuaJ || Settings.get.registerLuaJArchitecture
@ -37,6 +37,8 @@ object LuaStateFactory {
def include53: Boolean = Lua53.isAvailable && Settings.get.enableLua53 && !Settings.get.forceLuaJ
def include54: Boolean = Lua54.isAvailable && Settings.get.enableLua54 && !Settings.get.forceLuaJ
def default53: Boolean = include53 && Settings.get.defaultLua53
def setDefaultArch(stack: ItemStack): ItemStack = {
@ -53,7 +55,7 @@ object LuaStateFactory {
}
object Lua52 extends LuaStateFactory {
override def version: String = "lua52"
override def version: String = "52"
override protected def create(maxMemory: Option[Int]) = maxMemory.fold(new jnlua.LuaState())(new jnlua.LuaState(_))
@ -71,7 +73,7 @@ object LuaStateFactory {
}
object Lua53 extends LuaStateFactory {
override def version: String = "lua53"
override def version: String = "53"
override protected def create(maxMemory: Option[Int]) = maxMemory.fold(new jnlua.LuaStateFiveThree())(new jnlua.LuaStateFiveThree(_))
@ -88,6 +90,24 @@ object LuaStateFactory {
}
}
object Lua54 extends LuaStateFactory {
override def version: String = "54"
override protected def create(maxMemory: Option[Int]) = maxMemory.fold(new jnlua.LuaStateFiveFour())(new jnlua.LuaStateFiveFour(_))
override protected def openLibs(state: jnlua.LuaState): Unit = {
state.openLib(jnlua.LuaState.Library.BASE)
state.openLib(jnlua.LuaState.Library.COROUTINE)
state.openLib(jnlua.LuaState.Library.DEBUG)
state.openLib(jnlua.LuaState.Library.ERIS)
state.openLib(jnlua.LuaState.Library.MATH)
state.openLib(jnlua.LuaState.Library.STRING)
state.openLib(jnlua.LuaState.Library.TABLE)
state.openLib(jnlua.LuaState.Library.UTF8)
state.pop(8)
}
}
}
/**
@ -112,34 +132,35 @@ abstract class LuaStateFactory {
private val libraryName = {
if (!Strings.isNullOrEmpty(Settings.get.forceNativeLib)) Settings.get.forceNativeLib
else if (SystemUtils.IS_OS_FREE_BSD && Architecture.IS_OS_X64) "native.64.bsd.so"
else if (SystemUtils.IS_OS_FREE_BSD && Architecture.IS_OS_X86) "native.32.bsd.so"
else {
val libExtension = {
if (SystemUtils.IS_OS_MAC) ".dylib"
else if (SystemUtils.IS_OS_WINDOWS) ".dll"
else ".so"
}
else if (SystemUtils.IS_OS_LINUX && Architecture.IS_OS_ARM) "native.32.arm.so"
else if (SystemUtils.IS_OS_LINUX && Architecture.IS_OS_X64) "native.64.so"
else if (SystemUtils.IS_OS_LINUX && Architecture.IS_OS_X86) "native.32.so"
val systemName = {
if (SystemUtils.IS_OS_FREE_BSD) "freebsd"
else if (SystemUtils.IS_OS_NET_BSD) "netbsd"
else if (SystemUtils.IS_OS_OPEN_BSD) "openbsd"
else if (SystemUtils.IS_OS_SOLARIS) "solaris"
else if (SystemUtils.IS_OS_LINUX) "linux"
else if (SystemUtils.IS_OS_MAC) "darwin"
else if (SystemUtils.IS_OS_WINDOWS) "windows"
else "unknown"
}
else if (SystemUtils.IS_OS_MAC && Architecture.IS_OS_X64) "native.64.dylib"
else if (SystemUtils.IS_OS_MAC && Architecture.IS_OS_X86) "native.32.dylib"
val archName = {
if (Architecture.IS_OS_ARM64) "aarch64"
else if (Architecture.IS_OS_ARM) "arm"
else if (Architecture.IS_OS_X64) "x86_64"
else if (Architecture.IS_OS_X86) "x86"
else "unknown"
}
else if (SystemUtils.IS_OS_WINDOWS && Architecture.IS_OS_X64) "native.64.dll"
else if (SystemUtils.IS_OS_WINDOWS && Architecture.IS_OS_X86) "native.32.dll"
else null
}
// Register a custom library loader with JNLua. We have to trigger
// library loads through JNLua to ensure the LuaState class is the
// one loading the library and not the other way around - the native
// library also references the LuaState class, and if it is loaded
// that way, it will fail to access native methods in its static
// initializer, because the native lib will not have been completely
// loaded at the time the initializer runs.
private def prepareLoad(lib: String): Unit = jnlua.NativeSupport.getInstance().setLoader(new Loader {
def load(): Unit = {
System.load(lib)
"libjnlua" + version + "-" + systemName + "-" + archName + libExtension
}
})
}
protected def create(maxMemory: Option[Int] = None): jnlua.LuaState
@ -173,7 +194,7 @@ abstract class LuaStateFactory {
}
}
val libraryUrl = classOf[Machine].getResource(s"/assets/${Settings.resourceDomain}/lib/$version/$libraryName")
val libraryUrl = classOf[Machine].getResource(s"/assets/${Settings.resourceDomain}/lib/$libraryName")
if (libraryUrl == null) {
OpenComputers.log.warn(s"Native library with name '$version/$libraryName' not found.")
return
@ -277,7 +298,7 @@ abstract class LuaStateFactory {
currentLib = tmpLibFile.getAbsolutePath
try {
LuaStateFactory.synchronized {
prepareLoad(currentLib)
System.load(currentLib)
create().close()
}
OpenComputers.log.info(s"Found a compatible native library: '${tmpLibFile.getName}'.")
@ -286,7 +307,7 @@ abstract class LuaStateFactory {
catch {
case t: Throwable =>
if (Settings.get.logFullLibLoadErrors) {
OpenComputers.log.trace(s"Could not load native library '${tmpLibFile.getName}'.", t)
OpenComputers.log.warn(s"Could not load native library '${tmpLibFile.getName}'.", t)
}
else {
OpenComputers.log.trace(s"Could not load native library '${tmpLibFile.getName}'.")
@ -310,7 +331,7 @@ abstract class LuaStateFactory {
try {
val state = LuaStateFactory.synchronized {
prepareLoad(currentLib)
System.load(currentLib)
if (Settings.get.limitMemory) create(Some(Int.MaxValue))
else create()
}
@ -376,7 +397,7 @@ abstract class LuaStateFactory {
state.setField(-2, "random")
state.pushScalaFunction(lua => {
random.setSeed(lua.checkNumber(1).toLong)
random.setSeed(lua.checkInteger(1))
0
})
state.setField(-2, "randomseed")
@ -409,6 +430,8 @@ abstract class LuaStateFactory {
val IS_OS_ARM = isOSArchMatch("arm")
val IS_OS_ARM64 = isOSArchMatch("aarch64")
val IS_OS_X86 = isOSArchMatch("x86") || isOSArchMatch("i386")
val IS_OS_X64 = isOSArchMatch("x86_64") || isOSArchMatch("amd64")

View File

@ -30,6 +30,11 @@ class NativeLua53Architecture(machine: api.machine.Machine) extends NativeLuaArc
override def factory = LuaStateFactory.Lua53
}
@Architecture.Name("Lua 5.4")
class NativeLua54Architecture(machine: api.machine.Machine) extends NativeLuaArchitecture(machine) {
override def factory = LuaStateFactory.Lua54
}
abstract class NativeLuaArchitecture(val machine: api.machine.Machine) extends Architecture {
protected def factory: LuaStateFactory

View File

@ -25,7 +25,7 @@ class OSAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) {
else "%d/%m/%y %H:%M:%S"
val time =
if (lua.getTop > 1 && lua.isNumber(2)) lua.toNumber(2)
else (machine.worldTime + 6000) * 60 * 60 / 1000
else ((machine.worldTime + 6000) * 60 * 60) / 1000.0
val dt = GameTimeFormatter.parse(time)
def fmt(format: String) {
@ -70,7 +70,7 @@ class OSAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) {
// starts days at 6 o'clock, versus the 1 o'clock of timestamps so we
// add those five hours. Thus:
// timestamp = (time + 5000) * 60[kh] * 60[km] / 1000[s]
lua.pushNumber((machine.worldTime + 5000) * 60 * 60 / 1000)
lua.pushNumber(((machine.worldTime + 5000) * 60 * 60) / 1000.0)
}
else {
def getField(key: String, d: Int) = {
@ -80,7 +80,7 @@ class OSAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) {
if (res == null)
if (d < 0) throw new Exception("field '" + key + "' missing in date table")
else d
else res: Int
else res.intValue()
}
lua.checkType(1, LuaType.TABLE)

View File

@ -85,8 +85,8 @@ class PersistenceAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) {
lua.getGlobal("_G") /* ... perms uperms k v */
flattenAndStore() /* ... perms uperms */
lua.setField(LuaState.REGISTRYINDEX, "uperms") /* ... perms */
lua.setField(LuaState.REGISTRYINDEX, "perms") /* ... */
lua.setField(lua.getRegistryIndex, "uperms") /* ... perms */
lua.setField(lua.getRegistryIndex, "perms") /* ... */
}
}
@ -126,7 +126,7 @@ class PersistenceAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) {
lua.getGlobal("eris") // ... eris
lua.getField(-1, "persist") // ... eris persist
if (lua.isFunction(-1)) {
lua.getField(LuaState.REGISTRYINDEX, "perms") // ... eris persist perms
lua.getField(lua.getRegistryIndex, "perms") // ... eris persist perms
lua.pushValue(index) // ... eris persist perms obj
try {
lua.call(2, 1) // ... eris str?
@ -159,7 +159,7 @@ class PersistenceAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) {
lua.getGlobal("eris") // ... eris
lua.getField(-1, "unpersist") // ... eris unpersist
if (lua.isFunction(-1)) {
lua.getField(LuaState.REGISTRYINDEX, "uperms") // ... eris persist uperms
lua.getField(lua.getRegistryIndex, "uperms") // ... eris persist uperms
lua.pushByteArray(value) // ... eris unpersist uperms str
lua.call(2, 1) // ... eris obj
lua.insert(-2) // ... obj eris

View File

@ -11,7 +11,7 @@ class SystemAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) {
println((1 to lua.getTop).map(i => lua.`type`(i) match {
case LuaType.NIL => "nil"
case LuaType.BOOLEAN => lua.toBoolean(i)
case LuaType.NUMBER => lua.toNumber(i)
case LuaType.NUMBER => if (lua.isInteger(i)) lua.toInteger(i) else lua.toNumber(i)
case LuaType.STRING => lua.toString(i)
case LuaType.TABLE => "table"
case LuaType.FUNCTION => "function"

View File

@ -11,7 +11,7 @@ class UnicodeAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) {
lua.pushScalaFunction(lua => {
val builder = new java.lang.StringBuilder()
(1 to lua.getTop).map(lua.checkInteger).foreach(builder.appendCodePoint)
(1 to lua.getTop).map(lua.checkInt32).foreach(builder.appendCodePoint)
lua.pushString(builder.toString)
1
})
@ -39,12 +39,12 @@ class UnicodeAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) {
lua.pushScalaFunction(lua => {
val string = lua.checkString(1)
val sLength = ExtendedUnicodeHelper.length(string)
val start = lua.checkInteger(2) match {
val start = lua.checkInt32(2) match {
case i if i < 0 => string.offsetByCodePoints(string.length, math.max(i, -sLength))
case i => string.offsetByCodePoints(0, math.min(i - 1, sLength))
}
val end =
if (lua.getTop > 2) lua.checkInteger(3) match {
if (lua.getTop > 2) lua.checkInt32(3) match {
case i if i < 0 => string.offsetByCodePoints(string.length, math.max(i + 1, -sLength))
case i => string.offsetByCodePoints(0, math.min(i, sLength))
}

View File

@ -39,11 +39,11 @@ object ExtendedLuaState {
}) match {
case null | Unit | _: BoxedUnit => lua.pushNil()
case value: java.lang.Boolean => lua.pushBoolean(value.booleanValue)
case value: java.lang.Byte => lua.pushNumber(value.byteValue)
case value: java.lang.Byte => lua.pushInteger(value.byteValue)
case value: java.lang.Character => lua.pushString(String.valueOf(value))
case value: java.lang.Short => lua.pushNumber(value.shortValue)
case value: java.lang.Integer => lua.pushNumber(value.intValue)
case value: java.lang.Long => lua.pushNumber(value.longValue)
case value: java.lang.Short => lua.pushInteger(value.shortValue)
case value: java.lang.Integer => lua.pushInteger(value.intValue)
case value: java.lang.Long => lua.pushInteger(value.longValue)
case value: java.lang.Float => lua.pushNumber(value.floatValue)
case value: java.lang.Double => lua.pushNumber(value.doubleValue)
case value: java.lang.String => lua.pushString(value)
@ -108,7 +108,7 @@ object ExtendedLuaState {
def toSimpleJavaObject(index: Int): AnyRef = lua.`type`(index) match {
case LuaType.BOOLEAN => Boolean.box(lua.toBoolean(index))
case LuaType.NUMBER => Double.box(lua.toNumber(index))
case LuaType.NUMBER => if (lua.isInteger(index)) Long.box(lua.toInteger(index)) else Double.box(lua.toNumber(index))
case LuaType.STRING => lua.toByteArray(index)
case LuaType.TABLE => lua.toJavaObject(index, classOf[java.util.Map[_, _]])
case LuaType.USERDATA => lua.toJavaObjectRaw(index)