fix a couple of OpenJDK reflection bugs

We weren't wrapping exceptions thrown by invoked methods in
InvocationTargetExceptions in JVM_InvokeMethod or
JVM_NewInstanceFromConstructor.  Also, JVM_GetCallerClass is supposed
to ignore Method.invoke frames when walking the stack.
This commit is contained in:
Joel Dice 2012-09-22 20:22:33 -06:00
parent 2d9bbec214
commit e20c5cd9c6
3 changed files with 35 additions and 6 deletions

View File

@ -3802,7 +3802,7 @@ EXPORT(JVM_GetCallerClass)(Thread* t, int target)
{
ENTER(t, Thread::ActiveState);
object method = getCaller(t, target);
object method = getCaller(t, target, true);
return method ? makeLocalReference
(t, getJClass(t, methodClass(t, method))) : 0;
@ -4568,6 +4568,14 @@ jvmInvokeMethod(Thread* t, uintptr_t* arguments)
unsigned returnCode = methodReturnCode(t, vmMethod);
THREAD_RESOURCE0(t, {
if (t->exception) {
object exception = t->exception;
t->exception = makeThrowable
(t, Machine::InvocationTargetExceptionType, 0, 0, exception);
}
});
object result;
if (args) {
result = t->m->processor->invokeArray
@ -4606,6 +4614,14 @@ jvmNewInstanceFromConstructor(Thread* t, uintptr_t* arguments)
(t, jclassVmClass(t, jconstructorClazz(t, *constructor))),
jconstructorSlot(t, *constructor));
THREAD_RESOURCE0(t, {
if (t->exception) {
object exception = t->exception;
t->exception = makeThrowable
(t, Machine::InvocationTargetExceptionType, 0, 0, exception);
}
});
if (args) {
t->m->processor->invokeArray(t, method, instance, *args);
} else {

View File

@ -4839,15 +4839,27 @@ parseUtf8(Thread* t, const char* data, unsigned length)
}
object
getCaller(Thread* t, unsigned target)
getCaller(Thread* t, unsigned target, bool skipMethodInvoke)
{
class Visitor: public Processor::StackVisitor {
public:
Visitor(Thread* t, unsigned target):
t(t), method(0), count(0), target(target)
Visitor(Thread* t, unsigned target, bool skipMethodInvoke):
t(t), method(0), count(0), target(target),
skipMethodInvoke(skipMethodInvoke)
{ }
virtual bool visit(Processor::StackWalker* walker) {
if (skipMethodInvoke
and methodClass
(t, walker->method()) == type(t, Machine::JmethodType)
and strcmp
(&byteArrayBody(t, methodName(t, walker->method()), 0),
reinterpret_cast<const int8_t*>("invoke"))
== 0)
{
return true;
}
if (count == target) {
method = walker->method();
return false;
@ -4861,7 +4873,8 @@ getCaller(Thread* t, unsigned target)
object method;
unsigned count;
unsigned target;
} v(t, target);
bool skipMethodInvoke;
} v(t, target, skipMethodInvoke);
t->m->processor->walkStack(t, &v);

View File

@ -3801,7 +3801,7 @@ populateMultiArray(Thread* t, object array, int32_t* counts,
unsigned index, unsigned dimensions);
object
getCaller(Thread* t, unsigned target);
getCaller(Thread* t, unsigned target, bool skipMethodInvoke = false);
object
defineClass(Thread* t, object loader, const uint8_t* buffer, unsigned length);