re-implement System.getProperty to separate vm-specific properties from others

This commit is contained in:
Joel Dice 2007-08-27 07:46:17 -06:00
parent 493667a6cc
commit b8de552797
7 changed files with 105 additions and 30 deletions

View File

@ -6,6 +6,7 @@
#include <stdlib.h>
#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)
{

View File

@ -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

View File

@ -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();

18
classpath/jni-util.h Normal file
View File

@ -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

View File

@ -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<void*>(::ClassLoader_defineClass) },
{ "Java_java_lang_System_getVMProperty",
reinterpret_cast<void*>(::System_getVMProperty) },
{ "Java_java_lang_System_arraycopy",
reinterpret_cast<void*>(::System_arraycopy) },

View File

@ -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<char*>(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

View File

@ -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;
};