📄 kvmwriter.java
字号:
int alignment = meth.alignment(); int padding = alignment - (sectionCounter.getOffset() % alignment); if (padding != alignment) { sectionCounter.notNextSection(padding); out.println("\t\tBYTE padding" + (++padCount) + "[" + padding + "];"); todo.addElement(new Integer(padding)); } sectionCounter.maybeNextSection(mi.code.length); out.println("#define " + methodNativeName + "_CodeSection " + "section" + sectionCounter.getSection()); out.println("\t\t/* " + prettyName(mi) + " */"); out.println("\t\tBYTE " + methodNativeName + "[" + mi.code.length + "];" ); todo.addElement(meth); todo.addElement(methodNativeName); } } } sectionCounter.endLastSection(); ncodebytes = sectionCounter.getTotalLength(); out.println("};"); out.println(); out.println("#if !ENABLEFASTBYTECODES && !ENABLE_JAVA_DEBUGGER"); out.println("CONST"); out.println("#endif"); out.println("static struct AllCode_Struct AllCode = {"); sectionCounter.startFirstSection(SectionCounter.Initialization); for (Enumeration e = todo.elements(); e.hasMoreElements(); ) { Object nextElement = e.nextElement(); if (nextElement instanceof Integer) { int padding = ((Integer)nextElement).intValue(); sectionCounter.notNextSection(padding); out.println("\t\t{ 0 }, /* padding size " + padding + " */"); continue; } EVMMethodInfo meth = (EVMMethodInfo)nextElement; String methodNativeName = (String)e.nextElement(); final MethodInfo mi = meth.method; sectionCounter.maybeNextSection(mi.code.length); out.println("\t\t{ /* " + mi.parent.className + ": " + prettyName(mi) + " */"); writeArray(mi.code.length, 10, "\t\t\t", new ArrayPrinter() { public void print(int index) { if (index == 0 && (mi == runCustomCodeMethod)) { out.print("CUSTOMCODE"); } else { int value = mi.code[index] & 0xFF; out.printHexInt(value); } } }); out.println("\t\t},"); } sectionCounter.endLastSection(); out.println("};\n"); if (!relocatableROM) { for (Enumeration e = natives.elements(); e.hasMoreElements(); ) { EVMMethodInfo meth = (EVMMethodInfo)e.nextElement(); String jniName = meth.method.getNativeName(true); out.println("extern void " + jniName + "(void);"); } } if (relocatableROM) { sectionCounter.printRelocationInfo("AllCode", "CODE"); } } protected void writeAllHandlers(Vector instanceClasses) { Vector todo = new Vector(); out.println("struct AllHandlers_Struct { "); ExceptionEntry empty[] = new ExceptionEntry[0]; for (Enumeration e = instanceClasses.elements(); e.hasMoreElements();) { EVMClass cc = (EVMClass)e.nextElement(); String classNativeName = (String)e.nextElement(); // ignored EVMMethodInfo m[] = cc.methods; int nmethod = m.length; for (int j = 0; j < nmethod; j++){ EVMMethodInfo meth = m[j]; MethodInfo mi = meth.method; if (mi.exceptionTable == null) { mi.exceptionTable = empty; } int tryCatches = mi.exceptionTable.length; if (tryCatches > 0) { String methodNativeName = meth.getNativeName(); todo.addElement(meth); ncatchframes += tryCatches; out.println("\tstruct { /* " + mi.parent.className + ": " + prettyName(mi) + "*/"); out.println("\t\tlong length;"); out.println("\t\tstruct exceptionHandlerStruct handlers[" + tryCatches + "];"); out.println("\t} " + methodNativeName + ";"); } } } out.println("};"); out.println(); out.println("static CONST struct AllHandlers_Struct AllHandlers = {"); for (Enumeration e = todo.elements(); e.hasMoreElements(); ) { EVMMethodInfo meth = (EVMMethodInfo)e.nextElement(); MethodInfo mi = meth.method; ExceptionEntry[] exceptions = mi.exceptionTable; out.println("\t{ /* " + mi.parent.className + ": " + prettyName(mi) + "*/"); out.println("\t\t" + exceptions.length + ","); out.println("\t\t{"); int tryCatches = exceptions.length; for (int k = 0; k < tryCatches; k++) { ExceptionEntry ee = mi.exceptionTable[k]; out.println("\t\t\tHANDLER_ENTRY(" + ee.startPC + ", " + ee.endPC + ", " + ee.handlerPC + ", " + (ee.catchType == null ? 0 : ee.catchType.index) + ")" + ((k == tryCatches - 1) ? "" : ",")); } out.println("\t\t}"); out.println("\t},\n"); } out.println("};"); } protected void writeAllStackMaps(Vector instanceClasses) { Vector todo = new Vector(); StackMapFrame empty[] = new StackMapFrame[0]; out.println("struct AllStackMaps_Struct { "); for (Enumeration e = instanceClasses.elements(); e.hasMoreElements();) { EVMClass cc = (EVMClass)e.nextElement(); String classNativeName = (String)e.nextElement(); // ignored EVMMethodInfo m[] = cc.methods; int nmethod = m.length; for (int j = 0; j < nmethod; j++){ EVMMethodInfo meth = m[j]; MethodInfo mi = meth.method; if (mi.stackMapTable == null) { mi.stackMapTable = empty; } if (mi.stackMapTable.length > 0) { todo.addElement(meth); stackMapUtil.printDeclaration(out, meth, "\t"); } } } out.println("};"); out.println(); out.println("static CONST struct AllStackMaps_Struct AllStackMaps = {"); for (Enumeration e = todo.elements(); e.hasMoreElements(); ) { EVMMethodInfo meth = (EVMMethodInfo)e.nextElement(); stackMapUtil.printDefinition(out, meth, "\t"); } out.println("};"); } protected void writeMethods(EVMClass c) { EVMMethodInfo m[] = c.methods; int methodCount = m.length; out.println("\t\t\t" + methodCount + ","); out.println("\t\t\t{"); for (int i = 0; i < methodCount; i++) { EVMMethodInfo meth = m[i]; MethodInfo mi = meth.method; int access = mi.access; String typeString = mi.type.string; switch (typeString.charAt(typeString.indexOf(')') + 1)) { case 'L': case '[': access |= ACC_POINTER; break; case 'J': case 'D': access |= ACC_DOUBLE; break; case 'V': access |= (ACC_DOUBLE | ACC_POINTER); break; case 'B': case 'C': case 'S': case 'I': case 'F': case 'Z': break; default: System.out.println("Bad type string " + typeString); } String type = ((access & Const.ACC_ABSTRACT) != 0) ? "ABSTRACT_" : ((access & Const.ACC_NATIVE) != 0) ? "NATIVE_" : ""; out.println("\t\t\t\t" + type + "METHOD_INFO( /* " + prettyName(mi) + " */ \\"); out.println("\t\t\t\t\t" + c.getNativeName() + ", \\"); if ((access & Const.ACC_ABSTRACT) != 0) { // do nothing } else if ((access & Const.ACC_NATIVE) != 0) { if (relocatableROM) { out.println("\t\t\t\t\tNULL, \\"); } else { out.println("\t\t\t\t\t" + mi.getNativeName(true) + ", \\"); } } else { String methodNativeName = meth.getNativeName(); out.println("\t\t\t\t\tAllCode." + methodNativeName + "_CodeSection." + methodNativeName + ", \\"); if (mi.exceptionTable.length > 0) { out.println("\t\t\t\t\t&AllHandlers." + methodNativeName + ", \\"); } else { out.println("\t\t\t\t\t0, \\"); } if (mi.stackMapTable.length > 0) { out.println("\t\t\t\t\t&AllStackMaps." + methodNativeName + ", \\"); } else { out.println("\t\t\t\t\t0, \\"); } } out.print("\t\t\t\t\t"); out.printHexInt(access); out.print(", "); out.print(mi.argsSize + ", "); if ((access & (Const.ACC_ABSTRACT + Const.ACC_NATIVE)) != 0) { // out.println(mi.argsSize + ", 0, 0, \\"); } else { int locals = mi.locals; int stackSize = mi.stack; int codeLength = mi.code.length; if (mi == runCustomCodeMethod) { out.println(locals + ", RunCustomCodeMethod_MAX_STACK_SIZE, " + codeLength + ", \\"); } else { out.println(locals + ", " + stackSize + ", " + codeLength + ", \\"); } out.print("\t\t\t\t\t"); } out.print(classTable.getNameAndTypeKey(mi)); out.println((i == methodCount - 1) ? ")" : "),"); } out.println("\t\t\t}"); nmethods += methodCount; } void writeFields(EVMClass c) { // Some day, I'll have to deal with > 255 fields. // Today is not that day. Just do the simple case. FieldInfo ff[] = c.ci.fields; int nfields = ff == null ? 0 : ff.length; out.println("\t\t" + nfields + ","); out.println("\t\t{"); for ( int i = 0; i < nfields; i++ ){ FieldInfo f = ff[i]; if (f.isStaticMember()) { out.print("\t\t\tSTATIC_FIELD_INFO( "); } else { out.print("\t\t\tFIELD_INFO( "); } out.println("/* " + prettyName(f) + " */ \\"); out.print("\t\t\t\t" + c.getNativeName() + ", "); /* Note that access already includes ACC_DOUBLE, ACC_POINTER */ out.printHexInt(f.access); out.print(", " + f.instanceOffset + ", " + classTable.getNameAndTypeKey(f) + ")"); out.println( (i == nfields - 1) ? "" : "," ); } out.println("\t\t}"); this.nfields += nfields; } protected void writeConstantPool(EVMClass c) { final ConstantObject cpool[] = c.ci.constants; int length = cpool.length; final int[] tags = new int[length]; out.println("\t\t{"); out.println("\t\t\tROM_CPOOL_LENGTH(" + length + "),"); for (int index = 1; index < length; ) { ConstantObject cp = cpool[index]; int tag = cp.tag; switch (tag) { case Const.CONSTANT_INTEGER: case Const.CONSTANT_STRING: case Const.CONSTANT_LONG: case Const.CONSTANT_DOUBLE: tags[index] = tag; break; default: tags[index] = tag | (cp.isResolved() ? 0x80:0); break; } out.print("\t\t\tROM_CPOOL_"); writeConstant(cpool[index], true); index += cp.nSlots; out.println(index < length ? "," : ""); } out.println("\t\t},"); out.println("\t\t{"); writeArray(length, 12, "\t\t\t", new ArrayPrinter() { public void print(int index) { out.print(tags[index]); } }); nconstants += length; out.println("\t\t}"); } protected void writeInterfaces(final EVMClass c) { int length = c.ci.interfaces.length; out.println("\t\t" + length + ", /* interfaces */"); out.println("\t\t{"); writeArray(length, 12, "\t\t\t", new ArrayPrinter() { public void print(int index) { out.print(c.ci.interfaces[index].index); } }); out.println("\t\t}"); } protected void writePrimitiveArrayTable(ClassClass classes[]) { final EVMClass[] table = new EVMClass[12]; for (int i = 0; i < classes.length; i++) { EVMClass cc = (EVMClass) classes[i]; if (cc.isArrayClass()) { ArrayClassInfo aci = (ArrayClassInfo)cc.ci; if (aci.constants[1].tag == Const.CONSTANT_INTEGER) { int base = ((SingleValueConstant)aci.constants[1]).value; table[base] = cc; } } } out.println("ARRAY_CLASS PrimitiveArrayClasses[12] = {"); writeArray(0, 12, 1, "\t", new ArrayPrinter() { public void print(int index) { EVMClass entry = table[index]; if (entry == null) { out.print("NULL"); } else { out.print("&AllClassblocks." + entry.getNativeName()); } } }); out.println("};\n"); } protected void writeIntegerValue( int v ){ // little things make gcc happy. if (v==0x80000000) out.print( "(long)0x80000000" ); else out.print( v ); } protected void writeLongValue( String tag, int highval, int lowval ){ out.print( tag ); out.write( '(' ); writeIntegerValue( highval ); out.print( ", " ); writeIntegerValue( lowval ); out.write( ')' ); } protected void writeConstant(ConstantObject value, boolean verbose){ switch ( value.tag ){ case Const.CONSTANT_INTEGER: case Const.CONSTANT_FLOAT: out.print("INT("); writeIntegerValue(((SingleValueConstant)value).value); out.print(")"); break; case Const.CONSTANT_UTF8: System.out.println("Cannot write UTF entry: \"" + ((UnicodeConstant)value).string + "\""); out.print("UNKNOWN()"); formatError = true; break; case Const.CONSTANT_STRING: out.print("STRING("); stringTable.writeString(out, (StringConstant)value); out.print(")"); if (verbose) { out.print(" /* "); out.printSafeString(((StringConstant)value).str.string); out.print(" */"); } break; case Const.CONSTANT_LONG: { DoubleValueConstant dval = (DoubleValueConstant) value; writeLongValue( "LONG", dval.highVal, dval.lowVal ); break; } case Const.CONSTANT_DOUBLE: { DoubleValueConstant dval = (DoubleValueConstant) value; writeLongValue( "DOUBLE", dval.highVal, dval.lowVal ); break; } case Const.CONSTANT_CLASS: if (value.isResolved()) { ClassInfo ci = ((ClassConstant)value).find(); EVMClass c = (EVMClass)(ci.vmClass);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -