diff --git a/classpath/java/lang/Class.java b/classpath/java/lang/Class.java index b2464486eb..6425fb398a 100644 --- a/classpath/java/lang/Class.java +++ b/classpath/java/lang/Class.java @@ -38,6 +38,7 @@ public final class Class implements Type, GenericDeclaration { private byte arrayDimensions; private int[] objectMask; private byte[] name; + private byte[] sourceFile; private Class super_; private Object[] interfaceTable; private Method[] virtualTable; diff --git a/src/builtin.cpp b/src/builtin.cpp index 8f12b2921f..431fe0c6b6 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -827,19 +827,25 @@ Avian_java_lang_Throwable_resolveTrace object class_ = 0; PROTECT(t, class_); + object method = 0; + PROTECT(t, method); + for (unsigned i = 0; i < length; ++i) { e = arrayBody(t, trace, i); class_ = className(t, methodClass(t, traceElementMethod(t, e))); class_ = makeString(t, class_, 0, byteArrayLength(t, class_) - 1, 0); - object method = methodName(t, traceElementMethod(t, e)); + method = methodName(t, traceElementMethod(t, e)); method = makeString(t, method, 0, byteArrayLength(t, method) - 1, 0); unsigned line = t->m->processor->lineNumber (t, traceElementMethod(t, e), traceElementIp(t, e)); - object ste = makeStackTraceElement(t, class_, method, 0, line); + object file = classSourceFile(t, methodClass(t, traceElementMethod(t, e))); + file = file ? makeString(t, file, 0, byteArrayLength(t, file) - 1, 0) : 0; + + object ste = makeStackTraceElement(t, class_, method, file, line); set(t, array, ArrayBody + (i * BytesPerWord), ste); } diff --git a/src/compile.cpp b/src/compile.cpp index 0422d12e7d..808cdf3157 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -6466,6 +6466,7 @@ class MyProcessor: public Processor { uint8_t arrayDimensions, object objectMask, object name, + object sourceFile, object super, object interfaceTable, object virtualTable, @@ -6477,8 +6478,8 @@ class MyProcessor: public Processor { { return vm::makeClass (t, flags, vmFlags, fixedSize, arrayElementSize, arrayDimensions, - objectMask, name, super, interfaceTable, virtualTable, fieldTable, - methodTable, staticTable, loader, vtableLength); + objectMask, name, sourceFile, super, interfaceTable, virtualTable, + fieldTable, methodTable, staticTable, loader, vtableLength); } virtual void diff --git a/src/interpret.cpp b/src/interpret.cpp index ea3dcfad0a..2491b27847 100644 --- a/src/interpret.cpp +++ b/src/interpret.cpp @@ -3109,6 +3109,7 @@ class MyProcessor: public Processor { uint8_t arrayDimensions, object objectMask, object name, + object sourceFile, object super, object interfaceTable, object virtualTable, @@ -3120,8 +3121,8 @@ class MyProcessor: public Processor { { return vm::makeClass (t, flags, vmFlags, fixedSize, arrayElementSize, arrayDimensions, - objectMask, name, super, interfaceTable, virtualTable, fieldTable, - methodTable, staticTable, loader, 0); + objectMask, name, sourceFile, super, interfaceTable, virtualTable, + fieldTable, methodTable, staticTable, loader, 0); } virtual void diff --git a/src/machine.cpp b/src/machine.cpp index 8819dce09e..7780b35b19 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -1594,6 +1594,24 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool) } } +void +parseAttributeTable(Thread* t, Stream& s, object class_, object pool) +{ + unsigned attributeCount = s.read2(); + for (unsigned j = 0; j < attributeCount; ++j) { + object name = singletonObject(t, pool, s.read2() - 1); + unsigned length = s.read4(); + + if (vm::strcmp(reinterpret_cast("SourceFile"), + &byteArrayBody(t, name, 0)) == 0) + { + set(t, class_, ClassSourceFile, singletonObject(t, pool, s.read2() - 1)); + } else { + s.skip(length); + } + } +} + void updateClassTables(Thread* t, object newClass, object oldClass) { @@ -1672,6 +1690,7 @@ makeArrayClass(Thread* t, object loader, unsigned dimensions, object spec, dimensions, classObjectMask(t, arrayBody(t, t->m->types, Machine::ArrayType)), spec, + 0, arrayBody(t, t->m->types, Machine::JobjectType), 0, vtable, @@ -1806,8 +1825,8 @@ bootClass(Thread* t, Machine::Type type, int superType, uint32_t objectMask, super = (superType >= 0 ? arrayBody(t, t->m->types, superType) : 0); object class_ = t->m->processor->makeClass - (t, 0, BootstrapFlag, fixedSize, arrayElementSize, 0, mask, 0, super, 0, 0, - 0, 0, 0, t->m->loader, vtableLength); + (t, 0, BootstrapFlag, fixedSize, arrayElementSize, 0, mask, 0, 0, super, 0, + 0, 0, 0, 0, t->m->loader, vtableLength); set(t, t->m->types, ArrayBody + (type * BytesPerWord), class_); } @@ -2800,6 +2819,7 @@ parseClass(Thread* t, object loader, const uint8_t* data, unsigned size) 0, // object mask referenceName (t, singletonObject(t, pool, name - 1)), + 0, 0, // super 0, // interfaces 0, // vtable @@ -2832,6 +2852,9 @@ parseClass(Thread* t, object loader, const uint8_t* data, unsigned size) parseMethodTable(t, s, class_, pool); if (UNLIKELY(t->exception)) return 0; + parseAttributeTable(t, s, class_, pool); + if (UNLIKELY(t->exception)) return 0; + object vtable = classVirtualTable(t, class_); unsigned vtableLength = (vtable ? arrayLength(t, vtable) : 0); @@ -2844,6 +2867,7 @@ parseClass(Thread* t, object loader, const uint8_t* data, unsigned size) classArrayDimensions(t, class_), classObjectMask(t, class_), className(t, class_), + classSourceFile(t, class_), classSuper(t, class_), classInterfaceTable(t, class_), classVirtualTable(t, class_), diff --git a/src/processor.h b/src/processor.h index dddf9006f5..187994f3b2 100644 --- a/src/processor.h +++ b/src/processor.h @@ -66,6 +66,7 @@ class Processor { uint8_t arrayDimensions, object objectMask, object name, + object sourceFile, object super, object interfaceTable, object virtualTable,