src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java

changeset 1587
f1f605f85850
parent 1565
d04960f05593
child 1592
9345394ac8fe
     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          }

mercurial