Skip to content

Commit f544836

Browse files
committed
Adopt HotSpot behavior in member name resolution when argument are non-standard.
1 parent c6b071b commit f544836

File tree

1 file changed

+29
-3
lines changed

1 file changed

+29
-3
lines changed

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/substitutions/Target_java_lang_invoke_MethodHandleNatives.java

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ abstract static class ResolveNode extends SubstitutionNode {
420420
@JavaType(internalName = "Ljava/lang/invoke/MemberName;")
421421
StaticObject doCached(
422422
@JavaType(internalName = "Ljava/lang/invoke/MemberName;") StaticObject memberName,
423-
@JavaType(value = Class.class) StaticObject caller,
423+
@JavaType(value = Class.class) StaticObject guestCaller,
424424
@SuppressWarnings("unused") int lookupMode,
425425
@Bind("getMeta()") Meta meta,
426426
@Cached BranchProfile isMethodProfile,
@@ -448,18 +448,34 @@ StaticObject doCached(
448448
throw meta.throwExceptionWithMessage(meta.java_lang_IllegalArgumentException, "Nothing to resolve.");
449449
}
450450
// Extract resolution information from member name.
451-
Klass resolutionKlass = clazz.getMirrorKlass(meta);
452451
final int flags = meta.java_lang_invoke_MemberName_flags.getInt(memberName);
453452
if (Integer.bitCount(flags & ALL_KINDS) != 1) {
454453
// Ensure the flags field is not ill-formed.
455454
iaeProfile.enter();
456455
throw meta.throwExceptionWithMessage(meta.java_lang_IllegalArgumentException, "Invalid MemberName flag format.");
457456
}
458457

458+
// Determine the holder klass
459+
Klass resolutionKlass = clazz.getMirrorKlass(meta);
460+
if (!(resolutionKlass instanceof ObjectKlass)) {
461+
// Non-standard behavior: behave as HotSpot.
462+
if (resolutionKlass.isArray()) {
463+
resolutionKlass = meta.java_lang_Object;
464+
} else if (resolutionKlass.isPrimitive()) {
465+
throw defaultResolutionFailure(meta, flags);
466+
}
467+
}
468+
469+
// Determine caller klass
470+
Klass callerKlass = StaticObject.isNull(guestCaller) ? null : guestCaller.getMirrorKlass(meta);
471+
if (callerKlass != null && callerKlass.isPrimitive()) {
472+
// HotSpot behavior: primitive caller klass skip checks.
473+
callerKlass = null;
474+
}
475+
459476
EspressoContext ctx = meta.getContext();
460477
ByteSequence desc = asSignature(type, meta);
461478
Symbol<Name> name = lookupName(meta, meta.toHostString(guestName), (Constants.flagHas(flags, MN_IS_FIELD)) ? meta.java_lang_NoSuchFieldException : meta.java_lang_NoSuchMethodException);
462-
ObjectKlass callerKlass = StaticObject.isNull(caller) ? null : (ObjectKlass) caller.getMirrorKlass(meta);
463479

464480
boolean doAccessChecks = callerKlass != null;
465481
boolean doConstraintsChecks = (callerKlass != null && ((lookupMode & LM_UNCONDITIONAL) == 0));
@@ -511,6 +527,16 @@ StaticObject doCached(
511527
return memberName;
512528
}
513529

530+
private static RuntimeException defaultResolutionFailure(Meta meta, int flags) {
531+
if (Constants.flagHas(flags, MN_IS_FIELD)) {
532+
throw meta.throwExceptionWithMessage(meta.java_lang_NoSuchFieldError, "Field resolution failed");
533+
} else if (Constants.flagHas(flags, MN_IS_METHOD) || Constants.flagHas(flags, MN_IS_CONSTRUCTOR)) {
534+
throw meta.throwExceptionWithMessage(meta.java_lang_NoSuchMethodError, "Method resolution failed");
535+
} else {
536+
throw meta.throwExceptionWithMessage(meta.java_lang_LinkageError, "resolution failed");
537+
}
538+
}
539+
514540
private static PolySigIntrinsics getPolysignatureIntrinsicID(BranchProfile isHandleMethodProfile, int flags, Klass resolutionKlass, int refKind, Symbol<Name> name) {
515541
PolySigIntrinsics mhMethodId = None;
516542
if (Constants.flagHas(flags, MN_IS_METHOD) &&

0 commit comments

Comments
 (0)