| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 |
- using System.Runtime.CompilerServices;
- using Lua.Internal;
- namespace Lua.Runtime;
- public sealed class Closure : LuaFunction
- {
- Chunk proto;
- FastListCore<UpValue> upValues;
- public Closure(LuaState state, Chunk proto, LuaTable? environment = null)
- : base(proto.Name, (context, buffer, ct) => LuaVirtualMachine.ExecuteClosureAsync(context.State, buffer, ct))
- {
- this.proto = proto;
- // add upvalues
- for (int i = 0; i < proto.UpValues.Length; i++)
- {
- var description = proto.UpValues[i];
- var upValue = GetUpValueFromDescription(state, state.CurrentThread, environment == null ? state.EnvUpValue : UpValue.Closed(environment), description);
- upValues.Add(upValue);
- }
- IsClosure = true;
- }
- public Chunk Proto => proto;
- public ReadOnlySpan<UpValue> UpValues => upValues.AsSpan();
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal LuaValue GetUpValue(int index)
- {
- return upValues[index].GetValue();
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal void SetUpValue(int index, LuaValue value)
- {
- upValues[index].SetValue(value);
- }
- static UpValue GetUpValueFromDescription(LuaState state, LuaThread thread, UpValue envUpValue, UpValueInfo description)
- {
- if (description.IsInRegister)
- {
- return state.GetOrAddUpValue(thread, thread.GetCallStackFrames()[^1].Base + description.Index);
- }
- if (description.Index == -1) // -1 is global environment
- {
- return envUpValue;
- }
- {
- if (thread.GetCallStackFrames()[^1].Function is Closure parentClosure)
- {
- return parentClosure.UpValues[description.Index];
- }
- throw new InvalidOperationException("invalid upvalue description.");
- }
- }
- }
|