mirror of
https://github.com/corda/corda.git
synced 2025-01-03 19:54:13 +00:00
throw IncompatibleClassChangeError on unexpected static status
If a class references a field or method as static and we find it's actually non-static -- or vice-versa -- we ought to throw an error rather than abort.
This commit is contained in:
parent
362d6594a8
commit
90fae940a7
@ -2368,6 +2368,31 @@ findInterfaceMethodFromInstanceAndReference
|
|||||||
return findInterfaceMethodFromInstance(t, method, instance);
|
return findInterfaceMethodFromInstance(t, method, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
checkMethod(Thread* t, object method, bool shouldBeStatic)
|
||||||
|
{
|
||||||
|
if (((methodFlags(t, method) & ACC_STATIC) == 0) == shouldBeStatic) {
|
||||||
|
throwNew(t, Machine::IncompatibleClassChangeErrorType,
|
||||||
|
"expected %s.%s%s to be %s",
|
||||||
|
&byteArrayBody(t, className(t, methodClass(t, method)), 0),
|
||||||
|
&byteArrayBody(t, methodName(t, method), 0),
|
||||||
|
&byteArrayBody(t, methodSpec(t, method), 0),
|
||||||
|
shouldBeStatic ? "static" : "non-static");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
checkField(Thread* t, object field, bool shouldBeStatic)
|
||||||
|
{
|
||||||
|
if (((fieldFlags(t, field) & ACC_STATIC) == 0) == shouldBeStatic) {
|
||||||
|
throwNew(t, Machine::IncompatibleClassChangeErrorType,
|
||||||
|
"expected %s.%s to be %s",
|
||||||
|
&byteArrayBody(t, className(t, fieldClass(t, field)), 0),
|
||||||
|
&byteArrayBody(t, fieldName(t, field), 0),
|
||||||
|
shouldBeStatic ? "static" : "non-static");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int64_t
|
int64_t
|
||||||
findSpecialMethodFromReference(MyThread* t, object pair)
|
findSpecialMethodFromReference(MyThread* t, object pair)
|
||||||
{
|
{
|
||||||
@ -2380,7 +2405,7 @@ findSpecialMethodFromReference(MyThread* t, object pair)
|
|||||||
target = findVirtualMethod(t, target, classSuper(t, class_));
|
target = findVirtualMethod(t, target, classSuper(t, class_));
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(t, (methodFlags(t, target) & ACC_STATIC) == 0);
|
checkMethod(t, target, false);
|
||||||
|
|
||||||
return prepareMethodForCall(t, target);
|
return prepareMethodForCall(t, target);
|
||||||
}
|
}
|
||||||
@ -2390,7 +2415,7 @@ findStaticMethodFromReference(MyThread* t, object pair)
|
|||||||
{
|
{
|
||||||
object target = resolveMethod(t, pair);
|
object target = resolveMethod(t, pair);
|
||||||
|
|
||||||
assert(t, methodFlags(t, target) & ACC_STATIC);
|
checkMethod(t, target, true);
|
||||||
|
|
||||||
return prepareMethodForCall(t, target);
|
return prepareMethodForCall(t, target);
|
||||||
}
|
}
|
||||||
@ -2404,7 +2429,7 @@ findVirtualMethodFromReference(MyThread* t, object pair, object instance)
|
|||||||
|
|
||||||
target = findVirtualMethod(t, target, objectClass(t, instance));
|
target = findVirtualMethod(t, target, objectClass(t, instance));
|
||||||
|
|
||||||
assert(t, (methodFlags(t, target) & ACC_STATIC) == 0);
|
checkMethod(t, target, false);
|
||||||
|
|
||||||
return prepareMethodForCall(t, target);
|
return prepareMethodForCall(t, target);
|
||||||
}
|
}
|
||||||
@ -4583,7 +4608,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
Compiler::Operand* table;
|
Compiler::Operand* table;
|
||||||
|
|
||||||
if (instruction == getstatic) {
|
if (instruction == getstatic) {
|
||||||
assert(t, fieldFlags(t, field) & ACC_STATIC);
|
checkField(t, field, true);
|
||||||
|
|
||||||
PROTECT(t, field);
|
PROTECT(t, field);
|
||||||
|
|
||||||
@ -4603,7 +4628,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
|
|
||||||
table = frame->append(classStaticTable(t, fieldClass(t, field)));
|
table = frame->append(classStaticTable(t, fieldClass(t, field)));
|
||||||
} else {
|
} else {
|
||||||
assert(t, (fieldFlags(t, field) & ACC_STATIC) == 0);
|
checkField(t, field, false);
|
||||||
|
|
||||||
table = frame->popObject();
|
table = frame->popObject();
|
||||||
|
|
||||||
@ -5048,7 +5073,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
int returnCode;
|
int returnCode;
|
||||||
bool tailCall;
|
bool tailCall;
|
||||||
if (LIKELY(target)) {
|
if (LIKELY(target)) {
|
||||||
assert(t, (methodFlags(t, target) & ACC_STATIC) == 0);
|
checkMethod(t, target, false);
|
||||||
|
|
||||||
argument = target;
|
argument = target;
|
||||||
thunk = findInterfaceMethodFromInstanceThunk;
|
thunk = findInterfaceMethodFromInstanceThunk;
|
||||||
@ -5107,7 +5132,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
target = findVirtualMethod(t, target, classSuper(t, class_));
|
target = findVirtualMethod(t, target, classSuper(t, class_));
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(t, (methodFlags(t, target) & ACC_STATIC) == 0);
|
checkMethod(t, target, false);
|
||||||
|
|
||||||
bool tailCall = isTailCall(t, code, ip, context->method, target);
|
bool tailCall = isTailCall(t, code, ip, context->method, target);
|
||||||
|
|
||||||
@ -5137,7 +5162,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
object target = resolveMethod(t, context->method, index - 1, false);
|
object target = resolveMethod(t, context->method, index - 1, false);
|
||||||
|
|
||||||
if (LIKELY(target)) {
|
if (LIKELY(target)) {
|
||||||
assert(t, methodFlags(t, target) & ACC_STATIC);
|
checkMethod(t, target, true);
|
||||||
|
|
||||||
if (not intrinsic(t, frame, target)) {
|
if (not intrinsic(t, frame, target)) {
|
||||||
bool tailCall = isTailCall(t, code, ip, context->method, target);
|
bool tailCall = isTailCall(t, code, ip, context->method, target);
|
||||||
@ -5163,8 +5188,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
object target = resolveMethod(t, context->method, index - 1, false);
|
object target = resolveMethod(t, context->method, index - 1, false);
|
||||||
|
|
||||||
if (LIKELY(target)) {
|
if (LIKELY(target)) {
|
||||||
assert(t, (methodFlags(t, target) & ACC_STATIC) == 0);
|
checkMethod(t, target, false);
|
||||||
|
|
||||||
if (not intrinsic(t, frame, target)) {
|
if (not intrinsic(t, frame, target)) {
|
||||||
bool tailCall = isTailCall(t, code, ip, context->method, target);
|
bool tailCall = isTailCall(t, code, ip, context->method, target);
|
||||||
|
|
||||||
@ -5777,7 +5802,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
object staticTable = 0;
|
object staticTable = 0;
|
||||||
|
|
||||||
if (instruction == putstatic) {
|
if (instruction == putstatic) {
|
||||||
assert(t, fieldFlags(t, field) & ACC_STATIC);
|
checkField(t, field, true);
|
||||||
|
|
||||||
if (fieldClass(t, field) != methodClass(t, context->method)
|
if (fieldClass(t, field) != methodClass(t, context->method)
|
||||||
and classNeedsInit(t, fieldClass(t, field)))
|
and classNeedsInit(t, fieldClass(t, field)))
|
||||||
@ -5797,7 +5822,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
|
|
||||||
staticTable = classStaticTable(t, fieldClass(t, field));
|
staticTable = classStaticTable(t, fieldClass(t, field));
|
||||||
} else {
|
} else {
|
||||||
assert(t, (fieldFlags(t, field) & ACC_STATIC) == 0);
|
checkField(t, field, false);
|
||||||
|
|
||||||
if (inTryBlock(t, code, ip - 3)) {
|
if (inTryBlock(t, code, ip - 3)) {
|
||||||
c->saveLocals();
|
c->saveLocals();
|
||||||
|
1
vm.pro
1
vm.pro
@ -66,6 +66,7 @@
|
|||||||
-keep public class java.lang.UnsatisfiedLinkError
|
-keep public class java.lang.UnsatisfiedLinkError
|
||||||
-keep public class java.lang.ExceptionInInitializerError
|
-keep public class java.lang.ExceptionInInitializerError
|
||||||
-keep public class java.lang.OutOfMemoryError
|
-keep public class java.lang.OutOfMemoryError
|
||||||
|
-keep public class java.lang.IncompatibleClassChangeError
|
||||||
-keep public class java.lang.reflect.InvocationTargetException
|
-keep public class java.lang.reflect.InvocationTargetException
|
||||||
-keep public class java.io.IOException
|
-keep public class java.io.IOException
|
||||||
-keep public class java.io.FileNotFoundException
|
-keep public class java.io.FileNotFoundException
|
||||||
|
Loading…
Reference in New Issue
Block a user