internal FieldGen(TypeGen owner, string name, Type type, FieldAttributes attrs) { _owner = owner; _attrs = attrs; Name = name; _type = type; _fb = owner.TypeBuilder.DefineField(name, type, attrs); owner.RegisterForCompletion(this); }
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 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> /// 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, List<Type> Parameters) : base() { if (TypeBuilder == null) throw new ArgumentNullException("TypeBuilder"); if (string.IsNullOrEmpty(Name)) throw new ArgumentNullException("Name"); this.Name = Name; this.Type = TypeBuilder; this.Attributes = Attributes; this.GetMethodAttributes = GetMethodAttributes; this.SetMethodAttributes = SetMethodAttributes; this.DataType = PropertyType; this.Parameters = new List<ParameterBuilder>(); if (Parameters != null) { int x = 1; foreach (Type Parameter in Parameters) { this.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); List<Type> SetParameters = new List<System.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); }
// TODO: REMOVE breaks mutator public void Emit (OpCode opcode, FieldBuilder field) { ig.Emit (opcode, field); }
private static void DuplicateMethods(TypeBuilder typeBuilder, Type target, FieldBuilder fb, SharedClass sharedClass) { foreach (MethodInfo m in target.GetMethods()) { /*if ((m.GetCustomAttributes(typeof(RemoteExecutionAttribute), false).Length == 0 && * m.GetCustomAttributes(typeof(UncheckedRemoteExecutionAttribute), false).Length == 0) && * m.Name != "Dispose") * { * continue; * }*/ Type[] ArgumentTypes = GetParameterTypes(m.GetParameters()); MethodBuilder builder = typeBuilder.DefineMethod(m.Name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, m.CallingConvention, m.ReturnType, ArgumentTypes); typeBuilder.DefineMethodOverride(builder, m); //builder.CreateMethodBody(null, 0); ILGenerator gen = builder.GetILGenerator(); MethodInfo SharedCall = typeof(SharedClass).GetMethod("Invoke", new Type[] { typeof(int), typeof(object[]) }); SharedMethod sharedMethod = sharedClass.GetMethod(m.Name, ArgumentTypes); LocalBuilder lb = gen.DeclareLocal(typeof(object[])); //load $haredClass gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldfld, fb); gen.Emit(OpCodes.Ldc_I4, sharedMethod.MethodId); //gen.Emit(OpCodes.Ldstr, m.Name); //init local array gen.Emit(OpCodes.Ldc_I4, ArgumentTypes.Length); gen.Emit(OpCodes.Newarr, typeof(object)); gen.Emit(OpCodes.Stloc_0); for (int i = 0; i < ArgumentTypes.Length; i++) { gen.Emit(OpCodes.Ldloc_0); gen.Emit(OpCodes.Ldc_I4, i); gen.Emit(OpCodes.Ldarg, i + 1); if (ArgumentTypes[i].IsByRef) { //remove & at the end since ref/out adds & at the end of the argument ArgumentTypes[i] = Type.GetType(ArgumentTypes[i].FullName.Substring(0, ArgumentTypes[i].FullName.Length - 1)); } gen.Emit(OpCodes.Box, ArgumentTypes[i]); gen.Emit(OpCodes.Stelem_Ref); } gen.Emit(OpCodes.Ldloc_0); gen.Emit(OpCodes.Callvirt, SharedCall); bool isInt = m.ReturnType.IsAssignableFrom(typeof(System.Int32)) || m.ReturnType.IsAssignableFrom(typeof(System.UInt32)) || m.ReturnType.IsAssignableFrom(typeof(System.Boolean)) || m.ReturnType.IsAssignableFrom(typeof(System.Int64)) || m.ReturnType.IsAssignableFrom(typeof(System.UInt64)); if (m.ReturnType.FullName != "System.Void" && !isInt) { gen.Emit(OpCodes.Box, m.ReturnType); } else if (m.ReturnType.FullName == "System.Void") //no return { gen.Emit(OpCodes.Pop); } else if (isInt) { gen.Emit(OpCodes.Unbox, m.ReturnType); gen.Emit(OpCodes.Ldobj, m.ReturnType); } gen.Emit(OpCodes.Ret); } }
/// <summary> /// Compiles a dependency graph into an IOC container. /// </summary> /// <param name="dependencyContainer">The <see cref="IDependencyContainer"/> instance that contains the services that will be instantiated by compiled container.</param> /// <param name="typeName">The name of the <see cref="IMicroContainer"/> type.</param> /// <param name="namespaceName">The namespace name that will be associated with the container type.</param> /// <param name="assemblyName">The name of the assembly that will contain the container type.</param> /// <returns>An assembly containing the compiled IOC container.</returns> public AssemblyDefinition Compile(string typeName, string namespaceName, string assemblyName, IDependencyContainer dependencyContainer) { var containerType = _createContainerType.CreateContainerType(typeName, namespaceName, assemblyName); var module = containerType.Module; var assembly = module.Assembly; var hashEmitter = new ServiceHashEmitter(); var getServiceHash = hashEmitter.AddGetServiceHashMethodTo(containerType, false); var fieldType = module.Import(typeof(Dictionary<int, int>)); var fieldEmitter = new FieldBuilder(); var jumpTargetField = fieldEmitter.AddField(containerType, "__jumpTargets", fieldType); var serviceMap = _serviceMapBuilder.GetAvailableServices(dependencyContainer); var jumpTargets = new Dictionary<IDependency, int>(); // Map the switch labels in the default constructor AddJumpEntries(module, jumpTargetField, containerType, getServiceHash, serviceMap, jumpTargets); var defaultConstructor = containerType.GetDefaultConstructor(); var body = defaultConstructor.Body; var il = body.GetILProcessor(); AddInitializationMap(containerType, module, fieldEmitter); InitializeContainerPlugins(module, dependencyContainer, il); il.Emit(OpCodes.Ret); _containsMethodImplementor.DefineContainsMethod(containerType, module, getServiceHash, jumpTargetField); _getInstanceMethodImplementor.DefineGetInstanceMethod(containerType, module, getServiceHash, jumpTargetField, serviceMap); _getAllInstancesMethodImplementor.DefineGetAllInstancesMethod(containerType, module, serviceMap); // Remove the NextContainer property stub var targetMethods = new List<MethodDefinition>(); foreach (MethodDefinition method in containerType.Methods) { var methodName = method.Name; if (methodName == "get_NextContainer" || methodName == "set_NextContainer") targetMethods.Add(method); } targetMethods.ForEach(m => containerType.Methods.Remove(m)); // Add the NextContainer property containerType.AddProperty("NextContainer", typeof(IMicroContainer)); return assembly; }
public void SetConstant_CustomObject() { FieldBuilder field = s_type.DefineField("CustomObjectField", typeof(FieldBuilderSetConstant), FieldAttributes.Public); field.SetConstant(null); }
public void SetConstant_InvalidType_ThrowsArgumentException(FieldBuilder field, object defaultValue) { AssertExtensions.Throws <ArgumentException>(null, () => field.SetConstant(defaultValue)); }
void EmitFieldSize(int buffer_size) { int type_size = BuiltinTypeSpec.GetSize(MemberType); if (buffer_size > int.MaxValue / type_size) { Report.Error(1664, Location, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit", GetSignatureForError(), buffer_size.ToString(), TypeManager.CSharpName(MemberType)); return; } AttributeEncoder encoder; var ctor = Module.PredefinedMembers.StructLayoutAttributeCtor.Resolve(Location); if (ctor == null) { return; } var field_size = Module.PredefinedMembers.StructLayoutSize.Resolve(Location); var field_charset = Module.PredefinedMembers.StructLayoutCharSet.Resolve(Location); if (field_size == null || field_charset == null) { return; } var char_set = CharSet ?? Module.DefaultCharSet ?? 0; encoder = new AttributeEncoder(); encoder.Encode((short)LayoutKind.Sequential); encoder.EncodeNamedArguments( new [] { field_size, field_charset }, new Constant [] { new IntConstant(Compiler.BuiltinTypes, buffer_size * type_size, Location), new IntConstant(Compiler.BuiltinTypes, (int)char_set, Location) } ); fixed_buffer_type.SetCustomAttribute((ConstructorInfo)ctor.GetMetaInfo(), encoder.ToArray()); // // Don't emit FixedBufferAttribute attribute for private types // if ((ModFlags & Modifiers.PRIVATE) != 0) { return; } ctor = Module.PredefinedMembers.FixedBufferAttributeCtor.Resolve(Location); if (ctor == null) { return; } encoder = new AttributeEncoder(); encoder.EncodeTypeName(MemberType); encoder.Encode(buffer_size); encoder.EncodeEmptyNamedArguments(); FieldBuilder.SetCustomAttribute((ConstructorInfo)ctor.GetMetaInfo(), encoder.ToArray()); }
private void WriteGetKeyImpl(TypeBuilder type, bool hasInheritance, SerializerPair[] methodPairs, Compiler.CompilerContext.ILVersion ilVersion, string assemblyName, out ILGenerator il, out int knownTypesCategory, out FieldBuilder knownTypes, out Type knownTypesLookupType) { il = Override(type, "GetKeyImpl"); Compiler.CompilerContext ctx = new Compiler.CompilerContext(il, false, false, methodPairs, this, ilVersion, assemblyName, MapType(typeof(System.Type), true)); if (types.Count <= KnownTypes_ArrayCutoff) { knownTypesCategory = KnownTypes_Array; knownTypesLookupType = MapType(typeof(System.Type[]), true); } else { #if NO_GENERICS knownTypesLookupType = null; #else knownTypesLookupType = MapType(typeof(System.Collections.Generic.Dictionary<System.Type, int>), false); #endif if (knownTypesLookupType == null) { knownTypesLookupType = MapType(typeof(Hashtable), true); knownTypesCategory = KnownTypes_Hashtable; } else { knownTypesCategory = KnownTypes_Dictionary; } } knownTypes = type.DefineField("knownTypes", knownTypesLookupType, FieldAttributes.Private | FieldAttributes.InitOnly | FieldAttributes.Static); switch (knownTypesCategory) { case KnownTypes_Array: { il.Emit(OpCodes.Ldsfld, knownTypes); il.Emit(OpCodes.Ldarg_1); // note that Array.IndexOf is not supported under CF il.EmitCall(OpCodes.Callvirt, MapType(typeof(IList)).GetMethod( "IndexOf", new Type[] { MapType(typeof(object)) }), null); if (hasInheritance) { il.DeclareLocal(MapType(typeof(int))); // loc-0 il.Emit(OpCodes.Dup); il.Emit(OpCodes.Stloc_0); BasicList getKeyLabels = new BasicList(); int lastKey = -1; for (int i = 0; i < methodPairs.Length; i++) { if (methodPairs[i].MetaKey == methodPairs[i].BaseKey) break; if (lastKey == methodPairs[i].BaseKey) { // add the last label again getKeyLabels.Add(getKeyLabels[getKeyLabels.Count - 1]); } else { // add a new unique label getKeyLabels.Add(ctx.DefineLabel()); lastKey = methodPairs[i].BaseKey; } } Compiler.CodeLabel[] subtypeLabels = new Compiler.CodeLabel[getKeyLabels.Count]; getKeyLabels.CopyTo(subtypeLabels, 0); ctx.Switch(subtypeLabels); il.Emit(OpCodes.Ldloc_0); // not a sub-type; use the original value il.Emit(OpCodes.Ret); lastKey = -1; // now output the different branches per sub-type (not derived type) for (int i = subtypeLabels.Length - 1; i >= 0; i--) { if (lastKey != methodPairs[i].BaseKey) { lastKey = methodPairs[i].BaseKey; // find the actual base-index for this base-key (i.e. the index of // the base-type) int keyIndex = -1; for (int j = subtypeLabels.Length; j < methodPairs.Length; j++) { if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey) { keyIndex = j; break; } } ctx.MarkLabel(subtypeLabels[i]); Compiler.CompilerContext.LoadValue(il, keyIndex); il.Emit(OpCodes.Ret); } } } else { il.Emit(OpCodes.Ret); } } break; case KnownTypes_Dictionary: { LocalBuilder result = il.DeclareLocal(MapType(typeof(int))); Label otherwise = il.DefineLabel(); il.Emit(OpCodes.Ldsfld, knownTypes); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldloca_S, result); il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetMethod("TryGetValue", BindingFlags.Instance | BindingFlags.Public), null); il.Emit(OpCodes.Brfalse_S, otherwise); il.Emit(OpCodes.Ldloc_S, result); il.Emit(OpCodes.Ret); il.MarkLabel(otherwise); il.Emit(OpCodes.Ldc_I4_M1); il.Emit(OpCodes.Ret); } break; case KnownTypes_Hashtable: { Label otherwise = il.DefineLabel(); il.Emit(OpCodes.Ldsfld, knownTypes); il.Emit(OpCodes.Ldarg_1); il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetProperty("Item").GetGetMethod(), null); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Brfalse_S, otherwise); #if FX11 il.Emit(OpCodes.Unbox, MapType(typeof(int))); il.Emit(OpCodes.Ldobj, MapType(typeof(int))); #else if (ilVersion == Compiler.CompilerContext.ILVersion.Net1) { il.Emit(OpCodes.Unbox, MapType(typeof(int))); il.Emit(OpCodes.Ldobj, MapType(typeof(int))); } else { il.Emit(OpCodes.Unbox_Any, MapType(typeof(int))); } #endif il.Emit(OpCodes.Ret); il.MarkLabel(otherwise); il.Emit(OpCodes.Pop); il.Emit(OpCodes.Ldc_I4_M1); il.Emit(OpCodes.Ret); } break; default: throw new InvalidOperationException(); } }
public static T Import <T>(INativeLibImporter importer, string libName, string version, bool suppressUnload) where T : class { var subdir = GetArchName(RuntimeInformation.ProcessArchitecture); var assemblyName = new AssemblyName("DynamicLink"); var assemblyBuilder = CurrentFramework.DefineDynamicAssembly(assemblyName, System.Reflection.Emit.AssemblyBuilderAccess.Run); var moduleBuilder = assemblyBuilder.DefineDynamicModule("DynLinkModule"); string typeName = typeof(T).Name + "_impl"; var typeBuilder = moduleBuilder.DefineType(typeName, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, typeof(T)); FieldBuilder field_importer = typeBuilder.DefineField("importer", typeof(INativeLibImporter), FieldAttributes.Private | FieldAttributes.InitOnly); FieldBuilder field_libraryHandle = typeBuilder.DefineField("libraryHandle", typeof(IntPtr), FieldAttributes.Private | FieldAttributes.InitOnly); var methods = typeof(T).GetTypeInfo().GetMethods(BindingFlags.Public | BindingFlags.Instance).Where(m => m.IsAbstract && !m.IsGenericMethod).ToArray(); // Define delegate types for each of the method signatures var delegateMap = new Dictionary <string, Type>(); foreach (var method in methods) { var sig = GetMethodSig(method); if (delegateMap.ContainsKey(sig)) { continue; } var delegateTypeInfo = CreateDelegateType(moduleBuilder, method); delegateMap.Add(sig, delegateTypeInfo.AsType()); } // Define one field for each method to hold a delegate var delegates = methods.Select(m => new { MethodInfo = m, DelegateType = delegateMap[GetMethodSig(m)], }).ToArray(); var fields = delegates.Select((d, i) => typeBuilder.DefineField($"{d.MethodInfo.Name}_func_{i}", d.DelegateType, FieldAttributes.Private)).ToArray(); // Create the constructor which will initialize the importer and library handle // and also use the importer to populate each of the delegate fields ConstructorBuilder constructor = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, CallingConventions.Standard, new Type[] { typeof(INativeLibImporter), typeof(IntPtr) }); { var baseConstructor = typeof(T).GetTypeInfo().GetConstructors().Where(con => con.GetParameters().Length == 0).First(); ILGenerator il = constructor.GetILGenerator(); // Call base constructor il.Emit(OpCodes.Ldarg_0); // this il.Emit(OpCodes.Call, baseConstructor); // Store importer field il.Emit(OpCodes.Ldarg_0); // this il.Emit(OpCodes.Ldarg_1); // importer il.Emit(OpCodes.Stfld, field_importer); // Load and store library handle il.Emit(OpCodes.Ldarg_0); // this il.Emit(OpCodes.Ldarg_2); // library handle il.Emit(OpCodes.Stfld, field_libraryHandle); var getDelegateMethod = typeof(INativeLibImporter).GetTypeInfo().GetMethod("GetDelegate"); // Initialize each delegate field for (int i = 0; i < fields.Length; i++) { var delegateType = delegates[i].DelegateType; il.Emit(OpCodes.Ldarg_0); // this il.Emit(OpCodes.Ldarg_1); // importer il.Emit(OpCodes.Ldarg_0); // this il.Emit(OpCodes.Ldfld, field_libraryHandle); il.Emit(OpCodes.Ldstr, delegates[i].MethodInfo.Name); // use method name from original class as entry point il.Emit(OpCodes.Ldtoken, delegateType); // the delegate type il.Emit(OpCodes.Call, typeof(System.Type).GetTypeInfo().GetMethod("GetTypeFromHandle")); // typeof() il.Emit(OpCodes.Callvirt, getDelegateMethod); // importer.GetDelegate() il.Emit(OpCodes.Isinst, delegateType); // as <delegate type> il.Emit(OpCodes.Stfld, fields[i]); } // End of constructor il.Emit(OpCodes.Ret); } // Create destructor var destructor = typeBuilder.DefineMethod("Finalize", MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig); { var baseDestructor = typeof(T).GetTypeInfo().GetMethod("Finalize", BindingFlags.NonPublic | BindingFlags.Instance); var il = destructor.GetILGenerator(); var end = il.DefineLabel(); il.BeginExceptionBlock(); if (!suppressUnload) { il.Emit(OpCodes.Ldarg_0); // this il.Emit(OpCodes.Ldfld, field_importer); // .importer il.Emit(OpCodes.Ldarg_0); // this il.Emit(OpCodes.Ldfld, field_libraryHandle); // .libraryHandle il.Emit(OpCodes.Callvirt, typeof(INativeLibImporter).GetTypeInfo().GetMethod("FreeLibrary")); // INativeLibImporter::FreeLibrary() } //il.Emit(OpCodes.Leave, end); il.BeginFinallyBlock(); il.Emit(OpCodes.Ldarg_0); // this il.Emit(OpCodes.Call, baseDestructor); // object::Finalize() //il.Emit(OpCodes.Endfinally); il.EndExceptionBlock(); il.MarkLabel(end); il.Emit(OpCodes.Ret); } // Now override each method from the base class for (int i = 0; i < fields.Length; i++) { var baseMethod = delegates[i].MethodInfo; var args = baseMethod.GetParameters(); var omethod = typeBuilder.DefineMethod( baseMethod.Name, (baseMethod.Attributes & ~(MethodAttributes.Abstract | MethodAttributes.NewSlot)) | MethodAttributes.Virtual, baseMethod.CallingConvention, baseMethod.ReturnType, args.Select(arg => arg.ParameterType).ToArray() ); var il = omethod.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); // this il.Emit(OpCodes.Ldfld, fields[i]); // {field} if (args.Length >= 1) { il.Emit(OpCodes.Ldarg_1); } if (args.Length >= 2) { il.Emit(OpCodes.Ldarg_2); } if (args.Length >= 3) { il.Emit(OpCodes.Ldarg_3); } for (short argNum = 4; argNum <= args.Length; argNum++) { il.Emit(OpCodes.Ldarg_S, argNum); } il.Emit(OpCodes.Tailcall); il.Emit(OpCodes.Callvirt, delegates[i].DelegateType.GetTypeInfo().GetMethod("Invoke")); il.Emit(OpCodes.Ret); } var type = typeBuilder.CreateTypeInfo(); var versionParts = version.Split('.'); var names = versionParts.Select((p, i) => libName + "-" + string.Join(".", versionParts.Take(i + 1))) .Reverse() .Concat(Enumerable.Repeat(libName, 1)); // try to load locally var paths = new[] { Path.Combine("native", subdir), "native", subdir, "", }; // If the RocksDbNative package is referenced, then dynamically load it here so that it can tell us where the native libraries are string nativeCodeBase = null; try { var nativeLibName = new AssemblyName("RocksDbNative"); var native = Assembly.Load(nativeLibName); var nativePkgClass = native.GetTypes().First(t => t.FullName == "RocksDbSharp.NativePackage"); var getCodeBaseMethod = nativePkgClass.GetTypeInfo().GetMethod("GetCodeBase"); var getCodeBase = getCodeBaseMethod.CreateDelegate <Func <string> >(); nativeCodeBase = getCodeBase(); } catch (Exception) { } var basePaths = new string[] { nativeCodeBase, Path.GetDirectoryName(UriToPath(Transitional.CurrentFramework.GetBaseDirectory())), Path.GetDirectoryName(UriToPath(Assembly.GetEntryAssembly()?.CodeBase)), Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location), Path.GetDirectoryName(UriToPath(typeof(PosixImporter).GetTypeInfo().Assembly.CodeBase)), Path.GetDirectoryName(typeof(PosixImporter).GetTypeInfo().Assembly.Location), }; var search = basePaths .Where(p => p != null) .Distinct() .SelectMany(basePath => paths.SelectMany(path => names.Select(n => Path.Combine(basePath, path, importer.Translate(n)))) .Concat(names.Select(n => importer.Translate(n))) ) .Select(path => new SearchPath { Path = path }) .ToArray(); foreach (var spec in search) { var construct = type.GetConstructor(new Type[] { typeof(INativeLibImporter), typeof(IntPtr) }); IntPtr lib = IntPtr.Zero; try { lib = importer.LoadLibrary(spec.Path); if (lib == IntPtr.Zero) { throw new NativeLoadException("LoadLibrary returned 0", null); } } catch (TargetInvocationException tie) { spec.Error = tie.InnerException; continue; } catch (Exception e) { spec.Error = e; continue; } var obj = construct.Invoke(new object[] { importer, lib }); var t = obj as T; return(t); } throw new NativeLoadException("Unable to locate rocksdb native library, either install it, or use RocksDbNative nuget package\nSearched:\n" + string.Join("\n", search.Select(s => $"{s.Path}: ({s.Error.GetType().Name}) {s.Error.Message}")), null); }
/// <summary> /// Modifies the default constructor to initialize the "__initializedServices" field so that it can ensure that all /// services called with the <see cref="IInitialize.Initialize"/> are initialized once per object lifetime. /// </summary> /// <param name="containerType">The container type.</param> /// <param name="module">The module.</param> /// <param name="fieldEmitter">The field builder.</param> private void AddInitializationMap(TypeDefinition containerType, ModuleDefinition module, FieldBuilder fieldEmitter) { var initializationMapType = module.Import(typeof(Dictionary <int, int>)); var initializationMapField = new FieldDefinition("__initializedServices", FieldAttributes.Private | FieldAttributes.InitOnly, initializationMapType); containerType.Fields.Add(initializationMapField); var defaultConstructor = containerType.GetDefaultConstructor(); var body = defaultConstructor.Body; // __initializedServices = new Dictionary<int, int>(); var il = body.GetILProcessor(); var dictionaryCtor = module.ImportConstructor <Dictionary <int, int> >(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Newobj, dictionaryCtor); il.Emit(OpCodes.Stfld, initializationMapField); }
//TODO this might create cycle references private List <Type> EmitTypes(string AssemblyName, IEnumerable <BusinessObjectExtension> businessObjectExtensions) { List <Type> DynamicTypes = new List <Type>(); var baseType = typeof(BaseObject); var baseConstructor = baseType.GetConstructor(BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Instance, null, new Type[] { typeof(Session) }, null); // Create a Type Builder that generates a type directly into the current AppDomain. var appDomain = AppDomain.CurrentDomain; var assemblyName = new AssemblyName(AssemblyName); var assemblyBuilder = appDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave); var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name); foreach (BusinessObjectExtension businessObjectExtension in businessObjectExtensions) { var typeBuilder = moduleBuilder.DefineType(businessObjectExtension.Name, TypeAttributes.Class | TypeAttributes.Public, baseType); CreateConstructor(baseConstructor, typeBuilder); foreach (BusinessObjectField businessObjectField in businessObjectExtension.BusinessObjectFields) { var PropertyType = this.GetTypeByTypeCode(businessObjectField.PrimitiveType); FieldBuilder fbNumber = typeBuilder.DefineField( $"_{businessObjectField.Name}", PropertyType, FieldAttributes.Private); PropertyBuilder Property = typeBuilder.DefineProperty( $"{businessObjectField.Name}", PropertyAttributes.HasDefault, PropertyType, null); // The property "set" and property "get" methods require a special // set of attributes. MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; // Define the "get" accessor method for Number. The method returns // an integer and has no arguments. (Note that null could be // used instead of Types.EmptyTypes) MethodBuilder PropertyGet = typeBuilder.DefineMethod( $"get_{businessObjectField.Name}", getSetAttr, PropertyType, Type.EmptyTypes); ILGenerator numberGetIL = PropertyGet.GetILGenerator(); // For an instance property, argument zero is the instance. Load the // instance, then load the private field and return, leaving the // field value on the stack. numberGetIL.Emit(OpCodes.Ldarg_0); numberGetIL.Emit(OpCodes.Ldfld, fbNumber); numberGetIL.Emit(OpCodes.Ret); // Define the "set" accessor method for Number, which has no return // type and takes one argument of type int (Int32). MethodBuilder PropertySet = typeBuilder.DefineMethod( $"set_{businessObjectField.Name}", getSetAttr, null, new Type[] { PropertyType }); ILGenerator numberSetIL = PropertySet.GetILGenerator(); // Load the instance and then the numeric argument, then store the // argument in the field. numberSetIL.Emit(OpCodes.Ldarg_0); numberSetIL.Emit(OpCodes.Ldarg_1); numberSetIL.Emit(OpCodes.Stfld, fbNumber); numberSetIL.Emit(OpCodes.Ret); // Last, map the "get" and "set" accessor methods to the // PropertyBuilder. The property is now complete. Property.SetGetMethod(PropertyGet); Property.SetSetMethod(PropertySet); } DynamicTypes.Add(typeBuilder.CreateType()); } assemblyBuilder.Save(assemblyName.Name + ".dll"); return(DynamicTypes); }
/// <summary> /// /// </summary> /// <param name="types"></param> /// <param name="names"></param> /// <returns></returns> public static Type CreateType(Type[] types, string[] names) { if (types == null) { throw new ArgumentNullException("types"); } if (names == null) { throw new ArgumentNullException("names"); } if (types.Length != names.Length) { throw new ArgumentException("names"); } // Anonymous classes are generics based. The generic classes // are distinguished by number of parameters and name of // parameters. The specific types of the parameters are the // generic arguments. We recreate this by creating a fullName // composed of all the property names, separated by a "|" string fullName = string.Join("|", names.Select(x => Escape(x))); Type type; if (!GeneratedTypes.TryGetValue(fullName, out type)) { // We create only a single class at a time, through this lock // Note that this is a variant of the double-checked locking. // It is safe because we are using a thread safe class. lock (GeneratedTypes) { if (!GeneratedTypes.TryGetValue(fullName, out type)) { int index = Interlocked.Increment(ref Index); string name = names.Length != 0 ? string.Format("<>f__AnonymousType{0}`{1}", index, names.Length) : string.Format("<>f__AnonymousType{0}", index); TypeBuilder tb = ModuleBuilder.DefineType(name, TypeAttributes.AnsiClass | TypeAttributes.Class | TypeAttributes.AutoLayout | TypeAttributes.NotPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit); tb.SetCustomAttribute(CompilerGeneratedAttributeBuilder); GenericTypeParameterBuilder[] generics = null; if (names.Length != 0) { string[] genericNames = Array.ConvertAll(names, x => string.Format("<{0}>j__TPar", x)); generics = tb.DefineGenericParameters(genericNames); } else { generics = new GenericTypeParameterBuilder[0]; } // .ctor ConstructorBuilder constructor = tb.DefineConstructor(MethodAttributes.Public | MethodAttributes.HideBySig, CallingConventions.HasThis, generics); constructor.SetCustomAttribute(DebuggerHiddenAttributeBuilder); ILGenerator ilgeneratorConstructor = constructor.GetILGenerator(); ilgeneratorConstructor.Emit(OpCodes.Ldarg_0); ilgeneratorConstructor.Emit(OpCodes.Call, ObjectCtor); var fields = new FieldBuilder[names.Length]; // There are two for cycles because we want to have // all the getter methods before all the other // methods for (int i = 0; i < names.Length; i++) { // field fields[i] = tb.DefineField(string.Format("<{0}>i__Field", names[i]), generics[i], FieldAttributes.Private | FieldAttributes.InitOnly); fields[i].SetCustomAttribute(DebuggerBrowsableAttributeBuilder); // .ctor constructor.DefineParameter(i + 1, ParameterAttributes.None, names[i]); ilgeneratorConstructor.Emit(OpCodes.Ldarg_0); if (i == 0) { ilgeneratorConstructor.Emit(OpCodes.Ldarg_1); } else if (i == 1) { ilgeneratorConstructor.Emit(OpCodes.Ldarg_2); } else if (i == 2) { ilgeneratorConstructor.Emit(OpCodes.Ldarg_3); } else if (i < 255) { ilgeneratorConstructor.Emit(OpCodes.Ldarg_S, (byte)(i + 1)); } else { // Ldarg uses a ushort, but the Emit only // accepts short, so we use a unchecked(...), // cast to short and let the CLR interpret it // as ushort ilgeneratorConstructor.Emit(OpCodes.Ldarg, unchecked ((short)(i + 1))); } ilgeneratorConstructor.Emit(OpCodes.Stfld, fields[i]); // getter MethodBuilder getter = tb.DefineMethod(string.Format("get_{0}", names[i]), MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName, CallingConventions.HasThis, generics[i], Type.EmptyTypes); ILGenerator ilgeneratorGetter = getter.GetILGenerator(); ilgeneratorGetter.Emit(OpCodes.Ldarg_0); ilgeneratorGetter.Emit(OpCodes.Ldfld, fields[i]); ilgeneratorGetter.Emit(OpCodes.Ret); PropertyBuilder property = tb.DefineProperty(names[i], PropertyAttributes.None, CallingConventions.HasThis, generics[i], Type.EmptyTypes); property.SetGetMethod(getter); } // ToString() MethodBuilder toString = tb.DefineMethod("ToString", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.HasThis, typeof(string), Type.EmptyTypes); toString.SetCustomAttribute(DebuggerHiddenAttributeBuilder); ILGenerator ilgeneratorToString = toString.GetILGenerator(); ilgeneratorToString.DeclareLocal(typeof(StringBuilder)); ilgeneratorToString.Emit(OpCodes.Newobj, StringBuilderCtor); ilgeneratorToString.Emit(OpCodes.Stloc_0); // Equals MethodBuilder equals = tb.DefineMethod("Equals", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.HasThis, typeof(bool), new[] { typeof(object) }); equals.SetCustomAttribute(DebuggerHiddenAttributeBuilder); equals.DefineParameter(1, ParameterAttributes.None, "value"); ILGenerator ilgeneratorEquals = equals.GetILGenerator(); ilgeneratorEquals.DeclareLocal(tb); ilgeneratorEquals.Emit(OpCodes.Ldarg_1); ilgeneratorEquals.Emit(OpCodes.Isinst, tb); ilgeneratorEquals.Emit(OpCodes.Stloc_0); ilgeneratorEquals.Emit(OpCodes.Ldloc_0); Label equalsLabel = ilgeneratorEquals.DefineLabel(); // GetHashCode() MethodBuilder getHashCode = tb.DefineMethod("GetHashCode", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.HasThis, typeof(int), Type.EmptyTypes); getHashCode.SetCustomAttribute(DebuggerHiddenAttributeBuilder); ILGenerator ilgeneratorGetHashCode = getHashCode.GetILGenerator(); ilgeneratorGetHashCode.DeclareLocal(typeof(int)); if (names.Length == 0) { ilgeneratorGetHashCode.Emit(OpCodes.Ldc_I4_0); } else { // As done by Roslyn // Note that initHash can vary, because // string.GetHashCode() isn't "stable" for // different compilation of the code int initHash = 0; for (int i = 0; i < names.Length; i++) { initHash = unchecked (initHash * (-1521134295) + fields[i].Name.GetHashCode()); } // Note that the CSC seems to generate a // different seed for every anonymous class ilgeneratorGetHashCode.Emit(OpCodes.Ldc_I4, initHash); } for (int i = 0; i < names.Length; i++) { // Equals() Type equalityComparerT = EqualityComparer.MakeGenericType(generics[i]); MethodInfo equalityComparerTDefault = TypeBuilder.GetMethod(equalityComparerT, EqualityComparerDefault); MethodInfo equalityComparerTEquals = TypeBuilder.GetMethod(equalityComparerT, EqualityComparerEquals); ilgeneratorEquals.Emit(OpCodes.Brfalse_S, equalsLabel); ilgeneratorEquals.Emit(OpCodes.Call, equalityComparerTDefault); ilgeneratorEquals.Emit(OpCodes.Ldarg_0); ilgeneratorEquals.Emit(OpCodes.Ldfld, fields[i]); ilgeneratorEquals.Emit(OpCodes.Ldloc_0); ilgeneratorEquals.Emit(OpCodes.Ldfld, fields[i]); ilgeneratorEquals.Emit(OpCodes.Callvirt, equalityComparerTEquals); // GetHashCode(); MethodInfo EqualityComparerTGetHashCode = TypeBuilder.GetMethod(equalityComparerT, EqualityComparerGetHashCode); ilgeneratorGetHashCode.Emit(OpCodes.Stloc_0); ilgeneratorGetHashCode.Emit(OpCodes.Ldc_I4, -1521134295); ilgeneratorGetHashCode.Emit(OpCodes.Ldloc_0); ilgeneratorGetHashCode.Emit(OpCodes.Mul); ilgeneratorGetHashCode.Emit(OpCodes.Call, equalityComparerTDefault); ilgeneratorGetHashCode.Emit(OpCodes.Ldarg_0); ilgeneratorGetHashCode.Emit(OpCodes.Ldfld, fields[i]); ilgeneratorGetHashCode.Emit(OpCodes.Callvirt, EqualityComparerTGetHashCode); ilgeneratorGetHashCode.Emit(OpCodes.Add); // ToString() ilgeneratorToString.Emit(OpCodes.Ldloc_0); ilgeneratorToString.Emit(OpCodes.Ldstr, i == 0 ? string.Format("{{ {0} = ", names[i]) : string.Format(", {0} = ", names[i])); ilgeneratorToString.Emit(OpCodes.Callvirt, StringBuilderAppendString); ilgeneratorToString.Emit(OpCodes.Pop); ilgeneratorToString.Emit(OpCodes.Ldloc_0); ilgeneratorToString.Emit(OpCodes.Ldarg_0); ilgeneratorToString.Emit(OpCodes.Ldfld, fields[i]); ilgeneratorToString.Emit(OpCodes.Box, generics[i]); ilgeneratorToString.Emit(OpCodes.Callvirt, StringBuilderAppendObject); ilgeneratorToString.Emit(OpCodes.Pop); } // .ctor ilgeneratorConstructor.Emit(OpCodes.Ret); // Equals() if (names.Length == 0) { ilgeneratorEquals.Emit(OpCodes.Ldnull); ilgeneratorEquals.Emit(OpCodes.Ceq); ilgeneratorEquals.Emit(OpCodes.Ldc_I4_0); ilgeneratorEquals.Emit(OpCodes.Ceq); } else { ilgeneratorEquals.Emit(OpCodes.Ret); ilgeneratorEquals.MarkLabel(equalsLabel); ilgeneratorEquals.Emit(OpCodes.Ldc_I4_0); } ilgeneratorEquals.Emit(OpCodes.Ret); // GetHashCode() ilgeneratorGetHashCode.Emit(OpCodes.Stloc_0); ilgeneratorGetHashCode.Emit(OpCodes.Ldloc_0); ilgeneratorGetHashCode.Emit(OpCodes.Ret); // ToString() ilgeneratorToString.Emit(OpCodes.Ldloc_0); ilgeneratorToString.Emit(OpCodes.Ldstr, names.Length == 0 ? "{ }" : " }"); ilgeneratorToString.Emit(OpCodes.Callvirt, StringBuilderAppendString); ilgeneratorToString.Emit(OpCodes.Pop); ilgeneratorToString.Emit(OpCodes.Ldloc_0); ilgeneratorToString.Emit(OpCodes.Callvirt, ObjectToString); ilgeneratorToString.Emit(OpCodes.Ret); type = tb.CreateType(); type = GeneratedTypes.GetOrAdd(fullName, type); } } } if (types.Length != 0) { type = type.MakeGenericType(types); } return(type); }
public override void Define(TypeBuilder bl) { _blf = bl.DefineField(_name, _type, _attributes); }
/// <summary> /// Creates a propxy <see cref="Type" /> for the interface of <typeparamref name="T" />. /// </summary> /// <param name="modBuilder">The module builder to use.</param> /// <param name="proxyTypeNamePrefixProvider">The logic that returns the prefix for the full name of the proxy type to create.</param> /// <param name="proxyTypeNameProvider">The logic that returns the name part of the proxy type to create.</param> /// <param name="proxyTypeNameSuffixProvider">The logic that returns the suffix for the full name of the proxy type to create.</param> /// <returns>The created type object.</returns> /// <exception cref="ArgumentNullException"> /// <paramref name="modBuilder" /> is <see langword="null" />. /// </exception> public Type CreateType(ModuleBuilder modBuilder, TypeNameProvider proxyTypeNamePrefixProvider, TypeNameProvider proxyTypeNameProvider, TypeNameProvider proxyTypeNameSuffixProvider) { if (modBuilder == null) { throw new ArgumentNullException("modBuilder"); } string prefix = proxyTypeNamePrefixProvider == null ? null : (StringHelper.AsString(proxyTypeNamePrefixProvider(this.InterfaceType)) ?? string.Empty).Trim(); string name = proxyTypeNameProvider == null ? null : (StringHelper.AsString(proxyTypeNameProvider(this.InterfaceType)) ?? string.Empty).Trim(); string suffix = proxyTypeNameSuffixProvider == null ? null : (StringHelper.AsString(proxyTypeNameSuffixProvider(this.InterfaceType)) ?? string.Empty).Trim(); Type baseType = typeof(object); TypeBuilder typeBuilder = modBuilder.DefineType(string.Format("{0}{1}{2}", prefix, name, suffix), TypeAttributes.Public | TypeAttributes.Class, baseType); typeBuilder.AddInterfaceImplementation(this.InterfaceType); List <PropertyInfo> properties = new List <PropertyInfo>(); CollectProperties(properties, this.InterfaceType); // properties { foreach (PropertyInfo p in properties) { string propertyName = p.Name; Type propertyType = p.PropertyType; PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.None, propertyType, Type.EmptyTypes); string fieldName = char.ToLower(propertyName[0]) + new string(CollectionHelper.ToArray(CollectionHelper.Skip(propertyName, 1))); FieldBuilder field = typeBuilder.DefineField("_" + fieldName, propertyType, FieldAttributes.Family); // getter { MethodBuilder methodBuilder = typeBuilder.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.Virtual, propertyType, Type.EmptyTypes); ILGenerator ilGen = methodBuilder.GetILGenerator(); ilGen.Emit(OpCodes.Ldarg_0); // load "this" ilGen.Emit(OpCodes.Ldfld, field); // load the property's underlying field onto the stack ilGen.Emit(OpCodes.Ret); // return the value on the stack propertyBuilder.SetGetMethod(methodBuilder); } // setter { MethodBuilder methodBuilder = typeBuilder.DefineMethod("set_" + propertyName, MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), new Type[] { propertyType }); ILGenerator ilGen = methodBuilder.GetILGenerator(); ilGen.Emit(OpCodes.Ldarg_0); // load "this" ilGen.Emit(OpCodes.Ldarg_1); // load "value" onto the stack ilGen.Emit(OpCodes.Stfld, field); // set the field equal to the "value" on the stack ilGen.Emit(OpCodes.Ret); // return nothing propertyBuilder.SetSetMethod(methodBuilder); } } } // constructor { ConstructorInfo baseConstructor = baseType.GetConstructor(new Type[0]); ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes); ILGenerator ilGen = constructorBuilder.GetILGenerator(); ilGen.Emit(OpCodes.Ldarg_0); // load "this" ilGen.Emit(OpCodes.Call, baseConstructor); // call the base constructor //TODO // define initial values ilGen.Emit(OpCodes.Ret); // return nothing } return(typeBuilder.CreateType()); }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIDocument uiDoc = commandData.Application.ActiveUIDocument; Document doc = uiDoc.Document; // Create transaction for working with schema Transaction trans = new Transaction(doc, "Extensible Storage"); trans.Start(); // Select a wall element Wall wall = null; try { Reference r = uiDoc.Selection.PickObject(ObjectType.Element, new WallSelectionFilter()); wall = doc.GetElement(r) as Wall; } catch (Autodesk.Revit.Exceptions.OperationCanceledException) { message = "Nothing selected; please select a wall to attach extensible data to."; return(Result.Failed); } Debug.Assert(null != wall, "expected a wall to be selected"); if (null == wall) { message = "Please select a wall to attach extensible data to."; return(Result.Failed); } // Create a schema builder SchemaBuilder builder = new SchemaBuilder(_guid); // Set read and write access levels builder.SetReadAccessLevel(AccessLevel.Public); builder.SetWriteAccessLevel(AccessLevel.Public); // Note: if this was set as vendor or application access, // we would have been additionally required to use SetVendorId // Set name to this schema builder builder.SetSchemaName("WallSocketLocation"); builder.SetDocumentation("Data store for socket related info in a wall"); // Create field1 FieldBuilder fieldBuilder1 = builder.AddSimpleField("SocketLocation", typeof(XYZ)); // Set unit type fieldBuilder1.SetUnitType(UnitType.UT_Length); // Add documentation (optional) // Create field2 FieldBuilder fieldBuilder2 = builder.AddSimpleField("SocketNumber", typeof(string)); //fieldBuilder2.SetUnitType(UnitType.UT_Custom); // Register the schema object Schema schema = builder.Finish(); // Create an entity (object) for this schema (class) Entity ent = new Entity(schema); Field socketLocation = schema.GetField("SocketLocation"); ent.Set <XYZ>(socketLocation, new XYZ(2, 0, 0), DisplayUnitType.DUT_METERS); Field socketNumber = schema.GetField("SocketNumber"); ent.Set <string>(socketNumber, "200"); wall.SetEntity(ent); // Now create another entity (object) for this schema (class) Entity ent2 = new Entity(schema); Field socketNumber1 = schema.GetField("SocketNumber"); ent2.Set <String>(socketNumber1, "400"); wall.SetEntity(ent2); // Note: this will replace the previous entity on the wall // List all schemas in the document string s = string.Empty; IList <Schema> schemas = Schema.ListSchemas(); foreach (Schema sch in schemas) { s += "\r\nSchema Name: " + sch.SchemaName; } TaskDialog.Show("Schema details", s); // List all Fields for our schema s = string.Empty; Schema ourSchema = Schema.Lookup(_guid); IList <Field> fields = ourSchema.ListFields(); foreach (Field fld in fields) { s += "\r\nField Name: " + fld.FieldName; } TaskDialog.Show("Field details", s); // Extract the value for the field we created Entity wallSchemaEnt = wall.GetEntity(Schema.Lookup(_guid)); XYZ wallSocketPos = wallSchemaEnt.Get <XYZ>( Schema.Lookup(_guid).GetField("SocketLocation"), DisplayUnitType.DUT_METERS); s = "SocketLocation: " + Format.PointString(wallSocketPos); string wallSocketNumber = wallSchemaEnt.Get <String>( Schema.Lookup(_guid).GetField("SocketNumber")); s += "\r\nSocketNumber: " + wallSocketNumber; TaskDialog.Show("Field values", s); trans.Commit(); return(Result.Succeeded); }
public void InsertFieldWithFieldBuilder() { Document doc = new Document(); //Add some text into the paragraph Run run = DocumentHelper.InsertNewRun(doc, " Hello World!", 0); FieldArgumentBuilder argumentBuilder = new FieldArgumentBuilder(); argumentBuilder.AddField(new FieldBuilder(FieldType.FieldMergeField)); argumentBuilder.AddText("BestField"); FieldBuilder fieldBuilder = new FieldBuilder(FieldType.FieldIf); fieldBuilder.AddArgument(argumentBuilder) .AddArgument("=") .AddArgument("BestField") .AddArgument(10) .AddArgument(20.0) .AddSwitch("12", "13") .BuildAndInsert(run); doc.UpdateFields(); }
protected virtual void DescribeFieldInfo(FieldBuilder builder, Type type, FieldInfo fieldInfo) { }
public void SetConstant_InvalidType_ThrowsArgumentException(FieldBuilder field, object defaultValue) { Assert.Throws<ArgumentException>(null, () => field.SetConstant(defaultValue)); }
protected virtual void DescribePropertyInfo(FieldBuilder builder, Type type, PropertyInfo propertyInfo) { }
internal override void Apply(ClassLoaderWrapper loader, FieldBuilder fb, object annotation) { if (type.IsSubclassOf(Types.SecurityAttribute)) { // you can't add declarative security to a field } else { fb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } }
private static void WriteILForMethod(MethodBuilder builder, System.Type[] parameters, FieldBuilder handlerField) { int arrayPositionInStack = 1; ILGenerator gen = builder.GetILGenerator(); gen.DeclareLocal(typeof(MethodBase)); if (builder.ReturnType != typeof(void)) { gen.DeclareLocal(builder.ReturnType); arrayPositionInStack = 2; } gen.DeclareLocal(typeof(object[])); gen.Emit(OpCodes.Call, typeof(MethodBase).GetMethod("GetCurrentMethod")); gen.Emit(OpCodes.Stloc_0); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldfld, handlerField); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldloc_0); gen.Emit(OpCodes.Ldc_I4, parameters.Length); gen.Emit(OpCodes.Newarr, typeof(object)); if (parameters.Length != 0) { gen.Emit(OpCodes.Stloc, arrayPositionInStack); gen.Emit(OpCodes.Ldloc, arrayPositionInStack); } for (int c = 0; c < parameters.Length; ++c) { gen.Emit(OpCodes.Ldc_I4, c); gen.Emit(OpCodes.Ldarg, c + 1); if (parameters[c].IsValueType) { gen.Emit(OpCodes.Box, parameters[c].UnderlyingSystemType); } gen.Emit(OpCodes.Stelem_Ref); gen.Emit(OpCodes.Ldloc, arrayPositionInStack); } gen.Emit(OpCodes.Callvirt, typeof(InvocationHandler).GetMethod("Invoke")); if (builder.ReturnType != typeof(void)) { if (builder.ReturnType.IsValueType) { gen.Emit(OpCodes.Unbox_Any, builder.ReturnType); } else { gen.Emit(OpCodes.Castclass, builder.ReturnType); } gen.Emit(OpCodes.Stloc, 1); Label label = gen.DefineLabel(); gen.Emit(OpCodes.Br_S, label); gen.MarkLabel(label); gen.Emit(OpCodes.Ldloc, 1); } else { gen.Emit(OpCodes.Pop); } gen.Emit(OpCodes.Ret); }
static TypeAccessor CreateNew(Type type, bool allowNonPublicAccessors) { #if !NO_DYNAMIC #if WINDOWS_PHONE_APP if (typeof(IDynamicMetaObjectProvider).GetTypeInfo().IsAssignableFrom(type.GetTypeInfo())) #else if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(type)) #endif { return(DynamicAccessor.Singleton); } #endif #if WINDOWS_PHONE_APP PropertyInfo[] props = type.GetRuntimeProperties().ToArray(); FieldInfo[] fields = type.GetRuntimeFields().ToArray(); #else PropertyInfo[] props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance); #endif Dictionary <string, int> map = new Dictionary <string, int>(StringComparer.Ordinal); 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 WINDOWS_PHONE_APP if (type.GetTypeInfo().IsClass&& !type.GetTypeInfo().IsAbstract) { ctor = type.GetTypeInfo().DeclaredConstructors.FirstOrDefault(); } #else if (type.IsClass && !type.IsAbstract) { ctor = type.GetConstructor(Type.EmptyTypes); } #endif #if !__IOS__ && !WINDOWS_PHONE_APP 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), Type.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"); assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run); module = assembly.DefineDynamicModule(name.Name); } TypeBuilder tb = module.DefineType("FastMember_dynamic." + type.Name + "_" + Interlocked.Increment(ref counter), (typeof(TypeAccessor).Attributes | 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, Type.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, Type.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, Type.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); try { var accessor = (TypeAccessor)Activator.CreateInstance(tb.CreateType(), map); return(accessor); } catch (TargetInvocationException vex) { var _getter = new Func <int, object, object>((index, obj) => { return(obj.GetType().GetProperties()[index].GetValue(obj)); }); var _setter = new Action <int, object, object>((index, obj, value) => { try { obj.GetType().GetProperties()[index].SetValue(obj, value); } catch (ArgumentException icex) { throw new InvalidCastException(icex.Message, icex); } catch (Exception ex) { throw new Exception(ex.Message, ex); } }); return(new DelegateAccessor(map, _getter, _setter, delegate { return ctor.Invoke(null); }, type)); } catch (Exception ex) { throw new Exception(ex.Message, ex); } #else var _getter = new Func <int, object, object>((index, obj) => { #if WINDOWS_PHONE_APP return(obj.GetType().GetRuntimeProperties().ToArray()[index].GetValue(obj)); #else return(obj.GetType().GetProperties()[index].GetValue(obj)); #endif }); var _setter = new Action <int, object, object>((index, obj, value) => { try { #if WINDOWS_PHONE_APP obj.GetType().GetRuntimeProperties().ToArray()[index].SetValue(obj, value); #else obj.GetType().GetProperties()[index].SetValue(obj, value); #endif } catch (ArgumentException icex) { throw new InvalidCastException(icex.Message, icex); } catch (Exception ex) { throw new Exception(ex.Message, ex); } }); return(new DelegateAccessor(map, _getter, _setter, delegate { return ctor.Invoke(null); }, type)); //RuntimeTypeAccessor() (TypeAccessor) Activator.CreateInstance(type); //return (TypeAccessor)Activator.CreateInstance(type); #endif }
private void BuildWrappedInstanceField(TypeBuilder typeBuilder, Type basetype) { that = typeBuilder.DefineField("__wrappedInstanceField", basetype, FieldAttributes.Private); }
public static IEnumerable <object[]> SetConstant_Invalid_TestData() { FieldBuilder boolField = s_type.DefineField("BoolField2", typeof(bool), FieldAttributes.Public); yield return(new object[] { boolField, null }); yield return(new object[] { boolField, new object() }); FieldBuilder intField = s_type.DefineField("IntField2", typeof(int), FieldAttributes.Public); yield return(new object[] { intField, null }); yield return(new object[] { intField, new object() }); FieldBuilder sbyteField = s_type.DefineField("SByteField2", typeof(sbyte), FieldAttributes.Public); yield return(new object[] { sbyteField, null }); yield return(new object[] { sbyteField, new object() }); FieldBuilder shortField = s_type.DefineField("ShortField2", typeof(short), FieldAttributes.Public); yield return(new object[] { shortField, null }); yield return(new object[] { shortField, new object() }); FieldBuilder longField = s_type.DefineField("LongField2", typeof(long), FieldAttributes.Public); yield return(new object[] { longField, null }); yield return(new object[] { longField, new object() }); FieldBuilder byteField = s_type.DefineField("ByteField2", typeof(byte), FieldAttributes.Public); yield return(new object[] { byteField, null }); yield return(new object[] { byteField, new object() }); FieldBuilder ushortField = s_type.DefineField("UShortField2", typeof(ushort), FieldAttributes.Public); yield return(new object[] { ushortField, null }); yield return(new object[] { ushortField, new object() }); FieldBuilder uintField = s_type.DefineField("UIntField2", typeof(uint), FieldAttributes.Public); yield return(new object[] { uintField, null }); yield return(new object[] { uintField, new object() }); FieldBuilder ulongField = s_type.DefineField("ULongField2", typeof(ulong), FieldAttributes.Public); yield return(new object[] { ulongField, null }); yield return(new object[] { ulongField, new object() }); FieldBuilder floatField = s_type.DefineField("FloatField2", typeof(float), FieldAttributes.Public); yield return(new object[] { floatField, null }); yield return(new object[] { floatField, new object() }); FieldBuilder doubleField = s_type.DefineField("DoubleField2", typeof(double), FieldAttributes.Public); yield return(new object[] { doubleField, null }); yield return(new object[] { doubleField, new object() }); FieldBuilder dateTimeField = s_type.DefineField("DateTimeField2", typeof(DateTime), FieldAttributes.Public); yield return(new object[] { dateTimeField, null }); yield return(new object[] { dateTimeField, new object() }); FieldBuilder charField = s_type.DefineField("CharField2", typeof(char), FieldAttributes.Public); yield return(new object[] { charField, null }); yield return(new object[] { charField, new object() }); FieldBuilder stringField = s_type.DefineField("StringField2", typeof(string), FieldAttributes.Public); yield return(new object[] { stringField, new object() }); FieldBuilder enumField = s_type.DefineField("EnumField2", typeof(CustomEnum), FieldAttributes.Public); yield return(new object[] { enumField, null }); yield return(new object[] { enumField, new object() }); FieldBuilder decimalField = s_type.DefineField("DecimalField2", typeof(decimal), FieldAttributes.Public); yield return(new object[] { decimalField, new object() }); yield return(new object[] { decimalField, decimal.One }); FieldBuilder objectField = s_type.DefineField("ObjectField2", typeof(object), FieldAttributes.Public); yield return(new object[] { objectField, new object() }); FieldBuilder structField = s_type.DefineField("LongField2", typeof(FBTestStruct), FieldAttributes.Public); yield return(new object[] { structField, null }); }
private void BuildMixinMethods(MethodInfo[] methods, TypeBuilder typeBuilder, FieldBuilder mixinField) { foreach (MethodInfo method in methods) { // if (method.IsVirtual && !method.IsFinal && engine.PointCutMatcher.MethodShouldBeProxied(method, aspects)) // { // BuildMixinMethod(typeBuilder, method, mixinField); // } // else // { BuildMixinUnproxiedMethod(method.Name, typeBuilder, method, mixinField); // } } }
private static void BuildMethod(Type classType, FieldBuilder inspectorFieldBuilder, TypeBuilder typeBuilder) { var methodInfos = classType.GetMethods(); foreach (var methodInfo in methodInfos) { if (!methodInfo.IsVirtual && !methodInfo.IsAbstract) { continue; } if (methodInfo.Name == "ToString") { continue; } if (methodInfo.Name == "GetHashCode") { continue; } if (methodInfo.Name == "Equals") { continue; } var parameterInfos = methodInfo.GetParameters(); var parameterTypes = parameterInfos.Select(p => p.ParameterType).ToArray(); var parameterLength = parameterTypes.Length; var hasResult = methodInfo.ReturnType != VoidType; var methodBuilder = typeBuilder.DefineMethod(methodInfo.Name, MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual , methodInfo.ReturnType , parameterTypes); var il = methodBuilder.GetILGenerator(); //局部变量 il.DeclareLocal(typeof(object)); //correlationState il.DeclareLocal(typeof(object)); //result il.DeclareLocal(typeof(object[])); //parameters //BeforeCall(string operationName, object[] inputs); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, inspectorFieldBuilder); //获取字段_inspector il.Emit(OpCodes.Ldstr, methodInfo.Name); //参数operationName if (parameterLength == 0) //判断方法参数长度 { il.Emit(OpCodes.Ldnull); //null -> 参数 inputs } else { //创建new object[parameterLength]; il.Emit(OpCodes.Ldc_I4, parameterLength); il.Emit(OpCodes.Newarr, typeof(Object)); il.Emit(OpCodes.Stloc_2);//压入局部变量2 parameters for (int i = 0, j = 1; i < parameterLength; i++, j++) { //object[i] = arg[j] il.Emit(OpCodes.Ldloc_2); il.Emit(OpCodes.Ldc_I4, 0); il.Emit(OpCodes.Ldarg, j); if (parameterTypes[i].IsValueType) { il.Emit(OpCodes.Box, parameterTypes[i]); //对值类型装箱 } il.Emit(OpCodes.Stelem_Ref); } il.Emit(OpCodes.Ldloc_2);//取出局部变量2 parameters-> 参数 inputs } il.Emit(OpCodes.Callvirt, typeof(IInterceptor).GetMethod("BeforeCall")); //调用BeforeCall il.Emit(OpCodes.Stloc_0); //建返回压入局部变量0 correlationState //Call methodInfo il.Emit(OpCodes.Ldarg_0); //获取参数表 for (int i = 1, length = parameterLength + 1; i < length; i++) { il.Emit(OpCodes.Ldarg_S, i); } il.Emit(OpCodes.Call, methodInfo); //将返回值压入 局部变量1result void就压入null if (!hasResult) { il.Emit(OpCodes.Ldnull); } else if (methodInfo.ReturnType.IsValueType) { il.Emit(OpCodes.Box, methodInfo.ReturnType); //对值类型装箱 } il.Emit(OpCodes.Stloc_1); //AfterCall(string operationName, object returnValue, object correlationState); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, inspectorFieldBuilder); //获取字段_inspector il.Emit(OpCodes.Ldstr, methodInfo.Name); //参数 operationName il.Emit(OpCodes.Ldloc_1); //局部变量1 result il.Emit(OpCodes.Ldloc_0); // 局部变量0 correlationState il.Emit(OpCodes.Callvirt, typeof(IInterceptor).GetMethod("AfterCall")); //result if (!hasResult) { il.Emit(OpCodes.Ret); return; } il.Emit(OpCodes.Ldloc_1);//非void取出局部变量1 result if (methodInfo.ReturnType.IsValueType) { il.Emit(OpCodes.Unbox_Any, methodInfo.ReturnType); //对值类型拆箱 } il.Emit(OpCodes.Ret); } }
private void BuildMixinUnproxiedMethod(string wrapperName, TypeBuilder typeBuilder, MethodInfo method, FieldBuilder field) { BuildMixinWrapperMethod(wrapperName, typeBuilder, method, field); }
/// <summary> /// Modifies the default constructor to initialize the "__initializedServices" field so that it can ensure that all /// services called with the <see cref="IInitialize.Initialize"/> are initialized once per object lifetime. /// </summary> /// <param name="containerType">The container type.</param> /// <param name="module">The module.</param> /// <param name="fieldEmitter">The field builder.</param> private void AddInitializationMap(TypeDefinition containerType, ModuleDefinition module, FieldBuilder fieldEmitter) { var initializationMapType = module.Import(typeof(Dictionary<int, int>)); var initializationMapField = new FieldDefinition("__initializedServices", FieldAttributes.Private | FieldAttributes.InitOnly, initializationMapType); containerType.Fields.Add(initializationMapField); var defaultConstructor = containerType.GetDefaultConstructor(); var body = defaultConstructor.Body; // __initializedServices = new Dictionary<int, int>(); var il = body.GetILProcessor(); var dictionaryCtor = module.ImportConstructor<Dictionary<int, int>>(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Newobj, dictionaryCtor); il.Emit(OpCodes.Stfld, initializationMapField); }
private static MethodBuilder BuildSetter(TypeBuilder typeBuilder, PropertyInfo property, FieldBuilder fieldBuilder, MethodAttributes attributes) { var setterBuilder = typeBuilder.DefineMethod($"set_{property.Name}", attributes, null, new Type[] { property.PropertyType }); var ilGenerator = setterBuilder.GetILGenerator(); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldarg_1); // Build null check if (property.IsDefined(typeof(RequiredAttribute))) { var isValueNull = ilGenerator.DefineLabel(); ilGenerator.Emit(OpCodes.Dup); ilGenerator.Emit(OpCodes.Brtrue_S, isValueNull); ilGenerator.Emit(OpCodes.Pop); ilGenerator.Emit(OpCodes.Ldstr, property.Name); var argumentNullExceptionConstructor = typeof(ArgumentNullException).GetConstructor(new Type[] { typeof(string) }); ilGenerator.Emit(OpCodes.Newobj, argumentNullExceptionConstructor); ilGenerator.Emit(OpCodes.Throw); ilGenerator.MarkLabel(isValueNull); } ilGenerator.Emit(OpCodes.Stfld, fieldBuilder); ilGenerator.Emit(OpCodes.Ret); return(setterBuilder); }
// Methods /* private scope */ static void Main() { Console.WriteLine("CodeTrace was used to record the steps to build a specific assembly."); Console.WriteLine("CodeTrace started at 28/06/2010 11:46:26"); _ct_Product_Name = "TestCodeTrace.Rewrite.exe"; Dictionary<int, Type> dictionary = new Dictionary<int, Type>(); dictionary.Add(0, null); dictionary.Add(typeof(object).GetHashCode(), typeof(object)); _ct_SourceTypeHashToTypeLookup = dictionary; Dictionary<int, MethodBuilder> dictionary2 = new Dictionary<int, MethodBuilder>(); dictionary2.Add(0, null); _ct_SourceMethodHashToMethodBuilderLookup = dictionary2; _ct_SourceMethodHashToILGeneratorLookup = new Dictionary<int, Func<ILGenerator>>(); a = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(Path.GetFileNameWithoutExtension(_ct_Product_Name)), AssemblyBuilderAccess.RunAndSave, @"W:\jsc.svn\examples\rewrite\TestCodeTrace\TestCodeTrace\bin\Debug\staging"); m = a.DefineDynamicModule(Path.GetFileNameWithoutExtension(_ct_Product_Name), "~TestCodeTrace.Rewrite.exe"); DefineTypeName = "TestCodeTrace.Program"; Console.WriteLine("CodeTrace DefineType " + DefineTypeName); DeclaringType = m.DefineType(DefineTypeName, TypeAttributes.BeforeFieldInit, _ct_SourceTypeHashToTypeLookup[0], new Type[0]); _ct_SourceTypeHashToTypeLookup[0x52a258] = DeclaringType; (_ct_SourceTypeHashToTypeLookup[0x52a258] as TypeBuilder).SetParent(_ct_SourceTypeHashToTypeLookup[0x704e84dc]); DeclaringMethod = (_ct_SourceTypeHashToTypeLookup[0x52a258] as TypeBuilder).DefineMethod("Main", MethodAttributes.HideBySig | MethodAttributes.Static | MethodAttributes.FamORAssem, CallingConventions.Standard, null, null); _ct_SourceMethodHashToMethodBuilderLookup[-1395084204] = DeclaringMethod; _ct_SourceMethod = -1395084204; _ct_SourceMethodHashToILGeneratorLookup[_ct_SourceMethod] = new Func<ILGenerator>(_ct_SourceMethodHashToMethodBuilderLookup[_ct_SourceMethod].GetILGenerator); _ct_SourceMethodHashToILGeneratorLookup[-1395084204]().Emit(OpCodes.Nop); _ct_SourceMethodHashToILGeneratorLookup[-1395084204]().Emit(OpCodes.Ret); DeclaringMethod = (_ct_SourceTypeHashToTypeLookup[0x52a258] as TypeBuilder).DefineMethod("Method2", MethodAttributes.HideBySig | MethodAttributes.Static | MethodAttributes.Private, CallingConventions.Standard, null, null); _ct_SourceMethodHashToMethodBuilderLookup[-1395116976] = DeclaringMethod; _ct_SourceMethod = -1395116976; _ct_SourceMethodHashToILGeneratorLookup[_ct_SourceMethod] = new Func<ILGenerator>(_ct_SourceMethodHashToMethodBuilderLookup[_ct_SourceMethod].GetILGenerator); DefineTypeName = "TestCodeTrace.IDocument`1"; Console.WriteLine("CodeTrace DefineType " + DefineTypeName); DeclaringType = m.DefineType(DefineTypeName, TypeAttributes.BeforeFieldInit | TypeAttributes.Public, _ct_SourceTypeHashToTypeLookup[0], new Type[0]); _ct_SourceTypeHashToTypeLookup[0x41330fc] = DeclaringType; (_ct_SourceTypeHashToTypeLookup[0x41330fc] as TypeBuilder).SetParent(_ct_SourceTypeHashToTypeLookup[0x704e84dc]); _ct_GenericParameters = (_ct_SourceTypeHashToTypeLookup[0x41330fc] as TypeBuilder).DefineGenericParameters(new string[] { "TConstraint1" }); List<Type> list = new List<Type>(); foreach (int num in new int[] { 0x704e84dc }) { list.Add(_ct_SourceTypeHashToTypeLookup[num]); } _ct_DeclaringType = _ct_SourceTypeHashToTypeLookup[0x41330fc].MakeGenericType(list.ToArray()); _ct_SourceTypeHashToTypeLookup[0x41331e0] = _ct_DeclaringType; DefineTypeName = "TestCodeTrace.IXMLDocument"; Console.WriteLine("CodeTrace DefineType " + DefineTypeName); DeclaringType = m.DefineType(DefineTypeName, TypeAttributes.BeforeFieldInit | TypeAttributes.Public, _ct_SourceTypeHashToTypeLookup[0], new Type[0]); _ct_SourceTypeHashToTypeLookup[0x4133dec] = DeclaringType; (_ct_SourceTypeHashToTypeLookup[0x4133dec] as TypeBuilder).SetParent(_ct_SourceTypeHashToTypeLookup[0x41331e0]); DeclaringMethod = (_ct_SourceTypeHashToTypeLookup[0x4133dec] as TypeBuilder).DefineMethod("Method2", MethodAttributes.HideBySig | MethodAttributes.Private, CallingConventions.HasThis | CallingConventions.Standard, null, null); _ct_SourceMethodHashToMethodBuilderLookup[-1129754532] = DeclaringMethod; _ct_SourceMethod = -1129754532; _ct_SourceMethodHashToILGeneratorLookup[_ct_SourceMethod] = new Func<ILGenerator>(_ct_SourceMethodHashToMethodBuilderLookup[_ct_SourceMethod].GetILGenerator); _ct_SourceMethodHashToILGeneratorLookup[-1129754532]().Emit(OpCodes.Nop); _ct_SourceMethodHashToILGeneratorLookup[-1129754532]().Emit(OpCodes.Ret); DeclaringField = (_ct_SourceTypeHashToTypeLookup[0x41330fc] as TypeBuilder).DefineField("__Type1", _ct_SourceTypeHashToTypeLookup[0x4133dec], FieldAttributes.Public); Console.WriteLine("CodeTrace CreateType: " + "TestCodeTrace.IDocument`1"); (_ct_SourceTypeHashToTypeLookup[0x41330fc] as TypeBuilder).CreateType(); Console.WriteLine("CodeTrace CreateType: " + "TestCodeTrace.IXMLDocument"); (_ct_SourceTypeHashToTypeLookup[0x4133dec] as TypeBuilder).CreateType(); _ct_SourceMethodHashToILGeneratorLookup[-1395116976]().Emit(OpCodes.Nop); _ct_SourceMethodHashToILGeneratorLookup[-1395116976]().Emit(OpCodes.Ret); Console.WriteLine("CodeTrace CreateType: " + "TestCodeTrace.Program"); (_ct_SourceTypeHashToTypeLookup[0x52a258] as TypeBuilder).CreateType(); m.CreateGlobalFunctions(); a.Save("~TestCodeTrace.Rewrite.exe"); Console.WriteLine("CodeTrace ended at 28/06/2010 11:46:28"); }
public static void EmitProxyMethod(this ILGenerator ilGenerator, MethodInfo methodInfo, FieldBuilder _actors, FieldBuilder serviceProvider, FieldBuilder instance ) { var returnType = methodInfo.ReturnType; #if NETSTANDARD var isAsync = returnType == typeof(Task) || returnType.BaseType == typeof(Task) || returnType == typeof(ValueTask) || (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(ValueTask <>)); #else var isAsync = returnType == typeof(Task) || returnType.BaseType == typeof(Task) || (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(ValueTask <>)); #endif var funcType = ExpressionExtension.CreateFuncType(isAsync ? returnType : typeof(object)); var method = ilGenerator.DeclareLocal(typeof(MethodInfo)); var parameters = ilGenerator.DeclareLocal(typeof(object[])); var _delegate = ilGenerator.DeclareLocal(typeof(Delegate)); var _func = ilGenerator.DeclareLocal(funcType); var paramTypes = methodInfo .GetParameters() // ReSharper disable once InconsistentNaming .Select(_parameter => _parameter.ParameterType) .ToArray(); #region methodInfo ilGenerator.EmitMethod(methodInfo); ilGenerator.Emit(OpCodes.Stloc_0, method); #endregion #region args ilGenerator.AddLdcI4(paramTypes.Length); ilGenerator.Emit(OpCodes.Newarr, typeof(object)); for (var j = 0; j < paramTypes.Length; j++) { ilGenerator.Emit(OpCodes.Dup); ilGenerator.AddLdcI4(j); ilGenerator.EmitLoadArg(j + 1); var parameterType = paramTypes[j]; if (parameterType.GetTypeInfo().IsValueType || parameterType.IsGenericParameter) { ilGenerator.Emit(OpCodes.Box, parameterType); } ilGenerator.Emit(OpCodes.Stelem_Ref); } ilGenerator.Emit(OpCodes.Stloc, parameters); #endregion #region Delegate ilGenerator.Emit(OpCodes.Ldtoken, isAsync ? returnType : typeof(object)); ilGenerator.Emit(OpCodes.Call, MethodInfoExtension.GetTypeFromHandle); ilGenerator.Emit(OpCodes.Call, MethodInfoExtension.BuilderDelegate); ilGenerator.Emit(OpCodes.Stloc, _delegate); #endregion #region Convert To Func ilGenerator.Emit(OpCodes.Ldloc, _delegate); ilGenerator.Emit(OpCodes.Castclass, funcType); ilGenerator.Emit(OpCodes.Stloc, _func); #endregion ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldfld, _actors); ilGenerator.Emit(OpCodes.Ldloc, _func); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldfld, serviceProvider); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldfld, instance); ilGenerator.Emit(OpCodes.Ldloc, method); ilGenerator.Emit(OpCodes.Ldloc, parameters); #region AopContext ilGenerator.Emit(OpCodes.Newobj, typeof(AopContext).GetConstructor(new[] { typeof(IServiceProvider), typeof(object), typeof(MethodInfo), typeof(object[]) })); #endregion if (isAsync) { if (returnType.IsGenericType) { var typeInfo = returnType.GetTypeInfo(); var genericTypeDefinition = typeInfo.GetGenericArguments().Single(); if (returnType.BaseType == typeof(ValueType)) { ilGenerator.Emit(OpCodes.Callvirt, MethodInfoExtension.ExecuteValueAsync.MakeGenericMethod(genericTypeDefinition)); } else { ilGenerator.Emit(OpCodes.Callvirt, MethodInfoExtension.ExecuteAsync.MakeGenericMethod(genericTypeDefinition)); } } else { #if NETSTANDARD if (returnType == typeof(ValueTask)) { ilGenerator.Emit(OpCodes.Callvirt, MethodInfoExtension.InvokeValueAsync); } else { ilGenerator.Emit(OpCodes.Callvirt, MethodInfoExtension.InvokeAsync); } #else ilGenerator.Emit(OpCodes.Callvirt, MethodInfoExtension.InvokeAsync); #endif } } else { //_actor.Execute(_invoke,context); ilGenerator.Emit(OpCodes.Callvirt, MethodInfoExtension.Execute); if (returnType == typeof(void)) { ilGenerator.Emit(OpCodes.Pop); } if (returnType != typeof(void) && returnType.IsValueType) { ilGenerator.Emit(OpCodes.Unbox_Any, returnType); } if (!isAsync && returnType.IsGenericType) { ilGenerator.Emit(OpCodes.Castclass, returnType); } } ilGenerator.Emit(OpCodes.Ret); }
Type get_type(XCompoundTypeDescription xType) { string uno_name = xType.getName(); if (xType.getTypeClass() == TypeClass.EXCEPTION) { switch (uno_name) { case "com.sun.star.uno.Exception": return get_type_Exception(); case "com.sun.star.uno.RuntimeException": return get_type_RuntimeException(); default: break; } } string cts_name = to_cts_name(uno_name); // if the struct is an instantiated polymorphic struct then we create // the simple struct name // // For example: // void func ([in] PolyStruct<boolean> arg9, // PolyStruct<boolean> will be converted to PolyStruct polymorphicStructNameToStructName(ref cts_name); Type ret_type = get_type(cts_name, false /* no exc */); if (ret_type == null) { XCompoundTypeDescription xBaseType = xType.getBaseType() as XCompoundTypeDescription; Type base_type = (xBaseType != null ? get_type(xBaseType) : typeof(Object)); TypeBuilder type_builder = m_module_builder.DefineType( cts_name, (TypeAttributes.Public | TypeAttributes.BeforeFieldInit | TypeAttributes.AnsiClass), base_type); // Polymorphic struct, define uno.TypeParametersAttribute string[] type_parameters = null; XStructTypeDescription xStructTypeDesc = xType as XStructTypeDescription; if (xStructTypeDesc != null) { type_parameters = xStructTypeDesc.getTypeParameters(); if (type_parameters.Length != 0) { Type[] typesCtor = new Type[] { Type.GetType("System.String[]") }; CustomAttributeBuilder attrBuilder = new CustomAttributeBuilder( typeof(uno.TypeParametersAttribute) .GetConstructor(typesCtor), type_parameters); type_builder.SetCustomAttribute(attrBuilder); } } // FIXME huh? what does this mean: // optional: lookup base type whether generated entry of this session struct_entry base_type_entry = null; if (base_type != null) { base_type_entry = m_generated_structs[base_type.FullName] as struct_entry; } // members XTypeDescription[] seq_members = xType.getMemberTypes(); string[] member_names = xType.getMemberNames(); Trace.Assert(seq_members.Length == member_names.Length); int all_members_length = 0; int member_pos; int type_param_pos = 0; // collect base type; wrong order ArrayList base_types_list = new ArrayList(3 /* initial capacity */); for (Type base_type_pos = base_type_pos = base_type; ! base_type_pos.Equals(typeof(System.Object)); base_type_pos = base_type_pos.BaseType) { base_types_list.Add(base_type_pos); if (base_type_pos.Equals(typeof(System.Exception))) { // special Message member all_members_length += 1; break; // don't include System.Exception base classes } else { all_members_length += base_type_pos.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly).Length; } } // create all_members_arrays; right order string[] all_member_names = new string[all_members_length + seq_members.Length]; Type[] all_param_types = new Type[all_members_length + seq_members.Length]; member_pos =0; for (int pos = base_types_list.Count; pos-- != 0; ) { Type ancestor = (Type) base_types_list[pos]; if (ancestor.Equals(typeof(System.Exception))) { all_member_names[member_pos] = "Message"; all_param_types[member_pos] = typeof (System.String); ++member_pos; } else { struct_entry existing_entry = m_generated_structs[ancestor.FullName] as struct_entry; if (existing_entry == null) { // complete type FieldInfo[] fields = ancestor.GetFields( BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly); foreach (FieldInfo field in fields) { all_member_names[member_pos] = field.Name; all_param_types[member_pos] = field.FieldType; ++member_pos; } } else // generated during this session: // members may be incomplete ifaces { for (int i = 0; i < existing_entry.m_member_names.Length; ++i) { all_member_names[member_pos] = existing_entry.m_member_names[i]; all_param_types[member_pos] = existing_entry.m_param_types[i]; ++member_pos; } } } } Trace.Assert(all_members_length == member_pos); // build up entry struct_entry entry = new struct_entry(); entry.m_member_names = new string[seq_members.Length]; entry.m_param_types = new Type[seq_members.Length]; // add members FieldBuilder[] members = new FieldBuilder[seq_members.Length]; int curParamIndex = 0; // count the fields which have // parameterized types for (member_pos = 0; member_pos < seq_members.Length; ++member_pos) { string field_name = member_names[member_pos]; Type field_type; // Special handling of struct parameter types bool bParameterizedType = false; if (seq_members[member_pos].getTypeClass() == TypeClass.UNKNOWN) { bParameterizedType = true; if (type_param_pos < type_parameters.Length) { field_type = typeof(System.Object); type_param_pos++; } else { throw new System.Exception("unexpected member type in " + xType.getName()); } } else { field_type = get_type(seq_members[member_pos]); } members[member_pos] = type_builder.DefineField( field_name, field_type, FieldAttributes.Public); // parameterized type (polymorphic struct) ? if (bParameterizedType && xStructTypeDesc != null) { // get the name Trace.Assert(type_parameters.Length > curParamIndex); string sTypeName = type_parameters[curParamIndex++]; object[] args = new object[] { sTypeName }; // set ParameterizedTypeAttribute Type[] ctorTypes = new Type[] { typeof(System.String) }; CustomAttributeBuilder attrBuilder = new CustomAttributeBuilder( typeof(uno.ParameterizedTypeAttribute) .GetConstructor(ctorTypes), args); members[member_pos].SetCustomAttribute(attrBuilder); } // add to all_members all_member_names[all_members_length + member_pos] = field_name; all_param_types[all_members_length + member_pos] = field_type; // add to entry entry.m_member_names[member_pos] = field_name; entry.m_param_types[member_pos] = field_type; } all_members_length += members.Length; // default .ctor ConstructorBuilder ctor_builder = type_builder.DefineConstructor( c_ctor_method_attr, CallingConventions.Standard, new Type[0]); ILGenerator code = ctor_builder.GetILGenerator(); code.Emit(OpCodes.Ldarg_0); code.Emit(OpCodes.Call, base_type_entry == null ? base_type.GetConstructor(new Type[0]) : base_type_entry.m_default_ctor); // default initialize members for (member_pos = 0; member_pos < seq_members.Length; ++member_pos) { FieldInfo field = members[member_pos]; Type field_type = field.FieldType; // default initialize: // string, type, enum, sequence, struct, exception, any if (field_type.Equals(typeof(System.String))) { code.Emit(OpCodes.Ldarg_0); code.Emit(OpCodes.Ldstr, ""); code.Emit(OpCodes.Stfld, field); } else if (field_type.Equals(typeof(System.Type))) { code.Emit(OpCodes.Ldarg_0); code.Emit(OpCodes.Ldtoken, typeof(void)); code.Emit(OpCodes.Call, m_method_info_Type_GetTypeFromHandle); code.Emit(OpCodes.Stfld, field); } else if (field_type.IsArray) { code.Emit(OpCodes.Ldarg_0); code.Emit(OpCodes.Ldc_I4_0); code.Emit(OpCodes.Newarr, field_type.GetElementType()); code.Emit(OpCodes.Stfld, field); } else if (field_type.IsValueType) { if (field_type.FullName.Equals("uno.Any")) { code.Emit(OpCodes.Ldarg_0); code.Emit(OpCodes.Ldsfld, typeof(uno.Any).GetField("VOID")); code.Emit(OpCodes.Stfld, field); } } else if (field_type.IsClass) { /* may be XInterface */ if (! field_type.Equals(typeof(System.Object))) { // struct, exception code.Emit(OpCodes.Ldarg_0); code.Emit(OpCodes.Newobj, field_type.GetConstructor(new Type[0])); code.Emit(OpCodes.Stfld, field); } } } code.Emit(OpCodes.Ret); entry.m_default_ctor = ctor_builder; // parameterized .ctor including all base members ctor_builder = type_builder.DefineConstructor( c_ctor_method_attr, CallingConventions.Standard, all_param_types); for (member_pos = 0; member_pos < all_members_length; ++member_pos) { ctor_builder.DefineParameter( member_pos + 1 /* starts with 1 */, ParameterAttributes.In, all_member_names[member_pos]); } code = ctor_builder.GetILGenerator(); // call base .ctor code.Emit(OpCodes.Ldarg_0); // push this int base_members_length = all_members_length - seq_members.Length; Type[] param_types = new Type[base_members_length]; for (member_pos = 0; member_pos < base_members_length; ++member_pos) { emit_ldarg(code, member_pos + 1); param_types[member_pos] = all_param_types[member_pos]; } code.Emit(OpCodes.Call, base_type_entry == null ? base_type.GetConstructor(param_types) : base_type_entry.m_ctor); // initialize members for (member_pos = 0; member_pos < seq_members.Length; ++member_pos) { code.Emit(OpCodes.Ldarg_0); // push this emit_ldarg(code, member_pos + base_members_length + 1); code.Emit(OpCodes.Stfld, members[member_pos]); } code.Emit(OpCodes.Ret); entry.m_ctor = ctor_builder; if (Climaker.g_verbose) { Console.WriteLine("> emitting {0} type {1}", xType.getTypeClass() == TypeClass.STRUCT ? "struct" : "exception", cts_name); } // new entry m_generated_structs.Add(cts_name, entry); ret_type = type_builder.CreateType(); } return ret_type; }
private static MethodBuilder CreateConstructorAndDispatch(DynamicTypeWrapper.FinishContext context, ClassFile.ConstantPoolItemInvokeDynamic cpi, TypeBuilder tb, List<MethodWrapper> methods, TypeWrapper[] implParameters, ClassFile.ConstantPoolItemMethodType samMethodType, ClassFile.ConstantPoolItemMethodHandle implMethod, ClassFile.ConstantPoolItemMethodType instantiatedMethodType, bool serializable) { TypeWrapper[] args = cpi.GetArgTypes(); // captured values Type[] capturedTypes = new Type[args.Length]; FieldBuilder[] capturedFields = new FieldBuilder[capturedTypes.Length]; for (int i = 0; i < capturedTypes.Length; i++) { capturedTypes[i] = args[i].TypeAsSignatureType; FieldAttributes attr = FieldAttributes.Private; if (i > 0 || !args[0].IsGhost) { attr |= FieldAttributes.InitOnly; } capturedFields[i] = tb.DefineField("arg$" + (i + 1), capturedTypes[i], attr); } // constructor MethodBuilder ctor = ReflectUtil.DefineConstructor(tb, MethodAttributes.Assembly, capturedTypes); CodeEmitter ilgen = CodeEmitter.Create(ctor); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Call, Types.Object.GetConstructor(Type.EmptyTypes)); for (int i = 0; i < capturedTypes.Length; i++) { ilgen.EmitLdarg(0); ilgen.EmitLdarg(i + 1); ilgen.Emit(OpCodes.Stfld, capturedFields[i]); } ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); // dispatch methods foreach (MethodWrapper mw in methods) { EmitDispatch(context, args, tb, mw, implParameters, implMethod, instantiatedMethodType, capturedFields); } // writeReplace method if (serializable) { MethodBuilder writeReplace = tb.DefineMethod("writeReplace", MethodAttributes.Private, Types.Object, Type.EmptyTypes); ilgen = CodeEmitter.Create(writeReplace); context.TypeWrapper.EmitClassLiteral(ilgen); ilgen.Emit(OpCodes.Ldstr, cpi.GetRetType().Name.Replace('.', '/')); ilgen.Emit(OpCodes.Ldstr, cpi.Name); ilgen.Emit(OpCodes.Ldstr, samMethodType.Signature.Replace('.', '/')); ilgen.EmitLdc_I4((int)implMethod.Kind); ilgen.Emit(OpCodes.Ldstr, implMethod.Class.Replace('.', '/')); ilgen.Emit(OpCodes.Ldstr, implMethod.Name); ilgen.Emit(OpCodes.Ldstr, implMethod.Signature.Replace('.', '/')); ilgen.Emit(OpCodes.Ldstr, instantiatedMethodType.Signature.Replace('.', '/')); ilgen.EmitLdc_I4(capturedFields.Length); ilgen.Emit(OpCodes.Newarr, Types.Object); for (int i = 0; i < capturedFields.Length; i++) { ilgen.Emit(OpCodes.Dup); ilgen.EmitLdc_I4(i); ilgen.EmitLdarg(0); ilgen.Emit(OpCodes.Ldfld, capturedFields[i]); if (args[i].IsPrimitive) { Boxer.EmitBox(ilgen, args[i]); } else if (args[i].IsGhost) { args[i].EmitConvSignatureTypeToStackType(ilgen); } ilgen.Emit(OpCodes.Stelem, Types.Object); } MethodWrapper ctorSerializedLambda = ClassLoaderWrapper.LoadClassCritical("java.lang.invoke.SerializedLambda").GetMethodWrapper(StringConstants.INIT, "(Ljava.lang.Class;Ljava.lang.String;Ljava.lang.String;Ljava.lang.String;ILjava.lang.String;Ljava.lang.String;Ljava.lang.String;Ljava.lang.String;[Ljava.lang.Object;)V", false); ctorSerializedLambda.Link(); ctorSerializedLambda.EmitNewobj(ilgen); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); if (!context.TypeWrapper.GetClassLoader().NoAutomagicSerialization) { // add .NET serialization interop support Serialization.MarkSerializable(tb); Serialization.AddGetObjectData(tb); } } return ctor; }
public void InsertFieldWithFieldBuilderException() { Document doc = new Document(); //Add some text into the paragraph Run run = DocumentHelper.InsertNewRun(doc, " Hello World!", 0); FieldArgumentBuilder argumentBuilder = new FieldArgumentBuilder(); argumentBuilder.AddField(new FieldBuilder(FieldType.FieldMergeField)); argumentBuilder.AddNode(run); argumentBuilder.AddText("Text argument builder"); FieldBuilder fieldBuilder = new FieldBuilder(FieldType.FieldIncludeText); Assert.That(() => fieldBuilder.AddArgument(argumentBuilder).AddArgument("=").AddArgument("BestField").AddArgument(10).AddArgument(20.0).BuildAndInsert(run), Throws.TypeOf<ArgumentException>()); }
internal override void Apply(ClassLoaderWrapper loader, FieldBuilder fb, object annotation) { }
private static MethodBuilder BuildGetter(TypeBuilder typeBuilder, PropertyInfo property, FieldBuilder fieldBuilder, MethodAttributes attributes) { var getterBuilder = typeBuilder.DefineMethod($"get_{property.Name}", attributes, property.PropertyType, Type.EmptyTypes); var ilGenerator = getterBuilder.GetILGenerator(); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldfld, fieldBuilder); if (property.IsDefined(typeof(RequiredAttribute))) { // Build null check ilGenerator.Emit(OpCodes.Dup); var isFieldNull = ilGenerator.DefineLabel(); ilGenerator.Emit(OpCodes.Brtrue_S, isFieldNull); ilGenerator.Emit(OpCodes.Pop); ilGenerator.Emit(OpCodes.Ldstr, $"{property.Name} isn't set."); var invalidOperationExceptionConstructor = typeof(InvalidOperationException).GetConstructor(new Type[] { typeof(string) }); ilGenerator.Emit(OpCodes.Newobj, invalidOperationExceptionConstructor); ilGenerator.Emit(OpCodes.Throw); ilGenerator.MarkLabel(isFieldNull); } ilGenerator.Emit(OpCodes.Ret); return(getterBuilder); }
public static void Main() { // An assembly consists of one or more modules, each of which // contains zero or more types. This code creates a single-module // assembly, the most common case. The module contains one type, // named "MyDynamicType", that has a private field, a property // that gets and sets the private field, constructors that // initialize the private field, and a method that multiplies // a user-supplied number by the private field value and returns // the result. In C# the type might look like this: /* * public class MyDynamicType * { * private int m_number; * * public MyDynamicType() : this(42) {} * public MyDynamicType(int initNumber) * { * m_number = initNumber; * } * * public int Number * { * get { return m_number; } * set { m_number = value; } * } * * public int MyMethod(int multiplier) * { * return m_number * multiplier; * } * } */ AssemblyName aName = new AssemblyName("DynamicAssemblyExample"); AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly( aName, AssemblyBuilderAccess.RunAndSave); // For a single-module assembly, the module name is usually // the assembly name plus an extension. ModuleBuilder mb = ab.DefineDynamicModule(aName.Name, aName.Name + ".dll"); TypeBuilder tb = mb.DefineType( "MyDynamicType", TypeAttributes.Public); // Add a private field of type int (Int32). FieldBuilder fbNumber = tb.DefineField( "m_number", typeof(int), FieldAttributes.Private); // Define a constructor that takes an integer argument and // stores it in the private field. Type[] parameterTypes = { typeof(int) }; ConstructorBuilder ctor1 = tb.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, parameterTypes); ILGenerator ctor1IL = ctor1.GetILGenerator(); // For a constructor, argument zero is a reference to the new // instance. Push it on the stack before calling the base // class constructor. Specify the default constructor of the // base class (System.Object) by passing an empty array of // types (Type.EmptyTypes) to GetConstructor. ctor1IL.Emit(OpCodes.Ldarg_0); ctor1IL.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes)); // Push the instance on the stack before pushing the argument // that is to be assigned to the private field m_number. ctor1IL.Emit(OpCodes.Ldarg_0); ctor1IL.Emit(OpCodes.Ldarg_1); ctor1IL.Emit(OpCodes.Stfld, fbNumber); ctor1IL.Emit(OpCodes.Ret); // Define a default constructor that supplies a default value // for the private field. For parameter types, pass the empty // array of types or pass null. ConstructorBuilder ctor0 = tb.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes); ILGenerator ctor0IL = ctor0.GetILGenerator(); // For a constructor, argument zero is a reference to the new // instance. Push it on the stack before pushing the default // value on the stack, then call constructor ctor1. ctor0IL.Emit(OpCodes.Ldarg_0); ctor0IL.Emit(OpCodes.Ldc_I4_S, 42); ctor0IL.Emit(OpCodes.Call, ctor1); ctor0IL.Emit(OpCodes.Ret); // Define a property named Number that gets and sets the private // field. // // The last argument of DefineProperty is null, because the // property has no parameters. (If you don't specify null, you must // specify an array of Type objects. For a parameterless property, // use the built-in array with no elements: Type.EmptyTypes) PropertyBuilder pbNumber = tb.DefineProperty( "Number", PropertyAttributes.HasDefault, typeof(int), null); // The property "set" and property "get" methods require a special // set of attributes. MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; // Define the "get" accessor method for Number. The method returns // an integer and has no arguments. (Note that null could be // used instead of Types.EmptyTypes) MethodBuilder mbNumberGetAccessor = tb.DefineMethod( "get_Number", getSetAttr, typeof(int), Type.EmptyTypes); ILGenerator numberGetIL = mbNumberGetAccessor.GetILGenerator(); // For an instance property, argument zero is the instance. Load the // instance, then load the private field and return, leaving the // field value on the stack. numberGetIL.Emit(OpCodes.Ldarg_0); numberGetIL.Emit(OpCodes.Ldfld, fbNumber); numberGetIL.Emit(OpCodes.Ret); // Define the "set" accessor method for Number, which has no return // type and takes one argument of type int (Int32). MethodBuilder mbNumberSetAccessor = tb.DefineMethod( "set_Number", getSetAttr, null, new Type[] { typeof(int) }); ILGenerator numberSetIL = mbNumberSetAccessor.GetILGenerator(); // Load the instance and then the numeric argument, then store the // argument in the field. numberSetIL.Emit(OpCodes.Ldarg_0); numberSetIL.Emit(OpCodes.Ldarg_1); numberSetIL.Emit(OpCodes.Stfld, fbNumber); numberSetIL.Emit(OpCodes.Ret); // Last, map the "get" and "set" accessor methods to the // PropertyBuilder. The property is now complete. pbNumber.SetGetMethod(mbNumberGetAccessor); pbNumber.SetSetMethod(mbNumberSetAccessor); // Define a method that accepts an integer argument and returns // the product of that integer and the private field m_number. This // time, the array of parameter types is created on the fly. MethodBuilder meth = tb.DefineMethod( "MyMethod", MethodAttributes.Public, typeof(int), new Type[] { typeof(int) }); ILGenerator methIL = meth.GetILGenerator(); // To retrieve the private instance field, load the instance it // belongs to (argument zero). After loading the field, load the // argument one and then multiply. Return from the method with // the return value (the product of the two numbers) on the // execution stack. methIL.Emit(OpCodes.Ldarg_0); methIL.Emit(OpCodes.Ldfld, fbNumber); methIL.Emit(OpCodes.Ldarg_1); methIL.Emit(OpCodes.Mul); methIL.Emit(OpCodes.Ret); // Finish the type. Type t = tb.CreateType(); // The following line saves the single-module assembly. This // requires AssemblyBuilderAccess to include Save. You can now // type "ildasm MyDynamicAsm.dll" at the command prompt, and // examine the assembly. You can also write a program that has // a reference to the assembly, and use the MyDynamicType type. // ab.Save(aName.Name + ".dll"); // Because AssemblyBuilderAccess includes Run, the code can be // executed immediately. Start by getting reflection objects for // the method and the property. MethodInfo mi = t.GetMethod("MyMethod"); PropertyInfo pi = t.GetProperty("Number"); // Create an instance of MyDynamicType using the default // constructor. object o1 = Activator.CreateInstance(t); // Display the value of the property, then change it to 127 and // display it again. Use null to indicate that the property // has no index. Console.WriteLine("o1.Number: {0}", pi.GetValue(o1, null)); pi.SetValue(o1, 127, null); Console.WriteLine("o1.Number: {0}", pi.GetValue(o1, null)); // Call MyMethod, passing 22, and display the return value, 22 // times 127. Arguments must be passed as an array, even when // there is only one. object[] arguments = { 22 }; Console.WriteLine("o1.MyMethod(22): {0}", mi.Invoke(o1, arguments)); // Create an instance of MyDynamicType using the constructor // that specifies m_Number. The constructor is identified by // matching the types in the argument array. In this case, // the argument array is created on the fly. Display the // property value. object o2 = Activator.CreateInstance(t, new object[] { 5280 }); Console.WriteLine("o2.Number: {0}", pi.GetValue(o2, null)); }
private void setFieldModifiers(FieldDeclarationNode fieldDeclaration, FieldBuilder fieldBuilder) { foreach (var modifier in fieldDeclaration.Modifiers) { switch (modifier) { case Public: if (fieldBuilder.IsPrivate || fieldBuilder.IsProtected) { context.addError(CompileErrorId.PublicProtectedPrivate, fieldDeclaration); } else { fieldBuilder.setPublic(true); } break; case Protected: if (fieldBuilder.IsPrivate || fieldBuilder.IsPublic) { context.addError(CompileErrorId.PublicProtectedPrivate, fieldDeclaration); } else { fieldBuilder.setProtected(true); } break; case Private: if (fieldBuilder.IsProtected || fieldBuilder.IsPublic) { context.addError(CompileErrorId.PublicProtectedPrivate, fieldDeclaration); } else { fieldBuilder.setPrivate(true); } break; case Final: if (fieldBuilder.IsVolatile) { context.addError(CompileErrorId.FinalVolatile, fieldDeclaration); } else { fieldBuilder.setFinal(true); } break; case Static: fieldBuilder.setStatic(true); break; case Transient: fieldBuilder.setTransient(true); break; case Volatile: if (fieldBuilder.IsFinal) { context.addError(CompileErrorId.FinalVolatile, fieldDeclaration); } else { fieldBuilder.setVolatile(true); } break; default: context.addError(CompileErrorId.UnexpectedModifier, fieldDeclaration, modifier.toString().toLowerCase()); break; } } }
private static TInterface Invoke <TInterface, TImp>(bool inheritMode = false) where TImp : class, new() where TInterface : class { var impType = typeof(TImp); string nameOfAssembly = impType.Name + "ProxyAssembly"; string nameOfModule = impType.Name + "ProxyModule"; string nameOfType = impType.Name + "Proxy"; AssemblyBuilder assembly = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(nameOfAssembly), AssemblyBuilderAccess.RunAndSave); ModuleBuilder moduleBuilder = assembly.DefineDynamicModule(nameOfModule, "1.dll"); TypeBuilder typeBuilder; if (inheritMode) { typeBuilder = moduleBuilder.DefineType(nameOfType, TypeAttributes.Public, impType); } else { typeBuilder = moduleBuilder.DefineType(nameOfType, TypeAttributes.Public, null, new[] { typeof(TInterface) }); } Type interceptorAttributeType = impType.GetCustomAttribute(typeof(InterceptorBaseAttribute))?.GetType(); // ---- define fields ---- FieldBuilder fieldInterceptor = null; if (interceptorAttributeType != null) { fieldInterceptor = typeBuilder.DefineField("_interceptor", interceptorAttributeType, FieldAttributes.Private); } // ---- define costructors ---- if (interceptorAttributeType != null) { var constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, null); var ilOfCtor = constructorBuilder.GetILGenerator(); ilOfCtor.Emit(OpCodes.Ldarg_0); ilOfCtor.Emit(OpCodes.Newobj, interceptorAttributeType.GetConstructor(new Type[0])); ilOfCtor.Emit(OpCodes.Stfld, fieldInterceptor); ilOfCtor.Emit(OpCodes.Ret); } // ---- define methods ---- var methodsOfType = impType.GetMethods(BindingFlags.Public | BindingFlags.Instance); string[] ignoreMethodName = new[] { "GetType", "ToString", "GetHashCode", "Equals" }; foreach (var method in methodsOfType) { //ignore method if (ignoreMethodName.Contains(method.Name)) { continue; } var methodParameterTypes = method.GetParameters().Select(p => p.ParameterType).ToArray(); MethodAttributes methodAttributes; if (inheritMode) { methodAttributes = MethodAttributes.Public | MethodAttributes.Virtual; } else { methodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final; } var methodBuilder = typeBuilder.DefineMethod(method.Name, methodAttributes, CallingConventions.Standard, method.ReturnType, methodParameterTypes); var ilMethod = methodBuilder.GetILGenerator(); // set local field var impObj = ilMethod.DeclareLocal(impType); //instance of imp object var methodName = ilMethod.DeclareLocal(typeof(string)); //instance of method name var parameters = ilMethod.DeclareLocal(typeof(object[])); //instance of parameters var result = ilMethod.DeclareLocal(typeof(object)); //instance of result var beforeFlag = ilMethod.DeclareLocal(typeof(bool)); //OnBefore of result var gLabel = ilMethod.DefineLabel(); LocalBuilder actionAttributeObj = null; //attribute init Type actionAttributeType = null; if (method.GetCustomAttribute(typeof(ActionBaseAttribute)) != null || impType.GetCustomAttribute(typeof(ActionBaseAttribute)) != null) { //method can override class attrubute if (method.GetCustomAttribute(typeof(ActionBaseAttribute)) != null) { actionAttributeType = method.GetCustomAttribute(typeof(ActionBaseAttribute)).GetType(); } else if (impType.GetCustomAttribute(typeof(ActionBaseAttribute)) != null) { actionAttributeType = impType.GetCustomAttribute(typeof(ActionBaseAttribute)).GetType(); } actionAttributeObj = ilMethod.DeclareLocal(actionAttributeType); ilMethod.Emit(OpCodes.Newobj, actionAttributeType.GetConstructor(new Type[0])); ilMethod.Emit(OpCodes.Stloc, actionAttributeObj); } //instance imp ilMethod.Emit(OpCodes.Newobj, impType.GetConstructor(new Type[0])); ilMethod.Emit(OpCodes.Stloc, impObj); //if no attribute if (fieldInterceptor != null || actionAttributeObj != null) { ilMethod.Emit(OpCodes.Ldstr, method.Name); ilMethod.Emit(OpCodes.Stloc, methodName); ilMethod.Emit(OpCodes.Ldc_I4, methodParameterTypes.Length); ilMethod.Emit(OpCodes.Newarr, typeof(object)); ilMethod.Emit(OpCodes.Stloc, parameters); // build the method parameters for (var j = 0; j < methodParameterTypes.Length; j++) { ilMethod.Emit(OpCodes.Ldloc, parameters); ilMethod.Emit(OpCodes.Ldc_I4, j); ilMethod.Emit(OpCodes.Ldarg, j + 1); //box ilMethod.Emit(OpCodes.Box, methodParameterTypes[j]); ilMethod.Emit(OpCodes.Stelem_Ref); } } //dynamic proxy action before if (actionAttributeType != null) { //load arguments ilMethod.Emit(OpCodes.Ldloc, actionAttributeObj); ilMethod.Emit(OpCodes.Ldloc, methodName); ilMethod.Emit(OpCodes.Ldloc, parameters); ilMethod.Emit(OpCodes.Call, actionAttributeType.GetMethod("OnBefore")); ilMethod.Emit(OpCodes.Stloc, beforeFlag); ilMethod.Emit(OpCodes.Ldloc, beforeFlag); ilMethod.Emit(OpCodes.Brfalse_S, gLabel); } if (interceptorAttributeType != null) { //load arguments ilMethod.Emit(OpCodes.Ldarg_0);//this ilMethod.Emit(OpCodes.Ldfld, fieldInterceptor); ilMethod.Emit(OpCodes.Ldloc, impObj); ilMethod.Emit(OpCodes.Ldloc, methodName); ilMethod.Emit(OpCodes.Ldloc, parameters); // call Invoke() method of Interceptor ilMethod.Emit(OpCodes.Callvirt, interceptorAttributeType.GetMethod("Invoke")); } else { //direct call method if (method.ReturnType == typeof(void) && actionAttributeType == null) { ilMethod.Emit(OpCodes.Ldnull); } ilMethod.Emit(OpCodes.Ldloc, impObj); for (var j = 0; j < methodParameterTypes.Length; j++) { ilMethod.Emit(OpCodes.Ldarg, j + 1); } ilMethod.Emit(OpCodes.Callvirt, impType.GetMethod(method.Name)); //box if (actionAttributeType != null) { if (method.ReturnType != typeof(void)) { ilMethod.Emit(OpCodes.Box, method.ReturnType); } else { ilMethod.Emit(OpCodes.Ldnull); } } } //dynamic proxy action after if (actionAttributeType != null) { ilMethod.Emit(OpCodes.Stloc, result); ilMethod.MarkLabel(gLabel); //load arguments ilMethod.Emit(OpCodes.Ldloc, actionAttributeObj); ilMethod.Emit(OpCodes.Ldloc, methodName); ilMethod.Emit(OpCodes.Ldloc, result); ilMethod.Emit(OpCodes.Call, actionAttributeType.GetMethod("OnAfter")); } // pop the stack if return void if (method.ReturnType == typeof(void)) { ilMethod.Emit(OpCodes.Pop); } else { //unbox,if direct invoke,no box if (fieldInterceptor != null || actionAttributeObj != null) { if (method.ReturnType.IsValueType) { ilMethod.Emit(OpCodes.Unbox_Any, method.ReturnType); } else { ilMethod.Emit(OpCodes.Castclass, method.ReturnType); } } } // complete ilMethod.Emit(OpCodes.Ret); } var t = typeBuilder.CreateTypeInfo(); assembly.Save("1.dll"); return(Activator.CreateInstance(t) as TInterface); }
private static void EmitDispatch(DynamicTypeWrapper.FinishContext context, TypeWrapper[] args, TypeBuilder tb, MethodWrapper interfaceMethod, TypeWrapper[] implParameters, ClassFile.ConstantPoolItemMethodHandle implMethod, ClassFile.ConstantPoolItemMethodType instantiatedMethodType, FieldBuilder[] capturedFields) { MethodBuilder mb = interfaceMethod.GetDefineMethodHelper().DefineMethod(context.TypeWrapper, tb, interfaceMethod.Name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final); if (interfaceMethod.Name != interfaceMethod.RealName) { tb.DefineMethodOverride(mb, (MethodInfo)interfaceMethod.GetMethod()); } CodeEmitter ilgen = CodeEmitter.Create(mb); for (int i = 0; i < capturedFields.Length; i++) { ilgen.EmitLdarg(0); OpCode opc = OpCodes.Ldfld; if (i == 0 && args[0].IsGhost) { switch (implMethod.Kind) { case ClassFile.RefKind.invokeInterface: case ClassFile.RefKind.invokeVirtual: case ClassFile.RefKind.invokeSpecial: opc = OpCodes.Ldflda; break; } } ilgen.Emit(opc, capturedFields[i]); } for (int i = 0, count = interfaceMethod.GetParameters().Length, k = capturedFields.Length; i < count; i++) { ilgen.EmitLdarg(i + 1); TypeWrapper Ui = interfaceMethod.GetParameters()[i]; TypeWrapper Ti = instantiatedMethodType.GetArgTypes()[i]; TypeWrapper Aj = implParameters[i + k]; if (Ui == PrimitiveTypeWrapper.BYTE) { ilgen.Emit(OpCodes.Conv_I1); } if (Ti != Ui) { if (Ti.IsGhost) { Ti.EmitConvStackTypeToSignatureType(ilgen, Ui); } else if (Ui.IsGhost) { Ui.EmitConvSignatureTypeToStackType(ilgen); } else { Ti.EmitCheckcast(ilgen); } } if (Ti != Aj) { if (Ti.IsPrimitive && !Aj.IsPrimitive) { Boxer.EmitBox(ilgen, Ti); } else if (!Ti.IsPrimitive && Aj.IsPrimitive) { TypeWrapper primitive = GetPrimitiveFromWrapper(Ti); Boxer.EmitUnbox(ilgen, primitive, false); if (primitive == PrimitiveTypeWrapper.BYTE) { ilgen.Emit(OpCodes.Conv_I1); } } else if (Aj == PrimitiveTypeWrapper.LONG) { ilgen.Emit(OpCodes.Conv_I8); } else if (Aj == PrimitiveTypeWrapper.FLOAT) { ilgen.Emit(OpCodes.Conv_R4); } else if (Aj == PrimitiveTypeWrapper.DOUBLE) { ilgen.Emit(OpCodes.Conv_R8); } } } switch (implMethod.Kind) { case ClassFile.RefKind.invokeVirtual: case ClassFile.RefKind.invokeInterface: ((MethodWrapper)implMethod.Member).EmitCallvirt(ilgen); break; case ClassFile.RefKind.newInvokeSpecial: ((MethodWrapper)implMethod.Member).EmitNewobj(ilgen); break; case ClassFile.RefKind.invokeStatic: case ClassFile.RefKind.invokeSpecial: ((MethodWrapper)implMethod.Member).EmitCall(ilgen); break; default: throw new InvalidOperationException(); } TypeWrapper Ru = interfaceMethod.ReturnType; TypeWrapper Ra = GetImplReturnType(implMethod); TypeWrapper Rt = instantiatedMethodType.GetRetType(); if (Ra == PrimitiveTypeWrapper.BYTE) { ilgen.Emit(OpCodes.Conv_I1); } if (Ra != Ru) { if (Ru == PrimitiveTypeWrapper.VOID) { ilgen.Emit(OpCodes.Pop); } else if (Ra.IsGhost) { Ra.EmitConvSignatureTypeToStackType(ilgen); } else if (Ru.IsGhost) { Ru.EmitConvStackTypeToSignatureType(ilgen, Ra); } } if (Ra != Rt) { if (Rt.IsPrimitive) { if (Rt == PrimitiveTypeWrapper.VOID) { // already popped } else if (!Ra.IsPrimitive) { TypeWrapper primitive = GetPrimitiveFromWrapper(Ra); if (primitive != null) { Boxer.EmitUnbox(ilgen, primitive, false); } else { // If Q is not a primitive wrapper, cast Q to the base Wrapper(S); for example Number for numeric types EmitConvertingUnbox(ilgen, Rt); } } else if (Rt == PrimitiveTypeWrapper.LONG) { ilgen.Emit(OpCodes.Conv_I8); } else if (Rt == PrimitiveTypeWrapper.FLOAT) { ilgen.Emit(OpCodes.Conv_R4); } else if (Rt == PrimitiveTypeWrapper.DOUBLE) { ilgen.Emit(OpCodes.Conv_R8); } } else if (Ra.IsPrimitive) { Boxer.EmitBox(ilgen, GetPrimitiveFromWrapper(Rt)); } else { Rt.EmitCheckcast(ilgen); } } ilgen.EmitTailCallPrevention(); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); }
private void EmitBuildCtor(string scope, TypeBuilder typeBuilder, FieldBuilder sqlMapperField, FieldBuilder scopeField) { var paramTypes = new Type[] { typeof(ISmartSqlMapper) }; var ctorBuilder = typeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, paramTypes); var ctorIL = ctorBuilder.GetILGenerator(); ctorIL.Emit(OpCodes.Ldarg_0); ctorIL.Emit(OpCodes.Call, (typeof(object).GetConstructor(Type.EmptyTypes))); ctorIL.Emit(OpCodes.Ldarg_0); ctorIL.Emit(OpCodes.Ldarg_1); ctorIL.Emit(OpCodes.Stfld, sqlMapperField); ctorIL.Emit(OpCodes.Ldarg_0); ctorIL.Emit(OpCodes.Ldstr, scope); ctorIL.Emit(OpCodes.Stfld, scopeField); ctorIL.Emit(OpCodes.Ret); }
internal override void Apply(ClassLoaderWrapper loader, FieldBuilder fb, object annotation) { Annotation annot = type.Annotation; foreach (object ann in UnwrapArray(annotation)) { annot.Apply(loader, fb, ann); } }
private void BuildMethod(TypeBuilder typeBuilder, MethodInfo methodInfo, FieldBuilder sqlMapperField, string scope) { var methodParams = methodInfo.GetParameters(); var paramTypes = methodParams.Select(m => m.ParameterType).ToArray(); if (paramTypes.Any(p => p.IsGenericParameter)) { _logger.LogError("SmartSql.DyRepository method parameters do not support generic parameters for the time being!"); throw new SmartSqlException("SmartSql.DyRepository method parameters do not support generic parameters for the time being!"); } var returnType = methodInfo.ReturnType; var implMehtod = typeBuilder.DefineMethod(methodInfo.Name , MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final , returnType, paramTypes); var isTaskReturnType = _taskType.IsAssignableFrom(returnType); if (methodInfo.IsGenericMethod) { var genericArgs = methodInfo.GetGenericArguments(); var gArgNames = genericArgs.Select(gArg => gArg.Name).ToArray(); var defineGenericArgs = implMehtod.DefineGenericParameters(gArgNames); for (int i = 0; i < gArgNames.Length; i++) { var genericArg = genericArgs[i]; var defineGenericArg = defineGenericArgs[i]; defineGenericArg.SetGenericParameterAttributes(genericArg.GenericParameterAttributes); } } StatementAttribute statementAttr = PreStatement(scope, methodInfo, returnType, isTaskReturnType); var ilGenerator = implMehtod.GetILGenerator(); ilGenerator.DeclareLocal(_reqContextType); ilGenerator.DeclareLocal(_reqParamsDicType); if (paramTypes.Length == 1 && paramTypes.First() == _reqContextType) { ilGenerator.Emit(OpCodes.Ldarg_1); ilGenerator.Emit(OpCodes.Stloc_0); } else { EmitNewRequestContext(ilGenerator); if (String.IsNullOrEmpty(statementAttr.Sql)) { EmitSetScope(ilGenerator, statementAttr.Scope); EmitSetSqlId(ilGenerator, statementAttr); } else { EmitSetRealSql(ilGenerator, statementAttr); } if (paramTypes.Length == 1 && !IsSimpleParam(paramTypes.First())) { ilGenerator.Emit(OpCodes.Ldloc_0); ilGenerator.Emit(OpCodes.Ldarg_1); ilGenerator.Emit(OpCodes.Call, _set_RequestMethod); } else if (paramTypes.Length > 0) { ilGenerator.Emit(OpCodes.Newobj, _reqParamsDicCtor); ilGenerator.Emit(OpCodes.Stloc_1); for (int i = 0; i < methodParams.Length; i++) { int argIndex = i + 1; var reqParam = methodParams[i]; if (reqParam.ParameterType == typeof(DataSourceChoice)) { ilGenerator.Emit(OpCodes.Ldloc_0); EmitUtils.LoadArg(ilGenerator, argIndex); ilGenerator.Emit(OpCodes.Call, _set_DataSourceChoiceMethod); continue; } if (reqParam.ParameterType == typeof(CommandType)) { ilGenerator.Emit(OpCodes.Ldloc_0); EmitUtils.LoadArg(ilGenerator, argIndex); ilGenerator.Emit(OpCodes.Call, _set_CommandTypeMethod); continue; } ilGenerator.Emit(OpCodes.Ldloc_1); //[dic] ilGenerator.Emit(OpCodes.Ldstr, reqParam.Name); //[dic][param-name] EmitUtils.LoadArg(ilGenerator, argIndex); if (reqParam.ParameterType.IsValueType) { ilGenerator.Emit(OpCodes.Box, reqParam.ParameterType); } ilGenerator.Emit(OpCodes.Call, _addReqParamMehtod);//[empty] } ilGenerator.Emit(OpCodes.Ldloc_0); ilGenerator.Emit(OpCodes.Ldloc_1); ilGenerator.Emit(OpCodes.Call, _set_RequestMethod); } } MethodInfo executeMethod = null; executeMethod = PreExecuteMethod(statementAttr, returnType, isTaskReturnType); ilGenerator.Emit(OpCodes.Ldarg_0); // [this] ilGenerator.Emit(OpCodes.Ldfld, sqlMapperField); //[this][sqlMapper] ilGenerator.Emit(OpCodes.Ldloc_0); //[sqlMapper][requestContext] ilGenerator.Emit(OpCodes.Call, executeMethod); if (returnType == _voidType) { ilGenerator.Emit(OpCodes.Pop); } ilGenerator.Emit(OpCodes.Ret); if (_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug($"RepositoryBuilder.BuildMethod:{methodInfo.Name}->Statement:[Scope:{statementAttr.Scope},Id:{statementAttr.Id},Execute:{statementAttr.Execute},Sql:{statementAttr.Sql},IsAsync:{isTaskReturnType}]"); } }
private void WriteConstructors(TypeBuilder type, ref int index, SerializerPair[] methodPairs, ref ILGenerator il, int knownTypesCategory, FieldBuilder knownTypes, Type knownTypesLookupType, Compiler.CompilerContext ctx) { type.DefineDefaultConstructor(MethodAttributes.Public); il = type.DefineTypeInitializer().GetILGenerator(); switch (knownTypesCategory) { case KnownTypes_Array: { Compiler.CompilerContext.LoadValue(il, types.Count); il.Emit(OpCodes.Newarr, ctx.MapType(typeof(System.Type))); index = 0; foreach (SerializerPair pair in methodPairs) { il.Emit(OpCodes.Dup); Compiler.CompilerContext.LoadValue(il, index); il.Emit(OpCodes.Ldtoken, pair.Type.Type); il.EmitCall(OpCodes.Call, ctx.MapType(typeof(System.Type)).GetMethod("GetTypeFromHandle"), null); il.Emit(OpCodes.Stelem_Ref); index++; } il.Emit(OpCodes.Stsfld, knownTypes); il.Emit(OpCodes.Ret); } break; case KnownTypes_Dictionary: { Compiler.CompilerContext.LoadValue(il, types.Count); //LocalBuilder loc = il.DeclareLocal(knownTypesLookupType); il.Emit(OpCodes.Newobj, knownTypesLookupType.GetConstructor(new Type[] { MapType(typeof(int)) })); il.Emit(OpCodes.Stsfld, knownTypes); int typeIndex = 0; foreach (SerializerPair pair in methodPairs) { il.Emit(OpCodes.Ldsfld, knownTypes); il.Emit(OpCodes.Ldtoken, pair.Type.Type); il.EmitCall(OpCodes.Call, ctx.MapType(typeof(System.Type)).GetMethod("GetTypeFromHandle"), null); int keyIndex = typeIndex++, lastKey = pair.BaseKey; if (lastKey != pair.MetaKey) // not a base-type; need to give the index of the base-type { keyIndex = -1; // assume epic fail for (int j = 0; j < methodPairs.Length; j++) { if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey) { keyIndex = j; break; } } } Compiler.CompilerContext.LoadValue(il, keyIndex); il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetMethod("Add", new Type[] { MapType(typeof(System.Type)), MapType(typeof(int)) }), null); } il.Emit(OpCodes.Ret); } break; case KnownTypes_Hashtable: { Compiler.CompilerContext.LoadValue(il, types.Count); il.Emit(OpCodes.Newobj, knownTypesLookupType.GetConstructor(new Type[] { MapType(typeof(int)) })); il.Emit(OpCodes.Stsfld, knownTypes); int typeIndex = 0; foreach (SerializerPair pair in methodPairs) { il.Emit(OpCodes.Ldsfld, knownTypes); il.Emit(OpCodes.Ldtoken, pair.Type.Type); il.EmitCall(OpCodes.Call, ctx.MapType(typeof(System.Type)).GetMethod("GetTypeFromHandle"), null); int keyIndex = typeIndex++, lastKey = pair.BaseKey; if (lastKey != pair.MetaKey) // not a base-type; need to give the index of the base-type { keyIndex = -1; // assume epic fail for (int j = 0; j < methodPairs.Length; j++) { if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey) { keyIndex = j; break; } } } Compiler.CompilerContext.LoadValue(il, keyIndex); il.Emit(OpCodes.Box, MapType(typeof(int))); il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetMethod("Add", new Type[] { MapType(typeof(object)), MapType(typeof(object)) }), null); } il.Emit(OpCodes.Ret); } break; default: throw new InvalidOperationException(); } }
/// <summary> /// Add a Property To the new Type /// </summary> /// <param name="name">name of the Property</param> /// <param name="myTypeBuilder">The TypeBuidler Object</param> /// <param name="o">The default value for that Property</param> /// <param name="category">Category the Property is assigned to</param> /// <param name="description">Description for this Category</param> /// <param name="ro">true if this Item should be ReadOnly</param> protected static void AddProperty(string name, TypeBuilder myTypeBuilder, object o, string description, string category, bool ro) { Type type = o.GetType(); FieldBuilder customerNameBldr = myTypeBuilder.DefineField("_" + name.ToLower(), type, FieldAttributes.Private); PropertyBuilder custNamePropBldr = myTypeBuilder.DefineProperty( name, PropertyAttributes.HasDefault, type, new Type[] { }); //Define Category-Attribute if (category != null) { if (category != "") { PropertyObjectBuilderExt.AddAttribute(custNamePropBldr, typeof(CategoryAttribute), category); } } //Define Description-Attribute if (description != null) { PropertyObjectBuilderExt.AddAttribute(custNamePropBldr, typeof(DescriptionAttribute), description); } PropertyObjectBuilderExt.AddAttribute(custNamePropBldr, typeof(ReadOnlyAttribute), ro); //AddAttribute(custNamePropBldr, typeof(DefaultValueAttribute), o, true); // First, we'll define the behavior of the "get" property for CustomerName as a method. MethodBuilder custNameGetPropMthdBldr = myTypeBuilder.DefineMethod("Get" + name, MethodAttributes.Public, type, new Type[] { }); ILGenerator custNameGetIL = custNameGetPropMthdBldr.GetILGenerator(); custNameGetIL.Emit(OpCodes.Ldarg_0); custNameGetIL.Emit(OpCodes.Ldfld, customerNameBldr); custNameGetIL.Emit(OpCodes.Ret); // Now, we'll define the behavior of the "set" property for CustomerName. MethodBuilder custNameSetPropMthdBldr = myTypeBuilder.DefineMethod("Set" + name, MethodAttributes.Public, null, new Type[] { type }); ILGenerator custNameSetIL = custNameSetPropMthdBldr.GetILGenerator(); custNameSetIL.Emit(OpCodes.Ldarg_0); custNameSetIL.Emit(OpCodes.Ldarg_1); custNameSetIL.Emit(OpCodes.Stfld, customerNameBldr); custNameSetIL.Emit(OpCodes.Ret); // Last, we must map the two methods created above to our PropertyBuilder to // their corresponding behaviors, "get" and "set" respectively. custNamePropBldr.SetGetMethod(custNameGetPropMthdBldr); custNamePropBldr.SetSetMethod(custNameSetPropMthdBldr); }
private static void CreateProperty(TypeBuilder tb, Property property) { var propType = UpdatePropertyType(property); //Type editorType = typeof(StringEditorControl); FieldBuilder fieldBuilder = tb.DefineField("_" + property.Name, /*Type dynamic property (or type editor view model)*/ propType, FieldAttributes.Private); PropertyBuilder propertyBuilder = tb.DefineProperty(property.Name, PropertyAttributes.HasDefault, /*Type dynamic property (or type editor view model)*/ propType, null); ConstructorInfo displayCtor = typeof(CategoryAttribute).GetConstructor(new[] { typeof(string) }); if (displayCtor != null) { CustomAttributeBuilder displayAttrib = new CustomAttributeBuilder(displayCtor, new object[] { property.CatalogName }); propertyBuilder.SetCustomAttribute(displayAttrib); } //ConstructorInfo editorCtor = // typeof(TelerikGrid.EditorAttribute).GetConstructor(new[] { typeof(Type) }); //if (editorCtor != null) //{ // // todo: need all custom view editors // CustomAttributeBuilder editorAttrib = new CustomAttributeBuilder(editorCtor, // new object[] { editorType }); // propertyBuilder.SetCustomAttribute(editorAttrib); //} MethodBuilder getPropMthdBldr = tb.DefineMethod("get_" + property.Name, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, /*Type dynamic property (or type editor view model)*/ propType, 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_" + property.Name, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new[] { /*Type dynamic property (or type editor view model)*/ propType }); 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); }
private static void WriteMapImpl(ILGenerator il, Type type, List <MemberInfo> members, FieldBuilder mapField, bool allowNonPublicAccessors, bool isGet) { OpCode obj, index, value; Label fail = il.DefineLabel(); if (mapField == null) { index = OpCodes.Ldarg_0; obj = OpCodes.Ldarg_1; value = OpCodes.Ldarg_2; } else { il.DeclareLocal(typeof(int)); index = OpCodes.Ldloc_0; obj = OpCodes.Ldarg_1; value = OpCodes.Ldarg_3; il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, mapField); il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Ldloca_S, (byte)0); il.EmitCall(OpCodes.Callvirt, tryGetValue, null); il.Emit(OpCodes.Brfalse, fail); } Label[] labels = new Label[members.Count]; for (int i = 0; i < labels.Length; i++) { labels[i] = il.DefineLabel(); } il.Emit(index); il.Emit(OpCodes.Switch, labels); il.MarkLabel(fail); il.Emit(OpCodes.Ldstr, "name"); il.Emit(OpCodes.Newobj, typeof(ArgumentOutOfRangeException).GetConstructor(new Type[] { typeof(string) })); il.Emit(OpCodes.Throw); for (int i = 0; i < labels.Length; i++) { il.MarkLabel(labels[i]); var member = members[i]; bool isFail = true; switch (member.MemberType) { case MemberTypes.Field: var field = (FieldInfo)member; il.Emit(obj); Cast(il, type, true); if (isGet) { il.Emit(OpCodes.Ldfld, field); if (field.FieldType.IsValueType) { il.Emit(OpCodes.Box, field.FieldType); } } else { il.Emit(value); Cast(il, field.FieldType, false); il.Emit(OpCodes.Stfld, field); } il.Emit(OpCodes.Ret); isFail = false; break; case MemberTypes.Property: var prop = (PropertyInfo)member; MethodInfo accessor; if (prop.CanRead && (accessor = isGet ? prop.GetGetMethod(allowNonPublicAccessors) : prop.GetSetMethod(allowNonPublicAccessors)) != null) { il.Emit(obj); Cast(il, type, true); if (isGet) { il.EmitCall(type.IsValueType ? OpCodes.Call : OpCodes.Callvirt, accessor, null); if (prop.PropertyType.IsValueType) { il.Emit(OpCodes.Box, prop.PropertyType); } } else { il.Emit(value); Cast(il, prop.PropertyType, false); il.EmitCall(type.IsValueType ? OpCodes.Call : OpCodes.Callvirt, accessor, null); } il.Emit(OpCodes.Ret); isFail = false; } break; } if (isFail) { il.Emit(OpCodes.Br, fail); } } }