yanghuan / CSharp.lua

The C# to Lua compiler
Other
1.23k stars 202 forks source link

Order of input files can cause runtime errors #488

Closed joelverhagen closed 9 months ago

joelverhagen commented 10 months ago

The repro requires at least two files.

Program.cs

namespace FooBar;

public static class Program
{
    public static void Main()
    {
        var x = new Knapcode.ClassA<string>();
    }
}

LuaTest.cs

using System;
using System.Collections.Generic;

namespace Knapcode;

public class ClassA<T>
{
    public IEnumerable<KeyValuePair<MyStruct, T?>> EnumerateItems()
    {
        yield return new KeyValuePair<MyStruct, T?>(new MyStruct(), default);
    }
}

public struct MyStruct
{
}

Works: ./CSharp.lua.Launcher -s "LuaTest.cs;Program.cs" -d DT Does not work: ./CSharp.lua.Launcher -s "Program.cs;LuaTest.cs" -d DT

The generated Lua appears to be based on the input order which causes a problem with this line:

local KeyValuePairMyStructT = System.KeyValuePair(Knapcode.MyStruct, T)

Error:

lua5.2: ./out.lua:19675: attempt to index upvalue 'Knapcode' (a nil value)
stack traceback:
        ./out.lua:19675: in function 'cls'
        ./out.lua:371: in function 'ClassA_1'
        ./out.lua:19650: in function '?'
        ./out.lua:1637: in function 'init'
        ./out.lua:19693: in main chunk
        [C]: in function 'require'
        main.lua:1: in main chunk
        [C]: in ?

Workaround is to fiddle with the input order until the runtime works. Another workaround is to manually edit the Lua to move the usage of Knapcode.MyStruct into a method that uses the type (instead of in the initializer method where it is right now).