mirror of
https://github.com/corda/corda.git
synced 2025-01-19 11:16:54 +00:00
Merge remote branch 'osmandapp/upstream'
This commit is contained in:
commit
8a7b6488d4
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,3 +7,4 @@ build
|
||||
bin
|
||||
/lib
|
||||
/distrib
|
||||
*.pdb
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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
546
makefile
@ -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
|
||||
|
23
src/arm.cpp
23
src/arm.cpp
@ -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
|
||||
|
28
src/arm.h
28
src/arm.h
@ -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
89
src/arm.masm
Normal 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
|
@ -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
|
||||
|
@ -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";
|
||||
|
15
src/common.h
15
src/common.h
@ -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
252
src/compile-arm.masm
Normal 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
173
src/compile-x86.masm
Normal 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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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**>
|
||||
|
10
src/jnienv.h
10
src/jnienv.h
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
164
src/windows.cpp
164
src/windows.cpp
@ -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
168
src/x86.masm
Normal 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
|
Loading…
Reference in New Issue
Block a user