Example #1
0
            private bool IsClearlySafe(MethodCallInstruction instruction)
            {
                //TODO: can this be done better?

                var method = instruction.Method;
                var mtype  = method.ContainingType;

                if (mtype.FullName() == "ScopeRuntime.Row" || mtype.FullName() == "ScopeRuntime.RowSet" ||
                    mtype.FullName() == "ScopeRuntime.ColumnData")
                {
                    return(true);
                }

                if (instruction.Arguments.Count != 1)
                {
                    return(false);
                }

                var name = mtype.NestedName();

                if (name.StartsWith("IEnumerator<") || name.StartsWith("IEnumerable<") ||
                    name.StartsWith("List<") || name.StartsWith("HashSet<") ||
                    name.StartsWith("Dictionary<") || name.StartsWith("Queue<") ||
                    name.StartsWith("Stack<") || name.StartsWith("LinkedList<") ||
                    name.StartsWith("SortedList<") || name.StartsWith("SortedSet<"))
                {
                    return(true);
                }

                return(false);
            }
 public override void Visit(MethodCallInstruction instruction)
 {
     if (instruction.HasResult)
     {
         instruction.Result.Type = instruction.Method.Type;
     }
 }
Example #3
0
 private void ProcessJsonCall(MethodCallInstruction methodCall)
 {
     if (methodCall.Method.Name.Value == "DeserializeObject")
     {
         ptAnalysis.ProcessJSonAlloc(State, methodCall.Offset, methodCall.Result);
     }
 }
Example #4
0
 private void ProcessDelegateCtor(MethodCallInstruction methodCall)
 {
     if (methodCall.Arguments.Any())
     {
         var arg0Type = methodCall.Arguments[0].Type;
         if (arg0Type.IsDelegateType())
         {
             State.RemoveRootEdges(methodCall.Arguments[0]);
             if (methodCall.Arguments.Count == 3)
             {
                 // instance delegate
                 foreach (var dn in State.GetTargets(methodCall.Arguments[2]).OfType <DelegateNode>())
                 {
                     dn.Instance = methodCall.Arguments[1];
                     State.PointsTo(methodCall.Arguments[0], dn);
                 }
             }
             else
             {
                 foreach (var dn in State.GetTargets(methodCall.Arguments[1]).OfType <DelegateNode>())
                 {
                     State.PointsTo(methodCall.Arguments[0], dn);
                 }
             }
         }
     }
 }
Example #5
0
            public override void Visit(MethodCallInstruction instruction)
            {
                if (instruction.HasResult)
                {
                    // If we have Schema.IndexOf(param) and param is a constant, then we remember param
                    // as return value.
                    if (IsSchemaGetColumnIndex(instruction))
                    {
                        SavePreState(instruction, FreshCurrent());
                        var nstate = FreshCurrent();
                        UpdateStateCopy(nstate, instruction.Result, instruction.Arguments.ElementAt(1));
                        SetCurrent(nstate);
                        SavePostState(instruction, FreshCurrent());
                    }
                    else
                    {
                        // Here we explicitly handle string concatenation. In other words, if we have
                        // String.Concat method and both arguments are finite set of constants, then
                        // we do cross-product concatenation. Column string concat happens in Scope scripts.
                        if (IsStringConcatenationPossible(instruction, State))
                        {
                            var cons1 = State.Constants(instruction.Arguments.ElementAt(0));
                            var cons2 = State.Constants(instruction.Arguments.ElementAt(1));

                            var strings = new HashSet <string>();
                            foreach (var c1 in cons1.Elements)
                            {
                                foreach (var c2 in cons2.Elements)
                                {
                                    var s1 = c1.Value == null ? String.Empty : c1.Value.ToString();
                                    var s2 = c2.Value == null ? String.Empty : c2.Value.ToString();
                                    strings.Add(s1 + s2);
                                }
                            }

                            var cpd = ConstantSetDomain.Bottom;
                            foreach (var s in strings)
                            {
                                cpd.Add(new Constant(s));
                            }

                            SavePreState(instruction, FreshCurrent());
                            var nstate = FreshCurrent();
                            nstate.Set(instruction.Result, cpd);
                            SetCurrent(nstate);
                            SavePostState(instruction, FreshCurrent());
                        }
                        else
                        {
                            DefaultVarTop(instruction, instruction.Result);
                        }
                    }
                }
                else
                {
                    Default(instruction);
                }
            }
Example #6
0
        public virtual void VisitMethodCall(MethodCallInstruction x)
        {
            foreach (var arg in x.Arguments)
            {
                arg.VisitMe(this);
            }
            x.ThisObject.VisitMe(this);

            VisitInstruction(x);
        }
Example #7
0
            public override void Visit(MethodCallInstruction instruction)
            {
                var methodCall = instruction as MethodCallInstruction;

                // Hack for mapping delegates to nodes
                if (methodCall.Method.Name == ".ctor" && this.analyzeNextDelegateCtor)
                {
                    ProcessDelegateCtor(methodCall);
                    this.analyzeNextDelegateCtor = false;
                }
            }
Example #8
0
 public override void Visit(MethodCallInstruction instruction)
 {
     if (instruction.HasResult)
     {
         DefaultVarTop(instruction, instruction.Result);
     }
     else
     {
         Default(instruction);
     }
 }
Example #9
0
        public override void VisitMethodCall(MethodCallInstruction x)
        {
            var thisObj = getValue(x.ThisObject);

            var args = new List <Expression>();

            foreach (var arg in x.Arguments)
            {
                args.Add(getValue(arg));
            }

            emit(_compiler.MethodCall(x.IsStatic(), thisObj, x.Method, args));
        }
Example #10
0
        private bool IsGetOrSetProp(MethodCallInstruction m)
        {
            if (!m.Method.Type.Equals(Types.Instance.PlatformType.SystemVoid) && m.Method.Name.Value.StartsWith("get_"))
            {
                return(true);
            }

            if (m.Method.Type.Equals(Types.Instance.PlatformType.SystemVoid) && m.Method.Name.Value.StartsWith("set_"))
            {
                return(true);
            }

            return(false);
        }
Example #11
0
 public override void Visit(MethodCallInstruction instruction)
 {
     // We don't classify rows as escaped if they are passed
     // to whitelisted trusted methods.
     if (IsClearlySafe(instruction))
     {
         SavePreState(instruction, FreshCurrent());
         SetCurrent(FreshCurrent());
         SavePostState(instruction, FreshCurrent());
     }
     else
     {
         VisitMethodInvocation(instruction, instruction.Result, instruction.Arguments, instruction.HasResult, instruction.Method.IsStatic);
     }
 }
Example #12
0
            public override void Visit(MethodCallInstruction instruction)
            {
                var methodCall = instruction as MethodCallInstruction;

                // Hack for mapping delegates to nodes
                if (methodCall.Method.Name.Value == ".ctor" && this.analyzeNextDelegateCtor)
                {
                    ProcessDelegateCtor(methodCall);
                    this.analyzeNextDelegateCtor = false;
                }
                // DIEGODIEGO: Maybe this is no longer necessary
                //if (methodCall.Method.ContainingType.GetName().Contains("JsonConvert"))
                //{
                //	ProcessJsonCall(methodCall);
                //}
            }
Example #13
0
        /// <summary>
        /// Check if a method stands for accessing a column and soundly compute
        /// what columns are actually accessed.
        /// </summary>
        /// <param name="arguments"></param>
        /// <returns></returns>
        private ColumnsDomain GetCols(MethodCallInstruction instruction)
        {
            var ct = instruction.Method.ContainingType;

            // The methods must belong to Row.
            if (rowTypes.All(rt => ct != null && !ct.SubtypeOf(rt, host)))
            {
                return(ColumnsDomain.Bottom);
            }

            // If we don't trust the method, then only safe thing to do is to
            // set all columns have been used.
            if (!trustedRowMethods.Contains(instruction.Method.Name.Value))
            {
                Utils.WriteLine("USED COLUMNS untrusted method: " + instruction.ToString());
                return(ColumnsDomain.Top);
            }

            // get_Schema function is safe.
            if (instruction.Arguments.Count == 1)
            {
                return(ColumnsDomain.Bottom);
            }

            var arg  = instruction.Arguments.ElementAt(1);
            var cons = constInfo.GetConstants(instruction, arg);

            // If we don't know the initial value of the variable or the
            // variable cannot take value from a finite set of constants,
            // then we cannot say what column was used here, and in general.
            if (cons == null || cons.Count() == 0)
            {
                Utils.WriteLine("USED COLUMNS top|bottom: " + instruction.ToString());
                return(ColumnsDomain.Top);
            }
            else
            {
                UpdateColumnAccessesStats(arg.Type);

                var cols = ColumnsDomain.Bottom;
                foreach (var c in cons)
                {
                    cols.Add(c);
                }
                return(cols);
            }
        }
Example #14
0
            public override void Visit(MethodCallInstruction instruction)
            {
                var methodCall = instruction;

                if (methodCall.Method.Name.Equals(".ctor") && methodCall.HasResult)
                {
                    var variable = methodCall.Arguments[0] as IVariable;
                    var lastDefs = depAnalysis.LastDefGet(variable);
                    depAnalysis.SetDataDependency((int)methodCall.Offset, lastDefs);
                    depAnalysis.LastDefSet(methodCall.Result, (int)methodCall.Offset);
                }
                else
                {
                    MyDefault(instruction);
                    // base.Visit(instruction);
                }
            }
Example #15
0
            /// <summary>
            /// Method that conservatively checks if the current method is string concatenation
            /// and parameters are known string constants.
            /// </summary>
            /// <param name="instruction"></param>
            /// <param name="state"></param>
            /// <returns></returns>
            private bool IsStringConcatenationPossible(MethodCallInstruction instruction, ConstantPropagationDomain state)
            {
                if (!instruction.HasResult)
                {
                    return(false);
                }

                if (instruction.Arguments.Count != 2)
                {
                    return(false);
                }

                if (instruction.Method.ContainingType.FullName() != "System.String")
                {
                    return(false);
                }

                if (instruction.Method.Name.Value != "Concat")
                {
                    return(false);
                }

                var arg0 = instruction.Arguments.ElementAt(0);
                var arg1 = instruction.Arguments.ElementAt(1);

                if (arg0.Type.FullName() != "System.String" || arg1.Type.FullName() != "System.String")
                {
                    return(false);
                }

                var cons1 = state.Constants(arg0);
                var cons2 = state.Constants(arg1);

                if (cons1.IsBottom || cons2.IsBottom || cons1.IsTop || cons2.IsTop)
                {
                    return(false);
                }

                return(true);
            }
Example #16
0
        public bool IsInMethodCallAsRef(IVariable var)
        {
            // if we found a method call instruction that uses var as a ref parameter, then return true
            // manuel: test behavior with out parameters

            for (int i = instructionIndex + 1; i < methodBody.Instructions.Count(); i++)
            {
                MethodCallInstruction methodCallIns
                    = methodBody.Instructions[i] as MethodCallInstruction;

                if (methodCallIns != null)
                {
                    if (!methodCallIns.Method.IsStatic && methodCallIns.Arguments.Count() == 1) // only 'this'
                    {
                        continue;
                    }

                    if (methodCallIns.Arguments.IndexOf(var) != -1)
                    {
                        // subtract one because of the "this" argument
                        var idx = methodCallIns.Arguments.IndexOf(var) + (!methodCallIns.Method.IsStatic ? -1 : 0);

                        // This is null
                        if (idx == -1)
                        {
                            return(false);
                        }
                        // not sure what happens to out parameters
                        // here 'this' is not listed
                        if (methodCallIns.Method.Parameters.ElementAt(idx).IsByReference)
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
Example #17
0
            public override void Visit(MethodCallInstruction instruction)
            {
                if (instruction.HasResult)
                {
                    instruction.Result.Type = instruction.Method.Type;
                }

                // Skip implicit "this" parameter.
                var offset = instruction.Method.IsStatic ? 0 : 1;

                for (var i = offset; i < instruction.Arguments.Count; ++i)
                {
                    var argument  = instruction.Arguments[i];
                    var parameter = instruction.Method.Parameters.ElementAt(i - offset);

                    // Set the null variable a type.
                    if (argument.Type == null ||
                        parameter.Type.TypeCode == PrimitiveTypeCode.Boolean)
                    {
                        argument.Type = parameter.Type;
                    }
                }
            }
Example #18
0
            private bool IsSchemaGetColumnIndex(MethodCallInstruction instruction)
            {
                if (!instruction.HasResult || instruction.Arguments.Count != 2)
                {
                    return(false);
                }

                if (!IsConstantType(instruction.Arguments.ElementAt(1).Type))
                {
                    return(false);
                }

                if (instruction.Method.Name.Value != "get_Item" && instruction.Method.Name.Value != "IndexOf")
                {
                    return(false);
                }

                if (!parent.IsSchema(instruction.Method.ContainingType))
                {
                    return(false);
                }

                return(true);
            }
Example #19
0
        public static void Inline(this MethodBody callerBody, MethodCallInstruction methodCall, MethodBody calleeBody)
        {
            // TODO: Fix local variables (and parameters) name clashing

            var index = callerBody.Instructions.IndexOf(methodCall);

            callerBody.Instructions.RemoveAt(index);

            Instruction nextInstruction = null;

            if (callerBody.Instructions.Count > index)
            {
                // The caller method has more instructions after the method call
                nextInstruction = callerBody.Instructions[index];
            }

            for (var i = 0; i < calleeBody.Parameters.Count; ++i)
            {
                var parameter = calleeBody.Parameters[i];
                var argument  = methodCall.Arguments[i];
                var copy      = new LoadInstruction(methodCall.Offset, parameter, argument);

                copy.Label = string.Format("{0}_{1}", methodCall.Label, copy.Label);
                callerBody.Instructions.Insert(index, copy);
                index++;
            }

            var lastCalleeInstructionIndex = calleeBody.Instructions.Count - 1;

            for (var i = 0; i < calleeBody.Instructions.Count; ++i)
            {
                var instruction = calleeBody.Instructions[i];

                if (instruction is ReturnInstruction)
                {
                    var ret = instruction as ReturnInstruction;

                    if (ret.HasOperand && methodCall.HasResult)
                    {
                        // Copy the return value of the callee to the result variable of the method call
                        var copy = new LoadInstruction(ret.Offset, methodCall.Result, ret.Operand);

                        copy.Label = string.Format("{0}_{1}", methodCall.Label, copy.Label);
                        callerBody.Instructions.Insert(index, copy);
                        index++;
                    }

                    if (nextInstruction != null && i < lastCalleeInstructionIndex)
                    {
                        // Jump to the instruction after the method call
                        var branch = new UnconditionalBranchInstruction(ret.Offset, nextInstruction.Offset);

                        branch.Label = string.Format("{0}_{1}", methodCall.Label, branch.Label);
                        callerBody.Instructions.Insert(index, branch);
                        index++;
                    }
                }
                else
                {
                    // TODO: Fix! We should clone the instruction
                    // so the original is not modified
                    // and calleeBody remain intacted

                    if (instruction is BranchInstruction)
                    {
                        var branch = instruction as BranchInstruction;
                        branch.Target = string.Format("{0}_{1}", methodCall.Label, branch.Target);
                    }
                    else if (instruction is SwitchInstruction)
                    {
                        var branch = instruction as SwitchInstruction;

                        for (var j = 0; j < branch.Targets.Count; ++j)
                        {
                            var target = branch.Targets[j];
                            branch.Targets[j] = string.Format("{0}_{1}", methodCall.Label, target);
                        }
                    }

                    instruction.Label = string.Format("{0}_{1}", methodCall.Label, instruction.Label);
                    callerBody.Instructions.Insert(index, instruction);
                    index++;
                }
            }
        }
Example #20
0
 public virtual void Visit(MethodCallInstruction instruction)
 {
     Default(instruction);
 }
Example #21
0
 public virtual void Visit(MethodCallInstruction instruction)
 {
 }
Example #22
0
        public Tuple <IEnumerable <IMethodDefinition>, IEnumerable <IMethodReference> > ComputePotentialCallees(MethodCallInstruction instruction, SimplePointsToGraph ptg)
        {
            var resolvedCallees      = new HashSet <IMethodDefinition>();
            var unresolvedCallees    = new HashSet <IMethodReference>();
            var potentalDelegateCall = instruction.Method;

            // If it is a delegate
            if (potentalDelegateCall.Name.Value == "Invoke")
            {
                var classDef = (potentalDelegateCall.ContainingType.ResolvedType) as INamedTypeDefinition;
                if (classDef != null && classDef.IsDelegate)
                {
                    var delegateVar = instruction.Arguments[0];
                    return(ComputeDelegate(delegateVar, ptg));
                    //var potentialDelegates = ptg.GetTargets(delegateVar);
                    //var resolvedInvocations = potentialDelegates.OfType<DelegateNode>()
                    //    .Select(d => this.host.FindMethodImplementation(d.Instance.Type as BasicType, d.Method) as IMethodReference);
                    //resolvedCallees.UnionWith(resolvedInvocations.OfType<MethodDefinition>());
                    //unresolvedCallees.UnionWith(resolvedInvocations.Where(c => !resolvedCallees.Contains(c)));
                }
            }
            else
            {
                if (!instruction.Method.IsStatic && instruction.Method.Name.Value != ".ctor")
                {
                    var receiver            = instruction.Arguments[0];
                    var types               = ptg.GetTargets(receiver, false).Where(n => n.Kind != SimplePTGNodeKind.Null && n.Type != null).Select(n => n.Type);
                    var candidateCalless    = types.Select(t => t.FindMethodImplementation(instruction.Method));
                    var resolvedInvocations = candidateCalless.Select(c => c.ResolvedMethod as IMethodReference);
                    resolvedCallees.UnionWith(resolvedInvocations.OfType <IMethodDefinition>());
                    unresolvedCallees.UnionWith(candidateCalless.Where(c => !resolvedInvocations.Contains(c) &&
                                                                       (c.Name.Value != "Dispose" && c.ContainingType.ContainingAssembly() == "mscorlib")));
                    //unresolvedCallees.UnionWith(resolvedInvocations.Where(c => !(c is MethodDefinition)));
                }
                else
                {
                    var candidateCalee = instruction.Method.ContainingType.FindMethodImplementation(instruction.Method);
                    var resolvedCalle  = candidateCalee.ResolvedMethod;
                    if (resolvedCalle != null)
                    {
                        resolvedCallees.Add(resolvedCalle);
                    }
                }
            }
            return(new Tuple <IEnumerable <IMethodDefinition>, IEnumerable <IMethodReference> >(resolvedCallees, unresolvedCallees));
        }
Example #23
0
        public void VisitMethod(MethodBody mBody, ControlFlowGraph cfg)
        {
            VisitLocals(mBody);

            // Going through the instructions via cfg nodes instead of directly iterating over the instructions
            // of the methodBody becuase Phi instructions may not have been inserted in the insts of the methodBody.
            foreach (var node in cfg.Nodes)
            {
                foreach (var instruction in node.Instructions)
                {
                    // System.Console.WriteLine("{0}", instruction.ToString());
                    // System.Console.WriteLine("{0}", instruction.GetType().FullName());
                    // System.Console.WriteLine();

                    if (instruction is LoadInstruction)
                    {
                        LoadInstruction lInst      = instruction as LoadInstruction;
                        IValue          rhsOperand = lInst.Operand;
                        if (rhsOperand is StaticFieldAccess)
                        {
                            StaticFieldAccess rhsAcc  = rhsOperand as StaticFieldAccess;
                            IFieldReference   fld     = rhsAcc.Field;
                            ITypeDefinition   fldType = fld.ContainingType.ResolvedType;
                            Stubber.CheckAndAdd(fldType);
                        }
                        // Note: calls to static methods and instance methods appear as a StaticMethodReference
                        else if (rhsOperand is StaticMethodReference)
                        {
                            StaticMethodReference sMethAddr    = rhsOperand as StaticMethodReference;
                            IMethodDefinition     tgtMeth      = sMethAddr.Method.ResolvedMethod;
                            ITypeDefinition       containingTy = tgtMeth.ContainingTypeDefinition;
                            Stubber.CheckAndAdd(containingTy);
                            IMethodDefinition addedMeth = Stubber.CheckAndAdd(tgtMeth);
                            // addrTakenMethods do not contain templates.
                            if (addedMeth != null)
                            {
                                addrTakenMethods.Add(addedMeth);
                            }
                        }
                        //Note: calls to virtual, abstract or interface methods appear as VirtualMethodReference
                        else if (rhsOperand is VirtualMethodReference)
                        {
                            VirtualMethodReference sMethAddr    = rhsOperand as VirtualMethodReference;
                            IMethodDefinition      tgtMeth      = sMethAddr.Method.ResolvedMethod;
                            ITypeDefinition        containingTy = tgtMeth.ContainingTypeDefinition;
                            ITypeDefinition        addedTy      = Stubber.CheckAndAdd(containingTy);
                            IMethodDefinition      addedMeth    = Stubber.CheckAndAdd(tgtMeth);
                            if (addedTy != null && addedMeth != null)
                            {
                                // addrTakenMethods do not contain templates.
                                addrTakenMethods.Add(addedMeth);
                                ProcessVirtualInvoke(addedMeth, addedTy, true);
                            }
                        }
                        else if (rhsOperand is Reference)
                        {
                            Reference      rhsRef = rhsOperand as Reference;
                            IReferenceable refOf  = rhsRef.Value;
                            if (refOf is StaticFieldAccess)
                            {
                                StaticFieldAccess refAcc  = refOf as StaticFieldAccess;
                                IFieldDefinition  fld     = refAcc.Field.ResolvedField;
                                ITypeDefinition   fldType = fld.ContainingType.ResolvedType;
                                Stubber.CheckAndAdd(fldType);
                                addrTakenStatFlds.Add(fld);
                            }
                            else if (refOf is IVariable)
                            {
                                IVariable refVar = refOf as IVariable;
                                if (!refVar.Type.IsValueType || refVar.Type.ResolvedType.IsStruct)
                                {
                                    addrTakenLocals.Add(refVar);
                                }
                            }
                            else if (refOf is InstanceFieldAccess)
                            {
                                InstanceFieldAccess refAcc = refOf as InstanceFieldAccess;
                                IFieldDefinition    fld    = refAcc.Field.ResolvedField;
                                addrTakenInstFlds.Add(fld);
                            }
                            else if (refOf is ArrayElementAccess)
                            {
                                // All arrays will be added into domX as potential address taken.
                            }
                        }
                    }
                    else if (instruction is StoreInstruction)
                    {
                        StoreInstruction sInst = instruction as StoreInstruction;
                        IAssignableValue lhs   = sInst.Result;
                        if (lhs is StaticFieldAccess)
                        {
                            StaticFieldAccess lhsAcc  = lhs as StaticFieldAccess;
                            IFieldReference   fld     = lhsAcc.Field;
                            ITypeDefinition   fldType = fld.ContainingType.ResolvedType;
                            Stubber.CheckAndAdd(fldType);
                        }
                    }
                    else if (instruction is CreateObjectInstruction)
                    {
                        CreateObjectInstruction newObjInst = instruction as CreateObjectInstruction;
                        ITypeReference          objType    = newObjInst.AllocationType;
                        ITypeDefinition         objTypeDef = objType.ResolvedType;
                        if (objTypeDef is IGenericTypeInstance)
                        {
                            objTypeDef = objTypeDef.ResolvedType;
                        }
                        ITypeDefinition addedTy = Stubber.CheckAndAdd(objTypeDef);
                        if (addedTy != null && !allocClasses.Contains(addedTy))
                        {
                            allocClasses.Add(addedTy);
                        }
                    }
                    else if (instruction is CreateArrayInstruction)
                    {
                        CreateArrayInstruction newArrInst  = instruction as CreateArrayInstruction;
                        ITypeReference         elemType    = newArrInst.ElementType;
                        ITypeDefinition        elemTypeDef = elemType.ResolvedType;
                        ITypeDefinition        addedTy     = Stubber.CheckAndAdd(elemTypeDef);
                        if (addedTy != null && !allocClasses.Contains(addedTy))
                        {
                            allocClasses.Add(addedTy);
                        }
                    }
                    else if (instruction is MethodCallInstruction)
                    {
                        MethodCallInstruction invkInst       = instruction as MethodCallInstruction;
                        IMethodReference      callTgt        = invkInst.Method;
                        ITypeReference        containingType = callTgt.ContainingType;
                        ITypeDefinition       declType       = containingType.ResolvedType;
                        IMethodDefinition     callTgtDef     = callTgt.ResolvedMethod;
                        ITypeDefinition       addedType      = Stubber.CheckAndAdd(declType);
                        IMethodDefinition     addedMeth      = Stubber.CheckAndAdd(callTgtDef);
                        MethodCallOperation   callType       = invkInst.Operation;
                        if (callType == MethodCallOperation.Virtual && addedType != null && addedMeth != null)
                        {
                            ProcessVirtualInvoke(addedMeth, addedType, false);
                        }
                    }
                    else
                    {
                        // System.Console.WriteLine("{0}", instruction.ToString());
                        // System.Console.WriteLine("Not currently handled: {0}", instruction.GetType().ToString());
                        // System.Console.WriteLine();
                    }
                }
            }
        }