1.1 --- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Fri Feb 15 11:26:11 2013 -0800 1.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Fri Feb 15 18:40:38 2013 -0800 1.3 @@ -39,6 +39,9 @@ 1.4 import com.sun.tools.javac.code.*; 1.5 import com.sun.tools.javac.code.Attribute.RetentionPolicy; 1.6 import com.sun.tools.javac.code.Attribute.TypeCompound; 1.7 +import static com.sun.tools.javac.code.BoundKind.EXTENDS; 1.8 +import static com.sun.tools.javac.code.BoundKind.SUPER; 1.9 +import static com.sun.tools.javac.code.BoundKind.UNBOUND; 1.10 import com.sun.tools.javac.code.Symbol.*; 1.11 import com.sun.tools.javac.code.Type.*; 1.12 import com.sun.tools.javac.code.Types.UniqueType; 1.13 @@ -126,10 +129,6 @@ 1.14 */ 1.15 ByteBuffer poolbuf = new ByteBuffer(POOL_BUF_SIZE); 1.16 1.17 - /** An output buffer for type signatures. 1.18 - */ 1.19 - ByteBuffer sigbuf = new ByteBuffer(); 1.20 - 1.21 /** The constant pool. 1.22 */ 1.23 Pool pool; 1.24 @@ -158,6 +157,9 @@ 1.25 /** Access to files. */ 1.26 private final JavaFileManager fileManager; 1.27 1.28 + /** Sole signature generator */ 1.29 + private final CWSignatureGenerator signatureGen; 1.30 + 1.31 /** The tags and constants used in compressed stackmap. */ 1.32 static final int SAME_FRAME_SIZE = 64; 1.33 static final int SAME_LOCALS_1_STACK_ITEM_EXTENDED = 247; 1.34 @@ -185,6 +187,7 @@ 1.35 source = Source.instance(context); 1.36 types = Types.instance(context); 1.37 fileManager = context.get(JavaFileManager.class); 1.38 + signatureGen = new CWSignatureGenerator(types); 1.39 1.40 verbose = options.isSet(VERBOSE); 1.41 scramble = options.isSet("-scramble"); 1.42 @@ -270,172 +273,81 @@ 1.43 buf.elems[adr+3] = (byte)((x ) & 0xFF); 1.44 } 1.45 1.46 -/****************************************************************** 1.47 - * Signature Generation 1.48 - ******************************************************************/ 1.49 + /** 1.50 + * Signature Generation 1.51 + */ 1.52 + private class CWSignatureGenerator extends Types.SignatureGenerator { 1.53 1.54 - /** Assemble signature of given type in string buffer. 1.55 - */ 1.56 - void assembleSig(Type type) { 1.57 - type = type.unannotatedType(); 1.58 - switch (type.getTag()) { 1.59 - case BYTE: 1.60 - sigbuf.appendByte('B'); 1.61 - break; 1.62 - case SHORT: 1.63 - sigbuf.appendByte('S'); 1.64 - break; 1.65 - case CHAR: 1.66 - sigbuf.appendByte('C'); 1.67 - break; 1.68 - case INT: 1.69 - sigbuf.appendByte('I'); 1.70 - break; 1.71 - case LONG: 1.72 - sigbuf.appendByte('J'); 1.73 - break; 1.74 - case FLOAT: 1.75 - sigbuf.appendByte('F'); 1.76 - break; 1.77 - case DOUBLE: 1.78 - sigbuf.appendByte('D'); 1.79 - break; 1.80 - case BOOLEAN: 1.81 - sigbuf.appendByte('Z'); 1.82 - break; 1.83 - case VOID: 1.84 - sigbuf.appendByte('V'); 1.85 - break; 1.86 - case CLASS: 1.87 - sigbuf.appendByte('L'); 1.88 - assembleClassSig(type); 1.89 - sigbuf.appendByte(';'); 1.90 - break; 1.91 - case ARRAY: 1.92 - ArrayType at = (ArrayType)type; 1.93 - sigbuf.appendByte('['); 1.94 - assembleSig(at.elemtype); 1.95 - break; 1.96 - case METHOD: 1.97 - MethodType mt = (MethodType)type; 1.98 - sigbuf.appendByte('('); 1.99 - assembleSig(mt.argtypes); 1.100 - sigbuf.appendByte(')'); 1.101 - assembleSig(mt.restype); 1.102 - if (hasTypeVar(mt.thrown)) { 1.103 - for (List<Type> l = mt.thrown; l.nonEmpty(); l = l.tail) { 1.104 - sigbuf.appendByte('^'); 1.105 - assembleSig(l.head); 1.106 - } 1.107 + /** 1.108 + * An output buffer for type signatures. 1.109 + */ 1.110 + ByteBuffer sigbuf = new ByteBuffer(); 1.111 + 1.112 + CWSignatureGenerator(Types types) { 1.113 + super(types); 1.114 + } 1.115 + 1.116 + /** 1.117 + * Assemble signature of given type in string buffer. 1.118 + * Check for uninitialized types before calling the general case. 1.119 + */ 1.120 + @Override 1.121 + public void assembleSig(Type type) { 1.122 + type = type.unannotatedType(); 1.123 + switch (type.getTag()) { 1.124 + case UNINITIALIZED_THIS: 1.125 + case UNINITIALIZED_OBJECT: 1.126 + // we don't yet have a spec for uninitialized types in the 1.127 + // local variable table 1.128 + assembleSig(types.erasure(((UninitializedType)type).qtype)); 1.129 + break; 1.130 + default: 1.131 + super.assembleSig(type); 1.132 } 1.133 - break; 1.134 - case WILDCARD: { 1.135 - WildcardType ta = (WildcardType) type; 1.136 - switch (ta.kind) { 1.137 - case SUPER: 1.138 - sigbuf.appendByte('-'); 1.139 - assembleSig(ta.type); 1.140 - break; 1.141 - case EXTENDS: 1.142 - sigbuf.appendByte('+'); 1.143 - assembleSig(ta.type); 1.144 - break; 1.145 - case UNBOUND: 1.146 - sigbuf.appendByte('*'); 1.147 - break; 1.148 - default: 1.149 - throw new AssertionError(ta.kind); 1.150 - } 1.151 - break; 1.152 } 1.153 - case TYPEVAR: 1.154 - sigbuf.appendByte('T'); 1.155 - sigbuf.appendName(type.tsym.name); 1.156 - sigbuf.appendByte(';'); 1.157 - break; 1.158 - case FORALL: 1.159 - ForAll ft = (ForAll)type; 1.160 - assembleParamsSig(ft.tvars); 1.161 - assembleSig(ft.qtype); 1.162 - break; 1.163 - case UNINITIALIZED_THIS: 1.164 - case UNINITIALIZED_OBJECT: 1.165 - // we don't yet have a spec for uninitialized types in the 1.166 - // local variable table 1.167 - assembleSig(types.erasure(((UninitializedType)type).qtype)); 1.168 - break; 1.169 - default: 1.170 - throw new AssertionError("typeSig " + type.getTag()); 1.171 + 1.172 + @Override 1.173 + protected void append(char ch) { 1.174 + sigbuf.appendByte(ch); 1.175 + } 1.176 + 1.177 + @Override 1.178 + protected void append(byte[] ba) { 1.179 + sigbuf.appendBytes(ba); 1.180 + } 1.181 + 1.182 + @Override 1.183 + protected void append(Name name) { 1.184 + sigbuf.appendName(name); 1.185 + } 1.186 + 1.187 + @Override 1.188 + protected void classReference(ClassSymbol c) { 1.189 + enterInner(c); 1.190 + } 1.191 + 1.192 + private void reset() { 1.193 + sigbuf.reset(); 1.194 + } 1.195 + 1.196 + private Name toName() { 1.197 + return sigbuf.toName(names); 1.198 + } 1.199 + 1.200 + private boolean isEmpty() { 1.201 + return sigbuf.length == 0; 1.202 } 1.203 } 1.204 1.205 - boolean hasTypeVar(List<Type> l) { 1.206 - while (l.nonEmpty()) { 1.207 - if (l.head.hasTag(TYPEVAR)) return true; 1.208 - l = l.tail; 1.209 - } 1.210 - return false; 1.211 - } 1.212 - 1.213 - void assembleClassSig(Type type) { 1.214 - type = type.unannotatedType(); 1.215 - ClassType ct = (ClassType)type; 1.216 - ClassSymbol c = (ClassSymbol)ct.tsym; 1.217 - enterInner(c); 1.218 - Type outer = ct.getEnclosingType(); 1.219 - if (outer.allparams().nonEmpty()) { 1.220 - boolean rawOuter = 1.221 - c.owner.kind == MTH || // either a local class 1.222 - c.name == names.empty; // or anonymous 1.223 - assembleClassSig(rawOuter 1.224 - ? types.erasure(outer) 1.225 - : outer); 1.226 - sigbuf.appendByte('.'); 1.227 - Assert.check(c.flatname.startsWith(c.owner.enclClass().flatname)); 1.228 - sigbuf.appendName(rawOuter 1.229 - ? c.flatname.subName(c.owner.enclClass().flatname.getByteLength()+1,c.flatname.getByteLength()) 1.230 - : c.name); 1.231 - } else { 1.232 - sigbuf.appendBytes(externalize(c.flatname)); 1.233 - } 1.234 - if (ct.getTypeArguments().nonEmpty()) { 1.235 - sigbuf.appendByte('<'); 1.236 - assembleSig(ct.getTypeArguments()); 1.237 - sigbuf.appendByte('>'); 1.238 - } 1.239 - } 1.240 - 1.241 - 1.242 - void assembleSig(List<Type> types) { 1.243 - for (List<Type> ts = types; ts.nonEmpty(); ts = ts.tail) 1.244 - assembleSig(ts.head); 1.245 - } 1.246 - 1.247 - void assembleParamsSig(List<Type> typarams) { 1.248 - sigbuf.appendByte('<'); 1.249 - for (List<Type> ts = typarams; ts.nonEmpty(); ts = ts.tail) { 1.250 - TypeVar tvar = (TypeVar)ts.head; 1.251 - sigbuf.appendName(tvar.tsym.name); 1.252 - List<Type> bounds = types.getBounds(tvar); 1.253 - if ((bounds.head.tsym.flags() & INTERFACE) != 0) { 1.254 - sigbuf.appendByte(':'); 1.255 - } 1.256 - for (List<Type> l = bounds; l.nonEmpty(); l = l.tail) { 1.257 - sigbuf.appendByte(':'); 1.258 - assembleSig(l.head); 1.259 - } 1.260 - } 1.261 - sigbuf.appendByte('>'); 1.262 - } 1.263 - 1.264 - /** Return signature of given type 1.265 + /** 1.266 + * Return signature of given type 1.267 */ 1.268 Name typeSig(Type type) { 1.269 - Assert.check(sigbuf.length == 0); 1.270 + Assert.check(signatureGen.isEmpty()); 1.271 //- System.out.println(" ? " + type); 1.272 - assembleSig(type); 1.273 - Name n = sigbuf.toName(names); 1.274 - sigbuf.reset(); 1.275 + signatureGen.assembleSig(type); 1.276 + Name n = signatureGen.toName(); 1.277 + signatureGen.reset(); 1.278 //- System.out.println(" " + n); 1.279 return n; 1.280 } 1.281 @@ -711,7 +623,7 @@ 1.282 (flags & (SYNTHETIC|BRIDGE)) != SYNTHETIC && 1.283 (flags & ANONCONSTR) == 0 && 1.284 (!types.isSameType(sym.type, sym.erasure(types)) || 1.285 - hasTypeVar(sym.type.getThrownTypes()))) { 1.286 + signatureGen.hasTypeVar(sym.type.getThrownTypes()))) { 1.287 // note that a local class with captured variables 1.288 // will get a signature attribute 1.289 int alenIdx = writeAttr(names.Signature); 1.290 @@ -1730,7 +1642,7 @@ 1.291 Assert.check((c.flags() & COMPOUND) == 0); 1.292 databuf.reset(); 1.293 poolbuf.reset(); 1.294 - sigbuf.reset(); 1.295 + signatureGen.reset(); 1.296 pool = c.pool; 1.297 innerClasses = null; 1.298 innerClassesQueue = null; 1.299 @@ -1791,12 +1703,12 @@ 1.300 if (sigReq) { 1.301 Assert.check(source.allowGenerics()); 1.302 int alenIdx = writeAttr(names.Signature); 1.303 - if (typarams.length() != 0) assembleParamsSig(typarams); 1.304 - assembleSig(supertype); 1.305 + if (typarams.length() != 0) signatureGen.assembleParamsSig(typarams); 1.306 + signatureGen.assembleSig(supertype); 1.307 for (List<Type> l = interfaces; l.nonEmpty(); l = l.tail) 1.308 - assembleSig(l.head); 1.309 - databuf.appendChar(pool.put(sigbuf.toName(names))); 1.310 - sigbuf.reset(); 1.311 + signatureGen.assembleSig(l.head); 1.312 + databuf.appendChar(pool.put(signatureGen.toName())); 1.313 + signatureGen.reset(); 1.314 endAttr(alenIdx); 1.315 acount++; 1.316 }