mirror of
https://github.com/mlua-rs/mlua
synced 2026-06-08 16:05:43 +00:00
Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e7fa8d75bb | |||
| c10718ed2f | |||
| ec2ce3620f | |||
| 71757003c7 | |||
| 6bb7f09927 | |||
| e67ae7f0de | |||
| 8c1535c27b | |||
| fd245daa6f | |||
| 7fb7e8685f | |||
| 93617eef4e | |||
| 171cdf1758 | |||
| 3f8f016daa | |||
| 86d0c9bddb | |||
| 86d63ef27b | |||
| e33bcf7938 | |||
| c80a97b526 | |||
| 3c40cfe199 | |||
| e9efb73125 | |||
| 386c6d8ed8 | |||
| 8f086bf837 | |||
| ad167612dc | |||
| 3366f47d40 | |||
| 0b5ef91f44 | |||
| a162b0ceca | |||
| 8e6d652a21 | |||
| 1be9e6ce2d | |||
| b1f99aa852 | |||
| 4c5465229e | |||
| 9b24bb2319 | |||
| e1701b6b56 | |||
| 77d7d5d6bd | |||
| ee9232eda1 | |||
| da526595bb | |||
| 39a7d3b862 |
+14
-30
@@ -9,7 +9,7 @@ jobs:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
rust: [stable]
|
||||
lua: [lua54, lua53, lua52, lua51, luajit, luau, luau-jit, luau-vector4]
|
||||
lua: [lua55, lua54, lua53, lua52, lua51, luajit, luau, luau-jit, luau-vector4]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
target: x86_64-unknown-linux-gnu
|
||||
@@ -31,35 +31,19 @@ jobs:
|
||||
cargo build --features "${{ matrix.lua }},vendored,async,serde,macros,anyhow,userdata-wrappers,send"
|
||||
shell: bash
|
||||
- name: Build ${{ matrix.lua }} pkg-config
|
||||
if: ${{ matrix.os == 'ubuntu-latest' }}
|
||||
if: ${{ matrix.os == 'ubuntu-latest' && matrix.lua != 'lua55' }}
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends liblua5.4-dev liblua5.3-dev liblua5.2-dev liblua5.1-0-dev libluajit-5.1-dev
|
||||
cargo build --features "${{ matrix.lua }}"
|
||||
|
||||
build_aarch64_cross_macos:
|
||||
name: Cross-compile to aarch64-apple-darwin
|
||||
runs-on: macos-latest
|
||||
needs: build
|
||||
strategy:
|
||||
matrix:
|
||||
lua: [lua54, lua53, lua52, lua51, luajit]
|
||||
steps:
|
||||
- uses: actions/checkout@main
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
toolchain: stable
|
||||
target: aarch64-apple-darwin
|
||||
- name: Cross-compile
|
||||
run: cargo build --target aarch64-apple-darwin --features "${{ matrix.lua }},vendored,async,send,serde,macros,anyhow,userdata-wrappers"
|
||||
|
||||
build_aarch64_cross_ubuntu:
|
||||
name: Cross-compile to aarch64-unknown-linux-gnu
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
strategy:
|
||||
matrix:
|
||||
lua: [lua54, lua53, lua52, lua51, luajit]
|
||||
lua: [lua55, lua54, lua53, lua52, lua51, luajit]
|
||||
steps:
|
||||
- uses: actions/checkout@main
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
@@ -81,7 +65,7 @@ jobs:
|
||||
needs: build
|
||||
strategy:
|
||||
matrix:
|
||||
lua: [lua54, lua53, lua52, lua51]
|
||||
lua: [lua55, lua54, lua53, lua52, lua51]
|
||||
steps:
|
||||
- uses: actions/checkout@main
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
@@ -105,7 +89,7 @@ jobs:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
rust: [stable, nightly]
|
||||
lua: [lua54, lua53, lua52, lua51, luajit, luajit52, luau, luau-jit, luau-vector4]
|
||||
lua: [lua55, lua54, lua53, lua52, lua51, luajit, luajit52, luau, luau-jit, luau-vector4]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
target: x86_64-unknown-linux-gnu
|
||||
@@ -126,8 +110,8 @@ jobs:
|
||||
cargo test --features "${{ matrix.lua }},vendored,async,serde,macros,anyhow,userdata-wrappers"
|
||||
cargo test --features "${{ matrix.lua }},vendored,async,serde,macros,anyhow,userdata-wrappers,send"
|
||||
shell: bash
|
||||
- name: Run compile tests (macos lua54)
|
||||
if: ${{ matrix.os == 'macos-latest' && matrix.lua == 'lua54' }}
|
||||
- name: Run compile tests (macos lua55)
|
||||
if: ${{ matrix.os == 'macos-latest' && matrix.lua == 'lua55' }}
|
||||
run: |
|
||||
TRYBUILD=overwrite cargo test --features "${{ matrix.lua }},vendored" --tests -- --ignored
|
||||
TRYBUILD=overwrite cargo test --features "${{ matrix.lua }},vendored,async,send,serde,macros" --tests -- --ignored
|
||||
@@ -141,7 +125,7 @@ jobs:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
rust: [nightly]
|
||||
lua: [lua54, lua53, lua52, lua51, luajit, luau, luau-jit, luau-vector4]
|
||||
lua: [lua55, lua54, lua53, lua52, lua51, luajit, luau, luau-jit, luau-vector4]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
target: x86_64-unknown-linux-gnu
|
||||
@@ -168,7 +152,7 @@ jobs:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
rust: [nightly]
|
||||
lua: [lua54, lua53, lua52, lua51, luajit, luau, luau-jit, luau-vector4]
|
||||
lua: [lua55, lua54, lua53, lua52, lua51, luajit, luau, luau-jit, luau-vector4]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
target: x86_64-unknown-linux-gnu
|
||||
@@ -194,7 +178,7 @@ jobs:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
rust: [stable]
|
||||
lua: [lua54, lua53, lua52, lua51, luajit]
|
||||
lua: [lua55, lua54, lua53, lua52, lua51, luajit]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
target: x86_64-unknown-linux-gnu
|
||||
@@ -240,7 +224,7 @@ jobs:
|
||||
needs: build
|
||||
strategy:
|
||||
matrix:
|
||||
lua: [lua54, lua53, lua52, lua51, luau]
|
||||
lua: [lua55, lua54, lua53, lua52, lua51, luau]
|
||||
steps:
|
||||
- uses: actions/checkout@main
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
@@ -262,7 +246,7 @@ jobs:
|
||||
needs: build
|
||||
strategy:
|
||||
matrix:
|
||||
lua: [lua54, lua53, lua52, lua51]
|
||||
lua: [lua55, lua54, lua53, lua52, lua51]
|
||||
steps:
|
||||
- uses: actions/checkout@main
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
@@ -273,7 +257,7 @@ jobs:
|
||||
working-directory: ${{ runner.tool_cache }}
|
||||
run: |
|
||||
wasi_sdk=29
|
||||
wasmtime=v39.0.0
|
||||
wasmtime=v40.0.1
|
||||
|
||||
curl -LO https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-$wasi_sdk/wasi-sdk-$wasi_sdk.0-x86_64-linux.tar.gz
|
||||
tar xf wasi-sdk-$wasi_sdk.0-x86_64-linux.tar.gz
|
||||
@@ -306,7 +290,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
lua: [lua54, lua53, lua52, lua51, luajit, luau, luau-jit, luau-vector4]
|
||||
lua: [lua55, lua54, lua53, lua52, lua51, luajit, luau, luau-jit, luau-vector4]
|
||||
steps:
|
||||
- uses: actions/checkout@main
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
name: Typos Check
|
||||
name: Spelling Check
|
||||
on:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
CLICOLOR: 1
|
||||
|
||||
jobs:
|
||||
run:
|
||||
spelling:
|
||||
name: Spell Check with Typos
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Actions Repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
uses: actions/checkout@main
|
||||
- name: Check spelling
|
||||
uses: crate-ci/typos@master
|
||||
uses: crate-ci/typos@v1.42.1
|
||||
with:
|
||||
config: ./typos.toml
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
## v0.11.6 (Jan 27, 2026)
|
||||
|
||||
- Added Lua 5.5 support (`lua55` feature flag)
|
||||
- Luau updated to 0.705+
|
||||
- Added `AnyUserData::is_proxy` method to check if userdata is a proxy
|
||||
- Added `num_params`, `num_upvalues`, `is_vararg` to `FunctionInfo`
|
||||
|
||||
## v0.11.5 (Nov 22, 2025)
|
||||
|
||||
- Luau updated to 0.701
|
||||
|
||||
+6
-5
@@ -1,8 +1,8 @@
|
||||
[package]
|
||||
name = "mlua"
|
||||
version = "0.11.5" # remember to update mlua_derive
|
||||
version = "0.11.6" # remember to update mlua_derive
|
||||
authors = ["Aleksandr Orlenko <zxteam@pm.me>", "kyren <catherine@kyju.org>"]
|
||||
rust-version = "1.80.0"
|
||||
rust-version = "1.85.0"
|
||||
edition = "2021"
|
||||
repository = "https://github.com/mlua-rs/mlua"
|
||||
documentation = "https://docs.rs/mlua"
|
||||
@@ -11,12 +11,12 @@ keywords = ["lua", "luajit", "luau", "async", "scripting"]
|
||||
categories = ["api-bindings", "asynchronous"]
|
||||
license = "MIT"
|
||||
description = """
|
||||
High level bindings to Lua 5.4/5.3/5.2/5.1 (including LuaJIT) and Luau
|
||||
High level bindings to Lua 5.5/5.4/5.3/5.2/5.1 (including LuaJIT) and Luau
|
||||
with async/await features and support of writing native Lua modules in Rust.
|
||||
"""
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
features = ["lua54", "vendored", "async", "send", "serde", "macros"]
|
||||
features = ["lua55", "vendored", "async", "send", "serde", "macros"]
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[workspace]
|
||||
@@ -26,6 +26,7 @@ members = [
|
||||
]
|
||||
|
||||
[features]
|
||||
lua55 = ["ffi/lua55"]
|
||||
lua54 = ["ffi/lua54"]
|
||||
lua53 = ["ffi/lua53"]
|
||||
lua52 = ["ffi/lua52"]
|
||||
@@ -63,7 +64,7 @@ anyhow = { version = "1.0", optional = true }
|
||||
rustversion = "1.0"
|
||||
libc = "0.2"
|
||||
|
||||
ffi = { package = "mlua-sys", version = "0.9.0", path = "mlua-sys" }
|
||||
ffi = { package = "mlua-sys", version = "0.10.0", path = "mlua-sys" }
|
||||
|
||||
[dev-dependencies]
|
||||
trybuild = "1.0"
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
`mlua` is a set of bindings to the [Lua](https://www.lua.org) programming language for Rust with a goal of providing a
|
||||
_safe_ (as much as possible), high level, easy to use, practical and flexible API.
|
||||
|
||||
Started as an `rlua` fork, `mlua` supports Lua 5.4, 5.3, 5.2, 5.1 (including LuaJIT) and [Luau] and allows writing native Lua modules in Rust as well as using Lua in a standalone mode.
|
||||
Started as an `rlua` fork, `mlua` supports Lua 5.5, 5.4, 5.3, 5.2, 5.1 (including LuaJIT) and [Luau] and allows writing native Lua modules in Rust as well as using Lua in a standalone mode.
|
||||
|
||||
`mlua` is tested on Windows/macOS/Linux including module mode in [GitHub Actions] on `x86_64` platforms and cross-compilation to `aarch64` (other targets are also supported).
|
||||
|
||||
@@ -36,6 +36,7 @@ WebAssembly (WASM) is supported through the `wasm32-unknown-emscripten` target f
|
||||
`mlua` uses feature flags to reduce the number of dependencies and compiled code, and allow choosing only the required set of features.
|
||||
Below is a list of the available feature flags. By default `mlua` does not enable any features.
|
||||
|
||||
* `lua55`: enable Lua [5.5] support
|
||||
* `lua54`: enable Lua [5.4] support
|
||||
* `lua53`: enable Lua [5.3] support
|
||||
* `lua52`: enable Lua [5.2] support
|
||||
@@ -55,6 +56,7 @@ Below is a list of the available feature flags. By default `mlua` does not enabl
|
||||
* `anyhow`: enable `anyhow::Error` conversion into Lua
|
||||
* `userdata-wrappers`: opt into `impl UserData` for `Rc<T>`/`Arc<T>`/`Rc<RefCell<T>>`/`Arc<Mutex<T>>` where `T: UserData`
|
||||
|
||||
[5.5]: https://www.lua.org/manual/5.5/manual.html
|
||||
[5.4]: https://www.lua.org/manual/5.4/manual.html
|
||||
[5.3]: https://www.lua.org/manual/5.3/manual.html
|
||||
[5.2]: https://www.lua.org/manual/5.2/manual.html
|
||||
|
||||
@@ -336,7 +336,7 @@ In previous mlua versions, building a Lua module for Windows requires having Lua
|
||||
In contrast, on Linux and macOS, modules can be built without any external dependencies using the `-undefined=dynamic_lookup` linker flag.
|
||||
|
||||
With Rust 1.71+ it's now possible to lift this restriction for Windows as well. You can build modules normally and they will be linked with
|
||||
`lua54.dll`/`lua53.dll`/`lua52.dll`/`lua51.dll` depending on the enabled Lua version.
|
||||
`lua5x.dll` depending on the enabled Lua version.
|
||||
|
||||
You still need to have the dll although, linked to application where the module will be loaded.
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ crate-type = ["cdylib"]
|
||||
[workspace]
|
||||
|
||||
[features]
|
||||
lua55 = ["mlua/lua55"]
|
||||
lua54 = ["mlua/lua54"]
|
||||
lua53 = ["mlua/lua53"]
|
||||
lua52 = ["mlua/lua52"]
|
||||
|
||||
+9
-7
@@ -1,9 +1,9 @@
|
||||
[package]
|
||||
name = "mlua-sys"
|
||||
version = "0.9.0"
|
||||
version = "0.10.0"
|
||||
authors = ["Aleksandr Orlenko <zxteam@pm.me>"]
|
||||
rust-version = "1.71"
|
||||
edition = "2021"
|
||||
rust-version = "1.85"
|
||||
edition = "2024"
|
||||
repository = "https://github.com/mlua-rs/mlua"
|
||||
documentation = "https://docs.rs/mlua-sys"
|
||||
readme = "README.md"
|
||||
@@ -12,14 +12,15 @@ license = "MIT"
|
||||
links = "lua"
|
||||
build = "build/main.rs"
|
||||
description = """
|
||||
Low level (FFI) bindings to Lua 5.4/5.3/5.2/5.1 (including LuaJIT) and Luau
|
||||
Low level (FFI) bindings to Lua 5.5/5.4/5.3/5.2/5.1 (including LuaJIT) and Luau
|
||||
"""
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
features = ["lua54", "vendored"]
|
||||
features = ["lua55", "vendored"]
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[features]
|
||||
lua55 = []
|
||||
lua54 = []
|
||||
lua53 = []
|
||||
lua52 = []
|
||||
@@ -34,14 +35,15 @@ external = []
|
||||
module = []
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.0"
|
||||
cfg-if = "1.0"
|
||||
pkg-config = "0.3.17"
|
||||
lua-src = { version = ">= 548.1.0, < 548.2.0", optional = true }
|
||||
lua-src = { version = ">= 550.0.0, < 550.1.0", optional = true }
|
||||
luajit-src = { version = ">= 210.6.0, < 210.7.0", optional = true }
|
||||
luau0-src = { version = "0.17.0", optional = true }
|
||||
luau0-src = { version = "0.18.0", optional = true }
|
||||
|
||||
[lints.rust]
|
||||
unexpected_cfgs = { level = "allow", check-cfg = ['cfg(raw_dylib)'] }
|
||||
|
||||
+2
-1
@@ -1,8 +1,9 @@
|
||||
# mlua-sys
|
||||
|
||||
Low level (FFI) bindings to Lua 5.4/5.3/5.2/5.1 (including LuaJIT) and [Luau].
|
||||
Low level (FFI) bindings to Lua 5.5/5.4/5.3/5.2/5.1 (including [LuaJIT]) and [Luau].
|
||||
|
||||
Intended to be consumed by the [mlua] crate.
|
||||
|
||||
[LuaJIT]: https://github.com/LuaJIT/LuaJIT
|
||||
[Luau]: https://github.com/luau-lang/luau
|
||||
[mlua]: https://crates.io/crates/mlua
|
||||
|
||||
@@ -31,18 +31,16 @@ pub fn probe_lua() {
|
||||
|
||||
// Find using `pkg-config`
|
||||
|
||||
#[cfg(feature = "lua55")]
|
||||
let (incl_bound, excl_bound, alt_probe, ver) = ("5.5", "5.6", ["lua5.5", "lua-5.5", "lua55"], "5.5");
|
||||
#[cfg(feature = "lua54")]
|
||||
let (incl_bound, excl_bound, alt_probe, ver) =
|
||||
("5.4", "5.5", ["lua5.4", "lua-5.4", "lua54"], "5.4");
|
||||
let (incl_bound, excl_bound, alt_probe, ver) = ("5.4", "5.5", ["lua5.4", "lua-5.4", "lua54"], "5.4");
|
||||
#[cfg(feature = "lua53")]
|
||||
let (incl_bound, excl_bound, alt_probe, ver) =
|
||||
("5.3", "5.4", ["lua5.3", "lua-5.3", "lua53"], "5.3");
|
||||
let (incl_bound, excl_bound, alt_probe, ver) = ("5.3", "5.4", ["lua5.3", "lua-5.3", "lua53"], "5.3");
|
||||
#[cfg(feature = "lua52")]
|
||||
let (incl_bound, excl_bound, alt_probe, ver) =
|
||||
("5.2", "5.3", ["lua5.2", "lua-5.2", "lua52"], "5.2");
|
||||
let (incl_bound, excl_bound, alt_probe, ver) = ("5.2", "5.3", ["lua5.2", "lua-5.2", "lua52"], "5.2");
|
||||
#[cfg(feature = "lua51")]
|
||||
let (incl_bound, excl_bound, alt_probe, ver) =
|
||||
("5.1", "5.2", ["lua5.1", "lua-5.1", "lua51"], "5.1");
|
||||
let (incl_bound, excl_bound, alt_probe, ver) = ("5.1", "5.2", ["lua5.1", "lua-5.1", "lua51"], "5.1");
|
||||
#[cfg(feature = "luajit")]
|
||||
let (incl_bound, excl_bound, alt_probe, ver) = ("2.0.4", "2.2", [], "JIT");
|
||||
|
||||
@@ -54,9 +52,7 @@ pub fn probe_lua() {
|
||||
|
||||
if lua.is_err() {
|
||||
for pkg in alt_probe {
|
||||
lua = pkg_config::Config::new()
|
||||
.cargo_metadata(true)
|
||||
.probe(pkg);
|
||||
lua = pkg_config::Config::new().cargo_metadata(true).probe(pkg);
|
||||
|
||||
if lua.is_ok() {
|
||||
break;
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
pub fn probe_lua() {
|
||||
#[cfg(feature = "lua55")]
|
||||
let artifacts = lua_src::Build::new().build(lua_src::Lua55);
|
||||
|
||||
#[cfg(feature = "lua54")]
|
||||
let artifacts = lua_src::Build::new().build(lua_src::Lua54);
|
||||
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(all(feature = "lua54", not(any(feature = "lua53", feature = "lua52", feature = "lua51", feature = "luajit", feature = "luau"))))] {
|
||||
if #[cfg(all(feature = "lua55", not(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "lua51", feature = "luajit", feature = "luau"))))] {
|
||||
include!("main_inner.rs");
|
||||
} else if #[cfg(all(feature = "lua53", not(any(feature = "lua54", feature = "lua52", feature = "lua51", feature = "luajit", feature = "luau"))))] {
|
||||
} else if #[cfg(all(feature = "lua54", not(any(feature = "lua55", feature = "lua53", feature = "lua52", feature = "lua51", feature = "luajit", feature = "luau"))))] {
|
||||
include!("main_inner.rs");
|
||||
} else if #[cfg(all(feature = "lua52", not(any(feature = "lua54", feature = "lua53", feature = "lua51", feature = "luajit", feature = "luau"))))] {
|
||||
} else if #[cfg(all(feature = "lua53", not(any(feature = "lua55", feature = "lua54", feature = "lua52", feature = "lua51", feature = "luajit", feature = "luau"))))] {
|
||||
include!("main_inner.rs");
|
||||
} else if #[cfg(all(feature = "lua51", not(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luajit", feature = "luau"))))] {
|
||||
} else if #[cfg(all(feature = "lua52", not(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua51", feature = "luajit", feature = "luau"))))] {
|
||||
include!("main_inner.rs");
|
||||
} else if #[cfg(all(feature = "luajit", not(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "lua51", feature = "luau"))))] {
|
||||
} else if #[cfg(all(feature = "lua51", not(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52", feature = "luajit", feature = "luau"))))] {
|
||||
include!("main_inner.rs");
|
||||
} else if #[cfg(all(feature = "luau", not(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "lua51", feature = "luajit"))))] {
|
||||
} else if #[cfg(all(feature = "luajit", not(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52", feature = "lua51", feature = "luau"))))] {
|
||||
include!("main_inner.rs");
|
||||
} else if #[cfg(all(feature = "luau", not(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52", feature = "lua51", feature = "luajit"))))] {
|
||||
include!("main_inner.rs");
|
||||
} else {
|
||||
fn main() {
|
||||
compile_error!("You can enable only one of the features: lua54, lua53, lua52, lua51, luajit, luajit52, luau");
|
||||
compile_error!("You can enable only one of the features: lua55, lua54, lua53, lua52, lua51, luajit, luajit52, luau");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+31
-22
@@ -1,4 +1,4 @@
|
||||
//! Low level bindings to Lua 5.4/5.3/5.2/5.1 (including LuaJIT) and Luau.
|
||||
//! Low level bindings to Lua 5.5/5.4/5.3/5.2/5.1 (including LuaJIT) and Luau.
|
||||
|
||||
#![allow(non_camel_case_types, non_snake_case)]
|
||||
#![allow(clippy::missing_safety_doc)]
|
||||
@@ -8,6 +8,9 @@
|
||||
|
||||
use std::os::raw::c_int;
|
||||
|
||||
#[cfg(any(feature = "lua55", doc))]
|
||||
pub use lua55::*;
|
||||
|
||||
#[cfg(any(feature = "lua54", doc))]
|
||||
pub use lua54::*;
|
||||
|
||||
@@ -23,7 +26,7 @@ pub use lua51::*;
|
||||
#[cfg(any(feature = "luau", doc))]
|
||||
pub use luau::*;
|
||||
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
#[doc(hidden)]
|
||||
pub const LUA_MAX_UPVALUES: c_int = 255;
|
||||
|
||||
@@ -40,14 +43,22 @@ pub const LUA_MAX_UPVALUES: c_int = 200;
|
||||
#[doc(hidden)]
|
||||
pub const LUA_TRACEBACK_STACK: c_int = 11;
|
||||
|
||||
// Copied from https://github.com/rust-lang/rust/blob/master/library/std/src/sys/pal/common/alloc.rs
|
||||
// The minimum alignment guaranteed by the architecture. This value is used to
|
||||
// add fast paths for low alignment values.
|
||||
#[cfg(any(
|
||||
// The minimum alignment guaranteed by the architecture.
|
||||
// Copied from https://github.com/rust-lang/rust/blob/main/library/std/src/sys/alloc/mod.rs
|
||||
#[doc(hidden)]
|
||||
#[rustfmt::skip]
|
||||
pub const SYS_MIN_ALIGN: usize = if cfg!(any(
|
||||
all(target_arch = "riscv32", any(target_os = "espidf", target_os = "zkvm")),
|
||||
all(target_arch = "xtensa", target_os = "espidf"),
|
||||
)) {
|
||||
// The allocator on the esp-idf and zkvm platforms guarantees 4 byte alignment.
|
||||
4
|
||||
} else if cfg!(any(
|
||||
target_arch = "x86",
|
||||
target_arch = "arm",
|
||||
target_arch = "m68k",
|
||||
target_arch = "csky",
|
||||
target_arch = "loongarch32",
|
||||
target_arch = "mips",
|
||||
target_arch = "mips32r6",
|
||||
target_arch = "powerpc",
|
||||
@@ -55,12 +66,11 @@ pub const LUA_TRACEBACK_STACK: c_int = 11;
|
||||
target_arch = "sparc",
|
||||
target_arch = "wasm32",
|
||||
target_arch = "hexagon",
|
||||
all(target_arch = "riscv32", not(any(target_os = "espidf", target_os = "zkvm"))),
|
||||
all(target_arch = "xtensa", not(target_os = "espidf")),
|
||||
))]
|
||||
#[doc(hidden)]
|
||||
pub const SYS_MIN_ALIGN: usize = 8;
|
||||
#[cfg(any(
|
||||
target_arch = "riscv32",
|
||||
target_arch = "xtensa",
|
||||
)) {
|
||||
8
|
||||
} else if cfg!(any(
|
||||
target_arch = "x86_64",
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm64ec",
|
||||
@@ -71,20 +81,19 @@ pub const SYS_MIN_ALIGN: usize = 8;
|
||||
target_arch = "sparc64",
|
||||
target_arch = "riscv64",
|
||||
target_arch = "wasm64",
|
||||
))]
|
||||
#[doc(hidden)]
|
||||
pub const SYS_MIN_ALIGN: usize = 16;
|
||||
// The allocator on the esp-idf and zkvm platforms guarantee 4 byte alignment.
|
||||
#[cfg(any(
|
||||
all(target_arch = "riscv32", any(target_os = "espidf", target_os = "zkvm")),
|
||||
all(target_arch = "xtensa", target_os = "espidf"),
|
||||
))]
|
||||
#[doc(hidden)]
|
||||
pub const SYS_MIN_ALIGN: usize = 4;
|
||||
)) {
|
||||
16
|
||||
} else {
|
||||
panic!("no value for SYS_MIN_ALIGN")
|
||||
};
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
||||
#[cfg(any(feature = "lua55", doc))]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "lua55")))]
|
||||
pub mod lua55;
|
||||
|
||||
#[cfg(any(feature = "lua54", doc))]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "lua54")))]
|
||||
pub mod lua54;
|
||||
|
||||
@@ -55,11 +55,7 @@ unsafe fn compat53_checkmode(
|
||||
while *st != 0 && *st != c {
|
||||
st = st.offset(1);
|
||||
}
|
||||
if *st == c {
|
||||
st
|
||||
} else {
|
||||
ptr::null()
|
||||
}
|
||||
if *st == c { st } else { ptr::null() }
|
||||
}
|
||||
|
||||
if !mode.is_null() && strchr(mode, *modename).is_null() {
|
||||
|
||||
@@ -107,8 +107,6 @@ pub unsafe fn luaL_optstring(L: *mut lua_State, n: c_int, d: *const c_char) -> *
|
||||
luaL_optlstring(L, n, d, ptr::null_mut())
|
||||
}
|
||||
|
||||
// Deprecated from 5.3: luaL_checkint, luaL_optint, luaL_checklong, luaL_optlong
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_typename(L: *mut lua_State, i: c_int) -> *const c_char {
|
||||
lua::lua_typename(L, lua::lua_type(L, i))
|
||||
@@ -138,8 +136,62 @@ pub unsafe fn luaL_getmetatable(L: *mut lua_State, n: *const c_char) {
|
||||
lua::lua_getfield_(L, lua::LUA_REGISTRYINDEX, n);
|
||||
}
|
||||
|
||||
// TODO: luaL_opt
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_opt<T>(
|
||||
L: *mut lua_State,
|
||||
f: unsafe extern "C-unwind" fn(*mut lua_State, c_int) -> T,
|
||||
n: c_int,
|
||||
d: T,
|
||||
) -> T {
|
||||
if lua::lua_isnoneornil(L, n) != 0 {
|
||||
d
|
||||
} else {
|
||||
f(L, n)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// TODO: Generic Buffer Manipulation
|
||||
// Generic Buffer Manipulation
|
||||
//
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
const BUFSIZ: usize = 1024; // WASI libc's BUFSIZ is 1024
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
const BUFSIZ: usize = libc::BUFSIZ as usize;
|
||||
|
||||
// The buffer size used by the lauxlib buffer system.
|
||||
// The "16384" workaround is taken from the LuaJIT source code.
|
||||
pub const LUAL_BUFFERSIZE: usize = if BUFSIZ > 16384 { 8192 } else { BUFSIZ };
|
||||
|
||||
#[repr(C)]
|
||||
pub struct luaL_Buffer {
|
||||
pub p: *mut c_char, // current position in buffer
|
||||
pub lvl: c_int, // number of strings in the stack
|
||||
pub L: *mut lua_State,
|
||||
pub buffer: [c_char; LUAL_BUFFERSIZE],
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua51", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_buffinit(L: *mut lua_State, B: *mut luaL_Buffer);
|
||||
pub fn luaL_prepbuffer(B: *mut luaL_Buffer) -> *mut c_char;
|
||||
pub fn luaL_addlstring(B: *mut luaL_Buffer, s: *const c_char, l: usize);
|
||||
pub fn luaL_addstring(B: *mut luaL_Buffer, s: *const c_char);
|
||||
pub fn luaL_addvalue(B: *mut luaL_Buffer);
|
||||
pub fn luaL_pushresult(B: *mut luaL_Buffer);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_addchar(B: *mut luaL_Buffer, c: c_char) {
|
||||
let buffer_end = (*B).buffer.as_mut_ptr().add(LUAL_BUFFERSIZE);
|
||||
if (*B).p >= buffer_end {
|
||||
luaL_prepbuffer(B);
|
||||
}
|
||||
*(*B).p = c;
|
||||
(*B).p = (*B).p.add(1);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_addsize(B: *mut luaL_Buffer, n: usize) {
|
||||
(*B).p = (*B).p.add(n);
|
||||
}
|
||||
|
||||
@@ -270,7 +270,10 @@ pub unsafe fn lua_pushcfunction(L: *mut lua_State, f: lua_CFunction) {
|
||||
lua_pushcclosure(L, f, 0)
|
||||
}
|
||||
|
||||
// TODO: lua_strlen
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_strlen(L: *mut lua_State, i: c_int) -> usize {
|
||||
lua_objlen(L, i)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isfunction(L: *mut lua_State, n: c_int) -> c_int {
|
||||
|
||||
@@ -125,7 +125,7 @@ pub unsafe fn lua_rawget(L: *mut lua_State, idx: c_int) -> c_int {
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_rawgeti(L: *mut lua_State, idx: c_int, n: lua_Integer) -> c_int {
|
||||
let n = n.try_into().expect("cannot convert index to lua_Integer");
|
||||
let n = n.try_into().expect("cannot convert index to c_int");
|
||||
lua_rawgeti_(L, idx, n);
|
||||
lua_type(L, -1)
|
||||
}
|
||||
@@ -153,7 +153,7 @@ pub unsafe fn lua_seti(L: *mut lua_State, mut idx: c_int, n: lua_Integer) {
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_rawseti(L: *mut lua_State, idx: c_int, n: lua_Integer) {
|
||||
let n = n.try_into().expect("cannot convert index from lua_Integer");
|
||||
let n = n.try_into().expect("cannot convert index to c_int");
|
||||
lua_rawseti_(L, idx, n)
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ unsafe extern "C-unwind" {
|
||||
pub fn luaL_argerror(L: *mut lua_State, arg: c_int, extramsg: *const c_char) -> c_int;
|
||||
pub fn luaL_checklstring(L: *mut lua_State, arg: c_int, l: *mut usize) -> *const c_char;
|
||||
pub fn luaL_optlstring(L: *mut lua_State, arg: c_int, def: *const c_char, l: *mut usize)
|
||||
-> *const c_char;
|
||||
-> *const c_char;
|
||||
pub fn luaL_checknumber(L: *mut lua_State, arg: c_int) -> lua_Number;
|
||||
pub fn luaL_optnumber(L: *mut lua_State, arg: c_int, def: lua_Number) -> lua_Number;
|
||||
pub fn luaL_checkinteger(L: *mut lua_State, arg: c_int) -> lua_Integer;
|
||||
@@ -166,13 +166,76 @@ pub unsafe fn luaL_getmetatable(L: *mut lua_State, n: *const c_char) {
|
||||
lua::lua_getfield_(L, lua::LUA_REGISTRYINDEX, n);
|
||||
}
|
||||
|
||||
// luaL_opt would be implemented here but it is undocumented, so it's omitted
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_loadbuffer(L: *mut lua_State, s: *const c_char, sz: usize, n: *const c_char) -> c_int {
|
||||
luaL_loadbufferx(L, s, sz, n, ptr::null())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_opt<T>(
|
||||
L: *mut lua_State,
|
||||
f: unsafe extern "C-unwind" fn(*mut lua_State, c_int) -> T,
|
||||
n: c_int,
|
||||
d: T,
|
||||
) -> T {
|
||||
if lua::lua_isnoneornil(L, n) != 0 {
|
||||
d
|
||||
} else {
|
||||
f(L, n)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// TODO: Generic Buffer Manipulation
|
||||
// Generic Buffer Manipulation
|
||||
//
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
const BUFSIZ: usize = 1024; // WASI libc's BUFSIZ is 1024
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
const BUFSIZ: usize = libc::BUFSIZ as usize;
|
||||
|
||||
// The buffer size used by the lauxlib buffer system.
|
||||
// The "16384" workaround is taken from the LuaJIT source code.
|
||||
pub const LUAL_BUFFERSIZE: usize = if BUFSIZ > 16384 { 8192 } else { BUFSIZ };
|
||||
|
||||
#[repr(C)]
|
||||
pub struct luaL_Buffer {
|
||||
pub b: *mut c_char, // buffer address
|
||||
pub size: usize, // buffer size
|
||||
pub n: usize, // number of characters in buffer
|
||||
pub L: *mut lua_State,
|
||||
pub initb: [c_char; LUAL_BUFFERSIZE], // initial buffer space
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua52", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_buffinit(L: *mut lua_State, B: *mut luaL_Buffer);
|
||||
pub fn luaL_prepbuffsize(B: *mut luaL_Buffer, sz: usize) -> *mut c_char;
|
||||
pub fn luaL_addlstring(B: *mut luaL_Buffer, s: *const c_char, l: usize);
|
||||
pub fn luaL_addstring(B: *mut luaL_Buffer, s: *const c_char);
|
||||
pub fn luaL_addvalue(B: *mut luaL_Buffer);
|
||||
pub fn luaL_pushresult(B: *mut luaL_Buffer);
|
||||
pub fn luaL_pushresultsize(B: *mut luaL_Buffer, sz: usize);
|
||||
pub fn luaL_buffinitsize(L: *mut lua_State, B: *mut luaL_Buffer, sz: usize) -> *mut c_char;
|
||||
}
|
||||
|
||||
// Macro implementations as inline functions
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_prepbuffer(B: *mut luaL_Buffer) -> *mut c_char {
|
||||
luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_addchar(B: *mut luaL_Buffer, c: c_char) {
|
||||
if (*B).n >= (*B).size {
|
||||
luaL_prepbuffsize(B, 1);
|
||||
}
|
||||
*(*B).b.add((*B).n) = c;
|
||||
(*B).n += 1;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_addsize(B: *mut luaL_Buffer, n: usize) {
|
||||
(*B).n += n;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! Contains definitions from `lauxlib.h`.
|
||||
|
||||
use std::os::raw::{c_char, c_int, c_void};
|
||||
use std::ptr;
|
||||
use std::{mem, ptr};
|
||||
|
||||
use super::lua::{self, lua_CFunction, lua_Integer, lua_Number, lua_State};
|
||||
|
||||
@@ -31,7 +31,7 @@ unsafe extern "C-unwind" {
|
||||
pub fn luaL_argerror(L: *mut lua_State, arg: c_int, extramsg: *const c_char) -> c_int;
|
||||
pub fn luaL_checklstring(L: *mut lua_State, arg: c_int, l: *mut usize) -> *const c_char;
|
||||
pub fn luaL_optlstring(L: *mut lua_State, arg: c_int, def: *const c_char, l: *mut usize)
|
||||
-> *const c_char;
|
||||
-> *const c_char;
|
||||
pub fn luaL_checknumber(L: *mut lua_State, arg: c_int) -> lua_Number;
|
||||
pub fn luaL_optnumber(L: *mut lua_State, arg: c_int, def: lua_Number) -> lua_Number;
|
||||
pub fn luaL_checkinteger(L: *mut lua_State, arg: c_int) -> lua_Integer;
|
||||
@@ -166,13 +166,72 @@ pub unsafe fn luaL_tolstring(L: *mut lua_State, idx: c_int, len: *mut usize) ->
|
||||
luaL_tolstring_(L, lua::lua_absindex(L, idx), len)
|
||||
}
|
||||
|
||||
// luaL_opt would be implemented here but it is undocumented, so it's omitted
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_loadbuffer(L: *mut lua_State, s: *const c_char, sz: usize, n: *const c_char) -> c_int {
|
||||
luaL_loadbufferx(L, s, sz, n, ptr::null())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_opt<T>(
|
||||
L: *mut lua_State,
|
||||
f: unsafe extern "C-unwind" fn(*mut lua_State, c_int) -> T,
|
||||
n: c_int,
|
||||
d: T,
|
||||
) -> T {
|
||||
if lua::lua_isnoneornil(L, n) != 0 {
|
||||
d
|
||||
} else {
|
||||
f(L, n)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// TODO: Generic Buffer Manipulation
|
||||
// Generic Buffer Manipulation
|
||||
//
|
||||
|
||||
// The buffer size used by the lauxlib buffer system.
|
||||
// In Lua 5.3: LUAL_BUFFERSIZE = (int)(0x80 * sizeof(void*) * sizeof(lua_Integer))
|
||||
#[rustfmt::skip]
|
||||
pub const LUAL_BUFFERSIZE: usize = 0x80 * mem::size_of::<*const ()>() * mem::size_of::<lua_Integer>();
|
||||
|
||||
#[repr(C)]
|
||||
pub struct luaL_Buffer {
|
||||
pub b: *mut c_char, // buffer address
|
||||
pub size: usize, // buffer size
|
||||
pub n: usize, // number of characters in buffer
|
||||
pub L: *mut lua_State,
|
||||
pub initb: [c_char; LUAL_BUFFERSIZE], // initial buffer space
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua53", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_buffinit(L: *mut lua_State, B: *mut luaL_Buffer);
|
||||
pub fn luaL_prepbuffsize(B: *mut luaL_Buffer, sz: usize) -> *mut c_char;
|
||||
pub fn luaL_addlstring(B: *mut luaL_Buffer, s: *const c_char, l: usize);
|
||||
pub fn luaL_addstring(B: *mut luaL_Buffer, s: *const c_char);
|
||||
pub fn luaL_addvalue(B: *mut luaL_Buffer);
|
||||
pub fn luaL_pushresult(B: *mut luaL_Buffer);
|
||||
pub fn luaL_pushresultsize(B: *mut luaL_Buffer, sz: usize);
|
||||
pub fn luaL_buffinitsize(L: *mut lua_State, B: *mut luaL_Buffer, sz: usize) -> *mut c_char;
|
||||
}
|
||||
|
||||
// Macro implementations as inline functions
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_prepbuffer(B: *mut luaL_Buffer) -> *mut c_char {
|
||||
luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_addchar(B: *mut luaL_Buffer, c: c_char) {
|
||||
if (*B).n >= (*B).size {
|
||||
luaL_prepbuffsize(B, 1);
|
||||
}
|
||||
*(*B).b.add((*B).n) = c;
|
||||
(*B).n += 1;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_addsize(B: *mut luaL_Buffer, n: usize) {
|
||||
(*B).n += n;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! Contains definitions from `lauxlib.h`.
|
||||
|
||||
use std::os::raw::{c_char, c_int, c_void};
|
||||
use std::ptr;
|
||||
use std::os::raw::{c_char, c_double, c_int, c_long, c_void};
|
||||
use std::{mem, ptr};
|
||||
|
||||
use super::lua::{self, lua_CFunction, lua_Integer, lua_Number, lua_State};
|
||||
|
||||
@@ -30,7 +30,7 @@ unsafe extern "C-unwind" {
|
||||
pub fn luaL_argerror(L: *mut lua_State, arg: c_int, extramsg: *const c_char) -> c_int;
|
||||
pub fn luaL_checklstring(L: *mut lua_State, arg: c_int, l: *mut usize) -> *const c_char;
|
||||
pub fn luaL_optlstring(L: *mut lua_State, arg: c_int, def: *const c_char, l: *mut usize)
|
||||
-> *const c_char;
|
||||
-> *const c_char;
|
||||
pub fn luaL_checknumber(L: *mut lua_State, arg: c_int) -> lua_Number;
|
||||
pub fn luaL_optnumber(L: *mut lua_State, arg: c_int, def: lua_Number) -> lua_Number;
|
||||
pub fn luaL_checkinteger(L: *mut lua_State, arg: c_int) -> lua_Integer;
|
||||
@@ -91,7 +91,7 @@ unsafe extern "C-unwind" {
|
||||
|
||||
pub fn luaL_len(L: *mut lua_State, idx: c_int) -> lua_Integer;
|
||||
|
||||
// TODO: luaL_addgsub
|
||||
pub fn luaL_addgsub(B: *mut luaL_Buffer, s: *const c_char, p: *const c_char, r: *const c_char);
|
||||
|
||||
pub fn luaL_gsub(
|
||||
L: *mut lua_State,
|
||||
@@ -162,8 +162,6 @@ pub unsafe fn luaL_getmetatable(L: *mut lua_State, n: *const c_char) {
|
||||
lua::lua_getfield(L, lua::LUA_REGISTRYINDEX, n);
|
||||
}
|
||||
|
||||
// luaL_opt would be implemented here but it is undocumented, so it's omitted
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_loadbuffer(L: *mut lua_State, s: *const c_char, sz: usize, n: *const c_char) -> c_int {
|
||||
luaL_loadbufferx(L, s, sz, n, ptr::null())
|
||||
@@ -188,6 +186,96 @@ pub unsafe fn luaL_loadbufferenv(
|
||||
status
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_opt<T>(
|
||||
L: *mut lua_State,
|
||||
f: unsafe extern "C-unwind" fn(*mut lua_State, c_int) -> T,
|
||||
n: c_int,
|
||||
d: T,
|
||||
) -> T {
|
||||
if lua::lua_isnoneornil(L, n) != 0 {
|
||||
d
|
||||
} else {
|
||||
f(L, n)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// TODO: Generic Buffer Manipulation
|
||||
// Generic Buffer Manipulation
|
||||
//
|
||||
|
||||
// The buffer size used by the lauxlib buffer system.
|
||||
// LUAL_BUFFERSIZE = (int)(16 * sizeof(void*) * sizeof(lua_Number))
|
||||
#[rustfmt::skip]
|
||||
pub const LUAL_BUFFERSIZE: usize = 16 * mem::size_of::<*const ()>() * mem::size_of::<lua_Number>();
|
||||
|
||||
// Union used for the initial buffer with maximum alignment.
|
||||
// This ensures proper alignment for the buffer data.
|
||||
#[repr(C)]
|
||||
pub union luaL_BufferInit {
|
||||
// Alignment matches LUAI_MAXALIGN
|
||||
pub _align_n: lua_Number,
|
||||
pub _align_u: c_double,
|
||||
pub _align_s: *mut c_void,
|
||||
pub _align_i: lua_Integer,
|
||||
pub _align_l: c_long,
|
||||
// Initial buffer space
|
||||
pub b: [c_char; LUAL_BUFFERSIZE],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct luaL_Buffer {
|
||||
pub b: *mut c_char, // buffer address
|
||||
pub size: usize, // buffer size
|
||||
pub n: usize, // number of characters in buffer
|
||||
pub L: *mut lua_State,
|
||||
pub init: luaL_BufferInit, // initial buffer (union with alignment)
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua54", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_buffinit(L: *mut lua_State, B: *mut luaL_Buffer);
|
||||
pub fn luaL_prepbuffsize(B: *mut luaL_Buffer, sz: usize) -> *mut c_char;
|
||||
pub fn luaL_addlstring(B: *mut luaL_Buffer, s: *const c_char, l: usize);
|
||||
pub fn luaL_addstring(B: *mut luaL_Buffer, s: *const c_char);
|
||||
pub fn luaL_addvalue(B: *mut luaL_Buffer);
|
||||
pub fn luaL_pushresult(B: *mut luaL_Buffer);
|
||||
pub fn luaL_pushresultsize(B: *mut luaL_Buffer, sz: usize);
|
||||
pub fn luaL_buffinitsize(L: *mut lua_State, B: *mut luaL_Buffer, sz: usize) -> *mut c_char;
|
||||
}
|
||||
|
||||
// Macro implementations as inline functions
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_prepbuffer(B: *mut luaL_Buffer) -> *mut c_char {
|
||||
luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_addchar(B: *mut luaL_Buffer, c: c_char) {
|
||||
if (*B).n >= (*B).size {
|
||||
luaL_prepbuffsize(B, 1);
|
||||
}
|
||||
*(*B).b.add((*B).n) = c;
|
||||
(*B).n += 1;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_addsize(B: *mut luaL_Buffer, n: usize) {
|
||||
(*B).n += n;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_buffsub(B: *mut luaL_Buffer, n: usize) {
|
||||
(*B).n -= n;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_bufflen(B: *mut luaL_Buffer) -> usize {
|
||||
(*B).n
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_buffaddr(B: *mut luaL_Buffer) -> *mut c_char {
|
||||
(*B).b
|
||||
}
|
||||
|
||||
@@ -0,0 +1,299 @@
|
||||
//! Contains definitions from `lauxlib.h`.
|
||||
|
||||
use std::os::raw::{c_char, c_double, c_int, c_long, c_uint, c_void};
|
||||
use std::{mem, ptr};
|
||||
|
||||
use super::lua::{self, lua_CFunction, lua_Integer, lua_Number, lua_State};
|
||||
|
||||
// Extra error code for 'luaL_loadfilex'
|
||||
pub const LUA_ERRFILE: c_int = lua::LUA_ERRERR + 1;
|
||||
|
||||
// Key, in the registry, for table of loaded modules
|
||||
pub const LUA_LOADED_TABLE: *const c_char = cstr!("_LOADED");
|
||||
|
||||
// Key, in the registry, for table of preloaded loaders
|
||||
pub const LUA_PRELOAD_TABLE: *const c_char = cstr!("_PRELOAD");
|
||||
|
||||
#[repr(C)]
|
||||
pub struct luaL_Reg {
|
||||
pub name: *const c_char,
|
||||
pub func: lua_CFunction,
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_checkversion_(L: *mut lua_State, ver: lua_Number, sz: usize);
|
||||
|
||||
pub fn luaL_getmetafield(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int;
|
||||
pub fn luaL_callmeta(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int;
|
||||
pub fn luaL_tolstring(L: *mut lua_State, idx: c_int, len: *mut usize) -> *const c_char;
|
||||
pub fn luaL_argerror(L: *mut lua_State, arg: c_int, extramsg: *const c_char) -> c_int;
|
||||
pub fn luaL_checklstring(L: *mut lua_State, arg: c_int, l: *mut usize) -> *const c_char;
|
||||
pub fn luaL_optlstring(L: *mut lua_State, arg: c_int, def: *const c_char, l: *mut usize)
|
||||
-> *const c_char;
|
||||
pub fn luaL_checknumber(L: *mut lua_State, arg: c_int) -> lua_Number;
|
||||
pub fn luaL_optnumber(L: *mut lua_State, arg: c_int, def: lua_Number) -> lua_Number;
|
||||
pub fn luaL_checkinteger(L: *mut lua_State, arg: c_int) -> lua_Integer;
|
||||
pub fn luaL_optinteger(L: *mut lua_State, arg: c_int, def: lua_Integer) -> lua_Integer;
|
||||
|
||||
pub fn luaL_checkstack(L: *mut lua_State, sz: c_int, msg: *const c_char);
|
||||
pub fn luaL_checktype(L: *mut lua_State, arg: c_int, t: c_int);
|
||||
pub fn luaL_checkany(L: *mut lua_State, arg: c_int);
|
||||
|
||||
pub fn luaL_newmetatable(L: *mut lua_State, tname: *const c_char) -> c_int;
|
||||
pub fn luaL_setmetatable(L: *mut lua_State, tname: *const c_char);
|
||||
pub fn luaL_testudata(L: *mut lua_State, ud: c_int, tname: *const c_char) -> *mut c_void;
|
||||
pub fn luaL_checkudata(L: *mut lua_State, ud: c_int, tname: *const c_char) -> *mut c_void;
|
||||
|
||||
pub fn luaL_where(L: *mut lua_State, lvl: c_int);
|
||||
pub fn luaL_error(L: *mut lua_State, fmt: *const c_char, ...) -> c_int;
|
||||
|
||||
pub fn luaL_checkoption(
|
||||
L: *mut lua_State,
|
||||
arg: c_int,
|
||||
def: *const c_char,
|
||||
lst: *const *const c_char,
|
||||
) -> c_int;
|
||||
|
||||
pub fn luaL_fileresult(L: *mut lua_State, stat: c_int, fname: *const c_char) -> c_int;
|
||||
pub fn luaL_execresult(L: *mut lua_State, stat: c_int) -> c_int;
|
||||
pub fn luaL_alloc(L: *mut lua_State, ptr: *mut c_void, osize: usize, nsize: usize) -> *mut c_void;
|
||||
}
|
||||
|
||||
// Pre-defined references
|
||||
pub const LUA_NOREF: c_int = -2;
|
||||
pub const LUA_REFNIL: c_int = -1;
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_ref(L: *mut lua_State, t: c_int) -> c_int;
|
||||
pub fn luaL_unref(L: *mut lua_State, t: c_int, r#ref: c_int);
|
||||
|
||||
pub fn luaL_loadfilex(L: *mut lua_State, filename: *const c_char, mode: *const c_char) -> c_int;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_loadfile(L: *mut lua_State, f: *const c_char) -> c_int {
|
||||
luaL_loadfilex(L, f, ptr::null())
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_loadbufferx(
|
||||
L: *mut lua_State,
|
||||
buff: *const c_char,
|
||||
sz: usize,
|
||||
name: *const c_char,
|
||||
mode: *const c_char,
|
||||
) -> c_int;
|
||||
pub fn luaL_loadstring(L: *mut lua_State, s: *const c_char) -> c_int;
|
||||
|
||||
pub fn luaL_newstate() -> *mut lua_State;
|
||||
|
||||
#[link_name = "luaL_makeseed"]
|
||||
pub fn luaL_makeseed_(L: *mut lua_State) -> c_uint;
|
||||
|
||||
pub fn luaL_len(L: *mut lua_State, idx: c_int) -> lua_Integer;
|
||||
|
||||
pub fn luaL_addgsub(B: *mut luaL_Buffer, s: *const c_char, p: *const c_char, r: *const c_char);
|
||||
|
||||
pub fn luaL_gsub(
|
||||
L: *mut lua_State,
|
||||
s: *const c_char,
|
||||
p: *const c_char,
|
||||
r: *const c_char,
|
||||
) -> *const c_char;
|
||||
|
||||
pub fn luaL_setfuncs(L: *mut lua_State, l: *const luaL_Reg, nup: c_int);
|
||||
|
||||
pub fn luaL_getsubtable(L: *mut lua_State, idx: c_int, fname: *const c_char) -> c_int;
|
||||
|
||||
pub fn luaL_traceback(L: *mut lua_State, L1: *mut lua_State, msg: *const c_char, level: c_int);
|
||||
|
||||
pub fn luaL_requiref(L: *mut lua_State, modname: *const c_char, openf: lua_CFunction, glb: c_int);
|
||||
}
|
||||
|
||||
//
|
||||
// Some useful macros (implemented as Rust functions)
|
||||
//
|
||||
|
||||
// TODO: luaL_newlibtable, luaL_newlib
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_argcheck(L: *mut lua_State, cond: c_int, arg: c_int, extramsg: *const c_char) {
|
||||
if cond == 0 {
|
||||
luaL_argerror(L, arg, extramsg);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_checkstring(L: *mut lua_State, n: c_int) -> *const c_char {
|
||||
luaL_checklstring(L, n, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_optstring(L: *mut lua_State, n: c_int, d: *const c_char) -> *const c_char {
|
||||
luaL_optlstring(L, n, d, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_typename(L: *mut lua_State, i: c_int) -> *const c_char {
|
||||
lua::lua_typename(L, lua::lua_type(L, i))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_dofile(L: *mut lua_State, filename: *const c_char) -> c_int {
|
||||
let status = luaL_loadfile(L, filename);
|
||||
if status == 0 {
|
||||
lua::lua_pcall(L, 0, lua::LUA_MULTRET, 0)
|
||||
} else {
|
||||
status
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_dostring(L: *mut lua_State, s: *const c_char) -> c_int {
|
||||
let status = luaL_loadstring(L, s);
|
||||
if status == 0 {
|
||||
lua::lua_pcall(L, 0, lua::LUA_MULTRET, 0)
|
||||
} else {
|
||||
status
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_getmetatable(L: *mut lua_State, n: *const c_char) {
|
||||
lua::lua_getfield(L, lua::LUA_REGISTRYINDEX, n);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_loadbuffer(L: *mut lua_State, s: *const c_char, sz: usize, n: *const c_char) -> c_int {
|
||||
luaL_loadbufferx(L, s, sz, n, ptr::null())
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_loadbufferenv(
|
||||
L: *mut lua_State,
|
||||
data: *const c_char,
|
||||
size: usize,
|
||||
name: *const c_char,
|
||||
mode: *const c_char,
|
||||
mut env: c_int,
|
||||
) -> c_int {
|
||||
if env != 0 {
|
||||
env = lua::lua_absindex(L, env);
|
||||
}
|
||||
let status = luaL_loadbufferx(L, data, size, name, mode);
|
||||
if status == lua::LUA_OK && env != 0 {
|
||||
lua::lua_pushvalue(L, env);
|
||||
lua::lua_setupvalue(L, -2, 1);
|
||||
}
|
||||
status
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_makeseed(L: *mut lua_State) -> c_uint {
|
||||
#[cfg(macos)]
|
||||
return libc::arc4random();
|
||||
#[cfg(linux)]
|
||||
{
|
||||
let mut seed = 0u32;
|
||||
let buf = &mut seed as *mut _ as *mut c_void;
|
||||
if libc::getrandom(buf, 4, libc::GRND_NONBLOCK) == 4 {
|
||||
return seed;
|
||||
}
|
||||
}
|
||||
luaL_makeseed_(L)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_opt<T>(
|
||||
L: *mut lua_State,
|
||||
f: unsafe extern "C-unwind" fn(*mut lua_State, c_int) -> T,
|
||||
n: c_int,
|
||||
d: T,
|
||||
) -> T {
|
||||
if lua::lua_isnoneornil(L, n) != 0 {
|
||||
d
|
||||
} else {
|
||||
f(L, n)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Generic Buffer Manipulation
|
||||
//
|
||||
|
||||
// The buffer size used by the lauxlib buffer system.
|
||||
// LUAL_BUFFERSIZE = (int)(16 * sizeof(void*) * sizeof(lua_Number))
|
||||
#[rustfmt::skip]
|
||||
pub const LUAL_BUFFERSIZE: usize = 16 * mem::size_of::<*const ()>() * mem::size_of::<lua_Number>();
|
||||
|
||||
// Union used for the initial buffer with maximum alignment.
|
||||
// This ensures proper alignment for the buffer data.
|
||||
#[repr(C)]
|
||||
pub union luaL_BufferInit {
|
||||
// Alignment matches LUAI_MAXALIGN
|
||||
pub _align_n: lua_Number,
|
||||
pub _align_u: c_double,
|
||||
pub _align_s: *mut c_void,
|
||||
pub _align_i: lua_Integer,
|
||||
pub _align_l: c_long,
|
||||
// Initial buffer space
|
||||
pub b: [c_char; LUAL_BUFFERSIZE],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct luaL_Buffer {
|
||||
pub b: *mut c_char, // buffer address
|
||||
pub size: usize, // buffer size
|
||||
pub n: usize, // number of characters in buffer
|
||||
pub L: *mut lua_State,
|
||||
pub init: luaL_BufferInit, // initial buffer (union with alignment)
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_buffinit(L: *mut lua_State, B: *mut luaL_Buffer);
|
||||
pub fn luaL_prepbuffsize(B: *mut luaL_Buffer, sz: usize) -> *mut c_char;
|
||||
pub fn luaL_addlstring(B: *mut luaL_Buffer, s: *const c_char, l: usize);
|
||||
pub fn luaL_addstring(B: *mut luaL_Buffer, s: *const c_char);
|
||||
pub fn luaL_addvalue(B: *mut luaL_Buffer);
|
||||
pub fn luaL_pushresult(B: *mut luaL_Buffer);
|
||||
pub fn luaL_pushresultsize(B: *mut luaL_Buffer, sz: usize);
|
||||
pub fn luaL_buffinitsize(L: *mut lua_State, B: *mut luaL_Buffer, sz: usize) -> *mut c_char;
|
||||
}
|
||||
|
||||
// Macro implementations as inline functions
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_prepbuffer(B: *mut luaL_Buffer) -> *mut c_char {
|
||||
luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_addchar(B: *mut luaL_Buffer, c: c_char) {
|
||||
if (*B).n >= (*B).size {
|
||||
luaL_prepbuffsize(B, 1);
|
||||
}
|
||||
*(*B).b.add((*B).n) = c;
|
||||
(*B).n += 1;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_addsize(B: *mut luaL_Buffer, n: usize) {
|
||||
(*B).n += n;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_buffsub(B: *mut luaL_Buffer, n: usize) {
|
||||
(*B).n -= n;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_bufflen(B: *mut luaL_Buffer) -> usize {
|
||||
(*B).n
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_buffaddr(B: *mut luaL_Buffer) -> *mut c_char {
|
||||
(*B).b
|
||||
}
|
||||
@@ -0,0 +1,578 @@
|
||||
//! Contains definitions from `lua.h`.
|
||||
|
||||
use std::ffi::CStr;
|
||||
use std::marker::{PhantomData, PhantomPinned};
|
||||
use std::os::raw::{c_char, c_double, c_int, c_uchar, c_uint, c_void};
|
||||
use std::{mem, ptr};
|
||||
|
||||
// Mark for precompiled code (`<esc>Lua`)
|
||||
pub const LUA_SIGNATURE: &[u8] = b"\x1bLua";
|
||||
|
||||
// Option for multiple returns in 'lua_pcall' and 'lua_call'
|
||||
pub const LUA_MULTRET: c_int = -1;
|
||||
|
||||
// Size of the Lua stack
|
||||
#[doc(hidden)]
|
||||
pub const LUAI_MAXSTACK: c_int = c_int::MAX;
|
||||
|
||||
// Size of a raw memory area associated with a Lua state with very fast access.
|
||||
pub const LUA_EXTRASPACE: usize = mem::size_of::<*const ()>();
|
||||
|
||||
//
|
||||
// Pseudo-indices
|
||||
//
|
||||
pub const LUA_REGISTRYINDEX: c_int = -(c_int::MAX / 2 + 1000);
|
||||
|
||||
pub const fn lua_upvalueindex(i: c_int) -> c_int {
|
||||
LUA_REGISTRYINDEX - i
|
||||
}
|
||||
|
||||
//
|
||||
// Thread status
|
||||
//
|
||||
pub const LUA_OK: c_int = 0;
|
||||
pub const LUA_YIELD: c_int = 1;
|
||||
pub const LUA_ERRRUN: c_int = 2;
|
||||
pub const LUA_ERRSYNTAX: c_int = 3;
|
||||
pub const LUA_ERRMEM: c_int = 4;
|
||||
pub const LUA_ERRERR: c_int = 5;
|
||||
|
||||
/// A raw Lua state associated with a thread.
|
||||
#[repr(C)]
|
||||
pub struct lua_State {
|
||||
_data: [u8; 0],
|
||||
_marker: PhantomData<(*mut u8, PhantomPinned)>,
|
||||
}
|
||||
|
||||
//
|
||||
// Basic types
|
||||
//
|
||||
pub const LUA_TNONE: c_int = -1;
|
||||
|
||||
pub const LUA_TNIL: c_int = 0;
|
||||
pub const LUA_TBOOLEAN: c_int = 1;
|
||||
pub const LUA_TLIGHTUSERDATA: c_int = 2;
|
||||
pub const LUA_TNUMBER: c_int = 3;
|
||||
pub const LUA_TSTRING: c_int = 4;
|
||||
pub const LUA_TTABLE: c_int = 5;
|
||||
pub const LUA_TFUNCTION: c_int = 6;
|
||||
pub const LUA_TUSERDATA: c_int = 7;
|
||||
pub const LUA_TTHREAD: c_int = 8;
|
||||
|
||||
pub const LUA_NUMTYPES: c_int = 9;
|
||||
|
||||
/// Minimum Lua stack available to a C function
|
||||
pub const LUA_MINSTACK: c_int = 20;
|
||||
|
||||
// Predefined values in the registry
|
||||
// index 1 is reserved for the reference mechanism
|
||||
pub const LUA_RIDX_GLOBALS: lua_Integer = 2;
|
||||
pub const LUA_RIDX_MAINTHREAD: lua_Integer = 3;
|
||||
pub const LUA_RIDX_LAST: lua_Integer = 3;
|
||||
|
||||
/// A Lua number, usually equivalent to `f64`
|
||||
pub type lua_Number = c_double;
|
||||
|
||||
/// A Lua integer, usually equivalent to `i64`
|
||||
pub type lua_Integer = i64;
|
||||
|
||||
/// A Lua unsigned integer, usually equivalent to `u64`
|
||||
pub type lua_Unsigned = u64;
|
||||
|
||||
/// Type for continuation-function contexts
|
||||
pub type lua_KContext = isize;
|
||||
|
||||
/// Type for native C functions that can be passed to Lua
|
||||
pub type lua_CFunction = unsafe extern "C-unwind" fn(L: *mut lua_State) -> c_int;
|
||||
|
||||
/// Type for continuation functions
|
||||
pub type lua_KFunction =
|
||||
unsafe extern "C-unwind" fn(L: *mut lua_State, status: c_int, ctx: lua_KContext) -> c_int;
|
||||
|
||||
// Type for functions that read/write blocks when loading/dumping Lua chunks
|
||||
#[rustfmt::skip]
|
||||
pub type lua_Reader =
|
||||
unsafe extern "C-unwind" fn(L: *mut lua_State, ud: *mut c_void, sz: *mut usize) -> *const c_char;
|
||||
#[rustfmt::skip]
|
||||
pub type lua_Writer =
|
||||
unsafe extern "C-unwind" fn(L: *mut lua_State, p: *const c_void, sz: usize, ud: *mut c_void) -> c_int;
|
||||
|
||||
/// Type for memory-allocation functions (no unwinding)
|
||||
#[rustfmt::skip]
|
||||
pub type lua_Alloc =
|
||||
unsafe extern "C" fn(ud: *mut c_void, ptr: *mut c_void, osize: usize, nsize: usize) -> *mut c_void;
|
||||
|
||||
/// Type for warning functions
|
||||
pub type lua_WarnFunction = unsafe extern "C-unwind" fn(ud: *mut c_void, msg: *const c_char, tocont: c_int);
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
//
|
||||
// State manipulation
|
||||
//
|
||||
pub fn lua_newstate(f: lua_Alloc, ud: *mut c_void, seed: c_uint) -> *mut lua_State;
|
||||
pub fn lua_close(L: *mut lua_State);
|
||||
pub fn lua_newthread(L: *mut lua_State) -> *mut lua_State;
|
||||
pub fn lua_closethread(L: *mut lua_State, from: *mut lua_State) -> c_int;
|
||||
|
||||
pub fn lua_atpanic(L: *mut lua_State, panicf: lua_CFunction) -> lua_CFunction;
|
||||
|
||||
pub fn lua_version(L: *mut lua_State) -> lua_Number;
|
||||
|
||||
//
|
||||
// Basic stack manipulation
|
||||
//
|
||||
pub fn lua_absindex(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_gettop(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_settop(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_pushvalue(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_rotate(L: *mut lua_State, idx: c_int, n: c_int);
|
||||
pub fn lua_copy(L: *mut lua_State, fromidx: c_int, toidx: c_int);
|
||||
pub fn lua_checkstack(L: *mut lua_State, sz: c_int) -> c_int;
|
||||
|
||||
pub fn lua_xmove(from: *mut lua_State, to: *mut lua_State, n: c_int);
|
||||
|
||||
//
|
||||
// Access functions (stack -> C)
|
||||
//
|
||||
pub fn lua_isnumber(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_isstring(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_iscfunction(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_isinteger(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_isuserdata(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_type(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_typename(L: *mut lua_State, tp: c_int) -> *const c_char;
|
||||
|
||||
pub fn lua_tonumberx(L: *mut lua_State, idx: c_int, isnum: *mut c_int) -> lua_Number;
|
||||
pub fn lua_tointegerx(L: *mut lua_State, idx: c_int, isnum: *mut c_int) -> lua_Integer;
|
||||
pub fn lua_toboolean(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_tolstring(L: *mut lua_State, idx: c_int, len: *mut usize) -> *const c_char;
|
||||
#[link_name = "lua_rawlen"]
|
||||
fn lua_rawlen_(L: *mut lua_State, idx: c_int) -> lua_Unsigned;
|
||||
pub fn lua_tocfunction(L: *mut lua_State, idx: c_int) -> Option<lua_CFunction>;
|
||||
pub fn lua_touserdata(L: *mut lua_State, idx: c_int) -> *mut c_void;
|
||||
pub fn lua_tothread(L: *mut lua_State, idx: c_int) -> *mut lua_State;
|
||||
pub fn lua_topointer(L: *mut lua_State, idx: c_int) -> *const c_void;
|
||||
}
|
||||
|
||||
// lua_rawlen's return type changed from size_t to lua_Unsigned int in Lua 5.4.
|
||||
// This adapts the crate API to the new Lua ABI.
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_rawlen(L: *mut lua_State, idx: c_int) -> usize {
|
||||
lua_rawlen_(L, idx) as usize
|
||||
}
|
||||
|
||||
//
|
||||
// Comparison and arithmetic functions
|
||||
//
|
||||
pub const LUA_OPADD: c_int = 0;
|
||||
pub const LUA_OPSUB: c_int = 1;
|
||||
pub const LUA_OPMUL: c_int = 2;
|
||||
pub const LUA_OPMOD: c_int = 3;
|
||||
pub const LUA_OPPOW: c_int = 4;
|
||||
pub const LUA_OPDIV: c_int = 5;
|
||||
pub const LUA_OPIDIV: c_int = 6;
|
||||
pub const LUA_OPBAND: c_int = 7;
|
||||
pub const LUA_OPBOR: c_int = 8;
|
||||
pub const LUA_OPBXOR: c_int = 9;
|
||||
pub const LUA_OPSHL: c_int = 10;
|
||||
pub const LUA_OPSHR: c_int = 11;
|
||||
pub const LUA_OPUNM: c_int = 12;
|
||||
pub const LUA_OPBNOT: c_int = 13;
|
||||
|
||||
pub const LUA_OPEQ: c_int = 0;
|
||||
pub const LUA_OPLT: c_int = 1;
|
||||
pub const LUA_OPLE: c_int = 2;
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn lua_arith(L: *mut lua_State, op: c_int);
|
||||
pub fn lua_rawequal(L: *mut lua_State, idx1: c_int, idx2: c_int) -> c_int;
|
||||
pub fn lua_compare(L: *mut lua_State, idx1: c_int, idx2: c_int, op: c_int) -> c_int;
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
//
|
||||
// Push functions (C -> stack)
|
||||
//
|
||||
pub fn lua_pushnil(L: *mut lua_State);
|
||||
pub fn lua_pushnumber(L: *mut lua_State, n: lua_Number);
|
||||
pub fn lua_pushinteger(L: *mut lua_State, n: lua_Integer);
|
||||
pub fn lua_pushlstring(L: *mut lua_State, s: *const c_char, len: usize) -> *const c_char;
|
||||
pub fn lua_pushexternalstring(
|
||||
L: *mut lua_State,
|
||||
s: *const c_char,
|
||||
len: usize,
|
||||
falloc: Option<lua_Alloc>,
|
||||
ud: *mut c_void,
|
||||
) -> *const c_char;
|
||||
pub fn lua_pushstring(L: *mut lua_State, s: *const c_char) -> *const c_char;
|
||||
// lua_pushvfstring
|
||||
pub fn lua_pushfstring(L: *mut lua_State, fmt: *const c_char, ...) -> *const c_char;
|
||||
pub fn lua_pushcclosure(L: *mut lua_State, f: lua_CFunction, n: c_int);
|
||||
pub fn lua_pushboolean(L: *mut lua_State, b: c_int);
|
||||
pub fn lua_pushlightuserdata(L: *mut lua_State, p: *mut c_void);
|
||||
pub fn lua_pushthread(L: *mut lua_State) -> c_int;
|
||||
|
||||
//
|
||||
// Get functions (Lua -> stack)
|
||||
//
|
||||
pub fn lua_getglobal(L: *mut lua_State, name: *const c_char) -> c_int;
|
||||
pub fn lua_gettable(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_getfield(L: *mut lua_State, idx: c_int, k: *const c_char) -> c_int;
|
||||
pub fn lua_geti(L: *mut lua_State, idx: c_int, n: lua_Integer) -> c_int;
|
||||
pub fn lua_rawget(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_rawgeti(L: *mut lua_State, idx: c_int, n: lua_Integer) -> c_int;
|
||||
pub fn lua_rawgetp(L: *mut lua_State, idx: c_int, p: *const c_void) -> c_int;
|
||||
|
||||
pub fn lua_createtable(L: *mut lua_State, narr: c_int, nrec: c_int);
|
||||
pub fn lua_newuserdatauv(L: *mut lua_State, sz: usize, nuvalue: c_int) -> *mut c_void;
|
||||
pub fn lua_getmetatable(L: *mut lua_State, objindex: c_int) -> c_int;
|
||||
pub fn lua_getiuservalue(L: *mut lua_State, idx: c_int, n: c_int) -> c_int;
|
||||
|
||||
//
|
||||
// Set functions (stack -> Lua)
|
||||
//
|
||||
pub fn lua_setglobal(L: *mut lua_State, name: *const c_char);
|
||||
pub fn lua_settable(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_setfield(L: *mut lua_State, idx: c_int, k: *const c_char);
|
||||
pub fn lua_seti(L: *mut lua_State, idx: c_int, n: lua_Integer);
|
||||
pub fn lua_rawset(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_rawseti(L: *mut lua_State, idx: c_int, n: lua_Integer);
|
||||
pub fn lua_rawsetp(L: *mut lua_State, idx: c_int, p: *const c_void);
|
||||
pub fn lua_setmetatable(L: *mut lua_State, objindex: c_int) -> c_int;
|
||||
pub fn lua_setiuservalue(L: *mut lua_State, idx: c_int, n: c_int) -> c_int;
|
||||
|
||||
//
|
||||
// 'load' and 'call' functions (load and run Lua code)
|
||||
//
|
||||
pub fn lua_callk(
|
||||
L: *mut lua_State,
|
||||
nargs: c_int,
|
||||
nresults: c_int,
|
||||
ctx: lua_KContext,
|
||||
k: Option<lua_KFunction>,
|
||||
);
|
||||
pub fn lua_pcallk(
|
||||
L: *mut lua_State,
|
||||
nargs: c_int,
|
||||
nresults: c_int,
|
||||
errfunc: c_int,
|
||||
ctx: lua_KContext,
|
||||
k: Option<lua_KFunction>,
|
||||
) -> c_int;
|
||||
|
||||
pub fn lua_load(
|
||||
L: *mut lua_State,
|
||||
reader: lua_Reader,
|
||||
data: *mut c_void,
|
||||
chunkname: *const c_char,
|
||||
mode: *const c_char,
|
||||
) -> c_int;
|
||||
|
||||
pub fn lua_dump(L: *mut lua_State, writer: lua_Writer, data: *mut c_void, strip: c_int) -> c_int;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_call(L: *mut lua_State, n: c_int, r: c_int) {
|
||||
lua_callk(L, n, r, 0, None)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pcall(L: *mut lua_State, n: c_int, r: c_int, f: c_int) -> c_int {
|
||||
lua_pcallk(L, n, r, f, 0, None)
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
//
|
||||
// Coroutine functions
|
||||
//
|
||||
pub fn lua_yieldk(
|
||||
L: *mut lua_State,
|
||||
nresults: c_int,
|
||||
ctx: lua_KContext,
|
||||
k: Option<lua_KFunction>,
|
||||
) -> c_int;
|
||||
pub fn lua_resume(L: *mut lua_State, from: *mut lua_State, narg: c_int, nres: *mut c_int) -> c_int;
|
||||
pub fn lua_status(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_isyieldable(L: *mut lua_State) -> c_int;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_yield(L: *mut lua_State, n: c_int) -> c_int {
|
||||
lua_yieldk(L, n, 0, None)
|
||||
}
|
||||
|
||||
//
|
||||
// Warning-related functions
|
||||
//
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn lua_setwarnf(L: *mut lua_State, f: Option<lua_WarnFunction>, ud: *mut c_void);
|
||||
pub fn lua_warning(L: *mut lua_State, msg: *const c_char, tocont: c_int);
|
||||
}
|
||||
|
||||
//
|
||||
// Garbage-collection options
|
||||
//
|
||||
pub const LUA_GCSTOP: c_int = 0;
|
||||
pub const LUA_GCRESTART: c_int = 1;
|
||||
pub const LUA_GCCOLLECT: c_int = 2;
|
||||
pub const LUA_GCCOUNT: c_int = 3;
|
||||
pub const LUA_GCCOUNTB: c_int = 4;
|
||||
pub const LUA_GCSTEP: c_int = 5;
|
||||
pub const LUA_GCISRUNNING: c_int = 6;
|
||||
pub const LUA_GCGEN: c_int = 7;
|
||||
pub const LUA_GCINC: c_int = 8;
|
||||
pub const LUA_GCPARAM: c_int = 9;
|
||||
|
||||
// Parameters for GC generational mode
|
||||
pub const LUA_GCPMINORMUL: c_int = 0; // control minor collections
|
||||
pub const LUA_GCPMAJORMINOR: c_int = 1; // control shift major->minor
|
||||
pub const LUA_GCPMINORMAJOR: c_int = 2; // control shift minor->major
|
||||
|
||||
// Parameters for GC incremental mode
|
||||
pub const LUA_GCPPAUSE: c_int = 3; // size of pause between successive GCs
|
||||
pub const LUA_GCPSTEPMUL: c_int = 4; // GC "speed"
|
||||
pub const LUA_GCPSTEPSIZE: c_int = 5; // GC granularity
|
||||
|
||||
pub const LUA_GCPNUM: c_int = 6; // number of parameters
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn lua_gc(L: *mut lua_State, what: c_int, ...) -> c_int;
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
//
|
||||
// Miscellaneous functions
|
||||
//
|
||||
#[link_name = "lua_error"]
|
||||
fn lua_error_(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_next(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_concat(L: *mut lua_State, n: c_int);
|
||||
pub fn lua_len(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_numbertocstring(L: *mut lua_State, idx: c_int, buff: *mut c_char) -> c_uint;
|
||||
pub fn lua_stringtonumber(L: *mut lua_State, s: *const c_char) -> usize;
|
||||
pub fn lua_getallocf(L: *mut lua_State, ud: *mut *mut c_void) -> lua_Alloc;
|
||||
pub fn lua_setallocf(L: *mut lua_State, f: lua_Alloc, ud: *mut c_void);
|
||||
|
||||
pub fn lua_toclose(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_closeslot(L: *mut lua_State, idx: c_int);
|
||||
}
|
||||
|
||||
// lua_error does not return but is declared to return int, and Rust translates
|
||||
// ! to void which can cause link-time errors if the platform linker is aware
|
||||
// of return types and requires they match (for example: wasm does this).
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_error(L: *mut lua_State) -> ! {
|
||||
lua_error_(L);
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
//
|
||||
// Some useful macros (implemented as Rust functions)
|
||||
//
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_getextraspace(L: *mut lua_State) -> *mut c_void {
|
||||
(L as *mut c_char).sub(LUA_EXTRASPACE) as *mut c_void
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tonumber(L: *mut lua_State, i: c_int) -> lua_Number {
|
||||
lua_tonumberx(L, i, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tointeger(L: *mut lua_State, i: c_int) -> lua_Integer {
|
||||
lua_tointegerx(L, i, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pop(L: *mut lua_State, n: c_int) {
|
||||
lua_settop(L, -n - 1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_newtable(L: *mut lua_State) {
|
||||
lua_createtable(L, 0, 0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_register(L: *mut lua_State, n: *const c_char, f: lua_CFunction) {
|
||||
lua_pushcfunction(L, f);
|
||||
lua_setglobal(L, n)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushcfunction(L: *mut lua_State, f: lua_CFunction) {
|
||||
lua_pushcclosure(L, f, 0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isfunction(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TFUNCTION) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_istable(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TTABLE) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_islightuserdata(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TLIGHTUSERDATA) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isnil(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TNIL) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isboolean(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TBOOLEAN) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isthread(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TTHREAD) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isnone(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TNONE) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isnoneornil(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) <= 0) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushliteral(L: *mut lua_State, s: &'static CStr) {
|
||||
lua_pushstring(L, s.as_ptr());
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushglobaltable(L: *mut lua_State) -> c_int {
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tolightuserdata(L: *mut lua_State, idx: c_int) -> *mut c_void {
|
||||
if lua_islightuserdata(L, idx) != 0 {
|
||||
return lua_touserdata(L, idx);
|
||||
}
|
||||
ptr::null_mut()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tostring(L: *mut lua_State, i: c_int) -> *const c_char {
|
||||
lua_tolstring(L, i, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_insert(L: *mut lua_State, idx: c_int) {
|
||||
lua_rotate(L, idx, 1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_remove(L: *mut lua_State, idx: c_int) {
|
||||
lua_rotate(L, idx, -1);
|
||||
lua_pop(L, 1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_replace(L: *mut lua_State, idx: c_int) {
|
||||
lua_copy(L, -1, idx);
|
||||
lua_pop(L, 1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_xpush(from: *mut lua_State, to: *mut lua_State, idx: c_int) {
|
||||
lua_pushvalue(from, idx);
|
||||
lua_xmove(from, to, 1);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_newuserdata(L: *mut lua_State, sz: usize) -> *mut c_void {
|
||||
lua_newuserdatauv(L, sz, 1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_getuservalue(L: *mut lua_State, idx: c_int) -> c_int {
|
||||
lua_getiuservalue(L, idx, 1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_setuservalue(L: *mut lua_State, idx: c_int) -> c_int {
|
||||
lua_setiuservalue(L, idx, 1)
|
||||
}
|
||||
|
||||
//
|
||||
// Debug API
|
||||
//
|
||||
|
||||
// Maximum size for the description of the source of a function in debug information.
|
||||
const LUA_IDSIZE: usize = 60;
|
||||
|
||||
// Event codes
|
||||
pub const LUA_HOOKCALL: c_int = 0;
|
||||
pub const LUA_HOOKRET: c_int = 1;
|
||||
pub const LUA_HOOKLINE: c_int = 2;
|
||||
pub const LUA_HOOKCOUNT: c_int = 3;
|
||||
pub const LUA_HOOKTAILCALL: c_int = 4;
|
||||
|
||||
// Event masks
|
||||
pub const LUA_MASKCALL: c_int = 1 << (LUA_HOOKCALL as usize);
|
||||
pub const LUA_MASKRET: c_int = 1 << (LUA_HOOKRET as usize);
|
||||
pub const LUA_MASKLINE: c_int = 1 << (LUA_HOOKLINE as usize);
|
||||
pub const LUA_MASKCOUNT: c_int = 1 << (LUA_HOOKCOUNT as usize);
|
||||
|
||||
/// Type for functions to be called on debug events.
|
||||
pub type lua_Hook = unsafe extern "C-unwind" fn(L: *mut lua_State, ar: *mut lua_Debug);
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn lua_getstack(L: *mut lua_State, level: c_int, ar: *mut lua_Debug) -> c_int;
|
||||
pub fn lua_getinfo(L: *mut lua_State, what: *const c_char, ar: *mut lua_Debug) -> c_int;
|
||||
pub fn lua_getlocal(L: *mut lua_State, ar: *const lua_Debug, n: c_int) -> *const c_char;
|
||||
pub fn lua_setlocal(L: *mut lua_State, ar: *const lua_Debug, n: c_int) -> *const c_char;
|
||||
pub fn lua_getupvalue(L: *mut lua_State, funcindex: c_int, n: c_int) -> *const c_char;
|
||||
pub fn lua_setupvalue(L: *mut lua_State, funcindex: c_int, n: c_int) -> *const c_char;
|
||||
|
||||
pub fn lua_upvalueid(L: *mut lua_State, fidx: c_int, n: c_int) -> *mut c_void;
|
||||
pub fn lua_upvaluejoin(L: *mut lua_State, fidx1: c_int, n1: c_int, fidx2: c_int, n2: c_int);
|
||||
|
||||
pub fn lua_sethook(L: *mut lua_State, func: Option<lua_Hook>, mask: c_int, count: c_int);
|
||||
pub fn lua_gethook(L: *mut lua_State) -> Option<lua_Hook>;
|
||||
pub fn lua_gethookmask(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_gethookcount(L: *mut lua_State) -> c_int;
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct lua_Debug {
|
||||
pub event: c_int,
|
||||
pub name: *const c_char, // (n)
|
||||
pub namewhat: *const c_char, // (n) 'global', 'local', 'field', 'method'
|
||||
pub what: *const c_char, // (S) 'Lua', 'C', 'main', 'tail'
|
||||
pub source: *const c_char, // (S)
|
||||
pub srclen: usize, // (S)
|
||||
pub currentline: c_int, // (l)
|
||||
pub linedefined: c_int, // (S)
|
||||
pub lastlinedefined: c_int, // (S)
|
||||
pub nups: c_uchar, // (u) number of upvalues
|
||||
pub nparams: c_uchar, // (u) number of parameters
|
||||
pub isvararg: c_char, // (u)
|
||||
pub extraargs: c_uchar, // (t) number of extra arguments
|
||||
pub istailcall: c_char, // (t)
|
||||
pub ftransfer: c_int, // (r) index of first value transferred
|
||||
pub ntransfer: c_int, // (r) number of transferred values
|
||||
pub short_src: [c_char; LUA_IDSIZE], // (S)
|
||||
// lua.h mentions this is for private use
|
||||
i_ci: *mut c_void,
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
//! Contains definitions from `lualib.h`.
|
||||
|
||||
use std::os::raw::{c_char, c_int};
|
||||
|
||||
use super::lua::lua_State;
|
||||
|
||||
pub const LUA_GLIBK: c_int = 1;
|
||||
|
||||
pub const LUA_LOADLIBNAME: *const c_char = cstr!("package");
|
||||
pub const LUA_LOADLIBK: c_int = LUA_GLIBK << 1;
|
||||
|
||||
pub const LUA_COLIBNAME: *const c_char = cstr!("coroutine");
|
||||
pub const LUA_COLIBK: c_int = LUA_GLIBK << 2;
|
||||
|
||||
pub const LUA_DBLIBNAME: *const c_char = cstr!("debug");
|
||||
pub const LUA_DBLIBK: c_int = LUA_GLIBK << 3;
|
||||
|
||||
pub const LUA_IOLIBNAME: *const c_char = cstr!("io");
|
||||
pub const LUA_IOLIBK: c_int = LUA_GLIBK << 4;
|
||||
|
||||
pub const LUA_MATHLIBNAME: *const c_char = cstr!("math");
|
||||
pub const LUA_MATHLIBK: c_int = LUA_GLIBK << 5;
|
||||
|
||||
pub const LUA_OSLIBNAME: *const c_char = cstr!("os");
|
||||
pub const LUA_OSLIBK: c_int = LUA_GLIBK << 6;
|
||||
|
||||
pub const LUA_STRLIBNAME: *const c_char = cstr!("string");
|
||||
pub const LUA_STRLIBK: c_int = LUA_GLIBK << 7;
|
||||
|
||||
pub const LUA_TABLIBNAME: *const c_char = cstr!("table");
|
||||
pub const LUA_TABLIBK: c_int = LUA_GLIBK << 8;
|
||||
|
||||
pub const LUA_UTF8LIBNAME: *const c_char = cstr!("utf8");
|
||||
pub const LUA_UTF8LIBK: c_int = LUA_GLIBK << 9;
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaopen_base(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_package(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_coroutine(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_debug(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_io(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_math(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_os(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_string(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_table(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_utf8(L: *mut lua_State) -> c_int;
|
||||
|
||||
// open all builtin libraries
|
||||
pub fn luaL_openselectedlibs(L: *mut lua_State, load: c_int, preload: c_int);
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_openlibs(L: *mut lua_State) {
|
||||
luaL_openselectedlibs(L, !0, 0);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
//! Low level bindings to Lua 5.5.
|
||||
|
||||
pub use lauxlib::*;
|
||||
pub use lua::*;
|
||||
pub use lualib::*;
|
||||
|
||||
pub mod lauxlib;
|
||||
pub mod lua;
|
||||
pub mod lualib;
|
||||
@@ -3,7 +3,7 @@
|
||||
use std::os::raw::{c_char, c_float, c_int, c_void};
|
||||
use std::ptr;
|
||||
|
||||
use super::lua::{self, lua_CFunction, lua_Number, lua_State, lua_Unsigned, LUA_REGISTRYINDEX};
|
||||
use super::lua::{self, LUA_REGISTRYINDEX, lua_CFunction, lua_Number, lua_State, lua_Unsigned};
|
||||
|
||||
// Key, in the registry, for table of loaded modules
|
||||
pub const LUA_LOADED_TABLE: *const c_char = cstr!("_LOADED");
|
||||
@@ -85,6 +85,9 @@ unsafe extern "C-unwind" {
|
||||
|
||||
pub fn luaL_callyieldable(L: *mut lua_State, nargs: c_int, nresults: c_int) -> c_int;
|
||||
|
||||
#[link_name = "luaL_traceback"]
|
||||
pub fn luaL_traceback_(L: *mut lua_State, L1: *mut lua_State, msg: *const c_char, level: c_int);
|
||||
|
||||
// sandbox libraries and globals
|
||||
#[link_name = "luaL_sandbox"]
|
||||
pub fn luaL_sandbox_(L: *mut lua_State);
|
||||
@@ -119,7 +122,19 @@ pub unsafe fn luaL_optstring(L: *mut lua_State, n: c_int, d: *const c_char) -> *
|
||||
luaL_optlstring(L, n, d, ptr::null_mut())
|
||||
}
|
||||
|
||||
// TODO: luaL_opt
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_opt<T>(
|
||||
L: *mut lua_State,
|
||||
f: unsafe extern "C-unwind" fn(*mut lua_State, c_int) -> T,
|
||||
n: c_int,
|
||||
d: T,
|
||||
) -> T {
|
||||
if lua::lua_isnoneornil(L, n) != 0 {
|
||||
d
|
||||
} else {
|
||||
f(L, n)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_getmetatable(L: *mut lua_State, n: *const c_char) -> c_int {
|
||||
|
||||
@@ -37,6 +37,16 @@ pub const LUA_ERRRUN: c_int = 2;
|
||||
pub const LUA_ERRSYNTAX: c_int = 3;
|
||||
pub const LUA_ERRMEM: c_int = 4;
|
||||
pub const LUA_ERRERR: c_int = 5;
|
||||
pub const LUA_BREAK: c_int = 6; // yielded for a debug breakpoint
|
||||
|
||||
//
|
||||
// Coroutine status
|
||||
//
|
||||
pub const LUA_CORUN: c_int = 0; // running
|
||||
pub const LUA_COSUS: c_int = 1; // suspended
|
||||
pub const LUA_CONOR: c_int = 2; // 'normal' (it resumed another coroutine)
|
||||
pub const LUA_COFIN: c_int = 3; // finished
|
||||
pub const LUA_COERR: c_int = 4; // finished with error
|
||||
|
||||
/// A raw Lua state associated with a thread.
|
||||
#[repr(C)]
|
||||
@@ -145,8 +155,15 @@ unsafe extern "C-unwind" {
|
||||
pub fn lua_toboolean(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_tolstring(L: *mut lua_State, idx: c_int, len: *mut usize) -> *const c_char;
|
||||
pub fn lua_tostringatom(L: *mut lua_State, idx: c_int, atom: *mut c_int) -> *const c_char;
|
||||
pub fn lua_tolstringatom(
|
||||
L: *mut lua_State,
|
||||
idx: c_int,
|
||||
len: *mut usize,
|
||||
atom: *mut c_int,
|
||||
) -> *const c_char;
|
||||
pub fn lua_namecallatom(L: *mut lua_State, atom: *mut c_int) -> *const c_char;
|
||||
pub fn lua_objlen(L: *mut lua_State, idx: c_int) -> usize;
|
||||
#[link_name = "lua_objlen"]
|
||||
pub fn lua_objlen_(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_tocfunction(L: *mut lua_State, idx: c_int) -> Option<lua_CFunction>;
|
||||
pub fn lua_tolightuserdata(L: *mut lua_State, idx: c_int) -> *mut c_void;
|
||||
pub fn lua_tolightuserdatatagged(L: *mut lua_State, idx: c_int, tag: c_int) -> *mut c_void;
|
||||
@@ -218,6 +235,7 @@ unsafe extern "C-unwind" {
|
||||
//
|
||||
pub fn lua_settable(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_setfield(L: *mut lua_State, idx: c_int, k: *const c_char);
|
||||
pub fn lua_rawsetfield(L: *mut lua_State, idx: c_int, k: *const c_char);
|
||||
pub fn lua_rawset(L: *mut lua_State, idx: c_int);
|
||||
#[link_name = "lua_rawseti"]
|
||||
pub fn lua_rawseti_(L: *mut lua_State, idx: c_int, n: c_int);
|
||||
@@ -251,6 +269,12 @@ unsafe extern "C-unwind" {
|
||||
pub fn lua_isyieldable(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_getthreaddata(L: *mut lua_State) -> *mut c_void;
|
||||
pub fn lua_setthreaddata(L: *mut lua_State, data: *mut c_void);
|
||||
pub fn lua_costatus(L: *mut lua_State, co: *mut lua_State) -> c_int;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_objlen(L: *mut lua_State, idx: c_int) -> usize {
|
||||
lua_objlen_(L, idx) as usize
|
||||
}
|
||||
|
||||
//
|
||||
@@ -287,7 +311,7 @@ unsafe extern "C-unwind" {
|
||||
pub fn lua_next(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_rawiter(L: *mut lua_State, idx: c_int, iter: c_int) -> c_int;
|
||||
pub fn lua_concat(L: *mut lua_State, n: c_int);
|
||||
// TODO: lua_encodepointer
|
||||
pub fn lua_encodepointer(L: *mut lua_State, p: usize) -> usize;
|
||||
pub fn lua_clock() -> c_double;
|
||||
pub fn lua_setuserdatatag(L: *mut lua_State, idx: c_int, tag: c_int);
|
||||
pub fn lua_setuserdatadtor(L: *mut lua_State, tag: c_int, dtor: Option<lua_Destructor>);
|
||||
@@ -298,6 +322,7 @@ unsafe extern "C-unwind" {
|
||||
pub fn lua_getlightuserdataname(L: *mut lua_State, tag: c_int) -> *const c_char;
|
||||
pub fn lua_clonefunction(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_cleartable(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_clonetable(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_getallocf(L: *mut lua_State, ud: *mut *mut c_void) -> lua_Alloc;
|
||||
}
|
||||
|
||||
@@ -357,7 +382,10 @@ pub unsafe fn lua_newuserdata_t<T>(L: *mut lua_State, data: T) -> *mut T {
|
||||
ud_ptr
|
||||
}
|
||||
|
||||
// TODO: lua_strlen
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_strlen(L: *mut lua_State, i: c_int) -> usize {
|
||||
lua_objlen(L, i)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isfunction(L: *mut lua_State, n: c_int) -> c_int {
|
||||
|
||||
@@ -58,6 +58,18 @@ pub struct luarequire_Configuration {
|
||||
path: *const c_char,
|
||||
) -> luarequire_NavigateResult,
|
||||
|
||||
// Provides an initial alias override opportunity prior to searching for configuration files.
|
||||
// If NAVIGATE_SUCCESS is returned, the internal state must be updated to point at the
|
||||
// aliased location.
|
||||
// Can be left undefined.
|
||||
pub to_alias_override: Option<
|
||||
unsafe extern "C-unwind" fn(
|
||||
L: *mut lua_State,
|
||||
ctx: *mut c_void,
|
||||
alias_unprefixed: *const c_char,
|
||||
) -> luarequire_NavigateResult,
|
||||
>,
|
||||
|
||||
// Provides a final override opportunity if an alias cannot be found in configuration files. If
|
||||
// NAVIGATE_SUCCESS is returned, this must update the internal state to point at the aliased module.
|
||||
// Can be left undefined.
|
||||
|
||||
+22
-1
@@ -500,11 +500,21 @@ impl FromLua for crate::Buffer {
|
||||
impl IntoLua for StdString {
|
||||
#[inline]
|
||||
fn into_lua(self, lua: &Lua) -> Result<Value> {
|
||||
#[cfg(feature = "lua55")]
|
||||
if true {
|
||||
return Ok(Value::String(lua.create_external_string(self)?));
|
||||
}
|
||||
|
||||
Ok(Value::String(lua.create_string(self)?))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn push_into_stack(self, lua: &RawLua) -> Result<()> {
|
||||
#[cfg(feature = "lua55")]
|
||||
if lua.unlikely_memory_error() {
|
||||
return crate::util::push_external_string(lua.state(), self.into(), false);
|
||||
}
|
||||
|
||||
push_bytes_into_stack(self, lua)
|
||||
}
|
||||
}
|
||||
@@ -591,6 +601,11 @@ impl FromLua for Box<str> {
|
||||
impl IntoLua for CString {
|
||||
#[inline]
|
||||
fn into_lua(self, lua: &Lua) -> Result<Value> {
|
||||
#[cfg(feature = "lua55")]
|
||||
if true {
|
||||
return Ok(Value::String(lua.create_external_string(self)?));
|
||||
}
|
||||
|
||||
Ok(Value::String(lua.create_string(self.as_bytes())?))
|
||||
}
|
||||
}
|
||||
@@ -635,6 +650,11 @@ impl IntoLua for Cow<'_, CStr> {
|
||||
impl IntoLua for BString {
|
||||
#[inline]
|
||||
fn into_lua(self, lua: &Lua) -> Result<Value> {
|
||||
#[cfg(feature = "lua55")]
|
||||
if true {
|
||||
return Ok(Value::String(lua.create_external_string(self)?));
|
||||
}
|
||||
|
||||
Ok(Value::String(lua.create_string(self)?))
|
||||
}
|
||||
}
|
||||
@@ -1191,7 +1211,8 @@ impl<L: FromLua, R: FromLua> FromLua for Either<L, R> {
|
||||
Err(_) => match R::from_stack(idx, lua).map(Either::Right) {
|
||||
Ok(r) => Ok(r),
|
||||
Err(_) => {
|
||||
let value_type_name = CStr::from_ptr(ffi::luaL_typename(lua.state(), idx));
|
||||
let value_type_name =
|
||||
CStr::from_ptr(ffi::lua_typename(lua.state(), ffi::lua_type(lua.state(), idx)));
|
||||
Err(Error::FromLuaConversionError {
|
||||
from: value_type_name.to_str().unwrap(),
|
||||
to: Self::type_name(),
|
||||
|
||||
+32
-8
@@ -159,10 +159,10 @@ impl<'a> Debug<'a> {
|
||||
|
||||
/// Corresponds to the `t` "what" mask. Returns true if the hook is in a function tail call,
|
||||
/// false otherwise.
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
doc(cfg(any(feature = "lua54", feature = "lua53", feature = "lua52")))
|
||||
doc(cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52")))
|
||||
)]
|
||||
pub fn is_tail_call(&self) -> bool {
|
||||
unsafe {
|
||||
@@ -191,9 +191,9 @@ impl<'a> Debug<'a> {
|
||||
#[cfg(not(feature = "luau"))]
|
||||
let stack = DebugStack {
|
||||
num_ups: (*self.ar).nups as _,
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
num_params: (*self.ar).nparams as _,
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
is_vararg: (*self.ar).isvararg != 0,
|
||||
};
|
||||
#[cfg(feature = "luau")]
|
||||
@@ -248,17 +248,41 @@ pub struct DebugStack {
|
||||
/// Number of upvalues.
|
||||
pub num_ups: u8,
|
||||
/// Number of parameters.
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luau"))]
|
||||
#[cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "luau"
|
||||
))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
doc(cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luau")))
|
||||
doc(cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "luau"
|
||||
)))
|
||||
)]
|
||||
pub num_params: u8,
|
||||
/// Whether the function is a vararg function.
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luau"))]
|
||||
#[cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "luau"
|
||||
))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
doc(cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luau")))
|
||||
doc(cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "luau"
|
||||
)))
|
||||
)]
|
||||
pub is_vararg: bool,
|
||||
}
|
||||
|
||||
+38
-10
@@ -32,6 +32,7 @@ pub struct Function(pub(crate) ValueRef);
|
||||
///
|
||||
/// [`Lua Debug Interface`]: https://www.lua.org/manual/5.4/manual.html#4.7
|
||||
#[derive(Clone, Debug)]
|
||||
#[non_exhaustive]
|
||||
pub struct FunctionInfo {
|
||||
/// A (reasonable) name of the function (`None` if the name cannot be found).
|
||||
pub name: Option<String>,
|
||||
@@ -50,6 +51,16 @@ pub struct FunctionInfo {
|
||||
pub line_defined: Option<usize>,
|
||||
/// The line number where the definition of the function ends (not set by Luau).
|
||||
pub last_line_defined: Option<usize>,
|
||||
/// The number of upvalues of the function.
|
||||
pub num_upvalues: u8,
|
||||
/// The number of parameters of the function (always 0 for C).
|
||||
#[cfg(any(not(any(feature = "lua51", feature = "luajit")), doc))]
|
||||
#[cfg_attr(docsrs, doc(cfg(not(any(feature = "lua51", feature = "luajit")))))]
|
||||
pub num_params: u8,
|
||||
/// Whether the function is a variadic function (always true for C).
|
||||
#[cfg(any(not(any(feature = "lua51", feature = "luajit")), doc))]
|
||||
#[cfg_attr(docsrs, doc(cfg(not(any(feature = "lua51", feature = "luajit")))))]
|
||||
pub is_vararg: bool,
|
||||
}
|
||||
|
||||
/// Luau function coverage snapshot.
|
||||
@@ -276,7 +287,7 @@ impl Function {
|
||||
|
||||
#[cfg(any(feature = "lua51", feature = "luajit", feature = "luau"))]
|
||||
ffi::lua_getfenv(state, -1);
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
for i in 1..=255 {
|
||||
// Traverse upvalues until we find the _ENV one
|
||||
match ffi::lua_getupvalue(state, -1, i) {
|
||||
@@ -316,7 +327,7 @@ impl Function {
|
||||
lua.push_ref(&env.0);
|
||||
ffi::lua_setfenv(state, -2);
|
||||
}
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
for i in 1..=255 {
|
||||
match ffi::lua_getupvalue(state, -1, i) {
|
||||
s if s.is_null() => return Ok(false),
|
||||
@@ -343,7 +354,8 @@ impl Function {
|
||||
|
||||
/// Returns information about the function.
|
||||
///
|
||||
/// Corresponds to the `>Sn` what mask for [`lua_getinfo`] when applied to the function.
|
||||
/// Corresponds to the `>Snu` (`>Sn` for Luau) what mask for
|
||||
/// [`lua_getinfo`] when applied to the function.
|
||||
///
|
||||
/// [`lua_getinfo`]: https://www.lua.org/manual/5.4/manual.html#lua_getinfo
|
||||
pub fn info(&self) -> FunctionInfo {
|
||||
@@ -355,11 +367,16 @@ impl Function {
|
||||
|
||||
let mut ar: ffi::lua_Debug = mem::zeroed();
|
||||
lua.push_ref(&self.0);
|
||||
|
||||
#[cfg(not(feature = "luau"))]
|
||||
let res = ffi::lua_getinfo(state, cstr!(">Sn"), &mut ar);
|
||||
let res = ffi::lua_getinfo(state, cstr!(">Snu"), &mut ar);
|
||||
#[cfg(not(feature = "luau"))]
|
||||
mlua_assert!(res != 0, "lua_getinfo failed with `>Snu`");
|
||||
|
||||
#[cfg(feature = "luau")]
|
||||
let res = ffi::lua_getinfo(state, -1, cstr!("sn"), &mut ar);
|
||||
mlua_assert!(res != 0, "lua_getinfo failed with `>Sn`");
|
||||
let res = ffi::lua_getinfo(state, -1, cstr!("snau"), &mut ar);
|
||||
#[cfg(feature = "luau")]
|
||||
mlua_assert!(res != 0, "lua_getinfo failed with `snau`");
|
||||
|
||||
FunctionInfo {
|
||||
name: ptr_to_lossy_str(ar.name).map(|s| s.into_owned()),
|
||||
@@ -381,6 +398,14 @@ impl Function {
|
||||
last_line_defined: linenumber_to_usize(ar.lastlinedefined),
|
||||
#[cfg(feature = "luau")]
|
||||
last_line_defined: None,
|
||||
#[cfg(not(feature = "luau"))]
|
||||
num_upvalues: ar.nups as _,
|
||||
#[cfg(feature = "luau")]
|
||||
num_upvalues: ar.nupvals,
|
||||
#[cfg(not(any(feature = "lua51", feature = "luajit")))]
|
||||
num_params: ar.nparams,
|
||||
#[cfg(not(any(feature = "lua51", feature = "luajit")))]
|
||||
is_vararg: ar.isvararg != 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -400,11 +425,14 @@ impl Function {
|
||||
_state: *mut ffi::lua_State,
|
||||
buf: *const c_void,
|
||||
buf_len: usize,
|
||||
data: *mut c_void,
|
||||
data_ptr: *mut c_void,
|
||||
) -> c_int {
|
||||
let data = &mut *(data as *mut Vec<u8>);
|
||||
let buf = slice::from_raw_parts(buf as *const u8, buf_len);
|
||||
data.extend_from_slice(buf);
|
||||
// If `data` is null, then it's a signal that write is finished.
|
||||
if !data_ptr.is_null() && buf_len > 0 {
|
||||
let data = &mut *(data_ptr as *mut Vec<u8>);
|
||||
let buf = slice::from_raw_parts(buf as *const u8, buf_len);
|
||||
data.extend_from_slice(buf);
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -313,8 +313,8 @@ mod tests {
|
||||
fn test_error_cases() {
|
||||
assert!(parse("").is_err());
|
||||
assert!(parse("nul").is_err());
|
||||
assert!(parse("tru").is_err());
|
||||
assert!(parse("fals").is_err());
|
||||
assert!(parse("tru").is_err()); // typos:ignore
|
||||
assert!(parse("fals").is_err()); // typos:ignore
|
||||
assert!(parse(r#""unterminated"#).is_err());
|
||||
assert!(parse("[1,2,]").is_err());
|
||||
assert!(parse(r#"{"key""#).is_err());
|
||||
|
||||
@@ -299,6 +299,7 @@ pub(super) unsafe extern "C-unwind" fn init_config(config: *mut ffi::luarequire_
|
||||
(*config).is_require_allowed = is_require_allowed;
|
||||
(*config).reset = reset;
|
||||
(*config).jump_to_alias = jump_to_alias;
|
||||
(*config).to_alias_override = None;
|
||||
(*config).to_alias_fallback = None;
|
||||
(*config).to_parent = to_parent;
|
||||
(*config).to_child = to_child;
|
||||
|
||||
+1
-1
@@ -83,7 +83,7 @@ impl MemoryState {
|
||||
}
|
||||
|
||||
// Does nothing apart from calling `f()`, we don't need to bypass any limits
|
||||
#[cfg(any(feature = "lua52", feature = "lua53", feature = "lua54"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
#[inline]
|
||||
pub(crate) unsafe fn relax_limit_with(_state: *mut ffi::lua_State, f: impl FnOnce()) {
|
||||
f();
|
||||
|
||||
+107
-22
@@ -73,8 +73,8 @@ pub(crate) struct LuaGuard(ArcReentrantMutexGuard<RawLua>);
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum GCMode {
|
||||
Incremental,
|
||||
#[cfg(feature = "lua54")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "lua54")))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(any(feature = "lua55", feature = "lua54"))))]
|
||||
Generational,
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ impl Lua {
|
||||
ffi::luaL_loadstring as _,
|
||||
ffi::luaL_openlibs as _,
|
||||
]);
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
{
|
||||
_symbols.push(ffi::lua_getglobal as _);
|
||||
_symbols.push(ffi::lua_setglobal as _);
|
||||
@@ -337,6 +337,39 @@ impl Lua {
|
||||
R::from_stack_multi(nresults, &lua)
|
||||
}
|
||||
|
||||
/// Runs callback with the inner RawLua value. It can be used to manually push and get values on
|
||||
/// the stack.
|
||||
///
|
||||
/// This function is safe because all unsafe actions with RawLua can only be done with unsafe
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # use mlua::{Lua, Result, FromLua, IntoLua};
|
||||
/// # fn main() -> Result<()> {
|
||||
/// let lua = Lua::new();
|
||||
/// let n: i32 = {
|
||||
/// let num = 11i32;
|
||||
/// lua.exec_raw_lua(|lua| {
|
||||
/// unsafe {
|
||||
/// <i32 as IntoLua>::push_into_stack(num, lua)?;
|
||||
/// }
|
||||
///
|
||||
/// let n = unsafe {
|
||||
/// <i32 as FromLua>::from_stack(-1, lua)?
|
||||
/// };
|
||||
/// Result::Ok(n)
|
||||
/// })
|
||||
/// }?;
|
||||
/// assert_eq!(n, 11);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[doc(hidden)]
|
||||
pub fn exec_raw_lua<R>(&self, f: impl FnOnce(&RawLua) -> R) -> R {
|
||||
let lua = self.lock();
|
||||
f(&lua)
|
||||
}
|
||||
|
||||
/// Loads the specified subset of the standard libraries into an existing Lua state.
|
||||
///
|
||||
/// Use the [`StdLib`] flags to specify the libraries you want to load.
|
||||
@@ -382,7 +415,7 @@ impl Lua {
|
||||
#[cfg(not(feature = "luau"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(not(feature = "luau"))))]
|
||||
pub fn preload_module(&self, modname: &str, func: Function) -> Result<()> {
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
let preload = unsafe {
|
||||
self.exec_raw::<Option<Table>>((), |state| {
|
||||
ffi::lua_getfield(state, ffi::LUA_REGISTRYINDEX, ffi::LUA_PRELOAD_TABLE);
|
||||
@@ -814,8 +847,8 @@ impl Lua {
|
||||
}
|
||||
|
||||
/// Sets the warning function to be used by Lua to emit warnings.
|
||||
#[cfg(feature = "lua54")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "lua54")))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(any(feature = "lua55", feature = "lua54"))))]
|
||||
pub fn set_warning_function<F>(&self, callback: F)
|
||||
where
|
||||
F: Fn(&Lua, &str, bool) -> Result<()> + MaybeSend + 'static,
|
||||
@@ -847,8 +880,8 @@ impl Lua {
|
||||
/// Removes warning function previously set by `set_warning_function`.
|
||||
///
|
||||
/// This function has no effect if a warning function was not previously set.
|
||||
#[cfg(feature = "lua54")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "lua54")))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(any(feature = "lua55", feature = "lua54"))))]
|
||||
pub fn remove_warning_function(&self) {
|
||||
let lua = self.lock();
|
||||
unsafe {
|
||||
@@ -861,8 +894,8 @@ impl Lua {
|
||||
///
|
||||
/// A message in a call with `incomplete` set to `true` should be continued in
|
||||
/// another call to this function.
|
||||
#[cfg(feature = "lua54")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "lua54")))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(any(feature = "lua55", feature = "lua54"))))]
|
||||
pub fn warning(&self, msg: impl AsRef<str>, incomplete: bool) {
|
||||
let msg = msg.as_ref();
|
||||
let mut bytes = vec![0; msg.len() + 1];
|
||||
@@ -954,7 +987,13 @@ impl Lua {
|
||||
}
|
||||
|
||||
/// Returns `true` if the garbage collector is currently running automatically.
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luau"))]
|
||||
#[cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "luau"
|
||||
))]
|
||||
pub fn gc_is_running(&self) -> bool {
|
||||
let lua = self.lock();
|
||||
unsafe { ffi::lua_gc(lua.main_state(), ffi::LUA_GCISRUNNING, 0) != 0 }
|
||||
@@ -1019,8 +1058,12 @@ impl Lua {
|
||||
let lua = self.lock();
|
||||
let state = lua.main_state();
|
||||
unsafe {
|
||||
#[cfg(not(feature = "luau"))]
|
||||
#[cfg(feature = "lua55")]
|
||||
return ffi::lua_gc(state, ffi::LUA_GCPARAM, ffi::LUA_GCPPAUSE, pause);
|
||||
|
||||
#[cfg(not(any(feature = "lua55", feature = "luau")))]
|
||||
return ffi::lua_gc(state, ffi::LUA_GCSETPAUSE, pause);
|
||||
|
||||
#[cfg(feature = "luau")]
|
||||
return ffi::lua_gc(state, ffi::LUA_GCSETGOAL, pause);
|
||||
}
|
||||
@@ -1034,7 +1077,18 @@ impl Lua {
|
||||
/// [documentation]: https://www.lua.org/manual/5.4/manual.html#2.5
|
||||
pub fn gc_set_step_multiplier(&self, step_multiplier: c_int) -> c_int {
|
||||
let lua = self.lock();
|
||||
unsafe { ffi::lua_gc(lua.main_state(), ffi::LUA_GCSETSTEPMUL, step_multiplier) }
|
||||
unsafe {
|
||||
#[cfg(feature = "lua55")]
|
||||
return ffi::lua_gc(
|
||||
lua.main_state(),
|
||||
ffi::LUA_GCPARAM,
|
||||
ffi::LUA_GCPSTEPMUL,
|
||||
step_multiplier,
|
||||
);
|
||||
|
||||
#[cfg(not(feature = "lua55"))]
|
||||
return ffi::lua_gc(lua.main_state(), ffi::LUA_GCSETSTEPMUL, step_multiplier);
|
||||
}
|
||||
}
|
||||
|
||||
/// Changes the collector to incremental mode with the given parameters.
|
||||
@@ -1073,12 +1127,19 @@ impl Lua {
|
||||
#[cfg(not(feature = "luau"))]
|
||||
let _ = step_size; // Ignored
|
||||
|
||||
GCMode::Incremental
|
||||
return GCMode::Incremental;
|
||||
}
|
||||
|
||||
#[cfg(feature = "lua55")]
|
||||
let prev_mode = unsafe {
|
||||
ffi::lua_gc(state, ffi::LUA_GCPARAM, ffi::LUA_GCPPAUSE, pause);
|
||||
ffi::lua_gc(state, ffi::LUA_GCPARAM, ffi::LUA_GCPSTEPMUL, step_multiplier);
|
||||
ffi::lua_gc(state, ffi::LUA_GCPARAM, ffi::LUA_GCPSTEPSIZE, step_size);
|
||||
ffi::lua_gc(state, ffi::LUA_GCINC)
|
||||
};
|
||||
#[cfg(feature = "lua54")]
|
||||
let prev_mode = unsafe { ffi::lua_gc(state, ffi::LUA_GCINC, pause, step_multiplier, step_size) };
|
||||
#[cfg(feature = "lua54")]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54"))]
|
||||
match prev_mode {
|
||||
ffi::LUA_GCINC => GCMode::Incremental,
|
||||
ffi::LUA_GCGEN => GCMode::Generational,
|
||||
@@ -1092,11 +1153,19 @@ impl Lua {
|
||||
/// can be found in the Lua 5.4 [documentation][lua_doc].
|
||||
///
|
||||
/// [lua_doc]: https://www.lua.org/manual/5.4/manual.html#2.5.2
|
||||
#[cfg(feature = "lua54")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "lua54")))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(any(feature = "lua55", feature = "lua54"))))]
|
||||
pub fn gc_gen(&self, minor_multiplier: c_int, major_multiplier: c_int) -> GCMode {
|
||||
let lua = self.lock();
|
||||
let state = lua.main_state();
|
||||
#[cfg(feature = "lua55")]
|
||||
let prev_mode = unsafe {
|
||||
ffi::lua_gc(state, ffi::LUA_GCPARAM, ffi::LUA_GCPMINORMUL, minor_multiplier);
|
||||
ffi::lua_gc(state, ffi::LUA_GCPARAM, ffi::LUA_GCPMINORMAJOR, major_multiplier);
|
||||
// TODO: LUA_GCPMAJORMINOR
|
||||
ffi::lua_gc(state, ffi::LUA_GCGEN)
|
||||
};
|
||||
#[cfg(not(feature = "lua55"))]
|
||||
let prev_mode = unsafe { ffi::lua_gc(state, ffi::LUA_GCGEN, minor_multiplier, major_multiplier) };
|
||||
match prev_mode {
|
||||
ffi::LUA_GCGEN => GCMode::Generational,
|
||||
@@ -1183,6 +1252,17 @@ impl Lua {
|
||||
unsafe { self.lock().create_string(s.as_ref()) }
|
||||
}
|
||||
|
||||
/// Creates and returns an external Lua string.
|
||||
///
|
||||
/// External string is a string where the memory is managed by Rust code, and Lua only holds a
|
||||
/// reference to it. This can be used to avoid copying large strings into Lua memory.
|
||||
#[cfg(feature = "lua55")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "lua55")))]
|
||||
#[inline]
|
||||
pub fn create_external_string(&self, s: impl Into<Vec<u8>>) -> Result<String> {
|
||||
unsafe { self.lock().create_external_string(s.into()) }
|
||||
}
|
||||
|
||||
/// Creates and returns a Luau [buffer] object from a byte slice of data.
|
||||
///
|
||||
/// [buffer]: https://luau.org/library#buffer-library
|
||||
@@ -1317,7 +1397,12 @@ impl Lua {
|
||||
/// This function is unsafe because provides a way to execute unsafe C function.
|
||||
pub unsafe fn create_c_function(&self, func: ffi::lua_CFunction) -> Result<Function> {
|
||||
let lua = self.lock();
|
||||
if cfg!(any(feature = "lua54", feature = "lua53", feature = "lua52")) {
|
||||
if cfg!(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52"
|
||||
)) {
|
||||
ffi::lua_pushcfunction(lua.ref_thread(), func);
|
||||
return Ok(Function(lua.pop_ref_thread()));
|
||||
}
|
||||
@@ -1578,7 +1663,7 @@ impl Lua {
|
||||
unsafe {
|
||||
let _sg = StackGuard::new(state);
|
||||
assert_stack(state, 1);
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
ffi::lua_rawgeti(state, ffi::LUA_REGISTRYINDEX, ffi::LUA_RIDX_GLOBALS);
|
||||
#[cfg(any(feature = "lua51", feature = "luajit", feature = "luau"))]
|
||||
ffi::lua_pushvalue(state, ffi::LUA_GLOBALSINDEX);
|
||||
@@ -1610,7 +1695,7 @@ impl Lua {
|
||||
|
||||
lua.push_ref(&globals.0);
|
||||
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
ffi::lua_rawseti(state, ffi::LUA_REGISTRYINDEX, ffi::LUA_RIDX_GLOBALS);
|
||||
#[cfg(any(feature = "lua51", feature = "luajit", feature = "luau"))]
|
||||
ffi::lua_replace(state, ffi::LUA_GLOBALSINDEX);
|
||||
@@ -2098,7 +2183,7 @@ impl Lua {
|
||||
|
||||
/// Suspends the current async function, returning the provided arguments to caller.
|
||||
///
|
||||
/// This function is similar to [`coroutine.yield`] but allow yeilding Rust functions
|
||||
/// This function is similar to [`coroutine.yield`] but allow yielding Rust functions
|
||||
/// and passing values to the caller.
|
||||
/// Please note that you cannot cross [`Thread`] boundaries (e.g. calling `yield_with` on one
|
||||
/// thread and resuming on another).
|
||||
@@ -2210,7 +2295,7 @@ impl Lua {
|
||||
})?,
|
||||
)?;
|
||||
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
let searchers: Table = package.get("searchers")?;
|
||||
#[cfg(any(feature = "lua51", feature = "luajit"))]
|
||||
let searchers: Table = package.get("loaders")?;
|
||||
|
||||
+2
-2
@@ -77,7 +77,7 @@ pub(crate) struct ExtraData {
|
||||
pub(super) hook_callback: Option<crate::types::HookCallback>,
|
||||
#[cfg(not(feature = "luau"))]
|
||||
pub(super) hook_triggers: crate::debug::HookTriggers,
|
||||
#[cfg(feature = "lua54")]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54"))]
|
||||
pub(super) warn_callback: Option<crate::types::WarnCallback>,
|
||||
#[cfg(feature = "luau")]
|
||||
pub(super) interrupt_callback: Option<crate::types::InterruptCallback>,
|
||||
@@ -182,7 +182,7 @@ impl ExtraData {
|
||||
hook_callback: None,
|
||||
#[cfg(not(feature = "luau"))]
|
||||
hook_triggers: Default::default(),
|
||||
#[cfg(feature = "lua54")]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54"))]
|
||||
warn_callback: None,
|
||||
#[cfg(feature = "luau")]
|
||||
interrupt_callback: None,
|
||||
|
||||
+50
-11
@@ -122,6 +122,12 @@ impl RawLua {
|
||||
|
||||
pub(super) unsafe fn new(libs: StdLib, options: &LuaOptions) -> XRc<ReentrantMutex<Self>> {
|
||||
let mem_state: *mut MemoryState = Box::into_raw(Box::default());
|
||||
#[cfg(feature = "lua55")]
|
||||
let mut state = {
|
||||
let seed = ffi::luaL_makeseed(ptr::null_mut());
|
||||
ffi::lua_newstate(ALLOCATOR, mem_state as *mut c_void, seed)
|
||||
};
|
||||
#[cfg(not(feature = "lua55"))]
|
||||
let mut state = ffi::lua_newstate(ALLOCATOR, mem_state as *mut c_void);
|
||||
// If state is null then switch to Lua internal allocator
|
||||
if state.is_null() {
|
||||
@@ -153,7 +159,7 @@ impl RawLua {
|
||||
(|| -> Result<()> {
|
||||
let _sg = StackGuard::new(state);
|
||||
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
ffi::lua_rawgeti(state, ffi::LUA_REGISTRYINDEX, ffi::LUA_RIDX_GLOBALS);
|
||||
#[cfg(any(feature = "lua51", feature = "luajit", feature = "luau"))]
|
||||
ffi::lua_pushvalue(state, ffi::LUA_GLOBALSINDEX);
|
||||
@@ -416,7 +422,7 @@ impl RawLua {
|
||||
VmState::Yield => {
|
||||
// Only count and line events can yield
|
||||
if event == ffi::LUA_HOOKCOUNT || event == ffi::LUA_HOOKLINE {
|
||||
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53"))]
|
||||
if ffi::lua_isyieldable(state) != 0 {
|
||||
ffi::lua_yield(state, 0);
|
||||
}
|
||||
@@ -523,6 +529,23 @@ impl RawLua {
|
||||
Ok(String(self.pop_ref()))
|
||||
}
|
||||
|
||||
/// Creates an external string, that is, a string that uses memory not managed by Lua.
|
||||
///
|
||||
/// Modifies the input data to add `\0` terminator.
|
||||
#[cfg(feature = "lua55")]
|
||||
pub(crate) unsafe fn create_external_string(&self, bytes: Vec<u8>) -> Result<String> {
|
||||
let state = self.state();
|
||||
if self.unlikely_memory_error() {
|
||||
crate::util::push_external_string(state, bytes, false)?;
|
||||
return Ok(String(self.pop_ref()));
|
||||
}
|
||||
|
||||
let _sg = StackGuard::new(state);
|
||||
check_stack(state, 3)?;
|
||||
crate::util::push_external_string(state, bytes, true)?;
|
||||
Ok(String(self.pop_ref()))
|
||||
}
|
||||
|
||||
#[cfg(feature = "luau")]
|
||||
pub(crate) unsafe fn create_buffer_with_capacity(&self, size: usize) -> Result<(*mut u8, crate::Buffer)> {
|
||||
let state = self.state();
|
||||
@@ -709,14 +732,14 @@ impl RawLua {
|
||||
///
|
||||
/// Uses up to 2 stack spaces to push a single value, does not call `checkstack`.
|
||||
#[inline(always)]
|
||||
pub(crate) unsafe fn push(&self, value: impl IntoLua) -> Result<()> {
|
||||
pub unsafe fn push(&self, value: impl IntoLua) -> Result<()> {
|
||||
value.push_into_stack(self)
|
||||
}
|
||||
|
||||
/// Pushes a `Value` (by reference) onto the Lua stack.
|
||||
///
|
||||
/// Uses 2 stack spaces, does not call `checkstack`.
|
||||
pub(crate) unsafe fn push_value(&self, value: &Value) -> Result<()> {
|
||||
pub unsafe fn push_value(&self, value: &Value) -> Result<()> {
|
||||
let state = self.state();
|
||||
match value {
|
||||
Value::Nil => ffi::lua_pushnil(state),
|
||||
@@ -750,7 +773,8 @@ impl RawLua {
|
||||
/// Pops a value from the Lua stack.
|
||||
///
|
||||
/// Uses up to 1 stack spaces, does not call `checkstack`.
|
||||
pub(crate) unsafe fn pop_value(&self) -> Value {
|
||||
#[inline]
|
||||
pub unsafe fn pop_value(&self) -> Value {
|
||||
let value = self.stack_value(-1, None);
|
||||
ffi::lua_pop(self.state(), 1);
|
||||
value
|
||||
@@ -768,7 +792,7 @@ impl RawLua {
|
||||
|
||||
ffi::LUA_TLIGHTUSERDATA => Value::LightUserData(LightUserData(ffi::lua_touserdata(state, idx))),
|
||||
|
||||
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53"))]
|
||||
ffi::LUA_TNUMBER => {
|
||||
if ffi::lua_isinteger(state, idx) != 0 {
|
||||
Value::Integer(ffi::lua_tointeger(state, idx))
|
||||
@@ -899,7 +923,7 @@ impl RawLua {
|
||||
#[cfg(any(feature = "lua51", feature = "luajit", feature = "luau"))]
|
||||
ffi::lua_xpush(self.ref_thread(), state, ExtraData::ERROR_TRACEBACK_IDX);
|
||||
// Lua 5.2+ support light C functions that does not require extra allocations
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
ffi::lua_pushcfunction(state, crate::util::error_traceback);
|
||||
}
|
||||
|
||||
@@ -1195,7 +1219,10 @@ impl RawLua {
|
||||
Ok(type_id) => Ok(type_id),
|
||||
Err(Error::UserDataTypeMismatch) if ffi::lua_type(state, idx) != ffi::LUA_TUSERDATA => {
|
||||
// Report `FromLuaConversionError` instead
|
||||
let idx_type_name = CStr::from_ptr(ffi::luaL_typename(state, idx));
|
||||
// In Luau `luaL_typename` return heap-allocated string that is valid only for
|
||||
// the `state` lifetime.
|
||||
// `lua_typename` is used instead to get a truly static string.
|
||||
let idx_type_name = CStr::from_ptr(ffi::lua_typename(state, ffi::lua_type(state, idx)));
|
||||
let idx_type_name = idx_type_name.to_str().unwrap();
|
||||
let message = format!("expected userdata of type '{}'", short_type_name::<T>());
|
||||
Err(Error::from_lua_conversion(idx_type_name, "userdata", message))
|
||||
@@ -1279,7 +1306,13 @@ impl RawLua {
|
||||
#[cfg(feature = "async")]
|
||||
pub(crate) fn create_async_callback(&self, func: AsyncCallback) -> Result<Function> {
|
||||
// Ensure that the coroutine library is loaded
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luau"))]
|
||||
#[cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "luau"
|
||||
))]
|
||||
unsafe {
|
||||
if !(*self.extra.get()).libs.contains(StdLib::COROUTINE) {
|
||||
load_std_libs(self.main_state(), StdLib::COROUTINE)?;
|
||||
@@ -1492,7 +1525,13 @@ unsafe fn load_std_libs(state: *mut ffi::lua_State, libs: StdLib) -> Result<()>
|
||||
#[cfg(feature = "luajit")]
|
||||
let _gc_guard = GcGuard::new(state);
|
||||
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luau"))]
|
||||
#[cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "luau"
|
||||
))]
|
||||
{
|
||||
if libs.contains(StdLib::COROUTINE) {
|
||||
requiref(state, ffi::LUA_COLIBNAME, ffi::luaopen_coroutine, 1)?;
|
||||
@@ -1516,7 +1555,7 @@ unsafe fn load_std_libs(state: *mut ffi::lua_State, libs: StdLib) -> Result<()>
|
||||
requiref(state, ffi::LUA_STRLIBNAME, ffi::luaopen_string, 1)?;
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "luau"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "luau"))]
|
||||
{
|
||||
if libs.contains(StdLib::UTF8) {
|
||||
requiref(state, ffi::LUA_UTF8LIBNAME, ffi::luaopen_utf8, 1)?;
|
||||
|
||||
+19
-4
@@ -6,10 +6,22 @@ pub struct StdLib(u32);
|
||||
|
||||
impl StdLib {
|
||||
/// [`coroutine`](https://www.lua.org/manual/5.4/manual.html#6.2) library
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luau"))]
|
||||
#[cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "luau"
|
||||
))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
doc(cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luau")))
|
||||
doc(cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "luau"
|
||||
)))
|
||||
)]
|
||||
pub const COROUTINE: StdLib = StdLib(1);
|
||||
|
||||
@@ -28,8 +40,11 @@ impl StdLib {
|
||||
pub const STRING: StdLib = StdLib(1 << 4);
|
||||
|
||||
/// [`utf8`](https://www.lua.org/manual/5.4/manual.html#6.5) library
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "luau"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(any(feature = "lua54", feature = "lua53", feature = "luau"))))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "luau"))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
doc(cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "luau")))
|
||||
)]
|
||||
pub const UTF8: StdLib = StdLib(1 << 5);
|
||||
|
||||
/// [`bit`](https://www.lua.org/manual/5.2/manual.html#6.7) library
|
||||
|
||||
+4
-4
@@ -336,22 +336,22 @@ impl Thread {
|
||||
}
|
||||
ThreadStatusInner::Running => Err(Error::runtime("cannot reset a running thread")),
|
||||
ThreadStatusInner::Finished => Ok(()),
|
||||
#[cfg(not(any(feature = "lua54", feature = "luau")))]
|
||||
#[cfg(not(any(feature = "lua55", feature = "lua54", feature = "luau")))]
|
||||
ThreadStatusInner::Yielded(_) | ThreadStatusInner::Error => {
|
||||
Err(Error::runtime("cannot reset non-finished thread"))
|
||||
}
|
||||
#[cfg(any(feature = "lua54", feature = "luau"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "luau"))]
|
||||
ThreadStatusInner::Yielded(_) | ThreadStatusInner::Error => {
|
||||
let thread_state = self.state();
|
||||
|
||||
#[cfg(all(feature = "lua54", not(feature = "vendored")))]
|
||||
let status = ffi::lua_resetthread(thread_state);
|
||||
#[cfg(all(feature = "lua54", feature = "vendored"))]
|
||||
#[cfg(any(feature = "lua55", all(feature = "lua54", feature = "vendored")))]
|
||||
let status = {
|
||||
let lua = self.0.lua.lock();
|
||||
ffi::lua_closethread(thread_state, lua.state())
|
||||
};
|
||||
#[cfg(feature = "lua54")]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54"))]
|
||||
if status != ffi::LUA_OK {
|
||||
return Err(pop_error(thread_state, status));
|
||||
}
|
||||
|
||||
+4
-2
@@ -108,10 +108,12 @@ pub(crate) type ThreadCollectionCallback = XRc<dyn Fn(crate::LightUserData) + Se
|
||||
#[cfg(all(not(feature = "send"), feature = "luau"))]
|
||||
pub(crate) type ThreadCollectionCallback = XRc<dyn Fn(crate::LightUserData)>;
|
||||
|
||||
#[cfg(all(feature = "send", feature = "lua54"))]
|
||||
#[cfg(feature = "send")]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54"))]
|
||||
pub(crate) type WarnCallback = XRc<dyn Fn(&Lua, &str, bool) -> Result<()> + Send>;
|
||||
|
||||
#[cfg(all(not(feature = "send"), feature = "lua54"))]
|
||||
#[cfg(not(feature = "send"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54"))]
|
||||
pub(crate) type WarnCallback = XRc<dyn Fn(&Lua, &str, bool) -> Result<()>>;
|
||||
|
||||
/// A trait that adds `Send` requirement if `send` feature is enabled.
|
||||
|
||||
+74
-27
@@ -56,32 +56,53 @@ pub enum MetaMethod {
|
||||
/// The unary minus (`-`) operator.
|
||||
Unm,
|
||||
/// The floor division (//) operator.
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "luau"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(any(feature = "lua54", feature = "lua53", feature = "luau"))))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "luau"))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
doc(cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "luau")))
|
||||
)]
|
||||
IDiv,
|
||||
/// The bitwise AND (&) operator.
|
||||
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(any(feature = "lua54", feature = "lua53"))))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53"))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
doc(cfg(any(feature = "lua55", feature = "lua54", feature = "lua53")))
|
||||
)]
|
||||
BAnd,
|
||||
/// The bitwise OR (|) operator.
|
||||
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(any(feature = "lua54", feature = "lua53"))))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53"))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
doc(cfg(any(feature = "lua55", feature = "lua54", feature = "lua53")))
|
||||
)]
|
||||
BOr,
|
||||
/// The bitwise XOR (binary ~) operator.
|
||||
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(any(feature = "lua54", feature = "lua53"))))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53"))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
doc(cfg(any(feature = "lua55", feature = "lua54", feature = "lua53")))
|
||||
)]
|
||||
BXor,
|
||||
/// The bitwise NOT (unary ~) operator.
|
||||
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(any(feature = "lua54", feature = "lua53"))))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53"))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
doc(cfg(any(feature = "lua55", feature = "lua54", feature = "lua53")))
|
||||
)]
|
||||
BNot,
|
||||
/// The bitwise left shift (<<) operator.
|
||||
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(any(feature = "lua54", feature = "lua53"))))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53"))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
doc(cfg(any(feature = "lua55", feature = "lua54", feature = "lua53")))
|
||||
)]
|
||||
Shl,
|
||||
/// The bitwise right shift (>>) operator.
|
||||
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(any(feature = "lua54", feature = "lua53"))))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53"))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
doc(cfg(any(feature = "lua55", feature = "lua54", feature = "lua53")))
|
||||
)]
|
||||
Shr,
|
||||
/// The string concatenation operator `..`.
|
||||
Concat,
|
||||
@@ -106,10 +127,22 @@ pub enum MetaMethod {
|
||||
/// The `__pairs` metamethod.
|
||||
///
|
||||
/// This is not an operator, but it will be called by the built-in `pairs` function.
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luajit52"))]
|
||||
#[cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "luajit52"
|
||||
))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
doc(cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luajit52")))
|
||||
doc(cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "luajit52"
|
||||
)))
|
||||
)]
|
||||
Pairs,
|
||||
/// The `__ipairs` metamethod.
|
||||
@@ -135,8 +168,8 @@ pub enum MetaMethod {
|
||||
/// [documentation][lua_doc].
|
||||
///
|
||||
/// [lua_doc]: https://www.lua.org/manual/5.4/manual.html#3.3.8
|
||||
#[cfg(feature = "lua54")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "lua54")))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(any(feature = "lua55", feature = "lua54"))))]
|
||||
Close,
|
||||
/// The `__name`/`__type` metafield.
|
||||
///
|
||||
@@ -176,19 +209,19 @@ impl MetaMethod {
|
||||
MetaMethod::Pow => "__pow",
|
||||
MetaMethod::Unm => "__unm",
|
||||
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "luau"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "luau"))]
|
||||
MetaMethod::IDiv => "__idiv",
|
||||
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53"))]
|
||||
MetaMethod::BAnd => "__band",
|
||||
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53"))]
|
||||
MetaMethod::BOr => "__bor",
|
||||
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53"))]
|
||||
MetaMethod::BXor => "__bxor",
|
||||
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53"))]
|
||||
MetaMethod::BNot => "__bnot",
|
||||
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53"))]
|
||||
MetaMethod::Shl => "__shl",
|
||||
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53"))]
|
||||
MetaMethod::Shr => "__shr",
|
||||
|
||||
MetaMethod::Concat => "__concat",
|
||||
@@ -201,14 +234,20 @@ impl MetaMethod {
|
||||
MetaMethod::Call => "__call",
|
||||
MetaMethod::ToString => "__tostring",
|
||||
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luajit52"))]
|
||||
#[cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "luajit52"
|
||||
))]
|
||||
MetaMethod::Pairs => "__pairs",
|
||||
#[cfg(any(feature = "lua52", feature = "luajit52"))]
|
||||
MetaMethod::IPairs => "__ipairs",
|
||||
#[cfg(feature = "luau")]
|
||||
MetaMethod::Iter => "__iter",
|
||||
|
||||
#[cfg(feature = "lua54")]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54"))]
|
||||
MetaMethod::Close => "__close",
|
||||
|
||||
#[rustfmt::skip]
|
||||
@@ -679,6 +718,14 @@ impl AnyUserData {
|
||||
matches!(type_id, Some(type_id) if type_id == TypeId::of::<T>())
|
||||
}
|
||||
|
||||
/// Checks whether the type of this userdata is a [proxy object] for `T`.
|
||||
///
|
||||
/// [proxy object]: crate::Lua::create_proxy
|
||||
#[inline]
|
||||
pub fn is_proxy<T: 'static>(&self) -> bool {
|
||||
self.is::<UserDataProxy<T>>()
|
||||
}
|
||||
|
||||
/// Borrow this userdata immutably if it is of type `T`.
|
||||
///
|
||||
/// # Errors
|
||||
|
||||
+17
-11
@@ -208,7 +208,7 @@ where
|
||||
F: FnOnce(*mut ffi::lua_State) -> R,
|
||||
R: Copy,
|
||||
{
|
||||
let params = ffi::lua_touserdata(state, -1) as *mut Params<F, R>;
|
||||
let params = ffi::lua_tolightuserdata(state, -1) as *mut Params<F, R>;
|
||||
ffi::lua_pop(state, 1);
|
||||
|
||||
let f = (*params).function.take().unwrap();
|
||||
@@ -239,7 +239,7 @@ where
|
||||
|
||||
ffi::lua_pushlightuserdata(state, &mut params as *mut Params<F, R> as *mut c_void);
|
||||
let ret = ffi::lua_pcall(state, nargs + 1, nresults, stack_start + 1);
|
||||
ffi::lua_remove(state, stack_start + 1);
|
||||
ffi::lua_remove(state, stack_start + 1); // remove error handler
|
||||
|
||||
if ret == ffi::LUA_OK {
|
||||
// `LUA_OK` is only returned when the `do_call` function has completed successfully, so
|
||||
@@ -373,19 +373,19 @@ pub(crate) unsafe fn init_error_registry(state: *mut ffi::lua_State) -> Result<(
|
||||
"__mod",
|
||||
"__pow",
|
||||
"__unm",
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "luau"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "luau"))]
|
||||
"__idiv",
|
||||
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53"))]
|
||||
"__band",
|
||||
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53"))]
|
||||
"__bor",
|
||||
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53"))]
|
||||
"__bxor",
|
||||
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53"))]
|
||||
"__bnot",
|
||||
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53"))]
|
||||
"__shl",
|
||||
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53"))]
|
||||
"__shr",
|
||||
"__concat",
|
||||
"__len",
|
||||
@@ -396,7 +396,13 @@ pub(crate) unsafe fn init_error_registry(state: *mut ffi::lua_State) -> Result<(
|
||||
"__newindex",
|
||||
"__call",
|
||||
"__tostring",
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luajit52"))]
|
||||
#[cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "luajit52"
|
||||
))]
|
||||
"__pairs",
|
||||
#[cfg(any(feature = "lua53", feature = "lua52", feature = "luajit52"))]
|
||||
"__ipairs",
|
||||
@@ -404,7 +410,7 @@ pub(crate) unsafe fn init_error_registry(state: *mut ffi::lua_State) -> Result<(
|
||||
"__iter",
|
||||
#[cfg(feature = "luau")]
|
||||
"__namecall",
|
||||
#[cfg(feature = "lua54")]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54"))]
|
||||
"__close",
|
||||
] {
|
||||
ffi::lua_pushvalue(state, -1);
|
||||
|
||||
+33
-1
@@ -99,6 +99,38 @@ pub(crate) unsafe fn push_string(state: *mut ffi::lua_State, s: &[u8], protect:
|
||||
}
|
||||
}
|
||||
|
||||
// Uses 3 (or 1 if unprotected) stack spaces, does not call checkstack.
|
||||
#[cfg(feature = "lua55")]
|
||||
pub(crate) unsafe fn push_external_string(
|
||||
state: *mut ffi::lua_State,
|
||||
mut bytes: Vec<u8>,
|
||||
protect: bool,
|
||||
) -> Result<()> {
|
||||
bytes.push(0);
|
||||
let s_len = bytes.len() - 1; // exclude null terminator
|
||||
let s_ptr = bytes.as_ptr() as *const c_char;
|
||||
let bytes_ud = Box::into_raw(Box::new(bytes));
|
||||
|
||||
unsafe extern "C" fn dealloc(ud: *mut c_void, _: *mut c_void, _: usize, _: usize) -> *mut c_void {
|
||||
drop(Box::from_raw(ud as *mut Vec<u8>));
|
||||
ptr::null_mut()
|
||||
}
|
||||
|
||||
if protect {
|
||||
let res = protect_lua!(state, 0, 1, move |state| {
|
||||
ffi::lua_pushexternalstring(state, s_ptr, s_len, Some(dealloc), bytes_ud as *mut _);
|
||||
});
|
||||
if res.is_err() {
|
||||
// Deallocate on error
|
||||
drop(Box::from_raw(bytes_ud));
|
||||
return res;
|
||||
}
|
||||
} else {
|
||||
ffi::lua_pushexternalstring(state, s_ptr, s_len, Some(dealloc), bytes_ud as *mut _);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Uses 3 stack spaces (when protect), does not call checkstack.
|
||||
#[cfg(feature = "luau")]
|
||||
#[inline(always)]
|
||||
@@ -220,7 +252,7 @@ pub(crate) unsafe extern "C-unwind" fn safe_xpcall(state: *mut ffi::lua_State) -
|
||||
// Returns Lua main thread for Lua >= 5.2 or checks that the passed thread is main for Lua 5.1.
|
||||
// Does not call lua_checkstack, uses 1 stack space.
|
||||
pub(crate) unsafe fn get_main_state(state: *mut ffi::lua_State) -> Option<*mut ffi::lua_State> {
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
{
|
||||
ffi::lua_rawgeti(state, ffi::LUA_REGISTRYINDEX, ffi::LUA_RIDX_MAINTHREAD);
|
||||
let main_state = ffi::lua_tothread(state, -1);
|
||||
|
||||
+6
-6
@@ -1,11 +1,11 @@
|
||||
[lua54]
|
||||
features = "lua54,vendored,async,send,serde,macros,anyhow,userdata-wrappers"
|
||||
[lua55]
|
||||
features = "lua55,vendored,async,send,serde,macros,anyhow,userdata-wrappers"
|
||||
|
||||
[lua54_non_send]
|
||||
features = "lua54,vendored,async,serde,macros,anyhow,userdata-wrappers"
|
||||
[lua55_non_send]
|
||||
features = "lua55,vendored,async,serde,macros,anyhow,userdata-wrappers"
|
||||
|
||||
[lua54_with_memory_limit]
|
||||
features = "lua54,vendored,async,send,serde,macros,anyhow,userdata-wrappers"
|
||||
[lua55_with_memory_limit]
|
||||
features = "lua55,vendored,async,send,serde,macros,anyhow,userdata-wrappers"
|
||||
rustflags = "--cfg force_memory_limit"
|
||||
|
||||
[lua51]
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ async fn test_async_return_async_closure() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "lua54")]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54"))]
|
||||
#[tokio::test]
|
||||
async fn test_async_lua54_to_be_closed() -> Result<()> {
|
||||
let lua = Lua::new();
|
||||
@@ -670,7 +670,7 @@ async fn test_async_hook() -> Result<()> {
|
||||
static HOOK_CALLED: AtomicBool = AtomicBool::new(false);
|
||||
lua.set_global_hook(mlua::HookTriggers::new().every_line(), move |_, _| {
|
||||
if !HOOK_CALLED.swap(true, Ordering::Relaxed) {
|
||||
#[cfg(any(feature = "lu53", feature = "lua54"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53"))]
|
||||
return Ok(mlua::VmState::Yield);
|
||||
}
|
||||
Ok(mlua::VmState::Continue)
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
error[E0596]: cannot borrow `s` as mutable, as it is a captured variable in a `Fn` closure
|
||||
--> tests/compile/async_any_userdata_method.rs:9:49
|
||||
|
|
||||
9 | reg.add_async_method("t", |_, this, ()| async {
|
||||
| ^^^^^ cannot borrow as mutable
|
||||
8 | let mut s = &s;
|
||||
| ----- `s` declared here, outside the closure
|
||||
9 | reg.add_async_method("t", |_, this, ()| async {
|
||||
| ------------- ^^^^^ cannot borrow as mutable
|
||||
| |
|
||||
| in this closure
|
||||
10 | s = &*this;
|
||||
| - mutable borrow occurs due to use of `s` in closure
|
||||
|
||||
error[E0373]: async block may outlive the current function, but it borrows `this`, which is owned by the current function
|
||||
--> tests/compile/async_any_userdata_method.rs:9:49
|
||||
|
|
||||
9 | reg.add_async_method("t", |_, this, ()| async {
|
||||
9 | reg.add_async_method("t", |_, this, ()| async {
|
||||
| ^^^^^ may outlive borrowed value `this`
|
||||
10 | s = &*this;
|
||||
| ---- `this` is borrowed here
|
||||
@@ -17,7 +21,7 @@ error[E0373]: async block may outlive the current function, but it borrows `this
|
||||
note: async block is returned here
|
||||
--> tests/compile/async_any_userdata_method.rs:9:49
|
||||
|
|
||||
9 | reg.add_async_method("t", |_, this, ()| async {
|
||||
9 | reg.add_async_method("t", |_, this, ()| async {
|
||||
| _________________________________________________^
|
||||
10 | | s = &*this;
|
||||
11 | | Ok(())
|
||||
@@ -25,13 +29,13 @@ note: async block is returned here
|
||||
| |_________^
|
||||
help: to force the async block to take ownership of `this` (and any other referenced variables), use the `move` keyword
|
||||
|
|
||||
9 | reg.add_async_method("t", |_, this, ()| async move {
|
||||
9 | reg.add_async_method("t", |_, this, ()| async move {
|
||||
| ++++
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> tests/compile/async_any_userdata_method.rs:9:49
|
||||
|
|
||||
9 | reg.add_async_method("t", |_, this, ()| async {
|
||||
9 | reg.add_async_method("t", |_, this, ()| async {
|
||||
| ___________________________________-------------_^
|
||||
| | | |
|
||||
| | | return type of closure `{async block@$DIR/tests/compile/async_any_userdata_method.rs:9:49: 9:54}` contains a lifetime `'2`
|
||||
@@ -46,22 +50,28 @@ error: lifetime may not live long enough
|
||||
error[E0597]: `s` does not live long enough
|
||||
--> tests/compile/async_any_userdata_method.rs:8:21
|
||||
|
|
||||
7 | let s = String::new();
|
||||
7 | let s = String::new();
|
||||
| - binding `s` declared here
|
||||
8 | let mut s = &s;
|
||||
8 | let mut s = &s;
|
||||
| ^^ borrowed value does not live long enough
|
||||
9 | / reg.add_async_method("t", |_, this, ()| async {
|
||||
9 | / reg.add_async_method("t", |_, this, ()| async {
|
||||
10 | | s = &*this;
|
||||
11 | | Ok(())
|
||||
12 | | });
|
||||
| |__________- argument requires that `s` is borrowed for `'static`
|
||||
13 | })
|
||||
| - `s` dropped here while still borrowed
|
||||
|
|
||||
note: requirement that the value outlives `'static` introduced here
|
||||
--> src/userdata.rs
|
||||
|
|
||||
| M: Fn(Lua, UserDataRef<T>, A) -> MR + MaybeSend + 'static,
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0373]: closure may outlive the current function, but it borrows `s`, which is owned by the current function
|
||||
--> tests/compile/async_any_userdata_method.rs:9:35
|
||||
|
|
||||
9 | reg.add_async_method("t", |_, this, ()| async {
|
||||
9 | reg.add_async_method("t", |_, this, ()| async {
|
||||
| ^^^^^^^^^^^^^ may outlive borrowed value `s`
|
||||
10 | s = &*this;
|
||||
| - `s` is borrowed here
|
||||
@@ -69,12 +79,12 @@ error[E0373]: closure may outlive the current function, but it borrows `s`, whic
|
||||
note: function requires argument type to outlive `'static`
|
||||
--> tests/compile/async_any_userdata_method.rs:9:9
|
||||
|
|
||||
9 | / reg.add_async_method("t", |_, this, ()| async {
|
||||
9 | / reg.add_async_method("t", |_, this, ()| async {
|
||||
10 | | s = &*this;
|
||||
11 | | Ok(())
|
||||
12 | | });
|
||||
| |__________^
|
||||
help: to force the closure to take ownership of `s` (and any other referenced variables), use the `move` keyword
|
||||
|
|
||||
9 | reg.add_async_method("t", move |_, this, ()| async {
|
||||
9 | reg.add_async_method("t", move |_, this, ()| async {
|
||||
| ++++
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
error: lifetime may not live long enough
|
||||
--> tests/compile/async_nonstatic_userdata.rs:9:13
|
||||
|
|
||||
7 | impl UserData for MyUserData<'_> {
|
||||
7 | impl UserData for MyUserData<'_> {
|
||||
| -- lifetime `'1` appears in the `impl`'s self type
|
||||
8 | fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
||||
9 | / methods.add_async_method("print", |_, data, ()| async move {
|
||||
8 | fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
||||
9 | / methods.add_async_method("print", |_, data, ()| async move {
|
||||
10 | | println!("{}", data.0);
|
||||
11 | | Ok(())
|
||||
12 | | });
|
||||
|
||||
@@ -1,28 +1,32 @@
|
||||
error[E0277]: the type `UnsafeCell<*mut lua_State>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
||||
error[E0277]: the type `UnsafeCell<mlua::state::raw::RawLua>` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary
|
||||
--> tests/compile/lua_norefunwindsafe.rs:7:18
|
||||
|
|
||||
7 | catch_unwind(|| lua.create_table().unwrap());
|
||||
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<*mut lua_State>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
||||
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<mlua::state::raw::RawLua>` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: within `mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<*mut lua_State>`
|
||||
note: required because it appears within the type `Cell<*mut lua_State>`
|
||||
--> $RUST/core/src/cell.rs
|
||||
= help: within `Lua`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<mlua::state::raw::RawLua>`
|
||||
note: required because it appears within the type `lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>`
|
||||
--> $CARGO/lock_api-$VERSION/src/remutex.rs
|
||||
|
|
||||
| pub struct Cell<T: ?Sized> {
|
||||
| ^^^^
|
||||
note: required because it appears within the type `mlua::state::raw::RawLua`
|
||||
--> src/state/raw.rs
|
||||
| pub struct ReentrantMutex<R, G, T: ?Sized> {
|
||||
| ^^^^^^^^^^^^^^
|
||||
note: required because it appears within the type `alloc::sync::ArcInner<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>`
|
||||
--> $RUST/alloc/src/sync.rs
|
||||
|
|
||||
| pub struct RawLua {
|
||||
| ^^^^^^
|
||||
note: required because it appears within the type `mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>`
|
||||
--> src/types/sync.rs
|
||||
| struct ArcInner<T: ?Sized> {
|
||||
| ^^^^^^^^
|
||||
note: required because it appears within the type `PhantomData<alloc::sync::ArcInner<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>>`
|
||||
--> $RUST/core/src/marker.rs
|
||||
|
|
||||
| pub(crate) struct ReentrantMutex<T>(T);
|
||||
| ^^^^^^^^^^^^^^
|
||||
= note: required for `Rc<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>` to implement `RefUnwindSafe`
|
||||
| pub struct PhantomData<T: PointeeSized>;
|
||||
| ^^^^^^^^^^^
|
||||
note: required because it appears within the type `Arc<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>`
|
||||
--> $RUST/alloc/src/sync.rs
|
||||
|
|
||||
| pub struct Arc<
|
||||
| ^^^
|
||||
note: required because it appears within the type `Lua`
|
||||
--> src/state.rs
|
||||
|
|
||||
@@ -40,27 +44,45 @@ note: required by a bound in `std::panic::catch_unwind`
|
||||
| pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
|
||||
| ^^^^^^^^^^ required by this bound in `catch_unwind`
|
||||
|
||||
error[E0277]: the type `UnsafeCell<mlua::state::extra::ExtraData>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
||||
error[E0277]: the type `UnsafeCell<usize>` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary
|
||||
--> tests/compile/lua_norefunwindsafe.rs:7:18
|
||||
|
|
||||
7 | catch_unwind(|| lua.create_table().unwrap());
|
||||
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<mlua::state::extra::ExtraData>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
||||
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<usize>` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: the trait `RefUnwindSafe` is not implemented for `UnsafeCell<mlua::state::extra::ExtraData>`
|
||||
= note: required for `Rc<UnsafeCell<mlua::state::extra::ExtraData>>` to implement `RefUnwindSafe`
|
||||
note: required because it appears within the type `mlua::state::raw::RawLua`
|
||||
--> src/state/raw.rs
|
||||
= help: within `Lua`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<usize>`
|
||||
note: required because it appears within the type `Cell<usize>`
|
||||
--> $RUST/core/src/cell.rs
|
||||
|
|
||||
| pub struct RawLua {
|
||||
| ^^^^^^
|
||||
note: required because it appears within the type `mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>`
|
||||
--> src/types/sync.rs
|
||||
| pub struct Cell<T: ?Sized> {
|
||||
| ^^^^
|
||||
note: required because it appears within the type `lock_api::remutex::RawReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId>`
|
||||
--> $CARGO/lock_api-$VERSION/src/remutex.rs
|
||||
|
|
||||
| pub(crate) struct ReentrantMutex<T>(T);
|
||||
| ^^^^^^^^^^^^^^
|
||||
= note: required for `Rc<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>` to implement `RefUnwindSafe`
|
||||
| pub struct RawReentrantMutex<R, G> {
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
note: required because it appears within the type `lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>`
|
||||
--> $CARGO/lock_api-$VERSION/src/remutex.rs
|
||||
|
|
||||
| pub struct ReentrantMutex<R, G, T: ?Sized> {
|
||||
| ^^^^^^^^^^^^^^
|
||||
note: required because it appears within the type `alloc::sync::ArcInner<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>`
|
||||
--> $RUST/alloc/src/sync.rs
|
||||
|
|
||||
| struct ArcInner<T: ?Sized> {
|
||||
| ^^^^^^^^
|
||||
note: required because it appears within the type `PhantomData<alloc::sync::ArcInner<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>>`
|
||||
--> $RUST/core/src/marker.rs
|
||||
|
|
||||
| pub struct PhantomData<T: PointeeSized>;
|
||||
| ^^^^^^^^^^^
|
||||
note: required because it appears within the type `Arc<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>`
|
||||
--> $RUST/alloc/src/sync.rs
|
||||
|
|
||||
| pub struct Arc<
|
||||
| ^^^
|
||||
note: required because it appears within the type `Lua`
|
||||
--> src/state.rs
|
||||
|
|
||||
|
||||
@@ -1,143 +1,86 @@
|
||||
error[E0277]: the type `UnsafeCell<usize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
||||
error[E0277]: the type `UnsafeCell<mlua::state::raw::RawLua>` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary
|
||||
--> tests/compile/ref_nounwindsafe.rs:8:18
|
||||
|
|
||||
8 | catch_unwind(move || table.set("a", "b").unwrap());
|
||||
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<usize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
||||
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<mlua::state::raw::RawLua>` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: within `rc::RcInner<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<usize>`
|
||||
= help: within `alloc::sync::ArcInner<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<mlua::state::raw::RawLua>`
|
||||
note: required because it appears within the type `lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>`
|
||||
--> $CARGO/lock_api-$VERSION/src/remutex.rs
|
||||
|
|
||||
| pub struct ReentrantMutex<R, G, T: ?Sized> {
|
||||
| ^^^^^^^^^^^^^^
|
||||
note: required because it appears within the type `alloc::sync::ArcInner<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>`
|
||||
--> $RUST/alloc/src/sync.rs
|
||||
|
|
||||
| struct ArcInner<T: ?Sized> {
|
||||
| ^^^^^^^^
|
||||
= note: required for `NonNull<alloc::sync::ArcInner<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>>` to implement `UnwindSafe`
|
||||
note: required because it appears within the type `std::sync::Weak<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>`
|
||||
--> $RUST/alloc/src/sync.rs
|
||||
|
|
||||
| pub struct Weak<
|
||||
| ^^^^
|
||||
note: required because it appears within the type `WeakLua`
|
||||
--> src/state.rs
|
||||
|
|
||||
| pub struct WeakLua(XWeak<ReentrantMutex<RawLua>>);
|
||||
| ^^^^^^^
|
||||
note: required because it appears within the type `mlua::types::value_ref::ValueRef`
|
||||
--> src/types/value_ref.rs
|
||||
|
|
||||
| pub struct ValueRef {
|
||||
| ^^^^^^^^
|
||||
note: required because it appears within the type `LuaTable`
|
||||
--> src/table.rs
|
||||
|
|
||||
| pub struct Table(pub(crate) ValueRef);
|
||||
| ^^^^^
|
||||
note: required because it's used within this closure
|
||||
--> tests/compile/ref_nounwindsafe.rs:8:18
|
||||
|
|
||||
8 | catch_unwind(move || table.set("a", "b").unwrap());
|
||||
| ^^^^^^^
|
||||
note: required by a bound in `std::panic::catch_unwind`
|
||||
--> $RUST/std/src/panic.rs
|
||||
|
|
||||
| pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
|
||||
| ^^^^^^^^^^ required by this bound in `catch_unwind`
|
||||
|
||||
error[E0277]: the type `UnsafeCell<usize>` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary
|
||||
--> tests/compile/ref_nounwindsafe.rs:8:18
|
||||
|
|
||||
8 | catch_unwind(move || table.set("a", "b").unwrap());
|
||||
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<usize>` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: within `alloc::sync::ArcInner<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<usize>`
|
||||
note: required because it appears within the type `Cell<usize>`
|
||||
--> $RUST/core/src/cell.rs
|
||||
|
|
||||
| pub struct Cell<T: ?Sized> {
|
||||
| ^^^^
|
||||
note: required because it appears within the type `rc::RcInner<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>`
|
||||
--> $RUST/alloc/src/rc.rs
|
||||
note: required because it appears within the type `lock_api::remutex::RawReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId>`
|
||||
--> $CARGO/lock_api-$VERSION/src/remutex.rs
|
||||
|
|
||||
| struct RcInner<T: ?Sized> {
|
||||
| ^^^^^^^
|
||||
= note: required for `NonNull<rc::RcInner<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>>` to implement `UnwindSafe`
|
||||
note: required because it appears within the type `std::rc::Weak<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>`
|
||||
--> $RUST/alloc/src/rc.rs
|
||||
|
|
||||
| pub struct Weak<
|
||||
| ^^^^
|
||||
note: required because it appears within the type `WeakLua`
|
||||
--> src/state.rs
|
||||
|
|
||||
| pub struct WeakLua(XWeak<ReentrantMutex<RawLua>>);
|
||||
| ^^^^^^^
|
||||
note: required because it appears within the type `mlua::types::value_ref::ValueRef`
|
||||
--> src/types/value_ref.rs
|
||||
|
|
||||
| pub struct ValueRef {
|
||||
| ^^^^^^^^
|
||||
note: required because it appears within the type `LuaTable`
|
||||
--> src/table.rs
|
||||
|
|
||||
| pub struct Table(pub(crate) ValueRef);
|
||||
| ^^^^^
|
||||
note: required because it's used within this closure
|
||||
--> tests/compile/ref_nounwindsafe.rs:8:18
|
||||
|
|
||||
8 | catch_unwind(move || table.set("a", "b").unwrap());
|
||||
| ^^^^^^^
|
||||
note: required by a bound in `std::panic::catch_unwind`
|
||||
--> $RUST/std/src/panic.rs
|
||||
|
|
||||
| pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
|
||||
| ^^^^^^^^^^ required by this bound in `catch_unwind`
|
||||
|
||||
error[E0277]: the type `UnsafeCell<*mut lua_State>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
||||
--> tests/compile/ref_nounwindsafe.rs:8:18
|
||||
|
|
||||
8 | catch_unwind(move || table.set("a", "b").unwrap());
|
||||
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<*mut lua_State>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: within `rc::RcInner<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<*mut lua_State>`
|
||||
note: required because it appears within the type `Cell<*mut lua_State>`
|
||||
--> $RUST/core/src/cell.rs
|
||||
|
|
||||
| pub struct Cell<T: ?Sized> {
|
||||
| ^^^^
|
||||
note: required because it appears within the type `mlua::state::raw::RawLua`
|
||||
--> src/state/raw.rs
|
||||
|
|
||||
| pub struct RawLua {
|
||||
| ^^^^^^
|
||||
note: required because it appears within the type `mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>`
|
||||
--> src/types/sync.rs
|
||||
|
|
||||
| pub(crate) struct ReentrantMutex<T>(T);
|
||||
| ^^^^^^^^^^^^^^
|
||||
note: required because it appears within the type `rc::RcInner<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>`
|
||||
--> $RUST/alloc/src/rc.rs
|
||||
|
|
||||
| struct RcInner<T: ?Sized> {
|
||||
| ^^^^^^^
|
||||
= note: required for `NonNull<rc::RcInner<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>>` to implement `UnwindSafe`
|
||||
note: required because it appears within the type `std::rc::Weak<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>`
|
||||
--> $RUST/alloc/src/rc.rs
|
||||
|
|
||||
| pub struct Weak<
|
||||
| ^^^^
|
||||
note: required because it appears within the type `WeakLua`
|
||||
--> src/state.rs
|
||||
|
|
||||
| pub struct WeakLua(XWeak<ReentrantMutex<RawLua>>);
|
||||
| ^^^^^^^
|
||||
note: required because it appears within the type `mlua::types::value_ref::ValueRef`
|
||||
--> src/types/value_ref.rs
|
||||
|
|
||||
| pub struct ValueRef {
|
||||
| ^^^^^^^^
|
||||
note: required because it appears within the type `LuaTable`
|
||||
--> src/table.rs
|
||||
|
|
||||
| pub struct Table(pub(crate) ValueRef);
|
||||
| ^^^^^
|
||||
note: required because it's used within this closure
|
||||
--> tests/compile/ref_nounwindsafe.rs:8:18
|
||||
|
|
||||
8 | catch_unwind(move || table.set("a", "b").unwrap());
|
||||
| ^^^^^^^
|
||||
note: required by a bound in `std::panic::catch_unwind`
|
||||
--> $RUST/std/src/panic.rs
|
||||
|
|
||||
| pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
|
||||
| ^^^^^^^^^^ required by this bound in `catch_unwind`
|
||||
|
||||
error[E0277]: the type `UnsafeCell<mlua::state::extra::ExtraData>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
||||
--> tests/compile/ref_nounwindsafe.rs:8:18
|
||||
|
|
||||
8 | catch_unwind(move || table.set("a", "b").unwrap());
|
||||
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<mlua::state::extra::ExtraData>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: the trait `RefUnwindSafe` is not implemented for `UnsafeCell<mlua::state::extra::ExtraData>`
|
||||
= note: required for `Rc<UnsafeCell<mlua::state::extra::ExtraData>>` to implement `RefUnwindSafe`
|
||||
note: required because it appears within the type `mlua::state::raw::RawLua`
|
||||
--> src/state/raw.rs
|
||||
|
|
||||
| pub struct RawLua {
|
||||
| ^^^^^^
|
||||
note: required because it appears within the type `mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>`
|
||||
--> src/types/sync.rs
|
||||
|
|
||||
| pub(crate) struct ReentrantMutex<T>(T);
|
||||
| ^^^^^^^^^^^^^^
|
||||
note: required because it appears within the type `rc::RcInner<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>`
|
||||
--> $RUST/alloc/src/rc.rs
|
||||
|
|
||||
| struct RcInner<T: ?Sized> {
|
||||
| ^^^^^^^
|
||||
= note: required for `NonNull<rc::RcInner<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>>` to implement `UnwindSafe`
|
||||
note: required because it appears within the type `std::rc::Weak<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>`
|
||||
--> $RUST/alloc/src/rc.rs
|
||||
| pub struct RawReentrantMutex<R, G> {
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
note: required because it appears within the type `lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>`
|
||||
--> $CARGO/lock_api-$VERSION/src/remutex.rs
|
||||
|
|
||||
| pub struct ReentrantMutex<R, G, T: ?Sized> {
|
||||
| ^^^^^^^^^^^^^^
|
||||
note: required because it appears within the type `alloc::sync::ArcInner<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>`
|
||||
--> $RUST/alloc/src/sync.rs
|
||||
|
|
||||
| struct ArcInner<T: ?Sized> {
|
||||
| ^^^^^^^^
|
||||
= note: required for `NonNull<alloc::sync::ArcInner<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>>` to implement `UnwindSafe`
|
||||
note: required because it appears within the type `std::sync::Weak<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>`
|
||||
--> $RUST/alloc/src/sync.rs
|
||||
|
|
||||
| pub struct Weak<
|
||||
| ^^^^
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
error[E0373]: closure may outlive the current function, but it borrows `inner`, which is owned by the current function
|
||||
--> tests/compile/scope_callback_capture.rs:7:43
|
||||
|
|
||||
5 | lua.scope(|scope| {
|
||||
5 | lua.scope(|scope| {
|
||||
| ----- has type `&'1 mlua::Scope<'1, '_>`
|
||||
6 | let mut inner: Option<Table> = None;
|
||||
7 | let f = scope.create_function_mut(|_, t: Table| {
|
||||
6 | let mut inner: Option<Table> = None;
|
||||
7 | let f = scope.create_function_mut(|_, t: Table| {
|
||||
| ^^^^^^^^^^^^^ may outlive borrowed value `inner`
|
||||
8 | inner = Some(t);
|
||||
8 | inner = Some(t);
|
||||
| ----- `inner` is borrowed here
|
||||
|
|
||||
note: function requires argument type to outlive `'1`
|
||||
--> tests/compile/scope_callback_capture.rs:7:17
|
||||
|
|
||||
7 | let f = scope.create_function_mut(|_, t: Table| {
|
||||
7 | let f = scope.create_function_mut(|_, t: Table| {
|
||||
| _________________^
|
||||
8 | | inner = Some(t);
|
||||
9 | | Ok(())
|
||||
8 | | inner = Some(t);
|
||||
9 | | Ok(())
|
||||
10 | | })?;
|
||||
| |__________^
|
||||
help: to force the closure to take ownership of `inner` (and any other referenced variables), use the `move` keyword
|
||||
|
|
||||
7 | let f = scope.create_function_mut(move |_, t: Table| {
|
||||
7 | let f = scope.create_function_mut(move |_, t: Table| {
|
||||
| ++++
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
error[E0373]: closure may outlive the current function, but it borrows `test.field`, which is owned by the current function
|
||||
--> tests/compile/scope_invariance.rs:13:39
|
||||
|
|
||||
9 | lua.scope(|scope| {
|
||||
9 | lua.scope(|scope| {
|
||||
| ----- has type `&'1 mlua::Scope<'1, '_>`
|
||||
...
|
||||
13 | scope.create_function_mut(|_, ()| {
|
||||
|
||||
@@ -10,3 +10,9 @@ error[E0499]: cannot borrow `i` as mutable more than once at a time
|
||||
| argument requires that `i` is borrowed for `'1`
|
||||
12 | let _b = scope.create_userdata(MyUserData(&mut i)).unwrap();
|
||||
| ^^^^^^ second mutable borrow occurs here
|
||||
|
|
||||
note: requirement that the value outlives `'1` introduced here
|
||||
--> src/scope.rs
|
||||
|
|
||||
| T: UserData + 'env,
|
||||
| ^^^^
|
||||
|
||||
@@ -13,3 +13,9 @@ error[E0597]: `ibad` does not live long enough
|
||||
| argument requires that `ibad` is borrowed for `'1`
|
||||
16 | };
|
||||
| - `ibad` dropped here while still borrowed
|
||||
|
|
||||
note: requirement that the value outlives `'1` introduced here
|
||||
--> src/scope.rs
|
||||
|
|
||||
| T: UserData + 'env,
|
||||
| ^^^^
|
||||
|
||||
@@ -194,6 +194,25 @@ fn test_function_info() -> Result<()> {
|
||||
assert_eq!(print_info.what, "C");
|
||||
assert_eq!(print_info.line_defined, None);
|
||||
|
||||
// Function with upvalues and params
|
||||
#[cfg(not(any(feature = "lua51", feature = "luajit")))]
|
||||
{
|
||||
let func_with_upvalues = lua
|
||||
.load(
|
||||
r#"
|
||||
local x, y = ...
|
||||
return function(a, ...)
|
||||
return a*x + y
|
||||
end
|
||||
"#,
|
||||
)
|
||||
.call::<Function>((10, 20))?;
|
||||
let func_with_upvalues_info = func_with_upvalues.info();
|
||||
assert_eq!(func_with_upvalues_info.num_upvalues, 2);
|
||||
assert_eq!(func_with_upvalues_info.num_params, 1);
|
||||
assert_eq!(func_with_upvalues_info.is_vararg, true);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -274,7 +274,7 @@ fn test_hook_yield() -> Result<()> {
|
||||
|
||||
co.set_hook(HookTriggers::EVERY_LINE, move |_lua, _debug| Ok(VmState::Yield))?;
|
||||
|
||||
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53"))]
|
||||
{
|
||||
assert!(co.resume::<()>(()).is_ok());
|
||||
assert!(co.resume::<()>(()).is_ok());
|
||||
|
||||
+1
-1
@@ -448,7 +448,7 @@ fn test_loadstring() -> Result<()> {
|
||||
assert_eq!(f.call::<i32>(())?, 123);
|
||||
|
||||
let err = lua
|
||||
.load(r#"loadstring("retur 123", "chunk")"#)
|
||||
.load(r#"loadstring("retur 123", "chunk")"#) // typos:ignore
|
||||
.exec()
|
||||
.err()
|
||||
.unwrap();
|
||||
|
||||
+8
-2
@@ -72,13 +72,19 @@ fn test_gc_control() -> Result<()> {
|
||||
let lua = Lua::new();
|
||||
let globals = lua.globals();
|
||||
|
||||
#[cfg(feature = "lua54")]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54"))]
|
||||
{
|
||||
assert_eq!(lua.gc_gen(0, 0), GCMode::Incremental);
|
||||
assert_eq!(lua.gc_inc(0, 0, 0), GCMode::Generational);
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luau"))]
|
||||
#[cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "luau"
|
||||
))]
|
||||
{
|
||||
assert!(lua.gc_is_running());
|
||||
lua.gc_stop();
|
||||
|
||||
@@ -13,6 +13,7 @@ members = [
|
||||
]
|
||||
|
||||
[features]
|
||||
lua55 = ["mlua/lua55"]
|
||||
lua54 = ["mlua/lua54"]
|
||||
lua53 = ["mlua/lua53"]
|
||||
lua52 = ["mlua/lua52"]
|
||||
|
||||
@@ -5,6 +5,7 @@ authors = ["Aleksandr Orlenko <zxteam@pm.me>"]
|
||||
edition = "2021"
|
||||
|
||||
[features]
|
||||
lua55 = ["mlua/lua55"]
|
||||
lua54 = ["mlua/lua54"]
|
||||
lua53 = ["mlua/lua53"]
|
||||
lua52 = ["mlua/lua52"]
|
||||
|
||||
@@ -42,6 +42,7 @@ fn test_module_error() -> Result<()> {
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
@@ -70,6 +71,7 @@ fn test_module_from_thread() -> Result<()> {
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
|
||||
+4
-3
@@ -47,7 +47,6 @@ fn test_userdata_multithread_access_send_only() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[rustversion::stable]
|
||||
#[test]
|
||||
fn test_userdata_multithread_access_sync() -> Result<()> {
|
||||
let lua = Lua::new();
|
||||
@@ -76,11 +75,13 @@ fn test_userdata_multithread_access_sync() -> Result<()> {
|
||||
std::thread::scope(|s| {
|
||||
s.spawn(|| {
|
||||
// Getting another shared reference for `Sync` type is allowed.
|
||||
let _ = lua.globals().get::<UserDataRef<MyUserData>>("ud").unwrap();
|
||||
// FIXME: does not work due to https://github.com/rust-lang/rust/pull/135634
|
||||
// let _ = lua.globals().get::<UserDataRef<MyUserData>>("ud").unwrap();
|
||||
});
|
||||
});
|
||||
|
||||
lua.load("ud:method()").exec().unwrap();
|
||||
// FIXME: does not work due to https://github.com/rust-lang/rust/pull/135634
|
||||
// lua.load("ud:method()").exec().unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
+4
-4
@@ -36,7 +36,7 @@ fn test_serialize() -> Result<(), Box<dyn StdError>> {
|
||||
_integer = 123,
|
||||
_number = 321.99,
|
||||
_string = "test string serialization",
|
||||
_table_arr = {nil, "value 1", nil, "value 2", {}},
|
||||
_table_arr = {null, "value 1", 2, "value 3", {}},
|
||||
_table_map = {["table"] = "map", ["null"] = null},
|
||||
_bytes = "\240\040\140\040",
|
||||
_userdata = ud,
|
||||
@@ -53,7 +53,7 @@ fn test_serialize() -> Result<(), Box<dyn StdError>> {
|
||||
"_integer": 123,
|
||||
"_number": 321.99,
|
||||
"_string": "test string serialization",
|
||||
"_table_arr": [null, "value 1", null, "value 2", {}],
|
||||
"_table_arr": [null, "value 1", 2, "value 3", {}],
|
||||
"_table_map": {"table": "map", "null": null},
|
||||
"_bytes": [240, 40, 140, 40],
|
||||
"_userdata": [123, "test userdata"],
|
||||
@@ -184,7 +184,7 @@ fn test_serialize_sorted() -> LuaResult<()> {
|
||||
_integer = 123,
|
||||
_number = 321.99,
|
||||
_string = "test string serialization",
|
||||
_table_arr = {nil, "value 1", nil, "value 2", {}},
|
||||
_table_arr = {null, "value 1", 2, "value 3", {}},
|
||||
_table_map = {["table"] = "map", ["null"] = null},
|
||||
_bytes = "\240\040\140\040",
|
||||
_null = null,
|
||||
@@ -198,7 +198,7 @@ fn test_serialize_sorted() -> LuaResult<()> {
|
||||
let json = serde_json::to_string(&value.to_serializable().sort_keys(true)).unwrap();
|
||||
assert_eq!(
|
||||
json,
|
||||
r#"{"_bool":true,"_bytes":[240,40,140,40],"_empty_array":[],"_empty_map":{},"_integer":123,"_null":null,"_number":321.99,"_string":"test string serialization","_table_arr":[null,"value 1",null,"value 2",{}],"_table_map":{"null":null,"table":"map"}}"#
|
||||
r#"{"_bool":true,"_bytes":[240,40,140,40],"_empty_array":[],"_empty_map":{},"_integer":123,"_null":null,"_number":321.99,"_string":"test string serialization","_table_arr":[null,"value 1",2,"value 3",{}],"_table_map":{"null":null,"table":"map"}}"#
|
||||
);
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -157,3 +157,18 @@ fn test_bytes_into_iter() -> Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "lua55")]
|
||||
#[test]
|
||||
fn test_external_string() -> Result<()> {
|
||||
let lua = Lua::new();
|
||||
|
||||
let s = lua.create_external_string(b"abc\0")?;
|
||||
assert_eq!(
|
||||
s.as_bytes(),
|
||||
b"abc\0",
|
||||
"Trailing null byte should be preserved if present explicitly"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
+24
-6
@@ -581,7 +581,7 @@ fn test_num_conversion() -> Result<()> {
|
||||
|
||||
assert_eq!(lua.load("1.0").eval::<i64>()?, 1);
|
||||
assert_eq!(lua.load("1.0").eval::<f64>()?, 1.0);
|
||||
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53"))]
|
||||
assert_eq!(lua.load("1.0").eval::<String>()?, "1.0");
|
||||
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit", feature = "luau"))]
|
||||
assert_eq!(lua.load("1.0").eval::<String>()?, "1");
|
||||
@@ -611,7 +611,7 @@ fn test_num_conversion() -> Result<()> {
|
||||
assert!(negative_zero.is_sign_negative());
|
||||
|
||||
// In Lua <5.3 all numbers are floats
|
||||
#[cfg(not(any(feature = "lua54", feature = "lua53", feature = "luajit")))]
|
||||
#[cfg(not(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "luajit")))]
|
||||
{
|
||||
let negative_zero = lua.load("-0").eval::<f64>()?;
|
||||
assert_eq!(negative_zero, 0.0);
|
||||
@@ -675,7 +675,13 @@ fn test_pcall_xpcall() -> Result<()> {
|
||||
assert_eq!(globals.get::<String>("pcall_error")?, "testerror");
|
||||
|
||||
assert_eq!(globals.get::<bool>("xpcall_statusr")?, false);
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luajit"))]
|
||||
#[cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "luajit"
|
||||
))]
|
||||
assert_eq!(globals.get::<std::string::String>("xpcall_error")?, "testerror");
|
||||
#[cfg(feature = "lua51")]
|
||||
assert!(globals
|
||||
@@ -1167,7 +1173,13 @@ fn test_context_thread() -> Result<()> {
|
||||
)
|
||||
.into_function()?;
|
||||
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luajit52"))]
|
||||
#[cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "luajit52"
|
||||
))]
|
||||
f.call::<()>(lua.current_thread())?;
|
||||
|
||||
#[cfg(any(
|
||||
@@ -1343,7 +1355,13 @@ fn test_inspect_stack() -> Result<()> {
|
||||
})?;
|
||||
lua.globals().set("stack_info", stack_info)?;
|
||||
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luau"))]
|
||||
#[cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "luau"
|
||||
))]
|
||||
lua.load(
|
||||
r#"
|
||||
local stack_info = stack_info
|
||||
@@ -1483,7 +1501,7 @@ fn test_multi_states() -> Result<()> {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "lua54")]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54"))]
|
||||
fn test_warnings() -> Result<()> {
|
||||
let lua = Lua::new();
|
||||
lua.set_app_data::<Vec<(StdString, bool)>>(Vec::new());
|
||||
|
||||
+3
-2
@@ -140,7 +140,7 @@ fn test_thread_reset() -> Result<()> {
|
||||
let _ = thread.resume::<AnyUserData>(MyUserData(arc.clone()));
|
||||
assert_eq!(thread.status(), ThreadStatus::Error);
|
||||
assert_eq!(Arc::strong_count(&arc), 2);
|
||||
#[cfg(feature = "lua54")]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54"))]
|
||||
{
|
||||
assert!(thread.reset(func.clone()).is_err());
|
||||
// Reset behavior has changed in Lua v5.4.4
|
||||
@@ -149,7 +149,7 @@ fn test_thread_reset() -> Result<()> {
|
||||
assert!(thread.reset(func.clone()).is_ok());
|
||||
assert_eq!(thread.status(), ThreadStatus::Resumable);
|
||||
}
|
||||
#[cfg(any(feature = "lua54", feature = "luau"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "luau"))]
|
||||
{
|
||||
assert!(thread.reset(func.clone()).is_ok());
|
||||
assert_eq!(thread.status(), ThreadStatus::Resumable);
|
||||
@@ -181,6 +181,7 @@ fn test_coroutine_from_closure() -> Result<()> {
|
||||
lua.globals().set("main", thrd_main)?;
|
||||
|
||||
#[cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
|
||||
+30
-9
@@ -3,7 +3,7 @@ use std::collections::HashMap;
|
||||
use std::string::String as StdString;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[cfg(feature = "lua54")]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54"))]
|
||||
use std::sync::atomic::{AtomicI64, Ordering};
|
||||
|
||||
use mlua::{
|
||||
@@ -138,7 +138,13 @@ fn test_metamethods() -> Result<()> {
|
||||
Err("no such custom index".into_lua_err())
|
||||
}
|
||||
});
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luajit52"))]
|
||||
#[cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "luajit52"
|
||||
))]
|
||||
methods.add_meta_method(MetaMethod::Pairs, |lua, data, ()| {
|
||||
use std::iter::FromIterator;
|
||||
let stateless_iter = lua.create_function(|_, (data, i): (UserDataRef<Self>, i64)| {
|
||||
@@ -165,7 +171,13 @@ fn test_metamethods() -> Result<()> {
|
||||
10
|
||||
);
|
||||
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luajit52"))]
|
||||
#[cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "luajit52"
|
||||
))]
|
||||
let pairs_it = lua
|
||||
.load(
|
||||
r#"
|
||||
@@ -190,7 +202,13 @@ fn test_metamethods() -> Result<()> {
|
||||
assert_eq!(lua.load("userdata2.inner").eval::<i64>()?, 3);
|
||||
assert!(lua.load("userdata2.nonexist_field").eval::<()>().is_err());
|
||||
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luajit52"))]
|
||||
#[cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "luajit52"
|
||||
))]
|
||||
assert_eq!(pairs_it.call::<i64>(())?, 28);
|
||||
|
||||
let userdata2: Value = globals.get("userdata2")?;
|
||||
@@ -209,7 +227,7 @@ fn test_metamethods() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "lua54")]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54"))]
|
||||
#[test]
|
||||
fn test_metamethod_close() -> Result<()> {
|
||||
#[derive(Clone)]
|
||||
@@ -651,7 +669,7 @@ fn test_metatable() -> Result<()> {
|
||||
globals.set("ud", MyUserData)?;
|
||||
lua.load(r#"assert(ud:my_type_name() == "MyUserData")"#).exec()?;
|
||||
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "luau"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "luau"))]
|
||||
lua.load(r#"assert(tostring(ud):sub(1, 11) == "MyUserData:")"#)
|
||||
.exec()?;
|
||||
#[cfg(feature = "luau")]
|
||||
@@ -731,6 +749,9 @@ fn test_userdata_proxy() -> Result<()> {
|
||||
let globals = lua.globals();
|
||||
globals.set("MyUserData", lua.create_proxy::<MyUserData>()?)?;
|
||||
|
||||
assert!(!globals.get::<AnyUserData>("MyUserData")?.is_proxy::<()>());
|
||||
assert!(globals.get::<AnyUserData>("MyUserData")?.is_proxy::<MyUserData>());
|
||||
|
||||
lua.load(
|
||||
r#"
|
||||
assert(MyUserData.static_field == 123)
|
||||
@@ -957,7 +978,6 @@ fn test_nested_userdata_gc() -> Result<()> {
|
||||
}
|
||||
|
||||
#[cfg(feature = "userdata-wrappers")]
|
||||
#[rustversion::stable]
|
||||
#[test]
|
||||
fn test_userdata_wrappers() -> Result<()> {
|
||||
#[derive(Debug)]
|
||||
@@ -1319,8 +1339,9 @@ fn test_userdata_wrappers() -> Result<()> {
|
||||
assert_eq!(ud.borrow::<MyUserData>()?.0, 20);
|
||||
|
||||
// Multiple read borrows are allowed with parking_lot::RwLock
|
||||
let _borrow1 = ud.borrow::<MyUserData>()?;
|
||||
let _borrow2 = ud.borrow::<MyUserData>()?;
|
||||
let _borrow1 = ud.borrow::<MyUserData>().unwrap();
|
||||
// FIXME: does not work due to https://github.com/rust-lang/rust/pull/135634
|
||||
// let _borrow2 = ud.borrow::<MyUserData>().unwrap();
|
||||
assert!(matches!(
|
||||
ud.borrow_mut::<MyUserData>(),
|
||||
Err(Error::UserDataBorrowMutError)
|
||||
|
||||
+1
-1
@@ -239,7 +239,7 @@ fn test_value_conversions() -> Result<()> {
|
||||
assert_eq!(Value::Integer(1).as_u32(), Some(1u32));
|
||||
assert_eq!(Value::Integer(1).as_i64(), Some(1i64));
|
||||
assert_eq!(Value::Integer(1).as_u64(), Some(1u64));
|
||||
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53"))]
|
||||
{
|
||||
assert_eq!(Value::Integer(mlua::Integer::MAX).as_i32(), None);
|
||||
assert_eq!(Value::Integer(mlua::Integer::MAX).as_u32(), None);
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
[default]
|
||||
extend-ignore-identifiers-re = ["2nd", "ser"]
|
||||
extend-ignore-re = [
|
||||
# Custom ignore regex patterns: https://github.com/crate-ci/typos/blob/master/docs/reference.md#defaultextend-ignore-re
|
||||
".*(?:#|--|//|/*).*(?:spellchecker|typos):\\s?ignore[^\\n]*\\n",
|
||||
".*(?:spellchecker|typos):\\s?ignore-next-line[^\\n]*\\n[^\\n]*",
|
||||
]
|
||||
|
||||
[files]
|
||||
extend-exclude = ["tests/compile/*.stderr"]
|
||||
|
||||
[default.extend-words]
|
||||
thr = "thr"
|
||||
|
||||
Reference in New Issue
Block a user