/// <summary> /// Defines a new Local variable and returns the field that /// represents it. /// </summary> /// <param name="name">The Lua name of the variable.</param> /// <returns>The variable that represents the local.</returns> public VarDefinition DefineLocal(NameItem name) { if (captures.Contains(name)) { string mName = name.Name; if (members.Contains(mName)) { int i = 0; while (members.Contains(mName + "_" + i)) { i++; } mName += "_" + i; } members.Add(mName); var field = TypeDef.DefineField(mName, typeof(ILuaValue), FieldAttributes.Public); return(Locals.Peek()[name.Name] = new CapturedVarDef(Generator, ThisInst, field)); } else { var loc = Generator.DeclareLocal(typeof(ILuaValue)); return(Locals.Peek()[name.Name] = new LocalVarDef(Generator, loc)); } }
/// <summary> /// Creates a new nest with the given parent. /// </summary> /// <param name="parent">The parent nest.</param> /// <param name="gen">The generator used to generate code for this function.</param> /// <param name="storeParent"> /// True to create a field that stores the parent instance; otherwise false. /// </param> /// <param name="captures"> /// The local variables that have been captured by nested functions. /// </param> /// <param name="createType">True to create a nested type, otherwise false.</param> public NestInfo(NestInfo parent, ILGenerator gen, NameItem[] captures, bool createType, bool storeParent) { FreeLocals = new Dictionary <Type, Stack <LocalBuilder> >(); Members = new HashSet <string>(); _captures = new HashSet <NameItem>(captures); Parent = parent; Generator = gen; Locals = new Stack <Dictionary <string, IVarDefinition> >(); Locals.Push(new Dictionary <string, IVarDefinition>()); if (createType) { // create the type and constructor. TypeDef = parent.TypeDef.DefineNestedType( "<>c__DisplayClass" + (_id++), TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit); var ctor = TypeDef.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[0]); var cgen = ctor.GetILGenerator(); // base(); cgen.Emit(OpCodes.Ldarg_0); cgen.Emit(OpCodes.Call, typeof(object).GetConstructor(new Type[0])); cgen.Emit(OpCodes.Ret); if (storeParent) { ParentInst = TypeDef.DefineField("CS$<>__locals", parent.TypeDef, FieldAttributes.Public); } else { ParentInst = null; } // create the local definition // ThisInst = new TypeDef(); ThisInst = gen.DeclareLocal(TypeDef); gen.Emit(OpCodes.Newobj, ctor); gen.Emit(OpCodes.Stloc, ThisInst); if (storeParent) { // ThisInst.ParentInst = this; gen.Emit(OpCodes.Ldloc, ThisInst); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Stfld, ParentInst); } } else { TypeDef = null; ThisInst = null; ParentInst = null; } }