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);