public static string dumpMethod(Abc abc, MethodInfo m, string indent, string attr) { StringBuilder sb = new StringBuilder(); if (m.metadata != null) { foreach (MetaData md in m.metadata) { sb.Append(indent).AppendLine(md.ToString()); } } sb.Append(indent); formatMethod(m, sb); if (m.code != null && m.code.Length > 0) { sb.AppendLine(indent + "{"); if ((m.flags & MethodFlags.NeedActivation) > 0) { sb.AppendLine(indent + TAB + "// NEED ACTIVATION ???"); //m.activation.dump(abc, indent+TAB, ""); } dumpCode(abc, m, indent + TAB, sb); sb.AppendLine(indent + "}\n"); } return(sb.ToString()); }
private static void dumpCode(Abc abc, MethodInfo m, string indent, StringBuilder sb) { MemoryStream ms = new MemoryStream(m.code); BinaryReader br = new BinaryReader(ms); //long totalSize = 0; //long[] opSizes = new long[256]; string[] stack = new string[m.max_stack]; LabelInfo labels = new LabelInfo(); long len = m.code.Length; while (br.BaseStream.Position < len) { long start = br.BaseStream.Position; string s = indent + start; while (s.Length < 12) { s += ' '; } int opcode = br.ReadByte(); if (opcode == (int)Op.label || labels.ContainsKey(br.BaseStream.Position - 1)) { sb.AppendLine(indent) .AppendLine(indent + labels.labelFor(br.BaseStream.Position - 1) + ": "); } s += opNames[opcode]; s += opNames[opcode].Length < 8 ? TAB + TAB : TAB; switch ((Op)opcode) { case Op.debugfile: case Op.pushstring: s += '"' + abc.strings[Abc.readU32(br)].ToString().Replace("\n", "\\n").Replace("\t", "\\t") + '"'; break; case Op.pushnamespace: s += abc.namespaces[Abc.readU32(br)]; break; case Op.pushint: int i = (int)abc.ints[Abc.readU32(br)]; s += i; // + "\t// 0x" + i.ToString(16); break; case Op.pushuint: uint u = (uint)abc.uints[Abc.readU32(br)]; s += u; // + "\t// 0x" + u.ToString(16); break; case Op.pushdouble: s += abc.doubles[Abc.readU32(br)]; break; case Op.getsuper: case Op.setsuper: case Op.getproperty: case Op.initproperty: case Op.setproperty: case Op.getlex: case Op.findpropstrict: case Op.findproperty: case Op.finddef: case Op.deleteproperty: case Op.istype: case Op.coerce: case Op.astype: case Op.getdescendants: s += abc.names[Abc.readU32(br)]; break; case Op.constructprop: case Op.callproperty: case Op.callproplex: case Op.callsuper: case Op.callsupervoid: case Op.callpropvoid: s += abc.names[Abc.readU32(br)]; s += " (" + Abc.readU32(br) + ")"; break; case Op.newfunction: { var method_id = Abc.readU32(br); s += abc.methods[method_id]; abc.methods[method_id].anon = true; break; } case Op.callstatic: s += abc.methods[Abc.readU32(br)]; s += " (" + Abc.readU32(br) + ")"; break; case Op.newclass: s += abc.instances[Abc.readU32(br)]; break; case Op.lookupswitch: var pos = br.BaseStream.Position - 1; var target = pos + readS24(br); var maxindex = Abc.readU32(br); s += "default:" + labels.labelFor(target); // target + "("+(target-pos)+")" s += " maxcase:" + maxindex; for (int j = 0; j <= maxindex; j++) { target = pos + readS24(br); s += " " + labels.labelFor(target); // target + "("+(target-pos)+")" } break; case Op.jump: case Op.iftrue: case Op.iffalse: case Op.ifeq: case Op.ifne: case Op.ifge: case Op.ifnge: case Op.ifgt: case Op.ifngt: case Op.ifle: case Op.ifnle: case Op.iflt: case Op.ifnlt: case Op.ifstricteq: case Op.ifstrictne: int offset = readS24(br); target = br.BaseStream.Position + offset; //s += target + " ("+offset+")" s += labels.labelFor(target); if (!labels.ContainsKey(br.BaseStream.Position)) { s += "\n"; } break; case Op.inclocal: case Op.declocal: case Op.inclocal_i: case Op.declocal_i: case Op.getlocal: case Op.kill: case Op.setlocal: case Op.debugline: case Op.getglobalslot: case Op.getslot: case Op.setglobalslot: case Op.setslot: case Op.pushshort: case Op.newcatch: s += Abc.readU32(br); break; case Op.debug: s += br.ReadByte(); s += " " + Abc.readU32(br); s += " " + br.ReadByte(); s += " " + Abc.readU32(br); break; case Op.newobject: s += "{" + Abc.readU32(br) + "}"; break; case Op.newarray: s += "[" + Abc.readU32(br) + "]"; break; case Op.call: case Op.construct: case Op.constructsuper: case Op.applytype: s += "(" + Abc.readU32(br) + ")"; break; case Op.pushbyte: case Op.getscopeobject: s += br.ReadSByte(); break; case Op.hasnext2: s += Abc.readU32(br) + " " + Abc.readU32(br); break; default: /*if (opNames[opcode] == ("0x"+opcode.toString(16).toUpperCase())) * s += " UNKNOWN OPCODE"*/ break; } long size = br.BaseStream.Position - start; //totalSize += size; //opSizes[opcode] = opSizes[opcode] + size; sb.AppendLine(s); } }