public ImplementMembersForm(NemerleSource source, TypeBuilder ty, IEnumerable<IGrouping<FixedType.Class, IMember>> unimplementedMembers) { _source = source; _ty = ty; _unimplementedMembers = unimplementedMembers; InitializeComponent(); #region Init events hendlers _grid.CellPainting += CellPainting; _grid.CellValueChanged += CellValueChanged; _grid.CellValidating += CellValidating; _grid.CurrentCellDirtyStateChanged += CurrentCellDirtyStateChanged; #endregion #region Init ImageList imageList1.Images.AddStrip(Resources.SO_TreeViewIcons); _imageSize = imageList1.ImageSize.Width; Debug.Assert(imageList1.ImageSize.Width == imageList1.ImageSize.Height); #endregion if (_unimplementedMembers == null) return; FillTable(MakeTypeMembersMap()); }
public void SetSource(string source, int offset) { //System.Diagnostics.Debug.WriteLine(string.Format("Scan line {0}", _currentLine)); ScanLexer lexer = GetLexer(); if (lexer != null) { if (_currentLine >= 0 && source.Length > 0) { if (_source != null && _source.ProjectInfo != null) { var ret = _source.ProjectInfo.Engine.GetActiveEnv(_source.FileIndex, _currentLine + 1); if (ret.Field0 != null) { _env = ret.Field0; _type = ret.Field1; } } } lexer.SetLine(_currentLine + 1, source, offset, _env, _type); } }
internal static ConstructorInfo AddAutomagicSerialization(DynamicTypeWrapper wrapper, TypeBuilder typeBuilder) { ConstructorInfo serializationCtor = null; if (wrapper.GetClassLoader().NoAutomagicSerialization) { // do nothing } else if ((wrapper.Modifiers & IKVM.Attributes.Modifiers.Enum) != 0) { MarkSerializable(typeBuilder); } else if (wrapper.IsSubTypeOf(serializable) && IsSafeForAutomagicSerialization(wrapper)) { if (wrapper.IsSubTypeOf(externalizable)) { MethodWrapper ctor = wrapper.GetMethodWrapper("<init>", "()V", false); if (ctor != null && ctor.IsPublic) { MarkSerializable(typeBuilder); ctor.Link(); serializationCtor = AddConstructor(typeBuilder, ctor, null, true); if (!wrapper.BaseTypeWrapper.IsSubTypeOf(serializable)) { AddGetObjectData(typeBuilder); } if (wrapper.BaseTypeWrapper.GetMethodWrapper("readResolve", "()Ljava.lang.Object;", true) != null) { RemoveReadResolve(typeBuilder); } } } else if (wrapper.BaseTypeWrapper.IsSubTypeOf(serializable)) { ConstructorInfo baseCtor = wrapper.GetBaseSerializationConstructor(); if (baseCtor != null && (baseCtor.IsFamily || baseCtor.IsFamilyOrAssembly)) { MarkSerializable(typeBuilder); serializationCtor = AddConstructor(typeBuilder, null, baseCtor, false); AddReadResolve(wrapper, typeBuilder); } } else { MethodWrapper baseCtor = wrapper.BaseTypeWrapper.GetMethodWrapper("<init>", "()V", false); if (baseCtor != null && baseCtor.IsAccessibleFrom(wrapper.BaseTypeWrapper, wrapper, wrapper)) { MarkSerializable(typeBuilder); AddGetObjectData(typeBuilder); #if STATIC_COMPILER // because the base type can be a __WorkaroundBaseClass__, we may need to replace the constructor baseCtor = ((AotTypeWrapper)wrapper).ReplaceMethodWrapper(baseCtor); #endif baseCtor.Link(); serializationCtor = AddConstructor(typeBuilder, baseCtor, null, true); AddReadResolve(wrapper, typeBuilder); } } } return serializationCtor; }
// Helper method for nullable transform. Ideally, we would do the nullable transform upfront before // the types is build. Unfortunately, there does not seem to be easy way to test for Nullable<> type definition // without introducing type builder recursion private static RuntimeTypeHandle GetRuntimeTypeHandleWithNullableTransform(TypeBuilder builder, TypeDesc type) { RuntimeTypeHandle th = builder.GetRuntimeTypeHandle(type); if (RuntimeAugments.IsNullable(th)) th = builder.GetRuntimeTypeHandle(((DefType)type).Instantiation[0]); return th; }
/// <summary> /// Default ctor /// </summary> protected NestedTypeBuilder(TypeBuilder parent, string parentFullName, ClassFile cf, InnerClass inner) { this.parent = parent; this.parentFullName = parentFullName; this.cf = cf; this.inner = inner; }
private static void CreateProperty(TypeBuilder tb, string propertyName, Type propertyType) { FieldBuilder fieldBuilder = tb.DefineField("_" + propertyName, propertyType, FieldAttributes.Private); PropertyBuilder propertyBuilder = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null); MethodBuilder getPropMthdBldr = tb.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes); ILGenerator getIl = getPropMthdBldr.GetILGenerator(); getIl.Emit(OpCodes.Ldarg_0); getIl.Emit(OpCodes.Ldfld, fieldBuilder); getIl.Emit(OpCodes.Ret); MethodBuilder setPropMthdBldr = tb.DefineMethod("set_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new[] { propertyType }); ILGenerator setIl = setPropMthdBldr.GetILGenerator(); Label modifyProperty = setIl.DefineLabel(); Label exitSet = setIl.DefineLabel(); setIl.MarkLabel(modifyProperty); setIl.Emit(OpCodes.Ldarg_0); setIl.Emit(OpCodes.Ldarg_1); setIl.Emit(OpCodes.Stfld, fieldBuilder); setIl.Emit(OpCodes.Nop); setIl.MarkLabel(exitSet); setIl.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(getPropMthdBldr); propertyBuilder.SetSetMethod(setPropMthdBldr); }
override internal void Prepare(TypeBuilder builder) { if (Type.IsCanonicalSubtype(CanonicalFormKind.Any)) Environment.FailFast("Canonical types do not have EETypes"); builder.RegisterForPreparation(Type); }
/// <summary> /// Default ctor /// </summary> private MethodBuilder(MethodDefinition javaMethod, TypeBuilder declaringTypeBuilder, bool convertSignedBytes, bool addJavaPrefix) { this.javaMethod = javaMethod; this.declaringTypeBuilder = declaringTypeBuilder; this.convertSignedBytes = convertSignedBytes; this.addJavaPrefix = addJavaPrefix; }
override internal IntPtr Create(TypeBuilder builder) { if (Type.IsNullable) return builder.GetRuntimeTypeHandle(Type.Instantiation[0]).ToIntPtr(); else return builder.GetRuntimeTypeHandle(Type).ToIntPtr(); }
public void AddMethodDynamically (ref TypeBuilder myTypeBld, string mthdName, Type [] mthdParams, Type returnType, string mthdAction) { MethodBuilder myMthdBld = myTypeBld.DefineMethod ( mthdName, MethodAttributes.Public | MethodAttributes.Static, returnType, mthdParams); ILGenerator ILout = myMthdBld.GetILGenerator (); int numParams = mthdParams.Length; for (byte x = 0; x < numParams; x++) ILout.Emit (OpCodes.Ldarg_S, x); if (numParams > 1) { for (int y = 0; y < (numParams - 1); y++) { switch (mthdAction) { case "A": ILout.Emit (OpCodes.Add); break; case "M": ILout.Emit (OpCodes.Mul); break; default: ILout.Emit (OpCodes.Add); break; } } } ILout.Emit (OpCodes.Ret); }
/// <summary> /// Default ctor /// </summary> private MethodBuilder(MethodDefinition javaMethod, TypeBuilder declaringTypeBuilder, SignedByteMode signedByteMode) { this.javaMethod = javaMethod; this.declaringTypeBuilder = declaringTypeBuilder; this.signedByteMode = signedByteMode; this.addJavaPrefix = signedByteMode == SignedByteMode.HasUnsignedPartnerOnlyInReturnType; }
internal static IEnumerable<NestedTypeBuilder> Create(TypeBuilder parent, string parentFullName, ClassFile cf, InnerClass inner) { if (cf.IsInterface && cf.Fields.Any()) { yield return new NestedInterfaceConstantsTypeBuilder(parent, parentFullName, cf, inner); } yield return new NestedTypeBuilder(parent, parentFullName, cf, inner); }
/// <summary> /// Default ctor /// </summary> public FieldBuilder(FieldDefinition javaField, TypeBuilder declaringTypeBuilder) { if (javaField == null) throw new ArgumentNullException("javaField"); if (declaringTypeBuilder == null) throw new ArgumentNullException("declaringTypeBuilder"); this.javaField = javaField; this.declaringTypeBuilder = declaringTypeBuilder; }
public unsafe void Finish(TypeBuilder typeBuilder) { Debug.Assert(_cells.Length == 0 || _addressOfFirstCellSlot != IntPtr.Zero); IntPtr* realCells = (IntPtr*)_addressOfFirstCellSlot; for (int i = 0; i < _cells.Length; i++) { realCells[i] = _cells[i].Create(typeBuilder); } }
private void BuildEntitySets(EdmEntityContainer container, IEnumerable<EntityElement> rootElements, TypeBuilder typeBuilder) { foreach (var rootEntity in rootElements) { var entitySetName = rootEntity.EntitySetName ?? rootEntity.ResolveName(); var schemaType = typeBuilder.BuildSchemaType(rootEntity); container.AddEntitySet(entitySetName, (IEdmEntityType)schemaType); } }
/// <summary> /// Constructor /// </summary> /// <param name="TypeBuilder">Type builder</param> /// <param name="Name">Name of the method</param> /// <param name="Attributes">Attributes for the field (public, private, etc.)</param> /// <param name="FieldType">Type for the field</param> public FieldBuilder(TypeBuilder TypeBuilder, string Name, Type FieldType, FieldAttributes Attributes) : base() { Contract.Requires<ArgumentNullException>(TypeBuilder!=null,"TypeBuilder"); Contract.Requires<ArgumentNullException>(!string.IsNullOrEmpty(Name),"Name"); this.Name = Name; this.Type = TypeBuilder; this.DataType = FieldType; this.Attributes = Attributes; Builder = Type.Builder.DefineField(Name, FieldType, Attributes); }
private MethodBuilder ImplementMethod(TypeBuilder type, string methodName, MethodAttributes methodAttr, Type returnType, Type[] paramTypes, FieldBuilder field) { MethodBuilder method = type.DefineMethod(methodName, methodAttr, returnType, paramTypes); ILGenerator methodILGenerator = method.GetILGenerator(); methodILGenerator.Emit(OpCodes.Ldarg_0); methodILGenerator.Emit(OpCodes.Ldarg_1); methodILGenerator.Emit(OpCodes.Stfld, field); methodILGenerator.Emit(OpCodes.Ret); return method; }
/// <summary> /// Constructor /// </summary> /// <param name="typeBuilder">Type builder</param> /// <param name="name">Name of the method</param> /// <param name="attributes">Attributes for the field (public, private, etc.)</param> /// <param name="fieldType">Type for the field</param> public FieldBuilder(TypeBuilder typeBuilder, string name, Type fieldType, FieldAttributes attributes) { if (typeBuilder == null) throw new ArgumentNullException("typeBuilder"); if (string.IsNullOrEmpty(name)) throw new ArgumentNullException("name"); Name = name; Type = typeBuilder; DataType = fieldType; Attributes = attributes; Builder = Type.Builder.DefineField(name, fieldType, attributes); }
static void EmitCtor (TypeBuilder genericFoo) { ConstructorBuilder mb = genericFoo.DefineConstructor (MethodAttributes.Public, CallingConventions.Standard, null); ILGenerator il = mb.GetILGenerator (); for (int i = 0; i < 20; ++i) il.Emit (OpCodes.Nop); il.Emit (OpCodes.Ldarg_0); il.Emit (OpCodes.Call, typeof (object).GetConstructors()[0]); il.Emit (OpCodes.Ret); ctor = mb; }
public void NotCreateOtherElements() { CompilerContext cc = new CompilerContext(); GenericTypeBuilder gtb = new GenericTypeBuilder(); TypeBuilder tb = new TypeBuilder(); Testdata.ClassA classa = new Testdata.ClassA(); System.Reflection.ReflectionClass rc = new System.Reflection.ReflectionClass(); Assert.IsNull(TreeElementCreator.CreateFromObject("cc", cc)); Assert.IsNull(TreeElementCreator.CreateFromObject("gtb", gtb)); Assert.IsNull(TreeElementCreator.CreateFromObject("tb", tb)); Assert.IsNull(TreeElementCreator.CreateFromObject("rc", rc)); }
/// <summary> /// Constructor /// </summary> /// <param name="TypeBuilder">Type builder</param> /// <param name="Name">Name of the method</param> /// <param name="Attributes">Attributes for the field (public, private, etc.)</param> /// <param name="FieldType">Type for the field</param> public FieldBuilder(TypeBuilder TypeBuilder, string Name, Type FieldType, FieldAttributes Attributes) : base() { if (TypeBuilder == null) throw new ArgumentNullException("TypeBuilder"); if (string.IsNullOrEmpty(Name)) throw new ArgumentNullException("Name"); this.Name = Name; this.Type = TypeBuilder; this.DataType = FieldType; this.Attributes = Attributes; Builder = Type.Builder.DefineField(Name, FieldType, Attributes); }
override internal void Prepare(TypeBuilder builder) { if (Type.IsCanonicalSubtype(CanonicalFormKind.Any)) Environment.FailFast("Canonical types do not have EETypes"); if (Type.IsNullable) { Debug.Assert(Type.Instantiation.Length == 1); builder.RegisterForPreparation(Type.Instantiation[0]); } else builder.RegisterForPreparation(Type); }
private IEdmModel BuildModel(string namespaceName, StructuralModelElement conceptualModelElement) { var model = new EdmModel(); var container = new EdmEntityContainer(namespaceName, DefaultContainerName); model.AddElement(container); var typeBuilder = new TypeBuilder(namespaceName); BuildEntitySets(container, conceptualModelElement.RootEntities, typeBuilder); BuildTypes(model, conceptualModelElement.Entities, typeBuilder); return model; }
static void EmitTargetMethod (TypeBuilder genericFoo) { MethodBuilder mb = genericFoo.DefineMethod ("TargetMethod", MethodAttributes.Public, typeof (void), new Type[] {typeof (object) }); ILGenerator il = mb.GetILGenerator (); for (int i = 0; i < 20; ++i) il.Emit (OpCodes.Nop); il.Emit (OpCodes.Ldtoken, genericArgs [0]); il.Emit (OpCodes.Call, typeof (Type).GetMethod ("GetTypeFromHandle")); il.Emit (OpCodes.Call, typeof (Console).GetMethod ("WriteLine", new Type[] { typeof (object) })); il.Emit (OpCodes.Ret); targetMethod = mb; }
public AssemblyBuilder(AssemblyDefinition assembly, ReferenceResolver resolver) { if(assembly == null) throw new ArgumentNullException("assembly"); if(resolver == null) throw new ArgumentNullException("resolver"); Assembly = CloneAssembly(assembly); this.resolver = resolver; resolver.Module = Assembly.MainModule; typeBuilder = new TypeBuilder(Assembly.MainModule, resolver); }
static void EmitTestEvents (TypeBuilder genericFoo) { MethodBuilder mb = genericFoo.DefineMethod ("TestEvents", MethodAttributes.Public, typeof (void), null); ILGenerator il = mb.GetILGenerator (); for (int i = 0; i < 20; ++i) il.Emit (OpCodes.Nop); il.Emit (OpCodes.Ldarg_0); il.Emit (OpCodes.Ldnull); il.Emit (OpCodes.Callvirt, targetMethod); il.Emit (OpCodes.Ret); testEvents = mb; }
private static IEdmEntityContainer BuildContainer(IEnumerable<EntityElement> entities, TypeBuilder typeBuilder) { var container = new EdmEntityContainer(typeBuilder.NamespaceName, DefaultContainName); foreach (var entityElement in entities) { var entitySetName = entityElement.EntitySetName ?? entityElement.ResolveName(); var entityType = (IEdmEntityType)typeBuilder.ResolveComplexType(entityElement); container.AddEntitySet(entitySetName, entityType); } return container; }
/// <summary> /// Try to create a type builder for the given class. /// </summary> internal static bool TryCreateTypeBuilder(ClassFile cf, out TypeBuilder builder) { if (mappedTypeBuilders != null) { IMappedTypeBuilder mappedBuilder; if (mappedTypeBuilders.TryGetValue(cf.ClassName, out mappedBuilder)) { builder = mappedBuilder.Create(cf); return true; } } builder = null; return false; }
/// <summary> /// Constructor /// </summary> /// <param name="typeBuilder">Type builder</param> /// <param name="name">Name of the property</param> /// <param name="attributes">Attributes for the property (public, private, etc.)</param> /// <param name="getMethodAttributes">Get method attributes</param> /// <param name="setMethodAttributes">Set method attributes</param> /// <param name="propertyType">Property type for the property</param> /// <param name="parameters">Parameter types for the property</param> public DefaultPropertyBuilder(TypeBuilder typeBuilder, string name, PropertyAttributes attributes, MethodAttributes getMethodAttributes, MethodAttributes setMethodAttributes, Type propertyType, IEnumerable<Type> parameters) { if (typeBuilder == null) throw new ArgumentNullException("typeBuilder"); if (string.IsNullOrEmpty(name)) throw new ArgumentNullException("name"); Name = name; Type = typeBuilder; Attributes = attributes; GetMethodAttributes = getMethodAttributes; SetMethodAttributes = setMethodAttributes; DataType = propertyType; Parameters = new List<ParameterBuilder>(); if (parameters != null) { int x = 1; foreach (var parameter in parameters) { Parameters.Add(new ParameterBuilder(parameter, x)); ++x; } } Field = new FieldBuilder(Type, "_" + name + "field", propertyType, FieldAttributes.Private); Builder = Type.Builder.DefineProperty(name, attributes, propertyType, (parameters != null && parameters.Count() > 0) ? parameters.ToArray() : System.Type.EmptyTypes); GetMethod = new MethodBuilder(Type, "get_" + name, getMethodAttributes, parameters, propertyType); GetMethod.Generator.Emit(OpCodes.Ldarg_0); GetMethod.Generator.Emit(OpCodes.Ldfld, Field.Builder); GetMethod.Generator.Emit(OpCodes.Ret); var setParameters = new List<Type>(); if (parameters != null) { setParameters.AddRange(parameters); } setParameters.Add(propertyType); SetMethod = new MethodBuilder(Type, "set_" + name, setMethodAttributes, setParameters, typeof (void)); SetMethod.Generator.Emit(OpCodes.Ldarg_0); SetMethod.Generator.Emit(OpCodes.Ldarg_1); SetMethod.Generator.Emit(OpCodes.Stfld, Field.Builder); SetMethod.Generator.Emit(OpCodes.Ret); Builder.SetGetMethod(GetMethod.Builder); Builder.SetSetMethod(SetMethod.Builder); }
/// <summary> /// Create method builders for the given method. /// </summary> internal static IEnumerable<MethodBuilder> Create(MethodDefinition javaMethod, TypeBuilder declaringTypeBuilder) { bool onlyInReturnType; var convertSignedBytes = ContainsSignedByte(javaMethod, out onlyInReturnType) && !AvoidConvertSignedBytes(javaMethod); if (onlyInReturnType && javaMethod.DeclaringClass.IsInterface) { yield return new MethodBuilder(javaMethod, declaringTypeBuilder, true, false); } else { var addJavaPrefix = convertSignedBytes && onlyInReturnType; yield return new MethodBuilder(javaMethod, declaringTypeBuilder, false, addJavaPrefix); if (convertSignedBytes) yield return new MethodBuilder(javaMethod, declaringTypeBuilder, true, false); } }
protected Type CreateType(TypeBuilder type) { return(type.CreateTypeInfo()); }
private static Schema GetAvroSchema() { var s3 = SchemaBuilder.Record(SupportEventInfra.AVRO_TYPENAME + "_3", TypeBuilder.OptionalInt("nestedNestedValue")); var s2 = SchemaBuilder.Record(SupportEventInfra.AVRO_TYPENAME + "_2", TypeBuilder.OptionalInt("nestedValue"), TypeBuilder.Field("nestedNested", TypeBuilder.Union(TypeBuilder.Int(), s3))); var s1 = SchemaBuilder.Record(SupportEventInfra.AVRO_TYPENAME + "_1", TypeBuilder.Field("nested", TypeBuilder.Union(TypeBuilder.Int(), s2))); return(SchemaBuilder.Record(SupportEventInfra.AVRO_TYPENAME, TypeBuilder.Field("item", s1))); }
private unsafe static void ImplInterface(TypeBuilder delegateBuilder, MethodInfo invokeMethod, Type[] parameterTypes, Type resultType) { Type[] unByRefTypes = new Type[parameterTypes.Length]; bool haveByRef = false; for (int i = 0; i < parameterTypes.Length; i++) { if (parameterTypes[i].IsByRef || parameterTypes[i].IsPointer || parameterTypes[i] == typeof(TypedReference)) { unByRefTypes[i] = typeof(IntPtr); haveByRef = true; continue; } unByRefTypes[i] = parameterTypes[i]; } if (resultType.IsPointer || resultType == typeof(TypedReference)) { haveByRef = true; resultType = typeof(IntPtr); } Type interfaceType; if (resultType == typeof(void)) { if (parameterTypes.Length >= ActionInterfaces.Length) { return; } interfaceType = ActionInterfaces[parameterTypes.Length]; if (interfaceType.IsGenericTypeDefinition) { interfaceType = interfaceType.MakeGenericType(unByRefTypes); } } else { if (parameterTypes.Length >= FuncInterfaces.Length) { return; } interfaceType = FuncInterfaces[parameterTypes.Length]; if (interfaceType.IsGenericTypeDefinition) { var genericTypes = unByRefTypes; Array.Resize(ref genericTypes, unByRefTypes.Length + 1); genericTypes[unByRefTypes.Length] = resultType; interfaceType = interfaceType.MakeGenericType(genericTypes); } } if (!interfaceType.IsVisible) { return; } delegateBuilder.AddInterfaceImplementation(interfaceType); if (haveByRef) { var invokeBuilder = delegateBuilder.DefineMethod( "InvokeImpl", MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions.Standard, resultType, unByRefTypes); var iLGen = invokeBuilder.GetILGenerator(); for (int i = 0; i <= unByRefTypes.Length; ++i) { iLGen.LoadArgument(i); } iLGen.Call(invokeMethod); iLGen.Return(); delegateBuilder.DefineMethodOverride(invokeBuilder, interfaceType.GetMethod("Invoke")); } else { delegateBuilder.DefineMethodOverride(invokeMethod, interfaceType.GetMethod("Invoke")); } }
internal override void Seal(TypeDescription existing = null) { if (PocoType != null || TypeBuilder != null) { return; } var name = "POCO" + Guid.NewGuid().ToString().Replace("-", ""); var protoMemberAttr = typeof(ProtoMemberAttribute).GetConstructor(new[] { typeof(int) }); var protoContractAttr = typeof(ProtoContractAttribute).GetConstructor(new Type[0]); var fields = new Dictionary <string, FieldInfo>(); TypeBuilder = ModuleBuilder.DefineType(name, TypeAttributes.Public, typeof(DynamicObject), new [] { typeof(IEnumerable) }); var ix = 1; foreach (var kv in Members.OrderBy(o => o.Key, StringComparer.Ordinal)) { var memberAttrBuilder = new CustomAttributeBuilder(protoMemberAttr, new object[] { ix }); kv.Value.Seal(existing); var propType = kv.Value.GetPocoType(existing); var field = TypeBuilder.DefineField(kv.Key, propType, FieldAttributes.Public); field.SetCustomAttribute(memberAttrBuilder); fields[kv.Key] = field; ix++; } var contractAttrBuilder = new CustomAttributeBuilder(protoContractAttr, new object[0]); TypeBuilder.SetCustomAttribute(contractAttrBuilder); // Define indexer var strEq = typeof(object).GetMethod("Equals", new[] { typeof(object) }); var tryGetIndexEmit = Sigil.Emit <TryGetIndexerDelegate> .BuildMethod(TypeBuilder, "TryGetIndex", MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions.Standard | CallingConventions.HasThis); tryGetIndexEmit.LoadArgument(2); // object[] var invalid = tryGetIndexEmit.DefineLabel("invalid"); tryGetIndexEmit .Duplicate() // object[] object[] .LoadLength <object>() // int object[] .LoadConstant(1); // int int object[] tryGetIndexEmit.UnsignedBranchIfNotEqual(invalid); // object[] tryGetIndexEmit .LoadConstant(0) // int object[] .LoadElement <object>() // object .IsInstance <string>(); // int var valid = tryGetIndexEmit.DefineLabel("valid"); tryGetIndexEmit .BranchIfTrue(valid) // --empty-- .LoadArgument(2); // object[] tryGetIndexEmit.MarkLabel(invalid); tryGetIndexEmit.Pop(); // --empty-- tryGetIndexEmit .LoadArgument(3) // object& .LoadNull() // null object& .StoreIndirect(typeof(object)); // --empty-- tryGetIndexEmit .LoadConstant(0) // int .Return(); // --empty-- tryGetIndexEmit.MarkLabel(valid); tryGetIndexEmit.LoadArgument(3); // object& tryGetIndexEmit .LoadArgument(2) // object[] object& .LoadConstant(0) // int object[] object& .LoadElement <object>(); // object object& Sigil.Label next; var done = tryGetIndexEmit.DefineLabel("done"); foreach (var mem in Members) { next = tryGetIndexEmit.DefineLabel("next_" + mem.Key); var memKey = mem.Key; var field = fields[memKey]; tryGetIndexEmit .Duplicate() // object object object& .LoadConstant(memKey); // string object object object& tryGetIndexEmit.CallVirtual(strEq); // int object object7& tryGetIndexEmit.BranchIfFalse(next); // object object& tryGetIndexEmit .Pop() // object& .LoadArgument(0) // this object& .LoadField(field); // fieldType object& if (field.FieldType.IsValueType) { tryGetIndexEmit.Box(field.FieldType); // fieldType object& } tryGetIndexEmit.Branch(done); // fieldType object& tryGetIndexEmit.MarkLabel(next); // object object& } tryGetIndexEmit .Pop() // object& .LoadNull(); // null object& tryGetIndexEmit.MarkLabel(done); // *something* object& tryGetIndexEmit .StoreIndirect(typeof(object)) // --empty-- .LoadConstant(1) // int .Return(); // --empty-- var tryGetIndex = tryGetIndexEmit.CreateMethod(); TypeBuilder.DefineMethodOverride(tryGetIndex, typeof(DynamicObject).GetMethod("TryGetIndex")); // Implement IEnumerable var getEnumeratorEmit = Sigil.Emit <Func <IEnumerator> > .BuildMethod(TypeBuilder, "GetEnumerator", MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions.Standard | CallingConventions.HasThis); var newStrList = typeof(List <string>).GetConstructor(new[] { typeof(int) }); var newEnumerator = Enumerator.GetConstructor(new[] { typeof(List <string>), typeof(object) }); var add = typeof(List <string>).GetMethod("Add"); getEnumeratorEmit.LoadConstant(Members.Count); getEnumeratorEmit.NewObject(newStrList); foreach (var mem in Members) { getEnumeratorEmit.Duplicate(); getEnumeratorEmit.LoadConstant(mem.Key); getEnumeratorEmit.Call(add); } getEnumeratorEmit.LoadArgument(0); getEnumeratorEmit.NewObject(newEnumerator); getEnumeratorEmit.Return(); var getEnumerator = getEnumeratorEmit.CreateMethod(); TypeBuilder.DefineMethodOverride(getEnumerator, typeof(IEnumerable).GetMethod("GetEnumerator")); // Define ToString() var toStringEmit = Sigil.Emit <Func <string> > .BuildMethod(TypeBuilder, "ToString", MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions.Standard | CallingConventions.HasThis); var objToString = typeof(object).GetMethod("ToString"); var thunkField = TypeBuilder.DefineField("__ToStringThunk", typeof(Func <object, string>), FieldAttributes.Static | FieldAttributes.Private); var invoke = typeof(Func <object, string>).GetMethod("Invoke"); toStringEmit .LoadField(thunkField) .LoadArgument(0) .CallVirtual(invoke) .Return(); var toString = toStringEmit.CreateMethod(); TypeBuilder.DefineMethodOverride(toString, objToString); PocoType = TypeBuilder.CreateType(); // Set the ToStringCallback var firstInst = PocoType.GetConstructor(Type.EmptyTypes).Invoke(new object[0]); var setThunk = firstInst.GetType().GetField("__ToStringThunk", BindingFlags.NonPublic | BindingFlags.Static); setThunk.SetValue(firstInst, ToStringFunc); }
public static IConditional Compile(AssemblyEmitter assembly, Type objectType, ICondition[] conditions, int index) { TypeBuilder typeBuilder = assembly.DefineType( "__conditional" + index, TypeAttributes.Public, typeof(object) ); #region Constructor { ConstructorBuilder ctor = typeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes ); ILGenerator il = ctor.GetILGenerator(); // : base() il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes)); for (int i = 0; i < conditions.Length; ++i) { conditions[i].Construct(typeBuilder, il, i); } // return; il.Emit(OpCodes.Ret); } #endregion #region IComparer typeBuilder.AddInterfaceImplementation(typeof(IConditional)); MethodBuilder compareMethod; #region Compare { MethodEmitter emitter = new MethodEmitter(typeBuilder); emitter.Define( /* name */ "Verify", /* attr */ MethodAttributes.Public | MethodAttributes.Virtual, /* return */ typeof(bool), /* params */ new Type[] { typeof(object) }); LocalBuilder obj = emitter.CreateLocal(objectType); LocalBuilder eq = emitter.CreateLocal(typeof(bool)); emitter.LoadArgument(1); emitter.CastAs(objectType); emitter.StoreLocal(obj); Label done = emitter.CreateLabel(); for (int i = 0; i < conditions.Length; ++i) { if (i > 0) { emitter.LoadLocal(eq); emitter.BranchIfFalse(done); } emitter.LoadLocal(obj); conditions[i].Compile(emitter); emitter.StoreLocal(eq); } emitter.MarkLabel(done); emitter.LoadLocal(eq); emitter.Return(); typeBuilder.DefineMethodOverride( emitter.Method, typeof(IConditional).GetMethod( "Verify", new Type[] { typeof(object) } ) ); compareMethod = emitter.Method; } #endregion #endregion Type conditionalType = typeBuilder.CreateType(); return((IConditional)Activator.CreateInstance(conditionalType)); }
/// <summary> /// Defines additional fields in the proxy type. /// </summary> /// <param name="typeBuilder">The type builder for the proxy.</param> /// <returns>The defined proxy fields.</returns> protected virtual FieldInfo[] DefineProxyFields(TypeBuilder typeBuilder) { return(new FieldInfo[0]); }
/// <summary> /// Convenience method for creating static methods. /// /// Equivalent to calling to BuildMethod, but with MethodAttributes.Static set and CallingConventions.Standard. /// </summary> public static Emit BuildStaticMethod(Type returnType, Type[] parameterTypes, TypeBuilder type, string name, MethodAttributes attributes, bool allowUnverifiableCode = false, bool doVerify = true, bool strictBranchVerification = false) { return(BuildMethod(returnType, parameterTypes, type, name, attributes | MethodAttributes.Static, CallingConventions.Standard, allowUnverifiableCode, doVerify, strictBranchVerification)); }
public static Type Generate(string functionAssemblyName, string typeName, Collection <CustomAttributeBuilder> typeAttributes, ICollection <FunctionDescriptor> functions) { if (functions == null) { throw new ArgumentNullException(nameof(functions)); } AssemblyName assemblyName = new AssemblyName(functionAssemblyName); AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); ModuleBuilder mb = assemblyBuilder.DefineDynamicModule(assemblyName.Name); TypeBuilder tb = mb.DefineType(typeName, TypeAttributes.Public); if (typeAttributes != null) { foreach (CustomAttributeBuilder attributeBuilder in typeAttributes) { tb.SetCustomAttribute(attributeBuilder); } } foreach (FunctionDescriptor function in functions) { if (function.Metadata.IsDirect()) { continue; } var retValue = function.Parameters.Where(x => x.Name == ScriptConstants.SystemReturnParameterName).FirstOrDefault(); var parameters = function.Parameters.Where(x => x != retValue).ToArray(); MethodBuilder methodBuilder = tb.DefineMethod(function.Name, MethodAttributes.Public | MethodAttributes.Static); Type[] types = parameters.Select(p => p.Type).ToArray(); methodBuilder.SetParameters(types); Type innerReturnType = null; if (retValue == null) { methodBuilder.SetReturnType(typeof(Task)); } else { // It's critical to set the proper return type for the binder. // The return parameters was added a MakeByRefType, so need to get the inner type. innerReturnType = retValue.Type.GetElementType(); // Task<> derives from Task. var actualReturnType = typeof(Task <>).MakeGenericType(innerReturnType); methodBuilder.SetReturnType(actualReturnType); ParameterBuilder parameterBuilder = methodBuilder.DefineParameter(0, ParameterAttributes.Retval, null); if (retValue.CustomAttributes != null) { foreach (CustomAttributeBuilder attributeBuilder in retValue.CustomAttributes) { parameterBuilder.SetCustomAttribute(attributeBuilder); } } } if (function.CustomAttributes != null) { foreach (CustomAttributeBuilder attributeBuilder in function.CustomAttributes) { methodBuilder.SetCustomAttribute(attributeBuilder); } } for (int i = 0; i < parameters.Length; i++) { ParameterDescriptor parameter = parameters[i]; ParameterBuilder parameterBuilder = methodBuilder.DefineParameter(i + 1, parameter.Attributes, parameter.Name); if (parameter.CustomAttributes != null) { foreach (CustomAttributeBuilder attributeBuilder in parameter.CustomAttributes) { parameterBuilder.SetCustomAttribute(attributeBuilder); } } } _invokerMap[function.Name] = function.Invoker; MethodInfo invokeMethod = function.Invoker.GetType().GetMethod("Invoke"); MethodInfo getInvoker = typeof(FunctionGenerator).GetMethod("GetInvoker", BindingFlags.Static | BindingFlags.Public); ILGenerator il = methodBuilder.GetILGenerator(); LocalBuilder argsLocal = il.DeclareLocal(typeof(object[])); LocalBuilder invokerLocal = il.DeclareLocal(typeof(IFunctionInvoker)); il.Emit(OpCodes.Nop); // declare an array for all parameter values il.Emit(OpCodes.Ldc_I4, parameters.Length); il.Emit(OpCodes.Newarr, typeof(object)); il.Emit(OpCodes.Stloc, argsLocal); // copy each parameter into the arg array for (int i = 0; i < parameters.Length; i++) { ParameterDescriptor parameter = parameters[i]; il.Emit(OpCodes.Ldloc, argsLocal); il.Emit(OpCodes.Ldc_I4, i); il.Emit(OpCodes.Ldarg, i); // For Out and Ref types, need to do an indirection. if (parameter.Type.IsByRef) { il.Emit(OpCodes.Ldind_Ref); } // Box value types if (parameter.Type.IsValueType) { il.Emit(OpCodes.Box, parameter.Type); } il.Emit(OpCodes.Stelem_Ref); } // get the invoker instance il.Emit(OpCodes.Ldstr, function.Name); il.Emit(OpCodes.Call, getInvoker); il.Emit(OpCodes.Stloc, invokerLocal); // now call the invoker, passing in the args il.Emit(OpCodes.Ldloc, invokerLocal); il.Emit(OpCodes.Ldloc, argsLocal); il.Emit(OpCodes.Callvirt, invokeMethod); // pushes a Task<object> if (parameters.Any(p => p.Type.IsByRef)) { LocalBuilder taskLocal = il.DeclareLocal(typeof(Task <object>)); LocalBuilder taskAwaiterLocal = il.DeclareLocal(typeof(TaskAwaiter <object>)); // We need to wait on the function's task if we have any out/ref // parameters to ensure they have been populated before we copy them back // Store the result into a local Task // and load it onto the evaluation stack il.Emit(OpCodes.Stloc, taskLocal); il.Emit(OpCodes.Ldloc, taskLocal); // Call "GetAwaiter" on the Task il.Emit(OpCodes.Callvirt, typeof(Task <object>).GetMethod("GetAwaiter", Type.EmptyTypes)); // Call "GetResult", which will synchonously wait for the Task to complete il.Emit(OpCodes.Stloc, taskAwaiterLocal); il.Emit(OpCodes.Ldloca, taskAwaiterLocal); il.Emit(OpCodes.Call, typeof(TaskAwaiter <object>).GetMethod("GetResult")); il.Emit(OpCodes.Pop); // ignore GetResult(); // Copy back out and ref parameters for (int i = 0; i < parameters.Length; i++) { var param = parameters[i]; if (!param.Type.IsByRef) { continue; } il.Emit(OpCodes.Ldarg, i); il.Emit(OpCodes.Ldloc, argsLocal); il.Emit(OpCodes.Ldc_I4, i); il.Emit(OpCodes.Ldelem_Ref); il.Emit(OpCodes.Castclass, param.Type.GetElementType()); il.Emit(OpCodes.Stind_Ref); } il.Emit(OpCodes.Ldloc, taskLocal); } // Need to coerce. if (innerReturnType != null) { var m = typeof(FunctionGenerator).GetMethod("Coerce", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public); var m2 = m.MakeGenericMethod(innerReturnType); il.Emit(OpCodes.Call, m2); } il.Emit(OpCodes.Ret); } Type t = tb.CreateTypeInfo().AsType(); return(t); }
public override void GenerateMSIL(ILGenerator ilGenerator, TypeBuilder typeBuilder) { FirstPart.GenerateMSIL(ilGenerator, typeBuilder); SecondPart.GenerateMSIL(ilGenerator, typeBuilder); }
public BuilderGenerator(TypeBuilder typeBuilder) { _typeBuilder = typeBuilder; }
internal void AddToModule(ModuleBuilder module) { string typeName = (nextTypeId++).ToString(); // // Define a public class named "Property" in the assembly. // TypeBuilder myType = module.DefineType(typeName, TypeAttributes.Public); // // Mark the class as implementing IPropertyAccessor. // myType.AddInterfaceImplementation(typeof(IGetterSetter)); // Add a constructor //ConstructorBuilder constructor = myType.DefineDefaultConstructor(MethodAttributes.Public); // // Define a method for the get operation. // Type[] getParamTypes = new [] { typeof(object) }; Type getReturnType = typeof(object); MethodBuilder getMethod = myType.DefineMethod("Get", MethodAttributes.Public | MethodAttributes.Virtual, getReturnType, getParamTypes); // // From the method, get an ILGenerator. This is used to // emit the IL that we want. // ILGenerator getIL = getMethod.GetILGenerator(); // // Emit the IL. // var targetGetMethod = mProperty.GetGetMethod(); if (targetGetMethod != null) { getIL.DeclareLocal(typeof(object)); getIL.Emit(OpCodes.Ldarg_1); //Load the first argument //(target object) getIL.Emit(OpCodes.Castclass, mTargetType); //Cast to the source type getIL.EmitCall(OpCodes.Call, targetGetMethod, null); //Get the property value if (targetGetMethod.ReturnType.IsValueType) { getIL.Emit(OpCodes.Box, targetGetMethod.ReturnType); //Box if necessary } getIL.Emit(OpCodes.Stloc_0); //Store it getIL.Emit(OpCodes.Ldloc_0); } else { getIL.ThrowException(typeof(MissingMethodException)); } getIL.Emit(OpCodes.Ret); // // Define a method for the set operation. // Type[] setParamTypes = new [] { typeof(object), typeof(object) }; Type setReturnType = null; MethodBuilder setMethod = myType.DefineMethod("Set", MethodAttributes.Public | MethodAttributes.Virtual, setReturnType, setParamTypes); // // From the method, get an ILGenerator. This is used to // emit the IL that we want. // ILGenerator setIL = setMethod.GetILGenerator(); // // Emit the IL. // MethodInfo targetSetMethod = mProperty.GetSetMethod(); if (targetSetMethod != null) { Type paramType = targetSetMethod.GetParameters()[0].ParameterType; setIL.DeclareLocal(paramType); setIL.Emit(OpCodes.Ldarg_1); //Load the first argument //(target object) setIL.Emit(OpCodes.Castclass, mTargetType); //Cast to the source type setIL.Emit(OpCodes.Ldarg_2); //Load the second argument //(value object) if (paramType.IsValueType) { setIL.Emit(OpCodes.Unbox, paramType); //Unbox it if (typesHashes[paramType] != null) //and load { OpCode load = (OpCode)typesHashes[paramType]; setIL.Emit(load); } else { setIL.Emit(OpCodes.Ldobj, paramType); } } else { setIL.Emit(OpCodes.Castclass, paramType); //Cast class } setIL.EmitCall(OpCodes.Callvirt, targetSetMethod, null); //Set the property value } else { setIL.ThrowException(typeof(MissingMethodException)); } setIL.Emit(OpCodes.Ret); // // Load the type // myType.CreateType(); mEmittedPropertyAccessor = module.Assembly.CreateInstance(typeName) as IGetterSetter; if (mEmittedPropertyAccessor == null) { throw new Exception("Unable to create property accessor."); } }
static void DefineMethods(TypeBuilder typeBuilder, Type interfaceType, MethodDefinition[] definitions, ConstructorInfo emptyCtor) { var filedHolderType = typeof(MagicOnionClientBase); var baseType = typeof(MagicOnionClientBase <>).MakeGenericType(interfaceType); var hostField = filedHolderType.GetField("host", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var optionField = filedHolderType.GetField("option", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var invokerField = filedHolderType.GetField("callInvoker", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var resolverField = filedHolderType.GetField("resolver", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var filtersField = filedHolderType.GetField("filters", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); // Clone { var method = typeBuilder.DefineMethod("Clone", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual, typeof(MagicOnionClientBase <>).MakeGenericType(interfaceType), Type.EmptyTypes); var il = method.GetILGenerator(); il.Emit(OpCodes.Newobj, emptyCtor); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, hostField); il.Emit(OpCodes.Stfld, hostField); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, optionField); il.Emit(OpCodes.Stfld, optionField); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, invokerField); il.Emit(OpCodes.Stfld, invokerField); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, resolverField); il.Emit(OpCodes.Stfld, resolverField); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, filtersField); il.Emit(OpCodes.Stfld, filtersField); il.Emit(OpCodes.Ret); } // Overrides { // TSelf WithOption(CallOptions option) { var method = typeBuilder.DefineMethod("WithOptions", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual, interfaceType, new[] { typeof(CallOptions) }); var il = method.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Call, baseType.GetMethod("WithOptions", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)); il.Emit(OpCodes.Ret); } // TSelf WithHeaders(Metadata headers); { var method = typeBuilder.DefineMethod("WithHeaders", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual, interfaceType, new[] { typeof(Metadata) }); var il = method.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Call, baseType.GetMethod("WithHeaders", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)); il.Emit(OpCodes.Ret); } // TSelf WithDeadline(DateTime deadline); { var method = typeBuilder.DefineMethod("WithDeadline", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual, interfaceType, new[] { typeof(DateTime) }); var il = method.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Call, baseType.GetMethod("WithDeadline", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)); il.Emit(OpCodes.Ret); } // TSelf WithCancellationToken(CancellationToken cancellationToken); { var method = typeBuilder.DefineMethod("WithCancellationToken", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual, interfaceType, new[] { typeof(CancellationToken) }); var il = method.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Call, baseType.GetMethod("WithCancellationToken", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)); il.Emit(OpCodes.Ret); } // TSelf WithHost(string host); { var method = typeBuilder.DefineMethod("WithHost", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual, interfaceType, new[] { typeof(string) }); var il = method.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Call, baseType.GetMethod("WithHost", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)); il.Emit(OpCodes.Ret); } } // Proxy Methods for (int i = 0; i < definitions.Length; i++) { var def = definitions[i]; var parameters = def.MethodInfo.GetParameters().Select(x => x.ParameterType).ToArray(); var method = typeBuilder.DefineMethod(def.MethodInfo.Name, MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual, def.MethodInfo.ReturnType, parameters); var il = method.GetILGenerator(); switch (def.MethodType) { case MethodType.Unary: { // base.InvokeAsync<TRequest, TResponse>/InvokeTaskAsync(string path, TRequest request, Func<RequestContext, ResponseContext> requestMethod) // this. il.Emit(OpCodes.Ldarg_0); // path il.Emit(OpCodes.Ldstr, def.Path); // create request for (int j = 0; j < parameters.Length; j++) { il.Emit(OpCodes.Ldarg, j + 1); } if (parameters.Length == 0) { // use empty byte[0] il.Emit(OpCodes.Ldsfld, nilBytes); } else if (parameters.Length == 1) { // already loaded parameter. } else { // call new DynamicArgumentTuple<T> il.Emit(OpCodes.Newobj, def.RequestType.GetConstructors()[0]); } // requestMethod il.Emit(OpCodes.Ldsfld, def.UnaryRequestDelegate); // InvokeAsync/InvokeTaskAsync var invokeMethod = def.ResponseIsTask ? baseType.GetMethod("InvokeTaskAsync", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.Instance) : baseType.GetMethod("InvokeAsync", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.Instance); invokeMethod = invokeMethod.MakeGenericMethod(def.RequestType, def.ResponseType); il.Emit(OpCodes.Callvirt, invokeMethod); } break; case MethodType.ServerStreaming: { il.DeclareLocal(typeof(byte[])); // request il.DeclareLocal(typeof(AsyncServerStreamingCall <byte[]>)); // create request for (int j = 0; j < parameters.Length; j++) { il.Emit(OpCodes.Ldarg, j + 1); } if (parameters.Length == 0) { // use empty byte[0] il.Emit(OpCodes.Ldsfld, nilBytes); } else if (parameters.Length == 1) { // already loaded parameter. il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, resolverField); il.Emit(OpCodes.Call, callMessagePackSerialize.MakeGenericMethod(def.RequestType)); } else { // call new DynamicArgumentTuple<T> il.Emit(OpCodes.Newobj, def.RequestType.GetConstructors()[0]); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, resolverField); il.Emit(OpCodes.Call, callMessagePackSerialize.MakeGenericMethod(def.RequestType)); } il.Emit(OpCodes.Stloc_0); // create ***Result il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, invokerField); il.Emit(OpCodes.Ldsfld, def.FieldMethod); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, hostField); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, optionField); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Callvirt, typeof(CallInvoker).GetMethod("AsyncServerStreamingCall").MakeGenericMethod(typeof(byte[]), typeof(byte[]))); il.Emit(OpCodes.Stloc_1); // create return result il.Emit(OpCodes.Ldloc_1); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, resolverField); var resultType = typeof(ServerStreamingResult <>).MakeGenericType(def.ResponseType); il.Emit(OpCodes.Newobj, resultType.GetConstructors()[0]); if (def.ResponseIsTask) { il.Emit(OpCodes.Call, typeof(Task).GetMethod("FromResult").MakeGenericMethod(resultType)); } } break; case MethodType.ClientStreaming: case MethodType.DuplexStreaming: if (def.MethodType == MethodType.ClientStreaming) { il.DeclareLocal(typeof(AsyncClientStreamingCall <byte[], byte[]>)); // callResult } else { il.DeclareLocal(typeof(AsyncDuplexStreamingCall <byte[], byte[]>)); // callResult } il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, invokerField); il.Emit(OpCodes.Ldsfld, def.FieldMethod); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, hostField); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, optionField); if (def.MethodType == MethodType.ClientStreaming) { il.Emit(OpCodes.Callvirt, typeof(CallInvoker).GetMethod("AsyncClientStreamingCall").MakeGenericMethod(typeof(byte[]), typeof(byte[]))); } else { il.Emit(OpCodes.Callvirt, typeof(CallInvoker).GetMethod("AsyncDuplexStreamingCall").MakeGenericMethod(typeof(byte[]), typeof(byte[]))); } il.Emit(OpCodes.Stloc_0); // create return result il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, resolverField); Type resultType2; if (def.MethodType == MethodType.ClientStreaming) { resultType2 = typeof(ClientStreamingResult <,>).MakeGenericType(def.RequestType, def.ResponseType); il.Emit(OpCodes.Newobj, resultType2.GetConstructors().OrderBy(x => x.GetParameters().Length).Last()); } else { resultType2 = typeof(DuplexStreamingResult <,>).MakeGenericType(def.RequestType, def.ResponseType); il.Emit(OpCodes.Newobj, resultType2.GetConstructors()[0]); } if (def.ResponseIsTask) { il.Emit(OpCodes.Call, typeof(Task).GetMethod("FromResult").MakeGenericMethod(resultType2)); } break; default: throw new InvalidOperationException("Not supported method type:" + def.MethodType); } il.Emit(OpCodes.Ret); } }
static TypeAccessor CreateNew(Type type, bool allowNonPublicAccessors) { #if !NO_DYNAMIC if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(type)) { return(DynamicAccessor.Singleton); } #endif PropertyInfo[] props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance); Dictionary <string, int> map = new Dictionary <string, int>(); List <MemberInfo> members = new List <MemberInfo>(props.Length + fields.Length); int i = 0; foreach (var prop in props) { if (!map.ContainsKey(prop.Name) && prop.GetIndexParameters().Length == 0) { map.Add(prop.Name, i++); members.Add(prop); } } foreach (var field in fields) { if (!map.ContainsKey(field.Name)) { map.Add(field.Name, i++); members.Add(field); } } ConstructorInfo ctor = null; if (_IsClass(type) && !_IsAbstract(type)) { ctor = type.GetConstructor(TypeHelpers.EmptyTypes); } ILGenerator il; if (!IsFullyPublic(type, props, allowNonPublicAccessors)) { DynamicMethod dynGetter = new DynamicMethod(type.FullName + "_get", typeof(object), new Type[] { typeof(int), typeof(object) }, type, true), dynSetter = new DynamicMethod(type.FullName + "_set", null, new Type[] { typeof(int), typeof(object), typeof(object) }, type, true); WriteMapImpl(dynGetter.GetILGenerator(), type, members, null, allowNonPublicAccessors, true); WriteMapImpl(dynSetter.GetILGenerator(), type, members, null, allowNonPublicAccessors, false); DynamicMethod dynCtor = null; if (ctor != null) { dynCtor = new DynamicMethod(type.FullName + "_ctor", typeof(object), TypeHelpers.EmptyTypes, type, true); il = dynCtor.GetILGenerator(); il.Emit(OpCodes.Newobj, ctor); il.Emit(OpCodes.Ret); } return(new DelegateAccessor( map, (Func <int, object, object>)dynGetter.CreateDelegate(typeof(Func <int, object, object>)), (Action <int, object, object>)dynSetter.CreateDelegate(typeof(Action <int, object, object>)), dynCtor == null ? null : (Func <object>)dynCtor.CreateDelegate(typeof(Func <object>)), type)); } // note this region is synchronized; only one is being created at a time so we don't need to stress about the builders if (assembly == null) { AssemblyName name = new AssemblyName("FastMember_dynamic"); #if COREFX assembly = AssemblyBuilder.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run); #else assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run); #endif module = assembly.DefineDynamicModule(name.Name); } #if COREFX TypeAttributes attribs = typeof(TypeAccessor).GetTypeInfo().Attributes; #else TypeAttributes attribs = typeof(TypeAccessor).Attributes; #endif TypeBuilder tb = module.DefineType("FastMember_dynamic." + type.Name + "_" + GetNextCounterValue(), (attribs | TypeAttributes.Sealed | TypeAttributes.Public) & ~(TypeAttributes.Abstract | TypeAttributes.NotPublic), typeof(RuntimeTypeAccessor)); il = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new[] { typeof(Dictionary <string, int>) }).GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); FieldBuilder mapField = tb.DefineField("_map", typeof(Dictionary <string, int>), FieldAttributes.InitOnly | FieldAttributes.Private); il.Emit(OpCodes.Stfld, mapField); il.Emit(OpCodes.Ret); PropertyInfo indexer = typeof(TypeAccessor).GetProperty("Item"); MethodInfo baseGetter = indexer.GetGetMethod(), baseSetter = indexer.GetSetMethod(); MethodBuilder body = tb.DefineMethod(baseGetter.Name, baseGetter.Attributes & ~MethodAttributes.Abstract, typeof(object), new Type[] { typeof(object), typeof(string) }); il = body.GetILGenerator(); WriteMapImpl(il, type, members, mapField, allowNonPublicAccessors, true); tb.DefineMethodOverride(body, baseGetter); body = tb.DefineMethod(baseSetter.Name, baseSetter.Attributes & ~MethodAttributes.Abstract, null, new Type[] { typeof(object), typeof(string), typeof(object) }); il = body.GetILGenerator(); WriteMapImpl(il, type, members, mapField, allowNonPublicAccessors, false); tb.DefineMethodOverride(body, baseSetter); MethodInfo baseMethod; if (ctor != null) { baseMethod = typeof(TypeAccessor).GetProperty("CreateNewSupported").GetGetMethod(); body = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes, baseMethod.ReturnType, TypeHelpers.EmptyTypes); il = body.GetILGenerator(); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Ret); tb.DefineMethodOverride(body, baseMethod); baseMethod = typeof(TypeAccessor).GetMethod("CreateNew"); body = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes, baseMethod.ReturnType, TypeHelpers.EmptyTypes); il = body.GetILGenerator(); il.Emit(OpCodes.Newobj, ctor); il.Emit(OpCodes.Ret); tb.DefineMethodOverride(body, baseMethod); } baseMethod = typeof(RuntimeTypeAccessor).GetProperty("Type", BindingFlags.NonPublic | BindingFlags.Instance).GetGetMethod(true); body = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes & ~MethodAttributes.Abstract, baseMethod.ReturnType, TypeHelpers.EmptyTypes); il = body.GetILGenerator(); il.Emit(OpCodes.Ldtoken, type); il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle")); il.Emit(OpCodes.Ret); tb.DefineMethodOverride(body, baseMethod); var accessor = (TypeAccessor)Activator.CreateInstance(_CreateType(tb), map); return(accessor); }
protected override MethodEmitter BuildProxiedMethodBody( MethodEmitter emitter, ClassEmitter @class, INamingScope namingScope ) { var invocationType = invocation; var genericArguments = Type.EmptyTypes; var constructor = invocation.GetConstructors()[0]; IExpression proxiedMethodTokenExpression; if (MethodToOverride.IsGenericMethod) { // Not in the cache: generic method genericArguments = emitter.MethodBuilder.GetGenericArguments(); proxiedMethodTokenExpression = new MethodTokenExpression( MethodToOverride.MakeGenericMethod(genericArguments) ); if (invocationType.IsGenericTypeDefinition) { // bind generic method arguments to invocation's type arguments invocationType = invocationType.MakeGenericType(genericArguments); constructor = TypeBuilder.GetConstructor(invocationType, constructor); } } else { var proxiedMethodToken = @class.CreateStaticField( namingScope.GetUniqueName("token_" + MethodToOverride.Name), typeof(MethodInfo) ); @class.ClassConstructor.CodeBuilder.AddStatement( new AssignStatement( proxiedMethodToken, new MethodTokenExpression(MethodToOverride) ) ); proxiedMethodTokenExpression = proxiedMethodToken; } var methodInterceptors = SetMethodInterceptors( @class, namingScope, emitter, proxiedMethodTokenExpression ); var dereferencedArguments = IndirectReference.WrapIfByRef(emitter.Arguments); var hasByRefArguments = HasByRefArguments(emitter.Arguments); var arguments = GetCtorArguments( @class, proxiedMethodTokenExpression, dereferencedArguments, methodInterceptors ); var ctorArguments = ModifyArguments(@class, arguments); var invocationLocal = emitter.CodeBuilder.DeclareLocal(invocationType); emitter.CodeBuilder.AddStatement( new AssignStatement( invocationLocal, new NewInstanceExpression(constructor, ctorArguments) ) ); if (MethodToOverride.ContainsGenericParameters) { EmitLoadGenricMethodArguments( emitter, MethodToOverride.MakeGenericMethod(genericArguments), invocationLocal ); } if (hasByRefArguments) { emitter.CodeBuilder.AddStatement(new TryStatement()); } var proceed = new MethodInvocationExpression( invocationLocal, InvocationMethods.Proceed ); emitter.CodeBuilder.AddStatement(proceed); if (hasByRefArguments) { emitter.CodeBuilder.AddStatement(new FinallyStatement()); } GeneratorUtil.CopyOutAndRefParameters( dereferencedArguments, invocationLocal, MethodToOverride, emitter ); if (hasByRefArguments) { emitter.CodeBuilder.AddStatement(new EndExceptionBlockStatement()); } if (MethodToOverride.ReturnType != typeof(void)) { var getRetVal = new MethodInvocationExpression( invocationLocal, InvocationMethods.GetReturnValue ); // Emit code to ensure a value type return type is not null, otherwise the cast will cause a null-deref if (emitter.ReturnType.IsValueType && !emitter.ReturnType.IsNullableType()) { LocalReference returnValue = emitter.CodeBuilder.DeclareLocal(typeof(object)); emitter.CodeBuilder.AddStatement(new AssignStatement(returnValue, getRetVal)); emitter.CodeBuilder.AddStatement( new IfNullExpression( returnValue, new ThrowStatement( typeof(InvalidOperationException), "Interceptors failed to set a return value, or swallowed the exception thrown by the target" ) ) ); } // Emit code to return with cast from ReturnValue emitter.CodeBuilder.AddStatement( new ReturnStatement(new ConvertExpression(emitter.ReturnType, getRetVal)) ); } else { emitter.CodeBuilder.AddStatement(new ReturnStatement()); } return(emitter); }
/* * Generates an overriden implementation of method inside myType that delegates * to a function in a Lua table with the same name, if the function exists. If it * doesn't the method calls the base method (or does nothing, in case of interface * implementations). */ private void GenerateMethod(TypeBuilder myType, MethodInfo method, MethodAttributes attributes, int methodIndex, FieldInfo luaTableField, FieldInfo returnTypesField, bool generateBase, out Type[] returnTypes) { var paramInfo = method.GetParameters(); var paramTypes = new Type[paramInfo.Length]; var returnTypesList = new List <Type>(); // Counts out and ref parameters, for later use, // and creates the list of return types int nOutParams = 0; int nOutAndRefParams = 0; var returnType = method.ReturnType; returnTypesList.Add(returnType); for (int i = 0; i < paramTypes.Length; i++) { paramTypes[i] = paramInfo[i].ParameterType; if (!paramInfo[i].IsIn && paramInfo[i].IsOut) { nOutParams++; } if (paramTypes[i].IsByRef) { returnTypesList.Add(paramTypes[i].GetElementType()); nOutAndRefParams++; } } int[] refArgs = new int[nOutAndRefParams]; returnTypes = returnTypesList.ToArray(); // Generates a version of the method that calls the base implementation // directly, for use by the base field of the table if (generateBase) { var baseMethod = myType.DefineMethod("__luaInterface_base_" + method.Name, MethodAttributes.Private | MethodAttributes.NewSlot | MethodAttributes.HideBySig, returnType, paramTypes); ILGenerator generatorBase = baseMethod.GetILGenerator(); generatorBase.Emit(OpCodes.Ldarg_0); for (int i = 0; i < paramTypes.Length; i++) { generatorBase.Emit(OpCodes.Ldarg, i + 1); } generatorBase.Emit(OpCodes.Call, method); if (returnType == typeof(void)) { generatorBase.Emit(OpCodes.Pop); } generatorBase.Emit(OpCodes.Ret); } // Defines the method var methodImpl = myType.DefineMethod(method.Name, attributes, returnType, paramTypes); // If it's an implementation of an interface tells what method it // is overriding if (myType.BaseType.Equals(typeof(object))) { myType.DefineMethodOverride(methodImpl, method); } ILGenerator generator = methodImpl.GetILGenerator(); generator.DeclareLocal(typeof(object[])); // original arguments generator.DeclareLocal(typeof(object[])); // with out-only arguments removed generator.DeclareLocal(typeof(int[])); // indexes of out and ref arguments if (!(returnType == typeof(void))) // return value { generator.DeclareLocal(returnType); } else { generator.DeclareLocal(typeof(object)); } // Initializes local variables generator.Emit(OpCodes.Ldc_I4, paramTypes.Length); generator.Emit(OpCodes.Newarr, typeof(object)); generator.Emit(OpCodes.Stloc_0); generator.Emit(OpCodes.Ldc_I4, paramTypes.Length - nOutParams + 1); generator.Emit(OpCodes.Newarr, typeof(object)); generator.Emit(OpCodes.Stloc_1); generator.Emit(OpCodes.Ldc_I4, nOutAndRefParams); generator.Emit(OpCodes.Newarr, typeof(int)); generator.Emit(OpCodes.Stloc_2); generator.Emit(OpCodes.Ldloc_1); generator.Emit(OpCodes.Ldc_I4_0); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldfld, luaTableField); generator.Emit(OpCodes.Stelem_Ref); // Stores the arguments into the local variables, as needed for (int iArgs = 0, iInArgs = 1, iOutArgs = 0; iArgs < paramTypes.Length; iArgs++) { generator.Emit(OpCodes.Ldloc_0); generator.Emit(OpCodes.Ldc_I4, iArgs); generator.Emit(OpCodes.Ldarg, iArgs + 1); if (paramTypes[iArgs].IsByRef) { if (paramTypes[iArgs].GetElementType().IsValueType) { generator.Emit(OpCodes.Ldobj, paramTypes[iArgs].GetElementType()); generator.Emit(OpCodes.Box, paramTypes[iArgs].GetElementType()); } else { generator.Emit(OpCodes.Ldind_Ref); } } else { if (paramTypes[iArgs].IsValueType) { generator.Emit(OpCodes.Box, paramTypes[iArgs]); } } generator.Emit(OpCodes.Stelem_Ref); if (paramTypes[iArgs].IsByRef) { generator.Emit(OpCodes.Ldloc_2); generator.Emit(OpCodes.Ldc_I4, iOutArgs); generator.Emit(OpCodes.Ldc_I4, iArgs); generator.Emit(OpCodes.Stelem_I4); refArgs[iOutArgs] = iArgs; iOutArgs++; } if (paramInfo[iArgs].IsIn || (!paramInfo[iArgs].IsOut)) { generator.Emit(OpCodes.Ldloc_1); generator.Emit(OpCodes.Ldc_I4, iInArgs); generator.Emit(OpCodes.Ldarg, iArgs + 1); if (paramTypes[iArgs].IsByRef) { if (paramTypes[iArgs].GetElementType().IsValueType) { generator.Emit(OpCodes.Ldobj, paramTypes[iArgs].GetElementType()); generator.Emit(OpCodes.Box, paramTypes[iArgs].GetElementType()); } else { generator.Emit(OpCodes.Ldind_Ref); } } else { if (paramTypes[iArgs].IsValueType) { generator.Emit(OpCodes.Box, paramTypes[iArgs]); } } generator.Emit(OpCodes.Stelem_Ref); iInArgs++; } } // Gets the function the method will delegate to by calling // the getTableFunction method of class LuaClassHelper generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldfld, luaTableField); generator.Emit(OpCodes.Ldstr, method.Name); generator.Emit(OpCodes.Call, classHelper.GetMethod("GetTableFunction")); var lab1 = generator.DefineLabel(); generator.Emit(OpCodes.Dup); generator.Emit(OpCodes.Brtrue_S, lab1); // Function does not exist, call base method generator.Emit(OpCodes.Pop); if (!method.IsAbstract) { generator.Emit(OpCodes.Ldarg_0); for (int i = 0; i < paramTypes.Length; i++) { generator.Emit(OpCodes.Ldarg, i + 1); } generator.Emit(OpCodes.Call, method); if (returnType == typeof(void)) { generator.Emit(OpCodes.Pop); } generator.Emit(OpCodes.Ret); generator.Emit(OpCodes.Ldnull); } else { generator.Emit(OpCodes.Ldnull); } var lab2 = generator.DefineLabel(); generator.Emit(OpCodes.Br_S, lab2); generator.MarkLabel(lab1); // Function exists, call using method callFunction of LuaClassHelper generator.Emit(OpCodes.Ldloc_0); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldfld, returnTypesField); generator.Emit(OpCodes.Ldc_I4, methodIndex); generator.Emit(OpCodes.Ldelem_Ref); generator.Emit(OpCodes.Ldloc_1); generator.Emit(OpCodes.Ldloc_2); generator.Emit(OpCodes.Call, classHelper.GetMethod("CallFunction")); generator.MarkLabel(lab2); // Stores the function return value if (returnType == typeof(void)) { generator.Emit(OpCodes.Pop); generator.Emit(OpCodes.Ldnull); } else if (returnType.IsValueType) { generator.Emit(OpCodes.Unbox, returnType); generator.Emit(OpCodes.Ldobj, returnType); } else { generator.Emit(OpCodes.Castclass, returnType); } generator.Emit(OpCodes.Stloc_3); // Sets return values of out and ref parameters for (int i = 0; i < refArgs.Length; i++) { generator.Emit(OpCodes.Ldarg, refArgs[i] + 1); generator.Emit(OpCodes.Ldloc_0); generator.Emit(OpCodes.Ldc_I4, refArgs[i]); generator.Emit(OpCodes.Ldelem_Ref); if (paramTypes[refArgs[i]].GetElementType().IsValueType) { generator.Emit(OpCodes.Unbox, paramTypes[refArgs[i]].GetElementType()); generator.Emit(OpCodes.Ldobj, paramTypes[refArgs[i]].GetElementType()); generator.Emit(OpCodes.Stobj, paramTypes[refArgs[i]].GetElementType()); } else { generator.Emit(OpCodes.Castclass, paramTypes[refArgs[i]].GetElementType()); generator.Emit(OpCodes.Stind_Ref); } } // Returns if (!(returnType == typeof(void))) { generator.Emit(OpCodes.Ldloc_3); } generator.Emit(OpCodes.Ret); }
public ClassEmitter(TypeBuilder typeBuilder) : base(typeBuilder) { }
public static void Main() { // Create an assembly. AssemblyName myAssemblyName = new AssemblyName(); myAssemblyName.Name = "SampleAssembly"; AssemblyBuilder myAssembly = Thread.GetDomain().DefineDynamicAssembly(myAssemblyName, AssemblyBuilderAccess.RunAndSave); // Create a module. For a single-file assembly the module // name is usually the same as the assembly name. ModuleBuilder myModule = myAssembly.DefineDynamicModule(myAssemblyName.Name, myAssemblyName.Name + ".dll", true); // Define a public class 'Example'. TypeBuilder myTypeBuilder = myModule.DefineType("Example", TypeAttributes.Public); // Create the 'Function1' public method, which takes an integer // and returns a string. MethodBuilder myMethod = myTypeBuilder.DefineMethod("Function1", MethodAttributes.Public | MethodAttributes.Static, typeof(String), new Type[] { typeof(int) }); // Generate IL for 'Function1'. The function body demonstrates // assigning an argument to a local variable, assigning a // constant string to a local variable, and putting the contents // of local variables on the stack. ILGenerator myMethodIL = myMethod.GetILGenerator(); // <Snippet2> // Create local variables named myString and myInt. LocalBuilder myLB1 = myMethodIL.DeclareLocal(typeof(string)); myLB1.SetLocalSymInfo("myString"); Console.WriteLine("local 'myString' type is: {0}", myLB1.LocalType); LocalBuilder myLB2 = myMethodIL.DeclareLocal(typeof(int)); myLB2.SetLocalSymInfo("myInt", 1, 2); Console.WriteLine("local 'myInt' type is: {0}", myLB2.LocalType); // </Snippet2> // Store the function argument in myInt. myMethodIL.Emit(OpCodes.Ldarg_0); myMethodIL.Emit(OpCodes.Stloc_1); // Store a literal value in myString, and return the value. myMethodIL.Emit(OpCodes.Ldstr, "string value"); myMethodIL.Emit(OpCodes.Stloc_0); myMethodIL.Emit(OpCodes.Ldloc_0); myMethodIL.Emit(OpCodes.Ret); // Create "Example" class. Type myType1 = myTypeBuilder.CreateType(); Console.WriteLine("'Example' is created."); myAssembly.Save(myAssemblyName.Name + ".dll"); Console.WriteLine("'{0}' is created.", myAssemblyName.Name + ".dll"); // Invoke 'Function1' method of 'Example', passing the value 42. Object myObject2 = myType1.InvokeMember("Function1", BindingFlags.InvokeMethod, null, null, new Object[] { 42 }); Console.WriteLine("Example.Function1 returned: {0}", myObject2); }
private static bool TryCreatePropertyDescriptor(ref PropertyDescriptor descriptor) { try { PropertyInfo property = descriptor.ComponentType.GetProperty(descriptor.Name); if (property == null) { return(false); } lock (properties) { PropertyDescriptor foundBuiltAlready; if (properties.TryGetValue(property, out foundBuiltAlready)) { descriptor = foundBuiltAlready; return(true); } string name = "_c" + Interlocked.Increment(ref counter).ToString(); TypeBuilder tb = moduleBuilder.DefineType(name, TypeAttributes.Sealed | TypeAttributes.NotPublic | TypeAttributes.Class | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoClass | TypeAttributes.Public, typeof(ChainingPropertyDescriptor)); // ctor calls base ConstructorBuilder cb = tb.DefineConstructor(MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, CallingConventions.Standard, new Type[] { typeof(PropertyDescriptor) }); ILGenerator il = cb.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Call, typeof(ChainingPropertyDescriptor).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(PropertyDescriptor) }, null)); il.Emit(OpCodes.Ret); MethodBuilder mb; MethodInfo baseMethod; if (property.CanRead) { // obtain the implementation that we want to override baseMethod = typeof(ChainingPropertyDescriptor).GetMethod("GetValue"); // create a new method that accepts an object and returns an object (as per the base) mb = tb.DefineMethod(baseMethod.Name, MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final, baseMethod.CallingConvention, baseMethod.ReturnType, new Type[] { typeof(object) }); // start writing IL into the method il = mb.GetILGenerator(); if (property.DeclaringType.IsValueType) { // upbox the object argument into our known (instance) struct type LocalBuilder lb = il.DeclareLocal(property.DeclaringType); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Unbox_Any, property.DeclaringType); il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Ldloca_S, lb); } else { // cast the object argument into our known class type il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Castclass, property.DeclaringType); } // call the "get" method il.Emit(OpCodes.Callvirt, property.GetGetMethod()); if (property.PropertyType.IsValueType) { // box it from the known (value) struct type il.Emit(OpCodes.Box, property.PropertyType); } // return the value il.Emit(OpCodes.Ret); // signal that this method should override the base tb.DefineMethodOverride(mb, baseMethod); } bool supportsChangeEvents = descriptor.SupportsChangeEvents, isReadOnly = descriptor.IsReadOnly; // override SupportsChangeEvents baseMethod = typeof(ChainingPropertyDescriptor).GetProperty("SupportsChangeEvents").GetGetMethod(); mb = tb.DefineMethod(baseMethod.Name, MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.SpecialName, baseMethod.CallingConvention, baseMethod.ReturnType, Type.EmptyTypes); il = mb.GetILGenerator(); if (supportsChangeEvents) { il.Emit(OpCodes.Ldc_I4_1); } else { il.Emit(OpCodes.Ldc_I4_0); } il.Emit(OpCodes.Ret); tb.DefineMethodOverride(mb, baseMethod); // override IsReadOnly baseMethod = typeof(ChainingPropertyDescriptor).GetProperty("IsReadOnly").GetGetMethod(); mb = tb.DefineMethod(baseMethod.Name, MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.SpecialName, baseMethod.CallingConvention, baseMethod.ReturnType, Type.EmptyTypes); il = mb.GetILGenerator(); if (isReadOnly) { il.Emit(OpCodes.Ldc_I4_1); } else { il.Emit(OpCodes.Ldc_I4_0); } il.Emit(OpCodes.Ret); tb.DefineMethodOverride(mb, baseMethod); /* REMOVED: PropertyType, ComponentType; actually *adds* time overriding these * // override PropertyType * baseMethod = typeof(ChainingPropertyDescriptor).GetProperty("PropertyType").GetGetMethod(); * mb = tb.DefineMethod(baseMethod.Name, MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.SpecialName, baseMethod.CallingConvention, baseMethod.ReturnType, Type.EmptyTypes); * il = mb.GetILGenerator(); * il.Emit(OpCodes.Ldtoken, descriptor.PropertyType); * il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle")); * il.Emit(OpCodes.Ret); * tb.DefineMethodOverride(mb, baseMethod); * * // override ComponentType * baseMethod = typeof(ChainingPropertyDescriptor).GetProperty("ComponentType").GetGetMethod(); * mb = tb.DefineMethod(baseMethod.Name, MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.SpecialName, baseMethod.CallingConvention, baseMethod.ReturnType, Type.EmptyTypes); * il = mb.GetILGenerator(); * il.Emit(OpCodes.Ldtoken, descriptor.ComponentType); * il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle")); * il.Emit(OpCodes.Ret); * tb.DefineMethodOverride(mb, baseMethod); */ // for classes, implement write (would be lost in unbox for structs) if (!property.DeclaringType.IsValueType) { if (!isReadOnly && property.CanWrite) { // override set method baseMethod = typeof(ChainingPropertyDescriptor).GetMethod("SetValue"); mb = tb.DefineMethod(baseMethod.Name, MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final, baseMethod.CallingConvention, baseMethod.ReturnType, new Type[] { typeof(object), typeof(object) }); il = mb.GetILGenerator(); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Castclass, property.DeclaringType); il.Emit(OpCodes.Ldarg_2); if (property.PropertyType.IsValueType) { il.Emit(OpCodes.Unbox_Any, property.PropertyType); } else { il.Emit(OpCodes.Castclass, property.PropertyType); } il.Emit(OpCodes.Callvirt, property.GetSetMethod()); il.Emit(OpCodes.Ret); tb.DefineMethodOverride(mb, baseMethod); } if (supportsChangeEvents) { EventInfo ei = property.DeclaringType.GetEvent(property.Name + "Changed"); if (ei != null) { baseMethod = typeof(ChainingPropertyDescriptor).GetMethod("AddValueChanged"); mb = tb.DefineMethod(baseMethod.Name, MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.SpecialName, baseMethod.CallingConvention, baseMethod.ReturnType, new Type[] { typeof(object), typeof(EventHandler) }); il = mb.GetILGenerator(); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Castclass, property.DeclaringType); il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Callvirt, ei.GetAddMethod()); il.Emit(OpCodes.Ret); tb.DefineMethodOverride(mb, baseMethod); baseMethod = typeof(ChainingPropertyDescriptor).GetMethod("RemoveValueChanged"); mb = tb.DefineMethod(baseMethod.Name, MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.SpecialName, baseMethod.CallingConvention, baseMethod.ReturnType, new Type[] { typeof(object), typeof(EventHandler) }); il = mb.GetILGenerator(); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Castclass, property.DeclaringType); il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Callvirt, ei.GetRemoveMethod()); il.Emit(OpCodes.Ret); tb.DefineMethodOverride(mb, baseMethod); } } } PropertyDescriptor newDesc = tb.CreateType().GetConstructor(new Type[] { typeof(PropertyDescriptor) }) .Invoke(new object[] { descriptor }) as PropertyDescriptor; if (newDesc == null) { return(false); } descriptor = newDesc; properties.Add(property, descriptor); return(true); } } catch { return(false); } }
/// <summary> /// Creates a method builder for building an implementation of a native calling method. /// </summary> /// <param name="typeBuilder">The type builder to create the method in.</param> /// <param name="context">The IL generation context.</param> /// <returns>Create created method builder.</returns> protected abstract MethodBuilder CreateMethodBuilder(TypeBuilder typeBuilder, NativeIlGenContext context);
public void Acquire(TypeBuilder typeBuilder, ILGenerator il, string fieldName) { if (m_Value is string) { string toParse = (string)m_Value; if (!m_Type.IsValueType && toParse == "null") { m_Value = null; } else if (m_Type == typeof(string)) { if (toParse == @"@""null""") { toParse = "null"; } m_Value = toParse; } else if (m_Type.IsEnum) { m_Value = Enum.Parse(m_Type, toParse, true); } else { MethodInfo parseMethod = null; object[] parseArgs = null; MethodInfo parseNumber = m_Type.GetMethod( "Parse", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(string), typeof(NumberStyles) }, null ); if (parseNumber != null) { NumberStyles style = NumberStyles.Integer; if (Insensitive.StartsWith(toParse, "0x")) { style = NumberStyles.HexNumber; toParse = toParse.Substring(2); } parseMethod = parseNumber; parseArgs = new object[] { toParse, style }; } else { MethodInfo parseGeneral = m_Type.GetMethod( "Parse", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(string) }, null ); parseMethod = parseGeneral; parseArgs = new object[] { toParse }; } if (parseMethod != null) { m_Value = parseMethod.Invoke(null, parseArgs); if (!m_Type.IsPrimitive) { m_Field = typeBuilder.DefineField( fieldName, m_Type, FieldAttributes.Private | FieldAttributes.InitOnly ); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldstr, toParse); if (parseArgs.Length == 2) // dirty evil hack :-( { il.Emit(OpCodes.Ldc_I4, (int)parseArgs[1]); } il.Emit(OpCodes.Call, parseMethod); il.Emit(OpCodes.Stfld, m_Field); } } else { throw new InvalidOperationException( String.Format( "Unable to convert string \"{0}\" into type '{1}'.", m_Value, m_Type ) ); } } } }
private void GenerateNestedType(ref GeneratorContext ctx, MethodInfo method, MethodInfo methodImpl) { int idx; lock (indexLock) { idx = index++; } TypeBuilder builder = ctx.Module.DefineType($"<>c__CacheDelegate_{method.Name}_{idx}", TypeAttributes.Class | TypeAttributes.NotPublic | TypeAttributes.AnsiClass | TypeAttributes.AutoClass | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit); builder.SetCustomAttribute(new CustomAttributeBuilder( typeof(CompilerGeneratedAttribute) #if NETSTANDARD1_6 .GetTypeInfo() #endif .GetConstructor(Type.EmptyTypes), new object[0])); // add generic parameters GenericTypeParameterBuilder[] genPar = null; if (method.IsGenericMethod) { genPar = builder.DefineGenericParameters(ctx.GenericParameterNames); for (int i = 0; i < ctx.GenericParameterNames.Length; i++) { genPar[i].SetGenericParameterAttributes(ctx.GenericArguments[i] #if NETSTANDARD1_6 .GetTypeInfo() #endif .GenericParameterAttributes); genPar[i].SetInterfaceConstraints(ctx.GenericArguments[i] #if NETSTANDARD1_6 .GetTypeInfo() #endif .GetGenericParameterConstraints()); } } //FieldBuilder asyncState = null; //FieldBuilder asyncBuilder = null; //if (isAsync) //{ // asyncState = nested.DefineField("<>1__state", typeof(int), FieldAttributes.Public); // asyncBuilder = nested.DefineField("<>t__builder", // typeof(AsyncTaskMethodBuilder<>).MakeGenericType(method.ReturnType), // FieldAttributes.Public); //} #region Generate nested fields and key array List <string> parameters = method.GetParameters() .Where(o => o.GetCustomAttribute <CacheIgnoreAttribute>() == null) .Select(o => o.Name).ToList(); parameters = methodImpl.GetParameters() .Where(o => o.GetCustomAttribute <CacheIgnoreAttribute>() == null) .Where(o => parameters.Contains(o.Name)) .Select(o => o.Name).ToList(); foreach (ParameterInfo par in method.GetParameters()) { FieldBuilder field = null; #if !NETSTANDARD1_6 if (genPar != null) { GenericTypeParameterBuilder b = genPar.SingleOrDefault(o => o.Name == par.ParameterType.Name); if (b != null) { field = builder.DefineField(par.Name, b, FieldAttributes.Public); } } #else #endif //if (field == null) field = builder.DefineField(par.Name, par.ParameterType, FieldAttributes.Public); ctx.NestedFields.Add(field); if (parameters.Contains(field.Name)) { ctx.NestedKeyFields.Add(field); } } #endregion ctx.NestedMethod = builder.DefineMethod($"<{method.Name}>b__0", MethodAttributes.Assembly | MethodAttributes.HideBySig, method.ReturnType, new[] { ctx.ServiceBase }); #region Delegate code ParameterBuilder parBuilder = ctx.NestedMethod.DefineParameter(1, ParameterAttributes.None, "svc"); ILGenerator il = ctx.NestedMethod.GetILGenerator(); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Callvirt, NonCachedMethod(ctx.ServiceBase)); foreach (FieldBuilder item in ctx.NestedFields) { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, item); } il.Emit(OpCodes.Callvirt, methodImpl); il.Emit(OpCodes.Ret); builder.DefineDefaultConstructor(MethodAttributes.Public); Type result = builder.CreateTypeInfo().AsType(); if (result #if NETSTANDARD1_6 .GetTypeInfo() #endif .IsGenericTypeDefinition) { result.MakeGenericType(method.GetGenericArguments()); } ctx.NestedType = result; #endregion }
void ICondition.Construct(TypeBuilder typeBuilder, ILGenerator il, int index) { }
public MethodInfo GetMethod(Function f) { MethodInfo result; if (_methods.TryGetValue(f, out result)) return result; var method = f as Method; if (method != null && method.IsGenericParameterization) { var md = GetMethod(method.GenericDefinition); var targs = new Type[method.GenericArguments.Length]; for (int i = 0; i < targs.Length; i++) targs[i] = GetType(method.GenericArguments[i]); result = md.MakeGenericMethod(targs); _methods.Add(f, result); return result; } var type = GetType(f.DeclaringType); if (type.IsTypeBuilder()) { if (f != f.MasterDefinition) // Should always be true result = TypeBuilder.GetMethod(type, GetMethod(f.MasterDefinition)); } else if (f is Cast) { var returnType = GetType(f.ReturnType); var operandType = GetType(f.Parameters[0].Type); foreach (var mi in type.GetMethods(_memberFlags)) { var paramList = mi.GetParameters(); if (mi.Name != "op_Explicit" && mi.Name != "op_Implicit" || paramList.Length != 1 || paramList[0].ParameterType != operandType || mi.ReturnType != returnType) continue; result = mi; break; } } else if (method != null && method.IsGenericDefinition) { foreach (var mi in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance)) { if (!mi.IsGenericMethodDefinition || mi.Name != method.UnoName) continue; var paramList = mi.GetParameters(); if (paramList.Length != method.Parameters.Length) continue; var typeParams = mi.GetGenericMethodDefinition().GetGenericArguments(); if (typeParams.Length != method.GenericParameters.Length) continue; // TODO: Avoid copying types var oldTypes = new Dictionary<DataType, Type>(); foreach (var e in _types) oldTypes.Add(e.Key, e.Value); for (int i = 0; i < typeParams.Length; i++) _types[method.GenericParameters[i]] = typeParams[i]; if (GetType(method.ReturnType) == mi.ReturnType && ParameterTypesEquals(mi.GetParameters(), GetParameterTypes(method.Parameters))) { result = mi; break; } // Not found - reset types _types.Clear(); foreach (var e in oldTypes) _types.Add(e.Key, e.Value); } } else { var name = f.UnoName; if (type == System_String) switch (name) { case "get_Item": name = "get_Chars"; break; case "op_Addition": name = "Concat"; break; } var paramTypes = GetParameterTypes(f.Parameters); try { result = type.GetMethod(name, _memberFlags, _binder, paramTypes, null); if (result == null && method != null) { if (method.ImplementedMethod != null) TryGetImplementedMethod(type, method.ImplementedMethod.Name, paramTypes, out result); else TryGetInterfaceMethod(type, name, paramTypes, out result); } } catch (ArgumentException e) { ThrowPrebuiltSignatureException(e, f, f.Parameters, paramTypes); } } if (result == null) throw new FatalException(f.Source, ErrorCode.E0000, ".NET method not resolved: " + f + " [flags: " + f.Stats + "]"); _methods.Add(f, result); return result; }
public override void Construct(TypeBuilder typeBuilder, ILGenerator il, int index) { m_Value.Acquire(typeBuilder, il, "v" + index); }
public static void OrElse_NoMethod_TrueOperatorIncorrectMethod_ThrowsArgumentException(TypeBuilder builder, Type returnType, Type[] parameterTypes) { MethodBuilder opTrue = builder.DefineMethod("op_True", MethodAttributes.SpecialName | MethodAttributes.Static, returnType, parameterTypes); opTrue.GetILGenerator().Emit(OpCodes.Ret); MethodBuilder opFalse = builder.DefineMethod("op_False", MethodAttributes.SpecialName | MethodAttributes.Static, typeof(bool), new Type[] { builder.AsType() }); opFalse.GetILGenerator().Emit(OpCodes.Ret); MethodBuilder method = builder.DefineMethod("op_BitwiseOr", MethodAttributes.Public | MethodAttributes.Static, builder.AsType(), new Type[] { builder.AsType(), builder.AsType() }); method.GetILGenerator().Emit(OpCodes.Ret); TypeInfo createdType = builder.CreateTypeInfo(); object obj = Activator.CreateInstance(createdType.AsType()); Assert.Throws <ArgumentException>(null, () => Expression.OrElse(Expression.Constant(obj), Expression.Constant(obj))); }
public abstract void Construct(TypeBuilder typeBuilder, ILGenerator il, int index);
private unsafe static void OverrideDynamicInvokeImpl(TypeBuilder delegateBuilder, MethodInfo invokeMethod, Type[] parameterTypes, Type resultType) { var dynamicInvokeMethodBuilder = delegateBuilder.DefineMethod( "DynamicInvokeImpl", MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.Virtual, CallingConventions.Standard, typeof(object), new Type[] { typeof(object[]) }); var iLGen = dynamicInvokeMethodBuilder.GetILGenerator(); iLGen.LoadArgument(0); for (int i = 0; i < parameterTypes.Length; i++) { var item = parameterTypes[i]; iLGen.LoadArgument(1); iLGen.LoadConstant(i); if (item.IsByRef) { item = item.GetElementType(); iLGen.LoadReferenceElement(); iLGen.CastClass(item); if (item.IsValueType) { iLGen.LoadConstant(sizeof(IntPtr)); iLGen.Add(); continue; } iLGen.Pop(); iLGen.LoadArgument(1); iLGen.LoadConstant(i); iLGen.LoadElementAddress(typeof(object)); continue; } iLGen.LoadReferenceElement(); iLGen.CastClass(item); if (item.IsValueType) { iLGen.UnboxAny(item); } } iLGen.Call(invokeMethod); if (resultType == typeof(void)) { iLGen.LoadNull(); } else if (resultType.IsValueType) { iLGen.Box(resultType); } iLGen.Return(); }
private unsafe static void ImplObjectInterface(TypeBuilder delegateBuilder, MethodInfo invokeMethod, Type[] parameterTypes, Type resultType) { bool isAllEqualObject = true; foreach (var item in parameterTypes) { if (item != typeof(object)) { isAllEqualObject = false; break; } } if (isAllEqualObject) { return; } Type[] objectTypes = new Type[parameterTypes.Length]; for (int i = 0; i < objectTypes.Length; i++) { objectTypes[i] = typeof(object); } Type interfaceType; if (resultType == typeof(void)) { if (parameterTypes.Length >= ActionInterfaces.Length) { return; } interfaceType = ActionInterfaces[parameterTypes.Length]; if (interfaceType.IsGenericTypeDefinition) { interfaceType = interfaceType.MakeGenericType(objectTypes); } } else { if (parameterTypes.Length >= FuncInterfaces.Length) { return; } interfaceType = FuncInterfaces[parameterTypes.Length]; if (interfaceType.IsGenericTypeDefinition) { var genericTypes = objectTypes; Array.Resize(ref genericTypes, objectTypes.Length + 1); genericTypes[objectTypes.Length] = typeof(object); interfaceType = interfaceType.MakeGenericType(genericTypes); } } delegateBuilder.AddInterfaceImplementation(interfaceType); var interfaceInvoke = interfaceType.GetMethod("Invoke"); var invokeBuilder = delegateBuilder.DefineMethod( "InvokeImpl", MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions.Standard, interfaceInvoke.ReturnType, objectTypes); var iLGen = invokeBuilder.GetILGenerator(); iLGen.LoadArgument(0); for (int i = 0; i < parameterTypes.Length; ++i) { var item = parameterTypes[i]; iLGen.LoadArgument(i + 1); if (item.IsByRef) { item = typeof(IntPtr); } iLGen.CastClass(item); if (item.IsValueType) { iLGen.UnboxAny(item); } } iLGen.Call(invokeMethod); if (resultType.IsValueType) { iLGen.Box(resultType); } iLGen.Return(); delegateBuilder.DefineMethodOverride(invokeBuilder, interfaceInvoke); }
static void DefineUnaryRequestDelegate(ILGenerator staticContructorGenerator, TypeBuilder typeBuilder, Type interfaceType, MethodDefinition definition) { // static ResponseContext _Method(RequestContext context); MethodBuilder method; { method = typeBuilder.DefineMethod("_" + definition.MethodInfo.Name, MethodAttributes.Private | MethodAttributes.Static, typeof(ResponseContext), new[] { typeof(RequestContext) }); var il = method.GetILGenerator(); // CreateResponseContext<TRequest, TResponse>(Context, Method); var createMethod = typeof(MagicOnionClientBase) .GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static) .Where(x => x.Name == "CreateResponseContext") .OrderByDescending(x => x.GetGenericArguments().Length) .First() .MakeGenericMethod(definition.RequestType, definition.ResponseType); il.Emit(OpCodes.Ldarg_0); // context il.Emit(OpCodes.Ldsfld, definition.FieldMethod); // method il.Emit(OpCodes.Call, createMethod); il.Emit(OpCodes.Ret); } // static readonly Func<RequestContext, ResposneContext> methodDelegate = _Method; { definition.UnaryRequestDelegate = typeBuilder.DefineField(definition.MethodInfo.Name + "Delegate", typeof(Func <RequestContext, ResponseContext>), FieldAttributes.Private | FieldAttributes.Static); var il = staticContructorGenerator; il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Ldftn, method); il.Emit(OpCodes.Newobj, typeof(Func <RequestContext, ResponseContext>).GetConstructors()[0]); il.Emit(OpCodes.Stsfld, definition.UnaryRequestDelegate); } }
private static void ImplInstanceDynamicImpl(TypeBuilder delegateBuilder, MethodInfo invokeMethod, Type[] parameterTypes, Type resultType) { if (!(parameterTypes.Length != 0 && // Must one or more Parameters. (parameterTypes[0].IsClass || parameterTypes[0].IsInterface || // First Parameter Is Class Or Interface. (parameterTypes[0].IsByRef && parameterTypes[0].GetElementType().IsValueType) // Or First Parameter Is ValueType Ref. ))) { return; } GetParametersTypes(Method_IInstanceDynamicInvoker_Invoke, out var invokerParameterTypes, out var invokerReturnType, true); delegateBuilder.AddInterfaceImplementation(Type_IInstanceDynamicInvoker); var dynamicInvokeMethodBuilder = delegateBuilder.DefineMethod( "DynamicInvokeImpl", MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.Virtual, CallingConventions.Standard, invokerReturnType, invokerParameterTypes); var iLGen = dynamicInvokeMethodBuilder.GetILGenerator(); iLGen.LoadArgument(0); iLGen.LoadArgument(1); for (int i = 1; i < parameterTypes.Length; i++) { var item = parameterTypes[i]; iLGen.LoadArgument(2); iLGen.LoadConstant(i - 1); iLGen.LoadReferenceElement(); if (item.IsByRef) { item = item.GetElementType(); iLGen.CastClass(item); if (item.IsValueType) { iLGen.Call(Method_GetStructRef); continue; } iLGen.Pop(); iLGen.LoadArgument(2); iLGen.LoadConstant(i - 1); iLGen.LoadElementAddress(typeof(object)); continue; } if (item.IsValueType) { iLGen.UnboxAny(item); } } iLGen.Call(invokeMethod); if (resultType == typeof(void)) { iLGen.LoadNull(); } else if (resultType.IsValueType) { iLGen.Box(resultType); } iLGen.Return(); delegateBuilder.DefineMethodOverride(dynamicInvokeMethodBuilder, Method_IInstanceDynamicInvoker_Invoke); }