JLuaVM: Difference between revisions
No edit summary |
No edit summary |
||
| Line 85: | Line 85: | ||
|- | |- | ||
|<code>coroutine.resumeWithTimeout(co:thread, timeout:number, ...)</code> | |<code>coroutine.resumeWithTimeout(co:thread, timeout:number, ...)</code> | ||
| colspan="2" | | | colspan="2" style="padding:0;"| | ||
{| class="wikitable" style="margin:0;" | {| class="wikitable" style="margin:0;" | ||
!Returns | !Returns | ||
| Line 101: | Line 101: | ||
|} | |} | ||
Further functionality that is NOT available in [[Advanced Computers]]. | Further functionality that is NOT available in [[Advanced Computers]]. | ||
{| class="wikitable" | {| class="wikitable" | ||
!Function | !Function | ||
!Returns | !Returns | ||
Revision as of 15:15, 25 August 2026
The JLuaVM, is the runtime that executes the Lua code that is running on computers in Advanced Computers. The source can be found on GitHub. The most important feature for Advanced Computers is the ability to save and restore the Lua execution state, regardless of what Lua code may be loaded. We are not aware of any Java based Lua runtime being capable of this, hence why this project was born in the first place.
While we try to keep things very similar, there are a few tiny differences, listed below. In the remainder of this article, LuaC refers to PUC-Rio's implementation of Lua. If you spot a difference between JLuaVM and LuaC which is not listed here, please open a ticket at https://github.com/MidnightMages/JLuaVM/issues with a snippet that functions differently between JLuaVM and LuaC.
If you would like to contribute please see https://github.com/MidnightMages/JLuaVM/tree/master#contributing.
LuaC deviations
In these cases JLuaVM (referred to as 'we') behaves differently than LuaC, but we still fulfill the Lua specification.
| Area | Description |
|---|---|
| Indexing of strings | In LuaC indexing a string, where the index value someIndex can be an arbitrary value, always evaluates to nil. We argue that this is inconsistent and is almost never wanted behaviour. Therefore we instead throw an error just like indexing any other non-indexable type.("someString")[someIndex]
|
| Length of strings | We intentionally return the number of characters instead of the length in bytes. |
| assert | Produces a slightly different error message. Further, the message argument (second argument) is tostring()'ed before printing. This means that when the second argument happens to be a boolean, we properly print the value instead of simply stating that it was a boolean.
The following snippet will raise an error (as the first argument is falsy) and the message is simply the constant true represented as a string.assert(false, true)
|
| ipairs | In our case, ipairs only allows iterating over tables. LuaC would return nil when operating on a string and error when passing a type that is neither a string nor a table. For robustness we throw on all non-table arguments as it seems very unlikely that a string is passed intentionally. |
| pairs | The order in which the items are returned may differ from LuaC. |
| table.insert | In LuaC this function seems to behave differently depending on whether the table is a sequence or an actual dictionary. In our case table.insert behaves identical in both cases. |
| table.remove | behaviour differs slightly as the table-length operator behaves differently. |
| Printing numbers | We print numbers with a few more digits of precision. |
| Stacktraces are formatted differently | Due to the lack of a loadfile function, the chunkname is directly fed into stacktraces, allowing for specifying filenames, etc. without being surrounded by quotes. Also some things are named slightly different within the stacktrace. This indirectly also affects the error(msg [, level]) function when msg is directly a string and level == nil or level > 0, and thus, part of the stacktrace is appended.
|
Lua language spec deviations
In this one case we do not follow the spec.
| Area | Description |
|---|---|
| math.randomseed(seed) | This function does not accept two seeds, but instead only one. Similarly it also only returns one number. Extra arguments are ignored. |
Lua language spec extensions
We have also slightly extended the existing specification.
OOP callable constants
The following expression is not syntactically allowed in LuaC: "someString":sub(1,3). In LuaC this would need to instead be written as ("someString"):sub(1,3). But as there is no grammatical conflict, we simply treat them the same.
Type Extension Methods
LuaC supports setting type-metatables using debug.setmetatable, e.g. for the string type. This, to our knowledge, however only works on a global level, so you cannot easily configure this on a per-environment (as in _ENV) setting.
We have therefore added support for what we call "Type Extension Methods", as they behave similarly to extension methods in C#. If an index operation fails and would normally result in an error, we try to perform a lookup in a subtable of _EXT.
For example, the following code "test":sub(1,3) is processed as follows:
- "test" is a string, hence is not indexable, nor can it contain a metatable, so we immediately check for an extension function (or throw an index error otherwise)
- Thus we check for
_ENV["_EXT"]["string"]["sub"], which by default does exist, as_ENV._EXT.stringis set to a table that contains most of the string-library functions.
In more general terms we access _ENV["_EXT][NAME OF TYPE][NAME OF FUNCTION] (where _ENV is often equivalent to _G). If no match is found, we simply raise the usual error.
Additional standard library functions
| Function | Returns | Description | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
vm.listUdKeys(obj:userdata)
|
table
|
Returns a table whose keys are all values that are readable or writable in the given userdata object obj. The value of each key is either r, w or rw, depending on whether the key is readable writable or readwrite.
| ||||||||
coroutine.resumeWithTimeout(co:thread, timeout:number, ...)
|
| |||||||||
Further functionality that is NOT available in Advanced Computers.
| Function | Returns | Description |
|---|---|---|
vm.pause()
|
void
|
Immediately pauses the current LuaVM. |