| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- using System.Runtime.CompilerServices;
- using Lua.Internal;
- namespace Lua.Runtime;
- public class LuaStack(int initialSize = 256)
- {
- LuaValue[] array = new LuaValue[initialSize];
- int top;
- public int Count => top;
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void EnsureCapacity(int newSize)
- {
- var size = array.Length;
- if (size >= newSize) return;
- while (size < newSize)
- {
- size *= 2;
- }
- Array.Resize(ref array, size);
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void NotifyTop(int top)
- {
- if (this.top < top) this.top = top;
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void Push(LuaValue value)
- {
- EnsureCapacity(top + 1);
- UnsafeGet(top) = value;
- top++;
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void PushRange(ReadOnlySpan<LuaValue> values)
- {
- EnsureCapacity(top + values.Length);
- values.CopyTo(array.AsSpan()[top..]);
- top += values.Length;
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public LuaValue Pop()
- {
- if (top == 0) ThrowEmptyStack();
- top--;
- var item = UnsafeGet(top);
- UnsafeGet(top) = default;
- return item;
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void PopUntil(int newSize)
- {
- if (newSize >= top) return;
- if (newSize == 0)
- {
- array.AsSpan().Clear();
- }
- else
- {
- array.AsSpan(newSize - 1).Clear();
- }
- top = newSize;
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void Clear()
- {
- array.AsSpan().Clear();
- top = 0;
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Span<LuaValue> AsSpan()
- {
- return new Span<LuaValue>(array, 0, top);
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Span<LuaValue> GetBuffer()
- {
- return array.AsSpan();
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Memory<LuaValue> GetBufferMemory()
- {
- return array.AsMemory();
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public ref LuaValue UnsafeGet(int index)
- {
- return ref MemoryMarshalEx.UnsafeElementAt(array, index);
- }
- static void ThrowEmptyStack()
- {
- throw new InvalidOperationException("Empty stack");
- }
- }
|