mirror of
https://github.com/corda/corda.git
synced 2025-03-17 17:45:17 +00:00
implement JNI reflection methods
These include FromReflectedMethod, ToReflectedMethod, FromReflectedField, and ToReflectedField.
This commit is contained in:
parent
7b07b5b9a3
commit
d200019d10
@ -54,6 +54,37 @@ class MyClasspath : public Classpath {
|
||||
root(t, Machine::BootLoader), 0, 0, group, 0);
|
||||
}
|
||||
|
||||
virtual object
|
||||
makeJMethod(Thread* t, object vmMethod)
|
||||
{
|
||||
PROTECT(t, vmMethod);
|
||||
|
||||
object jmethod = makeJmethod(t, vmMethod, false);
|
||||
|
||||
return byteArrayBody(t, methodName(t, vmMethod), 0) == '<'
|
||||
? makeJconstructor(t, jmethod) : jmethod;
|
||||
}
|
||||
|
||||
virtual object
|
||||
getVMMethod(Thread* t, object jmethod)
|
||||
{
|
||||
return objectClass(t, jmethod) == type(t, Machine::JmethodType)
|
||||
? jmethodVmMethod(t, jmethod)
|
||||
: jmethodVmMethod(t, jconstructorMethod(t, jmethod));
|
||||
}
|
||||
|
||||
virtual object
|
||||
makeJField(Thread* t, object vmField)
|
||||
{
|
||||
return makeJfield(t, vmField, false);
|
||||
}
|
||||
|
||||
virtual object
|
||||
getVMField(Thread* t, object jfield)
|
||||
{
|
||||
return jfieldVmField(t, jfield);
|
||||
}
|
||||
|
||||
virtual void
|
||||
clearInterrupted(Thread*)
|
||||
{
|
||||
|
@ -341,6 +341,15 @@ makeClassNameString(Thread* t, object name)
|
||||
return makeString(t, "%s", s);
|
||||
}
|
||||
|
||||
object
|
||||
makeJmethod(Thread* t, object vmMethod, int index = -1);
|
||||
|
||||
object
|
||||
makeJconstructor(Thread* t, object vmMethod, int index = -1);
|
||||
|
||||
object
|
||||
makeJfield(Thread* t, object vmField, int index = -1);
|
||||
|
||||
void
|
||||
interceptFileOperations(Thread*);
|
||||
|
||||
@ -537,6 +546,44 @@ class MyClasspath : public Classpath {
|
||||
return thread;
|
||||
}
|
||||
|
||||
virtual object
|
||||
makeJMethod(Thread* t, object vmMethod)
|
||||
{
|
||||
PROTECT(t, vmMethod);
|
||||
|
||||
return byteArrayBody(t, methodName(t, vmMethod), 0) == '<'
|
||||
? makeJconstructor(t, vmMethod)
|
||||
: makeJmethod(t, vmMethod);
|
||||
}
|
||||
|
||||
virtual object
|
||||
getVMMethod(Thread* t, object jmethod)
|
||||
{
|
||||
return objectClass(t, jmethod) == type(t, Machine::JmethodType)
|
||||
? arrayBody
|
||||
(t, classMethodTable
|
||||
(t, jclassVmClass(t, jmethodClazz(t, jmethod))),
|
||||
jmethodSlot(t, jmethod))
|
||||
: arrayBody
|
||||
(t, classMethodTable
|
||||
(t, jclassVmClass(t, jconstructorClazz(t, jmethod))),
|
||||
jconstructorSlot(t, jmethod));
|
||||
}
|
||||
|
||||
virtual object
|
||||
makeJField(Thread* t, object vmField)
|
||||
{
|
||||
return makeJfield(t, vmField);
|
||||
}
|
||||
|
||||
virtual object
|
||||
getVMField(Thread* t, object jfield)
|
||||
{
|
||||
return arrayBody
|
||||
(t, classFieldTable
|
||||
(t, jclassVmClass(t, jfieldClazz(t, jfield))), jfieldSlot(t, jfield));
|
||||
}
|
||||
|
||||
virtual void
|
||||
clearInterrupted(Thread* t)
|
||||
{
|
||||
@ -2260,6 +2307,213 @@ resolveExceptionJTypes(Thread* t, object loader, object addendum)
|
||||
return array;
|
||||
}
|
||||
|
||||
object
|
||||
makeJmethod(Thread* t, object vmMethod, int index)
|
||||
{
|
||||
PROTECT(t, vmMethod);
|
||||
|
||||
object name = intern
|
||||
(t, t->m->classpath->makeString
|
||||
(t, methodName(t, vmMethod), 0, byteArrayLength
|
||||
(t, methodName(t, vmMethod)) - 1));
|
||||
PROTECT(t, name);
|
||||
|
||||
unsigned parameterCount;
|
||||
unsigned returnTypeSpec;
|
||||
object parameterTypes = local::resolveParameterJTypes
|
||||
(t, classLoader(t, methodClass(t, vmMethod)), methodSpec(t, vmMethod),
|
||||
¶meterCount, &returnTypeSpec);
|
||||
PROTECT(t, parameterTypes);
|
||||
|
||||
object returnType = local::resolveJType
|
||||
(t, classLoader(t, methodClass(t, vmMethod)), reinterpret_cast<char*>
|
||||
(&byteArrayBody(t, methodSpec(t, vmMethod), returnTypeSpec)),
|
||||
byteArrayLength(t, methodSpec(t, vmMethod)) - 1 - returnTypeSpec);
|
||||
PROTECT(t, returnType);
|
||||
|
||||
object exceptionTypes = local::resolveExceptionJTypes
|
||||
(t, classLoader(t, methodClass(t, vmMethod)),
|
||||
methodAddendum(t, vmMethod));
|
||||
PROTECT(t, exceptionTypes);
|
||||
|
||||
object signature;
|
||||
object annotationTable;
|
||||
object annotationDefault;
|
||||
object addendum = methodAddendum(t, vmMethod);
|
||||
if (addendum) {
|
||||
signature = addendumSignature(t, addendum);
|
||||
if (signature) {
|
||||
signature = t->m->classpath->makeString
|
||||
(t, signature, 0, byteArrayLength(t, signature) - 1);
|
||||
}
|
||||
|
||||
annotationTable = addendumAnnotationTable(t, addendum);
|
||||
|
||||
annotationDefault = methodAddendumAnnotationDefault(t, addendum);
|
||||
} else {
|
||||
signature = 0;
|
||||
annotationTable = 0;
|
||||
annotationDefault = 0;
|
||||
}
|
||||
|
||||
PROTECT(t, signature);
|
||||
PROTECT(t, annotationTable);
|
||||
PROTECT(t, annotationDefault);
|
||||
|
||||
if (annotationTable or annotationDefault) {
|
||||
object runtimeData = getClassRuntimeData(t, methodClass(t, vmMethod));
|
||||
|
||||
set(t, runtimeData, ClassRuntimeDataPool,
|
||||
addendumPool(t, methodAddendum(t, vmMethod)));
|
||||
}
|
||||
|
||||
if (index == -1) {
|
||||
object table = classMethodTable(t, methodClass(t, vmMethod));
|
||||
for (unsigned i = 0; i < arrayLength(t, table); ++i) {
|
||||
if (vmMethod == arrayBody(t, table, i)) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expect(t, index != -1);
|
||||
|
||||
object jclass = getJClass(t, methodClass(t, vmMethod));
|
||||
|
||||
return makeJmethod
|
||||
(t, true, 0, jclass, index, name, returnType, parameterTypes,
|
||||
exceptionTypes, methodFlags(t, vmMethod), signature, 0, annotationTable,
|
||||
0, annotationDefault, 0, 0, 0);
|
||||
}
|
||||
|
||||
object
|
||||
makeJconstructor(Thread* t, object vmMethod, int index)
|
||||
{
|
||||
PROTECT(t, vmMethod);
|
||||
|
||||
unsigned parameterCount;
|
||||
unsigned returnTypeSpec;
|
||||
object parameterTypes = local::resolveParameterJTypes
|
||||
(t, classLoader(t, methodClass(t, vmMethod)), methodSpec(t, vmMethod),
|
||||
¶meterCount, &returnTypeSpec);
|
||||
PROTECT(t, parameterTypes);
|
||||
|
||||
object exceptionTypes = local::resolveExceptionJTypes
|
||||
(t, classLoader(t, methodClass(t, vmMethod)),
|
||||
methodAddendum(t, vmMethod));
|
||||
PROTECT(t, exceptionTypes);
|
||||
|
||||
object signature;
|
||||
object annotationTable;
|
||||
object addendum = methodAddendum(t, vmMethod);
|
||||
if (addendum) {
|
||||
signature = addendumSignature(t, addendum);
|
||||
if (signature) {
|
||||
signature = t->m->classpath->makeString
|
||||
(t, signature, 0, byteArrayLength(t, signature) - 1);
|
||||
}
|
||||
|
||||
annotationTable = addendumAnnotationTable(t, addendum);
|
||||
} else {
|
||||
signature = 0;
|
||||
annotationTable = 0;
|
||||
}
|
||||
|
||||
PROTECT(t, signature);
|
||||
PROTECT(t, annotationTable);
|
||||
|
||||
if (annotationTable) {
|
||||
object runtimeData = getClassRuntimeData(t, methodClass(t, vmMethod));
|
||||
|
||||
set(t, runtimeData, ClassRuntimeDataPool,
|
||||
addendumPool(t, methodAddendum(t, vmMethod)));
|
||||
}
|
||||
|
||||
if (index == -1) {
|
||||
object table = classMethodTable(t, methodClass(t, vmMethod));
|
||||
for (unsigned i = 0; i < arrayLength(t, table); ++i) {
|
||||
if (vmMethod == arrayBody(t, table, i)) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expect(t, index != -1);
|
||||
|
||||
object jclass = getJClass(t, methodClass(t, vmMethod));
|
||||
|
||||
return makeJconstructor
|
||||
(t, true, 0, jclass, index, parameterTypes, exceptionTypes, methodFlags
|
||||
(t, vmMethod), signature, 0, annotationTable, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
object
|
||||
makeJfield(Thread* t, object vmField, int index)
|
||||
{
|
||||
PROTECT(t, vmField);
|
||||
|
||||
object name = intern
|
||||
(t, t->m->classpath->makeString
|
||||
(t, fieldName(t, vmField), 0, byteArrayLength
|
||||
(t, fieldName(t, vmField)) - 1));
|
||||
PROTECT(t, name);
|
||||
|
||||
object type = local::resolveClassBySpec
|
||||
(t, classLoader(t, fieldClass(t, vmField)),
|
||||
reinterpret_cast<char*>
|
||||
(&byteArrayBody(t, fieldSpec(t, vmField), 0)),
|
||||
byteArrayLength(t, fieldSpec(t, vmField)) - 1);
|
||||
PROTECT(t, type);
|
||||
|
||||
type = getJClass(t, type);
|
||||
|
||||
object signature;
|
||||
object annotationTable;
|
||||
object addendum = fieldAddendum(t, vmField);
|
||||
if (addendum) {
|
||||
signature = addendumSignature(t, addendum);
|
||||
if (signature) {
|
||||
signature = t->m->classpath->makeString
|
||||
(t, signature, 0, byteArrayLength(t, signature) - 1);
|
||||
}
|
||||
|
||||
annotationTable = addendumAnnotationTable(t, addendum);
|
||||
} else {
|
||||
signature = 0;
|
||||
annotationTable = 0;
|
||||
}
|
||||
|
||||
PROTECT(t, signature);
|
||||
PROTECT(t, annotationTable);
|
||||
|
||||
if (annotationTable) {
|
||||
object runtimeData = getClassRuntimeData(t, fieldClass(t, vmField));
|
||||
|
||||
set(t, runtimeData, ClassRuntimeDataPool,
|
||||
addendumPool(t, fieldAddendum(t, vmField)));
|
||||
}
|
||||
|
||||
if (index == -1) {
|
||||
object table = classFieldTable(t, fieldClass(t, vmField));
|
||||
for (unsigned i = 0; i < arrayLength(t, table); ++i) {
|
||||
if (vmField == arrayBody(t, table, i)) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expect(t, index != -1);
|
||||
|
||||
object jclass = getJClass(t, fieldClass(t, vmField));
|
||||
|
||||
return makeJfield
|
||||
(t, true, 0, jclass, index, name, type, fieldFlags
|
||||
(t, vmField), signature, 0, annotationTable, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
setProperty(Thread* t, object method, object properties,
|
||||
const char* name, const void* value, const char* format = "%s")
|
||||
@ -4380,65 +4634,7 @@ jvmGetClassDeclaredMethods(Thread* t, uintptr_t* arguments)
|
||||
if (((not publicOnly) or (methodFlags(t, vmMethod) & ACC_PUBLIC))
|
||||
and byteArrayBody(t, methodName(t, vmMethod), 0) != '<')
|
||||
{
|
||||
object name = intern
|
||||
(t, t->m->classpath->makeString
|
||||
(t, methodName(t, vmMethod), 0, byteArrayLength
|
||||
(t, methodName(t, vmMethod)) - 1));
|
||||
PROTECT(t, name);
|
||||
|
||||
unsigned parameterCount;
|
||||
unsigned returnTypeSpec;
|
||||
object parameterTypes = local::resolveParameterJTypes
|
||||
(t, classLoader(t, jclassVmClass(t, *c)), methodSpec(t, vmMethod),
|
||||
¶meterCount, &returnTypeSpec);
|
||||
PROTECT(t, parameterTypes);
|
||||
|
||||
object returnType = local::resolveJType
|
||||
(t, classLoader(t, jclassVmClass(t, *c)), reinterpret_cast<char*>
|
||||
(&byteArrayBody(t, methodSpec(t, vmMethod), returnTypeSpec)),
|
||||
byteArrayLength(t, methodSpec(t, vmMethod)) - 1 - returnTypeSpec);
|
||||
PROTECT(t, returnType);
|
||||
|
||||
object exceptionTypes = local::resolveExceptionJTypes
|
||||
(t, classLoader(t, jclassVmClass(t, *c)),
|
||||
methodAddendum(t, vmMethod));
|
||||
PROTECT(t, exceptionTypes);
|
||||
|
||||
object signature;
|
||||
object annotationTable;
|
||||
object annotationDefault;
|
||||
object addendum = methodAddendum(t, vmMethod);
|
||||
if (addendum) {
|
||||
signature = addendumSignature(t, addendum);
|
||||
if (signature) {
|
||||
signature = t->m->classpath->makeString
|
||||
(t, signature, 0, byteArrayLength(t, signature) - 1);
|
||||
}
|
||||
|
||||
annotationTable = addendumAnnotationTable(t, addendum);
|
||||
|
||||
annotationDefault = methodAddendumAnnotationDefault(t, addendum);
|
||||
} else {
|
||||
signature = 0;
|
||||
annotationTable = 0;
|
||||
annotationDefault = 0;
|
||||
}
|
||||
|
||||
if (annotationTable or annotationDefault) {
|
||||
PROTECT(t, signature);
|
||||
PROTECT(t, annotationTable);
|
||||
PROTECT(t, annotationDefault);
|
||||
|
||||
object runtimeData = getClassRuntimeData(t, jclassVmClass(t, *c));
|
||||
|
||||
set(t, runtimeData, ClassRuntimeDataPool,
|
||||
addendumPool(t, methodAddendum(t, vmMethod)));
|
||||
}
|
||||
|
||||
object method = makeJmethod
|
||||
(t, true, 0, *c, i, name, returnType, parameterTypes, exceptionTypes,
|
||||
methodFlags(t, vmMethod), signature, 0, annotationTable, 0,
|
||||
annotationDefault, 0, 0, 0);
|
||||
object method = makeJmethod(t, vmMethod, i);
|
||||
|
||||
assert(t, ai < objectArrayLength(t, array));
|
||||
|
||||
@ -4483,50 +4679,7 @@ jvmGetClassDeclaredFields(Thread* t, uintptr_t* arguments)
|
||||
PROTECT(t, vmField);
|
||||
|
||||
if ((not publicOnly) or (fieldFlags(t, vmField) & ACC_PUBLIC)) {
|
||||
object name = intern
|
||||
(t, t->m->classpath->makeString
|
||||
(t, fieldName(t, vmField), 0, byteArrayLength
|
||||
(t, fieldName(t, vmField)) - 1));
|
||||
PROTECT(t, name);
|
||||
|
||||
object type = local::resolveClassBySpec
|
||||
(t, classLoader(t, jclassVmClass(t, *c)),
|
||||
reinterpret_cast<char*>
|
||||
(&byteArrayBody(t, fieldSpec(t, vmField), 0)),
|
||||
byteArrayLength(t, fieldSpec(t, vmField)) - 1);
|
||||
PROTECT(t, type);
|
||||
|
||||
type = getJClass(t, type);
|
||||
|
||||
object signature;
|
||||
object annotationTable;
|
||||
object addendum = fieldAddendum(t, vmField);
|
||||
if (addendum) {
|
||||
signature = addendumSignature(t, addendum);
|
||||
if (signature) {
|
||||
signature = t->m->classpath->makeString
|
||||
(t, signature, 0, byteArrayLength(t, signature) - 1);
|
||||
}
|
||||
|
||||
annotationTable = addendumAnnotationTable(t, addendum);
|
||||
} else {
|
||||
signature = 0;
|
||||
annotationTable = 0;
|
||||
}
|
||||
|
||||
if (annotationTable) {
|
||||
PROTECT(t, signature);
|
||||
PROTECT(t, annotationTable);
|
||||
|
||||
object runtimeData = getClassRuntimeData(t, jclassVmClass(t, *c));
|
||||
|
||||
set(t, runtimeData, ClassRuntimeDataPool,
|
||||
addendumPool(t, fieldAddendum(t, vmField)));
|
||||
}
|
||||
|
||||
object field = makeJfield
|
||||
(t, true, 0, *c, i, name, type, fieldFlags
|
||||
(t, vmField), signature, 0, annotationTable, 0, 0, 0, 0);
|
||||
object field = makeJfield(t, vmField, i);
|
||||
|
||||
assert(t, ai < objectArrayLength(t, array));
|
||||
|
||||
@ -4577,47 +4730,7 @@ jvmGetClassDeclaredConstructors(Thread* t, uintptr_t* arguments)
|
||||
(&byteArrayBody(t, methodName(t, vmMethod), 0)),
|
||||
"<init>") == 0)
|
||||
{
|
||||
unsigned parameterCount;
|
||||
unsigned returnTypeSpec;
|
||||
object parameterTypes = local::resolveParameterJTypes
|
||||
(t, classLoader(t, jclassVmClass(t, *c)), methodSpec(t, vmMethod),
|
||||
¶meterCount, &returnTypeSpec);
|
||||
PROTECT(t, parameterTypes);
|
||||
|
||||
object exceptionTypes = local::resolveExceptionJTypes
|
||||
(t, classLoader(t, jclassVmClass(t, *c)),
|
||||
methodAddendum(t, vmMethod));
|
||||
PROTECT(t, exceptionTypes);
|
||||
|
||||
object signature;
|
||||
object annotationTable;
|
||||
object addendum = methodAddendum(t, vmMethod);
|
||||
if (addendum) {
|
||||
signature = addendumSignature(t, addendum);
|
||||
if (signature) {
|
||||
signature = t->m->classpath->makeString
|
||||
(t, signature, 0, byteArrayLength(t, signature) - 1);
|
||||
}
|
||||
|
||||
annotationTable = addendumAnnotationTable(t, addendum);
|
||||
} else {
|
||||
signature = 0;
|
||||
annotationTable = 0;
|
||||
}
|
||||
|
||||
if (annotationTable) {
|
||||
PROTECT(t, signature);
|
||||
PROTECT(t, annotationTable);
|
||||
|
||||
object runtimeData = getClassRuntimeData(t, jclassVmClass(t, *c));
|
||||
|
||||
set(t, runtimeData, ClassRuntimeDataPool,
|
||||
addendumPool(t, methodAddendum(t, vmMethod)));
|
||||
}
|
||||
|
||||
object method = makeJconstructor
|
||||
(t, true, 0, *c, i, parameterTypes, exceptionTypes, methodFlags
|
||||
(t, vmMethod), signature, 0, annotationTable, 0, 0, 0, 0);
|
||||
object method = makeJconstructor(t, vmMethod, i);
|
||||
|
||||
assert(t, ai < objectArrayLength(t, array));
|
||||
|
||||
|
@ -3154,6 +3154,82 @@ ReleasePrimitiveArrayCritical(Thread* t, jarray, void*, jint)
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t
|
||||
fromReflectedMethod(Thread* t, uintptr_t* arguments)
|
||||
{
|
||||
jobject m = reinterpret_cast<jobject>(arguments[0]);
|
||||
|
||||
return methodID(t, t->m->classpath->getVMMethod(t, *m));
|
||||
}
|
||||
|
||||
jmethodID JNICALL
|
||||
FromReflectedMethod(Thread* t, jobject method)
|
||||
{
|
||||
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(method) };
|
||||
|
||||
return reinterpret_cast<jmethodID>(run(t, fromReflectedMethod, arguments));
|
||||
}
|
||||
|
||||
uint64_t
|
||||
toReflectedMethod(Thread* t, uintptr_t* arguments)
|
||||
{
|
||||
jmethodID m = arguments[1];
|
||||
jboolean isStatic = arguments[2];
|
||||
|
||||
return reinterpret_cast<uintptr_t>
|
||||
(makeLocalReference
|
||||
(t, t->m->classpath->makeJMethod
|
||||
(t, isStatic ? getStaticMethod(t, m) : getMethod(t, m))));
|
||||
}
|
||||
|
||||
jobject JNICALL
|
||||
ToReflectedMethod(Thread* t, jclass c, jmethodID method, jboolean isStatic)
|
||||
{
|
||||
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
|
||||
reinterpret_cast<uintptr_t>(method),
|
||||
static_cast<uintptr_t>(isStatic) };
|
||||
|
||||
return reinterpret_cast<jobject>(run(t, toReflectedMethod, arguments));
|
||||
}
|
||||
|
||||
uint64_t
|
||||
fromReflectedField(Thread* t, uintptr_t* arguments)
|
||||
{
|
||||
jobject f = reinterpret_cast<jobject>(arguments[0]);
|
||||
|
||||
return fieldID(t, t->m->classpath->getVMField(t, *f));
|
||||
}
|
||||
|
||||
jfieldID JNICALL
|
||||
FromReflectedField(Thread* t, jobject field)
|
||||
{
|
||||
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(field) };
|
||||
|
||||
return reinterpret_cast<jfieldID>(run(t, fromReflectedField, arguments));
|
||||
}
|
||||
|
||||
uint64_t
|
||||
toReflectedField(Thread* t, uintptr_t* arguments)
|
||||
{
|
||||
jfieldID f = arguments[1];
|
||||
jboolean isStatic = arguments[2];
|
||||
|
||||
return reinterpret_cast<uintptr_t>
|
||||
(makeLocalReference
|
||||
(t, t->m->classpath->makeJField
|
||||
(t, isStatic ? getStaticField(t, f) : getField(t, f))));
|
||||
}
|
||||
|
||||
jobject JNICALL
|
||||
ToReflectedField(Thread* t, jclass c, jfieldID field, jboolean isStatic)
|
||||
{
|
||||
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
|
||||
reinterpret_cast<uintptr_t>(field),
|
||||
static_cast<uintptr_t>(isStatic) };
|
||||
|
||||
return reinterpret_cast<jobject>(run(t, toReflectedField, arguments));
|
||||
}
|
||||
|
||||
uint64_t
|
||||
registerNatives(Thread* t, uintptr_t* arguments)
|
||||
{
|
||||
@ -3607,6 +3683,10 @@ populateJNITables(JavaVMVTable* vmTable, JNIEnvVTable* envTable)
|
||||
envTable->IsSameObject = local::IsSameObject;
|
||||
envTable->PushLocalFrame = local::PushLocalFrame;
|
||||
envTable->PopLocalFrame = local::PopLocalFrame;
|
||||
envTable->FromReflectedMethod = local::FromReflectedMethod;
|
||||
envTable->ToReflectedMethod = local::ToReflectedMethod;
|
||||
envTable->FromReflectedField = local::FromReflectedField;
|
||||
envTable->ToReflectedField = local::ToReflectedField;
|
||||
}
|
||||
|
||||
} // namespace vm
|
||||
|
@ -1536,6 +1536,18 @@ class Classpath {
|
||||
virtual object
|
||||
makeThread(Thread* t, Thread* parent) = 0;
|
||||
|
||||
virtual object
|
||||
makeJMethod(Thread* t, object vmMethod) = 0;
|
||||
|
||||
virtual object
|
||||
getVMMethod(Thread* t, object jmethod) = 0;
|
||||
|
||||
virtual object
|
||||
makeJField(Thread* t, object vmField) = 0;
|
||||
|
||||
virtual object
|
||||
getVMField(Thread* t, object jfield) = 0;
|
||||
|
||||
virtual void
|
||||
clearInterrupted(Thread* t) = 0;
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class JNI {
|
||||
static {
|
||||
System.loadLibrary("test");
|
||||
@ -37,7 +41,27 @@ public class JNI {
|
||||
float a13, float a14, float a15, double a16, float a17, float a18,
|
||||
float a19, float a20);
|
||||
|
||||
public static void main(String[] args) {
|
||||
private static native long fromReflectedMethod(Object m);
|
||||
|
||||
private static native Object toReflectedMethod(Class c, long id,
|
||||
boolean isStatic);
|
||||
|
||||
private static native int callStaticIntMethod(Class c, long id);
|
||||
|
||||
private static native Object newObject(Class c, long id);
|
||||
|
||||
private static native long fromReflectedField(Field f);
|
||||
|
||||
private static native Field toReflectedField(Class c, long id,
|
||||
boolean isStatic);
|
||||
|
||||
private static native int getStaticIntField(Class c, long id);
|
||||
|
||||
public static int method242() { return 242; }
|
||||
|
||||
public static final int field950 = 950;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
expect(addDoubles
|
||||
(1.0d, 2.0d, 3.0d, 4.0d, 5.0d, 6.0d, 7.0d, 8.0d, 9.0d, 10.0d, 11.0d,
|
||||
12.0d, 13.0d, 14.0d, 15.0d, 16.0d, 17.0d, 18.0d, 19.0d, 20.0d)
|
||||
@ -55,5 +79,32 @@ public class JNI {
|
||||
|
||||
expect(doEcho(42.0f) == 42.0f);
|
||||
expect(doEcho(42.0d) == 42.0d);
|
||||
|
||||
expect(callStaticIntMethod
|
||||
(JNI.class, fromReflectedMethod
|
||||
(JNI.class.getMethod("method242"))) == 242);
|
||||
|
||||
expect(((Method) toReflectedMethod
|
||||
(JNI.class, fromReflectedMethod
|
||||
(JNI.class.getMethod("method242")), true))
|
||||
.getName().equals("method242"));
|
||||
|
||||
expect(newObject
|
||||
(JNI.class, fromReflectedMethod
|
||||
(JNI.class.getConstructor())) instanceof JNI);
|
||||
|
||||
expect(((Constructor) toReflectedMethod
|
||||
(JNI.class, fromReflectedMethod
|
||||
(JNI.class.getConstructor()), false))
|
||||
.getDeclaringClass().equals(JNI.class));
|
||||
|
||||
expect(getStaticIntField
|
||||
(JNI.class, fromReflectedField
|
||||
(JNI.class.getField("field950"))) == 950);
|
||||
|
||||
expect(toReflectedField
|
||||
(JNI.class, fromReflectedField
|
||||
(JNI.class.getField("field950")), true)
|
||||
.getName().equals("field950"));
|
||||
}
|
||||
}
|
||||
|
44
test/jni.cpp
44
test/jni.cpp
@ -57,6 +57,50 @@ Java_JNI_doEcho__D(JNIEnv* e, jclass c, jdouble f)
|
||||
(c, e->GetStaticMethodID(c, "echo", "(D)D"), array);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_JNI_fromReflectedMethod(JNIEnv* e, jclass, jobject method)
|
||||
{
|
||||
return reinterpret_cast<uintptr_t>(e->FromReflectedMethod(method));
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jobject JNICALL
|
||||
Java_JNI_toReflectedMethod(JNIEnv* e, jclass, jclass c, jlong id,
|
||||
jboolean isStatic)
|
||||
{
|
||||
return e->ToReflectedMethod(c, reinterpret_cast<jmethodID>(id), isStatic);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_JNI_callStaticIntMethod(JNIEnv* e, jclass, jclass c, jlong id)
|
||||
{
|
||||
return e->CallStaticIntMethod(c, reinterpret_cast<jmethodID>(id));
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jobject JNICALL
|
||||
Java_JNI_newObject(JNIEnv* e, jclass, jclass c, jlong id)
|
||||
{
|
||||
return e->NewObject(c, reinterpret_cast<jmethodID>(id));
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_JNI_fromReflectedField(JNIEnv* e, jclass, jobject field)
|
||||
{
|
||||
return reinterpret_cast<uintptr_t>(e->FromReflectedField(field));
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jobject JNICALL
|
||||
Java_JNI_toReflectedField(JNIEnv* e, jclass, jclass c, jlong id,
|
||||
jboolean isStatic)
|
||||
{
|
||||
return e->ToReflectedField(c, reinterpret_cast<jfieldID>(id), isStatic);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_JNI_getStaticIntField(JNIEnv* e, jclass, jclass c, jlong id)
|
||||
{
|
||||
return e->GetStaticIntField(c, reinterpret_cast<jfieldID>(id));
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jobject JNICALL
|
||||
Java_Buffers_allocateNative(JNIEnv* e, jclass, jint capacity)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user