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
19
View Source File : EntityMapperProvider.cs
License : Apache License 2.0
Project Creator : 1448376744
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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