static void EmitTemplateInclude(ILGenerator gen, StringTemplateAST args) { var name = gen.DeclareLocal(typeof(string)); var ldnull = gen.DefineLabel(); var endinclude = gen.DefineLabel(); gen.Emit(OpCodes.Dup); gen.Emit(OpCodes.Brfalse_S, endinclude); // the dup of a null object already loaded null back on the stack gen.Emit(OpCodes.Call, GetFuncMethodInfo <object, string>((o) => o.ToString())); // at this point, the name is the top item on the evaluation stack gen.Emit(OpCodes.Dup); gen.Emit(OpCodes.Brfalse_S, endinclude); gen.Emit(OpCodes.Stloc, name); // $value = chunk.GetTemplateInclude(self, name, args); EmitLoadChunk(gen); EmitLoadSelf(gen); gen.Emit(OpCodes.Ldloc, name); // TODO: handle args throw new System.NotImplementedException(); //gen.Emit( OpCodes.Callvirt, typeof( ASTExpr ).GetMethod( "GetTemplateInclude", new System.Type[] { typeof( StringTemplate ), typeof( string ), typeof( StringTemplateAST ) } ) ); //gen.MarkLabel( endinclude ); }
static void EmitAnonymousTemplate(ILGenerator gen, string value) { // Stack behavior: ... => ..., (StringTemplate)result //System.Func<StringTemplate, string, object> loadTemplate = ( self, text ) => //{ // if ( text != null ) // { // StringTemplate valueST = new StringTemplate( self.Group, text ); // valueST.EnclosingInstance = self; // valueST.Name = "<anonymous template argument>"; // return valueST; // } // return null; //}; if (value != null) { EmitLoadSelf(gen); gen.Emit(OpCodes.Call, GetFuncMethodInfo(( StringTemplate self ) => (object)self.Group)); gen.Emit(OpCodes.Ldstr, value); gen.Emit(OpCodes.Newobj, typeof(StringTemplate).GetConstructor(new System.Type[] { typeof(StringTemplateGroup), typeof(string) })); // copies for set EnclosingInstance, set Name, and one left on the evaluation stack gen.Emit(OpCodes.Dup); gen.Emit(OpCodes.Dup); EmitLoadSelf(gen); gen.Emit(OpCodes.Call, GetActionMethodInfo((StringTemplate v, StringTemplate self) => v.EnclosingInstance = self)); gen.Emit(OpCodes.Call, GetActionMethodInfo(( StringTemplate v ) => v.Name = "<anonymous template argument>")); } else { gen.Emit(OpCodes.Ldnull); } }
public static TDelegate MethodEmit <TDelegate>(MethodInfo methodInfo) where TDelegate : class { Type[] parameterTypes; parameterTypes = GetFuncDelegateArguments <TDelegate>(); System.Reflection.Emit.DynamicMethod m = new System.Reflection.Emit.DynamicMethod( "call_" + methodInfo.Name, GetFuncDelegateReturnType <TDelegate>(), parameterTypes, methodInfo.DeclaringType, true); System.Reflection.Emit.ILGenerator cg = m.GetILGenerator(); for (int i = 0; i < parameterTypes.Length; i++) { cg.Emit(System.Reflection.Emit.OpCodes.Ldarg, i); if (i > 0 && parameterTypes[i] == typeof(object)) { cg.Emit(System.Reflection.Emit.OpCodes.Unbox_Any, methodInfo.GetParameters()[i - 1].ParameterType); } } cg.Emit(System.Reflection.Emit.OpCodes.Callvirt, methodInfo); if (methodInfo.ReturnType.IsValueType) { cg.Emit(System.Reflection.Emit.OpCodes.Box, methodInfo.ReturnType); } cg.Emit(System.Reflection.Emit.OpCodes.Ret); return(m.CreateDelegate(typeof(TDelegate)) as TDelegate); }
static void EmitObjectProperty(ILGenerator gen) { // Stack behavior: ..., (object)o, (object)propertyName => ..., (object)result EmitLoadChunk(gen); EmitLoadSelf(gen); gen.Emit(OpCodes.Call, GetFuncMethodInfo((object o, object propertyName, ASTExpr chunk, StringTemplate self) => chunk.GetObjectProperty(self, o, propertyName))); }
/// <summary> /// Initializes new instance of <see cref="MethodBodyGenerator"/> /// </summary> public MethodBodyGenerator(IMethodBase method, System.Reflection.Emit.ILGenerator generator, bool emitInfo = false) : base(generator, emitInfo) { Method = method; ReturnType = method.ReturnType; Context = method.Context; SyntaxTree = method.SyntaxBody; }
/// <summary> /// Creates a new ReflectionEmitILGenerator instance. /// </summary> /// <param name="generator"> The ILGenerator that is used to output the IL. </param> public ReflectionEmitILGenerator(System.Reflection.Emit.ILGenerator generator) { if (generator == null) { throw new ArgumentNullException(nameof(generator)); } this.generator = generator; }
/// <summary> /// Excel decimal 四舍五入 /// </summary> /// <param name="generator"></param> internal void CheckExcelDecimalSize(System.Reflection.Emit.ILGenerator generator) { if (DataType == typeof(decimal) && DataMember.DecimalSize > 0) { generator.int32(DataMember.DecimalSize); generator.call(Excel.DataReader.SetDecimalSize.Method); } }
public override void Emit(IEasyMember member, System.Reflection.Emit.ILGenerator gen) { ArgumentsUtil.EmitLoadOwnerAndReference(_target.OwnerReference, gen); _expression.Emit(member, gen); _target.StoreReference(gen); }
static LocalBuilder EmitCreateList <T>(ILGenerator gen) { var local = gen.DeclareLocal(typeof(List <T>)); gen.Emit(OpCodes.Newobj, typeof(List <T>).GetConstructor(new System.Type[0])); gen.Emit(OpCodes.Stloc, local); return(local); }
static void EmitAddNothingToList(ILGenerator gen, LocalBuilder local) { gen.Emit(OpCodes.Ldc_I4_1); gen.Emit(OpCodes.Newarr, typeof(object)); gen.Emit(OpCodes.Newobj, typeof(ArrayList).GetConstructor(new System.Type[] { typeof(ICollection) })); gen.Emit(OpCodes.Ldloc, local); gen.Emit(OpCodes.Call, GetActionMethodInfo((object value, List <object> list) => list.Add(value))); }
/// <summary> /// Creates a new ReflectionEmitILGenerator instance. /// </summary> /// <param name="generator"> The ILGenerator that is used to output the IL. </param> /// <param name="emitDebugInfo"> Indicates whether to emit debugging information, like symbol names. </param> public ReflectionEmitILGenerator(System.Reflection.Emit.ILGenerator generator, bool emitDebugInfo) { if (generator == null) { throw new ArgumentNullException(nameof(generator)); } this.generator = generator; this.emitDebugInfo = emitDebugInfo; }
static void EmitAttribute(ILGenerator gen, string attribute) { // Stack behavior: ... => ..., (object)result //$value=self.GetAttribute($i3.text); EmitLoadSelf(gen); gen.Emit(OpCodes.Ldstr, attribute); gen.Emit(OpCodes.Call, GetFuncMethodInfo((StringTemplate self, string attr) => self.GetAttribute(attr))); }
internal static object Creator(this Type type) { #if !NETSTANDARD1_3 if (!DefaultConstructor.ContainsKey(type)) { DefaultConstructor.Add(type, type.GetConstructor(Type.EmptyTypes)); } #endif if (DefaultConstructor.ContainsKey(type) && DefaultConstructor[type] != null) { #if NETSTANDARD2_0 || NETSTANDARD1_3 || NETSTANDARD1_5 if (CachedConstructor.ContainsKey(type)) { return(CachedConstructor[type].Invoke()); } CachedConstructor.Add(type, Expression.Lambda <Func <object> >(Expression.New(type)).Compile()); return(CachedConstructor[type].Invoke()); #else if (CachedDynamicMethod.ContainsKey(type)) { return(CachedDynamicMethod[type]()); } lock (CachedDynamicMethod) { var emptyConstructor = DefaultConstructor[type]; var dynamicMethod = new System.Reflection.Emit.DynamicMethod("CreateInstance", type, Type.EmptyTypes, true); System.Reflection.Emit.ILGenerator ilGenerator = dynamicMethod.GetILGenerator(); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Nop); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Newobj, emptyConstructor); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ret); CachedDynamicMethod.Add(type, (ObjectActivator)dynamicMethod.CreateDelegate(typeof(ObjectActivator))); } return(CachedDynamicMethod[type]()); #endif } else { #if !NETSTANDARD1_3 return(FormatterServices.GetUninitializedObject(type)); #else try { if (CachedConstructor.ContainsKey(type)) { return(CachedConstructor[type].Invoke()); } CachedConstructor.Add(type, Expression.Lambda <Func <object> >(Expression.New(type)).Compile()); return(CachedConstructor[type].Invoke()); } catch { throw new Exception("CloneError: Default constructor is require for NETSTANDARD1_3 for type " + type.FullName); } #endif } }
/// <summary> /// Creates a new ReflectionEmitILGenerator instance from a MethodBuilder. /// </summary> /// <param name="methodBuilder"> The MethodBuilder to emit IL for. </param> /// <param name="emitDebugInfo"> Indicates whether to emit debugging information, like symbol names. </param> public ReflectionEmitILGenerator(System.Reflection.Emit.MethodBuilder methodBuilder, bool emitDebugInfo) { if (methodBuilder == null) { throw new ArgumentNullException(nameof(methodBuilder)); } this.method = methodBuilder; this.generator = methodBuilder.GetILGenerator(); this.emitDebugInfo = emitDebugInfo; }
static void EmitApplyAlternatingTemplates(ILGenerator gen, LocalBuilder local) { //{$value = chunk.ApplyListOfAlternatingTemplates(self,$a.value,templatesToApply);} gen.Emit(OpCodes.Ldloc, local); EmitLoadChunk(gen); EmitLoadSelf(gen); gen.Emit(OpCodes.Call, GetFuncMethodInfo( (object value, List <StringTemplate> templates, ASTExpr chunk, StringTemplate self) => chunk.ApplyListOfAlternatingTemplates(self, value, templates) )); }
static void EmitWriteAttribute(ILGenerator gen) { // Stack behavior: ..., (object)value => ..., (int32)result // $numCharsWritten = chunk.WriteAttribute(self,$expr.value,writer); EmitLoadChunk(gen); EmitLoadSelf(gen); EmitLoadWriter(gen); gen.Emit(OpCodes.Call, GetFuncMethodInfo( (object o, ASTExpr chunk, StringTemplate self, IStringTemplateWriter writer) => chunk.WriteAttribute(self, o, writer) )); }
public static object DynEmit(this System.Reflection.Emit.ILGenerator il, object[] emitArgs) { Type operandType = emitArgs[1].GetType(); object target = il.GetProxiedShim() ?? (object) il; Dictionary<Type, MethodInfo> emitters = target is ILGeneratorShim ? _EmittersShim : _Emitters; if (!emitters.TryGetValue(operandType, out MethodInfo emit)) emit = emitters.FirstOrDefault(kvp => kvp.Key.IsAssignableFrom(operandType)).Value; if (emit == null) throw new InvalidOperationException($"Unexpected unemittable operand type {operandType.FullName}"); return emit.Invoke(target, emitArgs); }
public static Action <TField> StaticFieldSet <TField>(this Type source, FieldInfo fieldInfo) { System.Reflection.Emit.DynamicMethod m = new System.Reflection.Emit.DynamicMethod( "setter_" + fieldInfo.Name, typeof(void), new Type[] { typeof(TField) }, source); System.Reflection.Emit.ILGenerator cg = m.GetILGenerator(); // arg0.<field> = arg1 cg.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); cg.Emit(System.Reflection.Emit.OpCodes.Stsfld, fieldInfo); cg.Emit(System.Reflection.Emit.OpCodes.Ret); return((Action <TField>)m.CreateDelegate(typeof(Action <TField>))); }
public static int GetManagedSize(Type type) { var method = new System.Reflection.Emit.DynamicMethod("GetManagedSizeImpl", typeof(uint), null); System.Reflection.Emit.ILGenerator gen = method.GetILGenerator(); gen.Emit(System.Reflection.Emit.OpCodes.Sizeof, type); gen.Emit(System.Reflection.Emit.OpCodes.Ret); var func = (Func <uint>)method.CreateDelegate(typeof(Func <uint>)); return(checked ((int)func())); }
static void EmitAddValueToList(ILGenerator gen, LocalBuilder local) { var label1 = gen.DefineLabel(); var label2 = gen.DefineLabel(); gen.Emit(OpCodes.Dup); gen.Emit(OpCodes.Brfalse_S, label1); gen.Emit(OpCodes.Ldloc, local); gen.Emit(OpCodes.Call, GetActionMethodInfo((object value, List <object> list) => list.Add(value))); gen.Emit(OpCodes.Br_S, label2); gen.MarkLabel(label1); gen.Emit(OpCodes.Pop); gen.MarkLabel(label2); }
static void EmitWriteToString(ILGenerator gen) { // Stack behavior: ..., (object)value => ..., (string)result //System.Func<object, StringTemplate, object> write = ( value, self ) => //{ // StringWriter buf = new StringWriter(); // IStringTemplateWriter sw = self.Group.GetStringTemplateWriter( buf ); // int n = chunk.WriteAttribute( self, value, sw ); // if ( n > 0 ) // return buf.ToString(); // return value; //}; var value = gen.DeclareLocal(typeof(object)); var buf = gen.DeclareLocal(typeof(StringWriter)); var sw = gen.DeclareLocal(typeof(IStringTemplateWriter)); var preserveValue = gen.DefineLabel(); var endOfWrite = gen.DefineLabel(); gen.Emit(OpCodes.Stloc, value); gen.Emit(OpCodes.Newobj, typeof(StringWriter)); gen.Emit(OpCodes.Stloc, buf); EmitLoadSelf(gen); gen.Emit(OpCodes.Call, GetFuncMethodInfo(( StringTemplate self ) => self.Group)); gen.Emit(OpCodes.Ldloc, buf); gen.Emit(OpCodes.Call, GetFuncMethodInfo((StringTemplateGroup group, System.IO.TextWriter writer) => group.GetStringTemplateWriter(writer))); gen.Emit(OpCodes.Stloc, sw); EmitLoadChunk(gen); EmitLoadSelf(gen); gen.Emit(OpCodes.Ldloc, value); gen.Emit(OpCodes.Ldloc, sw); gen.Emit(OpCodes.Call, GetFuncMethodInfo((ASTExpr chunk, StringTemplate self, object o, IStringTemplateWriter writer) => chunk.WriteAttribute(self, o, writer))); gen.Emit(OpCodes.Ldc_I4_0); gen.Emit(OpCodes.Ble, preserveValue); gen.Emit(OpCodes.Ldloc, buf); gen.Emit(OpCodes.Call, GetFuncMethodInfo(( StringWriter writer ) => writer.ToString())); gen.Emit(OpCodes.Br_S, endOfWrite); gen.MarkLabel(preserveValue); gen.Emit(OpCodes.Ldloc, value); gen.MarkLabel(endOfWrite); }
static void EmitApplyAnonymousTemplate(ILGenerator gen, StringTemplate anonymous, LocalBuilder attributes) { // Stack behavior: ... => ..., (StringTemplate)result int index; lock ( _anonymousTemplates ) { index = _anonymousTemplates.Count; _anonymousTemplates.Add(anonymous); } EmitLoadChunk(gen); EmitLoadSelf(gen); gen.Emit(OpCodes.Ldloc, attributes); gen.Emit(OpCodes.Ldc_I4, index); gen.Emit(OpCodes.Call, GetFuncMethodInfo(( int i ) => _anonymousTemplates[i])); gen.Emit(OpCodes.Call, GetFuncMethodInfo( (ASTExpr chunk, StringTemplate self, List <object> attr, StringTemplate anon) => chunk.ApplyTemplateToListOfAttributes(self, attr, anon))); }
/// <summary> /// <para>以IL方式克隆(复制)该对象</para> /// Generic cloning method that clones an object using IL. /// Only the first call of a certain type will hold back performance. /// After the first call, the compiled IL is executed. /// </summary> /// <typeparam name="T">Type of object to clone</typeparam> /// <param name="myObject">Object to clone</param> /// <returns>Cloned object</returns> public static T CloneByIL <T>(this T myObject) { Delegate myExec = null; if (!_cachedIL.TryGetValue(typeof(T), out myExec)) { // Create ILGenerator System.Reflection.Emit.DynamicMethod dymMethod = new System.Reflection.Emit.DynamicMethod("DoClone", typeof(T), new Type[] { typeof(T) }, true); ConstructorInfo cInfo = myObject.GetType().GetConstructor(new Type[] { }); System.Reflection.Emit.ILGenerator generator = dymMethod.GetILGenerator(); System.Reflection.Emit.LocalBuilder lbf = generator.DeclareLocal(typeof(T)); //lbf.SetLocalSymInfo("_temp"); generator.Emit(System.Reflection.Emit.OpCodes.Newobj, cInfo); generator.Emit(System.Reflection.Emit.OpCodes.Stloc_0); foreach (FieldInfo field in myObject.GetType().GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic)) { // Load the new object on the eval stack... (currently 1 item on eval stack) generator.Emit(System.Reflection.Emit.OpCodes.Ldloc_0); // Load initial object (parameter) (currently 2 items on eval stack) generator.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // Replace value by field value (still currently 2 items on eval stack) generator.Emit(System.Reflection.Emit.OpCodes.Ldfld, field); // Store the value of the top on the eval stack into the object underneath that value on the value stack. // (0 items on eval stack) generator.Emit(System.Reflection.Emit.OpCodes.Stfld, field); } // Load new constructed obj on eval stack -> 1 item on stack generator.Emit(System.Reflection.Emit.OpCodes.Ldloc_0); // Return constructed object. --> 0 items on stack generator.Emit(System.Reflection.Emit.OpCodes.Ret); myExec = dymMethod.CreateDelegate(typeof(Func <T, T>)); _cachedIL.Add(typeof(T), myExec); } return(((Func <T, T>)myExec)(myObject)); }
internal static object Creator(this Type type) { if (!DefaultConstructor.ContainsKey(type)) { DefaultConstructor.Add(type, type.GetConstructor(Type.EmptyTypes)); } if (DefaultConstructor[type] != null) { #if NETSTANDARD2_0 || NETSTANDARD1_3 || NETSTANDARD1_5 if (CachedConstructor.ContainsKey(type)) { return(CachedConstructor[type].Invoke()); } return(CachedConstructor.GetOrAdd(type, Expression.Lambda <Func <object> >(Expression.New(type)).Compile()).Invoke()); #else if (CachedDynamicMethod.ContainsKey(type)) { return(CachedDynamicMethod[type]()); } var emptyConstructor = DefaultConstructor[type]; var dynamicMethod = new System.Reflection.Emit.DynamicMethod("CreateInstance", type, Type.EmptyTypes, true); System.Reflection.Emit.ILGenerator ilGenerator = dynamicMethod.GetILGenerator(); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Nop); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Newobj, emptyConstructor); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ret); return(CachedDynamicMethod.GetOrAdd(type, (ObjectActivator)dynamicMethod.CreateDelegate(typeof(ObjectActivator)))()); #endif } else { return(FormatterServices.GetUninitializedObject(type)); } }
/// <summary> /// Creates a new ReflectionEmitILGenerator instance. /// </summary> /// <param name="generator"> The ILGenerator that is used to output the IL. </param> public ReflectionEmitILGenerator(System.Reflection.Emit.ILGenerator generator) { if (generator == null) throw new ArgumentNullException("generator"); this.generator = generator; }
public static void EmitCallV(this System.Reflection.Emit.ILGenerator gen, System.Reflection.MethodInfo method) { gen.Emit(method.IsVirtual ? System.Reflection.Emit.OpCodes.Callvirt : System.Reflection.Emit.OpCodes.Call, method); }
public override void Emit(IEasyMember member, System.Reflection.Emit.ILGenerator gen) { _expression.Emit(member, gen); }
public abstract void Emit(IEasyMember member, System.Reflection.Emit.ILGenerator gen);
public override void Emit(IEasyMember member, System.Reflection.Emit.ILGenerator gen) { gen.MarkLabel(_label.Reference); }
private static void EmitCode(System.Reflection.Emit.ILGenerator generator) { generator.LoadConstant(140314); generator.Return(); }
/// <summary> /// Creates a new ReflectionEmitILGenerator instance. /// </summary> /// <param name="generator"> The ILGenerator that is used to output the IL. </param> public ReflectionEmitILGenerator(ScriptEngine engine, System.Reflection.Emit.MethodBuilder builder) { this.generator = builder.GetILGenerator(); this.builder = builder; Engine = engine; }