コード例 #1
0
        void PrintInstructionJump(IndentedText txt, Instruction inst, int offset)
        {
            byte op = inst.Opcode;

            txt.Write(instMnemonics[op] ?? "???");

            switch (instOperandType[op])
            {
            case 0x42 when inst.Data is ushort targetLabel:
                txt.Write(" L.{0:X4}", targetLabel);
                break;

            case 0x44 when inst.Data is ushort targetLabelWide:
                txt.Write(" L.{0:X4}", targetLabelWide);
                break;

            case 0x4F when inst.Data is int[] switchData:
                txt.NewLine();
                txt.AdjustIndent(+23);
                txt.Write("{0} default @ L.{1:X4}", instMnemonics[op], switchData[0]);
                int i0 = switchData[1];
                for (int i = 3; i < switchData.Length; i++)
                {
                    txt.Write(", case {0} @ L.{1:X4}", i + i0 - 3, switchData[i]);
                }
                txt.AdjustIndent(-23);
                break;

            default:
                txt.Write(" unknown jump opcode kind");
                break;
            }
        }
コード例 #2
0
    static void PrintMethodBody(IndentedText txt, MethodBody body)
    {
        var numVars = body.HasVariables ? body.Variables.Count : 0;
        var numArgs = body.Method.HasParameters ? body.Method.Parameters.Count : 0;

        txt.Write("// stack={0}, locals={1}, args_size={2}, code_size={3}",
                  body.MaxStackSize, numVars, numArgs, body.CodeSize);
        txt.NewLine();
        txt.NewLine();

        var exceptions = new Dictionary <int, List <string> >();

        if (body.HasExceptionHandlers)
        {
            PrepareExceptions(body.ExceptionHandlers, exceptions);
            PrepareExceptions(null, exceptions);
        }

        foreach (var inst in body.Instructions)
        {
            if (exceptions.TryGetValue(inst.Offset, out var strs))
            {
                txt.AdjustIndent(3);
                foreach (var s in strs)
                {
                    txt.Write(s);
                    txt.NewLine();
                }
                txt.AdjustIndent(-3);
            }
            txt.Write(inst.ToString());
            txt.NewLine();
        }
    }
コード例 #3
0
        void PrintInstructionConst(IndentedText txt, Instruction inst, int offset)
        {
            txt.Write(instMnemonics[inst.Opcode] ?? "???");

            if (inst.Class != null)
            {
                if (inst.Data == null)
                {
                    txt.Write(" {0}", inst.Class);
                }

                else if (inst.Data is JavaMethodRef mr)
                {
                    txt.Write(" ({0}) {1}.{2}(", mr.ReturnType, inst.Class, mr.Name);
                    int numArgs = mr.Parameters?.Count ?? 0;
                    for (int i = 0; i < numArgs; i++)
                    {
                        txt.Write("{0}{1}",
                                  /* 0 */ (i > 0 ? ", " : string.Empty),
                                  /* 1 */ mr.Parameters[i].Type);
                    }
                    txt.Write(")");
                }

                else if (inst.Data is JavaFieldRef fr)
                {
                    txt.Write(" ({0}) {1}.{2}", fr.Type, inst.Class, fr.Name);
                }

                else
                {
                    txt.Write("???" + inst.Data + "???");
                }
            }

            else if (inst.Data is JavaCallSite callSite)
            {
                txt.Write(" {0}", callSite.BootstrapMethod);
                txt.NewLine();
                txt.AdjustIndent(+23);
                txt.Write("dynamic invocation name = {0}", callSite.InvokedMethod);
                txt.NewLine();
                if (callSite.BootstrapArgs != null)
                {
                    int n = callSite.BootstrapArgs.Length;
                    txt.Write("bootstrap method arguments = ");
                    for (int i = 0; i < n; i++)
                    {
                        txt.Write("{0}{1}", (i > 0 ? " ; " : ""), callSite.BootstrapArgs[i].ToString());
                    }
                }

                txt.AdjustIndent(-23);
            }

            else if (inst.Data is string strValue)
            {
                txt.Write(" \"{0}\"", strValue);
            }

            else if (inst.Data is int intValue)
            {
                txt.Write(" int {0} ({0:X8})", intValue, intValue);
            }

            else if (inst.Data is long longValue)
            {
                txt.Write(" long {0} ({0:X8})", longValue, longValue);
            }

            else if (inst.Data is float floatValue)
            {
                txt.Write(" float {0:F1}", floatValue);
            }

            else if (inst.Data is double doubeValue)
            {
                txt.Write(" double {0:F1}", doubeValue);
            }

            else
            {
                txt.Write(" unknown constant of type " + inst.Data.GetType());
            }
        }
コード例 #4
0
        public void Print(IndentedText txt)
        {
            if (Instructions.Count == 0)
            {
                return;
            }

            if (instMnemonics == null)
            {
                InitializeMnemonics();
            }

            var excStrings = PrepareExceptions();

            int    line = 0;
            string lineText;

            if (Instructions.Count > 0 && Instructions[0]?.Line != 0)
            {
                line     = Instructions[0].Line;
                lineText = "line " + line + ", ";
            }
            else
            {
                lineText = string.Empty;
            }

            txt.Write("        ----------     {0}stack={1}, locals={2}, args_size={3}",
                      lineText, MaxStack, MaxLocals, (Method.Parameters?.Count ?? 0));
            txt.NewLine();

            int offset = 0;

            foreach (var inst in Instructions)
            {
                if (inst.Line != 0 && inst.Line != line)
                {
                    line = inst.Line;
                    txt.Write("        ----------     line {0}", line);
                    txt.NewLine();
                }

                if (excStrings.TryGetValue(offset, out var strs))
                {
                    txt.AdjustIndent(+4);
                    foreach (var s in strs)
                    {
                        txt.Write(s);
                        txt.NewLine();
                    }
                    txt.AdjustIndent(-4);
                }

                if (StackMap != null)
                {
                    var(strLocals, strStack) = StackMap.FrameToString((ushort)offset);
                    if (strLocals != null)
                    {
                        txt.Write($"    locals = [ {strLocals} ]");
                        txt.NewLine();
                    }
                    if (strStack != null)
                    {
                        txt.Write($"    stack  = [ {strStack} ]");
                        txt.NewLine();
                    }
                }

                byte op;

                if (inst.Bytes != null)
                {
                    op = inst.Bytes[0];
                    txt.Write("{0:X4}    {1:X2}", offset, op);
                    for (int i = 1; i < inst.Bytes.Length; i++)
                    {
                        txt.Write(" {0:X2}", inst.Bytes[i]);
                    }
                    for (int i = inst.Bytes.Length; i < 5; i++)
                    {
                        txt.Write("   ");
                    }
                    txt.Write(" ");
                }
                else
                {
                    op = inst.Opcode;
                    txt.Write("L.{0:X4}  {1:X2}", inst.Label, op);
                    for (int i = 1; i < 5; i++)
                    {
                        txt.Write("   ");
                    }
                    txt.Write(" ");
                }

                if (op == 0xC4)
                {
                    PrintInstructionWide(txt, inst, offset);
                }
                else
                {
                    switch (instOperandType[op] & 0xF0)
                    {
                    case 0x80:
                        PrintInstructionConst(txt, inst, offset);
                        break;

                    case 0x40:
                        PrintInstructionJump(txt, inst, offset);
                        break;

                    case 0x20:
                        PrintInstructionMisc1(txt, inst, offset);
                        break;

                    case 0x10:
                        PrintInstructionNarrow(txt, inst, offset);
                        break;

                    case 0x00:
                        PrintInstructionMisc0(txt, inst, offset);
                        break;

                    default:
                        txt.Write("unknown opcode kind");
                        break;
                    }
                }

                txt.NewLine();

                if (inst.Bytes != null)
                {
                    offset += inst.Bytes.Length;
                }
            }
        }
コード例 #5
0
        public void PrintJava(IndentedText txt)
        {
            if (SourceFile != null)
            {
                txt.Write("//");
                txt.NewLine();
                txt.Write("// {0}", SourceFile);
                txt.NewLine();
                txt.Write("//");
                txt.NewLine();
                txt.NewLine();
            }

            PrintClassPrefix(txt, Flags, Name);

            if (Super != null)
            {
                txt.Write(" extends {0}", Super);
            }

            if (Interfaces != null)
            {
                txt.Write(" implements ");
                for (int i = 0; i < Interfaces.Count; i++)
                {
                    txt.Write("{0}{1}", (i > 0 ? ", " : string.Empty), Interfaces[i]);
                }
            }

            txt.Write(" {");
            txt.NewLine();
            txt.NewLine();
            txt.AdjustIndent(true);

            if (Signature != null)
            {
                txt.Write("// signature ");
                txt.Write(Signature);
                txt.NewLine();
                txt.NewLine();
            }

            if (OuterAndInnerClasses != null)
            {
                if (OuterAndInnerClasses[0] != null)
                {
                    if (OuterAndInnerClasses[0].InnerShortName != null)
                    {
                        txt.Write("// declared as {0} {{...}} in {1}",
                                  OuterAndInnerClasses[0].InnerShortName,
                                  OuterAndInnerClasses[0].OuterLongName);
                    }
                    else
                    {
                        txt.Write("// anonymous class {{...}} in {0}",
                                  OuterAndInnerClasses[0].OuterLongName);
                    }
                    txt.NewLine();
                    txt.NewLine();
                }

                for (int i = 1; i < OuterAndInnerClasses.Length; i++)
                {
                    PrintClassPrefix(txt,
                                     OuterAndInnerClasses[i].Flags,
                                     OuterAndInnerClasses[i].InnerShortName);
                    txt.Write("{0} {{...}} is {1};",
                              (OuterAndInnerClasses[i].InnerShortName == null
                                    ? "(anonymous)" : string.Empty),
                              OuterAndInnerClasses[i].InnerLongName);
                    txt.NewLine();
                    txt.NewLine();
                }
            }

            if (Fields != null)
            {
                for (int i = 0; i < Fields.Count; i++)
                {
                    Fields[i].Print(txt);
                    txt.NewLine();
                }
            }

            if (Methods != null)
            {
                for (int i = 0; i < Methods.Count; i++)
                {
                    Methods[i].Print(txt);
                }
            }

            txt.AdjustIndent(false);
            txt.Write("}");
            txt.NewLine();
            txt.NewLine();
        }
コード例 #6
0
    public static void PrintType(IndentedText txt, TypeDefinition type)
    {
        /*if (type.HasCustomAttributes)
         *  PrintCustomAttributes(txt, type.CustomAttributes);*/

        txt.Write("/* {0:X} */ {1}{2}{3}{4}{5}{6} {7}",
                  /* 0 */ type.Attributes,
                  /* 1 */ (type.IsPublic ? "public " : string.Empty),
                  /* 2 */ (type.IsAbstract ? "abstract " : string.Empty),
                  /* 3 */ (type.IsSealed ? "sealed " : string.Empty),
                  /* 4 */ ((type.IsAbstract && type.IsSealed) ? "/* static */ " : string.Empty),
                  /* 5 */ (type.IsSerializable ? "/* serializable */ " : string.Empty),
                  /* 6 */ (type.IsInterface ? "interface" : "class"),
                  /* 7 */ type.FullName);

        var baseType = type.BaseType;

        /*if (baseType != null && baseType.FullName == "System.Object")
         *  baseType = null;*/

        if (baseType != null || type.HasInterfaces)
        {
            txt.Write(" : ");
            bool comma = false;

            if (baseType != null)
            {
                txt.Write(baseType.FullName);
                comma = type.HasInterfaces;
            }

            if (type.HasInterfaces)
            {
                foreach (var intrface in type.Interfaces)
                {
                    txt.Write("{0}{1}",
                              (comma ? ", " : string.Empty),
                              intrface.InterfaceType?.FullName ?? "(null)");

                    comma = true;
                }
            }
        }

        txt.Write(" {");
        txt.NewLine();
        txt.NewLine();
        txt.AdjustIndent(true);

        foreach (var nested in type.NestedTypes)
        {
            PrintType(txt, nested);
        }

        if (type.HasNestedTypes)
        {
            txt.NewLine();
        }

        foreach (var field in type.Fields)
        {
            PrintField(txt, field);
        }

        if (type.HasFields)
        {
            txt.NewLine();
        }

        foreach (var method in type.Methods)
        {
            PrintMethod(txt, method);
        }

        txt.AdjustIndent(false);
        txt.Write("}");
        txt.NewLine();
        txt.NewLine();
    }
コード例 #7
0
    static void PrintMethod(IndentedText txt, MethodDefinition method)
    {
        txt.Write("/* {0} */ {1}{2}{3}",
                  /* 0 */ ((uint)method.Attributes).ToString("X4"),
                  /* 1 */ (method.IsPublic ? "public " :
                           (method.IsPrivate ? "private " :
                            (method.IsFamily ? "protected " :
                             (method.IsAssembly ? "internal " :
                              string.Empty)))),
                  /* 2 */ (method.IsStatic ? "static " : string.Empty),
                  /* 3 */ (method.IsVirtual ?
                           (method.IsNewSlot ? "virtual " : "override ")
                            : string.Empty));

        if (method.IsConstructor)
        {
            txt.Write(method.DeclaringType.FullName);
        }
        else
        {
            txt.Write("{0} {1}", method.ReturnType.FullName, method.Name);
        }

        txt.Write("(");

        int numArgs = 0;

        if (method.HasParameters)
        {
            bool comma = false;
            foreach (var arg in method.Parameters)
            {
                txt.Write("{0}{1} {2}",
                          /* 0 */ (comma ? ", " : string.Empty),
                          /* 1 */ arg.ParameterType.FullName,
                          /* 2 */ arg.Name);

                comma = true;
                numArgs++;
            }
        }

        txt.Write(")");
        txt.NewLine();

        if (method.HasOverrides)
        {
            txt.AdjustIndent(true);
            foreach (var m in method.Overrides)
            {
                txt.Write("overrides " + m);
                txt.NewLine();
            }
            txt.AdjustIndent(false);
        }

        if (method.HasBody)
        {
            txt.Write("{");
            txt.NewLine();
            txt.AdjustIndent(true);

            try
            {
                PrintMethodBody(txt, method.Body);
            }
            catch (Exception e)
            {
                foreach (var s in e.ToString().Split('\r', '\n'))
                {
                    if (!string.IsNullOrEmpty(s))
                    {
                        txt.Write(s);
                        txt.NewLine();
                    }
                }
            }

            txt.AdjustIndent(false);
            txt.Write("}");
        }

        txt.NewLine();
        txt.NewLine();
    }
コード例 #8
0
        public void Print(IndentedText txt)
        {
            txt.Write("/* {0} */ {1}{2}{3}",
                      /* 0 */ ((ushort)Flags).ToString("X4"),
                      /* 1 */ ((Flags & JavaAccessFlags.ACC_PUBLIC) != 0 ? "public " :
                               ((Flags & JavaAccessFlags.ACC_PRIVATE) != 0 ? "private " :
                                ((Flags & JavaAccessFlags.ACC_PROTECTED) != 0 ? "protected " :
                                 string.Empty))),
                      /* 2 */ ((Flags & JavaAccessFlags.ACC_STATIC) != 0 ? "static " :
                               ((Flags & JavaAccessFlags.ACC_ABSTRACT) != 0 ? "abstract " :
                                string.Empty)),
                      /* 3 */ ((Flags & JavaAccessFlags.ACC_FINAL) != 0 ? "final " : string.Empty));

            if (Name == "<init>" || Name == "<clinit>")
            {
                txt.Write("{0}", Class.Name);
            }
            else
            {
                txt.Write("{0} {1}", ReturnType, Name);
            }

            txt.Write("(");

            for (int i = 0; i < Parameters.Count; i++)
            {
                txt.Write("{0}{1} {2}",
                          /* 0 */ (i > 0 ? ", " : string.Empty),
                          /* 1 */ Parameters[i].Type,
                          /* 2 */ Parameters[i].Name);
            }

            txt.Write(")");

            if (Exceptions != null)
            {
                for (int i = 0; i < Exceptions.Length; i++)
                {
                    txt.Write("{0}{1}",
                              /* 0 */ (i > 0 ? ", " : " throws "),
                              /* 1 */ Exceptions[i].ClassName);
                }
            }

            if (Code != null)
            {
                txt.Write(" {");
                txt.NewLine();
                txt.AdjustIndent(true);

                Code.Print(txt);

                txt.AdjustIndent(false);
                txt.Write("}");
            }
            else
            {
                txt.Write(";");
            }

            txt.NewLine();
            txt.NewLine();
        }