mirror of
https://github.com/corda/corda.git
synced 2024-12-29 09:18:58 +00:00
working reflection
This commit is contained in:
parent
5f3bf175e0
commit
823d764998
@ -101,7 +101,8 @@ public final class String implements Comparable<String> {
|
|||||||
return new String(data, offset + start, end - start, false);
|
return new String(data, offset + start, end - start, false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new IndexOutOfBoundsException();
|
throw new IndexOutOfBoundsException
|
||||||
|
(start + " not in (0, " + end + ") or " + end + " > " + length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,15 +53,20 @@ public class Method<T> extends AccessibleObject implements Member {
|
|||||||
|
|
||||||
for (int i = 0; i < spec.length(); ++i) {
|
for (int i = 0; i < spec.length(); ++i) {
|
||||||
char c = spec.charAt(i);
|
char c = spec.charAt(i);
|
||||||
if (c == 'L') {
|
if (c == ')') {
|
||||||
String name = spec.substring(i + 1, next(';', spec, i + 1));
|
break;
|
||||||
|
} else if (c == 'L') {
|
||||||
|
int start = i + 1;
|
||||||
|
i = next(';', spec, start);
|
||||||
|
String name = spec.substring(start, i);
|
||||||
types[index++] = Class.forName(name);
|
types[index++] = Class.forName(name);
|
||||||
} else if (c == '[') {
|
} else if (c == '[') {
|
||||||
int start = i;
|
int start = i;
|
||||||
while (spec.charAt(i) == '[') ++i;
|
while (spec.charAt(i) == '[') ++i;
|
||||||
|
|
||||||
if (spec.charAt(i) == 'L') {
|
if (spec.charAt(i) == 'L') {
|
||||||
String name = spec.substring(start, next(';', spec, i + 1));
|
i = next(';', spec, i + 1);
|
||||||
|
String name = spec.substring(start, i);
|
||||||
types[index++] = Class.forName(name);
|
types[index++] = Class.forName(name);
|
||||||
} else {
|
} else {
|
||||||
String name = spec.substring(start, i + 1);
|
String name = spec.substring(start, i + 1);
|
||||||
|
@ -169,23 +169,29 @@ get(Thread* t, jobject this_, jobject instancep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
jobject
|
jobject
|
||||||
invoke(Thread* t, jobject this_, jobject instance, jobjectArray arguments)
|
invoke(Thread* t, jobject this_, jobject instancep, jobjectArray argumentsp)
|
||||||
{
|
{
|
||||||
object method = *this_;
|
object method = *this_;
|
||||||
|
|
||||||
if (arguments) {
|
if (argumentsp) {
|
||||||
|
object arguments = *argumentsp;
|
||||||
|
|
||||||
if (methodFlags(t, method) & ACC_STATIC) {
|
if (methodFlags(t, method) & ACC_STATIC) {
|
||||||
if (objectArrayLength(t, arguments) == methodParameterCount(t, method)) {
|
if (objectArrayLength(t, arguments)
|
||||||
return pushReference(t, doInvoke(t, method, 0, *arguments));
|
== methodParameterCount(t, method))
|
||||||
|
{
|
||||||
|
return pushReference(t, doInvoke(t, method, 0, arguments));
|
||||||
} else {
|
} else {
|
||||||
t->exception = makeArrayIndexOutOfBoundsException(t, 0);
|
t->exception = makeArrayIndexOutOfBoundsException(t, 0);
|
||||||
}
|
}
|
||||||
} else if (instance) {
|
} else if (instancep) {
|
||||||
|
object instance = *instancep;
|
||||||
|
|
||||||
if (instanceOf(t, methodClass(t, method), instance)) {
|
if (instanceOf(t, methodClass(t, method), instance)) {
|
||||||
if (objectArrayLength(t, arguments)
|
if (objectArrayLength(t, arguments)
|
||||||
== static_cast<unsigned>(methodParameterCount(t, method) - 1))
|
== static_cast<unsigned>(methodParameterCount(t, method) - 1))
|
||||||
{
|
{
|
||||||
return pushReference(t, doInvoke(t, method, *instance, *arguments));
|
return pushReference(t, doInvoke(t, method, instance, arguments));
|
||||||
} else {
|
} else {
|
||||||
t->exception = makeArrayIndexOutOfBoundsException(t, 0);
|
t->exception = makeArrayIndexOutOfBoundsException(t, 0);
|
||||||
}
|
}
|
||||||
@ -382,6 +388,10 @@ start(Thread* t, jobject this_)
|
|||||||
|
|
||||||
vm::run(t, "java/lang/Thread", "run", "()V", t->javaThread);
|
vm::run(t, "java/lang/Thread", "run", "()V", t->javaThread);
|
||||||
|
|
||||||
|
if (t->exception) {
|
||||||
|
printTrace(t, t->exception);
|
||||||
|
}
|
||||||
|
|
||||||
t->exit();
|
t->exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,12 +422,8 @@ populate(Thread* t, object map)
|
|||||||
} builtins[] = {
|
} builtins[] = {
|
||||||
{ "Java_java_lang_Class_forName",
|
{ "Java_java_lang_Class_forName",
|
||||||
reinterpret_cast<void*>(forName) },
|
reinterpret_cast<void*>(forName) },
|
||||||
|
{ "Java_java_lang_Class_isAssignableFrom",
|
||||||
{ "Java_java_lang_Field_get",
|
reinterpret_cast<void*>(isAssignableFrom) },
|
||||||
reinterpret_cast<void*>(get) },
|
|
||||||
|
|
||||||
{ "Java_java_lang_Method_invoke",
|
|
||||||
reinterpret_cast<void*>(invoke) },
|
|
||||||
|
|
||||||
{ "Java_java_lang_System_arraycopy",
|
{ "Java_java_lang_System_arraycopy",
|
||||||
reinterpret_cast<void*>(arraycopy) },
|
reinterpret_cast<void*>(arraycopy) },
|
||||||
@ -452,6 +458,12 @@ populate(Thread* t, object map)
|
|||||||
{ "Java_java_lang_Object_wait",
|
{ "Java_java_lang_Object_wait",
|
||||||
reinterpret_cast<void*>(wait) },
|
reinterpret_cast<void*>(wait) },
|
||||||
|
|
||||||
|
{ "Java_java_lang_reflect_Field_get",
|
||||||
|
reinterpret_cast<void*>(get) },
|
||||||
|
|
||||||
|
{ "Java_java_lang_reflect_Method_invoke",
|
||||||
|
reinterpret_cast<void*>(invoke) },
|
||||||
|
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ enum OpCode {
|
|||||||
i2s = 0x93,
|
i2s = 0x93,
|
||||||
iadd = 0x60,
|
iadd = 0x60,
|
||||||
iaload = 0x2e,
|
iaload = 0x2e,
|
||||||
iand = 0x73,
|
iand = 0x7e,
|
||||||
iastore = 0x4f,
|
iastore = 0x4f,
|
||||||
iconst_m1 = 0x02,
|
iconst_m1 = 0x02,
|
||||||
iconst_0 = 0x03,
|
iconst_0 = 0x03,
|
||||||
@ -113,9 +113,9 @@ enum OpCode {
|
|||||||
if_acmpne = 0xa6,
|
if_acmpne = 0xa6,
|
||||||
if_icmpeq = 0x9f,
|
if_icmpeq = 0x9f,
|
||||||
if_icmpne = 0xa0,
|
if_icmpne = 0xa0,
|
||||||
if_icmpgt = 0xa1,
|
if_icmplt = 0xa1,
|
||||||
if_icmpge = 0xa2,
|
if_icmpge = 0xa2,
|
||||||
if_icmplt = 0xa3,
|
if_icmpgt = 0xa3,
|
||||||
if_icmple = 0xa4,
|
if_icmple = 0xa4,
|
||||||
ifeq = 0x99,
|
ifeq = 0x99,
|
||||||
ifge = 0x9c,
|
ifge = 0x9c,
|
||||||
|
@ -1653,9 +1653,9 @@ instanceOf(Thread* t, object class_, object o)
|
|||||||
{
|
{
|
||||||
if (o == 0) {
|
if (o == 0) {
|
||||||
return false;
|
return false;
|
||||||
|
} else {
|
||||||
|
return isAssignableFrom(t, class_, objectClass(t, o));
|
||||||
}
|
}
|
||||||
|
|
||||||
return isAssignableFrom(t, class_, objectClass(t, o));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
@ -2346,6 +2346,51 @@ collect(Thread* t, Heap::CollectionType type)
|
|||||||
killZombies(t, m->rootThread);
|
killZombies(t, m->rootThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
printTrace(Thread* t, object exception)
|
||||||
|
{
|
||||||
|
for (object e = exception; e; e = throwableCauseUnsafe(t, e)) {
|
||||||
|
if (e != exception) {
|
||||||
|
fprintf(stderr, "caused by: ");
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "%s", &byteArrayBody
|
||||||
|
(t, className(t, objectClass(t, e)), 0));
|
||||||
|
|
||||||
|
if (throwableMessageUnsafe(t, e)) {
|
||||||
|
object m = throwableMessageUnsafe(t, e);
|
||||||
|
char message[stringLength(t, m) + 1];
|
||||||
|
stringChars(t, m, message);
|
||||||
|
fprintf(stderr, ": %s\n", message);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
object trace = throwableTraceUnsafe(t, e);
|
||||||
|
for (unsigned i = 0; i < arrayLength(t, trace); ++i) {
|
||||||
|
object e = arrayBody(t, trace, i);
|
||||||
|
const int8_t* class_ = &byteArrayBody
|
||||||
|
(t, className(t, methodClass(t, traceElementMethod(t, e))), 0);
|
||||||
|
const int8_t* method = &byteArrayBody
|
||||||
|
(t, methodName(t, traceElementMethod(t, e)), 0);
|
||||||
|
int line = lineNumber(t, traceElementMethod(t, e), traceElementIp(t, e));
|
||||||
|
|
||||||
|
fprintf(stderr, " at %s.%s ", class_, method);
|
||||||
|
|
||||||
|
switch (line) {
|
||||||
|
case NativeLine:
|
||||||
|
fprintf(stderr, "(native)\n");
|
||||||
|
break;
|
||||||
|
case UnknownLine:
|
||||||
|
fprintf(stderr, "(unknown line)\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "(line %d)\n", line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
noop()
|
noop()
|
||||||
{ }
|
{ }
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
namespace vm {
|
namespace vm {
|
||||||
|
|
||||||
const bool Verbose = false;
|
const bool Verbose = false;
|
||||||
const bool DebugRun = true;
|
const bool DebugRun = false;
|
||||||
const bool DebugStack = false;
|
const bool DebugStack = false;
|
||||||
const bool DebugMonitors = false;
|
const bool DebugMonitors = false;
|
||||||
|
|
||||||
@ -2079,6 +2079,9 @@ vmNotifyAll(Thread* t, object o)
|
|||||||
notifyAll(t, o);
|
notifyAll(t, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
printTrace(Thread* t, object exception);
|
||||||
|
|
||||||
void
|
void
|
||||||
exit(Thread* t);
|
exit(Thread* t);
|
||||||
|
|
||||||
|
78
src/run.cpp
78
src/run.cpp
@ -91,8 +91,7 @@ make(Thread* t, object class_)
|
|||||||
|
|
||||||
ACQUIRE(t, t->vm->referenceLock);
|
ACQUIRE(t, t->vm->referenceLock);
|
||||||
|
|
||||||
// jreferenceNext(t, instance)
|
jreferenceNextUnsafe(t, instance) = t->vm->weakReferences;
|
||||||
cast<object>(instance, BytesPerWord) = t->vm->weakReferences;
|
|
||||||
t->vm->weakReferences = instance;
|
t->vm->weakReferences = instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,6 +300,16 @@ makeNativeMethodData(Thread* t, object method, void* function, bool builtin)
|
|||||||
case '[':
|
case '[':
|
||||||
argumentTableSize += BytesPerWord;
|
argumentTableSize += BytesPerWord;
|
||||||
while (*s == '[') ++ s;
|
while (*s == '[') ++ s;
|
||||||
|
switch (*s) {
|
||||||
|
case 'L':
|
||||||
|
while (*s and *s != ';') ++ s;
|
||||||
|
++ s;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
++ s;
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1601,16 +1610,16 @@ run(Thread* t)
|
|||||||
|
|
||||||
if (objectClass(t, v) == arrayBody(t, t->vm->types, Machine::IntType)) {
|
if (objectClass(t, v) == arrayBody(t, t->vm->types, Machine::IntType)) {
|
||||||
pushInt(t, intValue(t, v));
|
pushInt(t, intValue(t, v));
|
||||||
} else if (objectClass(t, v)
|
|
||||||
== arrayBody(t, t->vm->types, Machine::StringType))
|
|
||||||
{
|
|
||||||
pushObject(t, v);
|
|
||||||
} else if (objectClass(t, v)
|
} else if (objectClass(t, v)
|
||||||
== arrayBody(t, t->vm->types, Machine::FloatType))
|
== arrayBody(t, t->vm->types, Machine::FloatType))
|
||||||
{
|
{
|
||||||
pushInt(t, floatValue(t, v));
|
pushInt(t, floatValue(t, v));
|
||||||
|
} else if (objectClass(t, v)
|
||||||
|
== arrayBody(t, t->vm->types, Machine::StringType))
|
||||||
|
{
|
||||||
|
pushObject(t, v);
|
||||||
} else {
|
} else {
|
||||||
abort(t);
|
pushObject(t, resolveClass(t, v));
|
||||||
}
|
}
|
||||||
} goto loop;
|
} goto loop;
|
||||||
|
|
||||||
@ -2123,7 +2132,7 @@ run(Thread* t)
|
|||||||
|
|
||||||
pokeInt(t, t->frame + FrameIpOffset, t->ip);
|
pokeInt(t, t->frame + FrameIpOffset, t->ip);
|
||||||
for (; frame >= 0; frame = frameNext(t, frame)) {
|
for (; frame >= 0; frame = frameNext(t, frame)) {
|
||||||
if (methodFlags(t, frameMethod(t, frame)) & ACC_NATIVE) {
|
if (frame <= base) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2160,49 +2169,6 @@ run(Thread* t)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (object e = exception; e; e = throwableCause(t, e)) {
|
|
||||||
if (e == exception) {
|
|
||||||
fprintf(stderr, "uncaught exception: ");
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "caused by: ");
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr, "%s", &byteArrayBody
|
|
||||||
(t, className(t, objectClass(t, exception)), 0));
|
|
||||||
|
|
||||||
if (throwableMessage(t, exception)) {
|
|
||||||
object m = throwableMessage(t, exception);
|
|
||||||
char message[stringLength(t, m) + 1];
|
|
||||||
stringChars(t, m, message);
|
|
||||||
fprintf(stderr, ": %s\n", message);
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
object trace = throwableTrace(t, e);
|
|
||||||
for (unsigned i = 0; i < arrayLength(t, trace); ++i) {
|
|
||||||
object e = arrayBody(t, trace, i);
|
|
||||||
const int8_t* class_ = &byteArrayBody
|
|
||||||
(t, className(t, methodClass(t, traceElementMethod(t, e))), 0);
|
|
||||||
const int8_t* method = &byteArrayBody
|
|
||||||
(t, methodName(t, traceElementMethod(t, e)), 0);
|
|
||||||
int line = lineNumber(t, traceElementMethod(t, e), traceElementIp(t, e));
|
|
||||||
|
|
||||||
fprintf(stderr, " at %s.%s ", class_, method);
|
|
||||||
|
|
||||||
switch (line) {
|
|
||||||
case NativeLine:
|
|
||||||
fprintf(stderr, "(native)\n");
|
|
||||||
break;
|
|
||||||
case UnknownLine:
|
|
||||||
fprintf(stderr, "(unknown line)\n");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "(line %d)\n", line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2354,8 +2320,9 @@ invoke(Thread* t, object method)
|
|||||||
if (LIKELY(t->exception == 0)) {
|
if (LIKELY(t->exception == 0)) {
|
||||||
pushFrame(t, method);
|
pushFrame(t, method);
|
||||||
result = ::run(t);
|
result = ::run(t);
|
||||||
popFrame(t);
|
if (LIKELY(t->exception == 0)) {
|
||||||
|
popFrame(t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2469,7 +2436,10 @@ run(System* system, Heap* heap, ClassFinder* classFinder,
|
|||||||
::run(t, className, argc, argv);
|
::run(t, className, argc, argv);
|
||||||
|
|
||||||
int exitCode = 0;
|
int exitCode = 0;
|
||||||
if (t->exception) exitCode = -1;
|
if (t->exception) {
|
||||||
|
exitCode = -1;
|
||||||
|
printTrace(t, t->exception);
|
||||||
|
}
|
||||||
|
|
||||||
exit(t);
|
exit(t);
|
||||||
|
|
||||||
|
@ -139,9 +139,9 @@
|
|||||||
|
|
||||||
(type throwable java/lang/Throwable
|
(type throwable java/lang/Throwable
|
||||||
(extends jobject)
|
(extends jobject)
|
||||||
(object message)
|
(noassert object message)
|
||||||
(object trace)
|
(noassert object trace)
|
||||||
(object cause))
|
(noassert object cause))
|
||||||
|
|
||||||
(type exception java/lang/Exception
|
(type exception java/lang/Exception
|
||||||
(extends throwable))
|
(extends throwable))
|
||||||
@ -237,7 +237,7 @@
|
|||||||
|
|
||||||
(type jreference java/lang/ref/Reference
|
(type jreference java/lang/ref/Reference
|
||||||
(extends jobject)
|
(extends jobject)
|
||||||
(void* next)
|
(noassert void* next)
|
||||||
(void* target)
|
(void* target)
|
||||||
(void* queue)
|
(void* queue)
|
||||||
(object jnext))
|
(object jnext))
|
||||||
|
Loading…
Reference in New Issue
Block a user