/// <summary> /// Decompress signature, migrate to other metadata scope and compress again. /// </summary> /// <param name="oldSignature">Compressed old signature</param> /// <param name="translator">Token translator</param> /// <param name="withStart">Indicates, whether there is padding at start of signature.</param> /// <returns>Compressed migrated signature in byte array</returns> public static byte[] Migrate(byte[] oldSignature, ITokenTranslator translator, int startIndex = 2) { Signature sig = new Signature(oldSignature, startIndex); sig.Migrate(translator); return(sig.Compress()); }
/// <summary> /// Identifies same variables in new and old. Compute differences between new and old local variable declarations and /// uses placeholder in case where it is needed. Placeholders are stored to placeholders container, used to correctly /// change IL code of new version of methods. /// </summary> /// <param name="original">Signature of original version of method.</param> /// <param name="newSig">Signature of new version of mehtod.</param> /// <param name="placeholders">Container, that holds placeholder translation when method succeded.</param> /// <param name="tkOldMethod">Metadata token to the original version of method.</param> /// <param name="tkNewMethod">Metadata token to the new version of method.</param> /// <param name="translator">Token translator used to translate signatures.</param> /// <returns>Signature with placeholders for new version of method in running assembly.</returns> public Signature makeSignature(Signature original, Signature newSig, out Dictionary <int, int> placeholders, uint tkOldMethod, uint tkNewMethod, ITokenTranslator translator) { placeholders = new Dictionary <int, int>(); int varCount = original.Types.Count - 2; List <LocalVarDefinition> olds; if (!oldLocalVars.TryGetValue(tkOldMethod, out olds)) { olds = getDefinitions(tkOldMethod, oldReader); } List <LocalVarDefinition> news = getDefinitions(tkNewMethod, newReader); olds.ForEach((LocalVarDefinition def) => { def.ilStart = remapper.TranslateILOffset(def.ilStart); def.ilEnd = remapper.TranslateILOffset(def.ilEnd); }); news.ForEach((LocalVarDefinition def) => { if (def.signature != null) { def.signature = Signature.Migrate(def.signature, translator, 0); } }); List <int> used = new List <int>(); for (int i = 0; i < news.Count; i++) { Predicate <LocalVarDefinition> lambda = (LocalVarDefinition def) => { return(def.Same(news[i])); }; if (!olds.Exists(lambda) || used.Contains(olds.FindIndex(lambda))) { placeholders.Add(i, olds.Count); original.AddSigPart(news[i].signature); olds.Add(news[i]); } else { int index = olds.FindIndex(lambda); placeholders.Add(i, index); used.Add(index); } } for (int i = 0; i < olds.Count; i++) { if (!placeholders.ContainsValue(i)) { olds[i].removed = true; } } original.Types[1].Code = (uint)olds.Count; oldLocalVars[tkOldMethod] = olds; return(original); }
/// <summary> /// Migrate whole signature to other metadata scope. /// </summary> /// <param name="translator">Translator used for migration</param> public void Migrate(ITokenTranslator translator) { foreach (ElementType el in this.types) { if (el.Operand is MetadataToken) { el.Operand = translator.TranslateToken((MetadataToken)el.Operand); } } }
public SymbolWriterClass(EnCManager manager,ITokenTranslator transl) { // Create the writer from the COM catalog Type writerType = Type.GetTypeFromCLSID(typeof(CorSymWriter_SxSClass).GUID); object comWriterObj = Activator.CreateInstance(writerType); Type readerType = Type.GetTypeFromCLSID(typeof(CorSymReader_SxSClass).GUID); object comReaderObj = Activator.CreateInstance(readerType); mWriter = (ISymUnmanagedWriter2)comWriterObj; mReader = (ISymUnmanagedReader)comReaderObj; this.manager = manager; this.stream = new CorMemStream(); this.translator = transl; State = WriterState.NotIninitialized; }
public SymbolWriterClass(EnCManager manager, ITokenTranslator transl) { // Create the writer from the COM catalog Type writerType = Type.GetTypeFromCLSID(typeof(CorSymWriter_SxSClass).GUID); object comWriterObj = Activator.CreateInstance(writerType); Type readerType = Type.GetTypeFromCLSID(typeof(CorSymReader_SxSClass).GUID); object comReaderObj = Activator.CreateInstance(readerType); mWriter = (ISymUnmanagedWriter2)comWriterObj; mReader = (ISymUnmanagedReader)comReaderObj; this.manager = manager; this.stream = new CorMemStream(); this.translator = transl; State = WriterState.NotIninitialized; }
/// <summary> /// Identifies same variables in new and old. Compute differences between new and old local variable declarations and /// uses placeholder in case where it is needed. Placeholders are stored to placeholders container, used to correctly /// change IL code of new version of methods. /// </summary> /// <param name="original">Signature of original version of method.</param> /// <param name="newSig">Signature of new version of mehtod.</param> /// <param name="placeholders">Container, that holds placeholder translation when method succeded.</param> /// <param name="tkOldMethod">Metadata token to the original version of method.</param> /// <param name="tkNewMethod">Metadata token to the new version of method.</param> /// <param name="translator">Token translator used to translate signatures.</param> /// <returns>Signature with placeholders for new version of method in running assembly.</returns> public Signature makeSignature(Signature original, Signature newSig, out Dictionary<int, int> placeholders, uint tkOldMethod, uint tkNewMethod, ITokenTranslator translator) { placeholders = new Dictionary<int, int>(); int varCount = original.Types.Count - 2; List<LocalVarDefinition> olds; if (!oldLocalVars.TryGetValue(tkOldMethod,out olds)) olds = getDefinitions(tkOldMethod, oldReader); List<LocalVarDefinition> news = getDefinitions(tkNewMethod, newReader); olds.ForEach((LocalVarDefinition def) => { def.ilStart = remapper.TranslateILOffset(def.ilStart); def.ilEnd = remapper.TranslateILOffset(def.ilEnd); }); news.ForEach((LocalVarDefinition def) => { if (def.signature != null) { def.signature = Signature.Migrate(def.signature, translator, 0); } }); List<int> used = new List<int>(); for (int i = 0; i < news.Count; i++) { Predicate<LocalVarDefinition> lambda = (LocalVarDefinition def) => { return def.Same(news[i]); }; if (!olds.Exists(lambda) || used.Contains(olds.FindIndex(lambda))) { placeholders.Add(i, olds.Count); original.AddSigPart(news[i].signature); olds.Add(news[i]); } else { int index = olds.FindIndex(lambda); placeholders.Add(i, index); used.Add(index); } } for (int i = 0; i < olds.Count; i++) { if (!placeholders.ContainsValue(i)) { olds[i].removed = true; } } original.Types[1].Code = (uint)olds.Count; oldLocalVars[tkOldMethod] = olds; return original; }
//returns true if line tags were written private bool ToString(StringBuilder sb, int depth, ITokenTranslator translator, string methodPrefix, bool rootCall, bool lineBreak, bool appendLineTags, bool retainLineIndices) { if (translator == null) translator = new DefaultITokenTranslator(); bool tagsWritten = false; if (translator.IncludeBlock(this,depth)) { if (lineBreak) { sb.AppendLine(); for (int i = 0; i < depth; i++) sb.Append('\t'); } bool replaceBracketWithParenthesis = false; string lastTagInset = null; for (int i = 0; i < Elements.Length; i++) { if (i != 0 && Tokenizer.IsIdentifierToken(Elements[i]) && Tokenizer.IsIdentifierToken(Elements[i - 1])) { sb.Append(' '); if (appendLineTags) { sb.Append(Elements[i].Insert); tagsWritten = true; } } if (retainLineIndices) { int line = 0; foreach (char c in sb.ToString()) { if (c == '\n') line++; } while (retainLineIndices && Elements[i].Line > line++) { sb.AppendLine(); } } sb.Append(translator.Translate(Elements[i], rootCall == false, out replaceBracketWithParenthesis)); lastTagInset = Elements[i].Insert; } if (BraceEnclosedChildren) { if (lastTagInset != null && appendLineTags) { sb.Append(lastTagInset); tagsWritten = true; } sb.AppendLine(); for (int i = 0; i < depth; i++) sb.Append('\t'); sb.Append('{'); depth++; //add the prefix.. if (methodPrefix != null) { foreach (string line in methodPrefix.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)) { sb.AppendLine(); for (int i = 0; i < depth; i++) sb.Append('\t'); sb.Append(line); } } } if (BracketEnclosedChildren) { sb.Append(replaceBracketWithParenthesis ? '(' : '['); } bool childTagsWritten = false; foreach (HlslStructure node in Children) childTagsWritten |= node.ToString(sb, depth, translator, null, false, lineBreak && !BracketEnclosedChildren, appendLineTags, retainLineIndices); if (BraceEnclosedChildren) { sb.AppendLine(); for (int i = 1; i < depth; i++) sb.Append('\t'); sb.Append('}'); if (Children.Length > 0 && !retainLineIndices) sb.AppendLine(); } if (BracketEnclosedChildren) { sb.Append(replaceBracketWithParenthesis ? ')' : ']'); } if (!BraceEnclosedChildren && !childTagsWritten && lastTagInset != null && appendLineTags) { sb.Append(lastTagInset); tagsWritten = true; } tagsWritten |= childTagsWritten; } return tagsWritten; }
public void ToString(StringBuilder sb, int depth, ITokenTranslator translator, string methodPrefix, bool appendLineTags, bool retainLines) { ToString(sb, depth, translator, methodPrefix, true, true, appendLineTags, retainLines); }
/// <summary> /// Decompress signature, migrate to other metadata scope and compress again. /// </summary> /// <param name="oldSignature">Compressed old signature</param> /// <param name="translator">Token translator</param> /// <param name="withStart">Indicates, whether there is padding at start of signature.</param> /// <returns>Compressed migrated signature in byte array</returns> public static byte[] Migrate(byte[] oldSignature, ITokenTranslator translator,int startIndex = 2) { Signature sig = new Signature(oldSignature,startIndex); sig.Migrate(translator); return sig.Compress(); }