|
22 | 22 | */
|
23 | 23 | package com.oracle.truffle.espresso.constantpool;
|
24 | 24 |
|
| 25 | +import java.util.logging.Level; |
| 26 | + |
25 | 27 | import com.oracle.truffle.api.Assumption;
|
26 | 28 | import com.oracle.truffle.api.CompilerAsserts;
|
27 | 29 | import com.oracle.truffle.api.CompilerDirectives;
|
28 | 30 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
29 | 31 | import com.oracle.truffle.espresso.EspressoLanguage;
|
30 | 32 | import com.oracle.truffle.espresso.EspressoOptions;
|
31 |
| -import com.oracle.truffle.espresso.classfile.descriptors.Signatures; |
32 |
| -import com.oracle.truffle.espresso.classfile.descriptors.Symbol; |
33 |
| -import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Descriptor; |
34 |
| -import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Name; |
35 |
| -import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Signature; |
36 |
| -import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Type; |
37 |
| -import com.oracle.truffle.espresso.impl.ClassRegistry; |
38 |
| -import com.oracle.truffle.espresso.impl.Field; |
39 |
| -import com.oracle.truffle.espresso.impl.Klass; |
40 |
| -import com.oracle.truffle.espresso.impl.Member; |
41 |
| -import com.oracle.truffle.espresso.impl.Method; |
42 |
| -import com.oracle.truffle.espresso.impl.ObjectKlass; |
43 |
| -import com.oracle.truffle.espresso.meta.Meta; |
44 |
| -import com.oracle.truffle.espresso.nodes.methodhandle.MHInvokeGenericNode; |
45 |
| -import com.oracle.truffle.espresso.nodes.methodhandle.MHLinkToNode; |
46 | 33 | import com.oracle.truffle.espresso.classfile.ConstantPool.Tag;
|
47 |
| -import com.oracle.truffle.espresso.meta.EspressoError; |
48 | 34 | import com.oracle.truffle.espresso.classfile.attributes.BootstrapMethodsAttribute;
|
49 | 35 | import com.oracle.truffle.espresso.classfile.constantpool.ClassConstant;
|
50 | 36 | import com.oracle.truffle.espresso.classfile.constantpool.ClassMethodRefConstant;
|
|
58 | 44 | import com.oracle.truffle.espresso.classfile.constantpool.MethodTypeConstant;
|
59 | 45 | import com.oracle.truffle.espresso.classfile.constantpool.Resolvable;
|
60 | 46 | import com.oracle.truffle.espresso.classfile.constantpool.StringConstant;
|
| 47 | +import com.oracle.truffle.espresso.classfile.descriptors.Signatures; |
| 48 | +import com.oracle.truffle.espresso.classfile.descriptors.Symbol; |
| 49 | +import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Descriptor; |
| 50 | +import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Name; |
| 51 | +import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Signature; |
| 52 | +import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Type; |
61 | 53 | import com.oracle.truffle.espresso.classfile.perf.DebugCounter;
|
| 54 | +import com.oracle.truffle.espresso.impl.ClassRegistry; |
| 55 | +import com.oracle.truffle.espresso.impl.Field; |
| 56 | +import com.oracle.truffle.espresso.impl.Klass; |
| 57 | +import com.oracle.truffle.espresso.impl.Member; |
| 58 | +import com.oracle.truffle.espresso.impl.Method; |
| 59 | +import com.oracle.truffle.espresso.impl.ObjectKlass; |
| 60 | +import com.oracle.truffle.espresso.meta.EspressoError; |
| 61 | +import com.oracle.truffle.espresso.meta.Meta; |
| 62 | +import com.oracle.truffle.espresso.nodes.methodhandle.MHInvokeGenericNode; |
| 63 | +import com.oracle.truffle.espresso.nodes.methodhandle.MHLinkToNode; |
62 | 64 | import com.oracle.truffle.espresso.redefinition.ClassRedefinition;
|
63 | 65 | import com.oracle.truffle.espresso.resolver.LinkResolver;
|
64 | 66 | import com.oracle.truffle.espresso.runtime.EspressoContext;
|
65 | 67 | import com.oracle.truffle.espresso.runtime.EspressoException;
|
66 | 68 | import com.oracle.truffle.espresso.runtime.staticobject.StaticObject;
|
67 | 69 | import com.oracle.truffle.espresso.substitutions.JavaType;
|
68 | 70 |
|
69 |
| -import java.util.logging.Level; |
70 |
| - |
71 | 71 | public final class Resolution {
|
72 | 72 | static final DebugCounter CLASS_RESOLVE_COUNT = DebugCounter.create("ClassConstant.resolve calls");
|
73 | 73 | static final DebugCounter FIELDREF_RESOLVE_COUNT = DebugCounter.create("FieldRef.resolve calls");
|
@@ -195,87 +195,32 @@ public static ResolvedClassConstant resolveClassConstant(ClassConstant.WithStrin
|
195 | 195 | }
|
196 | 196 | }
|
197 | 197 |
|
198 |
| - /** |
199 |
| - * <h3>5.4.3.2. Field Resolution</h3> |
200 |
| - * |
201 |
| - * To resolve an unresolved symbolic reference from D to a field in a class or interface C, the |
202 |
| - * symbolic reference to C given by the field reference must first be resolved (§5.4.3.1). |
203 |
| - * Therefore, any exception that can be thrown as a result of failure of resolution of a class |
204 |
| - * or interface reference can be thrown as a result of failure of field resolution. If the |
205 |
| - * reference to C can be successfully resolved, an exception relating to the failure of |
206 |
| - * resolution of the field reference itself can be thrown. |
207 |
| - * |
208 |
| - * When resolving a field reference, field resolution first attempts to look up the referenced |
209 |
| - * field in C and its superclasses: |
210 |
| - * <ol> |
211 |
| - * <li>If C declares a field with the name and descriptor specified by the field reference, |
212 |
| - * field lookup succeeds. The declared field is the result of the field lookup. |
213 |
| - * <li>Otherwise, field lookup is applied recursively to the direct superinterfaces of the |
214 |
| - * specified class or interface C. |
215 |
| - * <li>Otherwise, if C has a superclass S, field lookup is applied recursively to S. |
216 |
| - * <li>Otherwise, field lookup fails. |
217 |
| - * </ol> |
218 |
| - * |
219 |
| - * Then: |
220 |
| - * <ul> |
221 |
| - * <li>If field lookup fails, field resolution throws a NoSuchFieldError. |
222 |
| - * <li>Otherwise, if field lookup succeeds but the referenced field is not accessible |
223 |
| - * (§5.4.4) to D, field resolution throws an IllegalAccessError. |
224 |
| - * <li>Otherwise, let < E, L1 > be the class or interface in which the referenced field is |
225 |
| - * actually declared and let L2 be the defining loader of D. |
226 |
| - * <li>Given that the type of the referenced field is Tf, let T be Tf if Tf is not an array |
227 |
| - * type, and let T be the element type (§2.4) of Tf otherwise. |
228 |
| - * <li>The Java Virtual Machine must impose the loading constraint that TL1 = TL2 (§5.3.4). |
229 |
| - * </ul> |
230 |
| - */ |
231 |
| - private static Field lookupField(Klass seed, Symbol<Name> name, Symbol<Type> type) { |
232 |
| - Field f = seed.lookupDeclaredField(name, type); |
233 |
| - if (f != null) { |
234 |
| - return f; |
235 |
| - } |
236 |
| - for (Klass i : seed.getSuperInterfaces()) { |
237 |
| - f = lookupField(i, name, type); |
238 |
| - if (f != null) { |
239 |
| - return f; |
240 |
| - } |
241 |
| - } |
242 |
| - if (seed.getSuperKlass() != null) { |
243 |
| - return lookupField(seed.getSuperKlass(), name, type); |
244 |
| - } |
245 |
| - return null; |
246 |
| - } |
247 |
| - |
248 | 198 | public static Resolvable.ResolvedConstant resolveFieldRefConstant(FieldRefConstant.Indexes thiz, RuntimeConstantPool pool, @SuppressWarnings("unused") int thisIndex, ObjectKlass accessingKlass) {
|
249 | 199 | FIELDREF_RESOLVE_COUNT.inc();
|
250 | 200 | Klass holderKlass = getResolvedHolderKlass(thiz, pool, accessingKlass);
|
251 | 201 | Symbol<Name> name = thiz.getName(pool);
|
252 | 202 | Symbol<Type> type = thiz.getType(pool);
|
253 | 203 |
|
254 |
| - Field field = lookupField(holderKlass, name, type); |
255 |
| - if (field == null) { |
256 |
| - ClassRedefinition classRedefinition = pool.getContext().getClassRedefinition(); |
257 |
| - if (classRedefinition != null) { |
258 |
| - // could be due to ongoing redefinition |
259 |
| - classRedefinition.check(); |
260 |
| - field = lookupField(holderKlass, name, type); |
261 |
| - } |
262 |
| - if (field == null) { |
263 |
| - Meta meta = pool.getContext().getMeta(); |
264 |
| - EspressoException failure = EspressoException.wrap(Meta.initExceptionWithMessage(meta.java_lang_NoSuchFieldError, name.toString()), meta); |
265 |
| - Assumption missingFieldAssumption; |
| 204 | + Meta meta = pool.getContext().getMeta(); |
| 205 | + Field field; |
| 206 | + ClassRedefinition classRedefinition = null; |
| 207 | + try { |
| 208 | + try { |
| 209 | + field = LinkResolver.resolveFieldSymbol(meta, accessingKlass, name, type, holderKlass, true, true); |
| 210 | + } catch (EspressoException e) { |
| 211 | + classRedefinition = pool.getContext().getClassRedefinition(); |
266 | 212 | if (classRedefinition != null) {
|
267 |
| - missingFieldAssumption = classRedefinition.getMissingFieldAssumption(); |
| 213 | + // could be due to ongoing redefinition |
| 214 | + classRedefinition.check(); |
| 215 | + field = LinkResolver.resolveFieldSymbol(meta, accessingKlass, name, type, holderKlass, true, true); |
268 | 216 | } else {
|
269 |
| - missingFieldAssumption = Assumption.ALWAYS_VALID; |
| 217 | + throw e; |
270 | 218 | }
|
271 |
| - return new MissingFieldRefConstant(failure, missingFieldAssumption); |
272 | 219 | }
|
| 220 | + } catch (EspressoException e) { |
| 221 | + return new MissingFieldRefConstant(e, classRedefinition == null ? Assumption.ALWAYS_VALID : classRedefinition.getMissingFieldAssumption()); |
273 | 222 | }
|
274 | 223 |
|
275 |
| - memberDoAccessCheck(accessingKlass, holderKlass, field, pool.getContext().getMeta()); |
276 |
| - |
277 |
| - field.checkLoadingConstraints(accessingKlass.getDefiningClassLoader(), field.getDeclaringKlass().getDefiningClassLoader()); |
278 |
| - |
279 | 224 | return new ResolvedFieldRefConstant(field);
|
280 | 225 | }
|
281 | 226 |
|
@@ -411,7 +356,7 @@ public static Resolvable.ResolvedConstant resolveInterfaceMethodRefConstant(Inte
|
411 | 356 | Symbol<Name> name = thiz.getName(pool);
|
412 | 357 | Symbol<Signature> signature = thiz.getSignature(pool);
|
413 | 358 |
|
414 |
| - Method method = LinkResolver.resolveSymbol(pool.getContext().getMeta(), accessingKlass, name, signature, holderInterface, true, true, true); |
| 359 | + Method method = LinkResolver.resolveMethodSymbol(pool.getContext().getMeta(), accessingKlass, name, signature, holderInterface, true, true, true); |
415 | 360 |
|
416 | 361 | return new ResolvedInterfaceMethodRefConstant(method);
|
417 | 362 | }
|
@@ -533,7 +478,7 @@ public static Resolvable.ResolvedConstant resolveClassMethodRefConstant(ClassMet
|
533 | 478 | Symbol<Name> name = thiz.getName(pool);
|
534 | 479 | Symbol<Signature> signature = thiz.getSignature(pool);
|
535 | 480 |
|
536 |
| - Method method = LinkResolver.resolveSymbol(meta, accessingKlass, name, signature, holderKlass, false, true, true); |
| 481 | + Method method = LinkResolver.resolveMethodSymbol(meta, accessingKlass, name, signature, holderKlass, false, true, true); |
537 | 482 |
|
538 | 483 | if (method.isInvokeIntrinsic()) {
|
539 | 484 | MHInvokeGenericNode.MethodHandleInvoker invoker = MHInvokeGenericNode.linkMethod(meta.getLanguage(), meta, accessingKlass, method, name, signature);
|
|
0 commit comments