mirror of
https://github.com/corda/corda.git
synced 2025-01-28 23:24:29 +00:00
fix Method.invoke() to handle polymorphism properly
This commit is contained in:
parent
38e2abb818
commit
256bcf04e0
@ -163,16 +163,7 @@ Class_primitiveClass(Thread* t, jclass, jchar name)
|
|||||||
void
|
void
|
||||||
Class_initialize(Thread* t, jobject this_)
|
Class_initialize(Thread* t, jobject this_)
|
||||||
{
|
{
|
||||||
acquire(t, t->vm->classLock);
|
initClass(t, *this_);
|
||||||
object c = *this_;
|
|
||||||
if (classVmFlags(t, c) & NeedInitFlag
|
|
||||||
and (classVmFlags(t, c) & InitFlag) == 0)
|
|
||||||
{
|
|
||||||
classVmFlags(t, c) |= InitFlag;
|
|
||||||
run(t, classInitializer(t, c), 0);
|
|
||||||
} else {
|
|
||||||
release(t, t->vm->classLock);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jboolean
|
jboolean
|
||||||
|
@ -1131,6 +1131,9 @@ class Machine {
|
|||||||
unsigned heapPoolIndex;
|
unsigned heapPoolIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
object
|
||||||
|
run(Thread* t, object method, object this_, ...);
|
||||||
|
|
||||||
object
|
object
|
||||||
run(Thread* t, const char* className, const char* methodName,
|
run(Thread* t, const char* className, const char* methodName,
|
||||||
const char* methodSpec, object this_, ...);
|
const char* methodSpec, object this_, ...);
|
||||||
@ -2111,6 +2114,20 @@ resolveClass(Thread* t, object spec);
|
|||||||
object
|
object
|
||||||
resolveObjectArrayClass(Thread* t, object elementSpec);
|
resolveObjectArrayClass(Thread* t, object elementSpec);
|
||||||
|
|
||||||
|
inline void
|
||||||
|
initClass(Thread* t, object c)
|
||||||
|
{
|
||||||
|
acquire(t, t->vm->classLock);
|
||||||
|
if (classVmFlags(t, c) & NeedInitFlag
|
||||||
|
and (classVmFlags(t, c) & InitFlag) == 0)
|
||||||
|
{
|
||||||
|
classVmFlags(t, c) |= InitFlag;
|
||||||
|
run(t, classInitializer(t, c), 0);
|
||||||
|
} else {
|
||||||
|
release(t, t->vm->classLock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
makeObjectArray(Thread* t, object elementClass, unsigned count, bool clear);
|
makeObjectArray(Thread* t, object elementClass, unsigned count, bool clear);
|
||||||
|
|
||||||
|
35
src/run.cpp
35
src/run.cpp
@ -85,10 +85,10 @@ popFrame(Thread* t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
findInterfaceMethod(Thread* t, object method, object o)
|
findInterfaceMethod(Thread* t, object method, object class_)
|
||||||
{
|
{
|
||||||
object interface = methodClass(t, method);
|
object interface = methodClass(t, method);
|
||||||
object itable = classInterfaceTable(t, objectClass(t, o));
|
object itable = classInterfaceTable(t, class_);
|
||||||
for (unsigned i = 0; i < arrayLength(t, itable); i += 2) {
|
for (unsigned i = 0; i < arrayLength(t, itable); i += 2) {
|
||||||
if (arrayBody(t, itable, i) == interface) {
|
if (arrayBody(t, itable, i) == interface) {
|
||||||
return arrayBody(t, arrayBody(t, itable, i + 1),
|
return arrayBody(t, arrayBody(t, itable, i + 1),
|
||||||
@ -1594,9 +1594,7 @@ run(Thread* t)
|
|||||||
unsigned parameterFootprint = methodParameterFootprint(t, method);
|
unsigned parameterFootprint = methodParameterFootprint(t, method);
|
||||||
if (LIKELY(peekObject(t, sp - parameterFootprint))) {
|
if (LIKELY(peekObject(t, sp - parameterFootprint))) {
|
||||||
code = findInterfaceMethod
|
code = findInterfaceMethod
|
||||||
(t, method, peekObject(t, sp - parameterFootprint));
|
(t, method, objectClass(t, peekObject(t, sp - parameterFootprint)));
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
|
||||||
|
|
||||||
goto invoke;
|
goto invoke;
|
||||||
} else {
|
} else {
|
||||||
exception = makeNullPointerException(t);
|
exception = makeNullPointerException(t);
|
||||||
@ -1669,7 +1667,7 @@ run(Thread* t)
|
|||||||
if (UNLIKELY(classInit(t, class_, 3))) goto invoke;
|
if (UNLIKELY(classInit(t, class_, 3))) goto invoke;
|
||||||
}
|
}
|
||||||
|
|
||||||
code = findMethod(t, method, class_);
|
code = findMethod(t, method, class_);
|
||||||
goto invoke;
|
goto invoke;
|
||||||
} else {
|
} else {
|
||||||
exception = makeNullPointerException(t);
|
exception = makeNullPointerException(t);
|
||||||
@ -2575,6 +2573,31 @@ pushArguments(Thread* t, object this_, const char* spec, object a)
|
|||||||
object
|
object
|
||||||
invoke(Thread* t, object method)
|
invoke(Thread* t, object method)
|
||||||
{
|
{
|
||||||
|
PROTECT(t, method);
|
||||||
|
|
||||||
|
object class_;
|
||||||
|
PROTECT(t, class_);
|
||||||
|
|
||||||
|
if (methodFlags(t, method) & ACC_STATIC) {
|
||||||
|
class_ = methodClass(t, method);
|
||||||
|
} else {
|
||||||
|
unsigned parameterFootprint = methodParameterFootprint(t, method);
|
||||||
|
class_ = objectClass(t, peekObject(t, t->sp - parameterFootprint));
|
||||||
|
|
||||||
|
if (classFlags(t, methodClass(t, method)) & ACC_INTERFACE) {
|
||||||
|
method = findInterfaceMethod(t, method, class_);
|
||||||
|
} else {
|
||||||
|
if (classVirtualTable(t, class_) == 0) {
|
||||||
|
resolveClass(t, className(t, class_));
|
||||||
|
if (UNLIKELY(t->exception)) return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
method = findMethod(t, method, class_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initClass(t, class_);
|
||||||
|
|
||||||
object result = 0;
|
object result = 0;
|
||||||
|
|
||||||
if (methodFlags(t, method) & ACC_NATIVE) {
|
if (methodFlags(t, method) & ACC_NATIVE) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user