public ExecuteCompilationAction(Instruction callInstruction, ProcessedSubroutine subroutine, Assembly assembly) { var consumedInstructions = new List <Instruction>(); subroutine.TryGetFrameworkAttribute <CompileTimeExecutedMethodAttribute>(out var attribute); var parameterCount = subroutine.Parameters.Count; var arguments = new List <byte>(); var previousInstruction = callInstruction.Previous; for (var i = 0; i < parameterCount; i++) { arguments.Add((Convert.ToByte(previousInstruction.Operand))); consumedInstructions.Add(previousInstruction); previousInstruction = previousInstruction.Previous; } consumedInstructions.Add(callInstruction); var methodDefinition = subroutine.MethodDefinition; var method = assembly.DefinedTypes .Single(ti => ti.FullName == methodDefinition.DeclaringType.FullName) .GetMethod(attribute.ImplementationName, BindingFlags.Static | BindingFlags.NonPublic); ConsumedInstructions = consumedInstructions.ToImmutableHashSet(); MethodInfo = method; Arguments = arguments.ToImmutableArray(); }
public ProcessedType ReplaceSubroutine(ProcessedSubroutine oldSubroutine, CompiledSubroutine newSubroutine) { var finalSubroutines = new List <ProcessedSubroutine>(Subroutines); var oldSubroutineToRemove = finalSubroutines.Single(s => s.MethodDefinition == oldSubroutine.MethodDefinition); finalSubroutines.Remove(oldSubroutineToRemove); finalSubroutines.Add(newSubroutine); return(new ProcessedType( TypeDefinition, BaseType, Fields, FieldOffsets, finalSubroutines.ToImmutableList(), ThisSize, AllowedAsLValue)); }
public static CallGraph CreateFromEntryMethod(ProcessedSubroutine entryPoint) { var graph = new CallGraph(); graph.AddRootNode(entryPoint.MethodDefinition); AddCalleesToGraph(entryPoint.MethodDefinition); return(graph); void AddCalleesToGraph(MethodDefinition method) { var callees = method.Body.Instructions .Where(i => i.OpCode == OpCodes.Call) .Select(i => i.Operand) .OfType <MethodDefinition>(); foreach (var callee in callees) { graph.AddEdge(method, callee); AddCalleesToGraph(callee); } } }
protected ProcessedSubroutine(ProcessedSubroutine processedSubroutine) : this(processedSubroutine.MethodDefinition, processedSubroutine.ControlFlowGraph, processedSubroutine.IsEntryPoint, processedSubroutine.ReturnType, processedSubroutine.Parameters, processedSubroutine.Locals, processedSubroutine.FrameworkAttributes) { }
public CompiledSubroutine(ProcessedSubroutine processedSubroutine, IEnumerable <AssemblyLine> body) : base(processedSubroutine) { Body = body; }