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); } }
/// <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); } } } } }
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); } }
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; }
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); } }
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; }
/// <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()); }
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); } }
private SetOfObjects GetThisAndAllReferencedModules() { SetOfObjects referencedModules = new SetOfObjects(); referencedModules.Add(this.module); this.GetModulesReferenced(referencedModules, this.module); return referencedModules; }
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(); }
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(); } }