Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions sandbox/ConsoleApp1/Program.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Runtime.CompilerServices;
using Lua.CodeAnalysis.Syntax;
using Lua.CodeAnalysis.Compilation;
using Lua.Runtime;
Expand All @@ -11,7 +12,7 @@

try
{
var source = File.ReadAllText("test.lua");
var source = File.ReadAllText(GetAbsolutePath("test.lua"));

var syntaxTree = LuaSyntaxTree.Parse(source, "test.lua");

Expand Down Expand Up @@ -41,6 +42,15 @@
catch (Exception ex)
{
Console.WriteLine(ex);
if(ex is LuaRuntimeException { InnerException: not null } luaEx)
{
Console.WriteLine(luaEx.InnerException);
}
}

static string GetAbsolutePath(string relativePath, [CallerFilePath] string callerFilePath = "")
{
return Path.Combine(Path.GetDirectoryName(callerFilePath)!, relativePath);
}

static void DebugChunk(Chunk chunk, int id)
Expand All @@ -56,14 +66,24 @@ static void DebugChunk(Chunk chunk, int id)
index++;
}

Console.WriteLine("Constants " + new string('-', 50)); index = 0;
Console.WriteLine("Locals " + new string('-', 50));
index = 0;
foreach (var local in chunk.Locals.ToArray())
{
Console.WriteLine($"[{index}]\t{local.Index}\t{local.Name}\t{local.StartPc}\t{local.EndPc}");
index++;
}

Console.WriteLine("Constants " + new string('-', 50));
index = 0;
foreach (var constant in chunk.Constants.ToArray())
{
Console.WriteLine($"[{index}]\t{constant}");
index++;
}

Console.WriteLine("UpValues " + new string('-', 50)); index = 0;
Console.WriteLine("UpValues " + new string('-', 50));
index = 0;
foreach (var upValue in chunk.UpValues.ToArray())
{
Console.WriteLine($"[{index}]\t{upValue.Name}\t{(upValue.IsInRegister ? 1 : 0)}\t{upValue.Index}");
Expand Down
1 change: 1 addition & 0 deletions src/Lua/CodeAnalysis/Compilation/Descriptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace Lua.CodeAnalysis.Compilation
public readonly record struct LocalVariableDescription
{
public required byte RegisterIndex { get; init; }
public required int StartPc { get; init; }
}

public readonly record struct FunctionDescription
Expand Down
46 changes: 41 additions & 5 deletions src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ internal static FunctionCompilationContext Create(ScopeCompilationContext? paren

// upvalues
FastListCore<UpValueInfo> upvalues;
FastListCore<LocalValueInfo> localVariables;

// loop
FastListCore<BreakDescription> breakQueue;
Expand Down Expand Up @@ -90,6 +91,16 @@ internal static FunctionCompilationContext Create(ScopeCompilationContext? paren
/// </summary>
public bool HasVariableArguments { get; set; }

/// <summary>
/// Line number where the function is defined
/// </summary>
public int LineDefined { get; set; }

/// <summary>
/// Last line number where the function is defined
/// </summary>
public int LastLineDefined { get; set; }

/// <summary>
/// Parent scope context
/// </summary>
Expand Down Expand Up @@ -127,6 +138,7 @@ public void PushOrMergeInstruction(int lastLocal, in Instruction instruction, in
instructionPositions.Add(position);
return;
}

ref var lastInstruction = ref instructions.AsSpan()[^1];
var opcode = instruction.OpCode;
switch (opcode)
Expand Down Expand Up @@ -156,6 +168,7 @@ public void PushOrMergeInstruction(int lastLocal, in Instruction instruction, in
}
}
}

break;
case OpCode.GetTable:
{
Expand All @@ -169,8 +182,8 @@ public void PushOrMergeInstruction(int lastLocal, in Instruction instruction, in
incrementStackPosition = false;
return;
}

}

break;
}
case OpCode.SetTable:
Expand All @@ -197,6 +210,7 @@ public void PushOrMergeInstruction(int lastLocal, in Instruction instruction, in
return;
}
}

lastInstruction = Instruction.SetTable((byte)(lastB), instruction.B, instruction.C);
instructionPositions[^1] = position;
incrementStackPosition = false;
Expand All @@ -217,7 +231,6 @@ public void PushOrMergeInstruction(int lastLocal, in Instruction instruction, in
var last2OpCode = last2Instruction.OpCode;
if (last2OpCode is OpCode.LoadK or OpCode.Move)
{

var last2A = last2Instruction.A;
if (last2A != lastLocal && instruction.C == last2A)
{
Expand All @@ -231,18 +244,21 @@ public void PushOrMergeInstruction(int lastLocal, in Instruction instruction, in
}
}
}

break;
}
case OpCode.Unm:
case OpCode.Not:
case OpCode.Len:
if (lastInstruction.OpCode == OpCode.Move && lastLocal != lastInstruction.A && lastInstruction.A == instruction.B)
{
lastInstruction = instruction with { B = lastInstruction.B }; ;
lastInstruction = instruction with { B = lastInstruction.B };
;
instructionPositions[^1] = position;
incrementStackPosition = false;
return;
}

break;
case OpCode.Return:
if (lastInstruction.OpCode == OpCode.Move && instruction.B == 2 && lastInstruction.B < 256)
Expand All @@ -252,6 +268,7 @@ public void PushOrMergeInstruction(int lastLocal, in Instruction instruction, in
incrementStackPosition = false;
return;
}

break;
}

Expand Down Expand Up @@ -302,6 +319,17 @@ public bool TryGetFunctionProto(ReadOnlyMemory<char> name, [NotNullWhen(true)] o
}
}

public void AddLocalVariable(ReadOnlyMemory<char> name, LocalVariableDescription description)
{
localVariables.Add(new LocalValueInfo()
{
Name = name,
Index = description.RegisterIndex,
StartPc = description.StartPc,
EndPc = Instructions.Length,
});
}

public void AddUpValue(UpValueInfo upValue)
{
upvalues.Add(upValue);
Expand Down Expand Up @@ -378,6 +406,7 @@ public void ResolveAllBreaks(byte startPosition, int endPosition, ScopeCompilati
{
instruction.A = startPosition;
}

instruction.SBx = endPosition - description.Index;
}

Expand Down Expand Up @@ -409,18 +438,24 @@ public Chunk ToChunk()
{
// add return
instructions.Add(Instruction.Return(0, 1));
instructionPositions.Add(instructionPositions.Length == 0 ? default : instructionPositions[^1]);

instructionPositions.Add( new (LastLineDefined, 0));
Scope.RegisterLocalsToFunction();
var locals = localVariables.AsSpan().ToArray();
Array.Sort(locals, (x, y) => x.Index.CompareTo(y.Index));
var chunk = new Chunk()
{
Name = ChunkName ?? "chunk",
Instructions = instructions.AsSpan().ToArray(),
SourcePositions = instructionPositions.AsSpan().ToArray(),
Constants = constants.AsSpan().ToArray(),
UpValues = upvalues.AsSpan().ToArray(),
Locals = locals,
Functions = functions.AsSpan().ToArray(),
ParameterCount = ParameterCount,
HasVariableArguments = HasVariableArguments,
MaxStackPosition = MaxStackPosition,
LineDefined = LineDefined,
LastLineDefined = LastLineDefined,
};

foreach (var function in functions.AsSpan())
Expand All @@ -442,6 +477,7 @@ public void Reset()
constantIndexMap.Clear();
constants.Clear();
upvalues.Clear();
localVariables.Clear();
functionMap.Clear();
functions.Clear();
breakQueue.Clear();
Expand Down
Loading