diff --git a/crates/lune-roblox/src/instance/terrain.rs b/crates/lune-roblox/src/instance/terrain.rs index 96a036b..d4ff227 100644 --- a/crates/lune-roblox/src/instance/terrain.rs +++ b/crates/lune-roblox/src/instance/terrain.rs @@ -27,11 +27,13 @@ pub fn add_methods<'lua, M: LuaUserDataMethods<'lua, Instance>>(methods: &mut M) } fn get_or_create_material_colors(instance: &Instance) -> MaterialColors { - if let Some(Variant::MaterialColors(material_colors)) = instance.get_property("MaterialColors") + if let Variant::MaterialColors(inner) = instance + .get_property("MaterialColors") + .unwrap_or(Variant::MaterialColors(MaterialColors::default())) { - material_colors + inner } else { - MaterialColors::default() + unreachable!() } } diff --git a/crates/lune/src/cli/run.rs b/crates/lune/src/cli/run.rs index 35e523e..41c4c27 100644 --- a/crates/lune/src/cli/run.rs +++ b/crates/lune/src/cli/run.rs @@ -7,9 +7,8 @@ use tokio::{ io::{stdin, AsyncReadExt as _}, }; -use lune::Runtime; - use super::utils::files::{discover_script_path_including_lune_dirs, strip_shebang}; +use lune::Runtime; /// Run a script #[derive(Debug, Clone, Parser)] @@ -41,8 +40,8 @@ impl RunCommand { }; // Create a new lune object with all globals & run the script - let result = Runtime::new() - .with_args(self.script_args) + let mut runtime = Runtime::new().with_args(self.script_args); + let result = runtime .run(&script_display_name, strip_shebang(script_contents)) .await; Ok(match result { @@ -50,7 +49,7 @@ impl RunCommand { eprintln!("{err}"); ExitCode::FAILURE } - Ok(code) => code, + Ok((code, _)) => ExitCode::from(code), }) } } diff --git a/crates/lune/src/rt/runtime.rs b/crates/lune/src/rt/runtime.rs index 1aa2ace..51817aa 100644 --- a/crates/lune/src/rt/runtime.rs +++ b/crates/lune/src/rt/runtime.rs @@ -1,7 +1,6 @@ #![allow(clippy::missing_panics_doc)] use std::{ - process::ExitCode, rc::Rc, sync::{ atomic::{AtomicBool, Ordering}, @@ -144,7 +143,8 @@ impl Runtime { &mut self, script_name: impl AsRef, script_contents: impl AsRef<[u8]>, - ) -> RuntimeResult { + ) -> RuntimeResult<(u8, Vec)> { + // Create a new scheduler for this run let lua = self.inner.lua(); let sched = self.inner.scheduler(); @@ -162,18 +162,20 @@ impl Runtime { .set_name(script_name.as_ref()); // Run it on our scheduler until it and any other spawned threads complete - sched.push_thread_back(main, ())?; + let main_thread_id = sched.push_thread_back(main, ())?; sched.run().await; - // Return the exit code - default to FAILURE if we got any errors - let exit_code = sched.get_exit_code().unwrap_or({ - if got_any_error.load(Ordering::SeqCst) { - ExitCode::FAILURE - } else { - ExitCode::SUCCESS - } - }); + let thread_res = match sched.get_thread_result(main_thread_id) { + Some(res) => res, + None => LuaValue::Nil.into_lua_multi(lua), + }? + .into_vec(); - Ok(exit_code) + Ok(( + sched + .get_exit_code() + .unwrap_or(u8::from(got_any_error.load(Ordering::SeqCst))), + thread_res, + )) } } diff --git a/crates/lune/src/standalone/mod.rs b/crates/lune/src/standalone/mod.rs index fe58913..805eb95 100644 --- a/crates/lune/src/standalone/mod.rs +++ b/crates/lune/src/standalone/mod.rs @@ -29,16 +29,14 @@ pub async fn run(patched_bin: impl AsRef<[u8]>) -> Result { let args = env::args().skip(1).collect::>(); let meta = Metadata::from_bytes(patched_bin).expect("must be a standalone binary"); - let result = Runtime::new() - .with_args(args) - .run("STANDALONE", meta.bytecode) - .await; + let mut rt = Runtime::new().with_args(args); + let result = rt.run("STANDALONE", meta.bytecode).await; Ok(match result { Err(err) => { eprintln!("{err}"); ExitCode::FAILURE } - Ok(code) => code, + Ok((code, _)) => ExitCode::from(code), }) } diff --git a/crates/lune/src/tests.rs b/crates/lune/src/tests.rs index 2e866dc..c0a53d8 100644 --- a/crates/lune/src/tests.rs +++ b/crates/lune/src/tests.rs @@ -42,8 +42,8 @@ macro_rules! create_tests { .trim_end_matches(".luau") .trim_end_matches(".lua") .to_string(); - let exit_code = lune.run(&script_name, &script).await?; - Ok(exit_code) + let (exit_code, _) = lune.run(&script_name, &script).await?; + Ok(ExitCode::from(exit_code)) } )* } } diff --git a/crates/mlua-luau-scheduler/examples/exit_code.rs b/crates/mlua-luau-scheduler/examples/exit_code.rs index ee4a9a4..a6ede57 100644 --- a/crates/mlua-luau-scheduler/examples/exit_code.rs +++ b/crates/mlua-luau-scheduler/examples/exit_code.rs @@ -32,7 +32,7 @@ pub fn main() -> LuaResult<()> { // Verify that we got a correct exit code let code = sched.get_exit_code().unwrap_or_default(); - assert!(format!("{code:?}").contains("(1)")); + assert_eq!(code, 1); Ok(()) } diff --git a/crates/mlua-luau-scheduler/src/exit.rs b/crates/mlua-luau-scheduler/src/exit.rs index a2794dd..d8d9bd3 100644 --- a/crates/mlua-luau-scheduler/src/exit.rs +++ b/crates/mlua-luau-scheduler/src/exit.rs @@ -1,10 +1,10 @@ -use std::{cell::Cell, process::ExitCode, rc::Rc}; +use std::{cell::Cell, rc::Rc}; use event_listener::Event; #[derive(Debug, Clone)] pub(crate) struct Exit { - code: Rc>>, + code: Rc>>, event: Rc, } @@ -16,12 +16,12 @@ impl Exit { } } - pub fn set(&self, code: ExitCode) { + pub fn set(&self, code: u8) { self.code.set(Some(code)); self.event.notify(usize::MAX); } - pub fn get(&self) -> Option { + pub fn get(&self) -> Option { self.code.get() } diff --git a/crates/mlua-luau-scheduler/src/functions.rs b/crates/mlua-luau-scheduler/src/functions.rs index 7230b99..06e5c25 100644 --- a/crates/mlua-luau-scheduler/src/functions.rs +++ b/crates/mlua-luau-scheduler/src/functions.rs @@ -1,7 +1,7 @@ #![allow(unused_imports)] #![allow(clippy::too_many_lines)] -use std::process::ExitCode; +use std::process::{ExitCode, ExitStatus}; use mlua::prelude::*; @@ -232,7 +232,7 @@ impl<'lua> Functions<'lua> { "exit", lua.create_function(|lua, code: Option| { let _span = tracing::trace_span!("Scheduler::fn_exit").entered(); - let code = code.map(ExitCode::from).unwrap_or_default(); + let code = code.unwrap_or_default(); lua.set_exit_code(code); Ok(()) })?, diff --git a/crates/mlua-luau-scheduler/src/scheduler.rs b/crates/mlua-luau-scheduler/src/scheduler.rs index 31f699e..9a43aa3 100644 --- a/crates/mlua-luau-scheduler/src/scheduler.rs +++ b/crates/mlua-luau-scheduler/src/scheduler.rs @@ -2,7 +2,6 @@ use std::{ cell::Cell, - process::ExitCode, rc::{Rc, Weak as WeakRc}, sync::{Arc, Weak as WeakArc}, thread::panicking, @@ -168,7 +167,7 @@ impl<'lua> Scheduler<'lua> { Gets the exit code for this scheduler, if one has been set. */ #[must_use] - pub fn get_exit_code(&self) -> Option { + pub fn get_exit_code(&self) -> Option { self.exit.get() } @@ -177,7 +176,7 @@ impl<'lua> Scheduler<'lua> { This will cause [`Scheduler::run`] to exit immediately. */ - pub fn set_exit_code(&self, code: ExitCode) { + pub fn set_exit_code(&self, code: u8) { self.exit.set(code); } diff --git a/crates/mlua-luau-scheduler/src/traits.rs b/crates/mlua-luau-scheduler/src/traits.rs index cbe2e6e..caca387 100644 --- a/crates/mlua-luau-scheduler/src/traits.rs +++ b/crates/mlua-luau-scheduler/src/traits.rs @@ -82,7 +82,7 @@ pub trait LuaSchedulerExt<'lua> { Panics if called outside of a running [`Scheduler`]. */ - fn set_exit_code(&self, code: ExitCode); + fn set_exit_code(&self, code: u8); /** Pushes (spawns) a lua thread to the **front** of the current scheduler. @@ -283,7 +283,7 @@ pub trait LuaSpawnExt<'lua> { } impl<'lua> LuaSchedulerExt<'lua> for Lua { - fn set_exit_code(&self, code: ExitCode) { + fn set_exit_code(&self, code: u8) { let exit = self .app_data_ref::() .expect("exit code can only be set from within an active scheduler");