public override IExpression VisitCastExpression(CastExpressionSyntax node)
        {
            var o      = this.semanticModel.GetTypeInfo(node);
            var t      = this.mapper.Map(o.Type);
            var result = new Microsoft.Cci.MutableCodeModel.Conversion()
            {
                ValueToConvert      = this.Visit(node.Expression),
                Type                = t,
                TypeAfterConversion = t,
            };

            return(result);
        }
Ejemplo n.º 2
0
 private Expression ParseConversion(IOperation currentOperation)
 {
     Conversion result = new Conversion();
       Expression valueToConvert = this.PopOperandStack();
       result.ValueToConvert = valueToConvert;
       switch (currentOperation.OperationCode) {
     case OperationCode.Conv_R_Un:
       result.ValueToConvert = this.ConvertToUnsigned(valueToConvert); break;
     case OperationCode.Conv_Ovf_I_Un:
     case OperationCode.Conv_Ovf_I1_Un:
     case OperationCode.Conv_Ovf_I2_Un:
     case OperationCode.Conv_Ovf_I4_Un:
     case OperationCode.Conv_Ovf_I8_Un:
     case OperationCode.Conv_Ovf_U_Un:
     case OperationCode.Conv_Ovf_U1_Un:
     case OperationCode.Conv_Ovf_U2_Un:
     case OperationCode.Conv_Ovf_U4_Un:
     case OperationCode.Conv_Ovf_U8_Un:
       result.ValueToConvert = this.ConvertToUnsigned(valueToConvert);
       result.CheckNumericRange = true; break;
     case OperationCode.Conv_Ovf_I:
     case OperationCode.Conv_Ovf_I1:
     case OperationCode.Conv_Ovf_I2:
     case OperationCode.Conv_Ovf_I4:
     case OperationCode.Conv_Ovf_I8:
     case OperationCode.Conv_Ovf_U:
     case OperationCode.Conv_Ovf_U1:
     case OperationCode.Conv_Ovf_U2:
     case OperationCode.Conv_Ovf_U4:
     case OperationCode.Conv_Ovf_U8:
       result.CheckNumericRange = true; break;
       }
       switch (currentOperation.OperationCode) {
     case OperationCode.Box:
       ((Expression)result.ValueToConvert).Type = (ITypeReference)currentOperation.Value;
       var cc = result.ValueToConvert as CompileTimeConstant;
       if (cc != null) cc.Value = this.ConvertBoxedValue(cc.Value, cc.Type);
       result.TypeAfterConversion = this.platformType.SystemObject;
       break;
     case OperationCode.Castclass:
       result.TypeAfterConversion = (ITypeReference)currentOperation.Value;
       if (result.TypeAfterConversion.IsValueType)
     //This is not legal IL according to ECMA, but the CLR accepts it if the value to convert is a boxed value type.
     //Moreover, the CLR seems to leave the boxed object on the stack if the cast succeeds.
     result = new Conversion() { ValueToConvert = result, TypeAfterConversion = this.platformType.SystemObject };
       break;
     case OperationCode.Conv_I:
     case OperationCode.Conv_Ovf_I:
     case OperationCode.Conv_Ovf_I_Un:
       result.TypeAfterConversion = this.platformType.SystemIntPtr; break;
     case OperationCode.Conv_I1:
     case OperationCode.Conv_Ovf_I1:
     case OperationCode.Conv_Ovf_I1_Un:
       result.TypeAfterConversion = this.platformType.SystemInt8; break;
     case OperationCode.Conv_I2:
     case OperationCode.Conv_Ovf_I2:
     case OperationCode.Conv_Ovf_I2_Un:
       result.TypeAfterConversion = this.platformType.SystemInt16; break;
     case OperationCode.Conv_I4:
     case OperationCode.Conv_Ovf_I4:
     case OperationCode.Conv_Ovf_I4_Un:
       result.TypeAfterConversion = this.platformType.SystemInt32; break;
     case OperationCode.Conv_I8:
     case OperationCode.Conv_Ovf_I8:
     case OperationCode.Conv_Ovf_I8_Un:
       result.TypeAfterConversion = this.platformType.SystemInt64; break;
     case OperationCode.Conv_U:
     case OperationCode.Conv_Ovf_U:
     case OperationCode.Conv_Ovf_U_Un:
       result.TypeAfterConversion = this.platformType.SystemUIntPtr; break;
     case OperationCode.Conv_U1:
     case OperationCode.Conv_Ovf_U1:
     case OperationCode.Conv_Ovf_U1_Un:
       result.TypeAfterConversion = this.platformType.SystemUInt8; break;
     case OperationCode.Conv_U2:
     case OperationCode.Conv_Ovf_U2:
     case OperationCode.Conv_Ovf_U2_Un:
       result.TypeAfterConversion = this.platformType.SystemUInt16; break;
     case OperationCode.Conv_U4:
     case OperationCode.Conv_Ovf_U4:
     case OperationCode.Conv_Ovf_U4_Un:
       result.TypeAfterConversion = this.platformType.SystemUInt32; break;
     case OperationCode.Conv_U8:
     case OperationCode.Conv_Ovf_U8:
     case OperationCode.Conv_Ovf_U8_Un:
       result.TypeAfterConversion = this.platformType.SystemUInt64; break;
     case OperationCode.Conv_R_Un:
       result.TypeAfterConversion = this.platformType.SystemFloat64; break; //TODO: need a type for Float80+
     case OperationCode.Conv_R4:
       result.TypeAfterConversion = this.platformType.SystemFloat32; break;
     case OperationCode.Conv_R8:
       result.TypeAfterConversion = this.platformType.SystemFloat64; break;
     case OperationCode.Unbox:
       result.TypeAfterConversion = Immutable.ManagedPointerType.GetManagedPointerType((ITypeReference)currentOperation.Value, this.host.InternFactory); break;
     case OperationCode.Unbox_Any:
       result.TypeAfterConversion = (ITypeReference)currentOperation.Value; break;
       }
       return result;
 }
Ejemplo n.º 3
0
    private ArrayIndexer ParseArrayIndexer(IOperation currentOperation, ITypeReference elementType, bool treatArrayAsSingleDimensioned = false) {
      Contract.Requires(currentOperation != null);
      Contract.Requires(elementType != null);

      uint rank = 1;
      IArrayTypeReference/*?*/ arrayType = null;
      if (!treatArrayAsSingleDimensioned) //then currentOperation.Value contains the type of the array, not the type of the indexed element.
        arrayType = currentOperation.Value as IArrayTypeReference;
      if (arrayType != null) rank = arrayType.Rank;
      ArrayIndexer result = new ArrayIndexer();
      for (uint i = 0; i < rank; i++)
        result.Indices.Add(this.PopOperandStack());
      result.Indices.Reverse();
      var indexedObject = this.PopOperandStack();
      result.Type = elementType; //obtained from the instruction, but could be a lossy abstraction, or null
      if (arrayType == null)
        arrayType = indexedObject.Type as IArrayTypeReference;
      if (arrayType != null) //rather use its element type than the caller's element type (which is derived from the operation code).
        result.Type = arrayType.ElementType;
      else
        arrayType = Immutable.Vector.GetVector(elementType, this.host.InternFactory);
      if (!TypeHelper.TypesAreEquivalent(indexedObject.Type, arrayType))
        indexedObject = new Conversion() { ValueToConvert = indexedObject, TypeAfterConversion = arrayType };
      Contract.Assume(indexedObject.Type is IArrayTypeReference);
      result.IndexedObject = indexedObject;
      Contract.Assume(!(result.Type is Dummy));
      return result;
    }
Ejemplo n.º 4
0
 /// <summary>
 /// Visits the specified conversion.
 /// </summary>
 /// <param name="conversion">The conversion.</param>
 /// <returns></returns>
 protected virtual IExpression DeepCopy(Conversion conversion)
 {
     conversion.ValueToConvert = Substitute(conversion.ValueToConvert);
       conversion.Type = this.Substitute(conversion.Type);
       return conversion;
 }
Ejemplo n.º 5
0
 /// <summary>
 /// Visits the specified conversion.
 /// </summary>
 /// <param name="conversion">The conversion.</param>
 public override void Visit(IConversion conversion)
 {
     Conversion mutableConversion = new Conversion(conversion);
     this.resultExpression = this.myCodeCopier.DeepCopy(mutableConversion);
 }
Ejemplo n.º 6
0
 public override IExpression Visit(IExpression expression)
 {
     var convertToUnsigned = expression as ConvertToUnsigned;
       if (convertToUnsigned != null) expression = new Conversion(convertToUnsigned);
       return base.Visit(expression);
 }
Ejemplo n.º 7
0
 public override IExpression Visit(Conversion conversion)
 {
     conversion.ValueToConvert = this.Visit(conversion.ValueToConvert);
       if (TypeHelper.TypesAreEquivalent(conversion.TypeAfterConversion, conversion.ValueToConvert.Type) &&
     // converting a floating point number to the same floating point number is not a nop: it might result in precision loss.
     !(conversion.TypeAfterConversion.TypeCode == PrimitiveTypeCode.Float32 || conversion.TypeAfterConversion.TypeCode == PrimitiveTypeCode.Float64)
     )
     return conversion.ValueToConvert;
       else {
     var cc = conversion.ValueToConvert as CompileTimeConstant;
     if (cc != null) {
       if (cc.Value == null) {
     cc.Type = conversion.TypeAfterConversion;
     return cc;
       }
       if (conversion.TypeAfterConversion.TypeCode == PrimitiveTypeCode.Boolean && conversion.ValueToConvert.Type.TypeCode == PrimitiveTypeCode.Int32 && cc.Value is int) {
     var bcc = new CompileTimeConstant();
     bcc.Value = ((int)cc.Value) != 0;
     bcc.Type = conversion.TypeAfterConversion;
     return bcc;
       }
       if (conversion.TypeAfterConversion.TypeCode == PrimitiveTypeCode.Char && conversion.ValueToConvert.Type.TypeCode == PrimitiveTypeCode.Int32 && cc.Value is int) {
     var bcc = new CompileTimeConstant();
     bcc.Value = (char)(int)cc.Value;
     bcc.Type = conversion.TypeAfterConversion;
     return bcc;
       }
     } else if (conversion.TypeAfterConversion.TypeCode == PrimitiveTypeCode.Boolean) {
       var conditional = conversion.ValueToConvert as Conditional;
       if (conditional != null) {
     conditional.ResultIfFalse = this.ConvertToBoolean(conditional.ResultIfFalse);
     conditional.ResultIfTrue = this.ConvertToBoolean(conditional.ResultIfTrue);
     conditional.Type = conversion.TypeAfterConversion;
     return conditional;
       }
     }
     return conversion;
       }
 }
Ejemplo n.º 8
0
    /// <summary>
    /// Create two properties: object Current and T Current as the closure class implements both the 
    /// generic and non-generic version of ienumerator. 
    /// 
    /// Current Implementation generates getters, but not the property.
    /// </summary>
    /// <param name="iteratorClosure">Information about the closure created when compiling the current iterator method</param>
    private void CreateIteratorClosureProperties(IteratorClosureInformation iteratorClosure) {
      // Non-generic version of the get_Current, which returns the generic version of get_Current. 
      MethodDefinition getterNonGenericCurrent = new MethodDefinition() {
        Attributes = new List<ICustomAttribute>(1),
        InternFactory = this.host.InternFactory,
        Name = this.host.NameTable.GetNameFor("System.Collections.IEnumerator.get_Current")
      };
      CustomAttribute debuggerHiddenAttribute = new CustomAttribute();
      debuggerHiddenAttribute.Constructor = this.DebuggerHiddenCtor;
      getterNonGenericCurrent.Attributes.Add(debuggerHiddenAttribute);
      getterNonGenericCurrent.CallingConvention |= CallingConvention.HasThis;
      getterNonGenericCurrent.Visibility |= TypeMemberVisibility.Public;
      getterNonGenericCurrent.ContainingTypeDefinition = iteratorClosure.ClosureDefinition;
      getterNonGenericCurrent.Type = this.host.PlatformType.SystemObject;
      getterNonGenericCurrent.IsSpecialName = true;
      getterNonGenericCurrent.IsVirtual = true;
      getterNonGenericCurrent.IsNewSlot = true;
      getterNonGenericCurrent.IsHiddenBySignature = true;
      getterNonGenericCurrent.IsSealed = true;
      iteratorClosure.NonGenericGetCurrent = getterNonGenericCurrent;
      IMethodReference originalMethod = Dummy.MethodReference;
      foreach (ITypeMemberReference tref in iteratorClosure.NonGenericIEnumeratorInterface.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("get_Current"), false)) {
        originalMethod = tref as IMethodReference; if (originalMethod != null) break;
      }
      // assert originalMethod != Dummy
      MethodImplementation getterImplementation = new MethodImplementation() {
        ContainingType = iteratorClosure.ClosureDefinition,
        ImplementingMethod = getterNonGenericCurrent,
        ImplementedMethod = originalMethod
      };
      iteratorClosure.ClosureDefinition.ExplicitImplementationOverrides.Add(getterImplementation);

      List<IStatement> statements = new List<IStatement>();
      IFieldReference currentField = iteratorClosure.CurrentFieldReference;
      BoundExpression thisDotCurr = new BoundExpression() {
        Definition = currentField,
        Instance = new ThisReference(),
        Locations = iteratorClosure.ClosureDefinition.Locations,
        Type = currentField.Type
      };
      IExpression returnExpression;
      if (!iteratorClosure.ElementType.IsValueType && TypeHelper.TypesAreAssignmentCompatible(iteratorClosure.ElementType.ResolvedType, this.host.PlatformType.SystemObject.ResolvedType)) {
        returnExpression = thisDotCurr;
      } else {
        Conversion convertion = new Conversion() {
          CheckNumericRange = false,
          Type = this.host.PlatformType.SystemObject,
          TypeAfterConversion = getterNonGenericCurrent.Type,
          ValueToConvert = thisDotCurr
        };
        returnExpression = convertion;
      }
      ReturnStatement returnCurrent = new ReturnStatement() {
        Expression = returnExpression,
        Locations = iteratorClosure.ClosureDefinition.Locations
      };
      statements.Add(returnCurrent);
      BlockStatement block = new BlockStatement() { Statements = statements };
      SourceMethodBody body = new SourceMethodBody(this.host, this.sourceLocationProvider);
      body.IsNormalized = true;
      body.LocalsAreZeroed = true;
      body.Block = block;
      body.MethodDefinition = getterNonGenericCurrent;
      getterNonGenericCurrent.Body = body;

      // Create generic version of get_Current, the body of which is simply returning this.current.
      MethodDefinition getterGenericCurrent = new MethodDefinition() {
        Attributes = new List<ICustomAttribute>(1),
        InternFactory = this.host.InternFactory,
        Name = this.host.NameTable.GetNameFor("System.Collections.Generic.IEnumerator<" + iteratorClosure.ElementType.ToString() +">.get_Current")
      };
      getterGenericCurrent.Attributes.Add(debuggerHiddenAttribute);

      getterGenericCurrent.CallingConvention |= CallingConvention.HasThis;
      getterGenericCurrent.Visibility |= TypeMemberVisibility.Public;
      getterGenericCurrent.ContainingTypeDefinition = iteratorClosure.ClosureDefinition;
      getterGenericCurrent.Type = iteratorClosure.ElementType;
      getterGenericCurrent.IsSpecialName = true;
      getterGenericCurrent.IsVirtual = true;
      getterGenericCurrent.IsNewSlot = true;
      getterGenericCurrent.IsHiddenBySignature = true;
      getterGenericCurrent.IsSealed = true;
      iteratorClosure.GenericGetCurrent = getterGenericCurrent;
      originalMethod = Dummy.MethodReference;
      foreach (ITypeMemberReference tref in iteratorClosure.GenericIEnumeratorInterface.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("get_Current"), false)) {
        originalMethod = tref as IMethodReference; if (originalMethod != null) break;
      }
      MethodImplementation getterImplementation2 = new MethodImplementation() {
        ContainingType = iteratorClosure.ClosureDefinition,
        ImplementingMethod = getterGenericCurrent,
        ImplementedMethod = originalMethod
      };
      iteratorClosure.ClosureDefinition.ExplicitImplementationOverrides.Add(getterImplementation2);

      statements = new List<IStatement>();
      currentField = iteratorClosure.CurrentFieldReference;
      BoundExpression thisDotCurrent = new BoundExpression() {
        Definition = currentField, Instance = new ThisReference(), Locations = iteratorClosure.ClosureDefinition.Locations, Type = currentField.Type
      };
      returnCurrent = new ReturnStatement() {
        Expression = thisDotCurrent,
        Locations = iteratorClosure.ClosureDefinition.Locations
      };
      statements.Add(returnCurrent);
      block = new BlockStatement() { Statements = statements };
      body = new SourceMethodBody(this.host, this.sourceLocationProvider);
      body.LocalsAreZeroed = true;
      body.Block = block;
      body.MethodDefinition = getterGenericCurrent;
      getterGenericCurrent.Body = body;
    }
Ejemplo n.º 9
0
 /// <summary>
 /// Rewrites the children of the given conversion expression.
 /// </summary>
 public virtual void RewriteChildren(Conversion conversion)
 {
     this.RewriteChildren((Expression)conversion);
       conversion.ValueToConvert = this.Rewrite(conversion.ValueToConvert);
       conversion.TypeAfterConversion = this.Rewrite(conversion.TypeAfterConversion);
 }
Ejemplo n.º 10
0
 /// <summary>
 /// Visits the specified conversion.
 /// </summary>
 /// <param name="conversion">The conversion.</param>
 public override void Visit(IConversion conversion)
 {
     Conversion mutableConversion = conversion as Conversion;
     if (alwaysMakeACopy || mutableConversion == null) mutableConversion = new Conversion(conversion);
     this.resultExpression = this.myCodeMutator.Visit(mutableConversion);
 }
Ejemplo n.º 11
0
 /// <summary>
 /// Visits the specified conversion.
 /// </summary>
 /// <param name="conversion">The conversion.</param>
 /// <returns></returns>
 public virtual IExpression Visit(Conversion conversion)
 {
     conversion.ValueToConvert = Visit(conversion.ValueToConvert);
       conversion.TypeAfterConversion = this.Visit(conversion.TypeAfterConversion);
       return conversion;
 }