corda/src/classpath-android.cpp

1673 lines
42 KiB
C++
Raw Normal View History

/* Copyright (c) 2010-2012, 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. */
struct JavaVM;
extern "C" int JNI_OnLoad(JavaVM*, void*);
#define _POSIX_C_SOURCE 200112L
#undef _GNU_SOURCE
#include "avian/machine.h"
#include "avian/classpath-common.h"
#include "avian/process.h"
using namespace vm;
namespace {
namespace local {
2013-02-21 22:37:17 +00:00
void JNICALL
loadLibrary(Thread* t, object, uintptr_t* arguments)
{
object name = reinterpret_cast<object>(arguments[1]);
unsigned length = stringLength(t, name);
THREAD_RUNTIME_ARRAY(t, char, n, length + 1);
stringChars(t, name, RUNTIME_ARRAY_BODY(n));
loadLibrary(t, "", RUNTIME_ARRAY_BODY(n), true, true);
}
int64_t JNICALL
appLoader(Thread* t, object, uintptr_t*)
{
return reinterpret_cast<uintptr_t>(root(t, Machine::AppLoader));
}
int64_t JNICALL
mapData(Thread*, object, uintptr_t*);
void JNICALL
closeMemoryMappedFile(Thread*, object, uintptr_t*);
2013-02-22 18:06:49 +00:00
object
makeMethodOrConstructor(Thread* t, object c, unsigned index)
{
PROTECT(t, c);
object method = arrayBody
(t, classMethodTable(t, jclassVmClass(t, c)), index);
PROTECT(t, method);
unsigned parameterCount;
unsigned returnTypeSpec;
object parameterTypes = resolveParameterJTypes
(t, classLoader(t, methodClass(t, method)), methodSpec(t, method),
&parameterCount, &returnTypeSpec);
PROTECT(t, parameterTypes);
object returnType = resolveJType
(t, classLoader(t, methodClass(t, method)), reinterpret_cast<char*>
(&byteArrayBody(t, methodSpec(t, method), returnTypeSpec)),
byteArrayLength(t, methodSpec(t, method)) - 1 - returnTypeSpec);
PROTECT(t, returnType);
object exceptionTypes = resolveExceptionJTypes
(t, classLoader(t, methodClass(t, method)), methodAddendum(t, method));
if (byteArrayBody(t, methodName(t, method), 0) == '<') {
return makeJconstructor
(t, 0, c, parameterTypes, exceptionTypes, 0, 0, 0, 0, index);
} else {
PROTECT(t, exceptionTypes);
object name = t->m->classpath->makeString
(t, methodName(t, method), 0,
byteArrayLength(t, methodName(t, method)) - 1);
return makeJmethod
(t, 0, index, c, name, parameterTypes, exceptionTypes, returnType, 0, 0,
0, 0, 0);
}
}
object
makeField(Thread* t, object c, unsigned index)
{
PROTECT(t, c);
object field = arrayBody
(t, classFieldTable(t, jclassVmClass(t, c)), index);
PROTECT(t, field);
object type = resolveClassBySpec
(t, classLoader(t, fieldClass(t, field)),
reinterpret_cast<char*>
(&byteArrayBody(t, fieldSpec(t, field), 0)),
byteArrayLength(t, fieldSpec(t, field)) - 1);
PROTECT(t, type);
object name = t->m->classpath->makeString
(t, fieldName(t, field), 0,
byteArrayLength(t, fieldName(t, field)) - 1);
return makeJfield(t, 0, c, type, 0, 0, name, index);
}
void
initVmThread(Thread* t, object thread)
{
PROTECT(t, thread);
object field = resolveField
(t, objectClass(t, thread), "vmThread", "Ljava/lang/VMThread;");
if (fieldAtOffset<object>(thread, fieldOffset(t, field)) == 0) {
PROTECT(t, field);
2013-02-22 18:06:49 +00:00
object c = resolveClass
(t, root(t, Machine::BootLoader), "java/lang/VMThread");
PROTECT(t, c);
object instance = makeNew(t, c);
PROTECT(t, instance);
object constructor = resolveMethod
(t, c, "<init>", "(Ljava/lang/Thread;)V");
t->m->processor->invoke(t, constructor, instance, thread);
set(t, thread, fieldOffset(t, field), instance);
}
}
object
translateStackTrace(Thread* t, object raw)
{
PROTECT(t, raw);
object array = makeObjectArray
(t, resolveClass
(t, root(t, Machine::BootLoader), "java/lang/StackTraceElement"),
objectArrayLength(t, raw));
PROTECT(t, array);
for (unsigned i = 0; i < objectArrayLength(t, array); ++i) {
object e = makeStackTraceElement(t, objectArrayBody(t, raw, i));
set(t, array, ArrayBody + (i * BytesPerWord), e);
}
return array;
}
class MyClasspath : public Classpath {
public:
MyClasspath(Allocator* allocator):
allocator(allocator)
{ }
virtual object
makeJclass(Thread* t, object class_)
{
PROTECT(t, class_);
object c = allocate(t, FixedSizeOfJclass, true);
setObjectClass(t, c, type(t, Machine::JclassType));
set(t, c, JclassVmClass, class_);
return c;
}
virtual object
makeString(Thread* t, object array, int32_t offset, int32_t length)
{
if (objectClass(t, array) == type(t, Machine::ByteArrayType)) {
PROTECT(t, array);
object charArray = makeCharArray(t, length);
for (int i = 0; i < length; ++i) {
expect(t, (byteArrayBody(t, array, offset + i) & 0x80) == 0);
charArrayBody(t, charArray, i) = byteArrayBody(t, array, offset + i);
}
array = charArray;
} else {
expect(t, objectClass(t, array) == type(t, Machine::CharArrayType));
}
return vm::makeString(t, array, offset, length, 0);
}
virtual object
makeThread(Thread* t, Thread* parent)
{
const unsigned NormalPriority = 5;
2013-02-22 18:06:49 +00:00
object group = 0;
PROTECT(t, group);
if (parent) {
group = threadGroup(t, parent->javaThread);
} else {
2013-02-22 18:06:49 +00:00
resolveSystemClass
(t, root(t, Machine::BootLoader),
className(t, type(t, Machine::ThreadGroupType)), false);
2013-02-22 18:06:49 +00:00
group = makeNew(t, type(t, Machine::ThreadGroupType));
object constructor = resolveMethod
(t, type(t, Machine::ThreadGroupType), "<init>", "()V");
2013-02-21 22:37:17 +00:00
2013-02-22 18:06:49 +00:00
t->m->processor->invoke(t, constructor, group);
}
2013-02-21 22:37:17 +00:00
2013-02-22 18:06:49 +00:00
resolveSystemClass
(t, root(t, Machine::BootLoader),
className(t, type(t, Machine::ThreadType)), false);
object thread = makeNew(t, type(t, Machine::ThreadType));
PROTECT(t, thread);
2013-02-21 22:37:17 +00:00
2013-02-22 18:06:49 +00:00
object constructor = resolveMethod
(t, type(t, Machine::ThreadType), "<init>",
"(Ljava/lang/ThreadGroup;Ljava/lang/String;IZ)V");
2013-02-21 22:37:17 +00:00
2013-02-22 18:06:49 +00:00
t->m->processor->invoke
(t, constructor, thread, group, 0, NormalPriority, false);
2013-02-21 22:37:17 +00:00
set(t, thread, ThreadContextClassLoader, root(t, Machine::AppLoader));
2013-02-22 18:06:49 +00:00
initVmThread(t, thread);
return thread;
}
virtual object
2013-02-22 18:06:49 +00:00
makeJMethod(Thread* t, object vmMethod)
{
2013-02-22 18:06:49 +00:00
object table = classMethodTable(t, methodClass(t, vmMethod));
for (unsigned i = 0; i < arrayLength(t, table); ++i) {
if (vmMethod == arrayBody(t, table, i)) {
return makeMethodOrConstructor
(t, getJClass(t, methodClass(t, vmMethod)), i);
}
}
abort(t);
}
virtual object
2013-02-22 18:06:49 +00:00
getVMMethod(Thread* t, object jmethod)
{
2013-02-22 18:06:49 +00:00
return objectClass(t, jmethod) == type(t, Machine::JmethodType)
? arrayBody
(t, classMethodTable
(t, jclassVmClass(t, jmethodDeclaringClass(t, jmethod))),
jmethodSlot(t, jmethod))
: arrayBody
(t, classMethodTable
(t, jclassVmClass(t, jconstructorDeclaringClass(t, jmethod))),
jconstructorSlot(t, jmethod));
}
virtual object
2013-02-22 18:06:49 +00:00
makeJField(Thread* t, object vmField)
{
2013-02-22 18:06:49 +00:00
object table = classFieldTable(t, fieldClass(t, vmField));
for (unsigned i = 0; i < arrayLength(t, table); ++i) {
if (vmField == arrayBody(t, table, i)) {
return makeField(t, getJClass(t, fieldClass(t, vmField)), i);
}
}
abort(t);
}
virtual object
2013-02-22 18:06:49 +00:00
getVMField(Thread* t, object jfield)
{
2013-02-22 18:06:49 +00:00
return arrayBody
(t, classFieldTable
(t, jclassVmClass(t, jfieldDeclaringClass(t, jfield))),
jfieldSlot(t, jfield));
}
virtual void
clearInterrupted(Thread*)
{
// ignore
}
virtual void
runThread(Thread* t)
{
2013-02-22 18:06:49 +00:00
// force monitor creation so we don't get an OutOfMemory error
// later when we try to acquire it:
objectMonitor(t, t->javaThread, true);
THREAD_RESOURCE0(t, {
vm::acquire(t, t->javaThread);
t->flags &= ~Thread::ActiveFlag;
vm::notifyAll(t, t->javaThread);
vm::release(t, t->javaThread);
});
initVmThread(t, t->javaThread);
object method = resolveMethod
2013-02-22 18:06:49 +00:00
(t, root(t, Machine::BootLoader), "java/lang/Thread", "run", "()V");
2013-02-22 18:06:49 +00:00
t->m->processor->invoke(t, method, t->javaThread);
}
virtual void
resolveNative(Thread* t, object method)
{
vm::resolveNative(t, method);
}
virtual void
2013-02-22 21:41:24 +00:00
preBoot(Thread* t)
{
// Android's System.initSystemProperties throws an NPE if
// LD_LIBRARY_PATH is not set as of this writing:
setenv("LD_LIBRARY_PATH", "", false);
{ object c = resolveClass
2013-02-21 22:37:17 +00:00
(t, root(t, Machine::BootLoader), "java/lang/Runtime", false);
if (c) {
PROTECT(t, c);
2013-02-21 22:37:17 +00:00
intercept(t, c, "loadLibrary",
2013-02-21 22:37:17 +00:00
"(Ljava/lang/String;Ljava/lang/ClassLoader;)V",
voidPointer(loadLibrary));
}
}
{ object c = resolveClass
2013-02-21 22:37:17 +00:00
(t, root(t, Machine::BootLoader), "java/lang/ClassLoader", false);
if (c) {
PROTECT(t, c);
2013-02-21 22:37:17 +00:00
intercept(t, c, "createSystemClassLoader", "()Ljava/lang/ClassLoader;",
2013-02-21 22:37:17 +00:00
voidPointer(appLoader));
}
}
{ object c = resolveClass
(t, root(t, Machine::BootLoader), "libcore/util/ZoneInfoDB", false);
if (c) {
PROTECT(t, c);
intercept(t, c, "mapData", "()Llibcore/io/MemoryMappedFile;",
voidPointer(mapData));
}
}
{ object c = resolveClass
(t, root(t, Machine::BootLoader), "libcore/io/MemoryMappedFile",
false);
if (c) {
PROTECT(t, c);
intercept(t, c, "close", "()V", voidPointer(closeMemoryMappedFile));
}
}
2013-02-21 22:37:17 +00:00
JNI_OnLoad(reinterpret_cast< ::JavaVM*>(t->m), 0);
}
2013-02-22 21:41:24 +00:00
virtual void
boot(Thread*)
{
// ignore
}
virtual const char*
bootClasspath()
{
return AVIAN_CLASSPATH;
}
virtual void
updatePackageMap(Thread*, object)
{
// ignore
}
2013-02-21 22:37:17 +00:00
virtual object
makeDirectByteBuffer(Thread* t, void* p, jlong capacity)
{
object c = resolveClass
(t, root(t, Machine::BootLoader), "java/nio/ReadWriteDirectByteBuffer");
PROTECT(t, c);
object instance = makeNew(t, c);
PROTECT(t, instance);
object constructor = resolveMethod(t, c, "<init>", "(JI)V");
2013-02-21 22:37:17 +00:00
t->m->processor->invoke
(t, constructor, instance, reinterpret_cast<int64_t>(p),
2013-02-21 22:37:17 +00:00
static_cast<int>(capacity));
return instance;
}
virtual void*
getDirectBufferAddress(Thread* t, object b)
{
PROTECT(t, b);
object field = resolveField
(t, objectClass(t, b), "effectiveDirectAddress", "J");
2013-02-21 22:37:17 +00:00
return reinterpret_cast<void*>
(fieldAtOffset<int64_t>(b, fieldOffset(t, field)));
2013-02-21 22:37:17 +00:00
}
virtual int64_t
getDirectBufferCapacity(Thread* t, object b)
{
PROTECT(t, b);
object field = resolveField
(t, objectClass(t, b), "capacity", "I");
return fieldAtOffset<int32_t>(b, fieldOffset(t, field));
}
virtual void
dispose()
{
if (tzdata) {
tzdata->dispose();
}
allocator->free(this, sizeof(*this));
}
Allocator* allocator;
System::Region* tzdata;
};
int64_t JNICALL
mapData(Thread* t, object, uintptr_t*)
{
object c = resolveClass
(t, root(t, Machine::BootLoader), "libcore/io/MemoryMappedFile");
PROTECT(t, c);
object instance = makeNew(t, c);
PROTECT(t, instance);
object constructor = resolveMethod(t, c, "<init>", "(JJ)V");
const char* jar = "javahomeJar";
Finder* finder = getFinder(t, jar, strlen(jar));
if (finder) {
System::Region* r = finder->find("tzdata");
if (r) {
MyClasspath* cp = static_cast<MyClasspath*>(t->m->classpath);
expect(t, cp->tzdata == 0);
cp->tzdata = r;
t->m->processor->invoke
(t, constructor, instance, reinterpret_cast<int64_t>(r->start()),
static_cast<int64_t>(r->length()));
return reinterpret_cast<uintptr_t>(instance);
}
}
throwNew(t, Machine::RuntimeExceptionType);
}
void JNICALL
closeMemoryMappedFile(Thread* t, object method, uintptr_t* arguments)
{
object file = reinterpret_cast<object>(arguments[0]);
PROTECT(t, file);
MyClasspath* cp = static_cast<MyClasspath*>(t->m->classpath);
if (cp->tzdata) {
object field = resolveField(t, objectClass(t, file), "address", "J");
if (fieldAtOffset<int64_t>(file, fieldOffset(t, field))
== reinterpret_cast<int64_t>(cp->tzdata->start()))
{
cp->tzdata->dispose();
cp->tzdata = 0;
fieldAtOffset<int64_t>(file, fieldOffset(t, field)) = 0;
return;
}
}
t->m->processor->invoke
(t, nativeInterceptOriginal
(t, methodRuntimeDataNative(t, getMethodRuntimeData(t, method))),
file);
}
} // namespace local
} // namespace
namespace vm {
Classpath*
makeClasspath(System*, Allocator* allocator, const char*, const char*)
{
return new (allocator->allocate(sizeof(local::MyClasspath)))
local::MyClasspath(allocator);
}
} // namespace vm
extern "C" int
jniRegisterNativeMethods(JNIEnv* e, const char* className,
const JNINativeMethod* methods, int methodCount)
{
jclass c = e->vtable->FindClass(e, className);
if (c) {
e->vtable->RegisterNatives(e, c, methods, methodCount);
} else {
e->vtable->ExceptionClear(e);
}
return 0;
}
extern "C" void
jniLogException(JNIEnv*, int, const char*, jthrowable)
{
// ignore
}
extern "C" int
jniThrowException(JNIEnv* e, const char* className, const char* message)
{
jclass c = e->vtable->FindClass(e, className);
if (c) {
e->vtable->ThrowNew(e, c, message);
}
return 0;
}
extern "C" int
jniThrowExceptionFmt(JNIEnv* e, const char* className, const char* format,
va_list args)
{
const unsigned size = 4096;
char buffer[size];
::vsnprintf(buffer, size, format, args);
return jniThrowException(e, className, buffer);
}
extern "C" int
jniThrowNullPointerException(JNIEnv* e, const char* message)
{
return jniThrowException(e, "java/lang/NullPointerException", message);
}
extern "C" int
jniThrowRuntimeException(JNIEnv* e, const char* message)
{
return jniThrowException(e, "java/lang/RuntimeException", message);
}
extern "C" int
jniThrowIOException(JNIEnv* e, const char* message)
{
return jniThrowException(e, "java/lang/IOException", message);
}
extern "C" const char*
jniStrError(int error, char* buffer, size_t length)
{
if (static_cast<int>(strerror_r(error, buffer, length)) == 0) {
return buffer;
} else {
return 0;
}
}
extern "C" int
__android_log_print(int priority, const char* tag, const char* format, ...)
{
va_list a;
const unsigned size = 4096;
char buffer[size];
va_start(a, format);
::vsnprintf(buffer, size, format, a);
va_end(a);
return fprintf(stderr, "%d %s %s\n", priority, tag, buffer);
}
extern "C" int
jniGetFDFromFileDescriptor(JNIEnv* e, jobject descriptor)
{
return e->vtable->GetIntField
(e, descriptor, e->vtable->GetFieldID
(e, e->vtable->FindClass
(e, "java/io/FileDescriptor"), "descriptor", "I"));
}
extern "C" void
jniSetFileDescriptorOfFD(JNIEnv* e, jobject descriptor, int value)
{
e->vtable->SetIntField
(e, descriptor, e->vtable->GetFieldID
(e, e->vtable->FindClass
(e, "java/io/FileDescriptor"), "descriptor", "I"), value);
}
extern "C" jobject
jniCreateFileDescriptor(JNIEnv* e, int fd)
{
jobject descriptor = e->vtable->NewObject
(e, e->vtable->FindClass(e, "java/io/FileDescriptor"),
e->vtable->GetMethodID
(e, e->vtable->FindClass(e, "java/io/FileDescriptor"), "<init>", "()V"));
jniSetFileDescriptorOfFD(e, descriptor, fd);
return descriptor;
}
struct _JNIEnv;
int
register_org_apache_harmony_dalvik_NativeTestTarget(_JNIEnv*)
{
// ignore
return 0;
}
2013-02-22 18:06:49 +00:00
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_String_compareTo
(Thread* t, object, uintptr_t* arguments)
{
object a = reinterpret_cast<object>(arguments[0]);
object b = reinterpret_cast<object>(arguments[1]);
unsigned length = stringLength(t, a);
if (length > stringLength(t, b)) {
length = stringLength(t, b);
}
for (unsigned i = 0; i < length; ++i) {
int d = stringCharAt(t, a, i) - stringCharAt(t, b, i);
if (d) {
return d;
}
}
return stringLength(t, a) - stringLength(t, b);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_String_isEmpty
(Thread* t, object, uintptr_t* arguments)
{
return stringLength(t, reinterpret_cast<object>(arguments[0])) == 0;
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_String_length
(Thread* t, object, uintptr_t* arguments)
{
return stringLength(t, reinterpret_cast<object>(arguments[0]));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_String_charAt
(Thread* t, object, uintptr_t* arguments)
{
return stringCharAt(t, reinterpret_cast<object>(arguments[0]), arguments[1]);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_String_equals
(Thread* t, object, uintptr_t* arguments)
{
return arguments[1] and stringEqual
(t, reinterpret_cast<object>(arguments[0]),
reinterpret_cast<object>(arguments[1]));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_String_fastIndexOf
(Thread* t, object, uintptr_t* arguments)
{
object s = reinterpret_cast<object>(arguments[0]);
unsigned c = arguments[1];
unsigned start = arguments[2];
for (unsigned i = start; i < stringLength(t, s); ++i) {
if (stringCharAt(t, s, i) == c) {
return i;
}
}
return -1;
}
2013-02-22 18:06:49 +00:00
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Class_getInterfaces
(Thread* t, object, uintptr_t* arguments)
{
object c = reinterpret_cast<object>(arguments[0]);
object addendum = classAddendum(t, jclassVmClass(t, c));
if (addendum) {
object table = classAddendumInterfaceTable(t, addendum);
if (table) {
PROTECT(t, table);
object array = makeObjectArray(t, arrayLength(t, table));
PROTECT(t, array);
for (unsigned i = 0; i < arrayLength(t, table); ++i) {
object c = getJClass(t, arrayBody(t, table, i));
set(t, array, ArrayBody + (i * BytesPerWord), c);
}
return reinterpret_cast<uintptr_t>(array);
}
}
return reinterpret_cast<uintptr_t>
(makeObjectArray(t, type(t, Machine::JclassType), 0));
}
2013-02-21 22:37:17 +00:00
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Class_newInstanceImpl
(Thread* t, object, uintptr_t* arguments)
{
object c = jclassVmClass(t, reinterpret_cast<object>(arguments[0]));
object method = resolveMethod(t, c, "<init>", "()V");
PROTECT(t, method);
object instance = makeNew(t, c);
PROTECT(t, instance);
t->m->processor->invoke(t, method, instance);
return reinterpret_cast<uintptr_t>(instance);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Class_getComponentType
(Thread* t, object, uintptr_t* arguments)
{
object c = reinterpret_cast<object>(arguments[0]);
if (classArrayDimensions(t, jclassVmClass(t, c))) {
uint8_t n = byteArrayBody(t, className(t, jclassVmClass(t, c)), 1);
if (n != 'L' and n != '[') {
return reinterpret_cast<uintptr_t>
(getJClass(t, primitiveClass(t, n)));
} else {
return reinterpret_cast<uintptr_t>
(getJClass(t, classStaticTable(t, jclassVmClass(t, c))));
}
} else {
return 0;
}
}
2013-02-21 22:37:17 +00:00
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Class_classForName
(Thread* t, object, uintptr_t* arguments)
{
object name = reinterpret_cast<object>(arguments[0]);
PROTECT(t, name);
object loader = reinterpret_cast<object>(arguments[2]);
PROTECT(t, loader);
object method = resolveMethod
(t, root(t, Machine::BootLoader), "avian/Classes", "forName",
"(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;");
return reinterpret_cast<uintptr_t>
(t->m->processor->invoke
(t, method, 0, name, static_cast<int>(arguments[1]), loader));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Class_getDeclaredField
(Thread* t, object, uintptr_t* arguments)
{
object c = reinterpret_cast<object>(arguments[0]);
PROTECT(t, c);
object name = reinterpret_cast<object>(arguments[1]);
PROTECT(t, name);
object method = resolveMethod
2013-02-21 22:37:17 +00:00
(t, root(t, Machine::BootLoader), "avian/Classes", "findField",
"(Lavian/VMClass;Ljava/lang/String;)I");
2013-02-21 22:37:17 +00:00
int index = intValue
(t, t->m->processor->invoke
(t, method, 0, jclassVmClass(t, c), name));
if (index >= 0) {
2013-02-22 18:06:49 +00:00
return reinterpret_cast<uintptr_t>(local::makeField(t, c, index));
} else {
return 0;
}
}
2013-02-21 22:37:17 +00:00
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Class_getDeclaredConstructorOrMethod
(Thread* t, object, uintptr_t* arguments)
{
object c = reinterpret_cast<object>(arguments[0]);
PROTECT(t, c);
object name = reinterpret_cast<object>(arguments[1]);
PROTECT(t, name);
object parameterTypes = reinterpret_cast<object>(arguments[2]);
PROTECT(t, parameterTypes);
object method = resolveMethod
(t, root(t, Machine::BootLoader), "avian/Classes", "findMethod",
"(Lavian/VMClass;Ljava/lang/String;[Ljava/lang/Class;)I");
int index = intValue
(t, t->m->processor->invoke
(t, method, 0, jclassVmClass(t, c), name, parameterTypes));
if (index >= 0) {
return reinterpret_cast<uintptr_t>
(local::makeMethodOrConstructor(t, c, index));
} else {
return 0;
}
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_findLoadedVMClass
(Thread*, object, uintptr_t*);
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_VMClassLoader_findLoadedClass
(Thread* t, object method, uintptr_t* arguments)
{
int64_t v = Avian_avian_SystemClassLoader_findLoadedVMClass
(t, method, arguments);
if (v) {
return reinterpret_cast<uintptr_t>
(getJClass(t, reinterpret_cast<object>(v)));
} else {
return 0;
}
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_Classes_defineVMClass
(Thread*, object, uintptr_t*);
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_VMClassLoader_defineClass__Ljava_lang_ClassLoader_2Ljava_lang_String_2_3BII
(Thread* t, object method, uintptr_t* arguments)
{
uintptr_t args[]
= { arguments[0], arguments[2], arguments[3], arguments[4] };
int64_t v = Avian_avian_Classes_defineVMClass(t, method, args);
if (v) {
return reinterpret_cast<uintptr_t>
(getJClass(t, reinterpret_cast<object>(v)));
} else {
return 0;
}
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_dalvik_system_VMRuntime_bootClassPath
(Thread* t, object, uintptr_t*)
{
return reinterpret_cast<uintptr_t>(root(t, Machine::BootLoader));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_dalvik_system_VMRuntime_classPath
(Thread* t, object, uintptr_t*)
{
return reinterpret_cast<uintptr_t>(root(t, Machine::AppLoader));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_dalvik_system_VMRuntime_vmVersion
(Thread* t, object, uintptr_t*)
{
return reinterpret_cast<uintptr_t>(makeString(t, "%s", AVIAN_VERSION));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_dalvik_system_VMRuntime_properties
(Thread* t, object, uintptr_t*)
{
object array = makeObjectArray(t, type(t, Machine::StringType), 1);
PROTECT(t, array);
object property = makeString(t, "java.protocol.handler.pkgs=avian");
set(t, array, ArrayBody, property);
return reinterpret_cast<uintptr_t>(array);
}
2013-02-22 18:06:49 +00:00
extern "C" JNIEXPORT void JNICALL
Avian_java_lang_Runtime_gc
(Thread* t, object, uintptr_t*)
{
collect(t, Heap::MajorCollection);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Runtime_nativeLoad
(Thread* t, object, uintptr_t* arguments)
{
object name = reinterpret_cast<object>(arguments[0]);
PROTECT(t, name);
unsigned length = stringLength(t, name);
THREAD_RUNTIME_ARRAY(t, char, n, length + 1);
stringChars(t, name, RUNTIME_ARRAY_BODY(n));
if (loadLibrary(t, "", RUNTIME_ARRAY_BODY(n), false, true)) {
return 0;
} else {
return reinterpret_cast<uintptr_t>(name);
}
}
extern "C" JNIEXPORT void JNICALL
Avian_java_lang_System_arraycopy
(Thread* t, object, uintptr_t* arguments)
{
arrayCopy(t, reinterpret_cast<object>(arguments[0]),
arguments[1],
reinterpret_cast<object>(arguments[2]),
arguments[3],
arguments[4]);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_sun_misc_Unsafe_objectFieldOffset
(Thread* t, object, uintptr_t* arguments)
{
object jfield = reinterpret_cast<object>(arguments[1]);
return fieldOffset
(t, arrayBody
(t, classFieldTable
(t, jclassVmClass(t, jfieldDeclaringClass(t, jfield))),
jfieldSlot(t, jfield)));
}
2013-02-22 18:06:49 +00:00
extern "C" JNIEXPORT void JNICALL
Avian_java_lang_VMThread_interrupt
(Thread* t, object, uintptr_t* arguments)
{
object vmThread = reinterpret_cast<object>(arguments[0]);
PROTECT(t, vmThread);
object field = resolveField
(t, objectClass(t, vmThread), "thread", "Ljava/lang/Thread;");
interrupt
(t, reinterpret_cast<Thread*>
(threadPeer(t, fieldAtOffset<object>(vmThread, fieldOffset(t, field)))));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_VMThread_interrupted
(Thread* t, object, uintptr_t*)
{
return getAndClearInterrupted(t, t);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_VMThread_isInterrupted
(Thread* t, object, uintptr_t* arguments)
{
object vmThread = reinterpret_cast<object>(arguments[0]);
PROTECT(t, vmThread);
object field = resolveField
(t, objectClass(t, vmThread), "thread", "Ljava/lang/Thread;");
return threadInterrupted
(t, fieldAtOffset<object>(vmThread, fieldOffset(t, field)));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_VMThread_getStatus
(Thread*, object, uintptr_t*)
{
// todo
return -1;
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_VMThread_currentThread
(Thread* t, object, uintptr_t*)
{
return reinterpret_cast<uintptr_t>(t->javaThread);
}
2013-02-21 22:37:17 +00:00
2013-02-22 18:06:49 +00:00
extern "C" JNIEXPORT void JNICALL
Avian_java_lang_VMThread_create
(Thread* t, object, uintptr_t* arguments)
{
startThread(t, reinterpret_cast<object>(arguments[0]));
}
extern "C" JNIEXPORT void JNICALL
Avian_java_lang_VMThread_sleep
(Thread* t, object, uintptr_t* arguments)
{
int64_t milliseconds; memcpy(&milliseconds, arguments, 8);
if (arguments[2] > 0) ++ milliseconds;
if (milliseconds <= 0) milliseconds = 1;
if (threadSleepLock(t, t->javaThread) == 0) {
object lock = makeJobject(t);
set(t, t->javaThread, ThreadSleepLock, lock);
}
acquire(t, threadSleepLock(t, t->javaThread));
vm::wait(t, threadSleepLock(t, t->javaThread), milliseconds);
release(t, threadSleepLock(t, t->javaThread));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_dalvik_system_VMStack_getThreadStackTrace
(Thread* t, object, uintptr_t* arguments)
{
Thread* p = reinterpret_cast<Thread*>
(threadPeer(t, reinterpret_cast<object>(arguments[0])));
return reinterpret_cast<uintptr_t>
(local::translateStackTrace
(t, p == t
? makeTrace(t)
: t->m->processor->getStackTrace(t, p)));
}
2013-02-21 22:37:17 +00:00
extern "C" JNIEXPORT int64_t JNICALL
Avian_dalvik_system_VMStack_getCallingClassLoader
(Thread* t, object, uintptr_t*)
{
class Visitor: public Processor::StackVisitor {
public:
Visitor(Thread* t):
t(t), loader(0), counter(2)
{ }
virtual bool visit(Processor::StackWalker* walker) {
if (counter--) {
return true;
} else {
this->loader = classLoader(t, methodClass(t, walker->method()));
return false;
}
}
Thread* t;
object loader;
unsigned counter;
} v(t);
t->m->processor->walkStack(t, &v);
return reinterpret_cast<uintptr_t>(v.loader);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Math_min
(Thread*, object, uintptr_t* arguments)
{
return min(static_cast<int>(arguments[0]), static_cast<int>(arguments[1]));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Math_max
(Thread*, object, uintptr_t* arguments)
{
return max(static_cast<int>(arguments[0]), static_cast<int>(arguments[1]));
}
2013-02-22 18:06:49 +00:00
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Math_cos
2013-02-22 18:06:49 +00:00
(Thread*, object, uintptr_t* arguments)
{
int64_t v; memcpy(&v, arguments, 8);
return doubleToBits(cos(bitsToDouble(v)));
2013-02-22 18:06:49 +00:00
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Math_sin
(Thread*, object, uintptr_t* arguments)
{
int64_t v; memcpy(&v, arguments, 8);
return doubleToBits(sin(bitsToDouble(v)));
}
2013-02-22 18:06:49 +00:00
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Float_intBitsToFloat
(Thread*, object, uintptr_t* arguments)
{
return arguments[0];
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Float_floatToIntBits
(Thread*, object, uintptr_t* arguments)
{
if (((arguments[0] & 0x7F800000) == 0x7F800000)
and ((arguments[0] & 0x007FFFFF) != 0))
{
return 0x7fc00000;
} else {
return arguments[0];
}
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Double_doubleToRawLongBits
(Thread*, object, uintptr_t* arguments)
{
int64_t v; memcpy(&v, arguments, 8);
// todo: do we need to do NaN checks as in
// Avian_java_lang_Float_floatToIntBits above? If so, update
// Double.doubleToRawLongBits in the Avian class library too.
return v;
}
2013-02-22 18:06:49 +00:00
extern "C" JNIEXPORT void JNICALL
Avian_java_lang_Object_wait
(Thread* t, object, uintptr_t* arguments)
{
jlong milliseconds; memcpy(&milliseconds, arguments + 1, sizeof(jlong));
wait(t, reinterpret_cast<object>(arguments[0]), milliseconds);
}
extern "C" JNIEXPORT void JNICALL
Avian_java_lang_Object_notifyAll
(Thread* t, object, uintptr_t* arguments)
{
notifyAll(t, reinterpret_cast<object>(arguments[0]));
}
2013-02-21 22:37:17 +00:00
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Object_getClass
(Thread* t, object, uintptr_t* arguments)
{
return reinterpret_cast<uintptr_t>
(getJClass(t, objectClass(t, reinterpret_cast<object>(arguments[0]))));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Object_hashCode
(Thread* t, object, uintptr_t* arguments)
{
return objectHash(t, reinterpret_cast<object>(arguments[0]));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Object_internalClone
(Thread* t, object, uintptr_t* arguments)
{
return reinterpret_cast<uintptr_t>
(clone(t, reinterpret_cast<object>(arguments[1])));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Class_getModifiers
(Thread* t, object, uintptr_t* arguments)
{
return classFlags
(t, jclassVmClass(t, reinterpret_cast<object>(arguments[0])));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Class_getSuperclass
(Thread* t, object, uintptr_t* arguments)
{
object c = jclassVmClass(t, reinterpret_cast<object>(arguments[0]));
if (classFlags(t, c) & ACC_INTERFACE) {
return 0;
} else {
object s = classSuper(t, c);
return s ? reinterpret_cast<uintptr_t>(getJClass(t, s)) : 0;
}
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Class_desiredAssertionStatus
(Thread*, object, uintptr_t*)
{
return 1;
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Class_getNameNative
(Thread* t, object, uintptr_t* arguments)
{
object name = className
(t, jclassVmClass(t, reinterpret_cast<object>(arguments[0])));
THREAD_RUNTIME_ARRAY(t, char, s, byteArrayLength(t, name));
replace('/', '.', RUNTIME_ARRAY_BODY(s),
reinterpret_cast<char*>(&byteArrayBody(t, name, 0)));
2013-02-21 22:37:17 +00:00
return reinterpret_cast<uintptr_t>
(makeString(t, "%s", RUNTIME_ARRAY_BODY(s)));
2013-02-21 22:37:17 +00:00
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Class_isInterface
(Thread* t, object, uintptr_t* arguments)
{
return (classFlags
(t, jclassVmClass(t, reinterpret_cast<object>(arguments[0])))
& ACC_INTERFACE) != 0;
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Class_isPrimitive
(Thread* t, object, uintptr_t* arguments)
{
return (classVmFlags
(t, jclassVmClass(t, reinterpret_cast<object>(arguments[0])))
& PrimitiveFlag) != 0;
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Class_getClassLoader
(Thread* t, object, uintptr_t* arguments)
{
return reinterpret_cast<uintptr_t>
(classLoader
(t, jclassVmClass(t, reinterpret_cast<object>(arguments[0]))));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Class_isAssignableFrom
(Thread* t, object, uintptr_t* arguments)
{
object this_ = reinterpret_cast<object>(arguments[0]);
object that = reinterpret_cast<object>(arguments[1]);
if (LIKELY(that)) {
2013-02-22 18:06:49 +00:00
return isAssignableFrom
2013-02-21 22:37:17 +00:00
(t, jclassVmClass(t, this_), jclassVmClass(t, that));
} else {
throwNew(t, Machine::NullPointerExceptionType);
}
}
2013-02-22 18:06:49 +00:00
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Class_isInstance
(Thread* t, object, uintptr_t* arguments)
{
object this_ = reinterpret_cast<object>(arguments[0]);
object o = reinterpret_cast<object>(arguments[1]);
if (o) {
return instanceOf(t, jclassVmClass(t, this_), o);
} else {
return 0;
}
}
2013-02-21 22:37:17 +00:00
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_reflect_Method_invokeNative
(Thread* t, object, uintptr_t* arguments)
{
object instance = reinterpret_cast<object>(arguments[1]);
object args = reinterpret_cast<object>(arguments[2]);
object method = arrayBody
(t, classMethodTable
(t, jclassVmClass(t, reinterpret_cast<object>(arguments[3]))),
arguments[6]);
return reinterpret_cast<uintptr_t>(invoke(t, method, instance, args));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_reflect_Method_getMethodModifiers
(Thread* t, object, uintptr_t* arguments)
{
return methodFlags
(t, arrayBody
(t, classMethodTable
(t, jclassVmClass(t, reinterpret_cast<object>(arguments[0]))),
arguments[1]));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_reflect_Method_isAnnotationPresent
(Thread* t, object, uintptr_t* arguments)
{
object method = arrayBody
(t, classMethodTable
(t, jclassVmClass(t, reinterpret_cast<object>(arguments[0]))),
arguments[1]);
object addendum = methodAddendum(t, method);
if (addendum) {
object table = addendumAnnotationTable(t, addendum);
if (table) {
for (unsigned i = 0; i < objectArrayLength(t, table); ++i) {
if (objectArrayBody(t, objectArrayBody(t, table, i), 1)
== reinterpret_cast<object>(arguments[2]))
{
return true;
}
}
}
}
return false;
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_reflect_Method_getAnnotation
(Thread* t, object, uintptr_t* arguments)
{
object method = arrayBody
(t, classMethodTable
(t, jclassVmClass(t, reinterpret_cast<object>(arguments[0]))),
arguments[1]);
object addendum = methodAddendum(t, method);
if (addendum) {
object table = addendumAnnotationTable(t, addendum);
if (table) {
for (unsigned i = 0; i < objectArrayLength(t, table); ++i) {
if (objectArrayBody(t, objectArrayBody(t, table, i), 1)
== reinterpret_cast<object>(arguments[2]))
{
PROTECT(t, method);
PROTECT(t, table);
object get = resolveMethod
(t, root(t, Machine::BootLoader), "avian/Classes", "getAnnotation",
"(Ljava/lang/ClassLoader;[Ljava/lang/Object;)"
"Ljava/lang/annotation/Annotation;");
return reinterpret_cast<uintptr_t>
(t->m->processor->invoke
(t, get, 0, classLoader(t, methodClass(t, method)),
objectArrayBody(t, table, i)));
}
}
}
}
return false;
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_reflect_Method_getDeclaredAnnotations
(Thread* t, object, uintptr_t* arguments)
{
object method = arrayBody
(t, classMethodTable
(t, jclassVmClass(t, reinterpret_cast<object>(arguments[0]))),
arguments[1]);
object addendum = methodAddendum(t, method);
if (addendum) {
object table = addendumAnnotationTable(t, addendum);
if (table) {
PROTECT(t, method);
PROTECT(t, table);
object array = makeObjectArray
(t, resolveClass
(t, root(t, Machine::BootLoader), "java/lang/annotation/Annotation"),
objectArrayLength(t, table));
PROTECT(t, array);
object get = resolveMethod
(t, root(t, Machine::BootLoader), "avian/Classes", "getAnnotation",
"(Ljava/lang/ClassLoader;[Ljava/lang/Object;)"
"Ljava/lang/annotation/Annotation;");
PROTECT(t, get);
for (unsigned i = 0; i < objectArrayLength(t, table); ++i) {
object a = t->m->processor->invoke
(t, get, 0, classLoader(t, methodClass(t, method)),
objectArrayBody(t, table, i));
set(t, array, ArrayBody + (i * BytesPerWord), a);
}
return reinterpret_cast<uintptr_t>(array);
}
}
return reinterpret_cast<uintptr_t>
(makeObjectArray
(t, resolveClass
(t, root(t, Machine::BootLoader), "java/lang/annotation/Annotation"),
0));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_reflect_Constructor_constructNative
(Thread* t, object, uintptr_t* arguments)
{
object args = reinterpret_cast<object>(arguments[1]);
PROTECT(t, args);
object c = jclassVmClass(t, reinterpret_cast<object>(arguments[2]));
object method = arrayBody(t, classMethodTable(t, c), arguments[4]);
PROTECT(t, method);
object instance = makeNew(t, c);
PROTECT(t, instance);
t->m->processor->invokeArray(t, method, instance, args);
return reinterpret_cast<uintptr_t>(instance);
}
2013-02-22 18:06:49 +00:00
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_reflect_Field_getField
(Thread* t, object, uintptr_t* arguments)
{
object field = arrayBody
(t, classFieldTable
(t, jclassVmClass(t, reinterpret_cast<object>(arguments[2]))),
arguments[4]);
if (fieldFlags(t, field) & ACC_STATIC) {
return reinterpret_cast<uintptr_t>
(fieldAtOffset<object>
(classStaticTable(t, fieldClass(t, field)), fieldOffset(t, field)));
} else {
return reinterpret_cast<uintptr_t>
(fieldAtOffset<object>
(reinterpret_cast<object>(arguments[1]), fieldOffset(t, field)));
}
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_reflect_Field_getFieldModifiers
(Thread* t, object, uintptr_t* arguments)
{
return fieldFlags
(t, arrayBody
(t, classFieldTable
(t, jclassVmClass(t, reinterpret_cast<object>(arguments[1]))),
arguments[2]));
}
2013-02-21 22:37:17 +00:00
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Throwable_nativeFillInStackTrace
(Thread* t, object, uintptr_t*)
{
return reinterpret_cast<uintptr_t>(getTrace(t, 2));
}
2013-02-22 18:06:49 +00:00
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Throwable_nativeGetStackTrace
(Thread* t, object, uintptr_t* arguments)
{
return reinterpret_cast<uintptr_t>
(local::translateStackTrace(t, reinterpret_cast<object>(arguments[0])));
}
2013-02-21 22:37:17 +00:00
extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_Classes_makeMethod
(Thread* t, object, uintptr_t* arguments)
{
return reinterpret_cast<uintptr_t>
(local::makeMethodOrConstructor
(t, reinterpret_cast<object>(arguments[0]), arguments[1]));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_reflect_Array_createObjectArray
(Thread* t, object, uintptr_t* arguments)
{
return reinterpret_cast<uintptr_t>
(makeObjectArray
(t, jclassVmClass(t, reinterpret_cast<object>(arguments[0])),
arguments[1]));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_nio_ByteOrder_isLittleEndian
(Thread*, object, uintptr_t*)
{
#ifdef ARCH_powerpc
return false;
#else
return true;
#endif
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_dalvik_system_VMRuntime_newNonMovableArray
(Thread* t, object, uintptr_t* arguments)
{
if (jclassVmClass(t, reinterpret_cast<object>(arguments[1]))
== type(t, Machine::JbyteType))
{
object array = allocate3
(t, t->m->heap, Machine::FixedAllocation,
ArrayBody + arguments[2], false);
setObjectClass(t, array, type(t, Machine::ByteArrayType));
byteArrayLength(t, array) = arguments[2];
return reinterpret_cast<intptr_t>(array);
} else {
// todo
abort(t);
}
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_dalvik_system_VMRuntime_addressOf
(Thread*, object, uintptr_t* arguments)
{
return arguments[1] + ArrayBody;
}
extern "C" JNIEXPORT void JNICALL
Avian_libcore_io_Memory_pokeLong
(Thread*, object, uintptr_t* arguments)
{
int64_t address; memcpy(&address, arguments, 8);
int64_t v; memcpy(&v, arguments + 2, 8);
if (arguments[4]) {
2013-02-21 22:37:17 +00:00
v = swapV8(v);
}
memcpy(reinterpret_cast<void*>(address), &v, 8);
2013-02-21 22:37:17 +00:00
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_libcore_io_Memory_peekLong
(Thread*, object, uintptr_t* arguments)
{
int64_t address; memcpy(&address, arguments, 8);
int64_t v; memcpy(&v, reinterpret_cast<void*>(address), 8);
return arguments[2] ? swapV8(v) : v;
2013-02-21 22:37:17 +00:00
}
extern "C" JNIEXPORT void JNICALL
Avian_libcore_io_Memory_pokeInt
(Thread*, object, uintptr_t* arguments)
{
int64_t address; memcpy(&address, arguments, 8);
int32_t v = arguments[3] ? swapV4(arguments[2]) : arguments[2];
memcpy(reinterpret_cast<void*>(address), &v, 4);
2013-02-21 22:37:17 +00:00
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_libcore_io_Memory_peekInt
(Thread*, object, uintptr_t* arguments)
{
int64_t address; memcpy(&address, arguments, 8);
int32_t v; memcpy(&v, reinterpret_cast<void*>(address), 4);
return arguments[2] ? swapV4(v) : v;
2013-02-21 22:37:17 +00:00
}
extern "C" JNIEXPORT void JNICALL
Avian_libcore_io_Memory_pokeShort
(Thread*, object, uintptr_t* arguments)
{
int64_t address; memcpy(&address, arguments, 8);
int16_t v = arguments[3] ? swapV2(arguments[2]) : arguments[2];
memcpy(reinterpret_cast<void*>(address), &v, 2);
2013-02-21 22:37:17 +00:00
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_libcore_io_Memory_peekShort
(Thread*, object, uintptr_t* arguments)
{
int64_t address; memcpy(&address, arguments, 8);
int16_t v; memcpy(&v, reinterpret_cast<void*>(address), 2);
return arguments[2] ? swapV2(v) : v;
2013-02-21 22:37:17 +00:00
}
extern "C" JNIEXPORT void JNICALL
Avian_libcore_io_Memory_pokeByte
(Thread*, object, uintptr_t* arguments)
{
int64_t address; memcpy(&address, arguments, 8);
*reinterpret_cast<int8_t*>(address) = arguments[2];
2013-02-21 22:37:17 +00:00
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_libcore_io_Memory_peekByte
(Thread*, object, uintptr_t* arguments)
{
int64_t address; memcpy(&address, arguments, 8);
return *reinterpret_cast<int8_t*>(address);
}
2013-02-21 22:37:17 +00:00
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_System_nanoTime
(Thread* t, object, uintptr_t*)
{
return t->m->system->now() * 1000 * 1000;
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_System_currentTimeMillis
(Thread* t, object, uintptr_t*)
{
return t->m->system->now();
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_System_identityHashCode
(Thread* t, object, uintptr_t* arguments)
{
return objectHash(t, reinterpret_cast<object>(arguments[0]));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_System_mapLibraryName
(Thread* t, object, uintptr_t* arguments)
{
object original = reinterpret_cast<object>(arguments[0]);
unsigned originalLength = stringUTFLength(t, original);
THREAD_RUNTIME_ARRAY(t, char, originalChars, originalLength);
stringUTFChars
(t, original, RUNTIME_ARRAY_BODY(originalChars), originalLength);
return reinterpret_cast<uintptr_t>
(makeString(t, "%s%.*s%s", t->m->system->libraryPrefix(), originalLength,
RUNTIME_ARRAY_BODY(originalChars),
t->m->system->librarySuffix()));
}