public virtual void dump() { StringBuilder buf = new StringBuilder(7); for (int i = 0; i < 7; i++) { buf.Append((char)dis.read()); } String magic = buf.ToString(); Console.WriteLine("Header: \"" + magic + "\" Version " + dis.read()); if (!"MiniJoe".Equals(magic)) { throw new IOException("Magic does not match \"MiniJoe\"!"); } dumpTables(); Console.WriteLine("EOF: " + (dis.read() == -1)); }
/** * Parses the given stream and runs the main function * @throws IOException */ public static Object exec(DataInputStream dis, JsObject context) { //TODO check magic for (int i = 0; i < 8; i++) { dis.read(); } JsFunction main = new JsFunction(new JsFunction(dis, null), context); JsArray stack = new JsArray(); stack.setObject(0, context); stack.setObject(1, context); stack.setObject(2, main); main.eval(stack, 1, 0); return(stack.getObject(3)); }
/** * 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; } }