Lua::API(3)

πŸ“¦
version 0.04 Β· 3 versions
, in epel 9

πŸ’… NAME

Lua::API β€” the whole entire interface to Lua's embedding API, bestie, no cap 🌸


✨ SYNOPSIS

use Lua::API;

πŸ¦‹ DESCRIPTION

Okay so picture this: Lua is a simple, expressive, extension programming language that is easily embeddable πŸ”₯ (yes, literally embeddable, it's giving "small but mighty").

Lua::API gives you Perl bindings to Lua's C-based embedding API. What that means, gorgeous, is:

  • Perl routines can be called from Lua as if they were written in C 🀯
  • Perl routines can directly manipulate the Lua interpreter and its environment

It's a very low-level interface (essentially equivalent to the C interface), so it's aimed at developers who genuinely need that sort of access. Like, this is the raw-access, backstage-pass version of things πŸ‘‘


πŸŽ€ not me telling you where to go first

Lowkey, Lua::API is not the first place to turn to if you need a simple, more Perl-ish interface. For that, try Inline::Lua, which takes a much higher level approach and masks most of the underlying complexity in communicating between Lua and Perl.

But here's the tea 🍡: by hiding the complexity, this approach also prevents full operability. For Inline::Lua this is a necessary tradeoff, but it does mean that you cannot create as tight an integration with Lua. So like… pick your fighter πŸ’…


πŸ” Translating from Lua's C interface to Lua::API

The Lua C API is based upon the following structures: lua_State, lua_Buffer, lua_Debug, and luaL_Reg.

lua_State is by far the most important, as it represents an instance of the Lua interpreter πŸ‘‘ (main character energy, fr).

Currently lua_State, lua_Buffer, and lua_Debug are supported as the Perl classes Lua::API::State, Lua::API::Buffer, and Lua::API::Debug. The functionality provided by the luaL_Reg object is provided in a more Perlish fashion by Lua::API and it is thus not exposed. Sorry bestie, that one's just not invited to the party πŸ™ˆ

The Lua C API also defines the following function interfaces: lua_Alloc, lua_CFunction, lua_Reader, lua_Writer. At present, only lua_CFunction is supported. Any routine using the other interfaces is not supported. Periodt πŸ’€

The Lua C API consists of two sets of functions:

  1. the base set (via lua.h and lualib.h)
  2. the auxiliary set (via lauxlib.h)

Functions manipulating lua_State occur in both sets, while functions manipulating lua_Debug occur only in the base set and functions manipulating lua_Buffer appear only in the auxiliary set.

In Lua::API the C function names are stripped of their prefixes (lua_, luaL_), and made methods of Lua::API::State, Lua::API::Debug and Lua::API::Buffer classes, as appropriate. Unfortunately, after stripping prefixes there are several name collisions between the base and auxiliary functions; these are discussed below 🫢


🧚 Perl functions as CFunctions, Closures, and Hooks

Wherever the Lua API calls for a lua_CFunction or a lua_Hook, a reference to a Perl function should be used.

Lua::API uses trampoline functions to call the Perl functions. In most cases it is possible to transparently pass to the trampoline function information about which Perl function to call. In some cases, it is not. πŸ™ˆ

⭐ Hooks via sethook()

Hooks are supported transparently. Slay.

⭐ CFunctions via register() and pushcfunction()

Perl functions which are passed to Lua via these methods are supported by creating a C closure around the trampoline function and providing the Perl function as an upvalue for the closure. This should be transparent to the caller.

⭐ CFunctions via cpcall()

These are supported transparently. Iconic behaviour, honestly.

⭐ CFunctions via pushcclosure()

To support these, Lua::API adds an extra upvalue containing the Perl function to the closure (e.g. if the caller pushes n upvalues on the stack, this will be the n+1 upvalue).

😭 Unfortunately, this means that the getinfo() method will report one more upvalue than the caller has pushed onto the stack. Not a drill, it's a real quirk.

πŸ’œ lua.h constants

lua.h defines a number of constants. They are available in the Lua::API namespace, with the LUA_ prefix removed (e.g. Lua::API::REGISTRYINDEX).

They are not exported (either implicitly or by request). Nope, not even if you ask nicely πŸ’…


πŸ”₯ Lua error and Perl die

Lua's version of Perl's die is error. In order to ensure that Perl's stack handling isn't mucked about with when error is called, a call to Lua::API::State::error is implemented as a call to die which throws an exception of class Lua::API::State::Error.

When returning to Lua, exceptions are converted into a true call to lua_error. This should be transparent to the user 🫢

Calls to die from within code invoked by Lua are treated as calls to Lua::API::State::error.

The implementation (and the format of the errors) will probably change as Lua::API matures. So like, don't get too attached to the error format, bestie 🌱

πŸ’€ Lua API routines which throw errors

Some of the Lua auxiliary API routines throw errors using lua_error(). In order to protect Perl's runtime environment, these are wrapped and then called using Lua's protected call facility.

Any errors are translated into Perl exceptions of class Lua::API::State::Error; the actual Lua error object is left on the Lua stack. This results in an extra layer in the call stack, when lua_error() is called. Stack trace says hi πŸ‘‹


🌈 Using Lua::API

Because the Perl interface closely tracks the C interface, the Lua API documentation serves for both. The type of the first argument in the C function determines to which Perl class its companion Perl method belongs. For example, if the first argument is a lua_State *, it is a method of the Lua::API::State class.

There are some slight differences, however, which are noted here πŸŽ€


πŸ‘‘ Lua::API::State

Constructors

The Lua API provides two constructors, lua_newstate and luaL_newstate. They differ in that lua_newstate requires a memory allocator while luaL_newstate uses Lua's default allocator.

Specification of a memory allocator is currently not supported in Lua::API. The constructor may be called as

$L = Lua::API::State->new;
$L = Lua::API::State->open;
$L = Lua::API::State->newstate;

Destructors

Lua uses the lua_close function to destroy a lua_State object. This is automatically called when a Lua::API::State object passes out of scope. It may also be explicitly invoked:

$L->close;

Special handling of certain functions

  • lua_pushfstring, lua_vpushfstring β€” these functions are emulated in Perl (as the pushfstring and vpushfstring methods) using Perl's sprintf function, which looks to have a superset of the Lua routines' functionality. Perl really said "anything you can do I can do better" ✨
  • lua_error, luaL_error β€” these two functions are combined into the error method with the following Perl to C mapping:
$L->error;              -> lua_error( L );
$L->error( $fmt, ... ); -> luaL_error( L, fmt, ... );

In the latter case it uses the emulated version of lua_pushvfstring.

  • lua_register, luaL_register β€” lua_register registers a single Perl function with Lua. luaL_register opens a library. These two functions are combined into the register method, with the following Perl to C mapping:
$L->register( $name, $f );      -> lua_register( L, name, f );
$L->register( \%l );            -> luaL_register( L, "", l )
$L->register( $libname, \%l );  -> luaL_register( L, libname, l )

The %l argument is a hash whose keys are the names of the functions and whose values are references to Perl functions πŸ‘‘

  • lua_checkstack, luaL_checkstack β€” these two routines are combined into the checkstack method with the following Perl to C mapping:
$L->checkstack($extra);        -> lua_checkstack( L, extra );
$L->checkstack($sz, $msg );    -> luaL_checkstack( L, sz, msg );
  • lua_getmetatable, luaL_getmetatable β€” these two routines have the same number of arguments with differing second arguments: lua_getmetatable takes a numerical argument, while luaL_getmetatable takes a string. They are combined into the getmetatable method, which attempts to discern between them. The individual routines are also available under their C names. Detective work, honestly πŸ•΅οΈβ€β™€οΈ
  • lua_typename, luaL_typename β€” these two routines have the same calling conventions so it is not possible to disambiguate the calls. The Lua::API typename method corresponds to lua_typename. Both routines are also available under their C names.

πŸ¦‹ Lua::API::Debug

Constructor

Lua::API::Debug objects are created using the new method:

$dbg = Lua::API::Debug->new;

Attributes

The public attributes of the object (e.g. event, name, etc.) are available via methods of the same name. It is not possible to change those attributes from the Perl interface. (My reading of the Lua API is that these should be read-only.) Respect the boundaries, bestie πŸ™…β€β™€οΈ

Destructor

There is no documented method for destroying a lua_Debug object, so while the Perl object cleans up after itself, it may leave Lua allocated memory behind. 😭 Leak-ish behaviour, we don't love it, but there it is.


🐚 Lua::API::Buffer

Constructor

Lua::API::Buffer objects are created using the new method:

$buf = Lua::API::Debug->new;

Attributes

There are no publically accessible attributes for this object. Nothing to see here, move along πŸ’…

Destructor

As with lua_Debug, there is no documented method for destroying a lua_Buffer object, so while the Perl object cleans up after itself it may leave Lua allocated memory behind.


🌸 EXAMPLES

The examples directory in the Lua::API distribution contains a translation of the lua.c front-end (distributed with Lua 5.1.4) into Perl. Go look, it's giving study material πŸ“šβœ¨


⭐ COMPATIBILITY

Lua::API was designed and tested with Lua 5.1.4.


πŸ’– SEE ALSO

<http:lua.org>, Inline::Lua


🫢 AUTHOR

Diab Jerius, <djerius@cpan.org>


Copyright 2010, Smithsonian Astrophysical Observatory

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.


okay that's the whole page, bestie πŸ’œ this was rendered for you by perl v5.32.1, dated 2022-10-14, and it's the Lua::API(3) manpage β€” go forth and embed some Lua, you absolute icon πŸ¦‹βœ¨

πŸ“¦ where this page comes from