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

changeset 1336
26d93df3905a
parent 1313
873ddd9f4900
child 1343
f1e6b361a329
equal deleted inserted replaced
1335:99983a4a593b 1336:26d93df3905a
24 */ 24 */
25 25
26 package com.sun.tools.javac.jvm; 26 package com.sun.tools.javac.jvm;
27 27
28 import java.io.*; 28 import java.io.*;
29 import java.util.LinkedHashMap;
30 import java.util.Map;
29 import java.util.Set; 31 import java.util.Set;
30 import java.util.HashSet; 32 import java.util.HashSet;
31 33
32 import javax.tools.JavaFileManager; 34 import javax.tools.JavaFileManager;
33 import javax.tools.FileObject; 35 import javax.tools.FileObject;
134 136
135 /** The inner classes to be written, as a queue where 137 /** The inner classes to be written, as a queue where
136 * enclosing classes come first. 138 * enclosing classes come first.
137 */ 139 */
138 ListBuffer<ClassSymbol> innerClassesQueue; 140 ListBuffer<ClassSymbol> innerClassesQueue;
141
142 /** The bootstrap methods to be written in the corresponding class attribute
143 * (one for each invokedynamic)
144 */
145 Map<MethodSymbol, Pool.MethodHandle> bootstrapMethods;
139 146
140 /** The log to use for verbose output. 147 /** The log to use for verbose output.
141 */ 148 */
142 private final Log log; 149 private final Log log;
143 150
475 else if (value instanceof Pool.Variable) 482 else if (value instanceof Pool.Variable)
476 value = ((Pool.Variable)value).v; 483 value = ((Pool.Variable)value).v;
477 484
478 if (value instanceof MethodSymbol) { 485 if (value instanceof MethodSymbol) {
479 MethodSymbol m = (MethodSymbol)value; 486 MethodSymbol m = (MethodSymbol)value;
480 poolbuf.appendByte((m.owner.flags() & INTERFACE) != 0 487 if (!m.isDynamic()) {
481 ? CONSTANT_InterfaceMethodref 488 poolbuf.appendByte((m.owner.flags() & INTERFACE) != 0
482 : CONSTANT_Methodref); 489 ? CONSTANT_InterfaceMethodref
483 poolbuf.appendChar(pool.put(m.owner)); 490 : CONSTANT_Methodref);
484 poolbuf.appendChar(pool.put(nameType(m))); 491 poolbuf.appendChar(pool.put(m.owner));
492 poolbuf.appendChar(pool.put(nameType(m)));
493 } else {
494 //invokedynamic
495 DynamicMethodSymbol dynSym = (DynamicMethodSymbol)m;
496 Pool.MethodHandle handle = new Pool.MethodHandle(dynSym.bsmKind, dynSym.bsm, names);
497 bootstrapMethods.put(dynSym, handle);
498 //init cp entries
499 pool.put(names.BootstrapMethods);
500 pool.put(handle);
501 for (Object staticArg : dynSym.staticArgs) {
502 pool.put(staticArg);
503 }
504 poolbuf.appendByte(CONSTANT_InvokeDynamic);
505 poolbuf.appendChar(bootstrapMethods.size() - 1);
506 poolbuf.appendChar(pool.put(nameType(dynSym)));
507 }
485 } else if (value instanceof VarSymbol) { 508 } else if (value instanceof VarSymbol) {
486 VarSymbol v = (VarSymbol)value; 509 VarSymbol v = (VarSymbol)value;
487 poolbuf.appendByte(CONSTANT_Fieldref); 510 poolbuf.appendByte(CONSTANT_Fieldref);
488 poolbuf.appendChar(pool.put(v.owner)); 511 poolbuf.appendChar(pool.put(v.owner));
489 poolbuf.appendChar(pool.put(nameType(v))); 512 poolbuf.appendChar(pool.put(nameType(v)));
524 poolbuf.appendDouble(((Double)value).doubleValue()); 547 poolbuf.appendDouble(((Double)value).doubleValue());
525 i++; 548 i++;
526 } else if (value instanceof String) { 549 } else if (value instanceof String) {
527 poolbuf.appendByte(CONSTANT_String); 550 poolbuf.appendByte(CONSTANT_String);
528 poolbuf.appendChar(pool.put(names.fromString((String)value))); 551 poolbuf.appendChar(pool.put(names.fromString((String)value)));
552 } else if (value instanceof MethodType) {
553 MethodType mtype = (MethodType)value;
554 poolbuf.appendByte(CONSTANT_MethodType);
555 poolbuf.appendChar(pool.put(typeSig(mtype)));
529 } else if (value instanceof Type) { 556 } else if (value instanceof Type) {
530 Type type = (Type)value; 557 Type type = (Type)value;
531 if (type.tag == CLASS) enterInner((ClassSymbol)type.tsym); 558 if (type.tag == CLASS) enterInner((ClassSymbol)type.tsym);
532 poolbuf.appendByte(CONSTANT_Class); 559 poolbuf.appendByte(CONSTANT_Class);
533 poolbuf.appendChar(pool.put(xClassName(type))); 560 poolbuf.appendChar(pool.put(xClassName(type)));
561 } else if (value instanceof Pool.MethodHandle) {
562 Pool.MethodHandle ref = (Pool.MethodHandle)value;
563 poolbuf.appendByte(CONSTANT_MethodHandle);
564 poolbuf.appendByte(ref.refKind);
565 poolbuf.appendChar(pool.put(ref.refSym));
534 } else { 566 } else {
535 Assert.error("writePool " + value); 567 Assert.error("writePool " + value);
536 } 568 }
537 i++; 569 i++;
538 } 570 }
908 databuf.appendChar( 940 databuf.appendChar(
909 inner.owner.kind == TYP ? pool.get(inner.owner) : 0); 941 inner.owner.kind == TYP ? pool.get(inner.owner) : 0);
910 databuf.appendChar( 942 databuf.appendChar(
911 !inner.name.isEmpty() ? pool.get(inner.name) : 0); 943 !inner.name.isEmpty() ? pool.get(inner.name) : 0);
912 databuf.appendChar(flags); 944 databuf.appendChar(flags);
945 }
946 endAttr(alenIdx);
947 }
948
949 /** Write "bootstrapMethods" attribute.
950 */
951 void writeBootstrapMethods() {
952 int alenIdx = writeAttr(names.BootstrapMethods);
953 databuf.appendChar(bootstrapMethods.size());
954 for (Map.Entry<MethodSymbol, Pool.MethodHandle> entry : bootstrapMethods.entrySet()) {
955 DynamicMethodSymbol dsym = (DynamicMethodSymbol)entry.getKey();
956 //write BSM handle
957 databuf.appendChar(pool.get(entry.getValue()));
958 //write static args length
959 databuf.appendChar(dsym.staticArgs.length);
960 //write static args array
961 for (Object o : dsym.staticArgs) {
962 databuf.appendChar(pool.get(o));
963 }
913 } 964 }
914 endAttr(alenIdx); 965 endAttr(alenIdx);
915 } 966 }
916 967
917 /** Write field symbol, entering all references into constant pool. 968 /** Write field symbol, entering all references into constant pool.
1481 poolbuf.reset(); 1532 poolbuf.reset();
1482 sigbuf.reset(); 1533 sigbuf.reset();
1483 pool = c.pool; 1534 pool = c.pool;
1484 innerClasses = null; 1535 innerClasses = null;
1485 innerClassesQueue = null; 1536 innerClassesQueue = null;
1537 bootstrapMethods = new LinkedHashMap<MethodSymbol, Pool.MethodHandle>();
1486 1538
1487 Type supertype = types.supertype(c.type); 1539 Type supertype = types.supertype(c.type);
1488 List<Type> interfaces = types.interfaces(c.type); 1540 List<Type> interfaces = types.interfaces(c.type);
1489 List<Type> typarams = c.type.getTypeArguments(); 1541 List<Type> typarams = c.type.getTypeArguments();
1490 1542
1587 1639
1588 if (innerClasses != null) { 1640 if (innerClasses != null) {
1589 writeInnerClasses(); 1641 writeInnerClasses();
1590 acount++; 1642 acount++;
1591 } 1643 }
1644
1645 if (!bootstrapMethods.isEmpty()) {
1646 writeBootstrapMethods();
1647 acount++;
1648 }
1649
1592 endAttrs(acountIdx, acount); 1650 endAttrs(acountIdx, acount);
1593 1651
1594 poolbuf.appendBytes(databuf.elems, 0, databuf.length); 1652 poolbuf.appendBytes(databuf.elems, 0, databuf.length);
1595 out.write(poolbuf.elems, 0, poolbuf.length); 1653 out.write(poolbuf.elems, 0, poolbuf.length);
1596 1654

mercurial