mirror of
https://github.com/corda/corda.git
synced 2025-01-16 01:40:17 +00:00
flesh out ClassLoader, etc.
This commit is contained in:
parent
da692a539f
commit
38d4ee6e07
@ -6,6 +6,10 @@ import java.lang.reflect.Field;
|
|||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
|
|
||||||
public final class Class <T> {
|
public final class Class <T> {
|
||||||
|
private static final int ReferenceFlag = 1 << 0;
|
||||||
|
private static final int WeakReferenceFlag = 1 << 1;
|
||||||
|
private static final int NeedInitFlag = 1 << 2;
|
||||||
|
|
||||||
private short flags;
|
private short flags;
|
||||||
private byte vmFlags;
|
private byte vmFlags;
|
||||||
private byte arrayDimensions;
|
private byte arrayDimensions;
|
||||||
@ -19,6 +23,7 @@ public final class Class <T> {
|
|||||||
private Field[] fieldTable;
|
private Field[] fieldTable;
|
||||||
private Method[] methodTable;
|
private Method[] methodTable;
|
||||||
private Object[] staticTable;
|
private Object[] staticTable;
|
||||||
|
private ClassLoader loader;
|
||||||
|
|
||||||
private Class() { }
|
private Class() { }
|
||||||
|
|
||||||
@ -26,8 +31,25 @@ public final class Class <T> {
|
|||||||
return new String(name, 0, name.length - 1, false);
|
return new String(name, 0, name.length - 1, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static native Class forName(String name)
|
public static Class forName(String name) throws ClassNotFoundException {
|
||||||
throws ClassNotFoundException;
|
return forName
|
||||||
|
(name, true, Method.getCaller().getDeclaringClass().getClassLoader());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Class forName(String name, boolean initialize,
|
||||||
|
ClassLoader loader)
|
||||||
|
throws ClassNotFoundException
|
||||||
|
{
|
||||||
|
Class c = loader.loadClass(name);
|
||||||
|
if (initialize && ((c.flags & NeedInitFlag) != 0)) {
|
||||||
|
c.flags &= ~NeedInitFlag;
|
||||||
|
Method m = c.findMethod("<clinit>", new Class[0]);
|
||||||
|
if (m != null) {
|
||||||
|
m.invoke(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
private static native Class primitiveClass(char name);
|
private static native Class primitiveClass(char name);
|
||||||
|
|
||||||
@ -282,7 +304,7 @@ public final class Class <T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ClassLoader getClassLoader() {
|
public ClassLoader getClassLoader() {
|
||||||
return ClassLoader.getSystemClassLoader();
|
return loader;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getModifiers() {
|
public int getModifiers() {
|
||||||
|
@ -1,15 +1,78 @@
|
|||||||
package java.lang;
|
package java.lang;
|
||||||
|
|
||||||
public class ClassLoader {
|
public abstract class ClassLoader {
|
||||||
private static final ClassLoader instance = new ClassLoader();
|
private final ClassLoader parent;
|
||||||
|
|
||||||
private ClassLoader() { }
|
protected ClassLoader(ClassLoader parent) {
|
||||||
|
if (parent == null) {
|
||||||
|
this.parent = getSystemClassLoader();
|
||||||
|
} else {
|
||||||
|
this.parent = parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ClassLoader() {
|
||||||
|
this(getSystemClassLoader());
|
||||||
|
}
|
||||||
|
|
||||||
public static ClassLoader getSystemClassLoader() {
|
public static ClassLoader getSystemClassLoader() {
|
||||||
return instance;
|
return ClassLoader.class.getClassLoader();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native Class defineClass(byte[] b, int offset, int length);
|
||||||
|
|
||||||
|
protected Class defineClass(String name, byte[] b, int offset, int length) {
|
||||||
|
if (b == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset < 0 || offset > length || offset + length > b.length) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return defineClass(b, offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Class findClass(String name) throws ClassNotFoundException {
|
||||||
|
throw new ClassNotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Class findLoadedClass(String name) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class loadClass(String name) throws ClassNotFoundException {
|
public Class loadClass(String name) throws ClassNotFoundException {
|
||||||
return Class.forName(name);
|
return loadClass(name, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Class loadClass(String name, boolean resolve)
|
||||||
|
throws ClassNotFoundException
|
||||||
|
{
|
||||||
|
Class c = findLoadedClass(name);
|
||||||
|
if (c == null) {
|
||||||
|
if (parent != null) {
|
||||||
|
try {
|
||||||
|
c = parent.loadClass(name);
|
||||||
|
} catch (ClassNotFoundException ok) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == null) {
|
||||||
|
c = findClass(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resolve) {
|
||||||
|
resolveClass(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void resolveClass(Class c) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
private ClassLoader getParent() {
|
||||||
|
return parent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,63 +27,27 @@ public final class Math {
|
|||||||
return (int) (v + 0.5);
|
return (int) (v + 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double floor(double v) {
|
public static native double floor(double v);
|
||||||
// todo
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double ceil(double v) {
|
public static native double ceil(double v);
|
||||||
// todo
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double exp(double v) {
|
public static native double exp(double v);
|
||||||
// todo
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double log(double v) {
|
public static native double log(double v);
|
||||||
// todo
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double cos(double v) {
|
public static native double cos(double v);
|
||||||
// todo
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double sin(double v) {
|
public static native double sin(double v);
|
||||||
// todo
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double tan(double v) {
|
public static native double tan(double v);
|
||||||
// todo
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double acos(double v) {
|
public static native double acos(double v);
|
||||||
// todo
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double asin(double v) {
|
public static native double asin(double v);
|
||||||
// todo
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double atan(double v) {
|
public static native double atan(double v);
|
||||||
// todo
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double sqrt(double v) {
|
public static native double sqrt(double v);
|
||||||
// todo
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double pow(double v, double e) {
|
public static native double pow(double v, double e);
|
||||||
// todo
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
9
classpath/java/lang/SystemClassLoader.java
Normal file
9
classpath/java/lang/SystemClassLoader.java
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package java.lang;
|
||||||
|
|
||||||
|
public class SystemClassLoader extends ClassLoader {
|
||||||
|
private Object map;
|
||||||
|
|
||||||
|
protected native Class findClass(String name) throws ClassNotFoundException;
|
||||||
|
|
||||||
|
protected native Class findLoadedClass(String name);
|
||||||
|
}
|
@ -21,6 +21,8 @@ public class Method<T> extends AccessibleObject implements Member {
|
|||||||
if (v) vmFlags |= Accessible; else vmFlags &= ~Accessible;
|
if (v) vmFlags |= Accessible; else vmFlags &= ~Accessible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static native Method getCaller();
|
||||||
|
|
||||||
public Class<T> getDeclaringClass() {
|
public Class<T> getDeclaringClass() {
|
||||||
return class_;
|
return class_;
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ Object_notifyAll(Thread* t, jobject this_)
|
|||||||
}
|
}
|
||||||
|
|
||||||
jclass
|
jclass
|
||||||
Class_forName(Thread* t, jclass, jstring name)
|
search(Thread* t, jstring name, object (*op)(Thread*, object))
|
||||||
{
|
{
|
||||||
if (LIKELY(name)) {
|
if (LIKELY(name)) {
|
||||||
object n = makeByteArray(t, stringLength(t, *name) + 1, false);
|
object n = makeByteArray(t, stringLength(t, *name) + 1, false);
|
||||||
@ -68,18 +68,11 @@ Class_forName(Thread* t, jclass, jstring name)
|
|||||||
|
|
||||||
replace('.', '/', s);
|
replace('.', '/', s);
|
||||||
|
|
||||||
object c = resolveClass(t, n);
|
object c = op(t, n);
|
||||||
if (t->exception) {
|
if (t->exception) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classVmFlags(t, c) & NeedInitFlag) {
|
|
||||||
PROTECT(t, c);
|
|
||||||
|
|
||||||
classVmFlags(t, c) &= ~NeedInitFlag;
|
|
||||||
run(t, classInitializer(t, c), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pushReference(t, c);
|
return pushReference(t, c);
|
||||||
} else {
|
} else {
|
||||||
t->exception = makeNullPointerException(t);
|
t->exception = makeNullPointerException(t);
|
||||||
@ -87,6 +80,29 @@ Class_forName(Thread* t, jclass, jstring name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jclass
|
||||||
|
ClassLoader_defineClass(Thread* t, jclass, jbyteArray b, jint offset,
|
||||||
|
jint length)
|
||||||
|
{
|
||||||
|
uint8_t* buffer = static_cast<uint8_t*>(t->vm->system->allocate(length));
|
||||||
|
memcpy(buffer, &byteArrayBody(t, *b, offset), length);
|
||||||
|
object c = parseClass(t, buffer, length);
|
||||||
|
t->vm->system->free(buffer);
|
||||||
|
return pushReference(t, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
jclass
|
||||||
|
SystemClassLoader_findLoadedClass(Thread* t, jclass, jstring name)
|
||||||
|
{
|
||||||
|
return search(t, name, findClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
jclass
|
||||||
|
SystemClassLoader_findClass(Thread* t, jclass, jstring name)
|
||||||
|
{
|
||||||
|
return search(t, name, resolveClass);
|
||||||
|
}
|
||||||
|
|
||||||
jclass
|
jclass
|
||||||
Class_primitiveClass(Thread* t, jclass, jchar name)
|
Class_primitiveClass(Thread* t, jclass, jchar name)
|
||||||
{
|
{
|
||||||
@ -297,6 +313,13 @@ Constructor_make(Thread* t, jclass, jclass c)
|
|||||||
return pushReference(t, make(t, c));
|
return pushReference(t, make(t, c));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jobject
|
||||||
|
Method_getCaller(Thread* t, jclass)
|
||||||
|
{
|
||||||
|
return pushReference
|
||||||
|
(t, frameMethod(t, frameNext(t, frameNext(t, t->frame))));
|
||||||
|
}
|
||||||
|
|
||||||
jobject
|
jobject
|
||||||
Method_invoke(Thread* t, jobject this_, jobject instancep,
|
Method_invoke(Thread* t, jobject this_, jobject instancep,
|
||||||
jobjectArray argumentsp)
|
jobjectArray argumentsp)
|
||||||
@ -638,16 +661,22 @@ populateBuiltinMap(Thread* t, object map)
|
|||||||
const char* key;
|
const char* key;
|
||||||
void* value;
|
void* value;
|
||||||
} builtins[] = {
|
} builtins[] = {
|
||||||
{ "Java_java_lang_Class_forName",
|
|
||||||
reinterpret_cast<void*>(::Class_forName) },
|
|
||||||
{ "Java_java_lang_Class_isAssignableFrom",
|
{ "Java_java_lang_Class_isAssignableFrom",
|
||||||
reinterpret_cast<void*>(::Class_isAssignableFrom) },
|
reinterpret_cast<void*>(::Class_isAssignableFrom) },
|
||||||
{ "Java_java_lang_Class_primitiveClass",
|
{ "Java_java_lang_Class_primitiveClass",
|
||||||
reinterpret_cast<void*>(::Class_primitiveClass) },
|
reinterpret_cast<void*>(::Class_primitiveClass) },
|
||||||
|
|
||||||
|
{ "Java_java_lang_ClassLoader_defineClass",
|
||||||
|
reinterpret_cast<void*>(::ClassLoader_defineClass) },
|
||||||
|
|
||||||
{ "Java_java_lang_System_arraycopy",
|
{ "Java_java_lang_System_arraycopy",
|
||||||
reinterpret_cast<void*>(::System_arraycopy) },
|
reinterpret_cast<void*>(::System_arraycopy) },
|
||||||
|
|
||||||
|
{ "Java_java_lang_SystemClassLoader_findClass",
|
||||||
|
reinterpret_cast<void*>(::SystemClassLoader_findClass) },
|
||||||
|
{ "Java_java_lang_SystemClassLoader_findLoadedClass",
|
||||||
|
reinterpret_cast<void*>(::SystemClassLoader_findLoadedClass) },
|
||||||
|
|
||||||
{ "Java_java_lang_Runtime_loadLibrary",
|
{ "Java_java_lang_Runtime_loadLibrary",
|
||||||
reinterpret_cast<void*>(::Runtime_loadLibrary) },
|
reinterpret_cast<void*>(::Runtime_loadLibrary) },
|
||||||
{ "Java_java_lang_Runtime_gc",
|
{ "Java_java_lang_Runtime_gc",
|
||||||
@ -698,6 +727,8 @@ populateBuiltinMap(Thread* t, object map)
|
|||||||
{ "Java_java_lang_reflect_Field_set",
|
{ "Java_java_lang_reflect_Field_set",
|
||||||
reinterpret_cast<void*>(::Field_set) },
|
reinterpret_cast<void*>(::Field_set) },
|
||||||
|
|
||||||
|
{ "Java_java_lang_reflect_Method_getCaller",
|
||||||
|
reinterpret_cast<void*>(::Method_getCaller) },
|
||||||
{ "Java_java_lang_reflect_Method_invoke",
|
{ "Java_java_lang_reflect_Method_invoke",
|
||||||
reinterpret_cast<void*>(::Method_invoke) },
|
reinterpret_cast<void*>(::Method_invoke) },
|
||||||
|
|
||||||
|
170
src/machine.cpp
170
src/machine.cpp
@ -1064,73 +1064,6 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object
|
|
||||||
parseClass(Thread* t, const uint8_t* data, unsigned size)
|
|
||||||
{
|
|
||||||
class Client : public Stream::Client {
|
|
||||||
public:
|
|
||||||
Client(Thread* t): t(t) { }
|
|
||||||
|
|
||||||
virtual void NO_RETURN handleEOS() {
|
|
||||||
abort(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Thread* t;
|
|
||||||
} client(t);
|
|
||||||
|
|
||||||
Stream s(&client, data, size);
|
|
||||||
|
|
||||||
uint32_t magic = s.read4();
|
|
||||||
assert(t, magic == 0xCAFEBABE);
|
|
||||||
s.read2(); // minor version
|
|
||||||
s.read2(); // major version
|
|
||||||
|
|
||||||
object pool = parsePool(t, s);
|
|
||||||
PROTECT(t, pool);
|
|
||||||
|
|
||||||
unsigned flags = s.read2();
|
|
||||||
unsigned name = s.read2();
|
|
||||||
|
|
||||||
object class_ = makeClass(t,
|
|
||||||
flags,
|
|
||||||
0, // VM flags
|
|
||||||
0, // array dimensions
|
|
||||||
0, // fixed size
|
|
||||||
0, // array size
|
|
||||||
0, // object mask
|
|
||||||
arrayBody(t, pool, name - 1),
|
|
||||||
0, // super
|
|
||||||
0, // interfaces
|
|
||||||
0, // vtable
|
|
||||||
0, // fields
|
|
||||||
0, // methods
|
|
||||||
0); // static table
|
|
||||||
PROTECT(t, class_);
|
|
||||||
|
|
||||||
unsigned super = s.read2();
|
|
||||||
if (super) {
|
|
||||||
object sc = resolveClass(t, arrayBody(t, pool, super - 1));
|
|
||||||
if (UNLIKELY(t->exception)) return 0;
|
|
||||||
|
|
||||||
set(t, classSuper(t, class_), sc);
|
|
||||||
|
|
||||||
classVmFlags(t, class_)
|
|
||||||
|= (classVmFlags(t, sc) & (ReferenceFlag | WeakReferenceFlag));
|
|
||||||
}
|
|
||||||
|
|
||||||
parseInterfaceTable(t, s, class_, pool);
|
|
||||||
if (UNLIKELY(t->exception)) return 0;
|
|
||||||
|
|
||||||
parseFieldTable(t, s, class_, pool);
|
|
||||||
if (UNLIKELY(t->exception)) return 0;
|
|
||||||
|
|
||||||
parseMethodTable(t, s, class_, pool);
|
|
||||||
if (UNLIKELY(t->exception)) return 0;
|
|
||||||
|
|
||||||
return class_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
updateBootstrapClass(Thread* t, object bootstrapClass, object class_)
|
updateBootstrapClass(Thread* t, object bootstrapClass, object class_)
|
||||||
{
|
{
|
||||||
@ -1195,7 +1128,8 @@ makeArrayClass(Thread* t, unsigned dimensions, object spec,
|
|||||||
classVirtualTable(t, arrayBody(t, t->vm->types, Machine::JobjectType)),
|
classVirtualTable(t, arrayBody(t, t->vm->types, Machine::JobjectType)),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0);
|
0,
|
||||||
|
t->vm->loader);
|
||||||
}
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
@ -1285,7 +1219,7 @@ Machine::Machine(System* system, Heap* heap, ClassFinder* classFinder):
|
|||||||
classLock(0),
|
classLock(0),
|
||||||
referenceLock(0),
|
referenceLock(0),
|
||||||
libraries(0),
|
libraries(0),
|
||||||
classMap(0),
|
loader(0),
|
||||||
bootstrapClassMap(0),
|
bootstrapClassMap(0),
|
||||||
builtinMap(0),
|
builtinMap(0),
|
||||||
monitorMap(0),
|
monitorMap(0),
|
||||||
@ -1358,11 +1292,18 @@ Thread::Thread(Machine* m, object javaThread, Thread* parent):
|
|||||||
|
|
||||||
Thread* t = this;
|
Thread* t = this;
|
||||||
|
|
||||||
|
t->vm->loader = allocate(t, sizeof(void*) * 3);
|
||||||
|
memset(t->vm->loader, 0, sizeof(void*) * 2);
|
||||||
|
|
||||||
#include "type-initializations.cpp"
|
#include "type-initializations.cpp"
|
||||||
|
|
||||||
object arrayClass = arrayBody(t, t->vm->types, Machine::ArrayType);
|
object arrayClass = arrayBody(t, t->vm->types, Machine::ArrayType);
|
||||||
set(t, cast<object>(t->vm->types, 0), arrayClass);
|
set(t, cast<object>(t->vm->types, 0), arrayClass);
|
||||||
|
|
||||||
|
object loaderClass = arrayBody
|
||||||
|
(t, t->vm->types, Machine::SystemClassLoaderType);
|
||||||
|
set(t, cast<object>(t->vm->loader, 0), loaderClass);
|
||||||
|
|
||||||
object objectClass = arrayBody(t, m->types, Machine::JobjectType);
|
object objectClass = arrayBody(t, m->types, Machine::JobjectType);
|
||||||
|
|
||||||
object classClass = arrayBody(t, m->types, Machine::ClassType);
|
object classClass = arrayBody(t, m->types, Machine::ClassType);
|
||||||
@ -1386,7 +1327,9 @@ Thread::Thread(Machine* m, object javaThread, Thread* parent):
|
|||||||
|
|
||||||
#include "type-java-initializations.cpp"
|
#include "type-java-initializations.cpp"
|
||||||
|
|
||||||
m->classMap = makeHashMap(this, 0, 0);
|
object loaderMap = makeHashMap(this, 0, 0);
|
||||||
|
set(t, systemClassLoaderMap(t, m->loader), loaderMap);
|
||||||
|
|
||||||
m->builtinMap = makeHashMap(this, 0, 0);
|
m->builtinMap = makeHashMap(this, 0, 0);
|
||||||
m->monitorMap = makeWeakHashMap(this, 0, 0);
|
m->monitorMap = makeWeakHashMap(this, 0, 0);
|
||||||
m->stringMap = makeWeakHashMap(this, 0, 0);
|
m->stringMap = makeWeakHashMap(this, 0, 0);
|
||||||
@ -2087,14 +2030,92 @@ primitiveSize(Thread* t, unsigned code)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object
|
||||||
|
findClass(Thread* t, object spec)
|
||||||
|
{
|
||||||
|
PROTECT(t, spec);
|
||||||
|
ACQUIRE(t, t->vm->classLock);
|
||||||
|
|
||||||
|
return hashMapFind(t, systemClassLoaderMap(t, t->vm->loader),
|
||||||
|
spec, byteArrayHash, byteArrayEqual);
|
||||||
|
}
|
||||||
|
|
||||||
|
object
|
||||||
|
parseClass(Thread* t, const uint8_t* data, unsigned size)
|
||||||
|
{
|
||||||
|
class Client : public Stream::Client {
|
||||||
|
public:
|
||||||
|
Client(Thread* t): t(t) { }
|
||||||
|
|
||||||
|
virtual void NO_RETURN handleEOS() {
|
||||||
|
abort(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Thread* t;
|
||||||
|
} client(t);
|
||||||
|
|
||||||
|
Stream s(&client, data, size);
|
||||||
|
|
||||||
|
uint32_t magic = s.read4();
|
||||||
|
assert(t, magic == 0xCAFEBABE);
|
||||||
|
s.read2(); // minor version
|
||||||
|
s.read2(); // major version
|
||||||
|
|
||||||
|
object pool = parsePool(t, s);
|
||||||
|
PROTECT(t, pool);
|
||||||
|
|
||||||
|
unsigned flags = s.read2();
|
||||||
|
unsigned name = s.read2();
|
||||||
|
|
||||||
|
object class_ = makeClass(t,
|
||||||
|
flags,
|
||||||
|
0, // VM flags
|
||||||
|
0, // array dimensions
|
||||||
|
0, // fixed size
|
||||||
|
0, // array size
|
||||||
|
0, // object mask
|
||||||
|
arrayBody(t, pool, name - 1),
|
||||||
|
0, // super
|
||||||
|
0, // interfaces
|
||||||
|
0, // vtable
|
||||||
|
0, // fields
|
||||||
|
0, // methods
|
||||||
|
0, // static table
|
||||||
|
t->vm->loader);
|
||||||
|
PROTECT(t, class_);
|
||||||
|
|
||||||
|
unsigned super = s.read2();
|
||||||
|
if (super) {
|
||||||
|
object sc = resolveClass(t, arrayBody(t, pool, super - 1));
|
||||||
|
if (UNLIKELY(t->exception)) return 0;
|
||||||
|
|
||||||
|
set(t, classSuper(t, class_), sc);
|
||||||
|
|
||||||
|
classVmFlags(t, class_)
|
||||||
|
|= (classVmFlags(t, sc) & (ReferenceFlag | WeakReferenceFlag));
|
||||||
|
}
|
||||||
|
|
||||||
|
parseInterfaceTable(t, s, class_, pool);
|
||||||
|
if (UNLIKELY(t->exception)) return 0;
|
||||||
|
|
||||||
|
parseFieldTable(t, s, class_, pool);
|
||||||
|
if (UNLIKELY(t->exception)) return 0;
|
||||||
|
|
||||||
|
parseMethodTable(t, s, class_, pool);
|
||||||
|
if (UNLIKELY(t->exception)) return 0;
|
||||||
|
|
||||||
|
return class_;
|
||||||
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
resolveClass(Thread* t, object spec)
|
resolveClass(Thread* t, object spec)
|
||||||
{
|
{
|
||||||
PROTECT(t, spec);
|
PROTECT(t, spec);
|
||||||
ACQUIRE(t, t->vm->classLock);
|
ACQUIRE(t, t->vm->classLock);
|
||||||
|
|
||||||
object class_ = hashMapFind
|
object class_ = hashMapFind(t, systemClassLoaderMap(t, t->vm->loader),
|
||||||
(t, t->vm->classMap, spec, byteArrayHash, byteArrayEqual);
|
spec, byteArrayHash, byteArrayEqual);
|
||||||
if (class_ == 0) {
|
if (class_ == 0) {
|
||||||
if (byteArrayBody(t, spec, 0) == '[') {
|
if (byteArrayBody(t, spec, 0) == '[') {
|
||||||
class_ = hashMapFind
|
class_ = hashMapFind
|
||||||
@ -2137,7 +2158,8 @@ resolveClass(Thread* t, object spec)
|
|||||||
if (class_) {
|
if (class_) {
|
||||||
PROTECT(t, class_);
|
PROTECT(t, class_);
|
||||||
|
|
||||||
hashMapInsert(t, t->vm->classMap, spec, class_, byteArrayHash);
|
hashMapInsert(t, systemClassLoaderMap(t, t->vm->loader),
|
||||||
|
spec, class_, byteArrayHash);
|
||||||
} else if (t->exception == 0) {
|
} else if (t->exception == 0) {
|
||||||
object message = makeString(t, "%s", &byteArrayBody(t, spec, 0));
|
object message = makeString(t, "%s", &byteArrayBody(t, spec, 0));
|
||||||
t->exception = makeClassNotFoundException(t, message);
|
t->exception = makeClassNotFoundException(t, message);
|
||||||
@ -2285,7 +2307,7 @@ collect(Thread* t, Heap::CollectionType type)
|
|||||||
Client(Machine* m): m(m) { }
|
Client(Machine* m): m(m) { }
|
||||||
|
|
||||||
virtual void visitRoots(Heap::Visitor* v) {
|
virtual void visitRoots(Heap::Visitor* v) {
|
||||||
v->visit(&(m->classMap));
|
v->visit(&(m->loader));
|
||||||
v->visit(&(m->bootstrapClassMap));
|
v->visit(&(m->bootstrapClassMap));
|
||||||
v->visit(&(m->builtinMap));
|
v->visit(&(m->builtinMap));
|
||||||
v->visit(&(m->monitorMap));
|
v->visit(&(m->monitorMap));
|
||||||
|
@ -1106,7 +1106,7 @@ class Machine {
|
|||||||
System::Monitor* classLock;
|
System::Monitor* classLock;
|
||||||
System::Monitor* referenceLock;
|
System::Monitor* referenceLock;
|
||||||
System::Library* libraries;
|
System::Library* libraries;
|
||||||
object classMap;
|
object loader;
|
||||||
object bootstrapClassMap;
|
object bootstrapClassMap;
|
||||||
object builtinMap;
|
object builtinMap;
|
||||||
object monitorMap;
|
object monitorMap;
|
||||||
@ -2022,6 +2022,12 @@ fieldSize(Thread* t, object field)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object
|
||||||
|
findClass(Thread* t, object spec);
|
||||||
|
|
||||||
|
object
|
||||||
|
parseClass(Thread* t, const uint8_t* data, unsigned length);
|
||||||
|
|
||||||
object
|
object
|
||||||
resolveClass(Thread* t, object spec);
|
resolveClass(Thread* t, object spec);
|
||||||
|
|
||||||
|
@ -1488,7 +1488,7 @@ writeInitialization(Output* out, Object* type)
|
|||||||
out->write(typeFixedSize(type));
|
out->write(typeFixedSize(type));
|
||||||
out->write(", ");
|
out->write(", ");
|
||||||
out->write(typeArrayElementSize(type));
|
out->write(typeArrayElementSize(type));
|
||||||
out->write(", mask, 0, super, 0, 0, 0, 0, 0);\n");
|
out->write(", mask, 0, super, 0, 0, 0, 0, 0, t->vm->loader);\n");
|
||||||
|
|
||||||
out->write(" set(t, arrayBody(t, t->vm->types, Machine::");
|
out->write(" set(t, arrayBody(t, t->vm->types, Machine::");
|
||||||
out->write(capitalize(typeName(type)));
|
out->write(capitalize(typeName(type)));
|
||||||
|
@ -14,7 +14,16 @@
|
|||||||
(object virtualTable)
|
(object virtualTable)
|
||||||
(object fieldTable)
|
(object fieldTable)
|
||||||
(object methodTable)
|
(object methodTable)
|
||||||
(object staticTable))
|
(object staticTable)
|
||||||
|
(object loader))
|
||||||
|
|
||||||
|
(type classLoader java/lang/ClassLoader
|
||||||
|
(extends jobject)
|
||||||
|
(object parent))
|
||||||
|
|
||||||
|
(type systemClassLoader java/lang/SystemClassLoader
|
||||||
|
(extends classLoader)
|
||||||
|
(object map))
|
||||||
|
|
||||||
(type accessibleObject java/lang/reflect/AccessibleObject
|
(type accessibleObject java/lang/reflect/AccessibleObject
|
||||||
(extends jobject))
|
(extends jobject))
|
||||||
|
Loading…
Reference in New Issue
Block a user