2017-05-21 21:47:32 -04:00
|
|
|
# rlua -- High level bindings between Rust and Lua
|
|
|
|
|
2017-05-22 23:24:30 -04:00
|
|
|
[![Build Status](https://travis-ci.org/chucklefish/rlua.svg?branch=master)](https://travis-ci.org/chucklefish/rlua)
|
|
|
|
|
2017-06-25 22:25:28 -04:00
|
|
|
[API Documentation](https://docs.rs/rlua)
|
2017-05-29 16:28:29 -04:00
|
|
|
|
2017-06-25 22:25:28 -04:00
|
|
|
[Examples](examples/examples.rs)
|
|
|
|
|
|
|
|
This library is a high level interface between Rust and Lua. Its major goal is
|
|
|
|
to expose as easy to use, practical, and flexible of an API between Rust and Lua
|
|
|
|
as possible, while also being completely safe.
|
2017-05-21 21:47:32 -04:00
|
|
|
|
2018-02-10 17:50:04 -05:00
|
|
|
`rlua` is designed around "registry handles" to values inside the Lua state.
|
|
|
|
This means that when you get a type like `rlua::Table` or `rlua::Function` in
|
|
|
|
Rust, what you actually hold is an integer key into the Lua registry. This is
|
2018-02-10 17:55:20 -05:00
|
|
|
different from the bare Lua C API, where you create tables / functions on the
|
|
|
|
Lua stack and must be aware of their stack location. This is also similar to
|
|
|
|
how other Lua bindings systems like
|
|
|
|
[Selene](https://github.com/jeremyong/Selene) for C++ work, but it means that
|
|
|
|
using `rlua` may be slightly slower than what you could conceivably write using
|
|
|
|
the C API. The reasons for this design are safety and flexibility, and to
|
|
|
|
prevent the user of `rlua` from having to be aware of the Lua stack at all.
|
2018-02-10 17:50:04 -05:00
|
|
|
|
|
|
|
There are currently a few missing pieces of this API:
|
|
|
|
|
2018-01-26 21:36:13 -05:00
|
|
|
* Security limits on Lua code such as total instruction limits / memory limits
|
|
|
|
and control over which potentially dangerous libraries (e.g. io) are
|
|
|
|
available to scripts.
|
2017-05-22 10:52:32 -04:00
|
|
|
* Lua profiling support
|
2017-06-25 18:27:10 -04:00
|
|
|
* "Context" or "Sandboxing" support. There should be the ability to set the
|
|
|
|
`_ENV` upvalue of a loaded chunk to a table other than `_G`, so that you can
|
|
|
|
have different environments for different loaded chunks.
|
2017-08-02 17:04:44 -04:00
|
|
|
* Benchmarks, and quantifying performance differences with what you would
|
|
|
|
might write in C.
|
2017-05-21 21:47:32 -04:00
|
|
|
|
|
|
|
Additionally, there are ways I would like to change this API, once support lands
|
|
|
|
in rustc. For example:
|
|
|
|
|
2017-08-02 17:04:44 -04:00
|
|
|
* Currently, variadics are handled entirely with tuples and traits implemented
|
|
|
|
by macro for tuples up to size 12, it would be great if this was replaced
|
2018-02-10 17:50:04 -05:00
|
|
|
with real variadic generics when this is available in Rust.
|
2017-05-21 21:47:32 -04:00
|
|
|
|
2017-05-25 00:56:23 -04:00
|
|
|
It is also worth it to list some non-goals for the project:
|
|
|
|
|
2017-06-25 18:27:10 -04:00
|
|
|
* Be a perfect zero cost wrapper over the Lua C API
|
|
|
|
* Allow the user to do absolutely everything that the Lua C API might allow
|
2017-05-25 00:56:23 -04:00
|
|
|
|
2017-10-14 18:53:05 -04:00
|
|
|
## API stability
|
2017-05-22 03:09:59 -04:00
|
|
|
|
2017-10-14 18:53:05 -04:00
|
|
|
This library is very much Work In Progress, so there is a some API churn.
|
|
|
|
Currently, it follows a pre-1.0 semver, so all API changes should be accompanied
|
|
|
|
by 0.x version bumps.
|
2017-05-22 03:09:59 -04:00
|
|
|
|
2017-06-25 18:27:10 -04:00
|
|
|
## Safety and panics
|
2017-05-21 22:04:32 -04:00
|
|
|
|
2017-08-02 17:04:44 -04:00
|
|
|
The goal of this library is complete safety, it should not be possible to cause
|
|
|
|
undefined behavior whatsoever with the API, even in edge cases. There is,
|
|
|
|
however, QUITE a lot of unsafe code in this crate, and I would call the current
|
2017-10-14 18:53:05 -04:00
|
|
|
safety level of the crate "Work In Progress". Still, UB is considered the most
|
|
|
|
serious kind of bug, so if you find the ability to cause UB with this API *at
|
|
|
|
all*, please file a bug report.
|
2017-06-25 18:27:10 -04:00
|
|
|
|
2018-02-10 17:50:04 -05:00
|
|
|
Another goal of this library is complete protection from panics and aborts.
|
|
|
|
Currently, it should not be possible for a script to trigger a panic or abort
|
|
|
|
(with some important caveats described below). Similarly to the safety goal,
|
|
|
|
there ARE several internal panics and even aborts in `rlua` source, but they
|
|
|
|
should not be possible to trigger, and if you trigger them this should be
|
|
|
|
considered a bug.
|
|
|
|
|
|
|
|
There are some caveats to the panic / abort guarantee, however:
|
|
|
|
|
|
|
|
* `rlua` reserves the right to panic on API usage errors. Currently, the only
|
|
|
|
time this will happen is when passed a registry handle type from a different
|
|
|
|
main Lua state.
|
|
|
|
* Currently, there are no memory or execution limits on scripts, so untrusted
|
|
|
|
scripts can always at minimum infinite loop or allocate arbitrary amounts of
|
|
|
|
memory.
|
2017-12-04 01:47:04 -05:00
|
|
|
* The internal Lua allocator is set to use `realloc` from `libc`, but it is
|
2018-02-10 17:50:04 -05:00
|
|
|
wrapped in such a way that OOM errors are guaranteed to *abort*. This is
|
|
|
|
not currently such a big deal, as this matches the behavior of Rust itself.
|
2018-01-26 21:36:13 -05:00
|
|
|
This allows the internals of `rlua` to, in certain cases, call 'm' Lua C API
|
|
|
|
functions with the garbage collector disabled and know that these cannot
|
|
|
|
error. Eventually, `rlua` will support memory limits on scripts, and those
|
|
|
|
memory limits will cause regular memory errors rather than OOM aborts.
|
2018-02-10 17:50:04 -05:00
|
|
|
|
|
|
|
Yet another goal of the library is to, in all cases, safely handle panics
|
|
|
|
generated by Rust callbacks. Panic unwinds in Rust callbacks should currently
|
|
|
|
be handled correctly -- the unwind is caught and carried across the Lua API
|
|
|
|
boundary as a regular lua error in a way that prevents Lua from catching it.
|
|
|
|
This is done by overriding the normal Lua 'pcall' and 'xpcall' with custom
|
|
|
|
versions that cannot catch errors that are actually from Rust panics, and by
|
|
|
|
handling panic errors on the receiving rust side by resuming the panic.
|
|
|
|
|
|
|
|
In summary, here is a list of `rlua` behaviors that should be considered a bug.
|
|
|
|
If you encounter them, a bug report would be very welcome:
|
|
|
|
|
|
|
|
* If your code panics / aborts with a message that contains the string "rlua
|
|
|
|
internal error", this is a bug.
|
|
|
|
* The above is true even for the internal panic about running out of stack
|
|
|
|
space! There are a few ways to generate normal script errors by running out
|
|
|
|
of stack, but if you encounter a *panic* based on running out of stack, this
|
|
|
|
is a bug.
|
|
|
|
* When the internal version of Lua is built using the `gcc` crate, and
|
|
|
|
`cfg!(debug_assertions)` is true, Lua is built with the `LUA_USE_APICHECK`
|
|
|
|
define set. Any abort caused by this internal Lua API checking is
|
|
|
|
*absolutely* a bug, particularly because without `LUA_USE_APICHECK` it would
|
|
|
|
generally be unsafe.
|
2018-02-10 17:59:20 -05:00
|
|
|
* Lua C API errors are handled by lonjmp. *ALL* instances where the Lua C API
|
2018-02-10 17:50:04 -05:00
|
|
|
would longjmp should be protected from Rust, except in a few cases of
|
|
|
|
internal callbacks where there are only Copy types on the stack. If you
|
|
|
|
detect that `rlua` is triggering a longjmp over rust stack frames (other
|
|
|
|
than the internal ones), this is a bug! (NOTE: I believe it is still an
|
|
|
|
open question whether technically Rust allows longjmp over rust stack frames
|
|
|
|
*at all*, even if there are only Copy types on the stack. Currently `rlua`
|
|
|
|
uses this to avoid having to write a lot of messy C shims. It *currently*
|
|
|
|
works fine, and it is difficult to imagine how it would ever NOT work, but
|
|
|
|
what is and isn't UB in unsafe rust is not precisely specified.)
|