/// <summary> /// Creates a chunk from a Lua proto /// </summary> /// <param name="p"></param> public Chunk(Lua.Proto p) { Name = p.source.str.ToString(); MaxStackSize = p.maxstacksize; Vararg = p.is_vararg; ArgumentCount = p.numparams; UpvalueCount = p.nups; LastLine = (ulong)p.lastlinedefined; FirstLine = (uint)p.linedefined; foreach (uint instr in p.code) { Instructions.Add(Instruction.From(instr)); } foreach (Lua.lua_TValue k in p.k) { if (k.tt == Lua.LUA_TNIL) { Constants.Add(new Constant(ConstantType.Nil, null)); } else if (k.tt == Lua.LUA_TBOOLEAN) { Constants.Add(new Constant(ConstantType.Bool, (int)k.value.p != 0)); } else if (k.tt == Lua.LUA_TNUMBER) { Constants.Add(new Constant(ConstantType.Number, k.value.n)); } else if (k.tt == Lua.LUA_TSTRING) { Constants.Add(new Constant(ConstantType.String, k.value.p.ToString())); } } if (p.protos != null) { foreach (Lua.Proto p2 in p.protos) { Protos.Add(new Chunk(p2)); } } foreach (Lua.LocVar l in p.locvars) { Locals.Add(new Local(l.varname.str.ToString(), l.startpc, l.endpc)); } foreach (Lua.TString upval in p.upvalues) { Upvalues.Add(new Upvalue(upval.str.ToString())); } for (int i = 0; i < p.lineinfo.Length; i++) { Instructions[i].LineNumber = p.lineinfo[i]; } }
static Chunk ReadFunction() { Chunk c = new Chunk(); c.Name = ReadString(); c.FirstLine = (uint)ReadInt32(); c.LastLine = (ulong)ReadInt32(); c.UpvalueCount = ReadInt8(); // Upvalues c.ArgumentCount = ReadInt8(); c.Vararg = ReadInt8(); c.MaxStackSize = (uint)ReadInt8(); // Instructions long count = ReadInt32(); for (int i = 0; i < count; i++) { uint op = (uint)ReadInt32(); int opcode = (int)Lua.GET_OPCODE(op); //(int)Bit.Get(op, 1, 6); Instruction instr = Instruction.From(op); instr.Number = i; c.Instructions.Add(instr); } // Constants count = ReadInt32(); for (int i = 0; i < count; i++) { Constant cnst = new Constant(0, null); int t = ReadInt8(); cnst.Number = i; if (t == 0) { cnst.Type = ConstantType.Nil; cnst.Value = null; } else if (t == 1) { cnst.Type = ConstantType.Bool; cnst.Value = ReadInt8() != 0; } else if (t == 3) { cnst.Type = ConstantType.Number; cnst.Value = ReadNumber(); } else if (t == 4) { cnst.Type = ConstantType.String; cnst.Value = ReadString(); } c.Constants.Add(cnst); } // Protos count = ReadInt32(); for (int i = 0; i < count; i++) { c.Protos.Add(ReadFunction()); } // Line numbers count = ReadInt32(); for (int i = 0; i < count; i++) { c.Instructions[i].LineNumber = ReadInt32(); } // Locals count = ReadInt32(); for (int i = 0; i < count; i++) { c.Locals.Add(new Local(ReadString(), ReadInt32(), ReadInt32())); } // Upvalues count = ReadInt32(); for (int i = 0; i < count; i++) { c.Upvalues.Add(new Upvalue(ReadString())); } return(c); }