diff --git a/makefile b/makefile index 5214d37f0e..ee50870fc9 100644 --- a/makefile +++ b/makefile @@ -124,7 +124,7 @@ warnings = -Wall -Wextra -Werror -Wunused-parameter -Winit-self \ common-cflags = $(warnings) -fno-rtti -fno-exceptions -fno-omit-frame-pointer \ "-I$(JAVA_HOME)/include" -idirafter $(src) -I$(build) $(classpath-cflags) \ -D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" \ - -DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \ + -DUSE_ATOMIC_OPERATIONS "-DAVIAN_JAVA_HOME=\"$(javahome)\"" \ -DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \ @@ -138,6 +138,8 @@ build-lflags = -lz -lpthread -ldl lflags = $(common-lflags) -lpthread -ldl +build-system = posix + system = posix asm = x86 @@ -196,6 +198,8 @@ ifeq ($(platform),windows) inc = "$(root)/win32/include" lib = "$(root)/win32/lib" + embed-prefix = c:/avian-embedded + system = windows so-prefix = @@ -213,6 +217,7 @@ ifeq ($(platform),windows) ranlib = i586-mingw32msvc-ranlib strip = i586-mingw32msvc-strip else + build-platform = windows common-cflags += "-I$(JAVA_HOME)/include/win32" build-cflags = $(common-cflags) -I$(src) -mthreads ifeq ($(build-platform),cygwin) @@ -402,7 +407,7 @@ boot-object = $(build)/boot.o generator-depends := $(wildcard $(src)/*.h) generator-sources = \ $(src)/type-generator.cpp \ - $(src)/$(system).cpp \ + $(src)/$(build-system).cpp \ $(src)/finder.cpp generator-cpp-objects = \ $(foreach x,$(1),$(patsubst $(2)/%.cpp,$(3)/%-build.o,$(x))) diff --git a/openjdk-src.mk b/openjdk-src.mk index 5ee6a46096..1c2e62d0cd 100644 --- a/openjdk-src.mk +++ b/openjdk-src.mk @@ -128,7 +128,35 @@ openjdk-cflags = \ -D_GNU_SOURCE ifeq ($(platform),windows) -# todo + openjdk-sources += \ + $(openjdk-src)/windows/native/java/io/canonicalize_md.c \ + $(openjdk-src)/windows/native/java/io/Console_md.c \ + $(openjdk-src)/windows/native/java/io/FileDescriptor_md.c \ + $(openjdk-src)/windows/native/java/io/FileInputStream_md.c \ + $(openjdk-src)/windows/native/java/io/FileOutputStream_md.c \ + $(openjdk-src)/windows/native/java/io/FileSystem_md.c \ + $(openjdk-src)/windows/native/java/io/io_util_md.c \ + $(openjdk-src)/windows/native/java/io/RandomAccessFile_md.c \ + $(openjdk-src)/windows/native/java/io/Win32FileSystem_md.c \ + $(openjdk-src)/windows/native/java/io/WinNTFileSystem_md.c \ + $(openjdk-src)/windows/native/java/lang/java_props_md.c \ + $(openjdk-src)/windows/native/java/lang/ProcessEnvironment_md.c \ + $(openjdk-src)/windows/native/java/util/WindowsPreferences.c \ + $(openjdk-src)/windows/native/java/util/logging.c \ + $(openjdk-src)/windows/native/java/util/TimeZone_md.c \ + $(openjdk-src)/windows/native/sun/io/Win32ErrorMode.c \ + + openjdk-headers-classes += \ + sun.io.Win32ErrorMode + + openjdk-cflags += "-I$(openjdk-src)/windows/javavm/export" \ + "-I$(openjdk-src)/windows/native/common" \ + "-I$(openjdk-src)/windows/native/java/io" \ + "-I$(openjdk-src)/windows/native/java/util" \ + "-I$(openjdk-src)/windows/javavm/include" \ + "-I$(root)/win32/include" \ + -D_JNI_IMPLEMENTATION_ \ + -D_JAVASOFT_WIN32_TYPEDEF_MD_H_ else openjdk-sources += \ $(openjdk-src)/solaris/native/common/jdk_util_md.c \ diff --git a/src/classpath-openjdk.cpp b/src/classpath-openjdk.cpp index d2b3f131cc..3dea5e4efb 100644 --- a/src/classpath-openjdk.cpp +++ b/src/classpath-openjdk.cpp @@ -20,10 +20,21 @@ # include # include # include +# include +# include +# include +# include + +#undef interface # define CLOSE _close # define READ _read # define WRITE _write +# define FSTAT _fstat +# define STAT _stat +# define LSEEK _lseek + +# define S_ISSOCK(x) false # ifdef _MSC_VER # define S_ISREG(x) ((x) | _S_IFREG) @@ -31,13 +42,17 @@ # define S_IRUSR _S_IREAD # define S_IWUSR _S_IWRITE # else -# define OPEN _wopen -# define CREAT _wcreat +# define OPEN _open +# define CREAT _creat # endif +#define O_RDONLY _O_RDONLY + # define LIBRARY_PREFIX "" # define LIBRARY_SUFFIX ".dll" +typedef int socklen_t; + #else // not PLATFORM_WINDOWS # include @@ -355,11 +370,20 @@ class MyClasspath : public Classpath { globalMachine = t->m; #ifdef AVIAN_OPENJDK_SRC - { object ufsClass = resolveClass - (t, root(t, Machine::BootLoader), "java/io/UnixFileSystem"); + { +#ifdef PLATFORM_WINDOWS + const char* const fsClassName = "java/io/WinNTFileSystem"; + const char* const gbaMethodName = "getBooleanAttributes"; +#else + const char* const fsClassName = "java/io/UnixFileSystem"; + const char* const gbaMethodName = "getBooleanAttributes0"; +#endif - if (ufsClass) { - PROTECT(t, ufsClass); + object fsClass = resolveClass + (t, root(t, Machine::BootLoader), fsClassName, false); + + if (fsClass) { + PROTECT(t, fsClass); object fileClass = resolveClass (t, root(t, Machine::BootLoader), "java/io/File"); @@ -371,10 +395,10 @@ class MyClasspath : public Classpath { if (pathField) { this->pathField = fieldOffset(t, pathField); - intercept(t, ufsClass, "getBooleanAttributes0", - "(Ljava/io/File;)I", voidPointer(getFileAttributes)); + intercept(t, fsClass, gbaMethodName, "(Ljava/io/File;)I", + voidPointer(getFileAttributes)); - intercept(t, ufsClass, "getLength", "(Ljava/io/File;)J", + intercept(t, fsClass, "getLength", "(Ljava/io/File;)J", voidPointer(getLength)); } } @@ -511,10 +535,30 @@ getFinder(Thread* t, const char* name, unsigned nameLength) return 0; } +bool +pathEqual(const char* a, const char* b, unsigned length) +{ +#ifdef PLATFORM_WINDOWS + return strncasecmp(a, b, length) == 0; +#else + return strncmp(a, b, length) == 0; +#endif +} + +bool +pathEqual(const char* a, const char* b) +{ +#ifdef PLATFORM_WINDOWS + return strcasecmp(a, b) == 0; +#else + return strcmp(a, b) == 0; +#endif +} + class EmbeddedFile { public: EmbeddedFile(MyClasspath* cp, const char* path, unsigned pathLength) { - if (strncmp(cp->embedPrefix, path, cp->embedPrefixLength) == 0) { + if (pathEqual(cp->embedPrefix, path, cp->embedPrefixLength)) { const char* p = path + cp->embedPrefixLength; while (*p == '/') ++ p; @@ -564,8 +608,9 @@ getFileAttributes RUNTIME_ARRAY(char, p, stringLength(t, path) + 1); stringChars(t, path, RUNTIME_ARRAY_BODY(p)); + replace('\\', '/', RUNTIME_ARRAY_BODY(p)); - if (strcmp(cp->zipLibrary, RUNTIME_ARRAY_BODY(p)) == 0) { + if (pathEqual(cp->zipLibrary, RUNTIME_ARRAY_BODY(p))) { return Exists | Regular; } else { EmbeddedFile ef(cp, RUNTIME_ARRAY_BODY(p), stringLength(t, path)); @@ -613,6 +658,7 @@ getLength RUNTIME_ARRAY(char, p, stringLength(t, path) + 1); stringChars(t, path, RUNTIME_ARRAY_BODY(p)); + replace('\\', '/', RUNTIME_ARRAY_BODY(p)); EmbeddedFile ef(cp, RUNTIME_ARRAY_BODY(p), stringLength(t, path)); if (ef.jar) { @@ -894,6 +940,31 @@ interruptLock(Thread* t, object thread) return threadInterruptLock(t, thread); } +bool +pipeAvailable(int fd, int* available) +{ +#ifdef PLATFORM_WINDOWS + HANDLE h = reinterpret_cast(_get_osfhandle(fd)); + if (h == INVALID_HANDLE_VALUE) { + return false; + } + + DWORD n; + if (PeekNamedPipe(h, 0,0, 0, &n, 0)) { + *available = n; + } else { + if (GetLastError() != ERROR_BROKEN_PIPE) { + return false; + } + *available = 0; + } + + return true; +#else + return ioctl(fd, FIONREAD, available) >= 0; +#endif +} + } // namespace local } // namespace @@ -1470,13 +1541,17 @@ extern "C" JNIEXPORT jint JNICALL JVM_ActiveProcessorCount(void) { abort(); } extern "C" JNIEXPORT void* JNICALL -JVM_LoadLibrary(const char* name) +JVM_LoadLibrary(const char* path) { Thread* t = static_cast(local::globalMachine->localThread->get()); + RUNTIME_ARRAY(char, p, strlen(path) + 1); + replace('\\', '/', RUNTIME_ARRAY_BODY(p), path); + #ifdef AVIAN_OPENJDK_SRC - if (strcmp(static_cast(t->m->classpath)->zipLibrary, - name) == 0) + if (local::pathEqual + (static_cast(t->m->classpath)->zipLibrary, + RUNTIME_ARRAY_BODY(p))) { return t->m->libraries; } @@ -1485,8 +1560,8 @@ JVM_LoadLibrary(const char* name) ENTER(t, Thread::ActiveState); return loadLibrary - (t, static_cast(t->m->classpath)->libraryPath, name, - false, false); + (t, static_cast(t->m->classpath)->libraryPath, + RUNTIME_ARRAY_BODY(p), false, false); } extern "C" JNIEXPORT void JNICALL @@ -1597,7 +1672,11 @@ JVM_SetThreadPriority(Thread*, jobject, jint) extern "C" JNIEXPORT void JNICALL JVM_Yield(Thread*, jclass) { +#ifdef PLATFORM_WINDOWS + SwitchToThread(); +#else sched_yield(); +#endif } extern "C" JNIEXPORT void JNICALL @@ -2655,7 +2734,12 @@ JVM_Open(const char* path, jint flags, jint mode) Thread* t = static_cast(local::globalMachine->localThread->get()); local::MyClasspath* cp = static_cast(t->m->classpath); - local::EmbeddedFile ef(cp, path, strlen(path)); + unsigned length = strlen(path); + + RUNTIME_ARRAY(char, p, length + 1); + replace('\\', '/', RUNTIME_ARRAY_BODY(p), path); + + local::EmbeddedFile ef(cp, RUNTIME_ARRAY_BODY(p), length); if (ef.jar) { if (flags != O_RDONLY) { errno = EACCES; @@ -2706,7 +2790,7 @@ JVM_Open(const char* path, jint flags, jint mode) return index + local::VirtualFileBase; } else { - int r = OPEN(path, flags, mode); + int r = OPEN(RUNTIME_ARRAY_BODY(p), flags, mode); expect(t, r < local::VirtualFileBase); return r; } @@ -2797,13 +2881,13 @@ JVM_Available(jint fd, jlong* result) return 0; } } else { - struct stat buffer; + struct STAT buffer; int n; if (FSTAT(fd, &buffer) >= 0 and (S_ISCHR(buffer.st_mode) or S_ISFIFO(buffer.st_mode) or S_ISSOCK(buffer.st_mode)) - and ioctl(fd, FIONREAD, &n) >= 0) + and local::pipeAvailable(fd, &n)) { *result = n; return 1; @@ -2877,7 +2961,22 @@ JVM_SetLength(jint, jlong) { abort(); } extern "C" JNIEXPORT jint JNICALL JVM_Sync(jint fd) { +#ifdef PLATFORM_WINDOWS + HANDLE h = reinterpret_cast(_get_osfhandle(fd)); + if (h == INVALID_HANDLE_VALUE) { + errno = EBADF; + return -1; + } + + if (FlushFileBuffers(h)) { + return 0; + } else { + errno = EIO; + return -1; + } +#else return fsync(fd); +#endif } extern "C" JNIEXPORT jint JNICALL @@ -3091,3 +3190,18 @@ jio_vfprintf(FILE* stream, const char* format, va_list a) // return r; // } + +#ifdef PLATFORM_WINDOWS +namespace { HMODULE jvmHandle = 0; } + +extern "C" int JDK_InitJvmHandle() +{ + jvmHandle = GetModuleHandle(0); + return jvmHandle != 0; +} + +extern "C" void* JDK_FindJvmEntry(const char* name) +{ + return voidPointer(GetProcAddress(jvmHandle, name)); +} +#endif diff --git a/src/openjdk/Wincon.h b/src/openjdk/Wincon.h new file mode 100644 index 0000000000..40d2ad2a68 --- /dev/null +++ b/src/openjdk/Wincon.h @@ -0,0 +1,3 @@ +// Console_md.c #includes "Wincon.h", which only matches "wincon.h" on +// a case insensive filesystem, so we redirect here. +#include "wincon.h" diff --git a/src/openjdk/jni_md.h b/src/openjdk/jni_md.h index 3ddc8b9460..bda8d5ef35 100644 --- a/src/openjdk/jni_md.h +++ b/src/openjdk/jni_md.h @@ -15,12 +15,13 @@ #if (defined __MINGW32__) || (defined _MSC_VER) # define JNIEXPORT __declspec(dllexport) +# define JNICALL __stdcall #else // not (defined __MINGW32__) || (defined _MSC_VER) # define JNIEXPORT __attribute__ ((visibility("default"))) +# define JNICALL #endif // not (defined __MINGW32__) || (defined _MSC_VER) #define JNIIMPORT -#define JNICALL typedef int32_t jint; typedef int64_t jlong; diff --git a/src/windows.cpp b/src/windows.cpp index b0146334b6..3e32a15503 100644 --- a/src/windows.cpp +++ b/src/windows.cpp @@ -457,11 +457,10 @@ class MySystem: public System { class Library: public System::Library { public: - Library(System* s, HMODULE handle, const char* name, bool mapName): + Library(System* s, HMODULE handle, const char* name): s(s), handle(handle), name_(name), - mapName_(mapName), next_(0) { } @@ -476,10 +475,6 @@ class MySystem: public System { return name_; } - virtual bool mapName() { - return mapName_; - } - virtual System::Library* next() { return next_; } @@ -511,7 +506,6 @@ class MySystem: public System { System* s; HMODULE handle; const char* name_; - bool mapName_; System::Library* next_; }; @@ -701,35 +695,40 @@ class MySystem: public System { return status; } - virtual FileType identify(const char* name) { + virtual FileType stat(const char* name, unsigned* length) { struct _stat s; int r = _stat(name, &s); if (r == 0) { if (S_ISREG(s.st_mode)) { + *length = s.st_size; return TypeFile; } else if (S_ISDIR(s.st_mode)) { + *length = 0; return TypeDirectory; } else { + *length = 0; return TypeUnknown; } } else { + *length = 0; return TypeDoesNotExist; } } + virtual const char* libraryPrefix() { + return ""; + } + + virtual const char* librarySuffix() { + return SO_SUFFIX; + } + virtual Status load(System::Library** lib, - const char* name, - bool mapName) + const char* name) { HMODULE handle; unsigned nameLength = (name ? strlen(name) : 0); - if (mapName and name) { - unsigned size = sizeof(SO_PREFIX) + nameLength + sizeof(SO_SUFFIX); - RUNTIME_ARRAY(char, buffer, size);; - vm::snprintf - (RUNTIME_ARRAY_BODY(buffer), size, SO_PREFIX "%s" SO_SUFFIX, name); - handle = LoadLibrary(RUNTIME_ARRAY_BODY(buffer)); - } else if (name) { + if (name) { handle = LoadLibrary(name); } else { handle = GetModuleHandle(0); @@ -748,8 +747,7 @@ class MySystem: public System { n = 0; } - *lib = new (allocate(this, sizeof(Library))) - Library(this, handle, n, mapName); + *lib = new (allocate(this, sizeof(Library))) Library(this, handle, n); return 0; } else { @@ -761,6 +759,10 @@ class MySystem: public System { return ';'; } + virtual char fileSeparator() { + return '\\'; + } + virtual int64_t now() { static LARGE_INTEGER frequency; static LARGE_INTEGER time;