public void Load( MethodEmitter method )
		{
			if ( m_Field != null )
			{
				method.LoadArgument( 0 );
				method.LoadField( m_Field );
			}
			else if ( m_Value == null )
			{
				method.LoadNull( m_Type );
			}
			else
			{
				if ( m_Value is int )
					method.Load( (int) m_Value );
				else if ( m_Value is long )
					method.Load( (long) m_Value );
				else if ( m_Value is float )
					method.Load( (float) m_Value );
				else if ( m_Value is double )
					method.Load( (double) m_Value );
				else if ( m_Value is char )
					method.Load( (char) m_Value );
				else if ( m_Value is bool )
					method.Load( (bool) m_Value );
				else if ( m_Value is string )
					method.Load( (string) m_Value );
				else if ( m_Value is Enum )
					method.Load( (Enum) m_Value );
				else
					throw new InvalidOperationException( "Unrecognized comparison value." );
			}
		}
		void ICondition.Compile( MethodEmitter emitter )
		{
			// The object was safely cast to be the conditionals type
			// If it's null, then the type cast didn't work...

			emitter.LoadNull();
			emitter.Compare( OpCodes.Ceq );
			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 override void Compile( MethodEmitter emitter )
		{
			emitter.Chain( m_Property );

			bool inverse = false;

			bool couldCompare =
			emitter.CompareTo( 1, delegate()
			{
				m_Value.Load( emitter );
			} );

			if ( couldCompare )
			{
				emitter.Load( 0 );

				switch ( m_Operator )
				{
					case ComparisonOperator.Equal:
						emitter.Compare( OpCodes.Ceq );
						break;

					case ComparisonOperator.NotEqual:
						emitter.Compare( OpCodes.Ceq );
						inverse = true;
						break;

					case ComparisonOperator.Greater:
						emitter.Compare( OpCodes.Cgt );
						break;

					case ComparisonOperator.GreaterEqual:
						emitter.Compare( OpCodes.Clt );
						inverse = true;
						break;

					case ComparisonOperator.Lesser:
						emitter.Compare( OpCodes.Clt );
						break;

					case ComparisonOperator.LesserEqual:
						emitter.Compare( OpCodes.Cgt );
						inverse = true;
						break;

					default:
						throw new InvalidOperationException( "Invalid comparison operator." );
				}
			}
			else
			{
				// This type is -not- comparable
				// We can only support == and != operations

				m_Value.Load( emitter );

				switch ( m_Operator )
				{
					case ComparisonOperator.Equal:
						emitter.Compare( OpCodes.Ceq );
						break;

					case ComparisonOperator.NotEqual:
						emitter.Compare( OpCodes.Ceq );
						inverse = true;
						break;

					case ComparisonOperator.Greater:
					case ComparisonOperator.GreaterEqual:
					case ComparisonOperator.Lesser:
					case ComparisonOperator.LesserEqual:
						throw new InvalidOperationException( "Property does not support relational comparisons." );

					default:
						throw new InvalidOperationException( "Invalid operator." );
				}
			}

			if ( m_Not != inverse )
				emitter.LogicalNot();
		}
		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 abstract void Compile( MethodEmitter emitter );
Пример #7
0
		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 );
		}
Пример #8
0
		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 );
		}