2010-12-06 03:21:09 +00:00
|
|
|
/* Copyright (c) 2008-2010 Avian Contributors
|
2008-02-19 18:06:52 +00:00
|
|
|
|
|
|
|
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. */
|
|
|
|
|
2007-07-06 23:50:26 +00:00
|
|
|
#include "jnienv.h"
|
|
|
|
#include "machine.h"
|
2007-11-26 23:15:53 +00:00
|
|
|
#include "util.h"
|
2007-09-24 01:39:03 +00:00
|
|
|
#include "processor.h"
|
2007-09-07 23:20:21 +00:00
|
|
|
#include "constants.h"
|
2007-10-25 15:04:13 +00:00
|
|
|
|
2007-07-27 00:06:05 +00:00
|
|
|
using namespace vm;
|
2007-07-20 14:36:31 +00:00
|
|
|
|
2007-07-27 00:06:05 +00:00
|
|
|
namespace {
|
2007-07-06 15:24:06 +00:00
|
|
|
|
2010-04-15 17:11:10 +00:00
|
|
|
namespace local {
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
const uintptr_t InterfaceMethodID
|
|
|
|
= (static_cast<uintptr_t>(1) << (BitsPerWord - 1));
|
|
|
|
|
2007-11-04 21:15:28 +00:00
|
|
|
const uintptr_t NonVirtualMethodID
|
|
|
|
= (static_cast<uintptr_t>(1) << (BitsPerWord - 2));
|
|
|
|
|
2007-09-10 23:33:58 +00:00
|
|
|
jint JNICALL
|
|
|
|
AttachCurrentThread(Machine* m, Thread** t, void*)
|
|
|
|
{
|
|
|
|
*t = static_cast<Thread*>(m->localThread->get());
|
|
|
|
if (*t == 0) {
|
avoid inifinite recursion if java.lang.Object is missing; refactoring
When trying to create an array class, we try to resolve
java.lang.Object so we can use its vtable in the array class.
However, if Object is missing, we'll try to create and throw a
ClassNotFoundException, which requires creating an array to store the
stack trace, which requires creating an array class, which requires
resolving Object, etc.. This commit short-circuits this process by
telling resolveClass not to create and throw an exception if it can't
find Object.
While doing the above work, I noticed that the implementations of
Classpath::makeThrowable in classpath-avian.cpp and
classpath-openjdk.cpp were identical, so I made makeThrowable a
top-level function.
Finally, I discovered that Thread.setDaemon can only be called before
the target thread has been started, which allowed me to simplify the
code to track daemon threads in the VM.
2010-12-10 02:38:12 +00:00
|
|
|
*t = attachThread(m, false);
|
2007-09-10 23:33:58 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-11-03 21:52:14 +00:00
|
|
|
jint JNICALL
|
avoid inifinite recursion if java.lang.Object is missing; refactoring
When trying to create an array class, we try to resolve
java.lang.Object so we can use its vtable in the array class.
However, if Object is missing, we'll try to create and throw a
ClassNotFoundException, which requires creating an array to store the
stack trace, which requires creating an array class, which requires
resolving Object, etc.. This commit short-circuits this process by
telling resolveClass not to create and throw an exception if it can't
find Object.
While doing the above work, I noticed that the implementations of
Classpath::makeThrowable in classpath-avian.cpp and
classpath-openjdk.cpp were identical, so I made makeThrowable a
top-level function.
Finally, I discovered that Thread.setDaemon can only be called before
the target thread has been started, which allowed me to simplify the
code to track daemon threads in the VM.
2010-12-10 02:38:12 +00:00
|
|
|
AttachCurrentThreadAsDaemon(Machine* m, Thread** t, void*)
|
2009-11-03 21:52:14 +00:00
|
|
|
{
|
|
|
|
*t = static_cast<Thread*>(m->localThread->get());
|
|
|
|
if (*t == 0) {
|
avoid inifinite recursion if java.lang.Object is missing; refactoring
When trying to create an array class, we try to resolve
java.lang.Object so we can use its vtable in the array class.
However, if Object is missing, we'll try to create and throw a
ClassNotFoundException, which requires creating an array to store the
stack trace, which requires creating an array class, which requires
resolving Object, etc.. This commit short-circuits this process by
telling resolveClass not to create and throw an exception if it can't
find Object.
While doing the above work, I noticed that the implementations of
Classpath::makeThrowable in classpath-avian.cpp and
classpath-openjdk.cpp were identical, so I made makeThrowable a
top-level function.
Finally, I discovered that Thread.setDaemon can only be called before
the target thread has been started, which allowed me to simplify the
code to track daemon threads in the VM.
2010-12-10 02:38:12 +00:00
|
|
|
*t = attachThread(m, true);
|
2009-11-03 21:52:14 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-09-10 23:33:58 +00:00
|
|
|
jint JNICALL
|
|
|
|
DetachCurrentThread(Machine* m)
|
|
|
|
{
|
|
|
|
Thread* t = static_cast<Thread*>(m->localThread->get());
|
|
|
|
if (t) {
|
2009-08-18 21:29:25 +00:00
|
|
|
expect(t, t != m->rootThread);
|
|
|
|
|
2009-08-18 20:26:28 +00:00
|
|
|
m->localThread->set(0);
|
2009-08-18 21:29:25 +00:00
|
|
|
|
|
|
|
ACQUIRE_RAW(t, t->m->stateLock);
|
|
|
|
|
|
|
|
enter(t, Thread::ActiveState);
|
2009-08-20 14:49:01 +00:00
|
|
|
|
|
|
|
threadPeer(t, t->javaThread) = 0;
|
|
|
|
|
2009-08-18 21:29:25 +00:00
|
|
|
enter(t, Thread::ZombieState);
|
|
|
|
|
|
|
|
t->state = Thread::JoinedState;
|
|
|
|
|
2007-09-10 23:33:58 +00:00
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
uint64_t
|
|
|
|
destroyJavaVM(Thread* t, uintptr_t*)
|
2009-08-19 20:27:03 +00:00
|
|
|
{
|
|
|
|
// wait for other non-daemon threads to exit
|
|
|
|
{ ACQUIRE(t, t->m->stateLock);
|
|
|
|
while (t->m->liveCount - t->m->daemonCount > 1) {
|
|
|
|
t->m->stateLock->wait(t->systemThread, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
shutDown(t);
|
2009-08-19 20:27:03 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2009-08-19 20:27:03 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
jint JNICALL
|
|
|
|
DestroyJavaVM(Machine* m)
|
|
|
|
{
|
|
|
|
Thread* t; AttachCurrentThread(m, &t, 0);
|
2009-08-19 20:27:03 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
if (run(t, destroyJavaVM, 0)) {
|
|
|
|
t->exit();
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
return -1;
|
|
|
|
}
|
2009-08-19 20:27:03 +00:00
|
|
|
}
|
|
|
|
|
2007-09-10 23:33:58 +00:00
|
|
|
jint JNICALL
|
|
|
|
GetEnv(Machine* m, Thread** t, jint version)
|
|
|
|
{
|
|
|
|
*t = static_cast<Thread*>(m->localThread->get());
|
|
|
|
if (*t) {
|
|
|
|
if (version <= JNI_VERSION_1_4) {
|
|
|
|
return JNI_OK;
|
|
|
|
} else {
|
|
|
|
return JNI_EVERSION;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return JNI_EDETACHED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-04-15 17:11:10 +00:00
|
|
|
jint JNICALL
|
2009-06-22 22:25:13 +00:00
|
|
|
GetVersion(Thread* t)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
return JNI_VERSION_1_6;
|
|
|
|
}
|
|
|
|
|
2008-04-01 23:24:43 +00:00
|
|
|
jsize JNICALL
|
|
|
|
GetStringLength(Thread* t, jstring s)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
return stringLength(t, *s);
|
|
|
|
}
|
|
|
|
|
|
|
|
const jchar* JNICALL
|
|
|
|
GetStringChars(Thread* t, jstring s, jboolean* isCopy)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
jchar* chars = static_cast<jchar*>
|
2008-04-13 18:15:04 +00:00
|
|
|
(t->m->heap->allocate((stringLength(t, *s) + 1) * sizeof(jchar)));
|
2008-04-02 12:57:25 +00:00
|
|
|
stringChars(t, *s, chars);
|
2008-04-01 23:24:43 +00:00
|
|
|
|
|
|
|
if (isCopy) *isCopy = true;
|
|
|
|
return chars;
|
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
ReleaseStringChars(Thread* t, jstring s, const jchar* chars)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-04-13 18:15:04 +00:00
|
|
|
t->m->heap->free(chars, (stringLength(t, *s) + 1) * sizeof(jchar));
|
2008-04-01 23:24:43 +00:00
|
|
|
}
|
|
|
|
|
2010-09-10 21:05:29 +00:00
|
|
|
void JNICALL
|
|
|
|
GetStringRegion(Thread* t, jstring s, jsize start, jsize length, jchar* dst)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
stringChars(t, *s, start, length, dst);
|
|
|
|
}
|
|
|
|
|
|
|
|
const jchar* JNICALL
|
|
|
|
GetStringCritical(Thread* t, jstring s, jboolean* isCopy)
|
|
|
|
{
|
|
|
|
if ((t->criticalLevel ++) == 0) {
|
|
|
|
enter(t, Thread::ActiveState);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isCopy) {
|
|
|
|
*isCopy = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
object data = stringData(t, *s);
|
2010-09-14 16:49:41 +00:00
|
|
|
if (objectClass(t, data) == type(t, Machine::ByteArrayType)) {
|
2010-09-10 21:05:29 +00:00
|
|
|
return GetStringChars(t, s, isCopy);
|
|
|
|
} else {
|
|
|
|
return &charArrayBody(t, data, stringOffset(t, *s));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
ReleaseStringCritical(Thread* t, jstring s, const jchar* chars)
|
|
|
|
{
|
2010-09-14 16:49:41 +00:00
|
|
|
if (objectClass(t, stringData(t, *s)) == type(t, Machine::ByteArrayType)) {
|
2010-09-10 21:05:29 +00:00
|
|
|
ReleaseStringChars(t, s, chars);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((-- t->criticalLevel) == 0) {
|
|
|
|
enter(t, Thread::IdleState);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-09-07 00:21:52 +00:00
|
|
|
jsize JNICALL
|
2007-07-06 23:18:40 +00:00
|
|
|
GetStringUTFLength(Thread* t, jstring s)
|
2007-07-06 15:24:06 +00:00
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-04-20 16:03:07 +00:00
|
|
|
return stringUTFLength(t, *s);
|
2007-07-06 15:24:06 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 00:21:52 +00:00
|
|
|
const char* JNICALL
|
2007-07-06 23:18:40 +00:00
|
|
|
GetStringUTFChars(Thread* t, jstring s, jboolean* isCopy)
|
2007-07-06 15:24:06 +00:00
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-04-20 16:03:07 +00:00
|
|
|
int length = stringUTFLength(t, *s);
|
2007-07-06 23:18:40 +00:00
|
|
|
char* chars = static_cast<char*>
|
2010-04-20 16:03:07 +00:00
|
|
|
(t->m->heap->allocate(length + 1));
|
|
|
|
stringUTFChars(t, *s, chars, length);
|
2007-07-06 15:24:06 +00:00
|
|
|
|
|
|
|
if (isCopy) *isCopy = true;
|
|
|
|
return chars;
|
|
|
|
}
|
|
|
|
|
2007-09-07 00:21:52 +00:00
|
|
|
void JNICALL
|
2008-01-10 01:20:36 +00:00
|
|
|
ReleaseStringUTFChars(Thread* t, jstring s, const char* chars)
|
2007-07-06 15:24:06 +00:00
|
|
|
{
|
2008-04-01 23:24:43 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-04-13 18:15:04 +00:00
|
|
|
t->m->heap->free(chars, stringLength(t, *s) + 1);
|
2007-07-06 15:24:06 +00:00
|
|
|
}
|
|
|
|
|
2010-09-10 21:05:29 +00:00
|
|
|
void JNICALL
|
|
|
|
GetStringUTFRegion(Thread* t, jstring s, jsize start, jsize length, char* dst)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
stringUTFChars
|
|
|
|
(t, *s, start, length, dst, stringUTFLength(t, *s, start, length));
|
|
|
|
}
|
|
|
|
|
2007-11-14 23:22:29 +00:00
|
|
|
jsize JNICALL
|
|
|
|
GetArrayLength(Thread* t, jarray array)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
return cast<uintptr_t>(*array, BytesPerWord);
|
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
uint64_t
|
|
|
|
newString(Thread* t, uintptr_t* arguments)
|
2007-10-26 21:23:54 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
const jchar* chars = reinterpret_cast<const jchar*>(arguments[0]);
|
|
|
|
jsize size = arguments[1];
|
2007-10-26 21:23:54 +00:00
|
|
|
|
|
|
|
object a = 0;
|
|
|
|
if (size) {
|
2009-03-04 03:05:48 +00:00
|
|
|
a = makeCharArray(t, size);
|
2007-10-27 00:04:20 +00:00
|
|
|
memcpy(&charArrayBody(t, a, 0), chars, size * sizeof(jchar));
|
2007-10-26 21:23:54 +00:00
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<uint64_t>
|
|
|
|
(makeLocalReference(t, t->m->classpath->makeString(t, a, 0, size)));
|
2007-10-26 21:23:54 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 00:21:52 +00:00
|
|
|
jstring JNICALL
|
2010-12-27 22:55:23 +00:00
|
|
|
NewString(Thread* t, const jchar* chars, jsize size)
|
2007-07-07 23:47:35 +00:00
|
|
|
{
|
2009-11-18 18:01:47 +00:00
|
|
|
if (chars == 0) return 0;
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(chars), size };
|
|
|
|
|
|
|
|
return reinterpret_cast<jstring>(run(t, newString, arguments));
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
newStringUTF(Thread* t, uintptr_t* arguments)
|
|
|
|
{
|
|
|
|
const char* chars = reinterpret_cast<const char*>(arguments[0]);
|
2007-07-07 23:47:35 +00:00
|
|
|
|
2010-09-10 21:05:29 +00:00
|
|
|
object array = parseUtf8(t, chars, strlen(chars));
|
2007-10-27 00:04:20 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<uint64_t>
|
|
|
|
(makeLocalReference
|
|
|
|
(t, t->m->classpath->makeString
|
|
|
|
(t, array, 0, cast<uintptr_t>(array, BytesPerWord) - 1)));
|
|
|
|
}
|
|
|
|
|
|
|
|
jstring JNICALL
|
|
|
|
NewStringUTF(Thread* t, const char* chars)
|
|
|
|
{
|
|
|
|
if (chars == 0) return 0;
|
|
|
|
|
|
|
|
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(chars) };
|
|
|
|
|
|
|
|
return reinterpret_cast<jstring>(run(t, newStringUTF, arguments));
|
2007-07-07 23:47:35 +00:00
|
|
|
}
|
|
|
|
|
2008-01-19 20:30:11 +00:00
|
|
|
void
|
|
|
|
replace(int a, int b, const char* in, int8_t* out)
|
|
|
|
{
|
|
|
|
while (*in) {
|
|
|
|
*out = (*in == a ? b : *in);
|
|
|
|
++ in;
|
|
|
|
++ out;
|
|
|
|
}
|
|
|
|
*out = 0;
|
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
uint64_t
|
|
|
|
defineClass(Thread* t, uintptr_t* arguments)
|
|
|
|
{
|
|
|
|
jobject loader = reinterpret_cast<jobject>(arguments[0]);
|
|
|
|
const uint8_t* buffer = reinterpret_cast<const uint8_t*>(arguments[1]);
|
|
|
|
jsize length = arguments[2];
|
|
|
|
|
|
|
|
return reinterpret_cast<uint64_t>
|
|
|
|
(makeLocalReference
|
|
|
|
(t, getJClass
|
|
|
|
(t, defineClass
|
|
|
|
(t, loader ? *loader : root(t, Machine::BootLoader), buffer, length))));
|
|
|
|
}
|
|
|
|
|
2010-09-10 21:05:29 +00:00
|
|
|
jclass JNICALL
|
|
|
|
DefineClass(Thread* t, const char*, jobject loader, const jbyte* buffer,
|
|
|
|
jsize length)
|
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(loader),
|
|
|
|
reinterpret_cast<uintptr_t>(buffer),
|
|
|
|
length };
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<jclass>(run(t, defineClass, arguments));
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
uint64_t
|
|
|
|
findClass(Thread* t, uintptr_t* arguments)
|
2007-07-27 00:06:05 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
const char* name = reinterpret_cast<const char*>(arguments[0]);
|
2007-07-27 00:06:05 +00:00
|
|
|
|
2009-03-04 03:05:48 +00:00
|
|
|
object n = makeByteArray(t, strlen(name) + 1);
|
2008-01-19 20:30:11 +00:00
|
|
|
replace('.', '/', name, &byteArrayBody(t, n, 0));
|
2007-07-27 00:06:05 +00:00
|
|
|
|
2010-09-25 21:54:01 +00:00
|
|
|
object caller = getCaller(t, 0);
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<uint64_t>
|
|
|
|
(makeLocalReference
|
|
|
|
(t, getJClass
|
|
|
|
(t, resolveClass
|
|
|
|
(t, caller ? classLoader(t, methodClass(t, caller))
|
|
|
|
: root(t, Machine::AppLoader), n))));
|
|
|
|
}
|
2010-09-01 16:13:52 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
jclass JNICALL
|
|
|
|
FindClass(Thread* t, const char* name)
|
|
|
|
{
|
|
|
|
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(name) };
|
|
|
|
|
|
|
|
return reinterpret_cast<jclass>(run(t, findClass, arguments));
|
2007-07-27 00:06:05 +00:00
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
uint64_t
|
|
|
|
throwNew(Thread* t, uintptr_t* arguments)
|
2007-07-27 00:06:05 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
jclass c = reinterpret_cast<jclass>(arguments[0]);
|
|
|
|
const char* message = reinterpret_cast<const char*>(arguments[1]);
|
2007-07-27 00:06:05 +00:00
|
|
|
|
|
|
|
object m = 0;
|
|
|
|
PROTECT(t, m);
|
|
|
|
|
|
|
|
if (message) {
|
|
|
|
m = makeString(t, "%s", message);
|
|
|
|
}
|
|
|
|
|
|
|
|
object trace = makeTrace(t);
|
|
|
|
PROTECT(t, trace);
|
|
|
|
|
2010-09-01 16:13:52 +00:00
|
|
|
t->exception = make(t, jclassVmClass(t, *c));
|
2007-10-22 17:22:30 +00:00
|
|
|
set(t, t->exception, ThrowableMessage, m);
|
|
|
|
set(t, t->exception, ThrowableTrace, trace);
|
2007-07-27 00:06:05 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
jint JNICALL
|
|
|
|
ThrowNew(Thread* t, jclass c, const char* message)
|
|
|
|
{
|
|
|
|
if (t->exception) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
|
|
|
|
reinterpret_cast<uintptr_t>(message) };
|
|
|
|
|
|
|
|
return run(t, throwNew, arguments) ? 0 : -1;
|
2007-07-27 00:06:05 +00:00
|
|
|
}
|
|
|
|
|
2010-09-10 21:05:29 +00:00
|
|
|
jint JNICALL
|
|
|
|
Throw(Thread* t, jthrowable throwable)
|
|
|
|
{
|
|
|
|
if (t->exception) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
t->exception = *throwable;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-09-07 00:21:52 +00:00
|
|
|
void JNICALL
|
2007-09-24 01:39:03 +00:00
|
|
|
DeleteLocalRef(Thread* t, jobject r)
|
2007-08-14 13:27:10 +00:00
|
|
|
{
|
2007-11-29 15:04:07 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2007-09-24 01:39:03 +00:00
|
|
|
disposeLocalReference(t, r);
|
2007-08-14 13:27:10 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 00:21:52 +00:00
|
|
|
jboolean JNICALL
|
2007-07-27 00:06:05 +00:00
|
|
|
ExceptionCheck(Thread* t)
|
|
|
|
{
|
|
|
|
return t->exception != 0;
|
|
|
|
}
|
|
|
|
|
2009-06-04 23:21:42 +00:00
|
|
|
jobject JNICALL
|
|
|
|
NewDirectByteBuffer(Thread*, void*, jlong)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void* JNICALL
|
|
|
|
GetDirectBufferAddress(Thread*, jobject)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
jlong JNICALL
|
2009-06-11 00:15:00 +00:00
|
|
|
GetDirectBufferCapacity(Thread*, jobject)
|
2009-06-04 23:21:42 +00:00
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2007-09-07 00:21:52 +00:00
|
|
|
jclass JNICALL
|
|
|
|
GetObjectClass(Thread* t, jobject o)
|
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-09-01 16:13:52 +00:00
|
|
|
return makeLocalReference(t, getJClass(t, objectClass(t, *o)));
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jboolean JNICALL
|
|
|
|
IsInstanceOf(Thread* t, jobject o, jclass c)
|
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-09-01 16:13:52 +00:00
|
|
|
return instanceOf(t, jclassVmClass(t, *c), *o);
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2010-09-10 21:05:29 +00:00
|
|
|
jboolean JNICALL
|
2010-09-10 23:45:52 +00:00
|
|
|
IsAssignableFrom(Thread* t, jclass b, jclass a)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
return isAssignableFrom(t, jclassVmClass(t, *a), jclassVmClass(t, *b));
|
|
|
|
}
|
|
|
|
|
2007-09-07 00:21:52 +00:00
|
|
|
object
|
2008-03-21 00:36:53 +00:00
|
|
|
findMethod(Thread* t, jclass c, const char* name, const char* spec)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2007-09-13 00:21:37 +00:00
|
|
|
object n = makeByteArray(t, "%s", name);
|
2007-09-07 00:21:52 +00:00
|
|
|
PROTECT(t, n);
|
|
|
|
|
2007-09-13 00:21:37 +00:00
|
|
|
object s = makeByteArray(t, "%s", spec);
|
2010-09-01 16:13:52 +00:00
|
|
|
return vm::findMethod(t, jclassVmClass(t, *c), n, s);
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
jint
|
|
|
|
methodID(Thread* t, object method)
|
|
|
|
{
|
|
|
|
if (methodNativeID(t, method) == 0) {
|
|
|
|
PROTECT(t, method);
|
|
|
|
|
|
|
|
ACQUIRE(t, t->m->referenceLock);
|
|
|
|
|
|
|
|
if (methodNativeID(t, method) == 0) {
|
2010-09-14 16:49:41 +00:00
|
|
|
setRoot(t, Machine::JNIMethodTable, vectorAppend
|
|
|
|
(t, root(t, Machine::JNIMethodTable), method));
|
2010-11-26 19:41:31 +00:00
|
|
|
methodNativeID(t, method) = vectorSize
|
|
|
|
(t, root(t, Machine::JNIMethodTable));
|
2008-08-15 18:32:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return methodNativeID(t, method);
|
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
uint64_t
|
|
|
|
getMethodID(Thread* t, uintptr_t* arguments)
|
2007-09-07 23:20:21 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
jclass c = reinterpret_cast<jclass>(arguments[0]);
|
|
|
|
const char* name = reinterpret_cast<const char*>(arguments[1]);
|
|
|
|
const char* spec = reinterpret_cast<const char*>(arguments[2]);
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2008-03-21 00:36:53 +00:00
|
|
|
object method = findMethod(t, c, name, spec);
|
2007-09-07 00:21:52 +00:00
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
assert(t, (methodFlags(t, method) & ACC_STATIC) == 0);
|
2007-09-07 00:21:52 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return methodID(t, method);
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
2007-09-07 00:21:52 +00:00
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jmethodID JNICALL
|
2010-12-27 22:55:23 +00:00
|
|
|
GetMethodID(Thread* t, jclass c, const char* name, const char* spec)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
|
|
|
|
reinterpret_cast<uintptr_t>(name),
|
|
|
|
reinterpret_cast<uintptr_t>(spec) };
|
|
|
|
|
|
|
|
return run(t, getMethodID, arguments);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
getStaticMethodID(Thread* t, uintptr_t* arguments)
|
|
|
|
{
|
|
|
|
jclass c = reinterpret_cast<jclass>(arguments[0]);
|
|
|
|
const char* name = reinterpret_cast<const char*>(arguments[1]);
|
|
|
|
const char* spec = reinterpret_cast<const char*>(arguments[2]);
|
2007-09-07 00:21:52 +00:00
|
|
|
|
2008-03-21 00:36:53 +00:00
|
|
|
object method = findMethod(t, c, name, spec);
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
assert(t, methodFlags(t, method) & ACC_STATIC);
|
|
|
|
|
|
|
|
return methodID(t, method);
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
jmethodID JNICALL
|
|
|
|
GetStaticMethodID(Thread* t, jclass c, const char* name, const char* spec)
|
|
|
|
{
|
|
|
|
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
|
|
|
|
reinterpret_cast<uintptr_t>(name),
|
|
|
|
reinterpret_cast<uintptr_t>(spec) };
|
|
|
|
|
|
|
|
return run(t, getStaticMethodID, arguments);
|
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
inline object
|
2008-08-15 18:32:33 +00:00
|
|
|
getMethod(Thread* t, jmethodID m)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2010-09-14 16:49:41 +00:00
|
|
|
object method = vectorBody(t, root(t, Machine::JNIMethodTable), m - 1);
|
2008-04-01 17:37:59 +00:00
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
assert(t, (methodFlags(t, method) & ACC_STATIC) == 0);
|
2008-04-01 17:37:59 +00:00
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
return method;
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
uint64_t
|
|
|
|
newObjectV(Thread* t, uintptr_t* arguments)
|
2007-11-14 23:22:29 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
jclass c = reinterpret_cast<jclass>(arguments[0]);
|
|
|
|
jmethodID m = arguments[1];
|
|
|
|
va_list* a = reinterpret_cast<va_list*>(arguments[2]);
|
2007-11-14 23:22:29 +00:00
|
|
|
|
2010-09-01 16:13:52 +00:00
|
|
|
object o = make(t, jclassVmClass(t, *c));
|
2007-11-14 23:22:29 +00:00
|
|
|
PROTECT(t, o);
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
t->m->processor->invokeList(t, getMethod(t, m), o, true, *a);
|
2007-11-14 23:22:29 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<uint64_t>(makeLocalReference(t, o));
|
|
|
|
}
|
|
|
|
|
|
|
|
jobject JNICALL
|
|
|
|
NewObjectV(Thread* t, jclass c, jmethodID m, va_list a)
|
|
|
|
{
|
|
|
|
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
|
|
|
|
m,
|
|
|
|
reinterpret_cast<uintptr_t>(a) };
|
|
|
|
|
|
|
|
return reinterpret_cast<jobject>(run(t, newObjectV, arguments));
|
2007-11-14 23:22:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jobject JNICALL
|
|
|
|
NewObject(Thread* t, jclass c, jmethodID m, ...)
|
|
|
|
{
|
|
|
|
va_list a;
|
|
|
|
va_start(a, m);
|
|
|
|
|
2007-11-29 15:04:07 +00:00
|
|
|
jobject r = NewObjectV(t, c, m, a);
|
2007-11-14 23:22:29 +00:00
|
|
|
|
|
|
|
va_end(a);
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
uint64_t
|
|
|
|
callObjectMethodV(Thread* t, uintptr_t* arguments)
|
|
|
|
{
|
|
|
|
jobject o = reinterpret_cast<jclass>(arguments[0]);
|
|
|
|
jmethodID m = arguments[1];
|
|
|
|
va_list* a = reinterpret_cast<va_list*>(arguments[2]);
|
|
|
|
|
|
|
|
object method = getMethod(t, m);
|
|
|
|
return reinterpret_cast<uint64_t>
|
|
|
|
(makeLocalReference
|
|
|
|
(t, t->m->processor->invokeList(t, method, *o, true, *a)));
|
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jobject JNICALL
|
|
|
|
CallObjectMethodV(Thread* t, jobject o, jmethodID m, va_list a)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o),
|
|
|
|
m,
|
|
|
|
reinterpret_cast<uintptr_t>(a) };
|
2007-09-07 00:21:52 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<jobject>(run(t, callObjectMethodV, arguments));
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jobject JNICALL
|
2007-09-07 23:20:21 +00:00
|
|
|
CallObjectMethod(Thread* t, jobject o, jmethodID m, ...)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
va_list a;
|
|
|
|
va_start(a, m);
|
|
|
|
|
|
|
|
jobject r = CallObjectMethodV(t, o, m, a);
|
|
|
|
|
|
|
|
va_end(a);
|
|
|
|
|
|
|
|
return r;
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
uint64_t
|
|
|
|
callIntMethodV(Thread* t, uintptr_t* arguments)
|
|
|
|
{
|
|
|
|
jobject o = reinterpret_cast<jclass>(arguments[0]);
|
|
|
|
jmethodID m = arguments[1];
|
|
|
|
va_list* a = reinterpret_cast<va_list*>(arguments[2]);
|
|
|
|
|
|
|
|
object method = getMethod(t, m);
|
|
|
|
return intValue(t, t->m->processor->invokeList(t, method, *o, true, *a));
|
|
|
|
}
|
|
|
|
|
2007-09-07 00:21:52 +00:00
|
|
|
jboolean JNICALL
|
2007-09-07 23:20:21 +00:00
|
|
|
CallBooleanMethodV(Thread* t, jobject o, jmethodID m, va_list a)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o),
|
|
|
|
m,
|
|
|
|
reinterpret_cast<uintptr_t>(a) };
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return run(t, callIntMethodV, arguments) != 0;
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jboolean JNICALL
|
|
|
|
CallBooleanMethod(Thread* t, jobject o, jmethodID m, ...)
|
|
|
|
{
|
|
|
|
va_list a;
|
|
|
|
va_start(a, m);
|
|
|
|
|
|
|
|
jboolean r = CallBooleanMethodV(t, o, m, a);
|
|
|
|
|
|
|
|
va_end(a);
|
|
|
|
|
|
|
|
return r;
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jbyte JNICALL
|
2007-09-07 23:20:21 +00:00
|
|
|
CallByteMethodV(Thread* t, jobject o, jmethodID m, va_list a)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o),
|
|
|
|
m,
|
|
|
|
reinterpret_cast<uintptr_t>(a) };
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return run(t, callIntMethodV, arguments);
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jbyte JNICALL
|
|
|
|
CallByteMethod(Thread* t, jobject o, jmethodID m, ...)
|
|
|
|
{
|
|
|
|
va_list a;
|
|
|
|
va_start(a, m);
|
|
|
|
|
|
|
|
jbyte r = CallByteMethodV(t, o, m, a);
|
|
|
|
|
|
|
|
va_end(a);
|
|
|
|
|
|
|
|
return r;
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jchar JNICALL
|
2007-09-07 23:20:21 +00:00
|
|
|
CallCharMethodV(Thread* t, jobject o, jmethodID m, va_list a)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o),
|
|
|
|
m,
|
|
|
|
reinterpret_cast<uintptr_t>(a) };
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return run(t, callIntMethodV, arguments);
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jchar JNICALL
|
|
|
|
CallCharMethod(Thread* t, jobject o, jmethodID m, ...)
|
|
|
|
{
|
|
|
|
va_list a;
|
|
|
|
va_start(a, m);
|
|
|
|
|
|
|
|
jchar r = CallCharMethodV(t, o, m, a);
|
|
|
|
|
|
|
|
va_end(a);
|
|
|
|
|
|
|
|
return r;
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jshort JNICALL
|
2007-09-07 23:20:21 +00:00
|
|
|
CallShortMethodV(Thread* t, jobject o, jmethodID m, va_list a)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o),
|
|
|
|
m,
|
|
|
|
reinterpret_cast<uintptr_t>(a) };
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return run(t, callIntMethodV, arguments);
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jshort JNICALL
|
|
|
|
CallShortMethod(Thread* t, jobject o, jmethodID m, ...)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
va_list a;
|
|
|
|
va_start(a, m);
|
|
|
|
|
|
|
|
jshort r = CallShortMethodV(t, o, m, a);
|
|
|
|
|
|
|
|
va_end(a);
|
|
|
|
|
|
|
|
return r;
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jint JNICALL
|
|
|
|
CallIntMethodV(Thread* t, jobject o, jmethodID m, va_list a)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o),
|
|
|
|
m,
|
|
|
|
reinterpret_cast<uintptr_t>(a) };
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return run(t, callIntMethodV, arguments);
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jint JNICALL
|
|
|
|
CallIntMethod(Thread* t, jobject o, jmethodID m, ...)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
va_list a;
|
|
|
|
va_start(a, m);
|
|
|
|
|
|
|
|
jint r = CallIntMethodV(t, o, m, a);
|
|
|
|
|
|
|
|
va_end(a);
|
|
|
|
|
|
|
|
return r;
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
uint64_t
|
|
|
|
callLongMethodV(Thread* t, uintptr_t* arguments)
|
|
|
|
{
|
|
|
|
jobject o = reinterpret_cast<jclass>(arguments[0]);
|
|
|
|
jmethodID m = arguments[1];
|
|
|
|
va_list* a = reinterpret_cast<va_list*>(arguments[2]);
|
|
|
|
|
|
|
|
object method = getMethod(t, m);
|
|
|
|
return longValue(t, t->m->processor->invokeList(t, method, *o, true, *a));
|
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jlong JNICALL
|
|
|
|
CallLongMethodV(Thread* t, jobject o, jmethodID m, va_list a)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o),
|
|
|
|
m,
|
|
|
|
reinterpret_cast<uintptr_t>(a) };
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return run(t, callLongMethodV, arguments);
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jlong JNICALL
|
|
|
|
CallLongMethod(Thread* t, jobject o, jmethodID m, ...)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
va_list a;
|
|
|
|
va_start(a, m);
|
|
|
|
|
|
|
|
jlong r = CallLongMethodV(t, o, m, a);
|
|
|
|
|
|
|
|
va_end(a);
|
|
|
|
|
|
|
|
return r;
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jfloat JNICALL
|
|
|
|
CallFloatMethodV(Thread* t, jobject o, jmethodID m, va_list a)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o),
|
|
|
|
m,
|
|
|
|
reinterpret_cast<uintptr_t>(a) };
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return bitsToFloat(run(t, callIntMethodV, arguments));
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jfloat JNICALL
|
|
|
|
CallFloatMethod(Thread* t, jobject o, jmethodID m, ...)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
va_list a;
|
|
|
|
va_start(a, m);
|
|
|
|
|
|
|
|
jfloat r = CallFloatMethodV(t, o, m, a);
|
|
|
|
|
|
|
|
va_end(a);
|
|
|
|
|
|
|
|
return r;
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jdouble JNICALL
|
|
|
|
CallDoubleMethodV(Thread* t, jobject o, jmethodID m, va_list a)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o),
|
|
|
|
m,
|
|
|
|
reinterpret_cast<uintptr_t>(a) };
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return bitsToDouble(run(t, callLongMethodV, arguments));
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jdouble JNICALL
|
|
|
|
CallDoubleMethod(Thread* t, jobject o, jmethodID m, ...)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
va_list a;
|
|
|
|
va_start(a, m);
|
|
|
|
|
|
|
|
jdouble r = CallDoubleMethodV(t, o, m, a);
|
|
|
|
|
|
|
|
va_end(a);
|
|
|
|
|
|
|
|
return r;
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
uint64_t
|
|
|
|
callVoidMethodV(Thread* t, uintptr_t* arguments)
|
|
|
|
{
|
|
|
|
jobject o = reinterpret_cast<jclass>(arguments[0]);
|
|
|
|
jmethodID m = arguments[1];
|
|
|
|
va_list* a = reinterpret_cast<va_list*>(arguments[2]);
|
|
|
|
|
|
|
|
object method = getMethod(t, m);
|
|
|
|
t->m->processor->invokeList(t, method, *o, true, *a);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-09-07 00:21:52 +00:00
|
|
|
void JNICALL
|
2007-09-07 23:20:21 +00:00
|
|
|
CallVoidMethodV(Thread* t, jobject o, jmethodID m, va_list a)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o),
|
|
|
|
m,
|
|
|
|
reinterpret_cast<uintptr_t>(a) };
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
run(t, callVoidMethodV, arguments);
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
2007-09-07 23:20:21 +00:00
|
|
|
CallVoidMethod(Thread* t, jobject o, jmethodID m, ...)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
va_list a;
|
|
|
|
va_start(a, m);
|
|
|
|
|
|
|
|
CallVoidMethodV(t, o, m, a);
|
|
|
|
|
|
|
|
va_end(a);
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
inline object
|
2008-08-15 18:32:33 +00:00
|
|
|
getStaticMethod(Thread* t, jmethodID m)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2010-09-14 16:49:41 +00:00
|
|
|
object method = vectorBody(t, root(t, Machine::JNIMethodTable), m - 1);
|
2008-04-01 17:37:59 +00:00
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
assert(t, methodFlags(t, method) & ACC_STATIC);
|
2008-04-01 17:37:59 +00:00
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
return method;
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
uint64_t
|
|
|
|
callStaticObjectMethodV(Thread* t, uintptr_t* arguments)
|
|
|
|
{
|
|
|
|
jmethodID m = arguments[0];
|
|
|
|
va_list* a = reinterpret_cast<va_list*>(arguments[1]);
|
|
|
|
|
|
|
|
return reinterpret_cast<uint64_t>
|
|
|
|
(makeLocalReference
|
|
|
|
(t, t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, *a)));
|
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jobject JNICALL
|
2008-08-15 18:32:33 +00:00
|
|
|
CallStaticObjectMethodV(Thread* t, jclass, jmethodID m, va_list a)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[] = { m, reinterpret_cast<uintptr_t>(a) };
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<jobject>(run(t, callStaticObjectMethodV, arguments));
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jobject JNICALL
|
2007-09-07 23:20:21 +00:00
|
|
|
CallStaticObjectMethod(Thread* t, jclass c, jmethodID m, ...)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
va_list a;
|
|
|
|
va_start(a, m);
|
|
|
|
|
|
|
|
jobject r = CallStaticObjectMethodV(t, c, m, a);
|
|
|
|
|
|
|
|
va_end(a);
|
|
|
|
|
|
|
|
return r;
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
uint64_t
|
|
|
|
callStaticIntMethodV(Thread* t, uintptr_t* arguments)
|
|
|
|
{
|
|
|
|
jmethodID m = arguments[0];
|
|
|
|
va_list* a = reinterpret_cast<va_list*>(arguments[1]);
|
|
|
|
|
|
|
|
return intValue
|
|
|
|
(t, t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, *a));
|
|
|
|
}
|
|
|
|
|
2007-09-07 00:21:52 +00:00
|
|
|
jboolean JNICALL
|
2008-08-15 18:32:33 +00:00
|
|
|
CallStaticBooleanMethodV(Thread* t, jclass, jmethodID m, va_list a)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[] = { m, reinterpret_cast<uintptr_t>(a) };
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return run(t, callStaticIntMethodV, arguments) != 0;
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jboolean JNICALL
|
|
|
|
CallStaticBooleanMethod(Thread* t, jclass c, jmethodID m, ...)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
va_list a;
|
|
|
|
va_start(a, m);
|
|
|
|
|
|
|
|
jboolean r = CallStaticBooleanMethodV(t, c, m, a);
|
|
|
|
|
|
|
|
va_end(a);
|
|
|
|
|
|
|
|
return r;
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jbyte JNICALL
|
2008-08-15 18:32:33 +00:00
|
|
|
CallStaticByteMethodV(Thread* t, jclass, jmethodID m, va_list a)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[] = { m, reinterpret_cast<uintptr_t>(a) };
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return run(t, callStaticIntMethodV, arguments);
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jbyte JNICALL
|
|
|
|
CallStaticByteMethod(Thread* t, jclass c, jmethodID m, ...)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
va_list a;
|
|
|
|
va_start(a, m);
|
|
|
|
|
|
|
|
jbyte r = CallStaticByteMethodV(t, c, m, a);
|
|
|
|
|
|
|
|
va_end(a);
|
|
|
|
|
|
|
|
return r;
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jchar JNICALL
|
2008-08-15 18:32:33 +00:00
|
|
|
CallStaticCharMethodV(Thread* t, jclass, jmethodID m, va_list a)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[] = { m, reinterpret_cast<uintptr_t>(a) };
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return run(t, callStaticIntMethodV, arguments);
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jchar JNICALL
|
|
|
|
CallStaticCharMethod(Thread* t, jclass c, jmethodID m, ...)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
va_list a;
|
|
|
|
va_start(a, m);
|
|
|
|
|
|
|
|
jchar r = CallStaticCharMethodV(t, c, m, a);
|
|
|
|
|
|
|
|
va_end(a);
|
|
|
|
|
|
|
|
return r;
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jshort JNICALL
|
2008-08-15 18:32:33 +00:00
|
|
|
CallStaticShortMethodV(Thread* t, jclass, jmethodID m, va_list a)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[] = { m, reinterpret_cast<uintptr_t>(a) };
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return run(t, callStaticIntMethodV, arguments);
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jshort JNICALL
|
|
|
|
CallStaticShortMethod(Thread* t, jclass c, jmethodID m, ...)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
va_list a;
|
|
|
|
va_start(a, m);
|
|
|
|
|
|
|
|
jshort r = CallStaticShortMethodV(t, c, m, a);
|
|
|
|
|
|
|
|
va_end(a);
|
|
|
|
|
|
|
|
return r;
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jint JNICALL
|
2008-08-15 18:32:33 +00:00
|
|
|
CallStaticIntMethodV(Thread* t, jclass, jmethodID m, va_list a)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[] = { m, reinterpret_cast<uintptr_t>(a) };
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return run(t, callStaticIntMethodV, arguments);
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jint JNICALL
|
|
|
|
CallStaticIntMethod(Thread* t, jclass c, jmethodID m, ...)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
va_list a;
|
|
|
|
va_start(a, m);
|
|
|
|
|
|
|
|
jint r = CallStaticIntMethodV(t, c, m, a);
|
|
|
|
|
|
|
|
va_end(a);
|
|
|
|
|
|
|
|
return r;
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
uint64_t
|
|
|
|
callStaticLongMethodV(Thread* t, uintptr_t* arguments)
|
|
|
|
{
|
|
|
|
jmethodID m = arguments[0];
|
|
|
|
va_list* a = reinterpret_cast<va_list*>(arguments[1]);
|
|
|
|
|
|
|
|
return longValue
|
|
|
|
(t, t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, *a));
|
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jlong JNICALL
|
2008-08-15 18:32:33 +00:00
|
|
|
CallStaticLongMethodV(Thread* t, jclass, jmethodID m, va_list a)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[] = { m, reinterpret_cast<uintptr_t>(a) };
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return run(t, callStaticLongMethodV, arguments);
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jlong JNICALL
|
|
|
|
CallStaticLongMethod(Thread* t, jclass c, jmethodID m, ...)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
va_list a;
|
|
|
|
va_start(a, m);
|
|
|
|
|
|
|
|
jlong r = CallStaticLongMethodV(t, c, m, a);
|
|
|
|
|
|
|
|
va_end(a);
|
|
|
|
|
|
|
|
return r;
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jfloat JNICALL
|
2008-08-15 18:32:33 +00:00
|
|
|
CallStaticFloatMethodV(Thread* t, jclass, jmethodID m, va_list a)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[] = { m, reinterpret_cast<uintptr_t>(a) };
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return bitsToFloat(run(t, callStaticIntMethodV, arguments));
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jfloat JNICALL
|
|
|
|
CallStaticFloatMethod(Thread* t, jclass c, jmethodID m, ...)
|
|
|
|
{
|
|
|
|
va_list a;
|
|
|
|
va_start(a, m);
|
|
|
|
|
|
|
|
jfloat r = CallStaticFloatMethodV(t, c, m, a);
|
|
|
|
|
|
|
|
va_end(a);
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
jdouble JNICALL
|
2008-08-15 18:32:33 +00:00
|
|
|
CallStaticDoubleMethodV(Thread* t, jclass, jmethodID m, va_list a)
|
2007-09-07 23:20:21 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[] = { m, reinterpret_cast<uintptr_t>(a) };
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return bitsToDouble(run(t, callStaticLongMethodV, arguments));
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jdouble JNICALL
|
|
|
|
CallStaticDoubleMethod(Thread* t, jclass c, jmethodID m, ...)
|
|
|
|
{
|
|
|
|
va_list a;
|
|
|
|
va_start(a, m);
|
|
|
|
|
|
|
|
jdouble r = CallStaticDoubleMethodV(t, c, m, a);
|
|
|
|
|
|
|
|
va_end(a);
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
uint64_t
|
|
|
|
callStaticVoidMethodV(Thread* t, uintptr_t* arguments)
|
|
|
|
{
|
|
|
|
jmethodID m = arguments[0];
|
|
|
|
va_list* a = reinterpret_cast<va_list*>(arguments[1]);
|
|
|
|
|
|
|
|
t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, *a);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
void JNICALL
|
2008-08-15 18:32:33 +00:00
|
|
|
CallStaticVoidMethodV(Thread* t, jclass, jmethodID m, va_list a)
|
2007-09-07 23:20:21 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[] = { m, reinterpret_cast<uintptr_t>(a) };
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
run(t, callStaticVoidMethodV, arguments);
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
CallStaticVoidMethod(Thread* t, jclass c, jmethodID m, ...)
|
|
|
|
{
|
|
|
|
va_list a;
|
|
|
|
va_start(a, m);
|
|
|
|
|
|
|
|
CallStaticVoidMethodV(t, c, m, a);
|
|
|
|
|
|
|
|
va_end(a);
|
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
uint64_t
|
|
|
|
getFieldID(Thread* t, uintptr_t* arguments)
|
|
|
|
{
|
|
|
|
jclass c = reinterpret_cast<jclass>(arguments[0]);
|
|
|
|
const char* name = reinterpret_cast<const char*>(arguments[1]);
|
|
|
|
const char* spec = reinterpret_cast<const char*>(arguments[2]);
|
|
|
|
|
|
|
|
return fieldOffset(t, resolveField(t, jclassVmClass(t, *c), name, spec));
|
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jfieldID JNICALL
|
|
|
|
GetFieldID(Thread* t, jclass c, const char* name, const char* spec)
|
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
|
|
|
|
reinterpret_cast<uintptr_t>(name),
|
|
|
|
reinterpret_cast<uintptr_t>(spec) };
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return run(t, getFieldID, arguments);
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jfieldID JNICALL
|
|
|
|
GetStaticFieldID(Thread* t, jclass c, const char* name, const char* spec)
|
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
|
|
|
|
reinterpret_cast<uintptr_t>(name),
|
|
|
|
reinterpret_cast<uintptr_t>(spec) };
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return run(t, getFieldID, arguments);
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jobject JNICALL
|
|
|
|
GetObjectField(Thread* t, jobject o, jfieldID field)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2007-09-24 01:39:03 +00:00
|
|
|
return makeLocalReference(t, cast<object>(*o, field));
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jboolean JNICALL
|
|
|
|
GetBooleanField(Thread* t, jobject o, jfieldID field)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
return cast<jboolean>(*o, field);
|
|
|
|
}
|
|
|
|
|
|
|
|
jbyte JNICALL
|
|
|
|
GetByteField(Thread* t, jobject o, jfieldID field)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
return cast<jbyte>(*o, field);
|
|
|
|
}
|
|
|
|
|
|
|
|
jchar JNICALL
|
|
|
|
GetCharField(Thread* t, jobject o, jfieldID field)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
return cast<jchar>(*o, field);
|
|
|
|
}
|
|
|
|
|
|
|
|
jshort JNICALL
|
|
|
|
GetShortField(Thread* t, jobject o, jfieldID field)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
return cast<jshort>(*o, field);
|
|
|
|
}
|
|
|
|
|
|
|
|
jint JNICALL
|
|
|
|
GetIntField(Thread* t, jobject o, jfieldID field)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
return cast<jint>(*o, field);
|
|
|
|
}
|
|
|
|
|
|
|
|
jlong JNICALL
|
|
|
|
GetLongField(Thread* t, jobject o, jfieldID field)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
return cast<jlong>(*o, field);
|
|
|
|
}
|
|
|
|
|
|
|
|
jfloat JNICALL
|
|
|
|
GetFloatField(Thread* t, jobject o, jfieldID field)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
return cast<jfloat>(*o, field);
|
|
|
|
}
|
|
|
|
|
|
|
|
jdouble JNICALL
|
|
|
|
GetDoubleField(Thread* t, jobject o, jfieldID field)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
return cast<jdouble>(*o, field);
|
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetObjectField(Thread* t, jobject o, jfieldID field, jobject v)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2007-10-22 17:22:30 +00:00
|
|
|
set(t, *o, field, (v ? *v : 0));
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetBooleanField(Thread* t, jobject o, jfieldID field, jboolean v)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
cast<jboolean>(*o, field) = v;
|
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetByteField(Thread* t, jobject o, jfieldID field, jbyte v)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
cast<jbyte>(*o, field) = v;
|
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetCharField(Thread* t, jobject o, jfieldID field, jchar v)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
cast<jchar>(*o, field) = v;
|
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetShortField(Thread* t, jobject o, jfieldID field, jshort v)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
cast<jshort>(*o, field) = v;
|
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetIntField(Thread* t, jobject o, jfieldID field, jint v)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
cast<jint>(*o, field) = v;
|
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetLongField(Thread* t, jobject o, jfieldID field, jlong v)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
cast<jlong>(*o, field) = v;
|
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetFloatField(Thread* t, jobject o, jfieldID field, jfloat v)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
cast<jfloat>(*o, field) = v;
|
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetDoubleField(Thread* t, jobject o, jfieldID field, jdouble v)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
cast<jdouble>(*o, field) = v;
|
|
|
|
}
|
|
|
|
|
|
|
|
jobject JNICALL
|
|
|
|
GetStaticObjectField(Thread* t, jclass c, jfieldID field)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-09-01 16:13:52 +00:00
|
|
|
return makeLocalReference
|
|
|
|
(t, cast<object>(classStaticTable(t, jclassVmClass(t, *c)), field));
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jboolean JNICALL
|
|
|
|
GetStaticBooleanField(Thread* t, jclass c, jfieldID field)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-09-01 16:13:52 +00:00
|
|
|
return cast<int8_t>(classStaticTable(t, jclassVmClass(t, *c)), field);
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jbyte JNICALL
|
|
|
|
GetStaticByteField(Thread* t, jclass c, jfieldID field)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-09-01 16:13:52 +00:00
|
|
|
return cast<int8_t>(classStaticTable(t, jclassVmClass(t, *c)), field);
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jchar JNICALL
|
|
|
|
GetStaticCharField(Thread* t, jclass c, jfieldID field)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-09-01 16:13:52 +00:00
|
|
|
return cast<uint16_t>(classStaticTable(t, jclassVmClass(t, *c)), field);
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jshort JNICALL
|
|
|
|
GetStaticShortField(Thread* t, jclass c, jfieldID field)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-09-01 16:13:52 +00:00
|
|
|
return cast<int16_t>(classStaticTable(t, jclassVmClass(t, *c)), field);
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jint JNICALL
|
|
|
|
GetStaticIntField(Thread* t, jclass c, jfieldID field)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-09-01 16:13:52 +00:00
|
|
|
return cast<int32_t>(classStaticTable(t, jclassVmClass(t, *c)), field);
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jlong JNICALL
|
|
|
|
GetStaticLongField(Thread* t, jclass c, jfieldID field)
|
|
|
|
{
|
2007-09-13 00:21:37 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-09-01 16:13:52 +00:00
|
|
|
return cast<int64_t>(classStaticTable(t, jclassVmClass(t, *c)), field);
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jfloat JNICALL
|
|
|
|
GetStaticFloatField(Thread* t, jclass c, jfieldID field)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-09-01 16:13:52 +00:00
|
|
|
return cast<float>(classStaticTable(t, jclassVmClass(t, *c)), field);
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jdouble JNICALL
|
|
|
|
GetStaticDoubleField(Thread* t, jclass c, jfieldID field)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-09-01 16:13:52 +00:00
|
|
|
return cast<double>(classStaticTable(t, jclassVmClass(t, *c)), field);
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetStaticObjectField(Thread* t, jclass c, jfieldID field, jobject v)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-09-10 21:05:29 +00:00
|
|
|
set(t, classStaticTable(t, jclassVmClass(t, *c)), field, (v ? *v : 0));
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetStaticBooleanField(Thread* t, jclass c, jfieldID field, jboolean v)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
2009-08-03 22:18:16 +00:00
|
|
|
|
2010-09-01 16:13:52 +00:00
|
|
|
cast<int8_t>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetStaticByteField(Thread* t, jclass c, jfieldID field, jbyte v)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-09-01 16:13:52 +00:00
|
|
|
cast<int8_t>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetStaticCharField(Thread* t, jclass c, jfieldID field, jchar v)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-09-01 16:13:52 +00:00
|
|
|
cast<uint16_t>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetStaticShortField(Thread* t, jclass c, jfieldID field, jshort v)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-09-01 16:13:52 +00:00
|
|
|
cast<int16_t>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetStaticIntField(Thread* t, jclass c, jfieldID field, jint v)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-09-01 16:13:52 +00:00
|
|
|
cast<int32_t>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetStaticLongField(Thread* t, jclass c, jfieldID field, jlong v)
|
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-09-01 16:13:52 +00:00
|
|
|
cast<int64_t>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetStaticFloatField(Thread* t, jclass c, jfieldID field, jfloat v)
|
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-09-01 16:13:52 +00:00
|
|
|
cast<float>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetStaticDoubleField(Thread* t, jclass c, jfieldID field, jdouble v)
|
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-09-01 16:13:52 +00:00
|
|
|
cast<double>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
|
2007-09-07 00:21:52 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jobject JNICALL
|
|
|
|
NewGlobalRef(Thread* t, jobject o)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2007-09-24 01:39:03 +00:00
|
|
|
ACQUIRE(t, t->m->referenceLock);
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2007-09-30 03:33:38 +00:00
|
|
|
if (o) {
|
2009-12-17 02:16:51 +00:00
|
|
|
for (Reference* r = t->m->jniReferences; r; r = r->next) {
|
|
|
|
if (r->target == *o) {
|
|
|
|
acquire(t, r);
|
|
|
|
|
|
|
|
return &(r->target);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-04-13 18:15:04 +00:00
|
|
|
Reference* r = new (t->m->heap->allocate(sizeof(Reference)))
|
2007-09-30 03:33:38 +00:00
|
|
|
Reference(*o, &(t->m->jniReferences));
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2009-12-17 02:16:51 +00:00
|
|
|
acquire(t, r);
|
|
|
|
|
2007-09-30 03:33:38 +00:00
|
|
|
return &(r->target);
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
2007-09-30 03:33:38 +00:00
|
|
|
DeleteGlobalRef(Thread* t, jobject r)
|
2007-09-07 23:20:21 +00:00
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2007-09-24 01:39:03 +00:00
|
|
|
ACQUIRE(t, t->m->referenceLock);
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2007-09-30 03:33:38 +00:00
|
|
|
if (r) {
|
2009-12-17 02:16:51 +00:00
|
|
|
release(t, reinterpret_cast<Reference*>(r));
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-10 21:05:29 +00:00
|
|
|
jint JNICALL
|
|
|
|
EnsureLocalCapacity(Thread*, jint)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jthrowable JNICALL
|
|
|
|
ExceptionOccurred(Thread* t)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2007-09-24 01:39:03 +00:00
|
|
|
return makeLocalReference(t, t->exception);
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
ExceptionDescribe(Thread* t)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
return printTrace(t, t->exception);
|
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
ExceptionClear(Thread* t)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
t->exception = 0;
|
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
uint64_t
|
|
|
|
newObjectArray(Thread* t, uintptr_t* arguments)
|
2007-10-25 15:04:13 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
jsize length = arguments[0];
|
|
|
|
jclass class_ = reinterpret_cast<jclass>(arguments[1]);
|
|
|
|
jobject init = reinterpret_cast<jobject>(arguments[2]);
|
2007-10-25 15:04:13 +00:00
|
|
|
|
2010-09-14 16:49:41 +00:00
|
|
|
object a = makeObjectArray(t, jclassVmClass(t, *class_), length);
|
2007-10-25 15:04:13 +00:00
|
|
|
object value = (init ? *init : 0);
|
|
|
|
for (jsize i = 0; i < length; ++i) {
|
|
|
|
set(t, a, ArrayBody + (i * BytesPerWord), value);
|
|
|
|
}
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<uint64_t>(makeLocalReference(t, a));
|
|
|
|
}
|
|
|
|
|
|
|
|
jobjectArray JNICALL
|
|
|
|
NewObjectArray(Thread* t, jsize length, jclass class_, jobject init)
|
|
|
|
{
|
|
|
|
uintptr_t arguments[] = { length,
|
|
|
|
reinterpret_cast<uintptr_t>(class_),
|
|
|
|
reinterpret_cast<uintptr_t>(init) };
|
|
|
|
|
|
|
|
return reinterpret_cast<jobjectArray>(run(t, newObjectArray, arguments));
|
2007-10-25 15:04:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jobject JNICALL
|
|
|
|
GetObjectArrayElement(Thread* t, jobjectArray array, jsize index)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
return makeLocalReference(t, objectArrayBody(t, *array, index));
|
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetObjectArrayElement(Thread* t, jobjectArray array, jsize index,
|
|
|
|
jobject value)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2009-08-19 13:36:52 +00:00
|
|
|
set(t, *array, ArrayBody + (index * BytesPerWord), (value ? *value : 0));
|
2007-10-25 15:04:13 +00:00
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
uint64_t
|
|
|
|
newArray(Thread* t, uintptr_t* arguments)
|
|
|
|
{
|
|
|
|
object (*constructor)(Thread*, unsigned)
|
|
|
|
= reinterpret_cast<object (*)(Thread*, unsigned)>(arguments[0]);
|
|
|
|
|
|
|
|
jsize length = arguments[1];
|
|
|
|
|
|
|
|
return reinterpret_cast<uint64_t>
|
|
|
|
(makeLocalReference(t, constructor(t, length)));
|
|
|
|
}
|
|
|
|
|
2007-09-10 23:33:58 +00:00
|
|
|
jbooleanArray JNICALL
|
|
|
|
NewBooleanArray(Thread* t, jsize length)
|
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[]
|
|
|
|
= { reinterpret_cast<uintptr_t>(voidPointer(makeBooleanArray)),
|
|
|
|
length };
|
2007-09-10 23:33:58 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<jbooleanArray>(run(t, newArray, arguments));
|
|
|
|
}
|
|
|
|
|
|
|
|
object
|
|
|
|
makeByteArray0(Thread* t, unsigned length)
|
|
|
|
{
|
|
|
|
return makeByteArray(t, length);
|
2007-09-10 23:33:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jbyteArray JNICALL
|
|
|
|
NewByteArray(Thread* t, jsize length)
|
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[]
|
|
|
|
= { reinterpret_cast<uintptr_t>(voidPointer(makeByteArray0)),
|
|
|
|
length };
|
2007-09-10 23:33:58 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<jbyteArray>(run(t, newArray, arguments));
|
2007-09-10 23:33:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jcharArray JNICALL
|
|
|
|
NewCharArray(Thread* t, jsize length)
|
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[]
|
|
|
|
= { reinterpret_cast<uintptr_t>(voidPointer(makeCharArray)),
|
|
|
|
length };
|
2007-09-10 23:33:58 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<jcharArray>(run(t, newArray, arguments));
|
2007-09-10 23:33:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jshortArray JNICALL
|
|
|
|
NewShortArray(Thread* t, jsize length)
|
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[]
|
|
|
|
= { reinterpret_cast<uintptr_t>(voidPointer(makeShortArray)),
|
|
|
|
length };
|
2007-09-10 23:33:58 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<jshortArray>(run(t, newArray, arguments));
|
2007-09-10 23:33:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jintArray JNICALL
|
|
|
|
NewIntArray(Thread* t, jsize length)
|
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[]
|
|
|
|
= { reinterpret_cast<uintptr_t>(voidPointer(makeIntArray)),
|
|
|
|
length };
|
2007-09-10 23:33:58 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<jintArray>(run(t, newArray, arguments));
|
2007-09-10 23:33:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jlongArray JNICALL
|
|
|
|
NewLongArray(Thread* t, jsize length)
|
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[]
|
|
|
|
= { reinterpret_cast<uintptr_t>(voidPointer(makeLongArray)),
|
|
|
|
length };
|
2007-09-10 23:33:58 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<jlongArray>(run(t, newArray, arguments));
|
2007-09-10 23:33:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jfloatArray JNICALL
|
|
|
|
NewFloatArray(Thread* t, jsize length)
|
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[]
|
|
|
|
= { reinterpret_cast<uintptr_t>(voidPointer(makeFloatArray)),
|
|
|
|
length };
|
2007-09-10 23:33:58 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<jfloatArray>(run(t, newArray, arguments));
|
2007-09-10 23:33:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jdoubleArray JNICALL
|
|
|
|
NewDoubleArray(Thread* t, jsize length)
|
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[]
|
|
|
|
= { reinterpret_cast<uintptr_t>(voidPointer(makeDoubleArray)),
|
|
|
|
length };
|
2007-09-10 23:33:58 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<jdoubleArray>(run(t, newArray, arguments));
|
2007-09-10 23:33:58 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jboolean* JNICALL
|
|
|
|
GetBooleanArrayElements(Thread* t, jbooleanArray array, jboolean* isCopy)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
unsigned size = booleanArrayLength(t, *array) * sizeof(jboolean);
|
2008-04-13 18:15:04 +00:00
|
|
|
jboolean* p = static_cast<jboolean*>(t->m->heap->allocate(size));
|
2007-09-07 23:20:21 +00:00
|
|
|
if (size) {
|
|
|
|
memcpy(p, &booleanArrayBody(t, *array, 0), size);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isCopy) {
|
|
|
|
*isCopy = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
jbyte* JNICALL
|
|
|
|
GetByteArrayElements(Thread* t, jbyteArray array, jboolean* isCopy)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
unsigned size = byteArrayLength(t, *array) * sizeof(jbyte);
|
2008-04-13 18:15:04 +00:00
|
|
|
jbyte* p = static_cast<jbyte*>(t->m->heap->allocate(size));
|
2007-09-07 23:20:21 +00:00
|
|
|
if (size) {
|
|
|
|
memcpy(p, &byteArrayBody(t, *array, 0), size);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isCopy) {
|
|
|
|
*isCopy = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
jchar* JNICALL
|
|
|
|
GetCharArrayElements(Thread* t, jcharArray array, jboolean* isCopy)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
unsigned size = charArrayLength(t, *array) * sizeof(jchar);
|
2008-04-13 18:15:04 +00:00
|
|
|
jchar* p = static_cast<jchar*>(t->m->heap->allocate(size));
|
2007-09-07 23:20:21 +00:00
|
|
|
if (size) {
|
|
|
|
memcpy(p, &charArrayBody(t, *array, 0), size);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isCopy) {
|
|
|
|
*isCopy = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
jshort* JNICALL
|
|
|
|
GetShortArrayElements(Thread* t, jshortArray array, jboolean* isCopy)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
unsigned size = shortArrayLength(t, *array) * sizeof(jshort);
|
2008-04-13 18:15:04 +00:00
|
|
|
jshort* p = static_cast<jshort*>(t->m->heap->allocate(size));
|
2007-09-07 23:20:21 +00:00
|
|
|
if (size) {
|
|
|
|
memcpy(p, &shortArrayBody(t, *array, 0), size);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isCopy) {
|
|
|
|
*isCopy = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
jint* JNICALL
|
|
|
|
GetIntArrayElements(Thread* t, jintArray array, jboolean* isCopy)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
unsigned size = intArrayLength(t, *array) * sizeof(jint);
|
2008-04-13 18:15:04 +00:00
|
|
|
jint* p = static_cast<jint*>(t->m->heap->allocate(size));
|
2007-09-07 23:20:21 +00:00
|
|
|
if (size) {
|
|
|
|
memcpy(p, &intArrayBody(t, *array, 0), size);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isCopy) {
|
|
|
|
*isCopy = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
jlong* JNICALL
|
|
|
|
GetLongArrayElements(Thread* t, jlongArray array, jboolean* isCopy)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
unsigned size = longArrayLength(t, *array) * sizeof(jlong);
|
2008-04-13 18:15:04 +00:00
|
|
|
jlong* p = static_cast<jlong*>(t->m->heap->allocate(size));
|
2007-09-07 23:20:21 +00:00
|
|
|
if (size) {
|
|
|
|
memcpy(p, &longArrayBody(t, *array, 0), size);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isCopy) {
|
|
|
|
*isCopy = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
jfloat* JNICALL
|
|
|
|
GetFloatArrayElements(Thread* t, jfloatArray array, jboolean* isCopy)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
unsigned size = floatArrayLength(t, *array) * sizeof(jfloat);
|
2008-04-13 18:15:04 +00:00
|
|
|
jfloat* p = static_cast<jfloat*>(t->m->heap->allocate(size));
|
2007-09-07 23:20:21 +00:00
|
|
|
if (size) {
|
|
|
|
memcpy(p, &floatArrayBody(t, *array, 0), size);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isCopy) {
|
|
|
|
*isCopy = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
jdouble* JNICALL
|
|
|
|
GetDoubleArrayElements(Thread* t, jdoubleArray array, jboolean* isCopy)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
unsigned size = doubleArrayLength(t, *array) * sizeof(jdouble);
|
2008-04-13 18:15:04 +00:00
|
|
|
jdouble* p = static_cast<jdouble*>(t->m->heap->allocate(size));
|
2007-09-07 23:20:21 +00:00
|
|
|
if (size) {
|
|
|
|
memcpy(p, &doubleArrayBody(t, *array, 0), size);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isCopy) {
|
|
|
|
*isCopy = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
ReleaseBooleanArrayElements(Thread* t, jbooleanArray array, jboolean* p,
|
|
|
|
jint mode)
|
|
|
|
{
|
2008-01-18 01:26:46 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-01-10 01:20:36 +00:00
|
|
|
unsigned size = booleanArrayLength(t, *array) * sizeof(jboolean);
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
if (mode == 0 or mode == JNI_COMMIT) {
|
|
|
|
if (size) {
|
|
|
|
memcpy(&booleanArrayBody(t, *array, 0), p, size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mode == 0 or mode == JNI_ABORT) {
|
2008-04-13 18:15:04 +00:00
|
|
|
t->m->heap->free(p, size);
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
ReleaseByteArrayElements(Thread* t, jbyteArray array, jbyte* p, jint mode)
|
|
|
|
{
|
2008-01-18 01:26:46 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-01-10 01:20:36 +00:00
|
|
|
unsigned size = byteArrayLength(t, *array) * sizeof(jbyte);
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
if (mode == 0 or mode == JNI_COMMIT) {
|
|
|
|
if (size) {
|
|
|
|
memcpy(&byteArrayBody(t, *array, 0), p, size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mode == 0 or mode == JNI_ABORT) {
|
2008-04-13 18:15:04 +00:00
|
|
|
t->m->heap->free(p, size);
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
ReleaseCharArrayElements(Thread* t, jcharArray array, jchar* p, jint mode)
|
|
|
|
{
|
2008-01-18 01:26:46 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-01-10 01:20:36 +00:00
|
|
|
unsigned size = charArrayLength(t, *array) * sizeof(jchar);
|
|
|
|
|
2008-01-18 01:26:46 +00:00
|
|
|
if (mode == 0 or mode == JNI_COMMIT) {
|
2007-09-07 23:20:21 +00:00
|
|
|
if (size) {
|
|
|
|
memcpy(&charArrayBody(t, *array, 0), p, size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mode == 0 or mode == JNI_ABORT) {
|
2008-04-13 18:15:04 +00:00
|
|
|
t->m->heap->free(p, size);
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
ReleaseShortArrayElements(Thread* t, jshortArray array, jshort* p, jint mode)
|
|
|
|
{
|
2008-01-18 01:26:46 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-01-10 01:20:36 +00:00
|
|
|
unsigned size = shortArrayLength(t, *array) * sizeof(jshort);
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
if (mode == 0 or mode == JNI_COMMIT) {
|
|
|
|
if (size) {
|
|
|
|
memcpy(&shortArrayBody(t, *array, 0), p, size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mode == 0 or mode == JNI_ABORT) {
|
2008-04-13 18:15:04 +00:00
|
|
|
t->m->heap->free(p, size);
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
ReleaseIntArrayElements(Thread* t, jintArray array, jint* p, jint mode)
|
|
|
|
{
|
2008-01-18 01:26:46 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-01-10 01:20:36 +00:00
|
|
|
unsigned size = intArrayLength(t, *array) * sizeof(jint);
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
if (mode == 0 or mode == JNI_COMMIT) {
|
|
|
|
if (size) {
|
|
|
|
memcpy(&intArrayBody(t, *array, 0), p, size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mode == 0 or mode == JNI_ABORT) {
|
2008-04-13 18:15:04 +00:00
|
|
|
t->m->heap->free(p, size);
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
ReleaseLongArrayElements(Thread* t, jlongArray array, jlong* p, jint mode)
|
|
|
|
{
|
2008-01-18 01:26:46 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-01-10 01:20:36 +00:00
|
|
|
unsigned size = longArrayLength(t, *array) * sizeof(jlong);
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
if (mode == 0 or mode == JNI_COMMIT) {
|
|
|
|
if (size) {
|
|
|
|
memcpy(&longArrayBody(t, *array, 0), p, size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mode == 0 or mode == JNI_ABORT) {
|
2008-04-13 18:15:04 +00:00
|
|
|
t->m->heap->free(p, size);
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
ReleaseFloatArrayElements(Thread* t, jfloatArray array, jfloat* p, jint mode)
|
|
|
|
{
|
2008-01-18 01:26:46 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-01-10 01:20:36 +00:00
|
|
|
unsigned size = floatArrayLength(t, *array) * sizeof(jfloat);
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
if (mode == 0 or mode == JNI_COMMIT) {
|
|
|
|
if (size) {
|
|
|
|
memcpy(&floatArrayBody(t, *array, 0), p, size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mode == 0 or mode == JNI_ABORT) {
|
2008-04-13 18:15:04 +00:00
|
|
|
t->m->heap->free(p, size);
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
ReleaseDoubleArrayElements(Thread* t, jdoubleArray array, jdouble* p,
|
|
|
|
jint mode)
|
|
|
|
{
|
2008-01-18 01:26:46 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-01-10 01:20:36 +00:00
|
|
|
unsigned size = doubleArrayLength(t, *array) * sizeof(jdouble);
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
if (mode == 0 or mode == JNI_COMMIT) {
|
|
|
|
if (size) {
|
|
|
|
memcpy(&doubleArrayBody(t, *array, 0), p, size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mode == 0 or mode == JNI_ABORT) {
|
2008-04-13 18:15:04 +00:00
|
|
|
t->m->heap->free(p, size);
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
GetBooleanArrayRegion(Thread* t, jbooleanArray array, jint offset, jint length,
|
|
|
|
jboolean* dst)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2007-11-14 23:22:29 +00:00
|
|
|
if (length) {
|
|
|
|
memcpy(dst, &booleanArrayBody(t, *array, offset),
|
|
|
|
length * sizeof(jboolean));
|
|
|
|
}
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
GetByteArrayRegion(Thread* t, jbyteArray array, jint offset, jint length,
|
|
|
|
jbyte* dst)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2007-11-14 23:22:29 +00:00
|
|
|
if (length) {
|
|
|
|
memcpy(dst, &byteArrayBody(t, *array, offset), length * sizeof(jbyte));
|
|
|
|
}
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
GetCharArrayRegion(Thread* t, jcharArray array, jint offset, jint length,
|
|
|
|
jchar* dst)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2007-11-14 23:22:29 +00:00
|
|
|
if (length) {
|
|
|
|
memcpy(dst, &charArrayBody(t, *array, offset), length * sizeof(jchar));
|
|
|
|
}
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
GetShortArrayRegion(Thread* t, jshortArray array, jint offset, jint length,
|
2007-11-14 23:22:29 +00:00
|
|
|
jshort* dst)
|
2007-09-07 23:20:21 +00:00
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2007-11-14 23:22:29 +00:00
|
|
|
if (length) {
|
|
|
|
memcpy(dst, &shortArrayBody(t, *array, offset), length * sizeof(jshort));
|
|
|
|
}
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
GetIntArrayRegion(Thread* t, jintArray array, jint offset, jint length,
|
|
|
|
jint* dst)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2007-11-14 23:22:29 +00:00
|
|
|
if (length) {
|
|
|
|
memcpy(dst, &intArrayBody(t, *array, offset), length * sizeof(jint));
|
|
|
|
}
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
GetLongArrayRegion(Thread* t, jlongArray array, jint offset, jint length,
|
|
|
|
jlong* dst)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2007-11-14 23:22:29 +00:00
|
|
|
if (length) {
|
|
|
|
memcpy(dst, &longArrayBody(t, *array, offset), length * sizeof(jlong));
|
|
|
|
}
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
GetFloatArrayRegion(Thread* t, jfloatArray array, jint offset, jint length,
|
|
|
|
jfloat* dst)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2007-11-14 23:22:29 +00:00
|
|
|
if (length) {
|
|
|
|
memcpy(dst, &floatArrayBody(t, *array, offset), length * sizeof(jfloat));
|
|
|
|
}
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
GetDoubleArrayRegion(Thread* t, jdoubleArray array, jint offset, jint length,
|
|
|
|
jdouble* dst)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2007-11-14 23:22:29 +00:00
|
|
|
if (length) {
|
|
|
|
memcpy(dst, &doubleArrayBody(t, *array, offset), length * sizeof(jdouble));
|
|
|
|
}
|
2007-09-17 22:15:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetBooleanArrayRegion(Thread* t, jbooleanArray array, jint offset, jint length,
|
|
|
|
const jboolean* src)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2007-11-14 23:22:29 +00:00
|
|
|
if (length) {
|
|
|
|
memcpy(&booleanArrayBody(t, *array, offset), src,
|
|
|
|
length * sizeof(jboolean));
|
|
|
|
}
|
2007-09-17 22:15:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetByteArrayRegion(Thread* t, jbyteArray array, jint offset, jint length,
|
|
|
|
const jbyte* src)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2007-11-14 23:22:29 +00:00
|
|
|
if (length) {
|
|
|
|
memcpy(&byteArrayBody(t, *array, offset), src, length * sizeof(jbyte));
|
|
|
|
}
|
2007-09-17 22:15:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetCharArrayRegion(Thread* t, jcharArray array, jint offset, jint length,
|
|
|
|
const jchar* src)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2007-11-14 23:22:29 +00:00
|
|
|
if (length) {
|
|
|
|
memcpy(&charArrayBody(t, *array, offset), src, length * sizeof(jchar));
|
|
|
|
}
|
2007-09-17 22:15:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetShortArrayRegion(Thread* t, jshortArray array, jint offset, jint length,
|
|
|
|
const jshort* src)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2007-11-14 23:22:29 +00:00
|
|
|
if (length) {
|
|
|
|
memcpy(&shortArrayBody(t, *array, offset), src, length * sizeof(jshort));
|
|
|
|
}
|
2007-09-17 22:15:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetIntArrayRegion(Thread* t, jintArray array, jint offset, jint length,
|
|
|
|
const jint* src)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2007-11-14 23:22:29 +00:00
|
|
|
if (length) {
|
|
|
|
memcpy(&intArrayBody(t, *array, offset), src, length * sizeof(jint));
|
|
|
|
}
|
2007-09-17 22:15:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetLongArrayRegion(Thread* t, jlongArray array, jint offset, jint length,
|
|
|
|
const jlong* src)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2007-11-14 23:22:29 +00:00
|
|
|
if (length) {
|
|
|
|
memcpy(&longArrayBody(t, *array, offset), src, length * sizeof(jlong));
|
|
|
|
}
|
2007-09-17 22:15:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetFloatArrayRegion(Thread* t, jfloatArray array, jint offset, jint length,
|
|
|
|
const jfloat* src)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2007-11-14 23:22:29 +00:00
|
|
|
if (length) {
|
|
|
|
memcpy(&floatArrayBody(t, *array, offset), src, length * sizeof(jfloat));
|
|
|
|
}
|
2007-09-17 22:15:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
SetDoubleArrayRegion(Thread* t, jdoubleArray array, jint offset, jint length,
|
|
|
|
const jdouble* src)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2007-11-14 23:22:29 +00:00
|
|
|
if (length) {
|
|
|
|
memcpy(&doubleArrayBody(t, *array, offset), src, length * sizeof(jdouble));
|
|
|
|
}
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void* JNICALL
|
|
|
|
GetPrimitiveArrayCritical(Thread* t, jarray array, jboolean* isCopy)
|
|
|
|
{
|
|
|
|
if ((t->criticalLevel ++) == 0) {
|
|
|
|
enter(t, Thread::ActiveState);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isCopy) {
|
|
|
|
*isCopy = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return reinterpret_cast<uintptr_t*>(*array) + 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
void JNICALL
|
|
|
|
ReleasePrimitiveArrayCritical(Thread* t, jarray, void*, jint)
|
|
|
|
{
|
|
|
|
if ((-- t->criticalLevel) == 0) {
|
|
|
|
enter(t, Thread::IdleState);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
uint64_t
|
|
|
|
registerNatives(Thread* t, uintptr_t* arguments)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
jclass c = reinterpret_cast<jclass>(arguments[0]);
|
|
|
|
const JNINativeMethod* methods
|
|
|
|
= reinterpret_cast<const JNINativeMethod*>(arguments[1]);
|
|
|
|
jint methodCount = arguments[2];
|
2010-09-10 21:05:29 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < methodCount; ++i) {
|
|
|
|
if (methods[i].function) {
|
2010-11-04 17:02:09 +00:00
|
|
|
object method = findMethodOrNull
|
|
|
|
(t, jclassVmClass(t, *c), methods[i].name, methods[i].signature);
|
|
|
|
|
|
|
|
if (method == 0 or (methodFlags(t, method) & ACC_NATIVE) == 0) {
|
|
|
|
// The JNI spec says we must throw a NoSuchMethodError in this
|
|
|
|
// case, but that would prevent using a code shrinker like
|
|
|
|
// ProGuard effectively. Instead, we just ignore it.
|
|
|
|
} else {
|
|
|
|
registerNative(t, method, methods[i].function);
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
jint JNICALL
|
|
|
|
RegisterNatives(Thread* t, jclass c, const JNINativeMethod* methods,
|
|
|
|
jint methodCount)
|
|
|
|
{
|
|
|
|
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
|
|
|
|
reinterpret_cast<uintptr_t>(methods),
|
|
|
|
methodCount };
|
|
|
|
|
|
|
|
return run(t, registerNatives, arguments) ? 0 : -1;
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jint JNICALL
|
|
|
|
UnregisterNatives(Thread* t, jclass c)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-09-14 16:49:41 +00:00
|
|
|
unregisterNatives(t, *c);
|
2010-09-10 21:05:29 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
uint64_t
|
|
|
|
monitorOp(Thread* t, uintptr_t* arguments)
|
|
|
|
{
|
|
|
|
void (*op)(Thread*, object)
|
|
|
|
= reinterpret_cast<void (*)(Thread*, object)>(arguments[0]);
|
|
|
|
|
|
|
|
jobject o = reinterpret_cast<jobject>(arguments[1]);
|
|
|
|
|
|
|
|
op(t, *o);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
acquire0(Thread* t, object o)
|
|
|
|
{
|
|
|
|
return acquire(t, o);
|
|
|
|
}
|
|
|
|
|
2007-11-14 23:22:29 +00:00
|
|
|
jint JNICALL
|
|
|
|
MonitorEnter(Thread* t, jobject o)
|
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[]
|
|
|
|
= { reinterpret_cast<uintptr_t>(voidPointer(acquire0)),
|
|
|
|
reinterpret_cast<uintptr_t>(o) };
|
2007-11-14 23:22:29 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return run(t, monitorOp, arguments) ? 0 : -1;
|
|
|
|
}
|
2007-11-14 23:22:29 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
void
|
|
|
|
release0(Thread* t, object o)
|
|
|
|
{
|
|
|
|
return acquire(t, o);
|
2007-11-14 23:22:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jint JNICALL
|
|
|
|
MonitorExit(Thread* t, jobject o)
|
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
uintptr_t arguments[]
|
|
|
|
= { reinterpret_cast<uintptr_t>(voidPointer(release0)),
|
|
|
|
reinterpret_cast<uintptr_t>(o) };
|
2007-11-14 23:22:29 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return run(t, monitorOp, arguments) ? 0 : -1;
|
2007-11-14 23:22:29 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jint JNICALL
|
2007-09-10 23:33:58 +00:00
|
|
|
GetJavaVM(Thread* t, Machine** m)
|
2007-09-07 23:20:21 +00:00
|
|
|
{
|
2007-09-24 01:39:03 +00:00
|
|
|
*m = t->m;
|
2007-09-10 23:33:58 +00:00
|
|
|
return 0;
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jboolean JNICALL
|
|
|
|
IsSameObject(Thread* t, jobject a, jobject b)
|
|
|
|
{
|
2008-04-01 22:40:53 +00:00
|
|
|
if (a and b) {
|
|
|
|
ENTER(t, Thread::ActiveState);
|
2007-09-07 23:20:21 +00:00
|
|
|
|
2008-04-01 22:40:53 +00:00
|
|
|
return *a == *b;
|
|
|
|
} else {
|
|
|
|
return a == b;
|
|
|
|
}
|
2007-09-07 23:20:21 +00:00
|
|
|
}
|
|
|
|
|
2008-07-14 17:02:43 +00:00
|
|
|
struct JavaVMOption {
|
|
|
|
char* optionString;
|
|
|
|
void* extraInfo;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct JavaVMInitArgs {
|
2007-10-25 15:04:13 +00:00
|
|
|
jint version;
|
|
|
|
|
2008-07-14 17:02:43 +00:00
|
|
|
jint nOptions;
|
|
|
|
JavaVMOption* options;
|
|
|
|
jboolean ignoreUnrecognized;
|
2007-10-25 15:04:13 +00:00
|
|
|
};
|
|
|
|
|
2008-07-14 17:02:43 +00:00
|
|
|
int
|
|
|
|
parseSize(const char* s)
|
|
|
|
{
|
|
|
|
unsigned length = strlen(s);
|
2009-08-27 00:26:44 +00:00
|
|
|
RUNTIME_ARRAY(char, buffer, length + 1);
|
2008-07-14 17:02:43 +00:00
|
|
|
if (length == 0) {
|
|
|
|
return 0;
|
|
|
|
} else if (s[length - 1] == 'k') {
|
2009-08-27 00:26:44 +00:00
|
|
|
memcpy(RUNTIME_ARRAY_BODY(buffer), s, length - 1);
|
2010-09-17 01:43:27 +00:00
|
|
|
RUNTIME_ARRAY_BODY(buffer)[length - 1] = 0;
|
2009-08-27 00:26:44 +00:00
|
|
|
return atoi(RUNTIME_ARRAY_BODY(buffer)) * 1024;
|
2008-07-14 17:02:43 +00:00
|
|
|
} else if (s[length - 1] == 'm') {
|
2009-08-27 00:26:44 +00:00
|
|
|
memcpy(RUNTIME_ARRAY_BODY(buffer), s, length - 1);
|
2010-09-17 01:43:27 +00:00
|
|
|
RUNTIME_ARRAY_BODY(buffer)[length - 1] = 0;
|
2009-08-27 00:26:44 +00:00
|
|
|
return atoi(RUNTIME_ARRAY_BODY(buffer)) * 1024 * 1024;
|
2008-07-14 17:02:43 +00:00
|
|
|
} else {
|
|
|
|
return atoi(s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-07-14 17:51:20 +00:00
|
|
|
void
|
|
|
|
append(char** p, const char* value, unsigned length, char tail)
|
|
|
|
{
|
|
|
|
if (length) {
|
|
|
|
memcpy(*p, value, length);
|
|
|
|
*p += length;
|
|
|
|
*((*p)++) = tail;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-26 19:41:31 +00:00
|
|
|
void
|
|
|
|
boot(Thread* t)
|
|
|
|
{
|
|
|
|
enter(t, Thread::ActiveState);
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
t->javaThread = t->m->classpath->makeThread(t, 0);
|
|
|
|
|
|
|
|
setRoot(t, Machine::NullPointerException, makeThrowable
|
|
|
|
(t, Machine::NullPointerExceptionType));
|
2010-11-26 19:41:31 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
setRoot(t, Machine::ArithmeticException,
|
|
|
|
makeThrowable(t, Machine::ArithmeticExceptionType));
|
2010-12-20 00:47:21 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
setRoot(t, Machine::ArrayIndexOutOfBoundsException,
|
|
|
|
makeThrowable(t, Machine::ArrayIndexOutOfBoundsExceptionType));
|
|
|
|
|
|
|
|
setRoot(t, Machine::OutOfMemoryError,
|
|
|
|
makeThrowable(t, Machine::OutOfMemoryErrorType));
|
|
|
|
|
|
|
|
setRoot(t, Machine::FinalizerThread, t->m->classpath->makeThread(t, t));
|
|
|
|
|
|
|
|
threadDaemon(t, root(t, Machine::FinalizerThread)) = true;
|
2010-11-26 19:41:31 +00:00
|
|
|
|
|
|
|
t->m->classpath->boot(t);
|
|
|
|
|
|
|
|
enter(t, Thread::IdleState);
|
|
|
|
}
|
|
|
|
|
2010-04-15 17:11:10 +00:00
|
|
|
} // namespace local
|
|
|
|
|
2007-07-27 00:06:05 +00:00
|
|
|
} // namespace
|
|
|
|
|
|
|
|
namespace vm {
|
|
|
|
|
|
|
|
void
|
2007-09-10 23:33:58 +00:00
|
|
|
populateJNITables(JavaVMVTable* vmTable, JNIEnvVTable* envTable)
|
|
|
|
{
|
|
|
|
memset(vmTable, 0, sizeof(JavaVMVTable));
|
|
|
|
|
2010-04-15 17:11:10 +00:00
|
|
|
vmTable->DestroyJavaVM = local::DestroyJavaVM;
|
|
|
|
vmTable->AttachCurrentThread = local::AttachCurrentThread;
|
|
|
|
vmTable->AttachCurrentThreadAsDaemon = local::AttachCurrentThreadAsDaemon;
|
|
|
|
vmTable->DetachCurrentThread = local::DetachCurrentThread;
|
|
|
|
vmTable->GetEnv = local::GetEnv;
|
2007-09-10 23:33:58 +00:00
|
|
|
|
|
|
|
memset(envTable, 0, sizeof(JNIEnvVTable));
|
|
|
|
|
2010-04-15 17:11:10 +00:00
|
|
|
envTable->GetVersion = local::GetVersion;
|
|
|
|
envTable->GetStringLength = local::GetStringLength;
|
|
|
|
envTable->GetStringChars = local::GetStringChars;
|
|
|
|
envTable->ReleaseStringChars = local::ReleaseStringChars;
|
2010-09-10 21:05:29 +00:00
|
|
|
envTable->GetStringRegion = local::GetStringRegion;
|
|
|
|
envTable->GetStringCritical = local::GetStringCritical;
|
|
|
|
envTable->ReleaseStringCritical = local::ReleaseStringCritical;
|
2010-04-15 17:11:10 +00:00
|
|
|
envTable->GetStringUTFLength = local::GetStringUTFLength;
|
|
|
|
envTable->GetStringUTFChars = local::GetStringUTFChars;
|
|
|
|
envTable->ReleaseStringUTFChars = local::ReleaseStringUTFChars;
|
2010-09-10 21:05:29 +00:00
|
|
|
envTable->GetStringUTFRegion = local::GetStringUTFRegion;
|
2010-04-15 17:11:10 +00:00
|
|
|
envTable->GetArrayLength = local::GetArrayLength;
|
|
|
|
envTable->NewString = local::NewString;
|
|
|
|
envTable->NewStringUTF = local::NewStringUTF;
|
2010-09-10 21:05:29 +00:00
|
|
|
envTable->DefineClass = local::DefineClass;
|
2010-04-15 17:11:10 +00:00
|
|
|
envTable->FindClass = local::FindClass;
|
|
|
|
envTable->ThrowNew = local::ThrowNew;
|
2010-09-10 21:05:29 +00:00
|
|
|
envTable->Throw = local::Throw;
|
2010-04-15 17:11:10 +00:00
|
|
|
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;
|
2010-09-10 21:05:29 +00:00
|
|
|
envTable->IsAssignableFrom = local::IsAssignableFrom;
|
2010-04-15 17:11:10 +00:00
|
|
|
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;
|
2010-09-10 21:05:29 +00:00
|
|
|
envTable->EnsureLocalCapacity = local::EnsureLocalCapacity;
|
2010-04-15 17:11:10 +00:00
|
|
|
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;
|
2010-09-10 21:05:29 +00:00
|
|
|
envTable->RegisterNatives = local::RegisterNatives;
|
|
|
|
envTable->UnregisterNatives = local::UnregisterNatives;
|
2010-04-15 17:11:10 +00:00
|
|
|
envTable->MonitorEnter = local::MonitorEnter;
|
|
|
|
envTable->MonitorExit = local::MonitorExit;
|
|
|
|
envTable->GetJavaVM = local::GetJavaVM;
|
|
|
|
envTable->IsSameObject = local::IsSameObject;
|
2007-07-27 00:06:05 +00:00
|
|
|
}
|
2007-07-20 14:36:31 +00:00
|
|
|
|
2007-07-06 15:24:06 +00:00
|
|
|
} // namespace vm
|
2007-10-25 15:04:13 +00:00
|
|
|
|
2008-07-14 17:02:43 +00:00
|
|
|
#define BOOTSTRAP_PROPERTY "avian.bootstrap"
|
2008-11-11 15:20:49 +00:00
|
|
|
#define CRASHDIR_PROPERTY "avian.crash.dir"
|
2010-11-05 19:18:28 +00:00
|
|
|
#define EMBED_PREFIX_PROPERTY "avian.embed.prefix"
|
2008-07-14 17:02:43 +00:00
|
|
|
#define CLASSPATH_PROPERTY "java.class.path"
|
2010-09-21 00:38:38 +00:00
|
|
|
#define JAVA_HOME_PROPERTY "java.home"
|
2008-07-14 17:51:20 +00:00
|
|
|
#define BOOTCLASSPATH_PREPEND_OPTION "bootclasspath/p"
|
|
|
|
#define BOOTCLASSPATH_OPTION "bootclasspath"
|
|
|
|
#define BOOTCLASSPATH_APPEND_OPTION "bootclasspath/a"
|
2008-11-11 15:20:49 +00:00
|
|
|
#define BOOTCLASSPATH_APPEND_OPTION "bootclasspath/a"
|
2008-07-14 17:02:43 +00:00
|
|
|
|
2007-10-25 15:04:13 +00:00
|
|
|
extern "C" JNIEXPORT jint JNICALL
|
2008-07-14 17:02:43 +00:00
|
|
|
JNI_GetDefaultJavaVMInitArgs(void*)
|
2007-10-25 15:04:13 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" JNIEXPORT jint JNICALL
|
|
|
|
JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
|
|
|
|
{
|
2010-04-15 17:11:10 +00:00
|
|
|
local::JavaVMInitArgs* a = static_cast<local::JavaVMInitArgs*>(args);
|
2007-10-25 15:04:13 +00:00
|
|
|
|
2008-07-14 17:02:43 +00:00
|
|
|
unsigned heapLimit = 0;
|
2008-03-31 03:43:43 +00:00
|
|
|
const char* bootLibrary = 0;
|
2008-07-14 17:02:43 +00:00
|
|
|
const char* classpath = 0;
|
2010-09-21 00:38:38 +00:00
|
|
|
const char* javaHome = AVIAN_JAVA_HOME;
|
2010-11-05 19:18:28 +00:00
|
|
|
const char* embedPrefix = AVIAN_EMBED_PREFIX;
|
2008-07-14 17:51:20 +00:00
|
|
|
const char* bootClasspathPrepend = "";
|
2010-10-24 17:49:12 +00:00
|
|
|
const char* bootClasspath = 0;
|
2008-07-14 17:51:20 +00:00
|
|
|
const char* bootClasspathAppend = "";
|
2008-11-11 15:20:49 +00:00
|
|
|
const char* crashDumpDirectory = 0;
|
|
|
|
|
|
|
|
unsigned propertyCount = 0;
|
2008-07-14 17:02:43 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < a->nOptions; ++i) {
|
2008-07-14 17:51:20 +00:00
|
|
|
if (strncmp(a->options[i].optionString, "-X", 2) == 0) {
|
|
|
|
const char* p = a->options[i].optionString + 2;
|
|
|
|
if (strncmp(p, "mx", 2) == 0) {
|
2010-04-15 17:11:10 +00:00
|
|
|
heapLimit = local::parseSize(p + 2);
|
2008-07-14 17:51:20 +00:00
|
|
|
} else if (strncmp(p, BOOTCLASSPATH_PREPEND_OPTION ":",
|
|
|
|
sizeof(BOOTCLASSPATH_PREPEND_OPTION)) == 0)
|
|
|
|
{
|
|
|
|
bootClasspathPrepend = p + sizeof(BOOTCLASSPATH_PREPEND_OPTION);
|
|
|
|
} else if (strncmp(p, BOOTCLASSPATH_OPTION ":",
|
|
|
|
sizeof(BOOTCLASSPATH_OPTION)) == 0)
|
|
|
|
{
|
|
|
|
bootClasspath = p + sizeof(BOOTCLASSPATH_OPTION);
|
|
|
|
} else if (strncmp(p, BOOTCLASSPATH_APPEND_OPTION ":",
|
|
|
|
sizeof(BOOTCLASSPATH_APPEND_OPTION)) == 0)
|
|
|
|
{
|
|
|
|
bootClasspathAppend = p + sizeof(BOOTCLASSPATH_APPEND_OPTION);
|
|
|
|
}
|
2008-07-14 17:02:43 +00:00
|
|
|
} else if (strncmp(a->options[i].optionString, "-D", 2) == 0) {
|
|
|
|
const char* p = a->options[i].optionString + 2;
|
2008-11-11 15:20:49 +00:00
|
|
|
if (strncmp(p, BOOTSTRAP_PROPERTY "=",
|
|
|
|
sizeof(BOOTSTRAP_PROPERTY)) == 0)
|
2008-03-31 03:43:43 +00:00
|
|
|
{
|
2008-07-14 17:02:43 +00:00
|
|
|
bootLibrary = p + sizeof(BOOTSTRAP_PROPERTY);
|
2008-11-11 15:20:49 +00:00
|
|
|
} else if (strncmp(p, CRASHDIR_PROPERTY "=",
|
|
|
|
sizeof(CRASHDIR_PROPERTY)) == 0)
|
|
|
|
{
|
|
|
|
crashDumpDirectory = p + sizeof(CRASHDIR_PROPERTY);
|
2008-07-14 17:02:43 +00:00
|
|
|
} else if (strncmp(p, CLASSPATH_PROPERTY "=",
|
|
|
|
sizeof(CLASSPATH_PROPERTY)) == 0)
|
|
|
|
{
|
|
|
|
classpath = p + sizeof(CLASSPATH_PROPERTY);
|
2010-09-21 00:38:38 +00:00
|
|
|
} else if (strncmp(p, JAVA_HOME_PROPERTY "=",
|
|
|
|
sizeof(JAVA_HOME_PROPERTY)) == 0)
|
|
|
|
{
|
|
|
|
javaHome = p + sizeof(JAVA_HOME_PROPERTY);
|
2010-11-05 19:18:28 +00:00
|
|
|
} else if (strncmp(p, EMBED_PREFIX_PROPERTY "=",
|
|
|
|
sizeof(EMBED_PREFIX_PROPERTY)) == 0)
|
|
|
|
{
|
|
|
|
embedPrefix = p + sizeof(EMBED_PREFIX_PROPERTY);
|
2007-10-25 18:33:43 +00:00
|
|
|
}
|
2008-07-14 17:02:43 +00:00
|
|
|
|
2008-11-11 15:20:49 +00:00
|
|
|
++ propertyCount;
|
2007-10-25 18:33:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-07-14 17:02:43 +00:00
|
|
|
if (heapLimit == 0) heapLimit = 128 * 1024 * 1024;
|
|
|
|
|
|
|
|
if (classpath == 0) classpath = ".";
|
|
|
|
|
2010-09-20 23:31:23 +00:00
|
|
|
System* s = makeSystem(crashDumpDirectory);
|
|
|
|
Heap* h = makeHeap(s, heapLimit);
|
2010-11-05 19:18:28 +00:00
|
|
|
Classpath* c = makeClasspath(s, h, javaHome, embedPrefix);
|
2010-10-24 17:49:12 +00:00
|
|
|
|
|
|
|
if (bootClasspath == 0) {
|
|
|
|
bootClasspath = c->bootClasspath();
|
|
|
|
}
|
2010-09-20 23:31:23 +00:00
|
|
|
|
2008-07-14 17:51:20 +00:00
|
|
|
unsigned bcppl = strlen(bootClasspathPrepend);
|
|
|
|
unsigned bcpl = strlen(bootClasspath);
|
|
|
|
unsigned bcpal = strlen(bootClasspathAppend);
|
2008-07-14 17:02:43 +00:00
|
|
|
|
2010-10-24 17:49:12 +00:00
|
|
|
unsigned bootClasspathBufferSize = bcppl + bcpl + bcpal + 3;
|
2010-09-14 16:49:41 +00:00
|
|
|
RUNTIME_ARRAY(char, bootClasspathBuffer, bootClasspathBufferSize);
|
|
|
|
char* bootClasspathPointer = RUNTIME_ARRAY_BODY(bootClasspathBuffer);
|
2010-09-20 23:31:23 +00:00
|
|
|
local::append(&bootClasspathPointer, bootClasspathPrepend, bcppl,
|
2010-10-24 17:49:12 +00:00
|
|
|
bcpl + bcpal ? PATH_SEPARATOR : 0);
|
2010-09-14 16:49:41 +00:00
|
|
|
local::append(&bootClasspathPointer, bootClasspath, bcpl,
|
|
|
|
bcpal ? PATH_SEPARATOR : 0);
|
|
|
|
local::append(&bootClasspathPointer, bootClasspathAppend, bcpal, 0);
|
2008-07-14 17:02:43 +00:00
|
|
|
|
2010-09-14 16:49:41 +00:00
|
|
|
Finder* bf = makeFinder
|
2010-11-05 19:18:28 +00:00
|
|
|
(s, h, RUNTIME_ARRAY_BODY(bootClasspathBuffer), bootLibrary);
|
|
|
|
Finder* af = makeFinder(s, h, classpath, bootLibrary);
|
2009-11-28 04:15:12 +00:00
|
|
|
Processor* p = makeProcessor(s, h, true);
|
2008-03-31 03:43:43 +00:00
|
|
|
|
2008-11-11 15:20:49 +00:00
|
|
|
const char** properties = static_cast<const char**>
|
|
|
|
(h->allocate(sizeof(const char*) * propertyCount));
|
|
|
|
const char** propertyPointer = properties;
|
|
|
|
for (int i = 0; i < a->nOptions; ++i) {
|
|
|
|
if (strncmp(a->options[i].optionString, "-D", 2) == 0) {
|
|
|
|
*(propertyPointer++) = a->options[i].optionString + 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-04-13 18:15:04 +00:00
|
|
|
*m = new (h->allocate(sizeof(Machine)))
|
2010-09-14 16:49:41 +00:00
|
|
|
Machine(s, h, bf, af, p, c, properties, propertyCount);
|
2008-03-31 03:43:43 +00:00
|
|
|
|
2007-10-25 15:04:13 +00:00
|
|
|
*t = p->makeThread(*m, 0, 0);
|
|
|
|
|
2010-11-26 19:41:31 +00:00
|
|
|
local::boot(*t);
|
|
|
|
|
2007-10-25 15:04:13 +00:00
|
|
|
return 0;
|
|
|
|
}
|