mirror of
https://github.com/corda/corda.git
synced 2025-06-18 07:08:15 +00:00
Merge branch 'master' of git://github.com/ReadyTalk/avian
Conflicts: src/codegen/arm/assembler.cpp src/common.h src/machine.cpp
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,3 +7,4 @@ build
|
|||||||
bin
|
bin
|
||||||
/lib
|
/lib
|
||||||
/distrib
|
/distrib
|
||||||
|
*.pdb
|
||||||
|
@ -249,12 +249,11 @@ where OpenJDK is installed, e.g.:
|
|||||||
|
|
||||||
This will build Avian as a conventional JVM (e.g. libjvm.so) which
|
This will build Avian as a conventional JVM (e.g. libjvm.so) which
|
||||||
loads its boot class library and native libraries (e.g. libjava.so)
|
loads its boot class library and native libraries (e.g. libjava.so)
|
||||||
from _/usr/lib/jvm/java-7-openjdk/jre_ at runtime. To run an
|
from _/usr/lib/jvm/java-7-openjdk/jre_ at runtime. In this configuration,
|
||||||
application in this configuration, you'll need to make sure the VM is
|
OpenJDK needs to remain installed for Avian to work, and you can run
|
||||||
in your library search path. For example:
|
applications like this:
|
||||||
|
|
||||||
$ LD_LIBRARY_PATH=build/linux-x86_64-openjdk \
|
$ build/linux-x86_64-openjdk/avian-dynamic -cp /path/to/my/application \
|
||||||
build/linux-x86_64-openjdk/avian-dynamic -cp /path/to/my/application \
|
|
||||||
com.example.MyApplication
|
com.example.MyApplication
|
||||||
|
|
||||||
Alternatively, you can enable a stand-alone build using OpenJDK by
|
Alternatively, you can enable a stand-alone build using OpenJDK by
|
||||||
|
@ -55,6 +55,15 @@
|
|||||||
|
|
||||||
typedef wchar_t char_t;
|
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
|
#else // not PLATFORM_WINDOWS
|
||||||
|
|
||||||
# include <dirent.h>
|
# include <dirent.h>
|
||||||
@ -83,7 +92,19 @@ typedef char char_t;
|
|||||||
|
|
||||||
#endif // not PLATFORM_WINDOWS
|
#endif // not PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
#ifndef WINAPI_FAMILY
|
||||||
|
# ifndef WINAPI_PARTITION_DESKTOP
|
||||||
|
# define WINAPI_PARTITION_DESKTOP 1
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifndef WINAPI_FAMILY_PARTITION
|
||||||
|
# define WINAPI_FAMILY_PARTITION(x) (x)
|
||||||
|
# endif
|
||||||
|
#endif // WINAPI_FAMILY
|
||||||
|
|
||||||
|
#if !defined(SKIP_OPERATOR_NEW)
|
||||||
inline void* operator new(size_t, void* p) throw() { return p; }
|
inline void* operator new(size_t, void* p) throw() { return p; }
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef const char_t* string_t;
|
typedef const char_t* string_t;
|
||||||
|
|
||||||
@ -155,69 +176,9 @@ doWrite(JNIEnv* e, jint fd, const jbyte* data, jint length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef PLATFORM_WINDOWS
|
#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 {
|
class Directory {
|
||||||
public:
|
public:
|
||||||
Directory(): handle(0), findNext(false) { }
|
Directory(): handle(0), findNext(false) { }
|
||||||
@ -250,51 +211,9 @@ class Directory {
|
|||||||
|
|
||||||
#else // not PLATFORM_WINDOWS
|
#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
|
#endif // not PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
inline string_t getChars(JNIEnv* e, jstring path) {
|
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)
|
Java_java_io_File_toAbsolutePath(JNIEnv* e UNUSED, jclass, jstring path)
|
||||||
{
|
{
|
||||||
#ifdef PLATFORM_WINDOWS
|
#ifdef PLATFORM_WINDOWS
|
||||||
|
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
string_t chars = getChars(e, path);
|
string_t chars = getChars(e, path);
|
||||||
if (chars) {
|
if (chars) {
|
||||||
const unsigned BufferSize = MAX_PATH;
|
const unsigned BufferSize = MAX_PATH;
|
||||||
@ -330,6 +250,19 @@ Java_java_io_File_toAbsolutePath(JNIEnv* e UNUSED, jclass, jstring path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return 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
|
#else
|
||||||
jstring result = path;
|
jstring result = path;
|
||||||
string_t chars = getChars(e, 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
|
extern "C" JNIEXPORT jlong JNICALL
|
||||||
Java_java_io_File_length(JNIEnv* e, jclass, jstring path)
|
Java_java_io_File_length(JNIEnv* e, jclass, jstring path)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef PLATFORM_WINDOWS
|
#ifdef PLATFORM_WINDOWS
|
||||||
|
// Option: without opening file
|
||||||
LARGE_INTEGER fileSize;
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa364946(v=vs.85).aspx
|
||||||
string_t chars = getChars(e, path);
|
string_t chars = getChars(e, path);
|
||||||
|
if(chars) {
|
||||||
|
LARGE_INTEGER fileSize;
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
HANDLE file = CreateFileW
|
HANDLE file = CreateFileW
|
||||||
(chars, FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
|
(chars, FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
|
||||||
|
#else
|
||||||
|
HANDLE file = CreateFile2
|
||||||
|
(chars, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr);
|
||||||
|
#endif
|
||||||
releaseChars(e, path, chars);
|
releaseChars(e, path, chars);
|
||||||
if (file != INVALID_HANDLE_VALUE)
|
if (file == INVALID_HANDLE_VALUE)
|
||||||
GetFileSizeEx(file, &fileSize);
|
return 0;
|
||||||
else 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);
|
CloseHandle(file);
|
||||||
return static_cast<jlong>(fileSize.QuadPart);
|
return static_cast<jlong>(fileSize.QuadPart);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
string_t chars = getChars(e, path);
|
string_t chars = getChars(e, path);
|
||||||
@ -598,7 +552,11 @@ Java_java_io_File_openDir(JNIEnv* e, jclass, jstring path)
|
|||||||
releaseChars(e, path, chars);
|
releaseChars(e, path, chars);
|
||||||
|
|
||||||
Directory* d = new (malloc(sizeof(Directory))) Directory;
|
Directory* d = new (malloc(sizeof(Directory))) Directory;
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
d->handle = FindFirstFileW(RUNTIME_ARRAY_BODY(buffer), &(d->data));
|
d->handle = FindFirstFileW(RUNTIME_ARRAY_BODY(buffer), &(d->data));
|
||||||
|
#else
|
||||||
|
d->handle = FindFirstFileExW(RUNTIME_ARRAY_BODY(buffer), FindExInfoStandard, &(d->data), FindExSearchNameMatch, NULL, 0);
|
||||||
|
#endif
|
||||||
if (d->handle == INVALID_HANDLE_VALUE) {
|
if (d->handle == INVALID_HANDLE_VALUE) {
|
||||||
d->dispose();
|
d->dispose();
|
||||||
d = 0;
|
d = 0;
|
||||||
@ -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
|
extern "C" JNIEXPORT jstring JNICALL
|
||||||
Java_java_io_File_readDir(JNIEnv* e, jclass, jlong handle)
|
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)
|
(JNIEnv* e, jclass, jint fd, jbyteArray b, jint offset, jint length)
|
||||||
{
|
{
|
||||||
jbyte* data = static_cast<jbyte*>(malloc(length));
|
jbyte* data = static_cast<jbyte*>(malloc(length));
|
||||||
|
|
||||||
if (data == 0) {
|
if (data == 0) {
|
||||||
throwNew(e, "java/lang/OutOfMemoryError", 0);
|
throwNew(e, "java/lang/OutOfMemoryError", 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
e->GetByteArrayRegion(b, offset, length, data);
|
e->GetByteArrayRegion(b, offset, length, data);
|
||||||
|
|
||||||
if (not e->ExceptionCheck()) {
|
if (not e->ExceptionCheck()) {
|
||||||
doWrite(e, fd, data, length);
|
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);
|
string_t chars = getChars(e, path);
|
||||||
if (chars) {
|
if (chars) {
|
||||||
Mapping* mapping = map(e, chars);
|
jlong peer = 0;
|
||||||
|
jlong length = 0;
|
||||||
jlong peer = reinterpret_cast<jlong>(mapping);
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
e->SetLongArrayRegion(result, 0, 1, &peer);
|
#if defined(PLATFORM_WINDOWS)
|
||||||
|
int fd = ::_wopen(chars, O_RDONLY | OPEN_MASK);
|
||||||
jlong length = (mapping ? mapping->length : 0);
|
#else
|
||||||
e->SetLongArrayRegion(result, 1, 1, &length);
|
int fd = ::open((const char*)chars, O_RDONLY | OPEN_MASK);
|
||||||
|
#endif
|
||||||
releaseChars(e, path, chars);
|
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
|
||||||
|
|
||||||
|
e->SetLongArrayRegion(result, 0, 1, &peer);
|
||||||
|
e->SetLongArrayRegion(result, 1, 1, &length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
Java_java_io_RandomAccessFile_copy(JNIEnv* e, jclass, jlong peer,
|
Java_java_io_RandomAccessFile_readBytes(JNIEnv* e, jclass, jlong peer,
|
||||||
jlong position, jbyteArray buffer,
|
jlong position, jbyteArray buffer,
|
||||||
int offset, int length)
|
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*>
|
uint8_t* dst = reinterpret_cast<uint8_t*>
|
||||||
(e->GetPrimitiveArrayCritical(buffer, 0));
|
(e->GetPrimitiveArrayCritical(buffer, 0));
|
||||||
|
|
||||||
memcpy(dst + offset,
|
ssize_t bytesRead = ::read(fd, dst + offset, length);
|
||||||
reinterpret_cast<Mapping*>(peer)->start + position,
|
|
||||||
length);
|
|
||||||
|
|
||||||
e->ReleasePrimitiveArrayCritical(buffer, dst, 0);
|
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
|
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 "signal.h"
|
||||||
# include "sys/time.h"
|
# include "sys/time.h"
|
||||||
# include "sys/types.h"
|
# include "sys/types.h"
|
||||||
|
# ifndef __ANDROID__
|
||||||
# include "sys/sysctl.h"
|
# include "sys/sysctl.h"
|
||||||
|
# endif
|
||||||
# include "sys/utsname.h"
|
# include "sys/utsname.h"
|
||||||
# include "sys/wait.h"
|
# include "sys/wait.h"
|
||||||
|
|
||||||
#endif // not PLATFORM_WINDOWS
|
#endif // not PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
#ifndef WINAPI_FAMILY
|
||||||
|
# ifndef WINAPI_PARTITION_DESKTOP
|
||||||
|
# define WINAPI_PARTITION_DESKTOP 1
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifndef WINAPI_FAMILY_PARTITION
|
||||||
|
# define WINAPI_FAMILY_PARTITION(x) (x)
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
|
|
||||||
|
# include "avian-interop.h"
|
||||||
|
|
||||||
|
# endif
|
||||||
|
#endif // WINAPI_FAMILY
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
#ifdef PLATFORM_WINDOWS
|
#ifdef PLATFORM_WINDOWS
|
||||||
char* getErrorStr(DWORD err){
|
|
||||||
// The poor man's error string, just print the error code
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
char * errStr = (char*) malloc(9 * sizeof(char));
|
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);
|
snprintf(errStr, 9, "%d", (int) err);
|
||||||
return errStr;
|
return errStr;
|
||||||
|
|
||||||
// The better way to do this, if I could figure out how to convert LPTSTR to char*
|
|
||||||
//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;
|
|
||||||
}
|
}
|
||||||
|
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])
|
void makePipe(JNIEnv* e, HANDLE p[2])
|
||||||
{
|
{
|
||||||
SECURITY_ATTRIBUTES sa;
|
SECURITY_ATTRIBUTES sa;
|
||||||
@ -93,6 +124,7 @@ namespace {
|
|||||||
throwNew(e, "java/io/IOException", getErrorStr(GetLastError()));
|
throwNew(e, "java/io/IOException", getErrorStr(GetLastError()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int descriptor(JNIEnv* e, HANDLE h)
|
int descriptor(JNIEnv* e, HANDLE h)
|
||||||
{
|
{
|
||||||
@ -194,7 +226,7 @@ extern "C" JNIEXPORT void JNICALL
|
|||||||
Java_java_lang_Runtime_exec(JNIEnv* e, jclass,
|
Java_java_lang_Runtime_exec(JNIEnv* e, jclass,
|
||||||
jobjectArray command, jlongArray process)
|
jobjectArray command, jlongArray process)
|
||||||
{
|
{
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
int size = 0;
|
int size = 0;
|
||||||
for (int i = 0; i < e->GetArrayLength(command); ++i){
|
for (int i = 0; i < e->GetArrayLength(command); ++i){
|
||||||
jstring element = (jstring) e->GetObjectArrayElement(command, i);
|
jstring element = (jstring) e->GetObjectArrayElement(command, i);
|
||||||
@ -265,11 +297,15 @@ Java_java_lang_Runtime_exec(JNIEnv* e, jclass,
|
|||||||
e->SetLongArrayRegion(process, 0, 1, &pid);
|
e->SetLongArrayRegion(process, 0, 1, &pid);
|
||||||
jlong tid = reinterpret_cast<jlong>(pi.hThread);
|
jlong tid = reinterpret_cast<jlong>(pi.hThread);
|
||||||
e->SetLongArrayRegion(process, 1, 1, &tid);
|
e->SetLongArrayRegion(process, 1, 1, &tid);
|
||||||
|
#else
|
||||||
|
throwNew(e, "java/io/Exception", strdup("Not supported on WinRT/WinPhone8"));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jint JNICALL
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid, jlong tid)
|
Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid, jlong tid)
|
||||||
{
|
{
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
DWORD exitCode;
|
DWORD exitCode;
|
||||||
WaitForSingleObject(reinterpret_cast<HANDLE>(pid), INFINITE);
|
WaitForSingleObject(reinterpret_cast<HANDLE>(pid), INFINITE);
|
||||||
BOOL success = GetExitCodeProcess(reinterpret_cast<HANDLE>(pid), &exitCode);
|
BOOL success = GetExitCodeProcess(reinterpret_cast<HANDLE>(pid), &exitCode);
|
||||||
@ -281,14 +317,23 @@ Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid, jlong tid)
|
|||||||
CloseHandle(reinterpret_cast<HANDLE>(tid));
|
CloseHandle(reinterpret_cast<HANDLE>(tid));
|
||||||
|
|
||||||
return exitCode;
|
return exitCode;
|
||||||
|
#else
|
||||||
|
throwNew(e, "java/io/Exception", strdup("Not supported on WinRT/WinPhone8"));
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_java_lang_Runtime_kill(JNIEnv*, jclass, jlong pid) {
|
Java_java_lang_Runtime_kill(JNIEnv* e UNUSED, jclass, jlong pid) {
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
TerminateProcess(reinterpret_cast<HANDLE>(pid), 1);
|
TerminateProcess(reinterpret_cast<HANDLE>(pid), 1);
|
||||||
|
#else
|
||||||
|
throwNew(e, "java/io/Exception", strdup("Not supported on WinRT/WinPhone8"));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Locale getLocale() {
|
Locale getLocale() {
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
const char* lang = "";
|
const char* lang = "";
|
||||||
const char* reg = "";
|
const char* reg = "";
|
||||||
unsigned langid = GetUserDefaultUILanguage();
|
unsigned langid = GetUserDefaultUILanguage();
|
||||||
@ -360,8 +405,23 @@ Locale getLocale() {
|
|||||||
default: lang = "en";
|
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);
|
Locale locale(lang, reg);
|
||||||
|
free(cultureName);
|
||||||
return locale;
|
return locale;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
extern "C" JNIEXPORT void JNICALL
|
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) {
|
} else if (strcmp(chars, "file.separator") == 0) {
|
||||||
r = e->NewStringUTF("\\");
|
r = e->NewStringUTF("\\");
|
||||||
} else if (strcmp(chars, "os.name") == 0) {
|
} else if (strcmp(chars, "os.name") == 0) {
|
||||||
|
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
r = e->NewStringUTF("Windows");
|
r = e->NewStringUTF("Windows");
|
||||||
|
# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE)
|
||||||
|
r = e->NewStringUTF("Windows Phone");
|
||||||
|
# else
|
||||||
|
r = e->NewStringUTF("Windows RT");
|
||||||
|
# endif
|
||||||
} else if (strcmp(chars, "os.version") == 0) {
|
} else if (strcmp(chars, "os.version") == 0) {
|
||||||
|
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
unsigned size = 32;
|
unsigned size = 32;
|
||||||
RUNTIME_ARRAY(char, buffer, size);
|
RUNTIME_ARRAY(char, buffer, size);
|
||||||
OSVERSIONINFO OSversion;
|
OSVERSIONINFO OSversion;
|
||||||
@ -538,6 +605,10 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
|
|||||||
::GetVersionEx(&OSversion);
|
::GetVersionEx(&OSversion);
|
||||||
snprintf(RUNTIME_ARRAY_BODY(buffer), size, "%i.%i", (int)OSversion.dwMajorVersion, (int)OSversion.dwMinorVersion);
|
snprintf(RUNTIME_ARRAY_BODY(buffer), size, "%i.%i", (int)OSversion.dwMajorVersion, (int)OSversion.dwMinorVersion);
|
||||||
r = e->NewStringUTF(RUNTIME_ARRAY_BODY(buffer));
|
r = e->NewStringUTF(RUNTIME_ARRAY_BODY(buffer));
|
||||||
|
# else
|
||||||
|
// Currently there is no alternative on WinRT/WP8
|
||||||
|
r = e->NewStringUTF("8.0");
|
||||||
|
# endif
|
||||||
} else if (strcmp(chars, "os.arch") == 0) {
|
} else if (strcmp(chars, "os.arch") == 0) {
|
||||||
#ifdef ARCH_x86_32
|
#ifdef ARCH_x86_32
|
||||||
r = e->NewStringUTF("x86");
|
r = e->NewStringUTF("x86");
|
||||||
@ -549,15 +620,26 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
|
|||||||
r = e->NewStringUTF("arm");
|
r = e->NewStringUTF("arm");
|
||||||
#endif
|
#endif
|
||||||
} else if (strcmp(chars, "java.io.tmpdir") == 0) {
|
} else if (strcmp(chars, "java.io.tmpdir") == 0) {
|
||||||
|
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
TCHAR buffer[MAX_PATH];
|
TCHAR buffer[MAX_PATH];
|
||||||
GetTempPath(MAX_PATH, buffer);
|
GetTempPath(MAX_PATH, buffer);
|
||||||
r = e->NewStringUTF(buffer);
|
r = e->NewStringUTF(buffer);
|
||||||
|
# else
|
||||||
|
std::wstring tmpDir = AvianInterop::GetTemporaryFolder();
|
||||||
|
r = e->NewString((const jchar*)tmpDir.c_str(), tmpDir.length());
|
||||||
|
# endif
|
||||||
} else if (strcmp(chars, "user.dir") == 0) {
|
} else if (strcmp(chars, "user.dir") == 0) {
|
||||||
|
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
TCHAR buffer[MAX_PATH];
|
TCHAR buffer[MAX_PATH];
|
||||||
GetCurrentDirectory(MAX_PATH, buffer);
|
GetCurrentDirectory(MAX_PATH, buffer);
|
||||||
r = e->NewStringUTF(buffer);
|
r = e->NewStringUTF(buffer);
|
||||||
|
# else
|
||||||
|
std::wstring userDir = AvianInterop::GetInstalledLocation();
|
||||||
|
r = e->NewString((const jchar*)userDir.c_str(), userDir.length());
|
||||||
|
# endif
|
||||||
} else if (strcmp(chars, "user.home") == 0) {
|
} else if (strcmp(chars, "user.home") == 0) {
|
||||||
# ifdef _MSC_VER
|
# ifdef _MSC_VER
|
||||||
|
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
WCHAR buffer[MAX_PATH];
|
WCHAR buffer[MAX_PATH];
|
||||||
size_t needed;
|
size_t needed;
|
||||||
if (_wgetenv_s(&needed, buffer, MAX_PATH, L"USERPROFILE") == 0) {
|
if (_wgetenv_s(&needed, buffer, MAX_PATH, L"USERPROFILE") == 0) {
|
||||||
@ -565,6 +647,10 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
|
|||||||
} else {
|
} else {
|
||||||
r = 0;
|
r = 0;
|
||||||
}
|
}
|
||||||
|
# else
|
||||||
|
std::wstring userHome = AvianInterop::GetDocumentsLibraryLocation();
|
||||||
|
r = e->NewString((const jchar*)userHome.c_str(), userHome.length());
|
||||||
|
# endif
|
||||||
# else
|
# else
|
||||||
LPWSTR home = _wgetenv(L"USERPROFILE");
|
LPWSTR home = _wgetenv(L"USERPROFILE");
|
||||||
r = e->NewString(reinterpret_cast<jchar*>(home), lstrlenW(home));
|
r = e->NewString(reinterpret_cast<jchar*>(home), lstrlenW(home));
|
||||||
@ -652,6 +738,9 @@ namespace {
|
|||||||
#elif defined __APPLE__
|
#elif defined __APPLE__
|
||||||
# include <crt_externs.h>
|
# include <crt_externs.h>
|
||||||
# define environ (*_NSGetEnviron())
|
# define environ (*_NSGetEnviron())
|
||||||
|
#elif defined(WINAPI_FAMILY) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
|
// WinRT/WP8 does not provide alternative for environment variables
|
||||||
|
char* environ[] = { 0 };
|
||||||
#else
|
#else
|
||||||
extern char** environ;
|
extern char** environ;
|
||||||
#endif
|
#endif
|
||||||
@ -785,6 +874,54 @@ Java_java_lang_Math_cos(JNIEnv*, jclass, jdouble val)
|
|||||||
return cos(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
|
extern "C" JNIEXPORT jdouble JNICALL
|
||||||
Java_java_lang_Math_sqrt(JNIEnv*, jclass, jdouble val)
|
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);
|
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
|
extern "C" JNIEXPORT jdouble JNICALL
|
||||||
Java_java_lang_Math_floor(JNIEnv*, jclass, jdouble val)
|
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 openDir(String path);
|
||||||
|
|
||||||
|
private static native long lastModified(String path);
|
||||||
|
|
||||||
private static native String readDir(long handle);
|
private static native String readDir(long handle);
|
||||||
|
|
||||||
private static native long closeDir(long handle);
|
private static native long closeDir(long handle);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static class Pair {
|
private static class Pair {
|
||||||
public final String value;
|
public final String value;
|
||||||
public final Pair next;
|
public final Pair next;
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
package java.io;
|
package java.io;
|
||||||
|
|
||||||
|
import java.lang.IllegalArgumentException;
|
||||||
|
|
||||||
public class RandomAccessFile {
|
public class RandomAccessFile {
|
||||||
private long peer;
|
private long peer;
|
||||||
private File file;
|
private File file;
|
||||||
@ -56,26 +58,68 @@ public class RandomAccessFile {
|
|||||||
this.position = position;
|
this.position = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void readFully(byte[] buffer, int offset, int length)
|
public int skipBytes(int count) throws IOException {
|
||||||
throws IOException
|
if (position + count > length()) throw new IOException();
|
||||||
{
|
this.position = position + count;
|
||||||
if (peer == 0) throw new IOException();
|
return count;
|
||||||
|
|
||||||
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 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();
|
throw new ArrayIndexOutOfBoundsException();
|
||||||
|
int bytesRead = readBytes(peer, position, b, off, len);
|
||||||
copy(peer, position, buffer, offset, length);
|
position += bytesRead;
|
||||||
|
return bytesRead;
|
||||||
position += length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native void copy(long peer, long position, byte[] buffer,
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
int offset, int length);
|
||||||
|
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
|
@ -93,6 +93,12 @@ public final class Math {
|
|||||||
|
|
||||||
public static native double tan(double v);
|
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 acos(double v);
|
||||||
|
|
||||||
public static native double asin(double v);
|
public static native double asin(double v);
|
||||||
|
554
makefile
554
makefile
@ -55,8 +55,10 @@ ifeq ($(codegen-targets),all)
|
|||||||
options := $(options)-all
|
options := $(options)-all
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
aot-only = false
|
||||||
root := $(shell (cd .. && pwd))
|
root := $(shell (cd .. && pwd))
|
||||||
build = build/$(platform)-$(arch)$(options)
|
build = build/$(platform)-$(arch)$(options)
|
||||||
|
host-build-root = $(build)/host
|
||||||
classpath-build = $(build)/classpath
|
classpath-build = $(build)/classpath
|
||||||
test-build = $(build)/test
|
test-build = $(build)/test
|
||||||
src = src
|
src = src
|
||||||
@ -64,6 +66,8 @@ classpath-src = classpath
|
|||||||
test = test
|
test = test
|
||||||
win32 ?= $(root)/win32
|
win32 ?= $(root)/win32
|
||||||
win64 ?= $(root)/win64
|
win64 ?= $(root)/win64
|
||||||
|
winrt ?= $(root)/winrt
|
||||||
|
wp8 ?= $(root)/wp8
|
||||||
|
|
||||||
classpath = avian
|
classpath = avian
|
||||||
|
|
||||||
@ -180,7 +184,7 @@ dlltool = dlltool
|
|||||||
vg = nice valgrind --num-callers=32 --db-attach=yes --freelist-vol=100000000
|
vg = nice valgrind --num-callers=32 --db-attach=yes --freelist-vol=100000000
|
||||||
vg += --leak-check=full --suppressions=valgrind.supp
|
vg += --leak-check=full --suppressions=valgrind.supp
|
||||||
db = gdb --args
|
db = gdb --args
|
||||||
javac = "$(JAVA_HOME)/bin/javac"
|
javac = "$(JAVA_HOME)/bin/javac" -encoding UTF-8
|
||||||
javah = "$(JAVA_HOME)/bin/javah"
|
javah = "$(JAVA_HOME)/bin/javah"
|
||||||
jar = "$(JAVA_HOME)/bin/jar"
|
jar = "$(JAVA_HOME)/bin/jar"
|
||||||
strip = strip
|
strip = strip
|
||||||
@ -188,6 +192,18 @@ strip-all = --strip-all
|
|||||||
|
|
||||||
rdynamic = -rdynamic
|
rdynamic = -rdynamic
|
||||||
|
|
||||||
|
cflags_debug = -O0 -g3
|
||||||
|
cflags_debug_fast = -O0 -g3
|
||||||
|
cflags_stress = -O0 -g3
|
||||||
|
cflags_stress_major = -O0 -g3
|
||||||
|
ifeq ($(use-clang),true)
|
||||||
|
cflags_fast = -O4 -g3
|
||||||
|
cflags_small = -Oz -g3
|
||||||
|
else
|
||||||
|
cflags_fast = -O3 -g3
|
||||||
|
cflags_small = -Os -g3
|
||||||
|
endif
|
||||||
|
|
||||||
# note that we suppress the non-virtual-dtor warning because we never
|
# note that we suppress the non-virtual-dtor warning because we never
|
||||||
# use the delete operator, which means we don't need virtual
|
# use the delete operator, which means we don't need virtual
|
||||||
# destructors:
|
# destructors:
|
||||||
@ -203,7 +219,7 @@ common-cflags = $(warnings) -fno-rtti -fno-exceptions -I$(classpath-src) \
|
|||||||
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \
|
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \
|
||||||
-DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" $(target-cflags)
|
-DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" $(target-cflags)
|
||||||
|
|
||||||
asmflags = $(target-cflags)
|
asmflags = $(target-cflags) -I$(src)
|
||||||
|
|
||||||
ifneq (,$(filter i386 x86_64,$(arch)))
|
ifneq (,$(filter i386 x86_64,$(arch)))
|
||||||
ifeq ($(use-frame-pointer),true)
|
ifeq ($(use-frame-pointer),true)
|
||||||
@ -242,13 +258,29 @@ pointer-size = 8
|
|||||||
so-prefix = lib
|
so-prefix = lib
|
||||||
so-suffix = .so
|
so-suffix = .so
|
||||||
|
|
||||||
|
static-prefix = lib
|
||||||
|
static-suffix = .a
|
||||||
|
|
||||||
|
output = -o $(1)
|
||||||
|
asm-output = -o $(1)
|
||||||
|
asm-input = -c $(1)
|
||||||
|
asm-format = S
|
||||||
|
as = $(cc)
|
||||||
|
ld = $(cxx)
|
||||||
|
build-ld = $(build-cc)
|
||||||
|
|
||||||
|
static = -static
|
||||||
shared = -shared
|
shared = -shared
|
||||||
|
|
||||||
|
rpath = -Wl,-rpath=\$$ORIGIN -Wl,-z,origin
|
||||||
|
|
||||||
no-error = -Wno-error
|
no-error = -Wno-error
|
||||||
|
|
||||||
openjdk-extra-cflags = -fvisibility=hidden
|
openjdk-extra-cflags = -fvisibility=hidden
|
||||||
|
|
||||||
bootimage-cflags = -DTARGET_BYTES_PER_WORD=$(pointer-size)
|
bootimage-cflags = -DTARGET_BYTES_PER_WORD=$(pointer-size)
|
||||||
|
bootimage-symbols = _binary_bootimage_bin_start:_binary_bootimage_bin_end
|
||||||
|
codeimage-symbols = _binary_codeimage_bin_start:_binary_codeimage_bin_end
|
||||||
|
|
||||||
developer-dir := $(shell if test -d /Developer; then echo /Developer; \
|
developer-dir := $(shell if test -d /Developer; then echo /Developer; \
|
||||||
else echo /Applications/Xcode.app/Contents/Developer; fi)
|
else echo /Applications/Xcode.app/Contents/Developer; fi)
|
||||||
@ -358,6 +390,70 @@ ifeq ($(platform),freebsd)
|
|||||||
"-I$(JAVA_HOME)/include/freebsd" -I$(src) -pthread
|
"-I$(JAVA_HOME)/include/freebsd" -I$(src) -pthread
|
||||||
cflags = $(build-cflags)
|
cflags = $(build-cflags)
|
||||||
endif
|
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)
|
ifeq ($(platform),darwin)
|
||||||
target-format = macho
|
target-format = macho
|
||||||
@ -396,6 +492,7 @@ ifeq ($(platform),darwin)
|
|||||||
strip-all = -S -x
|
strip-all = -S -x
|
||||||
so-suffix = .dylib
|
so-suffix = .dylib
|
||||||
shared = -dynamiclib
|
shared = -dynamiclib
|
||||||
|
rpath =
|
||||||
|
|
||||||
sdk-dir = $(developer-dir)/Platforms/iPhoneOS.platform/Developer/SDKs
|
sdk-dir = $(developer-dir)/Platforms/iPhoneOS.platform/Developer/SDKs
|
||||||
|
|
||||||
@ -443,20 +540,23 @@ ifeq ($(platform),darwin)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(platform),windows)
|
ifeq ($(platform),windows)
|
||||||
|
ifeq ($(target-format),)
|
||||||
target-format = pe
|
target-format = pe
|
||||||
|
endif
|
||||||
|
|
||||||
inc = "$(win32)/include"
|
inc = "$(win32)/include"
|
||||||
lib = "$(win32)/lib"
|
lib = "$(win32)/lib"
|
||||||
|
|
||||||
embed-prefix = c:/avian-embedded
|
embed-prefix = c:/avian-embedded
|
||||||
|
|
||||||
system = windows
|
system = windows
|
||||||
|
|
||||||
so-prefix =
|
so-prefix =
|
||||||
so-suffix = .dll
|
so-suffix = .dll
|
||||||
exe-suffix = .exe
|
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
|
cflags = -I$(inc) $(common-cflags) -DWINVER=0x0500
|
||||||
|
|
||||||
ifeq (,$(filter mingw32 cygwin,$(build-platform)))
|
ifeq (,$(filter mingw32 cygwin,$(build-platform)))
|
||||||
@ -502,89 +602,217 @@ ifeq ($(platform),windows)
|
|||||||
shared += -Wl,--add-stdcall-alias
|
shared += -Wl,--add-stdcall-alias
|
||||||
endif
|
endif
|
||||||
|
|
||||||
embed = $(build-embed)/embed.exe
|
embed = $(build-embed)/embed$(exe-suffix)
|
||||||
embed-loader = $(build-embed-loader)/embed-loader.exe
|
embed-loader = $(build-embed-loader)/embed-loader$(exe-suffix)
|
||||||
embed-loader-o = $(build-embed)/embed-loader.o
|
embed-loader-o = $(build-embed)/embed-loader.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(mode),debug)
|
ifeq ($(platform),wp8)
|
||||||
optimization-cflags = -O0 -g3
|
ifeq ($(shell uname -s | grep -i -c WOW64),1)
|
||||||
converter-cflags += -O0 -g3
|
programFiles = Program Files (x86)
|
||||||
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
|
|
||||||
else
|
else
|
||||||
optimization-cflags = -O3 -g3 -DNDEBUG
|
programFiles = Program Files
|
||||||
endif
|
endif
|
||||||
use-lto = true
|
ifeq ($(MSVS_ROOT),)
|
||||||
endif
|
# Environment variable MSVS_ROOT not found. It should be something like
|
||||||
ifeq ($(mode),small)
|
# "C:\$(programFiles)\Microsoft Visual Studio 11.0"
|
||||||
ifeq ($(use-clang),true)
|
MSVS_ROOT = C:\$(programFiles)\Microsoft Visual Studio 11.0
|
||||||
optimization-cflags = -Oz -g3 -DNDEBUG
|
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
|
else
|
||||||
optimization-cflags = -Os -g3 -DNDEBUG
|
windows-path = $(native-path)
|
||||||
endif
|
endif
|
||||||
use-lto = true
|
windows-java-home := $(shell $(windows-path) "$(JAVA_HOME)")
|
||||||
endif
|
target-format = pe
|
||||||
|
ms_cl_compiler = wp8
|
||||||
ifeq ($(use-lto),true)
|
use-lto = false
|
||||||
ifeq ($(use-clang),true)
|
supports_avian_executable = false
|
||||||
optimization-cflags += -flto
|
aot-only = true
|
||||||
lflags += $(optimization-cflags)
|
ifneq ($(bootimage),true)
|
||||||
else
|
x := $(error Windows Phone 8 target requires bootimage=true)
|
||||||
# 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
|
||||||
|
system = windows
|
||||||
|
build-system = windows
|
||||||
|
static-prefix =
|
||||||
|
static-suffix = .lib
|
||||||
|
so-prefix =
|
||||||
|
so-suffix = .dll
|
||||||
|
exe-suffix = .exe
|
||||||
|
manifest-flags = -MANIFEST:NO
|
||||||
|
|
||||||
|
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
|
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
|
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
|
ifdef msvc
|
||||||
static =
|
|
||||||
no-error =
|
no-error =
|
||||||
windows-path = $(native-path)
|
windows-path = $(native-path)
|
||||||
windows-java-home := $(shell $(windows-path) "$(JAVA_HOME)")
|
windows-java-home := $(shell $(windows-path) "$(JAVA_HOME)")
|
||||||
zlib := $(shell $(windows-path) "$(win32)/msvc")
|
zlib := $(shell $(windows-path) "$(win32)/msvc")
|
||||||
|
ms_cl_compiler = regular
|
||||||
cxx = "$(msvc)/BIN/cl.exe"
|
cxx = "$(msvc)/BIN/cl.exe"
|
||||||
cc = $(cxx)
|
cc = $(cxx)
|
||||||
ld = "$(msvc)/BIN/link.exe"
|
ld = "$(msvc)/BIN/link.exe"
|
||||||
mt = "mt.exe"
|
mt = "mt.exe"
|
||||||
|
manifest-flags = -MANIFEST -MANIFESTFILE:$(@).manifest
|
||||||
cflags = -nologo -DAVIAN_VERSION=\"$(version)\" -D_JNI_IMPLEMENTATION_ \
|
cflags = -nologo -DAVIAN_VERSION=\"$(version)\" -D_JNI_IMPLEMENTATION_ \
|
||||||
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \
|
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \
|
||||||
-DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" \
|
-DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" \
|
||||||
@ -620,9 +848,70 @@ ifdef msvc
|
|||||||
strip = :
|
strip = :
|
||||||
endif
|
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)))
|
c-objects = $(foreach x,$(1),$(patsubst $(2)/%.c,$(3)/%.o,$(x)))
|
||||||
cpp-objects = $(foreach x,$(1),$(patsubst $(2)/%.cpp,$(3)/%.o,$(x)))
|
cpp-objects = $(foreach x,$(1),$(patsubst $(2)/%.cpp,$(3)/%.o,$(x)))
|
||||||
asm-objects = $(foreach x,$(1),$(patsubst $(2)/%.S,$(3)/%-asm.o,$(x)))
|
asm-objects = $(foreach x,$(1),$(patsubst $(2)/%.$(asm-format),$(3)/%-asm.o,$(x)))
|
||||||
java-classes = $(foreach x,$(1),$(patsubst $(2)/%.java,$(3)/%.class,$(x)))
|
java-classes = $(foreach x,$(1),$(patsubst $(2)/%.java,$(3)/%.class,$(x)))
|
||||||
|
|
||||||
generated-code = \
|
generated-code = \
|
||||||
@ -648,7 +937,7 @@ vm-sources = \
|
|||||||
$(src)/jnienv.cpp \
|
$(src)/jnienv.cpp \
|
||||||
$(src)/process.cpp
|
$(src)/process.cpp
|
||||||
|
|
||||||
vm-asm-sources = $(src)/$(asm).S
|
vm-asm-sources = $(src)/$(asm).$(asm-format)
|
||||||
|
|
||||||
target-asm = $(asm)
|
target-asm = $(asm)
|
||||||
|
|
||||||
@ -677,7 +966,11 @@ ifeq ($(process),compile)
|
|||||||
$(src)/codegen/powerpc/assembler.cpp
|
$(src)/codegen/powerpc/assembler.cpp
|
||||||
endif
|
endif
|
||||||
|
|
||||||
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
|
endif
|
||||||
|
|
||||||
vm-cpp-objects = $(call cpp-objects,$(vm-sources),$(src),$(build))
|
vm-cpp-objects = $(call cpp-objects,$(vm-sources),$(src),$(build))
|
||||||
@ -810,10 +1103,10 @@ converter-objects = $(call cpp-objects,$(converter-sources),$(src),$(build))
|
|||||||
converter-tool-objects = $(call cpp-objects,$(converter-tool-sources),$(src),$(build))
|
converter-tool-objects = $(call cpp-objects,$(converter-tool-sources),$(src),$(build))
|
||||||
converter = $(build)/binaryToObject/binaryToObject
|
converter = $(build)/binaryToObject/binaryToObject
|
||||||
|
|
||||||
static-library = $(build)/lib$(name).a
|
static-library = $(build)/$(static-prefix)$(name)$(static-suffix)
|
||||||
executable = $(build)/$(name)${exe-suffix}
|
executable = $(build)/$(name)${exe-suffix}
|
||||||
dynamic-library = $(build)/$(so-prefix)jvm$(so-suffix)
|
dynamic-library = $(build)/$(so-prefix)jvm$(so-suffix)
|
||||||
executable-dynamic = $(build)/$(name)-dynamic${exe-suffix}
|
executable-dynamic = $(build)/$(name)-dynamic$(exe-suffix)
|
||||||
|
|
||||||
ifneq ($(classpath),avian)
|
ifneq ($(classpath),avian)
|
||||||
# Assembler, ConstantPool, and Stream are not technically needed for a
|
# Assembler, ConstantPool, and Stream are not technically needed for a
|
||||||
@ -920,9 +1213,15 @@ test-flags = -Djava.library.path=$(build) -cp $(build)/test
|
|||||||
test-args = $(test-flags) $(input)
|
test-args = $(test-flags) $(input)
|
||||||
|
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
|
ifneq ($(supports_avian_executable),false)
|
||||||
build: $(static-library) $(executable) $(dynamic-library) $(lzma-loader) \
|
build: $(static-library) $(executable) $(dynamic-library) $(lzma-loader) \
|
||||||
$(lzma-encoder) $(executable-dynamic) $(classpath-dep) $(test-dep) \
|
$(lzma-encoder) $(executable-dynamic) $(classpath-dep) $(test-dep) \
|
||||||
$(test-extra-dep) $(embed)
|
$(test-extra-dep) $(embed)
|
||||||
|
else
|
||||||
|
build: $(static-library) $(dynamic-library) $(lzma-loader) \
|
||||||
|
$(lzma-encoder) $(classpath-dep) $(test-dep) \
|
||||||
|
$(test-extra-dep) $(embed)
|
||||||
|
endif
|
||||||
|
|
||||||
$(test-dep): $(classpath-dep)
|
$(test-dep): $(classpath-dep)
|
||||||
|
|
||||||
@ -962,12 +1261,24 @@ javadoc:
|
|||||||
-header "Avian v$(version)" \
|
-header "Avian v$(version)" \
|
||||||
-bottom "<a href=\"http://oss.readytalk.com/avian/\">http://oss.readytalk.com/avian</a>"
|
-bottom "<a href=\"http://oss.readytalk.com/avian/\">http://oss.readytalk.com/avian</a>"
|
||||||
|
|
||||||
|
.PHONY: clean-current
|
||||||
|
clean-current:
|
||||||
|
@echo "removing $(build)"
|
||||||
|
rm -rf $(build)
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
|
@echo "removing $(build)"
|
||||||
|
rm -rf $(build)
|
||||||
|
|
||||||
|
.PHONY: clean-all
|
||||||
|
clean-all:
|
||||||
@echo "removing build"
|
@echo "removing build"
|
||||||
rm -rf 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:')
|
gen-arg = $(shell echo $(1) | sed -e 's:$(build)/type-\(.*\)\.cpp:\1:')
|
||||||
$(generated-code): %.cpp: $(src)/types.def $(generator) $(classpath-dep)
|
$(generated-code): %.cpp: $(src)/types.def $(generator) $(classpath-dep)
|
||||||
@ -1018,7 +1329,7 @@ endef
|
|||||||
define compile-asm-object
|
define compile-asm-object
|
||||||
@echo "compiling $(@)"
|
@echo "compiling $(@)"
|
||||||
@mkdir -p $(dir $(@))
|
@mkdir -p $(dir $(@))
|
||||||
$(as) -I$(src) $(asmflags) -c $(<) -o $(@)
|
$(as) $(asmflags) $(call asm-output,$(@)) $(call asm-input,$(<))
|
||||||
endef
|
endef
|
||||||
|
|
||||||
$(vm-cpp-objects): $(build)/%.o: $(src)/%.cpp $(vm-depends)
|
$(vm-cpp-objects): $(build)/%.o: $(src)/%.cpp $(vm-depends)
|
||||||
@ -1029,10 +1340,13 @@ $(test-cpp-objects): $(test-build)/%.o: $(test)/%.cpp $(vm-depends)
|
|||||||
|
|
||||||
$(test-library): $(test-cpp-objects)
|
$(test-library): $(test-cpp-objects)
|
||||||
@echo "linking $(@)"
|
@echo "linking $(@)"
|
||||||
ifdef msvc
|
ifdef ms_cl_compiler
|
||||||
$(ld) $(shared) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb \
|
$(ld) $(shared) $(lflags) $(^) -out:$(@) \
|
||||||
-IMPLIB:$(test-build)/$(name).lib -MANIFESTFILE:$(@).manifest
|
-debug -PDB:$(subst $(so-suffix),.pdb,$(@)) \
|
||||||
$(mt) -manifest $(@).manifest -outputresource:"$(@);2"
|
-IMPLIB:$(test-build)/$(name).lib $(manifest-flags)
|
||||||
|
ifdef mt
|
||||||
|
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);2"
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
$(ld) $(^) $(shared) $(lflags) -o $(@)
|
$(ld) $(^) $(shared) $(lflags) -o $(@)
|
||||||
endif
|
endif
|
||||||
@ -1040,10 +1354,12 @@ endif
|
|||||||
ifdef embed
|
ifdef embed
|
||||||
$(embed): $(embed-objects) $(embed-loader-o)
|
$(embed): $(embed-objects) $(embed-loader-o)
|
||||||
@echo "building $(embed)"
|
@echo "building $(embed)"
|
||||||
ifdef msvc
|
ifdef ms_cl_compiler
|
||||||
$(ld) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb \
|
$(ld) $(lflags) $(^) -out:$(@) \
|
||||||
-IMPLIB:$(@).lib -MANIFESTFILE:$(@).manifest
|
-debug -PDB:$(subst $(exe-suffix),.pdb,$(@)) $(manifest-flags)
|
||||||
$(mt) -manifest $(@).manifest -outputresource:"$(@);1"
|
ifdef mt
|
||||||
|
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);1"
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
$(cxx) $(^) $(lflags) $(static) $(call output,$(@))
|
$(cxx) $(^) $(lflags) $(static) $(call output,$(@))
|
||||||
endif
|
endif
|
||||||
@ -1061,10 +1377,12 @@ $(embed-loader-o): $(embed-loader) $(converter)
|
|||||||
$(embed-loader): $(embed-loader-objects) $(static-library)
|
$(embed-loader): $(embed-loader-objects) $(static-library)
|
||||||
@mkdir -p $(dir $(@))
|
@mkdir -p $(dir $(@))
|
||||||
cd $(dir $(@)) && $(ar) x ../../../$(static-library)
|
cd $(dir $(@)) && $(ar) x ../../../$(static-library)
|
||||||
ifdef msvc
|
ifdef ms_cl_compiler
|
||||||
$(ld) $(lflags) $(dir $(@))/*.o -out:$(@) -PDB:$(@).pdb \
|
$(ld) $(lflags) $(dir $(@))/*.o -out:$(@) \
|
||||||
-IMPLIB:$(@).lib -MANIFESTFILE:$(@).manifest
|
-debug -PDB:$(subst $(exe-suffix),.pdb,$(@)) $(manifest-flags)
|
||||||
$(mt) -manifest $(@).manifest -outputresource:"$(@);1"
|
ifdef mt
|
||||||
|
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);1"
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
$(dlltool) -z $(addsuffix .def,$(basename $(@))) $(dir $(@))/*.o
|
$(dlltool) -z $(addsuffix .def,$(basename $(@))) $(dir $(@))/*.o
|
||||||
$(dlltool) -d $(addsuffix .def,$(basename $(@))) -e $(addsuffix .exp,$(basename $(@)))
|
$(dlltool) -d $(addsuffix .def,$(basename $(@))) -e $(addsuffix .exp,$(basename $(@)))
|
||||||
@ -1084,7 +1402,7 @@ $(build)/%.o: $(lzma)/C/%.c
|
|||||||
@mkdir -p $(dir $(@))
|
@mkdir -p $(dir $(@))
|
||||||
$(cxx) $(cflags) $(no-error) -c $$($(windows-path) $(<)) $(call output,$(@))
|
$(cxx) $(cflags) $(no-error) -c $$($(windows-path) $(<)) $(call output,$(@))
|
||||||
|
|
||||||
$(vm-asm-objects): $(build)/%-asm.o: $(src)/%.S
|
$(vm-asm-objects): $(build)/%-asm.o: $(src)/%.$(asm-format)
|
||||||
$(compile-asm-object)
|
$(compile-asm-object)
|
||||||
|
|
||||||
$(bootimage-generator-objects): $(build)/%.o: $(src)/%.cpp $(vm-depends)
|
$(bootimage-generator-objects): $(build)/%.o: $(src)/%.cpp $(vm-depends)
|
||||||
@ -1171,14 +1489,19 @@ $(static-library): $(vm-objects) $(classpath-objects) $(vm-heapwalk-objects) \
|
|||||||
$(javahome-object) $(boot-javahome-object) $(lzma-decode-objects)
|
$(javahome-object) $(boot-javahome-object) $(lzma-decode-objects)
|
||||||
@echo "creating $(@)"
|
@echo "creating $(@)"
|
||||||
rm -rf $(@)
|
rm -rf $(@)
|
||||||
|
ifdef ms_cl_compiler
|
||||||
|
$(ar) $(arflags) $(^) -out:$(@)
|
||||||
|
else
|
||||||
$(ar) cru $(@) $(^)
|
$(ar) cru $(@) $(^)
|
||||||
$(ranlib) $(@)
|
$(ranlib) $(@)
|
||||||
|
endif
|
||||||
|
|
||||||
$(bootimage-object) $(codeimage-object): $(bootimage-generator) \
|
$(bootimage-object) $(codeimage-object): $(bootimage-generator) \
|
||||||
$(build)/classpath.jar
|
$(openjdk-jar-dep)
|
||||||
|
@echo "generating bootimage and codeimage binaries from $(classpath-build) using $(<)"
|
||||||
$(<) -cp $(classpath-build) -bootimage $(bootimage-object) -codeimage $(codeimage-object) \
|
$(<) -cp $(classpath-build) -bootimage $(bootimage-object) -codeimage $(codeimage-object) \
|
||||||
-bootimage-symbols _binary_bootimage_bin_start:_binary_bootimage_bin_end \
|
-bootimage-symbols $(bootimage-symbols) \
|
||||||
-codeimage-symbols _binary_codeimage_bin_start:_binary_codeimage_bin_end
|
-codeimage-symbols $(codeimage-symbols)
|
||||||
|
|
||||||
executable-objects = $(vm-objects) $(classpath-objects) $(driver-object) \
|
executable-objects = $(vm-objects) $(classpath-objects) $(driver-object) \
|
||||||
$(vm-heapwalk-objects) $(boot-object) $(vm-classpath-objects) \
|
$(vm-heapwalk-objects) $(boot-object) $(vm-classpath-objects) \
|
||||||
@ -1187,10 +1510,12 @@ executable-objects = $(vm-objects) $(classpath-objects) $(driver-object) \
|
|||||||
$(executable): $(executable-objects)
|
$(executable): $(executable-objects)
|
||||||
@echo "linking $(@)"
|
@echo "linking $(@)"
|
||||||
ifeq ($(platform),windows)
|
ifeq ($(platform),windows)
|
||||||
ifdef msvc
|
ifdef ms_cl_compiler
|
||||||
$(ld) $(lflags) $(executable-objects) -out:$(@) -PDB:$(@).pdb \
|
$(ld) $(lflags) $(executable-objects) -out:$(@) \
|
||||||
-IMPLIB:$(@).lib -MANIFESTFILE:$(@).manifest
|
-debug -PDB:$(subst $(exe-suffix),.pdb,$(@)) $(manifest-flags)
|
||||||
$(mt) -manifest $(@).manifest -outputresource:"$(@);1"
|
ifdef mt
|
||||||
|
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);1"
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
$(dlltool) -z $(@).def $(executable-objects)
|
$(dlltool) -z $(@).def $(executable-objects)
|
||||||
$(dlltool) -d $(@).def -e $(@).exp
|
$(dlltool) -d $(@).def -e $(@).exp
|
||||||
@ -1202,9 +1527,11 @@ endif
|
|||||||
$(strip) $(strip-all) $(@)
|
$(strip) $(strip-all) $(@)
|
||||||
|
|
||||||
$(bootimage-generator): $(bootimage-generator-objects)
|
$(bootimage-generator): $(bootimage-generator-objects)
|
||||||
echo arch=$(arch) platform=$(platform)
|
echo building $(bootimage-generator) arch=$(build-arch) platform=$(bootimage-platform)
|
||||||
$(MAKE) mode=$(mode) \
|
$(MAKE) mode=$(mode) \
|
||||||
|
build=$(host-build-root) \
|
||||||
arch=$(build-arch) \
|
arch=$(build-arch) \
|
||||||
|
aot-only=false \
|
||||||
target-arch=$(arch) \
|
target-arch=$(arch) \
|
||||||
platform=$(bootimage-platform) \
|
platform=$(bootimage-platform) \
|
||||||
target-format=$(target-format) \
|
target-format=$(target-format) \
|
||||||
@ -1222,17 +1549,19 @@ $(build-bootimage-generator): \
|
|||||||
$(lzma-decode-objects) $(lzma-encode-objects)
|
$(lzma-decode-objects) $(lzma-encode-objects)
|
||||||
@echo "linking $(@)"
|
@echo "linking $(@)"
|
||||||
ifeq ($(platform),windows)
|
ifeq ($(platform),windows)
|
||||||
ifdef msvc
|
ifdef ms_cl_compiler
|
||||||
$(ld) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb -IMPLIB:$(@).lib \
|
$(ld) $(bootimage-generator-lflags) $(lflags) $(^) -out:$(@) \
|
||||||
-MANIFESTFILE:$(@).manifest
|
-debug -PDB:$(subst $(exe-suffix),.pdb,$(@)) $(manifest-flags)
|
||||||
$(mt) -manifest $(@).manifest -outputresource:"$(@);1"
|
ifdef mt
|
||||||
|
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);1"
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
$(dlltool) -z $(@).def $(^)
|
$(dlltool) -z $(@).def $(^)
|
||||||
$(dlltool) -d $(@).def -e $(@).exp
|
$(dlltool) -d $(@).def -e $(@).exp
|
||||||
$(ld) $(@).exp $(^) $(lflags) -o $(@)
|
$(ld) $(@).exp $(^) $(bootimage-generator-lflags) $(lflags) -o $(@)
|
||||||
endif
|
endif
|
||||||
else
|
else
|
||||||
$(ld) $(^) $(rdynamic) $(lflags) -o $(@)
|
$(ld) $(^) $(rdynamic) $(bootimage-generator-lflags) $(lflags) -o $(@)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(dynamic-library): $(vm-objects) $(dynamic-object) $(classpath-objects) \
|
$(dynamic-library): $(vm-objects) $(dynamic-object) $(classpath-objects) \
|
||||||
@ -1240,10 +1569,13 @@ $(dynamic-library): $(vm-objects) $(dynamic-object) $(classpath-objects) \
|
|||||||
$(classpath-libraries) $(javahome-object) $(boot-javahome-object) \
|
$(classpath-libraries) $(javahome-object) $(boot-javahome-object) \
|
||||||
$(lzma-decode-objects)
|
$(lzma-decode-objects)
|
||||||
@echo "linking $(@)"
|
@echo "linking $(@)"
|
||||||
ifdef msvc
|
ifdef ms_cl_compiler
|
||||||
$(ld) $(shared) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb \
|
$(ld) $(shared) $(lflags) $(^) -out:$(@) \
|
||||||
-IMPLIB:$(build)/$(name).lib -MANIFESTFILE:$(@).manifest
|
-debug -PDB:$(subst $(so-suffix),.pdb,$(@)) \
|
||||||
$(mt) -manifest $(@).manifest -outputresource:"$(@);2"
|
-IMPLIB:$(subst $(so-suffix),.lib,$(@)) $(manifest-flags)
|
||||||
|
ifdef mt
|
||||||
|
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);2"
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
$(ld) $(^) $(version-script-flag) $(soname-flag) \
|
$(ld) $(^) $(version-script-flag) $(soname-flag) \
|
||||||
$(shared) $(lflags) $(bootimage-lflags) \
|
$(shared) $(lflags) $(bootimage-lflags) \
|
||||||
@ -1255,13 +1587,15 @@ endif
|
|||||||
# Ubuntu 11.10 which may be fixable without disabling LTO.
|
# Ubuntu 11.10 which may be fixable without disabling LTO.
|
||||||
$(executable-dynamic): $(driver-dynamic-objects) $(dynamic-library)
|
$(executable-dynamic): $(driver-dynamic-objects) $(dynamic-library)
|
||||||
@echo "linking $(@)"
|
@echo "linking $(@)"
|
||||||
ifdef msvc
|
ifdef ms_cl_compiler
|
||||||
$(ld) $(lflags) -LIBPATH:$(build) -DEFAULTLIB:$(name) \
|
$(ld) $(lflags) -LIBPATH:$(build) -DEFAULTLIB:$(name) \
|
||||||
-PDB:$(@).pdb -IMPLIB:$(@).lib $(driver-dynamic-objects) -out:$(@) \
|
-debug -PDB:$(subst $(exe-suffix),.pdb,$(@))
|
||||||
-MANIFESTFILE:$(@).manifest
|
$(driver-dynamic-objects) -out:$(@) $(manifest-flags)
|
||||||
$(mt) -manifest $(@).manifest -outputresource:"$(@);1"
|
ifdef mt
|
||||||
|
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);1"
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
$(ld) $(driver-dynamic-objects) -L$(build) -ljvm $(lflags) $(no-lto) -o $(@)
|
$(ld) $(driver-dynamic-objects) -L$(build) -ljvm $(lflags) $(no-lto) $(rpath) -o $(@)
|
||||||
endif
|
endif
|
||||||
$(strip) $(strip-all) $(@)
|
$(strip) $(strip-all) $(@)
|
||||||
|
|
||||||
|
28
src/arm.h
28
src/arm.h
@ -71,33 +71,57 @@ namespace vm {
|
|||||||
inline void
|
inline void
|
||||||
trap()
|
trap()
|
||||||
{
|
{
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
__debugbreak();
|
||||||
|
#else
|
||||||
asm("bkpt");
|
asm("bkpt");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
inline void
|
inline void
|
||||||
memoryBarrier()
|
memoryBarrier()
|
||||||
{
|
{
|
||||||
asm("nop");
|
asm("nop");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
storeStoreMemoryBarrier()
|
storeStoreMemoryBarrier()
|
||||||
{
|
{
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
_ReadWriteBarrier();
|
||||||
|
#else
|
||||||
memoryBarrier();
|
memoryBarrier();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
storeLoadMemoryBarrier()
|
storeLoadMemoryBarrier()
|
||||||
{
|
{
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
MemoryBarrier();
|
||||||
|
#else
|
||||||
memoryBarrier();
|
memoryBarrier();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
loadMemoryBarrier()
|
loadMemoryBarrier()
|
||||||
{
|
{
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
_ReadWriteBarrier();
|
||||||
|
#else
|
||||||
memoryBarrier();
|
memoryBarrier();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(AVIAN_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
|
inline void
|
||||||
syncInstructionCache(const void* start, unsigned size)
|
syncInstructionCache(const void* start, unsigned size)
|
||||||
{
|
{
|
||||||
@ -112,6 +136,8 @@ syncInstructionCache(const void* start, unsigned size)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // AVIAN_AOT_ONLY
|
||||||
|
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr);
|
typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr);
|
||||||
# define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0)
|
# define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0)
|
||||||
@ -156,7 +182,7 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
|
|||||||
unsigned vfpIndex = 0;
|
unsigned vfpIndex = 0;
|
||||||
unsigned vfpBackfillIndex UNUSED = 0;
|
unsigned vfpBackfillIndex UNUSED = 0;
|
||||||
|
|
||||||
uintptr_t stack[(argumentCount * 8) / BytesPerWord]; // is > argumentSize to account for padding
|
RUNTIME_ARRAY(uintptr_t, stack, (argumentCount * 8) / BytesPerWord); // is > argumentSize to account for padding
|
||||||
unsigned stackIndex = 0;
|
unsigned stackIndex = 0;
|
||||||
|
|
||||||
unsigned ai = 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 {
|
namespace {
|
||||||
|
|
||||||
|
// --- winnt.h ----
|
||||||
#define IMAGE_SIZEOF_SHORT_NAME 8
|
#define IMAGE_SIZEOF_SHORT_NAME 8
|
||||||
|
|
||||||
#define IMAGE_FILE_RELOCS_STRIPPED 1
|
#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file.
|
||||||
#define IMAGE_FILE_LINE_NUMS_STRIPPED 4
|
#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file.
|
||||||
#define IMAGE_FILE_MACHINE_AMD64 0x8664
|
#define IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8)
|
||||||
#define IMAGE_FILE_MACHINE_I386 0x014c
|
#define IMAGE_FILE_MACHINE_I386 0x014c // Intel 386.
|
||||||
#define IMAGE_FILE_32BIT_MACHINE 256
|
#define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian
|
||||||
|
#define IMAGE_FILE_MACHINE_THUMB 0x01c2 // ARM Thumb/Thumb-2 Little-Endian
|
||||||
|
#define IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARM Thumb-2 Little-Endian
|
||||||
|
#define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine.
|
||||||
|
|
||||||
#define IMAGE_SCN_ALIGN_1BYTES 0x100000
|
#define IMAGE_SCN_ALIGN_1BYTES 0x100000
|
||||||
#define IMAGE_SCN_ALIGN_2BYTES 0x200000
|
#define IMAGE_SCN_ALIGN_2BYTES 0x200000
|
||||||
@ -73,6 +77,7 @@ struct IMAGE_SYMBOL {
|
|||||||
uint8_t StorageClass;
|
uint8_t StorageClass;
|
||||||
uint8_t NumberOfAuxSymbols;
|
uint8_t NumberOfAuxSymbols;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
// --- winnt.h ----
|
||||||
|
|
||||||
inline unsigned
|
inline unsigned
|
||||||
pad(unsigned n)
|
pad(unsigned n)
|
||||||
@ -82,7 +87,7 @@ pad(unsigned n)
|
|||||||
|
|
||||||
using namespace avian::tools;
|
using namespace avian::tools;
|
||||||
|
|
||||||
template<unsigned BytesPerWord>
|
template<unsigned BytesPerWord, PlatformInfo::Architecture Architecture>
|
||||||
class WindowsPlatform : public Platform {
|
class WindowsPlatform : public Platform {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -202,12 +207,15 @@ public:
|
|||||||
int machine;
|
int machine;
|
||||||
int machineMask;
|
int machineMask;
|
||||||
|
|
||||||
if (BytesPerWord == 8) {
|
if (Architecture == PlatformInfo::x86_64) {
|
||||||
machine = IMAGE_FILE_MACHINE_AMD64;
|
machine = IMAGE_FILE_MACHINE_AMD64;
|
||||||
machineMask = 0;
|
machineMask = 0;
|
||||||
} else { // if (BytesPerWord == 8)
|
} else if (Architecture == PlatformInfo::x86) {
|
||||||
machine = IMAGE_FILE_MACHINE_I386;
|
machine = IMAGE_FILE_MACHINE_I386;
|
||||||
machineMask = IMAGE_FILE_32BIT_MACHINE;
|
machineMask = IMAGE_FILE_32BIT_MACHINE;
|
||||||
|
} else if (Architecture == PlatformInfo::Arm) {
|
||||||
|
machine = IMAGE_FILE_MACHINE_ARMNT;
|
||||||
|
machineMask = IMAGE_FILE_32BIT_MACHINE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sectionMask;
|
int sectionMask;
|
||||||
@ -269,10 +277,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
WindowsPlatform():
|
WindowsPlatform():
|
||||||
Platform(PlatformInfo(PlatformInfo::Pe, BytesPerWord == 4 ? PlatformInfo::x86 : PlatformInfo::x86_64)) {}
|
Platform(PlatformInfo(PlatformInfo::Pe, Architecture)) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
WindowsPlatform<4> windows32Platform;
|
WindowsPlatform<4, PlatformInfo::x86> windows32Platform;
|
||||||
WindowsPlatform<8> windows64Platform;
|
WindowsPlatform<8, PlatformInfo::x86_64> windows64Platform;
|
||||||
|
WindowsPlatform<4, PlatformInfo::Arm> windowsRtPlatform; // Windows Phone 8 and Windows RT
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -342,7 +342,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
|||||||
|
|
||||||
unsigned count = s.read2() - 1;
|
unsigned count = s.read2() - 1;
|
||||||
if (count) {
|
if (count) {
|
||||||
Type types[count + 2];
|
THREAD_RUNTIME_ARRAY(t, Type, types, count + 2);
|
||||||
types[0] = Type_object;
|
types[0] = Type_object;
|
||||||
types[1] = Type_intptr_t;
|
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);
|
object fields = allFields(t, typeMaps, c, &count, &array);
|
||||||
PROTECT(t, fields);
|
PROTECT(t, fields);
|
||||||
|
|
||||||
Field memberFields[count + 1];
|
THREAD_RUNTIME_ARRAY(t, Field, memberFields, count + 1);
|
||||||
|
|
||||||
unsigned memberIndex;
|
unsigned memberIndex;
|
||||||
unsigned buildMemberOffset;
|
unsigned buildMemberOffset;
|
||||||
@ -444,7 +444,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
|||||||
++ memberIndex;
|
++ memberIndex;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
init(new (memberFields) Field, Type_object, 0, BytesPerWord, 0,
|
init(new (&memberFields[0]) Field, Type_object, 0, BytesPerWord, 0,
|
||||||
TargetBytesPerWord);
|
TargetBytesPerWord);
|
||||||
|
|
||||||
memberIndex = 1;
|
memberIndex = 1;
|
||||||
@ -454,15 +454,15 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
|||||||
|
|
||||||
const unsigned StaticHeader = 3;
|
const unsigned StaticHeader = 3;
|
||||||
|
|
||||||
Field staticFields[count + StaticHeader];
|
THREAD_RUNTIME_ARRAY(t, Field, staticFields, count + StaticHeader);
|
||||||
|
|
||||||
init(new (staticFields) Field, Type_object, 0, BytesPerWord, 0,
|
init(new (&staticFields[0]) Field, Type_object, 0, BytesPerWord, 0,
|
||||||
TargetBytesPerWord);
|
TargetBytesPerWord);
|
||||||
|
|
||||||
init(new (staticFields + 1) Field, Type_intptr_t, BytesPerWord,
|
init(new (&staticFields[1]) Field, Type_intptr_t, BytesPerWord,
|
||||||
BytesPerWord, TargetBytesPerWord, TargetBytesPerWord);
|
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);
|
BytesPerWord, TargetBytesPerWord * 2, TargetBytesPerWord);
|
||||||
|
|
||||||
unsigned staticIndex = StaticHeader;
|
unsigned staticIndex = StaticHeader;
|
||||||
@ -512,7 +512,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
|||||||
|
|
||||||
buildStaticOffset = fieldOffset(t, field);
|
buildStaticOffset = fieldOffset(t, field);
|
||||||
|
|
||||||
init(new (staticFields + staticIndex) Field, type,
|
init(new (&staticFields[staticIndex]) Field, type,
|
||||||
buildStaticOffset, buildSize, targetStaticOffset,
|
buildStaticOffset, buildSize, targetStaticOffset,
|
||||||
targetSize);
|
targetSize);
|
||||||
|
|
||||||
@ -526,7 +526,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
|||||||
|
|
||||||
buildMemberOffset = fieldOffset(t, field);
|
buildMemberOffset = fieldOffset(t, field);
|
||||||
|
|
||||||
init(new (memberFields + memberIndex) Field, type,
|
init(new (&memberFields[memberIndex]) Field, type,
|
||||||
buildMemberOffset, buildSize, targetMemberOffset,
|
buildMemberOffset, buildSize, targetMemberOffset,
|
||||||
targetSize);
|
targetSize);
|
||||||
|
|
||||||
@ -549,7 +549,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
|||||||
ceilingDivide(targetMemberOffset, TargetBytesPerWord), memberIndex);
|
ceilingDivide(targetMemberOffset, TargetBytesPerWord), memberIndex);
|
||||||
|
|
||||||
for (unsigned i = 0; i < memberIndex; ++i) {
|
for (unsigned i = 0; i < memberIndex; ++i) {
|
||||||
Field* f = memberFields + i;
|
Field* f = &memberFields[i];
|
||||||
|
|
||||||
expect(t, f->buildOffset
|
expect(t, f->buildOffset
|
||||||
< map->buildFixedSizeInWords * BytesPerWord);
|
< map->buildFixedSizeInWords * BytesPerWord);
|
||||||
@ -573,7 +573,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
|||||||
TypeMap::SingletonKind);
|
TypeMap::SingletonKind);
|
||||||
|
|
||||||
for (unsigned i = 0; i < staticIndex; ++i) {
|
for (unsigned i = 0; i < staticIndex; ++i) {
|
||||||
Field* f = staticFields + i;
|
Field* f = &staticFields[i];
|
||||||
|
|
||||||
expect(t, f->buildOffset
|
expect(t, f->buildOffset
|
||||||
< map->buildFixedSizeInWords * BytesPerWord);
|
< map->buildFixedSizeInWords * BytesPerWord);
|
||||||
@ -1334,9 +1334,9 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
|
|||||||
}
|
}
|
||||||
++ count;
|
++ count;
|
||||||
|
|
||||||
Field fields[count];
|
THREAD_RUNTIME_ARRAY(t, Field, fields, count);
|
||||||
|
|
||||||
init(new (fields) Field, Type_object, 0, BytesPerWord, 0,
|
init(new (&fields[0]) Field, Type_object, 0, BytesPerWord, 0,
|
||||||
TargetBytesPerWord);
|
TargetBytesPerWord);
|
||||||
|
|
||||||
unsigned buildOffset = BytesPerWord;
|
unsigned buildOffset = BytesPerWord;
|
||||||
@ -1414,7 +1414,7 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
|
|||||||
++ targetOffset;
|
++ targetOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
init(new (fields + j) Field, type, buildOffset, buildSize,
|
init(new (&fields[j]) Field, type, buildOffset, buildSize,
|
||||||
targetOffset, targetSize);
|
targetOffset, targetSize);
|
||||||
|
|
||||||
buildOffset += buildSize;
|
buildOffset += buildSize;
|
||||||
@ -1449,7 +1449,7 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
|
|||||||
targetArrayElementSize, arrayElementType);
|
targetArrayElementSize, arrayElementType);
|
||||||
|
|
||||||
for (unsigned j = 0; j < fixedFieldCount; ++j) {
|
for (unsigned j = 0; j < fixedFieldCount; ++j) {
|
||||||
Field* f = fields + j;
|
Field* f = &fields[j];
|
||||||
|
|
||||||
expect(t, f->buildOffset
|
expect(t, f->buildOffset
|
||||||
< map->buildFixedSizeInWords * BytesPerWord);
|
< 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));
|
Platform* platform = Platform::getPlatform(PlatformInfo((PlatformInfo::Format)AVIAN_TARGET_FORMAT, (PlatformInfo::Architecture)AVIAN_TARGET_ARCH));
|
||||||
|
|
||||||
// if(!platform) {
|
if(!platform) {
|
||||||
// fprintf(stderr, "unsupported platform: %s/%s\n", os, architecture);
|
fprintf(stderr, "unsupported platform: target-format = %d / target-arch = %d\n", AVIAN_TARGET_FORMAT, AVIAN_TARGET_ARCH);
|
||||||
// return false;
|
abort();
|
||||||
// }
|
}
|
||||||
|
|
||||||
SymbolInfo bootimageSymbols[] = {
|
SymbolInfo bootimageSymbols[] = {
|
||||||
SymbolInfo(0, bootimageStart),
|
SymbolInfo(0, bootimageStart),
|
||||||
@ -1768,7 +1768,7 @@ bool ArgParser::parse(int ac, const char** av) {
|
|||||||
}
|
}
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for(Arg* arg = first; arg; arg = arg->next) {
|
for(Arg* arg = first; arg; arg = arg->next) {
|
||||||
if(strcmp(arg->name, &av[i][1]) == 0) {
|
if(::strcmp(arg->name, &av[i][1]) == 0) {
|
||||||
found = true;
|
found = true;
|
||||||
if (arg->desc == 0) {
|
if (arg->desc == 0) {
|
||||||
arg->value = "true";
|
arg->value = "true";
|
||||||
|
@ -8,9 +8,12 @@
|
|||||||
There is NO WARRANTY for this software. See license.txt for
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
details. */
|
details. */
|
||||||
|
|
||||||
#include "codegen/assembler.h"
|
|
||||||
#include "alloc-vector.h"
|
#include "alloc-vector.h"
|
||||||
|
|
||||||
|
#include "codegen/assembler.h"
|
||||||
|
|
||||||
|
#include "util/runtime-array.h"
|
||||||
|
|
||||||
#define CAST1(x) reinterpret_cast<UnaryOperationType>(x)
|
#define CAST1(x) reinterpret_cast<UnaryOperationType>(x)
|
||||||
#define CAST2(x) reinterpret_cast<BinaryOperationType>(x)
|
#define CAST2(x) reinterpret_cast<BinaryOperationType>(x)
|
||||||
#define CAST3(x) reinterpret_cast<TernaryOperationType>(x)
|
#define CAST3(x) reinterpret_cast<TernaryOperationType>(x)
|
||||||
@ -18,7 +21,7 @@
|
|||||||
|
|
||||||
using namespace vm;
|
using namespace vm;
|
||||||
|
|
||||||
namespace {
|
namespace local {
|
||||||
|
|
||||||
namespace isa {
|
namespace isa {
|
||||||
// SYSTEM REGISTERS
|
// SYSTEM REGISTERS
|
||||||
@ -252,7 +255,7 @@ class MyBlock: public Assembler::Block {
|
|||||||
this->start = start;
|
this->start = start;
|
||||||
this->next = static_cast<MyBlock*>(next);
|
this->next = static_cast<MyBlock*>(next);
|
||||||
|
|
||||||
::resolve(this);
|
local::resolve(this);
|
||||||
|
|
||||||
return start + size + padding(this, size);
|
return start + size + padding(this, size);
|
||||||
}
|
}
|
||||||
@ -2150,7 +2153,7 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual unsigned argumentFootprint(unsigned footprint) {
|
virtual unsigned argumentFootprint(unsigned footprint) {
|
||||||
return ::argumentFootprint(footprint);
|
return local::argumentFootprint(footprint);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool argumentAlignment() {
|
virtual bool argumentAlignment() {
|
||||||
@ -2239,7 +2242,7 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
unsigned targetParameterFootprint, void** ip,
|
unsigned targetParameterFootprint, void** ip,
|
||||||
void** stack)
|
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);
|
mostRecent, targetParameterFootprint, ip, stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2552,19 +2555,20 @@ class MyAssembler: public Assembler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void pushFrame(unsigned argumentCount, ...) {
|
virtual void pushFrame(unsigned argumentCount, ...) {
|
||||||
struct {
|
struct Argument {
|
||||||
unsigned size;
|
unsigned size;
|
||||||
OperandType type;
|
OperandType type;
|
||||||
Operand* operand;
|
Operand* operand;
|
||||||
} arguments[argumentCount];
|
};
|
||||||
|
RUNTIME_ARRAY(Argument, arguments, argumentCount);
|
||||||
|
|
||||||
va_list a; va_start(a, argumentCount);
|
va_list a; va_start(a, argumentCount);
|
||||||
unsigned footprint = 0;
|
unsigned footprint = 0;
|
||||||
for (unsigned i = 0; i < argumentCount; ++i) {
|
for (unsigned i = 0; i < argumentCount; ++i) {
|
||||||
arguments[i].size = va_arg(a, unsigned);
|
RUNTIME_ARRAY_BODY(arguments)[i].size = va_arg(a, unsigned);
|
||||||
arguments[i].type = static_cast<OperandType>(va_arg(a, int));
|
RUNTIME_ARRAY_BODY(arguments)[i].type = static_cast<OperandType>(va_arg(a, int));
|
||||||
arguments[i].operand = va_arg(a, Operand*);
|
RUNTIME_ARRAY_BODY(arguments)[i].operand = va_arg(a, Operand*);
|
||||||
footprint += ceilingDivide(arguments[i].size, TargetBytesPerWord);
|
footprint += ceilingDivide(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord);
|
||||||
}
|
}
|
||||||
va_end(a);
|
va_end(a);
|
||||||
|
|
||||||
@ -2576,19 +2580,23 @@ class MyAssembler: public Assembler {
|
|||||||
Register dst(arch_->argumentRegister(i));
|
Register dst(arch_->argumentRegister(i));
|
||||||
|
|
||||||
apply(Move,
|
apply(Move,
|
||||||
arguments[i].size, arguments[i].type, arguments[i].operand,
|
RUNTIME_ARRAY_BODY(arguments)[i].size,
|
||||||
pad(arguments[i].size, TargetBytesPerWord), RegisterOperand,
|
RUNTIME_ARRAY_BODY(arguments)[i].type,
|
||||||
|
RUNTIME_ARRAY_BODY(arguments)[i].operand,
|
||||||
|
pad(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord), RegisterOperand,
|
||||||
&dst);
|
&dst);
|
||||||
|
|
||||||
offset += ceilingDivide(arguments[i].size, TargetBytesPerWord);
|
offset += ceilingDivide(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord);
|
||||||
} else {
|
} else {
|
||||||
Memory dst(StackRegister, offset * TargetBytesPerWord);
|
Memory dst(StackRegister, offset * TargetBytesPerWord);
|
||||||
|
|
||||||
apply(Move,
|
apply(Move,
|
||||||
arguments[i].size, arguments[i].type, arguments[i].operand,
|
RUNTIME_ARRAY_BODY(arguments)[i].size,
|
||||||
pad(arguments[i].size, TargetBytesPerWord), MemoryOperand, &dst);
|
RUNTIME_ARRAY_BODY(arguments)[i].type,
|
||||||
|
RUNTIME_ARRAY_BODY(arguments)[i].operand,
|
||||||
|
pad(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord), MemoryOperand, &dst);
|
||||||
|
|
||||||
offset += ceilingDivide(arguments[i].size, TargetBytesPerWord);
|
offset += ceilingDivide(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2800,7 +2808,7 @@ class MyAssembler: public Assembler {
|
|||||||
bool jump = needJump(b);
|
bool jump = needJump(b);
|
||||||
if (jump) {
|
if (jump) {
|
||||||
write4
|
write4
|
||||||
(dst + dstOffset, ::b((poolSize + TargetBytesPerWord - 8) >> 2));
|
(dst + dstOffset, isa::b((poolSize + TargetBytesPerWord - 8) >> 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
dstOffset += poolSize + (jump ? TargetBytesPerWord : 0);
|
dstOffset += poolSize + (jump ? TargetBytesPerWord : 0);
|
||||||
@ -2834,7 +2842,7 @@ class MyAssembler: public Assembler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual Promise* offset(bool forTrace) {
|
virtual Promise* offset(bool forTrace) {
|
||||||
return ::offset(&con, forTrace);
|
return local::offset(&con, forTrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Block* endBlock(bool startNew) {
|
virtual Block* endBlock(bool startNew) {
|
||||||
@ -2910,7 +2918,7 @@ namespace codegen {
|
|||||||
Assembler::Architecture*
|
Assembler::Architecture*
|
||||||
makeArchitectureArm(System* system, bool)
|
makeArchitectureArm(System* system, bool)
|
||||||
{
|
{
|
||||||
return new (allocate(system, sizeof(MyArchitecture))) MyArchitecture(system);
|
return new (allocate(system, sizeof(local::MyArchitecture))) local::MyArchitecture(system);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace codegen
|
} // namespace codegen
|
||||||
|
11
src/common.h
11
src/common.h
@ -94,7 +94,13 @@ typedef int64_t intptr_t;
|
|||||||
typedef uint64_t uintptr_t;
|
typedef uint64_t uintptr_t;
|
||||||
# define UINT64_C(x) x##L
|
# define UINT64_C(x) x##L
|
||||||
# define ARCH_x86_64
|
# define ARCH_x86_64
|
||||||
@ define BYTES_PER_WORD 8
|
# define BYTES_PER_WORD 8
|
||||||
|
# elif defined _M_ARM_FP
|
||||||
|
typedef int32_t intptr_t;
|
||||||
|
typedef uint32_t uintptr_t;
|
||||||
|
# define UINT64_C(x) x##LL
|
||||||
|
# define ARCH_arm
|
||||||
|
# define BYTES_PER_WORD 4
|
||||||
# else
|
# else
|
||||||
# error "unsupported architecture"
|
# error "unsupported architecture"
|
||||||
# endif
|
# endif
|
||||||
@ -214,6 +220,9 @@ typedef intptr_t __attribute__((__may_alias__)) intptr_alias_t;
|
|||||||
type name; \
|
type name; \
|
||||||
} MAKE_NAME(resource_)(name);
|
} MAKE_NAME(resource_)(name);
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# pragma warning( disable : 4291 )
|
||||||
|
#endif
|
||||||
inline void* operator new(size_t, void* p) throw() { return p; }
|
inline void* operator new(size_t, void* p) throw() { return p; }
|
||||||
|
|
||||||
namespace vm {
|
namespace vm {
|
||||||
|
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
|
@ -7392,8 +7392,9 @@ finish(MyThread* t, FixedAllocator* allocator, Context* context)
|
|||||||
{
|
{
|
||||||
trap();
|
trap();
|
||||||
}
|
}
|
||||||
|
#if !defined(AVIAN_AOT_ONLY)
|
||||||
syncInstructionCache(start, codeSize);
|
syncInstructionCache(start, codeSize);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -9155,7 +9156,9 @@ class MyProcessor: public Processor {
|
|||||||
|
|
||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
if (codeAllocator.base) {
|
if (codeAllocator.base) {
|
||||||
|
#if !defined(AVIAN_AOT_ONLY)
|
||||||
s->freeExecutable(codeAllocator.base, codeAllocator.capacity);
|
s->freeExecutable(codeAllocator.base, codeAllocator.capacity);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
compilationHandlers->dispose(allocator);
|
compilationHandlers->dispose(allocator);
|
||||||
@ -9316,11 +9319,13 @@ class MyProcessor: public Processor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void boot(Thread* t, BootImage* image, uint8_t* code) {
|
virtual void boot(Thread* t, BootImage* image, uint8_t* code) {
|
||||||
|
#if !defined(AVIAN_AOT_ONLY)
|
||||||
if (codeAllocator.base == 0) {
|
if (codeAllocator.base == 0) {
|
||||||
codeAllocator.base = static_cast<uint8_t*>
|
codeAllocator.base = static_cast<uint8_t*>
|
||||||
(s->tryAllocateExecutable(ExecutableAreaSizeInBytes));
|
(s->tryAllocateExecutable(ExecutableAreaSizeInBytes));
|
||||||
codeAllocator.capacity = ExecutableAreaSizeInBytes;
|
codeAllocator.capacity = ExecutableAreaSizeInBytes;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (image and code) {
|
if (image and code) {
|
||||||
local::boot(static_cast<MyThread*>(t), image, code);
|
local::boot(static_cast<MyThread*>(t), image, code);
|
||||||
@ -9337,11 +9342,15 @@ class MyProcessor: public Processor {
|
|||||||
root(t, MethodTreeSentinal));
|
root(t, MethodTreeSentinal));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef AVIAN_AOT_ONLY
|
||||||
|
thunks = bootThunks;
|
||||||
|
#else
|
||||||
local::compileThunks(static_cast<MyThread*>(t), &codeAllocator);
|
local::compileThunks(static_cast<MyThread*>(t), &codeAllocator);
|
||||||
|
|
||||||
if (not (image and code)) {
|
if (not (image and code)) {
|
||||||
bootThunks = thunks;
|
bootThunks = thunks;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
segFaultHandler.m = t->m;
|
segFaultHandler.m = t->m;
|
||||||
expect(t, t->m->system->success
|
expect(t, t->m->system->success
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
using namespace vm;
|
using namespace vm;
|
||||||
|
|
||||||
namespace {
|
namespace local {
|
||||||
|
|
||||||
const unsigned FrameBaseOffset = 0;
|
const unsigned FrameBaseOffset = 0;
|
||||||
const unsigned FrameNextOffset = 1;
|
const unsigned FrameNextOffset = 1;
|
||||||
@ -647,7 +647,7 @@ invokeNative(Thread* t, object method)
|
|||||||
{ THREAD_RESOURCE0(t, popFrame(static_cast<Thread*>(t)));
|
{ THREAD_RESOURCE0(t, popFrame(static_cast<Thread*>(t)));
|
||||||
|
|
||||||
unsigned footprint = methodParameterFootprint(t, method);
|
unsigned footprint = methodParameterFootprint(t, method);
|
||||||
RUNTIME_ARRAY(uintptr_t, args, footprint);
|
THREAD_RUNTIME_ARRAY(t, uintptr_t, args, footprint);
|
||||||
unsigned sp = frameBase(t, t->frame);
|
unsigned sp = frameBase(t, t->frame);
|
||||||
unsigned argOffset = 0;
|
unsigned argOffset = 0;
|
||||||
if ((methodFlags(t, method) & ACC_STATIC) == 0) {
|
if ((methodFlags(t, method) & ACC_STATIC) == 0) {
|
||||||
@ -2321,7 +2321,7 @@ interpret3(Thread* t, const int base)
|
|||||||
object class_ = resolveClassInPool(t, frameMethod(t, frame), index - 1);
|
object class_ = resolveClassInPool(t, frameMethod(t, frame), index - 1);
|
||||||
PROTECT(t, class_);
|
PROTECT(t, class_);
|
||||||
|
|
||||||
int32_t counts[dimensions];
|
THREAD_RUNTIME_ARRAY(t, int32_t, counts, dimensions);
|
||||||
for (int i = dimensions - 1; i >= 0; --i) {
|
for (int i = dimensions - 1; i >= 0; --i) {
|
||||||
counts[i] = popInt(t);
|
counts[i] = popInt(t);
|
||||||
if (UNLIKELY(counts[i] < 0)) {
|
if (UNLIKELY(counts[i] < 0)) {
|
||||||
@ -3100,7 +3100,7 @@ class MyProcessor: public Processor {
|
|||||||
(&byteArrayBody(t, methodSpec(t, method), 0));
|
(&byteArrayBody(t, methodSpec(t, method), 0));
|
||||||
pushArguments(t, this_, spec, arguments);
|
pushArguments(t, this_, spec, arguments);
|
||||||
|
|
||||||
return ::invoke(t, method);
|
return local::invoke(t, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual object
|
virtual object
|
||||||
@ -3124,7 +3124,7 @@ class MyProcessor: public Processor {
|
|||||||
(&byteArrayBody(t, methodSpec(t, method), 0));
|
(&byteArrayBody(t, methodSpec(t, method), 0));
|
||||||
pushArguments(t, this_, spec, arguments);
|
pushArguments(t, this_, spec, arguments);
|
||||||
|
|
||||||
return ::invoke(t, method);
|
return local::invoke(t, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual object
|
virtual object
|
||||||
@ -3148,7 +3148,7 @@ class MyProcessor: public Processor {
|
|||||||
(&byteArrayBody(t, methodSpec(t, method), 0));
|
(&byteArrayBody(t, methodSpec(t, method), 0));
|
||||||
pushArguments(t, this_, spec, indirectObjects, arguments);
|
pushArguments(t, this_, spec, indirectObjects, arguments);
|
||||||
|
|
||||||
return ::invoke(t, method);
|
return local::invoke(t, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual object
|
virtual object
|
||||||
@ -3174,7 +3174,7 @@ class MyProcessor: public Processor {
|
|||||||
|
|
||||||
assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0));
|
assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0));
|
||||||
|
|
||||||
return ::invoke(t, method);
|
return local::invoke(t, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual object getStackTrace(vm::Thread* t, vm::Thread*) {
|
virtual object getStackTrace(vm::Thread* t, vm::Thread*) {
|
||||||
@ -3254,8 +3254,8 @@ namespace vm {
|
|||||||
Processor*
|
Processor*
|
||||||
makeProcessor(System* system, Allocator* allocator, bool)
|
makeProcessor(System* system, Allocator* allocator, bool)
|
||||||
{
|
{
|
||||||
return new (allocator->allocate(sizeof(MyProcessor)))
|
return new (allocator->allocate(sizeof(local::MyProcessor)))
|
||||||
MyProcessor(system, allocator);
|
local::MyProcessor(system, allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace vm
|
} // namespace vm
|
||||||
|
@ -162,10 +162,12 @@ GetStringRegion(Thread* t, jstring s, jsize start, jsize length, jchar* dst)
|
|||||||
const jchar* JNICALL
|
const jchar* JNICALL
|
||||||
GetStringCritical(Thread* t, jstring s, jboolean* isCopy)
|
GetStringCritical(Thread* t, jstring s, jboolean* isCopy)
|
||||||
{
|
{
|
||||||
if ((t->criticalLevel ++) == 0) {
|
if (t->criticalLevel == 0) {
|
||||||
enter(t, Thread::ActiveState);
|
enter(t, Thread::ActiveState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
++ t->criticalLevel;
|
||||||
|
|
||||||
if (isCopy) {
|
if (isCopy) {
|
||||||
*isCopy = true;
|
*isCopy = true;
|
||||||
}
|
}
|
||||||
@ -3143,10 +3145,12 @@ SetDoubleArrayRegion(Thread* t, jdoubleArray array, jint offset, jint length,
|
|||||||
void* JNICALL
|
void* JNICALL
|
||||||
GetPrimitiveArrayCritical(Thread* t, jarray array, jboolean* isCopy)
|
GetPrimitiveArrayCritical(Thread* t, jarray array, jboolean* isCopy)
|
||||||
{
|
{
|
||||||
if ((t->criticalLevel ++) == 0) {
|
if (t->criticalLevel == 0) {
|
||||||
enter(t, Thread::ActiveState);
|
enter(t, Thread::ActiveState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
++ t->criticalLevel;
|
||||||
|
|
||||||
if (isCopy) {
|
if (isCopy) {
|
||||||
*isCopy = true;
|
*isCopy = true;
|
||||||
}
|
}
|
||||||
@ -3711,16 +3715,6 @@ populateJNITables(JavaVMVTable* vmTable, JNIEnvVTable* envTable)
|
|||||||
|
|
||||||
} // namespace vm
|
} // 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
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
JNI_GetDefaultJavaVMInitArgs(void*)
|
JNI_GetDefaultJavaVMInitArgs(void*)
|
||||||
{
|
{
|
||||||
@ -3741,7 +3735,7 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
|
|||||||
|
|
||||||
unsigned heapLimit = 0;
|
unsigned heapLimit = 0;
|
||||||
unsigned stackLimit = 0;
|
unsigned stackLimit = 0;
|
||||||
const char* bootLibrary = 0;
|
const char* bootLibraries = 0;
|
||||||
const char* classpath = 0;
|
const char* classpath = 0;
|
||||||
const char* javaHome = AVIAN_JAVA_HOME;
|
const char* javaHome = AVIAN_JAVA_HOME;
|
||||||
const char* embedPrefix = AVIAN_EMBED_PREFIX;
|
const char* embedPrefix = AVIAN_EMBED_PREFIX;
|
||||||
@ -3777,7 +3771,7 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
|
|||||||
if (strncmp(p, BOOTSTRAP_PROPERTY "=",
|
if (strncmp(p, BOOTSTRAP_PROPERTY "=",
|
||||||
sizeof(BOOTSTRAP_PROPERTY)) == 0)
|
sizeof(BOOTSTRAP_PROPERTY)) == 0)
|
||||||
{
|
{
|
||||||
bootLibrary = p + sizeof(BOOTSTRAP_PROPERTY);
|
bootLibraries = p + sizeof(BOOTSTRAP_PROPERTY);
|
||||||
} else if (strncmp(p, CRASHDIR_PROPERTY "=",
|
} else if (strncmp(p, CRASHDIR_PROPERTY "=",
|
||||||
sizeof(CRASHDIR_PROPERTY)) == 0)
|
sizeof(CRASHDIR_PROPERTY)) == 0)
|
||||||
{
|
{
|
||||||
@ -3831,9 +3825,16 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
|
|||||||
*RUNTIME_ARRAY_BODY(bootClasspathBuffer) = 0;
|
*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
|
Finder* bf = makeFinder
|
||||||
(s, h, RUNTIME_ARRAY_BODY(bootClasspathBuffer), bootLibrary);
|
(s, h, RUNTIME_ARRAY_BODY(bootClasspathBuffer), bootLibrary);
|
||||||
Finder* af = makeFinder(s, h, classpath, bootLibrary);
|
Finder* af = makeFinder(s, h, classpath, bootLibrary);
|
||||||
|
if(bootLibrary)
|
||||||
|
free(bootLibrary);
|
||||||
Processor* p = makeProcessor(s, h, true);
|
Processor* p = makeProcessor(s, h, true);
|
||||||
|
|
||||||
const char** properties = static_cast<const char**>
|
const char** properties = static_cast<const char**>
|
||||||
|
10
src/jnienv.h
10
src/jnienv.h
@ -13,6 +13,16 @@
|
|||||||
|
|
||||||
#include "machine.h"
|
#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 {
|
namespace vm {
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -19,6 +19,11 @@
|
|||||||
|
|
||||||
#include "util/runtime-array.h"
|
#include "util/runtime-array.h"
|
||||||
|
|
||||||
|
#if defined(PLATFORM_WINDOWS)
|
||||||
|
# define WIN32_LEAN_AND_MEAN
|
||||||
|
# include <Windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace vm;
|
using namespace vm;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -3005,6 +3010,14 @@ Machine::Machine(System* system, Heap* heap, Finder* bootFinder,
|
|||||||
|
|
||||||
populateJNITables(&javaVMVTable, &jniEnvVTable);
|
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
|
if (not system->success(system->make(&localThread)) or
|
||||||
not system->success(system->make(&stateLock)) or
|
not system->success(system->make(&stateLock)) or
|
||||||
not system->success(system->make(&heapLock)) or
|
not system->success(system->make(&heapLock)) or
|
||||||
@ -3012,10 +3025,25 @@ Machine::Machine(System* system, Heap* heap, Finder* bootFinder,
|
|||||||
not system->success(system->make(&referenceLock)) or
|
not system->success(system->make(&referenceLock)) or
|
||||||
not system->success(system->make(&shutdownLock)) or
|
not system->success(system->make(&shutdownLock)) or
|
||||||
not system->success
|
not system->success
|
||||||
(system->load(&libraries, findProperty(this, "avian.bootstrap"))))
|
(system->load(&libraries, bootstrapPropertyDup)))
|
||||||
{
|
{
|
||||||
system->abort();
|
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
|
void
|
||||||
@ -4733,6 +4761,30 @@ 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
|
||||||
|
va_end(a);
|
||||||
|
|
||||||
|
RUNTIME_ARRAY(char, buffer, length + 1);
|
||||||
|
va_start(a, fmt);
|
||||||
|
vsnprintf(&buffer[0], length + 1, fmt, a);
|
||||||
|
va_end(a);
|
||||||
|
buffer[length] = 0;
|
||||||
|
|
||||||
|
::fprintf(f, "%s", &buffer[0]);
|
||||||
|
#ifdef PLATFORM_WINDOWS
|
||||||
|
::OutputDebugStringA(&buffer[0]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
printTrace(Thread* t, object exception)
|
printTrace(Thread* t, object exception)
|
||||||
{
|
{
|
||||||
@ -4742,19 +4794,19 @@ printTrace(Thread* t, object exception)
|
|||||||
|
|
||||||
for (object e = exception; e; e = throwableCause(t, e)) {
|
for (object e = exception; e; e = throwableCause(t, e)) {
|
||||||
if (e != exception) {
|
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));
|
(t, className(t, objectClass(t, e)), 0));
|
||||||
|
|
||||||
if (throwableMessage(t, e)) {
|
if (throwableMessage(t, e)) {
|
||||||
object m = throwableMessage(t, e);
|
object m = throwableMessage(t, e);
|
||||||
THREAD_RUNTIME_ARRAY(t, char, message, stringLength(t, m) + 1);
|
THREAD_RUNTIME_ARRAY(t, char, message, stringLength(t, m) + 1);
|
||||||
stringChars(t, m, RUNTIME_ARRAY_BODY(message));
|
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 {
|
} else {
|
||||||
fprintf(errorLog(t), "\n");
|
logTrace(errorLog(t), "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
object trace = throwableTrace(t, e);
|
object trace = throwableTrace(t, e);
|
||||||
@ -4768,17 +4820,17 @@ printTrace(Thread* t, object exception)
|
|||||||
int line = t->m->processor->lineNumber
|
int line = t->m->processor->lineNumber
|
||||||
(t, traceElementMethod(t, e), traceElementIp(t, e));
|
(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) {
|
switch (line) {
|
||||||
case NativeLine:
|
case NativeLine:
|
||||||
fprintf(errorLog(t), "(native)\n");
|
logTrace(errorLog(t), "(native)\n");
|
||||||
break;
|
break;
|
||||||
case UnknownLine:
|
case UnknownLine:
|
||||||
fprintf(errorLog(t), "(unknown line)\n");
|
logTrace(errorLog(t), "(unknown line)\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(errorLog(t), "(line %d)\n", line);
|
logTrace(errorLog(t), "(line %d)\n", line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4788,7 +4840,7 @@ printTrace(Thread* t, object exception)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fflush(errorLog(t));
|
::fflush(errorLog(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
|
@ -1325,6 +1325,9 @@ checkDaemon(Thread* t);
|
|||||||
object&
|
object&
|
||||||
root(Thread* t, Machine::Root root);
|
root(Thread* t, Machine::Root root);
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
|
||||||
|
# define vmRun vmRun_
|
||||||
|
#endif
|
||||||
extern "C" uint64_t
|
extern "C" uint64_t
|
||||||
vmRun(uint64_t (*function)(Thread*, uintptr_t*), uintptr_t* arguments,
|
vmRun(uint64_t (*function)(Thread*, uintptr_t*), uintptr_t* arguments,
|
||||||
void* checkpoint);
|
void* checkpoint);
|
||||||
|
@ -12,10 +12,21 @@
|
|||||||
# define __STDC_CONSTANT_MACROS
|
# define __STDC_CONSTANT_MACROS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "sys/types.h"
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
# include "CoreFoundation/CoreFoundation.h"
|
# include "CoreFoundation/CoreFoundation.h"
|
||||||
# include "sys/ucontext.h"
|
# include "sys/ucontext.h"
|
||||||
# undef assert
|
# 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
|
#else
|
||||||
# if defined __FreeBSD__
|
# if defined __FreeBSD__
|
||||||
# include "limits.h"
|
# include "limits.h"
|
||||||
@ -24,7 +35,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "sys/mman.h"
|
#include "sys/mman.h"
|
||||||
#include "sys/types.h"
|
|
||||||
#include "sys/stat.h"
|
#include "sys/stat.h"
|
||||||
#include "sys/time.h"
|
#include "sys/time.h"
|
||||||
#include "time.h"
|
#include "time.h"
|
||||||
@ -37,10 +48,10 @@
|
|||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
#include "dirent.h"
|
#include "dirent.h"
|
||||||
#include "sched.h"
|
#include "sched.h"
|
||||||
|
|
||||||
#include "arch.h"
|
#include "arch.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
|
||||||
|
|
||||||
#define ACQUIRE(x) MutexResource MAKE_NAME(mutexResource_) (x)
|
#define ACQUIRE(x) MutexResource MAKE_NAME(mutexResource_) (x)
|
||||||
|
|
||||||
using namespace vm;
|
using namespace vm;
|
||||||
|
@ -121,8 +121,10 @@ class System {
|
|||||||
virtual bool success(Status) = 0;
|
virtual bool success(Status) = 0;
|
||||||
virtual void* tryAllocate(unsigned sizeInBytes) = 0;
|
virtual void* tryAllocate(unsigned sizeInBytes) = 0;
|
||||||
virtual void free(const void* p) = 0;
|
virtual void free(const void* p) = 0;
|
||||||
|
#if !defined(AVIAN_AOT_ONLY)
|
||||||
virtual void* tryAllocateExecutable(unsigned sizeInBytes) = 0;
|
virtual void* tryAllocateExecutable(unsigned sizeInBytes) = 0;
|
||||||
virtual void freeExecutable(const void* p, unsigned sizeInBytes) = 0;
|
virtual void freeExecutable(const void* p, unsigned sizeInBytes) = 0;
|
||||||
|
#endif
|
||||||
virtual Status attach(Runnable*) = 0;
|
virtual Status attach(Runnable*) = 0;
|
||||||
virtual Status start(Runnable*) = 0;
|
virtual Status start(Runnable*) = 0;
|
||||||
virtual Status make(Mutex**) = 0;
|
virtual Status make(Mutex**) = 0;
|
||||||
|
183
src/windows.cpp
183
src/windows.cpp
@ -26,6 +26,71 @@
|
|||||||
#include "arch.h"
|
#include "arch.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
|
||||||
|
#if defined(WINAPI_FAMILY)
|
||||||
|
|
||||||
|
#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
|
|
||||||
|
#define WaitForSingleObject(hHandle, dwMilliseconds) \
|
||||||
|
WaitForSingleObjectEx((hHandle), (dwMilliseconds), FALSE)
|
||||||
|
|
||||||
|
#define CreateEvent(lpEventAttributes, bManualReset, bInitialState, lpName) \
|
||||||
|
CreateEventEx((lpEventAttributes), (lpName), ((bManualReset)?CREATE_EVENT_MANUAL_RESET:0)|((bInitialState)?CREATE_EVENT_INITIAL_SET:0), EVENT_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)
|
#define ACQUIRE(s, x) MutexResource MAKE_NAME(mutexResource_) (s, x)
|
||||||
|
|
||||||
using namespace vm;
|
using namespace vm;
|
||||||
@ -57,8 +122,10 @@ const unsigned HandlerCount = 2;
|
|||||||
class MySystem;
|
class MySystem;
|
||||||
MySystem* system;
|
MySystem* system;
|
||||||
|
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
LONG CALLBACK
|
LONG CALLBACK
|
||||||
handleException(LPEXCEPTION_POINTERS e);
|
handleException(LPEXCEPTION_POINTERS e);
|
||||||
|
#endif
|
||||||
|
|
||||||
DWORD WINAPI
|
DWORD WINAPI
|
||||||
run(void* r)
|
run(void* r)
|
||||||
@ -559,7 +626,9 @@ class MySystem: public System {
|
|||||||
};
|
};
|
||||||
|
|
||||||
MySystem(const char* crashDumpDirectory):
|
MySystem(const char* crashDumpDirectory):
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
oldHandler(0),
|
oldHandler(0),
|
||||||
|
#endif
|
||||||
crashDumpDirectory(crashDumpDirectory)
|
crashDumpDirectory(crashDumpDirectory)
|
||||||
{
|
{
|
||||||
expect(this, system == 0);
|
expect(this, system == 0);
|
||||||
@ -582,25 +651,33 @@ class MySystem: public System {
|
|||||||
if (handler) {
|
if (handler) {
|
||||||
handlers[index] = handler;
|
handlers[index] = handler;
|
||||||
|
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
if (oldHandler == 0) {
|
if (oldHandler == 0) {
|
||||||
#ifdef ARCH_x86_32
|
# ifdef ARCH_x86_32
|
||||||
oldHandler = SetUnhandledExceptionFilter(handleException);
|
oldHandler = SetUnhandledExceptionFilter(handleException);
|
||||||
#elif defined ARCH_x86_64
|
# elif defined ARCH_x86_64
|
||||||
AddVectoredExceptionHandler(1, handleException);
|
AddVectoredExceptionHandler(1, handleException);
|
||||||
oldHandler = reinterpret_cast<LPTOP_LEVEL_EXCEPTION_FILTER>(1);
|
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;
|
return 0;
|
||||||
} else if (handlers[index]) {
|
} else if (handlers[index]) {
|
||||||
handlers[index] = 0;
|
handlers[index] = 0;
|
||||||
|
|
||||||
if (not findHandler()) {
|
if (not findHandler()) {
|
||||||
#ifdef ARCH_x86_32
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
|
# ifdef ARCH_x86_32
|
||||||
SetUnhandledExceptionFilter(oldHandler);
|
SetUnhandledExceptionFilter(oldHandler);
|
||||||
oldHandler = 0;
|
oldHandler = 0;
|
||||||
#elif defined ARCH_x86_64
|
# elif defined ARCH_x86_64
|
||||||
// do nothing, handlers are never "unregistered" anyway
|
// do nothing, handlers are never "unregistered" anyway
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
#pragma message("TODO: http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.windows.application.unhandledexception(v=vs.105).aspx")
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -618,6 +695,7 @@ class MySystem: public System {
|
|||||||
if (p) ::free(const_cast<void*>(p));
|
if (p) ::free(const_cast<void*>(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(AVIAN_AOT_ONLY)
|
||||||
virtual void* tryAllocateExecutable(unsigned sizeInBytes) {
|
virtual void* tryAllocateExecutable(unsigned sizeInBytes) {
|
||||||
return VirtualAlloc
|
return VirtualAlloc
|
||||||
(0, sizeInBytes, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
(0, sizeInBytes, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||||
@ -627,6 +705,7 @@ class MySystem: public System {
|
|||||||
int r UNUSED = VirtualFree(const_cast<void*>(p), 0, MEM_RELEASE);
|
int r UNUSED = VirtualFree(const_cast<void*>(p), 0, MEM_RELEASE);
|
||||||
assert(this, r);
|
assert(this, r);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
virtual bool success(Status s) {
|
virtual bool success(Status s) {
|
||||||
return s == 0;
|
return s == 0;
|
||||||
@ -677,6 +756,7 @@ class MySystem: public System {
|
|||||||
virtual Status visit(System::Thread* st UNUSED, System::Thread* sTarget,
|
virtual Status visit(System::Thread* st UNUSED, System::Thread* sTarget,
|
||||||
ThreadVisitor* visitor)
|
ThreadVisitor* visitor)
|
||||||
{
|
{
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
assert(this, st != sTarget);
|
assert(this, st != sTarget);
|
||||||
|
|
||||||
Thread* target = static_cast<Thread*>(sTarget);
|
Thread* target = static_cast<Thread*>(sTarget);
|
||||||
@ -692,15 +772,15 @@ class MySystem: public System {
|
|||||||
rv = GetThreadContext(target->thread, &context);
|
rv = GetThreadContext(target->thread, &context);
|
||||||
|
|
||||||
if (rv) {
|
if (rv) {
|
||||||
#ifdef ARCH_x86_32
|
# ifdef ARCH_x86_32
|
||||||
visitor->visit(reinterpret_cast<void*>(context.Eip),
|
visitor->visit(reinterpret_cast<void*>(context.Eip),
|
||||||
reinterpret_cast<void*>(context.Ebp),
|
reinterpret_cast<void*>(context.Ebp),
|
||||||
reinterpret_cast<void*>(context.Esp));
|
reinterpret_cast<void*>(context.Esp));
|
||||||
#elif defined ARCH_x86_64
|
# elif defined ARCH_x86_64
|
||||||
visitor->visit(reinterpret_cast<void*>(context.Rip),
|
visitor->visit(reinterpret_cast<void*>(context.Rip),
|
||||||
reinterpret_cast<void*>(context.Rbp),
|
reinterpret_cast<void*>(context.Rbp),
|
||||||
reinterpret_cast<void*>(context.Rsp));
|
reinterpret_cast<void*>(context.Rsp));
|
||||||
#endif
|
# endif
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -709,6 +789,10 @@ class MySystem: public System {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (success ? 0 : 1);
|
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,
|
virtual uint64_t call(void* function, uintptr_t* arguments, uint8_t* types,
|
||||||
@ -719,15 +803,37 @@ class MySystem: public System {
|
|||||||
|
|
||||||
virtual Status map(System::Region** region, const char* name) {
|
virtual Status map(System::Region** region, const char* name) {
|
||||||
Status status = 1;
|
Status status = 1;
|
||||||
|
size_t nameLen = strlen(name) * 2;
|
||||||
HANDLE file = CreateFile(name, FILE_READ_DATA, FILE_SHARE_READ, 0,
|
RUNTIME_ARRAY(wchar_t, wideName, nameLen + 1);
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, name, -1, wideName, nameLen + 1);
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
|
HANDLE file = CreateFileW(wideName, FILE_READ_DATA, FILE_SHARE_READ, 0,
|
||||||
OPEN_EXISTING, 0, 0);
|
OPEN_EXISTING, 0, 0);
|
||||||
|
#else
|
||||||
|
HANDLE file = CreateFile2(wideName, GENERIC_READ, FILE_SHARE_READ,
|
||||||
|
OPEN_EXISTING, 0);
|
||||||
|
#endif
|
||||||
if (file != INVALID_HANDLE_VALUE) {
|
if (file != INVALID_HANDLE_VALUE) {
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
unsigned size = GetFileSize(file, 0);
|
unsigned size = GetFileSize(file, 0);
|
||||||
|
#else
|
||||||
|
FILE_STANDARD_INFO info;
|
||||||
|
unsigned size = INVALID_FILE_SIZE;
|
||||||
|
if(GetFileInformationByHandleEx(file, FileStandardInfo, &info, sizeof(info)))
|
||||||
|
size = info.EndOfFile.QuadPart;
|
||||||
|
#endif
|
||||||
if (size != INVALID_FILE_SIZE) {
|
if (size != INVALID_FILE_SIZE) {
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
HANDLE mapping = CreateFileMapping(file, 0, PAGE_READONLY, 0, size, 0);
|
HANDLE mapping = CreateFileMapping(file, 0, PAGE_READONLY, 0, size, 0);
|
||||||
|
#else
|
||||||
|
HANDLE mapping = CreateFileMappingFromApp(file, 0, PAGE_READONLY, size, 0);
|
||||||
|
#endif
|
||||||
if (mapping) {
|
if (mapping) {
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
void* data = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);
|
void* data = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);
|
||||||
|
#else
|
||||||
|
void* data = MapViewOfFileFromApp(mapping, FILE_MAP_READ, 0, 0);
|
||||||
|
#endif
|
||||||
if (data) {
|
if (data) {
|
||||||
*region = new (allocate(this, sizeof(Region)))
|
*region = new (allocate(this, sizeof(Region)))
|
||||||
Region(this, static_cast<uint8_t*>(data), size, file, mapping);
|
Region(this, static_cast<uint8_t*>(data), size, file, mapping);
|
||||||
@ -757,7 +863,12 @@ class MySystem: public System {
|
|||||||
memcpy(RUNTIME_ARRAY_BODY(buffer) + length, "\\*", 3);
|
memcpy(RUNTIME_ARRAY_BODY(buffer) + length, "\\*", 3);
|
||||||
|
|
||||||
Directory* d = new (allocate(this, sizeof(Directory))) Directory(this);
|
Directory* d = new (allocate(this, sizeof(Directory))) Directory(this);
|
||||||
|
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
d->handle = FindFirstFile(RUNTIME_ARRAY_BODY(buffer), &(d->data));
|
d->handle = FindFirstFile(RUNTIME_ARRAY_BODY(buffer), &(d->data));
|
||||||
|
#else
|
||||||
|
d->handle = FindFirstFileEx(RUNTIME_ARRAY_BODY(buffer), FindExInfoStandard, &(d->data), FindExSearchNameMatch, 0, 0);
|
||||||
|
#endif
|
||||||
if (d->handle == INVALID_HANDLE_VALUE) {
|
if (d->handle == INVALID_HANDLE_VALUE) {
|
||||||
d->dispose();
|
d->dispose();
|
||||||
} else {
|
} else {
|
||||||
@ -769,21 +880,21 @@ class MySystem: public System {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual FileType stat(const char* name, unsigned* length) {
|
virtual FileType stat(const char* name, unsigned* length) {
|
||||||
struct _stat s;
|
size_t nameLen = strlen(name) * 2;
|
||||||
int r = _stat(name, &s);
|
RUNTIME_ARRAY(wchar_t, wideName, nameLen + 1);
|
||||||
if (r == 0) {
|
MultiByteToWideChar(CP_UTF8, 0, name, -1, wideName, nameLen + 1);
|
||||||
if (S_ISREG(s.st_mode)) {
|
WIN32_FILE_ATTRIBUTE_DATA data;
|
||||||
*length = s.st_size;
|
if (GetFileAttributesExW
|
||||||
return TypeFile;
|
(wideName, GetFileExInfoStandard, &data))
|
||||||
} else if (S_ISDIR(s.st_mode)) {
|
{
|
||||||
*length = 0;
|
if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
return TypeDirectory;
|
return TypeDirectory;
|
||||||
} else {
|
} else {
|
||||||
*length = 0;
|
*length = (data.nFileSizeHigh * static_cast<int64_t>(MAXDWORD + 1))
|
||||||
return TypeUnknown;
|
+ data.nFileSizeLow;
|
||||||
|
return TypeFile;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*length = 0;
|
|
||||||
return TypeDoesNotExist;
|
return TypeDoesNotExist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -797,6 +908,7 @@ class MySystem: public System {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual const char* toAbsolutePath(Allocator* allocator, const char* name) {
|
virtual const char* toAbsolutePath(Allocator* allocator, const char* name) {
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
if (strncmp(name, "//", 2) == 0
|
if (strncmp(name, "//", 2) == 0
|
||||||
or strncmp(name, "\\\\", 2) == 0
|
or strncmp(name, "\\\\", 2) == 0
|
||||||
or strncmp(name + 1, ":/", 2) == 0
|
or strncmp(name + 1, ":/", 2) == 0
|
||||||
@ -808,6 +920,10 @@ class MySystem: public System {
|
|||||||
GetCurrentDirectory(MAX_PATH, buffer);
|
GetCurrentDirectory(MAX_PATH, buffer);
|
||||||
return append(allocator, buffer, "\\", name);
|
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,
|
virtual Status load(System::Library** lib,
|
||||||
@ -816,9 +932,22 @@ class MySystem: public System {
|
|||||||
HMODULE handle;
|
HMODULE handle;
|
||||||
unsigned nameLength = (name ? strlen(name) : 0);
|
unsigned nameLength = (name ? strlen(name) : 0);
|
||||||
if (name) {
|
if (name) {
|
||||||
handle = LoadLibrary(name);
|
size_t nameLen = nameLength * 2;
|
||||||
|
RUNTIME_ARRAY(wchar_t, wideName, nameLen + 1);
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, name, -1, wideName, nameLen + 1);
|
||||||
|
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
|
handle = LoadLibraryW(wideName);
|
||||||
|
#else
|
||||||
|
handle = LoadPackagedLibrary(wideName, 0);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
handle = GetModuleHandle(0);
|
handle = GetModuleHandle(0);
|
||||||
|
#else
|
||||||
|
// Most of WinRT/WP8 applications can not host native object files inside main executable
|
||||||
|
assert(this, false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle) {
|
if (handle) {
|
||||||
@ -866,7 +995,11 @@ class MySystem: public System {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void yield() {
|
virtual void yield() {
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
SwitchToThread();
|
SwitchToThread();
|
||||||
|
#else
|
||||||
|
YieldProcessor();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void exit(int code) {
|
virtual void exit(int code) {
|
||||||
@ -887,10 +1020,14 @@ class MySystem: public System {
|
|||||||
|
|
||||||
HANDLE mutex;
|
HANDLE mutex;
|
||||||
SignalHandler* handlers[HandlerCount];
|
SignalHandler* handlers[HandlerCount];
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
LPTOP_LEVEL_EXCEPTION_FILTER oldHandler;
|
LPTOP_LEVEL_EXCEPTION_FILTER oldHandler;
|
||||||
|
#endif
|
||||||
const char* crashDumpDirectory;
|
const char* crashDumpDirectory;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
|
|
||||||
#pragma pack(push,4)
|
#pragma pack(push,4)
|
||||||
struct MINIDUMP_EXCEPTION_INFORMATION {
|
struct MINIDUMP_EXCEPTION_INFORMATION {
|
||||||
DWORD thread;
|
DWORD thread;
|
||||||
@ -1005,6 +1142,8 @@ handleException(LPEXCEPTION_POINTERS e)
|
|||||||
return EXCEPTION_CONTINUE_SEARCH;
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace vm {
|
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
|
1
vm.pro
1
vm.pro
@ -71,6 +71,7 @@
|
|||||||
-keep public class java.io.IOException
|
-keep public class java.io.IOException
|
||||||
-keep public class java.io.FileNotFoundException
|
-keep public class java.io.FileNotFoundException
|
||||||
-keep public class java.net.SocketException
|
-keep public class java.net.SocketException
|
||||||
|
-keep public class java.util.Locale
|
||||||
|
|
||||||
# ClassLoader.getSystemClassloader() depends on the existence of this class:
|
# ClassLoader.getSystemClassloader() depends on the existence of this class:
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user