From b8de552797b26d9cec6f1d9a40d8eb338f6e6cf2 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 27 Aug 2007 07:46:17 -0600 Subject: [PATCH] re-implement System.getProperty to separate vm-specific properties from others --- classpath/java-io.cpp | 11 +---------- classpath/java-lang.cpp | 28 ++++++++++++++++------------ classpath/java/lang/System.java | 29 ++++++++++++++++++++++++++++- classpath/jni-util.h | 18 ++++++++++++++++++ src/builtin.cpp | 19 +++++++++++++++++++ src/finder.cpp | 29 ++++++++++++++++++++++------- src/finder.h | 1 + 7 files changed, 105 insertions(+), 30 deletions(-) create mode 100644 classpath/jni-util.h diff --git a/classpath/java-io.cpp b/classpath/java-io.cpp index f945f44bc8..8bc85a8e05 100644 --- a/classpath/java-io.cpp +++ b/classpath/java-io.cpp @@ -6,6 +6,7 @@ #include #include "jni.h" +#include "jni-util.h" #undef JNIEXPORT #define JNIEXPORT __attribute__ ((visibility("default"))) @@ -36,16 +37,6 @@ namespace { -inline void -throwNew(JNIEnv* e, const char* class_, const char* message) -{ - jclass c = e->FindClass(class_); - if (c) { - e->ThrowNew(c, message); - e->DeleteLocalRef(c); - } -} - inline bool exists(const char* path) { diff --git a/classpath/java-lang.cpp b/classpath/java-lang.cpp index 59aac75c61..fd819c08f8 100644 --- a/classpath/java-lang.cpp +++ b/classpath/java-lang.cpp @@ -3,26 +3,30 @@ #include "time.h" #include "string.h" #include "jni.h" +#include "jni-util.h" #undef JNIEXPORT #define JNIEXPORT __attribute__ ((visibility("default"))) extern "C" JNIEXPORT jstring JNICALL -Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring key) +Java_java_lang_System_getProperty(JNIEnv* e, jclass, jint code) { - jstring value = 0; + enum { + LineSeparator = 100, + OsName = 101 + }; - const char* chars = e->GetStringUTFChars(key, 0); - if (chars) { - if (strcmp(chars, "line.separator") == 0) { - value = e->NewStringUTF("\n"); - } else if (strcmp(chars, "os.name") == 0) { - value = e->NewStringUTF("posix"); - } - e->ReleaseStringUTFChars(key, chars); + switch (code) { + case LineSeparator: + return e->NewStringUTF("\n"); + + case OsName: + return e->NewStringUTF("posix"); + + default: + throwNew(e, "java/lang/RuntimeException", 0); + return 0; } - - return value; } extern "C" JNIEXPORT jlong JNICALL diff --git a/classpath/java/lang/System.java b/classpath/java/lang/System.java index 0afee7fd5e..80d0367639 100644 --- a/classpath/java/lang/System.java +++ b/classpath/java/lang/System.java @@ -9,6 +9,12 @@ import java.io.FileOutputStream; import java.io.FileDescriptor; public abstract class System { + private static final int Unknown = 0; + private static final int JavaClassPath = 1; + private static final int LineSeparator = 100; + private static final int OsName = 101; + + static { loadLibrary("natives"); } @@ -25,7 +31,28 @@ public abstract class System { public static native void arraycopy(Object src, int srcOffset, Object dst, int dstOffset, int length); - public static native String getProperty(String name); + public static String getProperty(String name) { + int code = Unknown; + if (name.equals("java.class.path")) { + code = JavaClassPath; + } else if (name.equals("line.separator")) { + code = LineSeparator; + } else if (name.equals("os.name")) { + code = OsName; + } + + if (code == Unknown) { + return null; + } else if (code == JavaClassPath) { + return getVMProperty(code); + } else { + return getProperty(code); + } + } + + private static native String getProperty(int code); + + private static native String getVMProperty(int code); public static native long currentTimeMillis(); diff --git a/classpath/jni-util.h b/classpath/jni-util.h new file mode 100644 index 0000000000..5a5d7bf81f --- /dev/null +++ b/classpath/jni-util.h @@ -0,0 +1,18 @@ +#ifndef JNI_UTIL +#define JNI_UTIL + +namespace { + +inline void +throwNew(JNIEnv* e, const char* class_, const char* message) +{ + jclass c = e->FindClass(class_); + if (c) { + e->ThrowNew(c, message); + e->DeleteLocalRef(c); + } +} + +} // namespace + +#endif//JNI_UTIL diff --git a/src/builtin.cpp b/src/builtin.cpp index 479d721407..fe68a052c4 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -331,6 +331,23 @@ String_intern(Thread* t, jobject this_) return pushReference(t, intern(t, *this_)); } +jstring +System_getVMProperty(Thread* t, jclass, jint code) +{ + enum { + JavaClassPath = 1 + }; + + switch (code) { + case JavaClassPath: + return pushReference(t, makeString(t, "%s", t->vm->finder->path())); + + default: + t->exception = makeRuntimeException(t, 0); + return 0; + } +} + void System_arraycopy(Thread* t, jclass, jobject src, jint srcOffset, jobject dst, jint dstOffset, jint length) @@ -584,6 +601,8 @@ populateBuiltinMap(Thread* t, object map) { "Java_java_lang_ClassLoader_defineClass", reinterpret_cast(::ClassLoader_defineClass) }, + { "Java_java_lang_System_getVMProperty", + reinterpret_cast(::System_getVMProperty) }, { "Java_java_lang_System_arraycopy", reinterpret_cast(::System_arraycopy) }, diff --git a/src/finder.cpp b/src/finder.cpp index 2a56f769ba..ea4e980779 100644 --- a/src/finder.cpp +++ b/src/finder.cpp @@ -23,6 +23,15 @@ append(System* s, const char* a, const char* b, const char* c) return p; } +const char* +copy(System* s, const char* a) +{ + unsigned al = strlen(a); + char* p = static_cast(s->allocate(al + 1)); + memcpy(p, a, al + 1); + return p; +} + const char** parsePath(System* s, const char* path) { @@ -77,7 +86,8 @@ class MyFinder: public Finder { public: MyFinder(System* system, const char* path): system(system), - path(parsePath(system, path)) + path_(parsePath(system, path)), + pathString(copy(system, path)) { } class Data: public Finder::Data { @@ -111,7 +121,7 @@ class MyFinder: public Finder { virtual Data* find(const char* name) { Data* d = new (system->allocate(sizeof(Data))) Data(system, 0, 0); - for (const char** p = path; *p; ++p) { + for (const char** p = path_; *p; ++p) { const char* file = append(system, *p, "/", name); int fd = open(file, O_RDONLY); system->free(file); @@ -135,7 +145,7 @@ class MyFinder: public Finder { } virtual bool exists(const char* name) { - for (const char** p = path; *p; ++p) { + for (const char** p = path_; *p; ++p) { const char* file = append(system, *p, "/", name); struct stat s; int r = stat(file, &s); @@ -148,17 +158,22 @@ class MyFinder: public Finder { return false; } + virtual const char* path() { + return pathString; + } + virtual void dispose() { - for (const char** p = path; *p; ++p) { + for (const char** p = path_; *p; ++p) { system->free(*p); } - system->free(path); - + system->free(path_); + system->free(pathString); system->free(this); } System* system; - const char** path; + const char** path_; + const char* pathString; }; } // namespace diff --git a/src/finder.h b/src/finder.h index 02449a3a14..1caf1aa08b 100644 --- a/src/finder.h +++ b/src/finder.h @@ -19,6 +19,7 @@ class Finder { virtual ~Finder() { } virtual Data* find(const char* name) = 0; virtual bool exists(const char* name) = 0; + virtual const char* path() = 0; virtual void dispose() = 0; };