/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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 "precompiled.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/verifier.hpp"
#include "classfile/vmSymbols.hpp"
#include "interpreter/linkResolver.hpp"
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.inline.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.hpp"
#include "runtime/arguments.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/reflection.hpp"
#include "runtime/reflectionUtils.hpp"
#include "runtime/signature.hpp"
#include "runtime/vframe.hpp"
if (jthread->has_last_Java_frame()) {
// skip over any frames belonging to java.lang.Class
}
// this frame is a likely suspect
if (s != NULL) {
source_file = s->as_C_string();
}
}
}
// print in a single call to reduce interleaving between threads
if (source_file != NULL) {
} else {
}
}
}
return NULL;
}
// regular objects are not boxed
}
}
return result;
}
}
}
// Note: box is really the unboxed oop. It might even be a Short, etc.!
return T_OBJECT;
}
switch (wide_type) {
case T_BOOLEAN:
case T_BYTE:
case T_CHAR:
break; // fail
case T_SHORT:
switch (current_type) {
case T_BYTE:
return;
}
break; // fail
case T_INT:
switch (current_type) {
case T_BYTE:
return;
case T_CHAR:
return;
case T_SHORT:
return;
}
break; // fail
case T_LONG:
switch (current_type) {
case T_BYTE:
return;
case T_CHAR:
return;
case T_SHORT:
return;
case T_INT:
return;
}
break; // fail
case T_FLOAT:
switch (current_type) {
case T_BYTE:
return;
case T_CHAR:
return;
case T_SHORT:
return;
case T_INT:
return;
case T_LONG:
return;
}
break; // fail
case T_DOUBLE:
switch (current_type) {
case T_BYTE:
return;
case T_CHAR:
return;
case T_SHORT:
return;
case T_INT:
return;
case T_FLOAT:
return;
case T_LONG:
return;
}
break; // fail
default:
break; // fail
}
}
if (!a->is_within_bounds(index)) {
}
if (a->is_objArray()) {
return T_OBJECT;
} else {
switch (type) {
case T_BOOLEAN:
break;
case T_CHAR:
break;
case T_FLOAT:
break;
case T_DOUBLE:
break;
case T_BYTE:
break;
case T_SHORT:
break;
case T_INT:
break;
case T_LONG:
break;
default:
return T_ILLEGAL;
}
return type;
}
}
if (!a->is_within_bounds(index)) {
}
if (a->is_objArray()) {
if (value_type == T_OBJECT) {
}
}
}
} else {
if (array_type != value_type) {
// The widen operation can potentially throw an exception, but cannot block,
// so typeArrayOop a is safe if the call succeeds.
}
switch (array_type) {
case T_BOOLEAN:
break;
case T_CHAR:
break;
case T_FLOAT:
break;
case T_DOUBLE:
break;
case T_BYTE:
break;
case T_SHORT:
break;
case T_INT:
break;
case T_LONG:
break;
default:
}
}
}
} else {
}
}
}
if (element_mirror == NULL) {
}
if (length < 0) {
}
} else {
}
}
}
if (element_mirror == NULL) {
}
}
for (int i = 0; i < len; i++) {
if (d < 0) {
}
dimensions[i] = d;
}
} else {
}
}
}
}
return NULL;
}
return NULL;
}
#ifdef ASSERT
} else {
}
} else {
}
#endif //ASSERT
return result;
}
bool Reflection::reflect_check_access(klassOop field_class, AccessFlags acc, klassOop target_class, bool is_method_invoke, TRAPS) {
// field_class : declaring class
// acc : declared field access
// target_class : for protected
// Check if field or method is accessible to client. Throw an
// IllegalAccessException and return false if not.
// The "client" is the class associated with the nearest real frame
// getCallerClass already skips Method.invoke frames, so pass 0 in
// that case (same as classic).
klassOop client_class = ((JavaThread *)THREAD)->security_get_caller_class(is_method_invoke ? 0 : 1);
if (client_class != field_class) {
acc,
false)) {
}
}
// Additional test for protected members: JLS 6.6.2
if (acc.is_protected()) {
if (target_class != client_class) {
}
}
}
}
// Passed all tests
return true;
}
bool Reflection::verify_class_access(klassOop current_class, klassOop new_class, bool classloader_only) {
// Verify that current_class can access new_class. If the classloader_only
// flag is set, we automatically allow any accesses in which current_class
// doesn't have a classloader.
if ((current_class == NULL) ||
(current_class == new_class) ||
return true;
}
// New (1.4) reflection implementation. Allow all accesses from
// sun/reflect/MagicAccessorImpl subclasses to succeed trivially.
if ( JDK_Version::is_gte_jdk14x_version()
&& Klass::cast(current_class)->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) {
return true;
}
}
for (;;) {
if (hc == host_klass) return true;
// There's no way to make a host class loop short of patching memory.
// Therefore there cannot be a loop here unles there's another bug.
// Still, let's check for it.
}
}
// If either is on the other's host_klass chain, access is OK,
// because one is inside the other.
return true;
if (RelaxAccessControlCheck ||
return classloader_only &&
} else {
return false;
}
}
bool classloader_only,
bool protected_restriction) {
// Verify that current_class can access a field of field_class, where that
// field's access bits are "access". We assume that we've already verified
// that current_class can access field_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
// 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.
//
if ((current_class == NULL) ||
(current_class == field_class) ||
return true;
}
if (access.is_protected()) {
if (!protected_restriction) {
// See if current_class is a subclass of field_class
current_class == resolved_class ||
field_class == resolved_class ||
return true;
}
}
}
}
return true;
}
// New (1.4) reflection implementation. Allow all accesses from
// sun/reflect/MagicAccessorImpl subclasses to succeed trivially.
if ( JDK_Version::is_gte_jdk14x_version()
&& Klass::cast(current_class)->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) {
return true;
}
return can_relax_access_check_for(
}
}
}
// Checks that the 'outer' klass has declared 'inner' as being an inner klass. If not,
// throw an incompatible class change exception
// If inner_is_member, require the inner to be a member of the outer.
// If !inner_is_member, require the inner to be anonymous (a non-member).
// Caller is responsible for figuring out in advance which case must be true.
bool inner_is_member, TRAPS) {
if (o == outer()) {
if (i == inner()) {
return;
}
}
}
if (i == inner()) {
return;
}
}
}
// 'inner' not declared as an inner klass in outer
"%s and %s disagree on InnerClasses attribute",
outer->external_name(),
);
}
// Utility method converting a single SignatureStream element into java.lang.Class instance
default:
case T_OBJECT:
case T_ARRAY:
name,
true, CHECK_NULL);
if (TraceClassResolution) {
}
return k->java_mirror();
};
}
objArrayHandle Reflection::get_parameter_types(methodHandle method, int parameter_count, oop* return_type, TRAPS) {
// Allocate array holding parameter types (java.lang.Class instances)
objArrayOop m = oopFactory::new_objArray(SystemDictionary::Class_klass(), parameter_count, CHECK_(objArrayHandle()));
int index = 0;
// Collect parameter types
while (!ss.at_return_type()) {
}
if (return_type != NULL) {
// Collect return type as well
}
return mirrors;
}
}
// Basic types
}
if (TraceClassResolution) {
}
}
oop Reflection::new_method(methodHandle method, bool intern_name, bool for_constant_pool_access, TRAPS) {
// In jdk1.2.x, getMethods on an interface erroneously includes <clinit>, thus the complicated assert.
// Also allow sun.reflect.ConstantPool to refer to <clinit> methods as java.lang.reflect.Methods.
&& Klass::cast(method()->method_holder())->is_interface() && JDK_Version::is_jdk12x_version()), "should call new_constructor instead");
objArrayHandle parameter_types = get_parameter_types(method, parameter_count, &return_type_oop, CHECK_NULL);
if (intern_name) {
// intern_name is only true with UseNewReflection
} else {
}
if (java_lang_reflect_Method::has_signature_field() &&
}
}
}
}
return mh();
}
}
}
}
return ch();
}
if (intern_name) {
// intern_name is only true with UseNewReflection
} else {
}
// Note the ACC_ANNOTATION bit, which is a per-class access flag, is never set here.
java_lang_reflect_Field::set_modifiers(rh(), fd->access_flags().as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS);
if (java_lang_reflect_Field::has_signature_field() &&
fd->has_generic_signature()) {
}
if (java_lang_reflect_Field::has_annotations_field()) {
}
return rh();
}
KlassHandle(), false, true,
CHECK_(methodHandle()));
return info.selected_method();
}
// Ensure klass is initialized
if (is_static) {
// ignore receiver argument
} else {
// check for null receiver
}
// Check class of receiver against class declaring method
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "object is not an instance of declaring class");
}
// target klass is receiver's klass
// no need to resolve if method is private or <init>
if (reflected_method->is_private() || reflected_method->name() == vmSymbols::object_initializer_name()) {
} else {
// resolve based on the receiver
// resolve interface call
// new default: 6531596
// Match resolution errors with those thrown due to reflection inlining
// Linktime resolution & IllegalAccessCheck already done by Class.getMethod()
if (HAS_PENDING_EXCEPTION) {
// Method resolution threw an exception; wrap it in an InvocationTargetException
&args);
}
} else {
}
} else {
// if the method can be overridden, we resolve using the vtable index.
// target_klass might be an arrayKlassOop but all vtables start at
// the same place. The cast is to avoid virtual call and assertion.
}
// Check for abstract methods as well
if (method->is_abstract()) {
// new default: 6531596
&args);
} else {
}
}
}
}
}
}
// I believe this is a ShouldNotGetHere case which requires
// an internal vtable bug. If you ever get this please let Karen know.
reflected_method->name(),
reflected_method->signature()));
}
// In the JDK 1.4 reflection implementation, the security check is
// done at the Java level
// Access checking (unless overridden by Method)
if (!override) {
bool access = Reflection::reflect_check_access(klass(), reflected_method->access_flags(), target_klass(), is_method_invoke, CHECK_NULL);
if (!access) {
return NULL; // exception
}
}
}
} // !(Universe::is_gte_jdk14x_version() && UseNewReflection)
// Check number of arguments
}
// Create object to contain parameters for the JavaCall
if (!is_static) {
}
for (int i = 0; i < args_len; i++) {
}
switch (ptype) {
default:
}
} else {
}
}
}
}
// All oops (including receiver) is passed in as Handles. An potential oop is returned as an
// oop (i.e., NOT as an handle)
if (HAS_PENDING_EXCEPTION) {
// Method threw an exception; wrap it in an InvocationTargetException
&args);
} else {
}
}
switch (narrow_type) {
case T_BOOLEAN:
return;
case T_BYTE:
return;
case T_CHAR:
return;
case T_SHORT:
return;
default:
break; // fail
}
}
}
// This would be nicer if, say, java.lang.reflect.Method was a subclass
// of java.lang.reflect.Constructor
objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Method::parameter_types(method_mirror)));
} else {
}
if (m == NULL) {
}
}
objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Constructor::parameter_types(constructor_mirror)));
if (m == NULL) {
}
// Make sure klass gets initialize
// Create new instance (the receiver)
// Ignore result from call and return receiver
return receiver();
}