### Initialize Lua State and Load Libraries Source: https://github.com/fengari-lua/fengari/blob/master/README.md This snippet demonstrates how to initialize a new Lua state and open the standard Lua libraries using the Fengari JavaScript API. This is a common setup step before executing Lua code. ```javascript const luaconf = fengari.luaconf; const lua = fengari.lua; const lauxlib = fengari.lauxlib; const lualib = fengari.lualib; const L = lauxlib.luaL_newstate(); lualib.luaL_openlibs(L); ``` -------------------------------- ### Metatables and Metamethods Source: https://context7.com/fengari-lua/fengari/llms.txt Create objects with custom behavior using metatables in Lua via Fengari. This example defines a `Vector` type with custom `__tostring` and `__add` metamethods. ```javascript const fengari = require('fengari'); const lua = fengari.lua; const lauxlib = fengari.lauxlib; const lualib = fengari.lualib; const { to_luastring } = fengari; const L = lauxlib.luaL_newstate(); lualib.luaL_openlibs(L); const luaCode = " -- Create a vector "class" with metamethods local Vector = {} Vector.__index = Vector function Vector.new(x, y) return setmetatable({x = x, y = y}, Vector) end function Vector:__tostring() return string.format("Vector(%d, %d)", self.x, self.y) end function Vector:__add(other) return Vector.new(self.x + other.x, self.y + other.y) end function Vector:magnitude() return math.sqrt(self.x^2 + self.y^2) end local v1 = Vector.new(3, 4) local v2 = Vector.new(1, 2) local v3 = v1 + v2 return tostring(v1), tostring(v3), v1:magnitude() "; lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, 3); console.log(lua.lua_tojsstring(L, -3)); // "Vector(3, 4)" console.log(lua.lua_tojsstring(L, -2)); // "Vector(4, 6)" console.log(lua.lua_tonumber(L, -1)); // 5 ``` -------------------------------- ### Setting and Getting Global Variables Source: https://context7.com/fengari-lua/fengari/llms.txt Exchange data between JavaScript and Lua using global variables. This example shows how to set Lua global variables from JavaScript and read variables set by Lua back into JavaScript. ```javascript const fengari = require('fengari'); const lua = fengari.lua; const lauxlib = fengari.lauxlib; const lualib = fengari.lualib; const { to_luastring } = fengari; const L = lauxlib.luaL_newstate(); lualib.luaL_openlibs(L); // Set global variables from JavaScript lua.lua_pushliteral(L, "JavaScript"); lua.lua_setglobal(L, to_luastring("language")); lua.lua_pushinteger(L, 2024); lua.lua_setglobal(L, to_luastring("year")); lua.lua_newtable(L); lua.lua_pushliteral(L, "Node.js"); lua.lua_setfield(L, -2, to_luastring("runtime")); lua.lua_setglobal(L, to_luastring("config")); // Use globals in Lua and set new ones const luaCode = " result = language .. " in " .. tostring(year) config.version = "1.0" return result "; lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, 1); console.log(lua.lua_tojsstring(L, -1)); // "JavaScript in 2024" lua.lua_pop(L, 1); // Read global set by Lua lua.lua_getglobal(L, to_luastring("config")); lua.lua_getfield(L, -1, to_luastring("version")); console.log("Version:", lua.lua_tojsstring(L, -1)); // "1.0" ``` -------------------------------- ### JavaScript Closures with Upvalues Source: https://context7.com/fengari-lua/fengari/llms.txt Create Lua functions with associated upvalues using `lua_pushcclosure`. This example demonstrates how a JavaScript function can manage state across multiple calls via Lua upvalues. ```javascript const fengari = require('fengari'); const lua = fengari.lua; const lauxlib = fengari.lauxlib; const lualib = fengari.lualib; const { to_luastring } = fengari; const L = lauxlib.luaL_newstate(); lualib.luaL_openlibs(L); // Function that uses upvalue function counter(L) { // Get upvalue (at pseudo-index) const currentCount = lua.lua_tointeger(L, lua.lua_upvalueindex(1)); const newCount = currentCount + 1; // Update the upvalue lua.lua_pushinteger(L, newCount); lua.lua_replace(L, lua.lua_upvalueindex(1)); // Return the new count lua.lua_pushinteger(L, newCount); return 1; } // Push initial upvalue, then create closure lua.lua_pushinteger(L, 0); // Initial count = 0 lua.lua_pushcclosure(L, counter, 1); // 1 upvalue lua.lua_setglobal(L, to_luastring("counter")); const luaCode = " local a = counter() local b = counter() local c = counter() return a, b, c "; lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, 3); console.log(lua.lua_tointeger(L, -3)); // 1 console.log(lua.lua_tointeger(L, -2)); // 2 console.log(lua.lua_tointeger(L, -1)); // 3 ``` -------------------------------- ### Convert Lua value to DataView Source: https://github.com/fengari-lua/fengari/blob/master/README.md Use `lua_todataview` to get a DataView representation of a Lua value. This is an alternative to `lua_tolstring` when a binary view is needed. ```javascript var dv = lua_todataview(L, idx); ``` -------------------------------- ### Get proxy for Lua value Source: https://github.com/fengari-lua/fengari/blob/master/README.md Retrieve a JavaScript proxy object `p` for a Lua value at stack index `idx` using `lua_toproxy`. This proxy can be used to push the Lua value back onto a state's stack. ```javascript var p = lua_toproxy(L, 1); p(L); ``` -------------------------------- ### Create Lua State with Standard Libraries Source: https://context7.com/fengari-lua/fengari/llms.txt Initializes a new Lua state using `luaL_newstate` and opens all standard Lua libraries. Ensure to check for a successful state creation. ```javascript const fengari = require('fengari'); const lua = fengari.lua; const lauxlib = fengari.lauxlib; const lualib = fengari.lualib; // Create a new Lua state const L = lauxlib.luaL_newstate(); if (!L) throw Error("Failed to create Lua state"); // Open all standard libraries (math, string, table, coroutine, etc.) lualib.luaL_openlibs(L); // The state is now ready for use console.log("Lua state created successfully"); ``` -------------------------------- ### Load and Execute Lua Files in JavaScript Source: https://context7.com/fengari-lua/fengari/llms.txt Shows how to load and execute Lua code from external files using `luaL_loadfile` and `luaL_dofile`. Handles potential syntax, file, and runtime errors. ```javascript const fengari = require('fengari'); const lua = fengari.lua; const lauxlib = fengari.lauxlib; const lualib = fengari.lualib; const { to_luastring } = fengari; const L = lauxlib.luaL_newstate(); lualib.luaL_openlibs(L); // In Node.js: Load file with luaL_loadfile then execute const filename = to_luastring("./script.lua"); const loadStatus = lauxlib.luaL_loadfile(L, filename); if (loadStatus === lua.LUA_OK) { const callStatus = lua.lua_pcall(L, 0, lua.LUA_MULTRET, 0); if (callStatus !== lua.LUA_OK) { console.error("Runtime error:", lua.lua_tojsstring(L, -1)); } } else if (loadStatus === lauxlib.LUA_ERRFILE) { console.error("File error:", lua.lua_tojsstring(L, -1)); } else { console.error("Syntax error:", lua.lua_tojsstring(L, -1)); } // Or use luaL_dofile as shorthand (load + call) // Returns 0 on success const doStatus = lauxlib.luaL_dofile(L, to_luastring("./another_script.lua")); if (doStatus !== 0) { console.error("Error:", lua.lua_tojsstring(L, -1)); } ``` -------------------------------- ### Create and Manipulate Lua Tables in JavaScript Source: https://context7.com/fengari-lua/fengari/llms.txt Use lua_newtable to create a new Lua table. Employ lua_setfield and lua_seti for setting values with string and integer keys, respectively. For generic key-value pairs, use lua_pushliteral/lua_pushinteger for the key, push the value, and then use lua_settable. Values can be read back using lua_getfield and lua_geti. ```javascript const fengari = require('fengari'); const lua = fengari.lua; const lauxlib = fengari.lauxlib; const { to_luastring } = fengari; const L = lauxlib.luaL_newstate(); // Create a new table lua.lua_newtable(L); // Set string key: t["name"] = "Fengari" lua.lua_pushliteral(L, "Fengari"); lua.lua_setfield(L, -2, to_luastring("name")); // Set integer key: t[1] = 100 lua.lua_pushinteger(L, 100); lua.lua_seti(L, -2, 1); // Set using generic table access: t["version"] = "0.1.5" lua.lua_pushliteral(L, "version"); lua.lua_pushliteral(L, "0.1.5"); lua.lua_settable(L, -3); // Read values back lua.lua_getfield(L, -1, to_luastring("name")); console.log("name:", lua.lua_tojsstring(L, -1)); // "Fengari" lua.lua_pop(L, 1); lua.lua_geti(L, -1, 1); console.log("t[1]:", lua.lua_tointeger(L, -1)); // 100 lua.lua_pop(L, 1); // Iterate over table with lua_next lua.lua_pushnil(L); // First key while (lua.lua_next(L, -2) !== 0) { const keyType = lua.lua_type(L, -2); const key = keyType === lua.LUA_TSTRING ? lua.lua_tojsstring(L, -2) : lua.lua_tointeger(L, -2); console.log("Key:", key, "Value:", lua.lua_tojsstring(L, -1)); lua.lua_pop(L, 1); // Remove value, keep key for next iteration } ``` -------------------------------- ### Manage Lua Coroutines in JavaScript Source: https://context7.com/fengari-lua/fengari/llms.txt Demonstrates creating and managing Lua coroutines for cooperative multitasking using `coroutine.wrap`, `coroutine.create`, and `coroutine.resume`. This is useful for implementing generators or complex asynchronous flows within Lua. ```javascript const fengari = require('fengari'); const lua = fengari.lua; const lauxlib = fengari.lauxlib; const lualib = fengari.lualib; const { to_luastring } = fengari; const L = lauxlib.luaL_newstate(); lualib.luaL_openlibs(L); const luaCode = ` -- Generator function using coroutines local function range(from, to) return coroutine.wrap(function() for i = from, to do coroutine.yield(i) end end) end -- Using coroutine.create and coroutine.resume local co = coroutine.create(function(start) local value = start while true do value = coroutine.yield(value * 2) if value == nil then break end end end) local results = {} local _, r1 = coroutine.resume(co, 5) -- Start with 5, get 10 local _, r2 = coroutine.resume(co, r1) -- Send 10, get 20 local _, r3 = coroutine.resume(co, r2) -- Send 20, get 40 -- Also test range generator local sum = 0 for n in range(1, 5) do sum = sum + n end return r1, r2, r3, sum, coroutine.status(co) `; lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, 5); console.log("r1:", lua.lua_tonumber(L, -5)); // 10 console.log("r2:", lua.lua_tonumber(L, -4)); // 20 console.log("r3:", lua.lua_tonumber(L, -3)); // 40 console.log("sum:", lua.lua_tonumber(L, -2)); // 15 console.log("status:", lua.lua_tojsstring(L, -1)); // "suspended" ``` -------------------------------- ### Convert Between JavaScript and Lua Strings Source: https://context7.com/fengari-lua/fengari/llms.txt Demonstrates converting JavaScript strings to Lua's `Uint8Array` representation using `to_luastring` and back using `to_jsstring`. Supports cached conversions for performance. ```javascript const fengari = require('fengari'); const { to_luastring, to_jsstring } = fengari; // Convert JavaScript string to Lua string (Uint8Array) const luaStr = to_luastring("Hello, Fengari!"); console.log(luaStr instanceof Uint8Array); // true // Convert Lua string back to JavaScript string const jsStr = to_jsstring(luaStr); console.log(jsStr); // "Hello, Fengari!" // Cached conversion for frequently used strings (improves performance) const cachedStr = to_luastring("frequently used", true); ``` -------------------------------- ### Efficient String Concatenation with LuaL_Buffer Source: https://context7.com/fengari-lua/fengari/llms.txt Use `luaL_Buffer` from the auxiliary library for efficient string building in Lua. Initialize the buffer with `luaL_buffinit`, add strings or characters, and push the final result to the stack with `luaL_pushresult`. ```javascript const fengari = require('fengari'); const lua = fengari.lua; const lauxlib = fengari.lauxlib; const { to_luastring } = fengari; const L = lauxlib.luaL_newstate(); // Create a buffer for efficient string concatenation const B = new lauxlib.luaL_Buffer(); lauxlib.luaL_buffinit(L, B); // Add strings to the buffer lauxlib.luaL_addstring(B, to_luastring("Hello")); lauxlib.luaL_addstring(B, to_luastring(", ")); lauxlib.luaL_addstring(B, to_luastring("World")); lauxlib.luaL_addchar(B, 33); // ASCII for '!' // Push the result to the stack lauxlib.luaL_pushresult(B); console.log(lua.lua_tojsstring(L, -1)); // "Hello, World!" ``` -------------------------------- ### Create Custom Lua Objects with JavaScript Userdata Source: https://context7.com/fengari-lua/fengari/llms.txt Demonstrates creating custom Lua objects from JavaScript using userdata. This involves defining a metatable with methods and a constructor function, allowing JavaScript data to be manipulated within Lua. ```javascript const fengari = require('fengari'); const lua = fengari.lua; const lauxlib = fengari.lauxlib; const lualib = fengari.lualib; const { to_luastring } = fengari; const L = lauxlib.luaL_newstate(); lualib.luaL_openlibs(L); // Create a new metatable for our userdata type lauxlib.luaL_newmetatable(L, to_luastring("MyObject")); // Add methods to the metatable const methods = { getValue: function(L) { const ud = lauxlib.luaL_checkudata(L, 1, to_luastring("MyObject")); lua.lua_pushnumber(L, ud.value); return 1; }, setValue: function(L) { const ud = lauxlib.luaL_checkudata(L, 1, to_luastring("MyObject")); ud.value = lauxlib.luaL_checknumber(L, 2); return 0; } }; // Set __index to the metatable itself for method lookup lua.lua_pushvalue(L, -1); lua.lua_setfield(L, -2, to_luastring("__index")); // Add methods for (const [name, fn] of Object.entries(methods)) { lua.lua_pushcfunction(L, fn); lua.lua_setfield(L, -2, to_luastring(name)); } lua.lua_pop(L, 1); // Constructor function function createMyObject(L) { const initialValue = lauxlib.luaL_optnumber(L, 1, 0); const ud = lua.lua_newuserdata(L, 0); ud.value = initialValue; lauxlib.luaL_setmetatable(L, to_luastring("MyObject")); return 1; } lua.lua_register(L, to_luastring("MyObject"), createMyObject); // Use in Lua const luaCode = ` local obj = MyObject(42) local v1 = obj:getValue() obj:setValue(100) local v2 = obj:getValue() return v1, v2 `; lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, 2); console.log(lua.lua_tonumber(L, -2)); // 42 console.log(lua.lua_tonumber(L, -1)); // 100 ``` -------------------------------- ### Load and Execute Lua Code with lua_call Source: https://context7.com/fengari-lua/fengari/llms.txt Loads Lua source code using `luaL_loadstring` and executes it with `lua_call`. Handles potential loading errors and retrieves the result from the stack. ```javascript const fengari = require('fengari'); const lua = fengari.lua; const lauxlib = fengari.lauxlib; const lualib = fengari.lualib; const { to_luastring } = fengari; const L = lauxlib.luaL_newstate(); lualib.luaL_openlibs(L); const luaCode = ` local function greet(name) return "Hello, " .. name .. "!" end return greet("World") `; // Load the Lua code const loadStatus = lauxlib.luaL_loadstring(L, to_luastring(luaCode)); if (loadStatus !== lua.LUA_OK) { console.error("Load error:", lua.lua_tojsstring(L, -1)); } // Execute with lua_call (0 arguments, LUA_MULTRET for all return values) lua.lua_call(L, 0, lua.LUA_MULTRET); // Get the result console.log(lua.lua_tojsstring(L, -1)); // "Hello, World!" ``` -------------------------------- ### Fengari Library Metadata Source: https://github.com/fengari-lua/fengari/blob/master/README.md The 'fengari' library, automatically loaded by `luaL_openlibs`, provides metadata about the Fengari release, including authors, copyright, and version information. ```lua fengari.AUTHORS fengari.COPYRIGHT fengari.RELEASE fengari.VERSION fengari.VERSION_MAJOR fengari.VERSION_MINOR fengari.VERSION_NUM fengari.VERSION_RELEASE ``` -------------------------------- ### Fengari Library Metadata Source: https://github.com/fengari-lua/fengari/blob/master/README.md Accessing release and version information for the Fengari library. ```APIDOC ## fengari Library ### Description A library containing metadata about the fengari release, automatically loaded by luaL_openlibs into the global "fengari". ### Fields - AUTHORS - COPYRIGHT - RELEASE - VERSION - VERSION_MAJOR - VERSION_MINOR - VERSION_NUM - VERSION_RELEASE ``` -------------------------------- ### Data and Function Management Source: https://github.com/fengari-lua/fengari/blob/master/README.md Functions for converting stack values to DataViews and pushing JavaScript functions or closures onto the Lua stack. ```APIDOC ## lua_todataview(L, idx) ### Description Equivalent to lua_tolstring but returns a DataView instead of a string. ### Method Function Call ## lua_pushjsfunction(L, func) ### Description Alias for lua_pushcfunction. ## lua_pushjsclosure(L, func, n) ### Description Alias for lua_pushcclosure. ``` -------------------------------- ### Push JavaScript Values to Lua Stack Source: https://context7.com/fengari-lua/fengari/llms.txt Use type-specific functions like lua_pushnil, lua_pushboolean, lua_pushnumber, lua_pushinteger, lua_pushliteral, lua_pushstring, and lua_pushfstring to push various JavaScript data types onto the Lua stack. Ensure correct types are used for numbers and strings. ```javascript const fengari = require('fengari'); const lua = fengari.lua; const lauxlib = fengari.lauxlib; const { to_luastring } = fengari; const L = lauxlib.luaL_newstate(); // Push nil lua.lua_pushnil(L); // Push boolean lua.lua_pushboolean(L, true); // Push numbers lua.lua_pushnumber(L, 3.14159); // floating point lua.lua_pushinteger(L, 42); // integer (32-bit in Fengari) // Push strings lua.lua_pushliteral(L, "JavaScript string"); // from JS string lua.lua_pushstring(L, to_luastring("Lua string")); // from Uint8Array // Push formatted string lua.lua_pushfstring(L, to_luastring("Value: %d, Name: %s"), 100, to_luastring("test")); // Check stack contents console.log("Stack size:", lua.lua_gettop(L)); // 7 items // Check types console.log("Type at -1:", lua.lua_typename(L, lua.lua_type(L, -1))); // string ``` -------------------------------- ### Register JavaScript Functions for Lua Source: https://context7.com/fengari-lua/fengari/llms.txt Expose JavaScript functions to Lua using lua_register. The JavaScript function must accept the Lua state (L) as an argument and return the number of values pushed onto the stack. Use lauxlib.luaL_checknumber or lauxlib.luaL_checkstring to safely retrieve arguments from Lua. ```javascript const fengari = require('fengari'); const lua = fengari.lua; const lauxlib = fengari.lauxlib; const lualib = fengari.lualib; const { to_luastring } = fengari; const L = lauxlib.luaL_newstate(); lualib.luaL_openlibs(L); // Define a JavaScript function callable from Lua // Must return the number of return values pushed to stack function jsAdd(L) { const a = lauxlib.luaL_checknumber(L, 1); const b = lauxlib.luaL_checknumber(L, 2); lua.lua_pushnumber(L, a + b); return 1; // One return value } function jsGreet(L) { const name = lauxlib.luaL_checkstring(L, 1); const greeting = "Hello, " + fengari.to_jsstring(name) + "!"; lua.lua_pushliteral(L, greeting); return 1; } // Register functions globally lua.lua_register(L, to_luastring("js_add"), jsAdd); lua.lua_register(L, to_luastring("js_greet"), jsGreet); // Use from Lua const luaCode = "\n local sum = js_add(10, 20) local greeting = js_greet(\"Fengari\") return sum, greeting "; lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, 2); console.log("Sum:", lua.lua_tonumber(L, -2)); // 30 console.log("Greeting:", lua.lua_tojsstring(L, -1)); // "Hello, Fengari!" ``` -------------------------------- ### Error Handling and Proxy Management Source: https://github.com/fengari-lua/fengari/blob/master/README.md Functions for managing native JavaScript error handlers and interacting with Lua value proxies. ```APIDOC ## lua_atnativeerror(L, func) ### Description Sets a function to be called if a native JavaScript error is thrown across a lua pcall. The function will be run as if it were a message handler. ## lua_isproxy(p, L) ### Description Returns a boolean indicating whether p is a proxy. If L is non-null, only returns true if p belongs to the same global state. ## lua_toproxy(L, idx) ### Description Returns a JavaScript object p that holds a reference to the lua value at the stack index idx. This object can be called with a lua_State to push the value onto that state's stack. ``` -------------------------------- ### Execute Lua Code Safely with lua_pcall Source: https://context7.com/fengari-lua/fengari/llms.txt Executes Lua code using `lua_pcall` for protected calls, catching errors within the Lua environment. Errors are reported, and the stack is cleaned. ```javascript const fengari = require('fengari'); const lua = fengari.lua; const lauxlib = fengari.lauxlib; const lualib = fengari.lualib; const { to_luastring } = fengari; const L = lauxlib.luaL_newstate(); lualib.luaL_openlibs(L); const luaCode = ` local function riskyOperation(x) if x < 0 then error("Value must be non-negative!") end return math.sqrt(x) end return riskyOperation(-5) `; lauxlib.luaL_loadstring(L, to_luastring(luaCode)); // lua_pcall returns status code; 0 args, multiple returns, 0 = no error handler const status = lua.lua_pcall(L, 0, lua.LUA_MULTRET, 0); if (status !== lua.LUA_OK) { // Error occurred - message is on stack console.error("Lua error:", lua.lua_tojsstring(L, -1)); lua.lua_pop(L, 1); // Remove error message from stack } else { console.log("Result:", lua.lua_tonumber(L, -1)); } ``` -------------------------------- ### Create Proxy Objects for Cross-State References Source: https://context7.com/fengari-lua/fengari/llms.txt Use `lua_toproxy` to create JavaScript references to Lua values that can be passed between Lua states. `lua_isproxy` can be used to check if a value is a proxy object. ```javascript const fengari = require('fengari'); const lua = fengari.lua; const lauxlib = fengari.lauxlib; const { to_luastring } = fengari; const L = lauxlib.luaL_newstate(); // Create a table in Lua lua.lua_newtable(L); lua.lua_pushliteral(L, "important data"); lua.lua_setfield(L, -2, to_luastring("key")); // Create a proxy reference to this table const tableProxy = lua.lua_toproxy(L, -1); lua.lua_pop(L, 1); // Remove table from stack // Later, we can push the same table back to the stack tableProxy(L); lua.lua_getfield(L, -1, to_luastring("key")); console.log(lua.lua_tojsstring(L, -1)); // "important data" // Check if something is a proxy console.log(lua.lua_isproxy(tableProxy, L)); // true console.log(lua.lua_isproxy({}, L)); // false ``` -------------------------------- ### Push JavaScript function as Lua C function Source: https://github.com/fengari-lua/fengari/blob/master/README.md Use `lua_pushjsfunction` as an alias for `lua_pushcfunction` to expose a JavaScript function to Lua. ```javascript lua_pushjsfunction(L, func); ``` -------------------------------- ### Push JavaScript closure as Lua C closure Source: https://github.com/fengari-lua/fengari/blob/master/README.md Use `lua_pushjsclosure` as an alias for `lua_pushcclosure` to create a Lua closure from a JavaScript function. ```javascript lua_pushjsclosure(L, func, n); ``` -------------------------------- ### Use Debug Library for Lua Introspection Source: https://context7.com/fengari-lua/fengari/llms.txt The debug library provides functions for inspecting Lua code, including retrieving stack traces, function information, and local variable names and values. ```javascript const fengari = require('fengari'); const lua = fengari.lua; const lauxlib = fengari.lauxlib; const lualib = fengari.lualib; const { to_luastring } = fengari; const L = lauxlib.luaL_newstate(); lualib.luaL_openlibs(L); const luaCode = ` local function innerFunction() return debug.traceback("Stack trace:", 1) end local function outerFunction() return innerFunction() end -- Get function info local info = debug.getinfo(outerFunction) -- Get local variables in a function local function testLocals() local x = 10 local y = 20 local name, value = debug.getlocal(1, 1) return name, value end local trace = outerFunction() local localName, localValue = testLocals() return info.what, trace, localName, localValue `; lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, 4); console.log("Function type:", lua.lua_tojsstring(L, -4)); // "Lua" console.log("Traceback:", lua.lua_tojsstring(L, -3)); console.log("Local name:", lua.lua_tojsstring(L, -2)); // "x" console.log("Local value:", lua.lua_tonumber(L, -1)); // 10 ``` -------------------------------- ### Push a Literal String onto the Lua Stack Source: https://github.com/fengari-lua/fengari/blob/master/README.md Use `lua_pushliteral` to push a JavaScript string onto the Lua stack. Fengari automatically converts the string to a byte array, handling Lua's 8-bit clean string requirement. ```javascript lua.lua_pushliteral(L, "hello world!"); ``` -------------------------------- ### Set native error handler Source: https://github.com/fengari-lua/fengari/blob/master/README.md Configure `lua_atnativeerror` to specify a JavaScript function that will be invoked when a native JavaScript error occurs during a Lua `pcall`. This function acts as a message handler. ```javascript lua_atnativeerror(L, func); ``` -------------------------------- ### Read Lua Values from Stack to JavaScript Source: https://context7.com/fengari-lua/fengari/llms.txt Retrieve values from the Lua stack into JavaScript using functions like lua_tointeger, lua_tonumber, lua_tojsstring, and lua_toboolean. Use lua_istable to check if a value is a table. Indices are relative to the top of the stack, with -1 being the topmost element. ```javascript const fengari = require('fengari'); const lua = fengari.lua; const lauxlib = fengari.lauxlib; const lualib = fengari.lualib; const { to_luastring } = fengari; const L = lauxlib.luaL_newstate(); lualib.luaL_openlibs(L); const luaCode = "\n return 42, 3.14, \"hello\", true, {key = \"value\"}\n"; lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, 5); // Read integer (index -5 is first return value) const intVal = lua.lua_tointeger(L, -5); console.log("Integer:", intVal); // 42 // Read number const numVal = lua.lua_tonumber(L, -4); console.log("Number:", numVal); // 3.14 // Read string as JavaScript string const strVal = lua.lua_tojsstring(L, -3); console.log("String:", strVal); // "hello" // Read boolean const boolVal = lua.lua_toboolean(L, -2); console.log("Boolean:", boolVal); // true // Check if value is a table console.log("Is table:", lua.lua_istable(L, -1)); // true ``` -------------------------------- ### Handle JavaScript Exceptions with Native Error Handler Source: https://context7.com/fengari-lua/fengari/llms.txt Use `lua_atnativeerror` to catch and handle JavaScript exceptions thrown from Lua-called functions. The JavaScript error object is accessible as userdata at index 1. ```javascript const fengari = require('fengari'); const lua = fengari.lua; const lauxlib = fengari.lauxlib; const lualib = fengari.lualib; const { to_luastring } = fengari; const L = lauxlib.luaL_newstate(); lualib.luaL_openlibs(L); // Set up native error handler lua.lua_atnativeerror(L, function(L) { // The JavaScript error object is passed as userdata at index 1 const jsError = lua.lua_touserdata(L, 1); // Convert to Lua error message const message = "JavaScript Error: " + (jsError.message || String(jsError)); lua.lua_pushstring(L, to_luastring(message)); return 1; }); // A function that might throw a JavaScript error function riskyJsFunction(L) { const value = lauxlib.luaL_checknumber(L, 1); if (value < 0) { throw new Error("Negative values not allowed"); } lua.lua_pushnumber(L, Math.sqrt(value)); return 1; } lua.lua_register(L, to_luastring("risky_sqrt"), riskyJsFunction); const luaCode = ` local ok1, result1 = pcall(risky_sqrt, 16) local ok2, result2 = pcall(risky_sqrt, -1) return ok1, result1, ok2, result2 `; lauxlib.luaL_loadstring(L, to_luastring(luaCode)); lua.lua_call(L, 0, 4); console.log("ok1:", lua.lua_toboolean(L, -4)); // true console.log("result1:", lua.lua_tonumber(L, -3)); // 4 console.log("ok2:", lua.lua_toboolean(L, -2)); // false console.log("result2:", lua.lua_tojsstring(L, -1)); // Contains error message ``` -------------------------------- ### Check if a value is a proxy Source: https://github.com/fengari-lua/fengari/blob/master/README.md Use `lua_isproxy` to determine if a given JavaScript value `p` is a proxy object representing a Lua value. Optionally, check if it belongs to the specified Lua state `L`. ```javascript b = lua_isproxy(p, L); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.