mirror of
https://github.com/corda/corda.git
synced 2025-02-10 21:01:27 +00:00
Merge branch 'master' of oss.readytalk.com:/var/local/git/avian
This commit is contained in:
commit
1b31fb67e1
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,3 +1,7 @@
|
|||||||
.gdb_history
|
.gdb_history
|
||||||
build
|
build
|
||||||
*~
|
*~
|
||||||
|
.classpath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
bin
|
||||||
|
100
classpath/avian/Utf8.java
Normal file
100
classpath/avian/Utf8.java
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/* Copyright (c) 2010, 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. */
|
||||||
|
|
||||||
|
package avian;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
|
||||||
|
public class Utf8 {
|
||||||
|
public static boolean test(Object data) {
|
||||||
|
if (!(data instanceof byte[])) return false;
|
||||||
|
byte[] b = (byte[])data;
|
||||||
|
for (int i = 0; i < b.length; ++i) {
|
||||||
|
if (((int)b[i] & 0x080) != 0) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] encode(char[] s16, int offset, int length) {
|
||||||
|
ByteArrayOutputStream buf = new ByteArrayOutputStream();
|
||||||
|
for (int i = offset; i < offset+length; ++i) {
|
||||||
|
char c = s16[i];
|
||||||
|
if (c == '\u0000') { // null char
|
||||||
|
buf.write(0);
|
||||||
|
buf.write(0);
|
||||||
|
} else if (c < 0x080) { // 1 byte char
|
||||||
|
buf.write(c);
|
||||||
|
} else if (c < 0x0800) { // 2 byte char
|
||||||
|
buf.write(0x0c0 | (c >>> 6));
|
||||||
|
buf.write(0x080 | (c & 0x03f));
|
||||||
|
} else { // 3 byte char
|
||||||
|
buf.write(0x0e0 | ((c >>> 12) & 0x0f));
|
||||||
|
buf.write(0x080 | ((c >>> 6) & 0x03f));
|
||||||
|
buf.write(0x080 | (c & 0x03f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buf.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object decode(byte[] s8, int offset, int length) {
|
||||||
|
Object buf = new byte[length];
|
||||||
|
boolean isMultiByte = false;
|
||||||
|
int i=offset, j=0;
|
||||||
|
while (i < offset+length) {
|
||||||
|
int x = s8[i++];
|
||||||
|
if ((x & 0x080) == 0x0) { // 1 byte char
|
||||||
|
if (x == 0) ++i; // 2 byte null char
|
||||||
|
cram(buf, j++, x);
|
||||||
|
} else if ((x & 0x0e0) == 0x0c0) { // 2 byte char
|
||||||
|
if (!isMultiByte) {
|
||||||
|
buf = widen(buf, j, length-1);
|
||||||
|
isMultiByte = true;
|
||||||
|
}
|
||||||
|
int y = s8[i++];
|
||||||
|
cram(buf, j++, ((x & 0x1f) << 6) | (y & 0x3f));
|
||||||
|
} else if ((x & 0x0f0) == 0x0e0) { // 3 byte char
|
||||||
|
if (!isMultiByte) {
|
||||||
|
buf = widen(buf, j, length-2);
|
||||||
|
isMultiByte = true;
|
||||||
|
}
|
||||||
|
int y = s8[i++]; int z = s8[i++];
|
||||||
|
cram(buf, j++, ((x & 0xf) << 12) | ((y & 0x3f) << 6) | (z & 0x3f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return trim(buf, j);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static char[] decode16(byte[] s8, int offset, int length) {
|
||||||
|
Object decoded = decode(s8, offset, length);
|
||||||
|
if (decoded instanceof char[]) return (char[])decoded;
|
||||||
|
return (char[])widen(decoded, length, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void cram(Object data, int index, int val) {
|
||||||
|
if (data instanceof byte[]) ((byte[])data)[index] = (byte)val;
|
||||||
|
else ((char[])data)[index] = (char)val;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object widen(Object data, int length, int capacity) {
|
||||||
|
byte[] src = (byte[])data;
|
||||||
|
char[] result = new char[capacity];
|
||||||
|
for (int i = 0; i < length; ++i) result[i] = (char)((int)src[i] & 0x0ff);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object trim(Object data, int length) {
|
||||||
|
if (data instanceof byte[]) return data;
|
||||||
|
if (((char[])data).length == length) return data;
|
||||||
|
char[] result = new char[length];
|
||||||
|
System.arraycopy(data, 0, result, 0, length);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
@ -28,10 +28,11 @@
|
|||||||
# define CLOSE _close
|
# define CLOSE _close
|
||||||
# define READ _read
|
# define READ _read
|
||||||
# define WRITE _write
|
# define WRITE _write
|
||||||
# define STAT _stat
|
# define STAT _wstat
|
||||||
# define STRUCT_STAT struct _stat
|
# define STRUCT_STAT struct _stat
|
||||||
# define MKDIR(path, mode) _mkdir(path)
|
# define MKDIR(path, mode) _wmkdir(path)
|
||||||
# define UNLINK _unlink
|
# define UNLINK _wunlink
|
||||||
|
# define RENAME _wrename
|
||||||
# define OPEN_MASK O_BINARY
|
# define OPEN_MASK O_BINARY
|
||||||
|
|
||||||
# ifdef _MSC_VER
|
# ifdef _MSC_VER
|
||||||
@ -40,10 +41,15 @@
|
|||||||
# define S_IRUSR _S_IREAD
|
# define S_IRUSR _S_IREAD
|
||||||
# define S_IWUSR _S_IWRITE
|
# define S_IWUSR _S_IWRITE
|
||||||
# else
|
# else
|
||||||
# define OPEN _open
|
# define OPEN _wopen
|
||||||
# define CREAT _creat
|
# define CREAT _wcreat
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# define GET_CHARS GetStringChars
|
||||||
|
# define RELEASE_CHARS(path, chars) ReleaseStringChars(path, reinterpret_cast<const jchar*>(chars))
|
||||||
|
|
||||||
|
typedef wchar_t char_t;
|
||||||
|
|
||||||
#else // not PLATFORM_WINDOWS
|
#else // not PLATFORM_WINDOWS
|
||||||
|
|
||||||
# include <dirent.h>
|
# include <dirent.h>
|
||||||
@ -59,20 +65,28 @@
|
|||||||
# define MKDIR mkdir
|
# define MKDIR mkdir
|
||||||
# define CREAT creat
|
# define CREAT creat
|
||||||
# define UNLINK unlink
|
# define UNLINK unlink
|
||||||
|
# define RENAME rename
|
||||||
# define OPEN_MASK 0
|
# define OPEN_MASK 0
|
||||||
|
|
||||||
|
# define GET_CHARS GetStringUTFChars
|
||||||
|
# define RELEASE_CHARS ReleaseStringUTFChars
|
||||||
|
|
||||||
|
typedef char char_t;
|
||||||
|
|
||||||
#endif // not PLATFORM_WINDOWS
|
#endif // not PLATFORM_WINDOWS
|
||||||
|
|
||||||
inline void* operator new(size_t, void* p) throw() { return p; }
|
inline void* operator new(size_t, void* p) throw() { return p; }
|
||||||
|
|
||||||
|
typedef const char_t* string_t;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
inline int
|
inline int
|
||||||
OPEN(const char* path, int mask, int mode)
|
OPEN(string_t path, int mask, int mode)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
if (_sopen_s(&fd, path, mask, _SH_DENYNO, mode) == 0) {
|
if (_wsopen_s(&fd, path, mask, _SH_DENYNO, mode) == 0) {
|
||||||
return fd;
|
return fd;
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
@ -80,21 +94,21 @@ OPEN(const char* path, int mask, int mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline int
|
inline int
|
||||||
CREAT(const char* path, int mode)
|
CREAT(string_t path, int mode)
|
||||||
{
|
{
|
||||||
return OPEN(path, _O_CREAT, mode);
|
return OPEN(path, _O_CREAT, mode);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
exists(const char* path)
|
exists(string_t path)
|
||||||
{
|
{
|
||||||
STRUCT_STAT s;
|
STRUCT_STAT s;
|
||||||
return STAT(path, &s) == 0;
|
return STAT(path, &s) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int
|
inline int
|
||||||
doOpen(JNIEnv* e, const char* path, int mask)
|
doOpen(JNIEnv* e, string_t path, int mask)
|
||||||
{
|
{
|
||||||
int fd = OPEN(path, mask | OPEN_MASK, S_IRUSR | S_IWUSR);
|
int fd = OPEN(path, mask | OPEN_MASK, S_IRUSR | S_IWUSR);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
@ -157,10 +171,10 @@ class Mapping {
|
|||||||
};
|
};
|
||||||
|
|
||||||
inline Mapping*
|
inline Mapping*
|
||||||
map(JNIEnv* e, const char* path)
|
map(JNIEnv* e, string_t path)
|
||||||
{
|
{
|
||||||
Mapping* result = 0;
|
Mapping* result = 0;
|
||||||
HANDLE file = CreateFile(path, FILE_READ_DATA, FILE_SHARE_READ, 0,
|
HANDLE file = CreateFileW(path, FILE_READ_DATA, FILE_SHARE_READ, 0,
|
||||||
OPEN_EXISTING, 0, 0);
|
OPEN_EXISTING, 0, 0);
|
||||||
if (file != INVALID_HANDLE_VALUE) {
|
if (file != INVALID_HANDLE_VALUE) {
|
||||||
unsigned size = GetFileSize(file, 0);
|
unsigned size = GetFileSize(file, 0);
|
||||||
@ -205,10 +219,10 @@ class Directory {
|
|||||||
public:
|
public:
|
||||||
Directory(): handle(0), findNext(false) { }
|
Directory(): handle(0), findNext(false) { }
|
||||||
|
|
||||||
virtual const char* next() {
|
virtual string_t next() {
|
||||||
if (handle and handle != INVALID_HANDLE_VALUE) {
|
if (handle and handle != INVALID_HANDLE_VALUE) {
|
||||||
if (findNext) {
|
if (findNext) {
|
||||||
if (FindNextFile(handle, &data)) {
|
if (FindNextFileW(handle, &data)) {
|
||||||
return data.cFileName;
|
return data.cFileName;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -227,7 +241,7 @@ class Directory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
WIN32_FIND_DATA data;
|
WIN32_FIND_DATAW data;
|
||||||
bool findNext;
|
bool findNext;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -245,7 +259,7 @@ class Mapping {
|
|||||||
};
|
};
|
||||||
|
|
||||||
inline Mapping*
|
inline Mapping*
|
||||||
map(JNIEnv* e, const char* path)
|
map(JNIEnv* e, string_t path)
|
||||||
{
|
{
|
||||||
Mapping* result = 0;
|
Mapping* result = 0;
|
||||||
int fd = open(path, O_RDONLY);
|
int fd = open(path, O_RDONLY);
|
||||||
@ -280,6 +294,14 @@ unmap(JNIEnv*, Mapping* mapping)
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
inline string_t getChars(JNIEnv* e, jstring path) {
|
||||||
|
return reinterpret_cast<string_t>(e->GET_CHARS(path, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void releaseChars(JNIEnv* e, jstring path, string_t chars) {
|
||||||
|
e->RELEASE_CHARS(path, chars);
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jstring JNICALL
|
extern "C" JNIEXPORT jstring JNICALL
|
||||||
Java_java_io_File_toCanonicalPath(JNIEnv* /*e*/, jclass, jstring path)
|
Java_java_io_File_toCanonicalPath(JNIEnv* /*e*/, jclass, jstring path)
|
||||||
{
|
{
|
||||||
@ -297,14 +319,14 @@ Java_java_io_File_toAbsolutePath(JNIEnv* /*e*/, 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)
|
||||||
{
|
{
|
||||||
const char* chars = e->GetStringUTFChars(path, 0);
|
string_t chars = getChars(e, path);
|
||||||
if (chars) {
|
if (chars) {
|
||||||
STRUCT_STAT s;
|
STRUCT_STAT s;
|
||||||
int r = STAT(chars, &s);
|
int r = STAT(chars, &s);
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
return s.st_size;
|
return s.st_size;
|
||||||
}
|
}
|
||||||
e->ReleaseStringUTFChars(path, chars);
|
releaseChars(e, path, chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@ -313,7 +335,7 @@ Java_java_io_File_length(JNIEnv* e, jclass, jstring path)
|
|||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_java_io_File_mkdir(JNIEnv* e, jclass, jstring path)
|
Java_java_io_File_mkdir(JNIEnv* e, jclass, jstring path)
|
||||||
{
|
{
|
||||||
const char* chars = e->GetStringUTFChars(path, 0);
|
string_t chars = getChars(e, path);
|
||||||
if (chars) {
|
if (chars) {
|
||||||
if (not exists(chars)) {
|
if (not exists(chars)) {
|
||||||
int r = ::MKDIR(chars, 0700);
|
int r = ::MKDIR(chars, 0700);
|
||||||
@ -321,14 +343,14 @@ Java_java_io_File_mkdir(JNIEnv* e, jclass, jstring path)
|
|||||||
throwNewErrno(e, "java/io/IOException");
|
throwNewErrno(e, "java/io/IOException");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
e->ReleaseStringUTFChars(path, chars);
|
releaseChars(e, path, chars);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_java_io_File_createNewFile(JNIEnv* e, jclass, jstring path)
|
Java_java_io_File_createNewFile(JNIEnv* e, jclass, jstring path)
|
||||||
{
|
{
|
||||||
const char* chars = e->GetStringUTFChars(path, 0);
|
string_t chars = getChars(e, path);
|
||||||
if (chars) {
|
if (chars) {
|
||||||
if (not exists(chars)) {
|
if (not exists(chars)) {
|
||||||
int fd = CREAT(chars, 0600);
|
int fd = CREAT(chars, 0600);
|
||||||
@ -338,38 +360,38 @@ Java_java_io_File_createNewFile(JNIEnv* e, jclass, jstring path)
|
|||||||
doClose(e, fd);
|
doClose(e, fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
e->ReleaseStringUTFChars(path, chars);
|
releaseChars(e, path, chars);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_java_io_File_delete(JNIEnv* e, jclass, jstring path)
|
Java_java_io_File_delete(JNIEnv* e, jclass, jstring path)
|
||||||
{
|
{
|
||||||
const char* chars = e->GetStringUTFChars(path, 0);
|
string_t chars = getChars(e, path);
|
||||||
if (chars) {
|
if (chars) {
|
||||||
int r = UNLINK(chars);
|
int r = UNLINK(chars);
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
throwNewErrno(e, "java/io/IOException");
|
throwNewErrno(e, "java/io/IOException");
|
||||||
}
|
}
|
||||||
e->ReleaseStringUTFChars(path, chars);
|
releaseChars(e, path, chars);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jboolean JNICALL
|
extern "C" JNIEXPORT jboolean JNICALL
|
||||||
Java_java_io_File_rename(JNIEnv* e, jclass, jstring old, jstring new_)
|
Java_java_io_File_rename(JNIEnv* e, jclass, jstring old, jstring new_)
|
||||||
{
|
{
|
||||||
const char* oldChars = e->GetStringUTFChars(old, 0);
|
string_t oldChars = getChars(e, old);
|
||||||
const char* newChars = e->GetStringUTFChars(new_, 0);
|
string_t newChars = getChars(e, new_);
|
||||||
if (oldChars) {
|
if (oldChars) {
|
||||||
bool v;
|
bool v;
|
||||||
if (newChars) {
|
if (newChars) {
|
||||||
v = rename(oldChars, newChars) == 0;
|
v = RENAME(oldChars, newChars) == 0;
|
||||||
|
|
||||||
e->ReleaseStringUTFChars(new_, newChars);
|
releaseChars(e, new_, newChars);
|
||||||
} else {
|
} else {
|
||||||
v = false;
|
v = false;
|
||||||
}
|
}
|
||||||
e->ReleaseStringUTFChars(old, oldChars);
|
releaseChars(e, old, oldChars);
|
||||||
return v;
|
return v;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -379,12 +401,12 @@ Java_java_io_File_rename(JNIEnv* e, jclass, jstring old, jstring new_)
|
|||||||
extern "C" JNIEXPORT jboolean JNICALL
|
extern "C" JNIEXPORT jboolean JNICALL
|
||||||
Java_java_io_File_isDirectory(JNIEnv* e, jclass, jstring path)
|
Java_java_io_File_isDirectory(JNIEnv* e, jclass, jstring path)
|
||||||
{
|
{
|
||||||
const char* chars = e->GetStringUTFChars(path, 0);
|
string_t chars = getChars(e, path);
|
||||||
if (chars) {
|
if (chars) {
|
||||||
STRUCT_STAT s;
|
STRUCT_STAT s;
|
||||||
int r = STAT(chars, &s);
|
int r = STAT(chars, &s);
|
||||||
bool v = (r == 0 and S_ISDIR(s.st_mode));
|
bool v = (r == 0 and S_ISDIR(s.st_mode));
|
||||||
e->ReleaseStringUTFChars(path, chars);
|
releaseChars(e, path, chars);
|
||||||
return v;
|
return v;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -394,12 +416,12 @@ Java_java_io_File_isDirectory(JNIEnv* e, jclass, jstring path)
|
|||||||
extern "C" JNIEXPORT jboolean JNICALL
|
extern "C" JNIEXPORT jboolean JNICALL
|
||||||
Java_java_io_File_isFile(JNIEnv* e, jclass, jstring path)
|
Java_java_io_File_isFile(JNIEnv* e, jclass, jstring path)
|
||||||
{
|
{
|
||||||
const char* chars = e->GetStringUTFChars(path, 0);
|
string_t chars = getChars(e, path);
|
||||||
if (chars) {
|
if (chars) {
|
||||||
STRUCT_STAT s;
|
STRUCT_STAT s;
|
||||||
int r = STAT(chars, &s);
|
int r = STAT(chars, &s);
|
||||||
bool v = (r == 0 and S_ISREG(s.st_mode));
|
bool v = (r == 0 and S_ISREG(s.st_mode));
|
||||||
e->ReleaseStringUTFChars(path, chars);
|
releaseChars(e, path, chars);
|
||||||
return v;
|
return v;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -409,10 +431,10 @@ Java_java_io_File_isFile(JNIEnv* e, jclass, jstring path)
|
|||||||
extern "C" JNIEXPORT jboolean JNICALL
|
extern "C" JNIEXPORT jboolean JNICALL
|
||||||
Java_java_io_File_exists(JNIEnv* e, jclass, jstring path)
|
Java_java_io_File_exists(JNIEnv* e, jclass, jstring path)
|
||||||
{
|
{
|
||||||
const char* chars = e->GetStringUTFChars(path, 0);
|
string_t chars = getChars(e, path);
|
||||||
if (chars) {
|
if (chars) {
|
||||||
bool v = exists(chars);
|
bool v = exists(chars);
|
||||||
e->ReleaseStringUTFChars(path, chars);
|
releaseChars(e, path, chars);
|
||||||
return v;
|
return v;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -424,18 +446,19 @@ Java_java_io_File_exists(JNIEnv* e, jclass, jstring path)
|
|||||||
extern "C" JNIEXPORT jlong JNICALL
|
extern "C" JNIEXPORT jlong JNICALL
|
||||||
Java_java_io_File_openDir(JNIEnv* e, jclass, jstring path)
|
Java_java_io_File_openDir(JNIEnv* e, jclass, jstring path)
|
||||||
{
|
{
|
||||||
const char* chars = e->GetStringUTFChars(path, 0);
|
string_t chars = getChars(e, path);
|
||||||
if (chars) {
|
if (chars) {
|
||||||
unsigned length = strlen(chars);
|
unsigned length = wcslen(chars);
|
||||||
|
unsigned size = length * sizeof(char_t);
|
||||||
|
|
||||||
RUNTIME_ARRAY(char, buffer, length + 3);
|
RUNTIME_ARRAY(char_t, buffer, length + 3);
|
||||||
memcpy(RUNTIME_ARRAY_BODY(buffer), chars, length);
|
memcpy(RUNTIME_ARRAY_BODY(buffer), chars, size);
|
||||||
memcpy(RUNTIME_ARRAY_BODY(buffer) + length, "\\*", 3);
|
memcpy(RUNTIME_ARRAY_BODY(buffer) + length, L"\\*", 6);
|
||||||
|
|
||||||
e->ReleaseStringUTFChars(path, chars);
|
releaseChars(e, path, chars);
|
||||||
|
|
||||||
Directory* d = new (malloc(sizeof(Directory))) Directory;
|
Directory* d = new (malloc(sizeof(Directory))) Directory;
|
||||||
d->handle = FindFirstFile(RUNTIME_ARRAY_BODY(buffer), &(d->data));
|
d->handle = FindFirstFileW(RUNTIME_ARRAY_BODY(buffer), &(d->data));
|
||||||
if (d->handle == INVALID_HANDLE_VALUE) {
|
if (d->handle == INVALID_HANDLE_VALUE) {
|
||||||
d->dispose();
|
d->dispose();
|
||||||
d = 0;
|
d = 0;
|
||||||
@ -453,12 +476,12 @@ Java_java_io_File_readDir(JNIEnv* e, jclass, jlong handle)
|
|||||||
Directory* d = reinterpret_cast<Directory*>(handle);
|
Directory* d = reinterpret_cast<Directory*>(handle);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
const char* s = d->next();
|
string_t s = d->next();
|
||||||
if (s) {
|
if (s) {
|
||||||
if (strcmp(s, ".") == 0 || strcmp(s, "..") == 0) {
|
if (wcscmp(s, L".") == 0 || wcscmp(s, L"..") == 0) {
|
||||||
// skip . or .. and try again
|
// skip . or .. and try again
|
||||||
} else {
|
} else {
|
||||||
return e->NewStringUTF(s);
|
return e->NewString(reinterpret_cast<const jchar*>(s), wcslen(s));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
@ -477,10 +500,10 @@ Java_java_io_File_closeDir(JNIEnv* , jclass, jlong handle)
|
|||||||
extern "C" JNIEXPORT jlong JNICALL
|
extern "C" JNIEXPORT jlong JNICALL
|
||||||
Java_java_io_File_openDir(JNIEnv* e, jclass, jstring path)
|
Java_java_io_File_openDir(JNIEnv* e, jclass, jstring path)
|
||||||
{
|
{
|
||||||
const char* chars = e->GetStringUTFChars(path, 0);
|
string_t chars = getChars(e, path);
|
||||||
if (chars) {
|
if (chars) {
|
||||||
jlong handle = reinterpret_cast<jlong>(opendir(chars));
|
jlong handle = reinterpret_cast<jlong>(opendir(chars));
|
||||||
e->ReleaseStringUTFChars(path, chars);
|
releaseChars(e, path, chars);
|
||||||
return handle;
|
return handle;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
@ -522,10 +545,10 @@ Java_java_io_File_closeDir(JNIEnv* , jclass, jlong handle)
|
|||||||
extern "C" JNIEXPORT jint JNICALL
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
Java_java_io_FileInputStream_open(JNIEnv* e, jclass, jstring path)
|
Java_java_io_FileInputStream_open(JNIEnv* e, jclass, jstring path)
|
||||||
{
|
{
|
||||||
const char* chars = e->GetStringUTFChars(path, 0);
|
string_t chars = getChars(e, path);
|
||||||
if (chars) {
|
if (chars) {
|
||||||
int fd = doOpen(e, chars, O_RDONLY);
|
int fd = doOpen(e, chars, O_RDONLY);
|
||||||
e->ReleaseStringUTFChars(path, chars);
|
releaseChars(e, path, chars);
|
||||||
return fd;
|
return fd;
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
@ -572,10 +595,10 @@ Java_java_io_FileInputStream_close(JNIEnv* e, jclass, jint fd)
|
|||||||
extern "C" JNIEXPORT jint JNICALL
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
Java_java_io_FileOutputStream_open(JNIEnv* e, jclass, jstring path)
|
Java_java_io_FileOutputStream_open(JNIEnv* e, jclass, jstring path)
|
||||||
{
|
{
|
||||||
const char* chars = e->GetStringUTFChars(path, 0);
|
string_t chars = getChars(e, path);
|
||||||
if (chars) {
|
if (chars) {
|
||||||
int fd = doOpen(e, chars, O_WRONLY | O_CREAT | O_TRUNC);
|
int fd = doOpen(e, chars, O_WRONLY | O_CREAT | O_TRUNC);
|
||||||
e->ReleaseStringUTFChars(path, chars);
|
releaseChars(e, path, chars);
|
||||||
return fd;
|
return fd;
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
@ -618,7 +641,7 @@ extern "C" JNIEXPORT void JNICALL
|
|||||||
Java_java_io_RandomAccessFile_open(JNIEnv* e, jclass, jstring path,
|
Java_java_io_RandomAccessFile_open(JNIEnv* e, jclass, jstring path,
|
||||||
jlongArray result)
|
jlongArray result)
|
||||||
{
|
{
|
||||||
const char* chars = e->GetStringUTFChars(path, 0);
|
string_t chars = getChars(e, path);
|
||||||
if (chars) {
|
if (chars) {
|
||||||
Mapping* mapping = map(e, chars);
|
Mapping* mapping = map(e, chars);
|
||||||
|
|
||||||
@ -628,7 +651,7 @@ Java_java_io_RandomAccessFile_open(JNIEnv* e, jclass, jstring path,
|
|||||||
jlong length = (mapping ? mapping->length : 0);
|
jlong length = (mapping ? mapping->length : 0);
|
||||||
e->SetLongArrayRegion(result, 1, 1, &length);
|
e->SetLongArrayRegion(result, 1, 1, &length);
|
||||||
|
|
||||||
e->ReleaseStringUTFChars(path, chars);
|
releaseChars(e, path, chars);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,13 +56,15 @@ charsToArray(JNIEnv* e, const char* s)
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
inline void
|
inline void
|
||||||
close(int socket)
|
doClose(int socket)
|
||||||
{
|
{
|
||||||
|
#ifdef PLATFORM_WINDOWS
|
||||||
closesocket(socket);
|
closesocket(socket);
|
||||||
}
|
#else
|
||||||
|
close(socket);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
inline jbyteArray
|
inline jbyteArray
|
||||||
errorString(JNIEnv* e, int n)
|
errorString(JNIEnv* e, int n)
|
||||||
@ -428,13 +430,32 @@ Java_java_nio_channels_SocketChannel_natRead(JNIEnv *e,
|
|||||||
jint socket,
|
jint socket,
|
||||||
jbyteArray buffer,
|
jbyteArray buffer,
|
||||||
jint offset,
|
jint offset,
|
||||||
jint length)
|
jint length,
|
||||||
|
jboolean blocking)
|
||||||
{
|
{
|
||||||
|
int r;
|
||||||
|
if (blocking) {
|
||||||
|
uint8_t* buf = static_cast<uint8_t*>(allocate(e, length));
|
||||||
|
if (buf) {
|
||||||
|
r = ::doRead(socket, buf, length);
|
||||||
|
if (r > 0) {
|
||||||
|
e->SetByteArrayRegion
|
||||||
|
(buffer, offset, r, reinterpret_cast<jbyte*>(buf));
|
||||||
|
}
|
||||||
|
free(buf);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
jboolean isCopy;
|
jboolean isCopy;
|
||||||
uint8_t *buf = static_cast<uint8_t*>
|
uint8_t* buf = static_cast<uint8_t*>
|
||||||
(e->GetPrimitiveArrayCritical(buffer, &isCopy));
|
(e->GetPrimitiveArrayCritical(buffer, &isCopy));
|
||||||
int r = ::doRead(socket, buf + offset, length);
|
|
||||||
|
r = ::doRead(socket, buf + offset, length);
|
||||||
|
|
||||||
e->ReleasePrimitiveArrayCritical(buffer, buf, 0);
|
e->ReleasePrimitiveArrayCritical(buffer, buf, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
if (eagain()) {
|
if (eagain()) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -453,13 +474,30 @@ Java_java_nio_channels_SocketChannel_natWrite(JNIEnv *e,
|
|||||||
jint socket,
|
jint socket,
|
||||||
jbyteArray buffer,
|
jbyteArray buffer,
|
||||||
jint offset,
|
jint offset,
|
||||||
jint length)
|
jint length,
|
||||||
|
jboolean blocking)
|
||||||
{
|
{
|
||||||
|
int r;
|
||||||
|
if (blocking) {
|
||||||
|
uint8_t* buf = static_cast<uint8_t*>(allocate(e, length));
|
||||||
|
if (buf) {
|
||||||
|
e->GetByteArrayRegion
|
||||||
|
(buffer, offset, length, reinterpret_cast<jbyte*>(buf));
|
||||||
|
r = ::doWrite(socket, buf, length);
|
||||||
|
free(buf);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
jboolean isCopy;
|
jboolean isCopy;
|
||||||
uint8_t *buf = static_cast<uint8_t*>
|
uint8_t* buf = static_cast<uint8_t*>
|
||||||
(e->GetPrimitiveArrayCritical(buffer, &isCopy));
|
(e->GetPrimitiveArrayCritical(buffer, &isCopy));
|
||||||
int r = ::doWrite(socket, buf + offset, length);
|
|
||||||
|
r = ::doWrite(socket, buf + offset, length);
|
||||||
|
|
||||||
e->ReleasePrimitiveArrayCritical(buffer, buf, 0);
|
e->ReleasePrimitiveArrayCritical(buffer, buf, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
if (eagain()) {
|
if (eagain()) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -492,7 +530,7 @@ Java_java_nio_channels_SocketChannel_natCloseSocket(JNIEnv *,
|
|||||||
jclass,
|
jclass,
|
||||||
jint socket)
|
jint socket)
|
||||||
{
|
{
|
||||||
close(socket);
|
doClose(socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -526,9 +564,9 @@ class Pipe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void dispose() {
|
void dispose() {
|
||||||
if (listener_ >= 0) ::close(listener_);
|
if (listener_ >= 0) ::doClose(listener_);
|
||||||
if (reader_ >= 0) ::close(reader_);
|
if (reader_ >= 0) ::doClose(reader_);
|
||||||
if (writer_ >= 0) ::close(writer_);
|
if (writer_ >= 0) ::doClose(writer_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool connected() {
|
bool connected() {
|
||||||
@ -579,8 +617,8 @@ class Pipe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void dispose() {
|
void dispose() {
|
||||||
::close(pipe[0]);
|
::doClose(pipe[0]);
|
||||||
::close(pipe[1]);
|
::doClose(pipe[1]);
|
||||||
open_ = false;
|
open_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -742,9 +780,9 @@ Java_java_nio_channels_SocketSelector_natDoSocketSelect(JNIEnv *e, jclass,
|
|||||||
if (FD_ISSET(s->control.writer(), &(s->write)) or
|
if (FD_ISSET(s->control.writer(), &(s->write)) or
|
||||||
FD_ISSET(s->control.writer(), &(s->except)))
|
FD_ISSET(s->control.writer(), &(s->except)))
|
||||||
{
|
{
|
||||||
unsigned socket = s->control.writer();
|
int socket = s->control.writer();
|
||||||
FD_CLR(socket, &(s->write));
|
FD_CLR(static_cast<unsigned>(socket), &(s->write));
|
||||||
FD_CLR(socket, &(s->except));
|
FD_CLR(static_cast<unsigned>(socket), &(s->except));
|
||||||
|
|
||||||
int error;
|
int error;
|
||||||
socklen_t size = sizeof(int);
|
socklen_t size = sizeof(int);
|
||||||
|
16
classpath/java/io/Externalizable.java
Normal file
16
classpath/java/io/Externalizable.java
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/* Copyright (c) 2010, 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. */
|
||||||
|
|
||||||
|
package java.io;
|
||||||
|
|
||||||
|
public interface Externalizable {
|
||||||
|
public void readExternal(ObjectInput in);
|
||||||
|
public void writeExternal(ObjectOutput out);
|
||||||
|
}
|
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
package java.io;
|
package java.io;
|
||||||
|
|
||||||
|
import avian.Utf8;
|
||||||
|
|
||||||
public class InputStreamReader extends Reader {
|
public class InputStreamReader extends Reader {
|
||||||
private final InputStream in;
|
private final InputStream in;
|
||||||
|
|
||||||
@ -31,10 +33,14 @@ public class InputStreamReader extends Reader {
|
|||||||
public int read(char[] b, int offset, int length) throws IOException {
|
public int read(char[] b, int offset, int length) throws IOException {
|
||||||
byte[] buffer = new byte[length];
|
byte[] buffer = new byte[length];
|
||||||
int c = in.read(buffer);
|
int c = in.read(buffer);
|
||||||
for (int i = 0; i < c; ++i) {
|
|
||||||
b[i + offset] = (char) buffer[i];
|
if (c <= 0) return c;
|
||||||
}
|
|
||||||
return c;
|
char[] buffer16 = Utf8.decode16(buffer, 0, c);
|
||||||
|
|
||||||
|
System.arraycopy(buffer16, 0, b, offset, buffer16.length);
|
||||||
|
|
||||||
|
return buffer16.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
|
21
classpath/java/io/ObjectInput.java
Normal file
21
classpath/java/io/ObjectInput.java
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/* Copyright (c) 2010, 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. */
|
||||||
|
|
||||||
|
package java.io;
|
||||||
|
|
||||||
|
public interface ObjectInput {
|
||||||
|
public int available();
|
||||||
|
public void close();
|
||||||
|
public void read();
|
||||||
|
public void read(byte[] b);
|
||||||
|
public void read(byte[] b, int off, int len);
|
||||||
|
public Object readObject();
|
||||||
|
public long skip(long n);
|
||||||
|
}
|
20
classpath/java/io/ObjectOutput.java
Normal file
20
classpath/java/io/ObjectOutput.java
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/* Copyright (c) 2010, 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. */
|
||||||
|
|
||||||
|
package java.io;
|
||||||
|
|
||||||
|
public interface ObjectOutput {
|
||||||
|
public void close();
|
||||||
|
public void flush();
|
||||||
|
public void write(byte[] b);
|
||||||
|
public void write(byte[] b, int off, int len);
|
||||||
|
public void write(int b);
|
||||||
|
public void writeObject(Object obj);
|
||||||
|
}
|
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
package java.io;
|
package java.io;
|
||||||
|
|
||||||
|
import avian.Utf8;
|
||||||
|
|
||||||
public class OutputStreamWriter extends Writer {
|
public class OutputStreamWriter extends Writer {
|
||||||
private final OutputStream out;
|
private final OutputStream out;
|
||||||
|
|
||||||
@ -18,11 +20,7 @@ public class OutputStreamWriter extends Writer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void write(char[] b, int offset, int length) throws IOException {
|
public void write(char[] b, int offset, int length) throws IOException {
|
||||||
byte[] buffer = new byte[length];
|
out.write(Utf8.encode(b, offset, length));
|
||||||
for (int i = 0; i < length; ++i) {
|
|
||||||
buffer[i] = (byte) b[i + offset];
|
|
||||||
}
|
|
||||||
out.write(buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void flush() throws IOException {
|
public void flush() throws IOException {
|
||||||
|
@ -15,8 +15,8 @@ import java.util.regex.Pattern;
|
|||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Formatter;
|
import java.util.Formatter;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import avian.Utf8;
|
||||||
|
|
||||||
public final class String
|
public final class String
|
||||||
implements Comparable<String>, CharSequence, Serializable
|
implements Comparable<String>, CharSequence, Serializable
|
||||||
@ -112,7 +112,7 @@ public final class String
|
|||||||
(offset + " < 0 or " + offset + " + " + length + " > " + l);
|
(offset + " < 0 or " + offset + " + " + length + " > " + l);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!copy && isUTF8(data)) copy = true;
|
if(!copy && Utf8.test(data)) copy = true;
|
||||||
|
|
||||||
if (copy) {
|
if (copy) {
|
||||||
Object c;
|
Object c;
|
||||||
@ -120,7 +120,7 @@ public final class String
|
|||||||
c = new char[length];
|
c = new char[length];
|
||||||
System.arraycopy(data, offset, c, 0, length);
|
System.arraycopy(data, offset, c, 0, length);
|
||||||
} else {
|
} else {
|
||||||
c = decodeUTF8((byte[])data, offset, length);
|
c = Utf8.decode((byte[])data, offset, length);
|
||||||
if(c instanceof char[]) length = ((char[])c).length;
|
if(c instanceof char[]) length = ((char[])c).length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,85 +134,6 @@ public final class String
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isUTF8(Object data) {
|
|
||||||
if(!(data instanceof byte[])) return false;
|
|
||||||
byte[] b = (byte[])data;
|
|
||||||
for(int i = 0; i < b.length; ++i) {
|
|
||||||
if(((int)b[i] & 0x080) != 0) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static byte[] encodeUTF8(char[] s16, int offset, int length) {
|
|
||||||
ByteArrayOutputStream buf = new ByteArrayOutputStream();
|
|
||||||
for(int i = offset; i < offset+length; ++i) {
|
|
||||||
char c = s16[i];
|
|
||||||
if(c == '\u0000') { // null char
|
|
||||||
buf.write(0);
|
|
||||||
buf.write(0);
|
|
||||||
} else if(c < 0x080) { // 1 byte char
|
|
||||||
buf.write(c);
|
|
||||||
} else if(c < 0x0800) { // 2 byte char
|
|
||||||
buf.write(0x0c0 | (c >>> 6));
|
|
||||||
buf.write(0x080 | (c & 0x03f));
|
|
||||||
} else { // 3 byte char
|
|
||||||
buf.write(0x0e0 | ((c >>> 12) & 0x0f));
|
|
||||||
buf.write(0x080 | ((c >>> 6) & 0x03f));
|
|
||||||
buf.write(0x080 | (c & 0x03f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return buf.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void decodeUTF8_insert(Object data, int index, int val) {
|
|
||||||
if(data instanceof byte[]) ((byte[])data)[index] = (byte)val;
|
|
||||||
else ((char[])data)[index] = (char)val;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Object decodeUTF8_widen(Object data, int length, int capacity) {
|
|
||||||
byte[] src = (byte[])data;
|
|
||||||
char[] result = new char[capacity];
|
|
||||||
for(int i = 0; i < length; ++i) result[i] = (char)((int)src[i] & 0x0ff);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Object decodeUTF8_trim(Object data, int length) {
|
|
||||||
if(data instanceof byte[]) return data;
|
|
||||||
if(((char[])data).length == length) return data;
|
|
||||||
char[] result = new char[length];
|
|
||||||
System.arraycopy(data, 0, result, 0, length);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Object decodeUTF8(byte[] s8, int offset, int length) {
|
|
||||||
Object buf = new byte[length];
|
|
||||||
boolean isMultiByte = false;
|
|
||||||
int i=offset, j=0;
|
|
||||||
while(i < offset+length) {
|
|
||||||
int x = s8[i++];
|
|
||||||
if((x & 0x080) == 0x0) { // 1 byte char
|
|
||||||
if(x == 0) ++i; // 2 byte null char
|
|
||||||
decodeUTF8_insert(buf, j++, x);
|
|
||||||
} else if((x & 0x0e0) == 0x0c0) { // 2 byte char
|
|
||||||
if(!isMultiByte) {
|
|
||||||
buf = decodeUTF8_widen(buf, j, length-1);
|
|
||||||
isMultiByte = true;
|
|
||||||
}
|
|
||||||
int y = s8[i++];
|
|
||||||
decodeUTF8_insert(buf, j++, ((x & 0x1f) << 6) | (y & 0x3f));
|
|
||||||
} else if((x & 0x0f0) == 0x0e0) { // 3 byte char
|
|
||||||
if(!isMultiByte) {
|
|
||||||
buf = decodeUTF8_widen(buf, j, length-2);
|
|
||||||
isMultiByte = true;
|
|
||||||
}
|
|
||||||
int y = s8[i++]; int z = s8[i++];
|
|
||||||
decodeUTF8_insert(buf, j++, ((x & 0xf) << 12) | ((y & 0x3f) << 6) | (z & 0x3f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return decodeUTF8_trim(buf, j);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -494,7 +415,7 @@ public final class String
|
|||||||
getBytes(0, length, b, 0);
|
getBytes(0, length, b, 0);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
return encodeUTF8((char[])data, offset, length);
|
return Utf8.encode((char[])data, offset, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getBytes(String format)
|
public byte[] getBytes(String format)
|
||||||
|
@ -15,6 +15,7 @@ import java.nio.ByteBuffer;
|
|||||||
|
|
||||||
public abstract class SelectableChannel implements Channel {
|
public abstract class SelectableChannel implements Channel {
|
||||||
private SelectionKey key;
|
private SelectionKey key;
|
||||||
|
private boolean open = true;
|
||||||
|
|
||||||
abstract int socketFD();
|
abstract int socketFD();
|
||||||
|
|
||||||
@ -30,12 +31,11 @@ public abstract class SelectableChannel implements Channel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isOpen() {
|
public boolean isOpen() {
|
||||||
return key != null;
|
return open;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
if (key != null) {
|
open = false;
|
||||||
key = null;
|
key = null;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,7 @@ public class SocketChannel extends SelectableChannel
|
|||||||
byte[] array = b.array();
|
byte[] array = b.array();
|
||||||
if (array == null) throw new NullPointerException();
|
if (array == null) throw new NullPointerException();
|
||||||
|
|
||||||
int r = natRead(socket, array, b.arrayOffset() + b.position(), b.remaining());
|
int r = natRead(socket, array, b.arrayOffset() + b.position(), b.remaining(), blocking);
|
||||||
if (r > 0) {
|
if (r > 0) {
|
||||||
b.position(b.position() + r);
|
b.position(b.position() + r);
|
||||||
}
|
}
|
||||||
@ -108,7 +108,7 @@ public class SocketChannel extends SelectableChannel
|
|||||||
byte[] array = b.array();
|
byte[] array = b.array();
|
||||||
if (array == null) throw new NullPointerException();
|
if (array == null) throw new NullPointerException();
|
||||||
|
|
||||||
int w = natWrite(socket, array, b.arrayOffset() + b.position(), b.remaining());
|
int w = natWrite(socket, array, b.arrayOffset() + b.position(), b.remaining(), blocking);
|
||||||
if (w > 0) {
|
if (w > 0) {
|
||||||
b.position(b.position() + w);
|
b.position(b.position() + w);
|
||||||
}
|
}
|
||||||
@ -139,9 +139,9 @@ public class SocketChannel extends SelectableChannel
|
|||||||
throws IOException;
|
throws IOException;
|
||||||
private static native boolean natFinishConnect(int socket)
|
private static native boolean natFinishConnect(int socket)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
private static native int natRead(int socket, byte[] buffer, int offset, int length)
|
private static native int natRead(int socket, byte[] buffer, int offset, int length, boolean blocking)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
private static native int natWrite(int socket, byte[] buffer, int offset, int length)
|
private static native int natWrite(int socket, byte[] buffer, int offset, int length, boolean blocking)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
private static native void natThrowWriteError(int socket) throws IOException;
|
private static native void natThrowWriteError(int socket) throws IOException;
|
||||||
private static native void natCloseSocket(int socket);
|
private static native void natCloseSocket(int socket);
|
||||||
|
18
makefile
18
makefile
@ -3,7 +3,7 @@ MAKEFLAGS = -s
|
|||||||
name = avian
|
name = avian
|
||||||
version = 0.3
|
version = 0.3
|
||||||
|
|
||||||
build-arch := $(shell uname -m | sed 's/^i.86$$/i386/')
|
build-arch := $(shell uname -m | sed 's/^i.86$$/i386/' | sed 's/^arm.*$$/arm/')
|
||||||
ifeq (Power,$(filter Power,$(build-arch)))
|
ifeq (Power,$(filter Power,$(build-arch)))
|
||||||
build-arch = powerpc
|
build-arch = powerpc
|
||||||
endif
|
endif
|
||||||
@ -145,19 +145,8 @@ ifeq ($(arch),powerpc)
|
|||||||
pointer-size = 4
|
pointer-size = 4
|
||||||
endif
|
endif
|
||||||
ifeq ($(arch),arm)
|
ifeq ($(arch),arm)
|
||||||
lflags := -L/opt/crosstool/gcc-4.1.0-glibc-2.3.2/arm-unknown-linux-gnu/arm-unknown-linux-gnu/lib -L$(root)/arm/lib $(lflags)
|
|
||||||
cflags := -I/opt/crosstool/gcc-4.1.0-glibc-2.3.2/arm-unknown-linux-gnu/arm-unknown-linux-gnu/include -I$(root)/arm/include $(cflags)
|
|
||||||
|
|
||||||
asm = arm
|
asm = arm
|
||||||
object-arch = arm
|
|
||||||
object-format = elf32-littlearm
|
|
||||||
pointer-size = 4
|
pointer-size = 4
|
||||||
cxx = arm-unknown-linux-gnu-g++
|
|
||||||
cc = arm-unknown-linux-gnu-gcc
|
|
||||||
ar = arm-unknown-linux-gnu-ar
|
|
||||||
ranlib = arm-unknown-linux-gnu-ranlib
|
|
||||||
objcopy = arm-unknown-linux-gnu-objcopy
|
|
||||||
strip = arm-unknown-linux-gnu-strip
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(platform),darwin)
|
ifeq ($(platform),darwin)
|
||||||
@ -223,8 +212,8 @@ ifeq ($(platform),windows)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(arch),x86_64)
|
ifeq ($(arch),x86_64)
|
||||||
cxx = x86_64-w64-mingw32-g++
|
cxx = x86_64-w64-mingw32-g++ $(mflag)
|
||||||
cc = x86_64-w64-mingw32-gcc
|
cc = x86_64-w64-mingw32-gcc $(mflag)
|
||||||
dlltool = x86_64-w64-mingw32-dlltool
|
dlltool = x86_64-w64-mingw32-dlltool
|
||||||
ar = x86_64-w64-mingw32-ar
|
ar = x86_64-w64-mingw32-ar
|
||||||
ranlib = x86_64-w64-mingw32-ranlib
|
ranlib = x86_64-w64-mingw32-ranlib
|
||||||
@ -277,6 +266,7 @@ ifdef msvc
|
|||||||
ld = "$(msvc)/BIN/link.exe"
|
ld = "$(msvc)/BIN/link.exe"
|
||||||
mt = "mt.exe"
|
mt = "mt.exe"
|
||||||
cflags = -nologo -DAVIAN_VERSION=\"$(version)\" -D_JNI_IMPLEMENTATION_ \
|
cflags = -nologo -DAVIAN_VERSION=\"$(version)\" -D_JNI_IMPLEMENTATION_ \
|
||||||
|
-DUSE_ATOMIC_OPERATIONS \
|
||||||
-Fd$(native-build)/$(name).pdb -I"$(zlib)/include" -I$(src) \
|
-Fd$(native-build)/$(name).pdb -I"$(zlib)/include" -I$(src) \
|
||||||
-I"$(native-build)" -I"$(windows-java-home)/include" \
|
-I"$(native-build)" -I"$(windows-java-home)/include" \
|
||||||
-I"$(windows-java-home)/include/win32"
|
-I"$(windows-java-home)/include/win32"
|
||||||
|
@ -11,6 +11,14 @@
|
|||||||
#ifndef ARCH_H
|
#ifndef ARCH_H
|
||||||
#define ARCH_H
|
#define ARCH_H
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# include "windows.h"
|
||||||
|
# pragma push_macro("assert")
|
||||||
|
# include "intrin.h"
|
||||||
|
# pragma pop_macro("assert")
|
||||||
|
# undef interface
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
extern "C" void NO_RETURN
|
extern "C" void NO_RETURN
|
||||||
|
41
src/arm.h
41
src/arm.h
@ -14,9 +14,9 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#define IP_REGISTER(context) (context->uc_mcontext.gregs[15])
|
#define IP_REGISTER(context) (context->uc_mcontext.arm_pc)
|
||||||
#define STACK_REGISTER(context) (context->uc_mcontext.gregs[13])
|
#define STACK_REGISTER(context) (context->uc_mcontext.arm_sp)
|
||||||
#define THREAD_REGISTER(context) (context->uc_mcontext.gregs[12])
|
#define THREAD_REGISTER(context) (context->uc_mcontext.arm_ip)
|
||||||
|
|
||||||
extern "C" uint64_t
|
extern "C" uint64_t
|
||||||
vmNativeCall(void* function, unsigned stackTotal, void* memoryTable,
|
vmNativeCall(void* function, unsigned stackTotal, void* memoryTable,
|
||||||
@ -60,16 +60,32 @@ syncInstructionCache(const void* start UNUSED, unsigned size UNUSED)
|
|||||||
asm("nop");
|
asm("nop");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr);
|
||||||
|
#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0)
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
atomicCompareAndSwap32(uint32_t* p, uint32_t old, uint32_t new_)
|
||||||
|
{
|
||||||
|
int r = __kernel_cmpxchg(static_cast<int>(old), static_cast<int>(new_), reinterpret_cast<int*>(p));
|
||||||
|
return (!r ? true : false);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
atomicCompareAndSwap(uintptr_t* p, uintptr_t old, uintptr_t new_)
|
||||||
|
{
|
||||||
|
return atomicCompareAndSwap32(reinterpret_cast<uint32_t*>(p), old, new_);
|
||||||
|
}
|
||||||
|
|
||||||
inline uint64_t
|
inline uint64_t
|
||||||
dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
|
dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
|
||||||
unsigned argumentCount, unsigned argumentsSize,
|
unsigned argumentCount, unsigned argumentsSize UNUSED,
|
||||||
unsigned returnType UNUSED)
|
unsigned returnType UNUSED)
|
||||||
{
|
{
|
||||||
const unsigned GprCount = 4;
|
const unsigned GprCount = 4;
|
||||||
uintptr_t gprTable[GprCount];
|
uintptr_t gprTable[GprCount];
|
||||||
unsigned gprIndex = 0;
|
unsigned gprIndex = 0;
|
||||||
|
|
||||||
uintptr_t stack[argumentsSize / BytesPerWord];
|
uintptr_t stack[(argumentCount * 8) / BytesPerWord]; // is > argumentSize to account for padding
|
||||||
unsigned stackIndex = 0;
|
unsigned stackIndex = 0;
|
||||||
|
|
||||||
unsigned ai = 0;
|
unsigned ai = 0;
|
||||||
@ -77,15 +93,18 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
|
|||||||
switch (argumentTypes[ati]) {
|
switch (argumentTypes[ati]) {
|
||||||
case DOUBLE_TYPE:
|
case DOUBLE_TYPE:
|
||||||
case INT64_TYPE: {
|
case INT64_TYPE: {
|
||||||
if (gprIndex + (8 / BytesPerWord) <= GprCount) {
|
if (gprIndex + (8 / BytesPerWord) <= GprCount) { // pass argument on registers
|
||||||
|
if (gprIndex & 1) { // 8-byte alignment
|
||||||
|
memset(gprTable + gprIndex, 0, 4); // probably not necessary, but for good luck
|
||||||
|
++gprIndex;
|
||||||
|
}
|
||||||
memcpy(gprTable + gprIndex, arguments + ai, 8);
|
memcpy(gprTable + gprIndex, arguments + ai, 8);
|
||||||
gprIndex += 8 / BytesPerWord;
|
gprIndex += 8 / BytesPerWord;
|
||||||
} else if (gprIndex == GprCount-1) { // split between last GPR and stack
|
} else { // pass argument on stack
|
||||||
memcpy(gprTable + gprIndex, arguments + ai, 4);
|
if (stackIndex & 1) { // 8-byte alignment
|
||||||
++gprIndex;
|
memset(stack + stackIndex, 0, 4); // probably not necessary, but for good luck
|
||||||
memcpy(stack + stackIndex, arguments + ai + 4, 4);
|
|
||||||
++stackIndex;
|
++stackIndex;
|
||||||
} else {
|
}
|
||||||
memcpy(stack + stackIndex, arguments + ai, 8);
|
memcpy(stack + stackIndex, arguments + ai, 8);
|
||||||
stackIndex += 8 / BytesPerWord;
|
stackIndex += 8 / BytesPerWord;
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
|
|
||||||
#define EM_386 3
|
#define EM_386 3
|
||||||
#define EM_X86_64 62
|
#define EM_X86_64 62
|
||||||
|
#define EM_ARM 40
|
||||||
|
|
||||||
#define SHT_PROGBITS 1
|
#define SHT_PROGBITS 1
|
||||||
#define SHT_SYMTAB 2
|
#define SHT_SYMTAB 2
|
||||||
@ -352,6 +353,8 @@ MAKE_NAME(writeElf, BITS_PER_WORD, Object)
|
|||||||
machine = EM_X86_64;
|
machine = EM_X86_64;
|
||||||
} else if (strcmp(architecture, "i386") == 0) {
|
} else if (strcmp(architecture, "i386") == 0) {
|
||||||
machine = EM_386;
|
machine = EM_386;
|
||||||
|
} else if (strcmp(architecture, "arm") == 0) {
|
||||||
|
machine = EM_ARM;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "unsupported architecture: %s\n", architecture);
|
fprintf(stderr, "unsupported architecture: %s\n", architecture);
|
||||||
return false;
|
return false;
|
||||||
|
@ -73,7 +73,8 @@ writeObject(uint8_t* data, unsigned size, FILE* out, const char* startName,
|
|||||||
success = writeElf64Object
|
success = writeElf64Object
|
||||||
(data, size, out, startName, endName, architecture, alignment,
|
(data, size, out, startName, endName, architecture, alignment,
|
||||||
writable, executable);
|
writable, executable);
|
||||||
} else if (strcmp("i386", architecture) == 0) {
|
} else if (strcmp("i386", architecture) == 0 ||
|
||||||
|
strcmp("arm", architecture) == 0) {
|
||||||
found = true;
|
found = true;
|
||||||
success = writeElf32Object
|
success = writeElf32Object
|
||||||
(data, size, out, startName, endName, architecture, alignment,
|
(data, size, out, startName, endName, architecture, alignment,
|
||||||
|
@ -118,9 +118,6 @@ inline void
|
|||||||
pushDouble(Thread* t, double v)
|
pushDouble(Thread* t, double v)
|
||||||
{
|
{
|
||||||
uint64_t w = doubleToBits(v);
|
uint64_t w = doubleToBits(v);
|
||||||
#ifdef __arm__
|
|
||||||
w = w << 32 | w >> 32;
|
|
||||||
#endif
|
|
||||||
pushLong(t, w);
|
pushLong(t, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,9 +172,6 @@ inline double
|
|||||||
popDouble(Thread* t)
|
popDouble(Thread* t)
|
||||||
{
|
{
|
||||||
uint64_t v = popLong(t);
|
uint64_t v = popLong(t);
|
||||||
#ifdef __arm__
|
|
||||||
v = v << 32 | v >> 32;
|
|
||||||
#endif
|
|
||||||
return bitsToDouble(v);
|
return bitsToDouble(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -569,15 +563,6 @@ pushResult(Thread* t, unsigned returnCode, uint64_t result, bool indirect)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DoubleField:
|
case DoubleField:
|
||||||
#ifdef __arm__
|
|
||||||
result = result << 32 | result >> 32;
|
|
||||||
if (DebugRun) {
|
|
||||||
fprintf(stderr, "result: %"LLD"\n", result);
|
|
||||||
}
|
|
||||||
pushLong(t, result);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case LongField:
|
case LongField:
|
||||||
if (DebugRun) {
|
if (DebugRun) {
|
||||||
fprintf(stderr, "result: %"LLD"\n", result);
|
fprintf(stderr, "result: %"LLD"\n", result);
|
||||||
@ -629,15 +614,6 @@ marshalArguments(Thread* t, uintptr_t* args, unsigned i, unsigned count,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DOUBLE_TYPE:
|
case DOUBLE_TYPE:
|
||||||
#ifdef __arm__
|
|
||||||
{
|
|
||||||
uint64_t v = peekLong(t, sp);
|
|
||||||
v = v << 32 | v >> 32;
|
|
||||||
memcpy(args + offset, &v, 8);
|
|
||||||
offset += (8 / BytesPerWord);
|
|
||||||
sp += 2;
|
|
||||||
} break;
|
|
||||||
#endif
|
|
||||||
case INT64_TYPE: {
|
case INT64_TYPE: {
|
||||||
uint64_t v = peekLong(t, sp);
|
uint64_t v = peekLong(t, sp);
|
||||||
memcpy(args + offset, &v, 8);
|
memcpy(args + offset, &v, 8);
|
||||||
|
350
src/jnienv.cpp
350
src/jnienv.cpp
@ -13,12 +13,13 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "processor.h"
|
#include "processor.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "processor.h"
|
|
||||||
|
|
||||||
using namespace vm;
|
using namespace vm;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
namespace local {
|
||||||
|
|
||||||
const uintptr_t InterfaceMethodID
|
const uintptr_t InterfaceMethodID
|
||||||
= (static_cast<uintptr_t>(1) << (BitsPerWord - 1));
|
= (static_cast<uintptr_t>(1) << (BitsPerWord - 1));
|
||||||
|
|
||||||
@ -118,7 +119,7 @@ GetEnv(Machine* m, Thread** t, jint version)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jsize JNICALL
|
jint JNICALL
|
||||||
GetVersion(Thread* t)
|
GetVersion(Thread* t)
|
||||||
{
|
{
|
||||||
ENTER(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
@ -160,7 +161,7 @@ GetStringUTFLength(Thread* t, jstring s)
|
|||||||
{
|
{
|
||||||
ENTER(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
return stringLength(t, *s);
|
return stringUTFLength(t, *s);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* JNICALL
|
const char* JNICALL
|
||||||
@ -168,9 +169,10 @@ GetStringUTFChars(Thread* t, jstring s, jboolean* isCopy)
|
|||||||
{
|
{
|
||||||
ENTER(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
|
int length = stringUTFLength(t, *s);
|
||||||
char* chars = static_cast<char*>
|
char* chars = static_cast<char*>
|
||||||
(t->m->heap->allocate(stringLength(t, *s) + 1));
|
(t->m->heap->allocate(length + 1));
|
||||||
stringChars(t, *s, chars);
|
stringUTFChars(t, *s, chars, length);
|
||||||
|
|
||||||
if (isCopy) *isCopy = true;
|
if (isCopy) *isCopy = true;
|
||||||
return chars;
|
return chars;
|
||||||
@ -1907,6 +1909,8 @@ append(char** p, const char* value, unsigned length, char tail)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace local
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace vm {
|
namespace vm {
|
||||||
@ -1927,170 +1931,171 @@ populateJNITables(JavaVMVTable* vmTable, JNIEnvVTable* envTable)
|
|||||||
{
|
{
|
||||||
memset(vmTable, 0, sizeof(JavaVMVTable));
|
memset(vmTable, 0, sizeof(JavaVMVTable));
|
||||||
|
|
||||||
vmTable->DestroyJavaVM = DestroyJavaVM;
|
vmTable->DestroyJavaVM = local::DestroyJavaVM;
|
||||||
vmTable->AttachCurrentThread = AttachCurrentThread;
|
vmTable->AttachCurrentThread = local::AttachCurrentThread;
|
||||||
vmTable->AttachCurrentThreadAsDaemon = AttachCurrentThreadAsDaemon;
|
vmTable->AttachCurrentThreadAsDaemon = local::AttachCurrentThreadAsDaemon;
|
||||||
vmTable->DetachCurrentThread = DetachCurrentThread;
|
vmTable->DetachCurrentThread = local::DetachCurrentThread;
|
||||||
vmTable->GetEnv = GetEnv;
|
vmTable->GetEnv = local::GetEnv;
|
||||||
|
|
||||||
memset(envTable, 0, sizeof(JNIEnvVTable));
|
memset(envTable, 0, sizeof(JNIEnvVTable));
|
||||||
|
|
||||||
envTable->GetVersion = ::GetVersion;
|
envTable->GetVersion = local::GetVersion;
|
||||||
envTable->GetStringLength = ::GetStringLength;
|
envTable->GetStringLength = local::GetStringLength;
|
||||||
envTable->GetStringChars = ::GetStringChars;
|
envTable->GetStringChars = local::GetStringChars;
|
||||||
envTable->ReleaseStringChars = ::ReleaseStringChars;
|
envTable->ReleaseStringChars = local::ReleaseStringChars;
|
||||||
envTable->GetStringUTFLength = ::GetStringUTFLength;
|
envTable->GetStringUTFLength = local::GetStringUTFLength;
|
||||||
envTable->GetStringUTFChars = ::GetStringUTFChars;
|
envTable->GetStringUTFChars = local::GetStringUTFChars;
|
||||||
envTable->ReleaseStringUTFChars = ::ReleaseStringUTFChars;
|
envTable->ReleaseStringUTFChars = local::ReleaseStringUTFChars;
|
||||||
envTable->GetArrayLength = ::GetArrayLength;
|
envTable->GetArrayLength = local::GetArrayLength;
|
||||||
envTable->NewString = ::NewString;
|
envTable->NewString = local::NewString;
|
||||||
envTable->NewStringUTF = ::NewStringUTF;
|
envTable->NewStringUTF = local::NewStringUTF;
|
||||||
envTable->FindClass = ::FindClass;
|
envTable->FindClass = local::FindClass;
|
||||||
envTable->ThrowNew = ::ThrowNew;
|
envTable->ThrowNew = local::ThrowNew;
|
||||||
envTable->ExceptionCheck = ::ExceptionCheck;
|
envTable->ExceptionCheck = local::ExceptionCheck;
|
||||||
envTable->NewDirectByteBuffer = ::NewDirectByteBuffer;
|
envTable->NewDirectByteBuffer = local::NewDirectByteBuffer;
|
||||||
envTable->GetDirectBufferAddress = ::GetDirectBufferAddress;
|
envTable->GetDirectBufferAddress = local::GetDirectBufferAddress;
|
||||||
envTable->GetDirectBufferCapacity = ::GetDirectBufferCapacity;
|
envTable->GetDirectBufferCapacity = local::GetDirectBufferCapacity;
|
||||||
envTable->DeleteLocalRef = ::DeleteLocalRef;
|
envTable->DeleteLocalRef = local::DeleteLocalRef;
|
||||||
envTable->GetObjectClass = ::GetObjectClass;
|
envTable->GetObjectClass = local::GetObjectClass;
|
||||||
envTable->IsInstanceOf = ::IsInstanceOf;
|
envTable->IsInstanceOf = local::IsInstanceOf;
|
||||||
envTable->GetFieldID = ::GetFieldID;
|
envTable->GetFieldID = local::GetFieldID;
|
||||||
envTable->GetMethodID = ::GetMethodID;
|
envTable->GetMethodID = local::GetMethodID;
|
||||||
envTable->GetStaticMethodID = ::GetStaticMethodID;
|
envTable->GetStaticMethodID = local::GetStaticMethodID;
|
||||||
envTable->NewObject = ::NewObject;
|
envTable->NewObject = local::NewObject;
|
||||||
envTable->NewObjectV = ::NewObjectV;
|
envTable->NewObjectV = local::NewObjectV;
|
||||||
envTable->CallObjectMethodV = ::CallObjectMethodV;
|
envTable->CallObjectMethodV = local::CallObjectMethodV;
|
||||||
envTable->CallObjectMethod = ::CallObjectMethod;
|
envTable->CallObjectMethod = local::CallObjectMethod;
|
||||||
envTable->CallBooleanMethodV = ::CallBooleanMethodV;
|
envTable->CallBooleanMethodV = local::CallBooleanMethodV;
|
||||||
envTable->CallBooleanMethod = ::CallBooleanMethod;
|
envTable->CallBooleanMethod = local::CallBooleanMethod;
|
||||||
envTable->CallByteMethodV = ::CallByteMethodV;
|
envTable->CallByteMethodV = local::CallByteMethodV;
|
||||||
envTable->CallByteMethod = ::CallByteMethod;
|
envTable->CallByteMethod = local::CallByteMethod;
|
||||||
envTable->CallCharMethodV = ::CallCharMethodV;
|
envTable->CallCharMethodV = local::CallCharMethodV;
|
||||||
envTable->CallCharMethod = ::CallCharMethod;
|
envTable->CallCharMethod = local::CallCharMethod;
|
||||||
envTable->CallShortMethodV = ::CallShortMethodV;
|
envTable->CallShortMethodV = local::CallShortMethodV;
|
||||||
envTable->CallShortMethod = ::CallShortMethod;
|
envTable->CallShortMethod = local::CallShortMethod;
|
||||||
envTable->CallIntMethodV = ::CallIntMethodV;
|
envTable->CallIntMethodV = local::CallIntMethodV;
|
||||||
envTable->CallIntMethod = ::CallIntMethod;
|
envTable->CallIntMethod = local::CallIntMethod;
|
||||||
envTable->CallLongMethodV = ::CallLongMethodV;
|
envTable->CallLongMethodV = local::CallLongMethodV;
|
||||||
envTable->CallLongMethod = ::CallLongMethod;
|
envTable->CallLongMethod = local::CallLongMethod;
|
||||||
envTable->CallFloatMethodV = ::CallFloatMethodV;
|
envTable->CallFloatMethodV = local::CallFloatMethodV;
|
||||||
envTable->CallFloatMethod = ::CallFloatMethod;
|
envTable->CallFloatMethod = local::CallFloatMethod;
|
||||||
envTable->CallDoubleMethodV = ::CallDoubleMethodV;
|
envTable->CallDoubleMethodV = local::CallDoubleMethodV;
|
||||||
envTable->CallDoubleMethod = ::CallDoubleMethod;
|
envTable->CallDoubleMethod = local::CallDoubleMethod;
|
||||||
envTable->CallVoidMethodV = ::CallVoidMethodV;
|
envTable->CallVoidMethodV = local::CallVoidMethodV;
|
||||||
envTable->CallVoidMethod = ::CallVoidMethod;
|
envTable->CallVoidMethod = local::CallVoidMethod;
|
||||||
envTable->CallStaticObjectMethodV = ::CallStaticObjectMethodV;
|
envTable->CallStaticObjectMethodV = local::CallStaticObjectMethodV;
|
||||||
envTable->CallStaticObjectMethod = ::CallStaticObjectMethod;
|
envTable->CallStaticObjectMethod = local::CallStaticObjectMethod;
|
||||||
envTable->CallStaticBooleanMethodV = ::CallStaticBooleanMethodV;
|
envTable->CallStaticBooleanMethodV = local::CallStaticBooleanMethodV;
|
||||||
envTable->CallStaticBooleanMethod = ::CallStaticBooleanMethod;
|
envTable->CallStaticBooleanMethod = local::CallStaticBooleanMethod;
|
||||||
envTable->CallStaticByteMethodV = ::CallStaticByteMethodV;
|
envTable->CallStaticByteMethodV = local::CallStaticByteMethodV;
|
||||||
envTable->CallStaticByteMethod = ::CallStaticByteMethod;
|
envTable->CallStaticByteMethod = local::CallStaticByteMethod;
|
||||||
envTable->CallStaticCharMethodV = ::CallStaticCharMethodV;
|
envTable->CallStaticCharMethodV = local::CallStaticCharMethodV;
|
||||||
envTable->CallStaticCharMethod = ::CallStaticCharMethod;
|
envTable->CallStaticCharMethod = local::CallStaticCharMethod;
|
||||||
envTable->CallStaticShortMethodV = ::CallStaticShortMethodV;
|
envTable->CallStaticShortMethodV = local::CallStaticShortMethodV;
|
||||||
envTable->CallStaticShortMethod = ::CallStaticShortMethod;
|
envTable->CallStaticShortMethod = local::CallStaticShortMethod;
|
||||||
envTable->CallStaticIntMethodV = ::CallStaticIntMethodV;
|
envTable->CallStaticIntMethodV = local::CallStaticIntMethodV;
|
||||||
envTable->CallStaticIntMethod = ::CallStaticIntMethod;
|
envTable->CallStaticIntMethod = local::CallStaticIntMethod;
|
||||||
envTable->CallStaticLongMethodV = ::CallStaticLongMethodV;
|
envTable->CallStaticLongMethodV = local::CallStaticLongMethodV;
|
||||||
envTable->CallStaticLongMethod = ::CallStaticLongMethod;
|
envTable->CallStaticLongMethod = local::CallStaticLongMethod;
|
||||||
envTable->CallStaticFloatMethodV = ::CallStaticFloatMethodV;
|
envTable->CallStaticFloatMethodV = local::CallStaticFloatMethodV;
|
||||||
envTable->CallStaticFloatMethod = ::CallStaticFloatMethod;
|
envTable->CallStaticFloatMethod = local::CallStaticFloatMethod;
|
||||||
envTable->CallStaticDoubleMethodV = ::CallStaticDoubleMethodV;
|
envTable->CallStaticDoubleMethodV = local::CallStaticDoubleMethodV;
|
||||||
envTable->CallStaticDoubleMethod = ::CallStaticDoubleMethod;
|
envTable->CallStaticDoubleMethod = local::CallStaticDoubleMethod;
|
||||||
envTable->CallStaticVoidMethodV = ::CallStaticVoidMethodV;
|
envTable->CallStaticVoidMethodV = local::CallStaticVoidMethodV;
|
||||||
envTable->CallStaticVoidMethod = ::CallStaticVoidMethod;
|
envTable->CallStaticVoidMethod = local::CallStaticVoidMethod;
|
||||||
envTable->GetStaticFieldID = ::GetStaticFieldID;
|
envTable->GetStaticFieldID = local::GetStaticFieldID;
|
||||||
envTable->GetObjectField = ::GetObjectField;
|
envTable->GetObjectField = local::GetObjectField;
|
||||||
envTable->GetBooleanField = ::GetBooleanField;
|
envTable->GetBooleanField = local::GetBooleanField;
|
||||||
envTable->GetByteField = ::GetByteField;
|
envTable->GetByteField = local::GetByteField;
|
||||||
envTable->GetCharField = ::GetCharField;
|
envTable->GetCharField = local::GetCharField;
|
||||||
envTable->GetShortField = ::GetShortField;
|
envTable->GetShortField = local::GetShortField;
|
||||||
envTable->GetIntField = ::GetIntField;
|
envTable->GetIntField = local::GetIntField;
|
||||||
envTable->GetLongField = ::GetLongField;
|
envTable->GetLongField = local::GetLongField;
|
||||||
envTable->GetFloatField = ::GetFloatField;
|
envTable->GetFloatField = local::GetFloatField;
|
||||||
envTable->GetDoubleField = ::GetDoubleField;
|
envTable->GetDoubleField = local::GetDoubleField;
|
||||||
envTable->SetObjectField = ::SetObjectField;
|
envTable->SetObjectField = local::SetObjectField;
|
||||||
envTable->SetBooleanField = ::SetBooleanField;
|
envTable->SetBooleanField = local::SetBooleanField;
|
||||||
envTable->SetByteField = ::SetByteField;
|
envTable->SetByteField = local::SetByteField;
|
||||||
envTable->SetCharField = ::SetCharField;
|
envTable->SetCharField = local::SetCharField;
|
||||||
envTable->SetShortField = ::SetShortField;
|
envTable->SetShortField = local::SetShortField;
|
||||||
envTable->SetIntField = ::SetIntField;
|
envTable->SetIntField = local::SetIntField;
|
||||||
envTable->SetLongField = ::SetLongField;
|
envTable->SetLongField = local::SetLongField;
|
||||||
envTable->SetFloatField = ::SetFloatField;
|
envTable->SetFloatField = local::SetFloatField;
|
||||||
envTable->SetDoubleField = ::SetDoubleField;
|
envTable->SetDoubleField = local::SetDoubleField;
|
||||||
envTable->GetStaticObjectField = ::GetStaticObjectField;
|
envTable->GetStaticObjectField = local::GetStaticObjectField;
|
||||||
envTable->GetStaticBooleanField = ::GetStaticBooleanField;
|
envTable->GetStaticBooleanField = local::GetStaticBooleanField;
|
||||||
envTable->GetStaticByteField = ::GetStaticByteField;
|
envTable->GetStaticByteField = local::GetStaticByteField;
|
||||||
envTable->GetStaticCharField = ::GetStaticCharField;
|
envTable->GetStaticCharField = local::GetStaticCharField;
|
||||||
envTable->GetStaticShortField = ::GetStaticShortField;
|
envTable->GetStaticShortField = local::GetStaticShortField;
|
||||||
envTable->GetStaticIntField = ::GetStaticIntField;
|
envTable->GetStaticIntField = local::GetStaticIntField;
|
||||||
envTable->GetStaticLongField = ::GetStaticLongField;
|
envTable->GetStaticLongField = local::GetStaticLongField;
|
||||||
envTable->GetStaticFloatField = ::GetStaticFloatField;
|
envTable->GetStaticFloatField = local::GetStaticFloatField;
|
||||||
envTable->GetStaticDoubleField = ::GetStaticDoubleField;
|
envTable->GetStaticDoubleField = local::GetStaticDoubleField;
|
||||||
envTable->SetStaticObjectField = ::SetStaticObjectField;
|
envTable->SetStaticObjectField = local::SetStaticObjectField;
|
||||||
envTable->SetStaticBooleanField = ::SetStaticBooleanField;
|
envTable->SetStaticBooleanField = local::SetStaticBooleanField;
|
||||||
envTable->SetStaticByteField = ::SetStaticByteField;
|
envTable->SetStaticByteField = local::SetStaticByteField;
|
||||||
envTable->SetStaticCharField = ::SetStaticCharField;
|
envTable->SetStaticCharField = local::SetStaticCharField;
|
||||||
envTable->SetStaticShortField = ::SetStaticShortField;
|
envTable->SetStaticShortField = local::SetStaticShortField;
|
||||||
envTable->SetStaticIntField = ::SetStaticIntField;
|
envTable->SetStaticIntField = local::SetStaticIntField;
|
||||||
envTable->SetStaticLongField = ::SetStaticLongField;
|
envTable->SetStaticLongField = local::SetStaticLongField;
|
||||||
envTable->SetStaticFloatField = ::SetStaticFloatField;
|
envTable->SetStaticFloatField = local::SetStaticFloatField;
|
||||||
envTable->SetStaticDoubleField = ::SetStaticDoubleField;
|
envTable->SetStaticDoubleField = local::SetStaticDoubleField;
|
||||||
envTable->NewGlobalRef = ::NewGlobalRef;
|
envTable->NewGlobalRef = local::NewGlobalRef;
|
||||||
envTable->NewWeakGlobalRef = ::NewGlobalRef;
|
envTable->NewWeakGlobalRef = local::NewGlobalRef;
|
||||||
envTable->DeleteGlobalRef = ::DeleteGlobalRef;
|
envTable->DeleteGlobalRef = local::DeleteGlobalRef;
|
||||||
envTable->ExceptionOccurred = ::ExceptionOccurred;
|
envTable->ExceptionOccurred = local::ExceptionOccurred;
|
||||||
envTable->ExceptionDescribe = ::ExceptionDescribe;
|
envTable->ExceptionDescribe = local::ExceptionDescribe;
|
||||||
envTable->ExceptionClear = ::ExceptionClear;
|
envTable->ExceptionClear = local::ExceptionClear;
|
||||||
envTable->NewObjectArray = ::NewObjectArray;
|
envTable->NewObjectArray = local::NewObjectArray;
|
||||||
envTable->GetObjectArrayElement = ::GetObjectArrayElement;
|
envTable->GetObjectArrayElement = local::GetObjectArrayElement;
|
||||||
envTable->SetObjectArrayElement = ::SetObjectArrayElement;
|
envTable->SetObjectArrayElement = local::SetObjectArrayElement;
|
||||||
envTable->NewBooleanArray = ::NewBooleanArray;
|
envTable->NewBooleanArray = local::NewBooleanArray;
|
||||||
envTable->NewByteArray = ::NewByteArray;
|
envTable->NewByteArray = local::NewByteArray;
|
||||||
envTable->NewCharArray = ::NewCharArray;
|
envTable->NewCharArray = local::NewCharArray;
|
||||||
envTable->NewShortArray = ::NewShortArray;
|
envTable->NewShortArray = local::NewShortArray;
|
||||||
envTable->NewIntArray = ::NewIntArray;
|
envTable->NewIntArray = local::NewIntArray;
|
||||||
envTable->NewLongArray = ::NewLongArray;
|
envTable->NewLongArray = local::NewLongArray;
|
||||||
envTable->NewFloatArray = ::NewFloatArray;
|
envTable->NewFloatArray = local::NewFloatArray;
|
||||||
envTable->NewDoubleArray = ::NewDoubleArray;
|
envTable->NewDoubleArray = local::NewDoubleArray;
|
||||||
envTable->GetBooleanArrayElements = ::GetBooleanArrayElements;
|
envTable->GetBooleanArrayElements = local::GetBooleanArrayElements;
|
||||||
envTable->GetByteArrayElements = ::GetByteArrayElements;
|
envTable->GetByteArrayElements = local::GetByteArrayElements;
|
||||||
envTable->GetCharArrayElements = ::GetCharArrayElements;
|
envTable->GetCharArrayElements = local::GetCharArrayElements;
|
||||||
envTable->GetShortArrayElements = ::GetShortArrayElements;
|
envTable->GetShortArrayElements = local::GetShortArrayElements;
|
||||||
envTable->GetIntArrayElements = ::GetIntArrayElements;
|
envTable->GetIntArrayElements = local::GetIntArrayElements;
|
||||||
envTable->GetLongArrayElements = ::GetLongArrayElements;
|
envTable->GetLongArrayElements = local::GetLongArrayElements;
|
||||||
envTable->GetFloatArrayElements = ::GetFloatArrayElements;
|
envTable->GetFloatArrayElements = local::GetFloatArrayElements;
|
||||||
envTable->GetDoubleArrayElements = ::GetDoubleArrayElements;
|
envTable->GetDoubleArrayElements = local::GetDoubleArrayElements;
|
||||||
envTable->ReleaseBooleanArrayElements = ::ReleaseBooleanArrayElements;
|
envTable->ReleaseBooleanArrayElements = local::ReleaseBooleanArrayElements;
|
||||||
envTable->ReleaseByteArrayElements = ::ReleaseByteArrayElements;
|
envTable->ReleaseByteArrayElements = local::ReleaseByteArrayElements;
|
||||||
envTable->ReleaseCharArrayElements = ::ReleaseCharArrayElements;
|
envTable->ReleaseCharArrayElements = local::ReleaseCharArrayElements;
|
||||||
envTable->ReleaseShortArrayElements = ::ReleaseShortArrayElements;
|
envTable->ReleaseShortArrayElements = local::ReleaseShortArrayElements;
|
||||||
envTable->ReleaseIntArrayElements = ::ReleaseIntArrayElements;
|
envTable->ReleaseIntArrayElements = local::ReleaseIntArrayElements;
|
||||||
envTable->ReleaseLongArrayElements = ::ReleaseLongArrayElements;
|
envTable->ReleaseLongArrayElements = local::ReleaseLongArrayElements;
|
||||||
envTable->ReleaseFloatArrayElements = ::ReleaseFloatArrayElements;
|
envTable->ReleaseFloatArrayElements = local::ReleaseFloatArrayElements;
|
||||||
envTable->ReleaseDoubleArrayElements = ::ReleaseDoubleArrayElements;
|
envTable->ReleaseDoubleArrayElements = local::ReleaseDoubleArrayElements;
|
||||||
envTable->GetBooleanArrayRegion = ::GetBooleanArrayRegion;
|
envTable->GetBooleanArrayRegion = local::GetBooleanArrayRegion;
|
||||||
envTable->GetByteArrayRegion = ::GetByteArrayRegion;
|
envTable->GetByteArrayRegion = local::GetByteArrayRegion;
|
||||||
envTable->GetCharArrayRegion = ::GetCharArrayRegion;
|
envTable->GetCharArrayRegion = local::GetCharArrayRegion;
|
||||||
envTable->GetShortArrayRegion = ::GetShortArrayRegion;
|
envTable->GetShortArrayRegion = local::GetShortArrayRegion;
|
||||||
envTable->GetIntArrayRegion = ::GetIntArrayRegion;
|
envTable->GetIntArrayRegion = local::GetIntArrayRegion;
|
||||||
envTable->GetLongArrayRegion = ::GetLongArrayRegion;
|
envTable->GetLongArrayRegion = local::GetLongArrayRegion;
|
||||||
envTable->GetFloatArrayRegion = ::GetFloatArrayRegion;
|
envTable->GetFloatArrayRegion = local::GetFloatArrayRegion;
|
||||||
envTable->GetDoubleArrayRegion = ::GetDoubleArrayRegion;
|
envTable->GetDoubleArrayRegion = local::GetDoubleArrayRegion;
|
||||||
envTable->SetBooleanArrayRegion = ::SetBooleanArrayRegion;
|
envTable->SetBooleanArrayRegion = local::SetBooleanArrayRegion;
|
||||||
envTable->SetByteArrayRegion = ::SetByteArrayRegion;
|
envTable->SetByteArrayRegion = local::SetByteArrayRegion;
|
||||||
envTable->SetCharArrayRegion = ::SetCharArrayRegion;
|
envTable->SetCharArrayRegion = local::SetCharArrayRegion;
|
||||||
envTable->SetShortArrayRegion = ::SetShortArrayRegion;
|
envTable->SetShortArrayRegion = local::SetShortArrayRegion;
|
||||||
envTable->SetIntArrayRegion = ::SetIntArrayRegion;
|
envTable->SetIntArrayRegion = local::SetIntArrayRegion;
|
||||||
envTable->SetLongArrayRegion = ::SetLongArrayRegion;
|
envTable->SetLongArrayRegion = local::SetLongArrayRegion;
|
||||||
envTable->SetFloatArrayRegion = ::SetFloatArrayRegion;
|
envTable->SetFloatArrayRegion = local::SetFloatArrayRegion;
|
||||||
envTable->SetDoubleArrayRegion = ::SetDoubleArrayRegion;
|
envTable->SetDoubleArrayRegion = local::SetDoubleArrayRegion;
|
||||||
envTable->GetPrimitiveArrayCritical = ::GetPrimitiveArrayCritical;
|
envTable->GetPrimitiveArrayCritical = local::GetPrimitiveArrayCritical;
|
||||||
envTable->ReleasePrimitiveArrayCritical = ::ReleasePrimitiveArrayCritical;
|
envTable->ReleasePrimitiveArrayCritical
|
||||||
envTable->MonitorEnter = MonitorEnter;
|
= local::ReleasePrimitiveArrayCritical;
|
||||||
envTable->MonitorExit = MonitorExit;
|
envTable->MonitorEnter = local::MonitorEnter;
|
||||||
envTable->GetJavaVM = ::GetJavaVM;
|
envTable->MonitorExit = local::MonitorExit;
|
||||||
envTable->IsSameObject = ::IsSameObject;
|
envTable->GetJavaVM = local::GetJavaVM;
|
||||||
|
envTable->IsSameObject = local::IsSameObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace vm
|
} // namespace vm
|
||||||
@ -2112,7 +2117,7 @@ JNI_GetDefaultJavaVMInitArgs(void*)
|
|||||||
extern "C" JNIEXPORT jint JNICALL
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
|
JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
|
||||||
{
|
{
|
||||||
JavaVMInitArgs* a = static_cast<JavaVMInitArgs*>(args);
|
local::JavaVMInitArgs* a = static_cast<local::JavaVMInitArgs*>(args);
|
||||||
|
|
||||||
unsigned heapLimit = 0;
|
unsigned heapLimit = 0;
|
||||||
const char* bootLibrary = 0;
|
const char* bootLibrary = 0;
|
||||||
@ -2128,7 +2133,7 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
|
|||||||
if (strncmp(a->options[i].optionString, "-X", 2) == 0) {
|
if (strncmp(a->options[i].optionString, "-X", 2) == 0) {
|
||||||
const char* p = a->options[i].optionString + 2;
|
const char* p = a->options[i].optionString + 2;
|
||||||
if (strncmp(p, "mx", 2) == 0) {
|
if (strncmp(p, "mx", 2) == 0) {
|
||||||
heapLimit = parseSize(p + 2);
|
heapLimit = local::parseSize(p + 2);
|
||||||
} else if (strncmp(p, BOOTCLASSPATH_PREPEND_OPTION ":",
|
} else if (strncmp(p, BOOTCLASSPATH_PREPEND_OPTION ":",
|
||||||
sizeof(BOOTCLASSPATH_PREPEND_OPTION)) == 0)
|
sizeof(BOOTCLASSPATH_PREPEND_OPTION)) == 0)
|
||||||
{
|
{
|
||||||
@ -2175,10 +2180,11 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
|
|||||||
RUNTIME_ARRAY(char, classpathBuffer, classpathBufferSize);
|
RUNTIME_ARRAY(char, classpathBuffer, classpathBufferSize);
|
||||||
char* classpathPointer = RUNTIME_ARRAY_BODY(classpathBuffer);
|
char* classpathPointer = RUNTIME_ARRAY_BODY(classpathBuffer);
|
||||||
|
|
||||||
append(&classpathPointer, bootClasspathPrepend, bcppl, PATH_SEPARATOR);
|
local::append
|
||||||
append(&classpathPointer, bootClasspath, bcpl, PATH_SEPARATOR);
|
(&classpathPointer, bootClasspathPrepend, bcppl, PATH_SEPARATOR);
|
||||||
append(&classpathPointer, bootClasspathAppend, bcpal, PATH_SEPARATOR);
|
local::append(&classpathPointer, bootClasspath, bcpl, PATH_SEPARATOR);
|
||||||
append(&classpathPointer, classpath, cpl, 0);
|
local::append(&classpathPointer, bootClasspathAppend, bcpal, PATH_SEPARATOR);
|
||||||
|
local::append(&classpathPointer, classpath, cpl, 0);
|
||||||
|
|
||||||
System* s = makeSystem(crashDumpDirectory);
|
System* s = makeSystem(crashDumpDirectory);
|
||||||
Heap* h = makeHeap(s, heapLimit);
|
Heap* h = makeHeap(s, heapLimit);
|
||||||
|
@ -2690,6 +2690,30 @@ makeString(Thread* t, const char* format, ...)
|
|||||||
return makeString(t, s, 0, byteArrayLength(t, s) - 1, 0);
|
return makeString(t, s, 0, byteArrayLength(t, s) - 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
stringUTFLength(Thread* t, object string) {
|
||||||
|
int length = 0;
|
||||||
|
|
||||||
|
if (stringLength(t, string)) {
|
||||||
|
object data = stringData(t, string);
|
||||||
|
if (objectClass(t, data)
|
||||||
|
== arrayBody(t, t->m->types, Machine::ByteArrayType)) {
|
||||||
|
length = stringLength(t, string);
|
||||||
|
} else {
|
||||||
|
for (unsigned i = 0; i < stringLength(t, string); ++i) {
|
||||||
|
uint16_t c = charArrayBody(t, data, stringOffset(t, string) + i);
|
||||||
|
if (!c) length += 1; // null char (was 2 bytes in Java)
|
||||||
|
else if (c < 0x80) length += 1; // ASCII char
|
||||||
|
else if (c < 0x800) length += 2; // two-byte char
|
||||||
|
else length += 3; // three-byte char
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
stringChars(Thread* t, object string, char* chars)
|
stringChars(Thread* t, object string, char* chars)
|
||||||
{
|
{
|
||||||
@ -2730,6 +2754,42 @@ stringChars(Thread* t, object string, uint16_t* chars)
|
|||||||
chars[stringLength(t, string)] = 0;
|
chars[stringLength(t, string)] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
stringUTFChars(Thread* t, object string, char* chars, unsigned length UNUSED)
|
||||||
|
{
|
||||||
|
assert(t, static_cast<unsigned>(stringUTFLength(t, string)) == length);
|
||||||
|
|
||||||
|
if (stringLength(t, string)) {
|
||||||
|
object data = stringData(t, string);
|
||||||
|
if (objectClass(t, data)
|
||||||
|
== arrayBody(t, t->m->types, Machine::ByteArrayType))
|
||||||
|
{
|
||||||
|
memcpy(chars,
|
||||||
|
&byteArrayBody(t, data, stringOffset(t, string)),
|
||||||
|
stringLength(t, string));
|
||||||
|
chars[stringLength(t, string)] = 0;
|
||||||
|
} else {
|
||||||
|
int j = 0;
|
||||||
|
for (unsigned i = 0; i < stringLength(t, string); ++i) {
|
||||||
|
uint16_t c = charArrayBody(t, data, stringOffset(t, string) + i);
|
||||||
|
if(!c) { // null char
|
||||||
|
chars[j++] = 0;
|
||||||
|
} else if (c < 0x80) { // ASCII char
|
||||||
|
chars[j++] = static_cast<char>(c);
|
||||||
|
} else if (c < 0x800) { // two-byte char
|
||||||
|
chars[j++] = static_cast<char>(0x0c0 | (c >> 6));
|
||||||
|
chars[j++] = static_cast<char>(0x080 | (c & 0x03f));
|
||||||
|
} else { // three-byte char
|
||||||
|
chars[j++] = static_cast<char>(0x0e0 | ((c >> 12) & 0x0f));
|
||||||
|
chars[j++] = static_cast<char>(0x080 | ((c >> 6) & 0x03f));
|
||||||
|
chars[j++] = static_cast<char>(0x080 | (c & 0x03f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chars[j] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
isAssignableFrom(Thread* t, object a, object b)
|
isAssignableFrom(Thread* t, object a, object b)
|
||||||
{
|
{
|
||||||
|
@ -1901,12 +1901,18 @@ makeByteArray(Thread* t, const char* format, ...);
|
|||||||
object
|
object
|
||||||
makeString(Thread* t, const char* format, ...);
|
makeString(Thread* t, const char* format, ...);
|
||||||
|
|
||||||
|
int
|
||||||
|
stringUTFLength(Thread* t, object string);
|
||||||
|
|
||||||
void
|
void
|
||||||
stringChars(Thread* t, object string, char* chars);
|
stringChars(Thread* t, object string, char* chars);
|
||||||
|
|
||||||
void
|
void
|
||||||
stringChars(Thread* t, object string, uint16_t* chars);
|
stringChars(Thread* t, object string, uint16_t* chars);
|
||||||
|
|
||||||
|
void
|
||||||
|
stringUTFChars(Thread* t, object string, char* chars, unsigned length);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
isAssignableFrom(Thread* t, object a, object b);
|
isAssignableFrom(Thread* t, object a, object b);
|
||||||
|
|
||||||
|
@ -93,6 +93,8 @@ pathOfExecutable(System* s, const char** retBuf, unsigned* size)
|
|||||||
CFBundleRef bundle = CFBundleGetMainBundle();
|
CFBundleRef bundle = CFBundleGetMainBundle();
|
||||||
CFURLRef url = CFBundleCopyExecutableURL(bundle);
|
CFURLRef url = CFBundleCopyExecutableURL(bundle);
|
||||||
CFStringRef path = CFURLCopyPath(url);
|
CFStringRef path = CFURLCopyPath(url);
|
||||||
|
path = CFURLCreateStringByReplacingPercentEscapes(kCFAllocatorDefault,
|
||||||
|
path, CFSTR(""));
|
||||||
CFIndex pathSize = CFStringGetMaximumSizeOfFileSystemRepresentation(path);
|
CFIndex pathSize = CFStringGetMaximumSizeOfFileSystemRepresentation(path);
|
||||||
char* buffer = reinterpret_cast<char*>(allocate(s, pathSize));
|
char* buffer = reinterpret_cast<char*>(allocate(s, pathSize));
|
||||||
if (CFStringGetFileSystemRepresentation(path, buffer, pathSize)) {
|
if (CFStringGetFileSystemRepresentation(path, buffer, pathSize)) {
|
||||||
|
376
src/powerpc.cpp
376
src/powerpc.cpp
@ -20,29 +20,6 @@ using namespace vm;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
namespace field {
|
|
||||||
// BITFIELD MASKS
|
|
||||||
const int64_t MASK_LO32 = 0x0ffffffff;
|
|
||||||
const int MASK_LO16 = 0x0ffff;
|
|
||||||
const int MASK_LO8 = 0x0ff;
|
|
||||||
// BITFIELD EXTRACTORS
|
|
||||||
inline int lo32(int64_t i) { return (int)(i & MASK_LO32); }
|
|
||||||
inline int hi32(int64_t i) { return lo32(i >> 32); }
|
|
||||||
inline int lo16(int64_t i) { return (int)(i & MASK_LO16); }
|
|
||||||
inline int hi16(int64_t i) { return lo16(i >> 16); }
|
|
||||||
inline int lo8(int64_t i) { return (int)(i & MASK_LO8); }
|
|
||||||
inline int hi8(int64_t i) { return lo8(i >> 8); }
|
|
||||||
|
|
||||||
inline int ha16(int32_t i) {
|
|
||||||
return ((i >> 16) + ((i & 0x8000) ? 1 : 0)) & 0xffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int unha16(int32_t high, int32_t low) {
|
|
||||||
return ((high - ((low & 0x8000) ? 1 : 0)) << 16) | low;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace isa {
|
namespace isa {
|
||||||
// INSTRUCTION FORMATS
|
// INSTRUCTION FORMATS
|
||||||
inline int D(int op, int rt, int ra, int d) { return op<<26|rt<<21|ra<<16|(d & 0xFFFF); }
|
inline int D(int op, int rt, int ra, int d) { return op<<26|rt<<21|ra<<16|(d & 0xFFFF); }
|
||||||
@ -155,6 +132,24 @@ inline int cmpwi(int ra, int i) { return cmpi(0, ra, i); }
|
|||||||
inline int cmplwi(int ra, int i) { return cmpli(0, ra, i); }
|
inline int cmplwi(int ra, int i) { return cmpli(0, ra, i); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int64_t MASK_LO32 = 0x0ffffffff;
|
||||||
|
const int MASK_LO16 = 0x0ffff;
|
||||||
|
const int MASK_LO8 = 0x0ff;
|
||||||
|
inline int lo32(int64_t i) { return (int)(i & MASK_LO32); }
|
||||||
|
inline int hi32(int64_t i) { return lo32(i >> 32); }
|
||||||
|
inline int lo16(int64_t i) { return (int)(i & MASK_LO16); }
|
||||||
|
inline int hi16(int64_t i) { return lo16(i >> 16); }
|
||||||
|
inline int lo8(int64_t i) { return (int)(i & MASK_LO8); }
|
||||||
|
inline int hi8(int64_t i) { return lo8(i >> 8); }
|
||||||
|
|
||||||
|
inline int ha16(int32_t i) {
|
||||||
|
return ((i >> 16) + ((i & 0x8000) ? 1 : 0)) & 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int unha16(int32_t high, int32_t low) {
|
||||||
|
return ((high - ((low & 0x8000) ? 1 : 0)) << 16) | low;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
isInt16(intptr_t v)
|
isInt16(intptr_t v)
|
||||||
{
|
{
|
||||||
@ -445,100 +440,94 @@ branchIndex(ArchitectureContext* c UNUSED, OperandType operand1,
|
|||||||
|
|
||||||
// BEGIN OPERATION COMPILERS
|
// BEGIN OPERATION COMPILERS
|
||||||
|
|
||||||
using namespace field;
|
|
||||||
using namespace isa;
|
using namespace isa;
|
||||||
|
|
||||||
typedef Assembler::Register Reg;
|
inline void emit(Context* con, int code) { con->code.append4(code); }
|
||||||
typedef Assembler::Constant Const;
|
inline int newTemp(Context* con) { return con->client->acquireTemporary(); }
|
||||||
|
|
||||||
inline void issue(Context* con, int code) { con->code.append4(code); }
|
|
||||||
inline int getTemp(Context* con) { return con->client->acquireTemporary(); }
|
|
||||||
inline void freeTemp(Context* con, int r) { con->client->releaseTemporary(r); }
|
inline void freeTemp(Context* con, int r) { con->client->releaseTemporary(r); }
|
||||||
inline int64_t getVal(Const* c) { return c->value->value(); }
|
inline int64_t getValue(Assembler::Constant* c) { return c->value->value(); }
|
||||||
inline int R(Reg* r) { return r->low; }
|
|
||||||
inline int H(Reg* r) { return r->high; }
|
|
||||||
|
|
||||||
|
|
||||||
void shiftLeftR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t)
|
void shiftLeftR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t)
|
||||||
{
|
{
|
||||||
if(size == 8) {
|
if(size == 8) {
|
||||||
Reg Tmp(getTemp(con), getTemp(con)); Reg* tmp = &Tmp;
|
Assembler::Register Tmp(newTemp(con), newTemp(con)); Assembler::Register* tmp = &Tmp;
|
||||||
issue(con, subfic(H(tmp), R(a), 32));
|
emit(con, subfic(tmp->high, a->low, 32));
|
||||||
issue(con, slw(H(t), H(b), R(a)));
|
emit(con, slw(t->high, b->high, a->low));
|
||||||
issue(con, srw(R(tmp), R(b), H(tmp)));
|
emit(con, srw(tmp->low, b->low, tmp->high));
|
||||||
issue(con, or_(H(t), H(t), R(tmp)));
|
emit(con, or_(t->high, t->high, tmp->low));
|
||||||
issue(con, addi(H(tmp), R(a), -32));
|
emit(con, addi(tmp->high, a->low, -32));
|
||||||
issue(con, slw(R(tmp), R(b), H(tmp)));
|
emit(con, slw(tmp->low, b->low, tmp->high));
|
||||||
issue(con, or_(H(t), H(t), R(tmp)));
|
emit(con, or_(t->high, t->high, tmp->low));
|
||||||
freeTemp(con, H(tmp)); freeTemp(con, R(tmp));
|
freeTemp(con, tmp->high); freeTemp(con, tmp->low);
|
||||||
}
|
}
|
||||||
issue(con, slw(R(t), R(b), R(a)));
|
emit(con, slw(t->low, b->low, a->low));
|
||||||
}
|
}
|
||||||
|
|
||||||
void shiftLeftC(Context* con, unsigned size, Const* a, Reg* b, Reg* t)
|
void shiftLeftC(Context* con, unsigned size, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t)
|
||||||
{
|
{
|
||||||
int sh = getVal(a);
|
int sh = getValue(a);
|
||||||
if (size == 8) {
|
if (size == 8) {
|
||||||
if (sh < 32) {
|
if (sh < 32) {
|
||||||
issue(con, rlwinm(H(t),H(b),sh,0,31-sh));
|
emit(con, rlwinm(t->high,b->high,sh,0,31-sh));
|
||||||
issue(con, rlwimi(H(t),R(b),sh,32-sh,31));
|
emit(con, rlwimi(t->high,b->low,sh,32-sh,31));
|
||||||
} else {
|
} else {
|
||||||
issue(con, rlwinm(H(t),R(b),sh-32,0,63-sh));
|
emit(con, rlwinm(t->high,b->low,sh-32,0,63-sh));
|
||||||
issue(con, li(R(t),0));
|
emit(con, li(t->low,0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
issue(con, slwi(R(t), R(b), sh));
|
emit(con, slwi(t->low, b->low, sh));
|
||||||
}
|
}
|
||||||
|
|
||||||
void shiftRightR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t)
|
void shiftRightR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t)
|
||||||
{
|
{
|
||||||
if(size == 8) {
|
if(size == 8) {
|
||||||
Reg Tmp(getTemp(con), getTemp(con)); Reg* tmp = &Tmp;
|
Assembler::Register Tmp(newTemp(con), newTemp(con)); Assembler::Register* tmp = &Tmp;
|
||||||
issue(con, subfic(H(tmp), R(a), 32));
|
emit(con, subfic(tmp->high, a->low, 32));
|
||||||
issue(con, srw(R(t), R(b), R(a)));
|
emit(con, srw(t->low, b->low, a->low));
|
||||||
issue(con, slw(R(tmp), H(b), H(tmp)));
|
emit(con, slw(tmp->low, b->high, tmp->high));
|
||||||
issue(con, or_(R(t), R(t), R(tmp)));
|
emit(con, or_(t->low, t->low, tmp->low));
|
||||||
issue(con, addic(H(tmp), R(a), -32));
|
emit(con, addic(tmp->high, a->low, -32));
|
||||||
issue(con, sraw(R(tmp), H(b), H(tmp)));
|
emit(con, sraw(tmp->low, b->high, tmp->high));
|
||||||
issue(con, ble(8));
|
emit(con, ble(8));
|
||||||
issue(con, ori(R(t), R(tmp), 0));
|
emit(con, ori(t->low, tmp->low, 0));
|
||||||
issue(con, sraw(H(t), H(b), R(a)));
|
emit(con, sraw(t->high, b->high, a->low));
|
||||||
freeTemp(con, H(tmp)); freeTemp(con, R(tmp));
|
freeTemp(con, tmp->high); freeTemp(con, tmp->low);
|
||||||
} else {
|
} else {
|
||||||
issue(con, sraw(R(t), R(b), R(a)));
|
emit(con, sraw(t->low, b->low, a->low));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void shiftRightC(Context* con, unsigned size, Const* a, Reg* b, Reg* t)
|
void shiftRightC(Context* con, unsigned size, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t)
|
||||||
{
|
{
|
||||||
int sh = getVal(a);
|
int sh = getValue(a);
|
||||||
if(size == 8) {
|
if(size == 8) {
|
||||||
if (sh < 32) {
|
if (sh < 32) {
|
||||||
issue(con, rlwinm(R(t),R(b),32-sh,sh,31));
|
emit(con, rlwinm(t->low,b->low,32-sh,sh,31));
|
||||||
issue(con, rlwimi(R(t),H(b),32-sh,0,sh-1));
|
emit(con, rlwimi(t->low,b->high,32-sh,0,sh-1));
|
||||||
issue(con, srawi(H(t),H(b),sh));
|
emit(con, srawi(t->high,b->high,sh));
|
||||||
} else {
|
} else {
|
||||||
issue(con, srawi(H(t),H(b),31));
|
emit(con, srawi(t->high,b->high,31));
|
||||||
issue(con, srawi(R(t),H(b),sh-32));
|
emit(con, srawi(t->low,b->high,sh-32));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
issue(con, srawi(R(t), R(b), sh));
|
emit(con, srawi(t->low, b->low, sh));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void unsignedShiftRightR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t)
|
void unsignedShiftRightR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t)
|
||||||
{
|
{
|
||||||
issue(con, srw(R(t), R(b), R(a)));
|
emit(con, srw(t->low, b->low, a->low));
|
||||||
if(size == 8) {
|
if(size == 8) {
|
||||||
Reg Tmp(getTemp(con), getTemp(con)); Reg* tmp = &Tmp;
|
Assembler::Register Tmp(newTemp(con), newTemp(con)); Assembler::Register* tmp = &Tmp;
|
||||||
issue(con, subfic(H(tmp), R(a), 32));
|
emit(con, subfic(tmp->high, a->low, 32));
|
||||||
issue(con, slw(R(tmp), H(b), H(tmp)));
|
emit(con, slw(tmp->low, b->high, tmp->high));
|
||||||
issue(con, or_(R(t), R(t), R(tmp)));
|
emit(con, or_(t->low, t->low, tmp->low));
|
||||||
issue(con, addi(H(tmp), R(a), -32));
|
emit(con, addi(tmp->high, a->low, -32));
|
||||||
issue(con, srw(R(tmp), H(b), H(tmp)));
|
emit(con, srw(tmp->low, b->high, tmp->high));
|
||||||
issue(con, or_(R(t), R(t), R(tmp)));
|
emit(con, or_(t->low, t->low, tmp->low));
|
||||||
issue(con, srw(H(t), H(b), R(a)));
|
emit(con, srw(t->high, b->high, a->low));
|
||||||
freeTemp(con, H(tmp)); freeTemp(con, R(tmp));
|
freeTemp(con, tmp->high); freeTemp(con, tmp->low);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -546,24 +535,24 @@ void
|
|||||||
moveRR(Context* c, unsigned srcSize, Assembler::Register* src,
|
moveRR(Context* c, unsigned srcSize, Assembler::Register* src,
|
||||||
unsigned dstSize, Assembler::Register* dst);
|
unsigned dstSize, Assembler::Register* dst);
|
||||||
|
|
||||||
void unsignedShiftRightC(Context* con, unsigned size, Const* a, Reg* b, Reg* t)
|
void unsignedShiftRightC(Context* con, unsigned size, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t)
|
||||||
{
|
{
|
||||||
int sh = getVal(a);
|
int sh = getValue(a);
|
||||||
if (size == 8) {
|
if (size == 8) {
|
||||||
if (sh == 32) {
|
if (sh == 32) {
|
||||||
Assembler::Register high(b->high);
|
Assembler::Register high(b->high);
|
||||||
moveRR(con, 4, &high, 4, t);
|
moveRR(con, 4, &high, 4, t);
|
||||||
issue(con, li(H(t),0));
|
emit(con, li(t->high,0));
|
||||||
} else if (sh < 32) {
|
} else if (sh < 32) {
|
||||||
issue(con, srwi(R(t), R(b), sh));
|
emit(con, srwi(t->low, b->low, sh));
|
||||||
issue(con, rlwimi(R(t),H(b),32-sh,0,sh-1));
|
emit(con, rlwimi(t->low,b->high,32-sh,0,sh-1));
|
||||||
issue(con, rlwinm(H(t),H(b),32-sh,sh,31));
|
emit(con, rlwinm(t->high,b->high,32-sh,sh,31));
|
||||||
} else {
|
} else {
|
||||||
issue(con, rlwinm(R(t),H(b),64-sh,sh-32,31));
|
emit(con, rlwinm(t->low,b->high,64-sh,sh-32,31));
|
||||||
issue(con, li(H(t),0));
|
emit(con, li(t->high,0));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
issue(con, srwi(R(t), R(b), sh));
|
emit(con, srwi(t->low, b->low, sh));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -683,8 +672,8 @@ jumpR(Context* c, unsigned size UNUSED, Assembler::Register* target)
|
|||||||
{
|
{
|
||||||
assert(c, size == BytesPerWord);
|
assert(c, size == BytesPerWord);
|
||||||
|
|
||||||
issue(c, mtctr(target->low));
|
emit(c, mtctr(target->low));
|
||||||
issue(c, bctr());
|
emit(c, bctr());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -707,18 +696,18 @@ moveRR(Context* c, unsigned srcSize, Assembler::Register* src,
|
|||||||
{
|
{
|
||||||
switch (srcSize) {
|
switch (srcSize) {
|
||||||
case 1:
|
case 1:
|
||||||
issue(c, extsb(dst->low, src->low));
|
emit(c, extsb(dst->low, src->low));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
issue(c, extsh(dst->low, src->low));
|
emit(c, extsh(dst->low, src->low));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
case 8:
|
case 8:
|
||||||
if (srcSize == 4 and dstSize == 8) {
|
if (srcSize == 4 and dstSize == 8) {
|
||||||
moveRR(c, 4, src, 4, dst);
|
moveRR(c, 4, src, 4, dst);
|
||||||
issue(c, srawi(dst->high, src->low, 31));
|
emit(c, srawi(dst->high, src->low, 31));
|
||||||
} else if (srcSize == 8 and dstSize == 8) {
|
} else if (srcSize == 8 and dstSize == 8) {
|
||||||
Assembler::Register srcHigh(src->high);
|
Assembler::Register srcHigh(src->high);
|
||||||
Assembler::Register dstHigh(dst->high);
|
Assembler::Register dstHigh(dst->high);
|
||||||
@ -735,7 +724,7 @@ moveRR(Context* c, unsigned srcSize, Assembler::Register* src,
|
|||||||
moveRR(c, 4, &srcHigh, 4, &dstHigh);
|
moveRR(c, 4, &srcHigh, 4, &dstHigh);
|
||||||
}
|
}
|
||||||
} else if (src->low != dst->low) {
|
} else if (src->low != dst->low) {
|
||||||
issue(c, mr(dst->low, src->low));
|
emit(c, mr(dst->low, src->low));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -749,7 +738,7 @@ moveZRR(Context* c, unsigned srcSize, Assembler::Register* src,
|
|||||||
{
|
{
|
||||||
switch (srcSize) {
|
switch (srcSize) {
|
||||||
case 2:
|
case 2:
|
||||||
issue(c, andi(dst->low, src->low, 0xFFFF));
|
emit(c, andi(dst->low, src->low, 0xFFFF));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: abort(c);
|
default: abort(c);
|
||||||
@ -764,16 +753,16 @@ moveCR2(Context* c, unsigned, Assembler::Constant* src,
|
|||||||
if (src->value->resolved()) {
|
if (src->value->resolved()) {
|
||||||
int32_t v = src->value->value();
|
int32_t v = src->value->value();
|
||||||
if (isInt16(v)) {
|
if (isInt16(v)) {
|
||||||
issue(c, li(dst->low, v));
|
emit(c, li(dst->low, v));
|
||||||
} else {
|
} else {
|
||||||
issue(c, lis(dst->low, v >> 16));
|
emit(c, lis(dst->low, v >> 16));
|
||||||
issue(c, ori(dst->low, dst->low, v));
|
emit(c, ori(dst->low, dst->low, v));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
appendImmediateTask
|
appendImmediateTask
|
||||||
(c, src->value, offset(c), BytesPerWord, promiseOffset, false);
|
(c, src->value, offset(c), BytesPerWord, promiseOffset, false);
|
||||||
issue(c, lis(dst->low, 0));
|
emit(c, lis(dst->low, 0));
|
||||||
issue(c, ori(dst->low, dst->low, 0));
|
emit(c, ori(dst->low, dst->low, 0));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
abort(c); // todo
|
abort(c); // todo
|
||||||
@ -787,38 +776,38 @@ moveCR(Context* c, unsigned srcSize, Assembler::Constant* src,
|
|||||||
moveCR2(c, srcSize, src, dstSize, dst, 0);
|
moveCR2(c, srcSize, src, dstSize, dst, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) {
|
void addR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) {
|
||||||
if(size == 8) {
|
if(size == 8) {
|
||||||
issue(con, addc(R(t), R(a), R(b)));
|
emit(con, addc(t->low, a->low, b->low));
|
||||||
issue(con, adde(H(t), H(a), H(b)));
|
emit(con, adde(t->high, a->high, b->high));
|
||||||
} else {
|
} else {
|
||||||
issue(con, add(R(t), R(a), R(b)));
|
emit(con, add(t->low, a->low, b->low));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void addC(Context* con, unsigned size, Const* a, Reg* b, Reg* t) {
|
void addC(Context* con, unsigned size, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t) {
|
||||||
assert(con, size == BytesPerWord);
|
assert(con, size == BytesPerWord);
|
||||||
|
|
||||||
int32_t i = getVal(a);
|
int32_t i = getValue(a);
|
||||||
if(i) {
|
if(i) {
|
||||||
issue(con, addi(R(t), R(b), lo16(i)));
|
emit(con, addi(t->low, b->low, lo16(i)));
|
||||||
if(not isInt16(i))
|
if(not isInt16(i))
|
||||||
issue(con, addis(R(t), R(t), hi16(i) + carry16(i)));
|
emit(con, addis(t->low, t->low, hi16(i) + carry16(i)));
|
||||||
} else {
|
} else {
|
||||||
moveRR(con, size, b, size, t);
|
moveRR(con, size, b, size, t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void subR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) {
|
void subR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) {
|
||||||
if(size == 8) {
|
if(size == 8) {
|
||||||
issue(con, subfc(R(t), R(a), R(b)));
|
emit(con, subfc(t->low, a->low, b->low));
|
||||||
issue(con, subfe(H(t), H(a), H(b)));
|
emit(con, subfe(t->high, a->high, b->high));
|
||||||
} else {
|
} else {
|
||||||
issue(con, subf(R(t), R(a), R(b)));
|
emit(con, subf(t->low, a->low, b->low));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void subC(Context* c, unsigned size, Const* a, Reg* b, Reg* t) {
|
void subC(Context* c, unsigned size, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t) {
|
||||||
assert(c, size == BytesPerWord);
|
assert(c, size == BytesPerWord);
|
||||||
|
|
||||||
ResolvedPromise promise(- a->value->value());
|
ResolvedPromise promise(- a->value->value());
|
||||||
@ -826,7 +815,7 @@ void subC(Context* c, unsigned size, Const* a, Reg* b, Reg* t) {
|
|||||||
addC(c, size, &constant, b, t);
|
addC(c, size, &constant, b, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
void multiplyR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) {
|
void multiplyR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) {
|
||||||
if(size == 8) {
|
if(size == 8) {
|
||||||
bool useTemporaries = b->low == t->low;
|
bool useTemporaries = b->low == t->low;
|
||||||
int tmpLow;
|
int tmpLow;
|
||||||
@ -839,28 +828,28 @@ void multiplyR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) {
|
|||||||
tmpHigh = t->high;
|
tmpHigh = t->high;
|
||||||
}
|
}
|
||||||
|
|
||||||
issue(con, mullw(tmpHigh, H(a), R(b)));
|
emit(con, mullw(tmpHigh, a->high, b->low));
|
||||||
issue(con, mullw(tmpLow, R(a), H(b)));
|
emit(con, mullw(tmpLow, a->low, b->high));
|
||||||
issue(con, add(H(t), tmpHigh, tmpLow));
|
emit(con, add(t->high, tmpHigh, tmpLow));
|
||||||
issue(con, mulhwu(tmpLow, R(a), R(b)));
|
emit(con, mulhwu(tmpLow, a->low, b->low));
|
||||||
issue(con, add(H(t), H(t), tmpLow));
|
emit(con, add(t->high, t->high, tmpLow));
|
||||||
issue(con, mullw(R(t), R(a), R(b)));
|
emit(con, mullw(t->low, a->low, b->low));
|
||||||
|
|
||||||
if (useTemporaries) {
|
if (useTemporaries) {
|
||||||
con->client->releaseTemporary(tmpLow);
|
con->client->releaseTemporary(tmpLow);
|
||||||
con->client->releaseTemporary(tmpHigh);
|
con->client->releaseTemporary(tmpHigh);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
issue(con, mullw(R(t), R(a), R(b)));
|
emit(con, mullw(t->low, a->low, b->low));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void divideR(Context* con, unsigned size UNUSED, Reg* a, Reg* b, Reg* t) {
|
void divideR(Context* con, unsigned size UNUSED, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) {
|
||||||
assert(con, size == 4);
|
assert(con, size == 4);
|
||||||
issue(con, divw(R(t), R(b), R(a)));
|
emit(con, divw(t->low, b->low, a->low));
|
||||||
}
|
}
|
||||||
|
|
||||||
void remainderR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) {
|
void remainderR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) {
|
||||||
bool useTemporary = b->low == t->low;
|
bool useTemporary = b->low == t->low;
|
||||||
Assembler::Register tmp(t->low);
|
Assembler::Register tmp(t->low);
|
||||||
if (useTemporary) {
|
if (useTemporary) {
|
||||||
@ -935,15 +924,15 @@ store(Context* c, unsigned size, Assembler::Register* src,
|
|||||||
|
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case 1:
|
case 1:
|
||||||
issue(c, stbx(src->low, base, normalized));
|
emit(c, stbx(src->low, base, normalized));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
issue(c, sthx(src->low, base, normalized));
|
emit(c, sthx(src->low, base, normalized));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
issue(c, stwx(src->low, base, normalized));
|
emit(c, stwx(src->low, base, normalized));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 8: {
|
case 8: {
|
||||||
@ -959,15 +948,15 @@ store(Context* c, unsigned size, Assembler::Register* src,
|
|||||||
} else {
|
} else {
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case 1:
|
case 1:
|
||||||
issue(c, stb(src->low, base, offset));
|
emit(c, stb(src->low, base, offset));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
issue(c, sth(src->low, base, offset));
|
emit(c, sth(src->low, base, offset));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
issue(c, stw(src->low, base, offset));
|
emit(c, stw(src->low, base, offset));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 8: {
|
case 8: {
|
||||||
@ -998,12 +987,12 @@ moveAndUpdateRM(Context* c, unsigned srcSize UNUSED, Assembler::Register* src,
|
|||||||
assert(c, dstSize == BytesPerWord);
|
assert(c, dstSize == BytesPerWord);
|
||||||
|
|
||||||
if (dst->index == NoRegister) {
|
if (dst->index == NoRegister) {
|
||||||
issue(c, stwu(src->low, dst->base, dst->offset));
|
emit(c, stwu(src->low, dst->base, dst->offset));
|
||||||
} else {
|
} else {
|
||||||
assert(c, dst->offset == 0);
|
assert(c, dst->offset == 0);
|
||||||
assert(c, dst->scale == 1);
|
assert(c, dst->scale == 1);
|
||||||
|
|
||||||
issue(c, stwux(src->low, dst->base, dst->index));
|
emit(c, stwux(src->low, dst->base, dst->index));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1019,17 +1008,17 @@ load(Context* c, unsigned srcSize, int base, int offset, int index,
|
|||||||
|
|
||||||
switch (srcSize) {
|
switch (srcSize) {
|
||||||
case 1:
|
case 1:
|
||||||
issue(c, lbzx(dst->low, base, normalized));
|
emit(c, lbzx(dst->low, base, normalized));
|
||||||
if (signExtend) {
|
if (signExtend) {
|
||||||
issue(c, extsb(dst->low, dst->low));
|
emit(c, extsb(dst->low, dst->low));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
if (signExtend) {
|
if (signExtend) {
|
||||||
issue(c, lhax(dst->low, base, normalized));
|
emit(c, lhax(dst->low, base, normalized));
|
||||||
} else {
|
} else {
|
||||||
issue(c, lhzx(dst->low, base, normalized));
|
emit(c, lhzx(dst->low, base, normalized));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1043,7 +1032,7 @@ load(Context* c, unsigned srcSize, int base, int offset, int index,
|
|||||||
load(c, 4, base, 0, normalized, 1, 4, &dstHigh, preserveIndex, false);
|
load(c, 4, base, 0, normalized, 1, 4, &dstHigh, preserveIndex, false);
|
||||||
load(c, 4, base, 4, normalized, 1, 4, dst, preserveIndex, false);
|
load(c, 4, base, 4, normalized, 1, 4, dst, preserveIndex, false);
|
||||||
} else {
|
} else {
|
||||||
issue(c, lwzx(dst->low, base, normalized));
|
emit(c, lwzx(dst->low, base, normalized));
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -1054,22 +1043,22 @@ load(Context* c, unsigned srcSize, int base, int offset, int index,
|
|||||||
} else {
|
} else {
|
||||||
switch (srcSize) {
|
switch (srcSize) {
|
||||||
case 1:
|
case 1:
|
||||||
issue(c, lbz(dst->low, base, offset));
|
emit(c, lbz(dst->low, base, offset));
|
||||||
if (signExtend) {
|
if (signExtend) {
|
||||||
issue(c, extsb(dst->low, dst->low));
|
emit(c, extsb(dst->low, dst->low));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
if (signExtend) {
|
if (signExtend) {
|
||||||
issue(c, lha(dst->low, base, offset));
|
emit(c, lha(dst->low, base, offset));
|
||||||
} else {
|
} else {
|
||||||
issue(c, lha(dst->low, base, offset));
|
emit(c, lha(dst->low, base, offset));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
issue(c, lwz(dst->low, base, offset));
|
emit(c, lwz(dst->low, base, offset));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 8: {
|
case 8: {
|
||||||
@ -1078,7 +1067,7 @@ load(Context* c, unsigned srcSize, int base, int offset, int index,
|
|||||||
load(c, 4, base, offset, NoRegister, 1, 4, &dstHigh, false, false);
|
load(c, 4, base, offset, NoRegister, 1, 4, &dstHigh, false, false);
|
||||||
load(c, 4, base, offset + 4, NoRegister, 1, 4, dst, false, false);
|
load(c, 4, base, offset + 4, NoRegister, 1, 4, dst, false, false);
|
||||||
} else {
|
} else {
|
||||||
issue(c, lwzx(dst->low, base, offset));
|
emit(c, lwzx(dst->low, base, offset));
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -1103,19 +1092,6 @@ moveZMR(Context* c, unsigned srcSize, Assembler::Memory* src,
|
|||||||
dstSize, dst, true, false);
|
dstSize, dst, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// void moveCR3(Context* con, unsigned aSize, Const* a, unsigned tSize, Reg* t) {
|
|
||||||
// int64_t i = getVal(a);
|
|
||||||
// if(tSize == 8) {
|
|
||||||
// int64_t j;
|
|
||||||
// if(aSize == 8) j = i; // 64-bit const -> load high bits into high register
|
|
||||||
// else j = 0; // 32-bit const -> clear high register
|
|
||||||
// issue(con, lis(H(t), hi16(hi32(j))));
|
|
||||||
// issue(con, ori(H(t), H(t), lo16(hi32(j))));
|
|
||||||
// }
|
|
||||||
// issue(con, lis(R(t), hi16(i)));
|
|
||||||
// issue(con, ori(R(t), R(t), lo16(i)));
|
|
||||||
// }
|
|
||||||
|
|
||||||
void
|
void
|
||||||
andR(Context* c, unsigned size, Assembler::Register* a,
|
andR(Context* c, unsigned size, Assembler::Register* a,
|
||||||
Assembler::Register* b, Assembler::Register* dst)
|
Assembler::Register* b, Assembler::Register* dst)
|
||||||
@ -1128,7 +1104,7 @@ andR(Context* c, unsigned size, Assembler::Register* a,
|
|||||||
andR(c, 4, a, b, dst);
|
andR(c, 4, a, b, dst);
|
||||||
andR(c, 4, &ah, &bh, &dh);
|
andR(c, 4, &ah, &bh, &dh);
|
||||||
} else {
|
} else {
|
||||||
issue(c, and_(dst->low, a->low, b->low));
|
emit(c, and_(dst->low, a->low, b->low));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1181,9 +1157,9 @@ andC(Context* c, unsigned size, Assembler::Constant* a,
|
|||||||
// the topmost or bottommost 16 bits are zero.
|
// the topmost or bottommost 16 bits are zero.
|
||||||
|
|
||||||
if ((v32 >> 16) == 0) {
|
if ((v32 >> 16) == 0) {
|
||||||
issue(c, andi(dst->low, b->low, v32));
|
emit(c, andi(dst->low, b->low, v32));
|
||||||
} else if ((v32 & 0xFFFF) == 0) {
|
} else if ((v32 & 0xFFFF) == 0) {
|
||||||
issue(c, andis(dst->low, b->low, v32 >> 16));
|
emit(c, andis(dst->low, b->low, v32 >> 16));
|
||||||
} else {
|
} else {
|
||||||
bool useTemporary = b->low == dst->low;
|
bool useTemporary = b->low == dst->low;
|
||||||
Assembler::Register tmp(dst->low);
|
Assembler::Register tmp(dst->low);
|
||||||
@ -1206,12 +1182,12 @@ andC(Context* c, unsigned size, Assembler::Constant* a,
|
|||||||
|
|
||||||
if (state) {
|
if (state) {
|
||||||
if (start != 0 or end != 31) {
|
if (start != 0 or end != 31) {
|
||||||
issue(c, rlwinm(dst->low, b->low, 0, 31 - end, 31 - start));
|
emit(c, rlwinm(dst->low, b->low, 0, 31 - end, 31 - start));
|
||||||
} else {
|
} else {
|
||||||
moveRR(c, 4, b, 4, dst);
|
moveRR(c, 4, b, 4, dst);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
issue(c, li(dst->low, 0));
|
emit(c, li(dst->low, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1228,7 +1204,7 @@ orR(Context* c, unsigned size, Assembler::Register* a,
|
|||||||
orR(c, 4, a, b, dst);
|
orR(c, 4, a, b, dst);
|
||||||
orR(c, 4, &ah, &bh, &dh);
|
orR(c, 4, &ah, &bh, &dh);
|
||||||
} else {
|
} else {
|
||||||
issue(c, or_(dst->low, a->low, b->low));
|
emit(c, or_(dst->low, a->low, b->low));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1251,9 +1227,9 @@ orC(Context* c, unsigned size, Assembler::Constant* a,
|
|||||||
orC(c, 4, &al, b, dst);
|
orC(c, 4, &al, b, dst);
|
||||||
orC(c, 4, &ah, &bh, &dh);
|
orC(c, 4, &ah, &bh, &dh);
|
||||||
} else {
|
} else {
|
||||||
issue(c, ori(b->low, dst->low, v));
|
emit(c, ori(b->low, dst->low, v));
|
||||||
if (v >> 16) {
|
if (v >> 16) {
|
||||||
issue(c, oris(dst->low, dst->low, v >> 16));
|
emit(c, oris(dst->low, dst->low, v >> 16));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1270,7 +1246,7 @@ xorR(Context* c, unsigned size, Assembler::Register* a,
|
|||||||
xorR(c, 4, a, b, dst);
|
xorR(c, 4, a, b, dst);
|
||||||
xorR(c, 4, &ah, &bh, &dh);
|
xorR(c, 4, &ah, &bh, &dh);
|
||||||
} else {
|
} else {
|
||||||
issue(c, xor_(dst->low, a->low, b->low));
|
emit(c, xor_(dst->low, a->low, b->low));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1294,10 +1270,10 @@ xorC(Context* c, unsigned size, Assembler::Constant* a,
|
|||||||
xorC(c, 4, &ah, &bh, &dh);
|
xorC(c, 4, &ah, &bh, &dh);
|
||||||
} else {
|
} else {
|
||||||
if (v >> 16) {
|
if (v >> 16) {
|
||||||
issue(c, xoris(b->low, dst->low, v >> 16));
|
emit(c, xoris(b->low, dst->low, v >> 16));
|
||||||
issue(c, xori(dst->low, dst->low, v));
|
emit(c, xori(dst->low, dst->low, v));
|
||||||
} else {
|
} else {
|
||||||
issue(c, xori(b->low, dst->low, v));
|
emit(c, xori(b->low, dst->low, v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1313,7 +1289,7 @@ moveAR2(Context* c, unsigned srcSize UNUSED, Assembler::Address* src,
|
|||||||
appendImmediateTask
|
appendImmediateTask
|
||||||
(c, src->address, offset(c), BytesPerWord, promiseOffset, true);
|
(c, src->address, offset(c), BytesPerWord, promiseOffset, true);
|
||||||
|
|
||||||
issue(c, lis(dst->low, 0));
|
emit(c, lis(dst->low, 0));
|
||||||
moveMR(c, dstSize, &memory, dstSize, dst);
|
moveMR(c, dstSize, &memory, dstSize, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1330,7 +1306,7 @@ compareRR(Context* c, unsigned aSize UNUSED, Assembler::Register* a,
|
|||||||
{
|
{
|
||||||
assert(c, aSize == 4 and bSize == 4);
|
assert(c, aSize == 4 and bSize == 4);
|
||||||
|
|
||||||
issue(c, cmpw(b->low, a->low));
|
emit(c, cmpw(b->low, a->low));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1340,7 +1316,7 @@ compareCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
|||||||
assert(c, aSize == 4 and bSize == 4);
|
assert(c, aSize == 4 and bSize == 4);
|
||||||
|
|
||||||
if (a->value->resolved() and isInt16(a->value->value())) {
|
if (a->value->resolved() and isInt16(a->value->value())) {
|
||||||
issue(c, cmpwi(b->low, a->value->value()));
|
emit(c, cmpwi(b->low, a->value->value()));
|
||||||
} else {
|
} else {
|
||||||
Assembler::Register tmp(c->client->acquireTemporary());
|
Assembler::Register tmp(c->client->acquireTemporary());
|
||||||
moveCR(c, aSize, a, bSize, &tmp);
|
moveCR(c, aSize, a, bSize, &tmp);
|
||||||
@ -1379,7 +1355,7 @@ compareUnsignedRR(Context* c, unsigned aSize UNUSED, Assembler::Register* a,
|
|||||||
{
|
{
|
||||||
assert(c, aSize == 4 and bSize == 4);
|
assert(c, aSize == 4 and bSize == 4);
|
||||||
|
|
||||||
issue(c, cmplw(b->low, a->low));
|
emit(c, cmplw(b->low, a->low));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1389,7 +1365,7 @@ compareUnsignedCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
|||||||
assert(c, aSize == 4 and bSize == 4);
|
assert(c, aSize == 4 and bSize == 4);
|
||||||
|
|
||||||
if (a->value->resolved() and (a->value->value() >> 16) == 0) {
|
if (a->value->resolved() and (a->value->value() >> 16) == 0) {
|
||||||
issue(c, cmplwi(b->low, a->value->value()));
|
emit(c, cmplwi(b->low, a->value->value()));
|
||||||
} else {
|
} else {
|
||||||
Assembler::Register tmp(c->client->acquireTemporary());
|
Assembler::Register tmp(c->client->acquireTemporary());
|
||||||
moveCR(c, aSize, a, bSize, &tmp);
|
moveCR(c, aSize, a, bSize, &tmp);
|
||||||
@ -1429,7 +1405,7 @@ void
|
|||||||
conditional(Context* c, int32_t branch, Assembler::Constant* target)
|
conditional(Context* c, int32_t branch, Assembler::Constant* target)
|
||||||
{
|
{
|
||||||
appendOffsetTask(c, target->value, offset(c), true);
|
appendOffsetTask(c, target->value, offset(c), true);
|
||||||
issue(c, branch);
|
emit(c, branch);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1452,7 +1428,7 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al,
|
|||||||
switch (op) {
|
switch (op) {
|
||||||
case JumpIfEqual:
|
case JumpIfEqual:
|
||||||
next = c->code.length();
|
next = c->code.length();
|
||||||
issue(c, bne(0));
|
emit(c, bne(0));
|
||||||
|
|
||||||
compareSigned(c, 4, al, 4, bl);
|
compareSigned(c, 4, al, 4, bl);
|
||||||
conditional(c, beq(0), target);
|
conditional(c, beq(0), target);
|
||||||
@ -1469,7 +1445,7 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al,
|
|||||||
conditional(c, blt(0), target);
|
conditional(c, blt(0), target);
|
||||||
|
|
||||||
next = c->code.length();
|
next = c->code.length();
|
||||||
issue(c, bgt(0));
|
emit(c, bgt(0));
|
||||||
|
|
||||||
compareUnsigned(c, 4, al, 4, bl);
|
compareUnsigned(c, 4, al, 4, bl);
|
||||||
conditional(c, blt(0), target);
|
conditional(c, blt(0), target);
|
||||||
@ -1479,7 +1455,7 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al,
|
|||||||
conditional(c, bgt(0), target);
|
conditional(c, bgt(0), target);
|
||||||
|
|
||||||
next = c->code.length();
|
next = c->code.length();
|
||||||
issue(c, blt(0));
|
emit(c, blt(0));
|
||||||
|
|
||||||
compareUnsigned(c, 4, al, 4, bl);
|
compareUnsigned(c, 4, al, 4, bl);
|
||||||
conditional(c, bgt(0), target);
|
conditional(c, bgt(0), target);
|
||||||
@ -1489,7 +1465,7 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al,
|
|||||||
conditional(c, blt(0), target);
|
conditional(c, blt(0), target);
|
||||||
|
|
||||||
next = c->code.length();
|
next = c->code.length();
|
||||||
issue(c, bgt(0));
|
emit(c, bgt(0));
|
||||||
|
|
||||||
compareUnsigned(c, 4, al, 4, bl);
|
compareUnsigned(c, 4, al, 4, bl);
|
||||||
conditional(c, ble(0), target);
|
conditional(c, ble(0), target);
|
||||||
@ -1499,7 +1475,7 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al,
|
|||||||
conditional(c, bgt(0), target);
|
conditional(c, bgt(0), target);
|
||||||
|
|
||||||
next = c->code.length();
|
next = c->code.length();
|
||||||
issue(c, blt(0));
|
emit(c, blt(0));
|
||||||
|
|
||||||
compareUnsigned(c, 4, al, 4, bl);
|
compareUnsigned(c, 4, al, 4, bl);
|
||||||
conditional(c, bge(0), target);
|
conditional(c, bge(0), target);
|
||||||
@ -1621,10 +1597,10 @@ negateRR(Context* c, unsigned srcSize, Assembler::Register* src,
|
|||||||
if (srcSize == 8) {
|
if (srcSize == 8) {
|
||||||
Assembler::Register dstHigh(dst->high);
|
Assembler::Register dstHigh(dst->high);
|
||||||
|
|
||||||
issue(c, subfic(dst->low, src->low, 0));
|
emit(c, subfic(dst->low, src->low, 0));
|
||||||
issue(c, subfze(dst->high, src->high));
|
emit(c, subfze(dst->high, src->high));
|
||||||
} else {
|
} else {
|
||||||
issue(c, neg(dst->low, src->low));
|
emit(c, neg(dst->low, src->low));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1633,8 +1609,8 @@ callR(Context* c, unsigned size UNUSED, Assembler::Register* target)
|
|||||||
{
|
{
|
||||||
assert(c, size == BytesPerWord);
|
assert(c, size == BytesPerWord);
|
||||||
|
|
||||||
issue(c, mtctr(target->low));
|
emit(c, mtctr(target->low));
|
||||||
issue(c, bctrl());
|
emit(c, bctrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1643,7 +1619,7 @@ callC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
|
|||||||
assert(c, size == BytesPerWord);
|
assert(c, size == BytesPerWord);
|
||||||
|
|
||||||
appendOffsetTask(c, target->value, offset(c), false);
|
appendOffsetTask(c, target->value, offset(c), false);
|
||||||
issue(c, bl(0));
|
emit(c, bl(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1696,7 +1672,7 @@ jumpC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
|
|||||||
assert(c, size == BytesPerWord);
|
assert(c, size == BytesPerWord);
|
||||||
|
|
||||||
appendOffsetTask(c, target->value, offset(c), false);
|
appendOffsetTask(c, target->value, offset(c), false);
|
||||||
issue(c, b(0));
|
emit(c, b(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1705,7 +1681,7 @@ jumpIfEqualC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
|
|||||||
assert(c, size == BytesPerWord);
|
assert(c, size == BytesPerWord);
|
||||||
|
|
||||||
appendOffsetTask(c, target->value, offset(c), true);
|
appendOffsetTask(c, target->value, offset(c), true);
|
||||||
issue(c, beq(0));
|
emit(c, beq(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1714,7 +1690,7 @@ jumpIfNotEqualC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
|
|||||||
assert(c, size == BytesPerWord);
|
assert(c, size == BytesPerWord);
|
||||||
|
|
||||||
appendOffsetTask(c, target->value, offset(c), true);
|
appendOffsetTask(c, target->value, offset(c), true);
|
||||||
issue(c, bne(0));
|
emit(c, bne(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1723,7 +1699,7 @@ jumpIfGreaterC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
|
|||||||
assert(c, size == BytesPerWord);
|
assert(c, size == BytesPerWord);
|
||||||
|
|
||||||
appendOffsetTask(c, target->value, offset(c), true);
|
appendOffsetTask(c, target->value, offset(c), true);
|
||||||
issue(c, bgt(0));
|
emit(c, bgt(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1733,7 +1709,7 @@ jumpIfGreaterOrEqualC(Context* c, unsigned size UNUSED,
|
|||||||
assert(c, size == BytesPerWord);
|
assert(c, size == BytesPerWord);
|
||||||
|
|
||||||
appendOffsetTask(c, target->value, offset(c), true);
|
appendOffsetTask(c, target->value, offset(c), true);
|
||||||
issue(c, bge(0));
|
emit(c, bge(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1742,7 +1718,7 @@ jumpIfLessC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
|
|||||||
assert(c, size == BytesPerWord);
|
assert(c, size == BytesPerWord);
|
||||||
|
|
||||||
appendOffsetTask(c, target->value, offset(c), true);
|
appendOffsetTask(c, target->value, offset(c), true);
|
||||||
issue(c, blt(0));
|
emit(c, blt(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1752,19 +1728,19 @@ jumpIfLessOrEqualC(Context* c, unsigned size UNUSED,
|
|||||||
assert(c, size == BytesPerWord);
|
assert(c, size == BytesPerWord);
|
||||||
|
|
||||||
appendOffsetTask(c, target->value, offset(c), true);
|
appendOffsetTask(c, target->value, offset(c), true);
|
||||||
issue(c, ble(0));
|
emit(c, ble(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
return_(Context* c)
|
return_(Context* c)
|
||||||
{
|
{
|
||||||
issue(c, blr());
|
emit(c, blr());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
memoryBarrier(Context* c)
|
memoryBarrier(Context* c)
|
||||||
{
|
{
|
||||||
issue(c, sync(0));
|
emit(c, sync(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// END OPERATION COMPILERS
|
// END OPERATION COMPILERS
|
||||||
@ -2268,7 +2244,7 @@ class MyAssembler: public Assembler {
|
|||||||
|
|
||||||
virtual void allocateFrame(unsigned footprint) {
|
virtual void allocateFrame(unsigned footprint) {
|
||||||
Register returnAddress(0);
|
Register returnAddress(0);
|
||||||
issue(&c, mflr(returnAddress.low));
|
emit(&c, mflr(returnAddress.low));
|
||||||
|
|
||||||
Memory returnAddressDst(StackRegister, 8);
|
Memory returnAddressDst(StackRegister, 8);
|
||||||
moveRM(&c, BytesPerWord, &returnAddress, BytesPerWord, &returnAddressDst);
|
moveRM(&c, BytesPerWord, &returnAddress, BytesPerWord, &returnAddressDst);
|
||||||
@ -2296,7 +2272,7 @@ class MyAssembler: public Assembler {
|
|||||||
Memory returnAddressSrc(StackRegister, 8);
|
Memory returnAddressSrc(StackRegister, 8);
|
||||||
moveMR(&c, BytesPerWord, &returnAddressSrc, BytesPerWord, &returnAddress);
|
moveMR(&c, BytesPerWord, &returnAddressSrc, BytesPerWord, &returnAddress);
|
||||||
|
|
||||||
issue(&c, mtlr(returnAddress.low));
|
emit(&c, mtlr(returnAddress.low));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void popFrameForTailCall(unsigned footprint,
|
virtual void popFrameForTailCall(unsigned footprint,
|
||||||
@ -2310,7 +2286,7 @@ class MyAssembler: public Assembler {
|
|||||||
Memory returnAddressSrc(StackRegister, 8 + (footprint * BytesPerWord));
|
Memory returnAddressSrc(StackRegister, 8 + (footprint * BytesPerWord));
|
||||||
moveMR(&c, BytesPerWord, &returnAddressSrc, BytesPerWord, &tmp);
|
moveMR(&c, BytesPerWord, &returnAddressSrc, BytesPerWord, &tmp);
|
||||||
|
|
||||||
issue(&c, mtlr(tmp.low));
|
emit(&c, mtlr(tmp.low));
|
||||||
|
|
||||||
Memory stackSrc(StackRegister, footprint * BytesPerWord);
|
Memory stackSrc(StackRegister, footprint * BytesPerWord);
|
||||||
moveMR(&c, BytesPerWord, &stackSrc, BytesPerWord, &tmp);
|
moveMR(&c, BytesPerWord, &stackSrc, BytesPerWord, &tmp);
|
||||||
|
@ -199,7 +199,8 @@ inline bool
|
|||||||
atomicCompareAndSwap32(uint32_t* p, uint32_t old, uint32_t new_)
|
atomicCompareAndSwap32(uint32_t* p, uint32_t old, uint32_t new_)
|
||||||
{
|
{
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
InterlockedCompareExchange(p, new_, old);
|
return old == InterlockedCompareExchange
|
||||||
|
(reinterpret_cast<LONG*>(p), new_, old);
|
||||||
#elif (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)
|
#elif (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)
|
||||||
return __sync_bool_compare_and_swap(p, old, new_);
|
return __sync_bool_compare_and_swap(p, old, new_);
|
||||||
#else
|
#else
|
||||||
@ -218,7 +219,8 @@ inline bool
|
|||||||
atomicCompareAndSwap64(uint64_t* p, uint64_t old, uint64_t new_)
|
atomicCompareAndSwap64(uint64_t* p, uint64_t old, uint64_t new_)
|
||||||
{
|
{
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
InterlockedCompareExchange64(p, new_, old);
|
return old == InterlockedCompareExchange64
|
||||||
|
(reinterpret_cast<LONGLONG*>(p), new_, old);
|
||||||
#elif (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)
|
#elif (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)
|
||||||
return __sync_bool_compare_and_swap(p, old, new_);
|
return __sync_bool_compare_and_swap(p, old, new_);
|
||||||
#else
|
#else
|
||||||
|
Loading…
x
Reference in New Issue
Block a user