📄 classwriter.java
字号:
case FLOAT: databuf.appendByte('F'); break; case DOUBLE: databuf.appendByte('D'); break; case BOOLEAN: databuf.appendByte('Z'); break; case CLASS: assert value instanceof String; databuf.appendByte('s'); value = names.fromString(value.toString()); // CONSTANT_Utf8 break; default: throw new AssertionError(_value.type); } databuf.appendChar(pool.put(value)); } public void visitEnum(Attribute.Enum e) { databuf.appendByte('e'); databuf.appendChar(pool.put(typeSig(e.value.type))); databuf.appendChar(pool.put(e.value.name)); } public void visitClass(Attribute.Class clazz) { databuf.appendByte('c'); databuf.appendChar(pool.put(typeSig(clazz.type))); } public void visitCompound(Attribute.Compound compound) { databuf.appendByte('@'); writeCompoundAttribute(compound); } public void visitError(Attribute.Error x) { throw new AssertionError(x); } public void visitArray(Attribute.Array array) { databuf.appendByte('['); databuf.appendChar(array.values.length); for (Attribute a : array.values) { a.accept(this); } } } AttributeWriter awriter = new AttributeWriter(); /** Write a compound attribute excluding the '@' marker. */ void writeCompoundAttribute(Attribute.Compound c) { databuf.appendChar(pool.put(typeSig(c.type))); databuf.appendChar(c.values.length()); for (Pair<Symbol.MethodSymbol,Attribute> p : c.values) { databuf.appendChar(pool.put(p.fst.name)); p.snd.accept(awriter); } }/********************************************************************** * Writing Objects **********************************************************************/ /** Enter an inner class into the `innerClasses' set/queue. */ void enterInner(ClassSymbol c) { assert !c.type.isCompound(); try { c.complete(); } catch (CompletionFailure ex) { System.err.println("error: " + c + ": " + ex.getMessage()); throw ex; } if (c.type.tag != CLASS) return; // arrays if (pool != null && // pool might be null if called from xClassName c.owner.kind != PCK && (innerClasses == null || !innerClasses.contains(c))) {// log.errWriter.println("enter inner " + c);//DEBUG if (c.owner.kind == TYP) enterInner((ClassSymbol)c.owner); pool.put(c); pool.put(c.name); if (innerClasses == null) { innerClasses = new HashSet<ClassSymbol>(); innerClassesQueue = new ListBuffer<ClassSymbol>(); pool.put(names.InnerClasses); } innerClasses.add(c); innerClassesQueue.append(c); } } /** Write "inner classes" attribute. */ void writeInnerClasses() { int alenIdx = writeAttr(names.InnerClasses); databuf.appendChar(innerClassesQueue.length()); for (List<ClassSymbol> l = innerClassesQueue.toList(); l.nonEmpty(); l = l.tail) { ClassSymbol inner = l.head; char flags = (char) adjustFlags(inner.flags_field); if ((flags & INTERFACE) != 0) flags |= ABSTRACT; // Interfaces are always ABSTRACT if (inner.name.isEmpty()) flags &= ~FINAL; // Anonymous class: unset FINAL flag if (dumpInnerClassModifiers) { log.errWriter.println("INNERCLASS " + inner.name); log.errWriter.println("---" + flagNames(flags)); } databuf.appendChar(pool.get(inner)); databuf.appendChar( inner.owner.kind == TYP ? pool.get(inner.owner) : 0); databuf.appendChar( inner.name.len != 0 ? pool.get(inner.name) : 0); databuf.appendChar(flags); } endAttr(alenIdx); } /** Write field symbol, entering all references into constant pool. */ void writeField(VarSymbol v) { int flags = adjustFlags(v.flags()); databuf.appendChar(flags); if (dumpFieldModifiers) { log.errWriter.println("FIELD " + fieldName(v)); log.errWriter.println("---" + flagNames(v.flags())); } databuf.appendChar(pool.put(fieldName(v))); databuf.appendChar(pool.put(typeSig(v.erasure(types)))); int acountIdx = beginAttrs(); int acount = 0; if (v.getConstValue() != null) { int alenIdx = writeAttr(names.ConstantValue); databuf.appendChar(pool.put(v.getConstValue())); endAttr(alenIdx); acount++; } acount += writeMemberAttrs(v); endAttrs(acountIdx, acount); } /** Write method symbol, entering all references into constant pool. */ void writeMethod(MethodSymbol m) { int flags = adjustFlags(m.flags()); databuf.appendChar(flags); if (dumpMethodModifiers) { log.errWriter.println("METHOD " + fieldName(m)); log.errWriter.println("---" + flagNames(m.flags())); } databuf.appendChar(pool.put(fieldName(m))); databuf.appendChar(pool.put(typeSig(m.externalType(types)))); int acountIdx = beginAttrs(); int acount = 0; if (m.code != null) { int alenIdx = writeAttr(names.Code); writeCode(m.code); m.code = null; // to conserve space endAttr(alenIdx); acount++; } List<Type> thrown = m.erasure(types).getThrownTypes(); if (thrown.nonEmpty()) { int alenIdx = writeAttr(names.Exceptions); databuf.appendChar(thrown.length()); for (List<Type> l = thrown; l.nonEmpty(); l = l.tail) databuf.appendChar(pool.put(l.head.tsym)); endAttr(alenIdx); acount++; } if (m.defaultValue != null) { int alenIdx = writeAttr(names.AnnotationDefault); m.defaultValue.accept(awriter); endAttr(alenIdx); acount++; } acount += writeMemberAttrs(m); acount += writeParameterAttrs(m); endAttrs(acountIdx, acount); } /** Write code attribute of method. */ void writeCode(Code code) { databuf.appendChar(code.max_stack); databuf.appendChar(code.max_locals); databuf.appendInt(code.cp); databuf.appendBytes(code.code, 0, code.cp); databuf.appendChar(code.catchInfo.length()); for (List<char[]> l = code.catchInfo.toList(); l.nonEmpty(); l = l.tail) { for (int i = 0; i < l.head.length; i++) databuf.appendChar(l.head[i]); } int acountIdx = beginAttrs(); int acount = 0; if (code.lineInfo.nonEmpty()) { int alenIdx = writeAttr(names.LineNumberTable); databuf.appendChar(code.lineInfo.length()); for (List<char[]> l = code.lineInfo.reverse(); l.nonEmpty(); l = l.tail) for (int i = 0; i < l.head.length; i++) databuf.appendChar(l.head[i]); endAttr(alenIdx); acount++; } if (genCrt && (code.crt != null)) { CRTable crt = code.crt; int alenIdx = writeAttr(names.CharacterRangeTable); int crtIdx = beginAttrs(); int crtEntries = crt.writeCRT(databuf, code.lineMap, log); endAttrs(crtIdx, crtEntries); endAttr(alenIdx); acount++; } // counter for number of generic local variables int nGenericVars = 0; if (code.varBufferSize > 0) { int alenIdx = writeAttr(names.LocalVariableTable); databuf.appendChar(code.varBufferSize); for (int i=0; i<code.varBufferSize; i++) { Code.LocalVar var = code.varBuffer[i]; // write variable info assert var.start_pc >= 0; assert var.start_pc <= code.cp; databuf.appendChar(var.start_pc); assert var.length >= 0; assert (var.start_pc + var.length) <= code.cp; databuf.appendChar(var.length); VarSymbol sym = var.sym; databuf.appendChar(pool.put(sym.name)); Type vartype = sym.erasure(types); if (!types.isSameType(sym.type, vartype)) nGenericVars++; databuf.appendChar(pool.put(typeSig(vartype))); databuf.appendChar(var.reg); } endAttr(alenIdx); acount++; } if (nGenericVars > 0) { int alenIdx = writeAttr(names.LocalVariableTypeTable); databuf.appendChar(nGenericVars); int count = 0; for (int i=0; i<code.varBufferSize; i++) { Code.LocalVar var = code.varBuffer[i]; VarSymbol sym = var.sym; if (types.isSameType(sym.type, sym.erasure(types))) continue; count++; // write variable info databuf.appendChar(var.start_pc); databuf.appendChar(var.length); databuf.appendChar(pool.put(sym.name)); databuf.appendChar(pool.put(typeSig(sym.type))); databuf.appendChar(var.reg); } assert count == nGenericVars; endAttr(alenIdx); acount++; } if (code.stackMapBufferSize > 0) { if (debugstackmap) System.out.println("Stack map for " + code.meth); int alenIdx = writeAttr(code.stackMap.getAttributeName(names)); writeStackMap(code); endAttr(alenIdx); acount++; } endAttrs(acountIdx, acount); } void writeStackMap(Code code) { int nframes = code.stackMapBufferSize; if (debugstackmap) System.out.println(" nframes = " + nframes); databuf.appendChar(nframes); switch (code.stackMap) { case CLDC: for (int i=0; i<nframes; i++) { if (debugstackmap) System.out.print(" " + i + ":"); Code.StackMapFrame frame = code.stackMapBuffer[i]; // output PC if (debugstackmap) System.out.print(" pc=" + frame.pc); databuf.appendChar(frame.pc); // output locals int localCount = 0; for (int j=0; j<frame.locals.length; j += (target.generateEmptyAfterBig() ? 1 : Code.width(frame.locals[j]))) { localCount++; } if (debugstackmap) System.out.print(" nlocals=" + localCount); databuf.appendChar(localCount); for (int j=0; j<frame.locals.length; j += (target.generateEmptyAfterBig() ? 1 : Code.width(frame.locals[j]))) { if (debugstackmap) System.out.print(" local[" + j + "]="); writeStackMapType(frame.locals[j]); } // output stack int stackCount = 0; for (int j=0; j<frame.stack.length; j += (target.generateEmptyAfterBig() ? 1 : Code.width(frame.stack[j]))) { stackCount++; } if (debugstackmap) System.out.print(" nstack=" + stackCount); databuf.appendChar(stackCount); for (int j=0; j<frame.stack.length; j += (target.generateEmptyAfterBig() ? 1 : Code.width(frame.stack[j]))) { if (debugstackmap) System.out.print(" stack[" + j + "]="); writeStackMapType(frame.stack[j]); } if (debugstackmap) System.out.println(); } break; case JSR202: { assert code.stackMapBuffer == null; for (int i=0; i<nframes; i++) { if (debugstackmap) System.out.print(" " + i + ":"); StackMapTableFrame frame = code.stackMapTableBuffer[i]; frame.write(this); if (debugstackmap) System.out.println(); } break; } default: throw new AssertionError("Unexpected stackmap format value"); } } //where void writeStackMapType(Type t) { if (t == null) { if (debugstackmap) System.out.print("empty"); databuf.appendByte(0); } else switch(t.tag) { case BYTE: case CHAR: case SHORT: case INT: case BOOLEAN: if (debugstackmap) System.out.print("int"); databuf.appendByte(1); break; case FLOAT: if (debugstackmap) System.out.print("float"); databuf.appendByte(2); break; case DOUBLE: if (debugstackmap) System.out.print("double"); databuf.appendByte(3); break; case LONG: if (debugstackmap) System.out.print("long"); databuf.appendByte(4); break; case BOT: // null if (debugstackmap) System.out.print("null"); databuf.appendByte(5); break; case CLASS: case ARRAY: if (debugstackmap) System.out.print("object(" + t + ")"); databuf.appendByte(7); databuf.appendChar(pool.put(t)); break; case TYPEVAR: if (debugstackmap) System.out.print("object(" + types.erasure(t).tsym + ")"); databuf.appendByte(7); databuf.appendChar(pool.put(types.erasure(t).tsym)); break; case UNINITIALIZED_THIS: if (debugstackmap) System.out.print("uninit_this"); databuf.appendByte(6); break; case UNINITIALIZED_OBJECT: { UninitializedType uninitType = (UninitializedType)t; databuf.appendByte(8); if (debugstackmap) System.out.print("uninit_object@" + uninitType.offset); databuf.appendChar(uninitType.offset); } break; default: throw new AssertionError(); } } /** An entry in the JSR202 StackMapTable */ abstract static class StackMapTableFrame { abstract int getFrameType(); void write(ClassWriter writer) { int frameType = getFrameType(); writer.databuf.appendByte(frameType); if (writer.debugstackmap) System.out.print(" frame_type=" + frameType); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -