Ejemplo n.º 1
0
 public void VisitLoadField(LoadField load)
 {
     if (m_equality != null)
     {
         DoFieldRef(load.Field, load.Index);
     }
 }
Ejemplo n.º 2
0
        private bool DoCallsExternalCode(Call call, ref string name)
        {
            if (call.Target.Name == "Invoke" && call.Target.HasThis)
            {
                int i = call.GetThisIndex(m_info);
                Log.DebugLine(this, "found invoke call at {0:X2}", call.Untyped.Offset);

                if (i >= 0)
                {
                    LoadField load = m_info.Instructions[i] as LoadField;
                    if (load != null)
                    {
                        Log.DebugLine(this, "   this pointer is at {0:X2}", load.Untyped.Offset);
                        if (load.Field.FieldType.IsSameOrSubclassOf("System.Delegate", Cache))
                        {
                            Log.DebugLine(this, "   and is a delegate type");
                            name = load.Field.ToString();
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
Ejemplo n.º 3
0
        protected override void VisitLoadField(LoadField downNode, object o)
        {
            ObjectReferenceValue obj = this.state.Stack.Pop() as ObjectReferenceValue;
            PointerValue         ptr = new PointerToObjectFieldValue(obj.Obj, downNode.Field);

            this.loadVar(downNode, ptr, o);
        }
Ejemplo n.º 4
0
        Expression ProcessVertexBuffer(StageValue vertexBuffer)
        {
            Expression result;

            if (!VertexBuffers.TryGetValue(vertexBuffer.Value.ToString(), out result))
            {
                var src  = vertexBuffer.Value.Source;
                var type = ILFactory.GetType(src, "Uno.Graphics.VertexBuffer");

                if (vertexBuffer.Value.ReturnType.Equals(type))
                {
                    result = ProcessStage(vertexBuffer, MetaStage.Volatile, MetaStage.Volatile).Value;
                    VertexBuffers.Add(vertexBuffer.Value.ToString(), result);
                    return(result);
                }

                var loc = LocationStack.Last();
                var mp  = GetProperty(loc);

                var name  = CreateFieldName(mp, loc);
                var owner = Path.DrawBlock.Method.DeclaringType;

                var field = new Field(src, owner, name, null, Modifiers.Private | Modifiers.Generated, 0, type);
                owner.Fields.Add(field);

                result = new LoadField(src, new This(src, owner), field);
                VertexBuffers.Add(vertexBuffer.Value.ToString(), result);

                if (vertexBuffer.MinStage > MetaStage.Volatile)
                {
                    Log.Error(src, ErrorCode.E5025, "Vertex buffer cannot be accessed from " + vertexBuffer.MinStage + " stage");
                    return(result);
                }
                else if (vertexBuffer.MinStage == MetaStage.Volatile)
                {
                    InitScope.Statements.Add(
                        new StoreField(src, new This(src, owner), field,
                                       ILFactory.NewObject(src, "Uno.Graphics.VertexBuffer",
                                                           ILFactory.GetExpression(src, "Uno.Graphics.BufferUsage.Dynamic"))));

                    FrameScope.Statements.Add(
                        ILFactory.CallMethod(src, new LoadField(src, new This(src, owner), field), "Update",
                                             vertexBuffer.Value));
                }
                else
                {
                    InitScope.Statements.Add(
                        new StoreField(src, new This(src, owner), field,
                                       ILFactory.NewObject(src, "Uno.Graphics.VertexBuffer",
                                                           vertexBuffer.Value,
                                                           ILFactory.GetExpression(src, "Uno.Graphics.BufferUsage.Immutable"))));
                }

                FreeScope.Statements.Add(
                    ILFactory.CallMethod(src, new LoadField(src, new This(src, owner), field), "Dispose"));
            }

            return(result);
        }
Ejemplo n.º 5
0
        public Expression ThisInside(Expression thisExpr)
        {
            var loadFirstField = new LoadField(Source.Unknown, thisExpr, Type.Fields[0]);

            if (Parent == null)
            {
                return(loadFirstField);
            }
            else
            {
                return(Parent.ThisInside(loadFirstField));
            }
        }
Ejemplo n.º 6
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);
        }
Ejemplo n.º 7
0
            protected internal override void VisitLoadField(LoadField node, object data)
            {
                StackTypes stack = data as StackTypes;

                if (node.Field.IsStatic)
                {
                    stack.Push(node.Field.FieldType);
                }
                else
                {
                    Verifier.ProcessLdFld(stack, node.Field, false);
                }
                AddTask(node.Next, stack);
            }
Ejemplo n.º 8
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();
     }
 }
Ejemplo n.º 9
0
        protected override Statement TransformDraw(Draw draw)
        {
            var src   = draw.Source;
            var scope = new Scope(src);
            var field = GetField(draw);
            var obj   = new LoadField(src, new This(src, field.DeclaringType).Address, field).Address;
            var index = 0;

            foreach (var t in TerminalFields)
            {
                if (t.Value != draw.State.Terminals[t.Key].ToString())
                {
                    scope.Statements.Add(ILFactory.SetProperty(src, obj, t.Key, draw.State.Terminals[t.Key]));
                }
            }

            foreach (var v in draw.State.RuntimeConstants)
            {
                scope.Statements.Add(CallConst(src, obj, v, index++));
            }

            scope.Statements.Add(ILFactory.CallMethod(src, obj, "Use"));

            foreach (var v in draw.State.VertexAttributes)
            {
                scope.Statements.Add(CallAttrib(src, obj, v, index++));
            }
            foreach (var v in draw.State.Uniforms)
            {
                scope.Statements.Add(CallUniform(src, obj, v, index++));
            }
            foreach (var v in draw.State.PixelSamplers)
            {
                scope.Statements.Add(CallSampler(src, obj, v, index++));
            }

            scope.Statements.Add(draw.State.OptionalIndices == null
                ? ILFactory.CallMethod(src, obj,
                                       "DrawArrays",
                                       draw.State.Terminals["VertexCount"])
                : ILFactory.CallMethod(src, obj,
                                       "Draw",
                                       draw.State.Terminals["VertexCount"],
                                       draw.State.OptionalIndices.IndexType,
                                       draw.State.OptionalIndices.Buffer));

            return(draw.State.Terminals.ContainsKey("CullDrawable")
                ? (Statement) new IfElse(src, ILFactory.CallOperator(src, Essentials.Bool, "!", draw.State.Terminals["CullDrawable"]), scope)
                : scope);
        }
Ejemplo n.º 10
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;
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 11
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);
        }
Ejemplo n.º 12
0
 // ldfld bool Smokey.Tests.DisposeableTest/NoNullCheck2::m_disposed
 // brtrue IL_001d
 public void VisitConditional(ConditionalBranch branch)
 {
     if (m_disposable)
     {
         if (m_isNullaryDispose || m_isUnaryDispose)
         {
             if (branch.Index > 0)
             {
                 LoadField load = m_minfo.Instructions[branch.Index - 1] as LoadField;
                 if (load == null || load.Field.Name.IndexOf("m_disposed") < 0)                                  // testing m_disposed does not count as a branch for null checking
                 {
                     m_hasNoBranches = false;
                 }
             }
         }
     }
 }
Ejemplo n.º 13
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);
        }
Ejemplo n.º 14
0
 public void VisitLoadField(LoadField load)
 {
     if (m_needsCheck)
     {
         State state;
         if (m_fields.TryGetValue(load.Field, out state))
         {
             if (state == State.Defined)
             {
                 m_fields[load.Field] = State.Used;
             }
         }
         else
         {
             m_fields.Add(load.Field, State.Referenced);
         }
     }
 }
Ejemplo n.º 15
0
        // ldarg.0
        // ldfld string Smokey.Tests.EqualsMissesStateTest/Good1::m_name
        // ret
        private void DoTrivialGetter()
        {
            do
            {
                if (m_minfo.Instructions.Length != 3)
                {
                    break;
                }

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

                LoadField load = m_minfo.Instructions[1] as LoadField;
                if (load == null)
                {
                    break;
                }

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

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

                Log.DebugLine(this, "found trivial getter for {0}", load.Field.Name);
                string   name = m_minfo.Method.Name.Substring(4);
                Property prop = m_properties.SingleOrDefault(p => p.Name == name && p.Field == load.Field.Name);
                if (prop == null)
                {
                    prop = new Property(name, load.Field.Name);
                    m_properties.Add(prop);
                }
                prop.HasTrivialGetter = true;
            }while (false);
        }
Ejemplo n.º 16
0
        public static Expression TransformSwizzleToNewObject(this Swizzle s, Namescope scope)
        {
            // a.XYZ -> (temp = a, new T(temp.X, temp.Y, temp.Z))
            //   OR     new T(a.X, a.Y, a.Z)

            var obj = s.Object;
            var ind = TryCreateIndirection(scope, ref obj);

            var args = new Expression[s.Fields.Length];

            for (int i = 0; i < s.Fields.Length; i++)
            {
                args[i] = new LoadField(s.Source, obj, s.Fields[i]);
            }

            var result = new NewObject(s.Source, s.Constructor, args);

            return(ind != null
                ? (Expression) new SequenceOp(ind, result)
                :              result);
        }
Ejemplo n.º 17
0
        Expression AddCached(string type, Func <Expression> factory, params object[] descriptor)
        {
            if (descriptor.Length == 0)
            {
                throw new ArgumentException("Expected at least one descriptor");
            }

            var hash = type.GetHashCode();

            foreach (var e in descriptor)
            {
                hash = 13 * hash + (e ?? "<null>").ToString().GetHashCode();
            }

            var path = (descriptor[0] ?? "").ToString();

            if (path.IsValidPath())
            {
                type = Path.GetFileNameWithoutExtension(path);
            }

            Expression result;
            var        key = (type + hash.ToString("x8")).ToIdentifier();

            if (!_cache.TryGetValue(key, out result))
            {
                var value  = factory();
                var bundle = GetBundle(value.Source.Package);
                var field  = new Field(value.Source, bundle, key,
                                       null, Modifiers.Public | Modifiers.Static,
                                       FieldModifiers.ReadOnly, value.ReturnType);
                result = new LoadField(value.Source, null, field);
                bundle.Fields.Add(field);
                _fields[field] = value;
                _cache[key]    = result;
            }

            return(result);
        }
Ejemplo n.º 18
0
        private void DoGetReferences(Dictionary <MethodInfo, List <string> > references, MethodInfo info)
        {
            for (int i = 1; i < info.Instructions.Length; ++i)
            {
                do
                {
                    LoadField field = info.Instructions[i] as LoadField;
                    if (field != null)
                    {
                        if (info.Instructions.LoadsThisArg(i - 1))
                        {
                            DoAddReference(references, info, field.Field.Name, field.Untyped.Offset);
                        }
                        break;
                    }

                    LoadFieldAddress addr = info.Instructions[i] as LoadFieldAddress;
                    if (addr != null)
                    {
                        if (info.Instructions.LoadsThisArg(i - 1))
                        {
                            DoAddReference(references, info, addr.Field.Name, addr.Untyped.Offset);
                        }
                        break;
                    }

                    Call call = info.Instructions[i] as Call;
                    if (call != null && call.Target.Name.StartsWith("get_"))
                    {
                        if (info.Instructions.LoadsThisArg(i - 1))
                        {
                            DoAddReference(references, info, call.Target.Name, call.Untyped.Offset);
                        }
                        break;
                    }
                }while (false);
            }
        }
Ejemplo n.º 19
0
        private FieldReference DoSaveLocks(Call call)
        {
            FieldReference field = null;

            // Look for a lock using one of our fields.
            if (DoMatchLock1(call.Index))
            {
                LoadStaticField sload = (LoadStaticField)m_info.Instructions[call.Index - 3];
                if (sload.Field.DeclaringType == m_info.Type)
                {
                    field = sload.Field;
                }
            }
            else if (DoMatchLock2(call.Index))
            {
                LoadField load = (LoadField)m_info.Instructions[call.Index - 3];
                field = load.Field;
            }

            // If we found one then record that the method locked the field.
            if (field != null)
            {
                List <FieldReference> fields;

                if (!m_current.Locked.TryGetValue(m_info.Method, out fields))
                {
                    fields = new List <FieldReference>();
                    m_current.Locked.Add(m_info.Method, fields);
                }

                fields.Add(field);
                Log.DebugLine(this, "{0} locks {1}", m_info.Method.Name, field.Name);
            }

            return(field);
        }
Ejemplo n.º 20
0
 protected override void VisitLoadField(LoadField node, object data)
 {
     state.Stack.Perform_LoadField(node.Field, out exc);
     nextNode = node.Next;
 }
Ejemplo n.º 21
0
 public void VisitLoadField(LoadField load)
 {
     DoAddField(load.Field);
 }
Ejemplo n.º 22
0
        public static MethodBodyBlock Convert(MethodEx method)
        {
            if (!method.IsVerified)
            {
                throw new ConvertionException();
            }
            MethodInfoExtention _method_  = new MethodInfoExtention(method.Method);
            MethodBodyBlock     mainBlock = new MethodBodyBlock(_method_.GetReturnType().type);

            mainBlock.Options["StackTypes"] = new StackTypes();
            Block currentBlock = mainBlock;

            Node[] heads = new Node[method.Count];
            Node[] tails = new Node[method.Count];
            Node   head = null;
            Node   tail = null;
            Node   firstBlock = null;
            Node   lastBlock = null;
            int    iNum, iNumNext;

            Variable[]    locals        = new Variable[method.Locals.Count];
            Variable[]    args          = new Variable[_method_.ArgCount];
            VariablesList methodVarList = mainBlock.Variables;

            for (int i = 0; i < args.Length; i++)
            {
                args[i]      = methodVarList.CreateVar(_method_.GetArgType(i).type, VariableKind.Parameter);
                args[i].Name = "Arg" + i;
//				methodVarList.Add(args[i]);
            }
            for (int i = 0; i < locals.Length; i++)
            {
                locals[i]      = methodVarList.CreateVar(method.Locals[i], VariableKind.Local);
                locals[i].Name = "Loc" + i;
//				methodVarList.Add(locals[i]);
            }

            BlockType nextBlockType;
            int       nextBlockStart = -1;
            int       nextBlockEnd   = 1 << 30;
            int       nextBlockIndex;
            Type      nextCatchBlockType;
            Hashtable tryBlocks    = new Hashtable();
            Hashtable filterBlocks = new Hashtable();
            Stack     blockEnds    = new Stack();

            blockEnds.Push(method.Count);
            FindNextBlockStart(method.EHClauses, out nextBlockType, ref nextBlockStart, ref nextBlockEnd, out nextCatchBlockType, out nextBlockIndex);

            //Nodes and blocks creation, blocks linkage
            for (iNum = 0; iNum < method.Count; iNum++)
            {
                while (iNum == (int)blockEnds.Peek())
                {
                    currentBlock = currentBlock.Parent;
                    blockEnds.Pop();
                }

                firstBlock = null;
                lastBlock  = null;
                Node thisBlock = null;
                while (iNum == nextBlockStart)
                {
                    Block currentBlockOld = currentBlock;

                    switch (nextBlockType)
                    {
                    case BlockType.Try:
                        currentBlock = new ProtectedBlock();
                        break;

                    case BlockType.Catch:
                        currentBlock = new CatchBlock(nextCatchBlockType);
                        break;

                    case BlockType.Finally:
                        currentBlock = new FinallyBlock(false);
                        break;

                    case BlockType.Filter:
                        currentBlock = new FilterBlock();
                        break;

                    case BlockType.FilteredCatch:
                        currentBlock = new UserFilteredBlock();
                        break;
                    }

                    currentBlock.setParent(currentBlockOld);

                    blockEnds.Push(nextBlockEnd);
                    if (thisBlock == null)
                    {
                        thisBlock = firstBlock = currentBlock;
                    }
                    else
                    {
                        thisBlock.Next = currentBlock;
                        thisBlock      = currentBlock;
                    }
                    switch (nextBlockType)
                    {
                    case BlockType.Try:
                        tryBlocks.Add(new Segment(nextBlockStart, nextBlockEnd), thisBlock);
                        break;

                    case BlockType.Filter:
                        filterBlocks.Add(new Segment(nextBlockStart, nextBlockEnd), thisBlock);
                        break;

                    case BlockType.Finally:
                    case BlockType.Catch:
                    {
                        Segment        tryBlockKey = FindProtectedBlock(method.EHClauses, nextBlockIndex);
                        ProtectedBlock tryBlock    = tryBlocks[tryBlockKey] as ProtectedBlock;
                        tryBlock.AddHandler(thisBlock as EHBlock);
                    }       break;

                    case BlockType.FilteredCatch:
                    {
                        Segment        tryBlockKey = FindProtectedBlock(method.EHClauses, nextBlockIndex);
                        ProtectedBlock tryBlock    = tryBlocks[tryBlockKey] as ProtectedBlock;
                        tryBlock.AddHandler(thisBlock as EHBlock);

                        Segment     filterKey   = FindFilterBlock(method.EHClauses, nextBlockIndex);
                        FilterBlock filterBlock = filterBlocks[filterKey] as FilterBlock;
                        (thisBlock as UserFilteredBlock).Filter = filterBlock;
                    }       break;
                    }
                    FindNextBlockStart(method.EHClauses, out nextBlockType, ref nextBlockStart, ref nextBlockEnd, out nextCatchBlockType, out nextBlockIndex);
                }
                lastBlock = thisBlock;

                Instruction i = method[iNum];
                switch (i.Code)
                {
                case InstructionCode.NEG:
                case InstructionCode.NOT:
                {
                    head = tail = new UnaryOp(UnaryOpFromCode(i.Code));
                    /*!*/ head.setParent(currentBlock);
                } break;

                case InstructionCode.ADD:
                case InstructionCode.AND:
                case InstructionCode.CEQ:
                case InstructionCode.CGT:
                case InstructionCode.CLT:
                case InstructionCode.DIV:
                case InstructionCode.MUL:
                case InstructionCode.OR:
                case InstructionCode.REM:
                case InstructionCode.SHL:
                case InstructionCode.SHR:
                case InstructionCode.SUB:
                case InstructionCode.XOR:
                {
                    head = tail = new BinaryOp(BinaryOpFromCode(i.Code), i.OverflowFlag, i.UnsignedFlag);
                    /*!*/ head.setParent(currentBlock);
                } break;

                case InstructionCode.LDC:
                    head = tail = new LoadConst(i.Param);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDARG:
                    head = tail = new LoadVar(args[(int)(i.Param)]);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDLOC:
                    head = tail = new LoadVar(locals[(int)(i.Param)]);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDARGA:
                    head = tail = new LoadVarAddr(args[(int)(i.Param)]);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDLOCA:
                    head = tail = new LoadVarAddr(locals[(int)(i.Param)]);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDIND:
                    head = tail = new LoadIndirect(i.TypeBySuffixOrParam());
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDFLD:
                {
                    FieldInfo field = i.Param as FieldInfo;
                    if (field.IsStatic)
                    {
                        head = new RemoveStackTop();
                        /*!*/ head.setParent(currentBlock);
                        //remove the object instance when accessing the static field with LDFLD
                        tail = new LoadField(field);
                        /*!*/ tail.setParent(currentBlock);
                        head.Next = tail;
                    }
                    else
                    {
                        head = tail = new LoadField(field);
                        /*!*/ head.setParent(currentBlock);
                    }
                }       break;

                case InstructionCode.LDFLDA:
                {
                    FieldInfo field = i.Param as FieldInfo;
                    if (field.IsStatic)
                    {
                        head = new RemoveStackTop();
                        /*!*/ head.setParent(currentBlock);
                        tail = new LoadFieldAddr(field);
                        /*!*/ tail.setParent(currentBlock);
                        head.Next = tail;
                    }
                    else
                    {
                        head = tail = new LoadFieldAddr(field);
                        /*!*/ head.setParent(currentBlock);
                    }
                }       break;

                case InstructionCode.LDSFLD:
                    head = tail = new LoadField(i.Param as FieldInfo);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDSFLDA:
                    head = tail = new LoadFieldAddr(i.Param as FieldInfo);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDELEM:
                    head = tail = new LoadElement(i.TypeBySuffixOrParam());
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDELEMA:
                    head = tail = new LoadElementAddr(i.TypeBySuffixOrParam());
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDOBJ:
                    head = tail = new LoadIndirect(i.Param as Type);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.SIZEOF:
                    head = tail = new LoadSizeOfValue(i.Param as Type);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDLEN:
                    head = tail = new LoadLength();
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDTOKEN:
                    if (i.Param is Type)
                    {
                        head = tail = new LoadConst((i.Param as Type).TypeHandle);
                    }
                    else if (i.Param is MethodBase)
                    {
                        head = tail = new LoadConst((i.Param as MethodBase).MethodHandle);
                    }
                    else if (i.Param is FieldInfo)
                    {
                        head = tail = new LoadConst((i.Param as FieldInfo).FieldHandle);
                    }
                    else
                    {
                        throw new ConvertionException();
                    }
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDNULL:
                    head = tail = new LoadConst(null);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDSTR:
                    head = tail = new LoadConst(i.Param);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.STARG:
                    head = tail = new StoreVar(args[(int)(i.Param)]);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.STLOC:
                    head = tail = new StoreVar(locals[(int)(i.Param)]);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.STIND:
                    head = tail = new StoreIndirect(i.TypeBySuffixOrParam());
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.STFLD:
                {
                    FieldInfo field = i.Param as FieldInfo;
                    if (field.IsStatic)
                    {
                        head = new StoreField(field);
                        /*!*/ head.setParent(currentBlock);
                        tail = new RemoveStackTop();
                        /*!*/ tail.setParent(currentBlock);
                        head.Next = tail;
                    }
                    else
                    {
                        head = tail = new StoreField(i.Param as FieldInfo);
                        /*!*/ head.setParent(currentBlock);
                    }
                }       break;

                case InstructionCode.STSFLD:
                    head = tail = new StoreField(i.Param as FieldInfo);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.STELEM:
                    head = tail = new StoreElement(i.TypeBySuffixOrParam());
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.STOBJ:
                    head = tail = new StoreIndirect(i.Param as Type);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.CPOBJ:
                    head = new LoadIndirect(i.Param as Type);
                    /*!*/ head.setParent(currentBlock);
                    tail = new StoreIndirect(i.Param as Type);
                    /*!*/ tail.setParent(currentBlock);
                    head.Next = tail;
                    break;

                case InstructionCode.DUP:
                    head = tail = new DuplicateStackTop();
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.CALL:
                    head = tail = new CallMethod(i.Param as MethodBase, false, i.HasTail);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.CALLVIRT:
                    MethodInfo callee = i.Param as MethodInfo;
                    head = tail = new CallMethod(callee, callee.IsVirtual, i.HasTail);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.NEWOBJ:
                { ConstructorInfo ctor = i.Param as ConstructorInfo;
                  if (Verifier.IsDelegate(ctor.DeclaringType))
                  {
                      if (Verifier.IsInstanceDispatch(method, iNum))
                      {
                          heads[iNum - 1] = tails[iNum - 1] = null;
                          head            = tail = new CreateDelegate(ctor, method[iNum - 1].Param as MethodInfo, false);
                      }
                      else if (Verifier.IsVirtualDispatch(method, iNum))
                      {
                          heads[iNum - 2] = tails[iNum - 2] = null;
                          heads[iNum - 1] = tails[iNum - 1] = null;
                          head            = tail = new CreateDelegate(ctor, method[iNum - 1].Param as MethodInfo, true);
                      }
                  }
                  else
                  {
                      head = tail = new NewObject(ctor);
                  }
                  /*!*/ head.setParent(currentBlock); }       break;

                case InstructionCode.NEWARR:
                    head = tail = new NewArray(i.Param as Type);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.INITOBJ:
                    head = tail = new InitValue(i.Param as Type);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.ISINST:
                    head = tail = new CastClass(i.Param as Type, false);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.CASTCLASS:
                    head = tail = new CastClass(i.Param as Type, true);
                    /*!*/ head.setParent(currentBlock);
                    break;


                case InstructionCode.BOX:
                    head = tail = new BoxValue(i.Param as Type);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.UNBOX:
                    head = tail = new UnboxValue(i.Param as Type);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.CONV:
                    head = tail = new ConvertValue(i.TypeBySuffixOrParam(), i.OverflowFlag, i.UnsignedFlag);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.POP:
                    head = tail = new RemoveStackTop();
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.BEQ:
                    head = new BinaryOp(BinaryOp.ArithOp.CEQ, false, false);
                    /*!*/ head.setParent(currentBlock);
                    tail = new Branch();
                    /*!*/ tail.setParent(currentBlock);
                    head.Next = tail;
                    break;

                case InstructionCode.BNE:
                    head = new BinaryOp(BinaryOp.ArithOp.CEQ, false, false);
                    /*!*/ head.setParent(currentBlock);
                    tail = new Branch();
                    /*!*/ tail.setParent(currentBlock);
                    head.Next = tail;
                    break;

                case InstructionCode.BGE:
                    if (TypeFixer.IsFloatOrCompatible(i.Stack.Top()))
                    {
                        head = new BinaryOp(BinaryOp.ArithOp.CLT, false, !i.UnsignedFlag);
                    }
                    else
                    {
                        head = new BinaryOp(BinaryOp.ArithOp.CLT, false, i.UnsignedFlag);
                    }
                    tail = new Branch();
                    /*!*/ head.setParent(currentBlock);
                    /*!*/ tail.setParent(currentBlock);
                    head.Next = tail;
                    break;

                case InstructionCode.BGT:
                    head = new BinaryOp(BinaryOp.ArithOp.CGT, false, i.UnsignedFlag);
                    tail = new Branch();
                    /*!*/ head.setParent(currentBlock);
                    /*!*/ tail.setParent(currentBlock);
                    head.Next = tail;
                    break;

                case InstructionCode.BLE:
                    if (TypeFixer.IsFloatOrCompatible(i.Stack.Top()))
                    {
                        head = new BinaryOp(BinaryOp.ArithOp.CGT, false, !i.UnsignedFlag);
                    }
                    else
                    {
                        head = new BinaryOp(BinaryOp.ArithOp.CGT, false, i.UnsignedFlag);
                    }
                    tail = new Branch();
                    /*!*/ head.setParent(currentBlock);
                    /*!*/ tail.setParent(currentBlock);
                    head.Next = tail;
                    break;

                case InstructionCode.BLT:
                    head = new BinaryOp(BinaryOp.ArithOp.CLT, false, i.UnsignedFlag);
                    tail = new Branch();
                    /*!*/ head.setParent(currentBlock);
                    /*!*/ tail.setParent(currentBlock);
                    head.Next = tail;
                    break;

                case InstructionCode.BRTRUE:
                    head = tail = new Branch();
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.BRFALSE:
                    head = tail = new Branch();
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.SWITCH:
                    head = tail = new Switch((i.Param as int[]).Length);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.BR:
                case InstructionCode.NOP:
                case InstructionCode.BREAK:
                case InstructionCode.LDFTN:                             // Expecting further delegate construction...
                case InstructionCode.LDVIRTFTN:                         //
                    head = tail = new DummyNode();
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.THROW:
                    head = tail = new ThrowException();
                    /*!*/ head.setParent(currentBlock);
                    break;


                case InstructionCode.RET:
                case InstructionCode.ENDFINALLY:
                case InstructionCode.ENDFILTER:
                case InstructionCode.LEAVE:
                    head = tail = new Leave();
                    /*!*/ head.setParent(currentBlock);
                    break;

                default:
                    throw new ConvertionException();
                }
                if (head != null)
                {
                    head.Options["StackTypes"] = i.Stack.Clone() as StackTypes;
                }
                if (head != tail)                //=>   head :: BinaryOp, tail :: Branch
                //||   head :: LoadIndirect, tail :: StoreIndirect
                {
                    if (head is BinaryOp && tail is Branch)
                    {
                        StackTypes stack = i.Stack.Clone() as StackTypes;
                        stack.Pop();
                        stack.Pop();
                        stack.Push(typeof(int));
                        tail.Options["StackTypes"] = stack;
                    }
                    else if (head is LoadIndirect && tail is StoreIndirect)
                    {
                        StackTypes stack = i.Stack.Clone() as StackTypes;
                        TypeEx     type  = stack.Pop();                    //type == S&
                        stack.Push(type.type.GetElementType());
                        tail.Options["StackTypes"] = stack;
                    }
                }
                if (firstBlock != null)
                {
                    lastBlock.Next = head;
                    for (Node n = firstBlock; n != head; n = n.Next)
                    {
                        n.Options["StackTypes"] = i.Stack.Clone() as StackTypes;
                    }
                    head = firstBlock;
                    if (tail == null)
                    {
                        tail = lastBlock;                         //This may occure what the NOP instruction starts some block
                    }
                }
                heads[iNum] = head;
                tails[iNum] = tail;
            }            //for
            mainBlock.Next = heads[0];
            //Control flow linkage
            for (iNum = 0; iNum < method.Count; iNum++)
            {
                if (heads[iNum] == null)
                {
                    throw new ConvertionException();                     //impossible :)
                }
                Instruction i = method[iNum];

                switch (i.Code)
                {
                case InstructionCode.BR:
                case InstructionCode.LEAVE:
                    tails[iNum].Next = heads[(int)i.Param];
                    break;

                case InstructionCode.RET:
                case InstructionCode.ENDFINALLY:
                case InstructionCode.ENDFILTER:
                case InstructionCode.THROW:
                case InstructionCode.RETHROW:
                    break;

                case InstructionCode.BRFALSE:                     //false
                case InstructionCode.BGE:                         //false
                case InstructionCode.BLE:                         //false
                case InstructionCode.BNE:                         //false
                    tails[iNum].Next            = heads[(int)i.Param];
                    (tails[iNum] as Branch).Alt = heads[iNum + 1];
                    break;

                case InstructionCode.BRTRUE:                      //true
                case InstructionCode.BEQ:                         //true
                case InstructionCode.BGT:                         //true
                case InstructionCode.BLT:                         //true
                    tails[iNum].Next            = heads[iNum + 1];
                    (tails[iNum] as Branch).Alt = heads[(int)i.Param];
                    break;

                case InstructionCode.SWITCH:
                    tails[iNum].Next = heads[iNum + 1];
                    Switch node = tails[iNum] as Switch;
                    int[]  alt  = i.Param as int[];
                    for (int j = 0; j < node.Count; j++)
                    {
                        node[j] = heads[alt[j]];
                    }
                    break;

                default:
                    tails[iNum].Next = heads[iNum + 1];
                    break;
                }
            }

            //Removing DummyNodes
            for (iNum = 0; iNum < method.Count; iNum++)
            {
                if (heads[iNum] is DummyNode)
                {
                    Node   dummy = heads[iNum];
                    Node[] prev  = new Node[dummy.PrevArray.Count];
                    for (int j = 0; j < prev.Length; j++)
                    {
                        prev[j] = dummy.PrevArray[j];
                    }
                    for (int j = 0; j < prev.Length; j++)
                    {
                        prev[j].NextArray[prev[j].NextArray.IndexOf(dummy)] = dummy.Next;
                    }
                    dummy.RemoveFromGraph();
                }
            }


            return(mainBlock);
        }
Ejemplo n.º 23
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);
        }
Ejemplo n.º 24
0
 public void WriteLoadField(LoadField s, ExpressionUsage u)
 {
     WriteLoadField(s.Source, s.Field, s.Object, u);
 }
Ejemplo n.º 25
0
 public void VisitLoadField(LoadField field)
 {
     DoAdd(field.Field.FieldType);
 }
Ejemplo n.º 26
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);
        }
Ejemplo n.º 27
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"));
        }
Ejemplo n.º 28
0
 protected internal virtual void VisitLoadField(LoadField node, object data)
 {
     throw new NodeNotSupportedException(node);
 }