more progress on GNU Classpath compatibility

This commit is contained in:
Joel Dice 2009-06-04 17:21:42 -06:00
parent 4a87d82d8e
commit 0857f53651
5 changed files with 215 additions and 17 deletions

View File

@ -596,7 +596,9 @@ public final class String
} }
public static String valueOf(int v) { public static String valueOf(int v) {
return Integer.toString(v); // use Integer.toString(int, int), because GNU Classpath's
// Integer.toString(int) just calls String.valueOf(int):
return Integer.toString(v, 10);
} }
public static String valueOf(long v) { public static String valueOf(long v) {
@ -615,6 +617,10 @@ public final class String
return new String(data, offset, length); return new String(data, offset, length);
} }
public static String valueOf(char[] data) {
return valueOf(data, 0, data.length);
}
public int lastIndexOf(int ch, int lastIndex) { public int lastIndexOf(int ch, int lastIndex) {
for (int i = lastIndex ; i >= 0; --i) { for (int i = lastIndex ; i >= 0; --i) {
if (charAt(i) == ch) { if (charAt(i) == ch) {

View File

@ -1,4 +1,4 @@
#MAKEFLAGS = -s MAKEFLAGS = -s
name = avian name = avian
version = 0.2 version = 0.2
@ -326,12 +326,13 @@ gnu-blacklist = \
java/lang/reflect/Proxy.class java/lang/reflect/Proxy.class
gnu-overrides = \ gnu-overrides = \
avian/*.class \
java/lang/Class.class \ java/lang/Class.class \
java/lang/Enum.class \ java/lang/Enum.class \
java/lang/InheritableThreadLocal.class \ java/lang/InheritableThreadLocal.class \
java/lang/Object.class \ java/lang/Object.class \
java/lang/StackTraceElement.class \ java/lang/StackTraceElement.class \
java/lang/String.class \ java/lang/String*.class \
java/lang/StringBuffer.class \ java/lang/StringBuffer.class \
java/lang/StringBuilder.class \ java/lang/StringBuilder.class \
java/lang/Thread.class \ java/lang/Thread.class \
@ -432,7 +433,7 @@ ifdef gnu
(wd=$$(pwd); \ (wd=$$(pwd); \
cd $(classpath-build); \ cd $(classpath-build); \
$(jar) c0f "$$($(native-path) "$${wd}/$(build)/overrides.jar")" \ $(jar) c0f "$$($(native-path) "$${wd}/$(build)/overrides.jar")" \
$(gnu-overrides) $$(find avian -name '*.class'); \ $(gnu-overrides); \
rm -r *; \ rm -r *; \
$(jar) xf $(gnu)/share/classpath/glibj.zip; \ $(jar) xf $(gnu)/share/classpath/glibj.zip; \
rm $(gnu-blacklist); \ rm $(gnu-blacklist); \

View File

@ -60,21 +60,30 @@ Avian_gnu_classpath_VMSystemProperties_preInit
#ifdef WIN32 #ifdef WIN32
setProperty(t, method, properties, "line.separator", "\r\n"); setProperty(t, method, properties, "line.separator", "\r\n");
setProperty(t, method, properties, "file.separator", "\\"); setProperty(t, method, properties, "file.separator", "\\");
setProperty(t, method, properties, "path.separator", ";");
setProperty(t, method, properties, "os.name", "Windows"); setProperty(t, method, properties, "os.name", "Windows");
TCHAR buffer[MAX_PATH]; TCHAR buffer[MAX_PATH];
GetTempPath(MAX_PATH, buffer); GetTempPath(MAX_PATH, buffer);
setProperty(t, method, properties, "java.io.tmpdir", buffer); setProperty(t, method, properties, "java.io.tmpdir", buffer);
LPWSTR home = _wgetenv(L"USERPROFILE"); setProperty(t, method, properties, "user.home",
setProperty(t, method, properties, "user.home", home, "%ls"); _wgetenv(L"USERPROFILE"), "%ls");
setProperty(t, method, properties, "java.library.path",
_wgetenv(L"PATH"), "%ls");
#else #else
setProperty(t, method, properties, "line.separator", "\n"); setProperty(t, method, properties, "line.separator", "\n");
setProperty(t, method, properties, "file.separator", "/"); setProperty(t, method, properties, "file.separator", "/");
setProperty(t, method, properties, "path.separator", ":");
# ifdef __APPLE__ # ifdef __APPLE__
setProperty(t, method, properties, "os.name", "Mac OS X"); setProperty(t, method, properties, "os.name", "Mac OS X");
setProperty(t, method, properties, "java.library.path",
getenv("DYLD_LIBRARY_PATH"));
# else # else
setProperty(t, method, properties, "os.name", "Linux"); setProperty(t, method, properties, "os.name", "Linux");
setProperty(t, method, properties, "java.library.path",
getenv("LD_LIBRARY_PATH"));
# endif # endif
setProperty(t, method, properties, "java.io.tmpdir", "/tmp"); setProperty(t, method, properties, "java.io.tmpdir", "/tmp");
setProperty(t, method, properties, "user.home", getenv("HOME")); setProperty(t, method, properties, "user.home", getenv("HOME"));
@ -136,3 +145,103 @@ Avian_gnu_classpath_VMStackWalker_getClassLoader
return reinterpret_cast<int64_t> return reinterpret_cast<int64_t>
(classLoader(t, reinterpret_cast<object>(arguments[0]))); (classLoader(t, reinterpret_cast<object>(arguments[0])));
} }
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_VMRuntime_mapLibraryName
(Thread* t, object, uintptr_t* arguments)
{
object name = reinterpret_cast<object>(arguments[0]);
PROTECT(t, name);
const unsigned prefixLength = sizeof(SO_PREFIX) - 1;
const unsigned nameLength = stringLength(t, name);
const unsigned suffixLength = sizeof(SO_SUFFIX) - 1;
const unsigned total = prefixLength + nameLength + suffixLength;
object s = makeByteArray(t, total + 1);
char* p = reinterpret_cast<char*>(&byteArrayBody(t, s, 0));
memcpy(p, SO_PREFIX, prefixLength);
stringChars(t, name, p + prefixLength);
memcpy(p + prefixLength + nameLength, SO_SUFFIX, suffixLength);
p[total] = 0;
return reinterpret_cast<int64_t>(makeString(t, s, 0, total, 0));
}
extern "C" JNIEXPORT void JNICALL
Avian_java_lang_System_arraycopy
(Thread*, object, uintptr_t*);
extern "C" JNIEXPORT void JNICALL
Avian_java_lang_VMSystem_arraycopy
(Thread* t, object, uintptr_t* arguments)
{
Avian_java_lang_System_arraycopy(t, 0, arguments);
}
extern "C" JNIEXPORT void JNICALL
Avian_java_lang_Runtime_load
(Thread* t, object, uintptr_t*);
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_VMRuntime_nativeLoad
(Thread* t, object, uintptr_t* arguments)
{
uintptr_t args[] = { arguments[0], 0 };
Avian_java_lang_Runtime_load(t, 0, args);
if (t->exception) {
t->exception = 0;
return 0;
} else {
return 1;
}
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Class_primitiveClass
(Thread* t, object, uintptr_t*);
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_VMClassLoader_getPrimitiveClass
(Thread* t, object, uintptr_t* arguments)
{
return Avian_java_lang_Class_primitiveClass(t, 0, arguments);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_System_identityHashCode
(Thread*, object, uintptr_t*);
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_VMSystem_identityHashCode
(Thread* t, object, uintptr_t* arguments)
{
return Avian_java_lang_System_identityHashCode(t, 0, arguments);
}
extern "C" JNIEXPORT void JNICALL
Avian_java_lang_Runtime_gc
(Thread*, object, uintptr_t*);
extern "C" JNIEXPORT void JNICALL
Avian_java_lang_VMRuntime_gc
(Thread* t, object, uintptr_t*)
{
Avian_java_lang_Runtime_gc(t, 0, 0);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_findClass
(Thread*, object, uintptr_t*);
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_VMClassLoader_loadClass
(Thread* t, object, uintptr_t* arguments)
{
uintptr_t args[] = { 0, arguments[0] };
return Avian_avian_SystemClassLoader_findClass(t, 0, args);
}

View File

@ -256,6 +256,24 @@ ExceptionCheck(Thread* t)
return t->exception != 0; return t->exception != 0;
} }
jobject JNICALL
NewDirectByteBuffer(Thread*, void*, jlong)
{
return 0;
}
void* JNICALL
GetDirectBufferAddress(Thread*, jobject)
{
return 0;
}
jlong JNICALL
GetDirectBufferCapacity(JNIEnv*, jobject)
{
return -1;
}
jclass JNICALL jclass JNICALL
GetObjectClass(Thread* t, jobject o) GetObjectClass(Thread* t, jobject o)
{ {
@ -1905,6 +1923,9 @@ populateJNITables(JavaVMVTable* vmTable, JNIEnvVTable* envTable)
envTable->FindClass = ::FindClass; envTable->FindClass = ::FindClass;
envTable->ThrowNew = ::ThrowNew; envTable->ThrowNew = ::ThrowNew;
envTable->ExceptionCheck = ::ExceptionCheck; envTable->ExceptionCheck = ::ExceptionCheck;
envTable->NewDirectByteBuffer = ::NewDirectByteBuffer;
envTable->GetDirectBufferAddress = ::GetDirectBufferAddress;
envTable->GetDirectBufferCapacity = ::GetDirectBufferCapacity;
envTable->DeleteLocalRef = ::DeleteLocalRef; envTable->DeleteLocalRef = ::DeleteLocalRef;
envTable->GetObjectClass = ::GetObjectClass; envTable->GetObjectClass = ::GetObjectClass;
envTable->IsInstanceOf = ::IsInstanceOf; envTable->IsInstanceOf = ::IsInstanceOf;

View File

@ -496,6 +496,68 @@ makeByteArray(Thread* t, const char* format, va_list a)
return s; return s;
} }
object
parseUtf8NonAscii(Thread* t, Stream& s, object bytesSoFar, unsigned byteCount,
unsigned sourceIndex, unsigned lastByteRead)
{
PROTECT(t, bytesSoFar);
unsigned length = byteArrayLength(t, bytesSoFar) - 1;
object value = makeCharArray(t, length + 1);
unsigned vi = 0;
for (; vi < byteCount; ++vi) {
charArrayBody(t, value, vi) = byteArrayBody(t, bytesSoFar, vi);
}
unsigned a = lastByteRead;
unsigned si = sourceIndex;
while (true) {
if (a & 0x80) {
// todo: handle non-ASCII characters properly
if (a & 0x20) {
// 3 bytes
si += 2;
assert(t, si < length);
unsigned b = s.read1();
unsigned c = s.read1();
charArrayBody(t, value, vi++)
= ((a & 0xf) << 12) | ((b & 0x3f) << 6) | (c & 0x3f);
} else {
// 2 bytes
++ si;
assert(t, si < length);
unsigned b = s.read1();
if (a == 0xC0 and b == 0x80) {
charArrayBody(t, value, vi++) = 0;
} else {
charArrayBody(t, value, vi++) = ((a & 0x1f) << 6) | (b & 0x3f);
}
}
} else {
charArrayBody(t, value, vi++) = a;
}
if (++si < length) {
a = s.read1();
} else {
break;
}
}
if (vi < length) {
PROTECT(t, value);
object v = makeCharArray(t, vi + 1);
memcpy(&charArrayBody(t, v, 0), &charArrayBody(t, value, 0), vi * 2);
value = v;
}
charArrayBody(t, value, vi) = 0;
return value;
}
object object
parseUtf8(Thread* t, Stream& s, unsigned length) parseUtf8(Thread* t, Stream& s, unsigned length)
{ {
@ -507,21 +569,17 @@ parseUtf8(Thread* t, Stream& s, unsigned length)
// todo: handle non-ASCII characters properly // todo: handle non-ASCII characters properly
if (a & 0x20) { if (a & 0x20) {
// 3 bytes // 3 bytes
si += 2; return parseUtf8NonAscii(t, s, value, vi, si, a);
assert(t, si < length);
/*unsigned b = */s.read1();
/*unsigned c = */s.read1();
byteArrayBody(t, value, vi++) = '_';
} else { } else {
// 2 bytes // 2 bytes
++ si;
assert(t, si < length);
unsigned b = s.read1(); unsigned b = s.read1();
if (a == 0xC0 and b == 0x80) { if (a == 0xC0 and b == 0x80) {
++ si;
assert(t, si < length);
byteArrayBody(t, value, vi++) = 0; byteArrayBody(t, value, vi++) = 0;
} else { } else {
byteArrayBody(t, value, vi++) = '_'; return parseUtf8NonAscii(t, s, value, vi, si, a);
} }
} }
} else { } else {
@ -583,7 +641,8 @@ parsePoolEntry(Thread* t, Stream& s, uint32_t* index, object pool, unsigned i)
parsePoolEntry(t, s, index, pool, si); parsePoolEntry(t, s, index, pool, si);
object value = singletonObject(t, pool, si); object value = singletonObject(t, pool, si);
value = makeString(t, value, 0, byteArrayLength(t, value) - 1, 0); value = makeString
(t, value, 0, cast<uintptr_t>(value, BytesPerWord) - 1, 0);
value = intern(t, value); value = intern(t, value);
set(t, pool, SingletonBody + (i * BytesPerWord), value); set(t, pool, SingletonBody + (i * BytesPerWord), value);
} }
@ -1513,7 +1572,7 @@ boot(Thread* t)
m->unsafe = true; m->unsafe = true;
m->loader = allocate(t, sizeof(void*) * 3, true); m->loader = allocate(t, FixedSizeOfSystemClassLoader, true);
m->types = allocate(t, pad((TypeCount + 2) * BytesPerWord), true); m->types = allocate(t, pad((TypeCount + 2) * BytesPerWord), true);
arrayLength(t, m->types) = TypeCount; arrayLength(t, m->types) = TypeCount;
@ -2434,6 +2493,8 @@ parseClass(Thread* t, const uint8_t* data, unsigned size)
classLoader(t, class_), classLoader(t, class_),
vtableLength); vtableLength);
PROTECT(t, real);
t->m->processor->initVtable(t, real); t->m->processor->initVtable(t, real);
updateClassTables(t, real, class_); updateClassTables(t, real, class_);
@ -2977,7 +3038,7 @@ runJavaThread(Thread* t)
(t, "java/lang/Thread", "run", "(Ljava/lang/Thread;)V"); (t, "java/lang/Thread", "run", "(Ljava/lang/Thread;)V");
if (t->exception == 0) { if (t->exception == 0) {
t->m->processor->invoke (t, method, t->javaThread); t->m->processor->invoke(t, method, 0, t->javaThread);
} }
} }