Skip to content

Commit f36aaa5

Browse files
committed
Add loadstring function to Luau
Closes #578
1 parent df38878 commit f36aaa5

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

src/luau/mod.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
use std::ffi::CStr;
22
use std::os::raw::c_int;
3+
use std::ptr;
34

5+
use crate::chunk::ChunkMode;
46
use crate::error::Result;
57
use crate::function::Function;
6-
use crate::state::Lua;
8+
use crate::state::{callback_error_ext, Lua};
9+
use crate::traits::{FromLuaMulti, IntoLua};
710

811
pub use require::{NavigateError, Require};
912

@@ -22,6 +25,7 @@ impl Lua {
2225
let globals = self.globals();
2326

2427
globals.raw_set("collectgarbage", self.create_c_function(lua_collectgarbage)?)?;
28+
globals.raw_set("loadstring", self.create_c_function(lua_loadstring)?)?;
2529

2630
// Set `_VERSION` global to include version number
2731
// The environment variable `LUAU_VERSION` set by the build script
@@ -74,4 +78,20 @@ unsafe extern "C-unwind" fn lua_collectgarbage(state: *mut ffi::lua_State) -> c_
7478
}
7579
}
7680

81+
unsafe extern "C-unwind" fn lua_loadstring(state: *mut ffi::lua_State) -> c_int {
82+
callback_error_ext(state, ptr::null_mut(), false, move |extra, nargs| {
83+
let rawlua = (*extra).raw_lua();
84+
let (chunk, chunk_name) =
85+
<(String, Option<String>)>::from_stack_args(nargs, 1, Some("loadstring"), rawlua)?;
86+
let chunk_name = chunk_name.as_deref().unwrap_or("=(loadstring)");
87+
(rawlua.lua())
88+
.load(chunk)
89+
.set_name(chunk_name)
90+
.set_mode(ChunkMode::Text)
91+
.into_function()?
92+
.push_into_stack(rawlua)?;
93+
Ok(1)
94+
})
95+
}
96+
7797
mod require;

tests/luau.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ use std::panic::{catch_unwind, AssertUnwindSafe};
77
use std::sync::atomic::{AtomicBool, AtomicPtr, AtomicU64, Ordering};
88
use std::sync::Arc;
99

10-
use mlua::{Compiler, Error, Lua, LuaOptions, Result, StdLib, Table, ThreadStatus, Value, Vector, VmState};
10+
use mlua::{
11+
Compiler, Error, Function, Lua, LuaOptions, Result, StdLib, Table, ThreadStatus, Value, Vector, VmState,
12+
};
1113

1214
#[test]
1315
fn test_version() -> Result<()> {
@@ -415,5 +417,24 @@ fn test_thread_events() -> Result<()> {
415417
Ok(())
416418
}
417419

420+
#[test]
421+
fn test_loadstring() -> Result<()> {
422+
let lua = Lua::new();
423+
424+
let f = lua.load(r#"loadstring("return 123")"#).eval::<Function>()?;
425+
assert_eq!(f.call::<i32>(())?, 123);
426+
427+
let err = lua
428+
.load(r#"loadstring("retur 123", "chunk")"#)
429+
.exec()
430+
.err()
431+
.unwrap();
432+
assert!(err.to_string().contains(
433+
r#"syntax error: [string "chunk"]:1: Incomplete statement: expected assignment or a function call"#
434+
));
435+
436+
Ok(())
437+
}
438+
418439
#[path = "luau/require.rs"]
419440
mod require;

0 commit comments

Comments
 (0)