From 14c168f118691cf79d40eda2f2f4c2ff66ac7eaf Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Thu, 22 Jun 2017 00:13:49 +0200 Subject: [PATCH] Add `Lua::load` for precompiling chunks This allows loading scripts into memory, performing a syntax check and precompiling them, without immediately running them like `exec` and `eval` do. --- src/lua.rs | 34 ++++++++++++++++++++++++++++++++++ src/tests.rs | 12 +++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/lua.rs b/src/lua.rs index 3feb350..5df5747 100644 --- a/src/lua.rs +++ b/src/lua.rs @@ -1047,6 +1047,40 @@ impl Lua { } } + /// Loads a chunk of Lua code and returns it as a function. + /// + /// Unlike `exec`, this will not execute the chunk, but precompile it into a callable + /// `LuaFunction`. + /// + /// Equivalent to Lua's `load` function. + pub fn load(&self, source: &str, name: Option<&str>) -> LuaResult { + unsafe { + stack_guard(self.state, 0, || { + handle_error( + self.state, + if let Some(name) = name { + let name = CString::new(name.to_owned())?; + ffi::luaL_loadbuffer( + self.state, + source.as_ptr() as *const c_char, + source.len(), + name.as_ptr(), + ) + } else { + ffi::luaL_loadbuffer( + self.state, + source.as_ptr() as *const c_char, + source.len(), + ptr::null(), + ) + }, + )?; + + Ok(LuaFunction(self.pop_ref(self.state))) + }) + } + } + /// Pass a `&str` slice to Lua, creating and returning a interned Lua string. pub fn create_string(&self, s: &str) -> LuaResult { unsafe { diff --git a/src/tests.rs b/src/tests.rs index b835144..cf7eb7b 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -17,7 +17,7 @@ fn test_set_get() { } #[test] -fn test_load() { +fn test_exec() { let lua = Lua::new(); let globals = lua.globals().unwrap(); lua.exec::<()>( @@ -730,3 +730,13 @@ fn test_num_conversion() { assert_eq!(globals.get::<_, f64>("a").unwrap(), 1.5); assert_eq!(globals.get::<_, String>("a").unwrap(), "1.5"); } + +#[test] +fn test_load() { + let lua = Lua::new(); + let func = lua.load("return 1+2", None).unwrap(); + let result: i32 = func.call(()).unwrap(); + assert_eq!(result, 3); + + assert!(lua.load("§$%§&$%&", None).is_err()); +}