Skip to content

Commit aa077c8

Browse files
authored
pass original argument of require call to executed chunk (#85)
Fixes #83 Quoting SWeini: How the "fix" works: The first commit makes the argument to `require` available to the executed chunk of code. The require guards introduced by flib rely on the `...` being populated with the argument that was passed to the require call. The second commit reverts some de-duplication on YAFC-side which made something similar to what the require guards were doing. The caching in `required` dictionary now happens based on the argument, not on the resolved filename. Previously the require guards in flib didn't play nicely with the de-duplication happening in YAFC. Findings along the way: - There is not a single `luaL_unref` call in the codebase. Instead the whole lua context is disposed after loading everything. - The `LuaContext.Require` method looks very hacky. Relying on the stacktrace (`luaL_traceback`) to load relative files is kind of weird, but it works. I'm not sure how much the logic and search priorities mirror what Factorio is doing. But it worked so far. - `LuaContext.Require` has a weird line: `required[...] = LUA_REFNIL;` just before executing the code might not be exactly what should happen. The documentation says that it stores `nil` afterwards, and only if the executed chunk didn't write to `package.loaded[modname]`. We don't have `package.loaded` so that doesn't matter, but the unfixed caching should have ended up in a stack overflow instead of just returning nil. Was this assignment added to "fix" stack overflows previously? - The more I looked into this part of the code the more I was astonished that it does work most of the time. I still think that going to use --dump-data and read everything from json would remove a lot of complexity and a whole category of bugs.
2 parents 31966f4 + a51b6ea commit aa077c8

File tree

1 file changed

+8
-5
lines changed

1 file changed

+8
-5
lines changed

YAFCparser/LuaContext.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ private enum Type {
7878
private IntPtr L;
7979
private readonly int tracebackReg;
8080
private readonly List<(string mod, string name)> fullChunkNames = new List<(string, string)>();
81-
private readonly Dictionary<(string mod, string filename), int> required = new Dictionary<(string mod, string filename), int>();
81+
private readonly Dictionary<string, int> required = new Dictionary<string, int>();
8282
private readonly Dictionary<(string mod, string name), byte[]> modFixes = new Dictionary<(string mod, string name), byte[]>();
8383

8484
public LuaContext() {
@@ -285,6 +285,7 @@ private string GetDirectoryName(string s) {
285285

286286
private int Require(IntPtr lua) {
287287
string file = GetString(1); // 1
288+
string argument = file;
288289
if (file.Contains("..")) {
289290
throw new NotSupportedException("Attempt to traverse to parent directory");
290291
}
@@ -339,21 +340,23 @@ private int Require(IntPtr lua) {
339340
}
340341
}
341342

342-
if (required.TryGetValue(requiredFile, out int value)) {
343+
if (required.TryGetValue(argument, out int value)) {
343344
GetReg(value);
344345
return 1;
345346
}
346-
required[requiredFile] = LUA_REFNIL;
347+
required[argument] = LUA_REFNIL;
347348
Console.WriteLine("Require " + requiredFile.mod + "/" + requiredFile.path);
348349
byte[] bytes = FactorioDataSource.ReadModFile(requiredFile.mod, requiredFile.path);
349350
if (bytes != null) {
350-
int result = Exec(bytes, requiredFile.mod, requiredFile.path);
351+
_ = lua_pushstring(L, argument);
352+
int argumentReg = luaL_ref(L, REGISTRY);
353+
int result = Exec(bytes, requiredFile.mod, requiredFile.path, argumentReg);
351354
if (modFixes.TryGetValue(requiredFile, out byte[] fix)) {
352355
string modFixName = "mod-fix-" + requiredFile.mod + "." + requiredFile.path;
353356
Console.WriteLine("Running mod-fix " + modFixName);
354357
result = Exec(fix, "*", modFixName, result);
355358
}
356-
required[requiredFile] = result;
359+
required[argument] = result;
357360
GetReg(result);
358361
}
359362
else {

0 commit comments

Comments
 (0)