public override void Compile(MethodEmitter emitter) { emitter.Chain(m_Property); bool inverse = false; bool couldCompare = emitter.CompareTo(1, () => { 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(InsensitiveStringHelpers) : typeof(string); emitter.BeginCall( type.GetMethod( methodName, BindingFlags.Public | BindingFlags.Static, null, new[] { 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[] { typeof(string) }, null)); m_Value.Load(emitter); emitter.FinishCall(); emitter.MarkLabel(moveOn); } if (m_Not != inverse) { emitter.LogicalNot(); } }