Windows Phone 8 / Windows RT initial support

Conflicts:

	makefile
This commit is contained in:
Alexey Pelykh 2013-01-28 17:20:52 +02:00
parent cc237b94c4
commit 2f2cac556c
13 changed files with 912 additions and 126 deletions

View File

@ -83,6 +83,16 @@ typedef char char_t;
#endif // not PLATFORM_WINDOWS #endif // not PLATFORM_WINDOWS
#ifndef WINAPI_FAMILY
# ifndef WINAPI_PARTITION_DESKTOP
# define WINAPI_PARTITION_DESKTOP 1
# endif
# ifndef WINAPI_FAMILY_PARTITION
# define WINAPI_FAMILY_PARTITION(x) (x)
# endif
#endif // WINAPI_FAMILY
inline void* operator new(size_t, void* p) throw() { return p; } inline void* operator new(size_t, void* p) throw() { return p; }
typedef const char_t* string_t; typedef const char_t* string_t;
@ -214,6 +224,7 @@ extern "C" JNIEXPORT jstring JNICALL
Java_java_io_File_toAbsolutePath(JNIEnv* e UNUSED, jclass, jstring path) Java_java_io_File_toAbsolutePath(JNIEnv* e UNUSED, jclass, jstring path)
{ {
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
string_t chars = getChars(e, path); string_t chars = getChars(e, path);
if (chars) { if (chars) {
const unsigned BufferSize = MAX_PATH; const unsigned BufferSize = MAX_PATH;
@ -228,6 +239,11 @@ Java_java_io_File_toAbsolutePath(JNIEnv* e UNUSED, jclass, jstring path)
} }
return path; return path;
# else
// WinRT has no concept of full paths
throwNewErrno(e, "java/io/IOException");
return path;
# endif
#else #else
jstring result = path; jstring result = path;
string_t chars = getChars(e, path); string_t chars = getChars(e, path);
@ -256,11 +272,24 @@ Java_java_io_File_length(JNIEnv* e, jclass, jstring path)
LARGE_INTEGER fileSize; LARGE_INTEGER fileSize;
string_t chars = getChars(e, path); string_t chars = getChars(e, path);
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
HANDLE file = CreateFileW HANDLE file = CreateFileW
(chars, FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); (chars, FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
#else
HANDLE file = CreateFile2
(chars, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr);
#endif
releaseChars(e, path, chars); releaseChars(e, path, chars);
if (file != INVALID_HANDLE_VALUE) if (file != INVALID_HANDLE_VALUE)
{
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
GetFileSizeEx(file, &fileSize); GetFileSizeEx(file, &fileSize);
#else
FILE_STANDARD_INFO info;
if(GetFileInformationByHandleEx(file, FileStandardInfo, &info, sizeof(info)))
fileSize = info.EndOfFile;
#endif
}
else return 0; else return 0;
CloseHandle(file); CloseHandle(file);
return static_cast<jlong>(fileSize.QuadPart); return static_cast<jlong>(fileSize.QuadPart);
@ -496,7 +525,11 @@ Java_java_io_File_openDir(JNIEnv* e, jclass, jstring path)
releaseChars(e, path, chars); releaseChars(e, path, chars);
Directory* d = new (malloc(sizeof(Directory))) Directory; Directory* d = new (malloc(sizeof(Directory))) Directory;
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
d->handle = FindFirstFileW(RUNTIME_ARRAY_BODY(buffer), &(d->data)); d->handle = FindFirstFileW(RUNTIME_ARRAY_BODY(buffer), &(d->data));
#else
d->handle = FindFirstFileExW(RUNTIME_ARRAY_BODY(buffer), FindExInfoStandard, &(d->data), FindExSearchNameMatch, NULL, 0);
#endif
if (d->handle == INVALID_HANDLE_VALUE) { if (d->handle == INVALID_HANDLE_VALUE) {
d->dispose(); d->dispose();
d = 0; d = 0;
@ -725,7 +758,11 @@ Java_java_io_RandomAccessFile_readBytes(JNIEnv* e, jclass, jlong peer,
uint8_t* dst = reinterpret_cast<uint8_t*> uint8_t* dst = reinterpret_cast<uint8_t*>
(e->GetPrimitiveArrayCritical(buffer, 0)); (e->GetPrimitiveArrayCritical(buffer, 0));
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
ssize_t bytesRead = ::read(fd, dst + offset, length); ssize_t bytesRead = ::read(fd, dst + offset, length);
#else
auto bytesRead = ::read(fd, dst + offset, length);
#endif
e->ReleasePrimitiveArrayCritical(buffer, dst, 0); e->ReleasePrimitiveArrayCritical(buffer, dst, 0);
if(bytesRead == -1) { if(bytesRead == -1) {
@ -737,7 +774,7 @@ Java_java_io_RandomAccessFile_readBytes(JNIEnv* e, jclass, jlong peer,
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_io_RandomAccessFile_close(JNIEnv*/* e*/, jclass, jlong peer) Java_java_io_RandomAccessFile_close(JNIEnv* /* e*/, jclass, jlong peer)
{ {
int fd = (int)peer; int fd = (int)peer;
::close(fd); ::close(fd);

View File

@ -62,6 +62,16 @@
#endif // not PLATFORM_WINDOWS #endif // not PLATFORM_WINDOWS
#ifndef WINAPI_FAMILY
# ifndef WINAPI_PARTITION_DESKTOP
# define WINAPI_PARTITION_DESKTOP 1
# endif
# ifndef WINAPI_FAMILY_PARTITION
# define WINAPI_FAMILY_PARTITION(x) (x)
# endif
#endif // WINAPI_FAMILY
namespace { namespace {
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
char* getErrorStr(DWORD err){ char* getErrorStr(DWORD err){
@ -70,7 +80,8 @@ namespace {
snprintf(errStr, 9, "%d", (int) err); snprintf(errStr, 9, "%d", (int) err);
return errStr; return errStr;
// The better way to do this, if I could figure out how to convert LPTSTR to char* //TODO:
// The better way to do this, if I could figure out how to convert LPTSTR to char*
//char* errStr; //char* errStr;
//LPTSTR s; //LPTSTR s;
//if(FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | //if(FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
@ -83,6 +94,7 @@ namespace {
//return errStr; //return errStr;
} }
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
void makePipe(JNIEnv* e, HANDLE p[2]) void makePipe(JNIEnv* e, HANDLE p[2])
{ {
SECURITY_ATTRIBUTES sa; SECURITY_ATTRIBUTES sa;
@ -95,6 +107,7 @@ namespace {
throwNew(e, "java/io/IOException", getErrorStr(GetLastError())); throwNew(e, "java/io/IOException", getErrorStr(GetLastError()));
} }
} }
#endif
int descriptor(JNIEnv* e, HANDLE h) int descriptor(JNIEnv* e, HANDLE h)
{ {
@ -196,7 +209,7 @@ extern "C" JNIEXPORT void JNICALL
Java_java_lang_Runtime_exec(JNIEnv* e, jclass, Java_java_lang_Runtime_exec(JNIEnv* e, jclass,
jobjectArray command, jlongArray process) jobjectArray command, jlongArray process)
{ {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
int size = 0; int size = 0;
for (int i = 0; i < e->GetArrayLength(command); ++i){ for (int i = 0; i < e->GetArrayLength(command); ++i){
jstring element = (jstring) e->GetObjectArrayElement(command, i); jstring element = (jstring) e->GetObjectArrayElement(command, i);
@ -267,11 +280,15 @@ Java_java_lang_Runtime_exec(JNIEnv* e, jclass,
e->SetLongArrayRegion(process, 0, 1, &pid); e->SetLongArrayRegion(process, 0, 1, &pid);
jlong tid = reinterpret_cast<jlong>(pi.hThread); jlong tid = reinterpret_cast<jlong>(pi.hThread);
e->SetLongArrayRegion(process, 1, 1, &tid); e->SetLongArrayRegion(process, 1, 1, &tid);
#else
throwNew(e, "java/io/Exception", strdup("Not supported on WinRT/WinPhone8"));
#endif
} }
extern "C" JNIEXPORT jint JNICALL extern "C" JNIEXPORT jint JNICALL
Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid, jlong tid) Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid, jlong tid)
{ {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
DWORD exitCode; DWORD exitCode;
WaitForSingleObject(reinterpret_cast<HANDLE>(pid), INFINITE); WaitForSingleObject(reinterpret_cast<HANDLE>(pid), INFINITE);
BOOL success = GetExitCodeProcess(reinterpret_cast<HANDLE>(pid), &exitCode); BOOL success = GetExitCodeProcess(reinterpret_cast<HANDLE>(pid), &exitCode);
@ -283,14 +300,23 @@ Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid, jlong tid)
CloseHandle(reinterpret_cast<HANDLE>(tid)); CloseHandle(reinterpret_cast<HANDLE>(tid));
return exitCode; return exitCode;
#else
throwNew(e, "java/io/Exception", strdup("Not supported on WinRT/WinPhone8"));
return -1;
#endif
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_lang_Runtime_kill(JNIEnv*, jclass, jlong pid) { Java_java_lang_Runtime_kill(JNIEnv* e UNUSED, jclass, jlong pid) {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
TerminateProcess(reinterpret_cast<HANDLE>(pid), 1); TerminateProcess(reinterpret_cast<HANDLE>(pid), 1);
#else
throwNew(e, "java/io/Exception", strdup("Not supported on WinRT/WinPhone8"));
#endif
} }
Locale getLocale() { Locale getLocale() {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
const char* lang = ""; const char* lang = "";
const char* reg = ""; const char* reg = "";
unsigned langid = GetUserDefaultUILanguage(); unsigned langid = GetUserDefaultUILanguage();
@ -362,8 +388,11 @@ Locale getLocale() {
default: lang = "en"; default: lang = "en";
} }
Locale locale(lang, reg); return Locale(lang, reg);
return locale; #else
//TODO: CultureInfo.CurrentCulture
return Locale("en", "US");
#endif
} }
#else #else
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
@ -531,8 +560,15 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
} else if (strcmp(chars, "file.separator") == 0) { } else if (strcmp(chars, "file.separator") == 0) {
r = e->NewStringUTF("\\"); r = e->NewStringUTF("\\");
} else if (strcmp(chars, "os.name") == 0) { } else if (strcmp(chars, "os.name") == 0) {
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
r = e->NewStringUTF("Windows"); r = e->NewStringUTF("Windows");
# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE)
r = e->NewStringUTF("Windows Phone");
# else
r = e->NewStringUTF("Windows RT");
# endif
} else if (strcmp(chars, "os.version") == 0) { } else if (strcmp(chars, "os.version") == 0) {
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
unsigned size = 32; unsigned size = 32;
RUNTIME_ARRAY(char, buffer, size); RUNTIME_ARRAY(char, buffer, size);
OSVERSIONINFO OSversion; OSVERSIONINFO OSversion;
@ -540,6 +576,10 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
::GetVersionEx(&OSversion); ::GetVersionEx(&OSversion);
snprintf(RUNTIME_ARRAY_BODY(buffer), size, "%i.%i", (int)OSversion.dwMajorVersion, (int)OSversion.dwMinorVersion); snprintf(RUNTIME_ARRAY_BODY(buffer), size, "%i.%i", (int)OSversion.dwMajorVersion, (int)OSversion.dwMinorVersion);
r = e->NewStringUTF(RUNTIME_ARRAY_BODY(buffer)); r = e->NewStringUTF(RUNTIME_ARRAY_BODY(buffer));
# else
// Currently there is no alternative on WinRT/WP8
r = e->NewStringUTF("8.0");
# endif
} else if (strcmp(chars, "os.arch") == 0) { } else if (strcmp(chars, "os.arch") == 0) {
#ifdef ARCH_x86_32 #ifdef ARCH_x86_32
r = e->NewStringUTF("x86"); r = e->NewStringUTF("x86");
@ -551,15 +591,28 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
r = e->NewStringUTF("arm"); r = e->NewStringUTF("arm");
#endif #endif
} else if (strcmp(chars, "java.io.tmpdir") == 0) { } else if (strcmp(chars, "java.io.tmpdir") == 0) {
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
TCHAR buffer[MAX_PATH]; TCHAR buffer[MAX_PATH];
GetTempPath(MAX_PATH, buffer); GetTempPath(MAX_PATH, buffer);
r = e->NewStringUTF(buffer); r = e->NewStringUTF(buffer);
# else
//TODO:http://lunarfrog.com/blog/2012/05/21/winrt-folders-access/
//Windows.Storage.ApplicationData.Current.TemporaryFolder
r = 0;
# endif
} else if (strcmp(chars, "user.dir") == 0) { } else if (strcmp(chars, "user.dir") == 0) {
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
TCHAR buffer[MAX_PATH]; TCHAR buffer[MAX_PATH];
GetCurrentDirectory(MAX_PATH, buffer); GetCurrentDirectory(MAX_PATH, buffer);
r = e->NewStringUTF(buffer); r = e->NewStringUTF(buffer);
# else
//TODO:http://lunarfrog.com/blog/2012/05/21/winrt-folders-access/
//Windows.ApplicationModel.Package.Current.InstalledLocation
r = 0;
# endif
} else if (strcmp(chars, "user.home") == 0) { } else if (strcmp(chars, "user.home") == 0) {
# ifdef _MSC_VER # ifdef _MSC_VER
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WCHAR buffer[MAX_PATH]; WCHAR buffer[MAX_PATH];
size_t needed; size_t needed;
if (_wgetenv_s(&needed, buffer, MAX_PATH, L"USERPROFILE") == 0) { if (_wgetenv_s(&needed, buffer, MAX_PATH, L"USERPROFILE") == 0) {
@ -567,6 +620,11 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
} else { } else {
r = 0; r = 0;
} }
# else
//TODO:http://lunarfrog.com/blog/2012/05/21/winrt-folders-access/
//Windows.Storage.KnownFolders.DocumentsLibrary;
r = 0;
# endif
# else # else
LPWSTR home = _wgetenv(L"USERPROFILE"); LPWSTR home = _wgetenv(L"USERPROFILE");
r = e->NewString(reinterpret_cast<jchar*>(home), lstrlenW(home)); r = e->NewString(reinterpret_cast<jchar*>(home), lstrlenW(home));
@ -654,6 +712,9 @@ namespace {
#elif defined __APPLE__ #elif defined __APPLE__
# include <crt_externs.h> # include <crt_externs.h>
# define environ (*_NSGetEnviron()) # define environ (*_NSGetEnviron())
#elif defined(WINAPI_FAMILY) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
// WinRT/WP8 does not provide alternative for environment variables
char* environ[] = { 0 };
#else #else
extern char** environ; extern char** environ;
#endif #endif

401
makefile
View File

@ -51,7 +51,7 @@ ifeq ($(continuations),true)
endif endif
root := $(shell (cd .. && pwd)) root := $(shell (cd .. && pwd))
build = build/$(platform)-$(arch)$(options) build = $(build-prefix)build/$(platform)-$(arch)$(options)
classpath-build = $(build)/classpath classpath-build = $(build)/classpath
test-build = $(build)/test test-build = $(build)/test
src = src src = src
@ -59,6 +59,8 @@ classpath-src = classpath
test = test test = test
win32 ?= $(root)/win32 win32 ?= $(root)/win32
win64 ?= $(root)/win64 win64 ?= $(root)/win64
winrt ?= $(root)/winrt
wp8 ?= $(root)/wp8
classpath = avian classpath = avian
@ -183,6 +185,18 @@ strip-all = --strip-all
rdynamic = -rdynamic rdynamic = -rdynamic
cflags_debug = -O0 -g3
cflags_debug_fast = -O0 -g3
cflags_stress = -O0 -g3
cflags_stress_major = -O0 -g3
ifeq ($(use-clang),true)
cflags_fast = -O4 -g3
cflags_small = -Oz -g3
else
cflags_fast = -O3 -g3
cflags_small = -Os -g3
endif
# note that we suppress the non-virtual-dtor warning because we never # note that we suppress the non-virtual-dtor warning because we never
# use the delete operator, which means we don't need virtual # use the delete operator, which means we don't need virtual
# destructors: # destructors:
@ -198,7 +212,7 @@ common-cflags = $(warnings) -fno-rtti -fno-exceptions -I$(classpath-src) \
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \ -DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \
-DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" $(target-cflags) -DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" $(target-cflags)
asmflags = $(target-cflags) asmflags = $(target-cflags) -I$(src)
ifneq (,$(filter i386 x86_64,$(arch))) ifneq (,$(filter i386 x86_64,$(arch)))
ifeq ($(use-frame-pointer),true) ifeq ($(use-frame-pointer),true)
@ -237,6 +251,18 @@ pointer-size = 8
so-prefix = lib so-prefix = lib
so-suffix = .so so-suffix = .so
static-prefix = lib
static-suffix = .a
output = -o $(1)
asm-output = -o $(1)
asm-input = -c $(1)
asm-format = S
as = $(cc)
ld = $(cxx)
build-ld = $(build-cc)
static = -static
shared = -shared shared = -shared
no-error = -Wno-error no-error = -Wno-error
@ -244,6 +270,8 @@ no-error = -Wno-error
openjdk-extra-cflags = -fvisibility=hidden openjdk-extra-cflags = -fvisibility=hidden
bootimage-cflags = -DTARGET_BYTES_PER_WORD=$(pointer-size) bootimage-cflags = -DTARGET_BYTES_PER_WORD=$(pointer-size)
bootimage-symbols = _binary_bootimage_bin_start:_binary_bootimage_bin_end
codeimage-symbols = _binary_codeimage_bin_start:_binary_codeimage_bin_end
developer-dir := $(shell if test -d /Developer; then echo /Developer; \ developer-dir := $(shell if test -d /Developer; then echo /Developer; \
else echo /Applications/Xcode.app/Contents/Developer; fi) else echo /Applications/Xcode.app/Contents/Developer; fi)
@ -354,41 +382,68 @@ ifeq ($(platform),freebsd)
cflags = $(build-cflags) cflags = $(build-cflags)
endif endif
ifeq ($(platform),android) ifeq ($(platform),android)
asm = arm ifeq ($(build-platform),cygwin)
pointer-size = 4
no-psabi = -Wno-psabi
use-lto = false
ifeq ($(build-platform),cygwin)
ndk = "$$(cygpath -u "$(ANDROID_NDK)")" ndk = "$$(cygpath -u "$(ANDROID_NDK)")"
else else
ndk = $(ANDROID_NDK) ndk = $(ANDROID_NDK)
endif endif
ifeq ($(android-version),)
android-version = 5
endif
ifeq ($(android-toolchain),)
android-toolchain = 4.7
endif
ifeq ($(arch),arm)
android-toolchain-name = arm-linux-androideabi
android-toolchain-prefix = arm-linux-androideabi-
endif
ifeq ($(arch),i386)
android-toolchain-name = x86
android-toolchain-prefix = i686-linux-android-
endif
ifeq ($(android-arm-arch),)
android-arm-arch = armv5
endif
options := $(options)-api$(android-version)-$(android-toolchain)-$(android-arm-arch)
build-cflags = $(common-cflags) -I$(src) build-cflags = $(common-cflags) -I$(src)
#build-lflags = -lz -lpthread -ldl build-lflags = -lz -lpthread
ifeq ($(subst cygwin,windows,$(subst mingw32,windows,$(build-platform))),windows) ifeq ($(subst cygwin,windows,$(subst mingw32,windows,$(build-platform))),windows)
toolchain-host-platform = $(subst cygwin,windows,$(subst mingw32,windows,$(build-platform))) toolchain-host-platform = $(subst cygwin,windows,$(subst mingw32,windows,$(build-platform)))
build-system = windows build-system = windows
build-cxx = i686-w64-mingw32-g++ build-cxx = i686-w64-mingw32-g++
build-cc = i686-w64-mingw32-gcc build-cc = i686-w64-mingw32-gcc
sysroot = "$$(cygpath -w "$(ndk)/platforms/android-5/arch-arm")" sysroot = "$$(cygpath -w "$(ndk)/platforms/android-$(android-version)/arch-arm")"
build-cflags += "-I$(JAVA_HOME)/include/win32" build-cflags += "-I$(JAVA_HOME)/include/win32"
else else
toolchain-host-platform = $(subst cygwin,windows,$(subst mingw32,windows,$(build-platform)))-* toolchain-host-platform = $(subst cygwin,windows,$(subst mingw32,windows,$(build-platform)))-*
sysroot = $(ndk)/platforms/android-5/arch-arm sysroot = $(ndk)/platforms/android-$(android-version)/arch-arm
build-cflags += "-I$(JAVA_HOME)/include/linux" build-cflags += "-I$(JAVA_HOME)/include/linux"
build-lflags += -ldl
endif endif
toolchain = $(ndk)/toolchains/arm-linux-androideabi-4.7/prebuilt/$(toolchain-host-platform) toolchain = $(ndk)/toolchains/$(android-toolchain-name)-$(android-toolchain)/prebuilt/$(toolchain-host-platform)
cflags = "-I$(sysroot)/usr/include" "-I$(JAVA_HOME)/include/linux" $(common-cflags) "-I$(src)" -std=c++11 -marm $(no-psabi) cflags = "-I$(sysroot)/usr/include" "-I$(JAVA_HOME)/include/linux" $(common-cflags) "-I$(src)" -std=c++11 $(no-psabi)
lflags = "-L$(sysroot)/usr/lib" $(common-lflags) -ldl lflags = "-L$(sysroot)/usr/lib" $(common-lflags) -llog
target-format = elf
use-lto = false use-lto = false
cxx = $(toolchain)/bin/arm-linux-androideabi-g++ --sysroot="$(sysroot)" ifeq ($(arch),arm)
cc = $(toolchain)/bin/arm-linux-androideabi-gcc --sysroot="$(sysroot)" cflags += -marm -march=$(android-arm-arch) -ftree-vectorize -ffast-math -mfloat-abi=softfp
as = $(toolchain)/bin/arm-linux-androideabi-as --sysroot="$(sysroot)" endif
ar = $(toolchain)/bin/arm-linux-androideabi-ar ifeq ($(arch),i386)
ranlib = $(toolchain)/bin/arm-linux-androideabi-ranlib endif
strip = $(toolchain)/bin/arm-linux-androideabi-strip
cxx = $(toolchain)/bin/$(android-toolchain-prefix)g++ --sysroot="$(sysroot)"
cc = $(toolchain)/bin/$(android-toolchain-prefix)gcc --sysroot="$(sysroot)"
as = $(cxx)
ar = $(toolchain)/bin/$(android-toolchain-prefix)ar
ranlib = $(toolchain)/bin/$(android-toolchain-prefix)ranlib
strip = $(toolchain)/bin/$(android-toolchain-prefix)strip
endif endif
ifeq ($(platform),darwin) ifeq ($(platform),darwin)
@ -475,7 +530,9 @@ ifeq ($(platform),darwin)
endif endif
ifeq ($(platform),windows) ifeq ($(platform),windows)
target-format = pe ifeq ($(target-format),)
target-format = pe
endif
inc = "$(win32)/include" inc = "$(win32)/include"
lib = "$(win32)/lib" lib = "$(win32)/lib"
@ -488,7 +545,8 @@ ifeq ($(platform),windows)
so-suffix = .dll so-suffix = .dll
exe-suffix = .exe exe-suffix = .exe
lflags = -L$(lib) $(common-lflags) -lws2_32 -liphlpapi -mwindows -mconsole lflags = -L$(lib) $(common-lflags) -lws2_32 -liphlpapi -mconsole
bootimage-generator-lflags = -static-libstdc++ -static-libgcc
cflags = -I$(inc) $(common-cflags) -DWINVER=0x0500 cflags = -I$(inc) $(common-cflags) -DWINVER=0x0500
ifeq (,$(filter mingw32 cygwin,$(build-platform))) ifeq (,$(filter mingw32 cygwin,$(build-platform)))
@ -539,39 +597,197 @@ ifeq ($(platform),windows)
embed-loader-o = $(build-embed)/embed-loader.o embed-loader-o = $(build-embed)/embed-loader.o
endif endif
ifeq ($(platform),wp8)
ifeq ($(shell uname -s | grep -i -c WOW64),1)
programFiles = Program Files (x86)
else
programFiles = Program Files
endif
ifeq ($(MSVS_ROOT),)
# Environment variable MSVS_ROOT not found. It should be something like
# "C:\$(programFiles)\Microsoft Visual Studio 11.0"
MSVS_ROOT = C:\$(programFiles)\Microsoft Visual Studio 11.0
endif
ifeq ($(MSVC_ROOT),)
# Environment variable MSVC_ROOT not found. It should be something like
# "C:\$(programFiles)\Microsoft Visual Studio 11.0\VC"
MSVC_ROOT = $(MSVS_ROOT)\VC
endif
ifeq ($(WP80_SDK),)
# Environment variable WP8_SDK not found. It should be something like
# "C:\Program Files[ (x86)]\Microsoft Visual Studio 11.0\VC\WPSDK\WP80"
# TODO: Lookup in SOFTWARE\Microsoft\Microsoft SDKs\WindowsPhone\v8.0
WP80_SDK = C:\$(programFiles)\Microsoft Visual Studio 11.0\VC\WPSDK\WP80
endif
ifeq ($(WP80_KIT),)
# Environment variable WP8_KIT not found. It should be something like
# "c:\Program Files[ (x86)]\Windows Phone Kits\8.0"
# TODO: Lookup in SOFTWARE\Microsoft\Microsoft SDKs\WindowsPhone\v8.0
WP80_KIT = C:\$(programFiles)\Windows Phone Kits\8.0
endif
ifeq ($(WIN8_KIT),)
# Environment variable WIN8_KIT not found. It should be something like
# "c:\Program Files[ (x86)]\Windows Kits\8.0"
WIN8_KIT = C:\$(programFiles)\Windows Kits\8.0
endif
ifeq ($(build-platform),cygwin)
windows-path = cygpath -w
else
windows-path = $(native-path)
endif
windows-java-home := $(shell $(windows-path) "$(JAVA_HOME)")
target-format = pe
ms_cl_compiler = wp8
use-lto = false
supports_avian_executable = false
process = interpret
ifneq ($(process),compile)
options := -$(process)
endif
bootimage = true
ifeq ($(bootimage),true)
options := $(options)-bootimage
endif
system = windows
build-system = windows
static-prefix =
static-suffix = .lib
so-prefix =
so-suffix = .dll
exe-suffix = .exe
ifeq ($(arch),arm)
wp8_arch = \x86_arm
vc_arch = \arm
w8kit_arch = arm
deps_arch = ARM
as = "$$(cygpath -u "$(WP80_SDK)\bin\x86_arm\armasm.exe")"
cxx = "$$(cygpath -u "$(WP80_SDK)\bin\x86_arm\cl.exe")"
ld = "$$(cygpath -u "$(WP80_SDK)\bin\x86_arm\link.exe")"
asmflags = -machine ARM -32
asm-output = -o $(1)
asm-input = $(1)
machine_type = ARM
bootimage-symbols = binary_bootimage_bin_start:binary_bootimage_bin_end
codeimage-symbols = binary_codeimage_bin_start:binary_codeimage_bin_end
endif
ifeq ($(arch),i386)
wp8_arch =
vc_arch =
w8kit_arch = x86
deps_arch = x86
as = "$$(cygpath -u "$(WP80_SDK)\bin\ml.exe")"
cxx = "$$(cygpath -u "$(WP80_SDK)\bin\cl.exe")"
ld = "$$(cygpath -u "$(WP80_SDK)\bin\link.exe")"
asmflags += -nologo
asm-output = $(output)
machine_type = X86
endif
PATH := $(shell cygpath -u "$(MSVS_ROOT)\Common7\IDE"):$(shell cygpath -u "$(WP80_SDK)\bin$(wp8_arch)"):$(shell cygpath -u "$(WP80_SDK)\bin"):${PATH}
build-cflags = $(common-cflags) -I$(src) -I$(inc) -mthreads
build-lflags = -lz -lpthread
cflags = -nologo \
-I"$(WP80_SDK)\include" -I"$(WP80_KIT)\Include" -I"$(WP80_KIT)\Include\minwin" -I"$(WP80_KIT)\Include\mincore" \
-DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP \
-DAVIAN_VERSION=\"$(version)\" -D_JNI_IMPLEMENTATION_ \
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \
-DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" \
-I"$(shell $(windows-path) "$(wp8)/zlib/upstream")" \
-Fd$(build)/$(name).pdb -I"$(shell $(windows-path) "$(wp8)/include")" -I$(src) -I$(classpath-src) \
-I"$(build)" \
-I"$(windows-java-home)/include" -I"$(windows-java-home)/include/win32" \
-DTARGET_BYTES_PER_WORD=$(pointer-size)
common-lflags = $(classpath-lflags)
arflags = -MACHINE:$(machine_type)
lflags = $(common-lflags) -nologo \
-MACHINE:$(machine_type) \
-LIBPATH:"$(WP80_KIT)\lib\$(w8kit_arch)" -LIBPATH:"$(WIN8_KIT)\Lib\win8\um\$(w8kit_arch)" -LIBPATH:"$(MSVC_ROOT)\lib$(vc_arch)" \
ws2_32.lib \
"$(shell $(windows-path) "$(wp8)\lib\$(deps_arch)\zlib.lib")" "$(shell $(windows-path) "$(wp8)\lib\$(deps_arch)\ThreadEmulation.lib")"
cc = $(cxx)
asm-format = masm
shared = -dll
ar = "$$(cygpath -u "$(WP80_SDK)\bin\lib.exe")"
arflags += -nologo
ifeq ($(build-platform),cygwin)
build-cxx = i686-w64-mingw32-g++
build-cc = i686-w64-mingw32-gcc
dlltool = i686-w64-mingw32-dlltool
ranlib =
strip =
endif
output = -Fo$(1)
cflags_debug = -Od -Zi -MDd
cflags_debug_fast = -Od -Zi -MDd
cflags_stress = -O0 -g3 -MD
cflags_stress_major = -O0 -g3 -MD
cflags_fast = -O2 -Zi -MD
cflags_small = -O1s -Zi -MD
# -GL [whole program optimization] in 'fast' and 'small' breaks compilation for some reason
ifeq ($(mode),debug)
cflags +=
lflags +=
endif
ifeq ($(mode),debug-fast)
cflags += -DNDEBUG
lflags +=
endif
ifeq ($(mode),stress_major)
cflags +=
lflags +=
endif
ifeq ($(mode),fast)
cflags +=
lflags +=
endif
# -LTCG is needed only if -GL is used
ifeq ($(mode),fast)
cflags += -DNDEBUG
lflags += -LTCG
arflags +=
endif
ifeq ($(mode),small)
cflags += -DNDEBUG
lflags += -LTCG
arflags +=
endif
strip = :
endif
ifeq ($(mode),debug) ifeq ($(mode),debug)
optimization-cflags = -O0 -g3 optimization-cflags = $(cflags_debug)
converter-cflags += -O0 -g3 converter-cflags += $(cflags_debug)
strip = : strip = :
endif endif
ifeq ($(mode),debug-fast) ifeq ($(mode),debug-fast)
optimization-cflags = -O0 -g3 -DNDEBUG optimization-cflags = $(cflags_debug_fast) -DNDEBUG
strip = : strip = :
endif endif
ifeq ($(mode),stress) ifeq ($(mode),stress)
optimization-cflags = -O0 -g3 -DVM_STRESS optimization-cflags = $(cflags_stress) -DVM_STRESS
strip = : strip = :
endif endif
ifeq ($(mode),stress-major) ifeq ($(mode),stress-major)
optimization-cflags = -O0 -g3 -DVM_STRESS -DVM_STRESS_MAJOR optimization-cflags = $(cflags_stress_major) -DVM_STRESS -DVM_STRESS_MAJOR
strip = : strip = :
endif endif
ifeq ($(mode),fast) ifeq ($(mode),fast)
ifeq ($(use-clang),true) optimization-cflags = $(cflags_fast) -DNDEBUG
optimization-cflags = -O4 -g3 -DNDEBUG
else
optimization-cflags = -O3 -g3 -DNDEBUG
endif
ifeq ($(use-lto),) ifeq ($(use-lto),)
use-lto = true use-lto = true
endif endif
endif endif
ifeq ($(mode),small) ifeq ($(mode),small)
ifeq ($(use-clang),true) optimization-cflags = $(cflags_small) -DNDEBUG
optimization-cflags = -Oz -g3 -DNDEBUG
else
optimization-cflags = -Os -g3 -DNDEBUG
endif
ifeq ($(use-lto),) ifeq ($(use-lto),)
use-lto = true use-lto = true
endif endif
@ -596,6 +812,7 @@ endif
cflags += $(optimization-cflags) cflags += $(optimization-cflags)
ifndef ms_cl_compiler
ifneq ($(platform),darwin) ifneq ($(platform),darwin)
ifeq ($(arch),i386) ifeq ($(arch),i386)
# this is necessary to support __sync_bool_compare_and_swap: # this is necessary to support __sync_bool_compare_and_swap:
@ -603,16 +820,9 @@ ifeq ($(arch),i386)
lflags += -march=i586 lflags += -march=i586
endif endif
endif endif
endif
output = -o $(1)
as := $(cc)
ld := $(cc)
build-ld := $(build-cc)
static = -static
ifdef msvc ifdef msvc
static =
no-error = no-error =
windows-path = $(native-path) windows-path = $(native-path)
windows-java-home := $(shell $(windows-path) "$(JAVA_HOME)") windows-java-home := $(shell $(windows-path) "$(JAVA_HOME)")
@ -621,6 +831,7 @@ ifdef msvc
cc = $(cxx) cc = $(cxx)
ld = "$(msvc)/BIN/link.exe" ld = "$(msvc)/BIN/link.exe"
mt = "mt.exe" mt = "mt.exe"
manifest-flags = -MANIFEST -MANIFESTFILE:$(@).manifest
cflags = -nologo -DAVIAN_VERSION=\"$(version)\" -D_JNI_IMPLEMENTATION_ \ cflags = -nologo -DAVIAN_VERSION=\"$(version)\" -D_JNI_IMPLEMENTATION_ \
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \ -DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \
-DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" \ -DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" \
@ -629,7 +840,7 @@ ifdef msvc
-I"$(windows-java-home)/include" -I"$(windows-java-home)/include/win32" \ -I"$(windows-java-home)/include" -I"$(windows-java-home)/include/win32" \
-DTARGET_BYTES_PER_WORD=$(pointer-size) -DTARGET_BYTES_PER_WORD=$(pointer-size)
ifneq ($(lzma),) ifneq ($(lzma),)
cflags += -I$(shell $(windows-path) "$(lzma)") cflags += -I$(shell $(windows-path) "$(lzma)")
endif endif
@ -656,9 +867,11 @@ ifdef msvc
strip = : strip = :
endif endif
build-cflags += -DAVIAN_HOST_TARGET
c-objects = $(foreach x,$(1),$(patsubst $(2)/%.c,$(3)/%.o,$(x))) c-objects = $(foreach x,$(1),$(patsubst $(2)/%.c,$(3)/%.o,$(x)))
cpp-objects = $(foreach x,$(1),$(patsubst $(2)/%.cpp,$(3)/%.o,$(x))) cpp-objects = $(foreach x,$(1),$(patsubst $(2)/%.cpp,$(3)/%.o,$(x)))
asm-objects = $(foreach x,$(1),$(patsubst $(2)/%.S,$(3)/%-asm.o,$(x))) asm-objects = $(foreach x,$(1),$(patsubst $(2)/%.$(asm-format),$(3)/%-asm.o,$(x)))
java-classes = $(foreach x,$(1),$(patsubst $(2)/%.java,$(3)/%.class,$(x))) java-classes = $(foreach x,$(1),$(patsubst $(2)/%.java,$(3)/%.class,$(x)))
generated-code = \ generated-code = \
@ -684,7 +897,7 @@ vm-sources = \
$(src)/jnienv.cpp \ $(src)/jnienv.cpp \
$(src)/process.cpp $(src)/process.cpp
vm-asm-sources = $(src)/$(asm).S vm-asm-sources = $(src)/$(asm).$(asm-format)
target-asm = $(asm) target-asm = $(asm)
@ -702,8 +915,9 @@ ifeq ($(process),compile)
$(src)/compiler.cpp \ $(src)/compiler.cpp \
$(src)/$(target-asm).cpp $(src)/$(target-asm).cpp
vm-asm-sources += $(src)/compile-$(asm).S vm-asm-sources += $(src)/compile-$(asm).$(asm-format)
endif endif
cflags += -DAVIAN_PROCESS_$(process)
vm-cpp-objects = $(call cpp-objects,$(vm-sources),$(src),$(build)) vm-cpp-objects = $(call cpp-objects,$(vm-sources),$(src),$(build))
vm-asm-objects = $(call asm-objects,$(vm-asm-sources),$(src),$(build)) vm-asm-objects = $(call asm-objects,$(vm-asm-sources),$(src),$(build))
@ -835,7 +1049,7 @@ converter-objects = $(call cpp-objects,$(converter-sources),$(src),$(build))
converter-tool-objects = $(call cpp-objects,$(converter-tool-sources),$(src),$(build)) converter-tool-objects = $(call cpp-objects,$(converter-tool-sources),$(src),$(build))
converter = $(build)/binaryToObject/binaryToObject converter = $(build)/binaryToObject/binaryToObject
static-library = $(build)/lib$(name).a static-library = $(build)/$(static-prefix)$(name)${static-suffix}
executable = $(build)/$(name)${exe-suffix} executable = $(build)/$(name)${exe-suffix}
dynamic-library = $(build)/$(so-prefix)jvm$(so-suffix) dynamic-library = $(build)/$(so-prefix)jvm$(so-suffix)
executable-dynamic = $(build)/$(name)-dynamic${exe-suffix} executable-dynamic = $(build)/$(name)-dynamic${exe-suffix}
@ -945,9 +1159,15 @@ test-flags = -Djava.library.path=$(build) -cp $(build)/test
test-args = $(test-flags) $(input) test-args = $(test-flags) $(input)
.PHONY: build .PHONY: build
ifneq ($(supports_avian_executable),false)
build: $(static-library) $(executable) $(dynamic-library) $(lzma-loader) \ build: $(static-library) $(executable) $(dynamic-library) $(lzma-loader) \
$(lzma-encoder) $(executable-dynamic) $(classpath-dep) $(test-dep) \ $(lzma-encoder) $(executable-dynamic) $(classpath-dep) $(test-dep) \
$(test-extra-dep) $(embed) $(test-extra-dep) $(embed)
else
build: $(static-library) $(dynamic-library) $(lzma-loader) \
$(lzma-encoder) $(classpath-dep) $(test-dep) \
$(test-extra-dep) $(embed)
endif
$(test-dep): $(classpath-dep) $(test-dep): $(classpath-dep)
@ -992,7 +1212,7 @@ clean:
@echo "removing build" @echo "removing build"
rm -rf build rm -rf build
$(build)/compile-x86-asm.o: $(src)/continuations-x86.S $(build)/compile-x86-asm.o: $(src)/continuations-x86.$(asm-format)
gen-arg = $(shell echo $(1) | sed -e 's:$(build)/type-\(.*\)\.cpp:\1:') gen-arg = $(shell echo $(1) | sed -e 's:$(build)/type-\(.*\)\.cpp:\1:')
$(generated-code): %.cpp: $(src)/types.def $(generator) $(classpath-dep) $(generated-code): %.cpp: $(src)/types.def $(generator) $(classpath-dep)
@ -1043,7 +1263,7 @@ endef
define compile-asm-object define compile-asm-object
@echo "compiling $(@)" @echo "compiling $(@)"
@mkdir -p $(dir $(@)) @mkdir -p $(dir $(@))
$(as) -I$(src) $(asmflags) -c $(<) -o $(@) $(as) $(asmflags) $(call asm-output,$(@)) $(call asm-input,$(<))
endef endef
$(vm-cpp-objects): $(build)/%.o: $(src)/%.cpp $(vm-depends) $(vm-cpp-objects): $(build)/%.o: $(src)/%.cpp $(vm-depends)
@ -1054,10 +1274,12 @@ $(test-cpp-objects): $(test-build)/%.o: $(test)/%.cpp $(vm-depends)
$(test-library): $(test-cpp-objects) $(test-library): $(test-cpp-objects)
@echo "linking $(@)" @echo "linking $(@)"
ifdef msvc ifdef ms_cl_compiler
$(ld) $(shared) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb \ $(ld) $(shared) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb \
-IMPLIB:$(test-build)/$(name).lib -MANIFESTFILE:$(@).manifest -IMPLIB:$(test-build)/$(name).lib $(manifest-flags)
$(mt) -manifest $(@).manifest -outputresource:"$(@);2" ifdef mt
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);2"
endif
else else
$(ld) $(^) $(shared) $(lflags) -o $(@) $(ld) $(^) $(shared) $(lflags) -o $(@)
endif endif
@ -1065,10 +1287,12 @@ endif
ifdef embed ifdef embed
$(embed): $(embed-objects) $(embed-loader-o) $(embed): $(embed-objects) $(embed-loader-o)
@echo "building $(embed)" @echo "building $(embed)"
ifdef msvc ifdef ms_cl_compiler
$(ld) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb \ $(ld) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb \
-IMPLIB:$(@).lib -MANIFESTFILE:$(@).manifest -IMPLIB:$(@).lib $(manifest-flags)
$(mt) -manifest $(@).manifest -outputresource:"$(@);1" ifdef mt
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);1"
endif
else else
$(cxx) $(^) $(lflags) $(static) $(call output,$(@)) $(cxx) $(^) $(lflags) $(static) $(call output,$(@))
endif endif
@ -1086,10 +1310,12 @@ $(embed-loader-o): $(embed-loader) $(converter)
$(embed-loader): $(embed-loader-objects) $(static-library) $(embed-loader): $(embed-loader-objects) $(static-library)
@mkdir -p $(dir $(@)) @mkdir -p $(dir $(@))
cd $(dir $(@)) && $(ar) x ../../../$(static-library) cd $(dir $(@)) && $(ar) x ../../../$(static-library)
ifdef msvc ifdef ms_cl_compiler
$(ld) $(lflags) $(dir $(@))/*.o -out:$(@) -PDB:$(@).pdb \ $(ld) $(lflags) $(dir $(@))/*.o -out:$(@) -PDB:$(@).pdb \
-IMPLIB:$(@).lib -MANIFESTFILE:$(@).manifest -IMPLIB:$(@).lib $(manifest-flags)
$(mt) -manifest $(@).manifest -outputresource:"$(@);1" ifdef mt
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);1"
endif
else else
$(dlltool) -z $(addsuffix .def,$(basename $(@))) $(dir $(@))/*.o $(dlltool) -z $(addsuffix .def,$(basename $(@))) $(dir $(@))/*.o
$(dlltool) -d $(addsuffix .def,$(basename $(@))) -e $(addsuffix .exp,$(basename $(@))) $(dlltool) -d $(addsuffix .def,$(basename $(@))) -e $(addsuffix .exp,$(basename $(@)))
@ -1109,7 +1335,7 @@ $(build)/%.o: $(lzma)/C/%.c
@mkdir -p $(dir $(@)) @mkdir -p $(dir $(@))
$(cxx) $(cflags) $(no-error) -c $$($(windows-path) $(<)) $(call output,$(@)) $(cxx) $(cflags) $(no-error) -c $$($(windows-path) $(<)) $(call output,$(@))
$(vm-asm-objects): $(build)/%-asm.o: $(src)/%.S $(vm-asm-objects): $(build)/%-asm.o: $(src)/%.$(asm-format)
$(compile-asm-object) $(compile-asm-object)
$(bootimage-generator-objects): $(build)/%.o: $(src)/%.cpp $(vm-depends) $(bootimage-generator-objects): $(build)/%.o: $(src)/%.cpp $(vm-depends)
@ -1196,14 +1422,18 @@ $(static-library): $(vm-objects) $(classpath-objects) $(vm-heapwalk-objects) \
$(javahome-object) $(boot-javahome-object) $(lzma-decode-objects) $(javahome-object) $(boot-javahome-object) $(lzma-decode-objects)
@echo "creating $(@)" @echo "creating $(@)"
rm -rf $(@) rm -rf $(@)
ifdef ms_cl_compiler
$(ar) $(arflags) $(^) -out:$(@)
else
$(ar) cru $(@) $(^) $(ar) cru $(@) $(^)
$(ranlib) $(@) $(ranlib) $(@)
endif
$(bootimage-object) $(codeimage-object): $(bootimage-generator) \ $(bootimage-object) $(codeimage-object): $(bootimage-generator)
$(build)/classpath.jar @echo "generating bootimage and codeimage binaries using $(<)"
$(<) -cp $(classpath-build) -bootimage $(bootimage-object) -codeimage $(codeimage-object) \ $(<) -cp $(classpath-build) -bootimage $(bootimage-object) -codeimage $(codeimage-object) \
-bootimage-symbols _binary_bootimage_bin_start:_binary_bootimage_bin_end \ -bootimage-symbols $(bootimage-symbols) \
-codeimage-symbols _binary_codeimage_bin_start:_binary_codeimage_bin_end -codeimage-symbols $(codeimage-symbols)
executable-objects = $(vm-objects) $(classpath-objects) $(driver-object) \ executable-objects = $(vm-objects) $(classpath-objects) $(driver-object) \
$(vm-heapwalk-objects) $(boot-object) $(vm-classpath-objects) \ $(vm-heapwalk-objects) $(boot-object) $(vm-classpath-objects) \
@ -1212,10 +1442,12 @@ executable-objects = $(vm-objects) $(classpath-objects) $(driver-object) \
$(executable): $(executable-objects) $(executable): $(executable-objects)
@echo "linking $(@)" @echo "linking $(@)"
ifeq ($(platform),windows) ifeq ($(platform),windows)
ifdef msvc ifdef ms_cl_compiler
$(ld) $(lflags) $(executable-objects) -out:$(@) -PDB:$(@).pdb \ $(ld) $(lflags) $(executable-objects) -out:$(@) -PDB:$(@).pdb \
-IMPLIB:$(@).lib -MANIFESTFILE:$(@).manifest -IMPLIB:$(@).lib $(manifest-flags)
$(mt) -manifest $(@).manifest -outputresource:"$(@);1" ifdef mt
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);1"
endif
else else
$(dlltool) -z $(@).def $(executable-objects) $(dlltool) -z $(@).def $(executable-objects)
$(dlltool) -d $(@).def -e $(@).exp $(dlltool) -d $(@).def -e $(@).exp
@ -1229,6 +1461,7 @@ endif
$(bootimage-generator): $(bootimage-generator-objects) $(bootimage-generator): $(bootimage-generator-objects)
echo arch=$(arch) platform=$(platform) echo arch=$(arch) platform=$(platform)
$(MAKE) mode=$(mode) \ $(MAKE) mode=$(mode) \
build-prefix=$(build)/host/ \
arch=$(build-arch) \ arch=$(build-arch) \
target-arch=$(arch) \ target-arch=$(arch) \
platform=$(bootimage-platform) \ platform=$(bootimage-platform) \
@ -1247,17 +1480,19 @@ $(build-bootimage-generator): \
$(lzma-decode-objects) $(lzma-encode-objects) $(lzma-decode-objects) $(lzma-encode-objects)
@echo "linking $(@)" @echo "linking $(@)"
ifeq ($(platform),windows) ifeq ($(platform),windows)
ifdef msvc ifdef ms_cl_compiler
$(ld) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb -IMPLIB:$(@).lib \ $(ld) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb \
-MANIFESTFILE:$(@).manifest -IMPLIB:$(@).lib $(manifest-flags)
$(mt) -manifest $(@).manifest -outputresource:"$(@);1" ifdef mt
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);1"
endif
else else
$(dlltool) -z $(@).def $(^) $(dlltool) -z $(@).def $(^)
$(dlltool) -d $(@).def -e $(@).exp $(dlltool) -d $(@).def -e $(@).exp
$(ld) $(@).exp $(^) $(lflags) -o $(@) $(ld) $(@).exp $(^) $(bootimage-generator-lflags) $(lflags) -o $(@)
endif endif
else else
$(ld) $(^) $(rdynamic) $(lflags) -o $(@) $(ld) $(^) $(rdynamic) $(bootimage-generator-lflags) $(lflags) -o $(@)
endif endif
$(dynamic-library): $(vm-objects) $(dynamic-object) $(classpath-objects) \ $(dynamic-library): $(vm-objects) $(dynamic-object) $(classpath-objects) \
@ -1265,10 +1500,12 @@ $(dynamic-library): $(vm-objects) $(dynamic-object) $(classpath-objects) \
$(classpath-libraries) $(javahome-object) $(boot-javahome-object) \ $(classpath-libraries) $(javahome-object) $(boot-javahome-object) \
$(lzma-decode-objects) $(lzma-decode-objects)
@echo "linking $(@)" @echo "linking $(@)"
ifdef msvc ifdef ms_cl_compiler
$(ld) $(shared) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb \ $(ld) $(shared) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb \
-IMPLIB:$(build)/$(name).lib -MANIFESTFILE:$(@).manifest -IMPLIB:$(build)/$(name).lib $(manifest-flags)
$(mt) -manifest $(@).manifest -outputresource:"$(@);2" ifdef mt
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);2"
endif
else else
$(ld) $(^) $(version-script-flag) $(soname-flag) \ $(ld) $(^) $(version-script-flag) $(soname-flag) \
$(shared) $(lflags) $(bootimage-lflags) \ $(shared) $(lflags) $(bootimage-lflags) \
@ -1280,11 +1517,13 @@ endif
# Ubuntu 11.10 which may be fixable without disabling LTO. # Ubuntu 11.10 which may be fixable without disabling LTO.
$(executable-dynamic): $(driver-dynamic-objects) $(dynamic-library) $(executable-dynamic): $(driver-dynamic-objects) $(dynamic-library)
@echo "linking $(@)" @echo "linking $(@)"
ifdef msvc ifdef ms_cl_compiler
$(ld) $(lflags) -LIBPATH:$(build) -DEFAULTLIB:$(name) \ $(ld) $(lflags) -LIBPATH:$(build) -DEFAULTLIB:$(name) \
-PDB:$(@).pdb -IMPLIB:$(@).lib $(driver-dynamic-objects) -out:$(@) \ -PDB:$(@).pdb -IMPLIB:$(@).lib $(driver-dynamic-objects) \
-MANIFESTFILE:$(@).manifest -out:$(@) $(manifest-flags)
$(mt) -manifest $(@).manifest -outputresource:"$(@);1" ifdef mt
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);1"
endif
else else
$(ld) $(driver-dynamic-objects) -L$(build) -ljvm $(lflags) $(no-lto) -Wl,-rpath=\$$ORIGIN -z origin -o $(@) $(ld) $(driver-dynamic-objects) -L$(build) -ljvm $(lflags) $(no-lto) -Wl,-rpath=\$$ORIGIN -z origin -o $(@)
endif endif

View File

@ -71,33 +71,53 @@ namespace vm {
inline void inline void
trap() trap()
{ {
#ifdef _MSC_VER
__debugbreak();
#else
asm("bkpt"); asm("bkpt");
#endif
} }
#ifndef _MSC_VER
inline void inline void
memoryBarrier() memoryBarrier()
{ {
asm("nop"); asm("nop");
} }
#endif
inline void inline void
storeStoreMemoryBarrier() storeStoreMemoryBarrier()
{ {
#ifdef _MSC_VER
_ReadWriteBarrier();
#else
memoryBarrier(); memoryBarrier();
#endif
} }
inline void inline void
storeLoadMemoryBarrier() storeLoadMemoryBarrier()
{ {
#ifdef _MSC_VER
MemoryBarrier();
#else
memoryBarrier(); memoryBarrier();
#endif
} }
inline void inline void
loadMemoryBarrier() loadMemoryBarrier()
{ {
#ifdef _MSC_VER
_ReadWriteBarrier();
#else
memoryBarrier(); memoryBarrier();
#endif
} }
#if defined(AVIAN_PROCESS_compile)
#if defined(__ANDROID__) #if defined(__ANDROID__)
// http://code.google.com/p/android/issues/detail?id=1803 // http://code.google.com/p/android/issues/detail?id=1803
extern "C" void __clear_cache (void *beg __attribute__((__unused__)), void *end __attribute__((__unused__))); extern "C" void __clear_cache (void *beg __attribute__((__unused__)), void *end __attribute__((__unused__)));
@ -116,6 +136,8 @@ syncInstructionCache(const void* start, unsigned size)
#endif #endif
} }
#endif // AVIAN_PROCESS_compile
#ifndef __APPLE__ #ifndef __APPLE__
typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr); typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr);
# define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0) # define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0)
@ -160,7 +182,7 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
unsigned vfpIndex = 0; unsigned vfpIndex = 0;
unsigned vfpBackfillIndex UNUSED = 0; unsigned vfpBackfillIndex UNUSED = 0;
uintptr_t stack[(argumentCount * 8) / BytesPerWord]; // is > argumentSize to account for padding uintptr_t* stack = new uintptr_t[(argumentCount * 8) / BytesPerWord]; // is > argumentSize to account for padding
unsigned stackIndex = 0; unsigned stackIndex = 0;
unsigned ai = 0; unsigned ai = 0;
@ -250,10 +272,12 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
} }
unsigned stackSize = stackIndex*BytesPerWord + ((stackIndex & 1) << 2); unsigned stackSize = stackIndex*BytesPerWord + ((stackIndex & 1) << 2);
return vmNativeCall auto retVal = vmNativeCall
(function, stackSize, stack, stackIndex * BytesPerWord, (function, stackSize, stack, stackIndex * BytesPerWord,
(gprIndex ? gprTable : 0), (gprIndex ? gprTable : 0),
(vfpIndex ? vfpTable : 0), returnType); (vfpIndex ? vfpTable : 0), returnType);
delete[] stack;
return retVal;
} }
} // namespace vm } // namespace vm

77
src/arm.masm Normal file
View File

@ -0,0 +1,77 @@
AREA text, CODE, ARM
EXPORT vmNativeCall [FUNC]
vmNativeCall
; arguments:
; r0 -> r4 : function
; r1 -> r5 : stackTotal
; r2 : memoryTable
; r3 : memoryCount
; [sp, #0] -> r6 : gprTable
mov ip, sp ; save stack frame
stmfd sp!, {r4-r6, lr} ; save clobbered non-volatile regs
; mv args into non-volatile regs
mov r4, r0
mov r5, r1
ldr r6, [ip]
; setup stack arguments if necessary
sub sp, sp, r5 ; allocate stack
mov ip, sp
loop
tst r3, r3
ldrne r0, [r2], #4
strne r0, [ip], #4
subne r3, r3, #4
bne loop
; setup argument registers if necessary
tst r6, r6
ldmneia r6, {r0-r3}
blx r4 ; call function
add sp, sp, r5 ; deallocate stack
ldmfd sp!, {r4-r6, pc} ; restore non-volatile regs and return
EXPORT vmJump [FUNC]
vmJump
mov lr, r0
ldr r0, [sp]
ldr r1, [sp, #4]
mov sp, r2
mov r8, r3
bx lr
CHECKPOINT_THREAD EQU 4
CHECKPOINT_STACK EQU 24
EXPORT vmRun [FUNC]
vmRun
; r0: function
; r1: arguments
; r2: checkpoint
stmfd sp!, {r4-r11, lr}
; align stack
sub sp, sp, #12
str sp, [r2, #CHECKPOINT_STACK]
mov r12, r0
ldr r0, [r2, #CHECKPOINT_THREAD]
blx r12
EXPORT vmRun_returnAddress [FUNC]
vmRun_returnAddress
add sp, sp, #12
ldmfd sp!, {r4-r11, lr}
bx lr
EXPORT vmTrap [FUNC]
vmTrap
bkpt 3
END

View File

@ -17,13 +17,17 @@
namespace { namespace {
#define IMAGE_SIZEOF_SHORT_NAME 8 // --- winnt.h ----
#define IMAGE_SIZEOF_SHORT_NAME 8
#define IMAGE_FILE_RELOCS_STRIPPED 1 #define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file.
#define IMAGE_FILE_LINE_NUMS_STRIPPED 4 #define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file.
#define IMAGE_FILE_MACHINE_AMD64 0x8664 #define IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8)
#define IMAGE_FILE_MACHINE_I386 0x014c #define IMAGE_FILE_MACHINE_I386 0x014c // Intel 386.
#define IMAGE_FILE_32BIT_MACHINE 256 #define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian
#define IMAGE_FILE_MACHINE_THUMB 0x01c2 // ARM Thumb/Thumb-2 Little-Endian
#define IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARM Thumb-2 Little-Endian
#define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine.
#define IMAGE_SCN_ALIGN_1BYTES 0x100000 #define IMAGE_SCN_ALIGN_1BYTES 0x100000
#define IMAGE_SCN_ALIGN_2BYTES 0x200000 #define IMAGE_SCN_ALIGN_2BYTES 0x200000
@ -73,6 +77,7 @@ struct IMAGE_SYMBOL {
uint8_t StorageClass; uint8_t StorageClass;
uint8_t NumberOfAuxSymbols; uint8_t NumberOfAuxSymbols;
} __attribute__((packed)); } __attribute__((packed));
// --- winnt.h ----
inline unsigned inline unsigned
pad(unsigned n) pad(unsigned n)
@ -82,7 +87,7 @@ pad(unsigned n)
using namespace avian::tools; using namespace avian::tools;
template<unsigned BytesPerWord> template<unsigned BytesPerWord, PlatformInfo::Architecture Architecture>
class WindowsPlatform : public Platform { class WindowsPlatform : public Platform {
public: public:
@ -202,12 +207,15 @@ public:
int machine; int machine;
int machineMask; int machineMask;
if (BytesPerWord == 8) { if (Architecture == PlatformInfo::x86_64) {
machine = IMAGE_FILE_MACHINE_AMD64; machine = IMAGE_FILE_MACHINE_AMD64;
machineMask = 0; machineMask = 0;
} else { // if (BytesPerWord == 8) } else if (Architecture == PlatformInfo::x86) {
machine = IMAGE_FILE_MACHINE_I386; machine = IMAGE_FILE_MACHINE_I386;
machineMask = IMAGE_FILE_32BIT_MACHINE; machineMask = IMAGE_FILE_32BIT_MACHINE;
} else if (Architecture == PlatformInfo::Arm) {
machine = IMAGE_FILE_MACHINE_ARMNT;
machineMask = IMAGE_FILE_32BIT_MACHINE;
} }
int sectionMask; int sectionMask;
@ -269,10 +277,11 @@ public:
} }
WindowsPlatform(): WindowsPlatform():
Platform(PlatformInfo(PlatformInfo::Pe, BytesPerWord == 4 ? PlatformInfo::x86 : PlatformInfo::x86_64)) {} Platform(PlatformInfo(PlatformInfo::Pe, Architecture)) {}
}; };
WindowsPlatform<4> windows32Platform; WindowsPlatform<4, PlatformInfo::x86> windows32Platform;
WindowsPlatform<8> windows64Platform; WindowsPlatform<8, PlatformInfo::x86_64> windows64Platform;
WindowsPlatform<4, PlatformInfo::Arm> windowsRtPlatform; // Windows Phone 8 and Windows RT
} // namespace } // namespace

View File

@ -342,7 +342,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
unsigned count = s.read2() - 1; unsigned count = s.read2() - 1;
if (count) { if (count) {
Type types[count + 2]; Type* types = new Type[count + 2];
types[0] = Type_object; types[0] = Type_object;
types[1] = Type_intptr_t; types[1] = Type_intptr_t;
@ -410,6 +410,9 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
(t, typeMaps, hashMapFind (t, typeMaps, hashMapFind
(t, root(t, Machine::PoolMap), c, objectHash, objectEqual), array, (t, root(t, Machine::PoolMap), c, objectHash, objectEqual), array,
objectHash); objectHash);
delete[] types;
types = 0;
} }
} }
@ -420,7 +423,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
object fields = allFields(t, typeMaps, c, &count, &array); object fields = allFields(t, typeMaps, c, &count, &array);
PROTECT(t, fields); PROTECT(t, fields);
Field memberFields[count + 1]; Field* memberFields = new Field[count + 1];
unsigned memberIndex; unsigned memberIndex;
unsigned buildMemberOffset; unsigned buildMemberOffset;
@ -454,7 +457,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
const unsigned StaticHeader = 3; const unsigned StaticHeader = 3;
Field staticFields[count + StaticHeader]; Field* staticFields = new Field[count + StaticHeader];
init(new (staticFields) Field, Type_object, 0, BytesPerWord, 0, init(new (staticFields) Field, Type_object, 0, BytesPerWord, 0,
TargetBytesPerWord); TargetBytesPerWord);
@ -586,6 +589,12 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
hashMapInsert hashMapInsert
(t, typeMaps, classStaticTable(t, c), array, objectHash); (t, typeMaps, classStaticTable(t, c), array, objectHash);
} }
delete[] memberFields;
memberFields = 0;
delete[] staticFields;
staticFields = 0;
} }
} }
} }
@ -1334,7 +1343,7 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
} }
++ count; ++ count;
Field fields[count]; Field* fields = new Field[count];
init(new (fields) Field, Type_object, 0, BytesPerWord, 0, init(new (fields) Field, Type_object, 0, BytesPerWord, 0,
TargetBytesPerWord); TargetBytesPerWord);
@ -1462,6 +1471,9 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
hashMapInsert hashMapInsert
(t, typeMaps, vm::type(t, static_cast<Machine::Type>(i)), array, (t, typeMaps, vm::type(t, static_cast<Machine::Type>(i)), array,
objectHash); objectHash);
delete[] fields;
fields = 0;
} }
constants = makeCodeImage constants = makeCodeImage
@ -1646,10 +1658,10 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
Platform* platform = Platform::getPlatform(PlatformInfo((PlatformInfo::Format)AVIAN_TARGET_FORMAT, (PlatformInfo::Architecture)AVIAN_TARGET_ARCH)); Platform* platform = Platform::getPlatform(PlatformInfo((PlatformInfo::Format)AVIAN_TARGET_FORMAT, (PlatformInfo::Architecture)AVIAN_TARGET_ARCH));
// if(!platform) { if(!platform) {
// fprintf(stderr, "unsupported platform: %s/%s\n", os, architecture); fprintf(stderr, "unsupported platform: target-format = %d / target-arch = %d\n", AVIAN_TARGET_FORMAT, AVIAN_TARGET_ARCH);
// return false; abort();
// } }
SymbolInfo bootimageSymbols[] = { SymbolInfo bootimageSymbols[] = {
SymbolInfo(0, bootimageStart), SymbolInfo(0, bootimageStart),
@ -1768,7 +1780,7 @@ bool ArgParser::parse(int ac, const char** av) {
} }
bool found = false; bool found = false;
for(Arg* arg = first; arg; arg = arg->next) { for(Arg* arg = first; arg; arg = arg->next) {
if(strcmp(arg->name, &av[i][1]) == 0) { if(::strcmp(arg->name, &av[i][1]) == 0) {
found = true; found = true;
if (arg->desc == 0) { if (arg->desc == 0) {
arg->value = "true"; arg->value = "true";
@ -1905,20 +1917,26 @@ public:
exit(1); exit(1);
} }
# if AVIAN_TARGET_FORMAT != AVIAN_FORMAT_PE
# define SYMBOL_PREFIX "_"
# else
# define SYMBOL_PREFIX
# endif
if(!bootimageStart) { if(!bootimageStart) {
bootimageStart = strdup("_binary_bootimage_bin_start"); bootimageStart = strdup(SYMBOL_PREFIX"binary_bootimage_bin_start");
} }
if(!bootimageEnd) { if(!bootimageEnd) {
bootimageEnd = strdup("_binary_bootimage_bin_end"); bootimageEnd = strdup(SYMBOL_PREFIX"binary_bootimage_bin_end");
} }
if(!codeimageStart) { if(!codeimageStart) {
codeimageStart = strdup("_binary_codeimage_bin_start"); codeimageStart = strdup(SYMBOL_PREFIX"binary_codeimage_bin_start");
} }
if(!codeimageEnd) { if(!codeimageEnd) {
codeimageEnd = strdup("_binary_codeimage_bin_end"); codeimageEnd = strdup(SYMBOL_PREFIX"binary_codeimage_bin_end");
} }
} }

View File

@ -94,7 +94,13 @@ typedef int64_t intptr_t;
typedef uint64_t uintptr_t; typedef uint64_t uintptr_t;
# define UINT64_C(x) x##L # define UINT64_C(x) x##L
# define ARCH_x86_64 # define ARCH_x86_64
@ define BYTES_PER_WORD 8 # define BYTES_PER_WORD 8
# elif defined _M_ARM_FP
typedef int32_t intptr_t;
typedef uint32_t uintptr_t;
# define UINT64_C(x) x##LL
# define ARCH_arm
# define BYTES_PER_WORD 4
# else # else
# error "unsupported architecture" # error "unsupported architecture"
# endif # endif

View File

@ -18,7 +18,7 @@
using namespace vm; using namespace vm;
namespace { namespace local {
const unsigned FrameBaseOffset = 0; const unsigned FrameBaseOffset = 0;
const unsigned FrameNextOffset = 1; const unsigned FrameNextOffset = 1;
@ -2321,7 +2321,7 @@ interpret3(Thread* t, const int base)
object class_ = resolveClassInPool(t, frameMethod(t, frame), index - 1); object class_ = resolveClassInPool(t, frameMethod(t, frame), index - 1);
PROTECT(t, class_); PROTECT(t, class_);
int32_t counts[dimensions]; int32_t* counts = new int32_t[dimensions];
for (int i = dimensions - 1; i >= 0; --i) { for (int i = dimensions - 1; i >= 0; --i) {
counts[i] = popInt(t); counts[i] = popInt(t);
if (UNLIKELY(counts[i] < 0)) { if (UNLIKELY(counts[i] < 0)) {
@ -2338,6 +2338,9 @@ interpret3(Thread* t, const int base)
populateMultiArray(t, array, counts, 0, dimensions); populateMultiArray(t, array, counts, 0, dimensions);
pushObject(t, array); pushObject(t, array);
delete[] counts;
counts = 0;
} goto loop; } goto loop;
case new_: { case new_: {
@ -3100,7 +3103,7 @@ class MyProcessor: public Processor {
(&byteArrayBody(t, methodSpec(t, method), 0)); (&byteArrayBody(t, methodSpec(t, method), 0));
pushArguments(t, this_, spec, arguments); pushArguments(t, this_, spec, arguments);
return ::invoke(t, method); return local::invoke(t, method);
} }
virtual object virtual object
@ -3124,7 +3127,7 @@ class MyProcessor: public Processor {
(&byteArrayBody(t, methodSpec(t, method), 0)); (&byteArrayBody(t, methodSpec(t, method), 0));
pushArguments(t, this_, spec, arguments); pushArguments(t, this_, spec, arguments);
return ::invoke(t, method); return local::invoke(t, method);
} }
virtual object virtual object
@ -3148,7 +3151,7 @@ class MyProcessor: public Processor {
(&byteArrayBody(t, methodSpec(t, method), 0)); (&byteArrayBody(t, methodSpec(t, method), 0));
pushArguments(t, this_, spec, indirectObjects, arguments); pushArguments(t, this_, spec, indirectObjects, arguments);
return ::invoke(t, method); return local::invoke(t, method);
} }
virtual object virtual object
@ -3174,7 +3177,7 @@ class MyProcessor: public Processor {
assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0)); assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0));
return ::invoke(t, method); return local::invoke(t, method);
} }
virtual object getStackTrace(vm::Thread* t, vm::Thread*) { virtual object getStackTrace(vm::Thread* t, vm::Thread*) {
@ -3254,8 +3257,8 @@ namespace vm {
Processor* Processor*
makeProcessor(System* system, Allocator* allocator, bool) makeProcessor(System* system, Allocator* allocator, bool)
{ {
return new (allocator->allocate(sizeof(MyProcessor))) return new (allocator->allocate(sizeof(local::MyProcessor)))
MyProcessor(system, allocator); local::MyProcessor(system, allocator);
} }
} // namespace vm } // namespace vm

View File

@ -1325,6 +1325,9 @@ checkDaemon(Thread* t);
object& object&
root(Thread* t, Machine::Root root); root(Thread* t, Machine::Root root);
#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
# define vmRun vmRun_
#endif
extern "C" uint64_t extern "C" uint64_t
vmRun(uint64_t (*function)(Thread*, uintptr_t*), uintptr_t* arguments, vmRun(uint64_t (*function)(Thread*, uintptr_t*), uintptr_t* arguments,
void* checkpoint); void* checkpoint);

View File

@ -97,11 +97,13 @@ class System {
virtual void disposeAll() = 0; virtual void disposeAll() = 0;
}; };
#if defined(AVIAN_PROCESS_compile)
class SignalHandler { class SignalHandler {
public: public:
virtual bool handleSignal(void** ip, void** frame, void** stack, virtual bool handleSignal(void** ip, void** frame, void** stack,
void** thread) = 0; void** thread) = 0;
}; };
#endif
class MonitorResource { class MonitorResource {
public: public:
@ -121,17 +123,21 @@ class System {
virtual bool success(Status) = 0; virtual bool success(Status) = 0;
virtual void* tryAllocate(unsigned sizeInBytes) = 0; virtual void* tryAllocate(unsigned sizeInBytes) = 0;
virtual void free(const void* p) = 0; virtual void free(const void* p) = 0;
#if defined(AVIAN_PROCESS_compile)
virtual void* tryAllocateExecutable(unsigned sizeInBytes) = 0; virtual void* tryAllocateExecutable(unsigned sizeInBytes) = 0;
virtual void freeExecutable(const void* p, unsigned sizeInBytes) = 0; virtual void freeExecutable(const void* p, unsigned sizeInBytes) = 0;
#endif
virtual Status attach(Runnable*) = 0; virtual Status attach(Runnable*) = 0;
virtual Status start(Runnable*) = 0; virtual Status start(Runnable*) = 0;
virtual Status make(Mutex**) = 0; virtual Status make(Mutex**) = 0;
virtual Status make(Monitor**) = 0; virtual Status make(Monitor**) = 0;
virtual Status make(Local**) = 0; virtual Status make(Local**) = 0;
#if defined(AVIAN_PROCESS_compile)
virtual Status handleSegFault(SignalHandler* handler) = 0; virtual Status handleSegFault(SignalHandler* handler) = 0;
virtual Status handleDivideByZero(SignalHandler* handler) = 0; virtual Status handleDivideByZero(SignalHandler* handler) = 0;
virtual Status visit(Thread* thread, Thread* target, virtual Status visit(Thread* thread, Thread* target,
ThreadVisitor* visitor) = 0; ThreadVisitor* visitor) = 0;
#endif
virtual uint64_t call(void* function, uintptr_t* arguments, uint8_t* types, virtual uint64_t call(void* function, uintptr_t* arguments, uint8_t* types,
unsigned count, unsigned size, unsigned count, unsigned size,
unsigned returnType) = 0; unsigned returnType) = 0;

View File

@ -26,6 +26,71 @@
#include "arch.h" #include "arch.h"
#include "system.h" #include "system.h"
#if defined(WINAPI_FAMILY)
#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#define WaitForSingleObject(hHandle, dwMilliseconds) \
WaitForSingleObjectEx((hHandle), (dwMilliseconds), FALSE)
#define CreateEvent(lpEventAttributes, bManualReset, bInitialState, lpName) \
CreateEventEx((lpEventAttributes), (lpName), ((bManualReset)?CREATE_EVENT_MANUAL_RESET:0)|((bInitialState)?CREATE_EVENT_INITIAL_SET:0), EVENT_MODIFY_STATE)
#define CreateMutex(lpEventAttributes, bInitialOwner, lpName) \
CreateMutexEx((lpEventAttributes), (lpName), (bInitialOwner)?CREATE_MUTEX_INITIAL_OWNER:0, MUTEX_MODIFY_STATE)
#include "thread-emulation.h"
#endif
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE)
// Headers in Windows Phone 8 DevKit contain severe error, so let's define needed functions on our own
extern "C"
{
WINBASEAPI
_Ret_maybenull_
HANDLE
WINAPI
CreateFileMappingFromApp(
_In_ HANDLE hFile,
_In_opt_ PSECURITY_ATTRIBUTES SecurityAttributes,
_In_ ULONG PageProtection,
_In_ ULONG64 MaximumSize,
_In_opt_ PCWSTR Name
);
WINBASEAPI
_Ret_maybenull_ __out_data_source(FILE)
PVOID
WINAPI
MapViewOfFileFromApp(
_In_ HANDLE hFileMappingObject,
_In_ ULONG DesiredAccess,
_In_ ULONG64 FileOffset,
_In_ SIZE_T NumberOfBytesToMap
);
WINBASEAPI
BOOL
WINAPI
UnmapViewOfFile(
_In_ LPCVOID lpBaseAddress
);
}
#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE)
#else
#ifndef WINAPI_PARTITION_DESKTOP
#define WINAPI_PARTITION_DESKTOP 1
#endif
#ifndef WINAPI_FAMILY_PARTITION
#define WINAPI_FAMILY_PARTITION(x) (x)
#endif
#endif
#define ACQUIRE(s, x) MutexResource MAKE_NAME(mutexResource_) (s, x) #define ACQUIRE(s, x) MutexResource MAKE_NAME(mutexResource_) (s, x)
using namespace vm; using namespace vm;
@ -49,16 +114,20 @@ class MutexResource {
HANDLE m; HANDLE m;
}; };
#if defined(AVIAN_PROCESS_compile)
const unsigned SegFaultIndex = 0; const unsigned SegFaultIndex = 0;
const unsigned DivideByZeroIndex = 1; const unsigned DivideByZeroIndex = 1;
const unsigned HandlerCount = 2; const unsigned HandlerCount = 2;
#endif
class MySystem; class MySystem;
MySystem* system; MySystem* system;
#if defined(AVIAN_PROCESS_compile)
LONG CALLBACK LONG CALLBACK
handleException(LPEXCEPTION_POINTERS e); handleException(LPEXCEPTION_POINTERS e);
#endif
DWORD WINAPI DWORD WINAPI
run(void* r) run(void* r)
@ -559,18 +628,22 @@ class MySystem: public System {
}; };
MySystem(const char* crashDumpDirectory): MySystem(const char* crashDumpDirectory):
#if defined(AVIAN_PROCESS_compile)
oldHandler(0), oldHandler(0),
#endif
crashDumpDirectory(crashDumpDirectory) crashDumpDirectory(crashDumpDirectory)
{ {
expect(this, system == 0); expect(this, system == 0);
system = this; system = this;
#if defined(AVIAN_PROCESS_compile)
memset(handlers, 0, sizeof(handlers)); memset(handlers, 0, sizeof(handlers));
#endif
mutex = CreateMutex(0, false, 0); mutex = CreateMutex(0, false, 0);
assert(this, mutex); assert(this, mutex);
} }
#if defined(AVIAN_PROCESS_compile)
bool findHandler() { bool findHandler() {
for (unsigned i = 0; i < HandlerCount; ++i) { for (unsigned i = 0; i < HandlerCount; ++i) {
if (handlers[i]) return true; if (handlers[i]) return true;
@ -578,6 +651,7 @@ class MySystem: public System {
return false; return false;
} }
//TODO: http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.windows.application.unhandledexception(v=vs.105).aspx
int registerHandler(System::SignalHandler* handler, int index) { int registerHandler(System::SignalHandler* handler, int index) {
if (handler) { if (handler) {
handlers[index] = handler; handlers[index] = handler;
@ -609,7 +683,7 @@ class MySystem: public System {
return 1; return 1;
} }
} }
#endif
virtual void* tryAllocate(unsigned sizeInBytes) { virtual void* tryAllocate(unsigned sizeInBytes) {
return malloc(sizeInBytes); return malloc(sizeInBytes);
} }
@ -618,6 +692,7 @@ class MySystem: public System {
if (p) ::free(const_cast<void*>(p)); if (p) ::free(const_cast<void*>(p));
} }
#if defined(AVIAN_PROCESS_compile)
virtual void* tryAllocateExecutable(unsigned sizeInBytes) { virtual void* tryAllocateExecutable(unsigned sizeInBytes) {
return VirtualAlloc return VirtualAlloc
(0, sizeInBytes, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); (0, sizeInBytes, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
@ -627,6 +702,7 @@ class MySystem: public System {
int r UNUSED = VirtualFree(const_cast<void*>(p), 0, MEM_RELEASE); int r UNUSED = VirtualFree(const_cast<void*>(p), 0, MEM_RELEASE);
assert(this, r); assert(this, r);
} }
#endif
virtual bool success(Status s) { virtual bool success(Status s) {
return s == 0; return s == 0;
@ -666,6 +742,7 @@ class MySystem: public System {
return 0; return 0;
} }
#if defined(AVIAN_PROCESS_compile)
virtual Status handleSegFault(SignalHandler* handler) { virtual Status handleSegFault(SignalHandler* handler) {
return registerHandler(handler, SegFaultIndex); return registerHandler(handler, SegFaultIndex);
} }
@ -710,6 +787,7 @@ class MySystem: public System {
return (success ? 0 : 1); return (success ? 0 : 1);
} }
#endif
virtual uint64_t call(void* function, uintptr_t* arguments, uint8_t* types, virtual uint64_t call(void* function, uintptr_t* arguments, uint8_t* types,
unsigned count, unsigned size, unsigned returnType) unsigned count, unsigned size, unsigned returnType)
@ -719,15 +797,39 @@ class MySystem: public System {
virtual Status map(System::Region** region, const char* name) { virtual Status map(System::Region** region, const char* name) {
Status status = 1; Status status = 1;
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
HANDLE file = CreateFile(name, FILE_READ_DATA, FILE_SHARE_READ, 0, HANDLE file = CreateFile(name, FILE_READ_DATA, FILE_SHARE_READ, 0,
OPEN_EXISTING, 0, 0); OPEN_EXISTING, 0, 0);
#else
size_t nameLen = strlen(name);
wchar_t* wideName = new wchar_t[nameLen + 1];
size_t convertedChars = 0;
mbstowcs_s(&convertedChars, wideName, nameLen + 1, name, nameLen);
HANDLE file = CreateFile2(wideName, GENERIC_READ, FILE_SHARE_READ,
OPEN_EXISTING, 0);
delete[] wideName;
#endif
if (file != INVALID_HANDLE_VALUE) { if (file != INVALID_HANDLE_VALUE) {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
unsigned size = GetFileSize(file, 0); unsigned size = GetFileSize(file, 0);
#else
FILE_STANDARD_INFO info;
unsigned size = INVALID_FILE_SIZE;
if(GetFileInformationByHandleEx(file, FileStandardInfo, &info, sizeof(info)))
size = info.EndOfFile.QuadPart;
#endif
if (size != INVALID_FILE_SIZE) { if (size != INVALID_FILE_SIZE) {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
HANDLE mapping = CreateFileMapping(file, 0, PAGE_READONLY, 0, size, 0); HANDLE mapping = CreateFileMapping(file, 0, PAGE_READONLY, 0, size, 0);
#else
HANDLE mapping = CreateFileMappingFromApp(file, 0, PAGE_READONLY, size, 0);
#endif
if (mapping) { if (mapping) {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
void* data = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0); void* data = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);
#else
void* data = MapViewOfFileFromApp(mapping, FILE_MAP_READ, 0, 0);
#endif
if (data) { if (data) {
*region = new (allocate(this, sizeof(Region))) *region = new (allocate(this, sizeof(Region)))
Region(this, static_cast<uint8_t*>(data), size, file, mapping); Region(this, static_cast<uint8_t*>(data), size, file, mapping);
@ -757,7 +859,12 @@ class MySystem: public System {
memcpy(RUNTIME_ARRAY_BODY(buffer) + length, "\\*", 3); memcpy(RUNTIME_ARRAY_BODY(buffer) + length, "\\*", 3);
Directory* d = new (allocate(this, sizeof(Directory))) Directory(this); Directory* d = new (allocate(this, sizeof(Directory))) Directory(this);
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
d->handle = FindFirstFile(RUNTIME_ARRAY_BODY(buffer), &(d->data)); d->handle = FindFirstFile(RUNTIME_ARRAY_BODY(buffer), &(d->data));
#else
d->handle = FindFirstFileEx(RUNTIME_ARRAY_BODY(buffer), FindExInfoStandard, &(d->data), FindExSearchNameMatch, 0, 0);
#endif
if (d->handle == INVALID_HANDLE_VALUE) { if (d->handle == INVALID_HANDLE_VALUE) {
d->dispose(); d->dispose();
} else { } else {
@ -797,6 +904,7 @@ class MySystem: public System {
} }
virtual const char* toAbsolutePath(Allocator* allocator, const char* name) { virtual const char* toAbsolutePath(Allocator* allocator, const char* name) {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
if (strncmp(name, "//", 2) == 0 if (strncmp(name, "//", 2) == 0
or strncmp(name, "\\\\", 2) == 0 or strncmp(name, "\\\\", 2) == 0
or strncmp(name + 1, ":/", 2) == 0 or strncmp(name + 1, ":/", 2) == 0
@ -808,6 +916,11 @@ class MySystem: public System {
GetCurrentDirectory(MAX_PATH, buffer); GetCurrentDirectory(MAX_PATH, buffer);
return append(allocator, buffer, "\\", name); return append(allocator, buffer, "\\", name);
} }
#else
//TODO:http://lunarfrog.com/blog/2012/05/21/winrt-folders-access/
//Windows.ApplicationModel.Package.Current.InstalledLocation
return name;
#endif
} }
virtual Status load(System::Library** lib, virtual Status load(System::Library** lib,
@ -816,9 +929,23 @@ class MySystem: public System {
HMODULE handle; HMODULE handle;
unsigned nameLength = (name ? strlen(name) : 0); unsigned nameLength = (name ? strlen(name) : 0);
if (name) { if (name) {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
handle = LoadLibrary(name); handle = LoadLibrary(name);
#else
size_t nameLen = strlen(name);
wchar_t* wideName = new wchar_t[nameLen + 1];
size_t convertedChars = 0;
mbstowcs_s(&convertedChars, wideName, nameLen + 1, name, nameLen);
handle = LoadPackagedLibrary(wideName, 0);
delete[] wideName;
#endif
} else { } else {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
handle = GetModuleHandle(0); handle = GetModuleHandle(0);
#else
// Most of WinRT/WP8 applications can not host native object files inside main executable
assert(this, false);
#endif
} }
if (handle) { if (handle) {
@ -866,7 +993,11 @@ class MySystem: public System {
} }
virtual void yield() { virtual void yield() {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
SwitchToThread(); SwitchToThread();
#else
YieldProcessor();
#endif
} }
virtual void exit(int code) { virtual void exit(int code) {
@ -886,11 +1017,15 @@ class MySystem: public System {
} }
HANDLE mutex; HANDLE mutex;
#if defined(AVIAN_PROCESS_compile)
SignalHandler* handlers[HandlerCount]; SignalHandler* handlers[HandlerCount];
LPTOP_LEVEL_EXCEPTION_FILTER oldHandler; LPTOP_LEVEL_EXCEPTION_FILTER oldHandler;
#endif
const char* crashDumpDirectory; const char* crashDumpDirectory;
}; };
#if defined(AVIAN_PROCESS_compile)
#pragma pack(push,4) #pragma pack(push,4)
struct MINIDUMP_EXCEPTION_INFORMATION { struct MINIDUMP_EXCEPTION_INFORMATION {
DWORD thread; DWORD thread;
@ -1005,6 +1140,8 @@ handleException(LPEXCEPTION_POINTERS e)
return EXCEPTION_CONTINUE_SEARCH; return EXCEPTION_CONTINUE_SEARCH;
} }
#endif
} // namespace } // namespace
namespace vm { namespace vm {

166
src/x86.masm Normal file
View File

@ -0,0 +1,166 @@
comment #
Copyright (c) 2008-2011, 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.
#
.586
.MODEL FLAT, C
VOID_TYPE equ 0
INT8_TYPE equ 1
INT16_TYPE equ 2
INT32_TYPE equ 3
INT64_TYPE equ 4
FLOAT_TYPE equ 5
DOUBLE_TYPE equ 6
POINTER_TYPE equ 7
CHECKPOINT_THREAD equ 4
CHECKPOINT_STACK equ 24
CHECKPOINT_BASE equ 28
_TEXT SEGMENT
public C detectFeature
detectFeature:
push ebp
mov ebp,esp
push edx
push ecx
push ebx
push esi
push edi
mov esi,ds:dword ptr[12+ebp]
mov edi,ds:dword ptr[8+ebp]
mov eax,1
cpuid
and edx,esi
and ecx,edi
or ecx,edx
test ecx,ecx
je LNOSSE
mov eax,1
jmp LSSEEND
LNOSSE:
mov eax,0
LSSEEND:
pop edi
pop esi
pop ebx
pop ecx
pop edx
mov esp,ebp
pop ebp
ret
public C vmNativeCall
vmNativeCall:
push ebp
mov ebp,esp
mov ecx,ds:dword ptr[16+ebp]
sub esp,ecx
mov ecx,0
jmp Ltest
Lloop:
mov eax,ecx
mov edx,ecx
add edx,esp
add eax,ds:dword ptr[12+ebp]
mov eax,ds:dword ptr[eax]
mov ds:dword ptr[edx],eax
add ecx,4
Ltest:
cmp ecx,ds:dword ptr[16+ebp]
jb Lloop
call dword ptr[8+ebp]
mov ecx,ds:dword ptr[20+ebp]
Lvoid:
cmp ecx,offset VOID_TYPE
jne Lint64
jmp Lexit
Lint64:
cmp ecx,offset INT64_TYPE
jne Lfloat
jmp Lexit
Lfloat:
cmp ecx,offset FLOAT_TYPE
jne Ldouble
fstp ds:dword ptr[8+ebp]
mov eax,ds:dword ptr[8+ebp]
jmp Lexit
Ldouble:
cmp ecx,offset DOUBLE_TYPE
jne Lexit
fstp ds:dword ptr[8+ebp]
mov eax,ds:dword ptr[8+ebp]
mov edx,ds:dword ptr[12+ebp]
Lexit:
mov esp,ebp
pop ebp
ret
public C vmJump
vmJump:
mov esi,ds:dword ptr[4+esp]
mov ebp,ds:dword ptr[8+esp]
mov ebx,ds:dword ptr[16+esp]
mov eax,ds:dword ptr[20+esp]
mov edx,ds:dword ptr[24+esp]
mov esp,ds:dword ptr[12+esp]
jmp esi
VMRUN_FRAME_SIZE equ 24
public C vmRun_
vmRun_:
; 8(%ebp): function
; 12(%ebp): arguments
; 16(%ebp): checkpoint
push ebp
mov ebp,esp
sub esp,offset VMRUN_FRAME_SIZE
mov ds:dword ptr[8+esp],ebx
mov ds:dword ptr[12+esp],esi
mov ds:dword ptr[16+esp],edi
mov eax,ds:dword ptr[12+ebp]
mov ds:dword ptr[4+esp],eax
mov ecx,ds:dword ptr[16+ebp]
mov eax,ds:dword ptr[CHECKPOINT_THREAD+ecx]
mov ds:dword ptr[0+esp],eax
mov ds:dword ptr[CHECKPOINT_STACK+ecx],esp
call dword ptr[8+ebp]
public C vmRun_returnAddress
vmRun_returnAddress:
mov ebx,ds:dword ptr[8+esp]
mov esi,ds:dword ptr[12+esp]
mov edi,ds:dword ptr[16+esp]
add esp,offset VMRUN_FRAME_SIZE
pop ebp
ret
_TEXT ENDS
END