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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-19 20:27:03 +00:00
|
|
|
jint JNICALL
|
|
|
|
DestroyJavaVM(Machine* m)
|
|
|
|
{
|
|
|
|
Thread* t; AttachCurrentThread(m, &t, 0);
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
{ ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
shutDown(t);
|
|
|
|
}
|
|
|
|
|
|
|
|
int exitCode = (t->exception ? -1 : 0);
|
|
|
|
|
|
|
|
t->exit();
|
|
|
|
|
|
|
|
return exitCode;
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2007-10-26 21:23:54 +00:00
|
|
|
jstring JNICALL
|
|
|
|
NewString(Thread* t, const jchar* chars, jsize size)
|
|
|
|
{
|
2009-11-18 18:01:47 +00:00
|
|
|
if (chars == 0) return 0;
|
|
|
|
|
2007-10-26 21:23:54 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
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-09-10 21:05:29 +00:00
|
|
|
return 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
|
2007-07-07 23:47:35 +00:00
|
|
|
NewStringUTF(Thread* t, const char* chars)
|
|
|
|
{
|
2009-11-18 18:01:47 +00:00
|
|
|
if (chars == 0) return 0;
|
|
|
|
|
2007-07-07 23:47:35 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-09-10 21:05:29 +00:00
|
|
|
object array = parseUtf8(t, chars, strlen(chars));
|
2007-10-27 00:04:20 +00:00
|
|
|
|
2010-09-10 21:05:29 +00:00
|
|
|
return makeLocalReference
|
|
|
|
(t, t->m->classpath->makeString
|
|
|
|
(t, array, 0, cast<uintptr_t>(array, BytesPerWord) - 1));
|
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-09-10 21:05:29 +00:00
|
|
|
jclass JNICALL
|
|
|
|
DefineClass(Thread* t, const char*, jobject loader, const jbyte* buffer,
|
|
|
|
jsize length)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
object c = defineClass
|
2010-09-14 16:49:41 +00:00
|
|
|
(t, loader ? *loader : root(t, Machine::BootLoader),
|
2010-09-10 21:05:29 +00:00
|
|
|
reinterpret_cast<const uint8_t*>(buffer), length);
|
|
|
|
|
|
|
|
return makeLocalReference(t, c == 0 ? 0 : getJClass(t, c));
|
|
|
|
}
|
|
|
|
|
2007-09-07 00:21:52 +00:00
|
|
|
jclass JNICALL
|
2007-07-27 00:06:05 +00:00
|
|
|
FindClass(Thread* t, const char* name)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
object c = resolveClass
|
|
|
|
(t, caller ? classLoader(t, methodClass(t, caller))
|
|
|
|
: root(t, Machine::AppLoader), n);
|
2010-09-01 16:13:52 +00:00
|
|
|
|
|
|
|
return makeLocalReference(t, c == 0 ? 0 : getJClass(t, c));
|
2007-07-27 00:06:05 +00:00
|
|
|
}
|
|
|
|
|
2007-09-07 00:21:52 +00:00
|
|
|
jint JNICALL
|
2007-07-27 00:06:05 +00:00
|
|
|
ThrowNew(Thread* t, jclass c, const char* message)
|
|
|
|
{
|
|
|
|
if (t->exception) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2007-09-07 23:20:21 +00:00
|
|
|
jmethodID JNICALL
|
|
|
|
GetMethodID(Thread* t, jclass c, const char* name, const char* spec)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-03-21 00:36:53 +00:00
|
|
|
object method = findMethod(t, c, name, spec);
|
2010-12-06 00:37:13 +00:00
|
|
|
if (UNLIKELY(t->exception)) return 0;
|
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
|
|
|
|
2008-08-15 18:32:33 +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
|
|
|
|
GetStaticMethodID(Thread* t, jclass c, const char* name, const char* spec)
|
2007-09-07 00:21:52 +00:00
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
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
|
|
|
if (UNLIKELY(t->exception)) return 0;
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2007-11-14 23:22:29 +00:00
|
|
|
jobject JNICALL
|
|
|
|
NewObjectV(Thread* t, jclass c, jmethodID m, va_list a)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
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);
|
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
t->m->processor->invokeList(t, getMethod(t, m), o, true, a);
|
2007-11-14 23:22:29 +00:00
|
|
|
|
|
|
|
return makeLocalReference(t, o);
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
2007-09-07 00:21:52 +00:00
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
object method = getMethod(t, m);
|
2008-04-01 17:37:59 +00:00
|
|
|
return makeLocalReference
|
|
|
|
(t, t->m->processor->invokeList(t, method, *o, true, a));
|
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
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
object method = getMethod(t, m);
|
2008-04-01 17:37:59 +00:00
|
|
|
object r = t->m->processor->invokeList(t, method, *o, true, a);
|
2009-08-19 20:27:03 +00:00
|
|
|
return (r ? (intValue(t, r) != 0) : false);
|
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
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
object method = getMethod(t, m);
|
2008-04-01 17:37:59 +00:00
|
|
|
object r = t->m->processor->invokeList(t, method, *o, true, a);
|
2009-08-19 20:27:03 +00:00
|
|
|
return (r ? intValue(t, r) : 0);
|
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
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
object method = getMethod(t, m);
|
2008-04-01 17:37:59 +00:00
|
|
|
object r = t->m->processor->invokeList(t, method, *o, true, a);
|
2009-08-19 20:27:03 +00:00
|
|
|
return (r ? intValue(t, r) : 0);
|
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
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
object method = getMethod(t, m);
|
2008-04-01 17:37:59 +00:00
|
|
|
object r = t->m->processor->invokeList(t, method, *o, true, a);
|
2009-08-19 20:27:03 +00:00
|
|
|
return (r ? intValue(t, r) : 0);
|
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
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
object method = getMethod(t, m);
|
2008-04-01 17:37:59 +00:00
|
|
|
object r = t->m->processor->invokeList(t, method, *o, true, a);
|
2009-08-19 20:27:03 +00:00
|
|
|
return (r ? intValue(t, r) : 0);
|
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
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
object method = getMethod(t, m);
|
2008-04-01 17:37:59 +00:00
|
|
|
object r = t->m->processor->invokeList(t, method, *o, true, a);
|
2009-08-19 20:27:03 +00:00
|
|
|
return (r ? longValue(t, r) : 0);
|
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
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
object method = getMethod(t, m);
|
2008-04-01 17:37:59 +00:00
|
|
|
object r = t->m->processor->invokeList(t, method, *o, true, a);
|
2009-08-19 20:27:03 +00:00
|
|
|
return (r ? bitsToFloat(intValue(t, r)) : 0);
|
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
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
object method = getMethod(t, m);
|
2008-04-01 17:37:59 +00:00
|
|
|
object r = t->m->processor->invokeList(t, method, *o, true, a);
|
2009-08-19 20:27:03 +00:00
|
|
|
return (r ? bitsToDouble(longValue(t, r)) : 0);
|
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
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
object method = getMethod(t, m);
|
2008-04-01 17:37:59 +00:00
|
|
|
t->m->processor->invokeList(t, method, *o, true, a);
|
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
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2007-09-24 01:39:03 +00:00
|
|
|
return makeLocalReference(t, t->m->processor->invokeList
|
2008-08-15 18:32:33 +00:00
|
|
|
(t, getStaticMethod(t, m), 0, true, a));
|
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
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a);
|
2009-08-19 20:27:03 +00:00
|
|
|
return (r ? (intValue(t, r) != 0) : false);
|
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
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a);
|
2009-08-19 20:27:03 +00:00
|
|
|
return (r ? intValue(t, r) : 0);
|
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
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a);
|
2009-08-19 20:27:03 +00:00
|
|
|
return (r ? intValue(t, r) : 0);
|
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
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a);
|
2009-08-19 20:27:03 +00:00
|
|
|
return (r ? intValue(t, r) : 0);
|
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
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a);
|
2009-08-19 20:27:03 +00:00
|
|
|
return (r ? intValue(t, r) : 0);
|
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
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a);
|
2009-08-19 20:27:03 +00:00
|
|
|
return (r ? longValue(t, r) : 0);
|
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
|
|
|
{
|
2007-09-07 23:20:21 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a);
|
2009-08-19 20:27:03 +00:00
|
|
|
return (r ? bitsToFloat(intValue(t, r)) : 0);
|
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
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a);
|
2009-08-19 20:27:03 +00:00
|
|
|
return (r ? bitsToDouble(longValue(t, r)) : 0);
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2008-08-15 18:32:33 +00:00
|
|
|
t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a);
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
jfieldID JNICALL
|
|
|
|
GetFieldID(Thread* t, jclass c, const char* name, const char* spec)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-09-01 16:13:52 +00:00
|
|
|
object field = resolveField(t, jclassVmClass(t, *c), name, spec);
|
2007-09-07 23:20:21 +00:00
|
|
|
if (UNLIKELY(t->exception)) return 0;
|
|
|
|
|
|
|
|
return fieldOffset(t, field);
|
|
|
|
}
|
|
|
|
|
|
|
|
jfieldID JNICALL
|
|
|
|
GetStaticFieldID(Thread* t, jclass c, const char* name, const char* spec)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-09-01 16:13:52 +00:00
|
|
|
object field = resolveField(t, jclassVmClass(t, *c), name, spec);
|
2007-09-07 23:20:21 +00:00
|
|
|
if (UNLIKELY(t->exception)) return 0;
|
|
|
|
|
|
|
|
return fieldOffset(t, field);
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2007-10-25 15:04:13 +00:00
|
|
|
jobjectArray JNICALL
|
|
|
|
NewObjectArray(Thread* t, jsize length, jclass class_, jobject init)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
return makeLocalReference(t, a);
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2007-09-10 23:33:58 +00:00
|
|
|
jbooleanArray JNICALL
|
|
|
|
NewBooleanArray(Thread* t, jsize length)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2009-03-04 03:05:48 +00:00
|
|
|
return makeLocalReference(t, makeBooleanArray(t, length));
|
2007-09-10 23:33:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jbyteArray JNICALL
|
|
|
|
NewByteArray(Thread* t, jsize length)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2009-03-04 03:05:48 +00:00
|
|
|
return makeLocalReference(t, makeByteArray(t, length));
|
2007-09-10 23:33:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jcharArray JNICALL
|
|
|
|
NewCharArray(Thread* t, jsize length)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2009-03-04 03:05:48 +00:00
|
|
|
return makeLocalReference(t, makeCharArray(t, length));
|
2007-09-10 23:33:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jshortArray JNICALL
|
|
|
|
NewShortArray(Thread* t, jsize length)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2009-03-04 03:05:48 +00:00
|
|
|
return makeLocalReference(t, makeShortArray(t, length));
|
2007-09-10 23:33:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jintArray JNICALL
|
|
|
|
NewIntArray(Thread* t, jsize length)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2009-03-04 03:05:48 +00:00
|
|
|
return makeLocalReference(t, makeIntArray(t, length));
|
2007-09-10 23:33:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jlongArray JNICALL
|
|
|
|
NewLongArray(Thread* t, jsize length)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2009-03-04 03:05:48 +00:00
|
|
|
return makeLocalReference(t, makeLongArray(t, length));
|
2007-09-10 23:33:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jfloatArray JNICALL
|
|
|
|
NewFloatArray(Thread* t, jsize length)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2009-03-04 03:05:48 +00:00
|
|
|
return makeLocalReference(t, makeFloatArray(t, length));
|
2007-09-10 23:33:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
jdoubleArray JNICALL
|
|
|
|
NewDoubleArray(Thread* t, jsize length)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2009-03-04 03:05:48 +00:00
|
|
|
return makeLocalReference(t, makeDoubleArray(t, length));
|
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-09-10 21:05:29 +00:00
|
|
|
jint JNICALL
|
|
|
|
RegisterNatives(Thread* t, jclass c, const JNINativeMethod* methods,
|
|
|
|
jint methodCount)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2007-11-14 23:22:29 +00:00
|
|
|
jint JNICALL
|
|
|
|
MonitorEnter(Thread* t, jobject o)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
acquire(t, *o);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
jint JNICALL
|
|
|
|
MonitorExit(Thread* t, jobject o)
|
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
release(t, *o);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
if (t->exception == 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
|
|
|
setRoot(t, Machine::NullPointerException, makeThrowable
|
2010-11-26 19:41:31 +00:00
|
|
|
(t, Machine::NullPointerExceptionType));
|
|
|
|
|
|
|
|
if (t->exception == 0) {
|
|
|
|
setRoot(t, Machine::ArrayIndexOutOfBoundsException,
|
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
|
|
|
makeThrowable(t, Machine::ArrayIndexOutOfBoundsExceptionType));
|
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;
|
|
|
|
}
|