mirror of
https://github.com/corda/corda.git
synced 2025-06-01 23:20:54 +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);
|
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
|
virtual void
|
||||||
clearInterrupted(Thread*)
|
clearInterrupted(Thread*)
|
||||||
{
|
{
|
||||||
|
@ -341,6 +341,15 @@ makeClassNameString(Thread* t, object name)
|
|||||||
return makeString(t, "%s", s);
|
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
|
void
|
||||||
interceptFileOperations(Thread*);
|
interceptFileOperations(Thread*);
|
||||||
|
|
||||||
@ -537,6 +546,44 @@ class MyClasspath : public Classpath {
|
|||||||
return thread;
|
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
|
virtual void
|
||||||
clearInterrupted(Thread* t)
|
clearInterrupted(Thread* t)
|
||||||
{
|
{
|
||||||
@ -2260,6 +2307,213 @@ resolveExceptionJTypes(Thread* t, object loader, object addendum)
|
|||||||
return array;
|
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
|
void
|
||||||
setProperty(Thread* t, object method, object properties,
|
setProperty(Thread* t, object method, object properties,
|
||||||
const char* name, const void* value, const char* format = "%s")
|
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))
|
if (((not publicOnly) or (methodFlags(t, vmMethod) & ACC_PUBLIC))
|
||||||
and byteArrayBody(t, methodName(t, vmMethod), 0) != '<')
|
and byteArrayBody(t, methodName(t, vmMethod), 0) != '<')
|
||||||
{
|
{
|
||||||
object name = intern
|
object method = makeJmethod(t, vmMethod, i);
|
||||||
(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);
|
|
||||||
|
|
||||||
assert(t, ai < objectArrayLength(t, array));
|
assert(t, ai < objectArrayLength(t, array));
|
||||||
|
|
||||||
@ -4483,50 +4679,7 @@ jvmGetClassDeclaredFields(Thread* t, uintptr_t* arguments)
|
|||||||
PROTECT(t, vmField);
|
PROTECT(t, vmField);
|
||||||
|
|
||||||
if ((not publicOnly) or (fieldFlags(t, vmField) & ACC_PUBLIC)) {
|
if ((not publicOnly) or (fieldFlags(t, vmField) & ACC_PUBLIC)) {
|
||||||
object name = intern
|
object field = makeJfield(t, vmField, i);
|
||||||
(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);
|
|
||||||
|
|
||||||
assert(t, ai < objectArrayLength(t, array));
|
assert(t, ai < objectArrayLength(t, array));
|
||||||
|
|
||||||
@ -4577,47 +4730,7 @@ jvmGetClassDeclaredConstructors(Thread* t, uintptr_t* arguments)
|
|||||||
(&byteArrayBody(t, methodName(t, vmMethod), 0)),
|
(&byteArrayBody(t, methodName(t, vmMethod), 0)),
|
||||||
"<init>") == 0)
|
"<init>") == 0)
|
||||||
{
|
{
|
||||||
unsigned parameterCount;
|
object method = makeJconstructor(t, vmMethod, i);
|
||||||
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);
|
|
||||||
|
|
||||||
assert(t, ai < objectArrayLength(t, array));
|
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
|
uint64_t
|
||||||
registerNatives(Thread* t, uintptr_t* arguments)
|
registerNatives(Thread* t, uintptr_t* arguments)
|
||||||
{
|
{
|
||||||
@ -3607,6 +3683,10 @@ populateJNITables(JavaVMVTable* vmTable, JNIEnvVTable* envTable)
|
|||||||
envTable->IsSameObject = local::IsSameObject;
|
envTable->IsSameObject = local::IsSameObject;
|
||||||
envTable->PushLocalFrame = local::PushLocalFrame;
|
envTable->PushLocalFrame = local::PushLocalFrame;
|
||||||
envTable->PopLocalFrame = local::PopLocalFrame;
|
envTable->PopLocalFrame = local::PopLocalFrame;
|
||||||
|
envTable->FromReflectedMethod = local::FromReflectedMethod;
|
||||||
|
envTable->ToReflectedMethod = local::ToReflectedMethod;
|
||||||
|
envTable->FromReflectedField = local::FromReflectedField;
|
||||||
|
envTable->ToReflectedField = local::ToReflectedField;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace vm
|
} // namespace vm
|
||||||
|
@ -1536,6 +1536,18 @@ class Classpath {
|
|||||||
virtual object
|
virtual object
|
||||||
makeThread(Thread* t, Thread* parent) = 0;
|
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
|
virtual void
|
||||||
clearInterrupted(Thread* t) = 0;
|
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 {
|
public class JNI {
|
||||||
static {
|
static {
|
||||||
System.loadLibrary("test");
|
System.loadLibrary("test");
|
||||||
@ -37,7 +41,27 @@ public class JNI {
|
|||||||
float a13, float a14, float a15, double a16, float a17, float a18,
|
float a13, float a14, float a15, double a16, float a17, float a18,
|
||||||
float a19, float a20);
|
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
|
expect(addDoubles
|
||||||
(1.0d, 2.0d, 3.0d, 4.0d, 5.0d, 6.0d, 7.0d, 8.0d, 9.0d, 10.0d, 11.0d,
|
(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)
|
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.0f) == 42.0f);
|
||||||
expect(doEcho(42.0d) == 42.0d);
|
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);
|
(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
|
extern "C" JNIEXPORT jobject JNICALL
|
||||||
Java_Buffers_allocateNative(JNIEnv* e, jclass, jint capacity)
|
Java_Buffers_allocateNative(JNIEnv* e, jclass, jint capacity)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user