mirror of
https://github.com/corda/corda.git
synced 2025-01-29 07:34:13 +00:00
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:
parent
89b22dd3ab
commit
1c90ea5fd6
14
makefile
14
makefile
@ -52,7 +52,7 @@ warnings = -Wall -Wextra -Werror -Wunused-parameter \
|
|||||||
|
|
||||||
common-cflags = $(warnings) -fno-rtti -fno-exceptions \
|
common-cflags = $(warnings) -fno-rtti -fno-exceptions \
|
||||||
-I$(JAVA_HOME)/include -idirafter $(src) -I$(bld) -D__STDC_LIMIT_MACROS \
|
-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 \
|
cflags = $(common-cflags) -fPIC -fvisibility=hidden \
|
||||||
-I$(JAVA_HOME)/include/linux -I$(src) -pthread
|
-I$(JAVA_HOME)/include/linux -I$(src) -pthread
|
||||||
@ -140,8 +140,7 @@ interpreter-sources = \
|
|||||||
$(src)/heap.cpp \
|
$(src)/heap.cpp \
|
||||||
$(src)/$(process).cpp \
|
$(src)/$(process).cpp \
|
||||||
$(src)/builtin.cpp \
|
$(src)/builtin.cpp \
|
||||||
$(src)/jnienv.cpp \
|
$(src)/jnienv.cpp
|
||||||
$(src)/main.cpp
|
|
||||||
|
|
||||||
interpreter-asm-sources = $(src)/$(asm).S
|
interpreter-asm-sources = $(src)/$(asm).S
|
||||||
|
|
||||||
@ -157,6 +156,10 @@ interpreter-objects = \
|
|||||||
$(interpreter-cpp-objects) \
|
$(interpreter-cpp-objects) \
|
||||||
$(interpreter-asm-objects)
|
$(interpreter-asm-objects)
|
||||||
|
|
||||||
|
driver-sources = $(src)/main.cpp
|
||||||
|
|
||||||
|
driver-objects = $(call cpp-objects,$(driver-sources),$(src),$(bld))
|
||||||
|
|
||||||
generator-headers = \
|
generator-headers = \
|
||||||
$(src)/input.h \
|
$(src)/input.h \
|
||||||
$(src)/output.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
|
$(interpreter-asm-objects): $(bld)/%-asm.o: $(src)/%.S
|
||||||
$(compile-object)
|
$(compile-object)
|
||||||
|
|
||||||
|
$(driver-objects): $(bld)/%.o: $(src)/%.cpp
|
||||||
|
$(compile-object)
|
||||||
|
|
||||||
$(generator-objects): $(bld)/%.o: $(src)/%.cpp
|
$(generator-objects): $(bld)/%.o: $(src)/%.cpp
|
||||||
@echo "compiling $(@)"
|
@echo "compiling $(@)"
|
||||||
@mkdir -p -m 1777 $(dir $(@))
|
@mkdir -p -m 1777 $(dir $(@))
|
||||||
@ -273,7 +279,7 @@ $(archive): $(interpreter-objects) $(jni-objects)
|
|||||||
$(ranlib) $(@)
|
$(ranlib) $(@)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(executable): $(archive)
|
$(executable): $(archive) $(driver-objects)
|
||||||
@echo "linking $(@)"
|
@echo "linking $(@)"
|
||||||
$(cc) -Wl,--whole-archive $(^) -Wl,--no-whole-archive \
|
$(cc) -Wl,--whole-archive $(^) -Wl,--no-whole-archive \
|
||||||
$(lflags) $(rdynamic) -o $(@)
|
$(lflags) $(rdynamic) -o $(@)
|
||||||
|
@ -53,8 +53,6 @@
|
|||||||
|
|
||||||
inline void* operator new(size_t, void* p) throw() { return p; }
|
inline void* operator new(size_t, void* p) throw() { return p; }
|
||||||
|
|
||||||
inline void operator delete(void*) { abort(); }
|
|
||||||
|
|
||||||
namespace vm {
|
namespace vm {
|
||||||
|
|
||||||
const unsigned BytesPerWord = sizeof(uintptr_t);
|
const unsigned BytesPerWord = sizeof(uintptr_t);
|
||||||
|
@ -558,21 +558,21 @@ invokeNative(Thread* t, object method)
|
|||||||
case ByteField:
|
case ByteField:
|
||||||
case BooleanField:
|
case BooleanField:
|
||||||
if (DebugRun) {
|
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));
|
pushInt(t, static_cast<int8_t>(result));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CharField:
|
case CharField:
|
||||||
if (DebugRun) {
|
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));
|
pushInt(t, static_cast<uint16_t>(result));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ShortField:
|
case ShortField:
|
||||||
if (DebugRun) {
|
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));
|
pushInt(t, static_cast<int16_t>(result));
|
||||||
break;
|
break;
|
||||||
@ -580,7 +580,7 @@ invokeNative(Thread* t, object method)
|
|||||||
case FloatField:
|
case FloatField:
|
||||||
case IntField:
|
case IntField:
|
||||||
if (DebugRun) {
|
if (DebugRun) {
|
||||||
fprintf(stderr, "result: %"LLD"\n", result);
|
fprintf(stderr, "result: %d\n", static_cast<int32_t>(result));
|
||||||
}
|
}
|
||||||
pushInt(t, result);
|
pushInt(t, result);
|
||||||
break;
|
break;
|
||||||
|
109
src/jnienv.cpp
109
src/jnienv.cpp
@ -2,6 +2,13 @@
|
|||||||
#include "machine.h"
|
#include "machine.h"
|
||||||
#include "processor.h"
|
#include "processor.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
|
#include "processor.h"
|
||||||
|
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
# define JNIEXPORT __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
# define JNIEXPORT __attribute__ ((visibility("default")))
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace vm;
|
using namespace vm;
|
||||||
|
|
||||||
@ -10,6 +17,25 @@ namespace {
|
|||||||
const uintptr_t InterfaceMethodID
|
const uintptr_t InterfaceMethodID
|
||||||
= (static_cast<uintptr_t>(1) << (BitsPerWord - 1));
|
= (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
|
jint JNICALL
|
||||||
AttachCurrentThread(Machine* m, Thread** t, void*)
|
AttachCurrentThread(Machine* m, Thread** t, void*)
|
||||||
{
|
{
|
||||||
@ -1062,6 +1088,36 @@ ExceptionClear(Thread* t)
|
|||||||
t->exception = 0;
|
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
|
jbooleanArray JNICALL
|
||||||
NewBooleanArray(Thread* t, jsize length)
|
NewBooleanArray(Thread* t, jsize length)
|
||||||
{
|
{
|
||||||
@ -1589,6 +1645,30 @@ IsSameObject(Thread* t, jobject a, jobject b)
|
|||||||
return *a == *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
|
||||||
|
|
||||||
namespace vm {
|
namespace vm {
|
||||||
@ -1598,6 +1678,7 @@ populateJNITables(JavaVMVTable* vmTable, JNIEnvVTable* envTable)
|
|||||||
{
|
{
|
||||||
memset(vmTable, 0, sizeof(JavaVMVTable));
|
memset(vmTable, 0, sizeof(JavaVMVTable));
|
||||||
|
|
||||||
|
vmTable->DestroyJavaVM = DestroyJavaVM;
|
||||||
vmTable->AttachCurrentThread = AttachCurrentThread;
|
vmTable->AttachCurrentThread = AttachCurrentThread;
|
||||||
vmTable->DetachCurrentThread = DetachCurrentThread;
|
vmTable->DetachCurrentThread = DetachCurrentThread;
|
||||||
vmTable->GetEnv = GetEnv;
|
vmTable->GetEnv = GetEnv;
|
||||||
@ -1699,6 +1780,9 @@ populateJNITables(JavaVMVTable* vmTable, JNIEnvVTable* envTable)
|
|||||||
envTable->ExceptionOccurred = ::ExceptionOccurred;
|
envTable->ExceptionOccurred = ::ExceptionOccurred;
|
||||||
envTable->ExceptionDescribe = ::ExceptionDescribe;
|
envTable->ExceptionDescribe = ::ExceptionDescribe;
|
||||||
envTable->ExceptionClear = ::ExceptionClear;
|
envTable->ExceptionClear = ::ExceptionClear;
|
||||||
|
envTable->NewObjectArray = ::NewObjectArray;
|
||||||
|
envTable->GetObjectArrayElement = ::GetObjectArrayElement;
|
||||||
|
envTable->SetObjectArrayElement = ::SetObjectArrayElement;
|
||||||
envTable->NewBooleanArray = ::NewBooleanArray;
|
envTable->NewBooleanArray = ::NewBooleanArray;
|
||||||
envTable->NewByteArray = ::NewByteArray;
|
envTable->NewByteArray = ::NewByteArray;
|
||||||
envTable->NewCharArray = ::NewCharArray;
|
envTable->NewCharArray = ::NewCharArray;
|
||||||
@ -1746,3 +1830,28 @@ populateJNITables(JavaVMVTable* vmTable, JNIEnvVTable* envTable)
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace vm
|
} // 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;
|
||||||
|
}
|
||||||
|
@ -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
|
object
|
||||||
makeTrace(Thread* t, uintptr_t start)
|
makeTrace(Thread* t, uintptr_t start)
|
||||||
{
|
{
|
||||||
|
@ -2190,10 +2190,6 @@ intern(Thread* t, object s);
|
|||||||
void
|
void
|
||||||
exit(Thread* t);
|
exit(Thread* t);
|
||||||
|
|
||||||
int
|
|
||||||
run(System* system, Heap* heap, Finder* finder, Processor* processor,
|
|
||||||
const char* className, int argc, const char** argv);
|
|
||||||
|
|
||||||
inline jobject
|
inline jobject
|
||||||
makeLocalReference(Thread* t, object o)
|
makeLocalReference(Thread* t, object o)
|
||||||
{
|
{
|
||||||
|
78
src/main.cpp
78
src/main.cpp
@ -1,39 +1,17 @@
|
|||||||
#include "common.h"
|
#include "stdlib.h"
|
||||||
#include "system.h"
|
#include "string.h"
|
||||||
#include "heap.h"
|
#include "jni.h"
|
||||||
#include "finder.h"
|
|
||||||
#include "processor.h"
|
|
||||||
#include "machine.h"
|
|
||||||
|
|
||||||
using namespace vm;
|
|
||||||
|
|
||||||
extern "C" void __cxa_pure_virtual(void) { abort(); }
|
extern "C" void __cxa_pure_virtual(void) { abort(); }
|
||||||
|
|
||||||
|
void operator delete(void*) { abort(); }
|
||||||
|
|
||||||
namespace {
|
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
|
void
|
||||||
usageAndExit(const char* name)
|
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);
|
"<class name> [<argument> ...]\n", name);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
@ -43,17 +21,19 @@ usageAndExit(const char* name)
|
|||||||
int
|
int
|
||||||
main(int ac, const char** av)
|
main(int ac, const char** av)
|
||||||
{
|
{
|
||||||
unsigned heapSize = 128 * 1024 * 1024;
|
JDK1_1InitArgs vmArgs;
|
||||||
const char* path = ".";
|
vmArgs.version = 0x00010001;
|
||||||
|
JNI_GetDefaultJavaVMInitArgs(&vmArgs);
|
||||||
|
|
||||||
const char* class_ = 0;
|
const char* class_ = 0;
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
const char** argv = 0;
|
const char** argv = 0;
|
||||||
|
|
||||||
for (int i = 1; i < ac; ++i) {
|
for (int i = 1; i < ac; ++i) {
|
||||||
if (strcmp(av[i], "-cp") == 0) {
|
if (strcmp(av[i], "-cp") == 0) {
|
||||||
path = av[++i];
|
vmArgs.classpath = const_cast<char*>(av[++i]);
|
||||||
} else if (strcmp(av[i], "-hs") == 0) {
|
} else if (strncmp(av[i], "-Xmx", 4) == 0) {
|
||||||
heapSize = atoi(av[++i]);
|
vmArgs.maxHeapSize = atoi(av[i] + 4);
|
||||||
} else {
|
} else {
|
||||||
class_ = av[i++];
|
class_ = av[i++];
|
||||||
if (i < ac) {
|
if (i < ac) {
|
||||||
@ -68,5 +48,35 @@ main(int ac, const char** av)
|
|||||||
usageAndExit(av[0]);
|
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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user