예제 #1
0
    internal InstructionParser(SourceMethodBody sourceMethodBody) {
      Contract.Requires(sourceMethodBody != null);

      this.sourceMethodBody = sourceMethodBody;
      this.host = sourceMethodBody.host; Contract.Assume(this.host != null);
      this.ilMethodBody = sourceMethodBody.ilMethodBody; Contract.Assume(this.ilMethodBody != null);
      this.MethodDefinition = sourceMethodBody.MethodDefinition;
      this.nameTable = sourceMethodBody.nameTable; Contract.Assume(this.nameTable != null);
      this.sourceLocationProvider = sourceMethodBody.sourceLocationProvider;
      this.localScopeProvider = sourceMethodBody.localScopeProvider;
      this.options = sourceMethodBody.options;
      this.platformType = sourceMethodBody.platformType; Contract.Assume(this.platformType != null);
      this.numberOfAssignmentsToLocal = sourceMethodBody.numberOfAssignmentsToLocal; Contract.Assume(this.numberOfAssignmentsToLocal != null);
      this.numberOfReferencesToLocal = sourceMethodBody.numberOfReferencesToLocal; Contract.Assume(this.numberOfReferencesToLocal != null);
      this.gotosThatTarget = sourceMethodBody.gotosThatTarget; Contract.Assume(this.gotosThatTarget != null);
      this.cdfg = sourceMethodBody.cdfg; Contract.Assume(this.cdfg != null);
      this.bindingsThatMakeALastUseOfALocalVersion = sourceMethodBody.bindingsThatMakeALastUseOfALocalVersion; Contract.Assume(this.bindingsThatMakeALastUseOfALocalVersion != null);

      if (this.localScopeProvider != null) {
        var syncInfo = this.localScopeProvider.GetSynchronizationInformation(sourceMethodBody);
        if (syncInfo != null) {
          var syncPointFor = this.synchronizatonPointLocationFor = new Hashtable<SynchronizationPointLocation>();
          IDocument doc = Dummy.Document;
          foreach (var loc in this.MethodDefinition.Locations) { doc = loc.Document; break; }
          foreach (var syncPoint in syncInfo.SynchronizationPoints) {
            Contract.Assume(syncPoint != null);
            var syncLoc = new SynchronizationPointLocation(doc, syncPoint);
            syncPointFor[syncPoint.SynchronizeOffset] = syncLoc;
            if (syncPoint.ContinuationMethod == null)
              syncPointFor[syncPoint.ContinuationOffset] = syncLoc;
          }
        }
      }
    }
예제 #2
0
    internal LockReplacer(SourceMethodBody sourceMethodBody) {
      Contract.Requires(sourceMethodBody != null);
      this.host = sourceMethodBody.host; Contract.Assume(sourceMethodBody.host != null);
      this.sourceLocationProvider = sourceMethodBody.sourceLocationProvider;
      this.numberOfReferencesToLocal = sourceMethodBody.numberOfReferencesToLocal; Contract.Assume(sourceMethodBody.numberOfReferencesToLocal != null);
      this.numberOfAssignmentsToLocal = sourceMethodBody.numberOfAssignmentsToLocal; Contract.Assume(sourceMethodBody.numberOfAssignmentsToLocal != null);
      this.bindingsThatMakeALastUseOfALocalVersion = sourceMethodBody.bindingsThatMakeALastUseOfALocalVersion; Contract.Assume(sourceMethodBody.bindingsThatMakeALastUseOfALocalVersion != null);
      var systemThreading = new Immutable.NestedUnitNamespaceReference(this.host.PlatformType.SystemObject.ContainingUnitNamespace,
        this.host.NameTable.GetNameFor("Threading"));
      var systemThreadingMonitor = new Immutable.NamespaceTypeReference(this.host, systemThreading, this.host.NameTable.GetNameFor("Monitor"), 0,
        isEnum: false, isValueType: false, typeCode: PrimitiveTypeCode.NotPrimitive);
      var parameters = new IParameterTypeInformation[2];
      this.monitorEnter = new MethodReference(this.host, systemThreadingMonitor, CallingConvention.Default, this.host.PlatformType.SystemVoid,
        this.host.NameTable.GetNameFor("Enter"), 0, parameters);
      parameters[0] = new SimpleParameterTypeInformation(monitorEnter, 0, this.host.PlatformType.SystemObject);
      parameters[1] = new SimpleParameterTypeInformation(monitorEnter, 1, this.host.PlatformType.SystemBoolean, isByReference: true);
      this.monitorExit = new MethodReference(this.host, systemThreadingMonitor, CallingConvention.Default, this.host.PlatformType.SystemVoid,
        this.host.NameTable.GetNameFor("Exit"), 0, this.host.PlatformType.SystemObject);

    }
 public override IExpression Rewrite(IBoundExpression boundExpression) {
   if (this.expressionToSubstituteForSingleUseSingleReferenceLocal != null && boundExpression.Definition == this.currentSingleUseSingleReferenceLocal) {
     if (this.localsToEliminate == null) this.localsToEliminate = new SetOfObjects();
     this.localsToEliminate.Add(this.currentSingleUseSingleReferenceLocal);
     return this.expressionToSubstituteForSingleUseSingleReferenceLocal;
   }
   return base.Rewrite(boundExpression);
 }
예제 #4
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;
    }
예제 #5
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());
 }
예제 #6
0
    internal SingleAssignmentLocalReplacer(IMetadataHost host, SetOfObjects bindingsThatMakeALastUseOfALocalVersion, HashtableForUintValues<object> numberOfAssignmentsToLocal)
      : base(host) {
      Contract.Requires(host != null);
      Contract.Requires(bindingsThatMakeALastUseOfALocalVersion != null);
      Contract.Requires(numberOfAssignmentsToLocal != null);

      this.bindingsThatMakeALastUseOfALocalVersion = bindingsThatMakeALastUseOfALocalVersion;
      this.numberOfAssignmentsToLocal = numberOfAssignmentsToLocal;
      this.local = Dummy.LocalVariable;
      this.expressionToSubstituteForLocal = CodeDummy.Expression;
    }
예제 #7
0
    internal SingleAssignmentSingleReferenceFinder(SetOfObjects bindingsThatMakeALastUseOfALocalVersion, HashtableForUintValues<object> numberOfReferencesToLocal) {
      Contract.Requires(bindingsThatMakeALastUseOfALocalVersion != null);
      Contract.Requires(numberOfReferencesToLocal != null);

      this.bindingsThatMakeALastUseOfALocalVersion = bindingsThatMakeALastUseOfALocalVersion;
      this.numberOfReferencesToLocal = numberOfReferencesToLocal;
      this.local = Dummy.LocalVariable;
    }
예제 #8
0
 private IEnumerable<INamedTypeDefinition> GetAllNominalTypes(SetOfObjects modules) {
   Contract.Requires(modules != null);
   foreach (IModule module in modules.Values) {
     Contract.Assume(module != null);
     foreach (var type in module.GetAllTypes())
       yield return type;
   }
 }
예제 #9
0
    private IEnumerable<string> GetAllLiteralStringsIn(SetOfObjects modules) {
      Contract.Requires(modules != null);

      var stringSet = new HashSet<string>();
      foreach (IModule module in modules.Values) {
        Contract.Assume(module != null);
        foreach (var str in module.GetStrings())
          stringSet.Add(str);
      }
      return stringSet;
    }
예제 #10
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);
      }
    }
예제 #11
0
 private SetOfObjects GetThisAndAllReferencedModules() {
   SetOfObjects referencedModules = new SetOfObjects();
   referencedModules.Add(this.module);
   this.GetModulesReferenced(referencedModules, this.module);
   return referencedModules;
 }
예제 #12
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();
 }
예제 #13
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();
   }
 }
예제 #14
0
    private Hashtable<ITypeReference> GetAllClosedStructuralTypeInstanceReferencesIn(SetOfObjects modules, out Hashtable<IGenericMethodInstanceReference> closedGenericMethodInstances) {
      Contract.Requires(modules != null);

      var closedStructuralTypeReferences = new Hashtable<ITypeReference>();
      closedGenericMethodInstances = new Hashtable<IGenericMethodInstanceReference>();
      foreach (var module in modules.Values) {
        IModule mod = module as IModule;
        Contract.Assume(mod != null);
        this.FindAllClosedStructuralReferencesIn(mod, closedStructuralTypeReferences, closedGenericMethodInstances, followBaseClassReferencesIntoOtherModules: false);
      }
      return closedStructuralTypeReferences;
    }
예제 #15
0
        private void AddTransferInstructions(BasicBlock block, BasicBlock succ, int successorIndex, SetOfObjects definedSSAVariables)
        {
            Contract.Requires(block != null);
            Contract.Requires(succ != null);
            Contract.Requires(definedSSAVariables != null);

            if (succ.Joins == null)
            {
                return;
            }
            foreach (var join in succ.Joins)
            {
                Contract.Assume(join.Join1 != null);
                if (definedSSAVariables.Contains(join.Join1))
                {
                    this.AddTransferInstruction(block, succ, successorIndex, join.NewLocal, join.Join1, join.Type);
                    continue;
                }
                if (join.Join2 == null)
                {
                    continue;
                }
                if (definedSSAVariables.Contains(join.Join2))
                {
                    this.AddTransferInstruction(block, succ, successorIndex, join.NewLocal, join.Join2, join.Type);
                    continue;
                }
                if (join.OtherJoins == null)
                {
                    continue;
                }
                foreach (var joini in join.OtherJoins)
                {
                    if (!definedSSAVariables.Contains(joini))
                    {
                        continue;
                    }
                    this.AddTransferInstruction(block, succ, successorIndex, join.NewLocal, joini, join.Type);
                }
            }
        }