public static IEnumerable <Group> GroupCode(CacheFile cache, FunctionDefinition function) { var instance = new InstructionGrouper(cache, function); foreach (var group in instance.GroupCode()) { yield return(group); } }
private static void DumpFunction(CacheFile cacheFile, FunctionDefinition function, StringBuilder sb, bool validate) { var functionName = function.ToName(); if (function.Name != functionName) { sb.AppendLine($"// {function.Name}"); } sb.AppendLine(GetFunctionDeclaration(function, fullName: true)); sb.AppendLine("{"); const FunctionFlags ignoredFlags = FunctionFlags.HasReturnValue | FunctionFlags.HasParameters | FunctionFlags.HasLocals | FunctionFlags.HasCode; var flags = function.Flags & ~ignoredFlags; if (flags != FunctionFlags.None) { sb.AppendLine($" // Flags : {flags}"); } if (function.Locals != null && function.Locals.Count > 0) { foreach (var local in function.Locals) { sb.AppendLine($" var {local.ToName()} : {local.Type.ToPath()};"); } sb.AppendLine(); } var groups = InstructionGrouper.GroupCode(cacheFile, function).ToArray(); var groupStack = new LinkedList <(InstructionGrouper.Group group, string indent, bool isLast)>(); for (int i = 0; i < groups.Length; i++) { groupStack.AddLast((groups[i], "", i == groups.Length - 1)); } int opcodeIndex = 0; while (groupStack.Count > 0) { var(group, indent, isLast) = groupStack.First.Value; groupStack.RemoveFirst(); var instruction = group.Instruction; sb.Append(' '); if (instruction.LoadPosition < 0) { sb.Append($" (@0x?????? ????)"); } else { var loadPosition = instruction.LoadPosition; long absolutePosition; long relativePosition; if (validate) { absolutePosition = loadPosition + function.LoadPosition; relativePosition = loadPosition - function.CodeLoadPosition; } else { absolutePosition = loadPosition; relativePosition = loadPosition - function.CodeLoadPosition; } sb.Append($" (@0x{absolutePosition:X6} {relativePosition,4})"); } sb.Append($" #{opcodeIndex++,-4}"); sb.Append(indent); sb.Append(isLast == true ? " └─" : " ├─"); DumpInstruction(instruction, sb); var lastChildIndex = group.Children.Count - 1; for (int i = lastChildIndex; i >= 0; i--) { var child = group.Children[i]; groupStack.AddFirst((child, indent + (isLast == true ? " " : " │ "), i == lastChildIndex)); } } sb.AppendLine("}"); }