예제 #1
0
        private void AddTransferInstructions(BasicBlock block, SetOfObjects definedSSAVariables, SetOfObjects blocksAlreadyVisited)
        {
            Contract.Requires(block != null);
            Contract.Requires(definedSSAVariables != null);
            Contract.Requires(blocksAlreadyVisited != null);

            if (block.Joins != null)
            {
                foreach (var join in block.Joins)
                {
                    Contract.Assume(join.NewLocal != null);
                    definedSSAVariables.Add(join.NewLocal);
                }
            }

            foreach (var instruction in block.Instructions)
            {
                var ssaLocal = instruction.Operation.Value as SSALocalDefinition;
                if (ssaLocal != null)
                {
                    definedSSAVariables.Add(ssaLocal);
                }
                else
                {
                    var ssaParam = instruction.Operation.Value as SSAParameterDefinition;
                    if (ssaParam != null)
                    {
                        definedSSAVariables.Add(ssaParam);
                    }
                }
            }

            var successors = this.cdfg.SuccessorsFor(block);
            var n          = successors.Count;

            if (n == 0)
            {
                return;
            }
            for (var i = 0; i < n - 1; i++)
            {
                var succ = successors[i];
                this.AddTransferInstructions(block, succ, i, definedSSAVariables);
                if (!blocksAlreadyVisited.Add(succ))
                {
                    continue;
                }
                var copyOfssaVariableFor = new SetOfObjects(definedSSAVariables);
                this.AddTransferInstructions(succ, copyOfssaVariableFor, blocksAlreadyVisited);
            }
            var lastSucc = successors[n - 1];

            if (blocksAlreadyVisited.Add(lastSucc))
            {
                this.AddTransferInstructions(block, lastSucc, n - 1, definedSSAVariables);
                this.AddTransferInstructions(lastSucc, definedSSAVariables, blocksAlreadyVisited);
            }
        }
예제 #2
0
 /// <summary>
 ///
 /// </summary>
 protected virtual void PopulateLocals()
 {
     if (this.localScopeProvider != null)
     {
         var localAlreadySeen = new SetOfObjects();
         foreach (var scope in this.localScopeProvider.GetLocalScopes(this.cdfg.MethodBody))
         {
             Contract.Assume(scope != null);
             foreach (var local in this.localScopeProvider.GetVariablesInScope(scope))
             {
                 if (localAlreadySeen.Add(local))
                 {
                     if (this.sourceLocationProvider != null)
                     {
                         bool isCompilerGenerated;
                         this.sourceLocationProvider.GetSourceNameFor(local, out isCompilerGenerated);
                         if (isCompilerGenerated)
                         {
                             continue;
                         }
                     }
                     this.localVariables.Add(local);
                 }
             }
         }
     }
 }
예제 #3
0
        private void AddEdgesForSwitch(IOperation ilOperation, BasicBlock currentBlock, List <BasicBlock> edges, Instruction instruction)
        {
            Contract.Requires(ilOperation != null);
            Contract.Requires(currentBlock != null);
            Contract.Requires(ilOperation.OperationCode == OperationCode.Switch);
            Contract.Requires(edges != null);
            Contract.Requires(instruction != null);

            Contract.Assume(ilOperation.Value is uint[]); //This is an informally specified property of the Metadata model.
            uint[]       branches         = (uint[])ilOperation.Value;
            SetOfObjects currentSuccesors = new SetOfObjects((uint)branches.Length);

            foreach (uint targetAddress in branches)
            {
                this.blocksThatTarget.Add(targetAddress, currentBlock);
                var target = this.cdfg.BlockFor[targetAddress];
                Contract.Assume(target != null); //All branch targets must have blocks, but we can't put that in a contract that satisfies the checker.
                if (currentSuccesors.Contains(target))
                {
                    continue;
                }
                currentSuccesors.Add(target);
                edges.Add(target);
            }
        }
예제 #4
0
        private void SetupTraversalOrders(BasicBlock root, SetOfObjects alreadyTraversed, ref uint preOrderIndex, ref uint postOrderIndex)
        {
            Contract.Requires(root != null);
            Contract.Requires(alreadyTraversed != null);

            if (!alreadyTraversed.Add(root))
            {
                return;
            }
            Contract.Assume(this.preOrder != null);
            Contract.Assume(this.postOrder != null);
            Contract.Assume(preOrderIndex < this.preOrder.Length);
            this.preOrder[preOrderIndex++] = root;
            foreach (var successor in this.cfg.SuccessorsFor(root))
            {
                Contract.Assume(successor != null);
                this.SetupTraversalOrders(successor, alreadyTraversed, ref preOrderIndex, ref postOrderIndex);
            }
            Contract.Assume(this.postOrder != null);
            Contract.Assume(postOrderIndex < this.postOrder.Length);
            root.postOrderNumber             = postOrderIndex;
            this.postOrder[postOrderIndex++] = root;
        }
예제 #5
0
        private void Eliminate(BasicBlock block, SetOfObjects blocksAlreadyVisited)
        {
            Contract.Requires(block != null);
            Contract.Requires(blocksAlreadyVisited != null);

            var successors = this.cdfg.SuccessorsFor(block);
            var n          = successors.Count;

            if (n == 0)
            {
                return;
            }
            for (var i = 0; i < n; i++)
            {
                var succ = successors[i];
                this.AddTransferInstructions(block, succ, i);
                if (!blocksAlreadyVisited.Add(succ))
                {
                    continue;
                }
                this.Eliminate(succ, blocksAlreadyVisited);
            }
        }
예제 #6
0
    private bool NextReferenceIsAssignment(ILocalDefinition local, BasicBlock<Instruction> bb, int offset, SetOfObjects blocksAlreadyVisited) {
      Contract.Requires(bb != null);
      Contract.Requires(offset >= 0);
      Contract.Requires(blocksAlreadyVisited != null);

      blocksAlreadyVisited.Add(bb);
      for (int i = offset, n = bb.Instructions.Count; i < n; i++) {
        var instruction = bb.Instructions[i];
        switch (instruction.Operation.OperationCode) {
          case OperationCode.Ldloc:
          case OperationCode.Ldloc_0:
          case OperationCode.Ldloc_1:
          case OperationCode.Ldloc_2:
          case OperationCode.Ldloc_3:
          case OperationCode.Ldloc_S:
          case OperationCode.Ldloca:
          case OperationCode.Ldloca_S:
            if (instruction.Operation.Value == local) return false;
            break;

          case OperationCode.Stloc:
          case OperationCode.Stloc_0:
          case OperationCode.Stloc_1:
          case OperationCode.Stloc_2:
          case OperationCode.Stloc_3:
          case OperationCode.Stloc_S:
            if (instruction.Operation.Value == local) return true;
            break;
        }
      }
      var result = true;
      foreach (var successor in this.cdfg.SuccessorsFor(bb)) {
        Contract.Assume(successor != null);
        if (blocksAlreadyVisited.Contains(successor)) continue;
        result &= this.NextReferenceIsAssignment(local, successor, 0, blocksAlreadyVisited);
        if (!result) break;
      }
      return result;
    }
예제 #7
0
 /// <summary>
 /// Provides the host with an opportunity to add, remove or substitute assembly references in the given list.
 /// This avoids the cost of rewriting the entire unit in order to make such changes.
 /// </summary>
 /// <param name="referringUnit">The unit that contains these references.</param>
 /// <param name="assemblyReferences">The assembly references to substitute.</param>
 /// <returns>Usually assemblyReferences, but occasionally a modified enumeration.</returns>
 public override IEnumerable<IAssemblyReference> Redirect(IUnit referringUnit, IEnumerable<IAssemblyReference> assemblyReferences) {
   if (!this.projectToCLRTypes) return assemblyReferences;
   var referringModule = referringUnit as IModule;
   if (referringModule == null || referringModule.ContainingAssembly == null || !(referringModule.ContainingAssembly.ContainsForeignTypes)) return assemblyReferences;
   var platformType = (WindowsRuntimePlatform)this.PlatformType;
   var standardRefs = new SetOfObjects();
   if (string.Equals(this.CoreAssemblySymbolicIdentity.Name.Value, "System.Runtime", StringComparison.OrdinalIgnoreCase)) {
     standardRefs.Add(platformType.SystemObjectModel.AssemblyIdentity);
   } else {
     standardRefs.Add(platformType.System.AssemblyIdentity);
   }
   standardRefs.Add(platformType.CoreAssemblyRef.AssemblyIdentity);
   standardRefs.Add(platformType.SystemRuntimeWindowsRuntime.AssemblyIdentity);
   standardRefs.Add(platformType.SystemRuntimeWindowsRuntimeUIXaml.AssemblyIdentity);
   var result = new List<IAssemblyReference>();
   foreach (var aref in assemblyReferences) {
     if (string.Equals(aref.Name.Value, "mscorlib", StringComparison.OrdinalIgnoreCase)) continue;
     result.Add(aref);
     standardRefs.Remove(aref.AssemblyIdentity);
   }
   if (standardRefs.Contains(platformType.CoreAssemblyRef.AssemblyIdentity)) result.Add(platformType.CoreAssemblyRef);
   if (standardRefs.Contains(platformType.SystemRuntimeInteropServicesWindowsRuntime.AssemblyIdentity)) result.Add(platformType.SystemRuntimeInteropServicesWindowsRuntime);
   if (standardRefs.Contains(platformType.SystemRuntimeWindowsRuntime.AssemblyIdentity)) result.Add(platformType.SystemRuntimeWindowsRuntime);
   if (standardRefs.Contains(platformType.SystemRuntimeWindowsRuntimeUIXaml.AssemblyIdentity)) result.Add(platformType.SystemRuntimeWindowsRuntimeUIXaml);
   if (standardRefs.Contains(platformType.SystemObjectModel.AssemblyIdentity)) result.Add(platformType.SystemObjectModel);
   if (standardRefs.Contains(platformType.System.AssemblyIdentity)) result.Add(platformType.System);
   return IteratorHelper.GetReadonly(result.ToArray());
 }
예제 #8
0
    private void GetModulesReferenced(SetOfObjects referencedModules, IModule module) {
      Contract.Requires(referencedModules != null);
      Contract.Requires(module != null);

      foreach (var assembly in module.AssemblyReferences) {
        Contract.Assume(assembly != null);
        if (referencedModules.Add(assembly.ResolvedModule))
          this.GetModulesReferenced(referencedModules, assembly.ResolvedAssembly);
      }

      foreach (var referencedModule in module.ModuleReferences) {
        Contract.Assume(referencedModule != null);
        if (referencedModules.Add(referencedModule.ResolvedModule))
          this.GetModulesReferenced(referencedModules, referencedModule.ResolvedModule);
      }
    }
예제 #9
0
 private SetOfObjects GetThisAndAllReferencedModules() {
   SetOfObjects referencedModules = new SetOfObjects();
   referencedModules.Add(this.module);
   this.GetModulesReferenced(referencedModules, this.module);
   return referencedModules;
 }
예제 #10
0
 private void EmitReferences() {
   this.sourceEmitter.EmitString("#include <memory.h>");
   this.sourceEmitter.EmitNewLine();
   this.sourceEmitter.EmitString("#include <stdlib.h>");
   this.sourceEmitter.EmitNewLine();
   this.sourceEmitter.EmitString("#include <stdint.h>");
   this.sourceEmitter.EmitNewLine();
   this.sourceEmitter.EmitString("#include <math.h>");
   this.sourceEmitter.EmitNewLine();
   this.sourceEmitter.EmitString("#include \"Platform.h\"");
   this.sourceEmitter.EmitNewLine();
   this.sourceEmitter.EmitString("#include \"OverflowChecker.h\"");
   this.sourceEmitter.EmitNewLine();
   var arefs = new SetOfObjects();
   foreach (var referencedAssembly in this.module.AssemblyReferences) {
     Contract.Assume(referencedAssembly != null);
     var unifiedIdentity = referencedAssembly.UnifiedAssemblyIdentity;
     if (!arefs.Add(unifiedIdentity)) continue;
     var hfile = Path.ChangeExtension(unifiedIdentity.Location, ".h");
     this.sourceEmitter.EmitString("#include \"");
     this.sourceEmitter.EmitString(hfile);
     this.sourceEmitter.EmitString("\"");
     this.sourceEmitter.EmitNewLine();
   }
   foreach (var referencedModule in this.module.ModuleReferences) {
     Contract.Assume(referencedModule != null);
     var hfile = Path.ChangeExtension(referencedModule.ModuleIdentity.Location, ".h");
     this.sourceEmitter.EmitString("#include \"");
     this.sourceEmitter.EmitString(hfile);
     this.sourceEmitter.EmitString("\"");
     this.sourceEmitter.EmitNewLine();
   }
   this.sourceEmitter.EmitString("#define IMTSIZE " + this.imtsize);
   this.sourceEmitter.EmitNewLine();
 }
예제 #11
0
 private void LoadReferencedModules() {
   var arefs = new SetOfObjects();
   foreach (var referencedAssembly in this.module.AssemblyReferences) {
     Contract.Assume(referencedAssembly != null);
     var unifiedIdentity = referencedAssembly.UnifiedAssemblyIdentity;
     if (!arefs.Add(unifiedIdentity)) continue;
     this.sourceEmitter.EmitString(new Mangler().Mangle(referencedAssembly.ResolvedAssembly));
     this.sourceEmitter.EmitString("_type_loader();");
     this.sourceEmitter.EmitNewLine();
   }
   foreach (var referencedModule in this.module.ModuleReferences) {
     Contract.Assume(referencedModule != null);
     this.sourceEmitter.EmitString(new Mangler().Mangle(referencedModule.ResolvedModule));
     this.sourceEmitter.EmitString("_type_loader();");
     this.sourceEmitter.EmitNewLine();
   }
 }