implement -jar option in main.cpp

This commit is contained in:
Joel Dice 2010-11-27 14:46:07 -07:00
parent 1f6ccbf5b7
commit 0f04865e93
2 changed files with 120 additions and 7 deletions

View File

@ -462,7 +462,10 @@ endif
driver-source = $(src)/main.cpp
driver-object = $(build)/main.o
driver-dynamic-object = $(build)/main-dynamic.o
driver-dynamic-objects = \
$(build)/main-dynamic.o \
$(build)/$(build-system).o \
$(build)/finder.o
boot-source = $(src)/boot.cpp
boot-object = $(build)/boot.o
@ -657,7 +660,7 @@ $(heapwalk-objects): $(build)/%.o: $(src)/%.cpp $(vm-depends)
$(driver-object): $(driver-source)
$(compile-object)
$(driver-dynamic-object): $(driver-source)
$(build)/main-dynamic.o: $(driver-source)
@echo "compiling $(@)"
@mkdir -p $(dir $(@))
$(cxx) $(cflags) -DBOOT_LIBRARY=\"$(so-prefix)jvm$(so-suffix)\" \
@ -797,14 +800,15 @@ else
endif
$(strip) $(strip-all) $(@)
$(executable-dynamic): $(driver-dynamic-object) $(dynamic-library)
$(executable-dynamic): $(driver-dynamic-objects) $(dynamic-library)
@echo "linking $(@)"
ifdef msvc
$(ld) $(lflags) -LIBPATH:$(build) -DEFAULTLIB:$(name) \
-PDB:$(@).pdb -IMPLIB:$(@).lib $(<) -out:$(@) -MANIFESTFILE:$(@).manifest
-PDB:$(@).pdb -IMPLIB:$(@).lib $(driver-dynamic-objects) -out:$(@) \
-MANIFESTFILE:$(@).manifest
$(mt) -manifest $(@).manifest -outputresource:"$(@);1"
else
$(ld) $(<) -L$(build) -ljvm $(lflags) -o $(@)
$(ld) $(driver-dynamic-objects) -L$(build) -ljvm $(lflags) -o $(@)
endif
$(strip) $(strip-all) $(@)

View File

@ -13,6 +13,9 @@
#include "string.h"
#include "jni.h"
#include "system.h"
#include "finder.h"
#if (defined __MINGW32__) || (defined _MSC_VER)
# define PATH_SEPARATOR ';'
#else
@ -50,8 +53,92 @@ class RuntimeArray {
#endif // not _MSC_VER
#ifdef BOOT_LIBRARY
// since we aren't linking against libstdc++, we must implement this
// ourselves:
extern "C" void __cxa_pure_virtual(void) { abort(); }
#endif // BOOT_LIBRARY
namespace {
bool
readLine(const uint8_t* base, unsigned total, unsigned* start,
unsigned* length)
{
const uint8_t* p = base + *start;
const uint8_t* end = base + total;
while (p != end and (*p == '\n' or *p == '\r')) ++ p;
*start = p - base;
while (p != end and not (*p == '\n' or *p == '\r')) ++ p;
*length = (p - base) - *start;
return *length != 0;
}
const char*
mainClass(const char* jar)
{
using namespace vm;
System* system = makeSystem(0);
class MyAllocator: public Allocator {
public:
MyAllocator(System* s): s(s) { }
virtual void* tryAllocate(unsigned size) {
return s->tryAllocate(size);
}
virtual void* allocate(unsigned size) {
void* p = tryAllocate(size);
if (p == 0) {
abort(s);
}
return p;
}
virtual void free(const void* p, unsigned) {
s->free(p);
}
System* s;
} allocator(system);
Finder* finder = makeFinder(system, &allocator, jar, 0);
const char* result = 0;
System::Region* region = finder->find("META-INF/MANIFEST.MF");
if (region) {
unsigned start = 0;
unsigned length;
while (readLine(region->start(), region->length(), &start, &length)) {
if (strncmp("Main-Class: ", reinterpret_cast<const char*>
(region->start() + start), 12) == 0)
{
result = strndup
(reinterpret_cast<const char*>(region->start() + start + 12),
length - 12);
break;
}
start += length;
}
region->dispose();
}
finder->dispose();
system->dispose();
return result;
}
void
usageAndExit(const char* name)
{
@ -63,7 +150,7 @@ usageAndExit(const char* name)
"\t[-Xbootclasspath:<bootstrap classpath>]\n"
"\t[-Xbootclasspath/a:<classpath to append to bootstrap classpath>]\n"
"\t[-D<property name>=<property value> ...]\n"
"\t<class name> [<argument> ...]\n", name);
"\t{<class name>|-jar <app jar>} [<argument> ...]\n", name);
exit(-1);
}
@ -78,6 +165,7 @@ main(int ac, const char** av)
vmArgs.ignoreUnrecognized = JNI_TRUE;
const char* class_ = 0;
const char* jar = 0;
int argc = 0;
const char** argv = 0;
const char* classpath = ".";
@ -87,12 +175,17 @@ main(int ac, const char** av)
or strcmp(av[i], "-classpath") == 0)
{
classpath = av[++i];
} else if (strcmp(av[i], "-jar") == 0)
{
jar = av[++i];
} else if (strncmp(av[i], "-X", 2) == 0
or strncmp(av[i], "-D", 2) == 0)
{
++ vmArgs.nOptions;
} else {
class_ = av[i++];
if (jar == 0) {
class_ = av[i++];
}
if (i < ac) {
argc = ac - i;
argv = av + i;
@ -101,6 +194,17 @@ main(int ac, const char** av)
}
}
if (jar) {
classpath = jar;
class_ = mainClass(jar);
if (class_ == 0) {
fprintf(stderr, "Main-Class manifest header not found in %s\n", jar);
exit(-1);
}
}
#ifdef BOOT_LIBRARY
++ vmArgs.nOptions;
#endif
@ -169,6 +273,11 @@ main(int ac, const char** av)
JNIEnv* e = static_cast<JNIEnv*>(env);
jclass c = e->FindClass(class_);
if (jar) {
free(const_cast<char*>(class_));
}
if (not e->ExceptionCheck()) {
jmethodID m = e->GetStaticMethodID(c, "main", "([Ljava/lang/String;)V");
if (not e->ExceptionCheck()) {