/// <summary> /// 将源寄存器值赋值到目标寄存器,源寄存器由b指定,目标寄存器为a,c无效 /// </summary> /// <param name="i"></param> public void Move(Instruction i) { int a = 0, b = 0, c = 0; i.ABC(ref a, ref b, ref c); luaState.CopyTo(b + 1, a + 1); }
/// <summary> /// setupval指令,将寄存器的值赋值给upval,a指定寄存器索引,b指定upval索引,c没用 /// </summary> /// <param name="i"></param> public void SetUpval(Instruction i) { int a = 0, b = 0, c = 0; i.ABC(ref a, ref b, ref c); luaState.SetUpval(b, luaState.Get(a + 1)); }
private static void printOperands(Instruction i) { int a, b, c, ax, bx, sbx; switch (i.OpMode()) { case OpCodes.IABC: var abc = i.ABC(); Console.Write($"{abc.Item1:D}", abc.Item1); if (i.BMode() != OpCodes.OpArgN) { if (abc.Item2 > 0xFF) { Console.Write($" {-1 - (abc.Item2 & 0xFF):D}"); } else { Console.Write($" {abc.Item2:D}"); } } if (i.CMode() != OpCodes.OpArgN) { if (abc.Item3 > 0xFF) { Console.Write($"{-1 - (abc.Item3 & 0xFF):D}"); } else { Console.Write($" {abc.Item3:D}"); } } break; case OpCodes.IABx: var aBx = i.ABx(); Console.Write($" {aBx.Item1:D}"); if (i.BMode() == OpCodes.OpArgK) { Console.Write($"{-1 - aBx.Item2:D}"); } else if (i.BMode() == OpCodes.OpArgU) { Console.Write($" {aBx.Item2:D}"); } break; case OpCodes.IAsBx: var asBx = i.AsBx(); Console.Write($"{asBx.Item1:D} {asBx.Item2:D}"); break; case OpCodes.IAx: ax = i.Ax(); Console.Write($"{-1 - ax:D}"); break; } }
/// <summary> /// not指令,求某个变量是否为nil,a指定结果寄存器索引,b指定变量寄存器索引 /// </summary> /// <param name="i"></param> public void Not(Instruction i) { int a = 0, b = 0, c = 0; i.ABC(ref a, ref b, ref c); luaState.Push(new LuaValue(luaState.IsBool(b + 1), LuaValueType.Bool)); luaState.Replace(a + 1); }
internal static void GetUpval(Instruction i, ILuaVM vm) { var(a, b, _) = i.ABC(); a += 1; b += 1; vm.Copy(LuaState.LuaUpvalueIndex(b), a); }
/// <summary> /// 求长度指令,b代表变量寄存器索引,a代表结果目标索引 /// </summary> /// <param name="i"></param> public void Len(Instruction i) { int a = 0, b = 0, c = 0; i.ABC(ref a, ref b, ref c); luaState.Len(b + 1); luaState.Replace(a + 1); }
internal static void NewTable(Instruction i, ILuaVM vm) { var(a, b, c) = i.ABC(); a += 1; vm.CreateTable(Fb2int(b), Fb2int(c)); vm.Replace(a); }
internal static void Len(Instruction i, ILuaVM vm) { var(a, b, _) = i.ABC(); a += 1; b += 1; vm.Len(b); vm.Replace(a); }
internal static void Not(Instruction i, ILuaVM vm) { var(a, b, _) = i.ABC(); a += 1; b += 1; vm.PushBoolean(!vm.ToBoolean(b)); vm.Replace(a); }
internal static void SetTabUp(Instruction i, ILuaVM vm) { var(a, b, c) = i.ABC(); a += 1; vm.GetRK(b); vm.GetRK(c); vm.SetTable(LuaState.LuaUpvalueIndex(a)); }
internal static void TForCall(Instruction i, ILuaVM vm) { var(a, _, c) = i.ABC(); a += 1; PushFuncAndArgs(a, 3, vm); vm.Call(2, c); PopResults(a + 3, c + 1, vm); }
public static void SetTable(Instruction i, ILuaVM vm) { var(a, b, c) = i.ABC(); a += 1; vm.GetRK(b); vm.GetRK(c); vm.SetTable(a); }
/// <summary> /// NEWTABLE指令(iABC模式)创建空表,并将其放入指定寄存器。寄存器索引由操作数A指定,表的初始数组容量和哈希表容量分别由操作数B和C指定。 /// </summary> /// <param name="i"></param> public void NewTable(Instruction i) { int a = 0, b = 0, c = 0; i.ABC(ref a, ref b, ref c); a += 1; luaState.CreatLuaTable(b, c); luaState.Replace(a); }
internal static void Test(Instruction i, ILuaVM vm) { var(a, _, c) = i.ABC(); a += 1; if (vm.ToBoolean(a) != (c != 0)) { vm.AddPC(1); } }
internal static void Call(Instruction i, ILuaVM vm) { var(a, b, c) = i.ABC(); a += 1; int nArgs = PushFuncAndArgs(a, b, vm); vm.Call(nArgs, c - 1); PopResults(a, c, vm); }
private static void UnaryArith(Instruction i, ILuaVM vm, ArithOp op) { var(a, b, _) = i.ABC(); a += 1; b += 1; vm.PushValue(b); vm.Arith(op); vm.Replace(a); }
private static void BinaryArith(Instruction i, ILuaVM vm, ArithOp op) { var(a, b, c) = i.ABC(); a += 1; vm.GetRK(b); vm.GetRK(c); vm.Arith(op); vm.Replace(a); }
internal static void LoadBool(Instruction i, ILuaVM vm) { var(a, b, c) = i.ABC(); a += 1; vm.PushBoolean(b != 0); vm.Replace(a); if (c != 0) { vm.AddPC(1); } }
internal static void Vararg(Instruction i, ILuaVM vm) { var(a, b, _) = i.ABC(); a += 1; if (b != 1) { vm.LoadVararg(b - 1); PopResults(a, b, vm); } }
internal static void Self(Instruction i, ILuaVM vm) { var(a, b, c) = i.ABC(); a += 1; b += 1; vm.Copy(b, a + 1); vm.GetRK(c); vm.GetTable(b); vm.Replace(a); }
/// <summary> /// 连续为寄存器置n个nil值,寄存器起始索引为a,数量为b,c无效 /// </summary> /// <param name="i"></param> public void LoadNil(Instruction i) { int a = 0, b = 0, c = 0; i.ABC(ref a, ref b, ref c); luaState.Push(new LuaValue()); for (int j = a + 1; j <= a + b; j++) { luaState.CopyTo(-1, j); } luaState.Pop(1); }
private static void Compare(Instruction i, ILuaVM vm, CompareOp op) { var(a, b, c) = i.ABC(); vm.GetRK(b); vm.GetRK(c); if (vm.Compare(-2, -1, op) != (a != 0)) { vm.AddPC(1); } vm.Pop(2); }
/// <summary> /// SETTABLE指令(iABC模式)根据键往表里赋值。其中表位于寄存器中,索引由操作数A指定;键和值可能位于寄存器中,也可能在常量表里,索引分别由操作数B和C指定。 /// </summary> /// <param name="i"></param> public void SetTable(Instruction i) { int a = 0, b = 0, c = 0; i.ABC(ref a, ref b, ref c); luaState.GetRK(b); luaState.GetRK(c); var value = luaState.Pop(); var key = luaState.Pop(); luaState.SetTable(a + 1, key, value); }
internal static void LoadNil(Instruction i, ILuaVM vm) { var(a, b, _) = i.ABC(); a += 1; vm.PushNil(); for (int j = a; j <= a + b; j++) { vm.Copy(-1, j); } vm.Pop(1); }
/// <summary> /// gettableup指令,当某个upval是一个表,则通过该指令从该表中获取值,目标寄存器由a指定,upval索引由b指定,键由c指定,可能是常量也可能在寄存器中 /// </summary> /// <param name="i"></param> public void GetUpTable(Instruction i) { int a = 0, b = 0, c = 0; i.ABC(ref a, ref b, ref c); luaState.GetRK(c); var table = luaState.GetUpval(b); var key = luaState.Pop(); luaState.Push((table.OValue as LuaTable)[key]); luaState.Replace(a + 1); }
/// <summary> /// 尾调用指令,使用当前函数帧继续调用函数 /// </summary> /// <param name="i"></param> public void TailCall(Instruction i) { int a = 0, b = 0, c = 0; i.ABC(ref a, ref b, ref c); a += 1; c = 0; int nArg = PushArgAndFunc(a, b); luaState.Call(nArg, c - 1); PopResults(a, c); }
/// <summary> /// Self指令,把对象和函数对象拷贝到两个相邻的寄存器中。对象在寄存器中,由操作数B指定,方法名在常量表中,操作数C指定,目标寄存器由操作数A指定。这样比两次Move少一个指令 /// </summary> /// <param name="i"></param> public void Self(Instruction i) { int a = 0, b = 0, c = 0; i.ABC(ref a, ref b, ref c); a += 1; b += 1; luaState.CopyTo(b, a + 1); luaState.GetRK(c); luaState.GetTable(luaState.GetTopValue(), b); luaState.Replace(a); }
/// <summary> /// GETTABLE指令(iABC模式)根据键从表里取值,并放入目标寄存器中。 /// 其中表位于寄存器中,索引由操作数B指定;键可能位于寄存器中,也可能在常量表里,索引由操作数C指定;目标寄存器索引则由操作数A指定。 /// </summary> /// <param name="i"></param> public void GetTable(Instruction i) { int a = 0, b = 0, c = 0; i.ABC(ref a, ref b, ref c); a += 1; b += 1; luaState.GetRK(c); var key = luaState.Pop(); luaState.GetTable(key, b); luaState.Replace(a); }
/// <summary> /// 变长参数指令。把传递给当前函数的连续多个参数加载到连续的指定寄存器中。A操作数指定第一个寄存器。B操作数指定数量。C操作数没用 /// b == 1,表示没有,b > 1,表示 b-1个参数,b = 0表示把从栈顶到a的所有寄存器全部加载 /// </summary> /// <param name="i"></param> public void Vararg(Instruction i) { int a = 0, b = 0, c = 0; i.ABC(ref a, ref b, ref c); a += 1; //b > 1和b>0统一处理 if (b != 1) { luaState.LoadVararg(b - 1); PopResults(a, b); } }
/// <summary> /// 设置给定寄存器值为bool, a 为寄存器索引,b为bool值,c非0则跳过下一条指令 /// </summary> /// <param name="i"></param> public void LoadBool(Instruction i) { int a = 0, b = 0, c = 0; i.ABC(ref a, ref b, ref c); a += 1; luaState.Push(new LuaValue(b != 0, LuaValueType.Bool)); luaState.Replace(a, luaState.GetTopValue()); if (c != 0) { luaState.AddPC(); } }