8010319: Implementation of JEP 181: Nest-Based Access Control
Co-authored-by: Alex Buckley <alex.buckley@oracle.com> Co-authored-by: Maurizio Mimadamore <maurizio.mimadamore@oracle.com> Co-authored-by: Mandy Chung <mandy.chung@oracle.com> Co-authored-by: Tobias Hartmann <tobias.hartmann@oracle.com> Co-authored-by: Vlaidmir Ivanov <vladimir.x.ivanov@oracle.com> Co-authored-by: Karen Kinnear <karen.kinnear@oracle.com> Co-authored-by: Vladimir Kozlov <vladimir.kozlov@oracle.com> Co-authored-by: John Rose <john.r.rose@oracle.com> Co-authored-by: Daniel Smith <daniel.smith@oracle.com> Co-authored-by: Serguei Spitsyn <serguei.spitsyn@oracle.com> Co-authored-by: Kumar Srinivasan <kumardotsrinivasan@gmail.com> Co-authored-by: Boris Ulasevich <boris.ulasevich@bell-sw.com> Reviewed-by: alanb, psandoz, mchung, coleenp, acorn, mcimadamore, forax, jlahoda, sspitsyn, abuckley
This commit is contained in:
parent
6e0bd36f42
commit
95bf19563b
make
src
hotspot
cpu
aarch64
arm
ppc
s390
sparc
x86
share
ci
classfile
code
include
interpreter
logging
memory
oops
arrayKlass.cpparrayKlass.hppcpCache.cppinstanceKlass.cppinstanceKlass.hppklass.cppklass.hppklassVtable.cpp
opto
prims
jvm.cppjvmti.xmljvmtiClassFileReconstituter.cppjvmtiClassFileReconstituter.hppjvmtiExport.cppjvmtiH.xsljvmtiRedefineClasses.cppjvmtiRedefineClasses.hppmethodHandles.cpp
runtime
java.base/share
classes
native/libjava
java.instrument/share
jdk.compiler/share/classes/com/sun/tools/javac
jdk.jdeps/share/classes/com/sun/tools
classfile
javap
jdk.jdi/share/classes/com/sun
jdk.jdwp.agent/share/native/libjdwp
test/hotspot/jtreg
compiler
jsr292/methodHandleExceptions
jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test
runtime/Nestmates
NestmatesJNI.java
classFileParsing
BadNestHost.jcodBadNestHostLength.jcodBadNestMembersEntry.jcodBadNestMembersLength.jcodConflictingAttributesInNestHost.jcodConflictingAttributesInNestMember.jcodTestFinalMethodOverride.javaTestNestmateAttributes.javaTwoNestHost.jcodTwoNestMembers.jcod
legacy
libNestmatesJNI.cmembership
@ -395,8 +395,8 @@ JDWP "Java(tm) Debug Wire Protocol"
|
||||
"Can the VM add methods when redefining "
|
||||
"classes?")
|
||||
(boolean canUnrestrictedlyRedefineClasses
|
||||
"Can the VM redefine classes"
|
||||
"in arbitrary ways?")
|
||||
"Can the VM redefine classes "
|
||||
"in ways that are normally restricted?")
|
||||
(boolean canPopFrames
|
||||
"Can the VM pop stack frames?")
|
||||
(boolean canUseInstanceFilters
|
||||
@ -460,12 +460,23 @@ JDWP "Java(tm) Debug Wire Protocol"
|
||||
"<a href=\"#JDWP_StackFrame_PopFrames\">PopFrames</a> command can be used "
|
||||
"to pop frames with obsolete methods."
|
||||
"<p>"
|
||||
"Unless the canUnrestrictedlyRedefineClasses capability is present the following "
|
||||
"redefinitions are restricted: "
|
||||
"<ul>"
|
||||
"<li>changing the schema (the fields)</li>"
|
||||
"<li>changing the hierarchy (superclasses, interfaces)</li>"
|
||||
"<li>deleting a method</li>"
|
||||
"<li>changing class modifiers</li>"
|
||||
"<li>changing method modifiers</li>"
|
||||
"<li>changing the <code>NestHost</code> or <code>NestMembers</code> class attributes</li>"
|
||||
"</ul>"
|
||||
"<p>"
|
||||
"Requires canRedefineClasses capability - see "
|
||||
"<a href=\"#JDWP_VirtualMachine_CapabilitiesNew\">CapabilitiesNew</a>. "
|
||||
"In addition to the canRedefineClasses capability, the target VM must "
|
||||
"have the canAddMethod capability to add methods when redefining classes, "
|
||||
"or the canUnrestrictedlyRedefineClasses to redefine classes in arbitrary "
|
||||
"ways."
|
||||
"or the canUnrestrictedlyRedefineClasses capability to redefine classes in ways "
|
||||
"that are normally restricted."
|
||||
(Out
|
||||
(Repeat classes "Number of reference types that follow."
|
||||
(Group ClassDef
|
||||
@ -496,6 +507,7 @@ JDWP "Java(tm) Debug Wire Protocol"
|
||||
(Error DELETE_METHOD_NOT_IMPLEMENTED)
|
||||
(Error CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED)
|
||||
(Error METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED)
|
||||
(Error CLASS_ATTRIBUTE_CHANGE_NOT_IMPLEMENTED)
|
||||
(Error VM_DEAD)
|
||||
)
|
||||
)
|
||||
@ -3148,12 +3160,16 @@ JDWP "Java(tm) Debug Wire Protocol"
|
||||
"different from the name in the old class object.")
|
||||
(Constant CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED
|
||||
=70 "The new class version has different modifiers and "
|
||||
"and canUnrestrictedlyRedefineClasses is false.")
|
||||
"canUnrestrictedlyRedefineClasses is false.")
|
||||
(Constant METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED
|
||||
=71 "A method in the new class version has "
|
||||
"different modifiers "
|
||||
"than its counterpart in the old class version and "
|
||||
"and canUnrestrictedlyRedefineClasses is false.")
|
||||
"canUnrestrictedlyRedefineClasses is false.")
|
||||
(Constant CLASS_ATTRIBUTE_CHANGE_NOT_IMPLEMENTED
|
||||
=72 "The new class version has different NestHost or "
|
||||
"NestMembers class attribute and "
|
||||
"canUnrestrictedlyRedefineClasses is false.")
|
||||
(Constant NOT_IMPLEMENTED =99 "The functionality is not implemented in "
|
||||
"this virtual machine.")
|
||||
(Constant NULL_POINTER =100 "Invalid pointer.")
|
||||
|
@ -22,6 +22,7 @@
|
||||
#
|
||||
|
||||
JVM_ActiveProcessorCount
|
||||
JVM_AreNestMates
|
||||
JVM_ArrayCopy
|
||||
JVM_AssertionStatusDirectives
|
||||
JVM_BeforeHalt
|
||||
@ -118,6 +119,8 @@ JVM_GetMethodIxSignatureUTF
|
||||
JVM_GetMethodParameters
|
||||
JVM_GetMethodTypeAnnotations
|
||||
JVM_GetNanoTimeAdjustment
|
||||
JVM_GetNestHost
|
||||
JVM_GetNestMembers
|
||||
JVM_GetPrimitiveArrayElement
|
||||
JVM_GetProtectionDomain
|
||||
JVM_GetSimpleBinaryName
|
||||
|
@ -3362,22 +3362,45 @@ void TemplateTable::invokeinterface(int byte_no) {
|
||||
// r2: receiver
|
||||
// r3: flags
|
||||
|
||||
// First check for Object case, then private interface method,
|
||||
// then regular interface method.
|
||||
|
||||
// Special case of invokeinterface called for virtual method of
|
||||
// java.lang.Object. See cpCacheOop.cpp for details.
|
||||
// This code isn't produced by javac, but could be produced by
|
||||
// another compliant java compiler.
|
||||
Label notMethod;
|
||||
__ tbz(r3, ConstantPoolCacheEntry::is_forced_virtual_shift, notMethod);
|
||||
// java.lang.Object. See cpCache.cpp for details.
|
||||
Label notObjectMethod;
|
||||
__ tbz(r3, ConstantPoolCacheEntry::is_forced_virtual_shift, notObjectMethod);
|
||||
|
||||
invokevirtual_helper(rmethod, r2, r3);
|
||||
__ bind(notMethod);
|
||||
__ bind(notObjectMethod);
|
||||
|
||||
Label no_such_interface;
|
||||
|
||||
// Check for private method invocation - indicated by vfinal
|
||||
Label notVFinal;
|
||||
__ tbz(r3, ConstantPoolCacheEntry::is_vfinal_shift, notVFinal);
|
||||
|
||||
// Get receiver klass into r3 - also a null check
|
||||
__ null_check(r2, oopDesc::klass_offset_in_bytes());
|
||||
__ load_klass(r3, r2);
|
||||
|
||||
Label subtype;
|
||||
__ check_klass_subtype(r3, r0, r4, subtype);
|
||||
// If we get here the typecheck failed
|
||||
__ b(no_such_interface);
|
||||
__ bind(subtype);
|
||||
|
||||
__ profile_final_call(r0);
|
||||
__ profile_arguments_type(r0, rmethod, r4, true);
|
||||
__ jump_from_interpreted(rmethod, r0);
|
||||
|
||||
__ bind(notVFinal);
|
||||
|
||||
// Get receiver klass into r3 - also a null check
|
||||
__ restore_locals();
|
||||
__ null_check(r2, oopDesc::klass_offset_in_bytes());
|
||||
__ load_klass(r3, r2);
|
||||
|
||||
Label no_such_interface, no_such_method;
|
||||
Label no_such_method;
|
||||
|
||||
// Preserve method for throw_AbstractMethodErrorVerbose.
|
||||
__ mov(r16, rmethod);
|
||||
|
@ -4276,25 +4276,41 @@ void TemplateTable::invokeinterface(int byte_no) {
|
||||
const Register Rinterf = R5_tmp;
|
||||
const Register Rindex = R4_tmp;
|
||||
const Register Rflags = R3_tmp;
|
||||
const Register Rklass = R3_tmp;
|
||||
const Register Rklass = R2_tmp; // Note! Same register with Rrecv
|
||||
|
||||
prepare_invoke(byte_no, Rinterf, Rmethod, Rrecv, Rflags);
|
||||
|
||||
// Special case of invokeinterface called for virtual method of
|
||||
// java.lang.Object. See cpCacheOop.cpp for details.
|
||||
// This code isn't produced by javac, but could be produced by
|
||||
// another compliant java compiler.
|
||||
Label notMethod;
|
||||
__ tbz(Rflags, ConstantPoolCacheEntry::is_forced_virtual_shift, notMethod);
|
||||
// First check for Object case, then private interface method,
|
||||
// then regular interface method.
|
||||
|
||||
// Special case of invokeinterface called for virtual method of
|
||||
// java.lang.Object. See cpCache.cpp for details.
|
||||
Label notObjectMethod;
|
||||
__ tbz(Rflags, ConstantPoolCacheEntry::is_forced_virtual_shift, notObjectMethod);
|
||||
invokevirtual_helper(Rmethod, Rrecv, Rflags);
|
||||
__ bind(notMethod);
|
||||
__ bind(notObjectMethod);
|
||||
|
||||
// Get receiver klass into Rklass - also a null check
|
||||
__ load_klass(Rklass, Rrecv);
|
||||
|
||||
// Check for private method invocation - indicated by vfinal
|
||||
Label no_such_interface;
|
||||
|
||||
Label notVFinal;
|
||||
__ tbz(Rflags, ConstantPoolCacheEntry::is_vfinal_shift, notVFinal);
|
||||
|
||||
Label subtype;
|
||||
__ check_klass_subtype(Rklass, Rinterf, R1_tmp, R3_tmp, noreg, subtype);
|
||||
// If we get here the typecheck failed
|
||||
__ b(no_such_interface);
|
||||
__ bind(subtype);
|
||||
|
||||
// do the call
|
||||
__ profile_final_call(R0_tmp);
|
||||
__ jump_from_interpreted(Rmethod);
|
||||
|
||||
__ bind(notVFinal);
|
||||
|
||||
// Receiver subtype check against REFC.
|
||||
__ lookup_interface_method(// inputs: rec. class, interface
|
||||
Rklass, Rinterf, noreg,
|
||||
|
@ -3583,14 +3583,46 @@ void TemplateTable::invokeinterface(int byte_no) {
|
||||
|
||||
prepare_invoke(byte_no, Rinterface_klass, Rret_addr, Rmethod, Rreceiver, Rflags, Rscratch1);
|
||||
|
||||
// Get receiver klass.
|
||||
// First check for Object case, then private interface method,
|
||||
// then regular interface method.
|
||||
|
||||
// Get receiver klass - this is also a null check
|
||||
__ null_check_throw(Rreceiver, oopDesc::klass_offset_in_bytes(), Rscratch2);
|
||||
__ load_klass(Rrecv_klass, Rreceiver);
|
||||
|
||||
// Check corner case object method.
|
||||
Label LobjectMethod, L_no_such_interface, Lthrow_ame;
|
||||
// Special case of invokeinterface called for virtual method of
|
||||
// java.lang.Object. See ConstantPoolCacheEntry::set_method() for details:
|
||||
// The invokeinterface was rewritten to a invokevirtual, hence we have
|
||||
// to handle this corner case.
|
||||
|
||||
Label LnotObjectMethod, Lthrow_ame;
|
||||
__ testbitdi(CCR0, R0, Rflags, ConstantPoolCacheEntry::is_forced_virtual_shift);
|
||||
__ btrue(CCR0, LobjectMethod);
|
||||
__ bfalse(CCR0, LnotObjectMethod);
|
||||
invokeinterface_object_method(Rrecv_klass, Rret_addr, Rflags, Rmethod, Rscratch1, Rscratch2);
|
||||
__ bind(LnotObjectMethod);
|
||||
|
||||
// Check for private method invocation - indicated by vfinal
|
||||
Label LnotVFinal, L_no_such_interface, L_subtype;
|
||||
|
||||
__ testbitdi(CCR0, R0, Rflags, ConstantPoolCacheEntry::is_vfinal_shift);
|
||||
__ bfalse(CCR0, LnotVFinal);
|
||||
|
||||
__ check_klass_subtype(Rrecv_klass, Rinterface_klass, Rscratch1, Rscratch2, L_subtype);
|
||||
// If we get here the typecheck failed
|
||||
__ b(L_no_such_interface);
|
||||
__ bind(L_subtype);
|
||||
|
||||
// do the call
|
||||
|
||||
Register Rscratch = Rflags; // Rflags is dead now.
|
||||
|
||||
__ profile_final_call(Rscratch1, Rscratch);
|
||||
__ profile_arguments_type(Rindex, Rscratch, Rrecv_klass /* scratch */, true);
|
||||
|
||||
__ call_from_interpreter(Rindex, Rret_addr, Rscratch, Rrecv_klass /* scratch */);
|
||||
|
||||
__ bind(LnotVFinal);
|
||||
|
||||
__ lookup_interface_method(Rrecv_klass, Rinterface_klass, noreg, noreg, Rscratch1, Rscratch2,
|
||||
L_no_such_interface, /*return_method=*/false);
|
||||
@ -3631,14 +3663,6 @@ void TemplateTable::invokeinterface(int byte_no) {
|
||||
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeErrorVerbose),
|
||||
Rrecv_klass, Rinterface_klass);
|
||||
DEBUG_ONLY( __ should_not_reach_here(); )
|
||||
|
||||
// Special case of invokeinterface called for virtual method of
|
||||
// java.lang.Object. See ConstantPoolCacheEntry::set_method() for details:
|
||||
// The invokeinterface was rewritten to a invokevirtual, hence we have
|
||||
// to handle this corner case. This code isn't produced by javac, but could
|
||||
// be produced by another compliant java compiler.
|
||||
__ bind(LobjectMethod);
|
||||
invokeinterface_object_method(Rrecv_klass, Rret_addr, Rflags, Rmethod, Rscratch1, Rscratch2);
|
||||
}
|
||||
|
||||
void TemplateTable::invokedynamic(int byte_no) {
|
||||
|
@ -3610,20 +3610,43 @@ void TemplateTable::invokeinterface(int byte_no) {
|
||||
|
||||
BLOCK_COMMENT("invokeinterface {");
|
||||
|
||||
prepare_invoke(byte_no, interface, method, // Get f1 klassOop, f2 itable index.
|
||||
prepare_invoke(byte_no, interface, method, // Get f1 klassOop, f2 Method*.
|
||||
receiver, flags);
|
||||
|
||||
// Z_R14 (== Z_bytecode) : return entry
|
||||
|
||||
// First check for Object case, then private interface method,
|
||||
// then regular interface method.
|
||||
|
||||
// Special case of invokeinterface called for virtual method of
|
||||
// java.lang.Object. See cpCacheOop.cpp for details.
|
||||
// This code isn't produced by javac, but could be produced by
|
||||
// another compliant java compiler.
|
||||
NearLabel notMethod, no_such_interface, no_such_method;
|
||||
// java.lang.Object. See cpCache.cpp for details.
|
||||
NearLabel notObjectMethod, no_such_method;
|
||||
__ testbit(flags, ConstantPoolCacheEntry::is_forced_virtual_shift);
|
||||
__ z_brz(notMethod);
|
||||
__ z_brz(notObjectMethod);
|
||||
invokevirtual_helper(method, receiver, flags);
|
||||
__ bind(notMethod);
|
||||
__ bind(notObjectMethod);
|
||||
|
||||
// Check for private method invocation - indicated by vfinal
|
||||
NearLabel notVFinal;
|
||||
__ testbit(flags, ConstantPoolCacheEntry::is_vfinal_shift);
|
||||
__ z_brz(notVFinal);
|
||||
|
||||
// Get receiver klass into klass - also a null check.
|
||||
__ load_klass(klass, receiver);
|
||||
|
||||
NearLabel subtype, no_such_interface;
|
||||
|
||||
__ check_klass_subtype(klass, interface, Z_tmp_2, Z_tmp_3, subtype);
|
||||
// If we get here the typecheck failed
|
||||
__ z_bru(no_such_interface);
|
||||
__ bind(subtype);
|
||||
|
||||
// do the call
|
||||
__ profile_final_call(Z_tmp_2);
|
||||
__ profile_arguments_type(Z_tmp_2, method, Z_ARG5, true);
|
||||
__ jump_from_interpreted(method, Z_tmp_2);
|
||||
|
||||
__ bind(notVFinal);
|
||||
|
||||
// Get receiver klass into klass - also a null check.
|
||||
__ restore_locals();
|
||||
|
@ -3202,28 +3202,56 @@ void TemplateTable::invokeinterface(int byte_no) {
|
||||
|
||||
prepare_invoke(byte_no, Rinterface, Rret, Rmethod, O0_recv, O1_flags);
|
||||
|
||||
// get receiver klass
|
||||
// First check for Object case, then private interface method,
|
||||
// then regular interface method.
|
||||
|
||||
// get receiver klass - this is also a null check
|
||||
__ null_check(O0_recv, oopDesc::klass_offset_in_bytes());
|
||||
__ load_klass(O0_recv, O2_Klass);
|
||||
|
||||
// Special case of invokeinterface called for virtual method of
|
||||
// java.lang.Object. See cpCacheOop.cpp for details.
|
||||
// This code isn't produced by javac, but could be produced by
|
||||
// another compliant java compiler.
|
||||
Label notMethod;
|
||||
// java.lang.Object. See cpCache.cpp for details.
|
||||
Label notObjectMethod;
|
||||
__ set((1 << ConstantPoolCacheEntry::is_forced_virtual_shift), Rscratch);
|
||||
__ btst(O1_flags, Rscratch);
|
||||
__ br(Assembler::zero, false, Assembler::pt, notMethod);
|
||||
__ br(Assembler::zero, false, Assembler::pt, notObjectMethod);
|
||||
__ delayed()->nop();
|
||||
|
||||
invokeinterface_object_method(O2_Klass, Rinterface, Rret, O1_flags);
|
||||
|
||||
__ bind(notMethod);
|
||||
|
||||
Register Rtemp = O1_flags;
|
||||
__ bind(notObjectMethod);
|
||||
|
||||
Label L_no_such_interface;
|
||||
|
||||
// Check for private method invocation - indicated by vfinal
|
||||
Label notVFinal;
|
||||
{
|
||||
__ set((1 << ConstantPoolCacheEntry::is_vfinal_shift), Rscratch);
|
||||
__ btst(O1_flags, Rscratch);
|
||||
__ br(Assembler::zero, false, Assembler::pt, notVFinal);
|
||||
__ delayed()->nop();
|
||||
|
||||
Label subtype;
|
||||
Register Rtemp = O1_flags;
|
||||
__ check_klass_subtype(O2_Klass, Rinterface, Rscratch, Rtemp, subtype);
|
||||
// If we get here the typecheck failed
|
||||
__ ba(L_no_such_interface);
|
||||
__ delayed()->nop();
|
||||
__ bind(subtype);
|
||||
|
||||
// do the call
|
||||
Register Rcall = Rinterface;
|
||||
__ mov(Rmethod, G5_method);
|
||||
assert_different_registers(Rcall, G5_method, Gargs, Rret);
|
||||
|
||||
__ profile_arguments_type(G5_method, Rcall, Gargs, true);
|
||||
__ profile_final_call(Rscratch);
|
||||
__ call_from_interpreter(Rcall, Gargs, Rret);
|
||||
}
|
||||
__ bind(notVFinal);
|
||||
|
||||
Register Rtemp = O1_flags;
|
||||
|
||||
// Receiver subtype check against REFC.
|
||||
__ lookup_interface_method(// inputs: rec. class, interface, itable index
|
||||
O2_Klass, Rinterface, noreg,
|
||||
|
@ -3792,30 +3792,61 @@ void TemplateTable::invokeinterface(int byte_no) {
|
||||
prepare_invoke(byte_no, rax, rbx, // get f1 Klass*, f2 Method*
|
||||
rcx, rdx); // recv, flags
|
||||
|
||||
// rax: reference klass (from f1)
|
||||
// rax: reference klass (from f1) if interface method
|
||||
// rbx: method (from f2)
|
||||
// rcx: receiver
|
||||
// rdx: flags
|
||||
|
||||
// First check for Object case, then private interface method,
|
||||
// then regular interface method.
|
||||
|
||||
// Special case of invokeinterface called for virtual method of
|
||||
// java.lang.Object. See cpCacheOop.cpp for details.
|
||||
// This code isn't produced by javac, but could be produced by
|
||||
// another compliant java compiler.
|
||||
Label notMethod;
|
||||
// java.lang.Object. See cpCache.cpp for details.
|
||||
Label notObjectMethod;
|
||||
__ movl(rlocals, rdx);
|
||||
__ andl(rlocals, (1 << ConstantPoolCacheEntry::is_forced_virtual_shift));
|
||||
|
||||
__ jcc(Assembler::zero, notMethod);
|
||||
|
||||
__ jcc(Assembler::zero, notObjectMethod);
|
||||
invokevirtual_helper(rbx, rcx, rdx);
|
||||
__ bind(notMethod);
|
||||
// no return from above
|
||||
__ bind(notObjectMethod);
|
||||
|
||||
Label no_such_interface; // for receiver subtype check
|
||||
Register recvKlass; // used for exception processing
|
||||
|
||||
// Check for private method invocation - indicated by vfinal
|
||||
Label notVFinal;
|
||||
__ movl(rlocals, rdx);
|
||||
__ andl(rlocals, (1 << ConstantPoolCacheEntry::is_vfinal_shift));
|
||||
__ jcc(Assembler::zero, notVFinal);
|
||||
|
||||
// Get receiver klass into rlocals - also a null check
|
||||
__ null_check(rcx, oopDesc::klass_offset_in_bytes());
|
||||
__ load_klass(rlocals, rcx);
|
||||
|
||||
Label subtype;
|
||||
__ check_klass_subtype(rlocals, rax, rbcp, subtype);
|
||||
// If we get here the typecheck failed
|
||||
recvKlass = rdx;
|
||||
__ mov(recvKlass, rlocals); // shuffle receiver class for exception use
|
||||
__ jmp(no_such_interface);
|
||||
|
||||
__ bind(subtype);
|
||||
|
||||
// do the call - rbx is actually the method to call
|
||||
|
||||
__ profile_final_call(rdx);
|
||||
__ profile_arguments_type(rdx, rbx, rbcp, true);
|
||||
|
||||
__ jump_from_interpreted(rbx, rdx);
|
||||
// no return from above
|
||||
__ bind(notVFinal);
|
||||
|
||||
// Get receiver klass into rdx - also a null check
|
||||
__ restore_locals(); // restore r14
|
||||
__ null_check(rcx, oopDesc::klass_offset_in_bytes());
|
||||
__ load_klass(rdx, rcx);
|
||||
|
||||
Label no_such_interface, no_such_method;
|
||||
Label no_such_method;
|
||||
|
||||
// Preserve method for throw_AbstractMethodErrorVerbose.
|
||||
__ mov(rcx, rbx);
|
||||
@ -3877,12 +3908,12 @@ void TemplateTable::invokeinterface(int byte_no) {
|
||||
__ restore_locals(); // make sure locals pointer is correct as well (was destroyed)
|
||||
// Pass arguments for generating a verbose error message.
|
||||
#ifdef _LP64
|
||||
Register recvKlass = c_rarg1;
|
||||
recvKlass = c_rarg1;
|
||||
Register method = c_rarg2;
|
||||
if (recvKlass != rdx) { __ movq(recvKlass, rdx); }
|
||||
if (method != rcx) { __ movq(method, rcx); }
|
||||
#else
|
||||
Register recvKlass = rdx;
|
||||
recvKlass = rdx;
|
||||
Register method = rcx;
|
||||
#endif
|
||||
__ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodErrorVerbose),
|
||||
|
@ -70,22 +70,22 @@
|
||||
ciField::ciField(ciInstanceKlass* klass, int index) :
|
||||
_known_to_link_with_put(NULL), _known_to_link_with_get(NULL) {
|
||||
ASSERT_IN_VM;
|
||||
CompilerThread *thread = CompilerThread::current();
|
||||
CompilerThread *THREAD = CompilerThread::current();
|
||||
|
||||
assert(ciObjectFactory::is_initialized(), "not a shared field");
|
||||
|
||||
assert(klass->get_instanceKlass()->is_linked(), "must be linked before using its constant-pool");
|
||||
|
||||
constantPoolHandle cpool(thread, klass->get_instanceKlass()->constants());
|
||||
constantPoolHandle cpool(THREAD, klass->get_instanceKlass()->constants());
|
||||
|
||||
// Get the field's name, signature, and type.
|
||||
Symbol* name = cpool->name_ref_at(index);
|
||||
_name = ciEnv::current(thread)->get_symbol(name);
|
||||
_name = ciEnv::current(THREAD)->get_symbol(name);
|
||||
|
||||
int nt_index = cpool->name_and_type_ref_index_at(index);
|
||||
int sig_index = cpool->signature_ref_index_at(nt_index);
|
||||
Symbol* signature = cpool->symbol_at(sig_index);
|
||||
_signature = ciEnv::current(thread)->get_symbol(signature);
|
||||
_signature = ciEnv::current(THREAD)->get_symbol(signature);
|
||||
|
||||
BasicType field_type = FieldType::basic_type(signature);
|
||||
|
||||
@ -95,12 +95,12 @@ ciField::ciField(ciInstanceKlass* klass, int index) :
|
||||
bool ignore;
|
||||
// This is not really a class reference; the index always refers to the
|
||||
// field's type signature, as a symbol. Linkage checks do not apply.
|
||||
_type = ciEnv::current(thread)->get_klass_by_index(cpool, sig_index, ignore, klass);
|
||||
_type = ciEnv::current(THREAD)->get_klass_by_index(cpool, sig_index, ignore, klass);
|
||||
} else {
|
||||
_type = ciType::make(field_type);
|
||||
}
|
||||
|
||||
_name = (ciSymbol*)ciEnv::current(thread)->get_symbol(name);
|
||||
_name = (ciSymbol*)ciEnv::current(THREAD)->get_symbol(name);
|
||||
|
||||
// Get the field's declared holder.
|
||||
//
|
||||
@ -109,7 +109,7 @@ ciField::ciField(ciInstanceKlass* klass, int index) :
|
||||
int holder_index = cpool->klass_ref_index_at(index);
|
||||
bool holder_is_accessible;
|
||||
|
||||
ciKlass* generic_declared_holder = ciEnv::current(thread)->get_klass_by_index(cpool, holder_index,
|
||||
ciKlass* generic_declared_holder = ciEnv::current(THREAD)->get_klass_by_index(cpool, holder_index,
|
||||
holder_is_accessible,
|
||||
klass);
|
||||
|
||||
@ -126,7 +126,7 @@ ciField::ciField(ciInstanceKlass* klass, int index) :
|
||||
// handling in ciField::will_link and will result in a
|
||||
// java.lang.NoSuchFieldError exception being thrown by the compiled
|
||||
// code (the expected behavior in this case).
|
||||
_holder = ciEnv::current(thread)->Object_klass();
|
||||
_holder = ciEnv::current(THREAD)->Object_klass();
|
||||
_offset = -1;
|
||||
_is_constant = false;
|
||||
return;
|
||||
@ -164,10 +164,22 @@ ciField::ciField(ciInstanceKlass* klass, int index) :
|
||||
// to check access because it can erroneously succeed. If this check fails,
|
||||
// propagate the declared holder to will_link() which in turn will bail out
|
||||
// compilation for this field access.
|
||||
if (!Reflection::verify_field_access(klass->get_Klass(), declared_holder->get_Klass(), canonical_holder, field_desc.access_flags(), true)) {
|
||||
bool can_access = Reflection::verify_member_access(klass->get_Klass(),
|
||||
declared_holder->get_Klass(),
|
||||
canonical_holder,
|
||||
field_desc.access_flags(),
|
||||
true, false, THREAD);
|
||||
if (!can_access) {
|
||||
_holder = declared_holder;
|
||||
_offset = -1;
|
||||
_is_constant = false;
|
||||
// It's possible the access check failed due to a nestmate access check
|
||||
// encountering an exception. We can't propagate the exception from here
|
||||
// so we have to clear it. If the access check happens again in a different
|
||||
// context then the exception will be thrown there.
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
CLEAR_PENDING_EXCEPTION;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3148,7 +3148,6 @@ u2 ClassFileParser::parse_classfile_inner_classes_attribute(const ClassFileStrea
|
||||
_inner_classes = inner_classes;
|
||||
|
||||
int index = 0;
|
||||
const int cp_size = _cp->length();
|
||||
cfs->guarantee_more(8 * length, CHECK_0); // 4-tuples of u2
|
||||
for (int n = 0; n < length; n++) {
|
||||
// Inner class index
|
||||
@ -3222,6 +3221,38 @@ u2 ClassFileParser::parse_classfile_inner_classes_attribute(const ClassFileStrea
|
||||
return length;
|
||||
}
|
||||
|
||||
u2 ClassFileParser::parse_classfile_nest_members_attribute(const ClassFileStream* const cfs,
|
||||
const u1* const nest_members_attribute_start,
|
||||
TRAPS) {
|
||||
const u1* const current_mark = cfs->current();
|
||||
u2 length = 0;
|
||||
if (nest_members_attribute_start != NULL) {
|
||||
cfs->set_current(nest_members_attribute_start);
|
||||
cfs->guarantee_more(2, CHECK_0); // length
|
||||
length = cfs->get_u2_fast();
|
||||
}
|
||||
const int size = length;
|
||||
Array<u2>* const nest_members = MetadataFactory::new_array<u2>(_loader_data, size, CHECK_0);
|
||||
_nest_members = nest_members;
|
||||
|
||||
int index = 0;
|
||||
cfs->guarantee_more(2 * length, CHECK_0);
|
||||
for (int n = 0; n < length; n++) {
|
||||
const u2 class_info_index = cfs->get_u2_fast();
|
||||
check_property(
|
||||
valid_klass_reference_at(class_info_index),
|
||||
"Nest member class_info_index %u has bad constant type in class file %s",
|
||||
class_info_index, CHECK_0);
|
||||
nest_members->at_put(index++, class_info_index);
|
||||
}
|
||||
assert(index == size, "wrong size");
|
||||
|
||||
// Restore buffer's current position.
|
||||
cfs->set_current(current_mark);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
void ClassFileParser::parse_classfile_synthetic_attribute(TRAPS) {
|
||||
set_class_synthetic_flag(true);
|
||||
}
|
||||
@ -3329,10 +3360,14 @@ void ClassFileParser::parse_classfile_attributes(const ClassFileStream* const cf
|
||||
|
||||
// Set inner classes attribute to default sentinel
|
||||
_inner_classes = Universe::the_empty_short_array();
|
||||
// Set nest members attribute to default sentinel
|
||||
_nest_members = Universe::the_empty_short_array();
|
||||
cfs->guarantee_more(2, CHECK); // attributes_count
|
||||
u2 attributes_count = cfs->get_u2_fast();
|
||||
bool parsed_sourcefile_attribute = false;
|
||||
bool parsed_innerclasses_attribute = false;
|
||||
bool parsed_nest_members_attribute = false;
|
||||
bool parsed_nest_host_attribute = false;
|
||||
bool parsed_enclosingmethod_attribute = false;
|
||||
bool parsed_bootstrap_methods_attribute = false;
|
||||
const u1* runtime_visible_annotations = NULL;
|
||||
@ -3350,6 +3385,9 @@ void ClassFileParser::parse_classfile_attributes(const ClassFileStream* const cf
|
||||
u4 inner_classes_attribute_length = 0;
|
||||
u2 enclosing_method_class_index = 0;
|
||||
u2 enclosing_method_method_index = 0;
|
||||
const u1* nest_members_attribute_start = NULL;
|
||||
u4 nest_members_attribute_length = 0;
|
||||
|
||||
// Iterate over attributes
|
||||
while (attributes_count--) {
|
||||
cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length
|
||||
@ -3498,6 +3536,40 @@ void ClassFileParser::parse_classfile_attributes(const ClassFileStream* const cf
|
||||
assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations");
|
||||
}
|
||||
cfs->skip_u1(attribute_length, CHECK);
|
||||
} else if (_major_version >= JAVA_11_VERSION) {
|
||||
if (tag == vmSymbols::tag_nest_members()) {
|
||||
// Check for NestMembers tag
|
||||
if (parsed_nest_members_attribute) {
|
||||
classfile_parse_error("Multiple NestMembers attributes in class file %s", CHECK);
|
||||
} else {
|
||||
parsed_nest_members_attribute = true;
|
||||
}
|
||||
if (parsed_nest_host_attribute) {
|
||||
classfile_parse_error("Conflicting NestHost and NestMembers attributes in class file %s", CHECK);
|
||||
}
|
||||
nest_members_attribute_start = cfs->current();
|
||||
nest_members_attribute_length = attribute_length;
|
||||
cfs->skip_u1(nest_members_attribute_length, CHECK);
|
||||
} else if (tag == vmSymbols::tag_nest_host()) {
|
||||
if (parsed_nest_host_attribute) {
|
||||
classfile_parse_error("Multiple NestHost attributes in class file %s", CHECK);
|
||||
} else {
|
||||
parsed_nest_host_attribute = true;
|
||||
}
|
||||
if (parsed_nest_members_attribute) {
|
||||
classfile_parse_error("Conflicting NestMembers and NestHost attributes in class file %s", CHECK);
|
||||
}
|
||||
if (_need_verify) {
|
||||
guarantee_property(attribute_length == 2, "Wrong NestHost attribute length in class file %s", CHECK);
|
||||
}
|
||||
cfs->guarantee_more(2, CHECK);
|
||||
u2 class_info_index = cfs->get_u2_fast();
|
||||
check_property(
|
||||
valid_klass_reference_at(class_info_index),
|
||||
"Nest-host class_info_index %u has bad constant type in class file %s",
|
||||
class_info_index, CHECK);
|
||||
_nest_host = class_info_index;
|
||||
}
|
||||
} else {
|
||||
// Unknown attribute
|
||||
cfs->skip_u1(attribute_length, CHECK);
|
||||
@ -3526,13 +3598,25 @@ void ClassFileParser::parse_classfile_attributes(const ClassFileStream* const cf
|
||||
enclosing_method_class_index,
|
||||
enclosing_method_method_index,
|
||||
CHECK);
|
||||
if (parsed_innerclasses_attribute &&_need_verify && _major_version >= JAVA_1_5_VERSION) {
|
||||
if (parsed_innerclasses_attribute && _need_verify && _major_version >= JAVA_1_5_VERSION) {
|
||||
guarantee_property(
|
||||
inner_classes_attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes,
|
||||
"Wrong InnerClasses attribute length in class file %s", CHECK);
|
||||
}
|
||||
}
|
||||
|
||||
if (parsed_nest_members_attribute) {
|
||||
const u2 num_of_classes = parse_classfile_nest_members_attribute(
|
||||
cfs,
|
||||
nest_members_attribute_start,
|
||||
CHECK);
|
||||
if (_need_verify) {
|
||||
guarantee_property(
|
||||
nest_members_attribute_length == sizeof(num_of_classes) + sizeof(u2) * num_of_classes,
|
||||
"Wrong NestMembers attribute length in class file %s", CHECK);
|
||||
}
|
||||
}
|
||||
|
||||
if (_max_bootstrap_specifier_index >= 0) {
|
||||
guarantee_property(parsed_bootstrap_methods_attribute,
|
||||
"Missing BootstrapMethods attribute in class file %s", CHECK);
|
||||
@ -3595,6 +3679,8 @@ void ClassFileParser::apply_parsed_class_metadata(
|
||||
this_klass->set_fields(_fields, java_fields_count);
|
||||
this_klass->set_methods(_methods);
|
||||
this_klass->set_inner_classes(_inner_classes);
|
||||
this_klass->set_nest_members(_nest_members);
|
||||
this_klass->set_nest_host_index(_nest_host);
|
||||
this_klass->set_local_interfaces(_local_interfaces);
|
||||
this_klass->set_annotations(_combined_annotations);
|
||||
// Delay the setting of _transitive_interfaces until after initialize_supers() in
|
||||
@ -4605,24 +4691,26 @@ static void check_final_method_override(const InstanceKlass* this_klass, TRAPS)
|
||||
}
|
||||
|
||||
if (super_m->is_final() && !super_m->is_static() &&
|
||||
// matching method in super is final, and not static
|
||||
(Reflection::verify_field_access(this_klass,
|
||||
super_m->method_holder(),
|
||||
super_m->method_holder(),
|
||||
super_m->access_flags(), false))
|
||||
// this class can access super final method and therefore override
|
||||
) {
|
||||
ResourceMark rm(THREAD);
|
||||
Exceptions::fthrow(
|
||||
THREAD_AND_LOCATION,
|
||||
vmSymbols::java_lang_VerifyError(),
|
||||
"class %s overrides final method %s.%s%s",
|
||||
this_klass->external_name(),
|
||||
super_m->method_holder()->external_name(),
|
||||
name->as_C_string(),
|
||||
signature->as_C_string()
|
||||
);
|
||||
return;
|
||||
!super_m->access_flags().is_private()) {
|
||||
// matching method in super is final, and not static or private
|
||||
bool can_access = Reflection::verify_member_access(this_klass,
|
||||
super_m->method_holder(),
|
||||
super_m->method_holder(),
|
||||
super_m->access_flags(),
|
||||
false, false, CHECK);
|
||||
if (can_access) {
|
||||
// this class can access super final method and therefore override
|
||||
ResourceMark rm(THREAD);
|
||||
Exceptions::fthrow(THREAD_AND_LOCATION,
|
||||
vmSymbols::java_lang_VerifyError(),
|
||||
"class %s overrides final method %s.%s%s",
|
||||
this_klass->external_name(),
|
||||
super_m->method_holder()->external_name(),
|
||||
name->as_C_string(),
|
||||
signature->as_C_string()
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// continue to look from super_m's holder's super.
|
||||
@ -5470,6 +5558,7 @@ void ClassFileParser::fill_instance_klass(InstanceKlass* ik, bool changed_by_loa
|
||||
assert(NULL == _fields, "invariant");
|
||||
assert(NULL == _methods, "invariant");
|
||||
assert(NULL == _inner_classes, "invariant");
|
||||
assert(NULL == _nest_members, "invariant");
|
||||
assert(NULL == _local_interfaces, "invariant");
|
||||
assert(NULL == _combined_annotations, "invariant");
|
||||
|
||||
@ -5739,6 +5828,8 @@ ClassFileParser::ClassFileParser(ClassFileStream* stream,
|
||||
_fields(NULL),
|
||||
_methods(NULL),
|
||||
_inner_classes(NULL),
|
||||
_nest_members(NULL),
|
||||
_nest_host(0),
|
||||
_local_interfaces(NULL),
|
||||
_transitive_interfaces(NULL),
|
||||
_combined_annotations(NULL),
|
||||
@ -5843,6 +5934,7 @@ void ClassFileParser::clear_class_metadata() {
|
||||
_fields = NULL;
|
||||
_methods = NULL;
|
||||
_inner_classes = NULL;
|
||||
_nest_members = NULL;
|
||||
_local_interfaces = NULL;
|
||||
_combined_annotations = NULL;
|
||||
_annotations = _type_annotations = NULL;
|
||||
@ -5868,6 +5960,10 @@ ClassFileParser::~ClassFileParser() {
|
||||
MetadataFactory::free_array<u2>(_loader_data, _inner_classes);
|
||||
}
|
||||
|
||||
if (_nest_members != NULL && _nest_members != Universe::the_empty_short_array()) {
|
||||
MetadataFactory::free_array<u2>(_loader_data, _nest_members);
|
||||
}
|
||||
|
||||
// Free interfaces
|
||||
InstanceKlass::deallocate_interfaces(_loader_data, _super_klass,
|
||||
_local_interfaces, _transitive_interfaces);
|
||||
|
@ -97,6 +97,8 @@ class ClassFileParser {
|
||||
Array<u2>* _fields;
|
||||
Array<Method*>* _methods;
|
||||
Array<u2>* _inner_classes;
|
||||
Array<u2>* _nest_members;
|
||||
u2 _nest_host;
|
||||
Array<Klass*>* _local_interfaces;
|
||||
Array<Klass*>* _transitive_interfaces;
|
||||
Annotations* _combined_annotations;
|
||||
@ -290,6 +292,10 @@ class ClassFileParser {
|
||||
u2 enclosing_method_method_index,
|
||||
TRAPS);
|
||||
|
||||
u2 parse_classfile_nest_members_attribute(const ClassFileStream* const cfs,
|
||||
const u1* const nest_members_attribute_start,
|
||||
TRAPS);
|
||||
|
||||
void parse_classfile_attributes(const ClassFileStream* const cfs,
|
||||
ConstantPool* cp,
|
||||
ClassAnnotationCollector* parsed_annotations,
|
||||
|
@ -245,10 +245,6 @@ Klass* SystemDictionary::resolve_or_fail(Symbol* class_name,
|
||||
// Forwards to resolve_instance_class_or_null
|
||||
|
||||
Klass* SystemDictionary::resolve_or_null(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS) {
|
||||
assert(THREAD->can_call_java(),
|
||||
"can not load classes with compiler thread: class=%s, classloader=%s",
|
||||
class_name->as_C_string(),
|
||||
class_loader.is_null() ? "null" : class_loader->klass()->name()->as_C_string());
|
||||
if (FieldType::is_array(class_name)) {
|
||||
return resolve_array_class_or_null(class_name, class_loader, protection_domain, THREAD);
|
||||
} else if (FieldType::is_obj(class_name)) {
|
||||
@ -692,6 +688,10 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name,
|
||||
PlaceholderEntry* placeholder;
|
||||
Symbol* superclassname = NULL;
|
||||
|
||||
assert(THREAD->can_call_java(),
|
||||
"can not load classes with compiler thread: class=%s, classloader=%s",
|
||||
name->as_C_string(),
|
||||
class_loader.is_null() ? "null" : class_loader->klass()->name()->as_C_string());
|
||||
{
|
||||
MutexLocker mu(SystemDictionary_lock, THREAD);
|
||||
InstanceKlass* check = find_class(d_hash, name, dictionary);
|
||||
|
@ -142,6 +142,8 @@
|
||||
/* class file format tags */ \
|
||||
template(tag_source_file, "SourceFile") \
|
||||
template(tag_inner_classes, "InnerClasses") \
|
||||
template(tag_nest_members, "NestMembers") \
|
||||
template(tag_nest_host, "NestHost") \
|
||||
template(tag_constant_value, "ConstantValue") \
|
||||
template(tag_code, "Code") \
|
||||
template(tag_exceptions, "Exceptions") \
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "compiler/compileBroker.hpp"
|
||||
#include "compiler/compileTask.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/klass.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "oops/objArrayKlass.hpp"
|
||||
#include "runtime/flags/flagSetting.hpp"
|
||||
@ -1228,8 +1229,9 @@ class ClassHierarchyWalker {
|
||||
} else if (!k->is_instance_klass()) {
|
||||
return false; // no methods to find in an array type
|
||||
} else {
|
||||
// Search class hierarchy first.
|
||||
Method* m = InstanceKlass::cast(k)->find_instance_method(_name, _signature);
|
||||
// Search class hierarchy first, skipping private implementations
|
||||
// as they never override any inherited methods
|
||||
Method* m = InstanceKlass::cast(k)->find_instance_method(_name, _signature, Klass::skip_private);
|
||||
if (!Dependencies::is_concrete_method(m, k)) {
|
||||
// Check for re-abstraction of method
|
||||
if (!k->is_interface() && m != NULL && m->is_abstract()) {
|
||||
|
@ -522,6 +522,17 @@ JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnl
|
||||
JNIEXPORT jint JNICALL
|
||||
JVM_GetClassAccessFlags(JNIEnv *env, jclass cls);
|
||||
|
||||
/* Nestmates - since JDK 11 */
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
JVM_AreNestMates(JNIEnv *env, jclass current, jclass member);
|
||||
|
||||
JNIEXPORT jclass JNICALL
|
||||
JVM_GetNestHost(JNIEnv *env, jclass current);
|
||||
|
||||
JNIEXPORT jobjectArray JNICALL
|
||||
JVM_GetNestMembers(JNIEnv *env, jclass current);
|
||||
|
||||
/* The following two reflection routines are still needed due to startup time issues */
|
||||
/*
|
||||
* java.lang.reflect.Method
|
||||
|
@ -387,12 +387,13 @@ Method* LinkResolver::lookup_method_in_klasses(const LinkInfo& link_info,
|
||||
// Looks up method in classes, then looks up local default methods
|
||||
methodHandle LinkResolver::lookup_instance_method_in_klasses(Klass* klass,
|
||||
Symbol* name,
|
||||
Symbol* signature, TRAPS) {
|
||||
Method* result = klass->uncached_lookup_method(name, signature, Klass::find_overpass);
|
||||
Symbol* signature,
|
||||
Klass::PrivateLookupMode private_mode, TRAPS) {
|
||||
Method* result = klass->uncached_lookup_method(name, signature, Klass::find_overpass, private_mode);
|
||||
|
||||
while (result != NULL && result->is_static() && result->method_holder()->super() != NULL) {
|
||||
Klass* super_klass = result->method_holder()->super();
|
||||
result = super_klass->uncached_lookup_method(name, signature, Klass::find_overpass);
|
||||
result = super_klass->uncached_lookup_method(name, signature, Klass::find_overpass, private_mode);
|
||||
}
|
||||
|
||||
if (klass->is_array_klass()) {
|
||||
@ -582,11 +583,14 @@ void LinkResolver::check_method_accessability(Klass* ref_klass,
|
||||
}
|
||||
// assert(extra_arg_result_or_null != NULL, "must be able to return extra argument");
|
||||
|
||||
if (!Reflection::verify_field_access(ref_klass,
|
||||
resolved_klass,
|
||||
sel_klass,
|
||||
flags,
|
||||
true)) {
|
||||
bool can_access = Reflection::verify_member_access(ref_klass,
|
||||
resolved_klass,
|
||||
sel_klass,
|
||||
flags,
|
||||
true, false, CHECK);
|
||||
// Any existing exceptions that may have been thrown, for example LinkageErrors
|
||||
// from nest-host resolution, have been allowed to propagate.
|
||||
if (!can_access) {
|
||||
ResourceMark rm(THREAD);
|
||||
Exceptions::fthrow(
|
||||
THREAD_AND_LOCATION,
|
||||
@ -757,7 +761,7 @@ methodHandle LinkResolver::resolve_method(const LinkInfo& link_info,
|
||||
nested_exception, NULL);
|
||||
}
|
||||
|
||||
// 5. access checks, access checking may be turned off when calling from within the VM.
|
||||
// 6. access checks, access checking may be turned off when calling from within the VM.
|
||||
Klass* current_klass = link_info.current_klass();
|
||||
if (link_info.check_access()) {
|
||||
assert(current_klass != NULL , "current_klass should not be null");
|
||||
@ -773,6 +777,24 @@ methodHandle LinkResolver::resolve_method(const LinkInfo& link_info,
|
||||
check_method_loader_constraints(link_info, resolved_method, "method", CHECK_NULL);
|
||||
}
|
||||
|
||||
// For private method invocation we should only find the method in the resolved class.
|
||||
// If that is not the case then we have a found a supertype method that we have nestmate
|
||||
// access to.
|
||||
if (resolved_method->is_private() && resolved_method->method_holder() != resolved_klass) {
|
||||
ResourceMark rm(THREAD);
|
||||
DEBUG_ONLY(bool is_nestmate = InstanceKlass::cast(link_info.current_klass())->has_nestmate_access_to(InstanceKlass::cast(resolved_klass), THREAD);)
|
||||
assert(is_nestmate, "was only expecting nestmates to get here!");
|
||||
Exceptions::fthrow(
|
||||
THREAD_AND_LOCATION,
|
||||
vmSymbols::java_lang_NoSuchMethodError(),
|
||||
"%s: method %s%s not found",
|
||||
resolved_klass->external_name(),
|
||||
resolved_method->name()->as_C_string(),
|
||||
resolved_method->signature()->as_C_string()
|
||||
);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return resolved_method;
|
||||
}
|
||||
|
||||
@ -874,19 +896,6 @@ methodHandle LinkResolver::resolve_interface_method(const LinkInfo& link_info, B
|
||||
THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
|
||||
}
|
||||
|
||||
if (code == Bytecodes::_invokeinterface && resolved_method->is_private()) {
|
||||
ResourceMark rm(THREAD);
|
||||
char buf[200];
|
||||
|
||||
Klass* current_klass = link_info.current_klass();
|
||||
jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokeinterface: method %s, caller-class:%s",
|
||||
Method::name_and_sig_as_C_string(resolved_klass,
|
||||
resolved_method->name(),
|
||||
resolved_method->signature()),
|
||||
(current_klass == NULL ? "<NULL>" : current_klass->internal_name()));
|
||||
THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
|
||||
}
|
||||
|
||||
if (log_develop_is_enabled(Trace, itables)) {
|
||||
char buf[200];
|
||||
jio_snprintf(buf, sizeof(buf), "%s resolved interface method: caller-class:",
|
||||
@ -906,11 +915,14 @@ void LinkResolver::check_field_accessability(Klass* ref_klass,
|
||||
Klass* sel_klass,
|
||||
const fieldDescriptor& fd,
|
||||
TRAPS) {
|
||||
if (!Reflection::verify_field_access(ref_klass,
|
||||
resolved_klass,
|
||||
sel_klass,
|
||||
fd.access_flags(),
|
||||
true)) {
|
||||
bool can_access = Reflection::verify_member_access(ref_klass,
|
||||
resolved_klass,
|
||||
sel_klass,
|
||||
fd.access_flags(),
|
||||
true, false, CHECK);
|
||||
// Any existing exceptions that may have been thrown, for example LinkageErrors
|
||||
// from nest-host resolution, have been allowed to propagate.
|
||||
if (!can_access) {
|
||||
ResourceMark rm(THREAD);
|
||||
Exceptions::fthrow(
|
||||
THREAD_AND_LOCATION,
|
||||
@ -1128,7 +1140,8 @@ methodHandle LinkResolver::linktime_resolve_special_method(const LinkInfo& link_
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// check if invokespecial's interface method reference is in an indirect superinterface
|
||||
// ensure that invokespecial's interface method reference is in
|
||||
// a direct superinterface, not an indirect superinterface
|
||||
Klass* current_klass = link_info.current_klass();
|
||||
if (current_klass != NULL && resolved_klass->is_interface()) {
|
||||
InstanceKlass* ck = InstanceKlass::cast(current_klass);
|
||||
@ -1146,8 +1159,8 @@ methodHandle LinkResolver::linktime_resolve_special_method(const LinkInfo& link_
|
||||
jio_snprintf(buf, sizeof(buf),
|
||||
"Interface method reference: %s, is in an indirect superinterface of %s",
|
||||
Method::name_and_sig_as_C_string(resolved_klass,
|
||||
resolved_method->name(),
|
||||
resolved_method->signature()),
|
||||
resolved_method->name(),
|
||||
resolved_method->signature()),
|
||||
current_klass->external_name());
|
||||
THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
|
||||
}
|
||||
@ -1192,7 +1205,7 @@ void LinkResolver::runtime_resolve_special_method(CallInfo& result,
|
||||
resolved_method->name() != vmSymbols::object_initializer_name()) {
|
||||
|
||||
// check if this is an old-style super call and do a new lookup if so
|
||||
// a) check if ACC_SUPER flag is set for the current class
|
||||
// a) check if ACC_SUPER flag is set for the current class
|
||||
Klass* current_klass = link_info.current_klass();
|
||||
if ((current_klass->is_super() || !AllowNonVirtualCalls) &&
|
||||
// b) check if the class of the resolved_klass is a superclass
|
||||
@ -1200,12 +1213,14 @@ void LinkResolver::runtime_resolve_special_method(CallInfo& result,
|
||||
// This check is not performed for super.invoke for interface methods
|
||||
// in super interfaces.
|
||||
current_klass->is_subclass_of(resolved_klass) &&
|
||||
current_klass != resolved_klass) {
|
||||
current_klass != resolved_klass
|
||||
) {
|
||||
// Lookup super method
|
||||
Klass* super_klass = current_klass->super();
|
||||
sel_method = lookup_instance_method_in_klasses(super_klass,
|
||||
resolved_method->name(),
|
||||
resolved_method->signature(), CHECK);
|
||||
resolved_method->name(),
|
||||
resolved_method->signature(),
|
||||
Klass::find_private, CHECK);
|
||||
// check if found
|
||||
if (sel_method.is_null()) {
|
||||
ResourceMark rm(THREAD);
|
||||
@ -1356,11 +1371,12 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result,
|
||||
// a default or miranda method; therefore, it must have a valid vtable index.
|
||||
assert(!resolved_method->has_itable_index(), "");
|
||||
vtable_index = resolved_method->vtable_index();
|
||||
// We could get a negative vtable_index for final methods,
|
||||
// because as an optimization they are never put in the vtable,
|
||||
// unless they override an existing method.
|
||||
// If we do get a negative, it means the resolved method is the the selected
|
||||
// method, and it can never be changed by an override.
|
||||
// We could get a negative vtable_index of nonvirtual_vtable_index for private
|
||||
// methods, or for final methods. Private methods never appear in the vtable
|
||||
// and never override other methods. As an optimization, final methods are
|
||||
// never put in the vtable, unless they override an existing method.
|
||||
// So if we do get nonvirtual_vtable_index, it means the selected method is the
|
||||
// resolved method, and it can never be changed by an override.
|
||||
if (vtable_index == Method::nonvirtual_vtable_index) {
|
||||
assert(resolved_method->can_be_statically_bound(), "cannot override this method");
|
||||
selected_method = resolved_method;
|
||||
@ -1415,6 +1431,7 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result,
|
||||
Handle recv,
|
||||
Klass* recv_klass,
|
||||
bool check_null_and_abstract, TRAPS) {
|
||||
|
||||
// check if receiver exists
|
||||
if (check_null_and_abstract && recv.is_null()) {
|
||||
THROW(vmSymbols::java_lang_NullPointerException());
|
||||
@ -1430,35 +1447,43 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result,
|
||||
THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
|
||||
}
|
||||
|
||||
// do lookup based on receiver klass
|
||||
// This search must match the linktime preparation search for itable initialization
|
||||
// to correctly enforce loader constraints for interface method inheritance
|
||||
methodHandle selected_method = lookup_instance_method_in_klasses(recv_klass,
|
||||
resolved_method->name(),
|
||||
resolved_method->signature(), CHECK);
|
||||
if (selected_method.is_null() && !check_null_and_abstract) {
|
||||
// In theory this is a harmless placeholder value, but
|
||||
// in practice leaving in null affects the nsk default method tests.
|
||||
// This needs further study.
|
||||
selected_method = resolved_method;
|
||||
}
|
||||
// check if method exists
|
||||
if (selected_method.is_null()) {
|
||||
// Pass arguments for generating a verbose error message.
|
||||
throw_abstract_method_error(resolved_method, recv_klass, CHECK);
|
||||
}
|
||||
// check access
|
||||
// Throw Illegal Access Error if selected_method is not public.
|
||||
if (!selected_method->is_public()) {
|
||||
ResourceMark rm(THREAD);
|
||||
THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
|
||||
Method::name_and_sig_as_C_string(recv_klass,
|
||||
selected_method->name(),
|
||||
selected_method->signature()));
|
||||
}
|
||||
// check if abstract
|
||||
if (check_null_and_abstract && selected_method->is_abstract()) {
|
||||
throw_abstract_method_error(resolved_method, selected_method, recv_klass, CHECK);
|
||||
methodHandle selected_method = resolved_method;
|
||||
|
||||
// resolve the method in the receiver class, unless it is private
|
||||
if (!resolved_method()->is_private()) {
|
||||
// do lookup based on receiver klass
|
||||
// This search must match the linktime preparation search for itable initialization
|
||||
// to correctly enforce loader constraints for interface method inheritance.
|
||||
// Private methods are skipped as the resolved method was not private.
|
||||
selected_method = lookup_instance_method_in_klasses(recv_klass,
|
||||
resolved_method->name(),
|
||||
resolved_method->signature(),
|
||||
Klass::skip_private, CHECK);
|
||||
|
||||
if (selected_method.is_null() && !check_null_and_abstract) {
|
||||
// In theory this is a harmless placeholder value, but
|
||||
// in practice leaving in null affects the nsk default method tests.
|
||||
// This needs further study.
|
||||
selected_method = resolved_method;
|
||||
}
|
||||
// check if method exists
|
||||
if (selected_method.is_null()) {
|
||||
// Pass arguments for generating a verbose error message.
|
||||
throw_abstract_method_error(resolved_method, recv_klass, CHECK);
|
||||
}
|
||||
// check access
|
||||
// Throw Illegal Access Error if selected_method is not public.
|
||||
if (!selected_method->is_public()) {
|
||||
ResourceMark rm(THREAD);
|
||||
THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
|
||||
Method::name_and_sig_as_C_string(recv_klass,
|
||||
selected_method->name(),
|
||||
selected_method->signature()));
|
||||
}
|
||||
// check if abstract
|
||||
if (check_null_and_abstract && selected_method->is_abstract()) {
|
||||
throw_abstract_method_error(resolved_method, selected_method, recv_klass, CHECK);
|
||||
}
|
||||
}
|
||||
|
||||
if (log_develop_is_enabled(Trace, itables)) {
|
||||
@ -1466,13 +1491,25 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result,
|
||||
recv_klass, resolved_klass, selected_method, true);
|
||||
}
|
||||
// setup result
|
||||
if (!resolved_method->has_itable_index()) {
|
||||
if (resolved_method->has_vtable_index()) {
|
||||
int vtable_index = resolved_method->vtable_index();
|
||||
log_develop_trace(itables)(" -- vtable index: %d", vtable_index);
|
||||
assert(vtable_index == selected_method->vtable_index(), "sanity check");
|
||||
result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK);
|
||||
} else {
|
||||
} else if (resolved_method->has_itable_index()) {
|
||||
int itable_index = resolved_method()->itable_index();
|
||||
log_develop_trace(itables)(" -- itable index: %d", itable_index);
|
||||
result.set_interface(resolved_klass, recv_klass, resolved_method, selected_method, itable_index, CHECK);
|
||||
} else {
|
||||
int index = resolved_method->vtable_index();
|
||||
log_develop_trace(itables)(" -- non itable/vtable index: %d", index);
|
||||
assert(index == Method::nonvirtual_vtable_index, "Oops hit another case!");
|
||||
assert(resolved_method()->is_private() ||
|
||||
(resolved_method()->is_final() && resolved_method->method_holder() == SystemDictionary::Object_klass()),
|
||||
"Should only have non-virtual invokeinterface for private or final-Object methods!");
|
||||
assert(resolved_method()->can_be_statically_bound(), "Should only have non-virtual invokeinterface for statically bound methods!");
|
||||
// This sets up the nonvirtual form of "virtual" call (as needed for final and private methods)
|
||||
result.set_virtual(resolved_klass, resolved_klass, resolved_method, resolved_method, index, CHECK);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -211,8 +211,8 @@ class LinkResolver: AllStatic {
|
||||
Handle *method_type_result, TRAPS);
|
||||
JVMCI_ONLY(public:) // Needed for CompilerToVM.resolveMethod()
|
||||
// Not Linktime so doesn't take LinkInfo
|
||||
static methodHandle lookup_instance_method_in_klasses (
|
||||
Klass* klass, Symbol* name, Symbol* signature, TRAPS);
|
||||
static methodHandle lookup_instance_method_in_klasses (Klass* klass, Symbol* name, Symbol* signature,
|
||||
Klass::PrivateLookupMode private_mode, TRAPS);
|
||||
JVMCI_ONLY(private:)
|
||||
|
||||
// Similar loader constraint checking functions that throw
|
||||
|
@ -100,6 +100,7 @@
|
||||
LOG_TAG(module) \
|
||||
LOG_TAG(monitorinflation) \
|
||||
LOG_TAG(monitormismatch) \
|
||||
LOG_TAG(nestmates) \
|
||||
LOG_TAG(nmethod) \
|
||||
LOG_TAG(normalize) \
|
||||
LOG_TAG(objecttagging) \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -86,6 +86,8 @@
|
||||
"Number of bytes used by the InstanceKlass::fields() array") \
|
||||
f(inner_classes_bytes, IK_inner_classes, \
|
||||
"Number of bytes used by the InstanceKlass::inner_classes() array") \
|
||||
f(nest_members_bytes, IK_nest_members, \
|
||||
"Number of bytes used by the InstanceKlass::nest_members() array") \
|
||||
f(signers_bytes, IK_signers, \
|
||||
"Number of bytes used by the InstanceKlass::singers() array") \
|
||||
f(class_annotations_bytes, class_annotations, \
|
||||
|
@ -71,13 +71,14 @@ Klass* ArrayKlass::find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) co
|
||||
|
||||
Method* ArrayKlass::uncached_lookup_method(const Symbol* name,
|
||||
const Symbol* signature,
|
||||
OverpassLookupMode overpass_mode) const {
|
||||
OverpassLookupMode overpass_mode,
|
||||
PrivateLookupMode private_mode) const {
|
||||
// There are no methods in an array klass but the super class (Object) has some
|
||||
assert(super(), "super klass must be present");
|
||||
// Always ignore overpass methods in superclasses, although technically the
|
||||
// super klass of an array, (j.l.Object) should not have
|
||||
// any overpass methods present.
|
||||
return super()->uncached_lookup_method(name, signature, Klass::skip_overpass);
|
||||
return super()->uncached_lookup_method(name, signature, Klass::skip_overpass, private_mode);
|
||||
}
|
||||
|
||||
ArrayKlass::ArrayKlass(Symbol* name) :
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -87,7 +87,8 @@ class ArrayKlass: public Klass {
|
||||
// Lookup operations
|
||||
Method* uncached_lookup_method(const Symbol* name,
|
||||
const Symbol* signature,
|
||||
OverpassLookupMode overpass_mode) const;
|
||||
OverpassLookupMode overpass_mode,
|
||||
PrivateLookupMode private_mode = find_private) const;
|
||||
|
||||
static ArrayKlass* cast(Klass* k) {
|
||||
return const_cast<ArrayKlass*>(cast(const_cast<const Klass*>(k)));
|
||||
|
@ -174,17 +174,37 @@ void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_co
|
||||
|
||||
int byte_no = -1;
|
||||
bool change_to_virtual = false;
|
||||
|
||||
InstanceKlass* holder = NULL; // have to declare this outside the switch
|
||||
switch (invoke_code) {
|
||||
case Bytecodes::_invokeinterface:
|
||||
// We get here from InterpreterRuntime::resolve_invoke when an invokeinterface
|
||||
// instruction somehow links to a non-interface method (in Object).
|
||||
// In that case, the method has no itable index and must be invoked as a virtual.
|
||||
// Set a flag to keep track of this corner case.
|
||||
assert(method->is_public(), "Calling non-public method in Object with invokeinterface");
|
||||
change_to_virtual = true;
|
||||
holder = method->method_holder();
|
||||
// check for private interface method invocations
|
||||
if (vtable_index == Method::nonvirtual_vtable_index && holder->is_interface() ) {
|
||||
assert(method->is_private(), "unexpected non-private method");
|
||||
assert(method->can_be_statically_bound(), "unexpected non-statically-bound method");
|
||||
// set_f2_as_vfinal_method checks if is_vfinal flag is true.
|
||||
set_method_flags(as_TosState(method->result_type()),
|
||||
( 1 << is_vfinal_shift) |
|
||||
((method->is_final_method() ? 1 : 0) << is_final_shift),
|
||||
method()->size_of_parameters());
|
||||
set_f2_as_vfinal_method(method());
|
||||
byte_no = 2;
|
||||
set_f1(holder); // interface klass*
|
||||
break;
|
||||
}
|
||||
else {
|
||||
// We get here from InterpreterRuntime::resolve_invoke when an invokeinterface
|
||||
// instruction links to a non-interface method (in Object). This can happen when
|
||||
// an interface redeclares an Object method (like CharSequence declaring toString())
|
||||
// or when invokeinterface is used explicitly.
|
||||
// In that case, the method has no itable index and must be invoked as a virtual.
|
||||
// Set a flag to keep track of this corner case.
|
||||
assert(holder->is_interface() || holder == SystemDictionary::Object_klass(), "unexpected holder class");
|
||||
assert(method->is_public(), "Calling non-public method in Object with invokeinterface");
|
||||
change_to_virtual = true;
|
||||
|
||||
// ...and fall through as if we were handling invokevirtual:
|
||||
// ...and fall through as if we were handling invokevirtual:
|
||||
}
|
||||
case Bytecodes::_invokevirtual:
|
||||
{
|
||||
if (!is_vtable_call) {
|
||||
@ -237,7 +257,7 @@ void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_co
|
||||
// is executed.
|
||||
if (invoke_code != Bytecodes::_invokespecial || !sender_is_interface ||
|
||||
method->name() == vmSymbols::object_initializer_name()) {
|
||||
set_bytecode_1(invoke_code);
|
||||
set_bytecode_1(invoke_code);
|
||||
}
|
||||
} else if (byte_no == 2) {
|
||||
if (change_to_virtual) {
|
||||
@ -257,7 +277,18 @@ void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_co
|
||||
// We set bytecode_2() to _invokevirtual.
|
||||
// See also interpreterRuntime.cpp. (8/25/2000)
|
||||
} else {
|
||||
assert(invoke_code == Bytecodes::_invokevirtual, "");
|
||||
assert(invoke_code == Bytecodes::_invokevirtual ||
|
||||
(invoke_code == Bytecodes::_invokeinterface &&
|
||||
((method->is_private() ||
|
||||
(method->is_final() && method->method_holder() == SystemDictionary::Object_klass())))),
|
||||
"unexpected invocation mode");
|
||||
if (invoke_code == Bytecodes::_invokeinterface &&
|
||||
(method->is_private() || method->is_final())) {
|
||||
// We set bytecode_1() to _invokeinterface, because that is the
|
||||
// bytecode # used by the interpreter to see if it is resolved.
|
||||
// We set bytecode_2() to _invokevirtual.
|
||||
set_bytecode_1(invoke_code);
|
||||
}
|
||||
}
|
||||
// set up for invokevirtual, even if linking for invokeinterface also:
|
||||
set_bytecode_2(Bytecodes::_invokevirtual);
|
||||
|
@ -145,6 +145,198 @@ static inline bool is_class_loader(const Symbol* class_name,
|
||||
return false;
|
||||
}
|
||||
|
||||
// called to verify that k is a member of this nest
|
||||
bool InstanceKlass::has_nest_member(InstanceKlass* k, TRAPS) const {
|
||||
if (_nest_members == NULL || _nest_members == Universe::the_empty_short_array()) {
|
||||
if (log_is_enabled(Trace, class, nestmates)) {
|
||||
ResourceMark rm(THREAD);
|
||||
log_trace(class, nestmates)("Checked nest membership of %s in non-nest-host class %s",
|
||||
k->external_name(), this->external_name());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (log_is_enabled(Trace, class, nestmates)) {
|
||||
ResourceMark rm(THREAD);
|
||||
log_trace(class, nestmates)("Checking nest membership of %s in %s",
|
||||
k->external_name(), this->external_name());
|
||||
}
|
||||
|
||||
// Check names first and if they match then check actual klass. This avoids
|
||||
// resolving anything unnecessarily.
|
||||
for (int i = 0; i < _nest_members->length(); i++) {
|
||||
int cp_index = _nest_members->at(i);
|
||||
Symbol* name = _constants->klass_name_at(cp_index);
|
||||
if (name == k->name()) {
|
||||
log_trace(class, nestmates)("- Found it at nest_members[%d] => cp[%d]", i, cp_index);
|
||||
|
||||
// names match so check actual klass - this may trigger class loading if
|
||||
// it doesn't match (but that should be impossible)
|
||||
Klass* k2 = _constants->klass_at(cp_index, CHECK_false);
|
||||
if (k2 == k) {
|
||||
log_trace(class, nestmates)("- class is listed as a nest member");
|
||||
return true;
|
||||
} else {
|
||||
// same name but different klass!
|
||||
log_trace(class, nestmates)(" - klass comparison failed!");
|
||||
// can't have different classes for the same name, so we're done
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
log_trace(class, nestmates)("- class is NOT a nest member!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return nest-host class, resolving, validating and saving it if needed.
|
||||
// In cases where this is called from a thread that can not do classloading
|
||||
// (such as a native JIT thread) then we simply return NULL, which in turn
|
||||
// causes the access check to return false. Such code will retry the access
|
||||
// from a more suitable environment later.
|
||||
InstanceKlass* InstanceKlass::nest_host(Symbol* validationException, TRAPS) {
|
||||
InstanceKlass* nest_host_k = _nest_host;
|
||||
if (nest_host_k == NULL) {
|
||||
// need to resolve and save our nest-host class. This could be attempted
|
||||
// concurrently but as the result is idempotent and we don't use the class
|
||||
// then we do not need any synchronization beyond what is implicitly used
|
||||
// during class loading.
|
||||
if (_nest_host_index != 0) { // we have a real nest_host
|
||||
// Before trying to resolve check if we're in a suitable context
|
||||
if (!THREAD->can_call_java() && !_constants->tag_at(_nest_host_index).is_klass()) {
|
||||
if (log_is_enabled(Trace, class, nestmates)) {
|
||||
ResourceMark rm(THREAD);
|
||||
log_trace(class, nestmates)("Rejected resolution of nest-host of %s in unsuitable thread",
|
||||
this->external_name());
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (log_is_enabled(Trace, class, nestmates)) {
|
||||
ResourceMark rm(THREAD);
|
||||
log_trace(class, nestmates)("Resolving nest-host of %s using cp entry for %s",
|
||||
this->external_name(),
|
||||
_constants->klass_name_at(_nest_host_index)->as_C_string());
|
||||
}
|
||||
|
||||
Klass* k = _constants->klass_at(_nest_host_index, THREAD);
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
Handle exc_h = Handle(THREAD, PENDING_EXCEPTION);
|
||||
if (exc_h->is_a(SystemDictionary::NoClassDefFoundError_klass())) {
|
||||
// throw a new CDNFE with the original as its cause, and a clear msg
|
||||
ResourceMark rm(THREAD);
|
||||
char buf[200];
|
||||
CLEAR_PENDING_EXCEPTION;
|
||||
jio_snprintf(buf, sizeof(buf),
|
||||
"Unable to load nest-host class (%s) of %s",
|
||||
_constants->klass_name_at(_nest_host_index)->as_C_string(),
|
||||
this->external_name());
|
||||
log_trace(class, nestmates)("%s - NoClassDefFoundError", buf);
|
||||
THROW_MSG_CAUSE_NULL(vmSymbols::java_lang_NoClassDefFoundError(), buf, exc_h);
|
||||
}
|
||||
// All other exceptions pass through (OOME, StackOverflowError, LinkageErrors etc).
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// A valid nest-host is an instance class in the current package that lists this
|
||||
// class as a nest member. If any of these conditions are not met we post the
|
||||
// requested exception type (if any) and return NULL
|
||||
|
||||
const char* error = NULL;
|
||||
|
||||
// JVMS 5.4.4 indicates package check comes first
|
||||
if (is_same_class_package(k)) {
|
||||
|
||||
// Now check actual membership. We can't be a member if our "host" is
|
||||
// not an instance class.
|
||||
if (k->is_instance_klass()) {
|
||||
nest_host_k = InstanceKlass::cast(k);
|
||||
|
||||
bool is_member = nest_host_k->has_nest_member(this, CHECK_NULL);
|
||||
if (is_member) {
|
||||
// save resolved nest-host value
|
||||
_nest_host = nest_host_k;
|
||||
|
||||
if (log_is_enabled(Trace, class, nestmates)) {
|
||||
ResourceMark rm(THREAD);
|
||||
log_trace(class, nestmates)("Resolved nest-host of %s to %s",
|
||||
this->external_name(), k->external_name());
|
||||
}
|
||||
return nest_host_k;
|
||||
}
|
||||
}
|
||||
error = "current type is not listed as a nest member";
|
||||
} else {
|
||||
error = "types are in different packages";
|
||||
}
|
||||
|
||||
if (log_is_enabled(Trace, class, nestmates)) {
|
||||
ResourceMark rm(THREAD);
|
||||
log_trace(class, nestmates)("Type %s is not a nest member of resolved type %s: %s",
|
||||
this->external_name(),
|
||||
k->external_name(),
|
||||
error);
|
||||
}
|
||||
|
||||
if (validationException != NULL) {
|
||||
ResourceMark rm(THREAD);
|
||||
Exceptions::fthrow(THREAD_AND_LOCATION,
|
||||
validationException,
|
||||
"Type %s is not a nest member of %s: %s",
|
||||
this->external_name(),
|
||||
k->external_name(),
|
||||
error
|
||||
);
|
||||
}
|
||||
return NULL;
|
||||
} else {
|
||||
if (log_is_enabled(Trace, class, nestmates)) {
|
||||
ResourceMark rm(THREAD);
|
||||
log_trace(class, nestmates)("Type %s is not part of a nest: setting nest-host to self",
|
||||
this->external_name());
|
||||
}
|
||||
// save resolved nest-host value
|
||||
return (_nest_host = this);
|
||||
}
|
||||
}
|
||||
return nest_host_k;
|
||||
}
|
||||
|
||||
// check if 'this' and k are nestmates (same nest_host), or k is our nest_host,
|
||||
// or we are k's nest_host - all of which is covered by comparing the two
|
||||
// resolved_nest_hosts
|
||||
bool InstanceKlass::has_nestmate_access_to(InstanceKlass* k, TRAPS) {
|
||||
|
||||
assert(this != k, "this should be handled by higher-level code");
|
||||
|
||||
// Per JVMS 5.4.4 we first resolve and validate the current class, then
|
||||
// the target class k. Resolution exceptions will be passed on by upper
|
||||
// layers. IncompatibleClassChangeErrors from membership validation failures
|
||||
// will also be passed through.
|
||||
|
||||
Symbol* icce = vmSymbols::java_lang_IncompatibleClassChangeError();
|
||||
InstanceKlass* cur_host = nest_host(icce, CHECK_false);
|
||||
if (cur_host == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Klass* k_nest_host = k->nest_host(icce, CHECK_false);
|
||||
if (k_nest_host == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool access = (cur_host == k_nest_host);
|
||||
|
||||
if (log_is_enabled(Trace, class, nestmates)) {
|
||||
ResourceMark rm(THREAD);
|
||||
log_trace(class, nestmates)("Class %s does %shave nestmate access to %s",
|
||||
this->external_name(),
|
||||
access ? "" : "NOT ",
|
||||
k->external_name());
|
||||
}
|
||||
|
||||
return access;
|
||||
}
|
||||
|
||||
InstanceKlass* InstanceKlass::allocate_instance_klass(const ClassFileParser& parser, TRAPS) {
|
||||
const int size = InstanceKlass::size(parser.vtable_size(),
|
||||
parser.itable_size(),
|
||||
@ -169,13 +361,11 @@ InstanceKlass* InstanceKlass::allocate_instance_klass(const ClassFileParser& par
|
||||
else if (is_class_loader(class_name, parser)) {
|
||||
// class loader
|
||||
ik = new (loader_data, size, THREAD) InstanceClassLoaderKlass(parser);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// normal
|
||||
ik = new (loader_data, size, THREAD) InstanceKlass(parser, InstanceKlass::_misc_kind_other);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// reference
|
||||
ik = new (loader_data, size, THREAD) InstanceRefKlass(parser);
|
||||
}
|
||||
@ -215,7 +405,10 @@ InstanceKlass::InstanceKlass(const ClassFileParser& parser, unsigned kind) :
|
||||
_static_field_size(parser.static_field_size()),
|
||||
_nonstatic_oop_map_size(nonstatic_oop_map_size(parser.total_oop_map_count())),
|
||||
_itable_len(parser.itable_size()),
|
||||
_reference_type(parser.reference_type()) {
|
||||
_reference_type(parser.reference_type()),
|
||||
_nest_members(NULL),
|
||||
_nest_host_index(0),
|
||||
_nest_host(NULL) {
|
||||
set_vtable_length(parser.vtable_size());
|
||||
set_kind(kind);
|
||||
set_access_flags(parser.access_flags());
|
||||
@ -359,6 +552,13 @@ void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) {
|
||||
}
|
||||
set_inner_classes(NULL);
|
||||
|
||||
if (nest_members() != NULL &&
|
||||
nest_members() != Universe::the_empty_short_array() &&
|
||||
!nest_members()->is_shared()) {
|
||||
MetadataFactory::free_array<jushort>(loader_data, nest_members());
|
||||
}
|
||||
set_nest_members(NULL);
|
||||
|
||||
// We should deallocate the Annotations instance if it's not in shared spaces.
|
||||
if (annotations() != NULL && !annotations()->is_shared()) {
|
||||
MetadataFactory::free_metadata(loader_data, annotations());
|
||||
@ -643,7 +843,6 @@ bool InstanceKlass::link_class_impl(bool throw_verifyerror, TRAPS) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Rewrite the byte codes of all of the methods of a class.
|
||||
// The rewriter must be called exactly once. Rewriting must happen after
|
||||
// verification but before the first method of the class is executed.
|
||||
@ -1359,13 +1558,14 @@ Method* InstanceKlass::find_method_impl(const Symbol* name,
|
||||
// and skips over static methods
|
||||
Method* InstanceKlass::find_instance_method(const Array<Method*>* methods,
|
||||
const Symbol* name,
|
||||
const Symbol* signature) {
|
||||
const Symbol* signature,
|
||||
PrivateLookupMode private_mode) {
|
||||
Method* const meth = InstanceKlass::find_method_impl(methods,
|
||||
name,
|
||||
signature,
|
||||
find_overpass,
|
||||
skip_static,
|
||||
find_private);
|
||||
private_mode);
|
||||
assert(((meth == NULL) || !meth->is_static()),
|
||||
"find_instance_method should have skipped statics");
|
||||
return meth;
|
||||
@ -1373,8 +1573,10 @@ Method* InstanceKlass::find_instance_method(const Array<Method*>* methods,
|
||||
|
||||
// find_instance_method looks up the name/signature in the local methods array
|
||||
// and skips over static methods
|
||||
Method* InstanceKlass::find_instance_method(const Symbol* name, const Symbol* signature) const {
|
||||
return InstanceKlass::find_instance_method(methods(), name, signature);
|
||||
Method* InstanceKlass::find_instance_method(const Symbol* name,
|
||||
const Symbol* signature,
|
||||
PrivateLookupMode private_mode) const {
|
||||
return InstanceKlass::find_instance_method(methods(), name, signature, private_mode);
|
||||
}
|
||||
|
||||
// Find looks up the name/signature in the local methods array
|
||||
@ -1475,7 +1677,7 @@ int InstanceKlass::find_method_index(const Array<Method*>* methods,
|
||||
// Do linear search to find matching signature. First, quick check
|
||||
// for common case, ignoring overpasses if requested.
|
||||
if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) {
|
||||
return hit;
|
||||
return hit;
|
||||
}
|
||||
|
||||
// search downwards through overloaded methods
|
||||
@ -1531,10 +1733,12 @@ int InstanceKlass::find_method_by_name(const Array<Method*>* methods,
|
||||
}
|
||||
|
||||
// uncached_lookup_method searches both the local class methods array and all
|
||||
// superclasses methods arrays, skipping any overpass methods in superclasses.
|
||||
// superclasses methods arrays, skipping any overpass methods in superclasses,
|
||||
// and possibly skipping private methods.
|
||||
Method* InstanceKlass::uncached_lookup_method(const Symbol* name,
|
||||
const Symbol* signature,
|
||||
OverpassLookupMode overpass_mode) const {
|
||||
OverpassLookupMode overpass_mode,
|
||||
PrivateLookupMode private_mode) const {
|
||||
OverpassLookupMode overpass_local_mode = overpass_mode;
|
||||
const Klass* klass = this;
|
||||
while (klass != NULL) {
|
||||
@ -1542,7 +1746,7 @@ Method* InstanceKlass::uncached_lookup_method(const Symbol* name,
|
||||
signature,
|
||||
overpass_local_mode,
|
||||
find_static,
|
||||
find_private);
|
||||
private_mode);
|
||||
if (method != NULL) {
|
||||
return method;
|
||||
}
|
||||
@ -2044,6 +2248,8 @@ void InstanceKlass::metaspace_pointers_do(MetaspaceClosure* it) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
it->push(&_nest_members);
|
||||
}
|
||||
|
||||
void InstanceKlass::remove_unshareable_info() {
|
||||
@ -2087,10 +2293,12 @@ void InstanceKlass::remove_unshareable_info() {
|
||||
guarantee(_previous_versions == NULL, "must be");
|
||||
#endif
|
||||
|
||||
_init_thread = NULL;
|
||||
_methods_jmethod_ids = NULL;
|
||||
_jni_ids = NULL;
|
||||
_oop_map_cache = NULL;
|
||||
_init_thread = NULL;
|
||||
_methods_jmethod_ids = NULL;
|
||||
_jni_ids = NULL;
|
||||
_oop_map_cache = NULL;
|
||||
// clear _nest_host to ensure re-load at runtime
|
||||
_nest_host = NULL;
|
||||
}
|
||||
|
||||
void InstanceKlass::remove_java_mirror() {
|
||||
@ -2946,6 +3154,7 @@ void InstanceKlass::print_on(outputStream* st) const {
|
||||
st->cr();
|
||||
}
|
||||
st->print(BULLET"inner classes: "); inner_classes()->print_value_on(st); st->cr();
|
||||
st->print(BULLET"nest members: "); nest_members()->print_value_on(st); st->cr();
|
||||
st->print(BULLET"java mirror: "); java_mirror()->print_value_on(st); st->cr();
|
||||
st->print(BULLET"vtable length %d (start addr: " INTPTR_FORMAT ")", vtable_length(), p2i(start_of_vtable())); st->cr();
|
||||
if (vtable_length() > 0 && (Verbose || WizardMode)) print_vtable(start_of_vtable(), vtable_length(), st);
|
||||
@ -3188,6 +3397,7 @@ void InstanceKlass::collect_statistics(KlassSizeStats *sz) const {
|
||||
n += (sz->_transitive_interfaces_bytes = sz->count_array(transitive_interfaces()));
|
||||
n += (sz->_fields_bytes = sz->count_array(fields()));
|
||||
n += (sz->_inner_classes_bytes = sz->count_array(inner_classes()));
|
||||
n += (sz->_nest_members_bytes = sz->count_array(nest_members()));
|
||||
sz->_ro_bytes += n;
|
||||
|
||||
const ConstantPool* cp = constants();
|
||||
|
@ -165,6 +165,19 @@ class InstanceKlass: public Klass {
|
||||
// number_of_inner_classes * 4 + enclosing_method_attribute_size.
|
||||
Array<jushort>* _inner_classes;
|
||||
|
||||
// The NestMembers attribute. An array of shorts, where each is a
|
||||
// class info index for the class that is a nest member. This data
|
||||
// has not been validated.
|
||||
Array<jushort>* _nest_members;
|
||||
|
||||
// The NestHost attribute. The class info index for the class
|
||||
// that is the nest-host of this class. This data has not been validated.
|
||||
jushort _nest_host_index;
|
||||
|
||||
// Resolved nest-host klass: either true nest-host or self if we are not nested.
|
||||
// By always being set it makes nest-member access checks simpler.
|
||||
InstanceKlass* _nest_host;
|
||||
|
||||
// the source debug extension for this klass, NULL if not specified.
|
||||
// Specified as UTF-8 string without terminating zero byte in the classfile,
|
||||
// it is stored in the instanceklass as a NULL-terminated UTF-8 string
|
||||
@ -435,6 +448,24 @@ class InstanceKlass: public Klass {
|
||||
Array<u2>* inner_classes() const { return _inner_classes; }
|
||||
void set_inner_classes(Array<u2>* f) { _inner_classes = f; }
|
||||
|
||||
// nest members
|
||||
Array<u2>* nest_members() const { return _nest_members; }
|
||||
void set_nest_members(Array<u2>* m) { _nest_members = m; }
|
||||
|
||||
// nest-host index
|
||||
jushort nest_host_index() const { return _nest_host_index; }
|
||||
void set_nest_host_index(u2 i) { _nest_host_index = i; }
|
||||
|
||||
private:
|
||||
// Called to verify that k is a member of this nest - does not look at k's nest-host
|
||||
bool has_nest_member(InstanceKlass* k, TRAPS) const;
|
||||
public:
|
||||
// Returns nest-host class, resolving and validating it if needed
|
||||
// Returns NULL if an exception occurs during loading, or validation fails
|
||||
InstanceKlass* nest_host(Symbol* validationException, TRAPS);
|
||||
// Check if this klass is a nestmate of k - resolves this nest-host and k's
|
||||
bool has_nestmate_access_to(InstanceKlass* k, TRAPS);
|
||||
|
||||
enum InnerClassAttributeOffset {
|
||||
// From http://mirror.eng/products/jdk/1.1/docs/guide/innerclasses/spec/innerclasses.doc10.html#18814
|
||||
inner_class_inner_class_info_offset = 0,
|
||||
@ -554,10 +585,12 @@ class InstanceKlass: public Klass {
|
||||
const Symbol* signature);
|
||||
|
||||
// find a local method, but skip static methods
|
||||
Method* find_instance_method(const Symbol* name, const Symbol* signature) const;
|
||||
Method* find_instance_method(const Symbol* name, const Symbol* signature,
|
||||
PrivateLookupMode private_mode = find_private) const;
|
||||
static Method* find_instance_method(const Array<Method*>* methods,
|
||||
const Symbol* name,
|
||||
const Symbol* signature);
|
||||
const Symbol* signature,
|
||||
PrivateLookupMode private_mode = find_private);
|
||||
|
||||
// find a local method (returns NULL if not found)
|
||||
Method* find_local_method(const Symbol* name,
|
||||
@ -585,7 +618,8 @@ class InstanceKlass: public Klass {
|
||||
// lookup operation (returns NULL if not found)
|
||||
Method* uncached_lookup_method(const Symbol* name,
|
||||
const Symbol* signature,
|
||||
OverpassLookupMode overpass_mode) const;
|
||||
OverpassLookupMode overpass_mode,
|
||||
PrivateLookupMode private_mode = find_private) const;
|
||||
|
||||
// lookup a method in all the interfaces that this class implements
|
||||
// (returns NULL if not found)
|
||||
|
@ -168,7 +168,9 @@ Klass* Klass::find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Method* Klass::uncached_lookup_method(const Symbol* name, const Symbol* signature, OverpassLookupMode overpass_mode) const {
|
||||
Method* Klass::uncached_lookup_method(const Symbol* name, const Symbol* signature,
|
||||
OverpassLookupMode overpass_mode,
|
||||
PrivateLookupMode private_mode) const {
|
||||
#ifdef ASSERT
|
||||
tty->print_cr("Error: uncached_lookup_method called on a klass oop."
|
||||
" Likely error: reflection method does not correctly"
|
||||
|
@ -467,7 +467,9 @@ protected:
|
||||
// lookup operation for MethodLookupCache
|
||||
friend class MethodLookupCache;
|
||||
virtual Klass* find_field(Symbol* name, Symbol* signature, fieldDescriptor* fd) const;
|
||||
virtual Method* uncached_lookup_method(const Symbol* name, const Symbol* signature, OverpassLookupMode overpass_mode) const;
|
||||
virtual Method* uncached_lookup_method(const Symbol* name, const Symbol* signature,
|
||||
OverpassLookupMode overpass_mode,
|
||||
PrivateLookupMode = find_private) const;
|
||||
public:
|
||||
Method* lookup_method(const Symbol* name, const Symbol* signature) const {
|
||||
return uncached_lookup_method(name, signature, find_overpass);
|
||||
|
@ -1122,7 +1122,7 @@ void klassItable::initialize_itable(bool checkconstraints, TRAPS) {
|
||||
inline bool interface_method_needs_itable_index(Method* m) {
|
||||
if (m->is_static()) return false; // e.g., Stream.empty
|
||||
if (m->is_initializer()) return false; // <init> or <clinit>
|
||||
if (m->is_private()) return false; // requires invokeSpecial
|
||||
if (m->is_private()) return false; // uses direct call
|
||||
// If an interface redeclares a method from java.lang.Object,
|
||||
// it should already have a vtable index, don't touch it.
|
||||
// e.g., CharSequence.toString (from initialize_vtable)
|
||||
@ -1211,8 +1211,13 @@ void klassItable::initialize_itable_for_interface(int method_table_offset, Klass
|
||||
methodHandle target;
|
||||
if (m->has_itable_index()) {
|
||||
// This search must match the runtime resolution, i.e. selection search for invokeinterface
|
||||
// to correctly enforce loader constraints for interface method inheritance
|
||||
target = LinkResolver::lookup_instance_method_in_klasses(_klass, m->name(), m->signature(), CHECK);
|
||||
// to correctly enforce loader constraints for interface method inheritance.
|
||||
// Private methods are skipped as a private class method can never be the implementation
|
||||
// of an interface method.
|
||||
// Invokespecial does not perform selection based on the receiver, so it does not use
|
||||
// the cached itable.
|
||||
target = LinkResolver::lookup_instance_method_in_klasses(_klass, m->name(), m->signature(),
|
||||
Klass::skip_private, CHECK);
|
||||
}
|
||||
if (target == NULL || !target->is_public() || target->is_abstract() || target->is_overpass()) {
|
||||
assert(target == NULL || !target->is_overpass() || target->is_public(),
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -505,28 +505,36 @@ void Parse::do_call() {
|
||||
speculative_receiver_type = receiver_type != NULL ? receiver_type->speculative_type() : NULL;
|
||||
}
|
||||
|
||||
// invoke-super-special
|
||||
// Additional receiver subtype checks for interface calls via invokespecial or invokeinterface.
|
||||
ciKlass* receiver_constraint = NULL;
|
||||
if (iter().cur_bc_raw() == Bytecodes::_invokespecial && !orig_callee->is_object_initializer()) {
|
||||
ciInstanceKlass* calling_klass = method()->holder();
|
||||
ciInstanceKlass* sender_klass =
|
||||
calling_klass->is_anonymous() ? calling_klass->host_klass() :
|
||||
calling_klass;
|
||||
if (sender_klass->is_interface()) {
|
||||
Node* receiver_node = stack(sp() - nargs);
|
||||
Node* cls_node = makecon(TypeKlassPtr::make(sender_klass));
|
||||
Node* bad_type_ctrl = NULL;
|
||||
Node* casted_receiver = gen_checkcast(receiver_node, cls_node, &bad_type_ctrl);
|
||||
if (bad_type_ctrl != NULL) {
|
||||
PreserveJVMState pjvms(this);
|
||||
set_control(bad_type_ctrl);
|
||||
uncommon_trap(Deoptimization::Reason_class_check,
|
||||
Deoptimization::Action_none);
|
||||
}
|
||||
if (stopped()) {
|
||||
return; // MUST uncommon-trap?
|
||||
}
|
||||
set_stack(sp() - nargs, casted_receiver);
|
||||
receiver_constraint = sender_klass;
|
||||
}
|
||||
} else if (iter().cur_bc_raw() == Bytecodes::_invokeinterface && orig_callee->is_private()) {
|
||||
assert(holder->is_interface(), "How did we get a non-interface method here!");
|
||||
receiver_constraint = holder;
|
||||
}
|
||||
|
||||
if (receiver_constraint != NULL) {
|
||||
Node* receiver_node = stack(sp() - nargs);
|
||||
Node* cls_node = makecon(TypeKlassPtr::make(receiver_constraint));
|
||||
Node* bad_type_ctrl = NULL;
|
||||
Node* casted_receiver = gen_checkcast(receiver_node, cls_node, &bad_type_ctrl);
|
||||
if (bad_type_ctrl != NULL) {
|
||||
PreserveJVMState pjvms(this);
|
||||
set_control(bad_type_ctrl);
|
||||
uncommon_trap(Deoptimization::Reason_class_check,
|
||||
Deoptimization::Action_none);
|
||||
}
|
||||
if (stopped()) {
|
||||
return; // MUST uncommon-trap?
|
||||
}
|
||||
set_stack(sp() - nargs, casted_receiver);
|
||||
}
|
||||
|
||||
// Note: It's OK to try to inline a virtual call.
|
||||
|
@ -1892,6 +1892,98 @@ JVM_ENTRY(jint, JVM_GetClassAccessFlags(JNIEnv *env, jclass cls))
|
||||
}
|
||||
JVM_END
|
||||
|
||||
JVM_ENTRY(jboolean, JVM_AreNestMates(JNIEnv *env, jclass current, jclass member))
|
||||
{
|
||||
JVMWrapper("JVM_AreNestMates");
|
||||
Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current));
|
||||
assert(c->is_instance_klass(), "must be");
|
||||
InstanceKlass* ck = InstanceKlass::cast(c);
|
||||
Klass* m = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(member));
|
||||
assert(m->is_instance_klass(), "must be");
|
||||
InstanceKlass* mk = InstanceKlass::cast(m);
|
||||
return ck->has_nestmate_access_to(mk, THREAD);
|
||||
}
|
||||
JVM_END
|
||||
|
||||
JVM_ENTRY(jclass, JVM_GetNestHost(JNIEnv* env, jclass current))
|
||||
{
|
||||
// current is not a primitive or array class
|
||||
JVMWrapper("JVM_GetNestHost");
|
||||
Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current));
|
||||
assert(c->is_instance_klass(), "must be");
|
||||
InstanceKlass* ck = InstanceKlass::cast(c);
|
||||
// Don't post exceptions if validation fails
|
||||
InstanceKlass* host = ck->nest_host(NULL, THREAD);
|
||||
return (jclass) (host == NULL ? NULL :
|
||||
JNIHandles::make_local(THREAD, host->java_mirror()));
|
||||
}
|
||||
JVM_END
|
||||
|
||||
JVM_ENTRY(jobjectArray, JVM_GetNestMembers(JNIEnv* env, jclass current))
|
||||
{
|
||||
// current is not a primitive or array class
|
||||
JVMWrapper("JVM_GetNestMembers");
|
||||
Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current));
|
||||
assert(c->is_instance_klass(), "must be");
|
||||
InstanceKlass* ck = InstanceKlass::cast(c);
|
||||
// Get the nest host for this nest - throw ICCE if validation fails
|
||||
Symbol* icce = vmSymbols::java_lang_IncompatibleClassChangeError();
|
||||
InstanceKlass* host = ck->nest_host(icce, CHECK_NULL);
|
||||
|
||||
{
|
||||
JvmtiVMObjectAllocEventCollector oam;
|
||||
Array<u2>* members = host->nest_members();
|
||||
int length = members == NULL ? 0 : members->length();
|
||||
// nest host is first in the array so make it one bigger
|
||||
objArrayOop r = oopFactory::new_objArray(SystemDictionary::Class_klass(),
|
||||
length + 1, CHECK_NULL);
|
||||
objArrayHandle result (THREAD, r);
|
||||
result->obj_at_put(0, host->java_mirror());
|
||||
if (length != 0) {
|
||||
int i;
|
||||
for (i = 0; i < length; i++) {
|
||||
int cp_index = members->at(i);
|
||||
Klass* k = host->constants()->klass_at(cp_index, CHECK_NULL);
|
||||
if (k->is_instance_klass()) {
|
||||
InstanceKlass* nest_host_k =
|
||||
InstanceKlass::cast(k)->nest_host(icce, CHECK_NULL);
|
||||
if (nest_host_k == host) {
|
||||
result->obj_at_put(i+1, k->java_mirror());
|
||||
}
|
||||
else {
|
||||
// k's nest host is legal but it isn't our host so
|
||||
// throw ICCE
|
||||
ResourceMark rm(THREAD);
|
||||
Exceptions::fthrow(THREAD_AND_LOCATION,
|
||||
icce,
|
||||
"Nest member %s in %s declares a different nest host of %s",
|
||||
k->external_name(),
|
||||
host->external_name(),
|
||||
nest_host_k->external_name()
|
||||
);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// we have a bad nest member entry - throw ICCE
|
||||
ResourceMark rm(THREAD);
|
||||
Exceptions::fthrow(THREAD_AND_LOCATION,
|
||||
icce,
|
||||
"Class %s can not be a nest member of %s",
|
||||
k->external_name(),
|
||||
host->external_name()
|
||||
);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert(host == ck, "must be singleton nest");
|
||||
}
|
||||
return (jobjectArray)JNIHandles::make_local(THREAD, result());
|
||||
}
|
||||
}
|
||||
JVM_END
|
||||
|
||||
// Constant pool access //////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -358,7 +358,7 @@
|
||||
]>
|
||||
|
||||
<specification label="JVM(TM) Tool Interface"
|
||||
majorversion="9"
|
||||
majorversion="11"
|
||||
minorversion="0"
|
||||
microversion="0">
|
||||
<title subtitle="Version">
|
||||
@ -7631,9 +7631,12 @@ class C2 extends C1 implements I2 {
|
||||
<eventlink id="ClassFileLoadHook"/> event
|
||||
will be sent.
|
||||
<p/>
|
||||
The retransformation may change method bodies, the constant pool and attributes.
|
||||
The retransformation may change method bodies, the constant pool and attributes
|
||||
(unless explicitly prohibited).
|
||||
The retransformation must not add, remove or rename fields or methods, change the
|
||||
signatures of methods, change modifiers, or change inheritance.
|
||||
The retransformation must not change the <code>NestHost</code> or
|
||||
<code>NestMembers</code> attributes.
|
||||
These restrictions may be lifted in future versions.
|
||||
See the error return description below for information on error codes
|
||||
returned if an unsupported retransformation is attempted.
|
||||
@ -7704,6 +7707,9 @@ class C2 extends C1 implements I2 {
|
||||
A retransformed class file does not declare a method
|
||||
declared in the old class version.
|
||||
</error>
|
||||
<error id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED">
|
||||
A retransformed class file has unsupported differences in class attributes.
|
||||
</error>
|
||||
<error id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED">
|
||||
A retransformed class file has different class modifiers.
|
||||
</error>
|
||||
@ -7778,9 +7784,12 @@ class C2 extends C1 implements I2 {
|
||||
<eventlink id="ClassFileLoadHook">Class File Load Hook</eventlink>
|
||||
will be sent (if enabled), but no other <jvmti/> events will be sent.
|
||||
<p/>
|
||||
The redefinition may change method bodies, the constant pool and attributes.
|
||||
The redefinition may change method bodies, the constant pool and attributes
|
||||
(unless explicitly prohibited).
|
||||
The redefinition must not add, remove or rename fields or methods, change the
|
||||
signatures of methods, change modifiers, or change inheritance.
|
||||
The retransformation must not change the <code>NestHost</code> or
|
||||
<code>NestMembers</code> attributes.
|
||||
These restrictions may be lifted in future versions.
|
||||
See the error return description below for information on error codes
|
||||
returned if an unsupported redefinition is attempted.
|
||||
@ -7855,6 +7864,9 @@ class C2 extends C1 implements I2 {
|
||||
A new class version does not declare a method
|
||||
declared in the old class version.
|
||||
</error>
|
||||
<error id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED">
|
||||
A new class version has unsupported differences in class attributes.
|
||||
</error>
|
||||
<error id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED">
|
||||
A new class version has different modifiers.
|
||||
</error>
|
||||
@ -11788,6 +11800,9 @@ myInit() {
|
||||
A method in the new class version has different modifiers
|
||||
than its counterpart in the old class version.
|
||||
</errorid>
|
||||
<errorid id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED" num="72">
|
||||
A new class version has unsupported differences in class attributes.
|
||||
</errorid>
|
||||
</errorcategory>
|
||||
</errorsection>
|
||||
|
||||
@ -14927,6 +14942,13 @@ typedef void (JNICALL *jvmtiEventVMInit)
|
||||
- The function may return NULL in the start phase if the
|
||||
can_generate_early_vmstart capability is enabled.
|
||||
</change>
|
||||
<change date="7 February 2018" version="11.0.0">
|
||||
Minor update for new class file NestHost and NestMembers attributes:
|
||||
- Specify that RedefineClasses and RetransformClasses are not allowed
|
||||
to change the class file NestHost and NestMembers attributes.
|
||||
- Add new error JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED
|
||||
that can be returned by RedefineClasses and RetransformClasses.
|
||||
</change>
|
||||
</changehistory>
|
||||
|
||||
</specification>
|
||||
|
@ -388,6 +388,40 @@ void JvmtiClassFileReconstituter::write_bootstrapmethod_attribute() {
|
||||
}
|
||||
}
|
||||
|
||||
// NestHost_attribute {
|
||||
// u2 attribute_name_index;
|
||||
// u4 attribute_length;
|
||||
// u2 host_class_index;
|
||||
// }
|
||||
void JvmtiClassFileReconstituter::write_nest_host_attribute() {
|
||||
int length = sizeof(u2);
|
||||
int host_class_index = ik()->nest_host_index();
|
||||
|
||||
write_attribute_name_index("NestHost");
|
||||
write_u4(length);
|
||||
write_u2(host_class_index);
|
||||
}
|
||||
|
||||
// NestMembers_attribute {
|
||||
// u2 attribute_name_index;
|
||||
// u4 attribute_length;
|
||||
// u2 number_of_classes;
|
||||
// u2 classes[number_of_classes];
|
||||
// }
|
||||
void JvmtiClassFileReconstituter::write_nest_members_attribute() {
|
||||
Array<u2>* nest_members = ik()->nest_members();
|
||||
int number_of_classes = nest_members->length();
|
||||
int length = sizeof(u2) * (1 + number_of_classes);
|
||||
|
||||
write_attribute_name_index("NestMembers");
|
||||
write_u4(length);
|
||||
write_u2(number_of_classes);
|
||||
for (int i = 0; i < number_of_classes; i++) {
|
||||
u2 class_cp_index = nest_members->at(i);
|
||||
write_u2(class_cp_index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Write InnerClasses attribute
|
||||
// JVMSpec| InnerClasses_attribute {
|
||||
@ -658,6 +692,12 @@ void JvmtiClassFileReconstituter::write_class_attributes() {
|
||||
if (cpool()->operands() != NULL) {
|
||||
++attr_count;
|
||||
}
|
||||
if (ik()->nest_host_index() != 0) {
|
||||
++attr_count;
|
||||
}
|
||||
if (ik()->nest_members() != Universe::the_empty_short_array()) {
|
||||
++attr_count;
|
||||
}
|
||||
|
||||
write_u2(attr_count);
|
||||
|
||||
@ -682,6 +722,12 @@ void JvmtiClassFileReconstituter::write_class_attributes() {
|
||||
if (cpool()->operands() != NULL) {
|
||||
write_bootstrapmethod_attribute();
|
||||
}
|
||||
if (ik()->nest_host_index() != 0) {
|
||||
write_nest_host_attribute();
|
||||
}
|
||||
if (ik()->nest_members() != Universe::the_empty_short_array()) {
|
||||
write_nest_members_attribute();
|
||||
}
|
||||
}
|
||||
|
||||
// Write the method information portion of ClassFile structure
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -116,6 +116,8 @@ class JvmtiClassFileReconstituter : public JvmtiConstantPoolReconstituter {
|
||||
void write_attribute_name_index(const char* name);
|
||||
void write_annotations_attribute(const char* attr_name, AnnotationArray* annos);
|
||||
void write_bootstrapmethod_attribute();
|
||||
void write_nest_host_attribute();
|
||||
void write_nest_members_attribute();
|
||||
|
||||
address writeable_address(size_t size);
|
||||
void write_u1(u1 x);
|
||||
|
@ -370,6 +370,14 @@ JvmtiExport::get_jvmti_interface(JavaVM *jvm, void **penv, jint version) {
|
||||
return JNI_EVERSION; // unsupported minor version number
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
switch (minor) {
|
||||
case 0: // version 11.0.<micro> is recognized
|
||||
break;
|
||||
default:
|
||||
return JNI_EVERSION; // unsupported minor version number
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return JNI_EVERSION; // unsupported major version number
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
|
||||
This code is free software; you can redistribute it and/or modify it
|
||||
@ -20,7 +20,7 @@
|
||||
Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
or visit www.oracle.com if you need additional information or have any
|
||||
questions.
|
||||
|
||||
|
||||
-->
|
||||
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
@ -47,7 +47,7 @@
|
||||
/* Constants */
|
||||
</xsl:text>
|
||||
<xsl:apply-templates select="//constants"/>
|
||||
|
||||
|
||||
<xsl:text>
|
||||
|
||||
/* Errors */
|
||||
@ -91,7 +91,7 @@ typedef enum {
|
||||
<xsl:apply-templates select="functionsection"/>
|
||||
|
||||
<xsl:call-template name="outro"/>
|
||||
|
||||
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="intro">
|
||||
@ -114,6 +114,7 @@ enum {
|
||||
JVMTI_VERSION_1_1 = 0x30010100,
|
||||
JVMTI_VERSION_1_2 = 0x30010200,
|
||||
JVMTI_VERSION_9 = 0x30090000,
|
||||
JVMTI_VERSION_11 = 0x300B0000,
|
||||
|
||||
JVMTI_VERSION = 0x30000000 + (</xsl:text>
|
||||
<xsl:value-of select="//specification/@majorversion"/>
|
||||
@ -298,7 +299,7 @@ struct _jvmtiEnv {
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:text> RESERVED */
|
||||
void *reserved</xsl:text>
|
||||
void *reserved</xsl:text>
|
||||
<xsl:value-of select="$index"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
|
@ -683,6 +683,95 @@ void VM_RedefineClasses::finalize_operands_merge(const constantPoolHandle& merge
|
||||
_operands_index_map_count = 0;
|
||||
} // end finalize_operands_merge()
|
||||
|
||||
// Symbol* comparator for qsort
|
||||
// The caller must have an active ResourceMark.
|
||||
static int symcmp(const void* a, const void* b) {
|
||||
char* astr = (*(Symbol**)a)->as_C_string();
|
||||
char* bstr = (*(Symbol**)b)->as_C_string();
|
||||
return strcmp(astr, bstr);
|
||||
}
|
||||
|
||||
static jvmtiError check_nest_attributes(InstanceKlass* the_class,
|
||||
InstanceKlass* scratch_class) {
|
||||
// Check whether the class NestHost attribute has been changed.
|
||||
Thread* thread = Thread::current();
|
||||
ResourceMark rm(thread);
|
||||
JvmtiThreadState *state = JvmtiThreadState::state_for((JavaThread*)thread);
|
||||
u2 the_nest_host_idx = the_class->nest_host_index();
|
||||
u2 scr_nest_host_idx = scratch_class->nest_host_index();
|
||||
|
||||
if (the_nest_host_idx != 0 && scr_nest_host_idx != 0) {
|
||||
Symbol* the_sym = the_class->constants()->klass_name_at(the_nest_host_idx);
|
||||
Symbol* scr_sym = scratch_class->constants()->klass_name_at(scr_nest_host_idx);
|
||||
if (the_sym != scr_sym) {
|
||||
log_trace(redefine, class, nestmates)
|
||||
("redefined class %s attribute change error: NestHost class: %s replaced with: %s",
|
||||
the_class->external_name(), the_sym->as_C_string(), scr_sym->as_C_string());
|
||||
return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED;
|
||||
}
|
||||
} else if ((the_nest_host_idx == 0) ^ (scr_nest_host_idx == 0)) {
|
||||
const char* action_str = (the_nest_host_idx != 0) ? "removed" : "added";
|
||||
log_trace(redefine, class, nestmates)
|
||||
("redefined class %s attribute change error: NestHost attribute %s",
|
||||
the_class->external_name(), action_str);
|
||||
return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED;
|
||||
}
|
||||
|
||||
// Check whether the class NestMembers attribute has been changed.
|
||||
Array<u2>* the_nest_members = the_class->nest_members();
|
||||
Array<u2>* scr_nest_members = scratch_class->nest_members();
|
||||
bool the_members_exists = the_nest_members != Universe::the_empty_short_array();
|
||||
bool scr_members_exists = scr_nest_members != Universe::the_empty_short_array();
|
||||
|
||||
int members_len = the_nest_members->length();
|
||||
if (the_members_exists && scr_members_exists) {
|
||||
if (members_len != scr_nest_members->length()) {
|
||||
log_trace(redefine, class, nestmates)
|
||||
("redefined class %s attribute change error: NestMember len=%d changed to len=%d",
|
||||
the_class->external_name(), members_len, scr_nest_members->length());
|
||||
return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED;
|
||||
}
|
||||
|
||||
// The order of entries in the NestMembers array is not specified so we
|
||||
// have to explicitly check for the same contents. We do this by copying
|
||||
// the referenced symbols into their own arrays, sorting them and then
|
||||
// comparing each element pair.
|
||||
|
||||
Symbol** the_syms = NEW_RESOURCE_ARRAY_RETURN_NULL(Symbol*, members_len);
|
||||
Symbol** scr_syms = NEW_RESOURCE_ARRAY_RETURN_NULL(Symbol*, members_len);
|
||||
|
||||
if (the_syms == NULL || scr_syms == NULL) {
|
||||
return JVMTI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
for (int i = 0; i < members_len; i++) {
|
||||
int the_cp_index = the_nest_members->at(i);
|
||||
int scr_cp_index = scr_nest_members->at(i);
|
||||
the_syms[i] = the_class->constants()->klass_name_at(the_cp_index);
|
||||
scr_syms[i] = scratch_class->constants()->klass_name_at(scr_cp_index);
|
||||
}
|
||||
|
||||
qsort(the_syms, members_len, sizeof(Symbol*), symcmp);
|
||||
qsort(scr_syms, members_len, sizeof(Symbol*), symcmp);
|
||||
|
||||
for (int i = 0; i < members_len; i++) {
|
||||
if (the_syms[i] != scr_syms[i]) {
|
||||
log_trace(redefine, class, nestmates)
|
||||
("redefined class %s attribute change error: NestMembers[%d]: %s changed to %s",
|
||||
the_class->external_name(), i, the_syms[i]->as_C_string(), scr_syms[i]->as_C_string());
|
||||
return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED;
|
||||
}
|
||||
}
|
||||
} else if (the_members_exists ^ scr_members_exists) {
|
||||
const char* action_str = (the_members_exists) ? "removed" : "added";
|
||||
log_trace(redefine, class, nestmates)
|
||||
("redefined class %s attribute change error: NestMembers attribute %s",
|
||||
the_class->external_name(), action_str);
|
||||
return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED;
|
||||
}
|
||||
|
||||
return JVMTI_ERROR_NONE;
|
||||
}
|
||||
|
||||
jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions(
|
||||
InstanceKlass* the_class,
|
||||
@ -725,6 +814,12 @@ jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions(
|
||||
return JVMTI_ERROR_INVALID_CLASS;
|
||||
}
|
||||
|
||||
// Check whether the nest-related attributes have been changed.
|
||||
jvmtiError err = check_nest_attributes(the_class, scratch_class);
|
||||
if (err != JVMTI_ERROR_NONE) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// Check whether class modifiers are the same.
|
||||
jushort old_flags = (jushort) the_class->access_flags().get_flags();
|
||||
jushort new_flags = (jushort) scratch_class->access_flags().get_flags();
|
||||
@ -1598,6 +1693,12 @@ jvmtiError VM_RedefineClasses::merge_cp_and_rewrite(
|
||||
bool VM_RedefineClasses::rewrite_cp_refs(InstanceKlass* scratch_class,
|
||||
TRAPS) {
|
||||
|
||||
// rewrite constant pool references in the nest attributes:
|
||||
if (!rewrite_cp_refs_in_nest_attributes(scratch_class)) {
|
||||
// propagate failure back to caller
|
||||
return false;
|
||||
}
|
||||
|
||||
// rewrite constant pool references in the methods:
|
||||
if (!rewrite_cp_refs_in_methods(scratch_class, THREAD)) {
|
||||
// propagate failure back to caller
|
||||
@ -1680,6 +1781,22 @@ bool VM_RedefineClasses::rewrite_cp_refs(InstanceKlass* scratch_class,
|
||||
return true;
|
||||
} // end rewrite_cp_refs()
|
||||
|
||||
// Rewrite constant pool references in the NestHost and NestMembers attributes.
|
||||
bool VM_RedefineClasses::rewrite_cp_refs_in_nest_attributes(
|
||||
InstanceKlass* scratch_class) {
|
||||
|
||||
u2 cp_index = scratch_class->nest_host_index();
|
||||
if (cp_index != 0) {
|
||||
scratch_class->set_nest_host_index(find_new_index(cp_index));
|
||||
}
|
||||
Array<u2>* nest_members = scratch_class->nest_members();
|
||||
for (int i = 0; i < nest_members->length(); i++) {
|
||||
u2 cp_index = nest_members->at(i);
|
||||
nest_members->at_put(i, find_new_index(cp_index));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Rewrite constant pool references in the methods.
|
||||
bool VM_RedefineClasses::rewrite_cp_refs_in_methods(
|
||||
InstanceKlass* scratch_class, TRAPS) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -469,6 +469,7 @@ class VM_RedefineClasses: public VM_Operation {
|
||||
AnnotationArray* type_annotations_typeArray, int &byte_i_ref, TRAPS);
|
||||
bool rewrite_cp_refs_in_fields_annotations(
|
||||
InstanceKlass* scratch_class, TRAPS);
|
||||
bool rewrite_cp_refs_in_nest_attributes(InstanceKlass* scratch_class);
|
||||
void rewrite_cp_refs_in_method(methodHandle method,
|
||||
methodHandle * new_method_p, TRAPS);
|
||||
bool rewrite_cp_refs_in_methods(InstanceKlass* scratch_class, TRAPS);
|
||||
|
@ -238,7 +238,12 @@ oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) {
|
||||
vmindex);
|
||||
m->access_flags().print_on(tty);
|
||||
if (!m->is_abstract()) {
|
||||
tty->print("default");
|
||||
if (!m->is_private()) {
|
||||
tty->print("default");
|
||||
}
|
||||
else {
|
||||
tty->print("private-intf");
|
||||
}
|
||||
}
|
||||
tty->cr();
|
||||
}
|
||||
@ -292,6 +297,9 @@ oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) {
|
||||
} else if (m->is_initializer()) {
|
||||
flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
|
||||
} else {
|
||||
// "special" reflects that this is a direct call, not that it
|
||||
// necessarily originates from an invokespecial. We can also do
|
||||
// direct calls for private and/or final non-static methods.
|
||||
flags |= IS_METHOD | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
|
||||
}
|
||||
break;
|
||||
|
@ -650,26 +650,27 @@ char* Reflection::verify_class_access_msg(const Klass* current_class,
|
||||
return msg;
|
||||
}
|
||||
|
||||
bool Reflection::verify_field_access(const Klass* current_class,
|
||||
const Klass* resolved_class,
|
||||
const Klass* field_class,
|
||||
AccessFlags access,
|
||||
bool classloader_only,
|
||||
bool protected_restriction) {
|
||||
// Verify that current_class can access a field of field_class, where that
|
||||
bool Reflection::verify_member_access(const Klass* current_class,
|
||||
const Klass* resolved_class,
|
||||
const Klass* member_class,
|
||||
AccessFlags access,
|
||||
bool classloader_only,
|
||||
bool protected_restriction,
|
||||
TRAPS) {
|
||||
// Verify that current_class can access a member of member_class, where that
|
||||
// field's access bits are "access". We assume that we've already verified
|
||||
// that current_class can access field_class.
|
||||
// that current_class can access member_class.
|
||||
//
|
||||
// If the classloader_only flag is set, we automatically allow any accesses
|
||||
// in which current_class doesn't have a classloader.
|
||||
//
|
||||
// "resolved_class" is the runtime type of "field_class". Sometimes we don't
|
||||
// "resolved_class" is the runtime type of "member_class". Sometimes we don't
|
||||
// need this distinction (e.g. if all we have is the runtime type, or during
|
||||
// class file parsing when we only care about the static type); in that case
|
||||
// callers should ensure that resolved_class == field_class.
|
||||
// callers should ensure that resolved_class == member_class.
|
||||
//
|
||||
if ((current_class == NULL) ||
|
||||
(current_class == field_class) ||
|
||||
(current_class == member_class) ||
|
||||
access.is_public()) {
|
||||
return true;
|
||||
}
|
||||
@ -683,18 +684,18 @@ bool Reflection::verify_field_access(const Klass* current_class,
|
||||
InstanceKlass::cast(host_class)->is_anonymous()),
|
||||
"host_class should not be anonymous");
|
||||
}
|
||||
if (host_class == field_class) {
|
||||
if (host_class == member_class) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (access.is_protected()) {
|
||||
if (!protected_restriction) {
|
||||
// See if current_class (or outermost host class) is a subclass of field_class
|
||||
// See if current_class (or outermost host class) is a subclass of member_class
|
||||
// An interface may not access protected members of j.l.Object
|
||||
if (!host_class->is_interface() && host_class->is_subclass_of(field_class)) {
|
||||
if (!host_class->is_interface() && host_class->is_subclass_of(member_class)) {
|
||||
if (access.is_static() || // static fields are ok, see 6622385
|
||||
current_class == resolved_class ||
|
||||
field_class == resolved_class ||
|
||||
member_class == resolved_class ||
|
||||
host_class->is_subclass_of(resolved_class) ||
|
||||
resolved_class->is_subclass_of(host_class)) {
|
||||
return true;
|
||||
@ -703,18 +704,35 @@ bool Reflection::verify_field_access(const Klass* current_class,
|
||||
}
|
||||
}
|
||||
|
||||
if (!access.is_private() && is_same_class_package(current_class, field_class)) {
|
||||
// package access
|
||||
if (!access.is_private() && is_same_class_package(current_class, member_class)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// private access between different classes needs a nestmate check, but
|
||||
// not for anonymous classes - so check host_class
|
||||
if (access.is_private() && host_class == current_class) {
|
||||
if (current_class->is_instance_klass() && member_class->is_instance_klass() ) {
|
||||
InstanceKlass* cur_ik = const_cast<InstanceKlass*>(InstanceKlass::cast(current_class));
|
||||
InstanceKlass* field_ik = const_cast<InstanceKlass*>(InstanceKlass::cast(member_class));
|
||||
// Nestmate access checks may require resolution and validation of the nest-host.
|
||||
// It is up to the caller to check for pending exceptions and handle appropriately.
|
||||
bool access = cur_ik->has_nestmate_access_to(field_ik, CHECK_false);
|
||||
if (access) {
|
||||
guarantee(resolved_class->is_subclass_of(member_class), "must be!");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allow all accesses from jdk/internal/reflect/MagicAccessorImpl subclasses to
|
||||
// succeed trivially.
|
||||
if (current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return can_relax_access_check_for(
|
||||
current_class, field_class, classloader_only);
|
||||
// Check for special relaxations
|
||||
return can_relax_access_check_for(current_class, member_class, classloader_only);
|
||||
}
|
||||
|
||||
bool Reflection::is_same_class_package(const Klass* class1, const Klass* class2) {
|
||||
|
@ -90,12 +90,13 @@ class Reflection: public AllStatic {
|
||||
const InstanceKlass* new_class,
|
||||
const VerifyClassAccessResults result);
|
||||
|
||||
static bool verify_field_access(const Klass* current_class,
|
||||
const Klass* resolved_class,
|
||||
const Klass* field_class,
|
||||
AccessFlags access,
|
||||
bool classloader_only,
|
||||
bool protected_restriction = false);
|
||||
static bool verify_member_access(const Klass* current_class,
|
||||
const Klass* resolved_class,
|
||||
const Klass* member_class,
|
||||
AccessFlags access,
|
||||
bool classloader_only,
|
||||
bool protected_restriction,
|
||||
TRAPS);
|
||||
static bool is_same_class_package(const Klass* class1, const Klass* class2);
|
||||
|
||||
// inner class reflection
|
||||
|
@ -13,6 +13,8 @@ pack.code.attribute.CoverageTable = NH[PHHII]
|
||||
pack.code.attribute.CharacterRangeTable = NH[PHPOHIIH]
|
||||
pack.class.attribute.SourceID = RUH
|
||||
pack.class.attribute.CompilationID = RUH
|
||||
pack.class.attribute.NestHost = RCH
|
||||
pack.class.attribute.NestMembers = NH[RCH]
|
||||
|
||||
# Note: Zero-length ("marker") attributes do not need to be specified here.
|
||||
# They are automatically defined to have an empty layout.
|
||||
|
@ -82,9 +82,9 @@ import sun.reflect.annotation.*;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
/**
|
||||
* Instances of the class {@code Class} represent classes and
|
||||
* interfaces in a running Java application. An enum is a kind of
|
||||
* class and an annotation is a kind of interface. Every array also
|
||||
* Instances of the class {@code Class} represent classes and interfaces
|
||||
* in a running Java application. An enum type is a kind of class and an
|
||||
* annotation type is a kind of interface. Every array also
|
||||
* belongs to a class that is reflected as a {@code Class} object
|
||||
* that is shared by all arrays with the same element type and number
|
||||
* of dimensions. The primitive Java types ({@code boolean},
|
||||
@ -93,10 +93,34 @@ import sun.reflect.misc.ReflectUtil;
|
||||
* {@code double}), and the keyword {@code void} are also
|
||||
* represented as {@code Class} objects.
|
||||
*
|
||||
* <p> {@code Class} has no public constructor. Instead {@code Class}
|
||||
* objects are constructed automatically by the Java Virtual Machine as classes
|
||||
* are loaded and by calls to the {@code defineClass} method in the class
|
||||
* loader.
|
||||
* <p> {@code Class} has no public constructor. Instead a {@code Class}
|
||||
* object is constructed automatically by the Java Virtual Machine
|
||||
* when a class loader invokes one of the
|
||||
* {@link ClassLoader#defineClass(String,byte[], int,int) defineClass} methods
|
||||
* and passes the bytes of a {@code class} file.
|
||||
*
|
||||
* <p> The methods of class {@code Class} expose many characteristics of a
|
||||
* class or interface. Most characteristics are derived from the {@code class}
|
||||
* file that the class loader passed to the Java Virtual Machine. A few
|
||||
* characteristics are determined by the class loading environment at run time,
|
||||
* such as the module returned by {@link #getModule() getModule()}.
|
||||
*
|
||||
* <p> Some methods of class {@code Class} expose whether the declaration of
|
||||
* a class or interface in Java source code was <em>enclosed</em> within
|
||||
* another declaration. Other methods describe how a class or interface
|
||||
* is situated in a <em>nest</em>. A <a id="nest">nest</a> is a set of
|
||||
* classes and interfaces, in the same run-time package, that
|
||||
* allow mutual access to their {@code private} members.
|
||||
* The classes and interfaces are known as <em>nestmates</em>.
|
||||
* One nestmate acts as the
|
||||
* <em>nest host</em>, and enumerates the other nestmates which
|
||||
* belong to the nest; each of them in turn records it as the nest host.
|
||||
* The classes and interfaces which belong to a nest, including its host, are
|
||||
* determined when
|
||||
* {@code class} files are generated, for example, a Java compiler
|
||||
* will typically record a top-level class as the host of a nest where the
|
||||
* other members are the classes and interfaces whose declarations are
|
||||
* enclosed within the top-level class declaration.
|
||||
*
|
||||
* <p> The following example uses a {@code Class} object to print the
|
||||
* class name of an object:
|
||||
@ -3848,4 +3872,161 @@ public final class Class<T> implements java.io.Serializable,
|
||||
public AnnotatedType[] getAnnotatedInterfaces() {
|
||||
return TypeAnnotationParser.buildAnnotatedInterfaces(getRawTypeAnnotations(), getConstantPool(), this);
|
||||
}
|
||||
|
||||
private native Class<?> getNestHost0();
|
||||
|
||||
/**
|
||||
* Returns the nest host of the <a href=#nest>nest</a> to which the class
|
||||
* or interface represented by this {@code Class} object belongs.
|
||||
* Every class and interface is a member of exactly one nest.
|
||||
* A class or interface that is not recorded as belonging to a nest
|
||||
* belongs to the nest consisting only of itself, and is the nest
|
||||
* host.
|
||||
*
|
||||
* <p>Each of the {@code Class} objects representing array types,
|
||||
* primitive types, and {@code void} returns {@code this} to indicate
|
||||
* that the represented entity belongs to the nest consisting only of
|
||||
* itself, and is the nest host.
|
||||
*
|
||||
* <p>If there is a {@linkplain LinkageError linkage error} accessing
|
||||
* the nest host, or if this class or interface is not enumerated as
|
||||
* a member of the nest by the nest host, then it is considered to belong
|
||||
* to its own nest and {@code this} is returned as the host.
|
||||
*
|
||||
* @apiNote A {@code class} file of version 55.0 or greater may record the
|
||||
* host of the nest to which it belongs by using the {@code NestHost}
|
||||
* attribute (JVMS 4.7.28). Alternatively, a {@code class} file of
|
||||
* version 55.0 or greater may act as a nest host by enumerating the nest's
|
||||
* other members with the
|
||||
* {@code NestMembers} attribute (JVMS 4.7.29).
|
||||
* A {@code class} file of version 54.0 or lower does not use these
|
||||
* attributes.
|
||||
*
|
||||
* @return the nest host of this class or interface
|
||||
*
|
||||
* @throws SecurityException
|
||||
* If the returned class is not the current class, and
|
||||
* if a security manager, <i>s</i>, is present and the caller's
|
||||
* class loader is not the same as or an ancestor of the class
|
||||
* loader for the returned class and invocation of {@link
|
||||
* SecurityManager#checkPackageAccess s.checkPackageAccess()}
|
||||
* denies access to the package of the returned class
|
||||
* @since 11
|
||||
* @jvms 4.7.28 and 4.7.29 NestHost and NestMembers attributes
|
||||
* @jvms 5.4.4 Access Control
|
||||
*/
|
||||
@CallerSensitive
|
||||
public Class<?> getNestHost() {
|
||||
if (isPrimitive() || isArray()) {
|
||||
return this;
|
||||
}
|
||||
Class<?> host;
|
||||
try {
|
||||
host = getNestHost0();
|
||||
} catch (LinkageError e) {
|
||||
// if we couldn't load our nest-host then we
|
||||
// act as-if we have no nest-host attribute
|
||||
return this;
|
||||
}
|
||||
// if null then nest membership validation failed, so we
|
||||
// act as-if we have no nest-host attribute
|
||||
if (host == null || host == this) {
|
||||
return this;
|
||||
}
|
||||
// returning a different class requires a security check
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
checkPackageAccess(sm,
|
||||
ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
|
||||
}
|
||||
return host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the given {@code Class} is a nestmate of the
|
||||
* class or interface represented by this {@code Class} object.
|
||||
* Two classes or interfaces are nestmates
|
||||
* if they have the same {@linkplain #getNestHost() nest host}.
|
||||
*
|
||||
* @param c the class to check
|
||||
* @return {@code true} if this class and {@code c} are members of
|
||||
* the same nest; and {@code false} otherwise.
|
||||
*
|
||||
* @since 11
|
||||
*/
|
||||
public boolean isNestmateOf(Class<?> c) {
|
||||
if (this == c) {
|
||||
return true;
|
||||
}
|
||||
if (isPrimitive() || isArray() ||
|
||||
c.isPrimitive() || c.isArray()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
return getNestHost0() == c.getNestHost0();
|
||||
} catch (LinkageError e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private native Class<?>[] getNestMembers0();
|
||||
|
||||
/**
|
||||
* Returns an array containing {@code Class} objects representing all the
|
||||
* classes and interfaces that are members of the nest to which the class
|
||||
* or interface represented by this {@code Class} object belongs.
|
||||
* The {@linkplain #getNestHost() nest host} of that nest is the zeroth
|
||||
* element of the array. Subsequent elements represent any classes or
|
||||
* interfaces that are recorded by the nest host as being members of
|
||||
* the nest; the order of such elements is unspecified. Duplicates are
|
||||
* permitted.
|
||||
* If the nest host of that nest does not enumerate any members, then the
|
||||
* array has a single element containing {@code this}.
|
||||
*
|
||||
* <p>Each of the {@code Class} objects representing array types,
|
||||
* primitive types, and {@code void} returns an array containing only
|
||||
* {@code this}.
|
||||
*
|
||||
* <p>This method validates that, for each class or interface which is
|
||||
* recorded as a member of the nest by the nest host, that class or
|
||||
* interface records itself as a member of that same nest. Any exceptions
|
||||
* that occur during this validation are rethrown by this method.
|
||||
*
|
||||
* @return an array of all classes and interfaces in the same nest as
|
||||
* this class
|
||||
*
|
||||
* @throws LinkageError
|
||||
* If there is any problem loading or validating a nest member or
|
||||
* its nest host
|
||||
* @throws SecurityException
|
||||
* If any returned class is not the current class, and
|
||||
* if a security manager, <i>s</i>, is present and the caller's
|
||||
* class loader is not the same as or an ancestor of the class
|
||||
* loader for that returned class and invocation of {@link
|
||||
* SecurityManager#checkPackageAccess s.checkPackageAccess()}
|
||||
* denies access to the package of that returned class
|
||||
*
|
||||
* @since 11
|
||||
* @see #getNestHost()
|
||||
*/
|
||||
@CallerSensitive
|
||||
public Class<?>[] getNestMembers() {
|
||||
if (isPrimitive() || isArray()) {
|
||||
return new Class<?>[] { this };
|
||||
}
|
||||
Class<?>[] members = getNestMembers0();
|
||||
// Can't actually enable this due to bootstrapping issues
|
||||
// assert(members.length != 1 || members[0] == this); // expected invariant from VM
|
||||
|
||||
if (members.length > 1) {
|
||||
// If we return anything other than the current class we need
|
||||
// a security check
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
checkPackageAccess(sm,
|
||||
ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
|
||||
}
|
||||
}
|
||||
return members;
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,8 @@ class DirectMethodHandle extends MethodHandle {
|
||||
if (!member.isResolved()) throw new InternalError();
|
||||
|
||||
if (member.getDeclaringClass().isInterface() &&
|
||||
member.isMethod() && !member.isAbstract()) {
|
||||
member.getReferenceKind() == REF_invokeInterface &&
|
||||
member.isMethod() && !member.isAbstract()) {
|
||||
// Check for corner case: invokeinterface of Object method
|
||||
MemberName m = new MemberName(Object.class, member.getName(), member.getMethodType(), member.getReferenceKind());
|
||||
m = MemberName.getFactory().resolveOrNull(m.getReferenceKind(), m, null);
|
||||
@ -80,22 +81,28 @@ class DirectMethodHandle extends MethodHandle {
|
||||
mtype = mtype.insertParameterTypes(0, refc);
|
||||
}
|
||||
if (!member.isField()) {
|
||||
// refKind reflects the original type of lookup via findSpecial or
|
||||
// findVirtual etc.
|
||||
switch (refKind) {
|
||||
case REF_invokeSpecial: {
|
||||
member = member.asSpecial();
|
||||
LambdaForm lform = preparedLambdaForm(member, callerClass);
|
||||
Class<?> checkClass = refc; // Class to use for receiver type check
|
||||
if (callerClass != null) {
|
||||
checkClass = callerClass; // potentially strengthen to caller class
|
||||
// if caller is an interface we need to adapt to get the
|
||||
// receiver check inserted
|
||||
if (callerClass == null) {
|
||||
throw new InternalError("callerClass must not be null for REF_invokeSpecial");
|
||||
}
|
||||
return new Special(mtype, lform, member, checkClass);
|
||||
LambdaForm lform = preparedLambdaForm(member, callerClass.isInterface());
|
||||
return new Special(mtype, lform, member, callerClass);
|
||||
}
|
||||
case REF_invokeInterface: {
|
||||
LambdaForm lform = preparedLambdaForm(member, callerClass);
|
||||
// for interfaces we always need the receiver typecheck,
|
||||
// so we always pass 'true' to ensure we adapt if needed
|
||||
// to include the REF_invokeSpecial case
|
||||
LambdaForm lform = preparedLambdaForm(member, true);
|
||||
return new Interface(mtype, lform, member, refc);
|
||||
}
|
||||
default: {
|
||||
LambdaForm lform = preparedLambdaForm(member, callerClass);
|
||||
LambdaForm lform = preparedLambdaForm(member);
|
||||
return new DirectMethodHandle(mtype, lform, member);
|
||||
}
|
||||
}
|
||||
@ -165,11 +172,16 @@ class DirectMethodHandle extends MethodHandle {
|
||||
* Cache and share this structure among all methods with
|
||||
* the same basicType and refKind.
|
||||
*/
|
||||
private static LambdaForm preparedLambdaForm(MemberName m, Class<?> callerClass) {
|
||||
private static LambdaForm preparedLambdaForm(MemberName m, boolean adaptToSpecialIfc) {
|
||||
assert(m.isInvocable()) : m; // call preparedFieldLambdaForm instead
|
||||
MethodType mtype = m.getInvocationType().basicType();
|
||||
assert(!m.isMethodHandleInvoke()) : m;
|
||||
int which;
|
||||
// MemberName.getReferenceKind represents the JVM optimized form of the call
|
||||
// as distinct from the "kind" passed to DMH.make which represents the original
|
||||
// bytecode-equivalent request. Specifically private/final methods that use a direct
|
||||
// call have getReferenceKind adapted to REF_invokeSpecial, even though the actual
|
||||
// invocation mode may be invokevirtual or invokeinterface.
|
||||
switch (m.getReferenceKind()) {
|
||||
case REF_invokeVirtual: which = LF_INVVIRTUAL; break;
|
||||
case REF_invokeStatic: which = LF_INVSTATIC; break;
|
||||
@ -183,7 +195,7 @@ class DirectMethodHandle extends MethodHandle {
|
||||
preparedLambdaForm(mtype, which);
|
||||
which = LF_INVSTATIC_INIT;
|
||||
}
|
||||
if (which == LF_INVSPECIAL && callerClass != null && callerClass.isInterface()) {
|
||||
if (which == LF_INVSPECIAL && adaptToSpecialIfc) {
|
||||
which = LF_INVSPECIAL_IFC;
|
||||
}
|
||||
LambdaForm lform = preparedLambdaForm(mtype, which);
|
||||
@ -195,7 +207,7 @@ class DirectMethodHandle extends MethodHandle {
|
||||
}
|
||||
|
||||
private static LambdaForm preparedLambdaForm(MemberName m) {
|
||||
return preparedLambdaForm(m, null);
|
||||
return preparedLambdaForm(m, false);
|
||||
}
|
||||
|
||||
private static LambdaForm preparedLambdaForm(MethodType mtype, int which) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -250,6 +250,9 @@ import static java.lang.invoke.MethodHandleStatics.*;
|
||||
* can also be created. These do not perform virtual lookup based on
|
||||
* receiver type. Such a method handle simulates the effect of
|
||||
* an {@code invokespecial} instruction to the same method.
|
||||
* A non-virtual method handle can also be created to simulate the effect
|
||||
* of an {@code invokevirtual} or {@code invokeinterface} instruction on
|
||||
* a private method (as applicable).
|
||||
*
|
||||
* <h1>Usage examples</h1>
|
||||
* Here are some examples of usage:
|
||||
|
@ -469,15 +469,20 @@ public class MethodHandles {
|
||||
* methods as if they were normal methods, but the JVM bytecode verifier rejects them.
|
||||
* A lookup of such an internal method will produce a {@code NoSuchMethodException}.
|
||||
* <p>
|
||||
* In some cases, access between nested classes is obtained by the Java compiler by creating
|
||||
* an wrapper method to access a private method of another class
|
||||
* in the same top-level declaration.
|
||||
* If the relationship between nested types is expressed directly through the
|
||||
* {@code NestHost} and {@code NestMembers} attributes
|
||||
* (see the Java Virtual Machine Specification, sections 4.7.28 and 4.7.29),
|
||||
* then the associated {@code Lookup} object provides direct access to
|
||||
* the lookup class and all of its nestmates
|
||||
* (see {@link java.lang.Class#getNestHost Class.getNestHost}).
|
||||
* Otherwise, access between nested classes is obtained by the Java compiler creating
|
||||
* a wrapper method to access a private method of another class in the same nest.
|
||||
* For example, a nested class {@code C.D}
|
||||
* can access private members within other related classes such as
|
||||
* {@code C}, {@code C.D.E}, or {@code C.B},
|
||||
* but the Java compiler may need to generate wrapper methods in
|
||||
* those related classes. In such cases, a {@code Lookup} object on
|
||||
* {@code C.E} would be unable to those private members.
|
||||
* {@code C.E} would be unable to access those private members.
|
||||
* A workaround for this limitation is the {@link Lookup#in Lookup.in} method,
|
||||
* which can transform a lookup on {@code C.E} into one on any of those other
|
||||
* classes, without special elevation of privilege.
|
||||
@ -499,11 +504,12 @@ public class MethodHandles {
|
||||
* <em>Discussion of private access:</em>
|
||||
* We say that a lookup has <em>private access</em>
|
||||
* if its {@linkplain #lookupModes lookup modes}
|
||||
* include the possibility of accessing {@code private} members.
|
||||
* include the possibility of accessing {@code private} members
|
||||
* (which includes the private members of nestmates).
|
||||
* As documented in the relevant methods elsewhere,
|
||||
* only lookups with private access possess the following capabilities:
|
||||
* <ul style="font-size:smaller;">
|
||||
* <li>access private fields, methods, and constructors of the lookup class
|
||||
* <li>access private fields, methods, and constructors of the lookup class and its nestmates
|
||||
* <li>create method handles which invoke <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a> methods,
|
||||
* such as {@code Class.forName}
|
||||
* <li>create method handles which {@link Lookup#findSpecial emulate invokespecial} instructions
|
||||
@ -728,9 +734,7 @@ public class MethodHandles {
|
||||
* <p>
|
||||
* A freshly-created lookup object
|
||||
* on the {@linkplain java.lang.invoke.MethodHandles#lookup() caller's class} has
|
||||
* all possible bits set, except {@code UNCONDITIONAL}. The lookup can be used to
|
||||
* access all members of the caller's class, all public types in the caller's module,
|
||||
* and all public types in packages exported by other modules to the caller's module.
|
||||
* all possible bits set, except {@code UNCONDITIONAL}.
|
||||
* A lookup object on a new lookup class
|
||||
* {@linkplain java.lang.invoke.MethodHandles.Lookup#in created from a previous lookup object}
|
||||
* may have some mode bits set to zero.
|
||||
@ -1106,8 +1110,9 @@ assertEquals("[x, y]", MH_asList.invoke("x", "y").toString());
|
||||
* The method and all its argument types must be accessible to the lookup object.
|
||||
* <p>
|
||||
* When called, the handle will treat the first argument as a receiver
|
||||
* and dispatch on the receiver's type to determine which method
|
||||
* and, for non-private methods, dispatch on the receiver's type to determine which method
|
||||
* implementation to enter.
|
||||
* For private methods the named method in {@code refc} will be invoked on the receiver.
|
||||
* (The dispatching action is identical with that performed by an
|
||||
* {@code invokevirtual} or {@code invokeinterface} instruction.)
|
||||
* <p>
|
||||
@ -1171,7 +1176,6 @@ assertEquals("", (String) MH_newString.invokeExact());
|
||||
* @throws NoSuchMethodException if the method does not exist
|
||||
* @throws IllegalAccessException if access checking fails,
|
||||
* or if the method is {@code static},
|
||||
* or if the method is {@code private} method of interface,
|
||||
* or if the method's variable arity modifier bit
|
||||
* is set and {@code asVarargsCollector} fails
|
||||
* @exception SecurityException if a security manager is present and it
|
||||
@ -2225,17 +2229,13 @@ return mh1;
|
||||
return "member is private to package";
|
||||
}
|
||||
|
||||
private static final boolean ALLOW_NESTMATE_ACCESS = false;
|
||||
|
||||
private void checkSpecialCaller(Class<?> specialCaller, Class<?> refc) throws IllegalAccessException {
|
||||
int allowedModes = this.allowedModes;
|
||||
if (allowedModes == TRUSTED) return;
|
||||
if (!hasPrivateAccess()
|
||||
|| (specialCaller != lookupClass()
|
||||
// ensure non-abstract methods in superinterfaces can be special-invoked
|
||||
&& !(refc != null && refc.isInterface() && refc.isAssignableFrom(specialCaller))
|
||||
&& !(ALLOW_NESTMATE_ACCESS &&
|
||||
VerifyAccess.isSamePackageMember(specialCaller, lookupClass()))))
|
||||
&& !(refc != null && refc.isInterface() && refc.isAssignableFrom(specialCaller))))
|
||||
throw new MemberName(specialCaller).
|
||||
makeAccessException("no private access for invokespecial", this);
|
||||
}
|
||||
@ -2246,9 +2246,7 @@ return mh1;
|
||||
if (!method.isProtected() || method.isStatic()
|
||||
|| allowedModes == TRUSTED
|
||||
|| method.getDeclaringClass() == lookupClass()
|
||||
|| VerifyAccess.isSamePackage(method.getDeclaringClass(), lookupClass())
|
||||
|| (ALLOW_NESTMATE_ACCESS &&
|
||||
VerifyAccess.isSamePackageMember(method.getDeclaringClass(), lookupClass())))
|
||||
|| VerifyAccess.isSamePackage(method.getDeclaringClass(), lookupClass()))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@ -2288,6 +2286,7 @@ return mh1;
|
||||
private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method,
|
||||
boolean checkSecurity,
|
||||
boolean doRestrict, Class<?> boundCallerClass) throws IllegalAccessException {
|
||||
|
||||
checkMethod(refKind, refc, method);
|
||||
// Optionally check with the security manager; this isn't needed for unreflect* calls.
|
||||
if (checkSecurity)
|
||||
@ -2300,6 +2299,7 @@ return mh1;
|
||||
refc != lookupClass().getSuperclass() &&
|
||||
refc.isAssignableFrom(lookupClass())) {
|
||||
assert(!method.getName().equals("<init>")); // not this code path
|
||||
|
||||
// Per JVMS 6.5, desc. of invokespecial instruction:
|
||||
// If the method is in a superclass of the LC,
|
||||
// and if our original search was above LC.super,
|
||||
|
@ -47,7 +47,7 @@ import sun.security.util.SecurityConstants;
|
||||
* in a manner that would normally be prohibited.
|
||||
*
|
||||
* <p> Java language access control prevents use of private members outside
|
||||
* their class; package access members outside their package; protected members
|
||||
* their top-level class; package access members outside their package; protected members
|
||||
* outside their package or subclasses; and public members outside their
|
||||
* module unless they are declared in an {@link Module#isExported(String,Module)
|
||||
* exported} package and the user {@link Module#canRead reads} their module. By
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -505,8 +505,8 @@ public final class Method extends Executable {
|
||||
*
|
||||
* <p>If the underlying method is an instance method, it is invoked
|
||||
* using dynamic method lookup as documented in The Java Language
|
||||
* Specification, Second Edition, section 15.12.4.4; in particular,
|
||||
* overriding based on the runtime type of the target object will occur.
|
||||
* Specification, section 15.12.4.4; in particular,
|
||||
* overriding based on the runtime type of the target object may occur.
|
||||
*
|
||||
* <p>If the underlying method is static, the class that declared
|
||||
* the method is initialized if it has not already been initialized.
|
||||
|
@ -58,6 +58,8 @@
|
||||
*/
|
||||
package jdk.internal.org.objectweb.asm;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* A non standard class, field, method or code attribute.
|
||||
*
|
||||
@ -281,4 +283,72 @@ public class Attribute {
|
||||
attr = attr.next;
|
||||
}
|
||||
}
|
||||
|
||||
//The stuff below is temporary - once proper support for nestmate attribute has been added, it can be safely removed.
|
||||
//see also changes in ClassReader.accept.
|
||||
|
||||
public static class NestMembers extends Attribute {
|
||||
public NestMembers() {
|
||||
super("NestMembers");
|
||||
}
|
||||
|
||||
byte[] bytes;
|
||||
String[] classes;
|
||||
|
||||
@Override
|
||||
protected Attribute read(ClassReader cr, int off, int len, char[] buf, int codeOff, Label[] labels) {
|
||||
int offset = off;
|
||||
NestMembers a = new NestMembers();
|
||||
int size = cr.readShort(off);
|
||||
a.classes = new String[size];
|
||||
off += 2;
|
||||
for (int i = 0; i < size ; i++) {
|
||||
a.classes[i] = cr.readClass(off, buf);
|
||||
off += 2;
|
||||
}
|
||||
a.bytes = Arrays.copyOfRange(cr.b, offset, offset + len);
|
||||
return a;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ByteVector write(ClassWriter cw, byte[] code, int len, int maxStack, int maxLocals) {
|
||||
ByteVector v = new ByteVector(bytes.length);
|
||||
v.putShort(classes.length);
|
||||
for (String s : classes) {
|
||||
v.putShort(cw.newClass(s));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
public static class NestHost extends Attribute {
|
||||
|
||||
byte[] bytes;
|
||||
String clazz;
|
||||
|
||||
public NestHost() {
|
||||
super("NestHost");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Attribute read(ClassReader cr, int off, int len, char[] buf, int codeOff, Label[] labels) {
|
||||
int offset = off;
|
||||
NestHost a = new NestHost();
|
||||
a.clazz = cr.readClass(off, buf);
|
||||
a.bytes = Arrays.copyOfRange(cr.b, offset, offset + len);
|
||||
return a;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ByteVector write(ClassWriter cw, byte[] code, int len, int maxStack, int maxLocals) {
|
||||
ByteVector v = new ByteVector(bytes.length);
|
||||
v.putShort(cw.newClass(clazz));
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
static final Attribute[] DEFAULT_ATTRIBUTE_PROTOS = new Attribute[] {
|
||||
new NestMembers(),
|
||||
new NestHost()
|
||||
};
|
||||
}
|
||||
|
@ -530,7 +530,7 @@ public class ClassReader {
|
||||
* , {@link #SKIP_FRAMES}, {@link #SKIP_CODE}.
|
||||
*/
|
||||
public void accept(final ClassVisitor classVisitor, final int flags) {
|
||||
accept(classVisitor, new Attribute[0], flags);
|
||||
accept(classVisitor, Attribute.DEFAULT_ATTRIBUTE_PROTOS, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -629,14 +629,10 @@ class MethodAccessorGenerator extends AccessorGenerator {
|
||||
typeSizeInStackSlots(returnType));
|
||||
} else {
|
||||
if (isInterface()) {
|
||||
if (isPrivate()) {
|
||||
cb.opc_invokespecial(targetMethodRef, count, 0);
|
||||
} else {
|
||||
cb.opc_invokeinterface(targetMethodRef,
|
||||
count,
|
||||
count,
|
||||
typeSizeInStackSlots(returnType));
|
||||
}
|
||||
cb.opc_invokeinterface(targetMethodRef,
|
||||
count,
|
||||
count,
|
||||
typeSizeInStackSlots(returnType));
|
||||
} else {
|
||||
cb.opc_invokevirtual(targetMethodRef,
|
||||
count,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -143,6 +143,15 @@ public class Reflection {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for nestmate access if member is private
|
||||
if (Modifier.isPrivate(modifiers)) {
|
||||
// Note: targetClass may be outside the nest, but that is okay
|
||||
// as long as memberClass is in the nest.
|
||||
if (areNestMates(currentClass, memberClass)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
boolean successSoFar = false;
|
||||
|
||||
if (Modifier.isProtected(modifiers)) {
|
||||
@ -351,4 +360,12 @@ public class Reflection {
|
||||
|
||||
return new IllegalAccessException(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if {@code currentClass} and {@code memberClass}
|
||||
* are nestmates - that is, if they have the same nesthost as
|
||||
* determined by the VM.
|
||||
*/
|
||||
public static native boolean areNestMates(Class<?> currentClass,
|
||||
Class<?> memberClass);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -44,7 +44,6 @@ public class VerifyAccess {
|
||||
private static final int PACKAGE_ALLOWED = java.lang.invoke.MethodHandles.Lookup.PACKAGE;
|
||||
private static final int PROTECTED_OR_PACKAGE_ALLOWED = (PACKAGE_ALLOWED|PROTECTED);
|
||||
private static final int ALL_ACCESS_MODES = (PUBLIC|PRIVATE|PROTECTED|PACKAGE_ONLY);
|
||||
private static final boolean ALLOW_NESTMATE_ACCESS = false;
|
||||
|
||||
/**
|
||||
* Evaluate the JVM linkage rules for access to the given method
|
||||
@ -62,23 +61,29 @@ public class VerifyAccess {
|
||||
* the defining class should be passed for both arguments ({@code defc == refc}).
|
||||
* <h3>JVM Specification, 5.4.4 "Access Control"</h3>
|
||||
* A field or method R is accessible to a class or interface D if
|
||||
* and only if any of the following conditions is true:<ul>
|
||||
* <li>R is public.
|
||||
* and only if any of the following is true:
|
||||
* <ul>
|
||||
* <li>R is public.</li>
|
||||
* <li>R is protected and is declared in a class C, and D is either
|
||||
* a subclass of C or C itself. Furthermore, if R is not
|
||||
* static, then the symbolic reference to R must contain a
|
||||
* symbolic reference to a class T, such that T is either a
|
||||
* subclass of D, a superclass of D or D itself.
|
||||
* <li>R is either protected or has default access (that is,
|
||||
* neither public nor protected nor private), and is declared
|
||||
* by a class in the same runtime package as D.
|
||||
* <li>R is private and is declared in D.
|
||||
* a subclass of C or C itself. Furthermore, if R is not static,
|
||||
* then the symbolic reference to R must contain a symbolic
|
||||
* reference to a class T, such that T is either a subclass of D,
|
||||
* a superclass of D, or D itself.
|
||||
* <p>During verification, it was also required that, even if T is
|
||||
* a superclass of D, the target reference of a protected instance
|
||||
* field access or method invocation must be an instance of D or a
|
||||
* subclass of D (4.10.1.8).</p></li>
|
||||
* <li>R is either protected or has default access (that is, neither
|
||||
* public nor protected nor private), and is declared by a class
|
||||
* in the same run-time package as D.</li>
|
||||
* <li>R is private and is declared in D by a class or interface
|
||||
* belonging to the same nest as D.</li>
|
||||
* </ul>
|
||||
* This discussion of access control omits a related restriction
|
||||
* on the target of a protected field access or method invocation
|
||||
* (the target must be of class D or a subtype of D). That
|
||||
* requirement is checked as part of the verification process
|
||||
* (5.4.1); it is not part of link-time access control.
|
||||
* If a referenced field or method is not accessible, access checking
|
||||
* throws an IllegalAccessError. If an exception is thrown while
|
||||
* attempting to determine the nest host of a class or interface,
|
||||
* access checking fails for the same reason.
|
||||
*
|
||||
* @param refc the class used in the symbolic reference to the proposed member
|
||||
* @param defc the class in which the proposed member is actually defined
|
||||
* @param mods modifier flags for the proposed member
|
||||
@ -98,9 +103,10 @@ public class VerifyAccess {
|
||||
return false;
|
||||
}
|
||||
// Usually refc and defc are the same, but verify defc also in case they differ.
|
||||
if (defc == lookupClass &&
|
||||
if (defc == lookupClass &&
|
||||
(allowedModes & PRIVATE) != 0)
|
||||
return true; // easy check; all self-access is OK
|
||||
return true; // easy check; all self-access is OK with a private lookup
|
||||
|
||||
switch (mods & ALL_ACCESS_MODES) {
|
||||
case PUBLIC:
|
||||
return true; // already checked above
|
||||
@ -126,10 +132,13 @@ public class VerifyAccess {
|
||||
return ((allowedModes & PACKAGE_ALLOWED) != 0 &&
|
||||
isSamePackage(defc, lookupClass));
|
||||
case PRIVATE:
|
||||
// Loosened rules for privates follows access rules for inner classes.
|
||||
return (ALLOW_NESTMATE_ACCESS &&
|
||||
(allowedModes & PRIVATE) != 0 &&
|
||||
isSamePackageMember(defc, lookupClass));
|
||||
// Rules for privates follows access rules for nestmates.
|
||||
boolean canAccess = ((allowedModes & PRIVATE) != 0 &&
|
||||
Reflection.areNestMates(defc, lookupClass));
|
||||
// for private methods the selected method equals the
|
||||
// resolved method - so refc == defc
|
||||
assert (canAccess && refc == defc) || !canAccess;
|
||||
return canAccess;
|
||||
default:
|
||||
throw new IllegalArgumentException("bad modifiers: "+Modifier.toString(mods));
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1994, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -65,15 +65,17 @@ static JNINativeMethod methods[] = {
|
||||
{"getDeclaredMethods0","(Z)[" MHD, (void *)&JVM_GetClassDeclaredMethods},
|
||||
{"getDeclaredConstructors0","(Z)[" CTR, (void *)&JVM_GetClassDeclaredConstructors},
|
||||
{"getProtectionDomain0", "()" PD, (void *)&JVM_GetProtectionDomain},
|
||||
{"getDeclaredClasses0", "()[" CLS, (void *)&JVM_GetDeclaredClasses},
|
||||
{"getDeclaredClasses0", "()[" CLS, (void *)&JVM_GetDeclaredClasses},
|
||||
{"getDeclaringClass0", "()" CLS, (void *)&JVM_GetDeclaringClass},
|
||||
{"getSimpleBinaryName0", "()" STR, (void *)&JVM_GetSimpleBinaryName},
|
||||
{"getGenericSignature0", "()" STR, (void *)&JVM_GetClassSignature},
|
||||
{"getRawAnnotations", "()" BA, (void *)&JVM_GetClassAnnotations},
|
||||
{"getRawAnnotations", "()" BA, (void *)&JVM_GetClassAnnotations},
|
||||
{"getConstantPool", "()" CPL, (void *)&JVM_GetClassConstantPool},
|
||||
{"desiredAssertionStatus0","("CLS")Z",(void *)&JVM_DesiredAssertionStatus},
|
||||
{"desiredAssertionStatus0","("CLS")Z", (void *)&JVM_DesiredAssertionStatus},
|
||||
{"getEnclosingMethod0", "()[" OBJ, (void *)&JVM_GetEnclosingMethodInfo},
|
||||
{"getRawTypeAnnotations", "()" BA, (void *)&JVM_GetClassTypeAnnotations},
|
||||
{"getNestHost0", "()" CLS, (void *)&JVM_GetNestHost},
|
||||
{"getNestMembers0", "()[" CLS, (void *)&JVM_GetNestMembers},
|
||||
};
|
||||
|
||||
#undef OBJ
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -38,3 +38,9 @@ Java_jdk_internal_reflect_Reflection_getClassAccessFlags(JNIEnv *env, jclass unu
|
||||
{
|
||||
return JVM_GetClassAccessFlags(env, cls);
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_jdk_internal_reflect_Reflection_areNestMates(JNIEnv *env, jclass unused, jclass current, jclass member)
|
||||
{
|
||||
return JVM_AreNestMates(env, current, member);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -219,10 +219,14 @@ public interface Instrumentation {
|
||||
* Instances of the retransformed class are not affected.
|
||||
*
|
||||
* <P>
|
||||
* The retransformation may change method bodies, the constant pool and attributes.
|
||||
* The retransformation may change method bodies, the constant pool and
|
||||
* attributes (unless explicitly prohibited).
|
||||
* The retransformation must not add, remove or rename fields or methods, change the
|
||||
* signatures of methods, or change inheritance. These restrictions maybe be
|
||||
* lifted in future versions. The class file bytes are not checked, verified and installed
|
||||
* signatures of methods, or change inheritance.
|
||||
* The retransformation must not change the <code>NestHost</code> or
|
||||
* <code>NestMembers</code> attributes.
|
||||
* These restrictions may be lifted in future versions.
|
||||
* The class file bytes are not checked, verified and installed
|
||||
* until after the transformations have been applied, if the resultant bytes are in
|
||||
* error this method will throw an exception.
|
||||
*
|
||||
@ -306,10 +310,14 @@ public interface Instrumentation {
|
||||
* Instances of the redefined class are not affected.
|
||||
*
|
||||
* <P>
|
||||
* The redefinition may change method bodies, the constant pool and attributes.
|
||||
* The redefinition may change method bodies, the constant pool and attributes
|
||||
* (unless explicitly prohibited).
|
||||
* The redefinition must not add, remove or rename fields or methods, change the
|
||||
* signatures of methods, or change inheritance. These restrictions maybe be
|
||||
* lifted in future versions. The class file bytes are not checked, verified and installed
|
||||
* signatures of methods, or change inheritance.
|
||||
* The redefinition must not change the <code>NestHost</code> or
|
||||
* <code>NestMembers</code> attributes.
|
||||
* These restrictions may be lifted in future versions.
|
||||
* The class file bytes are not checked, verified and installed
|
||||
* until after the transformations have been applied, if the resultant bytes are in
|
||||
* error this method will throw an exception.
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -214,6 +214,11 @@ createThrowableFromJVMTIErrorCode(JNIEnv * jnienv, jvmtiError errorCode) {
|
||||
message = "class redefinition failed: attempted to change the class modifiers";
|
||||
break;
|
||||
|
||||
case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED:
|
||||
throwableClassName = "java/lang/UnsupportedOperationException";
|
||||
message = "class redefinition failed: attempted to change the class NestHost or NestMembers attribute";
|
||||
break;
|
||||
|
||||
case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
|
||||
throwableClassName = "java/lang/UnsupportedOperationException";
|
||||
message = "class redefinition failed: attempted to change method modifiers";
|
||||
|
@ -94,6 +94,7 @@ public class Lower extends TreeTranslator {
|
||||
private final Name dollarCloseResource;
|
||||
private final Types types;
|
||||
private final boolean debugLower;
|
||||
private final boolean disableProtectedAccessors; // experimental
|
||||
private final PkgInfo pkginfoOpt;
|
||||
|
||||
protected Lower(Context context) {
|
||||
@ -122,6 +123,7 @@ public class Lower extends TreeTranslator {
|
||||
Options options = Options.instance(context);
|
||||
debugLower = options.isSet("debuglower");
|
||||
pkginfoOpt = PkgInfo.get(options);
|
||||
disableProtectedAccessors = options.isSet("disableProtectedAccessors");
|
||||
}
|
||||
|
||||
/** The currently enclosing class.
|
||||
@ -1031,6 +1033,9 @@ public class Lower extends TreeTranslator {
|
||||
/** Do we need an access method to reference private symbol?
|
||||
*/
|
||||
boolean needsPrivateAccess(Symbol sym) {
|
||||
if (target.hasNestmateAccess()) {
|
||||
return false;
|
||||
}
|
||||
if ((sym.flags() & PRIVATE) == 0 || sym.owner == currentClass) {
|
||||
return false;
|
||||
} else if (sym.name == names.init && sym.owner.isLocal()) {
|
||||
@ -1045,6 +1050,7 @@ public class Lower extends TreeTranslator {
|
||||
/** Do we need an access method to reference symbol in other package?
|
||||
*/
|
||||
boolean needsProtectedAccess(Symbol sym, JCTree tree) {
|
||||
if (disableProtectedAccessors) return false;
|
||||
if ((sym.flags() & PROTECTED) == 0 ||
|
||||
sym.owner.owner == currentClass.owner || // fast special case
|
||||
sym.packge() == currentClass.packge())
|
||||
|
@ -31,6 +31,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.tools.JavaFileManager;
|
||||
import javax.tools.FileObject;
|
||||
@ -1106,6 +1107,56 @@ public class ClassWriter extends ClassFile {
|
||||
endAttr(alenIdx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write NestMembers attribute (if needed)
|
||||
*/
|
||||
int writeNestMembersIfNeeded(ClassSymbol csym) {
|
||||
ListBuffer<Symbol> nested = new ListBuffer<>();
|
||||
listNested(csym, nested);
|
||||
Set<Symbol> nestedUnique = new LinkedHashSet<>(nested);
|
||||
if (csym.owner.kind == PCK && !nestedUnique.isEmpty()) {
|
||||
int alenIdx = writeAttr(names.NestMembers);
|
||||
databuf.appendChar(nestedUnique.size());
|
||||
for (Symbol s : nestedUnique) {
|
||||
databuf.appendChar(pool.put(s));
|
||||
}
|
||||
endAttr(alenIdx);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write NestHost attribute (if needed)
|
||||
*/
|
||||
int writeNestHostIfNeeded(ClassSymbol csym) {
|
||||
if (csym.owner.kind != PCK) {
|
||||
int alenIdx = writeAttr(names.NestHost);
|
||||
databuf.appendChar(pool.put(csym.outermostClass()));
|
||||
endAttr(alenIdx);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void listNested(Symbol sym, ListBuffer<Symbol> seen) {
|
||||
if (sym.kind != TYP) return;
|
||||
ClassSymbol csym = (ClassSymbol)sym;
|
||||
if (csym.owner.kind != PCK) {
|
||||
seen.add(csym);
|
||||
}
|
||||
if (csym.members() != null) {
|
||||
for (Symbol s : sym.members().getSymbols()) {
|
||||
listNested(s, seen);
|
||||
}
|
||||
}
|
||||
if (csym.trans_local != null) {
|
||||
for (Symbol s : csym.trans_local) {
|
||||
listNested(s, seen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Write "bootstrapMethods" attribute.
|
||||
*/
|
||||
void writeBootstrapMethods() {
|
||||
@ -1835,6 +1886,13 @@ public class ClassWriter extends ClassFile {
|
||||
}
|
||||
poolbuf.appendChar(target.majorVersion);
|
||||
|
||||
if (c.owner.kind != MDL) {
|
||||
if (target.hasNestmateAccess()) {
|
||||
acount += writeNestMembersIfNeeded(c);
|
||||
acount += writeNestHostIfNeeded(c);
|
||||
}
|
||||
}
|
||||
|
||||
writePool(c.pool);
|
||||
|
||||
if (innerClasses != null) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -126,6 +126,7 @@ public class Gen extends JCTree.Visitor {
|
||||
genCrt = options.isSet(XJCOV);
|
||||
debugCode = options.isSet("debug.code");
|
||||
allowBetterNullChecks = target.hasObjects();
|
||||
disableVirtualizedPrivateInvoke = options.isSet("disableVirtualizedPrivateInvoke");
|
||||
pool = new Pool(types);
|
||||
|
||||
// ignore cldc because we cannot have both stackmap formats
|
||||
@ -140,6 +141,7 @@ public class Gen extends JCTree.Visitor {
|
||||
private final boolean genCrt;
|
||||
private final boolean debugCode;
|
||||
private final boolean allowBetterNullChecks;
|
||||
private boolean disableVirtualizedPrivateInvoke;
|
||||
|
||||
/** Code buffer, set by genMethod.
|
||||
*/
|
||||
@ -2064,10 +2066,17 @@ public class Gen extends JCTree.Visitor {
|
||||
} else {
|
||||
items.makeThisItem().load();
|
||||
sym = binaryQualifier(sym, env.enclClass.type);
|
||||
result = items.makeMemberItem(sym, (sym.flags() & PRIVATE) != 0);
|
||||
result = items.makeMemberItem(sym, nonVirtualForPrivateAccess(sym));
|
||||
}
|
||||
}
|
||||
|
||||
//where
|
||||
private boolean nonVirtualForPrivateAccess(Symbol sym) {
|
||||
boolean useVirtual = target.hasVirtualPrivateInvoke() &&
|
||||
!disableVirtualizedPrivateInvoke;
|
||||
return !useVirtual && ((sym.flags() & PRIVATE) != 0);
|
||||
}
|
||||
|
||||
public void visitSelect(JCFieldAccess tree) {
|
||||
Symbol sym = tree.sym;
|
||||
|
||||
@ -2124,7 +2133,7 @@ public class Gen extends JCTree.Visitor {
|
||||
} else {
|
||||
result = items.
|
||||
makeMemberItem(sym,
|
||||
(sym.flags() & PRIVATE) != 0 ||
|
||||
nonVirtualForPrivateAccess(sym) ||
|
||||
selectSuper || accessSuper);
|
||||
}
|
||||
}
|
||||
|
@ -160,4 +160,17 @@ public enum Target {
|
||||
public String multiReleaseValue() {
|
||||
return Integer.toString(this.ordinal() - Target.JDK1_1.ordinal() + 1);
|
||||
}
|
||||
|
||||
/** Does the target VM support nestmate access?
|
||||
*/
|
||||
public boolean hasNestmateAccess() {
|
||||
return compareTo(JDK1_11) >= 0;
|
||||
}
|
||||
|
||||
/** Does the target VM support virtual private invocations?
|
||||
*/
|
||||
public boolean hasVirtualPrivateInvoke() {
|
||||
return compareTo(JDK1_11) >= 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -152,6 +152,8 @@ public class Names {
|
||||
public final Name MethodParameters;
|
||||
public final Name Module;
|
||||
public final Name ModuleResolution;
|
||||
public final Name NestHost;
|
||||
public final Name NestMembers;
|
||||
public final Name RuntimeInvisibleAnnotations;
|
||||
public final Name RuntimeInvisibleParameterAnnotations;
|
||||
public final Name RuntimeInvisibleTypeAnnotations;
|
||||
@ -315,6 +317,8 @@ public class Names {
|
||||
MethodParameters = fromString("MethodParameters");
|
||||
Module = fromString("Module");
|
||||
ModuleResolution = fromString("ModuleResolution");
|
||||
NestHost = fromString("NestHost");
|
||||
NestMembers = fromString("NestMembers");
|
||||
RuntimeInvisibleAnnotations = fromString("RuntimeInvisibleAnnotations");
|
||||
RuntimeInvisibleParameterAnnotations = fromString("RuntimeInvisibleParameterAnnotations");
|
||||
RuntimeInvisibleTypeAnnotations = fromString("RuntimeInvisibleTypeAnnotations");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -58,6 +58,8 @@ public abstract class Attribute {
|
||||
public static final String ModulePackages = "ModulePackages";
|
||||
public static final String ModuleResolution = "ModuleResolution";
|
||||
public static final String ModuleTarget = "ModuleTarget";
|
||||
public static final String NestHost = "NestHost";
|
||||
public static final String NestMembers = "NestMembers";
|
||||
public static final String RuntimeVisibleAnnotations = "RuntimeVisibleAnnotations";
|
||||
public static final String RuntimeInvisibleAnnotations = "RuntimeInvisibleAnnotations";
|
||||
public static final String RuntimeVisibleParameterAnnotations = "RuntimeVisibleParameterAnnotations";
|
||||
@ -130,6 +132,8 @@ public abstract class Attribute {
|
||||
standardAttributes.put(ModulePackages, ModulePackages_attribute.class);
|
||||
standardAttributes.put(ModuleResolution, ModuleResolution_attribute.class);
|
||||
standardAttributes.put(ModuleTarget, ModuleTarget_attribute.class);
|
||||
standardAttributes.put(NestHost, NestHost_attribute.class);
|
||||
standardAttributes.put(NestMembers, NestMembers_attribute.class);
|
||||
standardAttributes.put(RuntimeInvisibleAnnotations, RuntimeInvisibleAnnotations_attribute.class);
|
||||
standardAttributes.put(RuntimeInvisibleParameterAnnotations, RuntimeInvisibleParameterAnnotations_attribute.class);
|
||||
standardAttributes.put(RuntimeVisibleAnnotations, RuntimeVisibleAnnotations_attribute.class);
|
||||
@ -193,6 +197,8 @@ public abstract class Attribute {
|
||||
R visitModulePackages(ModulePackages_attribute attr, P p);
|
||||
R visitModuleResolution(ModuleResolution_attribute attr, P p);
|
||||
R visitModuleTarget(ModuleTarget_attribute attr, P p);
|
||||
R visitNestHost(NestHost_attribute attr, P p);
|
||||
R visitNestMembers(NestMembers_attribute attr, P p);
|
||||
R visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, P p);
|
||||
R visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, P p);
|
||||
R visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, P p);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -528,6 +528,12 @@ public class ClassWriter {
|
||||
out.writeShort(entry.index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitNestHost(NestHost_attribute attr, ClassOutputStream out) {
|
||||
out.writeShort(attr.top_index);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitMethodParameters(MethodParameters_attribute attr, ClassOutputStream out) {
|
||||
out.writeByte(attr.method_parameter_table.length);
|
||||
@ -626,6 +632,15 @@ public class ClassWriter {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitNestMembers(NestMembers_attribute attr, ClassOutputStream out) {
|
||||
out.writeShort(attr.members_indexes.length);
|
||||
for (int i : attr.members_indexes) {
|
||||
out.writeShort(i);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, ClassOutputStream out) {
|
||||
annotationWriter.write(attr.annotations, out);
|
||||
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.classfile;
|
||||
|
||||
import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class NestHost_attribute extends Attribute {
|
||||
NestHost_attribute(ClassReader cr, int name_index, int length) throws IOException {
|
||||
super(name_index, length);
|
||||
top_index = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
public NestHost_attribute(ConstantPool constant_pool, int signature_index)
|
||||
throws ConstantPoolException {
|
||||
this(constant_pool.getUTF8Index(Attribute.Signature), signature_index);
|
||||
}
|
||||
|
||||
public NestHost_attribute(int name_index, int top_index) {
|
||||
super(name_index, 2);
|
||||
this.top_index = top_index;
|
||||
}
|
||||
|
||||
public CONSTANT_Class_info getNestTop(ConstantPool constant_pool) throws ConstantPoolException {
|
||||
return constant_pool.getClassInfo(top_index);
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitNestHost(this, data);
|
||||
}
|
||||
|
||||
public final int top_index;
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.classfile;
|
||||
|
||||
import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class NestMembers_attribute extends Attribute {
|
||||
NestMembers_attribute(ClassReader cr, int name_index, int length) throws IOException {
|
||||
super(name_index, length);
|
||||
int len = cr.readUnsignedShort();
|
||||
members_indexes = new int[len];
|
||||
for (int i = 0 ; i < len ; i++) {
|
||||
members_indexes[i] = cr.readUnsignedShort();
|
||||
}
|
||||
}
|
||||
|
||||
public NestMembers_attribute(int name_index, int[] members_indexes) {
|
||||
super(name_index, 2);
|
||||
this.members_indexes = members_indexes;
|
||||
}
|
||||
|
||||
public CONSTANT_Class_info[] getChildren(ConstantPool constant_pool) throws ConstantPoolException {
|
||||
return IntStream.of(members_indexes)
|
||||
.mapToObj(i -> {
|
||||
try {
|
||||
return constant_pool.getClassInfo(i);
|
||||
} catch (ConstantPoolException ex) {
|
||||
throw new AssertionError(ex);
|
||||
}
|
||||
}).toArray(CONSTANT_Class_info[]::new);
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitNestMembers(this, data);
|
||||
}
|
||||
|
||||
public final int[] members_indexes;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -35,6 +35,7 @@ import com.sun.tools.classfile.CharacterRangeTable_attribute.Entry;
|
||||
import com.sun.tools.classfile.Code_attribute;
|
||||
import com.sun.tools.classfile.CompilationID_attribute;
|
||||
import com.sun.tools.classfile.ConstantPool;
|
||||
import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info;
|
||||
import com.sun.tools.classfile.ConstantPoolException;
|
||||
import com.sun.tools.classfile.ConstantValue_attribute;
|
||||
import com.sun.tools.classfile.DefaultAttribute;
|
||||
@ -53,6 +54,8 @@ import com.sun.tools.classfile.ModuleMainClass_attribute;
|
||||
import com.sun.tools.classfile.ModulePackages_attribute;
|
||||
import com.sun.tools.classfile.ModuleResolution_attribute;
|
||||
import com.sun.tools.classfile.ModuleTarget_attribute;
|
||||
import com.sun.tools.classfile.NestHost_attribute;
|
||||
import com.sun.tools.classfile.NestMembers_attribute;
|
||||
import com.sun.tools.classfile.RuntimeInvisibleAnnotations_attribute;
|
||||
import com.sun.tools.classfile.RuntimeInvisibleParameterAnnotations_attribute;
|
||||
import com.sun.tools.classfile.RuntimeInvisibleTypeAnnotations_attribute;
|
||||
@ -397,6 +400,14 @@ public class AttributeWriter extends BasicWriter
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitNestHost(NestHost_attribute attr, Void aVoid) {
|
||||
print("NestHost: ");
|
||||
constantWriter.write(attr.top_index);
|
||||
println();
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getJavaClassName(ModuleMainClass_attribute a) {
|
||||
try {
|
||||
return getJavaName(a.getMainClassName(constant_pool));
|
||||
@ -686,6 +697,22 @@ public class AttributeWriter extends BasicWriter
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitNestMembers(NestMembers_attribute attr, Void aVoid) {
|
||||
println("NestMembers:");
|
||||
indent(+1);
|
||||
try {
|
||||
CONSTANT_Class_info[] children = attr.getChildren(constant_pool);
|
||||
for (int i = 0; i < attr.members_indexes.length; i++) {
|
||||
println(constantWriter.stringValue(children[i]));
|
||||
}
|
||||
indent(-1);
|
||||
} catch (ConstantPoolException ex) {
|
||||
throw new AssertionError(ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, Void ignore) {
|
||||
println("RuntimeVisibleAnnotations:");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -219,10 +219,11 @@ public interface VirtualMachine extends Mirror {
|
||||
* this exception
|
||||
* <UL>
|
||||
* <LI>changing the schema (the fields)
|
||||
* <LI>changing the hierarchy (subclasses, interfaces)
|
||||
* <LI>changing the hierarchy (superclasses, interfaces)
|
||||
* <LI>deleting a method
|
||||
* <LI>changing class modifiers
|
||||
* <LI>changing method modifiers
|
||||
* <LI>changing the {@code NestHost} or {@code NestMembers} class attributes
|
||||
* </UL>
|
||||
* </UL>
|
||||
*
|
||||
@ -595,8 +596,9 @@ public interface VirtualMachine extends Mirror {
|
||||
boolean canAddMethod();
|
||||
|
||||
/**
|
||||
* Determines if the target VM supports unrestricted
|
||||
* changes when performing class redefinition.
|
||||
* Determines if the target VM supports
|
||||
* changes when performing class redefinition that are
|
||||
* otherwise restricted by {@link #redefineClasses}.
|
||||
* @see #redefineClasses
|
||||
*
|
||||
* @return <code>true</code> if the feature is supported,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -395,6 +395,9 @@ class VirtualMachineImpl extends MirrorImpl
|
||||
case JDWP.Error.METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED :
|
||||
throw new UnsupportedOperationException(
|
||||
"changes to method modifiers not implemented");
|
||||
case JDWP.Error.CLASS_ATTRIBUTE_CHANGE_NOT_IMPLEMENTED :
|
||||
throw new UnsupportedOperationException(
|
||||
"changes to class attribute not implemented");
|
||||
case JDWP.Error.NAMES_DONT_MATCH :
|
||||
throw new NoClassDefFoundError(
|
||||
"class names do not match");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -52,7 +52,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManagerService {
|
||||
private final ThreadGroup mainGroupForJDI;
|
||||
private ResourceBundle messages = null;
|
||||
private int vmSequenceNumber = 0;
|
||||
private static final int majorVersion = 9;
|
||||
private static final int majorVersion = 11;
|
||||
private static final int minorVersion = 0;
|
||||
|
||||
private static final Object lock = new Object();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -35,7 +35,7 @@
|
||||
#include "FrameID.h"
|
||||
|
||||
static char *versionName = "Java Debug Wire Protocol (Reference Implementation)";
|
||||
static int majorVersion = 9; /* JDWP major version */
|
||||
static int majorVersion = 11; /* JDWP major version */
|
||||
static int minorVersion = 0; /* JDWP minor version */
|
||||
|
||||
static jboolean
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -285,6 +285,7 @@ jdwpErrorText(jdwpError serror)
|
||||
CASE_RETURN_JDWP_ERROR_TEXT(NAMES_DONT_MATCH)
|
||||
CASE_RETURN_JDWP_ERROR_TEXT(CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED)
|
||||
CASE_RETURN_JDWP_ERROR_TEXT(METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED)
|
||||
CASE_RETURN_JDWP_ERROR_TEXT(CLASS_ATTRIBUTE_CHANGE_NOT_IMPLEMENTED)
|
||||
CASE_RETURN_JDWP_ERROR_TEXT(NOT_IMPLEMENTED)
|
||||
CASE_RETURN_JDWP_ERROR_TEXT(NULL_POINTER)
|
||||
CASE_RETURN_JDWP_ERROR_TEXT(ABSENT_INFORMATION)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -1888,6 +1888,8 @@ map2jvmtiError(jdwpError error)
|
||||
return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED;
|
||||
case JDWP_ERROR(METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED):
|
||||
return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED;
|
||||
case JDWP_ERROR(CLASS_ATTRIBUTE_CHANGE_NOT_IMPLEMENTED):
|
||||
return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED;
|
||||
case JDWP_ERROR(NOT_IMPLEMENTED):
|
||||
return JVMTI_ERROR_NOT_AVAILABLE;
|
||||
case JDWP_ERROR(NULL_POINTER):
|
||||
@ -2220,6 +2222,8 @@ map2jdwpError(jvmtiError error)
|
||||
return JDWP_ERROR(CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED);
|
||||
case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
|
||||
return JDWP_ERROR(METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED);
|
||||
case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED:
|
||||
return JDWP_ERROR(CLASS_ATTRIBUTE_CHANGE_NOT_IMPLEMENTED);
|
||||
case AGENT_ERROR_NOT_CURRENT_FRAME:
|
||||
return JDWP_ERROR(NOT_CURRENT_FRAME);
|
||||
case AGENT_ERROR_INVALID_TAG:
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,8 +23,8 @@
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8025260 8016839
|
||||
* @summary Ensure that AbstractMethodError and IllegalAccessError are thrown appropriately, not NullPointerException
|
||||
* @bug 8025260 8016839 8046171
|
||||
* @summary Ensure that correct exceptions are thrown, not NullPointerException
|
||||
* @modules java.base/jdk.internal.org.objectweb.asm
|
||||
* @library / .
|
||||
*
|
||||
@ -34,6 +34,13 @@
|
||||
* @run main/othervm -Xcomp compiler.jsr292.methodHandleExceptions.TestAMEnotNPE
|
||||
*/
|
||||
|
||||
// Since this test was written the specification for interface method selection has been
|
||||
// revised (JEP 181 - Nestmates) so that private methods are never selected, as they never
|
||||
// override any inherited method. So where a private method was previously selected
|
||||
// and then resulted in IllegalAccessError, the private method is skipped and the invocation
|
||||
// will either succeed or fail based on what other implementations are found in the inheritance
|
||||
// hierarchy. This is explained for each test below.
|
||||
|
||||
package compiler.jsr292.methodHandleExceptions;
|
||||
|
||||
import p.Dok;
|
||||
@ -91,43 +98,41 @@ public class TestAMEnotNPE {
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
System.out.println("TRYING p.D.m PRIVATE interface-invoked as p.I.m, p.D extends p.F, p.F.m FINAL");
|
||||
tryAndCheckThrown(lt, bytesForDprivateSubWhat("p/F"),
|
||||
"p.D extends p.F (p.F implements p.I, FINAL public m), private m",
|
||||
IllegalAccessError.class, "pD_ext_pF");
|
||||
// We'll take either a VerifyError (pre 2013-11-30)
|
||||
// or an IllegalAccessError (post 2013-11-22)
|
||||
} catch (VerifyError ve) {
|
||||
System.out.println("Saw expected VerifyError " + ve);
|
||||
}
|
||||
System.out.println("TRYING p.D.m PRIVATE interface-invoked as p.I.m, p.D extends p.F, p.F.m FINAL");
|
||||
System.out.println(" - should invoke p.F.m as private p.D.m is skipped for selection");
|
||||
tryAndCheckThrown(lt, bytesForDprivateSubWhat("p/F"),
|
||||
"p.D extends p.F (p.F implements p.I, FINAL public m), private m",
|
||||
null /* should succeed */, "pD_ext_pF");
|
||||
System.out.println();
|
||||
|
||||
System.out.println("TRYING p.D.m PRIVATE interface-invoked as p.I.m, p.D extends p.E");
|
||||
System.out.println(" - should invoke p.E.m as private p.D.m is skipped for selection");
|
||||
tryAndCheckThrown(lt, bytesForDprivateSubWhat("p/E"),
|
||||
"p.D extends p.E (p.E implements p.I, public m), private m",
|
||||
IllegalAccessError.class, "pD_ext_pE");
|
||||
"p.D extends p.E (p.E implements p.I, public m), private m",
|
||||
null /* should succeed */, "pD_ext_pE");
|
||||
|
||||
System.out.println("TRYING p.D.m ABSTRACT interface-invoked as p.I.m");
|
||||
tryAndCheckThrown(lt, bytesForD(),
|
||||
"D extends abstract C, no m",
|
||||
AbstractMethodError.class, "pD_ext_pC");
|
||||
"D extends abstract C, no m",
|
||||
AbstractMethodError.class, "pD_ext_pC");
|
||||
|
||||
System.out.println("TRYING q.D.m PACKAGE interface-invoked as p.I.m");
|
||||
tryAndCheckThrown(lt, "q.D", bytesForDsomeAccess("q/D", 0),
|
||||
"q.D implements p.I, protected m", IllegalAccessError.class,
|
||||
"qD_m_pp_imp_pI");
|
||||
"q.D implements p.I, protected m",
|
||||
IllegalAccessError.class, "qD_m_pp_imp_pI");
|
||||
|
||||
// Note jar file name is used in the plural-arg case.
|
||||
System.out.println("TRYING p.D.m PRIVATE interface-invoked as p.I.m");
|
||||
System.out.println(" - should invoke p.I.m as private p.D.m is skipped for selection");
|
||||
tryAndCheckThrown(lt, bytesForDsomeAccess("p/D", ACC_PRIVATE),
|
||||
"p.D implements p.I, private m",
|
||||
IllegalAccessError.class, "pD_m_pri_imp_pI");
|
||||
"p.D implements p.I, private m",
|
||||
null /* should succeed */, "pD_m_pri_imp_pI");
|
||||
|
||||
// Plural-arg test.
|
||||
System.out.println("TRYING p.D.m PRIVATE MANY ARG interface-invoked as p.I.m");
|
||||
System.out.println(" - should invoke p.I.m as private p.D.m is skipped for selection");
|
||||
tryAndCheckThrownMany(lt, bytesForDsomeAccess("p/D", ACC_PRIVATE),
|
||||
"p.D implements p.I, private m", IllegalAccessError.class);
|
||||
"p.D implements p.I, private m", null /* should succeed */);
|
||||
|
||||
if (lt.size() > 0) {
|
||||
System.out.flush();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -39,6 +39,7 @@ import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
public class ResolvedJavaTypeResolveConcreteMethodTest {
|
||||
public final MetaAccessProvider metaAccess;
|
||||
@ -117,8 +118,9 @@ public class ResolvedJavaTypeResolveConcreteMethodTest {
|
||||
ResolvedJavaType c = getType(C.class);
|
||||
ResolvedJavaMethod priv = getMethod(a, "priv");
|
||||
|
||||
assertNull(a.resolveConcreteMethod(priv, c));
|
||||
assertNull(b.resolveConcreteMethod(priv, c));
|
||||
// nestmates have access to private methods
|
||||
assertNotNull(a.resolveConcreteMethod(priv, c));
|
||||
assertNotNull(b.resolveConcreteMethod(priv, c));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -39,6 +39,7 @@ import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
public class ResolvedJavaTypeResolveMethodTest {
|
||||
public final MetaAccessProvider metaAccess;
|
||||
@ -117,8 +118,9 @@ public class ResolvedJavaTypeResolveMethodTest {
|
||||
ResolvedJavaType c = getType(C.class);
|
||||
ResolvedJavaMethod priv = getMethod(a, "priv");
|
||||
|
||||
assertNull(a.resolveMethod(priv, c));
|
||||
assertNull(b.resolveMethod(priv, c));
|
||||
// nestmates have access to private methods
|
||||
assertNotNull(a.resolveMethod(priv, c));
|
||||
assertNotNull(b.resolveMethod(priv, c));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
54
test/hotspot/jtreg/runtime/Nestmates/NestmatesJNI.java
Normal file
54
test/hotspot/jtreg/runtime/Nestmates/NestmatesJNI.java
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Utility class for invoking methods and constructors and accessing fields
|
||||
* via JNI.
|
||||
*/
|
||||
public class NestmatesJNI {
|
||||
|
||||
static {
|
||||
System.loadLibrary("NestmatesJNI");
|
||||
}
|
||||
|
||||
public static native void callVoidVoid(Object target, String definingClassName, String methodName, boolean virtual);
|
||||
|
||||
public static native String callStringVoid(Object target, String definingClassName, String methodName, boolean virtual);
|
||||
|
||||
public static native void callStaticVoidVoid(String definingClassName, String methodName);
|
||||
|
||||
public static Object newInstance(String definingClassName, String sig, Object outerThis) {
|
||||
return newInstance0(definingClassName, "<init>", sig, outerThis);
|
||||
}
|
||||
|
||||
private static native Object newInstance0(String definingClassName, String method_name, String sig, Object outerThis);
|
||||
|
||||
public static native int getIntField(Object target, String definingClassName, String fieldName);
|
||||
|
||||
public static native void setIntField(Object target, String definingClassName, String fieldName, int newVal);
|
||||
|
||||
public static native int getStaticIntField(String definingClassName, String fieldName);
|
||||
|
||||
public static native void setStaticIntField(String definingClassName, String fieldName, int newVal);
|
||||
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* Source: NestmateAttributeHolder.java
|
||||
|
||||
public class NestmateAttributeHolder {
|
||||
public static class TwoNestHost {
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// NestHost attribute does not refer to a class
|
||||
|
||||
class NestmateAttributeHolder$BadNestHost {
|
||||
0xCAFEBABE;
|
||||
0; // minor version
|
||||
55; // version
|
||||
[] { // Constant Pool
|
||||
; // first element is empty
|
||||
Method #3 #12; // #1
|
||||
class #13; // #2
|
||||
class #16; // #3
|
||||
Utf8 "<init>"; // #4
|
||||
Utf8 "()V"; // #5
|
||||
Utf8 "Code"; // #6
|
||||
Utf8 "LineNumberTable"; // #7
|
||||
Utf8 "SourceFile"; // #8
|
||||
Utf8 "NestmateAttributeHolder.java"; // #9
|
||||
Utf8 "NestHost"; // #10
|
||||
class #17; // #11
|
||||
NameAndType #4 #5; // #12
|
||||
Utf8 "NestmateAttributeHolder$BadNestHost"; // #13
|
||||
Utf8 "BadNestHost"; // #14
|
||||
Utf8 "InnerClasses"; // #15
|
||||
Utf8 "java/lang/Object"; // #16
|
||||
Utf8 "NestmateAttributeHolder"; // #17
|
||||
} // Constant Pool
|
||||
|
||||
0x0021; // access
|
||||
#2;// this_cpx
|
||||
#3;// super_cpx
|
||||
|
||||
[] { // Interfaces
|
||||
} // Interfaces
|
||||
|
||||
[] { // fields
|
||||
} // fields
|
||||
|
||||
[] { // methods
|
||||
{ // Member
|
||||
0x0001; // access
|
||||
#4; // name_cpx
|
||||
#5; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#6) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0x2AB70001B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#7) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 2;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // methods
|
||||
|
||||
[] { // Attributes
|
||||
Attr(#8) { // SourceFile
|
||||
#9;
|
||||
} // end SourceFile
|
||||
;
|
||||
Attr(#10) { // NestHost
|
||||
0x000A; // not a class index
|
||||
} // end NestHost
|
||||
;
|
||||
Attr(#15) { // InnerClasses
|
||||
[] { // InnerClasses
|
||||
#2 #11 #14 9;
|
||||
}
|
||||
} // end InnerClasses
|
||||
} // Attributes
|
||||
} // end class NestmateAttributeHolder$BadNestHost
|
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* Source: NestmateAttributeHolder.java
|
||||
|
||||
public class NestmateAttributeHolder {
|
||||
public static class BadNestHostLength {
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Declare NestHost attribute as variable-length > 2
|
||||
class NestmateAttributeHolder$BadNestHostLength {
|
||||
0xCAFEBABE;
|
||||
0; // minor version
|
||||
55; // version
|
||||
[] { // Constant Pool
|
||||
; // first element is empty
|
||||
Method #3 #12; // #1
|
||||
class #13; // #2
|
||||
class #16; // #3
|
||||
Utf8 "<init>"; // #4
|
||||
Utf8 "()V"; // #5
|
||||
Utf8 "Code"; // #6
|
||||
Utf8 "LineNumberTable"; // #7
|
||||
Utf8 "SourceFile"; // #8
|
||||
Utf8 "NestmateAttributeHolder.java"; // #9
|
||||
Utf8 "NestHost"; // #10
|
||||
class #17; // #11
|
||||
NameAndType #4 #5; // #12
|
||||
Utf8 "NestmateAttributeHolder$BadNestHostLength"; // #13
|
||||
Utf8 "BadNestHostLength"; // #14
|
||||
Utf8 "InnerClasses"; // #15
|
||||
Utf8 "java/lang/Object"; // #16
|
||||
Utf8 "NestmateAttributeHolder"; // #17
|
||||
} // Constant Pool
|
||||
|
||||
0x0021; // access
|
||||
#2;// this_cpx
|
||||
#3;// super_cpx
|
||||
|
||||
[] { // Interfaces
|
||||
} // Interfaces
|
||||
|
||||
[] { // fields
|
||||
} // fields
|
||||
|
||||
[] { // methods
|
||||
{ // Member
|
||||
0x0001; // access
|
||||
#4; // name_cpx
|
||||
#5; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#6) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0x2AB70001B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#7) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 2;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // methods
|
||||
|
||||
[] { // Attributes
|
||||
Attr(#8) { // SourceFile
|
||||
#9;
|
||||
} // end SourceFile
|
||||
;
|
||||
Attr(#10) { // NestHost
|
||||
[] {
|
||||
#11 #11 #11 #11;
|
||||
}
|
||||
} // end NestHost
|
||||
;
|
||||
Attr(#15) { // InnerClasses
|
||||
[] { // InnerClasses
|
||||
#2 #11 #14 9;
|
||||
}
|
||||
} // end InnerClasses
|
||||
} // Attributes
|
||||
} // end class NestmateAttributeHolder$BadNestHostLength
|
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* Source: NestmateAttributeHolder.java
|
||||
|
||||
public class NestmateAttributeHolder {
|
||||
public static class TwoNestHost {
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// NestMembers attribute refers to non-class entry
|
||||
|
||||
class BadNestMembersEntry {
|
||||
0xCAFEBABE;
|
||||
0; // minor version
|
||||
55; // version
|
||||
[] { // Constant Pool
|
||||
; // first element is empty
|
||||
Method #3 #14; // #1
|
||||
class #15; // #2
|
||||
class #16; // #3
|
||||
class #17; // #4
|
||||
Utf8 "TwoNestHost"; // #5
|
||||
Utf8 "InnerClasses"; // #6
|
||||
Utf8 "<init>"; // #7
|
||||
Utf8 "()V"; // #8
|
||||
Utf8 "Code"; // #9
|
||||
Utf8 "LineNumberTable"; // #10
|
||||
Utf8 "SourceFile"; // #11
|
||||
Utf8 "BadNestMembersEntry.java"; // #12
|
||||
Utf8 "NestMembers"; // #13
|
||||
NameAndType #7 #8; // #14
|
||||
Utf8 "BadNestMembersEntry"; // #15
|
||||
Utf8 "java/lang/Object"; // #16
|
||||
Utf8 "BadNestMembersEntry$TwoNestHost"; // #17
|
||||
} // Constant Pool
|
||||
|
||||
0x0021; // access
|
||||
#2;// this_cpx
|
||||
#3;// super_cpx
|
||||
|
||||
[] { // Interfaces
|
||||
} // Interfaces
|
||||
|
||||
[] { // fields
|
||||
} // fields
|
||||
|
||||
[] { // methods
|
||||
{ // Member
|
||||
0x0001; // access
|
||||
#7; // name_cpx
|
||||
#8; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#9) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0x2AB70001B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#10) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 1;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // methods
|
||||
|
||||
[] { // Attributes
|
||||
Attr(#11) { // SourceFile
|
||||
#12;
|
||||
} // end SourceFile
|
||||
;
|
||||
Attr(#13) { // NestMembers
|
||||
0x00010009; // not a class index
|
||||
} // end NestMembers
|
||||
;
|
||||
Attr(#6) { // InnerClasses
|
||||
[] { // InnerClasses
|
||||
#4 #2 #5 9;
|
||||
}
|
||||
} // end InnerClasses
|
||||
} // Attributes
|
||||
} // end class BadNestMembersEntry
|
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* Source: NestmateAttributeHolder.java
|
||||
|
||||
public class NestmateAttributeHolder {
|
||||
public static class TwoNestHost {
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// NestMembers attribute has wrong count for number of nestmates
|
||||
|
||||
class BadNestMembersLength {
|
||||
0xCAFEBABE;
|
||||
0; // minor version
|
||||
55; // version
|
||||
[] { // Constant Pool
|
||||
; // first element is empty
|
||||
Method #3 #14; // #1
|
||||
class #15; // #2
|
||||
class #16; // #3
|
||||
class #17; // #4
|
||||
Utf8 "TwoNestHost"; // #5
|
||||
Utf8 "InnerClasses"; // #6
|
||||
Utf8 "<init>"; // #7
|
||||
Utf8 "()V"; // #8
|
||||
Utf8 "Code"; // #9
|
||||
Utf8 "LineNumberTable"; // #10
|
||||
Utf8 "SourceFile"; // #11
|
||||
Utf8 "BadNestMembersLength.java"; // #12
|
||||
Utf8 "NestMembers"; // #13
|
||||
NameAndType #7 #8; // #14
|
||||
Utf8 "BadNestMembersLength"; // #15
|
||||
Utf8 "java/lang/Object"; // #16
|
||||
Utf8 "BadNestMembersLength$TwoNestHost"; // #17
|
||||
} // Constant Pool
|
||||
|
||||
0x0021; // access
|
||||
#2;// this_cpx
|
||||
#3;// super_cpx
|
||||
|
||||
[] { // Interfaces
|
||||
} // Interfaces
|
||||
|
||||
[] { // fields
|
||||
} // fields
|
||||
|
||||
[] { // methods
|
||||
{ // Member
|
||||
0x0001; // access
|
||||
#7; // name_cpx
|
||||
#8; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#9) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0x2AB70001B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#10) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 1;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // methods
|
||||
|
||||
[] { // Attributes
|
||||
Attr(#11) { // SourceFile
|
||||
#12;
|
||||
} // end SourceFile
|
||||
;
|
||||
Attr(#13) { // NestMembers
|
||||
0x00000004; // bad length
|
||||
} // end NestMembers
|
||||
;
|
||||
Attr(#6) { // InnerClasses
|
||||
[] { // InnerClasses
|
||||
#4 #2 #5 9;
|
||||
}
|
||||
} // end InnerClasses
|
||||
} // Attributes
|
||||
} // end class BadNestMembersLength
|
116
test/hotspot/jtreg/runtime/Nestmates/classFileParsing/ConflictingAttributesInNestHost.jcod
Normal file
116
test/hotspot/jtreg/runtime/Nestmates/classFileParsing/ConflictingAttributesInNestHost.jcod
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* Source: NestmateAttributeHolder.java
|
||||
|
||||
public class NestmateAttributeHolder {
|
||||
public static class TwoNestHost {
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Add NestHost attribute to nest-host class - conflicting attributes
|
||||
|
||||
class ConflictingAttributesInNestHost {
|
||||
0xCAFEBABE;
|
||||
0; // minor version
|
||||
55; // version
|
||||
[] { // Constant Pool
|
||||
; // first element is empty
|
||||
Method #3 #14; // #1
|
||||
class #15; // #2
|
||||
class #16; // #3
|
||||
class #17; // #4
|
||||
Utf8 "TwoNestHost"; // #5
|
||||
Utf8 "InnerClasses"; // #6
|
||||
Utf8 "<init>"; // #7
|
||||
Utf8 "()V"; // #8
|
||||
Utf8 "Code"; // #9
|
||||
Utf8 "LineNumberTable"; // #10
|
||||
Utf8 "SourceFile"; // #11
|
||||
Utf8 "ConflictingAttributesInNestHost.java"; // #12
|
||||
Utf8 "NestMembers"; // #13
|
||||
NameAndType #7 #8; // #14
|
||||
Utf8 "ConflictingAttributesInNestHost"; // #15
|
||||
Utf8 "java/lang/Object"; // #16
|
||||
Utf8 "ConflictingAttributesInNestHost$TwoNestHost"; // #17
|
||||
Utf8 "NestHost"; // #18
|
||||
} // Constant Pool
|
||||
|
||||
0x0021; // access
|
||||
#2;// this_cpx
|
||||
#3;// super_cpx
|
||||
|
||||
[] { // Interfaces
|
||||
} // Interfaces
|
||||
|
||||
[] { // fields
|
||||
} // fields
|
||||
|
||||
[] { // methods
|
||||
{ // Member
|
||||
0x0001; // access
|
||||
#7; // name_cpx
|
||||
#8; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#9) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0x2AB70001B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#10) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 1;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // methods
|
||||
|
||||
[] { // Attributes
|
||||
Attr(#11) { // SourceFile
|
||||
#12;
|
||||
} // end SourceFile
|
||||
;
|
||||
Attr(#13) { // NestMembers
|
||||
0x00010004;
|
||||
} // end NestMembers
|
||||
;
|
||||
// conflict - can't be a member of a nest and have nest members
|
||||
Attr(#18) { // NestHost
|
||||
0x0003; // #3 is Object
|
||||
} // end NestHost
|
||||
;
|
||||
Attr(#6) { // InnerClasses
|
||||
[] { // InnerClasses
|
||||
#4 #2 #5 9;
|
||||
}
|
||||
} // end InnerClasses
|
||||
} // Attributes
|
||||
} // end class ConflictingAttributesInNestHost
|
114
test/hotspot/jtreg/runtime/Nestmates/classFileParsing/ConflictingAttributesInNestMember.jcod
Normal file
114
test/hotspot/jtreg/runtime/Nestmates/classFileParsing/ConflictingAttributesInNestMember.jcod
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* Source: NestmateAttributeHolder.java
|
||||
|
||||
public class NestmateAttributeHolder {
|
||||
public static class TwoNestHost {
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
class NestmateAttributeHolder$ConflictingAttributesInNestMember {
|
||||
0xCAFEBABE;
|
||||
0; // minor version
|
||||
55; // version
|
||||
[] { // Constant Pool
|
||||
; // first element is empty
|
||||
Method #3 #12; // #1
|
||||
class #13; // #2
|
||||
class #16; // #3
|
||||
Utf8 "<init>"; // #4
|
||||
Utf8 "()V"; // #5
|
||||
Utf8 "Code"; // #6
|
||||
Utf8 "LineNumberTable"; // #7
|
||||
Utf8 "SourceFile"; // #8
|
||||
Utf8 "NestmateAttributeHolder.java"; // #9
|
||||
Utf8 "NestHost"; // #10
|
||||
class #17; // #11
|
||||
NameAndType #4 #5; // #12
|
||||
Utf8 "NestmateAttributeHolder$ConflictingAttributesInNestMember"; // #13
|
||||
Utf8 "ConflictingAttributesInNestMember"; // #14
|
||||
Utf8 "InnerClasses"; // #15
|
||||
Utf8 "java/lang/Object"; // #16
|
||||
Utf8 "NestmateAttributeHolder"; // #17
|
||||
Utf8 "NestMembers"; // #18
|
||||
} // Constant Pool
|
||||
|
||||
0x0021; // access
|
||||
#2;// this_cpx
|
||||
#3;// super_cpx
|
||||
|
||||
[] { // Interfaces
|
||||
} // Interfaces
|
||||
|
||||
[] { // fields
|
||||
} // fields
|
||||
|
||||
[] { // methods
|
||||
{ // Member
|
||||
0x0001; // access
|
||||
#4; // name_cpx
|
||||
#5; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#6) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0x2AB70001B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#7) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 2;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // methods
|
||||
|
||||
[] { // Attributes
|
||||
Attr(#8) { // SourceFile
|
||||
#9;
|
||||
} // end SourceFile
|
||||
;
|
||||
Attr(#10) { // NestHost
|
||||
0x000B;
|
||||
} // end NestHost
|
||||
;
|
||||
// conflict: can't have nest members when you are a member of a nest
|
||||
Attr(#18) { // NestMembers
|
||||
0x00010004;
|
||||
} // end NestMembers
|
||||
;
|
||||
Attr(#15) { // InnerClasses
|
||||
[] { // InnerClasses
|
||||
#2 #11 #14 9;
|
||||
}
|
||||
} // end InnerClasses
|
||||
} // Attributes
|
||||
} // end class NestmateAttributeHolder$ConflictingAttributesInNestMember
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8046171
|
||||
* @summary Test nestmate checks are no longer used when check_final_method_override is executed during parsing
|
||||
* @run main TestFinalMethodOverride
|
||||
*/
|
||||
|
||||
// The check_final_method_override function in ClassfileParser uses an
|
||||
// accessability check to see if the subclass method overrides a same-named
|
||||
// superclass method. This would result in a nestmate access check if the
|
||||
// super class method is private, which in turn could lead to classloading
|
||||
// and possibly exceptions and cause havoc in the classfile parsing process.
|
||||
// To fix that we added a check for whether the super class method is private,
|
||||
// and if so, we skip the override check as by definition you can't override
|
||||
// a private method.
|
||||
//
|
||||
// This test simply sets up the case where a public subclass method has the
|
||||
// same signature as a private superclass method - the case we now skip when
|
||||
// doing check_final_method_override. The test should trivially complete
|
||||
// normally.
|
||||
|
||||
public class TestFinalMethodOverride {
|
||||
|
||||
public static class Super {
|
||||
private final void theMethod() {}
|
||||
}
|
||||
|
||||
public static class Inner extends Super {
|
||||
// define our own theMethod
|
||||
public void theMethod() {}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Inner i = new Inner();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8046171
|
||||
* @summary Test incorrect use of Nestmate related attributes
|
||||
* @compile TwoNestHost.jcod
|
||||
* TwoNestMembers.jcod
|
||||
* ConflictingAttributesInNestHost.jcod
|
||||
* ConflictingAttributesInNestMember.jcod
|
||||
* BadNestMembersLength.jcod
|
||||
* BadNestMembersEntry.jcod
|
||||
* BadNestHost.jcod
|
||||
* BadNestHostLength.jcod
|
||||
* @run main TestNestmateAttributes
|
||||
*/
|
||||
|
||||
public class TestNestmateAttributes {
|
||||
public static void main(String args[]) throws Throwable {
|
||||
String[] badClasses = new String[] {
|
||||
"NestmateAttributeHolder$TwoNestHost",
|
||||
"NestmateAttributeHolder",
|
||||
"ConflictingAttributesInNestHost",
|
||||
"NestmateAttributeHolder$ConflictingAttributesInNestMember",
|
||||
"BadNestMembersLength",
|
||||
"BadNestMembersEntry",
|
||||
"NestmateAttributeHolder$BadNestHost",
|
||||
"NestmateAttributeHolder$BadNestHostLength",
|
||||
};
|
||||
|
||||
String[] messages = new String[] {
|
||||
"Multiple NestHost attributes in class file",
|
||||
"Multiple NestMembers attributes in class file",
|
||||
"Conflicting NestMembers and NestHost attributes",
|
||||
"Conflicting NestHost and NestMembers attributes",
|
||||
"Wrong NestMembers attribute length",
|
||||
"Nest member class_info_index 9 has bad constant type",
|
||||
"Nest-host class_info_index 10 has bad constant type",
|
||||
"Wrong NestHost attribute length",
|
||||
};
|
||||
|
||||
for (int i = 0; i < badClasses.length; i++ ) {
|
||||
try {
|
||||
Class c = Class.forName(badClasses[i]);
|
||||
throw new Error("Missing ClassFormatError: " + messages[i]);
|
||||
}
|
||||
catch (ClassFormatError expected) {
|
||||
if (!expected.getMessage().contains(messages[i]))
|
||||
throw new Error("Wrong ClassFormatError message: \"" +
|
||||
expected.getMessage() + "\" does not contain \"" +
|
||||
messages[i] + "\"");
|
||||
System.out.println("OK - got expected exception: " + expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* Source: NestmateAttributeHolder.java
|
||||
|
||||
public class NestmateAttributeHolder {
|
||||
public static class TwoNestHost {
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Add second NestHost attribute - should fail parsing
|
||||
class NestmateAttributeHolder$TwoNestHost {
|
||||
0xCAFEBABE;
|
||||
0; // minor version
|
||||
55; // version
|
||||
[] { // Constant Pool
|
||||
; // first element is empty
|
||||
Method #3 #12; // #1
|
||||
class #13; // #2
|
||||
class #16; // #3
|
||||
Utf8 "<init>"; // #4
|
||||
Utf8 "()V"; // #5
|
||||
Utf8 "Code"; // #6
|
||||
Utf8 "LineNumberTable"; // #7
|
||||
Utf8 "SourceFile"; // #8
|
||||
Utf8 "NestmateAttributeHolder.java"; // #9
|
||||
Utf8 "NestHost"; // #10
|
||||
class #17; // #11
|
||||
NameAndType #4 #5; // #12
|
||||
Utf8 "NestmateAttributeHolder$TwoNestHost"; // #13
|
||||
Utf8 "TwoNestHost"; // #14
|
||||
Utf8 "InnerClasses"; // #15
|
||||
Utf8 "java/lang/Object"; // #16
|
||||
Utf8 "NestmateAttributeHolder"; // #17
|
||||
} // Constant Pool
|
||||
|
||||
0x0021; // access
|
||||
#2;// this_cpx
|
||||
#3;// super_cpx
|
||||
|
||||
[] { // Interfaces
|
||||
} // Interfaces
|
||||
|
||||
[] { // fields
|
||||
} // fields
|
||||
|
||||
[] { // methods
|
||||
{ // Member
|
||||
0x0001; // access
|
||||
#4; // name_cpx
|
||||
#5; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#6) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0x2AB70001B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#7) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 2;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // methods
|
||||
|
||||
[] { // Attributes
|
||||
Attr(#8) { // SourceFile
|
||||
#9;
|
||||
} // end SourceFile
|
||||
;
|
||||
Attr(#10) { // NestHost
|
||||
0x000B;
|
||||
} // end NestHost
|
||||
;
|
||||
Attr(#10) { // NestHost
|
||||
0x000B;
|
||||
} // end NestHost
|
||||
;
|
||||
Attr(#15) { // InnerClasses
|
||||
[] { // InnerClasses
|
||||
#2 #11 #14 9;
|
||||
}
|
||||
} // end InnerClasses
|
||||
} // Attributes
|
||||
} // end class NestmateAttributeHolder$TwoNestHost
|
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* Source: NestmateAttributeHolder.java
|
||||
|
||||
public class NestmateAttributeHolder {
|
||||
public static class TwoNestHost {
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Add second NestMembers attribute - should fail parsing
|
||||
|
||||
class NestmateAttributeHolder {
|
||||
0xCAFEBABE;
|
||||
0; // minor version
|
||||
55; // version
|
||||
[] { // Constant Pool
|
||||
; // first element is empty
|
||||
Method #3 #14; // #1
|
||||
class #15; // #2
|
||||
class #16; // #3
|
||||
class #17; // #4
|
||||
Utf8 "TwoNestHost"; // #5
|
||||
Utf8 "InnerClasses"; // #6
|
||||
Utf8 "<init>"; // #7
|
||||
Utf8 "()V"; // #8
|
||||
Utf8 "Code"; // #9
|
||||
Utf8 "LineNumberTable"; // #10
|
||||
Utf8 "SourceFile"; // #11
|
||||
Utf8 "NestmateAttributeHolder.java"; // #12
|
||||
Utf8 "NestMembers"; // #13
|
||||
NameAndType #7 #8; // #14
|
||||
Utf8 "NestmateAttributeHolder"; // #15
|
||||
Utf8 "java/lang/Object"; // #16
|
||||
Utf8 "NestmateAttributeHolder$TwoNestHost"; // #17
|
||||
} // Constant Pool
|
||||
|
||||
0x0021; // access
|
||||
#2;// this_cpx
|
||||
#3;// super_cpx
|
||||
|
||||
[] { // Interfaces
|
||||
} // Interfaces
|
||||
|
||||
[] { // fields
|
||||
} // fields
|
||||
|
||||
[] { // methods
|
||||
{ // Member
|
||||
0x0001; // access
|
||||
#7; // name_cpx
|
||||
#8; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#9) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0x2AB70001B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#10) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 1;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // methods
|
||||
|
||||
[] { // Attributes
|
||||
Attr(#11) { // SourceFile
|
||||
#12;
|
||||
} // end SourceFile
|
||||
;
|
||||
Attr(#13) { // NestMembers
|
||||
0x00010004;
|
||||
} // end NestMembers
|
||||
;
|
||||
Attr(#13) { // NestMembers
|
||||
0x00010004;
|
||||
} // end NestMembers
|
||||
;
|
||||
Attr(#6) { // InnerClasses
|
||||
[] { // InnerClasses
|
||||
#4 #2 #5 9;
|
||||
}
|
||||
} // end InnerClasses
|
||||
} // Attributes
|
||||
} // end class NestmateAttributeHolder
|
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8046171
|
||||
* @summary Test that private Lookup works for both nestmate-enabled classes
|
||||
* and legacy classes
|
||||
* @compile TestPrivateLookup.java
|
||||
* @run main TestPrivateLookup
|
||||
* @compile -source 10 -target 10 TestPrivateLookup.java
|
||||
* @run main TestPrivateLookup noNestmates
|
||||
*/
|
||||
|
||||
// Need the explicit first @compile above so that jtreg forces recompilation
|
||||
// with latest version. Otherwise compile-on-demand sees the JDK 10 version
|
||||
// and assumes it is up to date and then runs the test using that version -
|
||||
// which fails.
|
||||
|
||||
import java.lang.invoke.*;
|
||||
import static java.lang.invoke.MethodHandles.*;
|
||||
import static java.lang.invoke.MethodType.*;
|
||||
|
||||
public class TestPrivateLookup {
|
||||
|
||||
static boolean compiledForNestmates;
|
||||
|
||||
static class C {
|
||||
static class D {
|
||||
private void m() { }
|
||||
}
|
||||
|
||||
static void test() throws Throwable {
|
||||
MethodType M_T = MethodType.methodType(void.class);
|
||||
// Direct lookup from C
|
||||
Lookup l = lookup();
|
||||
try {
|
||||
MethodHandle mh = l.findVirtual(D.class, "m", M_T);
|
||||
if (compiledForNestmates) {
|
||||
System.out.println("Lookup of D.m from C succeeded as expected with nestmates");
|
||||
}
|
||||
else {
|
||||
throw new Error("Unexpected success when not compiled for nestmates!");
|
||||
}
|
||||
}
|
||||
catch (IllegalAccessException iae) {
|
||||
if (!compiledForNestmates) {
|
||||
System.out.println("Lookup of D.m from C failed as expected without nestmates");
|
||||
}
|
||||
else {
|
||||
throw new Error("Unexpected failure with nestmates", iae);
|
||||
}
|
||||
}
|
||||
// switch lookup class to D
|
||||
l = l.in(D.class);
|
||||
try {
|
||||
MethodHandle mh = l.findVirtual(D.class, "m", M_T);
|
||||
System.out.println("Lookup of D.m from D succeeded as expected" +
|
||||
" with" + (compiledForNestmates ? "" : "out") +
|
||||
" nestmates");
|
||||
}
|
||||
catch (IllegalAccessException iae) {
|
||||
throw new Error("Lookup of D.m from D failed", iae);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
|
||||
// If there's no nesthost attribute A.getNestHost() == A
|
||||
compiledForNestmates = C.D.class.getNestHost() == TestPrivateLookup.class;
|
||||
// sanity check
|
||||
boolean expectingNestmates = args.length == 0;
|
||||
|
||||
if (compiledForNestmates && !expectingNestmates) {
|
||||
throw new Error("Test is being run incorrectly: " +
|
||||
"nestmates are being used but not expected");
|
||||
}
|
||||
if (expectingNestmates && !compiledForNestmates) {
|
||||
throw new Error("Test is being run incorrectly: " +
|
||||
"nestmates are expected but not being used");
|
||||
}
|
||||
System.out.println("Testing with" + (expectingNestmates ? "" : "out") +
|
||||
" nestmates");
|
||||
|
||||
C.test();
|
||||
}
|
||||
}
|
241
test/hotspot/jtreg/runtime/Nestmates/libNestmatesJNI.c
Normal file
241
test/hotspot/jtreg/runtime/Nestmates/libNestmatesJNI.c
Normal file
@ -0,0 +1,241 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
// boolean flag for static versus non-static
|
||||
#define STATIC 1
|
||||
#define NON_STATIC 0
|
||||
|
||||
// Helper methods to get class/method/field IDs
|
||||
|
||||
static void getClassID(JNIEnv *env,
|
||||
jstring defining_class_name,
|
||||
jclass* clazz) {
|
||||
const char* name = (*env)->GetStringUTFChars(env, defining_class_name, NULL);
|
||||
if (name != NULL) {
|
||||
*clazz = (*env)->FindClass(env, name);
|
||||
(*env)->ReleaseStringUTFChars(env, defining_class_name, name);
|
||||
}
|
||||
}
|
||||
|
||||
static void getClassAndMethodID(JNIEnv *env,
|
||||
int is_static,
|
||||
jstring defining_class_name,
|
||||
jstring method_name,
|
||||
const char* sig,
|
||||
jmethodID* m_id, jclass* clazz) {
|
||||
getClassID(env, defining_class_name, clazz);
|
||||
if (*clazz != NULL) {
|
||||
const char* name = (*env)->GetStringUTFChars(env, method_name, NULL);
|
||||
if (name != NULL) {
|
||||
if (is_static) {
|
||||
*m_id = (*env)->GetStaticMethodID(env, *clazz, name, sig);
|
||||
} else {
|
||||
*m_id = (*env)->GetMethodID(env, *clazz, name, sig);
|
||||
}
|
||||
(*env)->ReleaseStringUTFChars(env, method_name, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void getClassAndFieldID(JNIEnv *env,
|
||||
int is_static,
|
||||
jstring defining_class_name,
|
||||
jstring field_name,
|
||||
const char* sig,
|
||||
jfieldID* m_id, jclass* clazz) {
|
||||
getClassID(env, defining_class_name, clazz);
|
||||
if (*clazz != NULL) {
|
||||
const char* name = (*env)->GetStringUTFChars(env, field_name, NULL);
|
||||
if (name != NULL) {
|
||||
if (is_static) {
|
||||
*m_id = (*env)->GetStaticFieldID(env, *clazz, name, sig);
|
||||
} else {
|
||||
*m_id = (*env)->GetFieldID(env, *clazz, name, sig);
|
||||
}
|
||||
(*env)->ReleaseStringUTFChars(env, field_name, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_NestmatesJNI_callVoidVoid(JNIEnv *env, jclass unused,
|
||||
jobject target,
|
||||
jstring defining_class_name,
|
||||
jstring method_name,
|
||||
jboolean virtual) {
|
||||
|
||||
// Lookup "void method_name()" in defining_class_name, and if it exists
|
||||
// call target.method_name() using a virtual or non-virtual invocation
|
||||
|
||||
jmethodID m_id = NULL;
|
||||
jclass clazz = NULL;
|
||||
getClassAndMethodID(env, NON_STATIC, defining_class_name, method_name,
|
||||
"()V", &m_id, &clazz);
|
||||
if (m_id != NULL && clazz != NULL) {
|
||||
if (!virtual) {
|
||||
(*env)->CallNonvirtualVoidMethod(env, target, clazz, m_id);
|
||||
} else {
|
||||
(*env)->CallVoidMethod(env, target, m_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_NestmatesJNI_callStringVoid(JNIEnv *env, jclass unused,
|
||||
jobject target,
|
||||
jstring defining_class_name,
|
||||
jstring method_name,
|
||||
jboolean virtual) {
|
||||
|
||||
// Lookup "String method_name()" in defining_class_name, and if it exists
|
||||
// call target.method_name() using a virtual or non-virtual invocation
|
||||
|
||||
jmethodID m_id = NULL;
|
||||
jclass clazz = NULL;
|
||||
getClassAndMethodID(env, NON_STATIC, defining_class_name, method_name,
|
||||
"()Ljava/lang/String;", &m_id, &clazz);
|
||||
if (m_id != NULL && clazz != NULL) {
|
||||
if (!virtual) {
|
||||
return (*env)->CallNonvirtualObjectMethod(env, target, clazz, m_id);
|
||||
} else {
|
||||
return (*env)->CallObjectMethod(env, target, m_id);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_NestmatesJNI_newInstance0(JNIEnv *env, jclass unused,
|
||||
jstring defining_class_name,
|
||||
jstring method_name,
|
||||
jstring sig,
|
||||
jobject outerThis) {
|
||||
|
||||
// Lookup the no-user-arg constructor in defining_class_name using sig,
|
||||
// and use it to create an instance of the class, and return it. For
|
||||
// inner classes we need an outerThis reference to pass to the constructor.
|
||||
|
||||
jmethodID m_id = NULL;
|
||||
jclass clazz = NULL;
|
||||
const char* _sig = (*env)->GetStringUTFChars(env, sig, NULL);
|
||||
getClassAndMethodID(env, NON_STATIC, defining_class_name, method_name,
|
||||
_sig, &m_id, &clazz);
|
||||
(*env)->ReleaseStringUTFChars(env, sig, _sig);
|
||||
if (m_id != NULL && clazz != NULL) {
|
||||
return (*env)->NewObject(env, clazz, m_id, outerThis);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_NestmatesJNI_callStaticVoidVoid(JNIEnv *env, jclass unused,
|
||||
jstring defining_class_name,
|
||||
jstring method_name) {
|
||||
|
||||
// Lookup "static void method_name()" in defining_class_name, and if it exists
|
||||
// invoke it.
|
||||
|
||||
jmethodID m_id = NULL;
|
||||
jclass clazz = NULL;
|
||||
getClassAndMethodID(env, STATIC, defining_class_name, method_name,
|
||||
"()V", &m_id, &clazz);
|
||||
if (m_id != NULL && clazz != NULL) {
|
||||
(*env)->CallStaticVoidMethod(env, clazz, m_id);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_NestmatesJNI_getIntField(JNIEnv *env, jclass unused,
|
||||
jobject target,
|
||||
jstring defining_class_name,
|
||||
jstring field_name) {
|
||||
|
||||
// Lookup field field_name in defining_class_name, and if it exists
|
||||
// return its value.
|
||||
|
||||
jfieldID f_id = NULL;
|
||||
jclass clazz = NULL;
|
||||
getClassAndFieldID(env, NON_STATIC, defining_class_name, field_name,
|
||||
"I", &f_id, &clazz);
|
||||
if (f_id != NULL && clazz != NULL) {
|
||||
return (*env)->GetIntField(env, target, f_id);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_NestmatesJNI_setIntField(JNIEnv *env, jclass unused,
|
||||
jobject target,
|
||||
jstring defining_class_name,
|
||||
jstring field_name,
|
||||
jint newVal) {
|
||||
|
||||
// Lookup field field_name in defining_class_name, and if it exists
|
||||
// set it to newVal.
|
||||
|
||||
jfieldID f_id = NULL;
|
||||
jclass clazz = NULL;
|
||||
getClassAndFieldID(env, NON_STATIC, defining_class_name, field_name,
|
||||
"I", &f_id, &clazz);
|
||||
if (f_id != NULL && clazz != NULL) {
|
||||
(*env)->SetIntField(env, target, f_id, newVal);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_NestmatesJNI_getStaticIntField(JNIEnv *env, jclass unused,
|
||||
jstring defining_class_name,
|
||||
jstring field_name) {
|
||||
|
||||
// Lookup field field_name in defining_class_name, and if it exists
|
||||
// return its value.
|
||||
|
||||
jfieldID f_id = NULL;
|
||||
jclass clazz = NULL;
|
||||
getClassAndFieldID(env, STATIC, defining_class_name, field_name,
|
||||
"I", &f_id, &clazz);
|
||||
if (f_id != NULL && clazz != NULL) {
|
||||
return (*env)->GetStaticIntField(env, clazz, f_id);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_NestmatesJNI_setStaticIntField(JNIEnv *env, jclass unused,
|
||||
jstring defining_class_name,
|
||||
jstring field_name,
|
||||
jint newVal) {
|
||||
|
||||
// Lookup field field_name in defining_class_name, and if it exists
|
||||
// set it to newVal.
|
||||
|
||||
jfieldID f_id = NULL;
|
||||
jclass clazz = NULL;
|
||||
getClassAndFieldID(env, STATIC, defining_class_name, field_name,
|
||||
"I", &f_id, &clazz);
|
||||
if (f_id != NULL && clazz != NULL) {
|
||||
(*env)->SetStaticIntField(env, clazz, f_id, newVal);
|
||||
}
|
||||
}
|
@ -0,0 +1,396 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
// NestHost attribute refers to non-existent class
|
||||
|
||||
class TestNestmateMembership$CallerMissingHost {
|
||||
0xCAFEBABE;
|
||||
0; // minor version
|
||||
55; // version
|
||||
[] { // Constant Pool
|
||||
; // first element is empty
|
||||
Field #38 #39; // #1
|
||||
String #40; // #2
|
||||
Method #41 #42; // #3
|
||||
Method #9 #43; // #4
|
||||
Method #11 #43; // #5
|
||||
Method #16 #44; // #6
|
||||
String #45; // #7
|
||||
Field #15 #46; // #8
|
||||
class #47; // #9
|
||||
Method #9 #44; // #10
|
||||
class #50; // #11
|
||||
Method #11 #44; // #12
|
||||
Field #9 #52; // #13
|
||||
Field #11 #52; // #14
|
||||
class #53; // #15
|
||||
class #55; // #16
|
||||
Utf8 "msg"; // #17
|
||||
Utf8 "Ljava/lang/String;"; // #18
|
||||
Utf8 "f"; // #19
|
||||
Utf8 "I"; // #20
|
||||
Utf8 "m"; // #21
|
||||
Utf8 "()V"; // #22
|
||||
Utf8 "Code"; // #23
|
||||
Utf8 "LineNumberTable"; // #24
|
||||
Utf8 "invokeTarget"; // #25
|
||||
Utf8 "invokeTargetMissingHost"; // #26
|
||||
Utf8 "<init>"; // #27
|
||||
Utf8 "newTarget"; // #28
|
||||
Utf8 "newTargetMissingHost"; // #29
|
||||
Utf8 "getFieldTarget"; // #30
|
||||
Utf8 "getFieldTargetMissingHost"; // #31
|
||||
Utf8 "putFieldTarget"; // #32
|
||||
Utf8 "putFieldTargetMissingHost"; // #33
|
||||
Utf8 "SourceFile"; // #34
|
||||
Utf8 "TestNestmateMembership.java"; // #35
|
||||
Utf8 "NestHost"; // #36
|
||||
class #56; // #37
|
||||
class #57; // #38
|
||||
NameAndType #58 #59; // #39
|
||||
Utf8 "CallerMissingHost.m() - java version"; // #40
|
||||
class #60; // #41
|
||||
NameAndType #61 #62; // #42
|
||||
NameAndType #21 #22; // #43
|
||||
NameAndType #27 #22; // #44
|
||||
Utf8 "NoCallerMissingHost"; // #45
|
||||
NameAndType #17 #18; // #46
|
||||
Utf8 "TestNestmateMembership$Target"; // #47
|
||||
Utf8 "Target"; // #48
|
||||
Utf8 "InnerClasses"; // #49
|
||||
Utf8 "TestNestmateMembership$TargetMissingHost"; // #50
|
||||
Utf8 "TargetMissingHost"; // #51
|
||||
NameAndType #19 #20; // #52
|
||||
Utf8 "TestNestmateMembership$CallerMissingHost"; // #53
|
||||
Utf8 "CallerMissingHost"; // #54
|
||||
Utf8 "java/lang/Object"; // #55
|
||||
Utf8 "TestNestmateMembership"; // #56
|
||||
Utf8 "java/lang/System"; // #57
|
||||
Utf8 "out"; // #58
|
||||
Utf8 "Ljava/io/PrintStream;"; // #59
|
||||
Utf8 "java/io/PrintStream"; // #60
|
||||
Utf8 "println"; // #61
|
||||
Utf8 "(Ljava/lang/String;)V"; // #62
|
||||
class #45; // added - #63
|
||||
} // Constant Pool
|
||||
|
||||
0x0020; // access
|
||||
#15;// this_cpx
|
||||
#16;// super_cpx
|
||||
|
||||
[] { // Interfaces
|
||||
} // Interfaces
|
||||
|
||||
[] { // fields
|
||||
{ // Member
|
||||
0x0000; // access
|
||||
#17; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x000A; // access
|
||||
#19; // name_cpx
|
||||
#20; // sig_cpx
|
||||
[] { // Attributes
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // fields
|
||||
|
||||
[] { // methods
|
||||
{ // Member
|
||||
0x000A; // access
|
||||
#21; // name_cpx
|
||||
#22; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#23) { // Code
|
||||
2; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0xB200011202B60003;
|
||||
0xB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#24) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 209;
|
||||
8 210;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#25; // name_cpx
|
||||
#22; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#23) { // Code
|
||||
0; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0xB80004B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#24) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 212;
|
||||
3 213;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#26; // name_cpx
|
||||
#22; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#23) { // Code
|
||||
0; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0xB80005B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#24) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 215;
|
||||
3 216;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0002; // access
|
||||
#27; // name_cpx
|
||||
#22; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#23) { // Code
|
||||
2; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0x2AB700062A1207B5;
|
||||
0x0008B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#24) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 220;
|
||||
4 204;
|
||||
10 220;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#28; // name_cpx
|
||||
#22; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#23) { // Code
|
||||
2; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0xBB000959B7000A4B;
|
||||
0xB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#24) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 223;
|
||||
8 224;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#29; // name_cpx
|
||||
#22; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#23) { // Code
|
||||
2; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0xBB000B59B7000C4B;
|
||||
0xB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#24) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 226;
|
||||
8 227;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#30; // name_cpx
|
||||
#22; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#23) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0xB2000D3BB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#24) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 234;
|
||||
4 235;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#31; // name_cpx
|
||||
#22; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#23) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0xB2000E3BB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#24) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 237;
|
||||
4 238;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#32; // name_cpx
|
||||
#22; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#23) { // Code
|
||||
1; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0x102AB3000DB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#24) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 240;
|
||||
5 241;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#33; // name_cpx
|
||||
#22; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#23) { // Code
|
||||
1; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0x102AB3000EB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#24) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 243;
|
||||
5 244;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // methods
|
||||
|
||||
[] { // Attributes
|
||||
Attr(#34) { // SourceFile
|
||||
#35;
|
||||
} // end SourceFile
|
||||
;
|
||||
Attr(#36) { // NestHost
|
||||
0x003F; // modified - #63
|
||||
} // end NestHost
|
||||
;
|
||||
Attr(#49) { // InnerClasses
|
||||
[] { // InnerClasses
|
||||
#9 #37 #48 8;
|
||||
#11 #37 #51 8;
|
||||
#15 #37 #54 8;
|
||||
}
|
||||
} // end InnerClasses
|
||||
} // Attributes
|
||||
} // end class TestNestmateMembership$CallerMissingHost
|
@ -0,0 +1,374 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
// NestHost attribute deleted
|
||||
|
||||
class TestNestmateMembership$CallerNoHost {
|
||||
0xCAFEBABE;
|
||||
0; // minor version
|
||||
55; // version
|
||||
[] { // Constant Pool
|
||||
; // first element is empty
|
||||
Field #34 #35; // #1
|
||||
String #36; // #2
|
||||
Method #37 #38; // #3
|
||||
Method #7 #39; // #4
|
||||
Method #9 #39; // #5
|
||||
Method #14 #40; // #6
|
||||
class #41; // #7
|
||||
Method #7 #40; // #8
|
||||
class #44; // #9
|
||||
Method #9 #40; // #10
|
||||
Field #7 #46; // #11
|
||||
Field #9 #46; // #12
|
||||
class #47; // #13
|
||||
class #49; // #14
|
||||
Utf8 "f"; // #15
|
||||
Utf8 "I"; // #16
|
||||
Utf8 "m"; // #17
|
||||
Utf8 "()V"; // #18
|
||||
Utf8 "Code"; // #19
|
||||
Utf8 "LineNumberTable"; // #20
|
||||
Utf8 "invokeTarget"; // #21
|
||||
Utf8 "invokeTargetNoHost"; // #22
|
||||
Utf8 "<init>"; // #23
|
||||
Utf8 "newTarget"; // #24
|
||||
Utf8 "newTargetNoHost"; // #25
|
||||
Utf8 "getFieldTarget"; // #26
|
||||
Utf8 "getFieldTargetNoHost"; // #27
|
||||
Utf8 "putFieldTarget"; // #28
|
||||
Utf8 "putFieldTargetNoHost"; // #29
|
||||
Utf8 "SourceFile"; // #30
|
||||
Utf8 "TestNestmateMembership.java"; // #31
|
||||
Utf8 "NestHost"; // #32
|
||||
class #50; // #33
|
||||
class #51; // #34
|
||||
NameAndType #52 #53; // #35
|
||||
Utf8 "CallerNoHost.m() - java version"; // #36
|
||||
class #54; // #37
|
||||
NameAndType #55 #56; // #38
|
||||
NameAndType #17 #18; // #39
|
||||
NameAndType #23 #18; // #40
|
||||
Utf8 "TestNestmateMembership$Target"; // #41
|
||||
Utf8 "Target"; // #42
|
||||
Utf8 "InnerClasses"; // #43
|
||||
Utf8 "TestNestmateMembership$TargetNoHost"; // #44
|
||||
Utf8 "TargetNoHost"; // #45
|
||||
NameAndType #15 #16; // #46
|
||||
Utf8 "TestNestmateMembership$CallerNoHost"; // #47
|
||||
Utf8 "CallerNoHost"; // #48
|
||||
Utf8 "java/lang/Object"; // #49
|
||||
Utf8 "TestNestmateMembership"; // #50
|
||||
Utf8 "java/lang/System"; // #51
|
||||
Utf8 "out"; // #52
|
||||
Utf8 "Ljava/io/PrintStream;"; // #53
|
||||
Utf8 "java/io/PrintStream"; // #54
|
||||
Utf8 "println"; // #55
|
||||
Utf8 "(Ljava/lang/String;)V"; // #56
|
||||
} // Constant Pool
|
||||
|
||||
0x0020; // access
|
||||
#13;// this_cpx
|
||||
#14;// super_cpx
|
||||
|
||||
[] { // Interfaces
|
||||
} // Interfaces
|
||||
|
||||
[] { // fields
|
||||
{ // Member
|
||||
0x000A; // access
|
||||
#15; // name_cpx
|
||||
#16; // sig_cpx
|
||||
[] { // Attributes
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // fields
|
||||
|
||||
[] { // methods
|
||||
{ // Member
|
||||
0x000A; // access
|
||||
#17; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
2; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0xB200011202B60003;
|
||||
0xB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 163;
|
||||
8 164;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#21; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
0; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0xB80004B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 166;
|
||||
3 167;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#22; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
0; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0xB80005B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 169;
|
||||
3 170;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0002; // access
|
||||
#23; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0x2AB70006B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 174;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#24; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
2; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0xBB000759B700084B;
|
||||
0xB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 177;
|
||||
8 178;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#25; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
2; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0xBB000959B7000A4B;
|
||||
0xB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 180;
|
||||
8 181;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#26; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0xB2000B3BB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 188;
|
||||
4 189;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#27; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0xB2000C3BB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 191;
|
||||
4 192;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#28; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
1; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0x102AB3000BB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 195;
|
||||
5 196;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#29; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
1; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0x102AB3000CB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 198;
|
||||
5 199;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // methods
|
||||
|
||||
[] { // Attributes
|
||||
Attr(#30) { // SourceFile
|
||||
#31;
|
||||
} // end SourceFile
|
||||
;
|
||||
Attr(#43) { // InnerClasses
|
||||
[] { // InnerClasses
|
||||
#7 #33 #42 8;
|
||||
#9 #33 #45 8;
|
||||
#13 #33 #48 8;
|
||||
}
|
||||
} // end InnerClasses
|
||||
} // Attributes
|
||||
} // end class TestNestmateMembership$CallerNoHost
|
@ -0,0 +1,389 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
// NestHost attribute refers to non-instance class
|
||||
|
||||
class TestNestmateMembership$CallerNotInstanceHost {
|
||||
0xCAFEBABE;
|
||||
0; // minor version
|
||||
55; // version
|
||||
[] { // Constant Pool
|
||||
; // first element is empty
|
||||
Field #36 #37; // #1
|
||||
String #38; // #2
|
||||
Method #39 #40; // #3
|
||||
Method #7 #41; // #4
|
||||
Method #9 #41; // #5
|
||||
Method #14 #42; // #6
|
||||
class #43; // #7
|
||||
Method #7 #42; // #8
|
||||
class #46; // #9
|
||||
Method #9 #42; // #10
|
||||
Field #7 #48; // #11
|
||||
Field #9 #48; // #12
|
||||
class #49; // #13
|
||||
class #51; // #14
|
||||
Utf8 "oa"; // #15
|
||||
Utf8 "[LInvalidNestHost;"; // #16
|
||||
Utf8 "f"; // #17
|
||||
Utf8 "I"; // #18
|
||||
Utf8 "m"; // #19
|
||||
Utf8 "()V"; // #20
|
||||
Utf8 "Code"; // #21
|
||||
Utf8 "LineNumberTable"; // #22
|
||||
Utf8 "invokeTarget"; // #23
|
||||
Utf8 "invokeTargetNotInstanceHost"; // #24
|
||||
Utf8 "<init>"; // #25
|
||||
Utf8 "newTarget"; // #26
|
||||
Utf8 "newTargetNotInstanceHost"; // #27
|
||||
Utf8 "getFieldTarget"; // #28
|
||||
Utf8 "getFieldTargetNotInstanceHost"; // #29
|
||||
Utf8 "putFieldTarget"; // #30
|
||||
Utf8 "putFieldTargetNotInstanceHost"; // #31
|
||||
Utf8 "SourceFile"; // #32
|
||||
Utf8 "TestNestmateMembership.java"; // #33
|
||||
Utf8 "NestHost"; // #34
|
||||
class #52; // #35
|
||||
class #53; // #36
|
||||
NameAndType #54 #55; // #37
|
||||
Utf8 "CallerNotInstanceHost.m() - java version"; // #38
|
||||
class #56; // #39
|
||||
NameAndType #57 #58; // #40
|
||||
NameAndType #19 #20; // #41
|
||||
NameAndType #25 #20; // #42
|
||||
Utf8 "TestNestmateMembership$Target"; // #43
|
||||
Utf8 "Target"; // #44
|
||||
Utf8 "InnerClasses"; // #45
|
||||
Utf8 "TestNestmateMembership$TargetNotInstanceHost"; // #46
|
||||
Utf8 "TargetNotInstanceHost"; // #47
|
||||
NameAndType #17 #18; // #48
|
||||
Utf8 "TestNestmateMembership$CallerNotInstanceHost"; // #49
|
||||
Utf8 "CallerNotInstanceHost"; // #50
|
||||
Utf8 "java/lang/Object"; // #51
|
||||
Utf8 "TestNestmateMembership"; // #52
|
||||
Utf8 "java/lang/System"; // #53
|
||||
Utf8 "out"; // #54
|
||||
Utf8 "Ljava/io/PrintStream;"; // #55
|
||||
Utf8 "java/io/PrintStream"; // #56
|
||||
Utf8 "println"; // #57
|
||||
Utf8 "(Ljava/lang/String;)V"; // #58
|
||||
class #16; // Added - #59
|
||||
} // Constant Pool
|
||||
|
||||
0x0020; // access
|
||||
#13;// this_cpx
|
||||
#14;// super_cpx
|
||||
|
||||
[] { // Interfaces
|
||||
} // Interfaces
|
||||
|
||||
[] { // fields
|
||||
{ // Member
|
||||
0x0000; // access
|
||||
#15; // name_cpx
|
||||
#16; // sig_cpx
|
||||
[] { // Attributes
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x000A; // access
|
||||
#17; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // fields
|
||||
|
||||
[] { // methods
|
||||
{ // Member
|
||||
0x000A; // access
|
||||
#19; // name_cpx
|
||||
#20; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#21) { // Code
|
||||
2; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0xB200011202B60003;
|
||||
0xB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#22) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 254;
|
||||
8 255;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#23; // name_cpx
|
||||
#20; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#21) { // Code
|
||||
0; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0xB80004B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#22) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 257;
|
||||
3 258;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#24; // name_cpx
|
||||
#20; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#21) { // Code
|
||||
0; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0xB80005B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#22) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 260;
|
||||
3 261;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0002; // access
|
||||
#25; // name_cpx
|
||||
#20; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#21) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0x2AB70006B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#22) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 265;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#26; // name_cpx
|
||||
#20; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#21) { // Code
|
||||
2; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0xBB000759B700084B;
|
||||
0xB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#22) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 268;
|
||||
8 269;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#27; // name_cpx
|
||||
#20; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#21) { // Code
|
||||
2; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0xBB000959B7000A4B;
|
||||
0xB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#22) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 271;
|
||||
8 272;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#28; // name_cpx
|
||||
#20; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#21) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0xB2000B3BB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#22) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 279;
|
||||
4 280;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#29; // name_cpx
|
||||
#20; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#21) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0xB2000C3BB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#22) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 282;
|
||||
4 283;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#30; // name_cpx
|
||||
#20; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#21) { // Code
|
||||
1; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0x102AB3000BB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#22) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 285;
|
||||
5 286;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#31; // name_cpx
|
||||
#20; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#21) { // Code
|
||||
1; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0x102AB3000CB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#22) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 288;
|
||||
5 289;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // methods
|
||||
|
||||
[] { // Attributes
|
||||
Attr(#32) { // SourceFile
|
||||
#33;
|
||||
} // end SourceFile
|
||||
;
|
||||
Attr(#34) { // NestHost
|
||||
0x003B; // modified #59
|
||||
} // end NestHost
|
||||
;
|
||||
Attr(#45) { // InnerClasses
|
||||
[] { // InnerClasses
|
||||
#7 #35 #44 8;
|
||||
#9 #35 #47 8;
|
||||
#13 #35 #50 8;
|
||||
}
|
||||
} // end InnerClasses
|
||||
} // Attributes
|
||||
} // end class TestNestmateMembership$CallerNotInstanceHost
|
@ -0,0 +1,381 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
// NestHost attribute refers to class with no nest
|
||||
|
||||
class TestNestmateMembership$CallerNotOurHost {
|
||||
0xCAFEBABE;
|
||||
0; // minor version
|
||||
55; // version
|
||||
[] { // Constant Pool
|
||||
; // first element is empty
|
||||
Field #34 #35; // #1
|
||||
String #36; // #2
|
||||
Method #37 #38; // #3
|
||||
Method #7 #39; // #4
|
||||
Method #9 #39; // #5
|
||||
Method #14 #40; // #6
|
||||
class #41; // #7
|
||||
Method #7 #40; // #8
|
||||
class #44; // #9
|
||||
Method #9 #40; // #10
|
||||
Field #7 #46; // #11
|
||||
Field #9 #46; // #12
|
||||
class #47; // #13
|
||||
class #49; // #14
|
||||
Utf8 "f"; // #15
|
||||
Utf8 "I"; // #16
|
||||
Utf8 "m"; // #17
|
||||
Utf8 "()V"; // #18
|
||||
Utf8 "Code"; // #19
|
||||
Utf8 "LineNumberTable"; // #20
|
||||
Utf8 "invokeTarget"; // #21
|
||||
Utf8 "invokeTargetNotOurHost"; // #22
|
||||
Utf8 "<init>"; // #23
|
||||
Utf8 "newTarget"; // #24
|
||||
Utf8 "newTargetNotOurHost"; // #25
|
||||
Utf8 "getFieldTarget"; // #26
|
||||
Utf8 "getFieldTargetNotOurHost"; // #27
|
||||
Utf8 "putFieldTarget"; // #28
|
||||
Utf8 "putFieldTargetNotOurHost"; // #29
|
||||
Utf8 "SourceFile"; // #30
|
||||
Utf8 "TestNestmateMembership.java"; // #31
|
||||
Utf8 "NestHost"; // #32
|
||||
class #50; // #33
|
||||
class #51; // #34
|
||||
NameAndType #52 #53; // #35
|
||||
Utf8 "CallerNotOurHost.m() - java version"; // #36
|
||||
class #54; // #37
|
||||
NameAndType #55 #56; // #38
|
||||
NameAndType #17 #18; // #39
|
||||
NameAndType #23 #18; // #40
|
||||
Utf8 "TestNestmateMembership$Target"; // #41
|
||||
Utf8 "Target"; // #42
|
||||
Utf8 "InnerClasses"; // #43
|
||||
Utf8 "TestNestmateMembership$TargetNotOurHost"; // #44
|
||||
Utf8 "TargetNotOurHost"; // #45
|
||||
NameAndType #15 #16; // #46
|
||||
Utf8 "TestNestmateMembership$CallerNotOurHost"; // #47
|
||||
Utf8 "CallerNotOurHost"; // #48
|
||||
Utf8 "java/lang/Object"; // #49
|
||||
Utf8 "TestNestmateMembership"; // #50
|
||||
Utf8 "java/lang/System"; // #51
|
||||
Utf8 "out"; // #52
|
||||
Utf8 "Ljava/io/PrintStream;"; // #53
|
||||
Utf8 "java/io/PrintStream"; // #54
|
||||
Utf8 "println"; // #55
|
||||
Utf8 "(Ljava/lang/String;)V"; // #56
|
||||
// Added
|
||||
Utf8 "InvalidNestHost"; // #57
|
||||
class #57; // #58
|
||||
} // Constant Pool
|
||||
|
||||
0x0020; // access
|
||||
#13;// this_cpx
|
||||
#14;// super_cpx
|
||||
|
||||
[] { // Interfaces
|
||||
} // Interfaces
|
||||
|
||||
[] { // fields
|
||||
{ // Member
|
||||
0x000A; // access
|
||||
#15; // name_cpx
|
||||
#16; // sig_cpx
|
||||
[] { // Attributes
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // fields
|
||||
|
||||
[] { // methods
|
||||
{ // Member
|
||||
0x000A; // access
|
||||
#17; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
2; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0xB200011202B60003;
|
||||
0xB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 297;
|
||||
8 298;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#21; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
0; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0xB80004B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 300;
|
||||
3 301;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#22; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
0; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0xB80005B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 303;
|
||||
3 304;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0002; // access
|
||||
#23; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0x2AB70006B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 308;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#24; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
2; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0xBB000759B700084B;
|
||||
0xB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 311;
|
||||
8 312;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#25; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
2; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0xBB000959B7000A4B;
|
||||
0xB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 314;
|
||||
8 315;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#26; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0xB2000B3BB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 322;
|
||||
4 323;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#27; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0xB2000C3BB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 325;
|
||||
4 326;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#28; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
1; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0x102AB3000BB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 328;
|
||||
5 329;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#29; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
1; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0x102AB3000CB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 331;
|
||||
5 332;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // methods
|
||||
|
||||
[] { // Attributes
|
||||
Attr(#30) { // SourceFile
|
||||
#31;
|
||||
} // end SourceFile
|
||||
;
|
||||
Attr(#32) { // NestHost
|
||||
0x003A; // modified - #58
|
||||
} // end NestHost
|
||||
;
|
||||
Attr(#43) { // InnerClasses
|
||||
[] { // InnerClasses
|
||||
#7 #33 #42 8;
|
||||
#9 #33 #45 8;
|
||||
#13 #33 #48 8;
|
||||
}
|
||||
} // end InnerClasses
|
||||
} // Attributes
|
||||
} // end class TestNestmateMembership$CallerNotOurHost
|
@ -0,0 +1,378 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
// NestHost attribute refers to current class
|
||||
|
||||
class TestNestmateMembership$CallerSelfHost {
|
||||
0xCAFEBABE;
|
||||
0; // minor version
|
||||
55; // version
|
||||
[] { // Constant Pool
|
||||
; // first element is empty
|
||||
Field #34 #35; // #1
|
||||
String #36; // #2
|
||||
Method #37 #38; // #3
|
||||
Method #7 #39; // #4
|
||||
Method #9 #39; // #5
|
||||
Method #14 #40; // #6
|
||||
class #41; // #7
|
||||
Method #7 #40; // #8
|
||||
class #44; // #9
|
||||
Method #9 #40; // #10
|
||||
Field #7 #46; // #11
|
||||
Field #9 #46; // #12
|
||||
class #47; // #13
|
||||
class #49; // #14
|
||||
Utf8 "f"; // #15
|
||||
Utf8 "I"; // #16
|
||||
Utf8 "m"; // #17
|
||||
Utf8 "()V"; // #18
|
||||
Utf8 "Code"; // #19
|
||||
Utf8 "LineNumberTable"; // #20
|
||||
Utf8 "invokeTarget"; // #21
|
||||
Utf8 "invokeTargetSelfHost"; // #22
|
||||
Utf8 "<init>"; // #23
|
||||
Utf8 "newTarget"; // #24
|
||||
Utf8 "newTargetSelfHost"; // #25
|
||||
Utf8 "getFieldTarget"; // #26
|
||||
Utf8 "getFieldTargetSelfHost"; // #27
|
||||
Utf8 "putFieldTarget"; // #28
|
||||
Utf8 "putFieldTargetSelfHost"; // #29
|
||||
Utf8 "SourceFile"; // #30
|
||||
Utf8 "TestNestmateMembership.java"; // #31
|
||||
Utf8 "NestHost"; // #32
|
||||
class #50; // #33
|
||||
class #51; // #34
|
||||
NameAndType #52 #53; // #35
|
||||
Utf8 "CallerSelfHost.m() - java version"; // #36
|
||||
class #54; // #37
|
||||
NameAndType #55 #56; // #38
|
||||
NameAndType #17 #18; // #39
|
||||
NameAndType #23 #18; // #40
|
||||
Utf8 "TestNestmateMembership$Target"; // #41
|
||||
Utf8 "Target"; // #42
|
||||
Utf8 "InnerClasses"; // #43
|
||||
Utf8 "TestNestmateMembership$TargetSelfHost"; // #44
|
||||
Utf8 "TargetSelfHost"; // #45
|
||||
NameAndType #15 #16; // #46
|
||||
Utf8 "TestNestmateMembership$CallerSelfHost"; // #47
|
||||
Utf8 "CallerSelfHost"; // #48
|
||||
Utf8 "java/lang/Object"; // #49
|
||||
Utf8 "TestNestmateMembership"; // #50
|
||||
Utf8 "java/lang/System"; // #51
|
||||
Utf8 "out"; // #52
|
||||
Utf8 "Ljava/io/PrintStream;"; // #53
|
||||
Utf8 "java/io/PrintStream"; // #54
|
||||
Utf8 "println"; // #55
|
||||
Utf8 "(Ljava/lang/String;)V"; // #56
|
||||
} // Constant Pool
|
||||
|
||||
0x0020; // access
|
||||
#13;// this_cpx
|
||||
#14;// super_cpx
|
||||
|
||||
[] { // Interfaces
|
||||
} // Interfaces
|
||||
|
||||
[] { // fields
|
||||
{ // Member
|
||||
0x000A; // access
|
||||
#15; // name_cpx
|
||||
#16; // sig_cpx
|
||||
[] { // Attributes
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // fields
|
||||
|
||||
[] { // methods
|
||||
{ // Member
|
||||
0x000A; // access
|
||||
#17; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
2; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0xB200011202B60003;
|
||||
0xB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 297;
|
||||
8 298;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#21; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
0; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0xB80004B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 300;
|
||||
3 301;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#22; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
0; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0xB80005B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 303;
|
||||
3 304;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0002; // access
|
||||
#23; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0x2AB70006B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 308;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#24; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
2; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0xBB000759B700084B;
|
||||
0xB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 311;
|
||||
8 312;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#25; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
2; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0xBB000959B7000A4B;
|
||||
0xB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 314;
|
||||
8 315;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#26; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0xB2000B3BB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 322;
|
||||
4 323;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#27; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0xB2000C3BB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 325;
|
||||
4 326;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#28; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
1; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0x102AB3000BB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 328;
|
||||
5 329;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#29; // name_cpx
|
||||
#18; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#19) { // Code
|
||||
1; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0x102AB3000CB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#20) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 331;
|
||||
5 332;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // methods
|
||||
|
||||
[] { // Attributes
|
||||
Attr(#30) { // SourceFile
|
||||
#31;
|
||||
} // end SourceFile
|
||||
;
|
||||
Attr(#32) { // NestHost
|
||||
0x000D; // modified - #13
|
||||
} // end NestHost
|
||||
;
|
||||
Attr(#43) { // InnerClasses
|
||||
[] { // InnerClasses
|
||||
#7 #33 #42 8;
|
||||
#9 #33 #45 8;
|
||||
#13 #33 #48 8;
|
||||
}
|
||||
} // end InnerClasses
|
||||
} // Attributes
|
||||
} // end class TestNestmateMembership$CallerSelfHost
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* Empty class to use as an invalid nest-host class, in the same package as
|
||||
* the test classes.
|
||||
*/
|
||||
public class InvalidNestHost {
|
||||
}
|
||||
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package P1;
|
||||
|
||||
/*
|
||||
* This is used to produce a jcod file in which we modify the
|
||||
* NestMembers attribute to claim that P2.PackagedNestHost.Member
|
||||
* is a member of our nest.
|
||||
*/
|
||||
public class PackagedNestHost {
|
||||
public static class Member {
|
||||
// jcod file will change these to private
|
||||
public Member() {}
|
||||
public static int f;
|
||||
public static void m() {
|
||||
System.out.println("You should never see this!");
|
||||
}
|
||||
}
|
||||
|
||||
// Entry points for main test.
|
||||
// These should fail at runtime as members will now be private
|
||||
// and the nestmate access check should fail due to being in a
|
||||
// different package.
|
||||
|
||||
public static void doInvoke() {
|
||||
P2.PackagedNestHost2.Member.m();
|
||||
}
|
||||
|
||||
public static void doConstruct() {
|
||||
Object o = new P2.PackagedNestHost2.Member();
|
||||
}
|
||||
|
||||
public static void doGetField() {
|
||||
int x = P2.PackagedNestHost2.Member.f;
|
||||
}
|
||||
|
||||
public static void doPutField() {
|
||||
P2.PackagedNestHost2.Member.f = 42;
|
||||
}
|
||||
}
|
@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
// NestMembers attribute is modified to contain P2.PackagedNestHost2.Member
|
||||
|
||||
class P1/PackagedNestHost {
|
||||
0xCAFEBABE;
|
||||
0; // minor version
|
||||
55; // version
|
||||
[] { // Constant Pool
|
||||
; // first element is empty
|
||||
Method #7 #22; // #1
|
||||
Method #3 #23; // #2
|
||||
class #25; // #3
|
||||
Method #3 #22; // #4
|
||||
Field #3 #26; // #5
|
||||
class #27; // #6
|
||||
class #28; // #7
|
||||
class #29; // #8
|
||||
Utf8 "Member"; // #9
|
||||
Utf8 "InnerClasses"; // #10
|
||||
Utf8 "<init>"; // #11
|
||||
Utf8 "()V"; // #12
|
||||
Utf8 "Code"; // #13
|
||||
Utf8 "LineNumberTable"; // #14
|
||||
Utf8 "doInvoke"; // #15
|
||||
Utf8 "doConstruct"; // #16
|
||||
Utf8 "doGetField"; // #17
|
||||
Utf8 "doPutField"; // #18
|
||||
Utf8 "SourceFile"; // #19
|
||||
Utf8 "PackagedNestHost.java"; // #20
|
||||
Utf8 "NestMembers"; // #21
|
||||
NameAndType #11 #12; // #22
|
||||
NameAndType #30 #12; // #23
|
||||
class #31; // #24
|
||||
Utf8 "P2/PackagedNestHost2$Member"; // #25
|
||||
NameAndType #32 #33; // #26
|
||||
Utf8 "P1/PackagedNestHost"; // #27
|
||||
Utf8 "java/lang/Object"; // #28
|
||||
Utf8 "P1/PackagedNestHost$Member"; // #29
|
||||
Utf8 "m"; // #30
|
||||
Utf8 "P2/PackagedNestHost2"; // #31
|
||||
Utf8 "f"; // #32
|
||||
Utf8 "I"; // #33
|
||||
} // Constant Pool
|
||||
|
||||
0x0021; // access
|
||||
#6;// this_cpx
|
||||
#7;// super_cpx
|
||||
|
||||
[] { // Interfaces
|
||||
} // Interfaces
|
||||
|
||||
[] { // fields
|
||||
} // fields
|
||||
|
||||
[] { // methods
|
||||
{ // Member
|
||||
0x0001; // access
|
||||
#11; // name_cpx
|
||||
#12; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#13) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0x2AB70001B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#14) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 31;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#15; // name_cpx
|
||||
#12; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#13) { // Code
|
||||
0; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0xB80002B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#14) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 47;
|
||||
3 48;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#16; // name_cpx
|
||||
#12; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#13) { // Code
|
||||
2; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0xBB000359B700044B;
|
||||
0xB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#14) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 51;
|
||||
8 52;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#17; // name_cpx
|
||||
#12; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#13) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0xB200053BB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#14) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 55;
|
||||
4 56;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#18; // name_cpx
|
||||
#12; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#13) { // Code
|
||||
1; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0x102AB30005B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#14) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 59;
|
||||
5 60;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // methods
|
||||
|
||||
[] { // Attributes
|
||||
Attr(#19) { // SourceFile
|
||||
#20;
|
||||
} // end SourceFile
|
||||
;
|
||||
Attr(#21) { // NestMembers
|
||||
0x00010003; // modified - #3
|
||||
} // end NestMembers
|
||||
;
|
||||
Attr(#10) { // InnerClasses
|
||||
[] { // InnerClasses
|
||||
#8 #6 #9 9;
|
||||
#3 #24 #9 9;
|
||||
}
|
||||
} // end InnerClasses
|
||||
} // Attributes
|
||||
} // end class P1/PackagedNestHost
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package P2;
|
||||
|
||||
/*
|
||||
* This is used to produce a jcod file in which we modify the
|
||||
* NestHost attribute to claim that P2.PackagedNestHost.Member
|
||||
* is a member of the nest of P1.PackagedNestHost.
|
||||
*/
|
||||
public class PackagedNestHost2 {
|
||||
public static class Member {
|
||||
// jcod file will change these to private
|
||||
public Member() {}
|
||||
public static int f;
|
||||
public static void m() {
|
||||
System.out.println("You should never see this!");
|
||||
}
|
||||
|
||||
// Entry points for main test.
|
||||
// These should fail at runtime as members will now be private
|
||||
// and our nest-host won't resolve as it's in a different package.
|
||||
|
||||
public static void doInvoke() {
|
||||
P1.PackagedNestHost.Member.m();
|
||||
}
|
||||
|
||||
public static void doConstruct() {
|
||||
Object o = new P1.PackagedNestHost.Member();
|
||||
}
|
||||
|
||||
public static void doGetField() {
|
||||
int x = P1.PackagedNestHost.Member.f;
|
||||
}
|
||||
|
||||
public static void doPutField() {
|
||||
P1.PackagedNestHost.Member.f = 42;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,268 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
// NestHost attribute is modified to contain P1.PackagedNestHost
|
||||
// Required members are declared private
|
||||
|
||||
class P2/PackagedNestHost2$Member {
|
||||
0xCAFEBABE;
|
||||
0; // minor version
|
||||
55; // version
|
||||
[] { // Constant Pool
|
||||
; // first element is empty
|
||||
Method #10 #26; // #1
|
||||
Field #27 #28; // #2
|
||||
String #29; // #3
|
||||
Method #30 #31; // #4
|
||||
Method #6 #32; // #5
|
||||
class #34; // #6
|
||||
Method #6 #26; // #7
|
||||
Field #6 #37; // #8
|
||||
class #38; // #9
|
||||
class #39; // #10
|
||||
Utf8 "f"; // #11
|
||||
Utf8 "I"; // #12
|
||||
Utf8 "<init>"; // #13
|
||||
Utf8 "()V"; // #14
|
||||
Utf8 "Code"; // #15
|
||||
Utf8 "LineNumberTable"; // #16
|
||||
Utf8 "m"; // #17
|
||||
Utf8 "doInvoke"; // #18
|
||||
Utf8 "doConstruct"; // #19
|
||||
Utf8 "doGetField"; // #20
|
||||
Utf8 "doPutField"; // #21
|
||||
Utf8 "SourceFile"; // #22
|
||||
Utf8 "PackagedNestHost2.java"; // #23
|
||||
Utf8 "NestHost"; // #24
|
||||
class #40; // #25
|
||||
NameAndType #13 #14; // #26
|
||||
class #41; // #27
|
||||
NameAndType #42 #43; // #28
|
||||
Utf8 "You should never see this!"; // #29
|
||||
class #44; // #30
|
||||
NameAndType #45 #46; // #31
|
||||
NameAndType #17 #14; // #32
|
||||
class #47; // #33
|
||||
Utf8 "P1/PackagedNestHost$Member"; // #34
|
||||
Utf8 "Member"; // #35
|
||||
Utf8 "InnerClasses"; // #36
|
||||
NameAndType #11 #12; // #37
|
||||
Utf8 "P2/PackagedNestHost2$Member"; // #38
|
||||
Utf8 "java/lang/Object"; // #39
|
||||
Utf8 "P2/PackagedNestHost2"; // #40
|
||||
Utf8 "java/lang/System"; // #41
|
||||
Utf8 "out"; // #42
|
||||
Utf8 "Ljava/io/PrintStream;"; // #43
|
||||
Utf8 "java/io/PrintStream"; // #44
|
||||
Utf8 "println"; // #45
|
||||
Utf8 "(Ljava/lang/String;)V"; // #46
|
||||
Utf8 "P1/PackagedNestHost"; // #47
|
||||
} // Constant Pool
|
||||
|
||||
0x0021; // access
|
||||
#9;// this_cpx
|
||||
#10;// super_cpx
|
||||
|
||||
[] { // Interfaces
|
||||
} // Interfaces
|
||||
|
||||
[] { // fields
|
||||
{ // Member
|
||||
0x000A; // access - modified
|
||||
#11; // name_cpx
|
||||
#12; // sig_cpx
|
||||
[] { // Attributes
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // fields
|
||||
|
||||
[] { // methods
|
||||
{ // Member
|
||||
0x0002; // access - modified
|
||||
#13; // name_cpx
|
||||
#14; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#15) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0x2AB70001B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#16) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 34;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x000A; // access - modified
|
||||
#17; // name_cpx
|
||||
#14; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#15) { // Code
|
||||
2; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0xB200021203B60004;
|
||||
0xB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#16) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 37;
|
||||
8 38;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#18; // name_cpx
|
||||
#14; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#15) { // Code
|
||||
0; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0xB80005B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#16) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 45;
|
||||
3 46;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#19; // name_cpx
|
||||
#14; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#15) { // Code
|
||||
2; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0xBB000659B700074B;
|
||||
0xB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#16) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 49;
|
||||
8 50;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#20; // name_cpx
|
||||
#14; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#15) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0xB200083BB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#16) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 53;
|
||||
4 54;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x0009; // access
|
||||
#21; // name_cpx
|
||||
#14; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#15) { // Code
|
||||
1; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0x102AB30008B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#16) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 57;
|
||||
5 58;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // methods
|
||||
|
||||
[] { // Attributes
|
||||
Attr(#22) { // SourceFile
|
||||
#23;
|
||||
} // end SourceFile
|
||||
;
|
||||
Attr(#24) { // NestHost
|
||||
0x0021; // modified - #33
|
||||
} // end NestHost
|
||||
;
|
||||
Attr(#36) { // InnerClasses
|
||||
[] { // InnerClasses
|
||||
#6 #33 #35 9;
|
||||
#9 #25 #35 9;
|
||||
}
|
||||
} // end InnerClasses
|
||||
} // Attributes
|
||||
} // end class P2/PackagedNestHost2$Member
|
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
// all members are declared private
|
||||
|
||||
class P1/PackagedNestHost$Member {
|
||||
0xCAFEBABE;
|
||||
0; // minor version
|
||||
55; // version
|
||||
[] { // Constant Pool
|
||||
; // first element is empty
|
||||
Method #6 #18; // #1
|
||||
Field #19 #20; // #2
|
||||
String #21; // #3
|
||||
Method #22 #23; // #4
|
||||
class #24; // #5
|
||||
class #27; // #6
|
||||
Utf8 "f"; // #7
|
||||
Utf8 "I"; // #8
|
||||
Utf8 "<init>"; // #9
|
||||
Utf8 "()V"; // #10
|
||||
Utf8 "Code"; // #11
|
||||
Utf8 "LineNumberTable"; // #12
|
||||
Utf8 "m"; // #13
|
||||
Utf8 "SourceFile"; // #14
|
||||
Utf8 "PackagedNestHost.java"; // #15
|
||||
Utf8 "NestHost"; // #16
|
||||
class #28; // #17
|
||||
NameAndType #9 #10; // #18
|
||||
class #29; // #19
|
||||
NameAndType #30 #31; // #20
|
||||
Utf8 "You should never see this!"; // #21
|
||||
class #32; // #22
|
||||
NameAndType #33 #34; // #23
|
||||
Utf8 "P1/PackagedNestHost$Member"; // #24
|
||||
Utf8 "Member"; // #25
|
||||
Utf8 "InnerClasses"; // #26
|
||||
Utf8 "java/lang/Object"; // #27
|
||||
Utf8 "P1/PackagedNestHost"; // #28
|
||||
Utf8 "java/lang/System"; // #29
|
||||
Utf8 "out"; // #30
|
||||
Utf8 "Ljava/io/PrintStream;"; // #31
|
||||
Utf8 "java/io/PrintStream"; // #32
|
||||
Utf8 "println"; // #33
|
||||
Utf8 "(Ljava/lang/String;)V"; // #34
|
||||
} // Constant Pool
|
||||
|
||||
0x0021; // access
|
||||
#5;// this_cpx
|
||||
#6;// super_cpx
|
||||
|
||||
[] { // Interfaces
|
||||
} // Interfaces
|
||||
|
||||
[] { // fields
|
||||
{ // Member
|
||||
0x000A; // access - modified
|
||||
#7; // name_cpx
|
||||
#8; // sig_cpx
|
||||
[] { // Attributes
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // fields
|
||||
|
||||
[] { // methods
|
||||
{ // Member
|
||||
0x0002; // access - modified
|
||||
#9; // name_cpx
|
||||
#10; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#11) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0x2AB70001B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#12) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 34;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x000A; // access - modified
|
||||
#13; // name_cpx
|
||||
#10; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#11) { // Code
|
||||
2; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0xB200021203B60004;
|
||||
0xB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#12) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 37;
|
||||
8 38;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // methods
|
||||
|
||||
[] { // Attributes
|
||||
Attr(#14) { // SourceFile
|
||||
#15;
|
||||
} // end SourceFile
|
||||
;
|
||||
Attr(#16) { // NestHost
|
||||
0x0011;
|
||||
} // end NestHost
|
||||
;
|
||||
Attr(#26) { // InnerClasses
|
||||
[] { // InnerClasses
|
||||
#5 #17 #25 9;
|
||||
}
|
||||
} // end InnerClasses
|
||||
} // Attributes
|
||||
} // end class P1/PackagedNestHost$Member
|
@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
// NestHost attribute refers to non-existent class
|
||||
|
||||
class TestNestmateMembership$TargetMissingHost {
|
||||
0xCAFEBABE;
|
||||
0; // minor version
|
||||
55; // version
|
||||
[] { // Constant Pool
|
||||
; // first element is empty
|
||||
Method #8 #22; // #1
|
||||
String #23; // #2
|
||||
Field #7 #24; // #3
|
||||
Field #25 #26; // #4
|
||||
String #27; // #5
|
||||
Method #28 #29; // #6
|
||||
class #30; // #7
|
||||
class #33; // #8
|
||||
Utf8 "msg"; // #9
|
||||
Utf8 "Ljava/lang/String;"; // #10
|
||||
Utf8 "f"; // #11
|
||||
Utf8 "I"; // #12
|
||||
Utf8 "<init>"; // #13
|
||||
Utf8 "()V"; // #14
|
||||
Utf8 "Code"; // #15
|
||||
Utf8 "LineNumberTable"; // #16
|
||||
Utf8 "m"; // #17
|
||||
Utf8 "SourceFile"; // #18
|
||||
Utf8 "TestNestmateMembership.java"; // #19
|
||||
Utf8 "NestHost"; // #20
|
||||
class #34; // #21
|
||||
NameAndType #13 #14; // #22
|
||||
Utf8 "NoTargetMissingHost"; // #23
|
||||
NameAndType #9 #10; // #24
|
||||
class #35; // #25
|
||||
NameAndType #36 #37; // #26
|
||||
Utf8 "TargetMissingHost.m() - java version"; // #27
|
||||
class #38; // #28
|
||||
NameAndType #39 #40; // #29
|
||||
Utf8 "TestNestmateMembership$TargetMissingHost"; // #30
|
||||
Utf8 "TargetMissingHost"; // #31
|
||||
Utf8 "InnerClasses"; // #32
|
||||
Utf8 "java/lang/Object"; // #33
|
||||
Utf8 "TestNestmateMembership"; // #34
|
||||
Utf8 "java/lang/System"; // #35
|
||||
Utf8 "out"; // #36
|
||||
Utf8 "Ljava/io/PrintStream;"; // #37
|
||||
Utf8 "java/io/PrintStream"; // #38
|
||||
Utf8 "println"; // #39
|
||||
Utf8 "(Ljava/lang/String;)V"; // #40
|
||||
class #23; // #41 - added
|
||||
} // Constant Pool
|
||||
|
||||
0x0020; // access
|
||||
#7;// this_cpx
|
||||
#8;// super_cpx
|
||||
|
||||
[] { // Interfaces
|
||||
} // Interfaces
|
||||
|
||||
[] { // fields
|
||||
{ // Member
|
||||
0x0000; // access
|
||||
#9; // name_cpx
|
||||
#10; // sig_cpx
|
||||
[] { // Attributes
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x000A; // access
|
||||
#11; // name_cpx
|
||||
#12; // sig_cpx
|
||||
[] { // Attributes
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // fields
|
||||
|
||||
[] { // methods
|
||||
{ // Member
|
||||
0x0002; // access
|
||||
#13; // name_cpx
|
||||
#14; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#15) { // Code
|
||||
2; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0x2AB700012A1202B5;
|
||||
0x0003B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#16) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 354;
|
||||
4 353;
|
||||
10 354;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x000A; // access
|
||||
#17; // name_cpx
|
||||
#14; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#15) { // Code
|
||||
2; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0xB200041205B60006;
|
||||
0xB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#16) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 357;
|
||||
8 358;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // methods
|
||||
|
||||
[] { // Attributes
|
||||
Attr(#18) { // SourceFile
|
||||
#19;
|
||||
} // end SourceFile
|
||||
;
|
||||
Attr(#20) { // NestHost
|
||||
0x0029; // modified #41
|
||||
} // end NestHost
|
||||
;
|
||||
Attr(#32) { // InnerClasses
|
||||
[] { // InnerClasses
|
||||
#7 #21 #31 8;
|
||||
}
|
||||
} // end InnerClasses
|
||||
} // Attributes
|
||||
} // end class TestNestmateMembership$TargetMissingHost
|
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
// NestHost attribute deleted
|
||||
|
||||
class TestNestmateMembership$TargetNoHost {
|
||||
0xCAFEBABE;
|
||||
0; // minor version
|
||||
55; // version
|
||||
[] { // Constant Pool
|
||||
; // first element is empty
|
||||
Method #6 #18; // #1
|
||||
Field #19 #20; // #2
|
||||
String #21; // #3
|
||||
Method #22 #23; // #4
|
||||
class #24; // #5
|
||||
class #27; // #6
|
||||
Utf8 "f"; // #7
|
||||
Utf8 "I"; // #8
|
||||
Utf8 "<init>"; // #9
|
||||
Utf8 "()V"; // #10
|
||||
Utf8 "Code"; // #11
|
||||
Utf8 "LineNumberTable"; // #12
|
||||
Utf8 "m"; // #13
|
||||
Utf8 "SourceFile"; // #14
|
||||
Utf8 "TestNestmateMembership.java"; // #15
|
||||
Utf8 "NestHost"; // #16
|
||||
class #28; // #17
|
||||
NameAndType #9 #10; // #18
|
||||
class #29; // #19
|
||||
NameAndType #30 #31; // #20
|
||||
Utf8 "TargetNoHost.m() - java version"; // #21
|
||||
class #32; // #22
|
||||
NameAndType #33 #34; // #23
|
||||
Utf8 "TestNestmateMembership$TargetNoHost"; // #24
|
||||
Utf8 "TargetNoHost"; // #25
|
||||
Utf8 "InnerClasses"; // #26
|
||||
Utf8 "java/lang/Object"; // #27
|
||||
Utf8 "TestNestmateMembership"; // #28
|
||||
Utf8 "java/lang/System"; // #29
|
||||
Utf8 "out"; // #30
|
||||
Utf8 "Ljava/io/PrintStream;"; // #31
|
||||
Utf8 "java/io/PrintStream"; // #32
|
||||
Utf8 "println"; // #33
|
||||
Utf8 "(Ljava/lang/String;)V"; // #34
|
||||
} // Constant Pool
|
||||
|
||||
0x0020; // access
|
||||
#5;// this_cpx
|
||||
#6;// super_cpx
|
||||
|
||||
[] { // Interfaces
|
||||
} // Interfaces
|
||||
|
||||
[] { // fields
|
||||
{ // Member
|
||||
0x000A; // access
|
||||
#7; // name_cpx
|
||||
#8; // sig_cpx
|
||||
[] { // Attributes
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // fields
|
||||
|
||||
[] { // methods
|
||||
{ // Member
|
||||
0x0002; // access
|
||||
#9; // name_cpx
|
||||
#10; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#11) { // Code
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[]{
|
||||
0x2AB70001B1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#12) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 345;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member
|
||||
0x000A; // access
|
||||
#13; // name_cpx
|
||||
#10; // sig_cpx
|
||||
[] { // Attributes
|
||||
Attr(#11) { // Code
|
||||
2; // max_stack
|
||||
0; // max_locals
|
||||
Bytes[]{
|
||||
0xB200021203B60004;
|
||||
0xB1;
|
||||
};
|
||||
[] { // Traps
|
||||
} // end Traps
|
||||
[] { // Attributes
|
||||
Attr(#12) { // LineNumberTable
|
||||
[] { // LineNumberTable
|
||||
0 348;
|
||||
8 349;
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // methods
|
||||
|
||||
[] { // Attributes
|
||||
Attr(#14) { // SourceFile
|
||||
#15;
|
||||
} // end SourceFile
|
||||
;
|
||||
Attr(#26) { // InnerClasses
|
||||
[] { // InnerClasses
|
||||
#5 #17 #25 8;
|
||||
}
|
||||
} // end InnerClasses
|
||||
} // Attributes
|
||||
} // end class TestNestmateMembership$TargetNoHost
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user