public override void Visit(IMetadataConstant literal) { ITypeReference type = literal.Type; Visit(type); base.Visit(literal); }
public LocalConstantDefinition(string name, Location location, IMetadataConstant compileTimeValue, bool isDynamic = false, ImmutableArray<TypedConstant> dynamicTransformFlags = default(ImmutableArray<TypedConstant>)) { Debug.Assert(!string.IsNullOrEmpty(name)); Debug.Assert(compileTimeValue != null); this.name = name; this.location = location; this.compileTimeValue = compileTimeValue; this.isDynamic = isDynamic; this.dynamicTransformFlags = dynamicTransformFlags; }
/// <summary> /// Allocates a mutable object that represents a local variable or constant. /// </summary> public GeneratorLocal() { this.compileTimeValue = Dummy.Constant; this.customModifiers = new List<ICustomModifier>(); this.isModified = false; this.isPinned = false; this.isReference = false; this.locations = new List<ILocation>(); this.name = Dummy.Name; this.methodDefinition = Dummy.Method; this.type = Dummy.TypeReference; }
public static bool IsIntegralMinusOne(IMetadataConstant constExpression) { IConvertible/*?*/ ic = constExpression.Value as IConvertible; if (ic == null) return false; switch (ic.GetTypeCode()) { case System.TypeCode.SByte: return ic.ToSByte(null) == -1; case System.TypeCode.Int16: return ic.ToInt16(null) == -1; case System.TypeCode.Int32: return ic.ToInt32(null) == -1; case System.TypeCode.Int64: return ic.ToInt64(null) == -1; case System.TypeCode.Byte: return ic.ToByte(null) == byte.MaxValue; case System.TypeCode.UInt16: return ic.ToUInt16(null) == ushort.MaxValue; case System.TypeCode.UInt32: return ic.ToUInt32(null) == uint.MaxValue; case System.TypeCode.UInt64: return ic.ToUInt64(null) == ulong.MaxValue; } return false; }
public static bool IsIntegralOne(IMetadataConstant constExpression) { IConvertible/*?*/ ic = constExpression.Value as IConvertible; if (ic == null) return false; switch (ic.GetTypeCode()) { case System.TypeCode.SByte: return ic.ToSByte(null) == 1; case System.TypeCode.Int16: return ic.ToInt16(null) == 1; case System.TypeCode.Int32: return ic.ToInt32(null) == 1; case System.TypeCode.Int64: return ic.ToInt64(null) == 1; case System.TypeCode.Byte: return ic.ToByte(null) == 1; case System.TypeCode.UInt16: return ic.ToUInt16(null) == 1; case System.TypeCode.UInt32: return ic.ToUInt32(null) == 1; case System.TypeCode.UInt64: return ic.ToUInt64(null) == 1; case System.TypeCode.Boolean: return ic.ToBoolean(null); } return false; }
/// <summary> /// Returns true if the given constant expression contains a finite numeric value. In other words, infinities and NaN are excluded. /// </summary> /// <param name="constExpression"></param> /// <returns></returns> public static bool IsFiniteNumeric(IMetadataConstant constExpression) { IConvertible/*?*/ ic = constExpression.Value as IConvertible; if (ic == null) return false; switch (ic.GetTypeCode()) { case System.TypeCode.SByte: case System.TypeCode.Int16: case System.TypeCode.Int32: case System.TypeCode.Int64: case System.TypeCode.Byte: case System.TypeCode.UInt16: case System.TypeCode.UInt32: case System.TypeCode.UInt64: return true; case System.TypeCode.Double: var d = ic.ToDouble(null); return !(Double.IsNaN(d) || Double.IsInfinity(d)); case System.TypeCode.Single: var s = ic.ToSingle(null); return !(Single.IsNaN(s) || Single.IsInfinity(s)); } return false; }
/// <summary> /// Specifies the symbol table elements on which it is valid to apply this attribute. /// This information is obtained from an attribute on the attribute type definition. /// </summary> public static AttributeTargets ValidOn(ITypeDefinition attributeType) { foreach (ICustomAttribute ca in attributeType.Attributes) { if (!TypeHelper.TypesAreEquivalent(ca.Type, attributeType.PlatformType.SystemAttributeUsageAttribute)) { continue; } foreach (IMetadataExpression expr in ca.Arguments) { IMetadataConstant /*?*/ ctorParam = expr as IMetadataConstant; if (ctorParam == null || ctorParam.Value == null || !(ctorParam.Value is int)) { break; } //^ assume false; //Unboxing cast might fail int val = (int)ctorParam.Value; return((AttributeTargets)val); } } return(AttributeTargets.All); }
/// <summary> /// Specifies whether this attribute applies to derived types and/or overridden methods. /// This information is obtained from an attribute on the attribute type definition. /// </summary> public static bool Inherited(ITypeDefinition attributeType, INameTable nameTable) { foreach (ICustomAttribute ca in attributeType.Attributes) { if (!TypeHelper.TypesAreEquivalent(ca.Type, attributeType.PlatformType.SystemAttributeUsageAttribute)) { continue; } foreach (IMetadataNamedArgument namedArgument in ca.NamedArguments) { if (namedArgument.ArgumentName.UniqueKey == nameTable.AllowMultiple.UniqueKey) { IMetadataConstant /*?*/ compileTimeConst = namedArgument.ArgumentValue as IMetadataConstant; if (compileTimeConst == null || compileTimeConst.Value == null || !(compileTimeConst.Value is bool)) { continue; } //^ assume false; //Unboxing cast might fail return((bool)compileTimeConst.Value); } } } return(false); }
private static ulong ConvertToUlong(IMetadataConstant c) { IConvertible /*?*/ ic = c.Value as IConvertible; if (ic == null) { return(0); //TODO: error } switch (ic.GetTypeCode()) { case TypeCode.SByte: case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: return((ulong)ic.ToInt64(null)); //TODO: error if < 0 case TypeCode.Byte: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.UInt64: return(ic.ToUInt64(null)); } return(0); //TODO: error }
public void Visit(IMetadataConstant constant) { throw new NotImplementedException(); }
private void ReplaceLocalArrayInitializerPattern(List <IStatement> statements, int i) { if (i > statements.Count - 4) { return; } PushStatement /*?*/ push = statements[i] as PushStatement; if (push == null) { return; } var pushDup = statements[i + 1] as PushStatement; if (pushDup == null || !(pushDup.ValueToPush is Dup)) { return; } CreateArray /*?*/ createArray = push.ValueToPush as CreateArray; if (createArray == null) { return; } ExpressionStatement /*?*/ expressionStatement = statements[i + 2] as ExpressionStatement; if (expressionStatement == null) { return; } MethodCall /*?*/ methodCall = expressionStatement.Expression as MethodCall; if (methodCall == null || !methodCall.IsStaticCall || methodCall.IsJumpCall || methodCall.Arguments.Count != 2) { return; } var pop = methodCall.Arguments[0] as Pop; if (pop == null) { return; } TokenOf /*?*/ tokenOf = methodCall.Arguments[1] as TokenOf; if (tokenOf == null) { return; } IFieldDefinition /*?*/ initialValueField = tokenOf.Definition as IFieldDefinition; if (initialValueField == null || !initialValueField.IsMapped) { return; } if (methodCall.MethodToCall.Name.UniqueKey != this.InitializeArray.UniqueKey) { return; } List <ulong> sizes = new List <ulong>(); foreach (IExpression expr in createArray.Sizes) { IMetadataConstant mdc = expr as IMetadataConstant; if (mdc == null) { return; } sizes.Add(ConvertToUlong(mdc)); } AddArrayInitializers(createArray, initialValueField, sizes.ToArray()); expressionStatement = statements[i + 3] as ExpressionStatement; if (expressionStatement != null) { Assignment /*?*/ assignment = expressionStatement.Expression as Assignment; if (assignment != null) { var pop2 = assignment.Source as Pop; if (pop2 != null) { assignment.Source = createArray; statements[i] = expressionStatement; statements.RemoveRange(i + 1, 3); return; } } } push.ValueToPush = createArray; statements.RemoveRange(i + 1, 2); }
public override void TraverseChildren(IMetadataConstant constant) { MethodEnter(constant); base.TraverseChildren(constant); MethodExit(); }
private void WriteMetadataConstant(IMetadataConstant constant, ITypeReference constantType = null) { object value = constant.Value; ITypeReference type = (constantType == null ? constant.Type : constantType); if (value == null) { if (type.IsValueType) { // Write default(T) for value types WriteDefaultOf(type); } else { WriteKeyword("null", noSpace: true); } } else if (type.ResolvedType.IsEnum) { //TODO: Do a better job translating the Enum value. WriteSymbol("("); WriteTypeName(type, noSpace: true); WriteSymbol(")"); WriteSymbol("("); // Wrap value in parens to avoid issues with negative values Write(value.ToString()); WriteSymbol(")"); } else if (value is string) { Write(QuoteString((string)value)); } else if (value is char) { Write(String.Format("'{0}'", EscapeChar((char)value, false))); } else if (value is double) { double val = (double)value; if (double.IsNegativeInfinity(val)) Write("-1.0 / 0.0"); else if (double.IsPositiveInfinity(val)) Write("1.0 / 0.0"); else if (double.IsNaN(val)) Write("0.0 / 0.0"); else Write(((double)value).ToString("R", CultureInfo.InvariantCulture)); } else if (value is float) { float val = (float)value; if (float.IsNegativeInfinity(val)) Write("-1.0f / 0.0f"); else if (float.IsPositiveInfinity(val)) Write("1.0f / 0.0f"); else if (float.IsNaN(val)) Write("0.0f / 0.0f"); else Write(((float)value).ToString("R", CultureInfo.InvariantCulture) + "f"); } else if (value is bool) { if ((bool)value) WriteKeyword("true", noSpace: true); else WriteKeyword("false", noSpace: true); } else if (value is int) { // int is the default and most used constant value so lets // special case int to avoid a bunch of useless casts. Write(value.ToString()); } else { // Explicitly cast the value so that we avoid any signed/unsigned resolution issues WriteSymbol("("); WriteTypeName(type, noSpace: true); WriteSymbol(")"); Write(value.ToString()); } // Might need to add support for other types... }
/// <summary> /// Traverses the children of the metadata constant. /// </summary> public virtual void TraverseChildren(IMetadataConstant constant) { Contract.Requires(constant != null); this.TraverseChildren((IMetadataExpression)constant); }
/// <summary> /// Performs some computation with the given metadata constant. /// </summary> public virtual void Visit(IMetadataConstant constant) { this.Visit((IMetadataExpression)constant); }
private void WriteMetadataConstant(IMetadataConstant constant, ITypeReference constantType = null) { object value = constant.Value; ITypeReference type = (constantType == null ? constant.Type : constantType); if (value == null) { if (type.IsValueType) { // Write default(T) for value types WriteDefaultOf(type); } else { WriteKeyword("null", noSpace: true); } } else if (type.ResolvedType.IsEnum) { //TODO: Do a better job translating the Enum value. WriteSymbol("("); WriteTypeName(type, noSpace: true); WriteSymbol(")"); WriteSymbol("("); // Wrap value in parens to avoid issues with negative values Write(value.ToString()); WriteSymbol(")"); } else if (value is string) { Write(QuoteString((string)value)); } else if (value is char) { Write(String.Format("'{0}'", EscapeChar((char)value, false))); } else if (value is double) { double val = (double)value; if (double.IsNegativeInfinity(val)) { Write("-1.0 / 0.0"); } else if (double.IsPositiveInfinity(val)) { Write("1.0 / 0.0"); } else if (double.IsNaN(val)) { Write("0.0 / 0.0"); } else { Write(((double)value).ToString("R", CultureInfo.InvariantCulture)); } } else if (value is float) { float val = (float)value; if (float.IsNegativeInfinity(val)) { Write("-1.0f / 0.0f"); } else if (float.IsPositiveInfinity(val)) { Write("1.0f / 0.0f"); } else if (float.IsNaN(val)) { Write("0.0f / 0.0f"); } else { Write(((float)value).ToString("R", CultureInfo.InvariantCulture) + "f"); } } else if (value is bool) { if ((bool)value) { WriteKeyword("true", noSpace: true); } else { WriteKeyword("false", noSpace: true); } } else if (value is int) { // int is the default and most used constant value so lets // special case int to avoid a bunch of useless casts. Write(value.ToString()); } else { // Explicitly cast the value so that we avoid any signed/unsigned resolution issues WriteSymbol("("); WriteTypeName(type, noSpace: true); WriteSymbol(")"); Write(value.ToString()); } // Might need to add support for other types... }
private static ulong ConvertToUlong(IMetadataConstant c) { Contract.Requires(c != null); IConvertible/*?*/ ic = c.Value as IConvertible; if (ic == null) return 0; //TODO: error switch (ic.GetTypeCode()) { case TypeCode.SByte: case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: return (ulong)ic.ToInt64(null); //TODO: error if < 0 case TypeCode.Byte: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.UInt64: return ic.ToUInt64(null); } return 0; //TODO: error }
public override void TraverseChildren(IMetadataConstant constant) { //The type should already be filled in }
/// <summary> /// Rewrites the given metadata constant. /// </summary> public virtual IMetadataConstant Rewrite(IMetadataConstant constant) { return constant; }
public override void Visit(IMetadataConstant constant) { this.value = constant.Value; }
public override void Visit(IMetadataConstant constant) { allElements.Add(new InvokInfo(Traverser, "IMetadataConstant", constant)); }
private void WriteEnumValue(IMetadataConstant constant, ITypeReference constantType = null) { ITypeReference enumType = (constantType == null ? constant.Type : constantType); var resolvedType = enumType.ResolvedType; if (resolvedType != null) { // First look for exact match foreach (var enumField in resolvedType.Fields) { var enumFieldValue = enumField?.Constant?.Value; if (enumFieldValue != null && enumFieldValue.Equals(constant.Value)) { WriteTypeName(enumType, noSpace: true); WriteSymbol("."); WriteIdentifier(enumField.Name); return; } } // if flags and we didn't find an exact match, find a combination of flags that match if (resolvedType.Attributes.Any(a => a.Type.GetTypeName() == "System.FlagsAttribute")) { ulong value = ToULongUnchecked(constant.Value); ulong satisfiedValue = 0; // keep track of candidate flags List <IFieldDefinition> candidateFlagFields = new List <IFieldDefinition>(); // ensure stable sort IEnumerable <IFieldDefinition> sortedFields = resolvedType.Fields.OrderBy(f => f.Name.Value, StringComparer.OrdinalIgnoreCase); foreach (var candidateFlagField in sortedFields) { object candidateFlagObj = candidateFlagField?.Constant?.Value; if (candidateFlagObj == null) { continue; } ulong candidateFlag = ToULongUnchecked(candidateFlagObj); if ((value & candidateFlag) == candidateFlag) { // reduce: find out if the current flag is better or worse // than any of those we've already seen bool shouldAdd = true; for (int i = 0; i < candidateFlagFields.Count; i++) { ulong otherFlagValue = ToULongUnchecked(candidateFlagFields[i].Constant.Value); ulong intersectingFlagValue = candidateFlag & otherFlagValue; if (intersectingFlagValue == otherFlagValue) { // other flag is completely redundant // remove it, but continue looking as other // flags may also be redundant candidateFlagFields.RemoveAt(i--); } else if (intersectingFlagValue == candidateFlag) { // this flag is redundant, don't add it and stop // comparing shouldAdd = false; break; } } if (shouldAdd) { candidateFlagFields.Add(candidateFlagField); satisfiedValue |= candidateFlag; if (value == satisfiedValue) { break; } } } } // we found a valid combination of flags if (value == satisfiedValue && candidateFlagFields.Count > 0) { for (int i = 0; i < candidateFlagFields.Count; i++) { if (i != 0) { WriteSymbol(" | "); } WriteTypeName(enumType, noSpace: true); WriteSymbol("."); WriteIdentifier(candidateFlagFields[i].Name); } return; } } } if (constant.Value == null || ToULongUnchecked(constant.Value) == 0) // default(T) on an enum is 0 { if (enumType.IsValueType) { // Write default(T) for value types WriteDefaultOf(enumType); } else { WriteKeyword("null", noSpace: true); } } else { // couldn't find a symbol for enum, just cast it WriteSymbol("("); WriteTypeName(enumType, noSpace: true); WriteSymbol(")"); WriteSymbol("("); // Wrap value in parens to avoid issues with negative values Write(constant.Value.ToString()); WriteSymbol(")"); } }
public virtual void Visit(IMetadataConstant constant) { }
/// <summary> /// Returns true if the given compile time constant does not match the type of the definition that it provides the initial value for. /// </summary> private static bool CompileTimeConstantTypeDoesNotMatchDefinitionType(IMetadataConstant compileTimeConstant, ITypeReference definitionType) { Contract.Requires(compileTimeConstant != null); Contract.Requires(definitionType != null); if (TypeHelper.TypesAreEquivalent(compileTimeConstant.Type, definitionType)) return false; if (definitionType.IsEnum || definitionType.ResolvedType.IsEnum) return CompileTimeConstantTypeDoesNotMatchDefinitionType(compileTimeConstant, definitionType.ResolvedType.UnderlyingType); if (compileTimeConstant.Value == null && TypeHelper.TypesAreEquivalent(compileTimeConstant.Type, compileTimeConstant.Type.PlatformType.SystemObject)) { if (definitionType.IsValueType || definitionType.ResolvedType.IsValueType) { var genericInstance = definitionType as IGenericTypeInstanceReference; if (genericInstance == null) return true; return !TypeHelper.TypesAreEquivalent(genericInstance.GenericType, definitionType.PlatformType.SystemNullable); } return false; } return true; }
public virtual void onMetadataElement(IMetadataConstant constant) { }
/// <summary> /// Traverses the metadata constant. /// </summary> public void Traverse(IMetadataConstant constant) { Contract.Requires(constant != null); if (this.preorderVisitor != null) this.preorderVisitor.Visit(constant); if (this.stopTraversal) return; this.TraverseChildren(constant); if (this.stopTraversal) return; if (this.postorderVisitor != null) this.postorderVisitor.Visit(constant); }
public override void Visit(IMetadataConstant constant) { if(Process(constant)){visitor.Visit(constant);} base.Visit(constant); }
public void Visit(IMetadataConstant constant) { this.traverser.Traverse(constant); }
//^ ensures this.path.Count == old(this.path.Count); /// <summary> /// Performs some computation with the given metadata constant. /// </summary> /// <param name="constant"></param> public virtual void Visit(IMetadataConstant constant) { }
/// <summary> /// Performs some computation with the given metadata constant. /// </summary> /// <param name="constant"></param> public virtual void Visit(IMetadataConstant constant) //^ ensures this.path.Count == old(this.path.Count); { }
/// <summary> /// Performs some computation with the given metadata constant. /// </summary> public void Visit(IMetadataConstant constant) { this.Visit((IMetadataExpression)constant); ITypeReference ctype = constant.Type; var rctype = constant.Type.ResolvedType; if (rctype != Dummy.Type) { if (rctype.IsEnum) ctype = rctype.UnderlyingType; else ctype = rctype; } bool validValue = false; switch (ctype.TypeCode) { case PrimitiveTypeCode.Boolean: validValue = constant.Value is bool; break; case PrimitiveTypeCode.Char: validValue = constant.Value is char; break; case PrimitiveTypeCode.Int8: validValue = constant.Value is sbyte; break; case PrimitiveTypeCode.UInt8: validValue = constant.Value is byte; break; case PrimitiveTypeCode.Int16: validValue = constant.Value is short; break; case PrimitiveTypeCode.UInt16: validValue = constant.Value is ushort; break; case PrimitiveTypeCode.Int32: validValue = constant.Value is int; break; case PrimitiveTypeCode.UInt32: validValue = constant.Value is uint; break; case PrimitiveTypeCode.Int64: validValue = constant.Value is long; break; case PrimitiveTypeCode.UInt64: validValue = constant.Value is ulong; break; case PrimitiveTypeCode.Float32: validValue = constant.Value is float; break; case PrimitiveTypeCode.Float64: validValue = constant.Value is double; break; case PrimitiveTypeCode.String: validValue = constant.Value is string || constant.Value == null; break; case PrimitiveTypeCode.NotPrimitive: validValue = constant.Value == null || rctype == Dummy.Type; break; //TODO: check that value can be enum val } if (!validValue) this.ReportError(MetadataError.InvalidMetadataConstant, constant); }
/// <summary> /// Uses Arithmetic and Boolean laws to simplify expressions. /// </summary> /// <typeparam name="Instruction"></typeparam> /// <param name="instruction"></param> /// <param name="mappings"></param> /// <param name="canonicalizer"></param> /// <returns></returns> internal static Instruction SimplifyBinary <Instruction>(Instruction instruction, ValueMappings <Instruction> mappings, ExpressionCanonicalizer <Instruction> canonicalizer) where Instruction : Microsoft.Cci.Analysis.Instruction, new() { Contract.Requires(instruction != null); Contract.Requires(mappings != null); Contract.Requires(canonicalizer != null); Contract.Ensures(Contract.Result <Instruction>() != null); var operation = instruction.Operation; Contract.Assume(instruction.Operand1 is Instruction); var operand1 = (Instruction)instruction.Operand1; Contract.Assume(instruction.Operand2 is Instruction); var operand2 = (Instruction)instruction.Operand2; IMetadataConstant constantResult = null; var compileTimeConstant1 = mappings.GetCompileTimeConstantValueFor(operand1); var compileTimeConstant2 = mappings.GetCompileTimeConstantValueFor(operand2); if (compileTimeConstant1 != null) { if (compileTimeConstant2 != null) { constantResult = Evaluator.Evaluate(instruction.Operation, compileTimeConstant1, compileTimeConstant2); } else { constantResult = Evaluator.Evaluate(instruction.Operation, compileTimeConstant1, operand2, mappings); } } else if (compileTimeConstant2 != null) { constantResult = Evaluator.Evaluate(instruction.Operation, operand1, compileTimeConstant2, mappings); } else { constantResult = Evaluator.Evaluate(instruction.Operation, operand1, operand2, mappings); } if (constantResult != null) { return(canonicalizer.GetAsCanonicalizedLoadConstant(constantResult, instruction)); } //If we get here, the instruction does not simplify to a constant, but it could still simplify to a simpler expression. bool operand1IsZero = compileTimeConstant1 != null && MetadataExpressionHelper.IsIntegralZero(compileTimeConstant1); bool operand1IsOne = compileTimeConstant1 != null && (operand1IsZero ? false : MetadataExpressionHelper.IsIntegralOne(compileTimeConstant1)); bool operand1IsMinusOne = compileTimeConstant1 != null && ((operand1IsZero || operand1IsOne) ? false : MetadataExpressionHelper.IsIntegralMinusOne(compileTimeConstant1)); bool operand2IsZero = compileTimeConstant2 != null && MetadataExpressionHelper.IsIntegralZero(compileTimeConstant2); bool operand2IsOne = compileTimeConstant2 != null && (operand1IsZero ? false : MetadataExpressionHelper.IsIntegralOne(compileTimeConstant2)); bool operand2IsMinusOne = compileTimeConstant2 != null && ((operand2IsZero || operand2IsOne) ? false : MetadataExpressionHelper.IsIntegralMinusOne(compileTimeConstant2)); operand1 = Simplify(operand1, mappings, canonicalizer); operand2 = Simplify(operand2, mappings, canonicalizer); switch (operation.OperationCode) { case OperationCode.Add: case OperationCode.Add_Ovf: case OperationCode.Add_Ovf_Un: if (operand1IsZero) { return(operand2); } if (operand2IsZero) { return(operand1); } //TODO: factor out common mults/divs/etc (subject to overflow checks). break; case OperationCode.And: if (operand1IsZero) { return(operand1); } if (operand2IsZero) { return(operand2); } if (operand1IsMinusOne) { return(operand2); } if (operand2IsMinusOne) { return(operand1); } if (operand1.Operation.OperationCode == OperationCode.Not && operand2.Operation.OperationCode == OperationCode.Not) { var opnd11 = operand1.Operand1 as Instruction; var opnd21 = operand2.Operand1 as Instruction; Contract.Assume(opnd11 != null && opnd21 != null); var or = new Operation() { OperationCode = OperationCode.Or, Location = operation.Location, Offset = operation.Offset }; var orInst = new Instruction() { Operation = or, Operand1 = opnd11, Operand2 = opnd21, Type = instruction.Type }; var not = new Operation { OperationCode = OperationCode.Not, Location = operation.Location, Offset = operation.Offset }; return(new Instruction() { Operation = not, Operand1 = orInst, Type = instruction.Type }); } break; case OperationCode.Ceq: //If one of the operands is const 0 and the other is a boolean expression, invert the boolean expression if (operand2IsZero && operand1.Type.TypeCode == PrimitiveTypeCode.Boolean) { var not = new Operation() { Location = instruction.Operation.Location, Offset = instruction.Operation.Offset, OperationCode = OperationCode.Not }; instruction = new Instruction() { Operation = not, Operand1 = operand1, Type = instruction.Type }; return(SimplifyUnary(instruction, mappings, canonicalizer)); } else if (operand1IsZero && operand2.Type.TypeCode == PrimitiveTypeCode.Boolean) { var not = new Operation() { Location = instruction.Operation.Location, Offset = instruction.Operation.Offset, OperationCode = OperationCode.Not }; instruction = new Instruction() { Operation = not, Operand1 = operand2, Type = instruction.Type }; return(SimplifyUnary(instruction, mappings, canonicalizer)); } else { operation = new Operation() { Location = instruction.Operation.Location, Offset = instruction.Operation.Offset, OperationCode = OperationCode.Beq }; } break; case OperationCode.Cgt: operation = new Operation() { Location = instruction.Operation.Location, Offset = instruction.Operation.Offset, OperationCode = OperationCode.Bgt }; break; case OperationCode.Cgt_Un: operation = new Operation() { Location = instruction.Operation.Location, Offset = instruction.Operation.Offset, OperationCode = OperationCode.Bgt_Un }; break; case OperationCode.Clt: operation = new Operation() { Location = instruction.Operation.Location, Offset = instruction.Operation.Offset, OperationCode = OperationCode.Blt }; break; case OperationCode.Clt_Un: operation = new Operation() { Location = instruction.Operation.Location, Offset = instruction.Operation.Offset, OperationCode = OperationCode.Blt_Un }; break; case OperationCode.Div: case OperationCode.Div_Un: if (operand2IsOne) { return(operand1); } break; case OperationCode.Mul: case OperationCode.Mul_Ovf: case OperationCode.Mul_Ovf_Un: if (operand1IsOne) { return(operand2); } if (operand2IsOne) { return(operand1); } break; case OperationCode.Or: if (operand1IsZero) { return(operand2); } if (operand2IsZero) { return(operand1); } if (operand1.Operation.OperationCode == OperationCode.Not && operand2.Operation.OperationCode == OperationCode.Not) { var opnd11 = operand1.Operand1 as Instruction; var opnd21 = operand2.Operand1 as Instruction; Contract.Assume(opnd11 != null && opnd21 != null); var and = new Operation() { OperationCode = OperationCode.And, Location = operation.Location, Offset = operation.Offset }; var andInst = new Instruction() { Operation = and, Operand1 = opnd11, Operand2 = opnd21, Type = instruction.Type }; var not = new Operation { OperationCode = OperationCode.Not, Location = operation.Location, Offset = operation.Offset }; return(new Instruction() { Operation = not, Operand1 = andInst, Type = instruction.Type }); } if (operand1.Operand1 == operand2.Operand1 && operand1.Operand2 == operand2.Operand2 && operand1.Operation.OperationCode != operand2.Operation.OperationCode && operand2.Operand1 != null && operand1.Operation.OperationCode == GetInverse(operand2.Operation.OperationCode, operand2.Operand1.Type.TypeCode == PrimitiveTypeCode.Float32 || operand2.Operand1.Type.TypeCode == PrimitiveTypeCode.Float64)) { return(canonicalizer.GetAsCanonicalizedLoadConstant(new MetadataConstant() { Value = true, Type = instruction.Type }, instruction)); } break; case OperationCode.Rem: case OperationCode.Rem_Un: break; case OperationCode.Shl: case OperationCode.Shr: case OperationCode.Shr_Un: if (operand2IsZero) { return(operand1); } break; case OperationCode.Sub: case OperationCode.Sub_Ovf: case OperationCode.Sub_Ovf_Un: if (operand2IsZero) { return(operand1); } break; case OperationCode.Xor: break; case OperationCode.Beq: case OperationCode.Beq_S: if (operand1IsZero && operand2.Type.TypeCode == PrimitiveTypeCode.Boolean) { var operand2inv = TryToGetSimplerLogicalInverse(operand2); if (operand2inv != null) { return(operand2inv); } } else if (operand2IsZero && operand1.Type.TypeCode == PrimitiveTypeCode.Boolean) { var operand1inv = TryToGetSimplerLogicalInverse(operand1); if (operand1inv != null) { return(operand1inv); } } goto case OperationCode.Bge_S; case OperationCode.Bne_Un: case OperationCode.Bne_Un_S: if (operand1IsZero && operand2.Type.TypeCode == PrimitiveTypeCode.Boolean) { return(operand2); } if (operand2IsZero && operand1.Type.TypeCode == PrimitiveTypeCode.Boolean) { return(operand1); } goto case OperationCode.Bge_S; case OperationCode.Bge_S: case OperationCode.Bge_Un_S: case OperationCode.Bgt_S: case OperationCode.Bgt_Un_S: case OperationCode.Ble_S: case OperationCode.Ble_Un_S: case OperationCode.Blt_S: case OperationCode.Blt_Un_S: operation = new Operation() { Location = operation.Location, Offset = operation.Offset, OperationCode = LongVersionOf(operation.OperationCode), Value = operation.Value }; break; } if (operation != instruction.Operation || operand1 != instruction.Operand1 || operand2 != instruction.Operand2) { return new Instruction() { Operation = operation, Operand1 = operand1, Operand2 = operand2, Type = instruction.Type } } ; return(instruction); }
public override void TraverseChildren(IMetadataConstant constant) { var val = constant.Value; if (val == null) this.PrintToken(CSharpToken.Null); else if (constant.Type.ResolvedType.IsEnum) PrintEnumValue(constant.Type.ResolvedType, val); else if (val is string) PrintString((string)val); else if (val is bool) PrintToken((bool)val ? CSharpToken.True : CSharpToken.False); else if (val is char) this.sourceEmitterOutput.Write(String.Format("'{0}'", EscapeChar((char)val, false))); else if (val is float) PrintFloat((float)val); else if (val is double) PrintDouble((double)val); else if (val is int) PrintInt((int)val); else if (val is uint) PrintUint((uint)val); else if (val is long) PrintLong((long)val); else if (val is ulong) PrintUlong((ulong)val); else this.sourceEmitterOutput.Write(constant.Value.ToString()); }
/// <summary> /// Traverses the children of the metadata constant. /// </summary> public virtual void TraverseChildren(IMetadataConstant constant) { this.TraverseChildren((IMetadataExpression)constant); }