Пример #1
0
        public void VisitCall(Call call)
        {
            if (m_needsCheck && m_offset < 0 && call.Target.HasThis)
            {
                int index = call.GetThisIndex(m_info);

                if (index >= 0)
                {
                    Log.DebugLine(this, "found this arg at {0:X2}", m_info.Instructions[index].Untyped.Offset);
                    LoadArg load = m_info.Instructions[index] as LoadArg;

                    if (load != null)
                    {
                        bool found;
                        if (m_table.TryGetValue(load.Name, out found))
                        {
                            if (!found)
                            {
                                m_offset = call.Untyped.Offset;
                                m_badArg = load.Name;
                                Log.DebugLine(this, "bad call at {0:X2}", m_offset);
                            }
                        }
                    }
                }
            }
        }
Пример #2
0
 // ldarg.0   this
 // ldc.i4.0
 // stfld     System.Int32 Smokey.Tests.UseDefaultInitTest/BadCase1::m_int
 public void VisitStore(StoreField store)
 {
     if (m_needsCheck && m_offset < 0)
     {
         long?value            = m_info.Tracker.GetStack(store.Index, 0);
         LoadConstantFloat flt = m_info.Instructions[store.Index - 1] as LoadConstantFloat;
         if ((value.HasValue && value.Value == 0) || (flt != null && flt.Value == 0.0))
         {
             Log.DebugLine(this, "found zero value at index {0}", store.Index - 1);
             int index = m_info.Tracker.GetStackIndex(store.Index, 1);
             if (index >= 0)
             {
                 LoadArg load = m_info.Instructions[index] as LoadArg;
                 if (load != null)
                 {
                     Log.DebugLine(this, "found load at index {0}", index);
                 }
                 if (load != null && load.Arg == 0)
                 {
                     m_offset = store.Untyped.Offset;
                     Log.DebugLine(this, "found zero field store at {0:X2}", m_offset);
                 }
             }
         }
     }
 }
Пример #3
0
 public void VisitLoad(LoadArg load)
 {
     if (m_needsCheck)
     {
         Log.DebugLine(this, "removing '{0}'", load.Name);
         Unused.Value = m_args.Remove(load.Name);
     }
 }
Пример #4
0
        public void Add(LoadArg l)
        {
            var e = new CmdLineModuleElement(l);

            BaseAdd(e);

            foreach (var a in l.Properties)
            {
                e.Add(a);
            }
        }
Пример #5
0
        public void VisitCall(Call call)
        {
            if (m_needsCheck)
            {
                Log.Indent();

                // See if an arg is being used as a this pointer,
                if (call.Target.HasThis)
                {
                    int index = call.GetThisIndex(m_info);
                    if (index >= 0)
                    {
                        LoadArg load = m_info.Instructions[index] as LoadArg;
                        if (load != null && m_types[load.Arg] != null)
                        {
                            TypeReference  tr   = call.Target.GetDeclaredIn(Cache);
                            TypeDefinition type = Cache.FindType(tr);
                            if (type != null && type.ExternallyVisible(Cache))
                            {
                                Log.DebugLine(this, "found type {0}", type.FullName);

                                if (!type.Name.StartsWith("_"))                                         // can get weird stuff like System.Runtime.InteropServices._Type otherwise
                                {
                                    DoUseArg(load.Arg, call.Untyped.Offset, type);
                                }
                                else if ("_" + load.Type.Name != type.Name)
                                {
                                    DoUseArg(load.Arg, call.Untyped.Offset, type);
                                }
                            }
                        }
                    }
                }

                // See if an arg is being used as an arg.
                for (int nth = 0; nth < call.Target.Parameters.Count; ++nth)
                {
                    int index = m_info.Tracker.GetStackIndex(call.Index, nth);
                    if (index >= 0)
                    {
                        LoadArg load = m_info.Instructions[index] as LoadArg;
                        if (load != null && m_types[load.Arg] != null)
                        {
                            int           argIndex = call.Target.Parameters.Count - nth - 1;
                            TypeReference type     = call.Target.Parameters[argIndex].ParameterType;
                            DoUseArg(load.Arg, call.Untyped.Offset, type);
                        }
                    }
                }

                Log.Unindent();
            }
        }
Пример #6
0
            private static void DoSpliceEq(TypedInstructionCollection instructions, BasicBlock block)
            {
                int index = block.Last.Index;

                // ldloc.0 V_0
                // ldnull
                // beq     2F
                LoadArg   arg   = null;
                LoadLocal local = null;

                if (instructions[index - 1].Untyped.OpCode.Code == Code.Ldnull)
                {
                    arg   = instructions[block.Last.Index - 2] as LoadArg;
                    local = instructions[block.Last.Index - 2] as LoadLocal;
                }
                else if (instructions[index - 2].Untyped.OpCode.Code == Code.Ldnull)
                {
                    arg   = instructions[block.Last.Index - 1] as LoadArg;
                    local = instructions[block.Last.Index - 1] as LoadLocal;
                }

                if (arg != null || local != null)
                {
                    TypedInstruction instruction = instructions[block.Last.Index];
                    Code             code        = instruction.Untyped.OpCode.Code;

                    if (code == Code.Bne_Un || code == Code.Bne_Un_S)
                    {
                        if (arg != null)
                        {
                            DoSpliceNull(block, FirstNullArgBlockLen - arg.Arg, FirstNonNullArgBlockLen - arg.Arg);
                        }

                        else
                        {
                            DoSpliceNull(block, FirstNullLocalBlockLen - local.Variable, FirstNonNullLocalBlockLen - local.Variable);
                        }
                    }
                    else
                    {
                        if (arg != null)
                        {
                            DoSpliceNull(block, FirstNonNullArgBlockLen - arg.Arg, FirstNullArgBlockLen - arg.Arg);
                        }

                        else
                        {
                            DoSpliceNull(block, FirstNonNullLocalBlockLen - local.Variable, FirstNullLocalBlockLen - local.Variable);
                        }
                    }
                }
            }
Пример #7
0
        public void VisitBinary(BinaryOp op)
        {
            if (m_offset < 0 && (op.Untyped.OpCode.Code == Code.Div || op.Untyped.OpCode.Code == Code.Div_Un))
            {
                do
                {
                    LoadConstantInt load1 = m_info.Instructions[op.Index - 1] as LoadConstantInt;
                    if (load1 != null)
                    {
                        if (load1.Value == 0)
                        {
                            m_offset = op.Untyped.Offset;
                            Log.DebugLine(this, "zero constant denominator at {0:X2}", m_offset);
                        }
                        break;
                    }

                    LoadLocal load2 = m_info.Instructions[op.Index - 1] as LoadLocal;
                    if (load2 != null)
                    {
                        if (DoIsIntType(load2.Type))
                        {
                            State state = m_info.Tracker.State(op.Index - 1);
                            long? value = state.Locals[load2.Variable];
                            if (value.HasValue && value.Value == 0)
                            {
                                m_offset = op.Untyped.Offset;
                                Log.DebugLine(this, "zero local denominator at {0:X2}", m_offset);
                            }
                        }
                        break;
                    }

                    LoadArg load3 = m_info.Instructions[op.Index - 1] as LoadArg;
                    if (load3 != null)
                    {
                        if (DoIsIntType(load3.Type))
                        {
                            State state2 = m_info.Tracker.State(op.Index - 1);
                            long? value2 = state2.Arguments[m_info.Method.HasThis ? load3.Arg : load3.Arg - 1];
                            if (value2.HasValue && value2.Value == 0)
                            {
                                m_offset = op.Untyped.Offset;
                                Log.DebugLine(this, "zero arg denominator at {0:X2}", m_offset);
                            }
                        }
                        break;
                    }
                }while (false);
            }
        }
Пример #8
0
        private TypeReference DoGetType(int index, int nth)
        {
            TypeReference type = null;

            int i = m_info.Tracker.GetStackIndex(index, nth);

            if (i >= 0)
            {
                do                      // TODO: would be nice to do something with load constant instructions as well
                {
                    LoadArg arg = m_info.Instructions[i] as LoadArg;
                    if (arg != null && arg.Arg >= 1)
                    {
                        ParameterDefinition p = m_info.Method.Parameters[arg.Arg - 1];
                        type = p.ParameterType;
                        break;
                    }

                    LoadField field = m_info.Instructions[i] as LoadField;
                    if (field != null)
                    {
                        type = field.Field.FieldType;
                        break;
                    }

                    LoadLocal local = m_info.Instructions[i] as LoadLocal;
                    if (local != null)
                    {
                        VariableDefinition v = m_info.Method.Body.Variables[local.Variable];
                        type = v.VariableType;
                        break;
                    }

                    LoadStaticField sfield = m_info.Instructions[i] as LoadStaticField;
                    if (sfield != null)
                    {
                        type = sfield.Field.FieldType;
                        break;
                    }

                    Box box = m_info.Instructions[i] as Box;
                    if (box != null)
                    {
                        type = box.Type;
                        break;
                    }
                }while (false);
            }

            return(type);
        }
Пример #9
0
 public void VisitStoreStaticField(StoreStaticField store)
 {
     if (m_needsCheck)
     {
         Log.Indent();
         LoadArg load = m_info.Instructions[store.Index - 1] as LoadArg;
         if (load != null && m_types[load.Arg] != null)
         {
             TypeReference type = store.Field.FieldType;
             DoUseArg(load.Arg, store.Untyped.Offset, type);
         }
         Log.Unindent();
     }
 }
Пример #10
0
 public void VisitStoreLocal(StoreLocal store)
 {
     if (m_needsCheck)
     {
         Log.Indent();
         LoadArg load = m_info.Instructions[store.Index - 1] as LoadArg;
         if (load != null && m_types[load.Arg] != null)
         {
             Log.DebugLine(this, "arg{0}: was saved to a local (at {1:X2})", load.Arg, store.Untyped.Offset);
             m_types[load.Arg] = null;
         }
         Log.Unindent();
     }
 }
Пример #11
0
 public void VisitLoadField(LoadField field)
 {
     if (m_needsCheck)
     {
         Log.Indent();
         LoadArg load = m_info.Instructions[field.Index - 1] as LoadArg;
         if (load != null && m_types[load.Arg] != null)
         {
             TypeReference type = field.Field.DeclaringType;
             DoUseArg(load.Arg, field.Untyped.Offset, type);
         }
         Log.Unindent();
     }
 }
Пример #12
0
 // ldarg.1    list
 // brtrue     11
 public void VisitBranch(ConditionalBranch branch)
 {
     if (m_needsCheck && m_offset < 0)
     {
         if (branch.Untyped.OpCode.Code == Code.Brtrue || branch.Untyped.OpCode.Code == Code.Brtrue_S || branch.Untyped.OpCode.Code == Code.Brfalse || branch.Untyped.OpCode.Code == Code.Brfalse_S)
         {
             LoadArg load = m_info.Instructions[branch.Index - 1] as LoadArg;
             if (load != null)
             {
                 m_table[load.Name] = true;
                 Log.DebugLine(this, "found a compare at {0:X2}", branch.Untyped.Offset);
             }
         }
     }
 }
Пример #13
0
        // ldarg.0
        // ldarg.1
        // stfld string Smokey.Tests.EqualsMissesStateTest/Good1::m_name
        // ret
        private void DoTrivialSetter()
        {
            do
            {
                if (m_minfo.Instructions.Length != 4)
                {
                    break;
                }

                LoadArg larg = m_minfo.Instructions[0] as LoadArg;
                if (larg == null || larg.Arg != 0)
                {
                    break;
                }

                larg = m_minfo.Instructions[1] as LoadArg;
                if (larg == null || larg.Arg != 1)
                {
                    break;
                }

                StoreField store = m_minfo.Instructions[2] as StoreField;
                if (store == null)
                {
                    break;
                }

                if (m_minfo.Type.Fields.GetField(store.Field.Name) == null)                     // only count fields defined int this class
                {
                    break;
                }

                if (m_minfo.Instructions[3].Untyped.OpCode.Code != Code.Ret)
                {
                    break;
                }

                Log.DebugLine(this, "found trivial setter for {0}", store.Field.Name);
                string   name = m_minfo.Method.Name.Substring(4);
                Property prop = m_properties.SingleOrDefault(p => p.Name == name && p.Field == store.Field.Name);
                if (prop == null)
                {
                    prop = new Property(name, store.Field.Name);
                    m_properties.Add(prop);
                }
                prop.HasTrivialSetter = true;
            }while (false);
        }
Пример #14
0
        public void VisitCall(Call call)
        {
            if (m_disposable)
            {
                if (m_isNullaryDispose)
                {
                    if (call.Target.ToString().Contains("System.GC::SuppressFinalize(System.Object)"))
                    {
                        Log.DebugLine(this, "has suppress call");
                        m_supressWasCalled = true;
                    }
                }

                if (m_disposableFields.Count > 0)
                {
                    // ldfld    class System.IO.TextWriter Smokey.DisposableFieldsTest/GoodCase::m_writer
                    // callvirt instance void class [mscorlib]System.IO.TextWriter::Dispose()
                    if (call.Target.Name == "Dispose" || call.Target.Name == "Close")
                    {
                        if (m_minfo.Instructions[call.Index - 1].Untyped.OpCode.Code == Code.Ldfld)
                        {
                            FieldReference field = (FieldReference)m_minfo.Instructions[call.Index - 1].Untyped.Operand;
                            Log.DebugLine(this, "found Dispose call for {0}", field.Name);
                            Unused.Value = m_disposableFields.Remove(field.ToString());
                        }
                    }
                }

                // ldarg.0
                // ldfld class [mscorlib]System.IO.StringWriter Smokey.Tests.DisposeableTest/NoNullCheck1::m_writer
                // callvirt instance void class [mscorlib]System.IO.TextWriter::Dispose()
                if ((m_isNullaryDispose || m_isUnaryDispose) && call.Index >= 2 && !m_callsNullableField && !m_hasNullCall)
                {
                    LoadArg   load1 = m_minfo.Instructions[call.Index - 2] as LoadArg;
                    LoadField load2 = m_minfo.Instructions[call.Index - 1] as LoadField;
                    if (load1 != null && load2 != null)
                    {
                        if (load1.Arg == 0 && !load2.Field.FieldType.IsValueType)
                        {
                            if (m_ownedFields.IndexOf(load2.Field) >= 0)
                            {
                                m_callsNullableField = true;
                            }
                        }
                    }
                }
            }
        }
Пример #15
0
 // ldarg.0  this
 // stloc.0  V_0
 public void VisitStore(StoreLocal store)
 {
     if (m_needsCheck && m_offset < 0)
     {
         LoadArg load = m_info.Instructions[store.Index - 1] as LoadArg;
         if (load != null && load.Arg == 0)
         {
             m_thisLocals.Add(store.Variable);
             Log.DebugLine(this, "{0} = this at {1:X2}", store.Name, store.Untyped.Offset);
         }
         else
         {
             Unused.Value = m_thisLocals.Remove(store.Variable);
         }
     }
 }
Пример #16
0
 public void VisitLoad(LoadArg load)
 {
     if (m_needsCheck)
     {
         if (load.Arg == 1 && !m_found1)
         {
             m_found1 = true;
             Log.DebugLine(this, "found value1 use at {0:X2}", load.Untyped.Offset);
         }
         else if (load.Arg == 2 && !m_found2)
         {
             m_found2 = true;
             Log.DebugLine(this, "found value2 use at {0:X2}", load.Untyped.Offset);
         }
     }
 }
Пример #17
0
        // ldarg.0  this
        // ldfld    System.String Smokey.Tests.WeakIdentityLockTest/Cases::m_string
        private FieldReference DoGetField(int index)
        {
            FieldReference field = null;

            if (index > 0)
            {
                LoadField load = m_info.Instructions[index] as LoadField;
                LoadArg   arg  = m_info.Instructions[index - 1] as LoadArg;

                if (arg != null && load != null && arg.Arg == 0)
                {
                    field = load.Field;
                }
            }

            return(field);
        }
Пример #18
0
        private TypeReference DoGetThisType(Call call)
        {
            TypeReference self = null;

            if (call.Target.HasThis)
            {
                int index = call.GetThisIndex(m_info);

                if (index >= 0)
                {
                    do
                    {
                        LoadArg arg = m_info.Instructions[index] as LoadArg;
                        if (arg != null)
                        {
                            self = arg.Type;
                            break;
                        }

                        LoadField field = m_info.Instructions[index] as LoadField;
                        if (field != null)
                        {
                            self = field.Field.FieldType;
                            break;
                        }

                        LoadStaticField sfield = m_info.Instructions[index] as LoadStaticField;
                        if (sfield != null)
                        {
                            self = sfield.Field.FieldType;
                            break;
                        }

                        LoadLocal local = m_info.Instructions[index] as LoadLocal;
                        if (local != null)
                        {
                            self = local.Type;
                            break;
                        }
                    }while (false);
                }
            }

            return(self);
        }
Пример #19
0
 // ldarg.0  this
 // ldflda   Smokey.Tests.UseDefaultInitTest/Struct Smokey.Tests.UseDefaultInitTest/BadCase3::m_struct
 // initobj  Smokey.Tests.UseDefaultInitTest/Struct
 public void VisitInit(InitObj init)
 {
     if (m_needsCheck && m_offset < 0)
     {
         if (init.Type.IsValueType)
         {
             LoadFieldAddress field = m_info.Instructions[init.Index - 1] as LoadFieldAddress;
             if (field != null)
             {
                 LoadArg arg = m_info.Instructions[init.Index - 2] as LoadArg;
                 if (arg != null && arg.Arg == 0)
                 {
                     m_offset = init.Untyped.Offset;
                     Log.DebugLine(this, "found default ctor call at {0:X2}", m_offset);
                 }
             }
         }
     }
 }
Пример #20
0
        // ldarg.1    list
        // ldnull
        // ceq
        public void VisitCeq(Ceq ceq)
        {
            if (m_needsCheck && m_offset < 0)
            {
                LoadNull load1 = m_info.Instructions[ceq.Index - 1] as LoadNull;
                LoadArg  load2 = m_info.Instructions[ceq.Index - 2] as LoadArg;

                if (load1 == null && load2 == null)
                {
                    load1 = m_info.Instructions[ceq.Index - 2] as LoadNull;
                    load2 = m_info.Instructions[ceq.Index - 1] as LoadArg;
                }

                if (load1 != null && load2 != null)
                {
                    m_table[load2.Name] = true;
                    Log.DebugLine(this, "found a compare at {0:X2}", ceq.Untyped.Offset);
                }
            }
        }
Пример #21
0
            private static void DoSpliceTrue(TypedInstructionCollection instructions, BasicBlock block)
            {
                int index = block.Last.Index;

                // ldarg.1 a1
                // brtrue  10	(not taken is the first branch)
                LoadArg   arg   = instructions[index - 1] as LoadArg;
                LoadLocal local = instructions[index - 1] as LoadLocal;

                if (arg != null || local != null)
                {
                    TypedInstruction instruction = instructions[index];
                    Code             code        = instruction.Untyped.OpCode.Code;

                    if (code == Code.Brtrue || code == Code.Brtrue_S)
                    {
                        if (arg != null)
                        {
                            DoSpliceNull(block, FirstNullArgBlockLen - arg.Arg, FirstNonNullArgBlockLen - arg.Arg);
                        }

                        else
                        {
                            DoSpliceNull(block, FirstNullLocalBlockLen - local.Variable, FirstNonNullLocalBlockLen - local.Variable);
                        }
                    }
                    else
                    {
                        if (arg != null)
                        {
                            DoSpliceNull(block, FirstNonNullArgBlockLen - arg.Arg, FirstNullArgBlockLen - arg.Arg);
                        }

                        else
                        {
                            DoSpliceNull(block, FirstNonNullLocalBlockLen - local.Variable, FirstNullLocalBlockLen - local.Variable);
                        }
                    }
                }
            }
Пример #22
0
        public static bool IsIntOperand(MethodInfo info, int index, int nth)
        {
            bool isInt = false;

            int i = info.Tracker.GetStackIndex(index, nth);

            if (i >= 0)
            {
                do
                {
                    LoadArg arg = info.Instructions[i] as LoadArg;
                    if (arg != null && arg.Arg >= 1)
                    {
                        ParameterDefinition p = info.Method.Parameters[arg.Arg - 1];
                        if (p.ParameterType.FullName == "System.Int32")
                        {
                            isInt = true;
                        }
                        break;
                    }

                    LoadConstantInt constant = info.Instructions[i] as LoadConstantInt;
                    if (constant != null)
                    {
                        Code code = constant.Untyped.OpCode.Code;
                        switch (code)
                        {
                        case Code.Ldc_I4_M1:
                        case Code.Ldc_I4_0:
                        case Code.Ldc_I4_1:
                        case Code.Ldc_I4_2:
                        case Code.Ldc_I4_3:
                        case Code.Ldc_I4_4:
                        case Code.Ldc_I4_5:
                        case Code.Ldc_I4_6:
                        case Code.Ldc_I4_7:
                        case Code.Ldc_I4_8:
                        case Code.Ldc_I4_S:
                        case Code.Ldc_I4:
                            isInt = true;
                            break;
                        }
                        break;
                    }

                    LoadField field = info.Instructions[i] as LoadField;
                    if (field != null)
                    {
                        if (field.Field.FieldType.FullName == "System.Int32")
                        {
                            isInt = true;
                        }
                        break;
                    }

                    LoadLocal local = info.Instructions[i] as LoadLocal;
                    if (local != null)
                    {
                        VariableDefinition v = info.Method.Body.Variables[local.Variable];
                        if (v.VariableType.FullName == "System.Int32")
                        {
                            isInt = true;
                        }
                        break;
                    }

                    LoadStaticField sfield = info.Instructions[i] as LoadStaticField;
                    if (sfield != null)
                    {
                        if (sfield.Field.FieldType.FullName == "System.Int32")
                        {
                            isInt = true;
                        }
                        break;
                    }
                }while (false);
            }

            return(isInt);
        }
 public void Add(LoadArg l)
 {
     modules.Add(l);
 }
Пример #24
0
            private void DoStackPushes(List <StackEntry> stack, int index, List <StackEntry> oldStack)
            {
                long?value;

                TypedInstruction instruction = m_instructions[index];

                switch (instruction.Untyped.OpCode.Code)
                {
                case Code.Add:
                case Code.Sub:
                case Code.Mul:
                case Code.Div:
                case Code.Div_Un:
                case Code.Rem:
                case Code.Rem_Un:
                case Code.And:
                case Code.Or:
                case Code.Xor:
                case Code.Shl:
                case Code.Shr:
                case Code.Shr_Un:
                case Code.Neg:
                case Code.Not:
                case Code.Add_Ovf:
                case Code.Add_Ovf_Un:
                case Code.Mul_Ovf:
                case Code.Mul_Ovf_Un:
                case Code.Sub_Ovf:
                case Code.Sub_Ovf_Un:
                    stack.Add(new StackEntry(null, index));                                     // could compute these, but we don't care too much about integer values atm
                    break;

                case Code.Arglist:                                              // push non-null
                case Code.Box:
                case Code.Ldarga:
                case Code.Ldarga_S:
                case Code.Ldelema:
                case Code.Ldflda:
                case Code.Ldftn:
                case Code.Ldind_Ref:
                case Code.Ldloca:
                case Code.Ldloca_S:
                case Code.Ldobj:
                case Code.Ldsflda:
                case Code.Ldstr:
                case Code.Ldtoken:
                case Code.Ldvirtftn:
                case Code.Localloc:
                case Code.Mkrefany:
                case Code.Newarr:
                case Code.Newobj:
                case Code.Refanytype:
                case Code.Refanyval:
                case Code.Unbox:
                case Code.Unbox_Any:
                    stack.Add(new StackEntry(1, index));
                    break;

                case Code.Call:
                case Code.Calli:
                case Code.Callvirt:
                    Call call = instruction as Call;
                    if (call.Target.ReturnType.ReturnType.ToString() != "System.Void")
                    {
                        stack.Add(new StackEntry(null, index));
                    }
                    break;

                case Code.Castclass:
                    value = oldStack.Back().Value;
                    if (value.HasValue && value.Value == 0)
                    {
                        stack.Add(new StackEntry(0, index));
                    }
                    else
                    {
                        stack.Add(new StackEntry(1, index));
                    }
                    break;

                case Code.Ceq:                                          // push indeterminate
                case Code.Cgt:
                case Code.Cgt_Un:
                case Code.Clt:
                case Code.Clt_Un:
                case Code.Ckfinite:
                case Code.Conv_I1:
                case Code.Conv_I2:
                case Code.Conv_I4:
                case Code.Conv_I8:
                case Code.Conv_U4:
                case Code.Conv_U8:
                case Code.Conv_R4:
                case Code.Conv_R8:
                case Code.Conv_U2:
                case Code.Conv_U1:
                case Code.Conv_I:
                case Code.Conv_R_Un:
                case Code.Conv_U:
                case Code.Ldelem_I1:
                case Code.Ldelem_U1:
                case Code.Ldelem_I2:
                case Code.Ldelem_U2:
                case Code.Ldelem_I4:
                case Code.Ldelem_U4:
                case Code.Ldelem_I8:
                case Code.Ldelem_I:
                case Code.Ldelem_R4:
                case Code.Ldelem_R8:
                case Code.Ldelem_Ref:
                case Code.Ldelem_Any:
                case Code.Ldind_I1:
                case Code.Ldind_U1:
                case Code.Ldind_I2:
                case Code.Ldind_U2:
                case Code.Ldind_I4:
                case Code.Ldind_U4:
                case Code.Ldind_I8:
                case Code.Ldind_I:
                case Code.Ldind_R4:
                case Code.Ldind_R8:
                case Code.Ldfld:
                case Code.Ldsfld:
                case Code.Ldlen:
                case Code.Sizeof:
                    stack.Add(new StackEntry(null, index));
                    break;

                case Code.Conv_Ovf_I1:                                  // push previous value
                case Code.Conv_Ovf_U1:
                case Code.Conv_Ovf_I2:
                case Code.Conv_Ovf_U2:
                case Code.Conv_Ovf_I4:
                case Code.Conv_Ovf_U4:
                case Code.Conv_Ovf_I8:
                case Code.Conv_Ovf_U8:
                case Code.Conv_Ovf_I:
                case Code.Conv_Ovf_U:
                case Code.Conv_Ovf_I1_Un:
                case Code.Conv_Ovf_I2_Un:
                case Code.Conv_Ovf_I4_Un:
                case Code.Conv_Ovf_I8_Un:
                case Code.Conv_Ovf_U1_Un:
                case Code.Conv_Ovf_U2_Un:
                case Code.Conv_Ovf_U4_Un:
                case Code.Conv_Ovf_U8_Un:
                case Code.Conv_Ovf_I_Un:
                case Code.Conv_Ovf_U_Un:
                    value = oldStack.Back().Value;
                    stack.Add(new StackEntry(value, index));
                    break;

                case Code.Dup:
                    value = oldStack.Back().Value;
                    stack.Add(new StackEntry(value, index));
                    stack.Add(new StackEntry(value, index));
                    break;

                case Code.Isinst:
                    value = oldStack.Back().Value;
                    if (value.HasValue && value.Value == 0)
                    {
                        stack.Add(new StackEntry(0, index));
                    }
                    else
                    {
                        stack.Add(new StackEntry(null, index));
                    }
                    break;

                case Code.Ldarg_0:
                case Code.Ldarg_1:
                case Code.Ldarg_2:
                case Code.Ldarg_3:
                case Code.Ldarg:
                case Code.Ldarg_S:
                    LoadArg arg = instruction as LoadArg;
                    value = m_state.Arguments[arg.Arg];
                    stack.Add(new StackEntry(value, index));
                    break;

                case Code.Ldc_I4_M1:
                case Code.Ldc_I4_0:
                case Code.Ldc_I4_1:
                case Code.Ldc_I4_2:
                case Code.Ldc_I4_3:
                case Code.Ldc_I4_4:
                case Code.Ldc_I4_5:
                case Code.Ldc_I4_6:
                case Code.Ldc_I4_7:
                case Code.Ldc_I4_8:
                case Code.Ldc_I4_S:
                case Code.Ldc_I4:
                case Code.Ldc_I8:
                    LoadConstantInt constant = instruction as LoadConstantInt;
                    stack.Add(new StackEntry(constant.Value, index));
                    break;

                case Code.Ldc_R4:
                case Code.Ldc_R8:
                    LoadConstantFloat constant2 = instruction as LoadConstantFloat;
                    if (constant2.Value == 0.0)
                    {
                        stack.Add(new StackEntry(0, index));
                    }
                    else
                    {
                        stack.Add(new StackEntry(null, index));
                    }
                    break;

                case Code.Ldloc_0:
                case Code.Ldloc_1:
                case Code.Ldloc_2:
                case Code.Ldloc_3:
                case Code.Ldloc:
                case Code.Ldloc_S:
                    LoadLocal local = instruction as LoadLocal;
                    value = m_state.Locals[local.Variable];
                    stack.Add(new StackEntry(value, index));
                    break;

                case Code.Ldnull:                                                               // push null
                    stack.Add(new StackEntry(0, index));
                    break;

                default:
                    DBC.Assert(instruction.Untyped.OpCode.StackBehaviourPush == StackBehaviour.Push0, "Expected {0} to push nothing", instruction.Untyped.OpCode);
                    break;
                }
            }
Пример #25
0
        private bool DoIsFloat(int index)
        {
            TypedInstruction instruction = m_info.Instructions[index];
            TypeReference    type        = null;

            do
            {
                LoadArg arg = instruction as LoadArg;
                if (arg != null && arg.Arg >= 1)
                {
                    type = m_info.Method.Parameters[arg.Arg - 1].ParameterType;
                    break;
                }

                LoadLocal local = instruction as LoadLocal;
                if (local != null)
                {
                    type = m_info.Method.Body.Variables[local.Variable].VariableType;
                    break;
                }

                LoadField field = instruction as LoadField;
                if (field != null)
                {
                    type = field.Field.FieldType;
                    break;
                }

                LoadStaticField sfield = instruction as LoadStaticField;
                if (sfield != null)
                {
                    type = sfield.Field.FieldType;
                    break;
                }

                LoadConstantFloat cf = instruction as LoadConstantFloat;
                if (cf != null)
                {
                    return(cf.Value != double.PositiveInfinity && cf.Value != double.NegativeInfinity);
                }

                BinaryOp binary = instruction as BinaryOp;
                if (binary != null)
                {
                    int j = m_info.Tracker.GetStackIndex(instruction.Index, 0);
                    int k = m_info.Tracker.GetStackIndex(instruction.Index, 1);

                    if (j >= 0 && k >= 0)
                    {
                        if (DoIsFloat(j) && DoIsFloat(k))
                        {
                            return(true);
                        }
                    }
                }

                if (instruction.Untyped.OpCode.Code == Code.Conv_R4 || instruction.Untyped.OpCode.Code == Code.Conv_R8 || instruction.Untyped.OpCode.Code == Code.Conv_R_Un)
                {
                    return(true);
                }

                Call call = instruction as Call;
                if (call != null)
                {
                    type = call.Target.ReturnType.ReturnType;
                    break;
                }
            }while (false);

            return(type != null && (type.FullName == "System.Single" || type.FullName == "System.Double"));
        }
Пример #26
0
 public CmdLineModuleElement(LoadArg l)
 {
     base["type"]       = l.ToString();
     base["properties"] = _properties;
 }
Пример #27
0
        private bool DoIsBad(int index)
        {
            bool bad = false;

            do
            {
                LoadArg arg = m_info.Instructions[index] as LoadArg;
                if (arg != null && arg.Arg >= 1)
                {
                    Log.DebugLine(this, "arg: {0}", arg.Arg);

                    ParameterDefinition p = m_info.Method.Parameters[arg.Arg - 1];
                    Log.DebugLine(this, "param {0} is of type {1}", arg.Arg, p.ParameterType.FullName);
                    if (DoIsBad(p.ParameterType))
                    {
                        bad = true;
                    }
                    break;
                }

                LoadLocal local = m_info.Instructions[index] as LoadLocal;
                if (local != null)
                {
                    Log.DebugLine(this, "local: {0}", local.Variable);

                    TypeReference type = m_info.Method.Body.Variables[local.Variable].VariableType;
                    Log.DebugLine(this, "local {0} is of type {1}", local.Variable, type.FullName);
                    if (DoIsBad(type))
                    {
                        bad = true;
                    }
                    break;
                }

                LoadField field = m_info.Instructions[index] as LoadField;
                if (field != null)
                {
                    Log.DebugLine(this, "field: {0}", field.Field.Name);

                    TypeReference type = field.Field.FieldType;
                    Log.DebugLine(this, "field {0} is of type {1}", field.Field.Name, type.FullName);
                    if (DoIsBad(type))
                    {
                        bad = true;
                    }
                    break;
                }

                LoadStaticField sfield = m_info.Instructions[index] as LoadStaticField;
                if (sfield != null)
                {
                    Log.DebugLine(this, "static field: {0}", sfield.Field.Name);

                    TypeReference type = sfield.Field.FieldType;
                    Log.DebugLine(this, "static field {0} is of type {1}", sfield.Field.Name, type.FullName);
                    if (DoIsBad(type))
                    {
                        bad = true;
                    }
                    break;
                }
            }while (false);

            return(bad);
        }