// This is an adaptation of SpecialInterfaceCall to only use private interface methods and with // virtual invocation semantics. Because we don't have the same corner cases as for invokespecial // there's no practical difference between the I3 and I2 cases here. But we do have to ensure the // correct versions of the methods get executed. // In addition we add tests that involve calls from nestmates - which also covers the distinction // between the caller being a class and being an interface.
staticvoid invokeDirect(I2 i) {
i.priv_m(); // generates invokeinterface
} staticvoid invokeInterfaceMH(I2 i) throws Throwable { // emulates behaviour of invokeDirect
mh_I2_priv_m_from_I2.invokeExact(i);
} // special case of invoking an Object method via an interface staticvoid invokeInterfaceObjectMH(I2 i) throws Throwable { // emulates invokeInterface of I2.toString on i, which resolves // to Object.toString
String s = (String) mh_I2_toString_from_I2.invokeExact(i);
} // special case of invoking a final Object method via an interface staticvoid invokeInterfaceObjectFinalMH(I2 i) throws Throwable { // emulates invokeInterface of I1.getClass on i, which resolves // to Object.getClass Class<?> c = (Class<?>) mh_I2_getClass_from_I2.invokeExact(i);
}
// This interface acts like I2 but we define directInvoke* methods // that we will rewrite the bytecode of to use invokeinterface // (see PrivateInterfaceCallI4.jasm). interface I4 extends I1 { staticvoid invokeDirect(I4 i) { // invokeinterface I4.toString() thrownew Error("Class file for I4 is not overwritten");
} staticvoid invokeDirectFinal(I4 i) { // invokeinterface I4.getClass() - final method thrownew Error("Class file for I4 is not overwritten");
}
}
// check invocations from nestmates outside the // inheritance hierarchy - and from a class not interface staticvoid invokeDirect(I2 i) {
i.priv_m(); // generates invokeinterface
} staticvoid invokeInterfaceMH(I2 i) throws Throwable {
mh_I2_priv_m_from_PIC.invokeExact(i);
}
// Classes that don't implement I2/I3 but do have a // priv_m method in their hierarchy staticclass D1 implements I1 { } staticclass E { privatevoid priv_m() { thrownew Error("Should not call this"); }
}
// This MH acts like the invocation in I2.invokeDirect with caller I2 static MethodHandle mh_I2_priv_m_from_I2;
// This MH acts like the invocation in I3.invokeDirect with caller I3 static MethodHandle mh_I2_priv_m_from_I3;
// This MH acts like the invocation in PrivateInterfaceCall.invokeDirect // with caller PrivateInterfaceCall static MethodHandle mh_I2_priv_m_from_PIC;
// This MH acts likes an invokeinterface of I2.toString from I2 static MethodHandle mh_I2_toString_from_I2;
// This MH acts likes an invokeinterface of I2.getClass from I2 static MethodHandle mh_I2_getClass_from_I2;
// This looks odd but at runtime the only constraint is that the // receiver is an I2. In contrast in the invokespecial case the // receiver must be an I3.
shouldNotThrow(() -> I3.invokeInterfaceMH(unsafeCastI3(new C2())));
shouldNotThrow(() -> I3.invokeInterfaceMH(new C3()));
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.