23 * questions. |
23 * questions. |
24 */ |
24 */ |
25 |
25 |
26 package com.sun.tools.javac.jvm; |
26 package com.sun.tools.javac.jvm; |
27 |
27 |
|
28 import com.sun.tools.javac.code.Flags; |
|
29 import com.sun.tools.javac.code.Kinds; |
28 import java.util.*; |
30 import java.util.*; |
29 |
31 |
|
32 import com.sun.tools.javac.code.Symbol; |
30 import com.sun.tools.javac.code.Symbol.*; |
33 import com.sun.tools.javac.code.Symbol.*; |
|
34 import com.sun.tools.javac.code.Type; |
|
35 import com.sun.tools.javac.util.Assert; |
|
36 import com.sun.tools.javac.util.Filter; |
|
37 import com.sun.tools.javac.util.Name; |
|
38 import com.sun.tools.javac.util.Names; |
31 |
39 |
32 /** An internal structure that corresponds to the constant pool of a classfile. |
40 /** An internal structure that corresponds to the constant pool of a classfile. |
33 * |
41 * |
34 * <p><b>This is NOT part of any supported API. |
42 * <p><b>This is NOT part of any supported API. |
35 * If you write code that depends on this, you do so at your own risk. |
43 * If you write code that depends on this, you do so at your own risk. |
165 v.name.hashCode() * 33 + |
173 v.name.hashCode() * 33 + |
166 v.owner.hashCode() * 9 + |
174 v.owner.hashCode() * 9 + |
167 v.type.hashCode(); |
175 v.type.hashCode(); |
168 } |
176 } |
169 } |
177 } |
|
178 |
|
179 public static class MethodHandle { |
|
180 |
|
181 /** Reference kind - see ClassFile */ |
|
182 int refKind; |
|
183 |
|
184 /** Reference symbol */ |
|
185 Symbol refSym; |
|
186 |
|
187 /** Reference to the name table */ |
|
188 Names names; |
|
189 |
|
190 public MethodHandle(int refKind, Symbol refSym, Names names) { |
|
191 this.refKind = refKind; |
|
192 this.refSym = refSym; |
|
193 this.names = names; |
|
194 checkConsistent(); |
|
195 } |
|
196 public boolean equals(Object other) { |
|
197 if (!(other instanceof MethodHandle)) return false; |
|
198 MethodHandle mr = (MethodHandle) other; |
|
199 if (mr.refKind != refKind) return false; |
|
200 Symbol o = mr.refSym; |
|
201 return |
|
202 o.name == refSym.name && |
|
203 o.owner == refSym.owner && |
|
204 o.type.equals(refSym.type); |
|
205 } |
|
206 public int hashCode() { |
|
207 return |
|
208 refKind * 65 + |
|
209 refSym.name.hashCode() * 33 + |
|
210 refSym.owner.hashCode() * 9 + |
|
211 refSym.type.hashCode(); |
|
212 } |
|
213 |
|
214 /** |
|
215 * Check consistency of reference kind and symbol (see JVMS 4.4.8) |
|
216 */ |
|
217 @SuppressWarnings("fallthrough") |
|
218 private void checkConsistent() { |
|
219 boolean staticOk = false; |
|
220 int expectedKind = -1; |
|
221 Filter<Name> nameFilter = nonInitFilter; |
|
222 boolean interfaceOwner = false; |
|
223 switch (refKind) { |
|
224 case ClassFile.REF_getStatic: |
|
225 case ClassFile.REF_putStatic: |
|
226 staticOk = true; |
|
227 case ClassFile.REF_getField: |
|
228 case ClassFile.REF_putField: |
|
229 expectedKind = Kinds.VAR; |
|
230 break; |
|
231 case ClassFile.REF_newInvokeSpecial: |
|
232 nameFilter = initFilter; |
|
233 expectedKind = Kinds.MTH; |
|
234 break; |
|
235 case ClassFile.REF_invokeInterface: |
|
236 interfaceOwner = true; |
|
237 expectedKind = Kinds.MTH; |
|
238 break; |
|
239 case ClassFile.REF_invokeStatic: |
|
240 staticOk = true; |
|
241 case ClassFile.REF_invokeVirtual: |
|
242 case ClassFile.REF_invokeSpecial: |
|
243 expectedKind = Kinds.MTH; |
|
244 break; |
|
245 } |
|
246 Assert.check(!refSym.isStatic() || staticOk); |
|
247 Assert.check(refSym.kind == expectedKind); |
|
248 Assert.check(nameFilter.accepts(refSym.name)); |
|
249 Assert.check(!refSym.owner.isInterface() || interfaceOwner); |
|
250 } |
|
251 //where |
|
252 Filter<Name> nonInitFilter = new Filter<Name>() { |
|
253 public boolean accepts(Name n) { |
|
254 return n != names.init && n != names.clinit; |
|
255 } |
|
256 }; |
|
257 |
|
258 Filter<Name> initFilter = new Filter<Name>() { |
|
259 public boolean accepts(Name n) { |
|
260 return n == names.init; |
|
261 } |
|
262 }; |
|
263 } |
170 } |
264 } |