diff --git a/Source/Test/Rewriting/AssemblyRewriter.cs b/Source/Test/Rewriting/AssemblyRewriter.cs index d742716f..75ac4312 100644 --- a/Source/Test/Rewriting/AssemblyRewriter.cs +++ b/Source/Test/Rewriting/AssemblyRewriter.cs @@ -58,8 +58,8 @@ namespace Microsoft.Coyote.Rewriting this.Transforms = new List() { - new TaskTransform(), - new MonitorTransform() + new TaskTransform(), + new MonitorTransform() }; } @@ -111,10 +111,14 @@ namespace Microsoft.Coyote.Rewriting } Console.WriteLine($"... Rewriting the '{assemblyName}' assembly ({assembly.FullName})"); - foreach (var module in assembly.Modules) + foreach (var transform in this.Transforms) { - Debug.WriteLine($"..... Rewriting the '{module.Name}' module ({module.FileName})"); - this.RewriteModule(module); + // Traverse the assembly to apply each transformation pass. + Debug.WriteLine($"..... Applying the '{transform.GetType().Name}' transform"); + foreach (var module in assembly.Modules) + { + RewriteModule(module, transform); + } } // Write the binary in the output path with portable symbols enabled. @@ -138,68 +142,51 @@ namespace Microsoft.Coyote.Rewriting } /// - /// Rewrites the specified module definition. + /// Rewrites the specified module definition using the specified transform. /// - private void RewriteModule(ModuleDefinition module) + private static void RewriteModule(ModuleDefinition module, AssemblyTransform transform) { - foreach (var t in this.Transforms) - { - t.VisitModule(module); - } - + Debug.WriteLine($"....... Module: {module.Name} ({module.FileName})"); + transform.VisitModule(module); foreach (var type in module.GetTypes()) { - this.RewriteType(type); + RewriteType(type, transform); } } /// - /// Rewrites the specified type definition. + /// Rewrites the specified type definition using the specified transform. /// - private void RewriteType(TypeDefinition type) + private static void RewriteType(TypeDefinition type, AssemblyTransform transform) { - Debug.WriteLine($"..... Rewriting type '{type.FullName}'"); - - foreach (var t in this.Transforms) - { - t.VisitType(type); - } - + Debug.WriteLine($"......... Type: {type.FullName}"); + transform.VisitType(type); foreach (var field in type.Fields) { - foreach (var t in this.Transforms) - { - t.VisitField(field); - } + Debug.WriteLine($"........... Field: {field.FullName}"); + transform.VisitField(field); } foreach (var method in type.Methods) { - this.RewriteMethod(method); + RewriteMethod(method, transform); } } /// - /// Rewrites the specified method definition. + /// Rewrites the specified method definition using the specified transform. /// - private void RewriteMethod(MethodDefinition method) + private static void RewriteMethod(MethodDefinition method, AssemblyTransform transform) { - Debug.WriteLine($"....... Rewriting method '{method.FullName}'"); - - foreach (var t in this.Transforms) - { - t.VisitMethod(method); - } + Debug.WriteLine($"........... Method {method.FullName}"); + transform.VisitMethod(method); // Only non-abstract method bodies can be rewritten. if (!method.IsAbstract) { foreach (var variable in method.Body.Variables) { - foreach (var t in this.Transforms) - { - t.VisitVariable(variable); - } + transform.VisitVariable(variable); } // Do exception handlers before the method instructions because they are a @@ -207,25 +194,18 @@ namespace Microsoft.Coyote.Rewriting // raw instructions. if (method.Body.HasExceptionHandlers) { - foreach (var t in this.Transforms) + foreach (var handler in method.Body.ExceptionHandlers) { - foreach (var handler in method.Body.ExceptionHandlers) - { - t.VisitExceptionHandler(handler); - } + transform.VisitExceptionHandler(handler); } } - // in this case run each transform as separate passes over the method body - // so they don't trip over each other's edits. - foreach (var t in this.Transforms) + // Rewrite the method body instructions. + Instruction instruction = method.Body.Instructions.FirstOrDefault(); + while (instruction != null) { - Instruction instruction = method.Body.Instructions.FirstOrDefault(); - while (instruction != null) - { - instruction = t.VisitInstruction(instruction); - instruction = instruction.Next; - } + instruction = transform.VisitInstruction(instruction); + instruction = instruction.Next; } } } diff --git a/Source/Test/Rewriting/Transforms/MonitorTransform.cs b/Source/Test/Rewriting/Transforms/MonitorTransform.cs index f1147abf..ac08a3e1 100644 --- a/Source/Test/Rewriting/Transforms/MonitorTransform.cs +++ b/Source/Test/Rewriting/Transforms/MonitorTransform.cs @@ -74,9 +74,9 @@ namespace Microsoft.Coyote.Rewriting { // Since the method parameters match there's no need to modify the parameter setup code // we can simply switch out the call. - Debug.WriteLine($"......... [-] call '{method}'"); + Debug.WriteLine($"............. [-] call '{method}'"); var newInstruction = Instruction.Create(OpCodes.Call, newMethod); - Debug.WriteLine($"......... [+] call '{newMethod}'"); + Debug.WriteLine($"............. [+] call '{newMethod}'"); this.Processor.Replace(instruction, newInstruction); instruction = newInstruction; } @@ -108,7 +108,7 @@ namespace Microsoft.Coyote.Rewriting } } - Debug.WriteLine($"......... [?] Monitor method not found '{monitorMethod}'"); + Debug.WriteLine($"............. [?] Monitor method not found '{monitorMethod}'"); return null; } } diff --git a/Source/Test/Rewriting/Transforms/TaskTransform.cs b/Source/Test/Rewriting/Transforms/TaskTransform.cs index 852635c5..d7883963 100644 --- a/Source/Test/Rewriting/Transforms/TaskTransform.cs +++ b/Source/Test/Rewriting/Transforms/TaskTransform.cs @@ -89,9 +89,9 @@ namespace Microsoft.Coyote.Rewriting { if (this.TryRewriteCompilerType(field.FieldType, out TypeReference newFieldType)) { - Debug.WriteLine($"....... [-] field '{field}'"); + Debug.WriteLine($"............. [-] field '{field}'"); field.FieldType = newFieldType; - Debug.WriteLine($"....... [+] field '{field}'"); + Debug.WriteLine($"............. [+] field '{field}'"); } } @@ -114,9 +114,9 @@ namespace Microsoft.Coyote.Rewriting // but good to understand what that entails and give warnings/errors perhaps: work item #4678 if (this.TryRewriteCompilerType(method.ReturnType, out TypeReference newReturnType)) { - Debug.WriteLine($"......... [-] return type '{method.ReturnType}'"); + Debug.WriteLine($"............. [-] return type '{method.ReturnType}'"); method.ReturnType = newReturnType; - Debug.WriteLine($"......... [+] return type '{method.ReturnType}'"); + Debug.WriteLine($"............. [+] return type '{method.ReturnType}'"); } } @@ -130,9 +130,9 @@ namespace Microsoft.Coyote.Rewriting if (this.TryRewriteCompilerType(variable.VariableType, out TypeReference newVariableType)) { - Debug.WriteLine($"......... [-] variable '{variable.VariableType}'"); + Debug.WriteLine($"............. [-] variable '{variable.VariableType}'"); variable.VariableType = newVariableType; - Debug.WriteLine($"......... [+] variable '{variable.VariableType}'"); + Debug.WriteLine($"............. [+] variable '{variable.VariableType}'"); } } @@ -152,16 +152,16 @@ namespace Microsoft.Coyote.Rewriting if (instruction.Operand is FieldDefinition fd && this.TryRewriteCompilerType(fd.FieldType, out TypeReference newFieldType)) { - Debug.WriteLine($"......... [-] {instruction}"); + Debug.WriteLine($"........... [-] {instruction}"); fd.FieldType = newFieldType; - Debug.WriteLine($"......... [+] {instruction}"); + Debug.WriteLine($"........... [+] {instruction}"); } else if (instruction.Operand is FieldReference fr && this.TryRewriteCompilerType(fr.FieldType, out newFieldType)) { - Debug.WriteLine($"......... [-] {instruction}"); + Debug.WriteLine($"........... [-] {instruction}"); fr.FieldType = newFieldType; - Debug.WriteLine($"......... [+] {instruction}"); + Debug.WriteLine($"........... [+] {instruction}"); } } else if (instruction.OpCode == OpCodes.Initobj) @@ -187,9 +187,11 @@ namespace Microsoft.Coyote.Rewriting if (this.TryRewriteCompilerType(type, out TypeReference newType)) { var newInstruction = Instruction.Create(instruction.OpCode, newType); - Debug.WriteLine($"......... [-] {instruction}"); + newInstruction.Offset = instruction.Offset; + + Debug.WriteLine($"............. [-] {instruction}"); this.Processor.Replace(instruction, newInstruction); - Debug.WriteLine($"......... [+] {newInstruction}"); + Debug.WriteLine($"............. [+] {newInstruction}"); instruction = newInstruction; } @@ -222,9 +224,9 @@ namespace Microsoft.Coyote.Rewriting Instruction newInstruction = Instruction.Create(resolvedMethod.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, newMethod); newInstruction.Offset = instruction.Offset; - Debug.WriteLine($"......... [-] {instruction}"); + Debug.WriteLine($"............. [-] {instruction}"); this.Processor.Replace(instruction, newInstruction); - Debug.WriteLine($"......... [+] {newInstruction}"); + Debug.WriteLine($"............. [+] {newInstruction}"); return newInstruction; }