From 38994b941c1e23b6bd1b57117d93cfd6e01620d7 Mon Sep 17 00:00:00 2001 From: Filip Tibell Date: Sun, 20 Aug 2023 12:01:28 -0500 Subject: [PATCH] Store reference to lua in require context --- src/lune/globals/require/alias.rs | 3 +- src/lune/globals/require/builtin.rs | 5 +-- src/lune/globals/require/context.rs | 66 ++++++++++++++--------------- src/lune/globals/require/mod.rs | 8 ++-- src/lune/globals/require/path.rs | 9 ++-- 5 files changed, 43 insertions(+), 48 deletions(-) diff --git a/src/lune/globals/require/alias.rs b/src/lune/globals/require/alias.rs index e0d38eb..f8fd15e 100644 --- a/src/lune/globals/require/alias.rs +++ b/src/lune/globals/require/alias.rs @@ -3,8 +3,7 @@ use mlua::prelude::*; use super::context::*; pub(super) async fn require<'lua, 'ctx>( - _lua: &'lua Lua, - _ctx: &'ctx RequireContext, + _ctx: &'ctx RequireContext<'lua>, alias: &str, name: &str, ) -> LuaResult> diff --git a/src/lune/globals/require/builtin.rs b/src/lune/globals/require/builtin.rs index 914d1c1..c4550dd 100644 --- a/src/lune/globals/require/builtin.rs +++ b/src/lune/globals/require/builtin.rs @@ -3,13 +3,12 @@ use mlua::prelude::*; use super::context::*; pub(super) async fn require<'lua, 'ctx>( - lua: &'lua Lua, - ctx: &'ctx RequireContext, + ctx: &'ctx RequireContext<'lua>, name: &str, ) -> LuaResult> where 'lua: 'ctx, 'lua: 'static, // FIXME: Remove static lifetime bound here when builtin libraries no longer need it { - ctx.load_builtin(lua, name) + ctx.load_builtin(name) } diff --git a/src/lune/globals/require/context.rs b/src/lune/globals/require/context.rs index 1e21d9f..61990ca 100644 --- a/src/lune/globals/require/context.rs +++ b/src/lune/globals/require/context.rs @@ -28,7 +28,8 @@ const REGISTRY_KEY: &str = "RequireContext"; path will first be transformed into an absolute path. */ #[derive(Debug, Clone)] -pub(super) struct RequireContext { +pub(super) struct RequireContext<'lua> { + lua: &'lua Lua, use_cwd_relative_paths: bool, working_directory: PathBuf, cache_builtins: Arc>>>, @@ -36,7 +37,7 @@ pub(super) struct RequireContext { cache_pending: Arc>>>, } -impl RequireContext { +impl<'lua> RequireContext<'lua> { /** Creates a new require context for the given [`Lua`] struct. @@ -44,11 +45,12 @@ impl RequireContext { context should be created per [`Lua`] struct, creating more than one context may lead to undefined require-behavior. */ - pub fn new() -> Self { + pub fn new(lua: &'lua Lua) -> Self { + // FUTURE: We could load some kind of config or env var + // to check if we should be using cwd-relative paths let cwd = env::current_dir().expect("Failed to get current working directory"); Self { - // FUTURE: We could load some kind of config or env var - // to check if we should be using cwd-relative paths + lua, use_cwd_relative_paths: false, working_directory: cwd, cache_builtins: Arc::new(AsyncMutex::new(HashMap::new())), @@ -118,11 +120,7 @@ impl RequireContext { Will panic if the path has not been cached, use [`is_cached`] first. */ - pub fn get_from_cache<'lua>( - &self, - lua: &'lua Lua, - abs_path: impl AsRef, - ) -> LuaResult> { + pub fn get_from_cache(&self, abs_path: impl AsRef) -> LuaResult> { let results = self .cache_results .try_lock() @@ -134,7 +132,8 @@ impl RequireContext { match cached { Err(e) => Err(e.clone()), Ok(key) => { - let multi_vec = lua + let multi_vec = self + .lua .registry_value::>(key) .expect("Missing require result in lua registry"); Ok(LuaMultiValue::from_vec(multi_vec)) @@ -147,9 +146,8 @@ impl RequireContext { Will panic if the path has not been cached, use [`is_cached`] first. */ - pub async fn wait_for_cache<'lua>( + pub async fn wait_for_cache( &self, - lua: &'lua Lua, abs_path: impl AsRef, ) -> LuaResult> { let mut thread_recv = { @@ -165,30 +163,31 @@ impl RequireContext { thread_recv.recv().await.into_lua_err()?; - self.get_from_cache(lua, abs_path.as_ref()) + self.get_from_cache(abs_path.as_ref()) } async fn load( &self, - lua: &Lua, abs_path: impl AsRef, rel_path: impl AsRef, ) -> LuaResult { let abs_path = abs_path.as_ref(); let rel_path = rel_path.as_ref(); - let sched = lua + let sched = self + .lua .app_data_ref::<&Scheduler>() .expect("Lua struct is missing scheduler"); // Read the file at the given path, try to parse and // load it into a new lua thread that we can schedule let file_contents = fs::read(&abs_path).await?; - let file_thread = lua + let file_thread = self + .lua .load(file_contents) .set_name(rel_path.to_string_lossy().to_string()) .into_function()? - .into_owned_lua_thread(lua)?; + .into_owned_lua_thread(self.lua)?; // Schedule the thread to run, wait for it to finish running let thread_id = sched.push_back(file_thread, ())?; @@ -199,7 +198,8 @@ impl RequireContext { Err(e) => Err(e), Ok(multi) => { let multi_vec = multi.into_vec(); - let multi_key = lua + let multi_key = self + .lua .create_registry_value(multi_vec) .expect("Failed to store require result in registry"); Ok(multi_key) @@ -210,9 +210,8 @@ impl RequireContext { /** Loads (requires) the file at the given path. */ - pub async fn load_with_caching<'lua>( + pub async fn load_with_caching( &self, - lua: &'lua Lua, abs_path: impl AsRef, rel_path: impl AsRef, ) -> LuaResult> { @@ -227,11 +226,12 @@ impl RequireContext { .insert(abs_path.to_path_buf(), broadcast_tx); // Try to load at this abs path - let load_res = self.load(lua, abs_path, rel_path).await; + let load_res = self.load(abs_path, rel_path).await; let load_val = match &load_res { Err(e) => Err(e.clone()), Ok(k) => { - let multi_vec = lua + let multi_vec = self + .lua .registry_value::>(k) .expect("Failed to fetch require result from registry"); Ok(LuaMultiValue::from_vec(multi_vec)) @@ -265,11 +265,7 @@ impl RequireContext { /** Loads (requires) the builtin with the given name. */ - pub fn load_builtin<'lua>( - &self, - lua: &'lua Lua, - name: impl AsRef, - ) -> LuaResult> + pub fn load_builtin(&self, name: impl AsRef) -> LuaResult> where 'lua: 'static, // FIXME: Remove static lifetime bound here when builtin libraries no longer need it { @@ -287,7 +283,8 @@ impl RequireContext { return match res { Err(e) => return Err(e.clone()), Ok(key) => { - let multi_vec = lua + let multi_vec = self + .lua .registry_value::>(key) .expect("Missing builtin result in lua registry"); Ok(LuaMultiValue::from_vec(multi_vec)) @@ -295,7 +292,7 @@ impl RequireContext { }; }; - let result = builtin.create(lua); + let result = builtin.create(self.lua); cache.insert( builtin, @@ -303,7 +300,8 @@ impl RequireContext { Err(e) => Err(e), Ok(multi) => { let multi_vec = multi.into_vec(); - let multi_key = lua + let multi_key = self + .lua .create_registry_value(multi_vec) .expect("Failed to store require result in registry"); Ok(multi_key) @@ -315,9 +313,9 @@ impl RequireContext { } } -impl LuaUserData for RequireContext {} +impl<'lua> LuaUserData for RequireContext<'lua> {} -impl<'lua> FromLua<'lua> for RequireContext { +impl<'lua> FromLua<'lua> for RequireContext<'lua> { fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult { if let LuaValue::UserData(ud) = value { if let Ok(ctx) = ud.borrow::() { @@ -328,7 +326,7 @@ impl<'lua> FromLua<'lua> for RequireContext { } } -impl<'lua> From<&'lua Lua> for RequireContext { +impl<'lua> From<&'lua Lua> for RequireContext<'lua> { fn from(value: &'lua Lua) -> Self { value .named_registry_value(REGISTRY_KEY) diff --git a/src/lune/globals/require/mod.rs b/src/lune/globals/require/mod.rs index 34b3e83..c3f1f81 100644 --- a/src/lune/globals/require/mod.rs +++ b/src/lune/globals/require/mod.rs @@ -14,7 +14,7 @@ return require(source(), ...) "#; pub fn create(lua: &'static Lua) -> LuaResult> { - lua.set_app_data(RequireContext::new()); + lua.set_app_data(RequireContext::new(lua)); /* Require implementation needs a few workarounds: @@ -88,13 +88,13 @@ where .strip_prefix("@lune/") .map(|name| name.to_ascii_lowercase()) { - builtin::require(lua, &context, &builtin_name).await + builtin::require(&context, &builtin_name).await } else if let Some(aliased_path) = path.strip_prefix('@') { let (alias, name) = aliased_path.split_once('/').ok_or(LuaError::runtime( "Require with custom alias must contain '/' delimiter", ))?; - alias::require(lua, &context, alias, name).await + alias::require(&context, alias, name).await } else { - path::require(lua, &context, &source, &path).await + path::require(&context, &source, &path).await } } diff --git a/src/lune/globals/require/path.rs b/src/lune/globals/require/path.rs index ad9ab0d..3d3f6e3 100644 --- a/src/lune/globals/require/path.rs +++ b/src/lune/globals/require/path.rs @@ -3,8 +3,7 @@ use mlua::prelude::*; use super::context::*; pub(super) async fn require<'lua, 'ctx>( - lua: &'lua Lua, - ctx: &'ctx RequireContext, + ctx: &'ctx RequireContext<'lua>, source: &str, path: &str, ) -> LuaResult> @@ -13,10 +12,10 @@ where { let (abs_path, rel_path) = ctx.resolve_paths(source, path)?; if ctx.is_cached(&abs_path)? { - ctx.get_from_cache(lua, &abs_path) + ctx.get_from_cache(&abs_path) } else if ctx.is_pending(&abs_path)? { - ctx.wait_for_cache(lua, &abs_path).await + ctx.wait_for_cache(&abs_path).await } else { - ctx.load_with_caching(lua, &abs_path, &rel_path).await + ctx.load_with_caching(&abs_path, &rel_path).await } }