rewrite main.cpp to use jni.h interface for creating the VM and invoking the main method of the specified class

This commit is contained in:
Joel Dice 2007-10-25 09:04:13 -06:00
parent 89b22dd3ab
commit 1c90ea5fd6
7 changed files with 167 additions and 70 deletions

View File

@ -52,7 +52,7 @@ warnings = -Wall -Wextra -Werror -Wunused-parameter \
common-cflags = $(warnings) -fno-rtti -fno-exceptions \
-I$(JAVA_HOME)/include -idirafter $(src) -I$(bld) -D__STDC_LIMIT_MACROS \
-DBUILTIN_LIBRARIES=\"natives,tlscontext,scaler\"
-DBUILTIN_LIBRARIES=\"natives,tlscontext,scaler\" -D_JNI_IMPLEMENTATION_
cflags = $(common-cflags) -fPIC -fvisibility=hidden \
-I$(JAVA_HOME)/include/linux -I$(src) -pthread
@ -140,8 +140,7 @@ interpreter-sources = \
$(src)/heap.cpp \
$(src)/$(process).cpp \
$(src)/builtin.cpp \
$(src)/jnienv.cpp \
$(src)/main.cpp
$(src)/jnienv.cpp
interpreter-asm-sources = $(src)/$(asm).S
@ -157,6 +156,10 @@ interpreter-objects = \
$(interpreter-cpp-objects) \
$(interpreter-asm-objects)
driver-sources = $(src)/main.cpp
driver-objects = $(call cpp-objects,$(driver-sources),$(src),$(bld))
generator-headers = \
$(src)/input.h \
$(src)/output.h
@ -249,6 +252,9 @@ $(interpreter-cpp-objects): $(bld)/%.o: $(src)/%.cpp $(interpreter-depends)
$(interpreter-asm-objects): $(bld)/%-asm.o: $(src)/%.S
$(compile-object)
$(driver-objects): $(bld)/%.o: $(src)/%.cpp
$(compile-object)
$(generator-objects): $(bld)/%.o: $(src)/%.cpp
@echo "compiling $(@)"
@mkdir -p -m 1777 $(dir $(@))
@ -273,7 +279,7 @@ $(archive): $(interpreter-objects) $(jni-objects)
$(ranlib) $(@)
endif
$(executable): $(archive)
$(executable): $(archive) $(driver-objects)
@echo "linking $(@)"
$(cc) -Wl,--whole-archive $(^) -Wl,--no-whole-archive \
$(lflags) $(rdynamic) -o $(@)

View File

@ -53,8 +53,6 @@
inline void* operator new(size_t, void* p) throw() { return p; }
inline void operator delete(void*) { abort(); }
namespace vm {
const unsigned BytesPerWord = sizeof(uintptr_t);

View File

@ -558,21 +558,21 @@ invokeNative(Thread* t, object method)
case ByteField:
case BooleanField:
if (DebugRun) {
fprintf(stderr, "result: %"LLD"\n", static_cast<int8_t>(result));
fprintf(stderr, "result: %d\n", static_cast<int8_t>(result));
}
pushInt(t, static_cast<int8_t>(result));
break;
case CharField:
if (DebugRun) {
fprintf(stderr, "result: %"LLD"\n", static_cast<uint16_t>(result));
fprintf(stderr, "result: %d\n", static_cast<uint16_t>(result));
}
pushInt(t, static_cast<uint16_t>(result));
break;
case ShortField:
if (DebugRun) {
fprintf(stderr, "result: %"LLD"\n", static_cast<int16_t>(result));
fprintf(stderr, "result: %d\n", static_cast<int16_t>(result));
}
pushInt(t, static_cast<int16_t>(result));
break;
@ -580,7 +580,7 @@ invokeNative(Thread* t, object method)
case FloatField:
case IntField:
if (DebugRun) {
fprintf(stderr, "result: %"LLD"\n", result);
fprintf(stderr, "result: %d\n", static_cast<int32_t>(result));
}
pushInt(t, result);
break;

View File

@ -2,6 +2,13 @@
#include "machine.h"
#include "processor.h"
#include "constants.h"
#include "processor.h"
#ifdef __MINGW32__
# define JNIEXPORT __declspec(dllexport)
#else
# define JNIEXPORT __attribute__ ((visibility("default")))
#endif
using namespace vm;
@ -10,6 +17,25 @@ namespace {
const uintptr_t InterfaceMethodID
= (static_cast<uintptr_t>(1) << (BitsPerWord - 1));
jint JNICALL
DestroyJavaVM(Machine* m)
{
System* s = m->system;
Processor* p = m->processor;
Heap* h = m->heap;
Finder* f = m->finder;
int exitCode = (m->rootThread->exception ? -1 : 0);
m->dispose();
p->dispose();
h->dispose();
f->dispose();
s->dispose();
return exitCode;
}
jint JNICALL
AttachCurrentThread(Machine* m, Thread** t, void*)
{
@ -1062,6 +1088,36 @@ ExceptionClear(Thread* t)
t->exception = 0;
}
jobjectArray JNICALL
NewObjectArray(Thread* t, jsize length, jclass class_, jobject init)
{
ENTER(t, Thread::ActiveState);
object a = makeObjectArray(t, *class_, length, false);
object value = (init ? *init : 0);
for (jsize i = 0; i < length; ++i) {
set(t, a, ArrayBody + (i * BytesPerWord), value);
}
return makeLocalReference(t, a);
}
jobject JNICALL
GetObjectArrayElement(Thread* t, jobjectArray array, jsize index)
{
ENTER(t, Thread::ActiveState);
return makeLocalReference(t, objectArrayBody(t, *array, index));
}
void JNICALL
SetObjectArrayElement(Thread* t, jobjectArray array, jsize index,
jobject value)
{
ENTER(t, Thread::ActiveState);
set(t, *array, ArrayBody + (index * BytesPerWord), *value);
}
jbooleanArray JNICALL
NewBooleanArray(Thread* t, jsize length)
{
@ -1589,6 +1645,30 @@ IsSameObject(Thread* t, jobject a, jobject b)
return *a == *b;
}
struct JDK1_1InitArgs {
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;
};
} // namespace
namespace vm {
@ -1598,6 +1678,7 @@ populateJNITables(JavaVMVTable* vmTable, JNIEnvVTable* envTable)
{
memset(vmTable, 0, sizeof(JavaVMVTable));
vmTable->DestroyJavaVM = DestroyJavaVM;
vmTable->AttachCurrentThread = AttachCurrentThread;
vmTable->DetachCurrentThread = DetachCurrentThread;
vmTable->GetEnv = GetEnv;
@ -1699,6 +1780,9 @@ populateJNITables(JavaVMVTable* vmTable, JNIEnvVTable* envTable)
envTable->ExceptionOccurred = ::ExceptionOccurred;
envTable->ExceptionDescribe = ::ExceptionDescribe;
envTable->ExceptionClear = ::ExceptionClear;
envTable->NewObjectArray = ::NewObjectArray;
envTable->GetObjectArrayElement = ::GetObjectArrayElement;
envTable->SetObjectArrayElement = ::SetObjectArrayElement;
envTable->NewBooleanArray = ::NewBooleanArray;
envTable->NewByteArray = ::NewByteArray;
envTable->NewCharArray = ::NewCharArray;
@ -1746,3 +1830,28 @@ populateJNITables(JavaVMVTable* vmTable, JNIEnvVTable* envTable)
}
} // namespace vm
extern "C" JNIEXPORT jint JNICALL
JNI_GetDefaultJavaVMInitArgs(void* args)
{
JDK1_1InitArgs* a = static_cast<JDK1_1InitArgs*>(args);
a->maxHeapSize = 128 * 1024 * 1024;
a->classpath = ".";
return 0;
}
extern "C" JNIEXPORT jint JNICALL
JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
{
JDK1_1InitArgs* a = static_cast<JDK1_1InitArgs*>(args);
System* s = makeSystem(a->maxHeapSize);
Finder* f = makeFinder(s, a->classpath);
Heap* h = makeHeap(s);
Processor* p = makeProcessor(s);
*m = new (s->allocate(sizeof(Machine))) Machine(s, h, f, p);
*t = p->makeThread(*m, 0, 0);
return 0;
}

View File

@ -2703,28 +2703,6 @@ printTrace(Thread* t, object exception)
}
}
int
run(System* system, Heap* heap, Finder* finder, Processor* processor,
const char* className, int argc, const char** argv)
{
Machine m(system, heap, finder, processor);
Thread* t = processor->makeThread(&m, 0, 0);
enter(t, Thread::ActiveState);
::invoke(t, className, argc, argv);
int exitCode = 0;
if (t->exception) {
exitCode = -1;
printTrace(t, t->exception);
}
exit(t);
return exitCode;
}
object
makeTrace(Thread* t, uintptr_t start)
{

View File

@ -2190,10 +2190,6 @@ intern(Thread* t, object s);
void
exit(Thread* t);
int
run(System* system, Heap* heap, Finder* finder, Processor* processor,
const char* className, int argc, const char** argv);
inline jobject
makeLocalReference(Thread* t, object o)
{

View File

@ -1,39 +1,17 @@
#include "common.h"
#include "system.h"
#include "heap.h"
#include "finder.h"
#include "processor.h"
#include "machine.h"
using namespace vm;
#include "stdlib.h"
#include "string.h"
#include "jni.h"
extern "C" void __cxa_pure_virtual(void) { abort(); }
void operator delete(void*) { abort(); }
namespace {
int
run(unsigned heapSize, const char* path, const char* class_, int argc,
const char** argv)
{
System* s = makeSystem(heapSize);
Finder* f = makeFinder(s, path);
Heap* heap = makeHeap(s);
Processor* p = makeProcessor(s);
int exitCode = run(s, heap, f, p, class_, argc, argv);
p->dispose();
heap->dispose();
f->dispose();
s->dispose();
return exitCode;
}
void
usageAndExit(const char* name)
{
fprintf(stderr, "usage: %s [-cp <classpath>] [-hs <maximum heap size>] "
fprintf(stderr, "usage: %s [-cp <classpath>] [-Xmx<maximum heap size>] "
"<class name> [<argument> ...]\n", name);
exit(-1);
}
@ -43,17 +21,19 @@ usageAndExit(const char* name)
int
main(int ac, const char** av)
{
unsigned heapSize = 128 * 1024 * 1024;
const char* path = ".";
JDK1_1InitArgs vmArgs;
vmArgs.version = 0x00010001;
JNI_GetDefaultJavaVMInitArgs(&vmArgs);
const char* class_ = 0;
int argc = 0;
const char** argv = 0;
for (int i = 1; i < ac; ++i) {
if (strcmp(av[i], "-cp") == 0) {
path = av[++i];
} else if (strcmp(av[i], "-hs") == 0) {
heapSize = atoi(av[++i]);
vmArgs.classpath = const_cast<char*>(av[++i]);
} else if (strncmp(av[i], "-Xmx", 4) == 0) {
vmArgs.maxHeapSize = atoi(av[i] + 4);
} else {
class_ = av[i++];
if (i < ac) {
@ -68,5 +48,35 @@ main(int ac, const char** av)
usageAndExit(av[0]);
}
return run(heapSize, path, class_, argc, argv);
JavaVM* vm;
JNIEnv* e;
JNI_CreateJavaVM(&vm, reinterpret_cast<void**>(&e), &vmArgs);
jclass c = e->FindClass(class_);
if (not e->ExceptionOccurred()) {
jmethodID m = e->GetStaticMethodID(c, "main", "([Ljava/lang/String;)V");
if (not e->ExceptionOccurred()) {
jclass stringClass = e->FindClass("java/lang/String");
if (not e->ExceptionOccurred()) {
jobjectArray a = e->NewObjectArray(argc, stringClass, 0);
if (not e->ExceptionOccurred()) {
for (int i = 0; i < argc; ++i) {
e->SetObjectArrayElement(a, i, e->NewStringUTF(argv[i]));
}
e->CallStaticVoidMethod(c, m, a);
}
}
}
}
int exitCode = 0;
if (e->ExceptionOccurred()) {
exitCode = -1;
e->ExceptionDescribe();
}
vm->DestroyJavaVM();
return exitCode;
}