コード例 #1
0
 internal void Push(TempVariable local)
 {
     if (this.elements == null)
     {
         this.elements = new TempVariable[8];
     }
     else if (this.top >= this.elements.Length - 1)
     {
         Array.Resize(ref this.elements, this.elements.Length * 2);
     }
     this.elements[++this.top] = local;
 }
コード例 #2
0
        public override IStatement Visit(IStatement statement)
        {
            IGotoStatement gotoStatement = statement as IGotoStatement;

            if (gotoStatement != null)
            {
                this.visitedUnconditionalBranch = true;
                foreach (object ob in this.path)
                {
                    if (ob is IConditionalStatement)
                    {
                        this.visitedUnconditionalBranch = false;
                    }
                }
                StackOfLocals newStack = null;
                if (this.stackFor.TryGetValue(gotoStatement.TargetStatement, out newStack))
                {
                    return(this.TransferStack(gotoStatement, newStack));
                }
                this.stackFor.Add(gotoStatement.TargetStatement, this.operandStack.Clone(this.block));
                return(gotoStatement);
            }
            ILabeledStatement labeledStatement = statement as ILabeledStatement;

            if (labeledStatement != null)
            {
                StackOfLocals newStack = null;
                if (this.stackFor.TryGetValue(labeledStatement, out newStack))
                {
                    return(this.TransferStack(labeledStatement, newStack));
                }
                this.stackFor.Add(labeledStatement, this.operandStack.Clone(this.block));
                return(labeledStatement);
            }
            PushStatement /*?*/ push = statement as PushStatement;

            if (push != null)
            {
                push.ValueToPush = this.Visit(push.ValueToPush);
                this.tempCounter = this.body.localVariablesAndTemporaries.Count;
                var temp = new TempVariable()
                {
                    Name = this.body.host.NameTable.GetNameFor("__temp_" + this.tempCounter++)
                };
                temp.Type = push.ValueToPush.Type;
                this.operandStack.Push(temp);
                this.body.numberOfReferences.Add(temp, 0);
                var ctc = push.ValueToPush as ICompileTimeConstant;
                // "push null" doesn't tell us enough to know what type it really is
                if (ctc != null && ctc.Value == null) // REVIEW: need to make sure the type is a reference type?
                {
                    temp.isPolymorphic = true;
                }
                var be = push.ValueToPush as IBoundExpression;
                if (be != null)
                {
                    var sourceLocal = be.Definition as TempVariable;
                    if (sourceLocal != null && sourceLocal.isPolymorphic)
                    {
                        temp.isPolymorphic = true;
                    }
                }
                if (push.ValueToPush.Type is IManagedPointerTypeReference)
                {
                    temp.turnIntoPopValueExpression = true;
                    return(statement);
                }
                this.body.localVariablesAndTemporaries.Add(temp);
                if (this.block.LocalVariables == null)
                {
                    this.block.LocalVariables = new List <ILocalDefinition>();
                }
                this.block.LocalVariables.Add(temp);
                this.body.numberOfAssignments.Add(temp, 1);
                return(new ExpressionStatement()
                {
                    Expression = new Assignment()
                    {
                        Target = new TargetExpression()
                        {
                            Definition = temp
                        }, Source = push.ValueToPush
                    },
                    Locations = push.Locations
                });
            }
            if (statement is EndFilter || statement is EndFinally)
            {
                this.visitedUnconditionalBranch = true;
                return(statement);
            }
            if (statement is SwitchInstruction)
            {
                return(statement);
            }
            return(base.Visit(statement));
        }