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 |