static void GenerateFields(object fields, string n, RecordTypeDescriptor rtd, TypeGen tg, object fieldtypes) { object[] f = RequiresNotNull <object[]>(fields); object[] ftypes = RequiresNotNull <object[]>(fieldtypes); List <FieldDescriptor> rtd_fields = new List <FieldDescriptor>(); for (int i = 0; i < f.Length; i++) { Cons c = (Cons)f[i]; // check for recursive definition Type t = rtd.Name == SymbolTable.IdToString((SymbolId)ftypes[i]) ? rtd.tg.TypeBuilder : ClrGenerator.ExtractTypeInfo(List(SymbolTable.StringToObject("quote"), ftypes[i])); // can this ever be null given ExtractTypeInfo throws? if (t == null) { ClrGenerator.ClrSyntaxError("GenerateFields", "type not found", ftypes[i]); } string fname = SymbolTable.IdToString(RequiresNotNull <SymbolId>(Second(c))); // we use standard names here, they will be mapped to the given names string aname = n + "-" + fname; string mname = n + "-" + fname + "-set!"; var fd = new FieldDescriptor { Name = fname }; FieldAttributes fattrs = FieldAttributes.Public;// | FieldAttributes.InitOnly; if (c.car == SymbolTable.StringToObject("mutable")) { fd.mutable = true; //fattrs &= ~FieldAttributes.InitOnly; } FieldSlot s = tg.AddField(t, fname, fattrs) as FieldSlot; fd.field = s.Field; PropertyBuilder pi = tg.TypeBuilder.DefineProperty(fname, PropertyAttributes.None, t, new Type[0]); // accesor MethodBuilder ab = tg.TypeBuilder.DefineMethod(aname, MethodAttributes.Public | MethodAttributes.Static, t, new Type[] { tg.TypeBuilder }); ab.DefineParameter(1, ParameterAttributes.None, n); ILGenerator agen = ab.GetILGenerator(); agen.Emit(OpCodes.Ldarg_0); //agen.Emit(OpCodes.Castclass, tg.TypeBuilder); agen.Emit(OpCodes.Ldfld, fd.field); agen.Emit(OpCodes.Ret); fd.accessor = ab; pi.SetGetMethod(ab); // mutator if (fd.mutable) { MethodBuilder mb = tg.TypeBuilder.DefineMethod(mname, MethodAttributes.Public | MethodAttributes.Static, typeof(object), new Type[] { tg.TypeBuilder, t }); mb.DefineParameter(1, ParameterAttributes.None, n); ILGenerator mgen = mb.GetILGenerator(); mgen.Emit(OpCodes.Ldarg_0); //mgen.Emit(OpCodes.Castclass, tg.TypeBuilder); mgen.Emit(OpCodes.Ldarg_1); mgen.Emit(OpCodes.Stfld, fd.field); mgen.Emit(OpCodes.Ldsfld, Compiler.Generator.Unspecified); mgen.Emit(OpCodes.Ret); fd.mutator = mb; pi.SetSetMethod(mb); } rtd_fields.Add(fd); } rtd.fields = rtd_fields.ToArray(); }
static void GenerateFields(object fields, string n, RecordTypeDescriptor rtd, TypeGen tg, object fieldtypes) { object[] f = RequiresNotNull<object[]>(fields); object[] ftypes = RequiresNotNull<object[]>(fieldtypes); List<FieldDescriptor> rtd_fields = new List<FieldDescriptor>(); for (int i = 0; i < f.Length; i++) { Cons c = (Cons) f[i]; Type t = ClrGenerator.ExtractTypeInfo(List(SymbolTable.StringToObject("quote"), ftypes[i])); if (t == null) { ClrGenerator.ClrSyntaxError("GenerateFields", "type not found", ftypes[i]); } string fname = SymbolTable.IdToString(RequiresNotNull<SymbolId>(Second(c))); // we use standard names here, they will be mapped to the given names string aname = n + "-" + fname; string mname = n + "-" + fname + "-set!"; var fd = new FieldDescriptor { Name = fname }; FieldAttributes fattrs = FieldAttributes.Public | FieldAttributes.InitOnly; if (c.car == SymbolTable.StringToObject("mutable")) { fd.mutable = true; fattrs &= ~FieldAttributes.InitOnly; } FieldSlot s = tg.AddField(t, fname, fattrs) as FieldSlot; fd.field = s.Field; PropertyBuilder pi = tg.TypeBuilder.DefineProperty(fname, PropertyAttributes.None, t, new Type[0]); // accesor MethodBuilder ab = tg.TypeBuilder.DefineMethod(aname, MethodAttributes.Public | MethodAttributes.Static, t, new Type[] { tg.TypeBuilder }); ab.DefineParameter(1, ParameterAttributes.None, n); ILGenerator agen = ab.GetILGenerator(); agen.Emit(OpCodes.Ldarg_0); //agen.Emit(OpCodes.Castclass, tg.TypeBuilder); agen.Emit(OpCodes.Ldfld, fd.field); agen.Emit(OpCodes.Ret); fd.accessor = ab; pi.SetGetMethod(ab); // mutator if (fd.mutable) { MethodBuilder mb = tg.TypeBuilder.DefineMethod(mname, MethodAttributes.Public | MethodAttributes.Static, typeof(object), new Type[] { tg.TypeBuilder, t }); mb.DefineParameter(1, ParameterAttributes.None, n); ILGenerator mgen = mb.GetILGenerator(); mgen.Emit(OpCodes.Ldarg_0); //mgen.Emit(OpCodes.Castclass, tg.TypeBuilder); mgen.Emit(OpCodes.Ldarg_1); mgen.Emit(OpCodes.Stfld, fd.field); mgen.Emit(OpCodes.Ldsfld, Compiler.Generator.Unspecified); mgen.Emit(OpCodes.Ret); fd.mutator = mb; pi.SetSetMethod(mb); } rtd_fields.Add(fd); } rtd.fields = rtd_fields.ToArray(); }
public static RecordTypeDescriptor Create(Type type, string name, string uid, bool opaque, RecordTypeDescriptor parentrtd) { var rtd = new RecordTypeDescriptor { type = type, Name = name, predicate = type.GetMethod(name + "?"), uid = uid, @sealed = type.IsSealed, opaque = opaque, Parent = parentrtd }; Records.typedescriptors[type] = rtd; MethodInfo ci = type.GetMethod("make"); var pari = ci.GetParameters(); int pcount = pari.Length; if (pcount < 9 && !(pcount == 1 && pari[0].ParameterType == typeof(object[]))) { rtd.Constructor = CreateCallable(ci); } else { rtd.Constructor = Closure.Create(Delegate.CreateDelegate(typeof(CallTargetN), ci)) as Callable; } rtd.DefaultConstructor = CreateCallable(type.GetMethod("$make", Type.EmptyTypes)); rtd.DefaultInit = CreateCallable(type.GetMethod("$init")); rtd.Predicate = Closure.Create(Delegate.CreateDelegate(typeof(CallTarget1), rtd.predicate)) as Callable; var flds = new List <FieldDescriptor>(); foreach (FieldInfo fi in type.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) { var fd = new FieldDescriptor { Name = fi.Name }; fd.field = fi; var pi = type.GetProperty(fi.Name); fd.accessor = pi.GetGetMethod(); fd.Accessor = CreateCallable(fd.accessor); if (pi.CanWrite) { fd.mutator = pi.GetSetMethod(); fd.Mutator = CreateCallable(fd.mutator); } else { fd.Mutator = Builtins.FALSE; } flds.Add(fd); } rtd.fields = flds.ToArray(); return(rtd); }
public static RecordTypeDescriptor Create(Type type, string name, string uid, RecordTypeDescriptor parentrtd) { var rtd = new RecordTypeDescriptor { type = type, Name = name, predicate = type.GetMethod(name + "?"), uid = uid, @sealed = type.IsSealed, Parent = parentrtd }; Records.typedescriptors[type] = rtd; MethodInfo ci = type.GetMethod("make"); var pari = ci.GetParameters(); int pcount = pari.Length; if (pcount < 9 && !(pcount == 1 && pari[0].ParameterType == typeof(object[]))) { rtd.Constructor = CreateCallable(ci); } else { rtd.Constructor = Closure.Create(Delegate.CreateDelegate(typeof(CallTargetN), ci)) as Callable; } rtd.Predicate = Closure.Create(Delegate.CreateDelegate(typeof(CallTarget1), rtd.predicate)) as Callable; var flds = new List<FieldDescriptor>(); foreach (FieldInfo fi in type.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) { var fd = new FieldDescriptor { Name = fi.Name }; fd.field = fi; var pi = type.GetProperty(fi.Name); fd.accessor = pi.GetGetMethod(); fd.Accessor = CreateCallable(fd.accessor); if (pi.CanWrite) { fd.mutator = pi.GetSetMethod(); fd.Mutator = CreateCallable(fd.mutator); } else { fd.Mutator = Builtins.FALSE; } flds.Add(fd); } rtd.fields = flds.ToArray(); return rtd; }