Skip to content
Closed
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
7 changes: 4 additions & 3 deletions sandbox/Benchmark/AddBenchmark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ public void Setup()
core.Setup("add.lua");
core.LuaCSharpState.OpenStandardLibraries();

core.LuaCSharpState.Environment["add"] = new LuaFunction("add", (context, buffer, ct) =>
core.LuaCSharpState.Environment["add"] = new LuaFunction("add", (context, ct) =>
{
buffer.Span[0] = context.GetArgument<double>(0) + context.GetArgument<double>(1);
return new(1);
var a = context.GetArgument<double>(0);
var b = context.GetArgument<double>(1);
return new(context.Return(a + b));
});
core.MoonSharpState.Globals["add"] = (Func<double, double, double>)Add;
core.NLuaState.RegisterFunction("add", typeof(AddBenchmark).GetMethod(nameof(Add), BindingFlags.Static | BindingFlags.Public));
Expand Down
4 changes: 3 additions & 1 deletion sandbox/Benchmark/InterpreterSteps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ public Chunk Compile()
[Benchmark]
public async ValueTask RunAsync()
{
await state.RunAsync(chunk, results);
using (await state.RunAsync(chunk))
{
}
}
}
35 changes: 29 additions & 6 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 All @@ -26,12 +27,11 @@

Console.WriteLine("Output " + new string('-', 50));

var results = new LuaValue[64];
var resultCount = await state.RunAsync(chunk, results);
using var results = await state.RunAsync(chunk);

Console.WriteLine("Result " + new string('-', 50));

for (int i = 0; i < resultCount; i++)
for (int i = 0; i < results.Count; i++)
{
Console.WriteLine(results[i]);
}
Expand All @@ -41,6 +41,19 @@
catch (Exception ex)
{
Console.WriteLine(ex);
if (ex is LuaRuntimeException luaRuntimeException)
{
Console.WriteLine(luaRuntimeException.LuaTraceback);
if (ex is { 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 +69,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
27 changes: 15 additions & 12 deletions src/Lua.SourceGenerator/LuaObjectGenerator.Emit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ static bool ValidateMembers(TypeMetadata typeMetadata, Compilation compilation,

static bool TryEmitIndexMetamethod(TypeMetadata typeMetadata, CodeBuilder builder, in SourceProductionContext context)
{
builder.AppendLine(@"static readonly global::Lua.LuaFunction __metamethod_index = new global::Lua.LuaFunction(""index"", (context, buffer, ct) =>");
builder.AppendLine(@"static readonly global::Lua.LuaFunction __metamethod_index = new global::Lua.LuaFunction(""index"", (context, ct) =>");

using (builder.BeginBlockScope())
{
Expand Down Expand Up @@ -233,8 +233,7 @@ static bool TryEmitIndexMetamethod(TypeMetadata typeMetadata, CodeBuilder builde
}
builder.AppendLine(";");

builder.AppendLine("buffer.Span[0] = result;");
builder.AppendLine("return new(1);");
builder.AppendLine( "return new global::System.Threading.Tasks.ValueTask<int>(context.Return(result));");
}

builder.AppendLine(");");
Expand All @@ -244,7 +243,7 @@ static bool TryEmitIndexMetamethod(TypeMetadata typeMetadata, CodeBuilder builde

static bool TryEmitNewIndexMetamethod(TypeMetadata typeMetadata, CodeBuilder builder, in SourceProductionContext context)
{
builder.AppendLine(@"static readonly global::Lua.LuaFunction __metamethod_newindex = new global::Lua.LuaFunction(""newindex"", (context, buffer, ct) =>");
builder.AppendLine(@"static readonly global::Lua.LuaFunction __metamethod_newindex = new global::Lua.LuaFunction(""newindex"", (context, ct) =>");

using (builder.BeginBlockScope())
{
Expand Down Expand Up @@ -295,8 +294,7 @@ static bool TryEmitNewIndexMetamethod(TypeMetadata typeMetadata, CodeBuilder bui
builder.AppendLine(@$"throw new global::Lua.LuaRuntimeException(context.State.GetTraceback(), $""'{{key}}' not found."");");
}
}

builder.AppendLine("return new(0);");
builder.AppendLine( "return new global::System.Threading.Tasks.ValueTask<int>(context.Return());");
}

builder.AppendLine(");");
Expand Down Expand Up @@ -348,7 +346,7 @@ static bool TryEmitMethods(TypeMetadata typeMetadata, CodeBuilder builder, Symbo

static void EmitMethodFunction(string functionName, string chunkName, TypeMetadata typeMetadata, MethodMetadata methodMetadata, CodeBuilder builder, SymbolReferences references)
{
builder.AppendLine($@"static readonly global::Lua.LuaFunction {functionName} = new global::Lua.LuaFunction(""{chunkName}"", {(methodMetadata.IsAsync ? "async" : "")} (context, buffer, ct) =>");
builder.AppendLine($@"static readonly global::Lua.LuaFunction {functionName} = new global::Lua.LuaFunction(""{chunkName}"", {(methodMetadata.IsAsync ? "async" : "")} (context, ct) =>");

using (builder.BeginBlockScope())
{
Expand Down Expand Up @@ -413,23 +411,28 @@ static void EmitMethodFunction(string functionName, string chunkName, TypeMetada
builder.Append(string.Join(",", Enumerable.Range(1, index - 1).Select(x => $"arg{x}")), false);
builder.AppendLine(");", false);
}


builder.Append("return ");
if (methodMetadata.HasReturnValue)
{
if (SymbolEqualityComparer.Default.Equals(methodMetadata.Symbol.ReturnType, references.LuaValue))
{
builder.AppendLine("buffer.Span[0] = result;");

builder.AppendLine(methodMetadata.IsAsync ?
"context.Return(result));" :
"new global::System.Threading.Tasks.ValueTask<int>(context.Return(result));");
}
else
{
builder.AppendLine("buffer.Span[0] = new global::Lua.LuaValue(result);");
builder.AppendLine(methodMetadata.IsAsync ?
"context.Return(new global::Lua.LuaValue(result))));" :
"new global::System.Threading.Tasks.ValueTask<int>(context.Return(new global::Lua.LuaValue(result)));");
}

builder.AppendLine($"return {(methodMetadata.IsAsync ? "1" : "new(1)")};");
}
else
{
builder.AppendLine($"return {(methodMetadata.IsAsync ? "0" : "new(0)")};");
builder.AppendLine(methodMetadata.IsAsync ? "context.Return();" : "new global::System.Threading.Tasks.ValueTask<int>(context.Return());");
}
}
builder.AppendLine(");");
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