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 :;
        }
Beispiel #2
0
        /**
         * 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;
            }
        }