private static Upvalue[] GetUpvalues(FuncInfo fi) { var upvals = new Upvalue[fi.Upvalues.Count]; foreach (var kv in fi.Upvalues) { if (kv.Value.LocVarSlot >= 0) { upvals[kv.Value.Index] = new Upvalue { Instack = 1, Idx = (byte)kv.Value.LocVarSlot }; } else { upvals[kv.Value.Index] = new Upvalue { Instack = 0, Idx = (byte)kv.Value.UpvalIndex }; } } return(upvals); }
/// <summary> /// Creates a closure from a bytecode address. /// </summary> /// <param name="address">The address.</param> /// <param name="envTable">The env table to create a 0-upvalue</param> /// <returns></returns> private DynValue MakeClosure(int address, Table envTable = null) { this.CheckScriptOwnership(envTable); Closure c; if (envTable == null) { Instruction?meta = m_MainProcessor.FindMeta(ref address); // if we find the meta for a new chunk, we use the value in the meta for the _ENV upvalue if ((meta != null) && (meta.Value.NumVal2 == (int)OpCodeMetadataType.ChunkEntrypoint)) { c = new Closure(this, address, new SymbolRef[] { SymbolRef.Upvalue(WellKnownSymbols.ENV, 0) }, new Upvalue[1]); } else { c = new Closure(this, address, new SymbolRef[0], new Upvalue[0]); } } else { var syms = new SymbolRef[] { new SymbolRef() { i_Env = null, i_Index = 0, i_Name = WellKnownSymbols.ENV, i_Type = SymbolRefType.DefaultEnv }, }; var vals = new Upvalue[] { Upvalue.Create(DynValue.NewTable(envTable)) }; c = new Closure(this, address, syms, vals); } return(DynValue.NewClosure(c)); }
public void AssignGenericSymbol(SymbolRef symref, DynValue value) { switch (symref.i_Type) { case SymbolRefType.Global: SetGlobalSymbol(GetGenericSymbol(symref.i_Env), symref.i_Name, value); break; case SymbolRefType.Local: { var stackframe = GetTopNonClrFunction(); m_ValueStack[stackframe.BasePointer + symref.i_Index] = value; } break; case SymbolRefType.Upvalue: { var stackframe = GetTopNonClrFunction(); if (stackframe.ClosureScope[symref.i_Index] == null) { stackframe.ClosureScope[symref.i_Index] = Upvalue.NewNil(); } stackframe.ClosureScope[symref.i_Index].Value() = value; } break; case SymbolRefType.DefaultEnv: { throw new ArgumentException("Can't AssignGenericSymbol on a DefaultEnv symbol"); } default: throw new InternalErrorException("Unexpected {0} LRef at resolution: {1}", symref.i_Type, symref.i_Name); } }
private void ReadLua53Smash(LuaFile file, BinaryReaderEx br) { Name = LuaFile.ReadLuaString(br, LuaVersion.Lua53Smash, false); LineDefined = br.ReadInt32(); br.ReadInt32(); // last line NumParams = br.ReadByte(); IsVarArg = br.ReadByte(); MaxStackSize = br.ReadByte(); int bytecodeCount = br.ReadInt32(); Bytecode = br.ReadBytes(bytecodeCount * 4); int constantsCount = br.ReadInt32(); Constants = new Constant[constantsCount]; for (int i = 0; i < constantsCount; i++) { Constants[i] = new Constant(file, br, LuaVersion.Lua53Smash); } int upvalct = br.ReadInt32(); Upvalues = new Upvalue[upvalct]; for (int i = 0; i < upvalct; i++) { Upvalues[i] = new Upvalue(br); } int funcCount = br.ReadInt32(); ChildFunctions = new Function[funcCount]; for (int i = 0; i < funcCount; i++) { ChildFunctions[i] = new Function(file, LuaVersion.Lua53Smash, br); } SizeLineInfo = br.ReadInt32(); // Eat line numbers br.ReadInt32s(SizeLineInfo); LocalVarsCount = br.ReadInt32(); Locals = new Local[LocalVarsCount]; LocalMap = new Dictionary <int, List <Local> >(); for (int i = 0; i < LocalVarsCount; i++) { Locals[i] = new Local(br, LuaVersion.Lua53Smash); if (!Locals[i].Name.StartsWith("(")) { if (!LocalMap.ContainsKey(Locals[i].Start)) { LocalMap[Locals[i].Start] = new List <Local>(); } LocalMap[Locals[i].Start].Add(Locals[i]); } } //br.ReadUInt32(); // upval names UpValuesCount = br.ReadInt32(); UpvalueNames = new UpvalueName[UpValuesCount]; for (int i = 0; i < UpValuesCount; i++) { UpvalueNames[i] = new UpvalueName(br, LuaVersion.Lua53Smash); } }