🐺 φεγγάρι - The Lua VM written in JS ES6 for Node and the browser
This repository contains the core fengari code (which is a port of the Lua C library) which includes parser, virtual machine and base libraries. However it is rare to use this repository directly.
- For a clone of the
luacommand line tool, but running under node.js, see fengari-node-cli
The JS API
Once you've loaded fengari, you can use the JS API:
const luaconf = fengariluaconf;const lua = fengarilua;const lauxlib = fengarilauxlib;const lualib = fengarilualib;const L = lauxlib;lualib;lua;
The JS API is exactly the same as the C API so
fengari.lua exposes the same constants and functions as
fengari.lauxlib the same as
fengari.lualib the same as
lualib.h. If you're unfamiliar with the C API, you can take a look at the manual.
Fengari implements Lua 5.3 semantics and will hopefully follow future Lua releases. If you find any noticeable difference between Fengari and Lua's behaviours, please report it.
Lua strings are 8-bits clean and can embed
\0. Which means that invalid UTF-8/16 strings are valid Lua strings. Lua functions like
string.dump even use strings as a way of storing binary data.
To address that issue, Fengari uses
Uint8Array objects containing the raw bytes to implement lua strings. To push a JS string on the stack you can use
lua_pushliteral which will convert it to an array of bytes before pushing it. To get a Lua string on the stack as a JS string you can use
lua_tojsstring which will attempt to convert it to a UTF-16 JS string. The latter won't give you what you expect if the Lua string is not a valid UTF-16 sequence. You can also convert strings with
The JS number type is always a double, and hence cannot accurately represent integers with more than 53 bits. As such, we've taken the route of a rarely used define (
LUA_INT_TYPE=LUA_INT_LONG) in the PUC-Rio sources, where floats are doubles, but integers are 32 bits.
In the browser
package.loadlib try to find a file by making synchronous XHR requests.
require has been extended to allow searchers to yield.
collectgarbage: Fengari relies on the JS garbage collector and does not implement its own.
- The following functions are only available in Node:
- The entire
- The entire
debug.debug()doesn't work from web workers due to lack of a method to get synchronous user input
- Weak tables
LUA_CPATH_DEFAULT(and contains .js extensions rather than .so or .dll extensions)
lua_tonumberxdo not have out-parameters indicating conversion success. Instead,
falseis returned when conversion fails.
luaL_execresulttakes an extra argument: an error object. The error object should have a fields
luaL_fileresulttakes an extra argument: an error object. The error object should have a field
Some luaconf options can be chosen at library load time. Fengari looks for
process.env.FENGARICONF and if it exists, parses it as a JSON string.
dv = lua_todataview(L, idx)
lua_tolstring but returns a
DataView instead of a string.
lua_pushjsclosure(L, func, n)
b = lua_isproxy(p, L)
Returns a boolean
b indicating whether
p is a proxy (See
L is non-null, only returns
p belongs to the same global state.
p = lua_toproxy(L, idx)
p that holds a reference to the lua value at the stack index
This object can be called with a lua_State to push the value onto that state's stack.
This example would be an inefficient way to write
var p = ;;
A library containing metadata about the fengari release.
This library is automatically loaded by
luaL_openlibs into the global
io.input(): partially implemented
io.output(): partially implemented