Skip to content

Commit 458aced

Browse files
committed
feat: add get/setFnEnvironment functions
1 parent 1bfbc59 commit 458aced

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

src/ziglua-5.1/lib.zig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,12 @@ pub const Lua = struct {
461461
return c.lua_getallocf(lua.state, @ptrCast([*c]?*anyopaque, data)).?;
462462
}
463463

464+
/// Pushes onto the stack the environment table of the value at the given index.
465+
/// See https://www.lua.org/manual/5.1/manual.html#lua_getfenv
466+
pub fn getFnEnvironment(lua: *Lua, index: i32) void {
467+
c.lua_getfenv(lua.state, index);
468+
}
469+
464470
/// Pushes onto the stack the value t[key] where t is the value at the given index
465471
/// See https://www.lua.org/manual/5.4/manual.html#lua_getfield
466472
pub fn getField(lua: *Lua, index: i32, key: [:0]const u8) void {
@@ -807,6 +813,13 @@ pub const Lua = struct {
807813
c.lua_setallocf(lua.state, alloc_fn, data);
808814
}
809815

816+
/// Pops a table from the stack and sets it as the new environment for the value at the
817+
/// given index. Returns an error if the value at that index is not a function or thread or userdata.
818+
/// See https://www.lua.org/manual/5.1/manual.html#setfenv
819+
pub fn setFnEnvironment(lua: *Lua, index: i32) !void {
820+
if (c.lua_setfenv(lua.state, index) == 0) return error.Fail;
821+
}
822+
810823
/// Does the equivalent to t[`k`] = v where t is the value at the given `index`
811824
/// and v is the value on the top of the stack
812825
pub fn setField(lua: *Lua, index: i32, k: [:0]const u8) void {

src/ziglua-5.1/tests.zig

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,3 +1116,35 @@ test "refs" {
11161116
_ = Lua.doFile;
11171117
_ = Lua.loadFile;
11181118
}
1119+
1120+
test "function environments" {
1121+
var lua = try Lua.init(testing.allocator);
1122+
defer lua.deinit();
1123+
1124+
try lua.doString("function test() return x end");
1125+
1126+
// set the global _G.x to be 10
1127+
lua.pushInteger(10);
1128+
lua.setGlobal("x");
1129+
1130+
lua.getGlobal("test");
1131+
try lua.protectedCall(0, 1, 0);
1132+
try testing.expectEqual(@as(Integer, 10), lua.toInteger(1));
1133+
lua.pop(1);
1134+
1135+
// now set the functions table to have a different value of x
1136+
lua.getGlobal("test");
1137+
lua.newTable();
1138+
lua.pushInteger(20);
1139+
lua.setField(2, "x");
1140+
try lua.setFnEnvironment(1);
1141+
1142+
try lua.protectedCall(0, 1, 0);
1143+
try testing.expectEqual(@as(Integer, 20), lua.toInteger(1));
1144+
lua.pop(1);
1145+
1146+
lua.getGlobal("test");
1147+
lua.getFnEnvironment(1);
1148+
lua.getField(2, "x");
1149+
try testing.expectEqual(@as(Integer, 20), lua.toInteger(3));
1150+
}

0 commit comments

Comments
 (0)