diff --git a/readme.txt b/readme.txt index fd4d549fbc..f28c70ebeb 100644 --- a/readme.txt +++ b/readme.txt @@ -176,40 +176,18 @@ extern "C" { } // extern "C" -#ifdef JNI_VERSION_1_6 -typedef struct JDK1_1InitArgs { - jint version; - - char **properties; - jint checkSource; - jint nativeStackSize; - jint javaStackSize; - jint minHeapSize; - jint maxHeapSize; - jint verifyMode; - char *classpath; - - jint (JNICALL *vfprintf)(FILE *fp, const char *format, va_list args); - void (JNICALL *exit)(jint code); - void (JNICALL *abort)(void); - - jint enableClassGC; - jint enableVerboseGC; - jint disableAsyncGC; - jint verbose; - jboolean debugging; - jint debugPort; -} JDK1_1InitArgs; -#endif - int main(int ac, const char** av) { - JDK1_1InitArgs vmArgs; - vmArgs.version = 0x00010001; - JNI_GetDefaultJavaVMInitArgs(&vmArgs); + JavaVMInitArgs vmArgs; + vmArgs.version = JNI_VERSION_1_2; + vmArgs.nOptions = 1; + vmArgs.ignoreUnrecognized = JNI_TRUE; - vmArgs.classpath = const_cast("[bootJar]"); + JavaVMOption options[vmArgs.nOptions]; + vmArgs.options = options; + + options[0].optionString = const_cast("-Djava.class.path=[bootJar]"); JavaVM* vm; void* env; diff --git a/src/common.h b/src/common.h index a02627b5d8..f0ac8f60cf 100644 --- a/src/common.h +++ b/src/common.h @@ -23,8 +23,10 @@ #undef JNIEXPORT #ifdef __MINGW32__ # define JNIEXPORT __declspec(dllexport) +# define PATH_SEPARATOR ';' #else # define JNIEXPORT __attribute__ ((visibility("default"))) +# define PATH_SEPARATOR ':' #endif #ifdef __i386__ diff --git a/src/jnienv.cpp b/src/jnienv.cpp index 9d2147e432..27827d86f9 100644 --- a/src/jnienv.cpp +++ b/src/jnienv.cpp @@ -1845,30 +1845,39 @@ IsSameObject(Thread* t, jobject a, jobject b) } } -struct JDK1_1InitArgs { +struct JavaVMOption { + char* optionString; + void* extraInfo; +}; + +struct JavaVMInitArgs { jint version; - const char** properties; - jint checkSource; - jint nativeStackSize; - jint javaStackSize; - jint minHeapSize; - jint maxHeapSize; - jint verifyMode; - const char* classpath; - - jint (JNICALL *vfprintf)(FILE* fp, const char* format, va_list args); - void (JNICALL *exit)(jint code); - void (JNICALL *abort)(void); - - jint enableClassGC; - jint enableVerboseGC; - jint disableAsyncGC; - jint verbose; - jboolean debugging; - jint debugPort; + jint nOptions; + JavaVMOption* options; + jboolean ignoreUnrecognized; }; +int +parseSize(const char* s) +{ + unsigned length = strlen(s); + char buffer[length + 1]; + if (length == 0) { + return 0; + } else if (s[length - 1] == 'k') { + memcpy(buffer, s, length - 1); + buffer[length] = 0; + return atoi(buffer) * 1024; + } else if (s[length - 1] == 'm') { + memcpy(buffer, s, length - 1); + buffer[length] = 0; + return atoi(buffer) * 1024 * 1024; + } else { + return atoi(s); + } +} + } // namespace namespace vm { @@ -2040,43 +2049,74 @@ populateJNITables(JavaVMVTable* vmTable, JNIEnvVTable* envTable) } // namespace vm -extern "C" JNIEXPORT jint JNICALL -JNI_GetDefaultJavaVMInitArgs(void* args) -{ - JDK1_1InitArgs* a = static_cast(args); - a->maxHeapSize = 128 * 1024 * 1024; - a->classpath = "."; - a->properties = 0; - return 0; -} - #define BUILTINS_PROPERTY "avian.builtins" #define BOOTSTRAP_PROPERTY "avian.bootstrap" +#define CLASSPATH_PROPERTY "java.class.path" + +extern "C" JNIEXPORT jint JNICALL +JNI_GetDefaultJavaVMInitArgs(void*) +{ + return 0; +} extern "C" JNIEXPORT jint JNICALL JNI_CreateJavaVM(Machine** m, Thread** t, void* args) { - JDK1_1InitArgs* a = static_cast(args); + JavaVMInitArgs* a = static_cast(args); + unsigned heapLimit = 0; const char* builtins = 0; const char* bootLibrary = 0; - if (a->properties) { - for (const char** p = a->properties; *p; ++p) { - if (strncmp(*p, BUILTINS_PROPERTY "=", + const char* classpath = 0; + const char* bootClasspath = 0; + + for (int i = 0; i < a->nOptions; ++i) { + if (strncmp(a->options[i].optionString, "-Xmx", 4) == 0) { + heapLimit = parseSize(a->options[i].optionString + 4); + } else if (strncmp(a->options[i].optionString, + "-Xbootclasspath:", 16) == 0) + { + bootClasspath = a->options[i].optionString + 16; + } else if (strncmp(a->options[i].optionString, "-D", 2) == 0) { + const char* p = a->options[i].optionString + 2; + if (strncmp(p, BUILTINS_PROPERTY "=", sizeof(BUILTINS_PROPERTY)) == 0) { - builtins = (*p) + sizeof(BUILTINS_PROPERTY); - } else if (strncmp(*p, BOOTSTRAP_PROPERTY "=", + builtins = p + sizeof(BUILTINS_PROPERTY); + } else if (strncmp(p, BOOTSTRAP_PROPERTY "=", sizeof(BOOTSTRAP_PROPERTY)) == 0) { - bootLibrary = (*p) + sizeof(BOOTSTRAP_PROPERTY); + bootLibrary = p + sizeof(BOOTSTRAP_PROPERTY); + } else if (strncmp(p, CLASSPATH_PROPERTY "=", + sizeof(CLASSPATH_PROPERTY)) == 0) + { + classpath = p + sizeof(CLASSPATH_PROPERTY); } + + // todo: add properties to VM } } + if (heapLimit == 0) heapLimit = 128 * 1024 * 1024; + + if (classpath == 0) classpath = "."; + + unsigned bcpl = bootClasspath ? strlen(bootClasspath) : 0; + unsigned cpl = strlen(classpath); + + unsigned classpathBufferSize = bcpl + cpl + 2; + char classpathBuffer[classpathBufferSize]; + + if (bootClasspath) { + snprintf(classpathBuffer, classpathBufferSize, "%s%c%s", + bootClasspath, PATH_SEPARATOR, classpath); + } else { + memcpy(classpathBuffer, classpath, cpl + 1); + } + System* s = makeSystem(); - Heap* h = makeHeap(s, a->maxHeapSize); - Finder* f = makeFinder(s, a->classpath, bootLibrary); + Heap* h = makeHeap(s, heapLimit); + Finder* f = makeFinder(s, classpathBuffer, bootLibrary); Processor* p = makeProcessor(s, h); *m = new (h->allocate(sizeof(Machine))) diff --git a/src/main.cpp b/src/main.cpp index f2557e3a68..0624f3cbc9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -20,33 +20,6 @@ # define PATH_SEPARATOR ':' #endif -#ifdef JNI_VERSION_1_6 -// todo: use JavaVMInitArgs instead -typedef struct JDK1_1InitArgs { - jint version; - - char **properties; - jint checkSource; - jint nativeStackSize; - jint javaStackSize; - jint minHeapSize; - jint maxHeapSize; - jint verifyMode; - char *classpath; - - jint (JNICALL *vfprintf)(FILE *fp, const char *format, va_list args); - void (JNICALL *exit)(jint code); - void (JNICALL *abort)(void); - - jint enableClassGC; - jint enableVerboseGC; - jint disableAsyncGC; - jint verbose; - jboolean debugging; - jint debugPort; -} JDK1_1InitArgs; -#endif - namespace { void @@ -62,22 +35,25 @@ usageAndExit(const char* name) int main(int ac, const char** av) { - JDK1_1InitArgs vmArgs; - vmArgs.version = 0x00010001; - JNI_GetDefaultJavaVMInitArgs(&vmArgs); + JavaVMInitArgs vmArgs; + vmArgs.version = JNI_VERSION_1_2; + vmArgs.nOptions = 1; + vmArgs.ignoreUnrecognized = JNI_TRUE; const char* class_ = 0; int argc = 0; const char** argv = 0; - int propertyCount = 0; + const char* classpath = "."; for (int i = 1; i < ac; ++i) { - if (strcmp(av[i], "-cp") == 0) { - vmArgs.classpath = const_cast(av[++i]); - } else if (strncmp(av[i], "-Xmx", 4) == 0) { - vmArgs.maxHeapSize = atoi(av[i] + 4); - } else if (strncmp(av[i], "-D", 2) == 0) { - ++ propertyCount; + if (strcmp(av[i], "-cp") == 0 + or strcmp(av[i], "-classpath") == 0) + { + classpath = av[++i]; + } else if (strncmp(av[i], "-X", 2) == 0 + or strncmp(av[i], "-D", 2) == 0) + { + ++ vmArgs.nOptions; } else { class_ = av[i++]; if (i < ac) { @@ -88,35 +64,54 @@ main(int ac, const char** av) } } -#ifdef BOOT_CLASSPATH - unsigned size = sizeof(BOOT_CLASSPATH) + 1 + strlen(vmArgs.classpath); - char classpath[size]; - snprintf(classpath, size, "%s%c%s", - BOOT_CLASSPATH, PATH_SEPARATOR, vmArgs.classpath); - vmArgs.classpath = classpath; +#ifdef BOOT_LIBRARY + ++ vmArgs.nOptions; #endif + JavaVMOption options[vmArgs.nOptions]; + vmArgs.options = options; + +#ifdef BOOT_CLASSPATH + unsigned classpathBufferSize + = sizeof(BOOT_CLASSPATH) + 1 + strlen(classpath); + char classpathBuffer[classpathBufferSize]; + + snprintf(classpathBuffer, classpathBufferSize, "%s%c%s", + BOOT_CLASSPATH, PATH_SEPARATOR, classpath); + classpath = classpathBuffer; +#endif + + unsigned optionIndex = 0; + #ifdef BOOT_LIBRARY - const int BootPropertyCount = 1; -#else - const int BootPropertyCount = 0; + options[optionIndex++].optionString + = const_cast("-Davian.bootstrap=" BOOT_LIBRARY); #endif - const char* properties[propertyCount + BootPropertyCount + 1]; - properties[propertyCount + BootPropertyCount] = 0; +#define CLASSPATH_PROPERTY "-Djava.class.path=" + + unsigned classpathSize = strlen(classpath); + unsigned classpathPropertyBufferSize + = sizeof(CLASSPATH_PROPERTY) + classpathSize; + + char classpathPropertyBuffer[classpathPropertyBufferSize]; + memcpy(classpathPropertyBuffer, + CLASSPATH_PROPERTY, + sizeof(CLASSPATH_PROPERTY) - 1); + memcpy(classpathPropertyBuffer + sizeof(CLASSPATH_PROPERTY) - 1, + classpath, + classpathSize + 1); + + options[optionIndex++].optionString = classpathPropertyBuffer; + for (int i = 1; i < ac; ++i) { - if (strncmp(av[i], "-D", 2) == 0) { - properties[--propertyCount] = av[i] + 2; + if (strncmp(av[i], "-X", 2) == 0 + or strncmp(av[i], "-D", 2) == 0) + { + options[optionIndex++].optionString = const_cast(av[i]); } } -#ifdef BOOT_LIBRARY - properties[propertyCount + BootPropertyCount - 1] - = "avian.bootstrap=" BOOT_LIBRARY; -#endif - - vmArgs.properties = const_cast(properties); - if (class_ == 0) { usageAndExit(av[0]); }