Ejemplo n.º 1
0
 private Statement ParseAssignment(IOperation currentOperation)
 {
     TargetExpression target = new TargetExpression();
       ITypeReference/*?*/ elementType = null;
       target.Alignment = this.alignment;
       target.Definition = currentOperation.Value;
       target.IsVolatile = this.sawVolatile;
       Assignment assignment = new Assignment();
       assignment.Target = target;
       assignment.Source = this.PopOperandStack();
       ExpressionStatement result = new ExpressionStatement();
       result.Expression = assignment;
       switch (currentOperation.OperationCode) {
     case OperationCode.Stfld:
       target.Instance = this.PopOperandStack();
       break;
     case OperationCode.Stelem:
     case OperationCode.Stelem_I:
     case OperationCode.Stelem_I1:
     case OperationCode.Stelem_I2:
     case OperationCode.Stelem_I4:
     case OperationCode.Stelem_I8:
     case OperationCode.Stelem_R4:
     case OperationCode.Stelem_R8:
     case OperationCode.Stelem_Ref:
       ArrayIndexer indexer = this.ParseArrayIndexer(currentOperation);
       target.Definition = indexer;
       target.Instance = indexer.IndexedObject;
       break;
     case OperationCode.Stind_I:
       elementType = this.platformType.SystemIntPtr;
       goto case OperationCode.Stind_Ref;
     case OperationCode.Stind_I1:
       elementType = this.platformType.SystemInt8;
       goto case OperationCode.Stind_Ref;
     case OperationCode.Stind_I2:
       elementType = this.platformType.SystemInt16;
       goto case OperationCode.Stind_Ref;
     case OperationCode.Stind_I4:
       elementType = this.platformType.SystemInt32;
       goto case OperationCode.Stind_Ref;
     case OperationCode.Stind_I8:
       elementType = this.platformType.SystemInt64;
       goto case OperationCode.Stind_Ref;
     case OperationCode.Stind_R4:
       elementType = this.platformType.SystemFloat32;
       goto case OperationCode.Stind_Ref;
     case OperationCode.Stind_R8:
       elementType = this.platformType.SystemFloat64;
       goto case OperationCode.Stind_Ref;
     case OperationCode.Stind_Ref:
     case OperationCode.Stobj:
       AddressDereference addressDereference = new AddressDereference();
       addressDereference.Address = this.PopOperandStack();
       addressDereference.Alignment = this.alignment;
       addressDereference.IsVolatile = this.sawVolatile;
       //capture the element type. The pointer might be untyped, in which case the instruction is the only point where the element type is known.
       if (elementType != null) addressDereference.Type = elementType; //else: The type inferencer will fill in the type once the pointer type is known.
       target.Definition = addressDereference;
       break;
     case OperationCode.Stloc:
     case OperationCode.Stloc_0:
     case OperationCode.Stloc_1:
     case OperationCode.Stloc_2:
     case OperationCode.Stloc_3:
     case OperationCode.Stloc_S:
       var local = this.GetLocalWithSourceName((ILocalDefinition)target.Definition);
       target.Definition = local;
       this.numberOfAssignments[local] =
     this.numberOfAssignments.ContainsKey(local) ?
     this.numberOfAssignments[local] + 1 :
     1;
       break;
       }
       this.alignment = 0;
       this.sawVolatile = false;
       return result;
 }
Ejemplo n.º 2
0
 private Expression ParseCopyObject()
 {
     AddressDereference source = new AddressDereference();
       source.Address = this.PopOperandStack();
       AddressDereference addressDeref = new AddressDereference();
       addressDeref.Address = this.PopOperandStack();
       TargetExpression target = new TargetExpression();
       target.Definition = addressDeref;
       Assignment result = new Assignment();
       result.Source = source;
       result.Target = target;
       return result;
 }
Ejemplo n.º 3
0
 private Expression ParseAddressDereference(IOperation currentOperation)
 {
     ITypeReference elementType = null;
       switch (currentOperation.OperationCode) {
     case OperationCode.Ldind_I: elementType = this.platformType.SystemIntPtr; break;
     case OperationCode.Ldind_I1: elementType = this.platformType.SystemInt8; break;
     case OperationCode.Ldind_I2: elementType = this.platformType.SystemInt16; break;
     case OperationCode.Ldind_I4: elementType = this.platformType.SystemInt32; break;
     case OperationCode.Ldind_I8: elementType = this.platformType.SystemInt64; break;
     case OperationCode.Ldind_R4: elementType = this.platformType.SystemFloat32; break;
     case OperationCode.Ldind_R8: elementType = this.platformType.SystemFloat64; break;
     case OperationCode.Ldind_U1: elementType = this.platformType.SystemUInt8; break;
     case OperationCode.Ldind_U2: elementType = this.platformType.SystemUInt16; break;
     case OperationCode.Ldind_U4: elementType = this.platformType.SystemUInt32; break;
       }
       AddressDereference result = new AddressDereference();
       result.Address = this.PopOperandStack();
       result.Alignment = this.alignment;
       result.IsVolatile = this.sawVolatile;
       //Capture the element type. The pointer might be untyped, in which case the instruction is the only point where the element type is known.
       if (elementType != null) result.Type = elementType; //else: The type inferencer will fill in the type once the pointer type is known.
       this.alignment = 0;
       this.sawVolatile = false;
       return result;
 }
Ejemplo n.º 4
0
 private Expression ParseAddressDereference(IOperation currentOperation) {
   Contract.Requires(currentOperation != null);
   AddressDereference result = new AddressDereference();
   result.Address = this.PopOperandStack();
   result.Alignment = this.alignment;
   result.IsVolatile = this.sawVolatile;
   this.alignment = 0;
   this.sawVolatile = false;
   return result;
 }
Ejemplo n.º 5
0
 private Statement ParseAssignment(IOperation currentOperation) {
   Contract.Requires(currentOperation != null);
   TargetExpression target = new TargetExpression();
   ITypeReference/*?*/ elementType = null;
   if (this.alignment > 0) {
     Contract.Assume(this.alignment == 1 || this.alignment == 2 || this.alignment == 4);
     target.Alignment = this.alignment;
   }
   target.IsVolatile = this.sawVolatile;
   Assignment assignment = new Assignment();
   assignment.Target = target;
   assignment.Source = this.PopOperandStack();
   ExpressionStatement result = new ExpressionStatement();
   result.Expression = assignment;
   switch (currentOperation.OperationCode) {
     case OperationCode.Starg:
     case OperationCode.Starg_S: {
         var definition = currentOperation.Value;
         if (definition == null) {
           target.Definition = new ThisReference();
           var typeForThis = (INamedTypeDefinition)this.MethodDefinition.ContainingTypeDefinition;
           if (typeForThis.IsValueType)
             target.Type = Immutable.ManagedPointerType.GetManagedPointerType(Microsoft.Cci.MutableCodeModel.NamedTypeDefinition.SelfInstance(typeForThis, this.host.InternFactory), this.host.InternFactory);
           else
             target.Type = NamedTypeDefinition.SelfInstance(typeForThis, this.host.InternFactory);
         } else {
           var par = definition as IParameterDefinition;
           Contract.Assume(par != null);
           target.Definition = definition;
           target.Type = par.Type;
         }
         break;
       }
     case OperationCode.Stfld:
       target.Instance = this.PopOperandStack();
       goto case OperationCode.Stsfld;
     case OperationCode.Stsfld:
       Contract.Assume(currentOperation.Value is IFieldReference);
       var field = (IFieldReference)currentOperation.Value;
       target.Definition = field;
       target.Type = field.Type;
       break;
     case OperationCode.Stelem:
       elementType = (ITypeReference)currentOperation.Value;
       goto case OperationCode.Stelem_Ref;
     case OperationCode.Stelem_I:
       elementType = this.platformType.SystemIntPtr;
       goto case OperationCode.Stelem_Ref;
     case OperationCode.Stelem_I1:
       elementType = this.platformType.SystemInt8;
       goto case OperationCode.Stelem_Ref;
     case OperationCode.Stelem_I2:
       elementType = this.platformType.SystemInt16;
       goto case OperationCode.Stelem_Ref;
     case OperationCode.Stelem_I4:
       elementType = this.platformType.SystemInt32;
       goto case OperationCode.Stelem_Ref;
     case OperationCode.Stelem_I8:
       elementType = this.platformType.SystemInt64;
       goto case OperationCode.Stelem_Ref;
     case OperationCode.Stelem_R4:
       elementType = this.platformType.SystemFloat32;
       goto case OperationCode.Stelem_Ref;
     case OperationCode.Stelem_R8:
       elementType = this.platformType.SystemFloat64;
       goto case OperationCode.Stelem_Ref;
     case OperationCode.Stelem_Ref:
       ArrayIndexer indexer = this.ParseArrayIndexer(currentOperation, elementType??this.platformType.SystemObject, treatArrayAsSingleDimensioned: true);
       target.Definition = indexer;
       target.Instance = indexer.IndexedObject;
       target.Type = indexer.Type;
       break;
     case OperationCode.Stind_I:
       elementType = this.platformType.SystemIntPtr;
       goto case OperationCode.Stind_Ref;
     case OperationCode.Stind_I1:
       elementType = this.platformType.SystemInt8;
       goto case OperationCode.Stind_Ref;
     case OperationCode.Stind_I2:
       elementType = this.platformType.SystemInt16;
       goto case OperationCode.Stind_Ref;
     case OperationCode.Stind_I4:
       elementType = this.platformType.SystemInt32;
       goto case OperationCode.Stind_Ref;
     case OperationCode.Stind_I8:
       elementType = this.platformType.SystemInt64;
       goto case OperationCode.Stind_Ref;
     case OperationCode.Stind_R4:
       elementType = this.platformType.SystemFloat32;
       goto case OperationCode.Stind_Ref;
     case OperationCode.Stind_R8:
       elementType = this.platformType.SystemFloat64;
       goto case OperationCode.Stind_Ref;
     case OperationCode.Stobj:
       elementType = (ITypeReference)currentOperation.Value;
       goto case OperationCode.Stind_Ref;
     case OperationCode.Stind_Ref:
       AddressDereference addressDereference = new AddressDereference();
       addressDereference.Address = this.PopOperandStack();
       addressDereference.Alignment = this.alignment;
       addressDereference.IsVolatile = this.sawVolatile;
       target.Definition = addressDereference;
       var pointerType = addressDereference.Address.Type as IPointerTypeReference;
       if (pointerType != null)
         addressDereference.Type = pointerType.TargetType;
       else {
         var managedPointerType = addressDereference.Address.Type as IManagedPointerTypeReference;
         if (managedPointerType != null)
           addressDereference.Type = managedPointerType.TargetType;
         else {
           //The pointer itself is untyped, so the instruction must have specified the element type
           addressDereference.Type = elementType??this.platformType.SystemObject;
         }
       }
       target.Type = addressDereference.Type;
       break;
     case OperationCode.Stloc:
     case OperationCode.Stloc_0:
     case OperationCode.Stloc_1:
     case OperationCode.Stloc_2:
     case OperationCode.Stloc_3:
     case OperationCode.Stloc_S:
       Contract.Assume(currentOperation.Value is ILocalDefinition);
       var local = this.GetLocalWithSourceName((ILocalDefinition)currentOperation.Value);
       target.Definition = local;
       this.numberOfAssignmentsToLocal[local] =
         this.numberOfAssignmentsToLocal.ContainsKey(local) ?
         this.numberOfAssignmentsToLocal[local] + 1 :
         1;
       target.Type = local.Type;
       break;
     default: {
         var definition = currentOperation.Value;
         Contract.Assume(definition is ILocalDefinition || definition is IParameterDefinition || 
         definition is IFieldReference || definition is IArrayIndexer || 
         definition is IAddressDereference || definition is IPropertyDefinition);
         target.Definition = definition;
         break;
       }
   }
   assignment.Source = TypeInferencer.Convert(assignment.Source, target.Type); //mainly to convert (u)ints to bools, chars and pointers.
   assignment.Type = target.Type;
   Contract.Assume(assignment.Target.Type.TypeCode != PrimitiveTypeCode.Boolean || assignment.Source.Type.TypeCode == PrimitiveTypeCode.Boolean || IsByRef(assignment.Target.Definition));
   this.alignment = 0;
   this.sawVolatile = false;
   return result;
 }
Ejemplo n.º 6
0
 /// <summary>
 /// Visits the specified address dereference.
 /// </summary>
 /// <param name="addressDereference">The address dereference.</param>
 /// <returns></returns>
 protected virtual IExpression DeepCopy(AddressDereference addressDereference)
 {
     addressDereference.Address = this.Substitute(addressDereference.Address);
       addressDereference.Type = this.Substitute(addressDereference.Type);
       return addressDereference;
 }
Ejemplo n.º 7
0
    private Statement ParseInitObject(IOperation currentOperation) {
      Contract.Requires(currentOperation != null);

      Contract.Assume(currentOperation.Value is ITypeReference);
      var objectType = (ITypeReference)currentOperation.Value;
      Assignment assignment = new Assignment();
      var addressDeref = new AddressDereference() { Address = this.PopOperandStack(), Type = objectType };
      assignment.Target = new TargetExpression() { Definition = addressDeref, Type = objectType };
      assignment.Source = new DefaultValue() { DefaultValueType = (ITypeReference)currentOperation.Value, Type = objectType };
      assignment.Type = objectType;
      return new ExpressionStatement() { Expression = assignment };
    }
Ejemplo n.º 8
0
 /// <summary>
 /// Visits the specified address dereference.
 /// </summary>
 /// <param name="addressDereference">The address dereference.</param>
 public override void Visit(IAddressDereference addressDereference)
 {
     AddressDereference mutableAddressDereference  = new AddressDereference(addressDereference);
     this.resultExpression = this.myCodeCopier.DeepCopy(mutableAddressDereference);
 }
Ejemplo n.º 9
0
 /// <summary>
 /// Create the new body of the iterator method. 
 /// </summary>
 /// <remarks>
 /// Pseudo code:
 /// iteratorClosureLocal = new Closure(0);
 /// iteratorClosureLocal.field = parameter; // for each parameter including this. 
 /// return iteratorClosureLocal;
 /// </remarks>
 private BlockStatement CreateNewIteratorMethodBody(IteratorClosureInformation iteratorClosure) {
   BlockStatement result = new BlockStatement();
   // iteratorClosureLocal = new IteratorClosure(0);
   LocalDefinition localDefinition = new LocalDefinition() {
     Name = this.host.NameTable.GetNameFor("iteratorClosureLocal"),
     Type = GetClosureTypeReferenceFromIterator(iteratorClosure),
   };
   CreateObjectInstance createObjectInstance = new CreateObjectInstance() {
     MethodToCall = GetMethodReference(iteratorClosure, iteratorClosure.Constructor),
     Type = localDefinition.Type
   };
   // the start state depends on whether the iterator is an IEnumerable or an IEnumerator. For the former,
   // it must be created in state -2. Then it is the GetEnumerator method that puts it into its
   // "start" state, i.e., state 0.
   var startState = this.isEnumerable ? -2 : 0;
   createObjectInstance.Arguments.Add(new CompileTimeConstant() { Value = startState, Type = this.host.PlatformType.SystemInt32 });
   LocalDeclarationStatement localDeclarationStatement = new LocalDeclarationStatement() {
     InitialValue = createObjectInstance,
     LocalVariable = localDefinition
   };
   result.Statements.Add(localDeclarationStatement);
   // Generate assignments to closure instance's fields for each of the parameters captured by the closure. 
   foreach (object capturedLocalOrParameter in FieldForCapturedLocalOrParameter.Keys) {
     BoundField boundField = FieldForCapturedLocalOrParameter[capturedLocalOrParameter];
     Assignment assignment;
     ITypeReference localOrParameterType = GetLocalOrParameterType(capturedLocalOrParameter);
     if (capturedLocalOrParameter is ILocalDefinition) continue;
     if (capturedLocalOrParameter is IThisReference) {
       var thisR = new ThisReference();
       IExpression thisValue = thisR;
       if (!this.method.ContainingTypeDefinition.IsClass) {
         thisValue = new AddressDereference() {
           Address = thisR,
           Type = this.method.ContainingTypeDefinition.IsGeneric ? (ITypeReference)this.method.ContainingTypeDefinition.InstanceType : (ITypeReference)this.method.ContainingTypeDefinition
         };
       }
       assignment = new Assignment {
         Source = thisValue,
         Type = this.method.ContainingType,
         Target = new TargetExpression() {
           Definition = GetFieldReference(iteratorClosure, boundField.Field),
           Type = this.method.ContainingType,
           Instance = new BoundExpression() {
             Type = localDefinition.Type,
             Instance = null,
             Definition = localDefinition,
             IsVolatile = false
           }
         },
       };
     } else {
       assignment = new Assignment {
         Source = new BoundExpression() {
           Definition = capturedLocalOrParameter,
           Instance = null,
           IsVolatile = false,
           Type = localOrParameterType
         },
         Type = localOrParameterType,
         Target = new TargetExpression() {
           Definition = GetFieldReference(iteratorClosure, boundField.Field),
           Type = localOrParameterType,
           Instance = new BoundExpression() {
             Type = localDefinition.Type,
             Instance = null,
             Definition = localDefinition,
             IsVolatile = false
           }
         },
       };
     }
     ExpressionStatement expressionStatement = new ExpressionStatement() { Expression = assignment };
     result.Statements.Add(expressionStatement);
   }
   // Generate: return iteratorClosureLocal;
   result.Statements.Add(new ReturnStatement() {
     Expression = new BoundExpression() { Definition = localDeclarationStatement.LocalVariable, Instance = null, Type = localDeclarationStatement.LocalVariable.Type }
   });
   return result;
 }
Ejemplo n.º 10
0
 /// <summary>
 /// Rewrites the children of the given address dereference expression.
 /// </summary>
 /// <param name="addressDereference"></param>
 public virtual void RewriteChildren(AddressDereference addressDereference)
 {
     this.RewriteChildren((Expression)addressDereference);
       addressDereference.Address = this.Rewrite(addressDereference.Address);
 }
Ejemplo n.º 11
0
 /// <summary>
 /// Visits the specified address dereference.
 /// </summary>
 /// <param name="addressDereference">The address dereference.</param>
 public override void Visit(IAddressDereference addressDereference)
 {
     AddressDereference mutableAddressDereference = addressDereference as AddressDereference;
     if (alwaysMakeACopy || mutableAddressDereference == null) mutableAddressDereference = new AddressDereference(addressDereference);
     this.resultExpression = this.myCodeMutator.Visit(mutableAddressDereference);
 }
Ejemplo n.º 12
0
 /// <summary>
 /// Visits the specified address dereference.
 /// </summary>
 /// <param name="addressDereference">The address dereference.</param>
 /// <returns></returns>
 public virtual IExpression Visit(AddressDereference addressDereference)
 {
     addressDereference.Address = this.Visit(addressDereference.Address);
       addressDereference.Type = this.Visit(addressDereference.Type);
       return addressDereference;
 }