1.1 --- a/src/share/classes/com/sun/tools/javac/jvm/Pool.java Tue Sep 25 11:52:37 2012 +0100 1.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Pool.java Tue Sep 25 11:53:18 2012 +0100 1.3 @@ -25,9 +25,17 @@ 1.4 1.5 package com.sun.tools.javac.jvm; 1.6 1.7 +import com.sun.tools.javac.code.Flags; 1.8 +import com.sun.tools.javac.code.Kinds; 1.9 import java.util.*; 1.10 1.11 +import com.sun.tools.javac.code.Symbol; 1.12 import com.sun.tools.javac.code.Symbol.*; 1.13 +import com.sun.tools.javac.code.Type; 1.14 +import com.sun.tools.javac.util.Assert; 1.15 +import com.sun.tools.javac.util.Filter; 1.16 +import com.sun.tools.javac.util.Name; 1.17 +import com.sun.tools.javac.util.Names; 1.18 1.19 /** An internal structure that corresponds to the constant pool of a classfile. 1.20 * 1.21 @@ -167,4 +175,90 @@ 1.22 v.type.hashCode(); 1.23 } 1.24 } 1.25 + 1.26 + public static class MethodHandle { 1.27 + 1.28 + /** Reference kind - see ClassFile */ 1.29 + int refKind; 1.30 + 1.31 + /** Reference symbol */ 1.32 + Symbol refSym; 1.33 + 1.34 + /** Reference to the name table */ 1.35 + Names names; 1.36 + 1.37 + public MethodHandle(int refKind, Symbol refSym, Names names) { 1.38 + this.refKind = refKind; 1.39 + this.refSym = refSym; 1.40 + this.names = names; 1.41 + checkConsistent(); 1.42 + } 1.43 + public boolean equals(Object other) { 1.44 + if (!(other instanceof MethodHandle)) return false; 1.45 + MethodHandle mr = (MethodHandle) other; 1.46 + if (mr.refKind != refKind) return false; 1.47 + Symbol o = mr.refSym; 1.48 + return 1.49 + o.name == refSym.name && 1.50 + o.owner == refSym.owner && 1.51 + o.type.equals(refSym.type); 1.52 + } 1.53 + public int hashCode() { 1.54 + return 1.55 + refKind * 65 + 1.56 + refSym.name.hashCode() * 33 + 1.57 + refSym.owner.hashCode() * 9 + 1.58 + refSym.type.hashCode(); 1.59 + } 1.60 + 1.61 + /** 1.62 + * Check consistency of reference kind and symbol (see JVMS 4.4.8) 1.63 + */ 1.64 + @SuppressWarnings("fallthrough") 1.65 + private void checkConsistent() { 1.66 + boolean staticOk = false; 1.67 + int expectedKind = -1; 1.68 + Filter<Name> nameFilter = nonInitFilter; 1.69 + boolean interfaceOwner = false; 1.70 + switch (refKind) { 1.71 + case ClassFile.REF_getStatic: 1.72 + case ClassFile.REF_putStatic: 1.73 + staticOk = true; 1.74 + case ClassFile.REF_getField: 1.75 + case ClassFile.REF_putField: 1.76 + expectedKind = Kinds.VAR; 1.77 + break; 1.78 + case ClassFile.REF_newInvokeSpecial: 1.79 + nameFilter = initFilter; 1.80 + expectedKind = Kinds.MTH; 1.81 + break; 1.82 + case ClassFile.REF_invokeInterface: 1.83 + interfaceOwner = true; 1.84 + expectedKind = Kinds.MTH; 1.85 + break; 1.86 + case ClassFile.REF_invokeStatic: 1.87 + staticOk = true; 1.88 + case ClassFile.REF_invokeVirtual: 1.89 + case ClassFile.REF_invokeSpecial: 1.90 + expectedKind = Kinds.MTH; 1.91 + break; 1.92 + } 1.93 + Assert.check(!refSym.isStatic() || staticOk); 1.94 + Assert.check(refSym.kind == expectedKind); 1.95 + Assert.check(nameFilter.accepts(refSym.name)); 1.96 + Assert.check(!refSym.owner.isInterface() || interfaceOwner); 1.97 + } 1.98 + //where 1.99 + Filter<Name> nonInitFilter = new Filter<Name>() { 1.100 + public boolean accepts(Name n) { 1.101 + return n != names.init && n != names.clinit; 1.102 + } 1.103 + }; 1.104 + 1.105 + Filter<Name> initFilter = new Filter<Name>() { 1.106 + public boolean accepts(Name n) { 1.107 + return n == names.init; 1.108 + } 1.109 + }; 1.110 + } 1.111 }