Merge remote branch 'osmandapp/upstream'

This commit is contained in:
Joel Dice 2013-02-12 09:26:01 -07:00
commit 8a7b6488d4
26 changed files with 1931 additions and 368 deletions

1
.gitignore vendored
View File

@ -7,3 +7,4 @@ build
bin
/lib
/distrib
*.pdb

View File

@ -55,6 +55,15 @@
typedef wchar_t char_t;
#if defined(WINAPI_FAMILY)
#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#include "avian-interop.h"
#define SKIP_OPERATOR_NEW
#endif
#endif
#else // not PLATFORM_WINDOWS
# include <dirent.h>
@ -83,7 +92,19 @@ typedef char char_t;
#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
#if !defined(SKIP_OPERATOR_NEW)
inline void* operator new(size_t, void* p) throw() { return p; }
#endif
typedef const char_t* string_t;
@ -155,69 +176,9 @@ doWrite(JNIEnv* e, jint fd, const jbyte* data, jint length)
}
}
#ifdef PLATFORM_WINDOWS
class Mapping {
public:
Mapping(uint8_t* start, size_t length, HANDLE mapping, HANDLE file):
start(start),
length(length),
mapping(mapping),
file(file)
{ }
uint8_t* start;
size_t length;
HANDLE mapping;
HANDLE file;
};
inline Mapping*
map(JNIEnv* e, string_t path)
{
Mapping* result = 0;
HANDLE file = CreateFileW(path, FILE_READ_DATA,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
OPEN_EXISTING, 0, 0);
if (file != INVALID_HANDLE_VALUE) {
unsigned size = GetFileSize(file, 0);
if (size != INVALID_FILE_SIZE) {
HANDLE mapping = CreateFileMapping(file, 0, PAGE_READONLY, 0, size, 0);
if (mapping) {
void* data = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);
if (data) {
void* p = allocate(e, sizeof(Mapping));
if (not e->ExceptionCheck()) {
result = new (p)
Mapping(static_cast<uint8_t*>(data), size, file, mapping);
}
}
if (result == 0) {
CloseHandle(mapping);
}
}
}
if (result == 0) {
CloseHandle(file);
}
}
if (result == 0 and not e->ExceptionCheck()) {
throwNew(e, "java/io/IOException", "%d", GetLastError());
}
return result;
}
inline void
unmap(JNIEnv*, Mapping* mapping)
{
UnmapViewOfFile(mapping->start);
CloseHandle(mapping->mapping);
CloseHandle(mapping->file);
free(mapping);
}
class Directory {
public:
Directory(): handle(0), findNext(false) { }
@ -250,51 +211,9 @@ class Directory {
#else // not PLATFORM_WINDOWS
class Mapping {
public:
Mapping(uint8_t* start, size_t length):
start(start),
length(length)
{ }
uint8_t* start;
size_t length;
};
inline Mapping*
map(JNIEnv* e, string_t path)
{
Mapping* result = 0;
int fd = open(path, O_RDONLY);
if (fd != -1) {
struct stat s;
int r = fstat(fd, &s);
if (r != -1) {
void* data = mmap(0, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (data) {
void* p = allocate(e, sizeof(Mapping));
if (not e->ExceptionCheck()) {
result = new (p) Mapping(static_cast<uint8_t*>(data), s.st_size);
}
}
}
close(fd);
}
if (result == 0 and not e->ExceptionCheck()) {
throwNewErrno(e, "java/io/IOException");
}
return result;
}
inline void
unmap(JNIEnv*, Mapping* mapping)
{
munmap(mapping->start, mapping->length);
free(mapping);
}
#endif // not PLATFORM_WINDOWS
} // namespace
inline string_t getChars(JNIEnv* e, jstring path) {
@ -316,6 +235,7 @@ extern "C" JNIEXPORT jstring JNICALL
Java_java_io_File_toAbsolutePath(JNIEnv* e UNUSED, jclass, jstring path)
{
#ifdef PLATFORM_WINDOWS
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
string_t chars = getChars(e, path);
if (chars) {
const unsigned BufferSize = MAX_PATH;
@ -330,6 +250,19 @@ Java_java_io_File_toAbsolutePath(JNIEnv* e UNUSED, jclass, jstring path)
}
return path;
# else
string_t chars = getChars(e, path);
if(chars) {
std::wstring partialPath = chars;
releaseChars(e, path, chars);
std::wstring fullPath = AvianInterop::GetFullPath(partialPath);
return e->NewString
(reinterpret_cast<const jchar*>(fullPath.c_str()), fullPath.length());
}
return path;
# endif
#else
jstring result = path;
string_t chars = getChars(e, path);
@ -353,20 +286,41 @@ Java_java_io_File_toAbsolutePath(JNIEnv* e UNUSED, jclass, jstring path)
extern "C" JNIEXPORT jlong JNICALL
Java_java_io_File_length(JNIEnv* e, jclass, jstring path)
{
#ifdef PLATFORM_WINDOWS
LARGE_INTEGER fileSize;
// Option: without opening file
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa364946(v=vs.85).aspx
string_t chars = getChars(e, path);
HANDLE file = CreateFileW
(chars, FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
releaseChars(e, path, chars);
if (file != INVALID_HANDLE_VALUE)
GetFileSizeEx(file, &fileSize);
else return 0;
CloseHandle(file);
return static_cast<jlong>(fileSize.QuadPart);
if(chars) {
LARGE_INTEGER fileSize;
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
HANDLE file = CreateFileW
(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);
if (file == INVALID_HANDLE_VALUE)
return 0;
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
if(!GetFileSizeEx(file, &fileSize))
{
CloseHandle(file);
return 0;
}
#else
FILE_STANDARD_INFO info;
if(!GetFileInformationByHandleEx(file, FileStandardInfo, &info, sizeof(info)))
{
CloseHandle(file);
return 0;
}
fileSize = info.EndOfFile;
#endif
CloseHandle(file);
return static_cast<jlong>(fileSize.QuadPart);
}
#else
string_t chars = getChars(e, path);
@ -598,7 +552,11 @@ Java_java_io_File_openDir(JNIEnv* e, jclass, jstring path)
releaseChars(e, path, chars);
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));
#else
d->handle = FindFirstFileExW(RUNTIME_ARRAY_BODY(buffer), FindExInfoStandard, &(d->data), FindExSearchNameMatch, NULL, 0);
#endif
if (d->handle == INVALID_HANDLE_VALUE) {
d->dispose();
d = 0;
@ -610,6 +568,62 @@ Java_java_io_File_openDir(JNIEnv* e, jclass, jstring path)
}
}
extern "C" JNIEXPORT jlong JNICALL
Java_java_io_File_lastModified(JNIEnv* e, jclass, jstring path)
{
string_t chars = getChars(e, path);
if (chars) {
#ifdef PLATFORM_WINDOWS
// Option: without opening file
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa364946(v=vs.85).aspx
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
HANDLE hFile = CreateFileW
(chars, FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
#else
HANDLE hFile = CreateFile2
(chars, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr);
#endif
releaseChars(e, path, chars);
if (hFile == INVALID_HANDLE_VALUE)
return 0;
LARGE_INTEGER fileDate, filetimeToUnixEpochAdjustment;
filetimeToUnixEpochAdjustment.QuadPart = 11644473600000L * 10000L;
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
FILETIME fileLastWriteTime;
if (!GetFileTime(hFile, 0, 0, &fileLastWriteTime))
{
CloseHandle(hFile);
return 0;
}
fileDate.HighPart = fileLastWriteTime.dwHighDateTime;
fileDate.LowPart = fileLastWriteTime.dwLowDateTime;
#else
FILE_BASIC_INFO fileInfo;
if (!GetFileInformationByHandleEx(hFile, FileBasicInfo, &fileInfo, sizeof(fileInfo)))
{
CloseHandle(hFile);
return 0;
}
fileDate = fileInfo.ChangeTime;
#endif
CloseHandle(hFile);
fileDate.QuadPart -= filetimeToUnixEpochAdjustment.QuadPart;
return fileDate.QuadPart / 10000000L;
#else
struct stat fileStat;
if (stat(chars, &fileStat) == -1) {
releaseChars(e, path, chars);
return 0;
}
return (static_cast<jlong>(st.st_mtim.tv_sec) * 1000) +
(static_cast<jlong>(st.st_mtim.tv_nsec) / (1000*1000));
#endif
}
return 0;
}
extern "C" JNIEXPORT jstring JNICALL
Java_java_io_File_readDir(JNIEnv* e, jclass, jlong handle)
{
@ -759,13 +773,13 @@ Java_java_io_FileOutputStream_write__I_3BII
(JNIEnv* e, jclass, jint fd, jbyteArray b, jint offset, jint length)
{
jbyte* data = static_cast<jbyte*>(malloc(length));
if (data == 0) {
throwNew(e, "java/lang/OutOfMemoryError", 0);
return;
}
e->GetByteArrayRegion(b, offset, length, data);
if (not e->ExceptionCheck()) {
doWrite(e, fd, data, length);
}
@ -785,35 +799,104 @@ Java_java_io_RandomAccessFile_open(JNIEnv* e, jclass, jstring path,
{
string_t chars = getChars(e, path);
if (chars) {
Mapping* mapping = map(e, chars);
jlong peer = 0;
jlong length = 0;
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#if defined(PLATFORM_WINDOWS)
int fd = ::_wopen(chars, O_RDONLY);
#else
int fd = ::open((const char*)chars, O_RDONLY);
#endif
releaseChars(e, path, chars);
if (fd == -1) {
throwNewErrno(e, "java/io/IOException");
return;
}
struct ::stat fileStats;
if(::fstat(fd, &fileStats) == -1) {
::close(fd);
throwNewErrno(e, "java/io/IOException");
return;
}
peer = fd;
length = fileStats.st_size;
#else
HANDLE hFile = CreateFile2
(chars, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr);
if (hFile == INVALID_HANDLE_VALUE) {
throwNewErrno(e, "java/io/IOException");
return;
}
FILE_STANDARD_INFO info;
if(!GetFileInformationByHandleEx(hFile, FileStandardInfo, &info, sizeof(info))) {
CloseHandle(hFile);
throwNewErrno(e, "java/io/IOException");
return;
}
peer = (jlong)hFile;
length = info.EndOfFile.QuadPart;
#endif
jlong peer = reinterpret_cast<jlong>(mapping);
e->SetLongArrayRegion(result, 0, 1, &peer);
jlong length = (mapping ? mapping->length : 0);
e->SetLongArrayRegion(result, 1, 1, &length);
releaseChars(e, path, chars);
}
}
extern "C" JNIEXPORT void JNICALL
Java_java_io_RandomAccessFile_copy(JNIEnv* e, jclass, jlong peer,
extern "C" JNIEXPORT jint JNICALL
Java_java_io_RandomAccessFile_readBytes(JNIEnv* e, jclass, jlong peer,
jlong position, jbyteArray buffer,
int offset, int length)
{
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
int fd = (int)peer;
if(::lseek(fd, position, SEEK_SET) == -1) {
throwNewErrno(e, "java/io/IOException");
return -1;
}
uint8_t* dst = reinterpret_cast<uint8_t*>
(e->GetPrimitiveArrayCritical(buffer, 0));
memcpy(dst + offset,
reinterpret_cast<Mapping*>(peer)->start + position,
length);
ssize_t bytesRead = ::read(fd, dst + offset, length);
e->ReleasePrimitiveArrayCritical(buffer, dst, 0);
if(bytesRead == -1) {
throwNewErrno(e, "java/io/IOException");
return -1;
}
#else
HANDLE hFile = (HANDLE)peer;
LARGE_INTEGER lPos;
lPos.QuadPart = position;
if(!SetFilePointerEx(hFile, lPos, nullptr, FILE_BEGIN)) {
throwNewErrno(e, "java/io/IOException");
return -1;
}
uint8_t* dst = reinterpret_cast<uint8_t*>
(e->GetPrimitiveArrayCritical(buffer, 0));
DWORD bytesRead = 0;
if(!ReadFile(hFile, dst + offset, length, &bytesRead, nullptr)) {
throwNewErrno(e, "java/io/IOException");
return -1;
}
e->ReleasePrimitiveArrayCritical(buffer, dst, 0);
#endif
return (jint)bytesRead;
}
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)
{
unmap(e, reinterpret_cast<Mapping*>(peer));
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
int fd = (int)peer;
::close(fd);
#else
HANDLE hFile = (HANDLE)peer;
CloseHandle(hFile);
#endif
}

View File

@ -54,33 +54,64 @@
# include "signal.h"
# include "sys/time.h"
# include "sys/types.h"
# ifndef __ANDROID__
# include "sys/sysctl.h"
# endif
# include "sys/utsname.h"
# include "sys/wait.h"
#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
#else
# if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
# include "avian-interop.h"
# endif
#endif // WINAPI_FAMILY
namespace {
#ifdef PLATFORM_WINDOWS
char* getErrorStr(DWORD err){
// The poor man's error string, just print the error code
char * errStr = (char*) malloc(9 * sizeof(char));
snprintf(errStr, 9, "%d", (int) err);
return errStr;
// The better way to do this, if I could figure out how to convert LPTSTR to char*
//char* errStr;
//LPTSTR s;
//if(FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
// FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, 0, &s, 0, NULL) == 0)
//{
// errStr.Format("Unknown error occurred (%08x)", err);
//} else {
// errStr = s;
//}
//return errStr;
}
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
char* getErrorStr(DWORD err) {
LPSTR errorStr = 0;
if(!FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, err, LANG_SYSTEM_DEFAULT, (LPSTR)&errorStr, 0, 0))
{
char* errStr = (char*) malloc(9 * sizeof(char));
snprintf(errStr, 9, "%d", (int) err);
return errStr;
}
char* errStr = strdup(errorStr);
LocalFree(errorStr);
return errStr;
}
#else
char* getErrorStr(DWORD err) {
LPSTR errorStr = (LPSTR)malloc(4096); //NOTE: something constant
if(!FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, err, LANG_SYSTEM_DEFAULT, errorStr, 0, 0))
{
free(errorStr);
char* errStr = (char*) malloc(9 * sizeof(char));
snprintf(errStr, 9, "%d", (int) err);
return errStr;
}
char* errStr = strdup(errorStr);
free(errorStr);
return errStr;
}
#endif
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
void makePipe(JNIEnv* e, HANDLE p[2])
{
SECURITY_ATTRIBUTES sa;
@ -93,6 +124,7 @@ namespace {
throwNew(e, "java/io/IOException", getErrorStr(GetLastError()));
}
}
#endif
int descriptor(JNIEnv* e, HANDLE h)
{
@ -194,7 +226,7 @@ extern "C" JNIEXPORT void JNICALL
Java_java_lang_Runtime_exec(JNIEnv* e, jclass,
jobjectArray command, jlongArray process)
{
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
int size = 0;
for (int i = 0; i < e->GetArrayLength(command); ++i){
jstring element = (jstring) e->GetObjectArrayElement(command, i);
@ -265,11 +297,15 @@ Java_java_lang_Runtime_exec(JNIEnv* e, jclass,
e->SetLongArrayRegion(process, 0, 1, &pid);
jlong tid = reinterpret_cast<jlong>(pi.hThread);
e->SetLongArrayRegion(process, 1, 1, &tid);
#else
throwNew(e, "java/io/Exception", strdup("Not supported on WinRT/WinPhone8"));
#endif
}
extern "C" JNIEXPORT jint JNICALL
Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid, jlong tid)
{
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
DWORD exitCode;
WaitForSingleObject(reinterpret_cast<HANDLE>(pid), INFINITE);
BOOL success = GetExitCodeProcess(reinterpret_cast<HANDLE>(pid), &exitCode);
@ -281,14 +317,23 @@ Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid, jlong tid)
CloseHandle(reinterpret_cast<HANDLE>(tid));
return exitCode;
#else
throwNew(e, "java/io/Exception", strdup("Not supported on WinRT/WinPhone8"));
return -1;
#endif
}
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);
#else
throwNew(e, "java/io/Exception", strdup("Not supported on WinRT/WinPhone8"));
#endif
}
Locale getLocale() {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
const char* lang = "";
const char* reg = "";
unsigned langid = GetUserDefaultUILanguage();
@ -360,8 +405,23 @@ Locale getLocale() {
default: lang = "en";
}
return Locale(lang, reg);
#else
std::wstring culture = AvianInterop::GetCurrentUICulture();
char* cultureName = strdup(std::string(culture.begin(), culture.end()).c_str());
char* delimiter = strchr(cultureName, '-');
if(!delimiter)
{
free(cultureName);
return Locale("en", "US");
}
const char* lang = cultureName;
const char* reg = delimiter + 1;
*delimiter = 0;
Locale locale(lang, reg);
free(cultureName);
return locale;
#endif
}
#else
extern "C" JNIEXPORT void JNICALL
@ -529,8 +589,15 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
} else if (strcmp(chars, "file.separator") == 0) {
r = e->NewStringUTF("\\");
} else if (strcmp(chars, "os.name") == 0) {
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
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) {
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
unsigned size = 32;
RUNTIME_ARRAY(char, buffer, size);
OSVERSIONINFO OSversion;
@ -538,6 +605,10 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
::GetVersionEx(&OSversion);
snprintf(RUNTIME_ARRAY_BODY(buffer), size, "%i.%i", (int)OSversion.dwMajorVersion, (int)OSversion.dwMinorVersion);
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) {
#ifdef ARCH_x86_32
r = e->NewStringUTF("x86");
@ -549,15 +620,26 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
r = e->NewStringUTF("arm");
#endif
} else if (strcmp(chars, "java.io.tmpdir") == 0) {
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
TCHAR buffer[MAX_PATH];
GetTempPath(MAX_PATH, buffer);
r = e->NewStringUTF(buffer);
# else
std::wstring tmpDir = AvianInterop::GetTemporaryFolder();
r = e->NewString((const jchar*)tmpDir.c_str(), tmpDir.length());
# endif
} else if (strcmp(chars, "user.dir") == 0) {
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
TCHAR buffer[MAX_PATH];
GetCurrentDirectory(MAX_PATH, buffer);
r = e->NewStringUTF(buffer);
# else
std::wstring userDir = AvianInterop::GetInstalledLocation();
r = e->NewString((const jchar*)userDir.c_str(), userDir.length());
# endif
} else if (strcmp(chars, "user.home") == 0) {
# ifdef _MSC_VER
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WCHAR buffer[MAX_PATH];
size_t needed;
if (_wgetenv_s(&needed, buffer, MAX_PATH, L"USERPROFILE") == 0) {
@ -565,6 +647,10 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
} else {
r = 0;
}
# else
std::wstring userHome = AvianInterop::GetDocumentsLibraryLocation();
r = e->NewString((const jchar*)userHome.c_str(), userHome.length());
# endif
# else
LPWSTR home = _wgetenv(L"USERPROFILE");
r = e->NewString(reinterpret_cast<jchar*>(home), lstrlenW(home));
@ -652,6 +738,9 @@ namespace {
#elif defined __APPLE__
# include <crt_externs.h>
# 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
extern char** environ;
#endif
@ -785,6 +874,54 @@ Java_java_lang_Math_cos(JNIEnv*, jclass, jdouble val)
return cos(val);
}
extern "C" JNIEXPORT jdouble JNICALL
Java_java_lang_Math_tan(JNIEnv*, jclass, jdouble val)
{
return tan(val);
}
extern "C" JNIEXPORT jdouble JNICALL
Java_java_lang_Math_asin(JNIEnv*, jclass, jdouble val)
{
return asin(val);
}
extern "C" JNIEXPORT jdouble JNICALL
Java_java_lang_Math_acos(JNIEnv*, jclass, jdouble val)
{
return acos(val);
}
extern "C" JNIEXPORT jdouble JNICALL
Java_java_lang_Math_atan(JNIEnv*, jclass, jdouble val)
{
return atan(val);
}
extern "C" JNIEXPORT jdouble JNICALL
Java_java_lang_Math_atan2(JNIEnv*, jclass, jdouble y, jdouble x)
{
return atan2(y, x);
}
extern "C" JNIEXPORT jdouble JNICALL
Java_java_lang_Math_sinh(JNIEnv*, jclass, jdouble val)
{
return sinh(val);
}
extern "C" JNIEXPORT jdouble JNICALL
Java_java_lang_Math_cosh(JNIEnv*, jclass, jdouble val)
{
return cosh(val);
}
extern "C" JNIEXPORT jdouble JNICALL
Java_java_lang_Math_tanh(JNIEnv*, jclass, jdouble val)
{
return tanh(val);
}
extern "C" JNIEXPORT jdouble JNICALL
Java_java_lang_Math_sqrt(JNIEnv*, jclass, jdouble val)
{
@ -797,6 +934,12 @@ Java_java_lang_Math_pow(JNIEnv*, jclass, jdouble val, jdouble exp)
return pow(val, exp);
}
extern "C" JNIEXPORT jdouble JNICALL
Java_java_lang_Math_log(JNIEnv*, jclass, jdouble val)
{
return log(val);
}
extern "C" JNIEXPORT jdouble JNICALL
Java_java_lang_Math_floor(JNIEnv*, jclass, jdouble val)
{

View File

@ -294,12 +294,19 @@ public class File implements Serializable {
}
}
public long lastModified() {
return lastModified(path);
}
private static native long openDir(String path);
private static native long lastModified(String path);
private static native String readDir(long handle);
private static native long closeDir(long handle);
private static class Pair {
public final String value;
public final Pair next;

View File

@ -10,6 +10,8 @@
package java.io;
import java.lang.IllegalArgumentException;
public class RandomAccessFile {
private long peer;
private File file;
@ -56,26 +58,68 @@ public class RandomAccessFile {
this.position = position;
}
public void readFully(byte[] buffer, int offset, int length)
throws IOException
{
if (peer == 0) throw new IOException();
if (length == 0) return;
if (position + length > this.length) {
if (position + length > length()) throw new EOFException();
}
if (offset < 0 || offset + length > buffer.length)
public int skipBytes(int count) throws IOException {
if (position + count > length()) throw new IOException();
this.position = position + count;
return count;
}
public int read(byte b[], int off, int len) throws IOException {
if(b == null)
throw new IllegalArgumentException();
if (peer == 0)
throw new IOException();
if(len == 0)
return 0;
if (position + len > this.length)
throw new EOFException();
if (off < 0 || off + len > b.length)
throw new ArrayIndexOutOfBoundsException();
copy(peer, position, buffer, offset, length);
position += length;
int bytesRead = readBytes(peer, position, b, off, len);
position += bytesRead;
return bytesRead;
}
public int read(byte b[]) throws IOException {
if(b == null)
throw new IllegalArgumentException();
if (peer == 0)
throw new IOException();
if(b.length == 0)
return 0;
if (position + b.length > this.length)
throw new EOFException();
int bytesRead = readBytes(peer, position, b, 0, b.length);
position += bytesRead;
return bytesRead;
}
private static native void copy(long peer, long position, byte[] buffer,
public void readFully(byte b[], int off, int len) throws IOException {
if(b == null)
throw new IllegalArgumentException();
if (peer == 0)
throw new IOException();
if(len == 0)
return;
if (position + len > this.length)
throw new EOFException();
if (off < 0 || off + len > b.length)
throw new ArrayIndexOutOfBoundsException();
int n = 0;
do {
int count = readBytes(peer, position, b, off + n, len - n);
position += count;
if (count == 0)
throw new EOFException();
n += count;
} while (n < len);
}
public void readFully(byte b[]) throws IOException {
readFully(b, 0, b.length);
}
private static native int readBytes(long peer, long position, byte[] buffer,
int offset, int length);
public void close() throws IOException {

View File

@ -93,6 +93,12 @@ public final class Math {
public static native double tan(double v);
public static native double cosh(double v);
public static native double sinh(double v);
public static native double tanh(double v);
public static native double acos(double v);
public static native double asin(double v);

546
makefile
View File

@ -50,8 +50,10 @@ ifeq ($(continuations),true)
options := $(options)-continuations
endif
aot-only = false
root := $(shell (cd .. && pwd))
build = build/$(platform)-$(arch)$(options)
host-build-root = $(build)/host
classpath-build = $(build)/classpath
test-build = $(build)/test
src = src
@ -59,6 +61,8 @@ classpath-src = classpath
test = test
win32 ?= $(root)/win32
win64 ?= $(root)/win64
winrt ?= $(root)/winrt
wp8 ?= $(root)/wp8
classpath = avian
@ -133,7 +137,7 @@ ifneq ($(openjdk),)
javahome = "$$($(native-path) "$(openjdk)/jre")"
endif
classpath = openjdk
classpath = openjdk
boot-classpath := "$(boot-classpath)$(path-separator)$$($(native-path) "$(openjdk)/jre/lib/rt.jar")"
build-javahome = $(openjdk)/jre
endif
@ -183,6 +187,18 @@ strip-all = --strip-all
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
# use the delete operator, which means we don't need virtual
# destructors:
@ -198,7 +214,7 @@ common-cflags = $(warnings) -fno-rtti -fno-exceptions -I$(classpath-src) \
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \
-DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" $(target-cflags)
asmflags = $(target-cflags)
asmflags = $(target-cflags) -I$(src)
ifneq (,$(filter i386 x86_64,$(arch)))
ifeq ($(use-frame-pointer),true)
@ -237,6 +253,18 @@ pointer-size = 8
so-prefix = lib
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
rpath = -Wl,-rpath=\$$ORIGIN
@ -246,6 +274,8 @@ no-error = -Wno-error
openjdk-extra-cflags = -fvisibility=hidden
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; \
else echo /Applications/Xcode.app/Contents/Developer; fi)
@ -355,6 +385,70 @@ ifeq ($(platform),freebsd)
"-I$(JAVA_HOME)/include/freebsd" -I$(src) -pthread
cflags = $(build-cflags)
endif
ifeq ($(platform),android)
ifeq ($(build-platform),cygwin)
ndk = "$$(cygpath -u "$(ANDROID_NDK)")"
else
ndk = $(ANDROID_NDK)
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-lflags = -lz -lpthread
ifeq ($(subst cygwin,windows,$(subst mingw32,windows,$(build-platform))),windows)
toolchain-host-platform = $(subst cygwin,windows,$(subst mingw32,windows,$(build-platform)))
build-system = windows
build-cxx = i686-w64-mingw32-g++
build-cc = i686-w64-mingw32-gcc
sysroot = "$$(cygpath -w "$(ndk)/platforms/android-$(android-version)/arch-arm")"
build-cflags += "-I$(JAVA_HOME)/include/win32"
else
toolchain-host-platform = $(subst cygwin,windows,$(subst mingw32,windows,$(build-platform)))-*
sysroot = $(ndk)/platforms/android-$(android-version)/arch-arm
build-cflags += "-I$(JAVA_HOME)/include/linux"
build-lflags += -ldl
endif
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 $(no-psabi)
lflags = "-L$(sysroot)/usr/lib" $(common-lflags) -llog
target-format = elf
use-lto = false
ifeq ($(arch),arm)
cflags += -marm -march=$(android-arm-arch) -ftree-vectorize -ffast-math -mfloat-abi=softfp
endif
ifeq ($(arch),i386)
endif
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
ifeq ($(platform),darwin)
target-format = macho
@ -441,13 +535,14 @@ ifeq ($(platform),darwin)
endif
ifeq ($(platform),windows)
target-format = pe
ifeq ($(target-format),)
target-format = pe
endif
inc = "$(win32)/include"
lib = "$(win32)/lib"
embed-prefix = c:/avian-embedded
system = windows
so-prefix =
@ -455,7 +550,8 @@ ifeq ($(platform),windows)
exe-suffix = .exe
rpath =
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
ifeq (,$(filter mingw32 cygwin,$(build-platform)))
@ -501,89 +597,217 @@ ifeq ($(platform),windows)
shared += -Wl,--add-stdcall-alias
endif
embed = $(build-embed)/embed.exe
embed-loader = $(build-embed-loader)/embed-loader.exe
embed = $(build-embed)/embed$(exe-suffix)
embed-loader = $(build-embed-loader)/embed-loader$(exe-suffix)
embed-loader-o = $(build-embed)/embed-loader.o
endif
ifeq ($(mode),debug)
optimization-cflags = -O0 -g3
converter-cflags += -O0 -g3
strip = :
endif
ifeq ($(mode),debug-fast)
optimization-cflags = -O0 -g3 -DNDEBUG
strip = :
endif
ifeq ($(mode),stress)
optimization-cflags = -O0 -g3 -DVM_STRESS
strip = :
endif
ifeq ($(mode),stress-major)
optimization-cflags = -O0 -g3 -DVM_STRESS -DVM_STRESS_MAJOR
strip = :
endif
ifeq ($(mode),fast)
ifeq ($(use-clang),true)
optimization-cflags = -O4 -g3 -DNDEBUG
ifeq ($(platform),wp8)
ifeq ($(shell uname -s | grep -i -c WOW64),1)
programFiles = Program Files (x86)
else
optimization-cflags = -O3 -g3 -DNDEBUG
programFiles = Program Files
endif
use-lto = true
endif
ifeq ($(mode),small)
ifeq ($(use-clang),true)
optimization-cflags = -Oz -g3 -DNDEBUG
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 = $(MSVS_ROOT)\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
optimization-cflags = -Os -g3 -DNDEBUG
windows-path = $(native-path)
endif
use-lto = true
endif
windows-java-home := $(shell $(windows-path) "$(JAVA_HOME)")
target-format = pe
ms_cl_compiler = wp8
use-lto = false
supports_avian_executable = false
aot-only = true
ifneq ($(bootimage),true)
x := $(error Windows Phone 8 target requires bootimage=true)
endif
system = windows
build-system = windows
static-prefix =
static-suffix = .lib
so-prefix =
so-suffix = .dll
exe-suffix = .exe
manifest-flags = -MANIFEST:NO
ifeq ($(use-lto),true)
ifeq ($(use-clang),true)
optimization-cflags += -flto
lflags += $(optimization-cflags)
else
# only try to use LTO when GCC 4.6.0 or greater is available
gcc-major := $(shell $(cc) -dumpversion | cut -f1 -d.)
gcc-minor := $(shell $(cc) -dumpversion | cut -f2 -d.)
ifeq ($(shell expr 4 \< $(gcc-major) \
\| \( 4 \<= $(gcc-major) \& 6 \<= $(gcc-minor) \)),1)
optimization-cflags += -flto
no-lto = -fno-lto
lflags += $(optimization-cflags)
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
asmflags = $(target-cflags) -safeseh -nologo -Gd
as = "$$(cygpath -u "$(WP80_SDK)\bin\ml.exe")"
cxx = "$$(cygpath -u "$(WP80_SDK)\bin\cl.exe")"
ld = "$$(cygpath -u "$(WP80_SDK)\bin\link.exe")"
ifeq ($(mode),debug)
asmflags += -Zd
endif
ifeq ($(mode),debug-fast)
asmflags += -Zd
endif
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 \
-AI"$(WP80_KIT)\Windows Metadata" \
-I"$(WP80_SDK)\include" -I"$(WP80_KIT)\Include" -I"$(WP80_KIT)\Include\minwin" -I"$(WP80_KIT)\Include\mincore" \
-DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP -D_USRDLL -D_WINDLL \
-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")" -I"$(shell $(windows-path) "$(wp8)/interop/avian-interop-client")" \
-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) \
-Gd -EHsc
common-lflags = $(classpath-lflags)
ifeq ($(mode),debug)
build-type = Debug
endif
ifeq ($(mode),debug-fast)
build-type = Debug
endif
ifeq ($(mode),stress_major)
build-type = Release
endif
ifeq ($(mode),fast)
build-type = Release
endif
ifeq ($(mode),fast)
build-type = Release
endif
ifeq ($(mode),small)
build-type = Release
endif
arflags = -MACHINE:$(machine_type)
lflags = $(common-lflags) -nologo \
-MACHINE:$(machine_type) \
-LIBPATH:"$(WP80_KIT)\lib\$(w8kit_arch)" -LIBPATH:"$(WP80_SDK)\lib$(vc_arch)" -LIBPATH:"$(WIN8_KIT)\Lib\win8\um\$(w8kit_arch)" \
ws2_32.lib \
"$(shell $(windows-path) "$(wp8)\lib\$(deps_arch)\$(build-type)\zlib.lib")" "$(shell $(windows-path) "$(wp8)\lib\$(deps_arch)\$(build-type)\ThreadEmulation.lib")" \
"$(shell $(windows-path) "$(wp8)\lib\$(deps_arch)\$(build-type)\AvianInteropClient.lib")"
lflags += -NXCOMPAT -DYNAMICBASE -SUBSYSTEM:CONSOLE -TLBID:1
lflags += -NODEFAULTLIB:"ole32.lib" -NODEFAULTLIB:"kernel32.lib"
lflags += PhoneAppModelHost.lib WindowsPhoneCore.lib -WINMD -WINMDFILE:$(subst $(so-suffix),.winmd,$(@))
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)
#TODO: -MT or -ZW?
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
cflags += $(optimization-cflags)
ifneq ($(platform),darwin)
ifeq ($(arch),i386)
# this is necessary to support __sync_bool_compare_and_swap:
cflags += -march=i586
lflags += -march=i586
endif
endif
output = -o $(1)
as := $(cc)
ld := $(cc)
build-ld := $(build-cc)
static = -static
ifdef msvc
static =
no-error =
windows-path = $(native-path)
windows-java-home := $(shell $(windows-path) "$(JAVA_HOME)")
zlib := $(shell $(windows-path) "$(win32)/msvc")
ms_cl_compiler = regular
cxx = "$(msvc)/BIN/cl.exe"
cc = $(cxx)
ld = "$(msvc)/BIN/link.exe"
mt = "mt.exe"
manifest-flags = -MANIFEST -MANIFESTFILE:$(@).manifest
cflags = -nologo -DAVIAN_VERSION=\"$(version)\" -D_JNI_IMPLEMENTATION_ \
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \
-DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" \
@ -592,7 +816,7 @@ ifdef msvc
-I"$(windows-java-home)/include" -I"$(windows-java-home)/include/win32" \
-DTARGET_BYTES_PER_WORD=$(pointer-size)
ifneq ($(lzma),)
ifneq ($(lzma),)
cflags += -I$(shell $(windows-path) "$(lzma)")
endif
@ -619,9 +843,70 @@ ifdef msvc
strip = :
endif
ifeq ($(mode),debug)
optimization-cflags = $(cflags_debug)
converter-cflags += $(cflags_debug)
strip = :
endif
ifeq ($(mode),debug-fast)
optimization-cflags = $(cflags_debug_fast) -DNDEBUG
strip = :
endif
ifeq ($(mode),stress)
optimization-cflags = $(cflags_stress) -DVM_STRESS
strip = :
endif
ifeq ($(mode),stress-major)
optimization-cflags = $(cflags_stress_major) -DVM_STRESS -DVM_STRESS_MAJOR
strip = :
endif
ifeq ($(mode),fast)
optimization-cflags = $(cflags_fast) -DNDEBUG
ifeq ($(use-lto),)
use-lto = true
endif
endif
ifeq ($(mode),small)
optimization-cflags = $(cflags_small) -DNDEBUG
ifeq ($(use-lto),)
use-lto = true
endif
endif
ifeq ($(use-lto),true)
ifeq ($(use-clang),true)
optimization-cflags += -flto
lflags += $(optimization-cflags)
else
# only try to use LTO when GCC 4.6.0 or greater is available
gcc-major := $(shell $(cc) -dumpversion | cut -f1 -d.)
gcc-minor := $(shell $(cc) -dumpversion | cut -f2 -d.)
ifeq ($(shell expr 4 \< $(gcc-major) \
\| \( 4 \<= $(gcc-major) \& 6 \<= $(gcc-minor) \)),1)
optimization-cflags += -flto
no-lto = -fno-lto
lflags += $(optimization-cflags)
endif
endif
endif
cflags += $(optimization-cflags)
ifndef ms_cl_compiler
ifneq ($(platform),darwin)
ifeq ($(arch),i386)
# this is necessary to support __sync_bool_compare_and_swap:
cflags += -march=i586
lflags += -march=i586
endif
endif
endif
build-cflags += -DAVIAN_HOST_TARGET
c-objects = $(foreach x,$(1),$(patsubst $(2)/%.c,$(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)))
generated-code = \
@ -647,7 +932,7 @@ vm-sources = \
$(src)/jnienv.cpp \
$(src)/process.cpp
vm-asm-sources = $(src)/$(asm).S
vm-asm-sources = $(src)/$(asm).$(asm-format)
target-asm = $(asm)
@ -665,7 +950,11 @@ ifeq ($(process),compile)
$(src)/compiler.cpp \
$(src)/$(target-asm).cpp
vm-asm-sources += $(src)/compile-$(asm).S
vm-asm-sources += $(src)/compile-$(asm).$(asm-format)
endif
cflags += -DAVIAN_PROCESS_$(process)
ifeq ($(aot-only),true)
cflags += -DAVIAN_AOT_ONLY
endif
vm-cpp-objects = $(call cpp-objects,$(vm-sources),$(src),$(build))
@ -798,10 +1087,10 @@ converter-objects = $(call cpp-objects,$(converter-sources),$(src),$(build))
converter-tool-objects = $(call cpp-objects,$(converter-tool-sources),$(src),$(build))
converter = $(build)/binaryToObject/binaryToObject
static-library = $(build)/lib$(name).a
static-library = $(build)/$(static-prefix)$(name)$(static-suffix)
executable = $(build)/$(name)${exe-suffix}
dynamic-library = $(build)/$(so-prefix)jvm$(so-suffix)
executable-dynamic = $(build)/$(name)-dynamic${exe-suffix}
executable-dynamic = $(build)/$(name)-dynamic$(exe-suffix)
ifneq ($(classpath),avian)
# Assembler, ConstantPool, and Stream are not technically needed for a
@ -908,9 +1197,15 @@ test-flags = -Djava.library.path=$(build) -cp $(build)/test
test-args = $(test-flags) $(input)
.PHONY: build
ifneq ($(supports_avian_executable),false)
build: $(static-library) $(executable) $(dynamic-library) $(lzma-loader) \
$(lzma-encoder) $(executable-dynamic) $(classpath-dep) $(test-dep) \
$(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)
@ -952,10 +1247,17 @@ javadoc:
.PHONY: clean
clean:
@echo "removing $(build)"
rm -rf $(build)
.PHONY: clean-all
clean-all:
@echo "removing build"
rm -rf build
$(build)/compile-x86-asm.o: $(src)/continuations-x86.S
ifeq ($(continuations),true)
$(build)/compile-x86-asm.o: $(src)/continuations-x86.$(asm-format)
endif
gen-arg = $(shell echo $(1) | sed -e 's:$(build)/type-\(.*\)\.cpp:\1:')
$(generated-code): %.cpp: $(src)/types.def $(generator) $(classpath-dep)
@ -1006,7 +1308,7 @@ endef
define compile-asm-object
@echo "compiling $(@)"
@mkdir -p $(dir $(@))
$(as) -I$(src) $(asmflags) -c $(<) -o $(@)
$(as) $(asmflags) $(call asm-output,$(@)) $(call asm-input,$(<))
endef
$(vm-cpp-objects): $(build)/%.o: $(src)/%.cpp $(vm-depends)
@ -1017,10 +1319,13 @@ $(test-cpp-objects): $(test-build)/%.o: $(test)/%.cpp $(vm-depends)
$(test-library): $(test-cpp-objects)
@echo "linking $(@)"
ifdef msvc
$(ld) $(shared) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb \
-IMPLIB:$(test-build)/$(name).lib -MANIFESTFILE:$(@).manifest
$(mt) -manifest $(@).manifest -outputresource:"$(@);2"
ifdef ms_cl_compiler
$(ld) $(shared) $(lflags) $(^) -out:$(@) \
-debug -PDB:$(subst $(so-suffix),.pdb,$(@)) \
-IMPLIB:$(test-build)/$(name).lib $(manifest-flags)
ifdef mt
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);2"
endif
else
$(ld) $(^) $(shared) $(lflags) -o $(@)
endif
@ -1028,10 +1333,12 @@ endif
ifdef embed
$(embed): $(embed-objects) $(embed-loader-o)
@echo "building $(embed)"
ifdef msvc
$(ld) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb \
-IMPLIB:$(@).lib -MANIFESTFILE:$(@).manifest
$(mt) -manifest $(@).manifest -outputresource:"$(@);1"
ifdef ms_cl_compiler
$(ld) $(lflags) $(^) -out:$(@) \
-debug -PDB:$(subst $(exe-suffix),.pdb,$(@)) $(manifest-flags)
ifdef mt
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);1"
endif
else
$(cxx) $(^) $(lflags) $(static) $(call output,$(@))
endif
@ -1049,10 +1356,12 @@ $(embed-loader-o): $(embed-loader) $(converter)
$(embed-loader): $(embed-loader-objects) $(static-library)
@mkdir -p $(dir $(@))
cd $(dir $(@)) && $(ar) x ../../../$(static-library)
ifdef msvc
$(ld) $(lflags) $(dir $(@))/*.o -out:$(@) -PDB:$(@).pdb \
-IMPLIB:$(@).lib -MANIFESTFILE:$(@).manifest
$(mt) -manifest $(@).manifest -outputresource:"$(@);1"
ifdef ms_cl_compiler
$(ld) $(lflags) $(dir $(@))/*.o -out:$(@) \
-debug -PDB:$(subst $(exe-suffix),.pdb,$(@)) $(manifest-flags)
ifdef mt
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);1"
endif
else
$(dlltool) -z $(addsuffix .def,$(basename $(@))) $(dir $(@))/*.o
$(dlltool) -d $(addsuffix .def,$(basename $(@))) -e $(addsuffix .exp,$(basename $(@)))
@ -1072,7 +1381,7 @@ $(build)/%.o: $(lzma)/C/%.c
@mkdir -p $(dir $(@))
$(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)
$(bootimage-generator-objects): $(build)/%.o: $(src)/%.cpp $(vm-depends)
@ -1159,14 +1468,18 @@ $(static-library): $(vm-objects) $(classpath-objects) $(vm-heapwalk-objects) \
$(javahome-object) $(boot-javahome-object) $(lzma-decode-objects)
@echo "creating $(@)"
rm -rf $(@)
ifdef ms_cl_compiler
$(ar) $(arflags) $(^) -out:$(@)
else
$(ar) cru $(@) $(^)
$(ranlib) $(@)
endif
$(bootimage-object) $(codeimage-object): $(bootimage-generator) \
$(build)/classpath.jar
$(bootimage-object) $(codeimage-object): $(bootimage-generator)
@echo "generating bootimage and codeimage binaries from $(classpath-build) using $(<)"
$(<) -cp $(classpath-build) -bootimage $(bootimage-object) -codeimage $(codeimage-object) \
-bootimage-symbols _binary_bootimage_bin_start:_binary_bootimage_bin_end \
-codeimage-symbols _binary_codeimage_bin_start:_binary_codeimage_bin_end
-bootimage-symbols $(bootimage-symbols) \
-codeimage-symbols $(codeimage-symbols)
executable-objects = $(vm-objects) $(classpath-objects) $(driver-object) \
$(vm-heapwalk-objects) $(boot-object) $(vm-classpath-objects) \
@ -1175,10 +1488,12 @@ executable-objects = $(vm-objects) $(classpath-objects) $(driver-object) \
$(executable): $(executable-objects)
@echo "linking $(@)"
ifeq ($(platform),windows)
ifdef msvc
$(ld) $(lflags) $(executable-objects) -out:$(@) -PDB:$(@).pdb \
-IMPLIB:$(@).lib -MANIFESTFILE:$(@).manifest
$(mt) -manifest $(@).manifest -outputresource:"$(@);1"
ifdef ms_cl_compiler
$(ld) $(lflags) $(executable-objects) -out:$(@) \
-debug -PDB:$(subst $(exe-suffix),.pdb,$(@)) $(manifest-flags)
ifdef mt
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);1"
endif
else
$(dlltool) -z $(@).def $(executable-objects)
$(dlltool) -d $(@).def -e $(@).exp
@ -1190,9 +1505,11 @@ endif
$(strip) $(strip-all) $(@)
$(bootimage-generator): $(bootimage-generator-objects)
echo arch=$(arch) platform=$(platform)
echo building $(bootimage-generator) arch=$(build-arch) platform=$(bootimage-platform)
$(MAKE) mode=$(mode) \
build=$(host-build-root) \
arch=$(build-arch) \
aot-only=false \
target-arch=$(arch) \
platform=$(bootimage-platform) \
target-format=$(target-format) \
@ -1210,17 +1527,19 @@ $(build-bootimage-generator): \
$(lzma-decode-objects) $(lzma-encode-objects)
@echo "linking $(@)"
ifeq ($(platform),windows)
ifdef msvc
$(ld) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb -IMPLIB:$(@).lib \
-MANIFESTFILE:$(@).manifest
$(mt) -manifest $(@).manifest -outputresource:"$(@);1"
ifdef ms_cl_compiler
$(ld) $(bootimage-generator-lflags) $(lflags) $(^) -out:$(@) \
-debug -PDB:$(subst $(exe-suffix),.pdb,$(@)) $(manifest-flags)
ifdef mt
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);1"
endif
else
$(dlltool) -z $(@).def $(^)
$(dlltool) -d $(@).def -e $(@).exp
$(ld) $(@).exp $(^) $(lflags) -o $(@)
$(ld) $(@).exp $(^) $(bootimage-generator-lflags) $(lflags) -o $(@)
endif
else
$(ld) $(^) $(rdynamic) $(lflags) -o $(@)
$(ld) $(^) $(rdynamic) $(bootimage-generator-lflags) $(lflags) -o $(@)
endif
$(dynamic-library): $(vm-objects) $(dynamic-object) $(classpath-objects) \
@ -1228,10 +1547,13 @@ $(dynamic-library): $(vm-objects) $(dynamic-object) $(classpath-objects) \
$(classpath-libraries) $(javahome-object) $(boot-javahome-object) \
$(lzma-decode-objects)
@echo "linking $(@)"
ifdef msvc
$(ld) $(shared) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb \
-IMPLIB:$(build)/$(name).lib -MANIFESTFILE:$(@).manifest
$(mt) -manifest $(@).manifest -outputresource:"$(@);2"
ifdef ms_cl_compiler
$(ld) $(shared) $(lflags) $(^) -out:$(@) \
-debug -PDB:$(subst $(so-suffix),.pdb,$(@)) \
-IMPLIB:$(subst $(so-suffix),.lib,$(@)) $(manifest-flags)
ifdef mt
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);2"
endif
else
$(ld) $(^) $(version-script-flag) $(soname-flag) \
$(shared) $(lflags) $(bootimage-lflags) \
@ -1243,11 +1565,13 @@ endif
# Ubuntu 11.10 which may be fixable without disabling LTO.
$(executable-dynamic): $(driver-dynamic-objects) $(dynamic-library)
@echo "linking $(@)"
ifdef msvc
ifdef ms_cl_compiler
$(ld) $(lflags) -LIBPATH:$(build) -DEFAULTLIB:$(name) \
-PDB:$(@).pdb -IMPLIB:$(@).lib $(driver-dynamic-objects) -out:$(@) \
-MANIFESTFILE:$(@).manifest
$(mt) -manifest $(@).manifest -outputresource:"$(@);1"
-debug -PDB:$(subst $(exe-suffix),.pdb,$(@))
$(driver-dynamic-objects) -out:$(@) $(manifest-flags)
ifdef mt
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);1"
endif
else
$(ld) $(driver-dynamic-objects) -L$(build) -ljvm $(lflags) $(no-lto) $(rpath) -z origin -o $(@)
endif

View File

@ -18,7 +18,7 @@
using namespace vm;
namespace {
namespace local {
namespace isa {
// SYSTEM REGISTERS
@ -252,7 +252,7 @@ class MyBlock: public Assembler::Block {
this->start = start;
this->next = static_cast<MyBlock*>(next);
::resolve(this);
local::resolve(this);
return start + size + padding(this, size);
}
@ -2150,7 +2150,7 @@ class MyArchitecture: public Assembler::Architecture {
}
virtual unsigned argumentFootprint(unsigned footprint) {
return ::argumentFootprint(footprint);
return local::argumentFootprint(footprint);
}
virtual bool argumentAlignment() {
@ -2239,7 +2239,7 @@ class MyArchitecture: public Assembler::Architecture {
unsigned targetParameterFootprint, void** ip,
void** stack)
{
::nextFrame(&con, static_cast<uint32_t*>(start), size, footprint, link,
local::nextFrame(&con, static_cast<uint32_t*>(start), size, footprint, link,
mostRecent, targetParameterFootprint, ip, stack);
}
@ -2550,11 +2550,12 @@ class MyAssembler: public Assembler {
}
virtual void pushFrame(unsigned argumentCount, ...) {
struct {
struct Argument {
unsigned size;
OperandType type;
Operand* operand;
} arguments[argumentCount];
};
RUNTIME_ARRAY(Argument, arguments, argumentCount);
va_list a; va_start(a, argumentCount);
unsigned footprint = 0;
@ -2798,7 +2799,7 @@ class MyAssembler: public Assembler {
bool jump = needJump(b);
if (jump) {
write4
(dst + dstOffset, ::b((poolSize + TargetBytesPerWord - 8) >> 2));
(dst + dstOffset, isa::b((poolSize + TargetBytesPerWord - 8) >> 2));
}
dstOffset += poolSize + (jump ? TargetBytesPerWord : 0);
@ -2832,7 +2833,7 @@ class MyAssembler: public Assembler {
}
virtual Promise* offset(bool forTrace) {
return ::offset(&con, forTrace);
return local::offset(&con, forTrace);
}
virtual Block* endBlock(bool startNew) {
@ -2903,15 +2904,15 @@ namespace vm {
Assembler::Architecture*
makeArchitecture(System* system, bool)
{
return new (allocate(system, sizeof(MyArchitecture))) MyArchitecture(system);
return new (allocate(system, sizeof(local::MyArchitecture))) local::MyArchitecture(system);
}
Assembler*
makeAssembler(System* system, Allocator* allocator, Zone* zone,
Assembler::Architecture* architecture)
{
return new(zone) MyAssembler(system, allocator, zone,
static_cast<MyArchitecture*>(architecture));
return new(zone) local::MyAssembler(system, allocator, zone,
static_cast<local::MyArchitecture*>(architecture));
}
} // namespace vm

View File

@ -71,33 +71,57 @@ namespace vm {
inline void
trap()
{
#ifdef _MSC_VER
__debugbreak();
#else
asm("bkpt");
#endif
}
#ifndef _MSC_VER
inline void
memoryBarrier()
{
asm("nop");
}
#endif
inline void
storeStoreMemoryBarrier()
{
#ifdef _MSC_VER
_ReadWriteBarrier();
#else
memoryBarrier();
#endif
}
inline void
storeLoadMemoryBarrier()
{
#ifdef _MSC_VER
MemoryBarrier();
#else
memoryBarrier();
#endif
}
inline void
loadMemoryBarrier()
{
#ifdef _MSC_VER
_ReadWriteBarrier();
#else
memoryBarrier();
#endif
}
#if !defined(AVIAN_AOT_ONLY)
#if defined(__ANDROID__)
// http://code.google.com/p/android/issues/detail?id=1803
extern "C" void __clear_cache (void *beg __attribute__((__unused__)), void *end __attribute__((__unused__)));
#endif
inline void
syncInstructionCache(const void* start, unsigned size)
{
@ -112,6 +136,8 @@ syncInstructionCache(const void* start, unsigned size)
#endif
}
#endif // AVIAN_AOT_ONLY
#ifndef __APPLE__
typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr);
# define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0)
@ -156,7 +182,7 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
unsigned vfpIndex = 0;
unsigned vfpBackfillIndex UNUSED = 0;
uintptr_t stack[(argumentCount * 8) / BytesPerWord]; // is > argumentSize to account for padding
RUNTIME_ARRAY(uintptr_t, stack, (argumentCount * 8) / BytesPerWord); // is > argumentSize to account for padding
unsigned stackIndex = 0;
unsigned ai = 0;

89
src/arm.masm Normal file
View File

@ -0,0 +1,89 @@
; 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.
;
; ORIGIN: https://github.com/gkvas/avian/tree/wince
AREA text, CODE, ARM
EXPORT vmNativeCall
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
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
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
vmRun_returnAddress
add sp, sp, #12
ldmfd sp!, {r4-r11, lr}
bx lr
EXPORT vmTrap
vmTrap
bkpt 3
END

View File

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

View File

@ -342,7 +342,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
unsigned count = s.read2() - 1;
if (count) {
Type types[count + 2];
RUNTIME_ARRAY(Type, types, count + 2);
types[0] = Type_object;
types[1] = Type_intptr_t;
@ -420,7 +420,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
object fields = allFields(t, typeMaps, c, &count, &array);
PROTECT(t, fields);
Field memberFields[count + 1];
RUNTIME_ARRAY(Field, memberFields, count + 1);
unsigned memberIndex;
unsigned buildMemberOffset;
@ -444,7 +444,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
++ memberIndex;
}
} else {
init(new (memberFields) Field, Type_object, 0, BytesPerWord, 0,
init(new (&memberFields[0]) Field, Type_object, 0, BytesPerWord, 0,
TargetBytesPerWord);
memberIndex = 1;
@ -454,15 +454,15 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
const unsigned StaticHeader = 3;
Field staticFields[count + StaticHeader];
RUNTIME_ARRAY(Field, staticFields, count + StaticHeader);
init(new (staticFields) Field, Type_object, 0, BytesPerWord, 0,
init(new (&staticFields[0]) Field, Type_object, 0, BytesPerWord, 0,
TargetBytesPerWord);
init(new (staticFields + 1) Field, Type_intptr_t, BytesPerWord,
init(new (&staticFields[1]) Field, Type_intptr_t, BytesPerWord,
BytesPerWord, TargetBytesPerWord, TargetBytesPerWord);
init(new (staticFields + 2) Field, Type_object, BytesPerWord * 2,
init(new (&staticFields[2]) Field, Type_object, BytesPerWord * 2,
BytesPerWord, TargetBytesPerWord * 2, TargetBytesPerWord);
unsigned staticIndex = StaticHeader;
@ -512,7 +512,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
buildStaticOffset = fieldOffset(t, field);
init(new (staticFields + staticIndex) Field, type,
init(new (&staticFields[staticIndex]) Field, type,
buildStaticOffset, buildSize, targetStaticOffset,
targetSize);
@ -526,7 +526,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
buildMemberOffset = fieldOffset(t, field);
init(new (memberFields + memberIndex) Field, type,
init(new (&memberFields[memberIndex]) Field, type,
buildMemberOffset, buildSize, targetMemberOffset,
targetSize);
@ -549,7 +549,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
ceiling(targetMemberOffset, TargetBytesPerWord), memberIndex);
for (unsigned i = 0; i < memberIndex; ++i) {
Field* f = memberFields + i;
Field* f = &memberFields[i];
expect(t, f->buildOffset
< map->buildFixedSizeInWords * BytesPerWord);
@ -573,7 +573,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
TypeMap::SingletonKind);
for (unsigned i = 0; i < staticIndex; ++i) {
Field* f = staticFields + i;
Field* f = &staticFields[i];
expect(t, f->buildOffset
< map->buildFixedSizeInWords * BytesPerWord);
@ -1334,9 +1334,9 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
}
++ count;
Field fields[count];
RUNTIME_ARRAY(Field, fields, count);
init(new (fields) Field, Type_object, 0, BytesPerWord, 0,
init(new (&fields[0]) Field, Type_object, 0, BytesPerWord, 0,
TargetBytesPerWord);
unsigned buildOffset = BytesPerWord;
@ -1414,7 +1414,7 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
++ targetOffset;
}
init(new (fields + j) Field, type, buildOffset, buildSize,
init(new (&fields[j]) Field, type, buildOffset, buildSize,
targetOffset, targetSize);
buildOffset += buildSize;
@ -1449,7 +1449,7 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
targetArrayElementSize, arrayElementType);
for (unsigned j = 0; j < fixedFieldCount; ++j) {
Field* f = fields + j;
Field* f = &fields[j];
expect(t, f->buildOffset
< map->buildFixedSizeInWords * BytesPerWord);
@ -1646,10 +1646,10 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
Platform* platform = Platform::getPlatform(PlatformInfo((PlatformInfo::Format)AVIAN_TARGET_FORMAT, (PlatformInfo::Architecture)AVIAN_TARGET_ARCH));
// if(!platform) {
// fprintf(stderr, "unsupported platform: %s/%s\n", os, architecture);
// return false;
// }
if(!platform) {
fprintf(stderr, "unsupported platform: target-format = %d / target-arch = %d\n", AVIAN_TARGET_FORMAT, AVIAN_TARGET_ARCH);
abort();
}
SymbolInfo bootimageSymbols[] = {
SymbolInfo(0, bootimageStart),
@ -1768,7 +1768,7 @@ bool ArgParser::parse(int ac, const char** av) {
}
bool found = false;
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;
if (arg->desc == 0) {
arg->value = "true";

View File

@ -94,7 +94,13 @@ typedef int64_t intptr_t;
typedef uint64_t uintptr_t;
# define UINT64_C(x) x##L
# 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
# error "unsupported architecture"
# endif
@ -214,6 +220,9 @@ typedef intptr_t __attribute__((__may_alias__)) intptr_alias_t;
type name; \
} MAKE_NAME(resource_)(name);
#ifdef _MSC_VER
# pragma warning( disable : 4291 )
#endif
inline void* operator new(size_t, void* p) throw() { return p; }
namespace vm {
@ -237,6 +246,10 @@ class RuntimeArray {
free(body);
}
T& operator[] (const unsigned index) {
return body[index];
}
T* body;
};

252
src/compile-arm.masm Normal file
View File

@ -0,0 +1,252 @@
; 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.
;
; ORIGIN: https://github.com/gkvas/avian/tree/wince
; types.inc
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
; target-fields.inc
;TARGET_BYTES_PER_WORD = 4
TARGET_THREAD_EXCEPTION equ 44
TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT equ 2164
TARGET_THREAD_EXCEPTIONOFFSET equ 2168
TARGET_THREAD_EXCEPTIONHANDLER equ 2172
TARGET_THREAD_IP equ 2144
TARGET_THREAD_STACK equ 2148
TARGET_THREAD_NEWSTACK equ 2152
TARGET_THREAD_SCRATCH equ 2156
TARGET_THREAD_CONTINUATION equ 2160
TARGET_THREAD_TAILADDRESS equ 2176
TARGET_THREAD_VIRTUALCALLTARGET equ 2180
TARGET_THREAD_VIRTUALCALLINDEX equ 2184
TARGET_THREAD_HEAPIMAGE equ 2188
TARGET_THREAD_CODEIMAGE equ 2192
TARGET_THREAD_THUNKTABLE equ 2196
TARGET_THREAD_STACKLIMIT equ 2220
AREA text, CODE, ARM
BYTES_PER_WORD equ 4
CONTINUATION_NEXT equ 4
CONTINUATION_ADDRESS equ 16
CONTINUATION_RETURN_ADDRESS_OFFSET equ 20
CONTINUATION_FRAME_POINTER_OFFSET equ 24
CONTINUATION_LENGTH equ 28
CONTINUATION_BODY equ 32
EXPORT vmInvoke
vmInvoke
; arguments
; r0 : thread
; r1 : function
; r2 : arguments
; r3 : argumentFootprint
; [sp, #0] : frameSize (not used)
; [sp, #4] : returnType
; save all non-volatile registers
stmfd sp!, {r4-r11, lr}
; save return type
ldr r4, [sp, #4]
str r4, [sp, #-4]!
str sp, [r0, #TARGET_THREAD_SCRATCH]
; align stack, if necessary
eor r4, sp, r3
tst r4, #4
subne sp, sp, #4
; copy arguments into place
sub sp, sp, r3
mov r4, #0
b vmInvoke_argumentTest
vmInvoke_argumentLoop
ldr r5, [r2, r4]
str r5, [sp, r4]
add r4, r4, #BYTES_PER_WORD
vmInvoke_argumentTest
cmp r4, r3
blt vmInvoke_argumentLoop
; we use r8 to hold the thread pointer, by convention
mov r8, r0
; load and call function address
blx r1
EXPORT vmInvoke_returnAddress
vmInvoke_returnAddress
; restore stack pointer
ldr sp, [r8, #TARGET_THREAD_SCRATCH]
; clear MyThread::stack to avoid confusing another thread calling
; java.lang.Thread.getStackTrace on this one. See
; MyProcess::getStackTrace in compile.cpp for details on how we get
; a reliable stack trace from a thread that might be interrupted at
; any point in its execution.
mov r5, #0
str r5, [r8, #TARGET_THREAD_STACK]
EXPORT vmInvoke_safeStack
vmInvoke_safeStack
;if AVIAN_CONTINUATIONS
; ; call the next continuation, if any
; ldr r5,[r8,#TARGET_THREAD_CONTINUATION]
; cmp r5,#0
; beq vmInvoke_exit)
;
; ldr r6,[r5,#CONTINUATION_LENGTH]
; lsl r6,r6,#2
; neg r7,r6
; add r7,r7,#-80
; mov r4,sp
; str r4,[sp,r7]!
;
; add r7,r5,#CONTINUATION_BODY
;
; mov r11,#0
; b vmInvoke_continuationTest
;
;vmInvoke_continuationLoop
; ldr r9,[r7,r11]
; str r9,[sp,r11]
; add r11,r11,#4
;
;vmInvoke_continuationTest
; cmp r11,r6
; ble vmInvoke_continuationLoop)
;
; ldr r7,[r5,#CONTINUATION_RETURN_ADDRESS_OFFSET]
; ldr r10,vmInvoke_returnAddress_word
; ldr r11,vmInvoke_getAddress_word
;vmInvoke_getAddress
; add r11,pc,r11
; ldr r11,[r11,r10]
; str r11,[sp,r7]
;
; ldr r7,[r5,#CONTINUATION_NEXT]
; str r7,[r8,#TARGET_THREAD_CONTINUATION]
;
; ; call the continuation unless we're handling an exception
; ldr r7,[r8,#TARGET_THREAD_EXCEPTION]
; cmp r7,#0
; bne vmInvoke_handleException)
; ldr r7,[r5,#CONTINUATION_ADDRESS]
; bx r7
;
;vmInvoke_handleException
; ; we're handling an exception - call the exception handler instead
; mov r11,#0
; str r11,[r8,#TARGET_THREAD_EXCEPTION]
; ldr r11,[r8,#TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT]
; ldr r9,[sp]
; neg r11,r11
; str r9,[sp,r11]!
; ldr r11,[r8,#TARGET_THREAD_EXCEPTIONOFFSET]
; str r7,[sp,r11]
;
; ldr r7,[r8,#TARGET_THREAD_EXCEPTIONHANDLER]
; bx r7
;
;vmInvoke_exit
;endif ; AVIAN_CONTINUATIONS
mov ip, #0
str ip, [r8, #TARGET_THREAD_STACK]
; restore return type
ldr ip, [sp], #4
; restore callee-saved registers
ldmfd sp!, {r4-r11, lr}
vmInvoke_return
bx lr
EXPORT vmJumpAndInvoke
vmJumpAndInvoke
;if :DEF:AVIAN_CONTINUATIONS
; ; r0: thread
; ; r1: address
; ; r2: stack
; ; r3: argumentFootprint
; ; [sp,#0]: arguments
; ; [sp,#4]: frameSize
;
; ldr r5,[sp,#0]
; ldr r6,[sp,#4]
;
; ; allocate new frame, adding room for callee-saved registers, plus
; ; 4 bytes of padding since the calculation of frameSize assumes 4
; ; bytes have already been allocated to save the return address,
; ; which is not true in this case
; sub r2,r2,r6
; sub r2,r2,#84
;
; mov r8,r0
;
; ; copy arguments into place
; mov r6,#0
; b vmJumpAndInvoke_argumentTest
;
;vmJumpAndInvoke_argumentLoop
; ldr r12,[r5,r6]
; str r12,[r2,r6]
; add r6,r6,#4
;
;vmJumpAndInvoke_argumentTest
; cmp r6,r3
; ble vmJumpAndInvoke_argumentLoop
;
; ; the arguments have been copied, so we can set the real stack
; ; pointer now
; mov sp,r2
;
; ; set return address to vmInvoke_returnAddress
; ldr r10,vmInvoke_returnAddress_word)
; ldr r11,vmJumpAndInvoke_getAddress_word)
;vmJumpAndInvoke_getAddress
; add r11,pc,r11
; ldr lr,[r11,r10]
;
; bx r1
;
;vmInvoke_returnAddress_word
; .word GLOBAL(vmInvoke_returnAddress)(GOT)
;vmInvoke_getAddress_word
; .word _GLOBAL_OFFSET_TABLE_-(vmInvoke_getAddress)+8)
;vmJumpAndInvoke_getAddress_word
; .word _GLOBAL_OFFSET_TABLE_-(vmJumpAndInvoke_getAddress)+8)
;
;else ; not AVIAN_CONTINUATIONS
; vmJumpAndInvoke should only be called when continuations are
; enabled
bkpt 0
;endif ; not AVIAN_CONTINUATIONS
END

173
src/compile-x86.masm Normal file
View File

@ -0,0 +1,173 @@
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.
ORIGIN: https://github.com/gkvas/avian/tree/wince
#
.586
.MODEL FLAT, C
comment # types.h #
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
comment # target-fields.h #
ifdef TARGET_BYTES_PER_WORD
if TARGET_BYTES_PER_WORD eq 8
TARGET_THREAD_EXCEPTION equ 80
TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT equ 2256
TARGET_THREAD_EXCEPTIONOFFSET equ 2264
TARGET_THREAD_EXCEPTIONHANDLER equ 2272
TARGET_THREAD_IP equ 2216
TARGET_THREAD_STACK equ 2224
TARGET_THREAD_NEWSTACK equ 2232
TARGET_THREAD_SCRATCH equ 2240
TARGET_THREAD_CONTINUATION equ 2248
TARGET_THREAD_TAILADDRESS equ 2280
TARGET_THREAD_VIRTUALCALLTARGET equ 2288
TARGET_THREAD_VIRTUALCALLINDEX equ 2296
TARGET_THREAD_HEAPIMAGE equ 2304
TARGET_THREAD_CODEIMAGE equ 2312
TARGET_THREAD_THUNKTABLE equ 2320
TARGET_THREAD_STACKLIMIT equ 2368
elseif TARGET_BYTES_PER_WORD eq 4
TARGET_THREAD_EXCEPTION equ 44
TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT equ 2164
TARGET_THREAD_EXCEPTIONOFFSET equ 2168
TARGET_THREAD_EXCEPTIONHANDLER equ 2172
TARGET_THREAD_IP equ 2144
TARGET_THREAD_STACK equ 2148
TARGET_THREAD_NEWSTACK equ 2152
TARGET_THREAD_SCRATCH equ 2156
TARGET_THREAD_CONTINUATION equ 2160
TARGET_THREAD_TAILADDRESS equ 2176
TARGET_THREAD_VIRTUALCALLTARGET equ 2180
TARGET_THREAD_VIRTUALCALLINDEX equ 2184
TARGET_THREAD_HEAPIMAGE equ 2188
TARGET_THREAD_CODEIMAGE equ 2192
TARGET_THREAD_THUNKTABLE equ 2196
TARGET_THREAD_STACKLIMIT equ 2220
else
error
endif
else
error
endif
ifdef AVIAN_USE_FRAME_POINTER
ALIGNMENT_ADJUSTMENT equ 0
else
ALIGNMENT_ADJUSTMENT equ 12
endif
CALLEE_SAVED_REGISTER_FOOTPRINT equ 16 + ALIGNMENT_ADJUSTMENT
_TEXT SEGMENT
public C vmInvoke
vmInvoke:
push ebp
mov ebp,esp
; 8(%ebp): thread
; 12(%ebp): function
; 16(%ebp): arguments
; 20(%ebp): argumentFootprint
; 24(%ebp): frameSize
; 28(%ebp): returnType
; allocate stack space for callee-saved registers
sub esp,offset CALLEE_SAVED_REGISTER_FOOTPRINT
; remember this stack position, since we won't be able to rely on
; %rbp being restored when the call returns
mov eax,ds:dword ptr[8+ebp]
mov ds:dword ptr[TARGET_THREAD_SCRATCH+eax],esp
mov ds:dword ptr[0+esp],ebx
mov ds:dword ptr[4+esp],esi
mov ds:dword ptr[8+esp],edi
; allocate stack space for arguments
sub esp,ds:dword ptr[24+ebp]
; we use ebx to hold the thread pointer, by convention
mov ebx,eax
; copy arguments into place
mov ecx,0
mov edx,ds:dword ptr[16+ebp]
jmp LvmInvoke_argumentTest
LvmInvoke_argumentLoop:
mov eax,ds:dword ptr[edx+ecx*1]
mov ds:dword ptr[esp+ecx*1],eax
add ecx,4
LvmInvoke_argumentTest:
cmp ecx,ds:dword ptr[20+ebp]
jb LvmInvoke_argumentLoop
; call function
call dword ptr[12+ebp]
public vmInvoke_returnAddress
vmInvoke_returnAddress:
; restore stack pointer
mov esp,ds:dword ptr[TARGET_THREAD_SCRATCH+ebx]
; clear MyThread::stack to avoid confusing another thread calling
; java.lang.Thread.getStackTrace on this one. See
; MyProcess::getStackTrace in compile.cpp for details on how we get
; a reliable stack trace from a thread that might be interrupted at
; any point in its execution.
mov ds:dword ptr[TARGET_THREAD_STACK+ebx],0
public vmInvoke_safeStack
vmInvoke_safeStack:
; restore callee-saved registers
mov ebx,ds:dword ptr[0+esp]
mov esi,ds:dword ptr[4+esp]
mov edi,ds:dword ptr[8+esp]
add esp,offset CALLEE_SAVED_REGISTER_FOOTPRINT
mov ecx,ds:dword ptr[28+esp]
pop ebp
ret
LgetPC:
mov esi,ds:dword ptr[esp]
ret
public vmJumpAndInvoke
vmJumpAndInvoke:
; vmJumpAndInvoke should only be called when continuations are
; enabled
int 3
_TEXT ENDS
END

View File

@ -7389,8 +7389,9 @@ finish(MyThread* t, FixedAllocator* allocator, Context* context)
{
trap();
}
#if !defined(AVIAN_AOT_ONLY)
syncInstructionCache(start, codeSize);
#endif
}
void
@ -9152,7 +9153,9 @@ class MyProcessor: public Processor {
virtual void dispose() {
if (codeAllocator.base) {
#if !defined(AVIAN_AOT_ONLY)
s->freeExecutable(codeAllocator.base, codeAllocator.capacity);
#endif
}
compilationHandlers->dispose(allocator);
@ -9313,11 +9316,13 @@ class MyProcessor: public Processor {
}
virtual void boot(Thread* t, BootImage* image, uint8_t* code) {
#if !defined(AVIAN_AOT_ONLY)
if (codeAllocator.base == 0) {
codeAllocator.base = static_cast<uint8_t*>
(s->tryAllocateExecutable(ExecutableAreaSizeInBytes));
codeAllocator.capacity = ExecutableAreaSizeInBytes;
}
#endif
if (image and code) {
local::boot(static_cast<MyThread*>(t), image, code);
@ -9334,11 +9339,15 @@ class MyProcessor: public Processor {
root(t, MethodTreeSentinal));
}
#ifdef AVIAN_AOT_ONLY
thunks = bootThunks;
#else
local::compileThunks(static_cast<MyThread*>(t), &codeAllocator);
if (not (image and code)) {
bootThunks = thunks;
}
#endif
segFaultHandler.m = t->m;
expect(t, t->m->system->success

View File

@ -18,7 +18,7 @@
using namespace vm;
namespace {
namespace local {
const unsigned FrameBaseOffset = 0;
const unsigned FrameNextOffset = 1;
@ -2321,7 +2321,7 @@ interpret3(Thread* t, const int base)
object class_ = resolveClassInPool(t, frameMethod(t, frame), index - 1);
PROTECT(t, class_);
int32_t counts[dimensions];
RUNTIME_ARRAY(int32_t, counts, dimensions);
for (int i = dimensions - 1; i >= 0; --i) {
counts[i] = popInt(t);
if (UNLIKELY(counts[i] < 0)) {
@ -3100,7 +3100,7 @@ class MyProcessor: public Processor {
(&byteArrayBody(t, methodSpec(t, method), 0));
pushArguments(t, this_, spec, arguments);
return ::invoke(t, method);
return local::invoke(t, method);
}
virtual object
@ -3124,7 +3124,7 @@ class MyProcessor: public Processor {
(&byteArrayBody(t, methodSpec(t, method), 0));
pushArguments(t, this_, spec, arguments);
return ::invoke(t, method);
return local::invoke(t, method);
}
virtual object
@ -3148,7 +3148,7 @@ class MyProcessor: public Processor {
(&byteArrayBody(t, methodSpec(t, method), 0));
pushArguments(t, this_, spec, indirectObjects, arguments);
return ::invoke(t, method);
return local::invoke(t, method);
}
virtual object
@ -3174,7 +3174,7 @@ class MyProcessor: public Processor {
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*) {
@ -3254,8 +3254,8 @@ namespace vm {
Processor*
makeProcessor(System* system, Allocator* allocator, bool)
{
return new (allocator->allocate(sizeof(MyProcessor)))
MyProcessor(system, allocator);
return new (allocator->allocate(sizeof(local::MyProcessor)))
local::MyProcessor(system, allocator);
}
} // namespace vm

View File

@ -3713,16 +3713,6 @@ populateJNITables(JavaVMVTable* vmTable, JNIEnvVTable* envTable)
} // namespace vm
#define BOOTSTRAP_PROPERTY "avian.bootstrap"
#define CRASHDIR_PROPERTY "avian.crash.dir"
#define EMBED_PREFIX_PROPERTY "avian.embed.prefix"
#define CLASSPATH_PROPERTY "java.class.path"
#define JAVA_HOME_PROPERTY "java.home"
#define BOOTCLASSPATH_PREPEND_OPTION "bootclasspath/p"
#define BOOTCLASSPATH_OPTION "bootclasspath"
#define BOOTCLASSPATH_APPEND_OPTION "bootclasspath/a"
#define BOOTCLASSPATH_APPEND_OPTION "bootclasspath/a"
extern "C" JNIEXPORT jint JNICALL
JNI_GetDefaultJavaVMInitArgs(void*)
{
@ -3743,7 +3733,7 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
unsigned heapLimit = 0;
unsigned stackLimit = 0;
const char* bootLibrary = 0;
const char* bootLibraries = 0;
const char* classpath = 0;
const char* javaHome = AVIAN_JAVA_HOME;
const char* embedPrefix = AVIAN_EMBED_PREFIX;
@ -3779,7 +3769,7 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
if (strncmp(p, BOOTSTRAP_PROPERTY "=",
sizeof(BOOTSTRAP_PROPERTY)) == 0)
{
bootLibrary = p + sizeof(BOOTSTRAP_PROPERTY);
bootLibraries = p + sizeof(BOOTSTRAP_PROPERTY);
} else if (strncmp(p, CRASHDIR_PROPERTY "=",
sizeof(CRASHDIR_PROPERTY)) == 0)
{
@ -3833,9 +3823,16 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
*RUNTIME_ARRAY_BODY(bootClasspathBuffer) = 0;
}
char* bootLibrary = bootLibraries ? strdup(bootLibraries) : 0;
char* bootLibraryEnd = bootLibrary ? strchr(bootLibrary, PATH_SEPARATOR) : 0;
if(bootLibraryEnd)
*bootLibraryEnd = 0;
Finder* bf = makeFinder
(s, h, RUNTIME_ARRAY_BODY(bootClasspathBuffer), bootLibrary);
Finder* af = makeFinder(s, h, classpath, bootLibrary);
if(bootLibrary)
free(bootLibrary);
Processor* p = makeProcessor(s, h, true);
const char** properties = static_cast<const char**>

View File

@ -13,6 +13,16 @@
#include "machine.h"
#define BOOTSTRAP_PROPERTY "avian.bootstrap"
#define CRASHDIR_PROPERTY "avian.crash.dir"
#define EMBED_PREFIX_PROPERTY "avian.embed.prefix"
#define CLASSPATH_PROPERTY "java.class.path"
#define JAVA_HOME_PROPERTY "java.home"
#define BOOTCLASSPATH_PREPEND_OPTION "bootclasspath/p"
#define BOOTCLASSPATH_OPTION "bootclasspath"
#define BOOTCLASSPATH_APPEND_OPTION "bootclasspath/a"
#define BOOTCLASSPATH_APPEND_OPTION "bootclasspath/a"
namespace vm {
void

View File

@ -17,6 +17,11 @@
#include "arch.h"
#include "lzma.h"
#if defined(PLATFORM_WINDOWS)
# define WIN32_LEAN_AND_MEAN
# include <Windows.h>
#endif
using namespace vm;
namespace {
@ -3003,6 +3008,14 @@ Machine::Machine(System* system, Heap* heap, Finder* bootFinder,
populateJNITables(&javaVMVTable, &jniEnvVTable);
const char* bootstrapProperty = findProperty(this, BOOTSTRAP_PROPERTY);
const char* bootstrapPropertyDup = bootstrapProperty ? strdup(bootstrapProperty) : 0;
const char* bootstrapPropertyEnd = bootstrapPropertyDup + (bootstrapPropertyDup ? strlen(bootstrapPropertyDup) : 0);
char* codeLibraryName = (char*)bootstrapPropertyDup;
char* codeLibraryNameEnd = 0;
if (codeLibraryName && (codeLibraryNameEnd = strchr(codeLibraryName, system->pathSeparator())))
*codeLibraryNameEnd = 0;
if (not system->success(system->make(&localThread)) or
not system->success(system->make(&stateLock)) or
not system->success(system->make(&heapLock)) or
@ -3010,10 +3023,25 @@ Machine::Machine(System* system, Heap* heap, Finder* bootFinder,
not system->success(system->make(&referenceLock)) or
not system->success(system->make(&shutdownLock)) or
not system->success
(system->load(&libraries, findProperty(this, "avian.bootstrap"))))
(system->load(&libraries, bootstrapPropertyDup)))
{
system->abort();
}
System::Library* additionalLibrary = 0;
while (codeLibraryNameEnd && codeLibraryNameEnd + 1 < bootstrapPropertyEnd) {
codeLibraryName = codeLibraryNameEnd + 1;
codeLibraryNameEnd = strchr(codeLibraryName, system->pathSeparator());
if (codeLibraryNameEnd)
*codeLibraryNameEnd = 0;
if (!system->success(system->load(&additionalLibrary, codeLibraryName)))
system->abort();
libraries->setNext(additionalLibrary);
}
if(bootstrapPropertyDup)
free((void*)bootstrapPropertyDup);
}
void
@ -4731,6 +4759,27 @@ visitRoots(Machine* m, Heap::Visitor* v)
}
}
void
logTrace(FILE* f, const char* fmt, ...)
{
va_list a;
va_start(a, fmt);
#ifdef PLATFORM_WINDOWS
const unsigned length = _vscprintf(fmt, a);
#else
const unsigned length = vsnprintf(0, 0, fmt, a);
#endif
RUNTIME_ARRAY(char, buffer, length + 1);
vsnprintf(&buffer[0], length, fmt, a);
buffer[length] = 0;
va_end(a);
::fprintf(f, "%s", &buffer[0]);
#ifdef PLATFORM_WINDOWS
::OutputDebugStringA(&buffer[0]);
#endif
}
void
printTrace(Thread* t, object exception)
{
@ -4740,19 +4789,19 @@ printTrace(Thread* t, object exception)
for (object e = exception; e; e = throwableCause(t, e)) {
if (e != exception) {
fprintf(errorLog(t), "caused by: ");
logTrace(errorLog(t), "caused by: ");
}
fprintf(errorLog(t), "%s", &byteArrayBody
logTrace(errorLog(t), "%s", &byteArrayBody
(t, className(t, objectClass(t, e)), 0));
if (throwableMessage(t, e)) {
object m = throwableMessage(t, e);
THREAD_RUNTIME_ARRAY(t, char, message, stringLength(t, m) + 1);
stringChars(t, m, RUNTIME_ARRAY_BODY(message));
fprintf(errorLog(t), ": %s\n", RUNTIME_ARRAY_BODY(message));
logTrace(errorLog(t), ": %s\n", RUNTIME_ARRAY_BODY(message));
} else {
fprintf(errorLog(t), "\n");
logTrace(errorLog(t), "\n");
}
object trace = throwableTrace(t, e);
@ -4766,17 +4815,17 @@ printTrace(Thread* t, object exception)
int line = t->m->processor->lineNumber
(t, traceElementMethod(t, e), traceElementIp(t, e));
fprintf(errorLog(t), " at %s.%s ", class_, method);
logTrace(errorLog(t), " at %s.%s ", class_, method);
switch (line) {
case NativeLine:
fprintf(errorLog(t), "(native)\n");
logTrace(errorLog(t), "(native)\n");
break;
case UnknownLine:
fprintf(errorLog(t), "(unknown line)\n");
logTrace(errorLog(t), "(unknown line)\n");
break;
default:
fprintf(errorLog(t), "(line %d)\n", line);
logTrace(errorLog(t), "(line %d)\n", line);
}
}
}
@ -4786,7 +4835,7 @@ printTrace(Thread* t, object exception)
}
}
fflush(errorLog(t));
::fflush(errorLog(t));
}
object

View File

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

View File

@ -12,10 +12,21 @@
# define __STDC_CONSTANT_MACROS
#endif
#include "sys/types.h"
#ifdef __APPLE__
# include "CoreFoundation/CoreFoundation.h"
# include "sys/ucontext.h"
# undef assert
#elif defined(__ANDROID__)
# include <asm/sigcontext.h> /* for sigcontext */
# include <asm/signal.h> /* for stack_t */
typedef struct ucontext {
unsigned long uc_flags;
struct ucontext *uc_link;
stack_t uc_stack;
struct sigcontext uc_mcontext;
unsigned long uc_sigmask;
} ucontext_t;
#else
# if defined __FreeBSD__
# include "limits.h"
@ -24,7 +35,7 @@
#endif
#include "sys/mman.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "sys/time.h"
#include "time.h"
@ -37,10 +48,10 @@
#include "stdint.h"
#include "dirent.h"
#include "sched.h"
#include "arch.h"
#include "system.h"
#define ACQUIRE(x) MutexResource MAKE_NAME(mutexResource_) (x)
using namespace vm;

View File

@ -121,8 +121,10 @@ class System {
virtual bool success(Status) = 0;
virtual void* tryAllocate(unsigned sizeInBytes) = 0;
virtual void free(const void* p) = 0;
#if !defined(AVIAN_AOT_ONLY)
virtual void* tryAllocateExecutable(unsigned sizeInBytes) = 0;
virtual void freeExecutable(const void* p, unsigned sizeInBytes) = 0;
#endif
virtual Status attach(Runnable*) = 0;
virtual Status start(Runnable*) = 0;
virtual Status make(Mutex**) = 0;

View File

@ -26,6 +26,71 @@
#include "arch.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_ALL_ACCESS)
#define CreateMutex(lpEventAttributes, bInitialOwner, lpName) \
CreateMutexEx((lpEventAttributes), (lpName), (bInitialOwner)?CREATE_MUTEX_INITIAL_OWNER:0, MUTEX_ALL_ACCESS)
#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)
using namespace vm;
@ -57,8 +122,10 @@ const unsigned HandlerCount = 2;
class MySystem;
MySystem* system;
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
LONG CALLBACK
handleException(LPEXCEPTION_POINTERS e);
#endif
DWORD WINAPI
run(void* r)
@ -559,7 +626,9 @@ class MySystem: public System {
};
MySystem(const char* crashDumpDirectory):
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
oldHandler(0),
#endif
crashDumpDirectory(crashDumpDirectory)
{
expect(this, system == 0);
@ -581,27 +650,35 @@ class MySystem: public System {
int registerHandler(System::SignalHandler* handler, int index) {
if (handler) {
handlers[index] = handler;
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
if (oldHandler == 0) {
#ifdef ARCH_x86_32
# ifdef ARCH_x86_32
oldHandler = SetUnhandledExceptionFilter(handleException);
#elif defined ARCH_x86_64
# elif defined ARCH_x86_64
AddVectoredExceptionHandler(1, handleException);
oldHandler = reinterpret_cast<LPTOP_LEVEL_EXCEPTION_FILTER>(1);
#endif
# endif
}
#else
#pragma message("TODO: http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.windows.application.unhandledexception(v=vs.105).aspx")
#endif
return 0;
} else if (handlers[index]) {
handlers[index] = 0;
if (not findHandler()) {
#ifdef ARCH_x86_32
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
# ifdef ARCH_x86_32
SetUnhandledExceptionFilter(oldHandler);
oldHandler = 0;
#elif defined ARCH_x86_64
# elif defined ARCH_x86_64
// do nothing, handlers are never "unregistered" anyway
#endif
# endif
#else
#pragma message("TODO: http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.windows.application.unhandledexception(v=vs.105).aspx")
#endif
}
return 0;
@ -618,6 +695,7 @@ class MySystem: public System {
if (p) ::free(const_cast<void*>(p));
}
#if !defined(AVIAN_AOT_ONLY)
virtual void* tryAllocateExecutable(unsigned sizeInBytes) {
return VirtualAlloc
(0, sizeInBytes, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
@ -627,6 +705,7 @@ class MySystem: public System {
int r UNUSED = VirtualFree(const_cast<void*>(p), 0, MEM_RELEASE);
assert(this, r);
}
#endif
virtual bool success(Status s) {
return s == 0;
@ -677,6 +756,7 @@ class MySystem: public System {
virtual Status visit(System::Thread* st UNUSED, System::Thread* sTarget,
ThreadVisitor* visitor)
{
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
assert(this, st != sTarget);
Thread* target = static_cast<Thread*>(sTarget);
@ -692,15 +772,15 @@ class MySystem: public System {
rv = GetThreadContext(target->thread, &context);
if (rv) {
#ifdef ARCH_x86_32
# ifdef ARCH_x86_32
visitor->visit(reinterpret_cast<void*>(context.Eip),
reinterpret_cast<void*>(context.Ebp),
reinterpret_cast<void*>(context.Esp));
#elif defined ARCH_x86_64
# elif defined ARCH_x86_64
visitor->visit(reinterpret_cast<void*>(context.Rip),
reinterpret_cast<void*>(context.Rbp),
reinterpret_cast<void*>(context.Rsp));
#endif
# endif
success = true;
}
@ -709,6 +789,10 @@ class MySystem: public System {
}
return (success ? 0 : 1);
#else
#pragma message("TODO: http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.windows.application.unhandledexception(v=vs.105).aspx")
return false;
#endif
}
virtual uint64_t call(void* function, uintptr_t* arguments, uint8_t* types,
@ -719,15 +803,39 @@ class MySystem: public System {
virtual Status map(System::Region** region, const char* name) {
Status status = 1;
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
HANDLE file = CreateFile(name, FILE_READ_DATA, FILE_SHARE_READ, 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 !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
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 !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
HANDLE mapping = CreateFileMapping(file, 0, PAGE_READONLY, 0, size, 0);
#else
HANDLE mapping = CreateFileMappingFromApp(file, 0, PAGE_READONLY, size, 0);
#endif
if (mapping) {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
void* data = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);
#else
void* data = MapViewOfFileFromApp(mapping, FILE_MAP_READ, 0, 0);
#endif
if (data) {
*region = new (allocate(this, sizeof(Region)))
Region(this, static_cast<uint8_t*>(data), size, file, mapping);
@ -757,7 +865,12 @@ class MySystem: public System {
memcpy(RUNTIME_ARRAY_BODY(buffer) + length, "\\*", 3);
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));
#else
d->handle = FindFirstFileEx(RUNTIME_ARRAY_BODY(buffer), FindExInfoStandard, &(d->data), FindExSearchNameMatch, 0, 0);
#endif
if (d->handle == INVALID_HANDLE_VALUE) {
d->dispose();
} else {
@ -797,6 +910,7 @@ class MySystem: public System {
}
virtual const char* toAbsolutePath(Allocator* allocator, const char* name) {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
if (strncmp(name, "//", 2) == 0
or strncmp(name, "\\\\", 2) == 0
or strncmp(name + 1, ":/", 2) == 0
@ -808,6 +922,10 @@ class MySystem: public System {
GetCurrentDirectory(MAX_PATH, buffer);
return append(allocator, buffer, "\\", name);
}
#else
#pragma message("TODO:http://lunarfrog.com/blog/2012/05/21/winrt-folders-access/ Windows.ApplicationModel.Package.Current.InstalledLocation")
return copy(allocator, name);
#endif
}
virtual Status load(System::Library** lib,
@ -816,9 +934,23 @@ class MySystem: public System {
HMODULE handle;
unsigned nameLength = (name ? strlen(name) : 0);
if (name) {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
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 {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
handle = GetModuleHandle(0);
#else
// Most of WinRT/WP8 applications can not host native object files inside main executable
assert(this, false);
#endif
}
if (handle) {
@ -866,7 +998,11 @@ class MySystem: public System {
}
virtual void yield() {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
SwitchToThread();
#else
YieldProcessor();
#endif
}
virtual void exit(int code) {
@ -887,10 +1023,14 @@ class MySystem: public System {
HANDLE mutex;
SignalHandler* handlers[HandlerCount];
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
LPTOP_LEVEL_EXCEPTION_FILTER oldHandler;
#endif
const char* crashDumpDirectory;
};
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#pragma pack(push,4)
struct MINIDUMP_EXCEPTION_INFORMATION {
DWORD thread;
@ -1005,6 +1145,8 @@ handleException(LPEXCEPTION_POINTERS e)
return EXCEPTION_CONTINUE_SEARCH;
}
#endif
} // namespace
namespace vm {

168
src/x86.masm Normal file
View File

@ -0,0 +1,168 @@
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.
ORIGIN: https://github.com/gkvas/avian/tree/wince
#
.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:qword 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

1
vm.pro
View File

@ -71,6 +71,7 @@
-keep public class java.io.IOException
-keep public class java.io.FileNotFoundException
-keep public class java.net.SocketException
-keep public class java.util.Locale
# ClassLoader.getSystemClassloader() depends on the existence of this class: