Security News
Supply Chain Attack Detected in Solana's web3.js Library
A supply chain attack has been detected in versions 1.95.6 and 1.95.7 of the popular @solana/web3.js library.
fengari-interop
Advanced tools
The fengari-interop npm package provides interoperability between JavaScript and Lua, allowing you to run Lua code from JavaScript and vice versa. It is built on top of Fengari, a Lua VM written in JavaScript.
Running Lua code from JavaScript
This feature allows you to execute Lua code directly from JavaScript. The code sample demonstrates how to load and run a simple Lua script that prints a message.
const fengari = require('fengari');
const interop = require('fengari-interop');
const luaCode = `
print('Hello from Lua!')
`;
const L = fengari.L;
fengari.luaL_loadstring(L, fengari.to_luastring(luaCode));
fengari.lua_call(L, 0, 0);
Calling JavaScript functions from Lua
This feature allows Lua code to call JavaScript functions. The code sample shows how to call the JavaScript `print` function from within Lua code.
const fengari = require('fengari');
const interop = require('fengari-interop');
const luaCode = `
js.global:print('Hello from Lua calling JS!')
`;
const L = fengari.L;
interop.luaopen_js(L);
fengari.luaL_loadstring(L, fengari.to_luastring(luaCode));
fengari.lua_call(L, 0, 0);
Accessing JavaScript objects from Lua
This feature allows Lua code to create and manipulate JavaScript objects. The code sample demonstrates creating a JavaScript object in Lua, setting a property, and then accessing that property.
const fengari = require('fengari');
const interop = require('fengari-interop');
const luaCode = `
local obj = js.new(js.global.Object)
obj.foo = 'bar'
print(obj.foo)
`;
const L = fengari.L;
interop.luaopen_js(L);
fengari.luaL_loadstring(L, fengari.to_luastring(luaCode));
fengari.lua_call(L, 0, 0);
lua.vm.js is a Lua VM implemented in JavaScript, similar to Fengari. It allows you to run Lua code in a JavaScript environment. However, it does not provide the same level of interoperability between Lua and JavaScript as fengari-interop.
Fengari is the core Lua VM written in JavaScript that fengari-interop builds upon. While Fengari allows you to run Lua code in JavaScript, fengari-interop extends this functionality by providing seamless interoperability between the two languages.
Fengari is a lua VM written in Javascript. It's implementation makes use of the JS garbage collector, which means it is fully capable of cross language interop.
js
libraryjs = require "js"
null
A userdata representing JavaScript null
global
A reference to the JavaScript global context. In the browser, this is usually equivalent to the window
object. In node.js it's equal to global
.
new(constructor, ...)
Invokes the JavaScript new
operator on constructor
passing the arguments specified.
Returns the created object.
of(iterable)
Returns a iterating function and an iterator state that behave like a JavaScript for...of loop. Suitable for use as a lua iterator. e.g.
for f in js.of(js.global:Array(10,20,30)) do
print(f)
end
Note: this function only exists if the JavaScript runtime supports Symbols
createproxy(x[, type])
Note: Only available if your JS environment has the Proxy
constructor
Creates a JavaScript Proxy object. The proxy supports configuring traps by setting them as metamethods on your object.
type
may be "function"
(the default) "arrow_function"
or "object"
:
"function"
:
typeof p === "function"
"arrow_function"
:
typeof p === "function"
"object"
:
typeof p === "object"
Note that JavaScript coerces all types except Symbols to strings before using them as a key in an indexing operation.
tonumber(x)
Coerces the value x
to a number using JavaScript coercion rules.
tostring(x)
Coerces the value x
to a string using JavaScript coercion rules.
instanceof(x, y)
Returns if the value x
is an instance of the class y
via use of the JavaScript instanceof
operator
typeof(x)
Returns what JavaScript sees as the type of x
. Uses the JavaScript typeof
operator
push(L, value)
Pushes an arbitrary JavaScript object value
as the most suitable lua type onto the lua stack L
.
Performs deduplication so that the same JavaScript objects are pushed as the same lua objects.
pushjs(L, value)
Pushes an arbitrary JavaScript object value
as a userdata onto the lua stack L
.
Rarely used; see push(L, value)
instead.
checkjs(L, idx)
If the value on the lua stack L
at index idx
is a JavaScript userdata object (as pushed by push
or pushjs
) then return it.
Otherwise throw an error.
testjs(L, idx)
If the value on the lua stack L
at index idx
is a JavaScript userdata object (as pushed by push
or pushjs
) then return it.
Otherwise returns undefined
.
tojs(L, idx)
Returns the object on the lua stack L
at index idx
as the most suitable javascript type.
nil
is returned as undefined
push
or pushjs
) returns the pushed JavaScript objectapply(this, [args...])
: calls the lua object. Returns only the first return valueinvoke(this, [args...])
: calls the lua object. Returns results as an arrayget(key)
: indexes the lua objecthas(key)
: checks if indexing the lua object results in nil
set(key, value)
delete(key)
: sets the key to nil
toString()
JavaScript arguments to these methods are passed in via push()
and results are returned via tojs()
.
Calling the function is equivalent to calling the lua function wrapped.luaopen_js
The entrypoint for loading the js library into a fengari lua_State
.
Usually passed to luaL_requiref
.
If the JavaScript environment supports Symbols, then some runtime-wide symbols can be used to customise behaviour:
__pairs
The __pairs
Symbol can be used to describe how to iterate over a JavaScript object. Use Symbol.for("__pairs")
to get the symbol. It should be used as a key on your objects, where the value is a function returning an object with three properties: "iter"
, "state"
and "first"
.
"iter"
should be a function that follows the standard Lua generic for protocol, that is, it gets called with your state (as this
) and the previous value produced; it should return an array of values or undefined
if done.
e.g. to make pairs
on a Map return entries in the map via the iterator symbol:
Map.prototype[Symbol.for("__pairs")] = function() {
return {
iter: function(last) {
var v = this.next();
if (v.done) return;
return v.value;
},
state: this[Symbol.iterator]()
};
};
If there is no __pairs
Symbol attached to an object, an iterator over Object.keys
is returned.
__len
The __len
Symbol can be used to describe how to get the length (used by the lua #
operator) of a JavaScript object.
Use Symbol.for("__len")
to get the symbol. It should be used as a key on your objects, where the value is a function returning the length of your objects (passed as this
).
e.g. to have the lua #
operator applied to a Map return the size
field:
Map.prototype[Symbol.for("__len")] = function() {
return this.size;
};
If there is no __len
Symbol attached to an object, the value of the .length
property is returned.
FAQs
JS library for Fengari
The npm package fengari-interop receives a total of 450,001 weekly downloads. As such, fengari-interop popularity was classified as popular.
We found that fengari-interop demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
A supply chain attack has been detected in versions 1.95.6 and 1.95.7 of the popular @solana/web3.js library.
Research
Security News
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Security News
Research
Socket researchers have discovered malicious npm packages targeting crypto developers, stealing credentials and wallet data using spyware delivered through typosquats of popular cryptographic libraries.