This commit is contained in:
Jiangli Zhou 2014-11-11 16:54:24 +00:00
commit 7251d384ac
6 changed files with 37 additions and 20 deletions

View File

@ -122,7 +122,7 @@ SA_LFLAGS = $(SA_LD_FLAGS) -nologo -subsystem:console -machine:$(MACHINE)
SA_LFLAGS = $(SA_LFLAGS) -map -debug
!endif
!if "$(BUILDARCH)" == "i486"
SA_LFLAGS = $(SAFESEH_FLAG) $(SA_LFLAGS)
SA_LFLAGS = /SAFESEH $(SA_LFLAGS)
!endif
SA_CFLAGS = $(SA_CFLAGS) $(MP_FLAG)

View File

@ -2059,7 +2059,7 @@ methodHandle ClassFileParser::parse_method(bool is_interface,
u2** localvariable_table_start;
u2* localvariable_type_table_length;
u2** localvariable_type_table_start;
u2 method_parameters_length = 0;
int method_parameters_length = -1;
u1* method_parameters_data = NULL;
bool method_parameters_seen = false;
bool parsed_code_attribute = false;
@ -2278,7 +2278,8 @@ methodHandle ClassFileParser::parse_method(bool is_interface,
}
method_parameters_seen = true;
method_parameters_length = cfs->get_u1_fast();
if (method_attribute_length != (method_parameters_length * 4u) + 1u) {
const u2 real_length = (method_parameters_length * 4u) + 1u;
if (method_attribute_length != real_length) {
classfile_parse_error(
"Invalid MethodParameters method attribute length %u in class file",
method_attribute_length, CHECK_(nullHandle));
@ -2288,7 +2289,7 @@ methodHandle ClassFileParser::parse_method(bool is_interface,
cfs->skip_u2_fast(method_parameters_length);
// ignore this attribute if it cannot be reflected
if (!SystemDictionary::Parameter_klass_loaded())
method_parameters_length = 0;
method_parameters_length = -1;
} else if (method_attribute_name == vmSymbols::tag_synthetic()) {
if (method_attribute_length != 0) {
classfile_parse_error(

View File

@ -116,7 +116,11 @@ int ConstMethod::size(int code_size,
if (sizes->generic_signature_index() != 0) {
extra_bytes += sizeof(u2);
}
if (sizes->method_parameters_length() > 0) {
// This has to be a less-than-or-equal check, because we might be
// storing information from a zero-length MethodParameters
// attribute. We have to store these, because in some cases, they
// cause the reflection API to throw a MalformedParametersException.
if (sizes->method_parameters_length() >= 0) {
extra_bytes += sizeof(u2);
extra_bytes += sizes->method_parameters_length() * sizeof(MethodParametersElement);
}
@ -237,7 +241,7 @@ void ConstMethod::set_inlined_tables_length(InlineTableSizes* sizes) {
_flags |= _has_linenumber_table;
if (sizes->generic_signature_index() != 0)
_flags |= _has_generic_signature;
if (sizes->method_parameters_length() > 0)
if (sizes->method_parameters_length() >= 0)
_flags |= _has_method_parameters;
if (sizes->checked_exceptions_length() > 0)
_flags |= _has_checked_exceptions;
@ -272,7 +276,7 @@ void ConstMethod::set_inlined_tables_length(InlineTableSizes* sizes) {
if (sizes->generic_signature_index() != 0)
*(generic_signature_index_addr()) = sizes->generic_signature_index();
// New data should probably go here.
if (sizes->method_parameters_length() > 0)
if (sizes->method_parameters_length() >= 0)
*(method_parameters_length_addr()) = sizes->method_parameters_length();
if (sizes->checked_exceptions_length() > 0)
*(checked_exceptions_length_addr()) = sizes->checked_exceptions_length();
@ -283,7 +287,7 @@ void ConstMethod::set_inlined_tables_length(InlineTableSizes* sizes) {
}
int ConstMethod::method_parameters_length() const {
return has_method_parameters() ? *(method_parameters_length_addr()) : 0;
return has_method_parameters() ? *(method_parameters_length_addr()) : -1;
}
MethodParametersElement* ConstMethod::method_parameters_start() const {

View File

@ -372,6 +372,11 @@ public:
ExceptionTableElement* exception_table_start() const;
// method parameters table
// This returns -1 if no parameters are present, a non-negative
// value otherwise. Note: sometimes, there are 0-length parameters
// attributes that must be reported up to the reflection API all the
// same.
int method_parameters_length() const;
MethodParametersElement* method_parameters_start() const;

View File

@ -1657,7 +1657,17 @@ JVM_ENTRY(jobjectArray, JVM_GetMethodParameters(JNIEnv *env, jobject method))
Handle reflected_method (THREAD, JNIHandles::resolve_non_null(method));
const int num_params = mh->method_parameters_length();
if (0 != num_params) {
if (num_params < 0) {
// A -1 return value from method_parameters_length means there is no
// parameter data. Return null to indicate this to the reflection
// API.
assert(num_params == -1, "num_params should be -1 if it is less than zero");
return (jobjectArray)NULL;
} else {
// Otherwise, we return something up to reflection, even if it is
// a zero-length array. Why? Because in some cases this can
// trigger a MalformedParametersException.
// make sure all the symbols are properly formatted
for (int i = 0; i < num_params; i++) {
MethodParametersElement* params = mh->method_parameters_start();
@ -1685,8 +1695,6 @@ JVM_ENTRY(jobjectArray, JVM_GetMethodParameters(JNIEnv *env, jobject method))
result->obj_at_put(i, param);
}
return (jobjectArray)JNIHandles::make_local(env, result());
} else {
return (jobjectArray)NULL;
}
}
JVM_END

View File

@ -806,17 +806,16 @@ oop Reflection::new_field(fieldDescriptor* fd, TRAPS) {
oop Reflection::new_parameter(Handle method, int index, Symbol* sym,
int flags, TRAPS) {
Handle name;
// A null symbol here translates to the empty string
if(NULL != sym) {
name = java_lang_String::create_from_symbol(sym, CHECK_NULL);
} else {
name = java_lang_String::create_from_str("", CHECK_NULL);
}
Handle rh = java_lang_reflect_Parameter::create(CHECK_NULL);
java_lang_reflect_Parameter::set_name(rh(), name());
if(NULL != sym) {
Handle name = java_lang_String::create_from_symbol(sym, CHECK_NULL);
java_lang_reflect_Parameter::set_name(rh(), name());
} else {
java_lang_reflect_Parameter::set_name(rh(), NULL);
}
java_lang_reflect_Parameter::set_modifiers(rh(), flags);
java_lang_reflect_Parameter::set_executable(rh(), method());
java_lang_reflect_Parameter::set_index(rh(), index);