Merge branch 'master' of oss.readytalk.com:/var/local/git/avian

This commit is contained in:
Joel Dice 2010-05-04 08:25:53 -06:00
commit a035c6892f
11 changed files with 368 additions and 254 deletions

View File

@ -28,10 +28,11 @@
# define CLOSE _close
# define READ _read
# define WRITE _write
# define STAT _stat
# define STAT _wstat
# define STRUCT_STAT struct _stat
# define MKDIR(path, mode) _mkdir(path)
# define UNLINK _unlink
# define MKDIR(path, mode) _wmkdir(path)
# define UNLINK _wunlink
# define RENAME _wrename
# define OPEN_MASK O_BINARY
# ifdef _MSC_VER
@ -40,10 +41,15 @@
# define S_IRUSR _S_IREAD
# define S_IWUSR _S_IWRITE
# else
# define OPEN _open
# define CREAT _creat
# define OPEN _wopen
# define CREAT _wcreat
# 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
# include <dirent.h>
@ -59,42 +65,50 @@
# define MKDIR mkdir
# define CREAT creat
# define UNLINK unlink
# define RENAME rename
# define OPEN_MASK 0
# define GET_CHARS GetStringUTFChars
# define RELEASE_CHARS ReleaseStringUTFChars
typedef char char_t;
#endif // not PLATFORM_WINDOWS
inline void* operator new(size_t, void* p) throw() { return p; }
typedef const char_t* string_t;
namespace {
#ifdef _MSC_VER
inline int
OPEN(const char* path, int mask, int mode)
inline int
OPEN(string_t path, int mask, int mode)
{
int fd;
if (_sopen_s(&fd, path, mask, _SH_DENYNO, mode) == 0) {
return fd;
int fd;
if (_wsopen_s(&fd, path, mask, _SH_DENYNO, mode) == 0) {
return fd;
} else {
return -1;
return -1;
}
}
inline int
CREAT(const char* path, int mode)
CREAT(string_t path, int mode)
{
return OPEN(path, _O_CREAT, mode);
}
#endif
inline bool
exists(const char* path)
exists(string_t path)
{
STRUCT_STAT s;
return STAT(path, &s) == 0;
}
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);
if (fd == -1) {
@ -157,11 +171,11 @@ class Mapping {
};
inline Mapping*
map(JNIEnv* e, const char* path)
map(JNIEnv* e, string_t path)
{
Mapping* result = 0;
HANDLE file = CreateFile(path, FILE_READ_DATA, FILE_SHARE_READ, 0,
OPEN_EXISTING, 0, 0);
HANDLE file = CreateFileW(path, FILE_READ_DATA, FILE_SHARE_READ, 0,
OPEN_EXISTING, 0, 0);
if (file != INVALID_HANDLE_VALUE) {
unsigned size = GetFileSize(file, 0);
if (size != INVALID_FILE_SIZE) {
@ -205,10 +219,10 @@ class Directory {
public:
Directory(): handle(0), findNext(false) { }
virtual const char* next() {
virtual string_t next() {
if (handle and handle != INVALID_HANDLE_VALUE) {
if (findNext) {
if (FindNextFile(handle, &data)) {
if (FindNextFileW(handle, &data)) {
return data.cFileName;
}
} else {
@ -227,7 +241,7 @@ class Directory {
}
HANDLE handle;
WIN32_FIND_DATA data;
WIN32_FIND_DATAW data;
bool findNext;
};
@ -245,7 +259,7 @@ class Mapping {
};
inline Mapping*
map(JNIEnv* e, const char* path)
map(JNIEnv* e, string_t path)
{
Mapping* result = 0;
int fd = open(path, O_RDONLY);
@ -280,6 +294,14 @@ unmap(JNIEnv*, Mapping* mapping)
} // 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
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
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) {
STRUCT_STAT s;
int r = STAT(chars, &s);
if (r == 0) {
return s.st_size;
}
e->ReleaseStringUTFChars(path, chars);
releaseChars(e, path, chars);
}
return -1;
@ -313,7 +335,7 @@ Java_java_io_File_length(JNIEnv* e, jclass, jstring path)
extern "C" JNIEXPORT void JNICALL
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 (not exists(chars)) {
int r = ::MKDIR(chars, 0700);
@ -321,14 +343,14 @@ Java_java_io_File_mkdir(JNIEnv* e, jclass, jstring path)
throwNewErrno(e, "java/io/IOException");
}
}
e->ReleaseStringUTFChars(path, chars);
releaseChars(e, path, chars);
}
}
extern "C" JNIEXPORT void JNICALL
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 (not exists(chars)) {
int fd = CREAT(chars, 0600);
@ -338,38 +360,38 @@ Java_java_io_File_createNewFile(JNIEnv* e, jclass, jstring path)
doClose(e, fd);
}
}
e->ReleaseStringUTFChars(path, chars);
releaseChars(e, path, chars);
}
}
extern "C" JNIEXPORT void JNICALL
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) {
int r = UNLINK(chars);
if (r != 0) {
throwNewErrno(e, "java/io/IOException");
}
e->ReleaseStringUTFChars(path, chars);
releaseChars(e, path, chars);
}
}
extern "C" JNIEXPORT jboolean JNICALL
Java_java_io_File_rename(JNIEnv* e, jclass, jstring old, jstring new_)
{
const char* oldChars = e->GetStringUTFChars(old, 0);
const char* newChars = e->GetStringUTFChars(new_, 0);
string_t oldChars = getChars(e, old);
string_t newChars = getChars(e, new_);
if (oldChars) {
bool v;
if (newChars) {
v = rename(oldChars, newChars) == 0;
v = RENAME(oldChars, newChars) == 0;
e->ReleaseStringUTFChars(new_, newChars);
releaseChars(e, new_, newChars);
} else {
v = false;
}
e->ReleaseStringUTFChars(old, oldChars);
releaseChars(e, old, oldChars);
return v;
} else {
return false;
@ -379,12 +401,12 @@ Java_java_io_File_rename(JNIEnv* e, jclass, jstring old, jstring new_)
extern "C" JNIEXPORT jboolean JNICALL
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) {
STRUCT_STAT s;
int r = STAT(chars, &s);
bool v = (r == 0 and S_ISDIR(s.st_mode));
e->ReleaseStringUTFChars(path, chars);
releaseChars(e, path, chars);
return v;
} else {
return false;
@ -394,12 +416,12 @@ Java_java_io_File_isDirectory(JNIEnv* e, jclass, jstring path)
extern "C" JNIEXPORT jboolean JNICALL
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) {
STRUCT_STAT s;
int r = STAT(chars, &s);
bool v = (r == 0 and S_ISREG(s.st_mode));
e->ReleaseStringUTFChars(path, chars);
releaseChars(e, path, chars);
return v;
} else {
return false;
@ -409,10 +431,10 @@ Java_java_io_File_isFile(JNIEnv* e, jclass, jstring path)
extern "C" JNIEXPORT jboolean JNICALL
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) {
bool v = exists(chars);
e->ReleaseStringUTFChars(path, chars);
releaseChars(e, path, chars);
return v;
} else {
return false;
@ -424,18 +446,19 @@ Java_java_io_File_exists(JNIEnv* e, jclass, jstring path)
extern "C" JNIEXPORT jlong JNICALL
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) {
unsigned length = strlen(chars);
unsigned length = wcslen(chars);
unsigned size = length * sizeof(char_t);
RUNTIME_ARRAY(char, buffer, length + 3);
memcpy(RUNTIME_ARRAY_BODY(buffer), chars, length);
memcpy(RUNTIME_ARRAY_BODY(buffer) + length, "\\*", 3);
RUNTIME_ARRAY(char_t, buffer, length + 3);
memcpy(RUNTIME_ARRAY_BODY(buffer), chars, size);
memcpy(RUNTIME_ARRAY_BODY(buffer) + length, L"\\*", 6);
e->ReleaseStringUTFChars(path, chars);
releaseChars(e, path, chars);
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) {
d->dispose();
d = 0;
@ -451,14 +474,14 @@ extern "C" JNIEXPORT jstring JNICALL
Java_java_io_File_readDir(JNIEnv* e, jclass, jlong handle)
{
Directory* d = reinterpret_cast<Directory*>(handle);
while (true) {
const char* s = d->next();
string_t s = d->next();
if (s) {
if (strcmp(s, ".") == 0 || strcmp(s, "..") == 0) {
if (wcscmp(s, L".") == 0 || wcscmp(s, L"..") == 0) {
// skip . or .. and try again
} else {
return e->NewStringUTF(s);
return e->NewString(reinterpret_cast<const jchar*>(s), wcslen(s));
}
} else {
return 0;
@ -477,10 +500,10 @@ Java_java_io_File_closeDir(JNIEnv* , jclass, jlong handle)
extern "C" JNIEXPORT jlong JNICALL
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) {
jlong handle = reinterpret_cast<jlong>(opendir(chars));
e->ReleaseStringUTFChars(path, chars);
releaseChars(e, path, chars);
return handle;
} else {
return 0;
@ -522,13 +545,13 @@ Java_java_io_File_closeDir(JNIEnv* , jclass, jlong handle)
extern "C" JNIEXPORT jint JNICALL
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) {
int fd = doOpen(e, chars, O_RDONLY);
e->ReleaseStringUTFChars(path, chars);
return fd;
releaseChars(e, path, chars);
return fd;
} else {
return -1;
return -1;
}
}
@ -572,10 +595,10 @@ Java_java_io_FileInputStream_close(JNIEnv* e, jclass, jint fd)
extern "C" JNIEXPORT jint JNICALL
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) {
int fd = doOpen(e, chars, O_WRONLY | O_CREAT | O_TRUNC);
e->ReleaseStringUTFChars(path, chars);
releaseChars(e, path, chars);
return fd;
} else {
return -1;
@ -618,7 +641,7 @@ extern "C" JNIEXPORT void JNICALL
Java_java_io_RandomAccessFile_open(JNIEnv* e, jclass, jstring path,
jlongArray result)
{
const char* chars = e->GetStringUTFChars(path, 0);
string_t chars = getChars(e, path);
if (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);
e->SetLongArrayRegion(result, 1, 1, &length);
e->ReleaseStringUTFChars(path, chars);
releaseChars(e, path, chars);
}
}

View File

@ -38,9 +38,7 @@ public class InputStreamReader extends Reader {
char[] buffer16 = Utf8.decode16(buffer, 0, c);
for (int i = 0; i < buffer16.length; ++i) {
b[i + offset] = buffer16[i];
}
System.arraycopy(buffer16, 0, b, offset, buffer16.length);
return buffer16.length;
}

View File

@ -3,7 +3,7 @@ MAKEFLAGS = -s
name = avian
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)))
build-arch = powerpc
endif
@ -145,19 +145,8 @@ ifeq ($(arch),powerpc)
pointer-size = 4
endif
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
object-arch = arm
object-format = elf32-littlearm
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
ifeq ($(platform),darwin)
@ -277,6 +266,7 @@ ifdef msvc
ld = "$(msvc)/BIN/link.exe"
mt = "mt.exe"
cflags = -nologo -DAVIAN_VERSION=\"$(version)\" -D_JNI_IMPLEMENTATION_ \
-DUSE_ATOMIC_OPERATIONS \
-Fd$(native-build)/$(name).pdb -I"$(zlib)/include" -I$(src) \
-I"$(native-build)" -I"$(windows-java-home)/include" \
-I"$(windows-java-home)/include/win32"

View File

@ -11,6 +11,14 @@
#ifndef 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"
extern "C" void NO_RETURN

View File

@ -14,9 +14,9 @@
#include "types.h"
#include "common.h"
#define IP_REGISTER(context) (context->uc_mcontext.gregs[15])
#define STACK_REGISTER(context) (context->uc_mcontext.gregs[13])
#define THREAD_REGISTER(context) (context->uc_mcontext.gregs[12])
#define IP_REGISTER(context) (context->uc_mcontext.arm_pc)
#define STACK_REGISTER(context) (context->uc_mcontext.arm_sp)
#define THREAD_REGISTER(context) (context->uc_mcontext.arm_ip)
extern "C" uint64_t
vmNativeCall(void* function, unsigned stackTotal, void* memoryTable,
@ -60,9 +60,25 @@ syncInstructionCache(const void* start UNUSED, unsigned size UNUSED)
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
dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
unsigned argumentCount, unsigned argumentsSize,
unsigned argumentCount, unsigned argumentsSize UNUSED,
unsigned returnType UNUSED)
{
const unsigned GprCount = 4;

View File

@ -42,6 +42,7 @@
#define EM_386 3
#define EM_X86_64 62
#define EM_ARM 40
#define SHT_PROGBITS 1
#define SHT_SYMTAB 2
@ -352,6 +353,8 @@ MAKE_NAME(writeElf, BITS_PER_WORD, Object)
machine = EM_X86_64;
} else if (strcmp(architecture, "i386") == 0) {
machine = EM_386;
} else if (strcmp(architecture, "arm") == 0) {
machine = EM_ARM;
} else {
fprintf(stderr, "unsupported architecture: %s\n", architecture);
return false;

View File

@ -73,7 +73,8 @@ writeObject(uint8_t* data, unsigned size, FILE* out, const char* startName,
success = writeElf64Object
(data, size, out, startName, endName, architecture, alignment,
writable, executable);
} else if (strcmp("i386", architecture) == 0) {
} else if (strcmp("i386", architecture) == 0 ||
strcmp("arm", architecture) == 0) {
found = true;
success = writeElf32Object
(data, size, out, startName, endName, architecture, alignment,

View File

@ -18,6 +18,8 @@ using namespace vm;
namespace {
namespace local {
const uintptr_t InterfaceMethodID
= (static_cast<uintptr_t>(1) << (BitsPerWord - 1));
@ -117,7 +119,7 @@ GetEnv(Machine* m, Thread** t, jint version)
}
}
jsize JNICALL
jint JNICALL
GetVersion(Thread* t)
{
ENTER(t, Thread::ActiveState);
@ -159,7 +161,7 @@ GetStringUTFLength(Thread* t, jstring s)
{
ENTER(t, Thread::ActiveState);
return stringLength(t, *s);
return stringUTFLength(t, *s);
}
const char* JNICALL
@ -167,9 +169,10 @@ GetStringUTFChars(Thread* t, jstring s, jboolean* isCopy)
{
ENTER(t, Thread::ActiveState);
int length = stringUTFLength(t, *s);
char* chars = static_cast<char*>
(t->m->heap->allocate(stringLength(t, *s) + 1));
stringChars(t, *s, chars);
(t->m->heap->allocate(length + 1));
stringUTFChars(t, *s, chars, length);
if (isCopy) *isCopy = true;
return chars;
@ -1906,6 +1909,8 @@ append(char** p, const char* value, unsigned length, char tail)
}
}
} // namespace local
} // namespace
namespace vm {
@ -1926,170 +1931,171 @@ populateJNITables(JavaVMVTable* vmTable, JNIEnvVTable* envTable)
{
memset(vmTable, 0, sizeof(JavaVMVTable));
vmTable->DestroyJavaVM = DestroyJavaVM;
vmTable->AttachCurrentThread = AttachCurrentThread;
vmTable->AttachCurrentThreadAsDaemon = AttachCurrentThreadAsDaemon;
vmTable->DetachCurrentThread = DetachCurrentThread;
vmTable->GetEnv = GetEnv;
vmTable->DestroyJavaVM = local::DestroyJavaVM;
vmTable->AttachCurrentThread = local::AttachCurrentThread;
vmTable->AttachCurrentThreadAsDaemon = local::AttachCurrentThreadAsDaemon;
vmTable->DetachCurrentThread = local::DetachCurrentThread;
vmTable->GetEnv = local::GetEnv;
memset(envTable, 0, sizeof(JNIEnvVTable));
envTable->GetVersion = ::GetVersion;
envTable->GetStringLength = ::GetStringLength;
envTable->GetStringChars = ::GetStringChars;
envTable->ReleaseStringChars = ::ReleaseStringChars;
envTable->GetStringUTFLength = ::GetStringUTFLength;
envTable->GetStringUTFChars = ::GetStringUTFChars;
envTable->ReleaseStringUTFChars = ::ReleaseStringUTFChars;
envTable->GetArrayLength = ::GetArrayLength;
envTable->NewString = ::NewString;
envTable->NewStringUTF = ::NewStringUTF;
envTable->FindClass = ::FindClass;
envTable->ThrowNew = ::ThrowNew;
envTable->ExceptionCheck = ::ExceptionCheck;
envTable->NewDirectByteBuffer = ::NewDirectByteBuffer;
envTable->GetDirectBufferAddress = ::GetDirectBufferAddress;
envTable->GetDirectBufferCapacity = ::GetDirectBufferCapacity;
envTable->DeleteLocalRef = ::DeleteLocalRef;
envTable->GetObjectClass = ::GetObjectClass;
envTable->IsInstanceOf = ::IsInstanceOf;
envTable->GetFieldID = ::GetFieldID;
envTable->GetMethodID = ::GetMethodID;
envTable->GetStaticMethodID = ::GetStaticMethodID;
envTable->NewObject = ::NewObject;
envTable->NewObjectV = ::NewObjectV;
envTable->CallObjectMethodV = ::CallObjectMethodV;
envTable->CallObjectMethod = ::CallObjectMethod;
envTable->CallBooleanMethodV = ::CallBooleanMethodV;
envTable->CallBooleanMethod = ::CallBooleanMethod;
envTable->CallByteMethodV = ::CallByteMethodV;
envTable->CallByteMethod = ::CallByteMethod;
envTable->CallCharMethodV = ::CallCharMethodV;
envTable->CallCharMethod = ::CallCharMethod;
envTable->CallShortMethodV = ::CallShortMethodV;
envTable->CallShortMethod = ::CallShortMethod;
envTable->CallIntMethodV = ::CallIntMethodV;
envTable->CallIntMethod = ::CallIntMethod;
envTable->CallLongMethodV = ::CallLongMethodV;
envTable->CallLongMethod = ::CallLongMethod;
envTable->CallFloatMethodV = ::CallFloatMethodV;
envTable->CallFloatMethod = ::CallFloatMethod;
envTable->CallDoubleMethodV = ::CallDoubleMethodV;
envTable->CallDoubleMethod = ::CallDoubleMethod;
envTable->CallVoidMethodV = ::CallVoidMethodV;
envTable->CallVoidMethod = ::CallVoidMethod;
envTable->CallStaticObjectMethodV = ::CallStaticObjectMethodV;
envTable->CallStaticObjectMethod = ::CallStaticObjectMethod;
envTable->CallStaticBooleanMethodV = ::CallStaticBooleanMethodV;
envTable->CallStaticBooleanMethod = ::CallStaticBooleanMethod;
envTable->CallStaticByteMethodV = ::CallStaticByteMethodV;
envTable->CallStaticByteMethod = ::CallStaticByteMethod;
envTable->CallStaticCharMethodV = ::CallStaticCharMethodV;
envTable->CallStaticCharMethod = ::CallStaticCharMethod;
envTable->CallStaticShortMethodV = ::CallStaticShortMethodV;
envTable->CallStaticShortMethod = ::CallStaticShortMethod;
envTable->CallStaticIntMethodV = ::CallStaticIntMethodV;
envTable->CallStaticIntMethod = ::CallStaticIntMethod;
envTable->CallStaticLongMethodV = ::CallStaticLongMethodV;
envTable->CallStaticLongMethod = ::CallStaticLongMethod;
envTable->CallStaticFloatMethodV = ::CallStaticFloatMethodV;
envTable->CallStaticFloatMethod = ::CallStaticFloatMethod;
envTable->CallStaticDoubleMethodV = ::CallStaticDoubleMethodV;
envTable->CallStaticDoubleMethod = ::CallStaticDoubleMethod;
envTable->CallStaticVoidMethodV = ::CallStaticVoidMethodV;
envTable->CallStaticVoidMethod = ::CallStaticVoidMethod;
envTable->GetStaticFieldID = ::GetStaticFieldID;
envTable->GetObjectField = ::GetObjectField;
envTable->GetBooleanField = ::GetBooleanField;
envTable->GetByteField = ::GetByteField;
envTable->GetCharField = ::GetCharField;
envTable->GetShortField = ::GetShortField;
envTable->GetIntField = ::GetIntField;
envTable->GetLongField = ::GetLongField;
envTable->GetFloatField = ::GetFloatField;
envTable->GetDoubleField = ::GetDoubleField;
envTable->SetObjectField = ::SetObjectField;
envTable->SetBooleanField = ::SetBooleanField;
envTable->SetByteField = ::SetByteField;
envTable->SetCharField = ::SetCharField;
envTable->SetShortField = ::SetShortField;
envTable->SetIntField = ::SetIntField;
envTable->SetLongField = ::SetLongField;
envTable->SetFloatField = ::SetFloatField;
envTable->SetDoubleField = ::SetDoubleField;
envTable->GetStaticObjectField = ::GetStaticObjectField;
envTable->GetStaticBooleanField = ::GetStaticBooleanField;
envTable->GetStaticByteField = ::GetStaticByteField;
envTable->GetStaticCharField = ::GetStaticCharField;
envTable->GetStaticShortField = ::GetStaticShortField;
envTable->GetStaticIntField = ::GetStaticIntField;
envTable->GetStaticLongField = ::GetStaticLongField;
envTable->GetStaticFloatField = ::GetStaticFloatField;
envTable->GetStaticDoubleField = ::GetStaticDoubleField;
envTable->SetStaticObjectField = ::SetStaticObjectField;
envTable->SetStaticBooleanField = ::SetStaticBooleanField;
envTable->SetStaticByteField = ::SetStaticByteField;
envTable->SetStaticCharField = ::SetStaticCharField;
envTable->SetStaticShortField = ::SetStaticShortField;
envTable->SetStaticIntField = ::SetStaticIntField;
envTable->SetStaticLongField = ::SetStaticLongField;
envTable->SetStaticFloatField = ::SetStaticFloatField;
envTable->SetStaticDoubleField = ::SetStaticDoubleField;
envTable->NewGlobalRef = ::NewGlobalRef;
envTable->NewWeakGlobalRef = ::NewGlobalRef;
envTable->DeleteGlobalRef = ::DeleteGlobalRef;
envTable->ExceptionOccurred = ::ExceptionOccurred;
envTable->ExceptionDescribe = ::ExceptionDescribe;
envTable->ExceptionClear = ::ExceptionClear;
envTable->NewObjectArray = ::NewObjectArray;
envTable->GetObjectArrayElement = ::GetObjectArrayElement;
envTable->SetObjectArrayElement = ::SetObjectArrayElement;
envTable->NewBooleanArray = ::NewBooleanArray;
envTable->NewByteArray = ::NewByteArray;
envTable->NewCharArray = ::NewCharArray;
envTable->NewShortArray = ::NewShortArray;
envTable->NewIntArray = ::NewIntArray;
envTable->NewLongArray = ::NewLongArray;
envTable->NewFloatArray = ::NewFloatArray;
envTable->NewDoubleArray = ::NewDoubleArray;
envTable->GetBooleanArrayElements = ::GetBooleanArrayElements;
envTable->GetByteArrayElements = ::GetByteArrayElements;
envTable->GetCharArrayElements = ::GetCharArrayElements;
envTable->GetShortArrayElements = ::GetShortArrayElements;
envTable->GetIntArrayElements = ::GetIntArrayElements;
envTable->GetLongArrayElements = ::GetLongArrayElements;
envTable->GetFloatArrayElements = ::GetFloatArrayElements;
envTable->GetDoubleArrayElements = ::GetDoubleArrayElements;
envTable->ReleaseBooleanArrayElements = ::ReleaseBooleanArrayElements;
envTable->ReleaseByteArrayElements = ::ReleaseByteArrayElements;
envTable->ReleaseCharArrayElements = ::ReleaseCharArrayElements;
envTable->ReleaseShortArrayElements = ::ReleaseShortArrayElements;
envTable->ReleaseIntArrayElements = ::ReleaseIntArrayElements;
envTable->ReleaseLongArrayElements = ::ReleaseLongArrayElements;
envTable->ReleaseFloatArrayElements = ::ReleaseFloatArrayElements;
envTable->ReleaseDoubleArrayElements = ::ReleaseDoubleArrayElements;
envTable->GetBooleanArrayRegion = ::GetBooleanArrayRegion;
envTable->GetByteArrayRegion = ::GetByteArrayRegion;
envTable->GetCharArrayRegion = ::GetCharArrayRegion;
envTable->GetShortArrayRegion = ::GetShortArrayRegion;
envTable->GetIntArrayRegion = ::GetIntArrayRegion;
envTable->GetLongArrayRegion = ::GetLongArrayRegion;
envTable->GetFloatArrayRegion = ::GetFloatArrayRegion;
envTable->GetDoubleArrayRegion = ::GetDoubleArrayRegion;
envTable->SetBooleanArrayRegion = ::SetBooleanArrayRegion;
envTable->SetByteArrayRegion = ::SetByteArrayRegion;
envTable->SetCharArrayRegion = ::SetCharArrayRegion;
envTable->SetShortArrayRegion = ::SetShortArrayRegion;
envTable->SetIntArrayRegion = ::SetIntArrayRegion;
envTable->SetLongArrayRegion = ::SetLongArrayRegion;
envTable->SetFloatArrayRegion = ::SetFloatArrayRegion;
envTable->SetDoubleArrayRegion = ::SetDoubleArrayRegion;
envTable->GetPrimitiveArrayCritical = ::GetPrimitiveArrayCritical;
envTable->ReleasePrimitiveArrayCritical = ::ReleasePrimitiveArrayCritical;
envTable->MonitorEnter = MonitorEnter;
envTable->MonitorExit = MonitorExit;
envTable->GetJavaVM = ::GetJavaVM;
envTable->IsSameObject = ::IsSameObject;
envTable->GetVersion = local::GetVersion;
envTable->GetStringLength = local::GetStringLength;
envTable->GetStringChars = local::GetStringChars;
envTable->ReleaseStringChars = local::ReleaseStringChars;
envTable->GetStringUTFLength = local::GetStringUTFLength;
envTable->GetStringUTFChars = local::GetStringUTFChars;
envTable->ReleaseStringUTFChars = local::ReleaseStringUTFChars;
envTable->GetArrayLength = local::GetArrayLength;
envTable->NewString = local::NewString;
envTable->NewStringUTF = local::NewStringUTF;
envTable->FindClass = local::FindClass;
envTable->ThrowNew = local::ThrowNew;
envTable->ExceptionCheck = local::ExceptionCheck;
envTable->NewDirectByteBuffer = local::NewDirectByteBuffer;
envTable->GetDirectBufferAddress = local::GetDirectBufferAddress;
envTable->GetDirectBufferCapacity = local::GetDirectBufferCapacity;
envTable->DeleteLocalRef = local::DeleteLocalRef;
envTable->GetObjectClass = local::GetObjectClass;
envTable->IsInstanceOf = local::IsInstanceOf;
envTable->GetFieldID = local::GetFieldID;
envTable->GetMethodID = local::GetMethodID;
envTable->GetStaticMethodID = local::GetStaticMethodID;
envTable->NewObject = local::NewObject;
envTable->NewObjectV = local::NewObjectV;
envTable->CallObjectMethodV = local::CallObjectMethodV;
envTable->CallObjectMethod = local::CallObjectMethod;
envTable->CallBooleanMethodV = local::CallBooleanMethodV;
envTable->CallBooleanMethod = local::CallBooleanMethod;
envTable->CallByteMethodV = local::CallByteMethodV;
envTable->CallByteMethod = local::CallByteMethod;
envTable->CallCharMethodV = local::CallCharMethodV;
envTable->CallCharMethod = local::CallCharMethod;
envTable->CallShortMethodV = local::CallShortMethodV;
envTable->CallShortMethod = local::CallShortMethod;
envTable->CallIntMethodV = local::CallIntMethodV;
envTable->CallIntMethod = local::CallIntMethod;
envTable->CallLongMethodV = local::CallLongMethodV;
envTable->CallLongMethod = local::CallLongMethod;
envTable->CallFloatMethodV = local::CallFloatMethodV;
envTable->CallFloatMethod = local::CallFloatMethod;
envTable->CallDoubleMethodV = local::CallDoubleMethodV;
envTable->CallDoubleMethod = local::CallDoubleMethod;
envTable->CallVoidMethodV = local::CallVoidMethodV;
envTable->CallVoidMethod = local::CallVoidMethod;
envTable->CallStaticObjectMethodV = local::CallStaticObjectMethodV;
envTable->CallStaticObjectMethod = local::CallStaticObjectMethod;
envTable->CallStaticBooleanMethodV = local::CallStaticBooleanMethodV;
envTable->CallStaticBooleanMethod = local::CallStaticBooleanMethod;
envTable->CallStaticByteMethodV = local::CallStaticByteMethodV;
envTable->CallStaticByteMethod = local::CallStaticByteMethod;
envTable->CallStaticCharMethodV = local::CallStaticCharMethodV;
envTable->CallStaticCharMethod = local::CallStaticCharMethod;
envTable->CallStaticShortMethodV = local::CallStaticShortMethodV;
envTable->CallStaticShortMethod = local::CallStaticShortMethod;
envTable->CallStaticIntMethodV = local::CallStaticIntMethodV;
envTable->CallStaticIntMethod = local::CallStaticIntMethod;
envTable->CallStaticLongMethodV = local::CallStaticLongMethodV;
envTable->CallStaticLongMethod = local::CallStaticLongMethod;
envTable->CallStaticFloatMethodV = local::CallStaticFloatMethodV;
envTable->CallStaticFloatMethod = local::CallStaticFloatMethod;
envTable->CallStaticDoubleMethodV = local::CallStaticDoubleMethodV;
envTable->CallStaticDoubleMethod = local::CallStaticDoubleMethod;
envTable->CallStaticVoidMethodV = local::CallStaticVoidMethodV;
envTable->CallStaticVoidMethod = local::CallStaticVoidMethod;
envTable->GetStaticFieldID = local::GetStaticFieldID;
envTable->GetObjectField = local::GetObjectField;
envTable->GetBooleanField = local::GetBooleanField;
envTable->GetByteField = local::GetByteField;
envTable->GetCharField = local::GetCharField;
envTable->GetShortField = local::GetShortField;
envTable->GetIntField = local::GetIntField;
envTable->GetLongField = local::GetLongField;
envTable->GetFloatField = local::GetFloatField;
envTable->GetDoubleField = local::GetDoubleField;
envTable->SetObjectField = local::SetObjectField;
envTable->SetBooleanField = local::SetBooleanField;
envTable->SetByteField = local::SetByteField;
envTable->SetCharField = local::SetCharField;
envTable->SetShortField = local::SetShortField;
envTable->SetIntField = local::SetIntField;
envTable->SetLongField = local::SetLongField;
envTable->SetFloatField = local::SetFloatField;
envTable->SetDoubleField = local::SetDoubleField;
envTable->GetStaticObjectField = local::GetStaticObjectField;
envTable->GetStaticBooleanField = local::GetStaticBooleanField;
envTable->GetStaticByteField = local::GetStaticByteField;
envTable->GetStaticCharField = local::GetStaticCharField;
envTable->GetStaticShortField = local::GetStaticShortField;
envTable->GetStaticIntField = local::GetStaticIntField;
envTable->GetStaticLongField = local::GetStaticLongField;
envTable->GetStaticFloatField = local::GetStaticFloatField;
envTable->GetStaticDoubleField = local::GetStaticDoubleField;
envTable->SetStaticObjectField = local::SetStaticObjectField;
envTable->SetStaticBooleanField = local::SetStaticBooleanField;
envTable->SetStaticByteField = local::SetStaticByteField;
envTable->SetStaticCharField = local::SetStaticCharField;
envTable->SetStaticShortField = local::SetStaticShortField;
envTable->SetStaticIntField = local::SetStaticIntField;
envTable->SetStaticLongField = local::SetStaticLongField;
envTable->SetStaticFloatField = local::SetStaticFloatField;
envTable->SetStaticDoubleField = local::SetStaticDoubleField;
envTable->NewGlobalRef = local::NewGlobalRef;
envTable->NewWeakGlobalRef = local::NewGlobalRef;
envTable->DeleteGlobalRef = local::DeleteGlobalRef;
envTable->ExceptionOccurred = local::ExceptionOccurred;
envTable->ExceptionDescribe = local::ExceptionDescribe;
envTable->ExceptionClear = local::ExceptionClear;
envTable->NewObjectArray = local::NewObjectArray;
envTable->GetObjectArrayElement = local::GetObjectArrayElement;
envTable->SetObjectArrayElement = local::SetObjectArrayElement;
envTable->NewBooleanArray = local::NewBooleanArray;
envTable->NewByteArray = local::NewByteArray;
envTable->NewCharArray = local::NewCharArray;
envTable->NewShortArray = local::NewShortArray;
envTable->NewIntArray = local::NewIntArray;
envTable->NewLongArray = local::NewLongArray;
envTable->NewFloatArray = local::NewFloatArray;
envTable->NewDoubleArray = local::NewDoubleArray;
envTable->GetBooleanArrayElements = local::GetBooleanArrayElements;
envTable->GetByteArrayElements = local::GetByteArrayElements;
envTable->GetCharArrayElements = local::GetCharArrayElements;
envTable->GetShortArrayElements = local::GetShortArrayElements;
envTable->GetIntArrayElements = local::GetIntArrayElements;
envTable->GetLongArrayElements = local::GetLongArrayElements;
envTable->GetFloatArrayElements = local::GetFloatArrayElements;
envTable->GetDoubleArrayElements = local::GetDoubleArrayElements;
envTable->ReleaseBooleanArrayElements = local::ReleaseBooleanArrayElements;
envTable->ReleaseByteArrayElements = local::ReleaseByteArrayElements;
envTable->ReleaseCharArrayElements = local::ReleaseCharArrayElements;
envTable->ReleaseShortArrayElements = local::ReleaseShortArrayElements;
envTable->ReleaseIntArrayElements = local::ReleaseIntArrayElements;
envTable->ReleaseLongArrayElements = local::ReleaseLongArrayElements;
envTable->ReleaseFloatArrayElements = local::ReleaseFloatArrayElements;
envTable->ReleaseDoubleArrayElements = local::ReleaseDoubleArrayElements;
envTable->GetBooleanArrayRegion = local::GetBooleanArrayRegion;
envTable->GetByteArrayRegion = local::GetByteArrayRegion;
envTable->GetCharArrayRegion = local::GetCharArrayRegion;
envTable->GetShortArrayRegion = local::GetShortArrayRegion;
envTable->GetIntArrayRegion = local::GetIntArrayRegion;
envTable->GetLongArrayRegion = local::GetLongArrayRegion;
envTable->GetFloatArrayRegion = local::GetFloatArrayRegion;
envTable->GetDoubleArrayRegion = local::GetDoubleArrayRegion;
envTable->SetBooleanArrayRegion = local::SetBooleanArrayRegion;
envTable->SetByteArrayRegion = local::SetByteArrayRegion;
envTable->SetCharArrayRegion = local::SetCharArrayRegion;
envTable->SetShortArrayRegion = local::SetShortArrayRegion;
envTable->SetIntArrayRegion = local::SetIntArrayRegion;
envTable->SetLongArrayRegion = local::SetLongArrayRegion;
envTable->SetFloatArrayRegion = local::SetFloatArrayRegion;
envTable->SetDoubleArrayRegion = local::SetDoubleArrayRegion;
envTable->GetPrimitiveArrayCritical = local::GetPrimitiveArrayCritical;
envTable->ReleasePrimitiveArrayCritical
= local::ReleasePrimitiveArrayCritical;
envTable->MonitorEnter = local::MonitorEnter;
envTable->MonitorExit = local::MonitorExit;
envTable->GetJavaVM = local::GetJavaVM;
envTable->IsSameObject = local::IsSameObject;
}
} // namespace vm
@ -2111,7 +2117,7 @@ JNI_GetDefaultJavaVMInitArgs(void*)
extern "C" JNIEXPORT jint JNICALL
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;
const char* bootLibrary = 0;
@ -2127,7 +2133,7 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
if (strncmp(a->options[i].optionString, "-X", 2) == 0) {
const char* p = a->options[i].optionString + 2;
if (strncmp(p, "mx", 2) == 0) {
heapLimit = parseSize(p + 2);
heapLimit = local::parseSize(p + 2);
} else if (strncmp(p, BOOTCLASSPATH_PREPEND_OPTION ":",
sizeof(BOOTCLASSPATH_PREPEND_OPTION)) == 0)
{
@ -2174,10 +2180,11 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
RUNTIME_ARRAY(char, classpathBuffer, classpathBufferSize);
char* classpathPointer = RUNTIME_ARRAY_BODY(classpathBuffer);
append(&classpathPointer, bootClasspathPrepend, bcppl, PATH_SEPARATOR);
append(&classpathPointer, bootClasspath, bcpl, PATH_SEPARATOR);
append(&classpathPointer, bootClasspathAppend, bcpal, PATH_SEPARATOR);
append(&classpathPointer, classpath, cpl, 0);
local::append
(&classpathPointer, bootClasspathPrepend, bcppl, PATH_SEPARATOR);
local::append(&classpathPointer, bootClasspath, bcpl, PATH_SEPARATOR);
local::append(&classpathPointer, bootClasspathAppend, bcpal, PATH_SEPARATOR);
local::append(&classpathPointer, classpath, cpl, 0);
System* s = makeSystem(crashDumpDirectory);
Heap* h = makeHeap(s, heapLimit);

View File

@ -2690,6 +2690,30 @@ makeString(Thread* t, const char* format, ...)
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
stringChars(Thread* t, object string, char* chars)
{
@ -2730,6 +2754,42 @@ stringChars(Thread* t, object string, uint16_t* chars)
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
isAssignableFrom(Thread* t, object a, object b)
{

View File

@ -1901,12 +1901,18 @@ makeByteArray(Thread* t, const char* format, ...);
object
makeString(Thread* t, const char* format, ...);
int
stringUTFLength(Thread* t, object string);
void
stringChars(Thread* t, object string, char* chars);
void
stringChars(Thread* t, object string, uint16_t* chars);
void
stringUTFChars(Thread* t, object string, char* chars, unsigned length);
bool
isAssignableFrom(Thread* t, object a, object b);

View File

@ -199,7 +199,8 @@ inline bool
atomicCompareAndSwap32(uint32_t* p, uint32_t old, uint32_t new_)
{
#ifdef _MSC_VER
InterlockedCompareExchange(p, new_, old);
return old == InterlockedCompareExchange
(reinterpret_cast<LONG*>(p), new_, old);
#elif (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)
return __sync_bool_compare_and_swap(p, old, new_);
#else
@ -218,7 +219,8 @@ inline bool
atomicCompareAndSwap64(uint64_t* p, uint64_t old, uint64_t new_)
{
#ifdef _MSC_VER
InterlockedCompareExchange64(p, new_, old);
return old == InterlockedCompareExchange64
(reinterpret_cast<LONGLONG*>(p), new_, old);
#elif (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)
return __sync_bool_compare_and_swap(p, old, new_);
#else