System.Reflection.Emit.ILGenerator.Emit(System.Reflection.Emit.OpCode, System.Reflection.Emit.LocalBuilder)

Here are the examples of the csharp api System.Reflection.Emit.ILGenerator.Emit(System.Reflection.Emit.OpCode, System.Reflection.Emit.LocalBuilder) taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.

1021 Examples 7

19 View Source File : EntityMapperProvider.cs
License : Apache License 2.0
Project Creator : 1448376744

private Func<IDataRecord, T> CreateTypeSerializerHandler<T>(MemberMapper mapper, IDataRecord record)
        {
            var type = typeof(T);
            var methodName = $"Serializer{Guid.NewGuid():N}";
            var dynamicMethod = new DynamicMethod(methodName, type, new Type[] { typeof(IDataRecord) }, type, true);
            var generator = dynamicMethod.GetILGenerator();
            LocalBuilder local = generator.DeclareLocal(type);
            var dataInfos = new DataReaderCellInfo[record.FieldCount];
            for (int i = 0; i < record.FieldCount; i++)
            {
                var dataname = record.GetName(i);
                var datatype = record.GetFieldType(i);
                var typename = record.GetDataTypeName(i);
                dataInfos[i] = new DataReaderCellInfo(i, typename, datatype, dataname);
            }
            if (dataInfos.Length == 1 && (type.IsValueType || type == typeof(string) || type == typeof(object)))
            {
                var dataInfo = dataInfos.First();
                var convertMethod = mapper.FindConvertMethod(type, dataInfo.DataType);
                generator.Emit(OpCodes.Ldarg_0);
                generator.Emit(OpCodes.Ldc_I4, 0);
                if (convertMethod.IsVirtual)
                    generator.Emit(OpCodes.Callvirt, convertMethod);
                else
                    generator.Emit(OpCodes.Call, convertMethod);
                if (type == typeof(object) && convertMethod.ReturnType.IsValueType)
                {
                    generator.Emit(OpCodes.Box, convertMethod.ReturnType);
                }
                generator.Emit(OpCodes.Stloc, local);
                generator.Emit(OpCodes.Ldloc, local);
                generator.Emit(OpCodes.Ret);
                return dynamicMethod.CreateDelegate(typeof(Func<IDataRecord, T>)) as Func<IDataRecord, T>;
            }
            var constructor = mapper.FindConstructor(type);
            if (constructor.GetParameters().Length > 0)
            {
                var parameters = constructor.GetParameters();
                var locals = new LocalBuilder[parameters.Length];
                for (int i = 0; i < locals.Length; i++)
                {
                    locals[i] = generator.DeclareLocal(parameters[i].ParameterType);
                }
                for (int i = 0; i < locals.Length; i++)
                {
                    var item = mapper.FindConstructorParameter(dataInfos, parameters[i]);
                    if (item == null)
                    {
                        continue;
                    }
                    var convertMethod = mapper.FindConvertMethod(parameters[i].ParameterType, item.DataType);
                    generator.Emit(OpCodes.Ldarg_0);
                    generator.Emit(OpCodes.Ldc_I4, item.Ordinal);
                    if (convertMethod.IsVirtual)
                        generator.Emit(OpCodes.Callvirt, convertMethod);
                    else
                        generator.Emit(OpCodes.Call, convertMethod);
                    generator.Emit(OpCodes.Stloc, locals[i]);
                }
                for (int i = 0; i < locals.Length; i++)
                {
                    generator.Emit(OpCodes.Ldloc, locals[i]);
                }
                generator.Emit(OpCodes.Newobj, constructor);
                generator.Emit(OpCodes.Stloc, local);
                generator.Emit(OpCodes.Ldloc, local);
                generator.Emit(OpCodes.Ret);
                return dynamicMethod.CreateDelegate(typeof(Func<IDataRecord, T>)) as Func<IDataRecord, T>;
            }
            else
            {
                var properties = type.GetProperties();
                generator.Emit(OpCodes.Newobj, constructor);
                generator.Emit(OpCodes.Stloc, local);
                foreach (var item in dataInfos)
                {
                    var property = mapper.FindMember(properties, item) as PropertyInfo;
                    if (property == null)
                    {
                        continue;
                    }
                    var convertMethod = mapper.FindConvertMethod(property.PropertyType, item.DataType);
                    if (convertMethod == null)
                    {
                        continue;
                    }
                    int i = record.GetOrdinal(item.DataName);
                    generator.Emit(OpCodes.Ldloc, local);
                    generator.Emit(OpCodes.Ldarg_0);
                    generator.Emit(OpCodes.Ldc_I4, i);
                    if (convertMethod.IsVirtual)
                        generator.Emit(OpCodes.Callvirt, convertMethod);
                    else
                        generator.Emit(OpCodes.Call, convertMethod);
                    generator.Emit(OpCodes.Callvirt, property.GetSetMethod());
                }
                generator.Emit(OpCodes.Ldloc, local);
                generator.Emit(OpCodes.Ret);
                return dynamicMethod.CreateDelegate(typeof(Func<IDataRecord, T>)) as Func<IDataRecord, T>;
            }
        }

19 View Source File : EntityMapperProvider.cs
License : Apache License 2.0
Project Creator : 1448376744

private Func<object, Dictionary<string, object>> CreateTypeDeserializerHandler(Type type)
        {
            var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            var methodName = $"{type.Name}Deserializer{Guid.NewGuid():N}";
            var dynamicMethod = new DynamicMethod(methodName, typeof(Dictionary<string, object>), new Type[] { typeof(object) }, type, true);
            var generator = dynamicMethod.GetILGenerator();
            LocalBuilder enreplacedyLocal1 = generator.DeclareLocal(typeof(Dictionary<string, object>));
            LocalBuilder enreplacedyLocal2 = generator.DeclareLocal(type);
            generator.Emit(OpCodes.Newobj, typeof(Dictionary<string, object>).GetConstructor(Type.EmptyTypes));
            generator.Emit(OpCodes.Stloc, enreplacedyLocal1);
            generator.Emit(OpCodes.Ldarg_0);
            generator.Emit(OpCodes.Castclreplaced, type);
            generator.Emit(OpCodes.Stloc, enreplacedyLocal2);
            foreach (var item in properties)
            {
                generator.Emit(OpCodes.Ldloc, enreplacedyLocal1);
                generator.Emit(OpCodes.Ldstr, item.Name);
                generator.Emit(OpCodes.Ldloc, enreplacedyLocal2);
                generator.Emit(OpCodes.Callvirt, item.GetGetMethod());
                if (item.PropertyType.IsValueType)
                {
                    generator.Emit(OpCodes.Box, item.PropertyType);
                }
                var addMethod = typeof(Dictionary<string, object>).GetMethod(nameof(Dictionary<string, object>.Add), new Type[] { typeof(string), typeof(object) });
                generator.Emit(OpCodes.Callvirt, addMethod);
            }
            generator.Emit(OpCodes.Ldloc, enreplacedyLocal1);
            generator.Emit(OpCodes.Ret);
            return dynamicMethod.CreateDelegate(typeof(Func<object, Dictionary<string, object>>)) as Func<object, Dictionary<string, object>>;
        }

19 View Source File : EmitHelper.cs
License : MIT License
Project Creator : 1996v

public static void EmitDefault(this ILGenerator il, Type type)
        {
            switch (Type.GetTypeCode(type))
            {
                case TypeCode.DateTime:
                    il.Emit(OpCodes.Ldsfld, typeof(DateTime).GetField(nameof(DateTime.MinValue)));
                    return;
                case TypeCode.Decimal:
                    il.Emit(OpCodes.Ldsfld, typeof(decimal).GetField(nameof(decimal.Zero)));
                    return;
                case TypeCode.Boolean:
                case TypeCode.Char:
                case TypeCode.SByte:
                case TypeCode.Byte:
                case TypeCode.Int16:
                case TypeCode.UInt16:
                case TypeCode.Int32:
                case TypeCode.UInt32:
                    il.Emit(OpCodes.Ldc_I4_0);
                    return;

                case TypeCode.Int64:
                case TypeCode.UInt64:
                    il.Emit(OpCodes.Ldc_I4_0);
                    il.Emit(OpCodes.Conv_I8);
                    return;

                case TypeCode.Single:
                    il.Emit(OpCodes.Ldc_R4, default(float));
                    return;

                case TypeCode.Double:
                    il.Emit(OpCodes.Ldc_R8, default(double));
                    return;
            }

            if (type.IsValueType)
            {
                LocalBuilder lb = il.DeclareLocal(type);
                il.Emit(OpCodes.Ldloca, lb);
                il.Emit(OpCodes.Initobj, type);
                il.Emit(OpCodes.Ldloc, lb);
            }
            else
            {
                il.Emit(OpCodes.Ldnull);
            }
        }

19 View Source File : ReaderCache.cs
License : Apache License 2.0
Project Creator : aadreja

internal static Func<IDataReader, T> ReaderToObject(IDataReader rdr)
        {
            MethodInfo rdrGetValueMethod = rdr.GetType().GetMethod("get_Item", new Type[] { typeof(int) });

            Type[] args = { typeof(IDataReader) };
            DynamicMethod method = new DynamicMethod("DynamicRead" + Guid.NewGuid().ToString(), typeof(T), args, typeof(Repository<T>).Module, true);
            ILGenerator il = method.GetILGenerator();

            LocalBuilder result = il.DeclareLocal(typeof(T)); //loc_0
            il.Emit(OpCodes.Newobj, typeof(T).GetConstructor(Type.EmptyTypes));
            il.Emit(OpCodes.Stloc_0, result); //Pops the current value from the top of the evaluation stack and stores it in a the local variable list at a specified index.

            Label tryBlock = il.BeginExceptionBlock();

            LocalBuilder valueCopy = il.DeclareLocal(typeof(object)); //declare local variable to store object value. loc_1

            il.DeclareLocal(typeof(int)); //declare local variable to store index //loc_2
            il.Emit(OpCodes.Ldc_I4_0); //load 0 in index
            il.Emit(OpCodes.Stloc_2); //pop and save to local variable loc 2

            //get FieldInfo of all properties
            TableAttribute tableInfo = EnreplacedyCache.Get(typeof(T));

            for (int i = 0; i < rdr.FieldCount; i++)
            {
                tableInfo.Columns.TryGetValue(rdr.GetName(i), out ColumnAttribute columnInfo);

                if (columnInfo != null && columnInfo.SetMethod != null)
                {
                    Label endIfLabel = il.DefineLabel();

                    il.Emit(OpCodes.Ldarg_0);//load the argument. Loads the argument at index 0 onto the evaluation stack.
                    il.Emit(OpCodes.Ldc_I4, i); //push field index as int32 to the stack. Pushes a supplied value of type int32 onto the evaluation stack as an int32.
                    il.Emit(OpCodes.Dup);//copy value
                    il.Emit(OpCodes.Stloc_2);//pop and save value to loc 2
                    il.Emit(OpCodes.Callvirt, rdrGetValueMethod); //Call rdr[i] method - Calls a late - bound method on an object, pushing the return value onto the evaluation stack.

                    //TODO: dynamic location using valueCopyLocal
                    il.Emit(OpCodes.Stloc_1); //pop the value and push in stack location 1
                    il.Emit(OpCodes.Ldloc_1); //load the variable in location 1

                    il.Emit(OpCodes.Isinst, typeof(DBNull)); //check whether value is null - Tests whether an object reference (type O) is an instance of a particular clreplaced.
                    il.Emit(OpCodes.Brtrue, endIfLabel); //go to end block if value is null

                    il.Emit(OpCodes.Ldloc_0); //load T result
                    il.Emit(OpCodes.Ldloc_1); //TODO: dynamic location using valueCopyLocal

                    //when Enum are without number values
                    if (columnInfo.Property.PropertyType.IsEnum)
                    {
                        Type numericType = Enum.GetUnderlyingType(columnInfo.Property.PropertyType);
                        if (rdr.GetFieldType(i) == typeof(string))
                        {
                            LocalBuilder stringEnumLocal = il.DeclareLocal(typeof(string));

                            il.Emit(OpCodes.Castclreplaced, typeof(string)); // stack is now [...][string]
                            il.Emit(OpCodes.Stloc, stringEnumLocal); // stack is now [...]
                            il.Emit(OpCodes.Ldtoken, columnInfo.Property.PropertyType); // stack is now [...][enum-type-token]
                            il.EmitCall(OpCodes.Call, typeof(Type).GetMethod(nameof(Type.GetTypeFromHandle)), null);// stack is now [...][enum-type]
                            il.Emit(OpCodes.Ldloc, stringEnumLocal); // stack is now [...][enum-type][string]
                            il.Emit(OpCodes.Ldc_I4_1); // stack is now [...][enum-type][string][true]
                            il.EmitCall(OpCodes.Call, enumParse, null); // stack is now [...][enum-as-object]
                            il.Emit(OpCodes.Unbox_Any, columnInfo.Property.PropertyType); // stack is now [...][typed-value]
                        }
                        else
                        {
                            ConvertValueToEnum(il, rdr.GetFieldType(i), columnInfo.Property.PropertyType, numericType);
                        }
                    }
                    else if (columnInfo.Property.PropertyType.IsValueType)
                        il.Emit(OpCodes.Unbox_Any, rdr.GetFieldType(i)); //type cast

                    // for nullable type fields
                    if (columnInfo.Property.PropertyType.IsGenericType && columnInfo.Property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                    {
                        var underlyingType = Nullable.GetUnderlyingType(columnInfo.Property.PropertyType);
                        il.Emit(OpCodes.Newobj, columnInfo.Property.PropertyType.GetConstructor(new Type[] { underlyingType }));
                    }

                    il.Emit(OpCodes.Callvirt, columnInfo.SetMethod);
                    il.Emit(OpCodes.Nop);

                    il.MarkLabel(endIfLabel);
                }
            }

            il.BeginCatchBlock(typeof(Exception)); //begin try block. exception is in stack
            il.Emit(OpCodes.Ldloc_2); //load index
            il.Emit(OpCodes.Ldarg_0); //load argument reader
            il.Emit(OpCodes.Ldloc_1); //load value //TODO: dynamic location using valueCopyLocal
            il.EmitCall(OpCodes.Call, typeof(ReaderCache<T>).GetMethod(nameof(ReaderCache<T>.HandleException)), null); //call exception handler
            il.EndExceptionBlock();

            il.Emit(OpCodes.Ldloc, result);
            il.Emit(OpCodes.Ret);
            

            var funcType = System.Linq.Expressions.Expression.GetFuncType(typeof(IDataReader), typeof(T));
            return (Func<IDataReader, T>)method.CreateDelegate(funcType);
        }

19 View Source File : ReaderCache.cs
License : Apache License 2.0
Project Creator : aadreja

internal static Func<IDataReader, T> ReaderToObject(IDataReader rdr)
        {
            MethodInfo rdrGetValueMethod = rdr.GetType().GetMethod("get_Item", new Type[] { typeof(int) });

            Type[] args = { typeof(IDataReader) };
            DynamicMethod method = new DynamicMethod("DynamicRead" + Guid.NewGuid().ToString(), typeof(T), args, typeof(Repository<T>).Module, true);
            ILGenerator il = method.GetILGenerator();

            LocalBuilder result = il.DeclareLocal(typeof(T)); //loc_0
            il.Emit(OpCodes.Newobj, typeof(T).GetConstructor(Type.EmptyTypes));
            il.Emit(OpCodes.Stloc_0, result); //Pops the current value from the top of the evaluation stack and stores it in a the local variable list at a specified index.

            Label tryBlock = il.BeginExceptionBlock();

            LocalBuilder valueCopy = il.DeclareLocal(typeof(object)); //declare local variable to store object value. loc_1

            il.DeclareLocal(typeof(int)); //declare local variable to store index //loc_2
            il.Emit(OpCodes.Ldc_I4_0); //load 0 in index
            il.Emit(OpCodes.Stloc_2); //pop and save to local variable loc 2

            //get FieldInfo of all properties
            TableAttribute tableInfo = EnreplacedyCache.Get(typeof(T));

            for (int i = 0; i < rdr.FieldCount; i++)
            {
                tableInfo.Columns.TryGetValue(rdr.GetName(i), out ColumnAttribute columnInfo);

                if (columnInfo != null && columnInfo.SetMethod != null)
                {
                    Label endIfLabel = il.DefineLabel();

                    il.Emit(OpCodes.Ldarg_0);//load the argument. Loads the argument at index 0 onto the evaluation stack.
                    il.Emit(OpCodes.Ldc_I4, i); //push field index as int32 to the stack. Pushes a supplied value of type int32 onto the evaluation stack as an int32.
                    il.Emit(OpCodes.Dup);//copy value
                    il.Emit(OpCodes.Stloc_2);//pop and save value to loc 2
                    il.Emit(OpCodes.Callvirt, rdrGetValueMethod); //Call rdr[i] method - Calls a late - bound method on an object, pushing the return value onto the evaluation stack.

                    //TODO: dynamic location using valueCopyLocal
                    il.Emit(OpCodes.Stloc_1); //pop the value and push in stack location 1
                    il.Emit(OpCodes.Ldloc_1); //load the variable in location 1

                    il.Emit(OpCodes.Isinst, typeof(DBNull)); //check whether value is null - Tests whether an object reference (type O) is an instance of a particular clreplaced.
                    il.Emit(OpCodes.Brtrue, endIfLabel); //go to end block if value is null

                    il.Emit(OpCodes.Ldloc_0); //load T result
                    il.Emit(OpCodes.Ldloc_1); //TODO: dynamic location using valueCopyLocal

                    //when Enum are without number values
                    if (columnInfo.Property.PropertyType.IsEnum)
                    {
                        Type numericType = Enum.GetUnderlyingType(columnInfo.Property.PropertyType);
                        if (rdr.GetFieldType(i) == typeof(string))
                        {
                            LocalBuilder stringEnumLocal = il.DeclareLocal(typeof(string));

                            il.Emit(OpCodes.Castclreplaced, typeof(string)); // stack is now [...][string]
                            il.Emit(OpCodes.Stloc, stringEnumLocal); // stack is now [...]
                            il.Emit(OpCodes.Ldtoken, columnInfo.Property.PropertyType); // stack is now [...][enum-type-token]
                            il.EmitCall(OpCodes.Call, typeof(Type).GetMethod(nameof(Type.GetTypeFromHandle)), null);// stack is now [...][enum-type]
                            il.Emit(OpCodes.Ldloc, stringEnumLocal); // stack is now [...][enum-type][string]
                            il.Emit(OpCodes.Ldc_I4_1); // stack is now [...][enum-type][string][true]
                            il.EmitCall(OpCodes.Call, enumParse, null); // stack is now [...][enum-as-object]
                            il.Emit(OpCodes.Unbox_Any, columnInfo.Property.PropertyType); // stack is now [...][typed-value]
                        }
                        else
                        {
                            ConvertValueToEnum(il, rdr.GetFieldType(i), columnInfo.Property.PropertyType, numericType);
                        }
                    }
                    else if (columnInfo.Property.PropertyType.IsValueType)
                        il.Emit(OpCodes.Unbox_Any, rdr.GetFieldType(i)); //type cast

                    // for nullable type fields
                    if (columnInfo.Property.PropertyType.IsGenericType && columnInfo.Property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                    {
                        var underlyingType = Nullable.GetUnderlyingType(columnInfo.Property.PropertyType);
                        il.Emit(OpCodes.Newobj, columnInfo.Property.PropertyType.GetConstructor(new Type[] { underlyingType }));
                    }

                    il.Emit(OpCodes.Callvirt, columnInfo.SetMethod);
                    il.Emit(OpCodes.Nop);

                    il.MarkLabel(endIfLabel);
                }
            }

            il.BeginCatchBlock(typeof(Exception)); //begin try block. exception is in stack
            il.Emit(OpCodes.Ldloc_2); //load index
            il.Emit(OpCodes.Ldarg_0); //load argument reader
            il.Emit(OpCodes.Ldloc_1); //load value //TODO: dynamic location using valueCopyLocal
            il.EmitCall(OpCodes.Call, typeof(ReaderCache<T>).GetMethod(nameof(ReaderCache<T>.HandleException)), null); //call exception handler
            il.EndExceptionBlock();

            il.Emit(OpCodes.Ldloc, result);
            il.Emit(OpCodes.Ret);
            

            var funcType = System.Linq.Expressions.Expression.GetFuncType(typeof(IDataReader), typeof(T));
            return (Func<IDataReader, T>)method.CreateDelegate(funcType);
        }

19 View Source File : PrefixWriter.cs
License : MIT License
Project Creator : Abc-Arbitrage

private static Action<PrefixWriter, ILogEventHeader> BuildAppendMethod(ICollection<PatternPart> parts, Dictionary<string, (int offset, int length)> stringMap)
        {
            var method = new DynamicMethod("WritePrefix", typeof(void), new[] { typeof(PrefixWriter), typeof(ILogEventHeader) }, typeof(PrefixWriter), false)
            {
                InitLocals = false
            };

            var il = method.GetILGenerator();

            var stringBufferLocal = il.DeclareLocal(typeof(StringBuffer));
            var stringsLocal = il.DeclareLocal(typeof(char).MakeByRefType(), true);
            var dateTimeLocal = default(LocalBuilder);

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, typeof(PrefixWriter).GetField(nameof(_stringBuffer), BindingFlags.Instance | BindingFlags.NonPublic)!);
            il.Emit(OpCodes.Stloc, stringBufferLocal);

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, typeof(PrefixWriter).GetField(nameof(_strings), BindingFlags.Instance | BindingFlags.NonPublic)!);
            il.Emit(OpCodes.Ldc_I4_0);
            il.Emit(OpCodes.Ldelema, typeof(char));
            il.Emit(OpCodes.Stloc, stringsLocal);

            foreach (var part in parts)
            {
                switch (part.Type)
                {
                    case PatternPartType.String:
                    {
                        // _stringBuffer.Append(&_strings[0] + offset * sizeof(char), length);

                        var (offset, length) = stringMap[part.Value!];

                        il.Emit(OpCodes.Ldloc, stringBufferLocal);

                        il.Emit(OpCodes.Ldloc, stringsLocal);
                        il.Emit(OpCodes.Conv_U);
                        il.Emit(OpCodes.Ldc_I4, offset * sizeof(char));
                        il.Emit(OpCodes.Add);

                        il.Emit(OpCodes.Ldc_I4, length);

                        il.Emit(OpCodes.Call, typeof(StringBuffer).GetMethod(nameof(StringBuffer.Append), new[] { typeof(char*), typeof(int) })!);
                        break;
                    }

                    case PatternPartType.Date:
                    {
                        // _stringBuffer.Append(logEventHeader.Timestamp, new StringView(&_strings[0] + offset * sizeof(char), length));

                        var (offset, length) = stringMap[_dateFormat];

                        il.Emit(OpCodes.Ldloc, stringBufferLocal);

                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Callvirt, typeof(ILogEventHeader).GetProperty(nameof(ILogEventHeader.Timestamp))?.GetGetMethod()!);

                        il.Emit(OpCodes.Ldloc, stringsLocal);
                        il.Emit(OpCodes.Conv_U);
                        il.Emit(OpCodes.Ldc_I4, offset * sizeof(char));
                        il.Emit(OpCodes.Add);

                        il.Emit(OpCodes.Ldc_I4, length);

                        il.Emit(OpCodes.Newobj, typeof(StringView).GetConstructor(new[] { typeof(char*), typeof(int) })!);

                        il.Emit(OpCodes.Call, typeof(StringBuffer).GetMethod(nameof(StringBuffer.Append), new[] { typeof(DateTime), typeof(StringView) })!);
                        break;
                    }

                    case PatternPartType.Time:
                    {
                        // _stringBuffer.Append(logEventHeader.Timestamp.TimeOfDay, StringView.Empty);

                        il.Emit(OpCodes.Ldloc, stringBufferLocal);

                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Callvirt, typeof(ILogEventHeader).GetProperty(nameof(ILogEventHeader.Timestamp))?.GetGetMethod()!);
                        il.Emit(OpCodes.Stloc, dateTimeLocal ??= il.DeclareLocal(typeof(DateTime)));
                        il.Emit(OpCodes.Ldloca, dateTimeLocal);
                        il.Emit(OpCodes.Call, typeof(DateTime).GetProperty(nameof(DateTime.TimeOfDay))?.GetGetMethod()!);

                        il.Emit(OpCodes.Ldsfld, typeof(StringView).GetField(nameof(StringView.Empty))!);

                        il.Emit(OpCodes.Call, typeof(StringBuffer).GetMethod(nameof(StringBuffer.Append), new[] { typeof(TimeSpan), typeof(StringView) })!);
                        break;
                    }

                    case PatternPartType.Thread:
                    {
                        // AppendThread(logEventHeader.Thread);

                        il.Emit(OpCodes.Ldarg_0);

                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Callvirt, typeof(ILogEventHeader).GetProperty(nameof(ILogEventHeader.Thread))?.GetGetMethod()!);

                        il.Emit(OpCodes.Call, typeof(PrefixWriter).GetMethod(nameof(AppendThread), BindingFlags.Instance | BindingFlags.NonPublic)!);
                        break;
                    }

                    case PatternPartType.Level:
                    {
                        // _stringBuffer.Append(LevelStringCache.GetLevelString(logEventHeader.Level));

                        il.Emit(OpCodes.Ldloc, stringBufferLocal);

                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Callvirt, typeof(ILogEventHeader).GetProperty(nameof(ILogEventHeader.Level))?.GetGetMethod()!);
                        il.Emit(OpCodes.Call, typeof(LevelStringCache).GetMethod(nameof(LevelStringCache.GetLevelString))!);

                        il.Emit(OpCodes.Call, typeof(StringBuffer).GetMethod(nameof(StringBuffer.Append), new[] { typeof(string) })!);
                        break;
                    }

                    case PatternPartType.Logger:
                    {
                        // _stringBuffer.Append(logEventHeader.Name);

                        il.Emit(OpCodes.Ldloc, stringBufferLocal);

                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Callvirt, typeof(ILogEventHeader).GetProperty(nameof(ILogEventHeader.Name))?.GetGetMethod()!);

                        il.Emit(OpCodes.Call, typeof(StringBuffer).GetMethod(nameof(StringBuffer.Append), new[] { typeof(string) })!);
                        break;
                    }

                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }

            il.Emit(OpCodes.Ret);

            return (Action<PrefixWriter, ILogEventHeader>)method.CreateDelegate(typeof(Action<PrefixWriter, ILogEventHeader>));
        }

19 View Source File : PrefixWriter.cs
License : MIT License
Project Creator : Abc-Arbitrage

private static Action<PrefixWriter, ILogEventHeader> BuildAppendMethod(ICollection<PatternPart> parts, Dictionary<string, (int offset, int length)> stringMap)
        {
            var method = new DynamicMethod("WritePrefix", typeof(void), new[] { typeof(PrefixWriter), typeof(ILogEventHeader) }, typeof(PrefixWriter), false)
            {
                InitLocals = false
            };

            var il = method.GetILGenerator();

            var stringBufferLocal = il.DeclareLocal(typeof(StringBuffer));
            var stringsLocal = il.DeclareLocal(typeof(char).MakeByRefType(), true);
            var dateTimeLocal = default(LocalBuilder);

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, typeof(PrefixWriter).GetField(nameof(_stringBuffer), BindingFlags.Instance | BindingFlags.NonPublic)!);
            il.Emit(OpCodes.Stloc, stringBufferLocal);

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, typeof(PrefixWriter).GetField(nameof(_strings), BindingFlags.Instance | BindingFlags.NonPublic)!);
            il.Emit(OpCodes.Ldc_I4_0);
            il.Emit(OpCodes.Ldelema, typeof(char));
            il.Emit(OpCodes.Stloc, stringsLocal);

            foreach (var part in parts)
            {
                switch (part.Type)
                {
                    case PatternPartType.String:
                    {
                        // _stringBuffer.Append(&_strings[0] + offset * sizeof(char), length);

                        var (offset, length) = stringMap[part.Value!];

                        il.Emit(OpCodes.Ldloc, stringBufferLocal);

                        il.Emit(OpCodes.Ldloc, stringsLocal);
                        il.Emit(OpCodes.Conv_U);
                        il.Emit(OpCodes.Ldc_I4, offset * sizeof(char));
                        il.Emit(OpCodes.Add);

                        il.Emit(OpCodes.Ldc_I4, length);

                        il.Emit(OpCodes.Call, typeof(StringBuffer).GetMethod(nameof(StringBuffer.Append), new[] { typeof(char*), typeof(int) })!);
                        break;
                    }

                    case PatternPartType.Date:
                    {
                        // _stringBuffer.Append(logEventHeader.Timestamp, new StringView(&_strings[0] + offset * sizeof(char), length));

                        var (offset, length) = stringMap[_dateFormat];

                        il.Emit(OpCodes.Ldloc, stringBufferLocal);

                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Callvirt, typeof(ILogEventHeader).GetProperty(nameof(ILogEventHeader.Timestamp))?.GetGetMethod()!);

                        il.Emit(OpCodes.Ldloc, stringsLocal);
                        il.Emit(OpCodes.Conv_U);
                        il.Emit(OpCodes.Ldc_I4, offset * sizeof(char));
                        il.Emit(OpCodes.Add);

                        il.Emit(OpCodes.Ldc_I4, length);

                        il.Emit(OpCodes.Newobj, typeof(StringView).GetConstructor(new[] { typeof(char*), typeof(int) })!);

                        il.Emit(OpCodes.Call, typeof(StringBuffer).GetMethod(nameof(StringBuffer.Append), new[] { typeof(DateTime), typeof(StringView) })!);
                        break;
                    }

                    case PatternPartType.Time:
                    {
                        // _stringBuffer.Append(logEventHeader.Timestamp.TimeOfDay, StringView.Empty);

                        il.Emit(OpCodes.Ldloc, stringBufferLocal);

                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Callvirt, typeof(ILogEventHeader).GetProperty(nameof(ILogEventHeader.Timestamp))?.GetGetMethod()!);
                        il.Emit(OpCodes.Stloc, dateTimeLocal ??= il.DeclareLocal(typeof(DateTime)));
                        il.Emit(OpCodes.Ldloca, dateTimeLocal);
                        il.Emit(OpCodes.Call, typeof(DateTime).GetProperty(nameof(DateTime.TimeOfDay))?.GetGetMethod()!);

                        il.Emit(OpCodes.Ldsfld, typeof(StringView).GetField(nameof(StringView.Empty))!);

                        il.Emit(OpCodes.Call, typeof(StringBuffer).GetMethod(nameof(StringBuffer.Append), new[] { typeof(TimeSpan), typeof(StringView) })!);
                        break;
                    }

                    case PatternPartType.Thread:
                    {
                        // AppendThread(logEventHeader.Thread);

                        il.Emit(OpCodes.Ldarg_0);

                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Callvirt, typeof(ILogEventHeader).GetProperty(nameof(ILogEventHeader.Thread))?.GetGetMethod()!);

                        il.Emit(OpCodes.Call, typeof(PrefixWriter).GetMethod(nameof(AppendThread), BindingFlags.Instance | BindingFlags.NonPublic)!);
                        break;
                    }

                    case PatternPartType.Level:
                    {
                        // _stringBuffer.Append(LevelStringCache.GetLevelString(logEventHeader.Level));

                        il.Emit(OpCodes.Ldloc, stringBufferLocal);

                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Callvirt, typeof(ILogEventHeader).GetProperty(nameof(ILogEventHeader.Level))?.GetGetMethod()!);
                        il.Emit(OpCodes.Call, typeof(LevelStringCache).GetMethod(nameof(LevelStringCache.GetLevelString))!);

                        il.Emit(OpCodes.Call, typeof(StringBuffer).GetMethod(nameof(StringBuffer.Append), new[] { typeof(string) })!);
                        break;
                    }

                    case PatternPartType.Logger:
                    {
                        // _stringBuffer.Append(logEventHeader.Name);

                        il.Emit(OpCodes.Ldloc, stringBufferLocal);

                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Callvirt, typeof(ILogEventHeader).GetProperty(nameof(ILogEventHeader.Name))?.GetGetMethod()!);

                        il.Emit(OpCodes.Call, typeof(StringBuffer).GetMethod(nameof(StringBuffer.Append), new[] { typeof(string) })!);
                        break;
                    }

                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }

            il.Emit(OpCodes.Ret);

            return (Action<PrefixWriter, ILogEventHeader>)method.CreateDelegate(typeof(Action<PrefixWriter, ILogEventHeader>));
        }

19 View Source File : DarksVMTrampoline.cs
License : GNU General Public License v3.0
Project Creator : Aekras1a

private static DynamicMethod CreateTrampolineNormal(int moduleId, ulong codeAdr, uint key, DarksVMFuncSig sig, uint sigId)
        {
            var dm = new DynamicMethod("", sig.RetType, sig.ParamTypes, Unverifier.Module, true);

            var gen = dm.GetILGenerator();
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, moduleId);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I8, (long) codeAdr);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int) key);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int) sigId);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, sig.ParamTypes.Length);
            gen.Emit(System.Reflection.Emit.OpCodes.Newarr, typeof(object));
            for(var i = 0; i < sig.ParamTypes.Length; i++)
            {
                gen.Emit(System.Reflection.Emit.OpCodes.Dup);
                gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, i);
                gen.Emit(System.Reflection.Emit.OpCodes.Ldarg, i);
                if(sig.ParamTypes[i].IsValueType)
                    gen.Emit(System.Reflection.Emit.OpCodes.Box, sig.ParamTypes[i]);
                gen.Emit(System.Reflection.Emit.OpCodes.Stelem_Ref);
            }

            gen.Emit(System.Reflection.Emit.OpCodes.Call, entryStubNormal);

            if(sig.RetType == typeof(void))
                gen.Emit(System.Reflection.Emit.OpCodes.Pop);
            else if(sig.RetType.IsValueType)
                gen.Emit(System.Reflection.Emit.OpCodes.Unbox_Any, sig.RetType);
            else
                gen.Emit(System.Reflection.Emit.OpCodes.Castclreplaced, sig.RetType);

            gen.Emit(System.Reflection.Emit.OpCodes.Ret);

            return dm;
        }

19 View Source File : DarksVMTrampoline.cs
License : GNU General Public License v3.0
Project Creator : Aekras1a

private static DynamicMethod CreateTrampolineTyped(int moduleId, ulong codeAdr, uint key, DarksVMFuncSig sig, uint sigId)
        {
            var dm = new DynamicMethod("", sig.RetType, sig.ParamTypes, Unverifier.Module, true);

            var gen = dm.GetILGenerator();
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, moduleId);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I8, (long) codeAdr);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int) key);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int) sigId);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, sig.ParamTypes.Length);
            gen.Emit(System.Reflection.Emit.OpCodes.Newarr, typeof(void*));
            for(var i = 0; i < sig.ParamTypes.Length; i++)
            {
                gen.Emit(System.Reflection.Emit.OpCodes.Dup);
                gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, i);
                if(sig.ParamTypes[i].IsByRef)
                {
                    gen.Emit(System.Reflection.Emit.OpCodes.Ldarg, i);
                    gen.Emit(System.Reflection.Emit.OpCodes.Mkrefany, sig.ParamTypes[i].GetElementType());
                }
                else
                {
                    gen.Emit(System.Reflection.Emit.OpCodes.Ldarga, i);
                    gen.Emit(System.Reflection.Emit.OpCodes.Mkrefany, sig.ParamTypes[i]);
                }
                var local = gen.DeclareLocal(typeof(TypedReference));
                gen.Emit(System.Reflection.Emit.OpCodes.Stloc, local);
                gen.Emit(System.Reflection.Emit.OpCodes.Ldloca, local);
                gen.Emit(System.Reflection.Emit.OpCodes.Conv_I);
                gen.Emit(System.Reflection.Emit.OpCodes.Stelem_I);
            }

            if(sig.RetType != typeof(void))
            {
                var retVar = gen.DeclareLocal(sig.RetType);
                var retRef = gen.DeclareLocal(typeof(TypedReference));
                gen.Emit(System.Reflection.Emit.OpCodes.Ldloca, retVar);
                gen.Emit(System.Reflection.Emit.OpCodes.Mkrefany, sig.RetType);
                gen.Emit(System.Reflection.Emit.OpCodes.Stloc, retRef);
                gen.Emit(System.Reflection.Emit.OpCodes.Ldloca, retRef);
                gen.Emit(System.Reflection.Emit.OpCodes.Call, entryStubTyped);

                gen.Emit(System.Reflection.Emit.OpCodes.Ldloc, retVar);
            }
            else
            {
                gen.Emit(System.Reflection.Emit.OpCodes.Ldnull);
                gen.Emit(System.Reflection.Emit.OpCodes.Call, entryStubTyped);
            }
            gen.Emit(System.Reflection.Emit.OpCodes.Ret);

            return dm;
        }

19 View Source File : DarksVMTrampoline.cs
License : GNU General Public License v3.0
Project Creator : Aekras1a

private static DynamicMethod CreateTrampolineTyped(int moduleId, ulong codeAdr, uint key, DarksVMFuncSig sig, uint sigId)
        {
            var dm = new DynamicMethod("", sig.RetType, sig.ParamTypes, Unverifier.Module, true);

            var gen = dm.GetILGenerator();
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, moduleId);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I8, (long) codeAdr);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int) key);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int) sigId);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, sig.ParamTypes.Length);
            gen.Emit(System.Reflection.Emit.OpCodes.Newarr, typeof(void*));
            for(var i = 0; i < sig.ParamTypes.Length; i++)
            {
                gen.Emit(System.Reflection.Emit.OpCodes.Dup);
                gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, i);
                if(sig.ParamTypes[i].IsByRef)
                {
                    gen.Emit(System.Reflection.Emit.OpCodes.Ldarg, i);
                    gen.Emit(System.Reflection.Emit.OpCodes.Mkrefany, sig.ParamTypes[i].GetElementType());
                }
                else
                {
                    gen.Emit(System.Reflection.Emit.OpCodes.Ldarga, i);
                    gen.Emit(System.Reflection.Emit.OpCodes.Mkrefany, sig.ParamTypes[i]);
                }
                var local = gen.DeclareLocal(typeof(TypedReference));
                gen.Emit(System.Reflection.Emit.OpCodes.Stloc, local);
                gen.Emit(System.Reflection.Emit.OpCodes.Ldloca, local);
                gen.Emit(System.Reflection.Emit.OpCodes.Conv_I);
                gen.Emit(System.Reflection.Emit.OpCodes.Stelem_I);
            }

            if(sig.RetType != typeof(void))
            {
                var retVar = gen.DeclareLocal(sig.RetType);
                var retRef = gen.DeclareLocal(typeof(TypedReference));
                gen.Emit(System.Reflection.Emit.OpCodes.Ldloca, retVar);
                gen.Emit(System.Reflection.Emit.OpCodes.Mkrefany, sig.RetType);
                gen.Emit(System.Reflection.Emit.OpCodes.Stloc, retRef);
                gen.Emit(System.Reflection.Emit.OpCodes.Ldloca, retRef);
                gen.Emit(System.Reflection.Emit.OpCodes.Call, entryStubTyped);

                gen.Emit(System.Reflection.Emit.OpCodes.Ldloc, retVar);
            }
            else
            {
                gen.Emit(System.Reflection.Emit.OpCodes.Ldnull);
                gen.Emit(System.Reflection.Emit.OpCodes.Call, entryStubTyped);
            }
            gen.Emit(System.Reflection.Emit.OpCodes.Ret);

            return dm;
        }

19 View Source File : DirectCall.cs
License : GNU General Public License v3.0
Project Creator : Aekras1a

public static TypedInvocation GetTypedInvocationProxy(MethodBase method, OpCode opCode, Type constrainType)
        {
            Hashtable table;
            object key;
            if(constrainType == null)
            {
                key = new KeyValuePair<MethodBase, OpCode>(method, opCode);
                table = typedProxies;
            }
            else
            {
                key = new KeyValuePair<MethodBase, Type>(method, constrainType);
                table = constrainedProxies;
            }

            var proxy = (TypedInvocation) table[key];
            if(proxy != null)
                return proxy;

            lock(typedProxies)
            {
                proxy = (TypedInvocation) table[key];
                if(proxy != null)
                    return proxy;

                var parameters = method.GetParameters();
                Type[] paramTypes;
                if(opCode != System.Reflection.Emit.OpCodes.Newobj)
                {
                    paramTypes = new Type[parameters.Length + (method.IsStatic ? 0 : 1) + 1];
                    for(var i = 0; i < paramTypes.Length - 1; i++)
                        if(method.IsStatic)
                        {
                            paramTypes[i] = parameters[i].ParameterType;
                        }
                        else
                        {
                            if(i == 0)
                                if(constrainType != null)
                                    paramTypes[0] = constrainType.MakeByRefType();
                                else if(method.DeclaringType.IsValueType)
                                    paramTypes[0] = method.DeclaringType.MakeByRefType();
                                else
                                    paramTypes[0] = method.DeclaringType;
                            else
                                paramTypes[i] = parameters[i - 1].ParameterType;
                        }
                }
                else
                {
                    paramTypes = new Type[parameters.Length + 1];
                    for(var i = 0; i < paramTypes.Length - 1; i++) paramTypes[i] = parameters[i].ParameterType;
                }

                var retType = method is MethodInfo ? ((MethodInfo) method).ReturnType : typeof(void);
                if(opCode == System.Reflection.Emit.OpCodes.Newobj)
                    retType = method.DeclaringType;
                var dm = new DynamicMethod("", typeof(object), new[] {typeof(DarksVMContext), typeof(IReference[]), typeof(Type[])},
                    Unverifier.Module, true);
                var gen = dm.GetILGenerator();

                for(var i = 0; i < paramTypes.Length - 1; i++)
                {
                    var paramType = paramTypes[i];
                    var isByRef = paramType.IsByRef;
                    if(isByRef)
                        paramType = paramType.GetElementType();

                    var typedRefLocal = gen.DeclareLocal(typeof(TypedReference));
                    gen.Emit(System.Reflection.Emit.OpCodes.Ldarg_1);
                    gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, i);
                    gen.Emit(System.Reflection.Emit.OpCodes.Ldelem_Ref);

                    gen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0);
                    gen.Emit(System.Reflection.Emit.OpCodes.Ldloca, typedRefLocal);

                    gen.Emit(System.Reflection.Emit.OpCodes.Ldarg_2);
                    gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, i);
                    gen.Emit(System.Reflection.Emit.OpCodes.Ldelem_Ref);

                    gen.Emit(System.Reflection.Emit.OpCodes.Callvirt, refToTypedRef);

                    gen.Emit(System.Reflection.Emit.OpCodes.Ldloca, typedRefLocal);
                    gen.Emit(System.Reflection.Emit.OpCodes.Ldarg_2);
                    gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, i);
                    gen.Emit(System.Reflection.Emit.OpCodes.Ldelem_Ref);
                    gen.Emit(System.Reflection.Emit.OpCodes.Call, castTypedRef);

                    gen.Emit(System.Reflection.Emit.OpCodes.Ldloc, typedRefLocal);
                    gen.Emit(System.Reflection.Emit.OpCodes.Refanyval, paramType);

                    if(!isByRef)
                        gen.Emit(System.Reflection.Emit.OpCodes.Ldobj, paramType);
                }

                if(constrainType != null)
                    gen.Emit(System.Reflection.Emit.OpCodes.Constrained, constrainType);

                if(method is MethodInfo)
                    gen.Emit(opCode, (MethodInfo) method);
                else
                    gen.Emit(opCode, (ConstructorInfo) method);

                if(retType.IsByRef)
                {
                    gen.Emit(System.Reflection.Emit.OpCodes.Mkrefany, retType.GetElementType());
                    gen.Emit(System.Reflection.Emit.OpCodes.Newobj, newTypedRef);
                }
                else if(retType == typeof(void))
                {
                    gen.Emit(System.Reflection.Emit.OpCodes.Ldnull);
                }
                else if(retType.IsValueType)
                {
                    gen.Emit(System.Reflection.Emit.OpCodes.Box, retType);
                }

                gen.Emit(System.Reflection.Emit.OpCodes.Ret);

                proxy = (TypedInvocation) dm.CreateDelegate(typeof(TypedInvocation));
                table[key] = proxy;
                return proxy;
            }
        }

19 View Source File : TypeExtend.cs
License : Mozilla Public License 2.0
Project Creator : agebullhu

public static Func<TArg, TRes> CreateFunc<TArg, TRes>(TypeInfo callInfo, string methodName, TypeInfo argInfo, TypeInfo resInfo)
        {
            var typeConstructor = resInfo.GetConstructor(Type.EmptyTypes);
            if (typeConstructor == null)
                throw new ArgumentException($"类型{callInfo.FullName}没有无参构造函数");
            var innerMethod = callInfo.GetMethod(methodName);
            if (innerMethod == null)
                throw new ArgumentException($"类型{callInfo.FullName}没有名称为{methodName}的方法");
            if (innerMethod.ReturnType != resInfo)
                throw new ArgumentException($"类型{callInfo.FullName}的方法{methodName}返回值不为{resInfo.FullName}");
            var args = innerMethod.GetParameters();
            if (args.Length != 1)
                throw new ArgumentException($"类型{callInfo.FullName}的方法{methodName}参数不是一个");
            if (args[0].ParameterType != argInfo)
                throw new ArgumentException($"类型{callInfo.FullName}的方法{methodName}唯一参数不为{argInfo.FullName}");
            //构造匿名方法
            var callMethod = new DynamicMethod(methodName, typeof(TRes), new[] { typeof(TArg) });
            //构造动态IL(方法内部实现)
            var il = callMethod.GetILGenerator();
            il.Emit(OpCodes.Nop);
            //1 参数类型转换
            il.Emit(OpCodes.Ldarg, 0);
            il.Emit(OpCodes.Castclreplaced, argInfo);
            var arg = il.DeclareLocal(argInfo);
            il.Emit(OpCodes.Stloc, arg);
            //2 调用对象构造
            il.Emit(OpCodes.Newobj, typeConstructor);
            var call = il.DeclareLocal(callInfo);
            il.Emit(OpCodes.Stloc, call);
            //3 方法调用
            il.Emit(OpCodes.Ldloc, call);
            il.Emit(OpCodes.Ldloc, arg);
            il.Emit(OpCodes.Callvirt, innerMethod);
            var ret = il.DeclareLocal(innerMethod.ReturnType);
            //4 返回值转换
            il.Emit(OpCodes.Stloc, ret);
            il.Emit(OpCodes.Ldloc, ret);
            il.Emit(OpCodes.Castclreplaced, typeof(TRes).GetTypeInfo());
            var res = il.DeclareLocal(resInfo);
            //5 返回
            il.Emit(OpCodes.Stloc, res);
            il.Emit(OpCodes.Ldloc, res);
            il.Emit(OpCodes.Ret);
            //返回动态委托
            return callMethod.CreateDelegate(typeof(Func<TArg, TRes>)) as Func<TArg, TRes>;
        }

19 View Source File : TypeExtend.cs
License : Mozilla Public License 2.0
Project Creator : agebullhu

public static Func<TRes> CreateFunc<TRes>(TypeInfo callInfo, string methodName, TypeInfo resInfo)
        {
            var typeConstructor = resInfo.GetConstructor(Type.EmptyTypes);
            if (typeConstructor == null)
                throw new ArgumentException($"类型{callInfo.FullName}没有无参构造函数");
            var innerMethod = callInfo.GetMethod(methodName);
            if (innerMethod == null)
                throw new ArgumentException($"类型{callInfo.FullName}没有名称为{methodName}的方法");
            if (innerMethod.ReturnType != resInfo)
                throw new ArgumentException($"类型{callInfo.FullName}的方法{methodName}返回值不为{resInfo.FullName}");
            var args = innerMethod.GetParameters();
            if (args.Length > 0)
                throw new ArgumentException($"类型{callInfo.FullName}的方法{methodName}参数不为空");
            //构造匿名方法
            var callMethod = new DynamicMethod(methodName, typeof(TRes), null);
            //构造动态IL(方法内部实现)
            var il = callMethod.GetILGenerator();
            il.Emit(OpCodes.Nop);
            //1 调用对象构造
            il.Emit(OpCodes.Newobj, typeConstructor);
            var call = il.DeclareLocal(callInfo);
            il.Emit(OpCodes.Stloc, call);
            //3 方法调用
            il.Emit(OpCodes.Ldloc, call);
            il.Emit(OpCodes.Callvirt, innerMethod);
            var ret = il.DeclareLocal(innerMethod.ReturnType);
            //4 返回值转换
            il.Emit(OpCodes.Stloc, ret);
            il.Emit(OpCodes.Ldloc, ret);
            il.Emit(OpCodes.Castclreplaced, typeof(TRes).GetTypeInfo());
            var res = il.DeclareLocal(resInfo);
            //5 返回
            il.Emit(OpCodes.Stloc, res);
            il.Emit(OpCodes.Ldloc, res);
            il.Emit(OpCodes.Ret);
            //返回动态委托
            return callMethod.CreateDelegate(typeof(Func<TRes>)) as Func<TRes>;
        }

19 View Source File : ZeroDiscover.cs
License : Mozilla Public License 2.0
Project Creator : agebullhu

public static Func<TArg, TRes> CreateFunc<TArg, TRes>(TypeInfo callInfo, string methodName, TypeInfo argInfo, TypeInfo resInfo)
        {
            ConstructorInfo constructor = callInfo.GetConstructor(Type.EmptyTypes);
            if (constructor == (ConstructorInfo)null)
                throw new ArgumentException("类型" + callInfo.FullName + "没有无参构造函数");
            MethodInfo method = callInfo.GetMethod(methodName);
            if (method == (MethodInfo)null)
                throw new ArgumentException("类型" + callInfo.FullName + "没有名称为" + methodName + "的方法");
            if (method.ReturnType != (Type)resInfo)
                throw new ArgumentException("类型" + callInfo.FullName + "的方法" + methodName + "返回值不为" + resInfo.FullName);
            ParameterInfo[] parameters = method.GetParameters();
            if (parameters.Length != 1)
                throw new ArgumentException("类型" + callInfo.FullName + "的方法" + methodName + "参数不是一个");
            if (parameters[0].ParameterType != (Type)argInfo)
                throw new ArgumentException("类型" + callInfo.FullName + "的方法" + methodName + "唯一参数不为" + argInfo.FullName);
            DynamicMethod dynamicMethod = new DynamicMethod(methodName, typeof(TRes), new Type[1]
            {
        typeof (TArg)
            });
            ILGenerator ilGenerator = dynamicMethod.GetILGenerator();
            ilGenerator.Emit(OpCodes.Nop);
            ilGenerator.Emit(OpCodes.Ldarg, 0);
            ilGenerator.Emit(OpCodes.Castclreplaced, (Type)argInfo);
            LocalBuilder local1 = ilGenerator.DeclareLocal((Type)argInfo);
            ilGenerator.Emit(OpCodes.Stloc, local1);
            ilGenerator.Emit(OpCodes.Newobj, constructor);
            LocalBuilder local2 = ilGenerator.DeclareLocal((Type)callInfo);
            ilGenerator.Emit(OpCodes.Stloc, local2);
            ilGenerator.Emit(OpCodes.Ldloc, local2);
            ilGenerator.Emit(OpCodes.Ldloc, local1);
            ilGenerator.Emit(OpCodes.Callvirt, method);
            LocalBuilder local3 = ilGenerator.DeclareLocal(method.ReturnType);
            ilGenerator.Emit(OpCodes.Stloc, local3);
            ilGenerator.Emit(OpCodes.Ldloc, local3);
            ilGenerator.Emit(OpCodes.Castclreplaced, (Type)typeof(TRes).GetTypeInfo());
            LocalBuilder local4 = ilGenerator.DeclareLocal((Type)resInfo);
            ilGenerator.Emit(OpCodes.Stloc, local4);
            ilGenerator.Emit(OpCodes.Ldloc, local4);
            ilGenerator.Emit(OpCodes.Ret);
            return dynamicMethod.CreateDelegate(typeof(Func<TArg, TRes>)) as Func<TArg, TRes>;
        }

19 View Source File : ZeroDiscover.cs
License : Mozilla Public License 2.0
Project Creator : agebullhu

public static Func<TRes> CreateFunc<TRes>(TypeInfo callInfo, string methodName, TypeInfo resInfo)
        {
            ConstructorInfo constructor = callInfo.GetConstructor(Type.EmptyTypes);
            if (constructor == (ConstructorInfo)null)
                throw new ArgumentException("类型" + callInfo.FullName + "没有无参构造函数");
            MethodInfo method = callInfo.GetMethod(methodName);
            if (method == (MethodInfo)null)
                throw new ArgumentException("类型" + callInfo.FullName + "没有名称为" + methodName + "的方法");
            if (method.ReturnType != (Type)resInfo)
                throw new ArgumentException("类型" + callInfo.FullName + "的方法" + methodName + "返回值不为" + resInfo.FullName);
            if ((uint)method.GetParameters().Length > 0U)
                throw new ArgumentException("类型" + callInfo.FullName + "的方法" + methodName + "参数不为空");
            DynamicMethod dynamicMethod = new DynamicMethod(methodName, typeof(TRes), (Type[])null);
            ILGenerator ilGenerator = dynamicMethod.GetILGenerator();
            ilGenerator.Emit(OpCodes.Nop);
            ilGenerator.Emit(OpCodes.Newobj, constructor);
            LocalBuilder local1 = ilGenerator.DeclareLocal((Type)callInfo);
            ilGenerator.Emit(OpCodes.Stloc, local1);
            ilGenerator.Emit(OpCodes.Ldloc, local1);
            ilGenerator.Emit(OpCodes.Callvirt, method);
            LocalBuilder local2 = ilGenerator.DeclareLocal(method.ReturnType);
            ilGenerator.Emit(OpCodes.Stloc, local2);
            ilGenerator.Emit(OpCodes.Ldloc, local2);
            ilGenerator.Emit(OpCodes.Castclreplaced, (Type)typeof(TRes).GetTypeInfo());
            LocalBuilder local3 = ilGenerator.DeclareLocal((Type)resInfo);
            ilGenerator.Emit(OpCodes.Stloc, local3);
            ilGenerator.Emit(OpCodes.Ldloc, local3);
            ilGenerator.Emit(OpCodes.Ret);
            return dynamicMethod.CreateDelegate(typeof(Func<TRes>)) as Func<TRes>;
        }

19 View Source File : DynamicReflectionDelegateFactory.cs
License : MIT License
Project Creator : akaskela

private void GenerateCreateMethodCallIL(MethodBase method, ILGenerator generator, int argsIndex)
        {
            ParameterInfo[] args = method.GetParameters();

            Label argsOk = generator.DefineLabel();

            // throw an error if the number of argument values doesn't match method parameters
            generator.Emit(OpCodes.Ldarg, argsIndex);
            generator.Emit(OpCodes.Ldlen);
            generator.Emit(OpCodes.Ldc_I4, args.Length);
            generator.Emit(OpCodes.Beq, argsOk);
            generator.Emit(OpCodes.Newobj, typeof(TargetParameterCountException).GetConstructor(ReflectionUtils.EmptyTypes));
            generator.Emit(OpCodes.Throw);

            generator.MarkLabel(argsOk);

            if (!method.IsConstructor && !method.IsStatic)
            {
                generator.PushInstance(method.DeclaringType);
            }

            int localVariableCount = 0;

            for (int i = 0; i < args.Length; i++)
            {
                ParameterInfo parameter = args[i];
                Type parameterType = parameter.ParameterType;

                if (parameterType.IsByRef)
                {
                    parameterType = parameterType.GetElementType();

                    LocalBuilder localVariable = generator.DeclareLocal(parameterType);

                    // don't need to set variable for 'out' parameter
                    if (!parameter.IsOut)
                    {
                        generator.PushArrayInstance(argsIndex, i);

                        if (parameterType.IsValueType())
                        {
                            Label skipSettingDefault = generator.DefineLabel();
                            Label finishedProcessingParameter = generator.DefineLabel();

                            // check if parameter is not null
                            generator.Emit(OpCodes.Brtrue_S, skipSettingDefault);

                            // parameter has no value, initialize to default
                            generator.Emit(OpCodes.Ldloca_S, localVariable);
                            generator.Emit(OpCodes.Initobj, parameterType);
                            generator.Emit(OpCodes.Br_S, finishedProcessingParameter);

                            // parameter has value, get value from array again and unbox and set to variable
                            generator.MarkLabel(skipSettingDefault);
                            generator.PushArrayInstance(argsIndex, i);
                            generator.UnboxIfNeeded(parameterType);
                            generator.Emit(OpCodes.Stloc, localVariableCount);

                            // parameter finished, we out!
                            generator.MarkLabel(finishedProcessingParameter);
                        }
                        else
                        {
                            generator.UnboxIfNeeded(parameterType);
                            generator.Emit(OpCodes.Stloc, localVariableCount);
                        }
                    }

                    generator.Emit(OpCodes.Ldloca_S, localVariable);

                    localVariableCount++;
                }
                else if (parameterType.IsValueType())
                {
                    generator.PushArrayInstance(argsIndex, i);

                    // have to check that value type parameters aren't null
                    // otherwise they will error when unboxed
                    Label skipSettingDefault = generator.DefineLabel();
                    Label finishedProcessingParameter = generator.DefineLabel();

                    // check if parameter is not null
                    generator.Emit(OpCodes.Brtrue_S, skipSettingDefault);

                    // parameter has no value, initialize to default
                    LocalBuilder localVariable = generator.DeclareLocal(parameterType);
                    generator.Emit(OpCodes.Ldloca_S, localVariable);
                    generator.Emit(OpCodes.Initobj, parameterType);
                    generator.Emit(OpCodes.Ldloc, localVariableCount);
                    generator.Emit(OpCodes.Br_S, finishedProcessingParameter);

                    // parameter has value, get value from array again and unbox
                    generator.MarkLabel(skipSettingDefault);
                    generator.PushArrayInstance(argsIndex, i);
                    generator.UnboxIfNeeded(parameterType);

                    // parameter finished, we out!
                    generator.MarkLabel(finishedProcessingParameter);
                    localVariableCount++;
                }
                else
                {
                    generator.PushArrayInstance(argsIndex, i);

                    generator.UnboxIfNeeded(parameterType);
                }
            }

            if (method.IsConstructor)
            {
                generator.Emit(OpCodes.Newobj, (ConstructorInfo)method);
            }
            else
            {
                generator.CallMethod((MethodInfo)method);
            }

            Type returnType = method.IsConstructor
                ? method.DeclaringType
                : ((MethodInfo)method).ReturnType;

            if (returnType != typeof(void))
            {
                generator.BoxIfNeeded(returnType);
            }
            else
            {
                generator.Emit(OpCodes.Ldnull);
            }

            generator.Return();
        }

19 View Source File : Instruction.cs
License : MIT License
Project Creator : alexanderkyte

protected void ShiftThisArgToFront (ILGenerator ilgen, Type [] args)
		{
			// Right now, we have arguments on the top of the stack.
			// We need to shift them back to preplaced the "this" argument first
			// We are going to make a scope, to give the JIT maximum visibility
			// into the lifetime of the temporaries needed to make this call.
			ilgen.BeginScope ();
			var locals = new List<LocalBuilder> ();

			// Traverse backwards, as last arg is the one that is pushed onto stack
			for (int i=args.Length - 1; i >= 0; i--) {
				Type ty = args [i];
				LocalBuilder myLocalBuilder = ilgen.DeclareLocal(ty);

				// Add backwards
				locals.Add (myLocalBuilder);
				ilgen.Emit (OpCodes.Stloc, myLocalBuilder);
			}

			// Emit load of "this" arg
			ilgen.Emit (OpCodes.Ldarg_0);

			// Since we added  the locals backwards, we traverse
			// "backwards" again, to restore the stack with "this" before all
			// the args
			for (int i=args.Length - 1; i >= 0; i--) {
				ilgen.Emit (OpCodes.Ldloc, locals [i]);
			}

			ilgen.EndScope ();
		}

19 View Source File : DynamicUnionResolver.cs
License : Apache License 2.0
Project Creator : allenai

private static void BuildDeserialize(Type type, UnionAttribute[] infos, MethodBuilder method, FieldBuilder keyToJumpMap, ILGenerator il)
        {
            // if(MessagePackBinary.TryReadNil()) { return null; }
            Label falseLabel = il.DefineLabel();
            il.EmitLdarg(1);
            il.EmitCall(MessagePackReaderTypeInfo.TryReadNil);
            il.Emit(OpCodes.Brfalse_S, falseLabel);

            il.Emit(OpCodes.Ldnull);
            il.Emit(OpCodes.Ret);

            il.MarkLabel(falseLabel);

            // IFormatterResolver resolver = options.Resolver;
            LocalBuilder localResolver = il.DeclareLocal(typeof(IFormatterResolver));
            il.EmitLdarg(2);
            il.EmitCall(getResolverFromOptions);
            il.EmitStloc(localResolver);

            // read-array header and validate, reader.ReadArrayHeader() != 2) throw;
            Label rightLabel = il.DefineLabel();
            var reader = new ArgumentField(il, 1);
            reader.EmitLdarg();
            il.EmitCall(MessagePackReaderTypeInfo.ReadArrayHeader);
            il.EmitLdc_I4(2);
            il.Emit(OpCodes.Beq_S, rightLabel);
            il.Emit(OpCodes.Ldstr, "Invalid Union data was detected. Type:" + type.FullName);
            il.Emit(OpCodes.Newobj, invalidOperationExceptionConstructor);
            il.Emit(OpCodes.Throw);

            il.MarkLabel(rightLabel);

            // read key
            LocalBuilder key = il.DeclareLocal(typeof(int));
            reader.EmitLdarg();
            il.EmitCall(MessagePackReaderTypeInfo.ReadInt32);
            il.EmitStloc(key);

            // is-sequential don't need else convert key to jump-table value
            if (!IsZeroStartSequential(infos))
            {
                Label endKeyMapGet = il.DefineLabel();
                il.EmitLdarg(0);
                il.EmitLdfld(keyToJumpMap);
                il.EmitLdloc(key);
                il.EmitLdloca(key);
                il.EmitCall(keyMapDictionaryTryGetValue);
                il.Emit(OpCodes.Brtrue_S, endKeyMapGet);
                il.EmitLdc_I4(-1);
                il.EmitStloc(key);

                il.MarkLabel(endKeyMapGet);
            }

            // switch->read
            LocalBuilder result = il.DeclareLocal(type);
            Label loopEnd = il.DefineLabel();
            il.Emit(OpCodes.Ldnull);
            il.EmitStloc(result);
            il.Emit(OpCodes.Ldloc, key);

            var switchLabels = infos.Select(x => new { Label = il.DefineLabel(), Attr = x }).ToArray();
            il.Emit(OpCodes.Switch, switchLabels.Select(x => x.Label).ToArray());

            // default
            reader.EmitLdarg();
            il.EmitCall(MessagePackReaderTypeInfo.Skip);
            il.Emit(OpCodes.Br, loopEnd);

            foreach (var item in switchLabels)
            {
                il.MarkLabel(item.Label);
                il.EmitLdloc(localResolver);
                il.EmitCall(getFormatterWithVerify.MakeGenericMethod(item.Attr.SubType));
                il.EmitLdarg(1);
                il.EmitLdarg(2);
                il.EmitCall(getDeserialize(item.Attr.SubType));
                if (item.Attr.SubType.GetTypeInfo().IsValueType)
                {
                    il.Emit(OpCodes.Box, item.Attr.SubType);
                }

                il.Emit(OpCodes.Stloc, result);
                il.Emit(OpCodes.Br, loopEnd);
            }

            il.MarkLabel(loopEnd);

            il.Emit(OpCodes.Ldloc, result);
            il.Emit(OpCodes.Ret);
        }

19 View Source File : DynamicUnionResolver.cs
License : Apache License 2.0
Project Creator : allenai

private static void BuildSerialize(Type type, UnionAttribute[] infos, MethodBuilder method, FieldBuilder typeToKeyAndJumpMap, ILGenerator il)
        {
            // if(value == null) return WriteNil
            Label elseBody = il.DefineLabel();
            Label notFoundType = il.DefineLabel();

            il.EmitLdarg(2);
            il.Emit(OpCodes.Brtrue_S, elseBody);
            il.Emit(OpCodes.Br, notFoundType);
            il.MarkLabel(elseBody);

            // IFormatterResolver resolver = options.Resolver;
            LocalBuilder localResolver = il.DeclareLocal(typeof(IFormatterResolver));
            il.EmitLdarg(3);
            il.EmitCall(getResolverFromOptions);
            il.EmitStloc(localResolver);

            LocalBuilder keyPair = il.DeclareLocal(typeof(KeyValuePair<int, int>));

            il.EmitLoadThis();
            il.EmitLdfld(typeToKeyAndJumpMap);
            il.EmitLdarg(2);
            il.EmitCall(objectGetType);
            il.EmitCall(getTypeHandle);
            il.EmitLdloca(keyPair);
            il.EmitCall(typeMapDictionaryTryGetValue);
            il.Emit(OpCodes.Brfalse, notFoundType);

            // writer.WriteArrayHeader(2, false);
            il.EmitLdarg(1);
            il.EmitLdc_I4(2);
            il.EmitCall(MessagePackWriterTypeInfo.WriteArrayHeader);

            // writer.Write(keyPair.Key)
            il.EmitLdarg(1);
            il.EmitLdloca(keyPair);
            il.EmitCall(intIntKeyValuePairGetKey);
            il.EmitCall(MessagePackWriterTypeInfo.WriteInt32);

            Label loopEnd = il.DefineLabel();

            // switch-case (offset += resolver.GetFormatter.Serialize(with cast)
            var switchLabels = infos.Select(x => new { Label = il.DefineLabel(), Attr = x }).ToArray();
            il.EmitLdloca(keyPair);
            il.EmitCall(intIntKeyValuePairGetValue);
            il.Emit(OpCodes.Switch, switchLabels.Select(x => x.Label).ToArray());
            il.Emit(OpCodes.Br, loopEnd); // default

            foreach (var item in switchLabels)
            {
                il.MarkLabel(item.Label);
                il.EmitLdloc(localResolver);
                il.Emit(OpCodes.Call, getFormatterWithVerify.MakeGenericMethod(item.Attr.SubType));

                il.EmitLdarg(1);
                il.EmitLdarg(2);
                if (item.Attr.SubType.GetTypeInfo().IsValueType)
                {
                    il.Emit(OpCodes.Unbox_Any, item.Attr.SubType);
                }
                else
                {
                    il.Emit(OpCodes.Castclreplaced, item.Attr.SubType);
                }

                il.EmitLdarg(3);
                il.Emit(OpCodes.Callvirt, getSerialize(item.Attr.SubType));

                il.Emit(OpCodes.Br, loopEnd);
            }

            // return;
            il.MarkLabel(loopEnd);
            il.Emit(OpCodes.Ret);

            // else, return WriteNil
            il.MarkLabel(notFoundType);
            il.EmitLdarg(1);
            il.EmitCall(MessagePackWriterTypeInfo.WriteNil);
            il.Emit(OpCodes.Ret);
        }

19 View Source File : DynamicUnionResolver.cs
License : Apache License 2.0
Project Creator : allenai

private static void BuildDeserialize(Type type, UnionAttribute[] infos, MethodBuilder method, FieldBuilder keyToJumpMap, ILGenerator il)
        {
            // if(MessagePackBinary.TryReadNil()) { return null; }
            Label falseLabel = il.DefineLabel();
            il.EmitLdarg(1);
            il.EmitCall(MessagePackReaderTypeInfo.TryReadNil);
            il.Emit(OpCodes.Brfalse_S, falseLabel);

            il.Emit(OpCodes.Ldnull);
            il.Emit(OpCodes.Ret);

            il.MarkLabel(falseLabel);

            // IFormatterResolver resolver = options.Resolver;
            LocalBuilder localResolver = il.DeclareLocal(typeof(IFormatterResolver));
            il.EmitLdarg(2);
            il.EmitCall(getResolverFromOptions);
            il.EmitStloc(localResolver);

            // read-array header and validate, reader.ReadArrayHeader() != 2) throw;
            Label rightLabel = il.DefineLabel();
            var reader = new ArgumentField(il, 1);
            reader.EmitLdarg();
            il.EmitCall(MessagePackReaderTypeInfo.ReadArrayHeader);
            il.EmitLdc_I4(2);
            il.Emit(OpCodes.Beq_S, rightLabel);
            il.Emit(OpCodes.Ldstr, "Invalid Union data was detected. Type:" + type.FullName);
            il.Emit(OpCodes.Newobj, invalidOperationExceptionConstructor);
            il.Emit(OpCodes.Throw);

            il.MarkLabel(rightLabel);

            // read key
            LocalBuilder key = il.DeclareLocal(typeof(int));
            reader.EmitLdarg();
            il.EmitCall(MessagePackReaderTypeInfo.ReadInt32);
            il.EmitStloc(key);

            // is-sequential don't need else convert key to jump-table value
            if (!IsZeroStartSequential(infos))
            {
                Label endKeyMapGet = il.DefineLabel();
                il.EmitLdarg(0);
                il.EmitLdfld(keyToJumpMap);
                il.EmitLdloc(key);
                il.EmitLdloca(key);
                il.EmitCall(keyMapDictionaryTryGetValue);
                il.Emit(OpCodes.Brtrue_S, endKeyMapGet);
                il.EmitLdc_I4(-1);
                il.EmitStloc(key);

                il.MarkLabel(endKeyMapGet);
            }

            // switch->read
            LocalBuilder result = il.DeclareLocal(type);
            Label loopEnd = il.DefineLabel();
            il.Emit(OpCodes.Ldnull);
            il.EmitStloc(result);
            il.Emit(OpCodes.Ldloc, key);

            var switchLabels = infos.Select(x => new { Label = il.DefineLabel(), Attr = x }).ToArray();
            il.Emit(OpCodes.Switch, switchLabels.Select(x => x.Label).ToArray());

            // default
            reader.EmitLdarg();
            il.EmitCall(MessagePackReaderTypeInfo.Skip);
            il.Emit(OpCodes.Br, loopEnd);

            foreach (var item in switchLabels)
            {
                il.MarkLabel(item.Label);
                il.EmitLdloc(localResolver);
                il.EmitCall(getFormatterWithVerify.MakeGenericMethod(item.Attr.SubType));
                il.EmitLdarg(1);
                il.EmitLdarg(2);
                il.EmitCall(getDeserialize(item.Attr.SubType));
                if (item.Attr.SubType.GetTypeInfo().IsValueType)
                {
                    il.Emit(OpCodes.Box, item.Attr.SubType);
                }

                il.Emit(OpCodes.Stloc, result);
                il.Emit(OpCodes.Br, loopEnd);
            }

            il.MarkLabel(loopEnd);

            il.Emit(OpCodes.Ldloc, result);
            il.Emit(OpCodes.Ret);
        }

19 View Source File : DynamicUnionResolver.cs
License : Apache License 2.0
Project Creator : allenai

private static void BuildConstructor(Type type, UnionAttribute[] infos, ConstructorInfo method, FieldBuilder typeToKeyAndJumpMap, FieldBuilder keyToJumpMap, ILGenerator il)
        {
            il.EmitLdarg(0);
            il.Emit(OpCodes.Call, objectCtor);

            {
                il.EmitLdarg(0);
                il.EmitLdc_I4(infos.Length);
                il.Emit(OpCodes.Ldsfld, runtimeTypeHandleEqualityComparer);
                il.Emit(OpCodes.Newobj, typeMapDictionaryConstructor);

                var index = 0;
                foreach (UnionAttribute item in infos)
                {
                    il.Emit(OpCodes.Dup);
                    il.Emit(OpCodes.Ldtoken, item.SubType);
                    il.EmitLdc_I4(item.Key);
                    il.EmitLdc_I4(index);
                    il.Emit(OpCodes.Newobj, intIntKeyValuePairConstructor);
                    il.EmitCall(typeMapDictionaryAdd);

                    index++;
                }

                il.Emit(OpCodes.Stfld, typeToKeyAndJumpMap);
            }

            {
                il.EmitLdarg(0);
                il.EmitLdc_I4(infos.Length);
                il.Emit(OpCodes.Newobj, keyMapDictionaryConstructor);

                var index = 0;
                foreach (UnionAttribute item in infos)
                {
                    il.Emit(OpCodes.Dup);
                    il.EmitLdc_I4(item.Key);
                    il.EmitLdc_I4(index);
                    il.EmitCall(keyMapDictionaryAdd);

                    index++;
                }

                il.Emit(OpCodes.Stfld, keyToJumpMap);
            }

            il.Emit(OpCodes.Ret);
        }

19 View Source File : EmitMemberAccessor.cs
License : MIT License
Project Creator : AllocZero

public static Func<object>? CreateConstructor(Type type)
        {
            Debug.replacedert(type != null);
            ConstructorInfo? realMethod = type.GetConstructor(BindingFlags.Public | BindingFlags.Instance, binder: null, Type.EmptyTypes, modifiers: null);

            if (type.IsAbstract)
            {
                return null;
            }

            if (realMethod == null && !type.IsValueType)
            {
                return null;
            }

            var dynamicMethod = new DynamicMethod(
                ConstructorInfo.ConstructorName,
                ObjectType,
                Type.EmptyTypes,
                typeof(EmitMemberAccessor).Module,
                skipVisibility: true);

            ILGenerator generator = dynamicMethod.GetILGenerator();

            if (realMethod == null)
            {
                LocalBuilder local = generator.DeclareLocal(type);

                generator.Emit(OpCodes.Ldloca_S, local);
                generator.Emit(OpCodes.Initobj, type);
                generator.Emit(OpCodes.Ldloc, local);
                generator.Emit(OpCodes.Box, type);
            }
            else
            {
                generator.Emit(OpCodes.Newobj, realMethod);
            }

            generator.Emit(OpCodes.Ret);

            return (Func<object>?)dynamicMethod.CreateDelegate(typeof(Func<object>));
        }

19 View Source File : EmitMemberAccessor.cs
License : MIT License
Project Creator : AllocZero

private static DynamicMethod CreatePropertySetter(PropertyInfo propertyInfo, Type runtimePropertyType)
        {
            MethodInfo? realMethod = propertyInfo.SetMethod;
            Debug.replacedert(realMethod != null);

            Type? declaringType = propertyInfo.DeclaringType;
            Debug.replacedert(declaringType != null);

            Type declaredPropertyType = propertyInfo.PropertyType;

            DynamicMethod dynamicMethod = CreateSetterMethod(propertyInfo.Name, runtimePropertyType);
            ILGenerator generator = dynamicMethod.GetILGenerator();

            generator.Emit(OpCodes.Ldarg_0);
            generator.Emit(declaringType.IsValueType ? OpCodes.Unbox : OpCodes.Castclreplaced, declaringType);
            generator.Emit(OpCodes.Ldarg_1);

            // declaredPropertyType: Type of the property
            // runtimePropertyType:  <T> of JsonConverter / JsonPropertyInfo

            if (declaredPropertyType != runtimePropertyType && declaredPropertyType.IsValueType)
            {
                generator.Emit(OpCodes.Unbox_Any, declaredPropertyType);
            }

            generator.Emit(declaringType.IsValueType ? OpCodes.Call : OpCodes.Callvirt, realMethod);
            generator.Emit(OpCodes.Ret);

            return dynamicMethod;
        }

19 View Source File : EmitMemberAccessor.cs
License : MIT License
Project Creator : AllocZero

public static Func<object>? CreateConstructor(Type type)
        {
            Debug.replacedert(type != null);
            ConstructorInfo? realMethod = type.GetConstructor(BindingFlags.Public | BindingFlags.Instance, binder: null, Type.EmptyTypes, modifiers: null);

            if (type.IsAbstract)
            {
                return null;
            }

            if (realMethod == null && !type.IsValueType)
            {
                return null;
            }

            var dynamicMethod = new DynamicMethod(
                ConstructorInfo.ConstructorName,
                ObjectType,
                Type.EmptyTypes,
                typeof(EmitMemberAccessor).Module,
                skipVisibility: true);

            ILGenerator generator = dynamicMethod.GetILGenerator();

            if (realMethod == null)
            {
                LocalBuilder local = generator.DeclareLocal(type);

                generator.Emit(OpCodes.Ldloca_S, local);
                generator.Emit(OpCodes.Initobj, type);
                generator.Emit(OpCodes.Ldloc, local);
                generator.Emit(OpCodes.Box, type);
            }
            else
            {
                generator.Emit(OpCodes.Newobj, realMethod);
            }

            generator.Emit(OpCodes.Ret);

            return (Func<object>?)dynamicMethod.CreateDelegate(typeof(Func<object>));
        }

19 View Source File : EmitMemberAccessor.cs
License : MIT License
Project Creator : AllocZero

private static DynamicMethod CreatePropertyGetter(PropertyInfo propertyInfo, Type runtimePropertyType)
        {
            MethodInfo? realMethod = propertyInfo.GetMethod;
            Debug.replacedert(realMethod != null);

            Type? declaringType = propertyInfo.DeclaringType;
            Debug.replacedert(declaringType != null);

            Type declaredPropertyType = propertyInfo.PropertyType;

            DynamicMethod dynamicMethod = CreateGetterMethod(propertyInfo.Name, runtimePropertyType);
            ILGenerator generator = dynamicMethod.GetILGenerator();

            generator.Emit(OpCodes.Ldarg_0);

            if (declaringType.IsValueType)
            {
                generator.Emit(OpCodes.Unbox, declaringType);
                generator.Emit(OpCodes.Call, realMethod);
            }
            else
            {
                generator.Emit(OpCodes.Castclreplaced, declaringType);
                generator.Emit(OpCodes.Callvirt, realMethod);
            }

            // declaredPropertyType: Type of the property
            // runtimePropertyType:  <T> of JsonConverter / JsonPropertyInfo

            if (declaredPropertyType != runtimePropertyType && declaredPropertyType.IsValueType)
            {
                generator.Emit(OpCodes.Box, declaredPropertyType);
            }

            generator.Emit(OpCodes.Ret);

            return dynamicMethod;
        }

19 View Source File : ReflectionHandlerFactory.cs
License : MIT License
Project Creator : aquilahkj

private static FastMethodHandler CreateMethodHandler(MethodInfo methodInfo)
        {
            int num;
            var method = new DynamicMethod(string.Empty, typeof(object), new[]
            {
                typeof(object),
                typeof(object[])
            }, methodInfo.DeclaringType.GetTypeInfo().Module);
            var iLGenerator = method.GetILGenerator();
            var parameters = methodInfo.GetParameters();
            var typeArray = new Type[parameters.Length];
            for (num = 0; num < typeArray.Length; num++)
            {
                if (parameters[num].ParameterType.IsByRef)
                {
                    typeArray[num] = parameters[num].ParameterType.GetElementType();
                }
                else
                {
                    typeArray[num] = parameters[num].ParameterType;
                }
            }

            var builderArray = new LocalBuilder[typeArray.Length];
            for (num = 0; num < typeArray.Length; num++)
            {
                builderArray[num] = iLGenerator.DeclareLocal(typeArray[num], true);
            }

            for (num = 0; num < typeArray.Length; num++)
            {
                iLGenerator.Emit(OpCodes.Ldarg_1);
                EmitFastInt(iLGenerator, num);
                iLGenerator.Emit(OpCodes.Ldelem_Ref);
                EmitCastToReference(iLGenerator, typeArray[num]);
                iLGenerator.Emit(OpCodes.Stloc, builderArray[num]);
            }

            if (!methodInfo.IsStatic)
            {
                iLGenerator.Emit(OpCodes.Ldarg_0);
            }

            for (num = 0; num < typeArray.Length; num++)
            {
                iLGenerator.Emit(parameters[num].ParameterType.IsByRef ? OpCodes.Ldloca_S : OpCodes.Ldloc,
                    builderArray[num]);
            }

            iLGenerator.EmitCall(methodInfo.IsStatic ? OpCodes.Call : OpCodes.Callvirt, methodInfo, null);
            if (methodInfo.ReturnType == typeof(void))
            {
                iLGenerator.Emit(OpCodes.Ldnull);
            }
            else
            {
                EmitBoxIfNeeded(iLGenerator, methodInfo.ReturnType);
            }

            for (num = 0; num < typeArray.Length; num++)
            {
                if (parameters[num].ParameterType.IsByRef)
                {
                    iLGenerator.Emit(OpCodes.Ldarg_1);
                    EmitFastInt(iLGenerator, num);
                    iLGenerator.Emit(OpCodes.Ldloc, builderArray[num]);
                    if (builderArray[num].LocalType.GetTypeInfo().IsValueType)
                    {
                        iLGenerator.Emit(OpCodes.Box, builderArray[num].LocalType);
                    }

                    iLGenerator.Emit(OpCodes.Stelem_Ref);
                }
            }

            iLGenerator.Emit(OpCodes.Ret);
            return (FastMethodHandler) method.CreateDelegate(typeof(FastMethodHandler));
        }

19 View Source File : EntityProxyFactory.cs
License : MIT License
Project Creator : Azure

private static void BuildConstructor(TypeBuilder typeBuilder)
        {
            var ctorArgTypes = new[] { typeof(IEnreplacedyProxyContext), typeof(EnreplacedyId) };

            // Create ctor
            var ctor = typeBuilder.DefineConstructor(
                MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
                CallingConventions.Standard,
                ctorArgTypes);

            var ilGenerator = ctor.GetILGenerator();

            ilGenerator.Emit(OpCodes.Ldarg_0);
            ilGenerator.Emit(OpCodes.Ldarg_1);
            ilGenerator.Emit(OpCodes.Ldarg_2);
            ilGenerator.Emit(OpCodes.Call, typeof(EnreplacedyProxy).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, ctorArgTypes, null));
            ilGenerator.Emit(OpCodes.Ret);
        }

19 View Source File : EntityProxyFactory.cs
License : MIT License
Project Creator : Azure

private static void BuildMethods(TypeBuilder typeBuilder, Type interfaceType)
        {
            var methods = interfaceType.GetMethods(BindingFlags.Instance | BindingFlags.Public).ToList();

            // Interfaces can inherit from other interfaces, getting those methods too
            var interfaces = interfaceType.GetInterfaces();
            if (interfaces.Length > 0)
            {
                foreach (var inter in interfaces)
                {
                    methods.AddRange(inter.GetMethods(BindingFlags.Instance | BindingFlags.Public));
                }
            }

            if (methods.Count == 0)
            {
                throw new InvalidOperationException($"Interface '{interfaceType.FullName}' has no methods defined.");
            }

            var enreplacedyProxyMethods = typeof(EnreplacedyProxy).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance);

            var callAsyncMethod = enreplacedyProxyMethods.First(x => x.Name == nameof(EnreplacedyProxy.CallAsync) && !x.IsGenericMethod);
            var callAsyncGenericMethod = enreplacedyProxyMethods.First(x => x.Name == nameof(EnreplacedyProxy.CallAsync) && x.IsGenericMethod);
            var signalMethod = enreplacedyProxyMethods.First(x => x.Name == nameof(EnreplacedyProxy.Signal));

            foreach (var methodInfo in methods)
            {
                var parameters = methodInfo.GetParameters();

                // check that the number of arguments is zero or one
                if (parameters.Length > 1)
                {
                    throw new InvalidOperationException($"Method '{methodInfo.Name}' defines more than one parameter. Enreplacedy proxy interface methods must define at most one argument for operation input.");
                }

                var returnType = methodInfo.ReturnType;

                // check that return type is void / Task / Task<T>.
                if (returnType != typeof(void) && !(returnType == typeof(Task) || returnType.BaseType == typeof(Task)))
                {
                    throw new InvalidOperationException($"Method '{methodInfo.Name}' has a return type which is neither void nor a Task. Enreplacedy proxy interface methods may only return void, Task, or Task<T>.");
                }

                var proxyMethod = typeBuilder.DefineMethod(
                    methodInfo.Name,
                    MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.SpecialName | MethodAttributes.Virtual,
                    returnType,
                    parameters.Length == 0 ? null : new[] { parameters[0].ParameterType });

                typeBuilder.DefineMethodOverride(proxyMethod, methodInfo);

                var ilGenerator = proxyMethod.GetILGenerator();

                ilGenerator.Emit(OpCodes.Ldarg_0);
                ilGenerator.Emit(OpCodes.Ldstr, methodInfo.Name);

                if (parameters.Length == 0)
                {
                    ilGenerator.Emit(OpCodes.Ldnull);
                }
                else
                {
                    ilGenerator.Emit(OpCodes.Ldarg_1);

                    // ValueType needs boxing.
                    if (parameters[0].ParameterType.IsValueType)
                    {
                        ilGenerator.Emit(OpCodes.Box, parameters[0].ParameterType);
                    }
                }

                if (returnType == typeof(void))
                {
                    ilGenerator.Emit(OpCodes.Call, signalMethod);
                }
                else
                {
                    ilGenerator.DeclareLocal(returnType);

                    ilGenerator.Emit(OpCodes.Call, returnType.IsGenericType ? callAsyncGenericMethod.MakeGenericMethod(returnType.GetGenericArguments()[0]) : callAsyncMethod);

                    ilGenerator.Emit(OpCodes.Stloc_0);
                    ilGenerator.Emit(OpCodes.Ldloc_0);
                }

                ilGenerator.Emit(OpCodes.Ret);
            }
        }

19 View Source File : ILCompiler.cs
License : MIT License
Project Creator : badamczewski

public ILCompilationUnit Compile(string il)
        {
            ILTokenizer tokenizer = new ILTokenizer();
            ILParser iLParser = new ILParser();

            var tokens = tokenizer.Tokenize(il);
            var root = iLParser.Parse(tokens);

            if (root.Errors.Count > 0)
            {
                return new ILCompilationUnit() { Errors = root.Errors };
            }

            var name = Guid.NewGuid().ToString();
            var asm  = replacedemblyBuilder.DefineDynamicreplacedembly(
                new replacedemblyName(name),
                replacedemblyBuilderAccess.Run);

            var module = asm.DefineDynamicModule(name);
            var type = module.DefineType("Compilation", TypeAttributes.Public | TypeAttributes.BeforeFieldInit);

            foreach (var ilMethod in root.Clreplacedes.First().Methods)
            {
                var returnType = StringToType(ilMethod.Returns);
               
                Type[] argTypes = new Type[ilMethod.Args.Count];
                int idx = 0;
                foreach(var arg in ilMethod.Args)
                {
                    argTypes[idx++] = StringToType(arg.Type);
                }

                int indexOffset = 1;
                MethodAttributes attributes = MethodAttributes.Public;
                if (ilMethod.Accessor == "private")
                {
                    attributes = MethodAttributes.Private;
                }

                if (ilMethod.InstanceType == "static")
                {
                    attributes |= MethodAttributes.Static;
                    indexOffset = 0;
                }

                var method = type.DefineMethod(ilMethod.Name, attributes | MethodAttributes.HideBySig, returnType, argTypes);
                var ilGen  = method.GetILGenerator();


                //
                // Book keep the labels 
                //
                Label[] labels = new Label[ilMethod.Code.Count];
                int opCodeindex = 0;

                foreach (var opCode in ilMethod.Code)
                {
                    var label = default(Label);  

                    if (labels[opCodeindex] == default(Label))
                    {
                        label = ilGen.DefineLabel();
                    }
                    else
                    {
                        label = labels[opCodeindex];
                    }

                    ilGen.MarkLabel(label);


                    switch (opCode.OpCode)
                    {
                        //
                        // Consts and Loads
                        //
                        case "ldc.i4.0": ilGen.Emit(OpCodes.Ldc_I4_0); break;
                        case "ldc.i4.1": ilGen.Emit(OpCodes.Ldc_I4_1); break;
                        case "ldc.i4.2": ilGen.Emit(OpCodes.Ldc_I4_2); break;
                        case "ldc.i4.3": ilGen.Emit(OpCodes.Ldc_I4_3); break;
                        case "ldc.i4.4": ilGen.Emit(OpCodes.Ldc_I4_4); break;
                        case "ldc.i4.5": ilGen.Emit(OpCodes.Ldc_I4_5); break;
                        case "ldc.i4.6": ilGen.Emit(OpCodes.Ldc_I4_6); break;
                        case "ldc.i4.7": ilGen.Emit(OpCodes.Ldc_I4_7); break;
                        case "ldc.i4.8": ilGen.Emit(OpCodes.Ldc_I4_8); break;
                        case "ldc.i4.s": ilGen.Emit(OpCodes.Ldc_I4_S,  int.Parse(opCode.GetFirstArg())); break;
                        case "ldc.i4":   ilGen.Emit(OpCodes.Ldc_I4,    int.Parse(opCode.GetFirstArg())); break;
                        case "ldarg.0":  ilGen.Emit(OpCodes.Ldarg_0);  break;
                        case "ldarg.1":  ilGen.Emit(OpCodes.Ldarg_1);  break;
                        case "ldarg.2":  ilGen.Emit(OpCodes.Ldarg_2);  break;
                        case "ldarg.3":  ilGen.Emit(OpCodes.Ldarg_3);  break;
                        case "ldarg.s":  ilGen.Emit(OpCodes.Ldarg_S,   FindArgIndex(opCode.GetFirstArg(), ilMethod, indexOffset)); break;
                        case "ldarga.s": ilGen.Emit(OpCodes.Ldarga_S,  FindArgIndex(opCode.GetFirstArg(), ilMethod, indexOffset)); break;
                        case "starg.s":  ilGen.Emit(OpCodes.Starg_S,   FindArgIndex(opCode.GetFirstArg(), ilMethod, indexOffset)); break;
                        case "starg":    ilGen.Emit(OpCodes.Starg,     FindArgIndex(opCode.GetFirstArg(), ilMethod, indexOffset)); break;

                        //
                        // Stringsssss
                        //
                        case "ldstr":    ilGen.Emit(OpCodes.Ldstr, opCode.GetFirstArg()); break;


                        //
                        // Conditions
                        //

                        // !=
                        case "bne.un.s":
                            {
                                var existing = GetOrCreateLabel(ilGen, labels, opCode, ilMethod);
                                ilGen.Emit(OpCodes.Bne_Un_S, existing); break;
                            }
                        case "bne.un":
                            {
                                var existing = GetOrCreateLabel(ilGen, labels, opCode, ilMethod);
                                ilGen.Emit(OpCodes.Bne_Un, existing); break;
                            }
                        // ==
                        case "beq.s":
                            {
                                var existing = GetOrCreateLabel(ilGen, labels, opCode, ilMethod);
                                ilGen.Emit(OpCodes.Beq_S, existing); break;
                            }
                        case "beq":
                            {
                                var existing = GetOrCreateLabel(ilGen, labels, opCode, ilMethod);
                                ilGen.Emit(OpCodes.Beq, existing); break;
                            }
                        // >=
                        case "bge.s":
                            {
                                var existing = GetOrCreateLabel(ilGen, labels, opCode, ilMethod);
                                ilGen.Emit(OpCodes.Bge_S, existing); break;
                            }
                        case "bge":
                            {
                                var existing = GetOrCreateLabel(ilGen, labels, opCode, ilMethod);
                                ilGen.Emit(OpCodes.Bge, existing); break;
                            }
                        // <=
                        case "ble.s":
                            {
                                var existing = GetOrCreateLabel(ilGen, labels, opCode, ilMethod);
                                ilGen.Emit(OpCodes.Ble_S, existing); break;
                            }
                        case "ble":
                            {
                                var existing = GetOrCreateLabel(ilGen, labels, opCode, ilMethod);
                                ilGen.Emit(OpCodes.Ble, existing); break;
                            }
                        // <
                        case "blt.s":
                            {
                                var existing = GetOrCreateLabel(ilGen, labels, opCode, ilMethod);
                                ilGen.Emit(OpCodes.Blt_S, existing); break;
                            }
                        case "blt":
                            {
                                var existing = GetOrCreateLabel(ilGen, labels, opCode, ilMethod);
                                ilGen.Emit(OpCodes.Blt, existing); break;
                            }
                        // >
                        case "bgt.s":
                            {
                                var existing = GetOrCreateLabel(ilGen, labels, opCode, ilMethod);
                                ilGen.Emit(OpCodes.Bgt_S, existing); break;
                            }
                        case "bgt":
                            {
                                var existing = GetOrCreateLabel(ilGen, labels, opCode, ilMethod);
                                ilGen.Emit(OpCodes.Bgt, existing); break;
                            }
                        // Unconditional Jump
                        case "br.s":
                            {
                                var existing = GetOrCreateLabel(ilGen, labels, opCode, ilMethod);
                                ilGen.Emit(OpCodes.Br_S, existing); break;
                            }
                        case "br":
                            {
                                var existing = GetOrCreateLabel(ilGen, labels, opCode, ilMethod);
                                ilGen.Emit(OpCodes.Br, existing); break;
                            }
                        case "stelem.i1": ilGen.Emit(OpCodes.Stelem_I1); break;
                        case "stelem.i2": ilGen.Emit(OpCodes.Stelem_I2); break;
                        case "stelem.i4": ilGen.Emit(OpCodes.Stelem_I4); break;
                        case "stelem.i8": ilGen.Emit(OpCodes.Stelem_I8); break;
                        case "stelem.r4": ilGen.Emit(OpCodes.Stelem_R4); break;
                        case "stelem.r8": ilGen.Emit(OpCodes.Stelem_R8); break;

                        //
                        // Boxing / Unboxing
                        //
                        case "box":       ilGen.Emit(OpCodes.Box,       StringToType(opCode.GetFirstArg())); break;
                        case "unbox.any": ilGen.Emit(OpCodes.Unbox_Any, StringToType(opCode.GetFirstArg())); break;
                        case "unbox":     ilGen.Emit(OpCodes.Unbox,     StringToType(opCode.GetFirstArg())); break;
                        //
                        // Switch / Case
                        //
                        case "switch":    ilGen.Emit(OpCodes.Switch, GetOrCreateLabels(ilGen, labels, opCode, ilMethod)); break;
                        //
                        // Call
                        // This needs better handling; we want to call methods we have defined in IL
                        // so to do this we first would need to figure out which one to emit first.
                        //
                        case "call":     ilGen.Emit(OpCodes.Call,     CreateCall((ILCallInst)opCode)); break;
                        case "callvirt": ilGen.Emit(OpCodes.Callvirt, CreateCall((ILCallInst)opCode)); break;
                        //
                        // Maths 
                        //
                        case "sub":      ilGen.Emit(OpCodes.Sub); break;
                        case "mul":      ilGen.Emit(OpCodes.Mul); break;
                        case "div":      ilGen.Emit(OpCodes.Div); break;
                        case "add":      ilGen.Emit(OpCodes.Add); break;
                        case "ret":      ilGen.Emit(OpCodes.Ret); break;
                    }

                    opCodeindex++;
                }
            }

            return new ILCompilationUnit() { CompiledType = type.CreateType() };
        }

19 View Source File : MethodPatchFactory.cs
License : MIT License
Project Creator : Bannerlord-Coop-Team

public static DynamicMethod GeneratePatch(
            string sMethodName,
            PatchedInvokable patchedInvokable,
            MethodInfo dispatcher)
        {
            var parameters = patchedInvokable.Original.GetParameters()
                .Select(
                    p => new SMethodParameter
                    {
                        Info = p,
                        ParameterType =
                            p.ParameterType,
                        Name = p.Name
                    })
                .ToList();
            if (!patchedInvokable.Original.IsStatic)
                parameters.Insert(
                    0,
                    new SMethodParameter
                    {
                        Info = null,
                        ParameterType = patchedInvokable.Original.DeclaringType,
                        Name = "__instance"
                    }); // Inject an __instance

            var dyn = new DynamicMethod(
                sMethodName,
                dispatcher.ReturnType,
                parameters.Select(p => p.ParameterType).ToArray(),
                patchedInvokable.DeclaringType,
                true);

            for (var i = 0; i < parameters.Count; ++i)
            {
                var parameter = parameters[i];
                var attr = parameter.Info?.Attributes ?? ParameterAttributes.In;

                var iArgIndex = i + 1; // +1 because 0 is the return value
                dyn.DefineParameter(iArgIndex, attr, parameter.Name);
            }

            // Generate a dispatcher call
            var il = dyn.GetILGenerator();

            // We want to embed the SyncMethod instance into the DynamicMethod. Unsafe code ahead!
            // https://stackoverflow.com/questions/4989681/place-an-object-on-top-of-stack-in-ilgenerator
            var gcHandle = GCHandle.Alloc(patchedInvokable);
            var pMethod = GCHandle.ToIntPtr(gcHandle);

            // Arg0: SyncMethod instance
            if (IntPtr.Size == 4)
                il.Emit(OpCodes.Ldc_I4, pMethod.ToInt32());
            else
                il.Emit(OpCodes.Ldc_I8, pMethod.ToInt64());

            il.Emit(OpCodes.Ldobj, typeof(PatchedInvokable));

            // Arg1: The instance. 
            var isStatic = patchedInvokable.Original.IsStatic;
            if (isStatic)
            {
                il.Emit(OpCodes.Ldnull);
            }
            else
            {
                // Forwarded the injected "__instance" field
                il.Emit(OpCodes.Ldarg_0);

                // Remove the injected instance from the parameters
                parameters.RemoveAt(0);
            }

            // Arg2: object[] of all args. Prepare the array
            var args = il.DeclareLocal(typeof(object[]));

            // start off by creating an object[] with correct size
            il.Emit(OpCodes.Ldc_I4, parameters.Count);
            il.Emit(OpCodes.Newarr, typeof(object));
            il.Emit(OpCodes.Stloc, args); // store into local var `args`

            // Place argument in array
            for (var i = 0; i < parameters.Count; ++i)
            {
                var iArgIndex = isStatic ? i : i + 1; // +1 because of the injected __instance
                il.Emit(OpCodes.Ldloc, args); // Object reference to `args`
                il.Emit(OpCodes.Ldc_I4, i); // Array index into `args`
                il.Emit(OpCodes.Ldarg, iArgIndex); // value to put at index
                if (parameters[i].ParameterType.IsValueType) il.Emit(OpCodes.Box, parameters[i].ParameterType);

                il.Emit(OpCodes.Stelem_Ref); // pops value, index and array reference from stack.
            }

            // Arg2 done, push it to the stack
            il.Emit(OpCodes.Ldloc, args); // Object reference to `args`

            // Call dispatcher
            il.EmitCall(dispatcher.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, dispatcher, null);

            // Done
            il.Emit(OpCodes.Ret);

            return dyn;
        }

19 View Source File : MethodPatchFactory.cs
License : MIT License
Project Creator : Bannerlord-Coop-Team

public static DynamicMethod GeneratePatch(
            string sMethodName,
            PatchedInvokable patchedInvokable,
            MethodInfo dispatcher)
        {
            var parameters = patchedInvokable.Original.GetParameters()
                .Select(
                    p => new SMethodParameter
                    {
                        Info = p,
                        ParameterType =
                            p.ParameterType,
                        Name = p.Name
                    })
                .ToList();
            if (!patchedInvokable.Original.IsStatic)
                parameters.Insert(
                    0,
                    new SMethodParameter
                    {
                        Info = null,
                        ParameterType = patchedInvokable.Original.DeclaringType,
                        Name = "__instance"
                    }); // Inject an __instance

            var dyn = new DynamicMethod(
                sMethodName,
                dispatcher.ReturnType,
                parameters.Select(p => p.ParameterType).ToArray(),
                patchedInvokable.DeclaringType,
                true);

            for (var i = 0; i < parameters.Count; ++i)
            {
                var parameter = parameters[i];
                var attr = parameter.Info?.Attributes ?? ParameterAttributes.In;

                var iArgIndex = i + 1; // +1 because 0 is the return value
                dyn.DefineParameter(iArgIndex, attr, parameter.Name);
            }

            // Generate a dispatcher call
            var il = dyn.GetILGenerator();

            // We want to embed the SyncMethod instance into the DynamicMethod. Unsafe code ahead!
            // https://stackoverflow.com/questions/4989681/place-an-object-on-top-of-stack-in-ilgenerator
            var gcHandle = GCHandle.Alloc(patchedInvokable);
            var pMethod = GCHandle.ToIntPtr(gcHandle);

            // Arg0: SyncMethod instance
            if (IntPtr.Size == 4)
                il.Emit(OpCodes.Ldc_I4, pMethod.ToInt32());
            else
                il.Emit(OpCodes.Ldc_I8, pMethod.ToInt64());

            il.Emit(OpCodes.Ldobj, typeof(PatchedInvokable));

            // Arg1: The instance. 
            var isStatic = patchedInvokable.Original.IsStatic;
            if (isStatic)
            {
                il.Emit(OpCodes.Ldnull);
            }
            else
            {
                // Forwarded the injected "__instance" field
                il.Emit(OpCodes.Ldarg_0);

                // Remove the injected instance from the parameters
                parameters.RemoveAt(0);
            }

            // Arg2: object[] of all args. Prepare the array
            var args = il.DeclareLocal(typeof(object[]));

            // start off by creating an object[] with correct size
            il.Emit(OpCodes.Ldc_I4, parameters.Count);
            il.Emit(OpCodes.Newarr, typeof(object));
            il.Emit(OpCodes.Stloc, args); // store into local var `args`

            // Place argument in array
            for (var i = 0; i < parameters.Count; ++i)
            {
                var iArgIndex = isStatic ? i : i + 1; // +1 because of the injected __instance
                il.Emit(OpCodes.Ldloc, args); // Object reference to `args`
                il.Emit(OpCodes.Ldc_I4, i); // Array index into `args`
                il.Emit(OpCodes.Ldarg, iArgIndex); // value to put at index
                if (parameters[i].ParameterType.IsValueType) il.Emit(OpCodes.Box, parameters[i].ParameterType);

                il.Emit(OpCodes.Stelem_Ref); // pops value, index and array reference from stack.
            }

            // Arg2 done, push it to the stack
            il.Emit(OpCodes.Ldloc, args); // Object reference to `args`

            // Call dispatcher
            il.EmitCall(dispatcher.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, dispatcher, null);

            // Done
            il.Emit(OpCodes.Ret);

            return dyn;
        }

19 View Source File : MessageController.cs
License : Apache License 2.0
Project Creator : beetlex-io

private static FastMethodHandler CreateMethodHandler(MethodInfo methodInfo)
		{
			DynamicMethod dynamicMethod = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object), typeof(object[]) }, methodInfo.DeclaringType.Module);
			ILGenerator il = dynamicMethod.GetILGenerator();
			ParameterInfo[] ps = methodInfo.GetParameters();
			Type[] paramTypes = new Type[ps.Length];
			for (int i = 0; i < paramTypes.Length; i++)
			{
				if (ps[i].ParameterType.IsByRef)
					paramTypes[i] = ps[i].ParameterType.GetElementType();
				else
					paramTypes[i] = ps[i].ParameterType;
			}
			LocalBuilder[] locals = new LocalBuilder[paramTypes.Length];

			for (int i = 0; i < paramTypes.Length; i++)
			{
				locals[i] = il.DeclareLocal(paramTypes[i], true);
			}
			for (int i = 0; i < paramTypes.Length; i++)
			{
				il.Emit(OpCodes.Ldarg_1);
				EmitFastInt(il, i);
				il.Emit(OpCodes.Ldelem_Ref);
				EmitCastToReference(il, paramTypes[i]);
				il.Emit(OpCodes.Stloc, locals[i]);
			}
			if (!methodInfo.IsStatic)
			{
				il.Emit(OpCodes.Ldarg_0);
			}
			for (int i = 0; i < paramTypes.Length; i++)
			{
				if (ps[i].ParameterType.IsByRef)
					il.Emit(OpCodes.Ldloca_S, locals[i]);
				else
					il.Emit(OpCodes.Ldloc, locals[i]);
			}
			if (methodInfo.IsStatic)
				il.EmitCall(OpCodes.Call, methodInfo, null);
			else
				il.EmitCall(OpCodes.Callvirt, methodInfo, null);
			if (methodInfo.ReturnType == typeof(void))
				il.Emit(OpCodes.Ldnull);
			else
				EmitBoxIfNeeded(il, methodInfo.ReturnType);

			for (int i = 0; i < paramTypes.Length; i++)
			{
				if (ps[i].ParameterType.IsByRef)
				{
					il.Emit(OpCodes.Ldarg_1);
					EmitFastInt(il, i);
					il.Emit(OpCodes.Ldloc, locals[i]);
					if (locals[i].LocalType.IsValueType)
						il.Emit(OpCodes.Box, locals[i].LocalType);
					il.Emit(OpCodes.Stelem_Ref);
				}
			}

			il.Emit(OpCodes.Ret);
			FastMethodHandler invoder = (FastMethodHandler)dynamicMethod.CreateDelegate(typeof(FastMethodHandler));
			return invoder;
		}

19 View Source File : EntityReader.cs
License : Apache License 2.0
Project Creator : beetlex-io

private static FastMethodHandler CreateMethodHandler(MethodInfo methodInfo)
        {
            DynamicMethod dynamicMethod = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object), typeof(object[]) }, methodInfo.DeclaringType.Module);
            ILGenerator il = dynamicMethod.GetILGenerator();
            ParameterInfo[] ps = methodInfo.GetParameters();
            Type[] paramTypes = new Type[ps.Length];
            for (int i = 0; i < paramTypes.Length; i++)
            {
                if (ps[i].ParameterType.IsByRef)
                    paramTypes[i] = ps[i].ParameterType.GetElementType();
                else
                    paramTypes[i] = ps[i].ParameterType;
            }
            LocalBuilder[] locals = new LocalBuilder[paramTypes.Length];

            for (int i = 0; i < paramTypes.Length; i++)
            {
                locals[i] = il.DeclareLocal(paramTypes[i], true);
            }
            for (int i = 0; i < paramTypes.Length; i++)
            {
                il.Emit(OpCodes.Ldarg_1);
                EmitFastInt(il, i);
                il.Emit(OpCodes.Ldelem_Ref);
                EmitCastToReference(il, paramTypes[i]);
                il.Emit(OpCodes.Stloc, locals[i]);
            }
            if (!methodInfo.IsStatic)
            {
                il.Emit(OpCodes.Ldarg_0);
            }
            for (int i = 0; i < paramTypes.Length; i++)
            {
                if (ps[i].ParameterType.IsByRef)
                    il.Emit(OpCodes.Ldloca_S, locals[i]);
                else
                    il.Emit(OpCodes.Ldloc, locals[i]);
            }
            if (methodInfo.IsStatic)
                il.EmitCall(OpCodes.Call, methodInfo, null);
            else
                il.EmitCall(OpCodes.Callvirt, methodInfo, null);
            if (methodInfo.ReturnType == typeof(void))
                il.Emit(OpCodes.Ldnull);
            else
                EmitBoxIfNeeded(il, methodInfo.ReturnType);

            for (int i = 0; i < paramTypes.Length; i++)
            {
                if (ps[i].ParameterType.IsByRef)
                {
                    il.Emit(OpCodes.Ldarg_1);
                    EmitFastInt(il, i);
                    il.Emit(OpCodes.Ldloc, locals[i]);
                    if (locals[i].LocalType.IsValueType)
                        il.Emit(OpCodes.Box, locals[i].LocalType);
                    il.Emit(OpCodes.Stelem_Ref);
                }
            }

            il.Emit(OpCodes.Ret);
            FastMethodHandler invoder = (FastMethodHandler)dynamicMethod.CreateDelegate(typeof(FastMethodHandler));
            return invoder;
        }

19 View Source File : IL2CPPDetourMethodPatcher.cs
License : GNU Lesser General Public License v2.1
Project Creator : BepInEx

private static void EmitConvertArgumentToManaged(ILGenerator il,
                                                         int argIndex,
                                                         Type managedParamType,
                                                         out LocalBuilder variable)
        {
            variable = null;

            // Box struct into object first before conversion
            // This will likely incur struct copying down the line, but it shouldn't be a mreplacedive loss
            if (managedParamType.IsSubclreplacedOf(typeof(ValueType)))
            {
                il.Emit(OpCodes.Ldc_I8, Il2CppTypeToClreplacedPointer(managedParamType).ToInt64());
                il.Emit(OpCodes.Conv_I);
                il.Emit(OpCodes.Ldarga_S, argIndex);
                il.Emit(OpCodes.Call,
                        AccessTools.Method(typeof(UnhollowerBaseLib.IL2CPP),
                                           nameof(UnhollowerBaseLib.IL2CPP.il2cpp_value_box)));
            }
            else
            {
                il.Emit(OpCodes.Ldarg_S, argIndex);
            }

            if (managedParamType.IsValueType) // don't need to convert blittable types
                return;

            void EmitCreateIl2CppObject(Type originalType)
            {
                var endLabel = il.DefineLabel();
                var notNullLabel = il.DefineLabel();

                il.Emit(OpCodes.Dup);
                il.Emit(OpCodes.Brtrue_S, notNullLabel);

                il.Emit(OpCodes.Pop);
                il.Emit(OpCodes.Ldnull);
                il.Emit(OpCodes.Br_S, endLabel);

                il.MarkLabel(notNullLabel);
                il.Emit(OpCodes.Newobj, AccessTools.DeclaredConstructor(originalType, new[] { typeof(IntPtr) }));

                il.MarkLabel(endLabel);
            }

            void HandleTypeConversion(Type originalType)
            {
                if (originalType == typeof(string))
                    il.Emit(OpCodes.Call, IL2CPPToManagedStringMethodInfo);
                else if (originalType.IsSubclreplacedOf(typeof(Il2CppObjectBase)))
                    EmitCreateIl2CppObject(originalType);
            }

            if (managedParamType.IsByRef)
            {
                // TODO: directType being ValueType is not handled yet (but it's not that common in games). Implement when needed.
                var directType = managedParamType.GetElementType();

                variable = il.DeclareLocal(directType);

                il.Emit(OpCodes.Ldind_I);

                HandleTypeConversion(directType);

                il.Emit(OpCodes.Stloc, variable);
                il.Emit(OpCodes.Ldloca, variable);
            }
            else
            {
                HandleTypeConversion(managedParamType);
            }
        }

19 View Source File : IL2CPPDetourMethodPatcher.cs
License : GNU Lesser General Public License v2.1
Project Creator : BepInEx

private static void EmitConvertArgumentToManaged(ILGenerator il,
                                                         int argIndex,
                                                         Type managedParamType,
                                                         out LocalBuilder variable)
        {
            variable = null;

            // Box struct into object first before conversion
            // This will likely incur struct copying down the line, but it shouldn't be a mreplacedive loss
            if (managedParamType.IsSubclreplacedOf(typeof(ValueType)))
            {
                il.Emit(OpCodes.Ldc_I8, Il2CppTypeToClreplacedPointer(managedParamType).ToInt64());
                il.Emit(OpCodes.Conv_I);
                il.Emit(OpCodes.Ldarga_S, argIndex);
                il.Emit(OpCodes.Call,
                        AccessTools.Method(typeof(UnhollowerBaseLib.IL2CPP),
                                           nameof(UnhollowerBaseLib.IL2CPP.il2cpp_value_box)));
            }
            else
            {
                il.Emit(OpCodes.Ldarg_S, argIndex);
            }

            if (managedParamType.IsValueType) // don't need to convert blittable types
                return;

            void EmitCreateIl2CppObject(Type originalType)
            {
                var endLabel = il.DefineLabel();
                var notNullLabel = il.DefineLabel();

                il.Emit(OpCodes.Dup);
                il.Emit(OpCodes.Brtrue_S, notNullLabel);

                il.Emit(OpCodes.Pop);
                il.Emit(OpCodes.Ldnull);
                il.Emit(OpCodes.Br_S, endLabel);

                il.MarkLabel(notNullLabel);
                il.Emit(OpCodes.Newobj, AccessTools.DeclaredConstructor(originalType, new[] { typeof(IntPtr) }));

                il.MarkLabel(endLabel);
            }

            void HandleTypeConversion(Type originalType)
            {
                if (originalType == typeof(string))
                    il.Emit(OpCodes.Call, IL2CPPToManagedStringMethodInfo);
                else if (originalType.IsSubclreplacedOf(typeof(Il2CppObjectBase)))
                    EmitCreateIl2CppObject(originalType);
            }

            if (managedParamType.IsByRef)
            {
                // TODO: directType being ValueType is not handled yet (but it's not that common in games). Implement when needed.
                var directType = managedParamType.GetElementType();

                variable = il.DeclareLocal(directType);

                il.Emit(OpCodes.Ldind_I);

                HandleTypeConversion(directType);

                il.Emit(OpCodes.Stloc, variable);
                il.Emit(OpCodes.Ldloca, variable);
            }
            else
            {
                HandleTypeConversion(managedParamType);
            }
        }

19 View Source File : Il2CppManagedEnumerator.cs
License : GNU Lesser General Public License v2.1
Project Creator : BepInEx

private static System.Func<object, Object> GetValueBoxer(Type t)
        {
            if (boxers.TryGetValue(t, out var conv))
                return conv;

            var dm = new DynamicMethod($"Il2CppUnbox_{t.FullDescription()}", typeof(Object),
                                       new[] { typeof(object) });
            var il = dm.GetILGenerator();
            var loc = il.DeclareLocal(t);
            var clreplacedField = typeof(Il2CppClreplacedPointerStore<>).MakeGenericType(t)
                                                              .GetField(nameof(Il2CppClreplacedPointerStore<int>
                                                                                   .NativeClreplacedPtr));
            il.Emit(OpCodes.Ldsfld, clreplacedField);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Unbox_Any, t);
            il.Emit(OpCodes.Stloc, loc);
            il.Emit(OpCodes.Ldloca, loc);
            il.Emit(OpCodes.Call,
                    typeof(UnhollowerBaseLib.IL2CPP).GetMethod(nameof(UnhollowerBaseLib.IL2CPP.il2cpp_value_box)));
            il.Emit(OpCodes.Newobj, typeof(Object).GetConstructor(new[] { typeof(IntPtr) }));
            il.Emit(OpCodes.Ret);

            var converter = dm.CreateDelegate(typeof(System.Func<object, Object>)) as System.Func<object, Object>;
            boxers[t] = converter;
            return converter;
        }

19 View Source File : FieldNullable.cs
License : MIT License
Project Creator : BigBigZBBing

internal static LocalBuilder ToNullable(LocalBuilder stack, ILGenerator generator)
        {
            LocalBuilder NullValue = generator.DeclareLocal(typeof(Nullable<T>));
            generator.Emit(OpCodes.Ldloca_S, NullValue);
            generator.Emit(OpCodes.Ldloc_S, stack);
            generator.Emit(OpCodes.Call, typeof(Nullable<T>).GetConstructor(new Type[] { typeof(T) }));
            return NullValue;
        }

19 View Source File : TryCatchManager.cs
License : MIT License
Project Creator : BigBigZBBing

public TryCatchManager Catch(Action<LocalBuilder> builder)
        {
            generator.BeginCatchBlock(typeof(Exception));
            var ex = generator.DeclareLocal(typeof(Exception));
            generator.Emit(OpCodes.Stloc_S, ex);
            builder(ex);
            return this;
        }

19 View Source File : ComponentStyle.cs
License : MIT License
Project Creator : BlazorFluentUI

private static Func<object, object> GetCachedGetter(PropertyInfo property, Dictionary<PropertyInfo, Func<object,object>> cache)
        {
            long start = DateTime.Now.Ticks;
            if (cache.TryGetValue(property, out Func<object, object>? getter) == false)
            {
                DynamicMethod dynamicMethod = new(property.Name + "_DynamicMethod", typeof(Func<object, object>), new Type[] { typeof(object) });
                ILGenerator IL = dynamicMethod.GetILGenerator();
                IL.Emit(OpCodes.Ldarg_0);
                IL.Emit(OpCodes.Castclreplaced, property.DeclaringType!);
                IL.Emit(OpCodes.Call, property.GetGetMethod()!);
                IL.Emit(OpCodes.Ret);

                getter = (Func<object, object>)dynamicMethod.CreateDelegate(typeof(Func<object, object>));
                if (getter != null)
                    cache.Add(property, getter);
                //Debug.WriteLine($"Emit creation took: {TimeSpan.FromTicks(DateTime.Now.Ticks - start).TotalMilliseconds}ms");
            }
            else
            {
                //Debug.WriteLine($"Cached getter took: {TimeSpan.FromTicks(DateTime.Now.Ticks-start).TotalMilliseconds}ms");
            }

            return getter!;
        }

19 View Source File : ScriptComponentEditor.cs
License : MIT License
Project Creator : bonsai-rx

public override bool EditComponent(ITypeDescriptorContext context, object component, IServiceProvider provider, IWin32Window owner)
        {
            var scriptComponent = (CSharpScript)component;
            if (scriptComponent == null || provider == null) return false;

            var workflowBuilder = (WorkflowBuilder)provider.GetService(typeof(WorkflowBuilder));
            var commandExecutor = (CommandExecutor)provider.GetService(typeof(CommandExecutor));
            var editorService = (IWorkflowEditorService)provider.GetService(typeof(IWorkflowEditorService));
            var selectionModel = (WorkflowSelectionModel)provider.GetService(typeof(WorkflowSelectionModel));
            var scriptEnvironment = (IScriptEnvironment)provider.GetService(typeof(IScriptEnvironment));
            if (workflowBuilder == null || commandExecutor == null || selectionModel == null || scriptEnvironment == null)
            {
                return false;
            }

            var selectedView = selectionModel.SelectedView;
            if (selectedView == null) return false;

            var selectedNode = selectionModel.SelectedNodes.SingleOrDefault();
            if (selectedNode == null) return false;

            string typeName;
            string scriptFile;
            var inputType = default(Type);
            var scriptName = scriptComponent.Category + DefaultScriptName;
            using (var codeProvider = new CSharpCodeProvider())
            {
                var builderNode = (Node<ExpressionBuilder, ExpressionBuilderArgument>)selectedNode.Tag;
                var predecessor = selectedView.Workflow.Predecessors(builderNode).FirstOrDefault();
                if (predecessor != null)
                {
                    var expression = workflowBuilder.Workflow.Build(predecessor.Value);
                    if (expression.Type == typeof(void))
                    {
                        throw new InvalidOperationException(
                            "Script generation failed because the input type could not be determined. " +
                            "Please ensure that the preceding node has a valid output and that all " +
                            "other generated scripts have been successfully compiled.");
                    }

                    inputType = expression.Type;
                }

                var typeReference = CreateTypeReference(inputType ?? typeof(IObservable<int>));
                typeName = codeProvider.GetTypeOutput(typeReference);

                var extensionsDirectory = editorService.EnsureExtensionsDirectory();
                if (!extensionsDirectory.Exists) return false;

                using (var dialog = new SaveFileDialog { InitialDirectory = extensionsDirectory.FullName, FileName = scriptName, Filter = ScriptFilter })
                {
                    if (dialog.ShowDialog() != DialogResult.OK) return false;
                    scriptFile = dialog.FileName;
                    scriptName = Path.GetFileNameWithoutExtension(scriptFile);
                    if (!codeProvider.IsValidIdentifier(scriptName))
                    {
                        throw new InvalidOperationException(
                            "The specified name '" + scriptName + "' is not a valid type identifier. " +
                            "Valid identifiers must start with a letter and must not contain white spaces.");
                    }
                }
            }

            if (scriptEnvironment.replacedemblyName != null)
            {
                var existingType = Type.GetType(scriptName + ", " + scriptEnvironment.replacedemblyName.FullName);
                if (existingType != null)
                {
                    throw new InvalidOperationException("An extension type with the name " + scriptName + " already exists.");
                }
            }

            var namespaces = new HashSet<string>();
            var replacedemblyReferences = new HashSet<string>();
            replacedemblyReferences.Add("Bonsai.Core");
            namespaces.Add("Bonsai");
            namespaces.Add("System");
            namespaces.Add("System.ComponentModel");
            namespaces.Add("System.Collections.Generic");
            namespaces.Add("System.Linq");
            namespaces.Add("System.Reactive.Linq");
            if (inputType != null)
            {
                CollectNamespaces(inputType, namespaces);
                CollectreplacedemblyReferences(inputType, replacedemblyReferences);
                replacedemblyReferences.ExceptWith(IgnorereplacedemblyReferences);
            }
            scriptEnvironment.AddreplacedemblyReferences(replacedemblyReferences);

            var scriptBuilder = new StringBuilder();
            foreach (var ns in namespaces) scriptBuilder.AppendLine("using " + ns + ";");
            scriptBuilder.AppendLine();
            scriptBuilder.AppendLine("[Combinator]");
            scriptBuilder.AppendLine("[Description(\"\")]");
            scriptBuilder.AppendLine("[WorkflowElementCategory(ElementCategory." + scriptComponent.Category + ")]");
            scriptBuilder.AppendLine("public clreplaced " + scriptName);
            scriptBuilder.AppendLine("{");
            scriptBuilder.AppendLine("    public " + typeName + " Process(" + (inputType != null ? typeName + " source)" : ")"));
            scriptBuilder.AppendLine("    {");
            string template;
            switch (scriptComponent.Category)
            {
                case ElementCategory.Source: template = "Observable.Return(0)"; break;
                case ElementCategory.Transform: template = "source.Select(value => value)"; break;
                case ElementCategory.Sink: template = "source.Do(value => Console.WriteLine(value))"; break;
                case ElementCategory.Combinator: template = "source"; break;
                default: throw new InvalidOperationException("The specified element category is not allowed for automatic script generation.");
            }
            scriptBuilder.AppendLine("        return " + template + ";");
            scriptBuilder.AppendLine("    }");
            scriptBuilder.AppendLine("}");

            using (var writer = new StreamWriter(scriptFile))
            {
                writer.Write(scriptBuilder);
            }

            if (moduleBuilder == null)
            {
                var replacedemblyName = new replacedemblyName("@DynamicExtensions");
                var replacedemblyBuilder = replacedemblyBuilder.DefineDynamicreplacedembly(replacedemblyName, replacedemblyBuilderAccess.Run);
                var iconAttributeBuilder = new CustomAttributeBuilder(
                    typeof(WorkflowNamespaceIconAttribute).GetConstructor(new[] { typeof(string) }),
                    new object[] { "Bonsai:ElementIcon.CSharp" });
                replacedemblyBuilder.SetCustomAttribute(iconAttributeBuilder);
                moduleBuilder = replacedemblyBuilder.DefineDynamicModule(replacedemblyName.FullName);

                var emptyExpressionBuilder = moduleBuilder.DefineType("@EmptyExpression", TypeAttributes.Clreplaced, typeof(Expression));
                var propertyMethodAttributes = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.Virtual | MethodAttributes.HideBySig;
                var nodeTypeProperty = emptyExpressionBuilder.DefineProperty("NodeType", PropertyAttributes.None, typeof(ExpressionType), null);
                var nodeTypeGet = emptyExpressionBuilder.DefineMethod("get_NodeType", propertyMethodAttributes, typeof(ExpressionType), Type.EmptyTypes);
                var nodeTypeGetGenerator = nodeTypeGet.GetILGenerator();
                nodeTypeGetGenerator.Emit(OpCodes.Ldc_I4, (int)ExpressionType.Extension);
                nodeTypeGetGenerator.Emit(OpCodes.Ret);
                nodeTypeProperty.SetGetMethod(nodeTypeGet);

                var typeProperty = emptyExpressionBuilder.DefineProperty("Type", PropertyAttributes.None, typeof(Type), null);
                var typePropertyGet = emptyExpressionBuilder.DefineMethod("get_Type", propertyMethodAttributes, typeof(Type), Type.EmptyTypes);
                var typeGetGenerator = typePropertyGet.GetILGenerator();
                var typeGetExceptionConstructor = typeof(InvalidOperationException).GetConstructor(new[] { typeof(string) });
                typeGetGenerator.Emit(OpCodes.Ldstr, Resources.UncompiledScriptExpression_Error);
                typeGetGenerator.Emit(OpCodes.Newobj, typeGetExceptionConstructor);
                typeGetGenerator.Emit(OpCodes.Throw);
                typeProperty.SetGetMethod(typePropertyGet);

                var emptyExpressionType = emptyExpressionBuilder.CreateType();
                emptyExpression = emptyExpressionType.GetConstructor(Type.EmptyTypes);
            }

            var typeBuilder = moduleBuilder.DefineType(
                scriptName,
                TypeAttributes.Public | TypeAttributes.Clreplaced,
                inputType == null ? typeof(ZeroArgumentExpressionBuilder) : typeof(SingleArgumentExpressionBuilder));
            var descriptionAttributeBuilder = new CustomAttributeBuilder(
                typeof(DescriptionAttribute).GetConstructor(new[] { typeof(string) }),
                new object[] { "Extensions must be reloaded in order to compile and use the script." });
            var categoryAttributeBuilder = new CustomAttributeBuilder(
                typeof(WorkflowElementCategoryAttribute).GetConstructor(new[] { typeof(ElementCategory) }),
                new object[] { scriptComponent.Category });
            typeBuilder.SetCustomAttribute(descriptionAttributeBuilder);
            typeBuilder.SetCustomAttribute(categoryAttributeBuilder);
            var buildMethod = typeBuilder.DefineMethod("Build",
                MethodAttributes.Public |
                MethodAttributes.ReuseSlot |
                MethodAttributes.Virtual |
                MethodAttributes.HideBySig,
                typeof(Expression),
                new[] { typeof(IEnumerable<Expression>) });
            var generator = buildMethod.GetILGenerator();
            generator.Emit(OpCodes.Newobj, emptyExpression);
            generator.Emit(OpCodes.Ret);

            var type = typeBuilder.CreateType();
            var builder = new CombinatorBuilder();
            builder.Combinator = Activator.CreateInstance(type);
            selectedView.Editor.CreateGraphNode(builder, selectedNode, CreateGraphNodeType.Successor, branch: false, validate: false);
            selectedView.Editor.DeleteGraphNodes(selectionModel.SelectedNodes);
            commandExecutor.Execute(() => { }, null);

            ScriptEditorLauncher.Launch(owner, scriptEnvironment.ProjectFileName, scriptFile);
            return true;
        }

19 View Source File : ILEmitter.cs
License : MIT License
Project Creator : bryanperris

public void Emit(OpCode opcode, LocalBuilder local)
        {
            m_Generator.Emit(opcode, local);
            LogIL(opcode);
        }

19 View Source File : ILExtensions.cs
License : Apache License 2.0
Project Creator : busterwood

public static ILGenerator Store(this ILGenerator il, LocalBuilder local)
        {
            if (il == null)
                throw new ArgumentNullException(nameof(il));

            if (local == null)
                throw new ArgumentNullException(nameof(local));

            il.Emit(OpCodes.Stloc, local);
            return il;
        }

19 View Source File : ILExtensions.cs
License : Apache License 2.0
Project Creator : busterwood

public static ILGenerator Load(this ILGenerator il, LocalBuilder local)
        {
            if (local == null)
                throw new ArgumentNullException(nameof(local));
            if (il == null)
                throw new ArgumentNullException(nameof(il));

            il.Emit(OpCodes.Ldloc, local);
            return il;
        }

19 View Source File : TypeEmitHelper.cs
License : GNU Lesser General Public License v3.0
Project Creator : CarefreeXT

public static void GetFieldByIndex(this ILGenerator il, LocalBuilder field, int index, int argIndex = 1)
        {
            il.LoadArgument(argIndex);
            il.Emit(OpCodes.Ldc_I4, index);
            il.Emit(OpCodes.Ldelem_I4);
            il.Emit(OpCodes.Stloc, field);
        }

19 View Source File : TypeEmitHelper.cs
License : GNU Lesser General Public License v3.0
Project Creator : CarefreeXT

public static void IfFieldGreaterEqualZero(this ILGenerator il, LocalBuilder field, ref Label judge)
        {
            il.Emit(OpCodes.Ldloc, field);
            il.Emit(OpCodes.Ldc_I4_0);
            il.Emit(OpCodes.Blt_S, judge);
        }

19 View Source File : TypeEmitHelper.cs
License : GNU Lesser General Public License v3.0
Project Creator : CarefreeXT

public static void IfReaderIsDbNull(this ILGenerator il, Type type, LocalBuilder field, ref Label judge, int argIndex = 0)
        {
            if (type.IsNullable())
            {
                il.LoadArgument(argIndex);
                il.Emit(OpCodes.Ldloc, field);
                il.Emit(OpCodes.Callvirt, SupportMembers.DataReader.IsDBNull);
                il.Emit(OpCodes.Ldc_I4_0);
                il.Emit(OpCodes.Ceq);
                il.Emit(OpCodes.Brfalse_S, judge);
            }
        }

19 View Source File : TypeEmitHelper.cs
License : GNU Lesser General Public License v3.0
Project Creator : CarefreeXT

public static void IfReaderIsDbNull(this ILGenerator il, Type type, LocalBuilder field, ref Label judge, int argIndex = 0)
        {
            if (type.IsNullable())
            {
                il.LoadArgument(argIndex);
                il.Emit(OpCodes.Ldloc, field);
                il.Emit(OpCodes.Callvirt, SupportMembers.DataReader.IsDBNull);
                il.Emit(OpCodes.Ldc_I4_0);
                il.Emit(OpCodes.Ceq);
                il.Emit(OpCodes.Brfalse_S, judge);
            }
        }

19 View Source File : TypeEmitHelper.cs
License : GNU Lesser General Public License v3.0
Project Creator : CarefreeXT

public static void ReaderGetValue(this ILGenerator il, TypeMetadata metadata, PropertyInfo property, LocalBuilder field, int argIndex = 0)
        {
            var autoconvert = metadata.Engine.AutoTypeConversion;

            var type = property.PropertyType;
            var isConvert = metadata.Engine.TryGetConversion(type, out ConversionInfo info);
            if (isConvert)
            {
                type = info.StorageType;
            }

            il.LoadArgument(argIndex);
            il.Emit(OpCodes.Ldloc, field);

            if (autoconvert)
            {
                il.Emit(OpCodes.Callvirt, SupportMembers.DataReader.GetValue);
                var method = ValueConvertMethod.MakeGenericMethod(type);
                il.Emit(OpCodes.Call, method);
            }
            else
            {
                if (TypeMetadata.DataReaderMethodMap.TryGetValue(type, out MethodInfo getMethod))
                {
                    il.Emit(OpCodes.Callvirt, getMethod);
                }
                else
                {
                    il.Emit(OpCodes.Callvirt, SupportMembers.DataReader.GetValue);
                    il.Emit(OpCodes.Castclreplaced, type);
                }
                if (type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
                {
                    var constructor = type.GetConstructor(new Type[] { type.GetGenericArguments()[0] });
                    il.Emit(OpCodes.Newobj, constructor);
                }
            }
            if (isConvert)
            {
                il.Emit(OpCodes.Call, info.ConvertToObject);
            }
        }

19 View Source File : TypeEmitHelper.cs
License : GNU Lesser General Public License v3.0
Project Creator : CarefreeXT

public static void ReaderGetValue(this ILGenerator il, TypeMetadata metadata, PropertyInfo property, LocalBuilder field, int argIndex = 0)
        {
            var autoconvert = metadata.Engine.AutoTypeConversion;

            var type = property.PropertyType;
            var isConvert = metadata.Engine.TryGetConversion(type, out ConversionInfo info);
            if (isConvert)
            {
                type = info.StorageType;
            }

            il.LoadArgument(argIndex);
            il.Emit(OpCodes.Ldloc, field);

            if (autoconvert)
            {
                il.Emit(OpCodes.Callvirt, SupportMembers.DataReader.GetValue);
                var method = ValueConvertMethod.MakeGenericMethod(type);
                il.Emit(OpCodes.Call, method);
            }
            else
            {
                if (TypeMetadata.DataReaderMethodMap.TryGetValue(type, out MethodInfo getMethod))
                {
                    il.Emit(OpCodes.Callvirt, getMethod);
                }
                else
                {
                    il.Emit(OpCodes.Callvirt, SupportMembers.DataReader.GetValue);
                    il.Emit(OpCodes.Castclreplaced, type);
                }
                if (type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
                {
                    var constructor = type.GetConstructor(new Type[] { type.GetGenericArguments()[0] });
                    il.Emit(OpCodes.Newobj, constructor);
                }
            }
            if (isConvert)
            {
                il.Emit(OpCodes.Call, info.ConvertToObject);
            }
        }

19 View Source File : TypeEmitHelper.cs
License : GNU Lesser General Public License v3.0
Project Creator : CarefreeXT

public static void ArrayGetValue(this ILGenerator il, TypeMetadata metadata, PropertyInfo property, LocalBuilder field, int argIndex = 0)
        {
            var type = property.PropertyType;
            var isConvert = metadata.Engine.TryGetConversion(type, out ConversionInfo info);
            if (isConvert)
            {
                type = info.StorageType;
            }

            il.LoadArgument(argIndex);
            il.Emit(OpCodes.Ldloc, field);
            il.Emit(OpCodes.Ldelem_Ref);
            if (type.IsValueType)
            {
                il.Emit(OpCodes.Unbox_Any, type);
            }
            else
            {
                il.Emit(OpCodes.Castclreplaced, type);
            }
            if (type.IsGenericType
                   && type.GetGenericTypeDefinition().Equals(typeof(Nullable<>))
                   )
            {
                var constructor = type.GetConstructor(new Type[] { type.GetGenericArguments()[0] });
                il.Emit(OpCodes.Newobj, constructor);
            }
            if (isConvert)
            {
                il.Emit(OpCodes.Call, info.ConvertToObject);
            }
        }

See More Examples