mirror of
https://github.com/corda/corda.git
synced 2025-01-19 03:06:36 +00:00
various fixes and additions to increase app compatiblity
The main changes here are: * fixes for runtime annotation support * proper support for runtime generic type introspection * throw NoClassDefFoundErrors instead of ClassNotFoundExceptions where appropriate
This commit is contained in:
parent
8a28578ef5
commit
7004c0ddf3
@ -12,5 +12,6 @@ package avian;
|
||||
|
||||
public class Addendum {
|
||||
public Object pool;
|
||||
public Object annotationTable;
|
||||
public Object annotationTable;
|
||||
public Object signature;
|
||||
}
|
||||
|
@ -12,4 +12,5 @@ package avian;
|
||||
|
||||
public class MethodAddendum extends Addendum {
|
||||
public Object exceptionTable;
|
||||
public Object annotationDefault;
|
||||
}
|
||||
|
@ -42,7 +42,8 @@ search(Thread* t, object loader, object name,
|
||||
object
|
||||
resolveSystemClassThrow(Thread* t, object loader, object spec)
|
||||
{
|
||||
return resolveSystemClass(t, loader, spec, true);
|
||||
return resolveSystemClass
|
||||
(t, loader, spec, true, Machine::ClassNotFoundExceptionType);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -610,7 +610,8 @@ Avian_avian_Classes_resolveVMClass
|
||||
object loader = reinterpret_cast<object>(arguments[0]);
|
||||
object spec = reinterpret_cast<object>(arguments[1]);
|
||||
|
||||
return reinterpret_cast<int64_t>(resolveClass(t, loader, spec));
|
||||
return reinterpret_cast<int64_t>
|
||||
(resolveClass(t, loader, spec, true, Machine::ClassNotFoundExceptionType));
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT int64_t JNICALL
|
||||
|
@ -277,7 +277,10 @@ class MyClasspath : public Classpath {
|
||||
}
|
||||
|
||||
array = charArray;
|
||||
} else {
|
||||
expect(t, objectClass(t, array) == type(t, Machine::CharArrayType));
|
||||
}
|
||||
|
||||
return vm::makeString(t, array, offset, length, 0);
|
||||
}
|
||||
|
||||
@ -2118,6 +2121,16 @@ Avian_sun_misc_Unsafe_getInt__Ljava_lang_Object_2J
|
||||
return cast<int32_t>(o, offset);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT int64_t JNICALL
|
||||
Avian_sun_misc_Unsafe_getFloat__Ljava_lang_Object_2J
|
||||
(Thread*, object, uintptr_t* arguments)
|
||||
{
|
||||
object o = reinterpret_cast<object>(arguments[1]);
|
||||
int64_t offset; memcpy(&offset, arguments + 2, 8);
|
||||
|
||||
return cast<int32_t>(o, offset);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT int64_t JNICALL
|
||||
Avian_sun_misc_Unsafe_getIntVolatile
|
||||
(Thread*, object, uintptr_t* arguments)
|
||||
@ -2177,6 +2190,17 @@ Avian_sun_misc_Unsafe_putInt__Ljava_lang_Object_2JI
|
||||
cast<int32_t>(o, offset) = value;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Avian_sun_misc_Unsafe_putFloat__Ljava_lang_Object_2JF
|
||||
(Thread*, object, uintptr_t* arguments)
|
||||
{
|
||||
object o = reinterpret_cast<object>(arguments[1]);
|
||||
int64_t offset; memcpy(&offset, arguments + 2, 8);
|
||||
int32_t value = arguments[4];
|
||||
|
||||
cast<int32_t>(o, offset) = value;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT int64_t JNICALL
|
||||
Avian_sun_misc_Unsafe_getBoolean
|
||||
(Thread*, object, uintptr_t* arguments)
|
||||
@ -3248,21 +3272,10 @@ jvmFindClassFromClassLoader(Thread* t, uintptr_t* arguments)
|
||||
jobject loader = reinterpret_cast<jobject>(arguments[2]);
|
||||
jboolean throwError = arguments[3];
|
||||
|
||||
THREAD_RESOURCE(t, jboolean, throwError, {
|
||||
if (t->exception and throwError) {
|
||||
object exception = t->exception;
|
||||
t->exception = 0;
|
||||
|
||||
t->exception = makeThrowable
|
||||
(t, Machine::NoClassDefFoundErrorType,
|
||||
throwableMessage(t, exception),
|
||||
throwableTrace(t, exception),
|
||||
throwableCause(t, exception));
|
||||
}
|
||||
});
|
||||
|
||||
object c = resolveClass
|
||||
(t, loader ? *loader : root(t, Machine::BootLoader), name);
|
||||
(t, loader ? *loader : root(t, Machine::BootLoader), name, true,
|
||||
throwError ? Machine::NoClassDefFoundErrorType
|
||||
: Machine::ClassNotFoundExceptionType);
|
||||
|
||||
if (init) {
|
||||
PROTECT(t, c);
|
||||
@ -3542,9 +3555,19 @@ EXPORT(JVM_GetDeclaringClass)(Thread*, jclass)
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jstring JNICALL
|
||||
EXPORT(JVM_GetClassSignature)(Thread*, jclass)
|
||||
EXPORT(JVM_GetClassSignature)(Thread* t, jclass c)
|
||||
{
|
||||
// todo: implement properly
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
object addendum = classAddendum(t, jclassVmClass(t, *c));
|
||||
if (addendum) {
|
||||
object signature = addendumSignature(t, addendum);
|
||||
if (signature) {
|
||||
return makeLocalReference
|
||||
(t, t->m->classpath->makeString
|
||||
(t, signature, 0, byteArrayLength(t, signature) - 1));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3605,16 +3628,30 @@ jvmGetClassDeclaredMethods(Thread* t, uintptr_t* arguments)
|
||||
methodAddendum(t, vmMethod));
|
||||
PROTECT(t, exceptionTypes);
|
||||
|
||||
object signature = t->m->classpath->makeString
|
||||
(t, methodSpec(t, vmMethod), 0, byteArrayLength
|
||||
(t, methodSpec(t, vmMethod)) - 1);
|
||||
object signature;
|
||||
object annotationTable;
|
||||
object annotationDefault;
|
||||
object addendum = methodAddendum(t, vmMethod);
|
||||
if (addendum) {
|
||||
signature = addendumSignature(t, addendum);
|
||||
if (signature) {
|
||||
signature = t->m->classpath->makeString
|
||||
(t, signature, 0, byteArrayLength(t, signature) - 1);
|
||||
}
|
||||
|
||||
object annotationTable = methodAddendum(t, vmMethod) == 0
|
||||
? 0 : addendumAnnotationTable(t, methodAddendum(t, vmMethod));
|
||||
annotationTable = addendumAnnotationTable(t, addendum);
|
||||
|
||||
if (annotationTable) {
|
||||
annotationDefault = methodAddendumAnnotationDefault(t, addendum);
|
||||
} else {
|
||||
signature = 0;
|
||||
annotationTable = 0;
|
||||
annotationDefault = 0;
|
||||
}
|
||||
|
||||
if (annotationTable or annotationDefault) {
|
||||
PROTECT(t, signature);
|
||||
PROTECT(t, annotationTable);
|
||||
PROTECT(t, annotationDefault);
|
||||
|
||||
object runtimeData = getClassRuntimeData(t, jclassVmClass(t, *c));
|
||||
|
||||
@ -3624,8 +3661,8 @@ jvmGetClassDeclaredMethods(Thread* t, uintptr_t* arguments)
|
||||
|
||||
object method = makeJmethod
|
||||
(t, true, *c, i, name, returnType, parameterTypes, exceptionTypes,
|
||||
methodFlags(t, vmMethod), signature, 0, annotationTable, 0, 0, 0, 0,
|
||||
0, 0, 0);
|
||||
methodFlags(t, vmMethod), signature, 0, annotationTable, 0,
|
||||
annotationDefault, 0, 0, 0, 0, 0);
|
||||
|
||||
assert(t, ai < objectArrayLength(t, array));
|
||||
|
||||
@ -3685,12 +3722,21 @@ jvmGetClassDeclaredFields(Thread* t, uintptr_t* arguments)
|
||||
|
||||
type = getJClass(t, type);
|
||||
|
||||
object signature = t->m->classpath->makeString
|
||||
(t, fieldSpec(t, vmField), 0, byteArrayLength
|
||||
(t, fieldSpec(t, vmField)) - 1);
|
||||
object signature;
|
||||
object annotationTable;
|
||||
object addendum = fieldAddendum(t, vmField);
|
||||
if (addendum) {
|
||||
signature = addendumSignature(t, addendum);
|
||||
if (signature) {
|
||||
signature = t->m->classpath->makeString
|
||||
(t, signature, 0, byteArrayLength(t, signature) - 1);
|
||||
}
|
||||
|
||||
object annotationTable = fieldAddendum(t, vmField) == 0
|
||||
? 0 : addendumAnnotationTable(t, fieldAddendum(t, vmField));
|
||||
annotationTable = addendumAnnotationTable(t, addendum);
|
||||
} else {
|
||||
signature = 0;
|
||||
annotationTable = 0;
|
||||
}
|
||||
|
||||
if (annotationTable) {
|
||||
PROTECT(t, signature);
|
||||
@ -3767,12 +3813,21 @@ jvmGetClassDeclaredConstructors(Thread* t, uintptr_t* arguments)
|
||||
methodAddendum(t, vmMethod));
|
||||
PROTECT(t, exceptionTypes);
|
||||
|
||||
object signature = t->m->classpath->makeString
|
||||
(t, methodSpec(t, vmMethod), 0, byteArrayLength
|
||||
(t, methodSpec(t, vmMethod)) - 1);
|
||||
object signature;
|
||||
object annotationTable;
|
||||
object addendum = methodAddendum(t, vmMethod);
|
||||
if (addendum) {
|
||||
signature = addendumSignature(t, addendum);
|
||||
if (signature) {
|
||||
signature = t->m->classpath->makeString
|
||||
(t, signature, 0, byteArrayLength(t, signature) - 1);
|
||||
}
|
||||
|
||||
object annotationTable = methodAddendum(t, vmMethod) == 0
|
||||
? 0 : addendumAnnotationTable(t, methodAddendum(t, vmMethod));
|
||||
annotationTable = addendumAnnotationTable(t, addendum);
|
||||
} else {
|
||||
signature = 0;
|
||||
annotationTable = 0;
|
||||
}
|
||||
|
||||
if (annotationTable) {
|
||||
PROTECT(t, signature);
|
||||
@ -4405,7 +4460,7 @@ extern "C" JNIEXPORT jint JNICALL
|
||||
EXPORT(JVM_GetSockOpt)(jint socket, int level, int optionName,
|
||||
char* optionValue, int* optionLength)
|
||||
{
|
||||
socklen_t length;
|
||||
socklen_t length = *optionLength;
|
||||
int rv = getsockopt(socket, level, optionName, optionValue, &length);
|
||||
*optionLength = length;
|
||||
return rv;
|
||||
|
123
src/machine.cpp
123
src/machine.cpp
@ -954,7 +954,8 @@ addInterfaces(Thread* t, object class_, object map)
|
||||
}
|
||||
|
||||
void
|
||||
parseInterfaceTable(Thread* t, Stream& s, object class_, object pool)
|
||||
parseInterfaceTable(Thread* t, Stream& s, object class_, object pool,
|
||||
Machine::Type throwType)
|
||||
{
|
||||
PROTECT(t, class_);
|
||||
PROTECT(t, pool);
|
||||
@ -971,7 +972,8 @@ parseInterfaceTable(Thread* t, Stream& s, object class_, object pool)
|
||||
object name = referenceName(t, singletonObject(t, pool, s.read2() - 1));
|
||||
PROTECT(t, name);
|
||||
|
||||
object interface = resolveClass(t, classLoader(t, class_), name);
|
||||
object interface = resolveClass
|
||||
(t, classLoader(t, class_), name, true, throwType);
|
||||
|
||||
PROTECT(t, interface);
|
||||
|
||||
@ -1047,6 +1049,8 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
|
||||
|
||||
unsigned value = 0;
|
||||
|
||||
addendum = 0;
|
||||
|
||||
unsigned code = fieldCode
|
||||
(t, byteArrayBody(t, singletonObject(t, pool, spec - 1), 0));
|
||||
|
||||
@ -1059,14 +1063,28 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
|
||||
&byteArrayBody(t, name, 0)) == 0)
|
||||
{
|
||||
value = s.read2();
|
||||
} else if (vm::strcmp(reinterpret_cast<const int8_t*>("Signature"),
|
||||
&byteArrayBody(t, name, 0)) == 0)
|
||||
{
|
||||
if (addendum == 0) {
|
||||
addendum = makeFieldAddendum(t, pool, 0, 0);
|
||||
}
|
||||
|
||||
set(t, addendum, AddendumSignature,
|
||||
singletonObject(t, pool, s.read2() - 1));
|
||||
} else if (vm::strcmp(reinterpret_cast<const int8_t*>
|
||||
("RuntimeVisibleAnnotations"),
|
||||
&byteArrayBody(t, name, 0)) == 0)
|
||||
{
|
||||
if (addendum == 0) {
|
||||
addendum = makeFieldAddendum(t, pool, 0, 0);
|
||||
}
|
||||
|
||||
object body = makeByteArray(t, length);
|
||||
s.read(reinterpret_cast<uint8_t*>(&byteArrayBody(t, body, 0)),
|
||||
length);
|
||||
addendum = makeFieldAddendum(t, pool, body);
|
||||
|
||||
set(t, addendum, AddendumAnnotationTable, body);
|
||||
} else {
|
||||
s.skip(length);
|
||||
}
|
||||
@ -1387,6 +1405,7 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
|
||||
unsigned name = s.read2();
|
||||
unsigned spec = s.read2();
|
||||
|
||||
addendum = 0;
|
||||
code = 0;
|
||||
|
||||
unsigned attributeCount = s.read2();
|
||||
@ -1402,7 +1421,7 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
|
||||
&byteArrayBody(t, name, 0)) == 0)
|
||||
{
|
||||
if (addendum == 0) {
|
||||
addendum = makeMethodAddendum(t, pool, 0, 0);
|
||||
addendum = makeMethodAddendum(t, pool, 0, 0, 0, 0);
|
||||
}
|
||||
unsigned exceptionCount = s.read2();
|
||||
object body = makeShortArray(t, exceptionCount);
|
||||
@ -1410,16 +1429,40 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
|
||||
shortArrayBody(t, body, i) = s.read2();
|
||||
}
|
||||
set(t, addendum, MethodAddendumExceptionTable, body);
|
||||
} else if (vm::strcmp(reinterpret_cast<const int8_t*>
|
||||
("AnnotationDefault"),
|
||||
&byteArrayBody(t, name, 0)) == 0)
|
||||
{
|
||||
if (addendum == 0) {
|
||||
addendum = makeMethodAddendum(t, pool, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
object body = makeByteArray(t, length);
|
||||
s.read(reinterpret_cast<uint8_t*>(&byteArrayBody(t, body, 0)),
|
||||
length);
|
||||
|
||||
set(t, addendum, MethodAddendumAnnotationDefault, body);
|
||||
} else if (vm::strcmp(reinterpret_cast<const int8_t*>("Signature"),
|
||||
&byteArrayBody(t, name, 0)) == 0)
|
||||
{
|
||||
if (addendum == 0) {
|
||||
addendum = makeMethodAddendum(t, pool, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
set(t, addendum, AddendumSignature,
|
||||
singletonObject(t, pool, s.read2() - 1));
|
||||
} else if (vm::strcmp(reinterpret_cast<const int8_t*>
|
||||
("RuntimeVisibleAnnotations"),
|
||||
&byteArrayBody(t, name, 0)) == 0)
|
||||
{
|
||||
if (addendum == 0) {
|
||||
addendum = makeMethodAddendum(t, pool, 0, 0);
|
||||
addendum = makeMethodAddendum(t, pool, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
object body = makeByteArray(t, length);
|
||||
s.read(reinterpret_cast<uint8_t*>(&byteArrayBody(t, body, 0)),
|
||||
length);
|
||||
|
||||
set(t, addendum, AddendumAnnotationTable, body);
|
||||
} else {
|
||||
s.skip(length);
|
||||
@ -1632,6 +1675,12 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
|
||||
void
|
||||
parseAttributeTable(Thread* t, Stream& s, object class_, object pool)
|
||||
{
|
||||
PROTECT(t, class_);
|
||||
PROTECT(t, pool);
|
||||
|
||||
object addendum = 0;
|
||||
PROTECT(t, addendum);
|
||||
|
||||
unsigned attributeCount = s.read2();
|
||||
for (unsigned j = 0; j < attributeCount; ++j) {
|
||||
object name = singletonObject(t, pool, s.read2() - 1);
|
||||
@ -1641,20 +1690,33 @@ parseAttributeTable(Thread* t, Stream& s, object class_, object pool)
|
||||
&byteArrayBody(t, name, 0)) == 0)
|
||||
{
|
||||
set(t, class_, ClassSourceFile, singletonObject(t, pool, s.read2() - 1));
|
||||
} else if (vm::strcmp(reinterpret_cast<const int8_t*>("Signature"),
|
||||
&byteArrayBody(t, name, 0)) == 0)
|
||||
{
|
||||
if (addendum == 0) {
|
||||
addendum = makeClassAddendum(t, pool, 0, 0);
|
||||
}
|
||||
|
||||
set(t, addendum, AddendumSignature,
|
||||
singletonObject(t, pool, s.read2() - 1));
|
||||
} else if (vm::strcmp(reinterpret_cast<const int8_t*>
|
||||
("RuntimeVisibleAnnotations"),
|
||||
&byteArrayBody(t, name, 0)) == 0)
|
||||
{
|
||||
if (addendum == 0) {
|
||||
addendum = makeClassAddendum(t, pool, 0, 0);
|
||||
}
|
||||
|
||||
object body = makeByteArray(t, length);
|
||||
s.read(reinterpret_cast<uint8_t*>(&byteArrayBody(t, body, 0)), length);
|
||||
|
||||
object addendum = makeClassAddendum(t, pool, body);
|
||||
|
||||
set(t, class_, ClassAddendum, addendum);
|
||||
set(t, addendum, AddendumAnnotationTable, body);
|
||||
} else {
|
||||
s.skip(length);
|
||||
}
|
||||
}
|
||||
|
||||
set(t, class_, ClassAddendum, addendum);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1713,6 +1775,7 @@ updateBootstrapClass(Thread* t, object bootstrapClass, object class_)
|
||||
set(t, bootstrapClass, ClassFieldTable, classFieldTable(t, class_));
|
||||
set(t, bootstrapClass, ClassMethodTable, classMethodTable(t, class_));
|
||||
set(t, bootstrapClass, ClassStaticTable, classStaticTable(t, class_));
|
||||
set(t, bootstrapClass, ClassAddendum, classAddendum(t, class_));
|
||||
|
||||
updateClassTables(t, bootstrapClass, class_);
|
||||
}
|
||||
@ -1765,7 +1828,8 @@ makeArrayClass(Thread* t, object loader, unsigned dimensions, object spec,
|
||||
}
|
||||
|
||||
object
|
||||
makeArrayClass(Thread* t, object loader, object spec, bool throw_)
|
||||
makeArrayClass(Thread* t, object loader, object spec, bool throw_,
|
||||
Machine::Type throwType)
|
||||
{
|
||||
PROTECT(t, loader);
|
||||
PROTECT(t, spec);
|
||||
@ -1807,7 +1871,7 @@ makeArrayClass(Thread* t, object loader, object spec, bool throw_)
|
||||
byteArrayEqual);
|
||||
|
||||
if (elementClass == 0) {
|
||||
elementClass = resolveClass(t, loader, elementSpec, throw_);
|
||||
elementClass = resolveClass(t, loader, elementSpec, throw_, throwType);
|
||||
if (elementClass == 0) return 0;
|
||||
}
|
||||
|
||||
@ -1820,7 +1884,8 @@ makeArrayClass(Thread* t, object loader, object spec, bool throw_)
|
||||
}
|
||||
|
||||
object
|
||||
resolveArrayClass(Thread* t, object loader, object spec, bool throw_)
|
||||
resolveArrayClass(Thread* t, object loader, object spec, bool throw_,
|
||||
Machine::Type throwType)
|
||||
{
|
||||
object c = hashMapFind
|
||||
(t, root(t, Machine::BootstrapClassMap), spec, byteArrayHash,
|
||||
@ -1840,7 +1905,7 @@ resolveArrayClass(Thread* t, object loader, object spec, bool throw_)
|
||||
if (c) {
|
||||
return c;
|
||||
} else {
|
||||
return makeArrayClass(t, loader, spec, throw_);
|
||||
return makeArrayClass(t, loader, spec, throw_, throwType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3145,7 +3210,8 @@ primitiveSize(Thread* t, unsigned code)
|
||||
}
|
||||
|
||||
object
|
||||
parseClass(Thread* t, object loader, const uint8_t* data, unsigned size)
|
||||
parseClass(Thread* t, object loader, const uint8_t* data, unsigned size,
|
||||
Machine::Type throwType)
|
||||
{
|
||||
PROTECT(t, loader);
|
||||
|
||||
@ -3199,7 +3265,8 @@ parseClass(Thread* t, object loader, const uint8_t* data, unsigned size)
|
||||
unsigned super = s.read2();
|
||||
if (super) {
|
||||
object sc = resolveClass
|
||||
(t, loader, referenceName(t, singletonObject(t, pool, super - 1)));
|
||||
(t, loader, referenceName(t, singletonObject(t, pool, super - 1)),
|
||||
true, throwType);
|
||||
|
||||
set(t, class_, ClassSuper, sc);
|
||||
|
||||
@ -3208,7 +3275,7 @@ parseClass(Thread* t, object loader, const uint8_t* data, unsigned size)
|
||||
& (ReferenceFlag | WeakReferenceFlag | HasFinalizerFlag));
|
||||
}
|
||||
|
||||
parseInterfaceTable(t, s, class_, pool);
|
||||
parseInterfaceTable(t, s, class_, pool, throwType);
|
||||
|
||||
parseFieldTable(t, s, class_, pool);
|
||||
|
||||
@ -3249,7 +3316,8 @@ parseClass(Thread* t, object loader, const uint8_t* data, unsigned size)
|
||||
}
|
||||
|
||||
object
|
||||
resolveSystemClass(Thread* t, object loader, object spec, bool throw_)
|
||||
resolveSystemClass(Thread* t, object loader, object spec, bool throw_,
|
||||
Machine::Type throwType)
|
||||
{
|
||||
PROTECT(t, loader);
|
||||
PROTECT(t, spec);
|
||||
@ -3269,7 +3337,7 @@ resolveSystemClass(Thread* t, object loader, object spec, bool throw_)
|
||||
}
|
||||
|
||||
if (byteArrayBody(t, spec, 0) == '[') {
|
||||
class_ = resolveArrayClass(t, loader, spec, throw_);
|
||||
class_ = resolveArrayClass(t, loader, spec, throw_, throwType);
|
||||
} else {
|
||||
THREAD_RUNTIME_ARRAY(t, char, file, byteArrayLength(t, spec) + 6);
|
||||
memcpy(RUNTIME_ARRAY_BODY(file),
|
||||
@ -3291,7 +3359,8 @@ resolveSystemClass(Thread* t, object loader, object spec, bool throw_)
|
||||
{ THREAD_RESOURCE(t, System::Region*, region, region->dispose());
|
||||
|
||||
// parse class file
|
||||
class_ = parseClass(t, loader, region->start(), region->length());
|
||||
class_ = parseClass
|
||||
(t, loader, region->start(), region->length(), throwType);
|
||||
}
|
||||
|
||||
if (Verbose) {
|
||||
@ -3318,8 +3387,7 @@ resolveSystemClass(Thread* t, object loader, object spec, bool throw_)
|
||||
|
||||
hashMapInsert(t, classLoaderMap(t, loader), spec, class_, byteArrayHash);
|
||||
} else if (throw_) {
|
||||
throwNew(t, Machine::ClassNotFoundExceptionType, "%s",
|
||||
&byteArrayBody(t, spec, 0));
|
||||
throwNew(t, throwType, "%s", &byteArrayBody(t, spec, 0));
|
||||
}
|
||||
}
|
||||
|
||||
@ -3339,10 +3407,11 @@ findLoadedClass(Thread* t, object loader, object spec)
|
||||
}
|
||||
|
||||
object
|
||||
resolveClass(Thread* t, object loader, object spec, bool throw_)
|
||||
resolveClass(Thread* t, object loader, object spec, bool throw_,
|
||||
Machine::Type throwType)
|
||||
{
|
||||
if (objectClass(t, loader) == type(t, Machine::SystemClassLoaderType)) {
|
||||
return resolveSystemClass(t, loader, spec, throw_);
|
||||
return resolveSystemClass(t, loader, spec, throw_, throwType);
|
||||
} else {
|
||||
PROTECT(t, loader);
|
||||
PROTECT(t, spec);
|
||||
@ -3353,7 +3422,7 @@ resolveClass(Thread* t, object loader, object spec, bool throw_)
|
||||
}
|
||||
|
||||
if (byteArrayBody(t, spec, 0) == '[') {
|
||||
c = resolveArrayClass(t, loader, spec, throw_);
|
||||
c = resolveArrayClass(t, loader, spec, throw_, throwType);
|
||||
} else {
|
||||
if (root(t, Machine::LoadClassMethod) == 0) {
|
||||
object m = resolveMethod
|
||||
@ -3383,6 +3452,7 @@ resolveClass(Thread* t, object loader, object spec, bool throw_)
|
||||
(&byteArrayBody(t, spec, 0)));
|
||||
|
||||
object specString = makeString(t, "%s", RUNTIME_ARRAY_BODY(s));
|
||||
PROTECT(t, specString);
|
||||
|
||||
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(method),
|
||||
reinterpret_cast<uintptr_t>(loader),
|
||||
@ -3395,7 +3465,9 @@ resolveClass(Thread* t, object loader, object spec, bool throw_)
|
||||
c = jclassVmClass(t, jc);
|
||||
} else if (t->exception) {
|
||||
if (throw_) {
|
||||
object e = t->exception;
|
||||
object e = type(t, throwType) == objectClass(t, t->exception)
|
||||
? t->exception
|
||||
: makeThrowable(t, throwType, specString, 0, t->exception);
|
||||
t->exception = 0;
|
||||
vm::throw_(t, e);
|
||||
} else {
|
||||
@ -3417,8 +3489,7 @@ resolveClass(Thread* t, object loader, object spec, bool throw_)
|
||||
hashMapInsert
|
||||
(t, classLoaderMap(t, loader), spec, c, byteArrayHash);
|
||||
} else if (throw_) {
|
||||
throwNew(t, Machine::ClassNotFoundExceptionType, "%s",
|
||||
&byteArrayBody(t, spec, 0));
|
||||
throwNew(t, throwType, "%s", &byteArrayBody(t, spec, 0));
|
||||
}
|
||||
|
||||
return c;
|
||||
|
@ -2466,21 +2466,26 @@ object
|
||||
parseUtf8(Thread* t, const char* data, unsigned length);
|
||||
|
||||
object
|
||||
parseClass(Thread* t, object loader, const uint8_t* data, unsigned length);
|
||||
parseClass(Thread* t, object loader, const uint8_t* data, unsigned length,
|
||||
Machine::Type throwType = Machine::NoClassDefFoundErrorType);
|
||||
|
||||
object
|
||||
resolveClass(Thread* t, object loader, object name, bool throw_ = true);
|
||||
resolveClass(Thread* t, object loader, object name, bool throw_ = true,
|
||||
Machine::Type throwType = Machine::NoClassDefFoundErrorType);
|
||||
|
||||
inline object
|
||||
resolveClass(Thread* t, object loader, const char* name, bool throw_ = true)
|
||||
resolveClass(Thread* t, object loader, const char* name, bool throw_ = true,
|
||||
Machine::Type throwType = Machine::NoClassDefFoundErrorType)
|
||||
{
|
||||
PROTECT(t, loader);
|
||||
object n = makeByteArray(t, "%s", name);
|
||||
return resolveClass(t, loader, n, throw_);
|
||||
return resolveClass(t, loader, n, throw_, throwType);
|
||||
}
|
||||
|
||||
object
|
||||
resolveSystemClass(Thread* t, object loader, object name, bool throw_ = true);
|
||||
resolveSystemClass
|
||||
(Thread* t, object loader, object name, bool throw_ = true,
|
||||
Machine::Type throwType = Machine::NoClassDefFoundErrorType);
|
||||
|
||||
inline object
|
||||
resolveSystemClass(Thread* t, object loader, const char* name)
|
||||
|
Loading…
Reference in New Issue
Block a user