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

changeset 1336
26d93df3905a
parent 1313
873ddd9f4900
child 1343
f1e6b361a329
     1.1 --- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Tue Sep 25 11:52:37 2012 +0100
     1.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Tue Sep 25 11:53:18 2012 +0100
     1.3 @@ -26,6 +26,8 @@
     1.4  package com.sun.tools.javac.jvm;
     1.5  
     1.6  import java.io.*;
     1.7 +import java.util.LinkedHashMap;
     1.8 +import java.util.Map;
     1.9  import java.util.Set;
    1.10  import java.util.HashSet;
    1.11  
    1.12 @@ -137,6 +139,11 @@
    1.13       */
    1.14      ListBuffer<ClassSymbol> innerClassesQueue;
    1.15  
    1.16 +    /** The bootstrap methods to be written in the corresponding class attribute
    1.17 +     *  (one for each invokedynamic)
    1.18 +     */
    1.19 +    Map<MethodSymbol, Pool.MethodHandle> bootstrapMethods;
    1.20 +
    1.21      /** The log to use for verbose output.
    1.22       */
    1.23      private final Log log;
    1.24 @@ -477,11 +484,27 @@
    1.25  
    1.26              if (value instanceof MethodSymbol) {
    1.27                  MethodSymbol m = (MethodSymbol)value;
    1.28 -                poolbuf.appendByte((m.owner.flags() & INTERFACE) != 0
    1.29 -                          ? CONSTANT_InterfaceMethodref
    1.30 -                          : CONSTANT_Methodref);
    1.31 -                poolbuf.appendChar(pool.put(m.owner));
    1.32 -                poolbuf.appendChar(pool.put(nameType(m)));
    1.33 +                if (!m.isDynamic()) {
    1.34 +                    poolbuf.appendByte((m.owner.flags() & INTERFACE) != 0
    1.35 +                              ? CONSTANT_InterfaceMethodref
    1.36 +                              : CONSTANT_Methodref);
    1.37 +                    poolbuf.appendChar(pool.put(m.owner));
    1.38 +                    poolbuf.appendChar(pool.put(nameType(m)));
    1.39 +                } else {
    1.40 +                    //invokedynamic
    1.41 +                    DynamicMethodSymbol dynSym = (DynamicMethodSymbol)m;
    1.42 +                    Pool.MethodHandle handle = new Pool.MethodHandle(dynSym.bsmKind, dynSym.bsm, names);
    1.43 +                    bootstrapMethods.put(dynSym, handle);
    1.44 +                    //init cp entries
    1.45 +                    pool.put(names.BootstrapMethods);
    1.46 +                    pool.put(handle);
    1.47 +                    for (Object staticArg : dynSym.staticArgs) {
    1.48 +                        pool.put(staticArg);
    1.49 +                    }
    1.50 +                    poolbuf.appendByte(CONSTANT_InvokeDynamic);
    1.51 +                    poolbuf.appendChar(bootstrapMethods.size() - 1);
    1.52 +                    poolbuf.appendChar(pool.put(nameType(dynSym)));
    1.53 +                }
    1.54              } else if (value instanceof VarSymbol) {
    1.55                  VarSymbol v = (VarSymbol)value;
    1.56                  poolbuf.appendByte(CONSTANT_Fieldref);
    1.57 @@ -526,11 +549,20 @@
    1.58              } else if (value instanceof String) {
    1.59                  poolbuf.appendByte(CONSTANT_String);
    1.60                  poolbuf.appendChar(pool.put(names.fromString((String)value)));
    1.61 +            } else if (value instanceof MethodType) {
    1.62 +                MethodType mtype = (MethodType)value;
    1.63 +                poolbuf.appendByte(CONSTANT_MethodType);
    1.64 +                poolbuf.appendChar(pool.put(typeSig(mtype)));
    1.65              } else if (value instanceof Type) {
    1.66                  Type type = (Type)value;
    1.67                  if (type.tag == CLASS) enterInner((ClassSymbol)type.tsym);
    1.68                  poolbuf.appendByte(CONSTANT_Class);
    1.69                  poolbuf.appendChar(pool.put(xClassName(type)));
    1.70 +            } else if (value instanceof Pool.MethodHandle) {
    1.71 +                Pool.MethodHandle ref = (Pool.MethodHandle)value;
    1.72 +                poolbuf.appendByte(CONSTANT_MethodHandle);
    1.73 +                poolbuf.appendByte(ref.refKind);
    1.74 +                poolbuf.appendChar(pool.put(ref.refSym));
    1.75              } else {
    1.76                  Assert.error("writePool " + value);
    1.77              }
    1.78 @@ -914,6 +946,25 @@
    1.79          endAttr(alenIdx);
    1.80      }
    1.81  
    1.82 +    /** Write "bootstrapMethods" attribute.
    1.83 +     */
    1.84 +    void writeBootstrapMethods() {
    1.85 +        int alenIdx = writeAttr(names.BootstrapMethods);
    1.86 +        databuf.appendChar(bootstrapMethods.size());
    1.87 +        for (Map.Entry<MethodSymbol, Pool.MethodHandle> entry : bootstrapMethods.entrySet()) {
    1.88 +            DynamicMethodSymbol dsym = (DynamicMethodSymbol)entry.getKey();
    1.89 +            //write BSM handle
    1.90 +            databuf.appendChar(pool.get(entry.getValue()));
    1.91 +            //write static args length
    1.92 +            databuf.appendChar(dsym.staticArgs.length);
    1.93 +            //write static args array
    1.94 +            for (Object o : dsym.staticArgs) {
    1.95 +                databuf.appendChar(pool.get(o));
    1.96 +            }
    1.97 +        }
    1.98 +        endAttr(alenIdx);
    1.99 +    }
   1.100 +
   1.101      /** Write field symbol, entering all references into constant pool.
   1.102       */
   1.103      void writeField(VarSymbol v) {
   1.104 @@ -1483,6 +1534,7 @@
   1.105          pool = c.pool;
   1.106          innerClasses = null;
   1.107          innerClassesQueue = null;
   1.108 +        bootstrapMethods = new LinkedHashMap<MethodSymbol, Pool.MethodHandle>();
   1.109  
   1.110          Type supertype = types.supertype(c.type);
   1.111          List<Type> interfaces = types.interfaces(c.type);
   1.112 @@ -1589,6 +1641,12 @@
   1.113              writeInnerClasses();
   1.114              acount++;
   1.115          }
   1.116 +
   1.117 +        if (!bootstrapMethods.isEmpty()) {
   1.118 +            writeBootstrapMethods();
   1.119 +            acount++;
   1.120 +        }
   1.121 +
   1.122          endAttrs(acountIdx, acount);
   1.123  
   1.124          poolbuf.appendBytes(databuf.elems, 0, databuf.length);

mercurial