public CodeGen DefineMethod(string methodName, Type returnType, IList <Type> paramTypes, ConstantPool constantPool) { CodeGen cg; if (GenerateStaticMethods) { int index = Interlocked.Increment(ref _index); TypeGen tg = DefinePublicType("Type$" + methodName + "$" + index, typeof(object)); cg = tg.DefineMethod("Handle" + index, returnType, paramTypes, null, constantPool); cg.DynamicMethod = true; } else { Type[] parameterTypes = CompilerHelpers.MakeParamTypeArray(paramTypes, constantPool); string dynamicMethodName = methodName + "##" + Interlocked.Increment(ref _index); DynamicMethod target; #if SILVERLIGHT // Module-hosted DynamicMethod is not available in SILVERLIGHT target = new DynamicMethod(dynamicMethodName, returnType, parameterTypes); #else target = new DynamicMethod(dynamicMethodName, returnType, parameterTypes, _myModule); #endif cg = new CodeGen(null, this, target, target.GetILGenerator(), parameterTypes, constantPool); } return(cg); }
internal static CodeGen CreateDebuggableDynamicCodeGenerator(CompilerContext context, string name, Type retType, IList <Type> paramTypes, IList <string> paramNames, ConstantPool constantPool) { TypeGen tg = ScriptDomainManager.CurrentManager.Snippets.DefineDebuggableType(name, context.SourceUnit); CodeGen cg = tg.DefineMethod("Initialize", retType, paramTypes, paramNames, constantPool); tg.AddCodeContextField(); cg.DynamicMethod = true; return(cg); }
static void GenerateConstructor(RecordTypeDescriptor rtd, TypeGen tg, Type parenttype) { // constructor logic { List<Type> paramtypes = new List<Type>(); List<FieldDescriptor> allfields = new List<FieldDescriptor>(rtd.GetAllFields()); int diff = allfields.Count - rtd.Fields.Length; foreach (FieldDescriptor var in allfields) { paramtypes.Add(var.Type); } List<Type> parenttypes = new List<Type>(); for (int i = 0; i < diff; i++) { parenttypes.Add(typeof(object)); //TODO: fix this, it looks broken } if (paramtypes.Count < 9) { CodeGen cg = tg.DefineConstructor(paramtypes.ToArray()); CodeGen mk = tg.DefineMethod(MethodAttributes.Public | MethodAttributes.Static, "make", tg.TypeBuilder, paramtypes.ToArray(), allfields.ConvertAll(x => x.Name).ToArray()); for (int i = 0; i < allfields.Count; i++) { cg.DefineParameter(i + 1, ParameterAttributes.None, allfields[i].Name); } int fi = 0; cg.EmitThis(); for (fi = 0; fi < diff; fi++) { cg.EmitArgGet(fi); mk.EmitArgGet(fi); } cg.Emit(OpCodes.Call, (rtd.Parent == null ? parenttype.GetConstructor(Type.EmptyTypes) : rtd.Parent.DefaultConstructor)); foreach (FieldDescriptor fd in rtd.Fields) { cg.EmitThis(); cg.EmitArgGet(fi); cg.EmitFieldSet(fd.field); mk.EmitArgGet(fi); fi++; } mk.EmitNew(cg.MethodBase as ConstructorInfo); mk.EmitReturn(); cg.EmitReturn(); rtd.cg = cg; } else { CodeGen cg = tg.DefineConstructor(paramtypes.ToArray()); CodeGen mk = tg.DefineMethod(MethodAttributes.Public | MethodAttributes.Static, "make", tg.TypeBuilder, new Type[] { typeof(object[]) }, new string[] { "args" }); for (int i = 0; i < allfields.Count; i++) { cg.DefineParameter(i + 1, ParameterAttributes.None, allfields[i].Name); } int fi = 0; cg.EmitThis(); for (fi = 0; fi < diff; fi++) { cg.EmitArgGet(fi); mk.EmitArgGet(0); mk.EmitConstant(fi); mk.Emit(OpCodes.Ldelem, typeof(object)); } cg.Emit(OpCodes.Call, (rtd.Parent == null ? typeof(object).GetConstructor(Type.EmptyTypes) : rtd.Parent.DefaultConstructor)); foreach (FieldDescriptor fd in rtd.Fields) { cg.EmitThis(); cg.EmitArgGet(fi); cg.EmitFieldSet(fd.field); mk.EmitArgGet(0); mk.EmitConstant(fi); mk.Emit(OpCodes.Ldelem, typeof(object)); fi++; } mk.EmitNew(cg.MethodBase as ConstructorInfo); mk.EmitReturn(); cg.EmitReturn(); rtd.cg = cg; } } }