public static IComparer Compile(AssemblyEmitter assembly, Type objectType, OrderInfo[] orders) { TypeBuilder typeBuilder = assembly.DefineType( "__sort", TypeAttributes.Public, typeof(object)); #region Constructor { ConstructorBuilder ctor = typeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes); ILGenerator il = ctor.GetILGenerator(); // : base() il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes)); // return; il.Emit(OpCodes.Ret); } #endregion #region IComparer typeBuilder.AddInterfaceImplementation(typeof(IComparer)); MethodBuilder compareMethod; #region Compare { MethodEmitter emitter = new MethodEmitter(typeBuilder); emitter.Define( /* name */ "Compare", /* attr */ MethodAttributes.Public | MethodAttributes.Virtual, /* return */ typeof(int), /* params */ new Type[] { typeof(object), typeof(object) }); LocalBuilder a = emitter.CreateLocal(objectType); LocalBuilder b = emitter.CreateLocal(objectType); LocalBuilder v = emitter.CreateLocal(typeof(int)); emitter.LoadArgument(1); emitter.CastAs(objectType); emitter.StoreLocal(a); emitter.LoadArgument(2); emitter.CastAs(objectType); emitter.StoreLocal(b); emitter.Load(0); emitter.StoreLocal(v); Label end = emitter.CreateLabel(); for (int i = 0; i < orders.Length; ++i) { if (i > 0) { emitter.LoadLocal(v); emitter.BranchIfTrue(end); // if ( v != 0 ) return v; } OrderInfo orderInfo = orders[i]; Property prop = orderInfo.Property; int sign = orderInfo.Sign; emitter.LoadLocal(a); emitter.Chain(prop); bool couldCompare = emitter.CompareTo(sign, delegate() { emitter.LoadLocal(b); emitter.Chain(prop); }); if (!couldCompare) throw new InvalidOperationException("Property is not comparable."); emitter.StoreLocal(v); } emitter.MarkLabel(end); emitter.LoadLocal(v); emitter.Return(); typeBuilder.DefineMethodOverride( emitter.Method, typeof(IComparer).GetMethod( "Compare", new Type[] { typeof(object), typeof(object) })); compareMethod = emitter.Method; } #endregion #endregion Type comparerType = typeBuilder.CreateType(); return (IComparer)Activator.CreateInstance(comparerType); }
public override void Compile( MethodEmitter emitter ) { bool inverse = false; string methodName; switch ( m_Operator ) { case StringOperator.Equal: methodName = "Equals"; break; case StringOperator.NotEqual: methodName = "Equals"; inverse = true; break; case StringOperator.Contains: methodName = "Contains"; break; case StringOperator.StartsWith: methodName = "StartsWith"; break; case StringOperator.EndsWith: methodName = "EndsWith"; break; default: throw new InvalidOperationException( "Invalid string comparison operator." ); } if ( m_IgnoreCase || methodName == "Equals" ) { Type type = ( m_IgnoreCase ? typeof( Insensitive ) : typeof( String ) ); emitter.BeginCall( type.GetMethod( methodName, BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof( string ), typeof( string ) }, null ) ); emitter.Chain( m_Property ); m_Value.Load( emitter ); emitter.FinishCall(); } else { Label notNull = emitter.CreateLabel(); Label moveOn = emitter.CreateLabel(); LocalBuilder temp = emitter.AcquireTemp( m_Property.Type ); emitter.Chain( m_Property ); emitter.StoreLocal( temp ); emitter.LoadLocal( temp ); emitter.BranchIfTrue( notNull ); emitter.Load( false ); emitter.Pop(); emitter.Branch( moveOn ); emitter.MarkLabel( notNull ); emitter.LoadLocal( temp ); emitter.BeginCall( typeof( string ).GetMethod( methodName, BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof( string ) }, null ) ); m_Value.Load( emitter ); emitter.FinishCall(); emitter.MarkLabel( moveOn ); } if ( m_Not != inverse ) emitter.LogicalNot(); }
public static IConditional Compile( AssemblyEmitter assembly, Type objectType, ICondition[] conditions, int index ) { TypeBuilder typeBuilder = assembly.DefineType( "__conditional" + index, TypeAttributes.Public, typeof( object ) ); #region Constructor { ConstructorBuilder ctor = typeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes ); ILGenerator il = ctor.GetILGenerator(); // : base() il.Emit( OpCodes.Ldarg_0 ); il.Emit( OpCodes.Call, typeof( object ).GetConstructor( Type.EmptyTypes ) ); for ( int i = 0; i < conditions.Length; ++i ) conditions[i].Construct( typeBuilder, il, i ); // return; il.Emit( OpCodes.Ret ); } #endregion #region IComparer typeBuilder.AddInterfaceImplementation( typeof( IConditional ) ); MethodBuilder compareMethod; #region Compare { MethodEmitter emitter = new MethodEmitter( typeBuilder ); emitter.Define( /* name */ "Verify", /* attr */ MethodAttributes.Public | MethodAttributes.Virtual, /* return */ typeof( bool ), /* params */ new Type[] { typeof( object ) } ); LocalBuilder obj = emitter.CreateLocal( objectType ); LocalBuilder eq = emitter.CreateLocal( typeof( bool ) ); emitter.LoadArgument( 1 ); emitter.CastAs( objectType ); emitter.StoreLocal( obj ); Label done = emitter.CreateLabel(); for ( int i = 0; i < conditions.Length; ++i ) { if ( i > 0 ) { emitter.LoadLocal( eq ); emitter.BranchIfFalse( done ); } emitter.LoadLocal( obj ); conditions[i].Compile( emitter ); emitter.StoreLocal( eq ); } emitter.MarkLabel( done ); emitter.LoadLocal( eq ); emitter.Return(); typeBuilder.DefineMethodOverride( emitter.Method, typeof( IConditional ).GetMethod( "Verify", new Type[] { typeof( object ) } ) ); compareMethod = emitter.Method; } #endregion #endregion Type conditionalType = typeBuilder.CreateType(); return (IConditional) Activator.CreateInstance( conditionalType ); }
public static IComparer Compile(AssemblyEmitter assembly, Type objectType, OrderInfo[] orders) { TypeBuilder typeBuilder = assembly.DefineType( "__sort", TypeAttributes.Public, typeof(object) ); #region Constructor { ConstructorBuilder ctor = typeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes ); ILGenerator il = ctor.GetILGenerator(); // : base() il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes)); // return; il.Emit(OpCodes.Ret); } #endregion #region IComparer typeBuilder.AddInterfaceImplementation(typeof(IComparer)); MethodBuilder compareMethod; #region Compare { MethodEmitter emitter = new MethodEmitter(typeBuilder); emitter.Define( /* name */ "Compare", /* attr */ MethodAttributes.Public | MethodAttributes.Virtual, /* return */ typeof(int), /* params */ new Type[] { typeof(object), typeof(object) }); LocalBuilder a = emitter.CreateLocal(objectType); LocalBuilder b = emitter.CreateLocal(objectType); LocalBuilder v = emitter.CreateLocal(typeof(int)); emitter.LoadArgument(1); emitter.CastAs(objectType); emitter.StoreLocal(a); emitter.LoadArgument(2); emitter.CastAs(objectType); emitter.StoreLocal(b); emitter.Load(0); emitter.StoreLocal(v); Label end = emitter.CreateLabel(); for (int i = 0; i < orders.Length; ++i) { if (i > 0) { emitter.LoadLocal(v); emitter.BranchIfTrue(end); // if ( v != 0 ) return v; } OrderInfo orderInfo = orders[i]; Property prop = orderInfo.Property; int sign = orderInfo.Sign; emitter.LoadLocal(a); emitter.Chain(prop); bool couldCompare = emitter.CompareTo(sign, delegate() { emitter.LoadLocal(b); emitter.Chain(prop); }); if (!couldCompare) { throw new InvalidOperationException("Property is not comparable."); } emitter.StoreLocal(v); } emitter.MarkLabel(end); emitter.LoadLocal(v); emitter.Return(); typeBuilder.DefineMethodOverride( emitter.Method, typeof(IComparer).GetMethod( "Compare", new Type[] { typeof(object), typeof(object) } ) ); compareMethod = emitter.Method; } #endregion #endregion Type comparerType = typeBuilder.CreateType(); return((IComparer)Activator.CreateInstance(comparerType)); }
public static IComparer Compile(AssemblyEmitter assembly, Type objectType, Property[] props) { TypeBuilder typeBuilder = assembly.DefineType( "__distinct", TypeAttributes.Public, typeof(object)); #region Constructor { ConstructorBuilder ctor = typeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes); ILGenerator il = ctor.GetILGenerator(); // : base() il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes)); // return; il.Emit(OpCodes.Ret); } #endregion #region IComparer typeBuilder.AddInterfaceImplementation(typeof(IComparer)); MethodBuilder compareMethod; #region Compare { MethodEmitter emitter = new MethodEmitter(typeBuilder); emitter.Define( /* name */ "Compare", /* attr */ MethodAttributes.Public | MethodAttributes.Virtual, /* return */ typeof(int), /* params */ new Type[] { typeof(object), typeof(object) }); LocalBuilder a = emitter.CreateLocal(objectType); LocalBuilder b = emitter.CreateLocal(objectType); LocalBuilder v = emitter.CreateLocal(typeof(int)); emitter.LoadArgument(1); emitter.CastAs(objectType); emitter.StoreLocal(a); emitter.LoadArgument(2); emitter.CastAs(objectType); emitter.StoreLocal(b); emitter.Load(0); emitter.StoreLocal(v); Label end = emitter.CreateLabel(); for (int i = 0; i < props.Length; ++i) { if (i > 0) { emitter.LoadLocal(v); emitter.BranchIfTrue(end); // if ( v != 0 ) return v; } Property prop = props[i]; emitter.LoadLocal(a); emitter.Chain(prop); bool couldCompare = emitter.CompareTo(1, delegate() { emitter.LoadLocal(b); emitter.Chain(prop); }); if (!couldCompare) throw new InvalidOperationException("Property is not comparable."); emitter.StoreLocal(v); } emitter.MarkLabel(end); emitter.LoadLocal(v); emitter.Return(); typeBuilder.DefineMethodOverride( emitter.Method, typeof(IComparer).GetMethod( "Compare", new Type[] { typeof(object), typeof(object) })); compareMethod = emitter.Method; } #endregion #endregion #region IEqualityComparer typeBuilder.AddInterfaceImplementation(typeof(IEqualityComparer<object>)); #region Equals { MethodEmitter emitter = new MethodEmitter(typeBuilder); emitter.Define( /* name */ "Equals", /* attr */ MethodAttributes.Public | MethodAttributes.Virtual, /* return */ typeof(bool), /* params */ new Type[] { typeof(object), typeof(object) }); emitter.Generator.Emit(OpCodes.Ldarg_0); emitter.Generator.Emit(OpCodes.Ldarg_1); emitter.Generator.Emit(OpCodes.Ldarg_2); emitter.Generator.Emit(OpCodes.Call, compareMethod); emitter.Generator.Emit(OpCodes.Ldc_I4_0); emitter.Generator.Emit(OpCodes.Ceq); emitter.Generator.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride( emitter.Method, typeof(IEqualityComparer<object>).GetMethod( "Equals", new Type[] { typeof(object), typeof(object) })); } #endregion #region GetHashCode { MethodEmitter emitter = new MethodEmitter(typeBuilder); emitter.Define( /* name */ "GetHashCode", /* attr */ MethodAttributes.Public | MethodAttributes.Virtual, /* return */ typeof(int), /* params */ new Type[] { typeof(object) }); LocalBuilder obj = emitter.CreateLocal(objectType); emitter.LoadArgument(1); emitter.CastAs(objectType); emitter.StoreLocal(obj); for (int i = 0; i < props.Length; ++i) { Property prop = props[i]; emitter.LoadLocal(obj); emitter.Chain(prop); Type active = emitter.Active; MethodInfo getHashCode = active.GetMethod("GetHashCode", Type.EmptyTypes); if (getHashCode == null) getHashCode = typeof(object).GetMethod("GetHashCode", Type.EmptyTypes); if (active != typeof(int)) { if (!active.IsValueType) { LocalBuilder value = emitter.AcquireTemp(active); Label valueNotNull = emitter.CreateLabel(); Label done = emitter.CreateLabel(); emitter.StoreLocal(value); emitter.LoadLocal(value); emitter.BranchIfTrue(valueNotNull); emitter.Load(0); emitter.Pop(typeof(int)); emitter.Branch(done); emitter.MarkLabel(valueNotNull); emitter.LoadLocal(value); emitter.Call(getHashCode); emitter.ReleaseTemp(value); emitter.MarkLabel(done); } else { emitter.Call(getHashCode); } } if (i > 0) emitter.Xor(); } emitter.Return(); typeBuilder.DefineMethodOverride( emitter.Method, typeof(IEqualityComparer<object>).GetMethod( "GetHashCode", new Type[] { typeof(object) })); } #endregion #endregion Type comparerType = typeBuilder.CreateType(); return (IComparer)Activator.CreateInstance(comparerType); }
public static IComparer Compile(AssemblyEmitter assembly, Type objectType, Property[] props) { TypeBuilder typeBuilder = assembly.DefineType( "__distinct", TypeAttributes.Public, typeof(object) ); #region Constructor { ConstructorBuilder ctor = typeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes ); ILGenerator il = ctor.GetILGenerator(); // : base() il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes)); // return; il.Emit(OpCodes.Ret); } #endregion #region IComparer typeBuilder.AddInterfaceImplementation(typeof(IComparer)); MethodBuilder compareMethod; #region Compare { MethodEmitter emitter = new MethodEmitter(typeBuilder); emitter.Define( /* name */ "Compare", /* attr */ MethodAttributes.Public | MethodAttributes.Virtual, /* return */ typeof(int), /* params */ new Type[] { typeof(object), typeof(object) }); LocalBuilder a = emitter.CreateLocal(objectType); LocalBuilder b = emitter.CreateLocal(objectType); LocalBuilder v = emitter.CreateLocal(typeof(int)); emitter.LoadArgument(1); emitter.CastAs(objectType); emitter.StoreLocal(a); emitter.LoadArgument(2); emitter.CastAs(objectType); emitter.StoreLocal(b); emitter.Load(0); emitter.StoreLocal(v); Label end = emitter.CreateLabel(); for (int i = 0; i < props.Length; ++i) { if (i > 0) { emitter.LoadLocal(v); emitter.BranchIfTrue(end); // if ( v != 0 ) return v; } Property prop = props[i]; emitter.LoadLocal(a); emitter.Chain(prop); bool couldCompare = emitter.CompareTo(1, delegate() { emitter.LoadLocal(b); emitter.Chain(prop); }); if (!couldCompare) { throw new InvalidOperationException("Property is not comparable."); } emitter.StoreLocal(v); } emitter.MarkLabel(end); emitter.LoadLocal(v); emitter.Return(); typeBuilder.DefineMethodOverride( emitter.Method, typeof(IComparer).GetMethod( "Compare", new Type[] { typeof(object), typeof(object) } ) ); compareMethod = emitter.Method; } #endregion #endregion #region IEqualityComparer typeBuilder.AddInterfaceImplementation(typeof(IEqualityComparer <object>)); #region Equals { MethodEmitter emitter = new MethodEmitter(typeBuilder); emitter.Define( /* name */ "Equals", /* attr */ MethodAttributes.Public | MethodAttributes.Virtual, /* return */ typeof(bool), /* params */ new Type[] { typeof(object), typeof(object) }); emitter.Generator.Emit(OpCodes.Ldarg_0); emitter.Generator.Emit(OpCodes.Ldarg_1); emitter.Generator.Emit(OpCodes.Ldarg_2); emitter.Generator.Emit(OpCodes.Call, compareMethod); emitter.Generator.Emit(OpCodes.Ldc_I4_0); emitter.Generator.Emit(OpCodes.Ceq); emitter.Generator.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride( emitter.Method, typeof(IEqualityComparer <object>).GetMethod( "Equals", new Type[] { typeof(object), typeof(object) } ) ); } #endregion #region GetHashCode { MethodEmitter emitter = new MethodEmitter(typeBuilder); emitter.Define( /* name */ "GetHashCode", /* attr */ MethodAttributes.Public | MethodAttributes.Virtual, /* return */ typeof(int), /* params */ new Type[] { typeof(object) }); LocalBuilder obj = emitter.CreateLocal(objectType); emitter.LoadArgument(1); emitter.CastAs(objectType); emitter.StoreLocal(obj); for (int i = 0; i < props.Length; ++i) { Property prop = props[i]; emitter.LoadLocal(obj); emitter.Chain(prop); Type active = emitter.Active; MethodInfo getHashCode = active.GetMethod("GetHashCode", Type.EmptyTypes); if (getHashCode == null) { getHashCode = typeof(object).GetMethod("GetHashCode", Type.EmptyTypes); } if (active != typeof(int)) { if (!active.IsValueType) { LocalBuilder value = emitter.AcquireTemp(active); Label valueNotNull = emitter.CreateLabel(); Label done = emitter.CreateLabel(); emitter.StoreLocal(value); emitter.LoadLocal(value); emitter.BranchIfTrue(valueNotNull); emitter.Load(0); emitter.Pop(typeof(int)); emitter.Branch(done); emitter.MarkLabel(valueNotNull); emitter.LoadLocal(value); emitter.Call(getHashCode); emitter.ReleaseTemp(value); emitter.MarkLabel(done); } else { emitter.Call(getHashCode); } } if (i > 0) { emitter.Xor(); } } emitter.Return(); typeBuilder.DefineMethodOverride( emitter.Method, typeof(IEqualityComparer <object>).GetMethod( "GetHashCode", new Type[] { typeof(object) } ) ); } #endregion #endregion Type comparerType = typeBuilder.CreateType(); return((IComparer)Activator.CreateInstance(comparerType)); }
public static IConditional Compile(AssemblyEmitter assembly, Type objectType, ICondition[] conditions, int index) { TypeBuilder typeBuilder = assembly.DefineType( "__conditional" + index, TypeAttributes.Public, typeof(object) ); #region Constructor { ConstructorBuilder ctor = typeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes ); ILGenerator il = ctor.GetILGenerator(); // : base() il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes)); for (int i = 0; i < conditions.Length; ++i) { conditions[i].Construct(typeBuilder, il, i); } // return; il.Emit(OpCodes.Ret); } #endregion #region IComparer typeBuilder.AddInterfaceImplementation(typeof(IConditional)); MethodBuilder compareMethod; #region Compare { MethodEmitter emitter = new MethodEmitter(typeBuilder); emitter.Define( /* name */ "Verify", /* attr */ MethodAttributes.Public | MethodAttributes.Virtual, /* return */ typeof(bool), /* params */ new Type[] { typeof(object) }); LocalBuilder obj = emitter.CreateLocal(objectType); LocalBuilder eq = emitter.CreateLocal(typeof(bool)); emitter.LoadArgument(1); emitter.CastAs(objectType); emitter.StoreLocal(obj); Label done = emitter.CreateLabel(); for (int i = 0; i < conditions.Length; ++i) { if (i > 0) { emitter.LoadLocal(eq); emitter.BranchIfFalse(done); } emitter.LoadLocal(obj); conditions[i].Compile(emitter); emitter.StoreLocal(eq); } emitter.MarkLabel(done); emitter.LoadLocal(eq); emitter.Return(); typeBuilder.DefineMethodOverride( emitter.Method, typeof(IConditional).GetMethod( "Verify", new Type[] { typeof(object) } ) ); compareMethod = emitter.Method; } #endregion #endregion Type conditionalType = typeBuilder.CreateType(); return((IConditional)Activator.CreateInstance(conditionalType)); }
public override void Compile(MethodEmitter emitter) { bool inverse = false; string methodName; switch (m_Operator) { case StringOperator.Equal: methodName = "Equals"; break; case StringOperator.NotEqual: methodName = "Equals"; inverse = true; break; case StringOperator.Contains: methodName = "Contains"; break; case StringOperator.StartsWith: methodName = "StartsWith"; break; case StringOperator.EndsWith: methodName = "EndsWith"; break; default: throw new InvalidOperationException("Invalid string comparison operator."); } if (m_IgnoreCase || methodName == "Equals") { Type type = (m_IgnoreCase ? typeof(Insensitive) : typeof(String)); emitter.BeginCall( type.GetMethod( methodName, BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(string), typeof(string) }, null ) ); emitter.Chain(m_Property); m_Value.Load(emitter); emitter.FinishCall(); } else { Label notNull = emitter.CreateLabel(); Label moveOn = emitter.CreateLabel(); LocalBuilder temp = emitter.AcquireTemp(m_Property.Type); emitter.Chain(m_Property); emitter.StoreLocal(temp); emitter.LoadLocal(temp); emitter.BranchIfTrue(notNull); emitter.Load(false); emitter.Pop(); emitter.Branch(moveOn); emitter.MarkLabel(notNull); emitter.LoadLocal(temp); emitter.BeginCall( typeof(string).GetMethod( methodName, BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(string) }, null ) ); m_Value.Load(emitter); emitter.FinishCall(); emitter.MarkLabel(moveOn); } if (m_Not != inverse) { emitter.LogicalNot(); } }