internal virtual void dumpTables() { //loop: while (true) { int type = dis.read(); Console.Write(indent); Console.Write("Block type "); printHex(type); Console.Write(": "); int count; switch (type) { case 0x00: Console.WriteLine("Comment"); Console.Write(indent); Console.WriteLine(dis.readUTF()); break; case 0x10: count = dis.readUnsignedShort(); Console.WriteLine("Global String Table (" + count + " entries)"); globalStringTable = new string[count]; for (int i = 0; i < count; i++) { globalStringTable[i] = dis.readUTF(); Console.WriteLine(indent + " " + i + ": \"" + globalStringTable[i] + "\""); } break; case 0x20: count = dis.readUnsignedShort(); Console.WriteLine("Number Literals (" + count + " entries)"); numberLiterals = new double[count]; for (int i = 0; i < count; i++) { numberLiterals[i] = dis.readDouble(); Console.WriteLine(indent + " " + i + ": " + numberLiterals[i]); } break; case 0x30: count = dis.readUnsignedShort(); Console.WriteLine("String Literals (" + count + " entries)"); stringLiterals = new String[count]; for (int i = 0; i < count; i++) { int index = dis.readUnsignedShort(); Console.WriteLine(indent + " " + i + " -> " + index + ": \"" + globalStringTable[index] + "\""); stringLiterals[i] = globalStringTable[index]; } break; case 0x40: count = dis.readUnsignedShort(); Console.WriteLine("Regex Literals (" + count + " entries)"); stringLiterals = new String[count]; for (int i = 0; i < count; i++) { int index = dis.readUnsignedShort(); Console.WriteLine(indent + " " + i + " -> " + index + ": \"" + globalStringTable[index] + "\""); } break; case 0x50: count = dis.readUnsignedShort(); Console.WriteLine("Function Literals (" + count + " entries)"); for (int i = 0; i < count; i++) { Console.WriteLine(indent + " function literal " + i + ": "); new Disassembler(dis, globalStringTable, indent + " ").dumpTables(); } break; case 0x60: count = dis.readUnsignedShort(); Console.WriteLine("Local Variable Names (" + count + " entries)"); localVariableNames = new String[count]; for (int i = 0; i < count; i++) { int index = dis.readUnsignedShort(); Console.WriteLine(indent + " " + i + " -> " + index + ": \"" + globalStringTable[index] + "\""); localVariableNames[i] = globalStringTable[index]; } break; case 0x080: int locals = dis.readUnsignedShort(); int parameters = dis.readUnsignedShort(); int flags = dis.read(); int size = dis.readUnsignedShort(); Console.WriteLine("Code (locals:" + locals + " param:" + parameters + " flags:" + MyInteger.toBinaryString(flags) + " size: " + size + ")"); sbyte[] code = new sbyte [size]; dis.readFully(code); disassemble(code); break; case 0xE0: count = dis.readUnsignedShort(); Console.WriteLine("Line Numbers (" + count + " entries)"); for (int i = 0; i < count; i++) { int programCounter = dis.readUnsignedShort(); int lineNumber = dis.readUnsignedShort(); Console.Write(indent + " "); printHex(programCounter >> 8); printHex(programCounter); Console.WriteLine(" line = " + lineNumber); } break; case 0x0ff: Console.WriteLine("End Marker"); goto loopBreak; default: Console.WriteLine("Unknown block type -- aborting"); throw new IOException("Unknown block type: " + type); } } loopBreak :; }
/** * Constructs a function literal from the serialized binary form including the * string table. Please note that function literals cannot be invoked * directly, a function must be created from this function literal using the * corresponding constructor. If the global string table is null, the file * header is expected. * * @throws IOException thrown for underlying stream IO errors */ public JsFunction(DataInputStream dis, string[] globalStringTable) : base(FUNCTION_PROTOTYPE) { // __proto__ above, prototype below... this.prototype = new JsObject(OBJECT_PROTOTYPE); sbyte[] buf = null; int flags = 0; //loop: while (true) { int blockType = dis.read(); int count; switch (blockType) { case BLOCK_COMMENT: count = dis.readUnsignedShort(); if (buf == null || buf.Length < count) { buf = new sbyte[count]; } dis.readFully(buf, 0, count); break; case BLOCK_GLOBAL_STRING_TABLE: count = dis.readUnsignedShort(); globalStringTable = new String[count]; for (int i = 0; i < count; i++) { globalStringTable[i] = dis.readUTF(); } break; case BLOCK_STRING_LITERALS: count = dis.readUnsignedShort(); stringLiterals = new String[count]; for (int i = 0; i < count; i++) { stringLiterals[i] = globalStringTable[dis.readShort()]; } break; case BLOCK_NUMBER_LITERALS: count = dis.readUnsignedShort(); numberLiterals = new double[count]; for (int i = 0; i < count; i++) { numberLiterals[i] = dis.readDouble(); } break; case BLOCK_FUNCTION_LITERALS: count = dis.readUnsignedShort(); functionLiterals = new JsFunction[count]; for (int i = 0; i < count; i++) { functionLiterals[i] = new JsFunction(dis, globalStringTable); } break; case BLOCK_LOCAL_VARIABLE_NAMES: count = dis.readUnsignedShort(); localNames = new String[count]; for (int i = 0; i < count; i++) { localNames[i] = globalStringTable[dis.readShort()]; } break; case BLOCK_BYTE_CODE: varCount = dis.readUnsignedShort(); expectedParameterCount = dis.readUnsignedShort(); varCount -= expectedParameterCount; flags = dis.read(); byteCode = new sbyte[dis.readShort()]; dis.readFully(byteCode); break; case BLOCK_LINE_NUMBERS: count = dis.readUnsignedShort(); lineNumbers = new int[count * 2]; for (int i = 0; i < count; i++) { lineNumbers[i << 1] = dis.readUnsignedShort(); lineNumbers[(i << 1) + 1] = dis.readUnsignedShort(); } break; case END_MARKER: goto loopBreak; default: throw new IOException("Illegal Block type " + MyInteger.toString(blockType, 16)); } } loopBreak: if ((flags & 1) == 0) { if (localNames == null) { localNames = new String[0]; } } else { localNames = null; } }