From a6ed00ad33d4218ac3b3bcdceee9e2604abbab45 Mon Sep 17 00:00:00 2001 From: Filip Tibell Date: Sat, 29 Apr 2023 11:02:46 +0200 Subject: [PATCH] Fix _G --- CHANGELOG.md | 2 ++ packages/lib/src/importer/mod.rs | 3 +-- packages/lib/src/lua/create.rs | 3 +++ packages/lib/src/tests.rs | 1 + tests/globals/_G.luau | 20 ++++++++++++++++++++ 5 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 tests/globals/_G.luau diff --git a/CHANGELOG.md b/CHANGELOG.md index d2b99e8..916b032 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- Fixed `_G` not being a readable & writable table +- Fixed `_G` containing normal globals such as `print`, `math`, ... - Fixed using instances as keys in tables ## `0.6.5` - March 27th, 2023 diff --git a/packages/lib/src/importer/mod.rs b/packages/lib/src/importer/mod.rs index e1fb93b..50802f1 100644 --- a/packages/lib/src/importer/mod.rs +++ b/packages/lib/src/importer/mod.rs @@ -40,11 +40,10 @@ pub fn create(lua: &'static Lua, args: Vec) -> LuaResult<()> { ("printinfo", lua.create_function(top_level::printinfo)?), ]; - // Set top-level globals and seal them + // Set top-level globals for (name, global) in globals { lua_globals.set(name, global)?; } - lua_globals.set_readonly(true); Ok(()) } diff --git a/packages/lib/src/lua/create.rs b/packages/lib/src/lua/create.rs index c618adc..cde5f2e 100644 --- a/packages/lib/src/lua/create.rs +++ b/packages/lib/src/lua/create.rs @@ -81,6 +81,9 @@ pub fn create() -> LuaResult<&'static Lua> { let table: LuaTable = globals.raw_get("table")?; let string: LuaTable = globals.raw_get("string")?; let coroutine: LuaTable = globals.get("coroutine")?; + // Create a _G table that is separate from our built-in globals + let global_table = lua.create_table()?; + globals.set("_G", global_table)?; // Store original lua global functions in the registry so we can use // them later without passing them around and dealing with lifetimes lua.set_named_registry_value("print", globals.get::<_, LuaFunction>("print")?)?; diff --git a/packages/lib/src/tests.rs b/packages/lib/src/tests.rs index 846b88c..f66232f 100644 --- a/packages/lib/src/tests.rs +++ b/packages/lib/src/tests.rs @@ -69,6 +69,7 @@ create_tests! { require_nested: "require/tests/nested", require_parents: "require/tests/parents", require_siblings: "require/tests/siblings", + global_g_table: "globals/_G", // TODO: Uncomment this test, it is commented out right // now to let CI pass so that we can make a new release // global_coroutine: "globals/coroutine", diff --git a/tests/globals/_G.luau b/tests/globals/_G.luau new file mode 100644 index 0000000..3011f54 --- /dev/null +++ b/tests/globals/_G.luau @@ -0,0 +1,20 @@ +assert(_G ~= nil, "Missing _G") + +assert(type(_G) == "table", "Invalid type for _G") + +assert(_G.require == nil, "Built-in global value was found in _G") +assert(_G.print == nil, "Built-in global value was found in _G") +assert(_G.warn == nil, "Built-in global value was found in _G") +assert(_G.error == nil, "Built-in global value was found in _G") +assert(_G.coroutine == nil, "Built-in global value was found in _G") +assert(_G.typeof == nil, "Built-in global value was found in _G") +assert(_G.type == nil, "Built-in global value was found in _G") + +assert(next(_G) == nil, "_G contained value but should be empty") + +_G.Hello = "World" +assert(_G.Hello == "World", "Failed to set value in _G") + +local bar = {} +_G.Foo = bar +assert(_G.Foo == bar, "Failed to set reference in _G")