public void SetTop(int idx) { int newTop = LuaStack.AbsIndex(idx); if (newTop < 0) { throw new LuaException("stack underflow!"); } int n = LuaStack.Top - newTop; if (n > 0) { for (int i = 0; i < n; i++) { LuaStack.Pop(); } } else if (n < 0) { for (int i = 0; i > n; i--) { LuaStack.Push(LuaValue.Nil); } } }
public void Call(int nArgs, int nResults) { var val = LuaStack.Get(-(nArgs + 1)); var f = val.Value as LuaClosure; if (f == null) { if (LuaValue.GetMetaField(val, "__call", this) is LuaValue mf) { if (mf.Value is LuaClosure c) { LuaStack.Push(val); Insert(-(nArgs + 2)); nArgs += 1; f = c; } } } if (f != null) { if (f.Proto != null) { CallLuaClosure(nArgs, nResults, f); } else { CallCSharpClosure(nArgs, nResults, f); } } else { throw new LuaException("not function!"); } }
static int Log(IntPtr state) { string log = LuaStack.GetString(state, -1); Debug.Log(log); return(0); }
public LuaType RawGet(int idx) { var t = LuaStack.Get(idx); var k = LuaStack.Pop(); return(GetTable(t, k, true)); }
public void Arith(ArithOp op) { LuaValue a, b; b = LuaStack.Pop(); if (op != ArithOp.Unm && op != ArithOp.Bnot) { a = LuaStack.Pop(); } else { a = b; } var aop = global::Arith.Operators[(int)op]; var result = ArithSub(a, b, aop); if (result.Value != null) { LuaStack.Push(result); return; } string mm = aop.Metamethod; if (LuaValue.TryCallMetamethod(a, b, mm, this, out LuaValue metaRes)) { LuaStack.Push(metaRes); return; } throw new LuaException("arithmetic error!");
public void LoadProto(int idx) { var subProto = LuaStack.Closure.Proto.Protos[idx]; var closure = new LuaClosure(subProto); LuaStack.Push(closure); for (int i = 0; i < subProto.UpValues.Length; i++) { var uvInfo = subProto.UpValues[i]; int uvIdx = uvInfo.Idx; if (uvInfo.InStack == 1) { if (LuaStack.Openuvs == null) { LuaStack.Openuvs = new Dictionary <int, LuaUpValue>(); } if (LuaStack.Openuvs.TryGetValue(uvIdx, out LuaUpValue openuv)) { closure.Upvals[i] = openuv; } else { closure.Upvals[i] = LuaUpValue.CreateOpen(LuaStack, uvIdx); LuaStack.Openuvs[uvIdx] = closure.Upvals[i]; } } else { closure.Upvals[i] = LuaStack.Closure.Upvals[uvIdx]; } } }
public void RawSetGlobal(string name) { var t = Registry.Get(Consts.LUA_RIDX_GLOBALS); var v = LuaStack.Pop(); SetTable(t, name, v, true); }
public static LuaState New() { return(new LuaState { stack = LuaStack.newLuaStack(20) }); }
public void SetField(int idx, string k) { var t = LuaStack.Get(idx); var v = LuaStack.Pop(); SetTable(t, k, v, false); }
public void RawSetI(int idx, Int64 i) { var t = LuaStack.Get(idx); var v = LuaStack.Pop(); SetTable(t, i, v, true); }
public void Concat(int n) { if (n == 0) { LuaStack.Push(new LuaValue(string.Empty)); } else if (n >= 2) { for (int i = 1; i < n; i++) { if (IsString(-1) && IsString(-2)) { string s2 = ToString(-1); string s1 = ToString(-2); LuaStack.Pop(); LuaStack.Pop(); LuaStack.Push(new LuaValue(s1 + s2)); continue; } var b = LuaStack.Pop(); var a = LuaStack.Pop(); if (LuaValue.TryCallMetamethod(a, b, "__concat", this, out LuaValue result)) { LuaStack.Push(result); continue; } throw new LuaException("concatenation error!"); } } // n == 1, do nothing }
public LuaType GetTable(int idx) { var t = LuaStack.Get(idx); var k = LuaStack.Pop(); return(GetTable(t, k, false)); }
public void SetTable(int idx) { var t = LuaStack.Get(idx); var v = LuaStack.Pop(); var k = LuaStack.Pop(); SetTable(t, k, v, false); }
public void RawSet(int idx) { var t = LuaStack.Get(idx); var v = LuaStack.Pop(); var k = LuaStack.Pop(); SetTable(t, k, v, true); }
public void Migrate() { if (_stack == null) { return; } _val = _stack.Get(Index + 1); _stack = null; }
public void LoadVararg(int n) { if (n < 0) { n = LuaStack.Varargs.Count; } LuaStack.Check(n); LuaStack.PushN(LuaStack.Varargs.ToArray(), n); }
static int TimeoutAsync(IntPtr state) { IntPtr co = LuaStack.GetThread(state, 1); float time = (float)LuaStack.GetNumber(state, 2); Observable.Timer(TimeSpan.FromSeconds(time)).Subscribe(x => { LuaThread.ResumeSubthread(co, state, 0, out _); }); return(0); }
public bool IsCSharpFunction(int idx) { var val = LuaStack.Get(idx); if (val.Value is LuaClosure lc) { return(lc.CSharpFunc != null); } return(false); }
public void Rotate(int idx, int n) { int t = LuaStack.Top - 1; int p = LuaStack.AbsIndex(idx) - 1; int m = n >= 0 ? t - n : p - n - 1; LuaStack.Reverse(p, m); LuaStack.Reverse(m + 1, t); LuaStack.Reverse(p, t); }
public void PushCSharpClosure(CSharpFunction f, int n) { var closure = new LuaClosure(f, n); for (int i = n - 1; i >= 0; i--) { var val = LuaStack.Pop(); closure.Upvals[i] = LuaUpValue.CreateClosed(val); } LuaStack.Push(closure); }
public bool Compare(int idx1, int idx2, CompareOp op) { var a = LuaStack.Get(idx1); var b = LuaStack.Get(idx2); return(op switch { CompareOp.Eq => Eq(a, b, this), CompareOp.Lt => Lt(a, b, this), CompareOp.Le => Le(a, b, this), _ => throw new LuaException("invalid compare op!") });
private void CallLuaClosure(int nArgs, int nResults, LuaClosure c) { int nRegs = c.Proto.MaxStackSize; int nParams = c.Proto.NumParams; bool isVararg = c.Proto.IsVararg == 1; var newStack = new LuaStack(nRegs + 20, this) { Closure = c }; LuaValue[] funcAndArgs = LuaStack.PopN(nArgs + 1); newStack.PushN(funcAndArgs[1..], nParams);
public ErrState Load(byte[] chunk, string chunkName, string mode) { var proto = Prototype.Undump(chunk); var c = new LuaClosure(proto); LuaStack.Push(c); if (proto.UpValues != null && proto.UpValues.Length > 0) { var env = Registry.Get(Consts.LUA_RIDX_GLOBALS); c.Upvals[0] = LuaUpValue.CreateClosed(env); } return(ErrState.Ok); }
public bool GetMetatable(int idx) { var val = LuaStack.Get(idx); if (LuaValue.GetMetatable(val, this) is LuaTable mt) { LuaStack.Push(mt); return(true); } else { return(false); } }
public uint RawLen(int idx) { var val = LuaStack.Get(idx); if (val.Value is string s) { return((uint)s.Length); } else if (val.Value is LuaTable t) { return((uint)t.Len); } return(0); }
public bool Next(int idx) { var val = LuaStack.Get(idx); if (val.Value is LuaTable t) { var key = LuaStack.Pop(); var nextKey = t.NextKey(key); if (nextKey.Value != null) { LuaStack.Push(nextKey); LuaStack.Push(t.Get(nextKey)); return(true); } return(false); } throw new LuaException("table expected!"); }
public void SetMetatable(int idx) { var val = LuaStack.Get(idx); var mtVal = LuaStack.Pop(); if (mtVal == null) { LuaValue.SetMetatable(val, null, this); } else if (mtVal.Value is LuaTable mt) { LuaValue.SetMetatable(val, mt, this); } else { throw new LuaException("table expected!"); } }
public void Len(int idx) { var val = LuaStack.Get(idx); if (val.Value is string s) { LuaStack.Push(new LuaValue((Int64)s.Length)); } else if (LuaValue.TryCallMetamethod(val, val, "__len", this, out LuaValue result)) { LuaStack.Push(result); } else if (val.Value is LuaTable t) { LuaStack.Push(t.Len); } else { throw new LuaException("lengh error!"); } }
public ErrState PCall(int nArgs, int nResults, int msgh) { var caller = LuaStack; var status = ErrState.ErrRun; try { Call(nArgs, nResults); status = ErrState.Ok; return(status); } catch (LuaException e) { while (LuaStack != caller) { PopLuaStack(); } LuaStack.Push(e.Content); } return(status); }
private LuaType GetTable(LuaValue t, LuaValue k, bool raw) { if (t.Value is LuaTable tbl) { var v = tbl.Get(k); if (raw || v.Value != null || !tbl.HasMetafield("__index")) { LuaStack.Push(v); return(LuaValue.TypeOf(v)); } } if (!raw) { if (LuaValue.GetMetaField(t, "__index", this) is LuaValue mf) { switch (mf.Value) { case LuaTable x: return(GetTable(x, k, false)); case LuaClosure _: { LuaStack.Push(mf); LuaStack.Push(t); LuaStack.Push(k); Call(2, 1); var v = LuaStack.Get(-1); return(LuaValue.TypeOf(v)); } } } } throw new LuaException("not a table!"); }