/// <summary>
        /// Decodes the specified CIL instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        /// <remarks>
        /// This method is used by instructions to retrieve immediate operands
        /// From the instruction stream.
        /// </remarks>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            int index;

            // Opcode specific handling
            switch (opcode)
            {
            case OpCode.Ldarg:
            case OpCode.Ldarg_s: index = (int)decoder.Instruction.Operand; break;

            case OpCode.Ldarg_0: index = 0; break;

            case OpCode.Ldarg_1: index = 1; break;

            case OpCode.Ldarg_2: index = 2; break;

            case OpCode.Ldarg_3: index = 3; break;

            default: throw new System.NotImplementedException();
            }

            // Push the loaded value onto the evaluation stack
            var parameterOperand = decoder.Compiler.GetParameterOperand(index);
            var result           = LoadInstruction.CreateResultOperand(decoder, parameterOperand.Type);

            ctx.Operand1 = parameterOperand;
            ctx.Result   = result;
        }
示例#2
0
        public override void Visit(LoadInstruction instruction)
        {
            base.Visit(instruction);

            // method argument is assigned
            // thus violating corral's requirements
            if (methodBody.Parameters.Contains(instruction.Result))
            {
                // check if it was processed already
                if (argumentToNewVariable.ContainsKey(instruction.Result))
                {
                    return;
                }

                // creates new copy of the assigned argument
                // creates a load instruction for to set original argument value to the new local copy
                // the new local copy will replace the use of the argument

                var newVar  = AddNewLocalVariable(instruction.Result);
                var newLoad = new LoadInstruction(0, newVar, instruction.Result);
                newLoad.Label = String.Empty;
                newLoads.Add(newLoad);
                argumentToNewVariable.Add(instruction.Result, newVar);
            }
        }
 public LoadJob Load(LoadInstruction instruction)
 {
     // do load via adaptor
     var loadJob = (LoadJob)InvokeAdaptor("Load", instruction);
     this.EnqueueJob(loadJob);
     return loadJob;
 }
示例#4
0
 public Form1()
 {
     InitializeComponent();
     string[] args = Environment.GetCommandLineArgs();
     ReadXls.onSheetChoise += this.getXlsSheet;
     loadInstruction        = new LoadInstruction(this);
 }
    public LoadJob Load(LoadInstruction instruction)
    {
        // do load via adaptor
        var loadJob = (LoadJob)InvokeAdaptor("Load", instruction);

        this.EnqueueJob(loadJob);
        return(loadJob);
    }
示例#6
0
 public override void Visit(LoadInstruction instruction)
 {
     if (instruction.Operand is Constant)
     {
         var value = ExtractConstant(instruction.Operand as Constant);
         this.State.SetValue(instruction.Result, value);
     }
     if (instruction.Operand is IVariable)
     {
         this.State.SetValue(instruction.Result, this.State.GetValue(instruction.Operand as IVariable));
     }
 }
示例#7
0
            private bool HandleLoadWithOperand(LoadInstruction load, IValue operand)
            {
                var result = true;

                if (operand is Constant)
                {
                    var constant = operand as Constant;

                    if (constant.Value == null)
                    {
                        ptAnalysis.ProcessNull(State, load.Result);
                    }
                }
                if (operand is IVariable)
                {
                    var variable = operand as IVariable;
                    ptAnalysis.ProcessCopy(State, load.Result, variable);
                }
                else if (operand is InstanceFieldAccess)
                {
                    var access = operand as InstanceFieldAccess;
                    ptAnalysis.ProcessLoad(State, load.Offset, load.Result, access.Instance, access.Field);
                }
                else if (operand is StaticFieldAccess)
                {
                    var access = operand as StaticFieldAccess;
                    ptAnalysis.ProcessLoad(State, load.Offset, load.Result, IteratorPointsToAnalysis.GlobalVariable, access.Field);
                }
                else if (operand is ArrayElementAccess)
                {
                    var arrayAccess = operand as ArrayElementAccess;
                    var baseArray   = arrayAccess.Array;
                    ptAnalysis.ProcessLoad(State, load.Offset, load.Result, baseArray, new FieldReference("[]", operand.Type, this.ptAnalysis.method.ContainingType));
                }
                else if (operand is VirtualMethodReference)
                {
                    var loadDelegateStmt = operand as VirtualMethodReference;
                    var methodRef        = loadDelegateStmt.Method;
                    var instance         = loadDelegateStmt.Instance;
                    ptAnalysis.ProcessDelegateAddr(State, load.Offset, load.Result, methodRef, instance);
                }
                else if (operand is StaticMethodReference)
                {
                    var loadDelegateStmt = operand as StaticMethodReference;
                    var methodRef        = loadDelegateStmt.Method;
                    ptAnalysis.ProcessDelegateAddr(State, load.Offset, load.Result, methodRef, null);
                }
                else
                {
                    result = false;
                }
                return(result);
            }
示例#8
0
            public override void Visit(LoadInstruction instruction)
            {
                if (instruction.Operand is Reference reference)
                {
                    // Reference object is an expression of the form &<...>
                    // <...> is the pointedObj
                    IReferenceable pointedObj = reference.Value;

                    if (pointedObj is InstanceFieldAccess ||
                        pointedObj is StaticFieldAccess)
                    {
                        return;
                    }

                    ReferenceFinder.AddReference(pointedObj);
                }
            }
示例#9
0
            public override void Visit(LoadInstruction instruction)
            {
                if (instruction.Operand is Reference reference)
                {
                    // Reference object is an expression of the form &<...>
                    // <...> is the pointedObj
                    IReferenceable pointedObj = reference.Value;

                    if (pointedObj is StaticFieldAccess staticFieldAccess)
                    {
                        FieldReferencedSet.Add(staticFieldAccess.Field);
                    }
                    else if (pointedObj is InstanceFieldAccess instanceFieldAccess)
                    {
                        FieldReferencedSet.Add(instanceFieldAccess.Field);
                    }
                }
            }
示例#10
0
            public override void Visit(LoadInstruction instruction)
            {
                SavePreState(instruction, FreshCurrent());
                var nstate = FreshCurrent();

                var operand = instruction.Operand;
                var result  = instruction.Result;

                if (operand is Dereference || operand is Reference)
                {
                    //TODO: make this more precise
                    UpdateStateNotConstant(nstate);
                }
                else if (IsConstantType(result.Type))
                {
                    if (operand is Constant)
                    {
                        var c = operand as Constant;
                        UpdateState(nstate, result, c);
                    }
                    else if (operand is IVariable)
                    {
                        var v = operand as IVariable;
                        UpdateStateCopy(nstate, result, v);
                    }
                    else if (operand is InstanceFieldAccess)
                    {
                        var ifa = operand as InstanceFieldAccess;
                        UpdateStateCopy(nstate, result, ifa.Field);
                    }
                    else if (operand is StaticFieldAccess)
                    {
                        var sfa = operand as StaticFieldAccess;
                        UpdateStateCopy(nstate, result, sfa.Field);
                    }
                    else
                    {
                        UpdateStateNotConstant(nstate, result);
                    }
                }

                SetCurrent(nstate);
                SavePostState(instruction, FreshCurrent());
            }
        public override void Visit(LoadInstruction instruction)
        {
            var operand = instruction.Operand;

            if (operand is VirtualMethodReference)
            {
                // DIEGO TODO: Maybe I will need to add the instance
                var loadDelegateStmt = operand as VirtualMethodReference;
                var methodRef        = loadDelegateStmt.Method;
                var instance         = loadDelegateStmt.Instance;
                methodVisitor.Delegates.Add(methodRef);
            }
            else if (operand is StaticMethodReference)
            {
                var loadDelegateStmt = operand as StaticMethodReference;
                var methodRef        = loadDelegateStmt.Method;
                methodVisitor.Delegates.Add(methodRef);
            }
        }
示例#12
0
            public override void Visit(LoadInstruction instruction)
            {
                if (instruction.Operand is StaticFieldAccess)
                {
                    var fieldAccess = (instruction.Operand as StaticFieldAccess);
                    var field       = fieldAccess.Field.ResolvedField;
                    if (field != null)
                    {
                        RangeDomain value;
                        if (RangeAnalysis.GlobalVariables.TryGetValue(field, out value))
                        {
                            this.State.SetValue(instruction.Result, value);
                        }
                    }
                }
                var source = instruction.Operand;
                var dest   = instruction.Result;

                Copy(source, dest);
            }
示例#13
0
            public override void Visit(LoadInstruction instruction)
            {
                var load = instruction as LoadInstruction;

                if (load.Operand is Constant)
                {
                }
                else if (load.Operand is IVariable)
                {
                    var variable = load.Operand as IVariable;
                    var lastDefs = depAnalysis.LastDefGet(variable);
                    depAnalysis.SetDataDependency((int)load.Offset, lastDefs);
                }

                else if (load.Operand is InstanceFieldAccess)
                {
                    var fieldAccess = load.Operand as InstanceFieldAccess;
                    var lastDefs    = depAnalysis.LastDefGet(fieldAccess.Instance, fieldAccess.Field, ptg);
                    depAnalysis.SetDataDependency((int)load.Offset, lastDefs);
                }
                depAnalysis.LastDefSet(load.Result, (int)load.Offset);
            }
示例#14
0
            public override void Visit(LoadInstruction instruction)
            {
                var load    = instruction as LoadInstruction;
                var operand = load.Operand;

                HandleLoadWithOperand(load, operand);

                if (operand is Reference)
                {
                    var referencedValue = (operand as Reference).Value;
                    var isHandled       = HandleLoadWithOperand(load, referencedValue);
                    if (!(referencedValue is IVariable))
                    {
                    }
                    addressMap[instruction.Result] = referencedValue;
                }
                else if (operand is Dereference)
                {
                    var reference = (operand as Dereference).Reference;
                    var isHandled = HandleLoadWithOperand(load, reference);
                }
            }
 // shortcut
 public static UnityLoadJob Load(LoadInstruction instruction)
 {
     return (UnityLoadJob)Module.Find<SinozeAssetLoader>().Load(instruction);
 }
 public void Visit(LoadInstruction instruction)
 {
     lines.Add($"{label}\tLOAD {instruction.Destination.GetAssemblySymbol()},{instruction.MemoryAddress.GetAssemblySymbol()}");
 }
示例#17
0
 public LoadJob(LoadInstruction instruction)
 {
     this.Instruction = instruction;
 }
 public override void Visit(LoadInstruction instruction)
 {
     instruction.Result.Type = instruction.Operand.Type;
 }
示例#19
0
 public virtual void Visit(LoadInstruction instruction)
 {
     Default(instruction);
 }
示例#20
0
            public override void Visit(LoadInstruction instruction)
            {
                var operandAsConstant = instruction.Operand as Constant;
                var operandAsVariable = instruction.Operand as IVariable;

                // Null is a polymorphic value so we handle it specially. We don't set the
                // corresponding variable's type yet. We postpone it to usage of the variable
                // or set it to System.Object if it is never used.
                if (operandAsConstant != null)
                {
                    if (operandAsConstant.Value == null)
                    {
                        instruction.Result.Type = Types.Instance.PlatformType.SystemObject;
                    }
                    else if (instruction.Result.Type != null &&
                             instruction.Result.Type.TypeCode == PrimitiveTypeCode.Boolean)
                    {
                        // If the result of the load has type Boolean,
                        // then we are actually loading a Boolean constant.
                        if (operandAsConstant.Value.Equals(0))
                        {
                            operandAsConstant.Value = false;
                            operandAsConstant.Type  = Types.Instance.PlatformType.SystemBoolean;
                        }
                        else if (operandAsConstant.Value.Equals(1))
                        {
                            operandAsConstant.Value = true;
                            operandAsConstant.Type  = Types.Instance.PlatformType.SystemBoolean;
                        }
                    }
                }
                // If we have variable to variable assignment where the result was assigned
                // a type but the operand was not, then we set the operand type accordingly.
                else if (operandAsVariable != null &&
                         instruction.Result.Type != null &&
                         (operandAsVariable.Type == null ||
                          operandAsVariable.Type == Types.Instance.PlatformType.SystemObject ||
                          instruction.Result.Type.TypeCode == PrimitiveTypeCode.Boolean))
                {
                    operandAsVariable.Type = instruction.Result.Type;
                }

                if (instruction.Result.Type == null)
                {
                    instruction.Result.Type = instruction.Operand.Type;
                }

                if (instruction.Operand is Dereference)
                {
                    var deref = instruction.Operand as Dereference;
                    // SRK (4th Oct 2019) instruction.Result.Type = deref.Reference.Type;
                    if (deref.Reference.Type.TypeCode == PrimitiveTypeCode.Reference && deref.Type != null)
                    {
                        instruction.Result.Type = deref.Type;
                    }
                    else
                    {
                        instruction.Result.Type = deref.Reference.Type;
                    }
                }

                if (instruction.Operand.Type != null && // we can be in the middle of the type inference analysis
                    instruction.Operand.Type is IManagedPointerType)
                {
                    instruction.Result.Type = instruction.Operand.Type;
                }
            }
示例#21
0
        public override void Visit(LoadInstruction instruction)
        {
            base.Visit(instruction);
            string name = instruction.Operand.ToString();
            var    v    = instruction.Operand as IVariable;

            /*
             *  // we want to detect code like this
             *  // and use in the method call i and j
             *  // in boogie the method will overwrite their values
             *
             *  local Int32 i;
             *  local Int32 j;
             *  local Int32* $r2;
             *  local Int32* $r3;
             *
             *  $r2 = &i;
             *  $r3 = &j;
             *  RefKeyword::Ref($r2, $r3);
             *
             *  // expected boogie (bct works like this)
             *  call i, j := RefKeyword::Ref(i, j);
             *  // we copy their values and then return a new value
             */

            if (instruction.Operand.Type is IManagedPointerType &&
                instruction.Operand is Reference &&
                IsInMethodCallAsRef(instruction.Result))
            {
                var r = instruction.Operand as Reference;
                instruction.Result.Type = r.Value.Type;
                instruction.Operand     = r.Value;
                //variableToParameter.Add(instruction.Result, r.Variables.First());
            }


            /*
             *  this check is used to detect ref/out parameters
             *
             *  parameter Int32* a;
             *  parameter Int32* b;
             *
             *  local Int32* $r0;
             *  local Int32 $r1;
             *  local Int32* $r2;
             *  local Int32 $r3;
             *
             *  LABEL_0:
             *          $r0 = a;
             *          $r1 = 10;
             *$r0 = $r1;
             *  LABEL_1:
             *          $r2 = b;
             *          $r3 = 11;
             *$r2 = $r3;
             *          return;
             *
             *  // we will ignore pointers and use them as their target types
             *  // that's why the aliasing in LABEL_0 and LABEL_1 wont work
             *  // we need to replace every use of $r0 by a and $r2 by b
             *
             *  // in boogie we return the new values of a and b (read previous comment)
             */

            if (instruction.HasResult && v != null && methodBody.Parameters.Contains(instruction.Operand) && IsRefArgument(v))
            {
                variableToParameter.Add(instruction.Result, v);
            }
        }
示例#22
0
        // some field initialization can be missing in constructors
        // example:

        /*
         * class Foo{
         *      int x; // this initialization is not added by the compiler
         *      int y = y;
         *  }
         */

        // therefore we are adding the initialization for each field at the top of every constructor.

        public void Transform()
        {
            // these variables hold the default value
            IDictionary <Helpers.BoogieType, LocalVariable> boogieTypeToLocalVariable =
                new Dictionary <Helpers.BoogieType, LocalVariable>();

            // they are the same stored in boogieTypeToLocalVariable
            IList <LocalVariable> variables
                = new List <LocalVariable>();

            // assignment of constants
            IList <Instruction> instructions
                = new List <Instruction>();

            CreateLocalVariablesWithDefaultValues(boogieTypeToLocalVariable, variables, instructions);

            // we need to initialize local variables.

            foreach (var lv in methodBody.Variables)
            {
                if (lv.IsParameter ||
                    // in the delegate handling this type of variables are not used
                    // calling get boogie type will crash
                    lv.Type is Microsoft.Cci.Immutable.FunctionPointerType)
                {
                    continue;
                }

                var       varBoogieType    = Helpers.GetBoogieType(lv);
                IVariable initialValue     = boogieTypeToLocalVariable[varBoogieType];
                var       storeInstruction = new LoadInstruction(0, lv, initialValue);
                storeInstruction.Label = String.Empty;
                instructions.Add(storeInstruction);
            }


            var fields = methodBody.MethodDefinition.ContainingTypeDefinition.Fields;

            if (methodBody.MethodDefinition.IsStaticConstructor)
            {
                foreach (IFieldDefinition field in fields.Where(f => f.IsStatic))
                {
                    var       fieldBoogieType  = Helpers.GetBoogieType(field);
                    IVariable initialValue     = boogieTypeToLocalVariable[fieldBoogieType];
                    var       staticAccess     = new StaticFieldAccess(field);
                    var       storeInstruction = new StoreInstruction(0, staticAccess, initialValue);
                    storeInstruction.Label = String.Empty;
                    instructions.Add(storeInstruction);
                }
            }
            else if (methodBody.MethodDefinition.IsConstructor)
            {
                var thisVariable = methodBody.Parameters[0];

                foreach (IFieldDefinition field in fields.Where(f => !f.IsStatic))
                {
                    var       fieldBoogieType  = Helpers.GetBoogieType(field);
                    IVariable initialValue     = boogieTypeToLocalVariable[fieldBoogieType];
                    var       instanceAccess   = new InstanceFieldAccess(thisVariable, field);
                    var       storeInstruction = new StoreInstruction(0, instanceAccess, initialValue);
                    storeInstruction.Label = String.Empty;
                    instructions.Add(storeInstruction);
                }
            }

            methodBody.Variables.UnionWith(variables);
            int idx = 0;

            foreach (var i in instructions)
            {
                methodBody.Instructions.Insert(idx, i);
                idx++;
            }
        }
示例#23
0
        // some field initialization can be missing in constructors
        // example:

        /*
         * class Foo{
         *      int x; // this initialization is not added by the compiler
         *      int y = y;
         *  }
         */

        // therefore we are adding the initialization for each field at the top of every constructor.

        public void Transform()
        {
            // these variables hold the default value
            IDictionary <Helpers.BoogieType, LocalVariable> boogieTypeToLocalVariable =
                new Dictionary <Helpers.BoogieType, LocalVariable>();

            // they are the same stored in boogieTypeToLocalVariable
            IList <LocalVariable> variables
                = new List <LocalVariable>();

            // assignment of constants
            IList <Instruction> instructions
                = new List <Instruction>();

            CreateLocalVariablesWithDefaultValues(boogieTypeToLocalVariable, variables, instructions);

            // we need to initialize local variables.

            foreach (var lv in methodBody.Variables)
            {
                if (lv.IsParameter ||
                    // in the delegate handling this type of variables are not used
                    // calling get boogie type will crash
                    lv.Type is Microsoft.Cci.Immutable.FunctionPointerType ||
                    (lv.Type is IManagedPointerType && Settings.AddressesEnabled()))
                {
                    continue;
                }

                var       varBoogieType    = Helpers.GetBoogieType(lv.Type);
                IVariable initialValue     = boogieTypeToLocalVariable[varBoogieType];
                var       storeInstruction = new LoadInstruction(0, lv, initialValue);
                storeInstruction.Label = String.Empty;
                instructions.Add(storeInstruction);
            }


            if (methodBody.MethodDefinition.IsConstructor)
            {
                IEnumerable <IFieldDefinition> fields = null;
                if (methodBody.MethodDefinition.ContainingTypeDefinition.IsGeneric)
                {
                    /*
                     *  This solves the issue of having a generic class (ie. class A<T>) and mismatches between field names.
                     *  If we just use ContaingTypeDefinition.Fields we have have a different IFieldDefinition than the ones found in the method bodies
                     *  Here, I want to be sure that we use A<T>.field as a field definition and not A.field
                     *  However, this could not be the ultimate solution and there could be a better way to tackle it.
                     */
                    var instanceOrSpecialized = TypeHelper.GetInstanceOrSpecializedNestedType(methodBody.MethodDefinition.ContainingTypeDefinition);
                    fields = instanceOrSpecialized.Fields;
                }
                else
                {
                    fields = methodBody.MethodDefinition.ContainingTypeDefinition.Fields;
                }

                var thisVariable = methodBody.Parameters[0];

                foreach (IFieldDefinition field in fields.Where(f => !f.IsStatic))
                {
                    var       fieldBoogieType  = Helpers.GetBoogieType(field.Type);
                    IVariable initialValue     = boogieTypeToLocalVariable[fieldBoogieType];
                    var       instanceAccess   = new InstanceFieldAccess(thisVariable, field);
                    var       storeInstruction = new StoreInstruction(0, instanceAccess, initialValue);
                    storeInstruction.Label = String.Empty;
                    instructions.Add(storeInstruction);
                }
            }

            methodBody.Variables.UnionWith(variables);
            int idx = 0;

            foreach (var i in instructions)
            {
                methodBody.Instructions.Insert(idx, i);
                idx++;
            }
        }
示例#24
0
 public virtual void Visit(LoadInstruction instruction)
 {
 }
 public UnityLoadJob Load(LoadInstruction instruction)
 {
     return new UnityLoadJob(instruction);
 }
示例#26
0
        public void VisitMethod(MethodBody mBody, ControlFlowGraph cfg)
        {
            VisitLocals(mBody);

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

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

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

            callerBody.Instructions.RemoveAt(index);

            Instruction nextInstruction = null;

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

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

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

            var lastCalleeInstructionIndex = calleeBody.Instructions.Count - 1;

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

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

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

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

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

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

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

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

                    instruction.Label = string.Format("{0}_{1}", methodCall.Label, instruction.Label);
                    callerBody.Instructions.Insert(index, instruction);
                    index++;
                }
            }
        }
示例#28
0
        private void ReadLoop(PHINode phi, BasicBlock oldBlock, BasicBlock testBlock)
        {
            // parse the input file and generate code for it
            Symbol currentSymbol = Symbol.None;
            Symbol nextSymbol = Symbol.None;
            Int32 currentValue = 0, nextValue = 0;
            Char c;
            Int32 direction;

            while (currentSymbol != Symbol.EOF && currentSymbol != Symbol.EndLoop)
            {
                switch (currentSymbol)
                {
                    case Symbol.None:
                        break;
                    case Symbol.Read:
                        {
                            CallInstruction getCharCall = this.builder.CreateCall(this.getcharFunction, "tape");
                            getCharCall.TailCall = false;

                            Value tape0 = (Value)getCharCall;
                            Value tape1 = this.builder.CreateTrunc(tape0, Type.GetInteger8Type(this.context), "tape");
                            builder.CreateStore(tape1, this.currentHead);
                        }
                        break;
                    case Symbol.Write:
                        {
                            LoadInstruction tape0 = this.builder.CreateLoad(this.currentHead, "tape");
                            Value tape1 = this.builder.CreateSignExtend(tape0, Type.GetInteger32Type(this.context), "tape");
                            CallInstruction putcharCall = this.builder.CreateCall(this.putcharFunction, tape1);
                            putcharCall.TailCall = false;
                        }
                        break;
                    case Symbol.Move:
                        this.currentHead = this.builder.CreateGEP(
                            this.currentHead,
                            new Constant(this.context, 32, (UInt64)currentValue),
                            "head");
                        break;
                    case Symbol.Change:
                        {
                            LoadInstruction tape0 = this.builder.CreateLoad(this.currentHead, "tape");
                            Value tape1 = this.builder.CreateAdd(tape0, new Constant(this.context, 8, (UInt64)currentValue), "tape");
                            this.builder.CreateStore(tape1, this.currentHead);
                        }
                        break;
                    case Symbol.Loop:
                        BasicBlock testbb = new BasicBlock(this.context, this.brainfFunction, "brainf");
                        this.builder.CreateBranch(testbb);

                        BasicBlock bb0 = this.builder.GetInsertBlock();
                        BasicBlock bb1 = new BasicBlock(this.context, this.brainfFunction, "brainf");
                        this.builder.SetInsertPoint(bb1);

                        PHINode phi0 = new PHINode(PointerType.GetUnqualified(Type.GetInteger8Type(this.context)), 2, "head", testbb);
                        phi0.AddIncomding(this.currentHead, bb0);
                        this.currentHead = phi0;

                        this.ReadLoop(phi0, bb1, testbb);

                        break;
                    default:
                        throw new Exception("Unknown symbol.");
                }

                currentSymbol = nextSymbol;
                currentValue = nextValue;
                nextSymbol = Symbol.None;

                bool loop = currentSymbol == Symbol.None ||
                    currentSymbol == Symbol.Move ||
                    currentSymbol == Symbol.Change;

                while (loop)
                {
                    if (this.reader.EndOfStream)
                    {
                        if (currentSymbol == Symbol.None) currentSymbol = Symbol.EOF;
                        else nextSymbol = Symbol.EOF;

                        loop = false;
                    }
                    else
                    {
                        c = (Char)this.reader.Read();
                        direction = 1;

                        switch (c)
                        {
                            case '-':
                                direction = -1;
                                goto case '+';
                            case '+':
                                if (currentSymbol == Symbol.Change)
                                {
                                    currentValue += direction;
                                }
                                else
                                {
                                    if (currentSymbol == Symbol.None)
                                    {
                                        currentSymbol = Symbol.Change;
                                        currentValue = direction;
                                    }
                                    else
                                    {
                                        nextSymbol = Symbol.Change;
                                        nextValue = direction;
                                        loop = false;
                                    }
                                }
                                break;
                            case '<':
                                direction = -1;
                                goto case '>';
                            case '>':
                                if (currentSymbol == Symbol.Move)
                                {
                                    currentValue += direction;
                                }
                                else
                                {
                                    if (currentSymbol == Symbol.None)
                                    {
                                        currentSymbol = Symbol.Move;
                                        currentValue = direction;
                                    }
                                    else
                                    {
                                        nextSymbol = Symbol.Move;
                                        nextValue = direction;
                                        loop = false;
                                    }
                                }
                                break;
                            case ',':
                                if (currentSymbol == Symbol.None)
                                    currentSymbol = Symbol.Read;
                                else
                                    nextSymbol = Symbol.Read;
                                loop = false;
                                break;
                            case '.':
                                if (currentSymbol == Symbol.None)
                                    currentSymbol = Symbol.Write;
                                else
                                    nextSymbol = Symbol.Write;
                                loop = false;
                                break;
                            case '[':
                                if (currentSymbol == Symbol.None)
                                    currentSymbol = Symbol.Loop;
                                else
                                    nextSymbol = Symbol.Loop;
                                loop = false;
                                break;
                            case ']':
                                if (currentSymbol == Symbol.None)
                                    currentSymbol = Symbol.EndLoop;
                                else
                                    nextSymbol = Symbol.EndLoop;
                                loop = false;
                                break;
                            default:
                                break;
                        }
                    }
                }
            }

            if (currentSymbol == Symbol.EndLoop)
            {
                if(phi == null)
                    throw new Exception("Unexpected ]");

                this.builder.CreateBranch(testBlock);

                phi.AddIncomding(this.currentHead, this.builder.GetInsertBlock());
                Value head0 = phi;

                LoadInstruction tape0 = new LoadInstruction(head0, "tape", testBlock);

                IntegerCompareInstruction test0 = new IntegerCompareInstruction(
                    testBlock, Predicate.Equal, tape0, new Constant(this.context, 8, 0), "test");

                BasicBlock bb0 = new BasicBlock(this.context, this.brainfFunction, "brainf");
                BranchInstruction.Create(bb0, oldBlock, test0, testBlock);

                this.builder.SetInsertPoint(bb0);

                PHINode phi1 = this.builder.CreatePHI(Type.GetInteger8PointerType(this.context), 1, "head");
                phi1.AddIncomding(head0, testBlock);

                this.currentHead = phi1;

                return;
            }

            this.builder.CreateBranch(this.endBlock);

            if (phi != null)
                throw new Exception("Missing ]");
        }
示例#29
0
        private void CreateLocalVariablesWithDefaultValues(IDictionary <Helpers.BoogieType, LocalVariable> boogieTypeToLocalVariable, IList <LocalVariable> variables, IList <Instruction> instructions)
        {
            // int

            var defaultInt = new LocalVariable("$defaultIntValue", false, methodBody.MethodDefinition);

            defaultInt.Type = Types.Instance.PlatformType.SystemInt32;
            Contract.Assert(Helpers.GetBoogieType(defaultInt).Equals(Helpers.BoogieType.Int));

            var intAssign = new LoadInstruction(0, defaultInt, new Constant(0)
            {
                Type = defaultInt.Type
            });

            intAssign.Label = String.Empty;

            variables.Add(defaultInt);
            instructions.Add(intAssign);

            boogieTypeToLocalVariable.Add(Helpers.BoogieType.Int, defaultInt);

            // real

            var defaultReal = new LocalVariable("$defaultRealValue", false, methodBody.MethodDefinition);

            defaultReal.Type = Types.Instance.PlatformType.SystemFloat32;
            Contract.Assert(Helpers.GetBoogieType(defaultReal).Equals(Helpers.BoogieType.Real));

            var realAssing = new LoadInstruction(0, defaultReal, new Constant(0F)
            {
                Type = defaultReal.Type
            });

            realAssing.Label = String.Empty;

            variables.Add(defaultReal);
            instructions.Add(realAssing);

            boogieTypeToLocalVariable.Add(Helpers.BoogieType.Real, defaultReal);

            // bool

            var defaultBool = new LocalVariable("$defaultBoolValue", false, methodBody.MethodDefinition);

            defaultBool.Type = Types.Instance.PlatformType.SystemBoolean;
            Contract.Assert(Helpers.GetBoogieType(defaultBool).Equals(Helpers.BoogieType.Bool));

            var boolAssign = new LoadInstruction(0, defaultBool, new Constant(false)
            {
                Type = defaultBool.Type
            });

            boolAssign.Label = String.Empty;

            variables.Add(defaultBool);
            instructions.Add(boolAssign);

            boogieTypeToLocalVariable.Add(Helpers.BoogieType.Bool, defaultBool);

            // Ref

            var defaultRef = new LocalVariable("$defaultRef", false, methodBody.MethodDefinition);

            defaultRef.Type = Types.Instance.PlatformType.SystemObject;
            Contract.Assert(Helpers.GetBoogieType(defaultRef).Equals(Helpers.BoogieType.Ref));

            var refAssign = new LoadInstruction(0, defaultRef, new Constant(null)
            {
                Type = defaultRef.Type
            });

            refAssign.Label = String.Empty;

            variables.Add(defaultRef);
            instructions.Add(refAssign);

            boogieTypeToLocalVariable.Add(Helpers.BoogieType.Ref, defaultRef);
        }