diff --git a/makefile b/makefile index 59099aa323..f9762c6938 100644 --- a/makefile +++ b/makefile @@ -43,6 +43,10 @@ endif ifeq ($(continuations),true) options := $(options)-continuations endif +ifdef gnu + options := $(options)-gnu + gnu-sources = $(src)/gnu.cpp +endif root = $(shell (cd .. && pwd)) build = build @@ -232,7 +236,8 @@ vm-sources = \ $(src)/$(process).cpp \ $(src)/builtin.cpp \ $(src)/jnienv.cpp \ - $(src)/process.cpp + $(src)/process.cpp \ + $(gnu-sources) vm-asm-sources = $(src)/$(asm).S @@ -314,16 +319,38 @@ classpath-sources = $(shell find $(classpath) -name '*.java') classpath-classes = \ $(call java-classes,$(classpath-sources),$(classpath),$(classpath-build)) classpath-object = $(native-build)/classpath-jar.o -classpath-dep = $(classpath-build)/dep +classpath-dep = $(classpath-build).dep + +gnu-blacklist = \ + java/lang/AbstractStringBuffer.class \ + java/lang/reflect/Proxy.class + +gnu-overrides = \ + java/lang/Class.class \ + java/lang/Enum.class \ + java/lang/Object.class \ + java/lang/StackTraceElement.class \ + java/lang/String.class \ + java/lang/StringBuffer.class \ + java/lang/StringBuilder.class \ + java/lang/Throwable.class \ + java/lang/ref/PhantomReference.class \ + java/lang/ref/Reference.class \ + java/lang/ref/ReferenceQueue.class \ + java/lang/ref/WeakReference.class \ + java/lang/reflect/AccessibleObject.class \ + java/lang/reflect/Constructor.class \ + java/lang/reflect/Field.class \ + java/lang/reflect/Method.class test-sources = $(wildcard $(test)/*.java) test-classes = $(call java-classes,$(test-sources),$(test),$(test-build)) -test-dep = $(test-build)/dep +test-dep = $(test-build).dep test-extra-sources = $(wildcard $(test)/extra/*.java) test-extra-classes = \ $(call java-classes,$(test-extra-sources),$(test),$(test-build)) -test-extra-dep = $(test-build)/extra/dep +test-extra-dep = $(test-build)-extra.dep class-name = $(patsubst $(1)/%.class,%,$(2)) class-names = $(foreach x,$(2),$(call class-name,$(1),$(x))) @@ -395,8 +422,8 @@ $(classpath-build)/%.class: $(classpath)/%.java $(classpath-dep): $(classpath-sources) @echo "compiling classpath classes" - @mkdir -p $(dir $(@)) - $(javac) -d $(dir $(@)) -bootclasspath $(classpath-build) \ + @mkdir -p $(classpath-build) + $(javac) -d $(classpath-build) -bootclasspath $(classpath-build) \ $(shell $(MAKE) -s --no-print-directory $(classpath-classes)) @touch $(@) @@ -405,8 +432,8 @@ $(test-build)/%.class: $(test)/%.java $(test-dep): $(test-sources) @echo "compiling test classes" - @mkdir -p $(dir $(@)) - $(javac) -d $(dir $(@)) -bootclasspath $(classpath-build) \ + @mkdir -p $(test-build) + $(javac) -d $(test-build) -bootclasspath $(classpath-build) \ $(shell $(MAKE) -s --no-print-directory $(test-classes)) $(javac) -source 1.2 -target 1.1 -XDjsrlimit=0 -d $(dir $(@)) \ test/Subroutine.java @@ -414,7 +441,7 @@ $(test-dep): $(test-sources) $(test-extra-dep): $(test-extra-sources) @echo "compiling extra test classes" - @mkdir -p $(dir $(@)) + @mkdir -p $(test-build) $(javac) -d $(test-build) -bootclasspath $(classpath-build) \ $(shell $(MAKE) -s --no-print-directory $(test-extra-classes)) @touch $(@) @@ -456,9 +483,21 @@ $(boot-object): $(boot-source) $(compile-object) $(build)/classpath.jar: $(classpath-dep) +ifdef gnu + mkdir $(build)/gnu + (wd=$$(pwd); \ + cd $(build)/gnu; \ + $(jar) xf $(gnu)/share/classpath/glibj.zip; \ + rm $(gnu-blacklist); \ + $(jar) c0f "$$($(native-path) "$${wd}/$(@)")" .) (wd=$$(pwd); \ cd $(classpath-build); \ - $(jar) c0f "$$($(native-path) "$${wd}/$(@)")" $$(find . -name '*.class')) + $(jar) u0f "$$($(native-path) "$${wd}/$(@)")" $(gnu-overrides)) +else + (wd=$$(pwd); \ + cd $(classpath-build); \ + $(jar) c0f "$$($(native-path) "$${wd}/$(@)")" .) +endif $(binaryToMacho): $(src)/binaryToMacho.cpp $(cxx) $(^) -o $(@) diff --git a/src/gnu.cpp b/src/gnu.cpp new file mode 100644 index 0000000000..7620fe18bf --- /dev/null +++ b/src/gnu.cpp @@ -0,0 +1,82 @@ +/* Copyright (c) 2009, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +#include "machine.h" +#include "constants.h" +#include "processor.h" + +using namespace vm; + +namespace { + +void +setProperty(Thread* t, object method, object properties, + const char* name, const void* value, const char* format = "%s") +{ + PROTECT(t, method); + PROTECT(t, properties); + + object n = makeString(t, "%s", name); + PROTECT(t, n); + + object v = makeString(t, format, value); + + t->m->processor->invoke(t, method, properties, n, v); +} + +} // namespace + +extern "C" JNIEXPORT void JNICALL +Avian_gnu_classpath_VMSystemProperties_preInit +(Thread* t, object, uintptr_t* arguments) +{ + object properties = reinterpret_cast(arguments[0]); + PROTECT(t, properties); + + object method = resolveMethod + (t, "java/util/Properties", "setProperty", + "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;"); + + if (UNLIKELY(t->exception)) { + return; + } + + PROTECT(t, method); + + setProperty(t, method, properties, "java.vm.name", "Avian"); + + setProperty(t, method, properties, "java.lang.classpath", + t->m->finder->path()); + + setProperty(t, method, properties, "file.encoding", "ASCII"); + +#ifdef WIN32 + setProperty(t, method, properties, "line.separator", "\r\n"); + setProperty(t, method, properties, "file.separator", "\\"); + setProperty(t, method, properties, "os.name", "Windows"); + + TCHAR buffer[MAX_PATH]; + GetTempPath(MAX_PATH, buffer); + setProperty(t, method, properties, "java.io.tmpdir", buffer); + + LPWSTR home = _wgetenv(L"USERPROFILE"); + setProperty(t, method, properties, "user.home", home, "%ls"); +#else + setProperty(t, method, properties, "line.separator", "\n"); + setProperty(t, method, properties, "file.separator", "/"); +# ifdef __APPLE__ + setProperty(t, method, properties, "os.name", "Mac OS X"); +# else + setProperty(t, method, properties, "os.name", "Linux"); +# endif + setProperty(t, method, properties, "java.io.tmpdir", "/tmp"); + setProperty(t, method, properties, "user.home", getenv("HOME")); +#endif +}