Пример #1
0
 public override Statement VisitAssignmentStatement(AssignmentStatement assignment)
 {
     if (assignment == null) return null;
     assignment.Source = this.VisitExpression(assignment.Source);
     assignment.Target = this.VisitTargetExpression(assignment.Target);
     return assignment;
 }
Пример #2
0
        public override void VisitAssignmentStatement(AssignmentStatement assignment)
        {
            if (assignment.Target is Local && IsResultExpression(assignment.Source))
            {
                exemptResultLocal = (Local) assignment.Target;
            }

            base.VisitAssignmentStatement(assignment);
        }
Пример #3
0
        //public override Block VisitBlock(Block block) {
        //  if(block.Statements != null && block.Statements.Count == 1) {
        //    Return r = block.Statements[0] as Return;
        //    if(r != null) {
        //      Statement s = this.VisitReturn(r);
        //      Block retBlock = s as Block;
        //      if(retBlock != null) {
        //        block.Statements = retBlock.Statements;
        //        return block;
        //      } else {
        //        return base.VisitBlock(block);
        //      }
        //    } else {
        //      return base.VisitBlock(block);
        //    }
        //  } else {
        //    return base.VisitBlock(block);
        //  }
        //}

        public override Statement VisitReturn(Return Return)
        {
            if (Return == null)
            {
                return null;
            }

            returnCount++;
            this.lastReturnSourceContext = Return.SourceContext;

            StatementList stmts = new StatementList();

            Return.Expression = this.VisitExpression(Return.Expression);

            if (Return.Expression != null)
            {
                MethodCall mc = Return.Expression as MethodCall;
                if (mc != null && mc.IsTailCall)
                {
                    mc.IsTailCall = false;
                }

                var assgnmt = new AssignmentStatement(result, Return.Expression);

                assgnmt.SourceContext = Return.SourceContext;
                stmts.Add(assgnmt);
            }

            // the branch is a "leave" out of the try block that the body will be
            // in.
            var branch = new Branch(null, newExit, false, false, this.leaveExceptionBody);
            branch.SourceContext = Return.SourceContext;

            stmts.Add(branch);

            return new Block(stmts);
        }
            /// <summary>
            /// Returns true the assignment was done from local variable that holds parameter expression
            /// to the indexer.
            /// </summary>
            private bool ExpressionTreeInitialization(AssignmentStatement assignment)
            {
                if (assignment == null || assignment.Source == null)
                    return false;

                var sourceAsLocal = assignment.Source as Local;
                return NameUtils.IsExpressionTreeLocal(sourceAsLocal);
            }
Пример #5
0
 public override Statement VisitAssignmentStatement(AssignmentStatement assignment)
 {
     this.VisitExpression(assignment.Target);
     Write(" {0} ", GetAssignmentOperator(assignment.Operator));
     this.VisitExpression(assignment.Source);
     return assignment;
 }
Пример #6
0
 private AssignmentStatement ParseStoreField(){
   Expression rhvalue = PopOperand();
   Expression thisob = PopOperand();
   AssignmentStatement s = new AssignmentStatement(new MemberBinding(thisob, this.GetMemberFromToken(), this.isVolatile, this.alignment), rhvalue);
   return s;
 }
Пример #7
0
        // The method added by Jiri Adamek
        // It generates NAtiveZOM calls
        private void GenerateNativeZOMCall(Block block, MethodCall call, bool callIsAsync, AssignmentStatement assignmentStatement)
        {
            ZMethod method = (ZMethod)((MemberBinding)call.Callee).BoundMember;

            // Eventually, this will be checked by an earlier phase.
            Debug.Assert(method.Parameters.Count == call.Operands.Count);

            // Asynchronous calls
            Debug.Assert(!callIsAsync, "async not supporrted for NativeZOM calls");

            // Debugging - parameters
            for (int i = 0, n = call.Operands.Count; i < n; i++)
            {
                Parameter param = method.Parameters[i];

                Debug.Assert(param != null);

                // In fact, call.operands[i] MAY BE null due to the error recovery (if the type of the
                // expression does not match the type in the method definition)
                //
                // Debug.Assert(call.Operands[i] != null);

                Debug.Assert((param.Flags & ParameterFlags.Out) == 0, "out parameters not supported for NativeZOM calls");
            }

            Expression typename = new QualifiedIdentifier(new Identifier("Microsoft.Zing"), method.DeclaringType.Name);
            Expression callee;

            if (!method.IsStatic)
            {
                callee = Templates.GetExpressionTemplate("NativeZOMCallee");
                Replacer.Replace(callee, "_TypeName", typename);
                Expression pointer = this.VisitExpression(((MemberBinding)call.Callee).TargetObject);
                Replacer.Replace(callee, "_Pointer", pointer);
                Replacer.Replace(callee, "_MethodName", method.Name);
            }
            else
            {
                callee = Templates.GetExpressionTemplate("NativeZOMStaticCall");
                Replacer.Replace(callee, "_ClassName", typename);
                Replacer.Replace(callee, "_MethodName", method.Name);
            }

            ExpressionList argumentList = new ExpressionList();
            argumentList.Add(Templates.GetExpressionTemplate("NativeZOMCallFirstArgument"));
            foreach (Expression operand in call.Operands) argumentList.Add(this.VisitExpression(operand));
            MethodCall nativeCall = new MethodCall(callee, argumentList);

            Statement newStatement;
            if (assignmentStatement != null)
            {
                newStatement = Templates.GetStatementTemplate("NativeZOMCallWithAssignment");
                Replacer.Replace(newStatement, "_Dest", this.VisitExpression(assignmentStatement.Target));
                Replacer.Replace(newStatement, "_Source", nativeCall);
            }
            else
            {
                newStatement = new ExpressionStatement(nativeCall);
            }

            block.Statements.Add(newStatement);
        }
Пример #8
0
        public override Statement VisitAssignmentStatement(AssignmentStatement assignment)
        {
            if (assignment.Source == null || assignment.Target == null)
                return null;

            Expression normalizedSource = this.VisitExpression(assignment.Source);
            Expression normalizedTarget = this.VisitExpression(assignment.Target);

            assignment.Source = normalizedSource;
            assignment.Target = normalizedTarget;

            if (inExpressionStatement)
                return assignment;
            else
            {
                // This form shows up in initialized local variables. We have to wrap the
                // assignment back up to get the decompiler to generate appropriate code.
                ExpressionStatement exprStmt = new ExpressionStatement(new AssignmentExpression(assignment));
                exprStmt.SourceContext = assignment.SourceContext;
                return exprStmt;
            }
        }
Пример #9
0
    public override Expression VisitOldExpression(OldExpression oldExpression) {
      if (this.topLevelClosureClass != null) {
        #region In Closure ==> Create a field
        // Since we're within a closure, we can't create a local to hold the value of the old expression
        // but instead have to create a field for it. That field can be a member of the top-level
        // closure class since nothing mentioned in the old expression (except possibly for the
        // bound variables of enclosing quantifications) should be anything captured from
        // an inner anonymous delegate.

        // BUT, first we have to know if the old expression depends on any of the bound
        // variables of the closures in which it is located. If not, then we can implement
        // it as a scalar and just generate the assignment "closure_class.field := e" for
        // "Old(e)" to take a snapshot of e's value in the prestate. If it does depend on
        // any of the bound variables, then we need to generate a set of for-loops that
        // compute the indices and values of e for each tuple of indices so it can be retrieved
        // (given the indices) in the post-state.
        CollectBoundVariables cbv = new CollectBoundVariables(this.stackOfBoundVariables);
        cbv.VisitExpression(oldExpression.expression);

        SubstituteClosureClassWithinOldExpressions subst =
            new SubstituteClosureClassWithinOldExpressions(this.closureLocals);
        Expression e = subst.VisitExpression(oldExpression.expression);
        if (cbv.FoundVariables.Count == 0) {
          #region Use a scalar for the old variable
          Local closureLocal;
          if (!this.closureLocals.TryGetValue(this.topLevelClosureClass, out closureLocal))
          {
            Contract.Assume(false, "can't find closure local!");
          }
          #region Define a scalar
          var clTemplate = HelperMethods.Unspecialize(this.topLevelClosureClass);
          Field f = new Field(clTemplate,
            null,
            FieldFlags.CompilerControlled | FieldFlags.Public,
            Identifier.For("_old" + oldExpression.expression.UniqueKey.ToString()), // unique name for this old expr.
            oldExpression.Type,
            null);
          clTemplate.Members.Add(f);
          // now produce properly instantiated field
          f = (Field)Rewriter.GetMemberInstanceReference(f, this.topLevelClosureClass);
          #endregion
          #region Generate code to store value in prestate
          this.prestateValuesOfOldExpressions.Statements.Add(new AssignmentStatement(new MemberBinding(closureLocal, f), e));
          #endregion
          #region Return expression to be used in poststate
          // Return an expression that will evaluate in the poststate to the value of the old
          // expression in the prestate. This will be this.up.f where "up" is the field C#
          // generated to point to the instance of the top-level closure class.
          if (this.PointerToTopLevelClosureClass == null) {
            // then the old expression occurs in the top-level closure class. Just return "this.f"
            // where "this" refers to the top-level closure class.
            return new MemberBinding(new This(this.currentClosureClass), f);
          } else {
            return new MemberBinding(
              new MemberBinding(new This(this.currentClosureClass), this.PointerToTopLevelClosureClass),
              f);
          }
          #endregion
          #endregion
        } else {
          // the Old expression *does* depend upon at least one of the bound variable
          // in a ForAll or Exists expression
          #region Use an indexed variable for the old variable
          TypeNode oldVariableTypeDomain;
          #region Decide if domain is one-dimensional or not
          bool oneDimensional = cbv.FoundVariables.Count == 1 && cbv.FoundVariables[0].Type.IsValueType;
          if (oneDimensional) {
            // a one-dimensional old-expression can use the index variable directly
            oldVariableTypeDomain = cbv.FoundVariables[0].Type;
          } else {
            oldVariableTypeDomain = SystemTypes.GenericList.GetTemplateInstance(this.module, SystemTypes.Int32);
          }
          #endregion
          TypeNode oldVariableTypeRange = oldExpression.Type;
          TypeNode oldVariableType = SystemTypes.GenericDictionary.GetTemplateInstance(this.module, oldVariableTypeDomain, oldVariableTypeRange);
          Local closureLocal;
          if (!this.closureLocals.TryGetValue(this.topLevelClosureClass, out closureLocal))
          {
            Contract.Assume(false, "can't find closure local");
          }
          #region Define an indexed variable
          var clTemplate = HelperMethods.Unspecialize(this.topLevelClosureClass);
          Field f = new Field(clTemplate,
            null,
            FieldFlags.CompilerControlled | FieldFlags.Assembly, // can't be private or protected because it needs to be accessed from inner (closure) classes that don't inherit from the class this field is added to.
            Identifier.For("_old" + oldExpression.expression.UniqueKey.ToString()), // unique name for this old expr.
            oldVariableType,
            null);
          clTemplate.Members.Add(f);
          // instantiate f
          f = (Field)Rewriter.GetMemberInstanceReference(f, closureLocal.Type);
          #endregion
          #region Generate code to initialize the indexed variable
          Statement init = new AssignmentStatement(
            new MemberBinding(closureLocal, f),
            new Construct(new MemberBinding(null, oldVariableType.GetConstructor()), null));
          this.prestateValuesOfOldExpressions.Statements.Add(init);
          #endregion
          #region Generate code to store values in prestate
          #region Create assignment: this.closure.f[i,j,k,...] = e;
          Method setItem = oldVariableType.GetMethod(Identifier.For("set_Item"), oldVariableTypeDomain, oldVariableTypeRange);
          Expression index;
          if (oneDimensional) {
            index = cbv.FoundVariables[0];
          } else {
            //InstanceInitializer ctor =
            //  ContractNodes.TupleClass.GetConstructor(SystemTypes.Int32.GetArrayType(1));
            //Expression index = new Construct(new MemberBinding(null,ctor),new ExpressionList(
            index = Literal.Null;
          }
          MethodCall mc = new MethodCall(new MemberBinding(new MemberBinding(closureLocal, f), setItem),
            new ExpressionList(index, e));
          Statement stat = new ExpressionStatement(mc);
          #endregion
          List<Local> locals = new List<Local>(this.stackOfBoundVariables.Count);
          TrivialHashtable paramMap = new TrivialHashtable();
          #region Generate a local for each bound variable to use in for-loop
          foreach (Variable v in this.stackOfBoundVariables) {
            Local l = new Local(Identifier.Empty, v.Type);
            paramMap[v.UniqueKey] = l;
            locals.Add(l);
          }
          #endregion
          #region Substitute locals for bound variables in old expression *AND* in inner loop bounds
          SubstituteParameters sps = new SubstituteParameters(paramMap, this.stackOfBoundVariables);
          sps.Visit(stat);
          #endregion
          #region Create nested for-loops around assignment
          // keep track of when the first variable is used (from innermost to outermost)
          // as soon as the first one is needed because the old expression depends on it,
          // then keep all enclosing loops. It would be possible to keep only those where
          // the necessary loops have loop bounds that depend on an enclosing loop, but I
          // haven't calculated that, so just keep them all. For instance, if the old expression
          // depends on j and the loops are "for i,0,n" and inside that "for j,0,i", then need
          // both loops. If the inner loop bounds were 0 and n, then wouldn't need the outer
          // loop.
          bool usedAVariable = false;
          for (int i = this.stackOfBoundVariables.Count - 1; 0 <= i; i--) {
            if (!usedAVariable
              && !cbv.FoundVariables.Contains(this.stackOfBoundVariables[i])) continue;
            usedAVariable = true;
            Expression lowerBound = new Duplicator(this.module, this.currentClosureClass).VisitExpression(
              this.stackOfMethods[i].Operands[0]);
            lowerBound = subst.VisitExpression(lowerBound);
            lowerBound = sps.VisitExpression(lowerBound);
            Expression upperBound = new Duplicator(this.module, this.currentClosureClass).VisitExpression(
              this.stackOfMethods[i].Operands[1]);
            upperBound = subst.VisitExpression(upperBound);
            upperBound = sps.VisitExpression(upperBound);
            stat = RewriteHelper.GenerateForLoop(locals[i], lowerBound, upperBound, stat);
          }
          #endregion
          this.prestateValuesOfOldExpressions.Statements.Add(stat);
          #endregion
          #region Return expression to be used in poststate
          Method getItem = oldVariableType.GetMethod(Identifier.For("get_Item"), oldVariableTypeDomain);
          if (oneDimensional) {
            index = cbv.FoundReferences[0];
          } else {
            //InstanceInitializer ctor =
            //  ContractNodes.TupleClass.GetConstructor(SystemTypes.Int32.GetArrayType(1));
            //Expression index = new Construct(new MemberBinding(null,ctor),new ExpressionList(
            index = Literal.Null;
          }
          // Return an expression that will evaluate in the poststate to the value of the old
          // expression in the prestate. This will be this.up.f[i,j,k,...] where "up" is the field C#
          // generated to point to the instance of the top-level closure class.
          MemberBinding thisDotF;
          if (this.PointerToTopLevelClosureClass == null) {
            // then the old expression occurs in the top-level closure class. Just return "this.f"
            // where "this" refers to the top-level closure class.
            Contract.Assume(f != null);
            thisDotF = new MemberBinding(new This(clTemplate), HelperMethods.Unspecialize(f));
          } else {
            thisDotF = new MemberBinding(
              new MemberBinding(new This(clTemplate), this.PointerToTopLevelClosureClass),
              f);
          }
          return new MethodCall(new MemberBinding(thisDotF, getItem), new ExpressionList(index));
          #endregion
          #endregion
        }
        #endregion
      } else {
        #region Not in closure ==> Create a local variable
        Local l = GetLocalForOldExpression(oldExpression);
        #region Make sure local can be seen in the debugger (for the entire method, unfortunately)
        if (currentMethod.LocalList == null) {
          currentMethod.LocalList = new LocalList();
        }
        currentMethod.LocalList.Add(l);
        currentMethod.Body.HasLocals = true;
        #endregion
        this.prestateValuesOfOldExpressions.Statements.Add(
          new AssignmentStatement(l, oldExpression.expression));

        // Return an expression that will evaluate in the poststate to the value of the old
        // expression in the prestate. When we're not in a closure, this is just the local
        // itself.
        return l;
        #endregion
      }
    }
Пример #10
0
    /// <summary>
    /// </summary>
    /// <param name="cons">Cloned</param>
    /// <returns></returns>
		public override Expression VisitConstruct(Construct cons)
		{
			ExpressionList operands = this.VisitExpressionList(cons.Operands);
			MemberBinding mb = this.VisitExpression(cons.Constructor) as MemberBinding;
      if (mb == null) return null;

			Debug.Assert(mb.TargetObject == null, "constructor target not null!");

			if ( this.expandAllocations ) 
			{
				// Now split the expression into 3:
				//  allocTemp = new T;
				//  allocTemp..ctor(args...);
				//  allocTemp

				// For value types, the construction is even more involved:
				//  valTemp = new VT;
				//  allocTemp = &valTemp;
				//  allocTemp..ctor(args...);
				//  valTemp

				if (mb.BoundMember != null && mb.BoundMember.DeclaringType != null && mb.BoundMember.DeclaringType.IsValueType) 
				{
					Variable valTemp = StackVariable.NEWValueTemp(mb.BoundMember.DeclaringType);

					Construct newcons = new Construct(new MemberBinding(null, mb.BoundMember), new ExpressionList(0), mb.BoundMember.DeclaringType);
					AssignmentStatement new_stat = new AssignmentStatement(valTemp, newcons);
					new_stat.SourceContext = this.current_source_context;
					new_stats.Add(new_stat);

          Variable allocTemp = StackVariable.NEWTemp(mb.BoundMember.DeclaringType);
          new_stats.Add(new AssignmentStatement(allocTemp, new UnaryExpression(valTemp, NodeType.AddressOf, mb.BoundMember.DeclaringType.GetReferenceType()), NodeType.Nop));
          mb.TargetObject = allocTemp;

					ExpressionStatement call_stat = new ExpressionStatement(new MethodCall(mb, operands, NodeType.Call, Cci.SystemTypes.Void));
					call_stat.SourceContext = this.current_source_context;
					new_stats.Add(call_stat);

					return valTemp;
				}
				else 
				{
					Variable vtemp = StackVariable.NEWTemp(mb.BoundMember.DeclaringType);

					Construct newcons = new Construct(new MemberBinding(null, mb.BoundMember), new ExpressionList(0), mb.BoundMember.DeclaringType);
					AssignmentStatement new_stat = new AssignmentStatement(vtemp, newcons);
					new_stat.SourceContext = this.current_source_context;
					new_stats.Add(new_stat);

					mb.TargetObject = vtemp;

					ExpressionStatement call_stat = new ExpressionStatement(new MethodCall(mb, operands, NodeType.Call, Cci.SystemTypes.Void));
					call_stat.SourceContext = this.current_source_context;
					new_stats.Add(call_stat);

					return vtemp;
				}
			}
			else 
			{
				Construct newcons = new Construct(mb, operands, mb.BoundMember.DeclaringType);
				newcons.SourceContext = this.current_source_context;

				return newcons;
			}
		}
Пример #11
0
		public override Statement VisitAssignmentStatement(AssignmentStatement assignment)
		{
      assignment = (AssignmentStatement)assignment.Clone();

			Expression target = assignment.Target;
			Expression source = assignment.Source;

      if (assignment.SourceContext.Document == null) {
        assignment.SourceContext = this.current_source_context;
      }

			if((target == null) || (source == null))
				throw new ApplicationException("Strange CCI format " + CodePrinter.StatementToString(assignment));

			switch(target.NodeType)
			{
				case NodeType.AddressDereference:
          assignment.Target = (Expression)this.Visit(target);
          if (source is Literal && ((Literal)source).Value == null && 
            ((assignment.Target.Type != null && assignment.Target.Type.IsValueType) || (assignment.Target.Type is TypeParameter) ||
              (assignment.Target.Type is ClassParameter)))
          {
              // initobj encoding.
              return assignment;
          }
          assignment.Source = simplify(source, true);
          return assignment;

				case NodeType.MemberBinding:
				case NodeType.Indexer:
					assignment.Target = (Expression)this.Visit(target);
					assignment.Source = simplify(source, true);
					return assignment;

				case NodeType.Local:
				case NodeType.Parameter:
					// target is a Variable; we can be more relaxed on the right side
					// Note: VS has a strange indentation for switch inside a switch ...
				switch(source.NodeType)
				{
						// (source is MethodCall) ||
					case NodeType.Call :
					case NodeType.Calli :
					case NodeType.Callvirt :
					case NodeType.Jmp :
					case NodeType.MethodCall :
						// (source is ArrayConstruct) ||
					case NodeType.ConstructArray:
						// (source is AddressDereference) ||
					case NodeType.AddressDereference:
						// (source is MemberBinding) ||
					case NodeType.MemberBinding:
						// (source is Indexer)
					case NodeType.Indexer:
						assignment.Source = (Expression)this.Visit(source);
						break;
					case NodeType.Literal:
						break;

					// (source is Construct)
					case NodeType.Construct:
					default:
						assignment.Source = simplify(source, true);
						break;
				}
					return assignment;

				default:
					throw new ApplicationException("Strange CCI format " + CodePrinter.StatementToString(assignment));
			}
		}
Пример #12
0
      // After they have been duplicated for each "leave" instruction, the "finally"
      // handlers are transformed into catch handlers that rethrow their exceptions.
      //
      public void ConvertFinallyHandlerIntoCatchHandler () {
        foreach (ExceptionHandler eh in this.allExceptionHandlers) {
          if (eh.HandlerType == NodeType.Finally ||
            eh.HandlerType == NodeType.FaultHandler) {
            // transform the finally / fault handler into a catch handler ...
            eh.HandlerType = NodeType.Catch;
            // ... that catches all exceptions ... (cont'd at alpha)
            // (btw: in MSIL, one can throw any object, including non-Exceptions)
            eh.FilterType = Cci.SystemTypes.Object;

            // variable to store the caught exception (we can't leave it on the stack because the
            // code of the original finally handler must start with an empty stack).
            Variable exceptionVariable = new Local(new Identifier(FINALLYVARPREFIX + (finally_var_count++)), eh.FilterType);

            // the new catch handler must start with FINALLYVARPREFIX<n> := EPOP ...
            Block firstBlock = eh.HandlerStartBlock;
            StatementList stats = firstBlock.Statements;
            StatementList newBlockStatements = new StatementList();

            AssignmentStatement exceptionAssignment = 
              new AssignmentStatement(exceptionVariable, new Expression(NodeType.Pop));
            if (stats.Count > 0) {
              exceptionAssignment.SourceContext = stats[0].SourceContext;
              exceptionAssignment.Source.SourceContext = stats[0].SourceContext;
            }
            newBlockStatements.Add(exceptionAssignment);

            for(int i = 0; i < stats.Count; i++) {
              newBlockStatements.Add(stats[i]);
            }
            firstBlock.Statements = newBlockStatements;

            // (alpha) ... and rethrows the exception.
            // replace the last instruction of eh with a throw exceptionVariable
            Block lastBlock = (Block) this.lastHandledBlock[eh];

            Statement lastStatement = lastBlock.Statements[lastBlock.Statements.Count - 1];
            if (lastStatement is EndFinally) {

              // replace the endfinally with a rethrow; this is OK because (re)throw flushes the stack too.
              Statement throwStatement;
              {
#if EXPLICIT_THROW_OF_CAPTURED_VARIABLE_RATHER_THAN_RETHROW_IN_FINALLY_EXPANDED_CATCH

						if (false) // for now
						{
							throwStatement = new Throw(exceptionVariable);
						}
						else
#endif
                throwStatement = new Throw(null);
                throwStatement.NodeType = NodeType.Rethrow;
              }
              throwStatement.SourceContext = lastBlock.Statements[lastBlock.Statements.Count - 1].SourceContext;
              lastBlock.Statements[lastBlock.Statements.Count - 1] = throwStatement;
            }
            else {
              Debug.Assert(lastStatement is Throw,
                "finally/fault not terminated in endfinally/endfault or throw! " +
                CodePrinter.StatementToString(lastBlock.Statements[lastBlock.Statements.Count - 1]));
            }
          }
        }
      }
Пример #13
0
        private static bool IsCoalescableAssignment(AssignmentStatement aStmt)
        {
            if (aStmt == null) return true;
            if (aStmt.Source == null || aStmt.Target == null)
                return false;

            if (aStmt.Source is MethodCall) return false;
            if ((ZingNodeType)aStmt.Source.NodeType == ZingNodeType.Choose)
                return false;
            return true;
        }
Пример #14
0
        public override Statement VisitAssignmentStatement(AssignmentStatement assignment)
        {
            if (assignment == null) return null;

            BasicBlock block = AddBlock(new BasicBlock(assignment, CurrentContinuation));
            CurrentContinuation = block;

            return assignment;
        }
Пример #15
0
 public override Statement VisitAssignmentStatement(AssignmentStatement assignment)
 {
     if (assignment == null) return null;
     return base.VisitAssignmentStatement((AssignmentStatement)assignment.Clone());
 }
        /// <summary>
        /// Have to special case assignment of "this" param into other local or closure this-field when we have call-site wrappers
        /// for constrained virtcalls. In this case, we have to insert a box.
        /// </summary>
        public override Statement VisitAssignmentStatement(AssignmentStatement assignment)
        {
            if (assignment == null) return null;

            var result = base.VisitAssignmentStatement(assignment);
                
            assignment = result as AssignmentStatement;
                
            if (assignment != null && assignment.Target != null && assignment.Target.Type is Interface)
            {
                if (assignment.Source != null & assignment.Source.Type is Reference)
                {
                    var refType = (Reference) assignment.Source.Type;
                    if (refType.ElementType is ITypeParameter)
                    {
                        // found a type mismatch
                        assignment.Source =
                            new BinaryExpression(
                                new AddressDereference(assignment.Source, refType.ElementType),
                                new Literal(refType.ElementType), NodeType.Box);
                    }
                }
            }

            return result;
        }
Пример #17
0
        private void AddContinueWithMethodToReturnBlock(Block returnBlock, Local taskBasedResult)
        {
            Contract.Requires(returnBlock != null);
            Contract.Requires(taskBasedResult != null);

            var taskType = taskBasedResult.Type;

            // To find appropriate ContinueWith method task type should be unwrapped
            var taskTemplate = HelperMethods.Unspecialize(taskType);

            var continueWithMethodLocal = GetContinueWithMethod(closureClass, taskTemplate, taskType);

            // TODO: not sure that this is possible situation when continueWith method is null. 
            // Maybe Contract.Assert(continueWithMethod != null) should be used instead!

            if (continueWithMethodLocal != null)
            {
                // We need to create delegate instance that should be passed to ContinueWith method
                var funcType = continueWithMethodLocal.Parameters[0].Type;
                var funcCtor = funcType.GetConstructor(SystemTypes.Object, SystemTypes.IntPtr);

                Contract.Assume(funcCtor != null);

                var funcLocal = new Local(funcCtor.DeclaringType);

                // Creating a method pointer to the AsyncClosure.CheckMethod
                // In this case we can't use checkMethod field.
                // Getting CheckMethod from clsoureClassInstance will provide correct (potentially updated)
                // generic arguments for enclosing type.
                var checkMethodFromClosureInstance = (Method) closureClassInstance.GetMembersNamed(CheckMethodId)[0];
                Contract.Assume(checkMethodFromClosureInstance != null);

                var ldftn = new UnaryExpression(
                    new MemberBinding(null, checkMethodFromClosureInstance),
                    NodeType.Ldftn,
                    CoreSystemTypes.IntPtr);

                // Creating delegate that would be used as a continuation for original task
                returnBlock.Statements.Add(
                    new AssignmentStatement(funcLocal,
                        new Construct(new MemberBinding(null, funcCtor),
                            new ExpressionList(closureLocal, ldftn))));

                // Wrapping continuation into TaskExtensions.Unwrap method
                // (this helps to preserve original exception and original result of the task,
                // but allows to throw postconditions violations).

                // Generating: result.ContinueWith(closure.CheckPost);
                var taskContinuationOption = new Literal(TaskContinuationOptions.ExecuteSynchronously);
                var continueWithCall =
                    new MethodCall(
                        new MemberBinding(taskBasedResult, continueWithMethodLocal),
                        new ExpressionList(funcLocal, taskContinuationOption));

                // Generating: TaskExtensions.Unwrap(result.ContinueWith(...))
                var unwrapMethod = GetUnwrapMethod(checkMethodTaskType);
                var unwrapCall =
                    new MethodCall(
                        new MemberBinding(null, unwrapMethod), new ExpressionList(continueWithCall));

                // Generating: result = Unwrap(...);
                var resultAssignment =
                    new AssignmentStatement(taskBasedResult, unwrapCall);
                returnBlock.Statements.Add(resultAssignment);
            }
        }
Пример #18
0
            public override void VisitAssignmentStatement(AssignmentStatement assignment)
            {
                Expression source = assignment.Source;
                Construct sourceConstruct = source as Construct;

                if (sourceConstruct != null)
                {
                    if (sourceConstruct.Type != null && sourceConstruct.Type.Name.Name.StartsWith(this.closureTag))
                    {
                        if (sourceConstruct.Type.Template != null)
                        {
                            TypeNode template = sourceConstruct.Type.Template;
                            while (template.Template != null)
                            {
                                template = template.Template;
                            }
                            this.closureClass = (Class) template;
                        }
                        else
                        {
                            this.closureClass = (Class) sourceConstruct.Type;
                        }

                        return;
                    }
                }

                if (IAsyncStateMachineType == null)
                {
                    return;
                }

                var mb = assignment.Target as MemberBinding;
                if (mb != null)
                {
                    var addrOf = mb.TargetObject as UnaryExpression;
                    if (addrOf != null && addrOf.NodeType == NodeType.AddressOf)
                    {
                        var loc = addrOf.Operand as Local;
                        if (loc != null)
                        {
                            var cand = loc.Type;
                            if (HelperMethods.IsCompilerGenerated(cand) && cand.IsAssignableTo(IAsyncStateMachineType))
                            {
                                this.closureClass = HelperMethods.Unspecialize(cand);
                            }
                        }
                    }
                }
            }
Пример #19
0
 public AssignmentExpression(AssignmentStatement assignment)
     : base(NodeType.AssignmentExpression)
 {
     this.AssignmentStatement = assignment;
 }
Пример #20
0
        private void GenerateMethodReturn(Block block, AssignmentStatement assignmentStatement, MethodCall call)
        {
            ZMethod method = (ZMethod)((MemberBinding)call.Callee).BoundMember;

            // Eventually, this will be checked by an earlier phase.
            Debug.Assert(method.Parameters.Count == call.Operands.Count);

            // process output parameters and the return value;
            for (int i = 0, n = call.Operands.Count; i < n; i++)
            {
                Parameter param = method.Parameters[i];
                if ((param.Flags & ParameterFlags.Out) != 0 && call.Operands[i] != null && method.Parameters[i] != null)
                {
                    Statement assignOutParam = Templates.GetStatementTemplate("FetchOutputParameter");
                    Replacer.Replace(assignOutParam, "_dest",
                        this.VisitExpression(((UnaryExpression)call.Operands[i]).Operand));
                    Replacer.Replace(assignOutParam, "_paramName", new Identifier("_Lfc_" + method.Parameters[i].Name.Name));
                    Replacer.Replace(assignOutParam, "_Callee", method.Name);
                    Replacer.Replace(assignOutParam, "_CalleeClass", method.DeclaringType.Name);
                    block.Statements.Add(assignOutParam);
                }
            }

            if (assignmentStatement != null)
            {
                Statement assignReturnValue = Templates.GetStatementTemplate("FetchReturnValue");
                Replacer.Replace(assignReturnValue, "_dest", this.VisitExpression(assignmentStatement.Target));
                Replacer.Replace(assignReturnValue, "_CalleeClass", method.DeclaringType.Name);
                Replacer.Replace(assignReturnValue, "_Callee", method.Name);

                block.Statements.Add(assignReturnValue);
            }

            Statement stmt = Templates.GetStatementTemplate("InvalidateLastFunctionCompleted");
            block.Statements.Add(stmt);
        }
Пример #21
0
 private Expression ParseAssignmentExpression(Expression operand1, TokenSet followers){
   Debug.Assert(Parser.InfixOperators[this.currentToken]);
   Debug.Assert(this.currentToken != Token.Conditional);
   switch (this.currentToken){
     case Token.AddAssign:
     case Token.Assign:
     case Token.BitwiseAndAssign:
     case Token.BitwiseOrAssign:
     case Token.BitwiseXorAssign:
     case Token.DivideAssign:
     case Token.LeftShiftAssign:
     case Token.MultiplyAssign:
     case Token.RemainderAssign:
     case Token.RightShiftAssign:
     case Token.SubtractAssign:
       Token assignmentOperator = this.currentToken;
       this.GetNextToken();
       Expression operand2 = this.ParseExpression(followers);
       if (operand1 == null || operand2 == null) return null;
       AssignmentStatement statement = new AssignmentStatement(operand1, operand2, Parser.ConvertToBinaryNodeType(assignmentOperator));
       statement.SourceContext = operand1.SourceContext;
       statement.SourceContext.EndPos = operand2.SourceContext.EndPos;
       Expression expression = new AssignmentExpression(statement);
       expression.SourceContext = statement.SourceContext;
       return expression;
     default:
       operand1 = this.ParseBinaryExpression(operand1, followers|Token.Conditional);
       if (operand1 != null && this.currentToken == Token.Conditional)
         return this.ParseConditional(operand1, followers);
       return operand1;
   }
 }
Пример #22
0
    private bool ParseStatement(Block/*!*/ block) {
      //parse instructions and put in expression tree until an assignment, void call, branch target, or branch is encountered
      StatementList statementList = block.Statements;
      Expression expr = null;
      Statement statement = null;
      bool transferStatement = false;
      int startingAddress = 0;
#if !FxCop
      SourceContext sourceContext = new SourceContext();
      sourceContext.StartPos = this.counter;
#endif
#if !ROTOR
      if (this.method.contextForOffset != null){
        object sctx = this.method.contextForOffset[this.counter+1];
        if (sctx != null) sourceContext = (SourceContext)sctx;
      }
#endif
      while (true){
        bool isStatement = false;
        startingAddress = this.counter+1; //Add one so that it is never zero (the latter means no entry to the TrivialHashtable)
#if FxCop || ILOFFSETS
        this.ilOffset = this.counter;
        this.opCode = this.GetOpCode();
#else
        OpCode opCode = this.GetOpCode();
#endif
#if FxCop
        if (this.handlerMap.TryGetValue(this.ilOffset, out expr)){
          expr.sourceContext = sourceContext;
          expr.ILOffset = this.ilOffset;
          this.operandStack.Push(expr);
        }
#endif
        switch (opCode){
          case OpCode.Nop: statement = new Statement(NodeType.Nop); goto done;
          case OpCode.Break: statement = new Statement(NodeType.DebugBreak); goto done;
          case OpCode.Ldarg_0: expr = this.Parameters(0); break;
          case OpCode.Ldarg_1: expr = this.Parameters(1); break;
          case OpCode.Ldarg_2: expr = this.Parameters(2); break;
          case OpCode.Ldarg_3: expr = this.Parameters(3); break;
          case OpCode.Ldloc_0: expr = this.locals[0]; break;
          case OpCode.Ldloc_1: expr = this.locals[1]; break;
          case OpCode.Ldloc_2: expr = this.locals[2]; break;
          case OpCode.Ldloc_3: expr = this.locals[3]; break;
          case OpCode.Stloc_0: statement = new AssignmentStatement(this.locals[0], PopOperand()); goto done;
          case OpCode.Stloc_1: statement = new AssignmentStatement(this.locals[1], PopOperand()); goto done;
          case OpCode.Stloc_2: statement = new AssignmentStatement(this.locals[2], PopOperand()); goto done;
          case OpCode.Stloc_3: statement = new AssignmentStatement(this.locals[3], PopOperand()); goto done;
          case OpCode.Ldarg_S: expr = this.Parameters(this.GetByte()); break;
          case OpCode.Ldarga_S: expr = SetType(new UnaryExpression(this.Parameters(this.GetByte()), NodeType.AddressOf)); break;
          case OpCode.Starg_S: statement = new AssignmentStatement(this.Parameters(this.GetByte()), PopOperand()); goto done;
          case OpCode.Ldloc_S: expr = this.locals[this.GetByte()]; break;
          case OpCode.Ldloca_S: expr = SetType(new UnaryExpression(this.locals[this.GetByte()], NodeType.AddressOf)); break;
          case OpCode.Stloc_S: statement = new AssignmentStatement(this.locals[this.GetByte()], PopOperand()); goto done;
          case OpCode.Ldnull: expr = new Literal(null, CoreSystemTypes.Object); break;
          case OpCode.Ldc_I4_M1: expr = new Literal(-1, CoreSystemTypes.Int32); break;
          case OpCode.Ldc_I4_0: expr = new Literal(0, CoreSystemTypes.Int32); break;
          case OpCode.Ldc_I4_1: expr = new Literal(1, CoreSystemTypes.Int32); break;
          case OpCode.Ldc_I4_2: expr = new Literal(2, CoreSystemTypes.Int32); break;
          case OpCode.Ldc_I4_3: expr = new Literal(3, CoreSystemTypes.Int32); break;
          case OpCode.Ldc_I4_4: expr = new Literal(4, CoreSystemTypes.Int32); break;
          case OpCode.Ldc_I4_5: expr = new Literal(5, CoreSystemTypes.Int32); break;
          case OpCode.Ldc_I4_6: expr = new Literal(6, CoreSystemTypes.Int32); break;
          case OpCode.Ldc_I4_7: expr = new Literal(7, CoreSystemTypes.Int32); break;
          case OpCode.Ldc_I4_8: expr = new Literal(8, CoreSystemTypes.Int32); break;
          case OpCode.Ldc_I4_S: expr = new Literal((int)this.GetSByte(), CoreSystemTypes.Int32); break;
          case OpCode.Ldc_I4: expr = new Literal(this.GetInt32(), CoreSystemTypes.Int32); break;
          case OpCode.Ldc_I8: expr = new Literal(this.GetInt64(), CoreSystemTypes.Int64); break;
          case OpCode.Ldc_R4: expr = new Literal(this.GetSingle(), CoreSystemTypes.Single); break;
          case OpCode.Ldc_R8: expr = new Literal(this.GetDouble(), CoreSystemTypes.Double); break;
          case OpCode.Dup: statement = new ExpressionStatement(new Expression(NodeType.Dup)); goto done;
          case OpCode.Pop: statement = new ExpressionStatement(new UnaryExpression(PopOperand(), NodeType.Pop)); goto done;
          case OpCode.Jmp: expr = this.ParseCall(NodeType.Jmp, out isStatement); if (isStatement) goto done; break;
          case OpCode.Call: expr = this.ParseCall(NodeType.Call, out isStatement); if (isStatement) goto done; break;
          case OpCode.Calli: expr = this.ParseCalli(out isStatement); if (isStatement) goto done; break;
          case OpCode.Ret:
            Expression retVal = BodyParser.TypeIsVoid(this.method.ReturnType) ? null : PopOperand();
            statement = new Return(retVal); 
            transferStatement = true; goto done;
          case OpCode.Br_S: statement = this.ParseBranch(NodeType.Nop, 0, true, false); transferStatement = true; goto done;
          case OpCode.Brfalse_S: statement = this.ParseBranch(NodeType.LogicalNot, 1, true, false); transferStatement = true; goto done;
          case OpCode.Brtrue_S: statement = this.ParseBranch(NodeType.Nop, 1, true, false); transferStatement = true; goto done;
          case OpCode.Beq_S: statement = this.ParseBranch(NodeType.Eq, 2, true, false); transferStatement = true; goto done;
          case OpCode.Bge_S: statement = this.ParseBranch(NodeType.Ge, 2, true, false); transferStatement = true; goto done;
          case OpCode.Bgt_S: statement = this.ParseBranch(NodeType.Gt, 2, true, false); transferStatement = true; goto done;
          case OpCode.Ble_S: statement = this.ParseBranch(NodeType.Le, 2, true, false); transferStatement = true; goto done;
          case OpCode.Blt_S: statement = this.ParseBranch(NodeType.Lt, 2, true, false); transferStatement = true; goto done;
          case OpCode.Bne_Un_S: statement = this.ParseBranch(NodeType.Ne, 2, true, true); transferStatement = true; goto done;
          case OpCode.Bge_Un_S: statement = this.ParseBranch(NodeType.Ge, 2, true, true); transferStatement = true; goto done;
          case OpCode.Bgt_Un_S: statement = this.ParseBranch(NodeType.Gt, 2, true, true); transferStatement = true; goto done;
          case OpCode.Ble_Un_S: statement = this.ParseBranch(NodeType.Le, 2, true, true); transferStatement = true; goto done;
          case OpCode.Blt_Un_S: statement = this.ParseBranch(NodeType.Lt, 2, true, true); transferStatement = true; goto done;
          case OpCode.Br: statement = this.ParseBranch(NodeType.Nop, 0, false, false); transferStatement = true; goto done;
          case OpCode.Brfalse: statement = this.ParseBranch(NodeType.LogicalNot, 1, false, false); transferStatement = true; goto done;
          case OpCode.Brtrue: statement = this.ParseBranch(NodeType.Nop, 1, false, false); transferStatement = true; goto done;
          case OpCode.Beq: statement = this.ParseBranch(NodeType.Eq, 2, false, false); transferStatement = true; goto done;
          case OpCode.Bge: statement = this.ParseBranch(NodeType.Ge, 2, false, false); transferStatement = true; goto done;
          case OpCode.Bgt: statement = this.ParseBranch(NodeType.Gt, 2, false, false); transferStatement = true; goto done;
          case OpCode.Ble: statement = this.ParseBranch(NodeType.Le, 2, false, false); transferStatement = true; goto done;
          case OpCode.Blt: statement = this.ParseBranch(NodeType.Lt, 2, false, false); transferStatement = true; goto done;
          case OpCode.Bne_Un: statement = this.ParseBranch(NodeType.Ne, 2, false, true); transferStatement = true; goto done;
          case OpCode.Bge_Un: statement = this.ParseBranch(NodeType.Ge, 2, false, true); transferStatement = true; goto done;
          case OpCode.Bgt_Un: statement = this.ParseBranch(NodeType.Gt, 2, false, true); transferStatement = true; goto done;
          case OpCode.Ble_Un: statement = this.ParseBranch(NodeType.Le, 2, false, true); transferStatement = true; goto done;
          case OpCode.Blt_Un: statement = this.ParseBranch(NodeType.Lt, 2, false, true); transferStatement = true; goto done;
          case OpCode.Switch: statement = this.ParseSwitchInstruction(); transferStatement = true; goto done;
          case OpCode.Ldind_I1: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Int8, this.isVolatile, this.alignment); break;
          case OpCode.Ldind_U1: expr = new AddressDereference(PopOperand(), CoreSystemTypes.UInt8, this.isVolatile, this.alignment); break;
          case OpCode.Ldind_I2: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Int16, this.isVolatile, this.alignment); break;
          case OpCode.Ldind_U2: expr = new AddressDereference(PopOperand(), CoreSystemTypes.UInt16, this.isVolatile, this.alignment); break;
          case OpCode.Ldind_I4: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Int32, this.isVolatile, this.alignment); break;
          case OpCode.Ldind_U4: expr = new AddressDereference(PopOperand(), CoreSystemTypes.UInt32, this.isVolatile, this.alignment); break;
          case OpCode.Ldind_I8: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Int64, this.isVolatile, this.alignment); break;
          case OpCode.Ldind_I: expr = new AddressDereference(PopOperand(), CoreSystemTypes.IntPtr, this.isVolatile, this.alignment); break;
          case OpCode.Ldind_R4: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Single, this.isVolatile, this.alignment); break;
          case OpCode.Ldind_R8: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Double, this.isVolatile, this.alignment); break;
          case OpCode.Ldind_Ref: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Object, this.isVolatile, this.alignment); break;
          case OpCode.Stind_Ref: statement = this.ParseStoreIndirect(CoreSystemTypes.Object); goto done;
          case OpCode.Stind_I1: statement = this.ParseStoreIndirect(CoreSystemTypes.Int8); goto done;
          case OpCode.Stind_I2: statement = this.ParseStoreIndirect(CoreSystemTypes.Int16); goto done;
          case OpCode.Stind_I4: statement = this.ParseStoreIndirect(CoreSystemTypes.Int32); goto done;
          case OpCode.Stind_I8: statement = this.ParseStoreIndirect(CoreSystemTypes.Int64); goto done;
          case OpCode.Stind_R4: statement = this.ParseStoreIndirect(CoreSystemTypes.Single); goto done;
          case OpCode.Stind_R8: statement = this.ParseStoreIndirect(CoreSystemTypes.Double); goto done;
          case OpCode.Add: expr = this.ParseBinaryOperation(NodeType.Add); break;
          case OpCode.Sub: expr = this.ParseBinaryOperation(NodeType.Sub); break;
          case OpCode.Mul: expr = this.ParseBinaryOperation(NodeType.Mul); break;
          case OpCode.Div: expr = this.ParseBinaryOperation(NodeType.Div); break;
          case OpCode.Div_Un: expr = this.ParseBinaryOperation(NodeType.Div_Un); break;
          case OpCode.Rem: expr = this.ParseBinaryOperation(NodeType.Rem); break;
          case OpCode.Rem_Un: expr = this.ParseBinaryOperation(NodeType.Rem_Un); break;
          case OpCode.And: expr = this.ParseBinaryOperation(NodeType.And); break;
          case OpCode.Or: expr = this.ParseBinaryOperation(NodeType.Or); break;
          case OpCode.Xor: expr = this.ParseBinaryOperation(NodeType.Xor); break;
          case OpCode.Shl: expr = this.ParseBinaryOperation(NodeType.Shl); break;
          case OpCode.Shr: expr = this.ParseBinaryOperation(NodeType.Shr); break;
          case OpCode.Shr_Un: expr = this.ParseBinaryOperation(NodeType.Shr_Un); break;
          case OpCode.Neg: expr = this.ParseUnaryOperation(NodeType.Neg); break;
          case OpCode.Not: expr = this.ParseUnaryOperation(NodeType.Not); break;
          case OpCode.Conv_I1: expr = new UnaryExpression(PopOperand(), NodeType.Conv_I1, CoreSystemTypes.Int8); break;
          case OpCode.Conv_I2: expr = new UnaryExpression(PopOperand(), NodeType.Conv_I2, CoreSystemTypes.Int16); break;
          case OpCode.Conv_I4: expr = new UnaryExpression(PopOperand(), NodeType.Conv_I4, CoreSystemTypes.Int32); break;
          case OpCode.Conv_I8: expr = new UnaryExpression(PopOperand(), NodeType.Conv_I8, CoreSystemTypes.Int64); break;
          case OpCode.Conv_R4: expr = new UnaryExpression(PopOperand(), NodeType.Conv_R4, CoreSystemTypes.Single); break;
          case OpCode.Conv_R8: expr = new UnaryExpression(PopOperand(), NodeType.Conv_R8, CoreSystemTypes.Double); break;
          case OpCode.Conv_U4: expr = new UnaryExpression(PopOperand(), NodeType.Conv_U4, CoreSystemTypes.UInt32); break;
          case OpCode.Conv_U8: expr = new UnaryExpression(PopOperand(), NodeType.Conv_U8, CoreSystemTypes.UInt64); break;
          case OpCode.Callvirt: expr = this.ParseCall(NodeType.Callvirt, out isStatement); if (isStatement) goto done; break;
          case OpCode.Cpobj: statement = this.ParseCopyObject(); goto done;
          case OpCode.Ldobj: expr = new AddressDereference(PopOperand(), (TypeNode)this.GetMemberFromToken(), this.isVolatile, this.alignment); break;
          case OpCode.Ldstr: expr = new Literal(this.GetStringFromToken(), CoreSystemTypes.String); break;
          case OpCode.Newobj: expr = this.ParseConstruct(); break;
          case OpCode.Castclass: expr = ParseTypeCheck(PopOperand(), (TypeNode)this.GetMemberFromToken(), NodeType.Castclass); break;
          case OpCode.Isinst: expr = ParseTypeCheck(PopOperand(), (TypeNode)this.GetMemberFromToken(), NodeType.Isinst); break;
          case OpCode.Conv_R_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_R_Un, CoreSystemTypes.Double); break;
          case OpCode.Unbox: expr = ParseTypeCheck(PopOperand(), (TypeNode)this.GetMemberFromToken(), NodeType.Unbox); break;
          case OpCode.Throw: statement = new Throw(PopOperand()); transferStatement = true; goto done;
          case OpCode.Ldfld: 
            expr = new MemberBinding(PopOperand(), this.GetMemberFromToken(), this.isVolatile, this.alignment);
            break;
          case OpCode.Ldflda: 
            expr = SetType(new UnaryExpression(new MemberBinding(PopOperand(), this.GetMemberFromToken(), this.isVolatile, this.alignment), NodeType.AddressOf)); 
            break;
          case OpCode.Stfld: statement = this.ParseStoreField(); goto done;
          case OpCode.Ldsfld: expr = new MemberBinding(null, this.GetMemberFromToken(), this.isVolatile, this.alignment); break;
          case OpCode.Ldsflda: expr = SetType(new UnaryExpression(new MemberBinding(null, this.GetMemberFromToken(), this.isVolatile, this.alignment), NodeType.AddressOf)); break;
          case OpCode.Stsfld: statement = new AssignmentStatement(new MemberBinding(null, this.GetMemberFromToken(), this.isVolatile, this.alignment), PopOperand()); goto done;
          case OpCode.Stobj: statement = this.ParseStoreIndirect((TypeNode)this.GetMemberFromToken()); goto done;
          case OpCode.Conv_Ovf_I1_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I1_Un, CoreSystemTypes.Int8); break;
          case OpCode.Conv_Ovf_I2_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I2_Un, CoreSystemTypes.Int16); break;
          case OpCode.Conv_Ovf_I4_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I4_Un, CoreSystemTypes.Int32); break;
          case OpCode.Conv_Ovf_I8_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I8_Un, CoreSystemTypes.Int64); break;
          case OpCode.Conv_Ovf_U1_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U1_Un, CoreSystemTypes.UInt8); break;
          case OpCode.Conv_Ovf_U2_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U2_Un, CoreSystemTypes.UInt16); break;
          case OpCode.Conv_Ovf_U4_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U4_Un, CoreSystemTypes.UInt32); break;
          case OpCode.Conv_Ovf_U8_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U8_Un, CoreSystemTypes.UInt64); break;
          case OpCode.Conv_Ovf_I_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I_Un, CoreSystemTypes.IntPtr); break;
          case OpCode.Conv_Ovf_U_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U_Un, CoreSystemTypes.UIntPtr); break;
          case OpCode.Box: 
            TypeNode t = (TypeNode)this.GetMemberFromToken();
            TypeNode bt = t is EnumNode ? CoreSystemTypes.Enum : CoreSystemTypes.ValueType;
            expr = new BinaryExpression(PopOperand(), new Literal(t, CoreSystemTypes.Type), NodeType.Box, bt); break;
          case OpCode.Newarr: expr = this.ParseNewArray(); break;
          case OpCode.Ldlen: expr = new UnaryExpression(PopOperand(), NodeType.Ldlen, CoreSystemTypes.UIntPtr); break;
          case OpCode.Ldelema: expr = this.ParseArrayElementLoadAddress(); break;
          case OpCode.Ldelem_I1: 
          case OpCode.Ldelem_U1: 
          case OpCode.Ldelem_I2: 
          case OpCode.Ldelem_U2: 
          case OpCode.Ldelem_I4: 
          case OpCode.Ldelem_U4: 
          case OpCode.Ldelem_I8: 
          case OpCode.Ldelem_I: 
          case OpCode.Ldelem_R4: 
          case OpCode.Ldelem_R8: 
          case OpCode.Ldelem_Ref: expr = this.ParseArrayElementLoad(opCode, null); break;
          case OpCode.Stelem_I:
          case OpCode.Stelem_I1:
          case OpCode.Stelem_I2:
          case OpCode.Stelem_I4:
          case OpCode.Stelem_I8:
          case OpCode.Stelem_R4:
          case OpCode.Stelem_R8:
          case OpCode.Stelem_Ref: statement = this.ParseArrayElementAssignment(opCode); goto done;
          case OpCode.Ldelem: expr = this.ParseArrayElementLoad(opCode, null); break;
          case OpCode.Stelem: statement = this.ParseArrayElementAssignment(opCode); goto done;
          case OpCode.Unbox_Any: expr = ParseTypeCheck(PopOperand(), (TypeNode)this.GetMemberFromToken(), NodeType.UnboxAny); break;
          case OpCode.Conv_Ovf_I1: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I1, CoreSystemTypes.Int8); break;
          case OpCode.Conv_Ovf_U1: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U1, CoreSystemTypes.UInt8); break;
          case OpCode.Conv_Ovf_I2: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I2, CoreSystemTypes.Int16); break;
          case OpCode.Conv_Ovf_U2: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U2, CoreSystemTypes.UInt16); break;
          case OpCode.Conv_Ovf_I4: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I4, CoreSystemTypes.Int32); break;
          case OpCode.Conv_Ovf_U4: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U4, CoreSystemTypes.UInt32); break;
          case OpCode.Conv_Ovf_I8: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I8, CoreSystemTypes.Int64); break;
          case OpCode.Conv_Ovf_U8: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U8, CoreSystemTypes.UInt64); break;
          case OpCode.Refanyval: expr = new BinaryExpression(PopOperand(), new Literal(this.GetMemberFromToken(), CoreSystemTypes.Type), NodeType.Refanyval, CoreSystemTypes.IntPtr); break;
          case OpCode.Ckfinite: expr = this.ParseUnaryOperation(NodeType.Ckfinite); break;
          case OpCode.Mkrefany: expr = new BinaryExpression(PopOperand(), new Literal(this.GetMemberFromToken(), CoreSystemTypes.Type), NodeType.Mkrefany, CoreSystemTypes.DynamicallyTypedReference); break;
          case OpCode.Ldtoken: expr = ParseLoadRuntimeMetadataToken(); break;
          case OpCode.Conv_U2: expr = new UnaryExpression(PopOperand(), NodeType.Conv_U2, CoreSystemTypes.UInt16); break;
          case OpCode.Conv_U1: expr = new UnaryExpression(PopOperand(), NodeType.Conv_U1, CoreSystemTypes.UInt8); break;
          case OpCode.Conv_I: expr = new UnaryExpression(PopOperand(), NodeType.Conv_I, CoreSystemTypes.IntPtr); break;
          case OpCode.Conv_Ovf_I: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I, CoreSystemTypes.IntPtr); break;
          case OpCode.Conv_Ovf_U: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U, CoreSystemTypes.UIntPtr); break;
          case OpCode.Add_Ovf: expr = this.ParseBinaryOperation(NodeType.Add_Ovf); break;
          case OpCode.Add_Ovf_Un: expr = this.ParseBinaryOperation(NodeType.Add_Ovf_Un); break;
          case OpCode.Mul_Ovf: expr = this.ParseBinaryOperation(NodeType.Mul_Ovf); break;
          case OpCode.Mul_Ovf_Un: expr = this.ParseBinaryOperation(NodeType.Mul_Ovf_Un); break;
          case OpCode.Sub_Ovf: expr = this.ParseBinaryOperation(NodeType.Sub_Ovf); break;
          case OpCode.Sub_Ovf_Un: expr = this.ParseBinaryOperation(NodeType.Sub_Ovf_Un); break;
          case OpCode.Endfinally: statement = new EndFinally(); transferStatement = true; goto done;
          case OpCode.Leave: statement = this.ParseBranch(NodeType.Nop, 0, false, false, true); transferStatement = true; goto done;
          case OpCode.Leave_S: statement = this.ParseBranch(NodeType.Nop, 0, true, false, true); transferStatement = true; goto done;
          case OpCode.Stind_I: statement = this.ParseStoreIndirect(CoreSystemTypes.IntPtr); goto done;
          case OpCode.Conv_U: expr = new UnaryExpression(PopOperand(), NodeType.Conv_U, CoreSystemTypes.UIntPtr); break;
          case OpCode.Arglist: expr = new Expression(NodeType.Arglist, CoreSystemTypes.ArgIterator); break;
          case OpCode.Ceq: expr = this.ParseBinaryComparison(NodeType.Ceq); break;
          case OpCode.Cgt: expr = this.ParseBinaryComparison(NodeType.Cgt); break;
          case OpCode.Cgt_Un: expr = this.ParseBinaryComparison(NodeType.Cgt_Un); break;
          case OpCode.Clt: expr = this.ParseBinaryComparison(NodeType.Clt); break;
          case OpCode.Clt_Un: expr = this.ParseBinaryComparison(NodeType.Clt_Un); break;
          case OpCode.Ldftn: expr = new UnaryExpression(new MemberBinding(null, this.GetMemberFromToken()), NodeType.Ldftn, CoreSystemTypes.IntPtr); break;
          case OpCode.Ldvirtftn: expr = new BinaryExpression(PopOperand(), new MemberBinding(null, this.GetMemberFromToken()), NodeType.Ldvirtftn, CoreSystemTypes.IntPtr); break;
          case OpCode.Ldarg: expr = this.Parameters((ushort)this.GetInt16()); break;
          case OpCode.Ldarga: expr = SetType(new UnaryExpression(this.Parameters((ushort)this.GetInt16()), NodeType.AddressOf)); break;
          case OpCode.Starg: statement = new AssignmentStatement(this.Parameters((ushort)this.GetInt16()), PopOperand()); goto done;
          case OpCode.Ldloc: expr = this.locals[(ushort)this.GetInt16()]; break;
          case OpCode.Ldloca: expr = SetType(new UnaryExpression(this.locals[(ushort)this.GetInt16()], NodeType.AddressOf)); break;
          case OpCode.Stloc: statement = new AssignmentStatement(this.locals[(ushort)this.GetInt16()], PopOperand()); goto done;
          case OpCode.Localloc: expr = new UnaryExpression(PopOperand(), NodeType.Localloc, CoreSystemTypes.Void); break;
          case OpCode.Endfilter: statement = new EndFilter(PopOperand()); transferStatement = true; goto done;
          case OpCode.Unaligned_: this.alignment = this.GetByte(); continue;
          case OpCode.Volatile_: this.isVolatile = true; continue;
          case OpCode.Tail_: this.isTailCall = true; continue;
          case OpCode.Initobj: statement = this.ParseInitObject(); goto done;
          case OpCode.Constrained_: this.constraint = this.GetMemberFromToken() as TypeNode; continue;
          case OpCode.Cpblk: expr = this.ParseTernaryOperation(NodeType.Cpblk); goto done;
          case OpCode.Initblk: expr = this.ParseTernaryOperation(NodeType.Initblk); goto done;
          case OpCode.Rethrow: statement = new Throw(null); statement.NodeType = NodeType.Rethrow; transferStatement = true; goto done;
          case OpCode.Sizeof: expr = new UnaryExpression(new Literal(this.GetMemberFromToken(), CoreSystemTypes.Type), NodeType.Sizeof, CoreSystemTypes.Int32); break;
          case OpCode.Refanytype: expr = new UnaryExpression(PopOperand(), NodeType.Refanytype, CoreSystemTypes.RuntimeTypeHandle); break;
          case OpCode.Readonly_: this.isReadOnly = true; continue;
          default: throw new InvalidMetadataException(ExceptionStrings.UnknownOpCode);
        }
        if (this.blockMap[this.counter+1] != null){
          transferStatement = true; //Falls through to the next basic block, so implicitly a "transfer" statement
          goto done;
        }
        //^ assume expr != null;
#if FxCop
        expr.sourceContext = sourceContext;
#endif
#if FxCop || ILOFFSETS
        expr.ILOffset = this.ilOffset;
#endif
        this.operandStack.Push(expr);
        this.isReadOnly = false;
        this.isVolatile = false;
        this.isTailCall = false;        
        this.alignment = -1;
      }
    done:
      for (int i = 0; i <= this.operandStack.top; i++){
        Expression e = this.operandStack.elements[i];
        //^ assume e != null;
        Statement s = new ExpressionStatement(e);
#if FxCop
        s.SourceContext = this.sourceContext;
#endif
#if FxCop || ILOFFSETS
        s.ILOffset = this.ilOffset;
#endif
        statementList.Add(s);
      }
      this.operandStack.top = -1;
      if (statement == null) {
        statement = new ExpressionStatement(expr);
#if FxCop
        expr.sourceContext = this.sourceContext;
#endif
#if FxCop || ILOFFSETS
        expr.ILOffset = this.ilOffset;
#endif
      }
      statement.SourceContext = sourceContext;
#if FxCop || ILOFFSETS
      statement.ILOffset = this.ilOffset;
#endif
#if ILOFFSETS
      this.lastSourceContext = sourceContext;
#endif
      statementList.Add(statement);
      if (transferStatement) return true;
      return this.blockMap[this.counter+1] != null;
    }
        public override void VisitAssignmentStatement(AssignmentStatement assignment)
        {
            if (assignment == null) return;

            Construct cons = assignment.Source as Construct;
            if (cons == null) goto JustVisit;
                
            if (!(cons.Type.IsDelegateType())) goto JustVisit;
                
            UnaryExpression ue = cons.Operands[1] as UnaryExpression;
            if (ue == null) goto JustVisit;
                
            MemberBinding mb = ue.Operand as MemberBinding;
            if (mb == null) goto JustVisit;
                
            Method m = mb.BoundMember as Method;

            if (m.IsStatic)
            {
                mb = assignment.Target as MemberBinding;
                if (mb == null) goto JustVisit;

                if (mb.TargetObject != null) goto JustVisit;
                    
                // Record the static cache field used to hold the static closure
                MembersToDuplicate.Add(mb.BoundMember);

                goto End;
            }

            JustVisit:
            if (assignment.Source == null) goto JustVisit2;
                
            if (assignment.Source.NodeType != NodeType.Pop) goto JustVisit2;
                
            mb = assignment.Target as MemberBinding;
                
            if (mb == null) goto JustVisit2;
                
            if (mb.TargetObject != null) goto JustVisit2;
                
            if (mb.BoundMember == null) goto JustVisit2;
                
            if (HelperMethods.Unspecialize(mb.BoundMember.DeclaringType) != this.containingType) goto JustVisit2;
                
            MembersToDuplicate.Add(mb.BoundMember);

            JustVisit2:
            ;

            End:
            base.VisitAssignmentStatement(assignment);
        }
Пример #24
0
 public override Statement VisitAssignmentStatement(AssignmentStatement assignment)
 {
     Statement result = base.VisitAssignmentStatement(assignment);
     return result;
 }
            /// <summary>
            /// Verifies that assignment statements are pure.
            /// </summary>
            /// <param name="assignment">Assignment to inspect.</param>
            /// <returns><paramref name="assignment"/></returns>
            public override void VisitAssignmentStatement(AssignmentStatement assignment)
            {
                // F: Should it be a Precondition?
                Contract.Assume(assignment != null);

                // Skip compiler-generated code.
                // Since we only visit contract regions, any assignment to state is not allowed.
                bool targetIsLocal = false;
                
                if (assignment.Target is Local) targetIsLocal = true;
                
                Indexer idxr = assignment.Target as Indexer;

                // Roslyn compiler introduced new pattern: in the expression tree there is an assignment
                // from local variable that holds expression to the array. But unlike old compiler
                // Roslyn is not introducing local variable for holding an array.
                // Instead of that it uses "dup" instruction and assignes parameter expression
                // directly to the stack slot.
                // This change should be addressed here, because otherwise ccrewrite will fail
                // with an error.
                if (idxr != null && (idxr.Object is Local || ExpressionTreeInitialization(assignment)))
                    targetIsLocal = true;
                
                // Assignments to locals that are structs show up as address deference
                AddressDereference addressDereference = assignment.Target as AddressDereference;
                if (addressDereference != null)
                {
                    UnaryExpression ue = addressDereference.Address as UnaryExpression;
                    if (ue != null)
                    {
                        // F: no idea why this is != null
                        Contract.Assume(assignment.Target.Type != null);

                        if (ue.Operand is Local &&
                            (assignment.Target.Type.IsPrimitive || assignment.Target.Type.IsStructural || assignment.Target.Type.IsTypeArgument ||
                             assignment.Target.Type is Struct || assignment.Target.Type is EnumNode))
                        {
                            targetIsLocal = true;
                        }
                    }
                }

                if (!IsAnonymousDelegateConstruction(assignment) && !targetIsLocal)
                {
                    this.assignmentFound = true;
                    //this.errorHandler(new Error("Detected assignment in a pure region in method '"
                    //  + this.currentMethod.FullName + "'.", assignment.SourceContext));
                }

                base.VisitAssignmentStatement(assignment);
            }
Пример #26
0
            /// <summary>
            /// Verifies that assignment statements are pure.
            /// </summary>
            /// <param name="assignment">Assignment to inspect.</param>
            /// <returns><paramref name="assignment"/></returns>
            public override void VisitAssignmentStatement(AssignmentStatement assignment)
            {
                // F: Should it be a Precondition?
                Contract.Assume(assignment != null);

                // Skip compiler-generated code.
                // Since we only visit contract regions, any assignment to state is not allowed.
                bool targetIsLocal = false;
                
                if (assignment.Target is Local) targetIsLocal = true;
                
                Indexer idxr = assignment.Target as Indexer;
                if (idxr != null && idxr.Object is Local)
                    targetIsLocal = true;
                
                // Assignments to locals that are structs show up as address deference
                AddressDereference addressDereference = assignment.Target as AddressDereference;
                if (addressDereference != null)
                {
                    UnaryExpression ue = addressDereference.Address as UnaryExpression;
                    if (ue != null)
                    {
                        // F: no idea why this is != null
                        Contract.Assume(assignment.Target.Type != null);
                        if (ue.Operand is Local &&
                            (assignment.Target.Type.IsPrimitive || assignment.Target.Type is Struct ||
                             assignment.Target.Type.IsStructural))
                        {
                            targetIsLocal = true;
                        }
                    }
                }

                if (!IsAnonymousDelegateConstruction(assignment) && !targetIsLocal)
                {
                    this.assignmentFound = true;
                    //this.errorHandler(new Error("Detected assignment in a pure region in method '"
                    //  + this.currentMethod.FullName + "'.", assignment.SourceContext));
                }

                base.VisitAssignmentStatement(assignment);
            }
Пример #27
0
 public EventingVisitor(Action<AssignmentStatement> visitAssignmentStatement) { VisitedAssignmentStatement += visitAssignmentStatement; } public event Action<AssignmentStatement> VisitedAssignmentStatement; public override Statement VisitAssignmentStatement(AssignmentStatement assignment) { if (VisitedAssignmentStatement != null) VisitedAssignmentStatement(assignment); return base.VisitAssignmentStatement(assignment); }