/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ /* * Proxy JNI implementation. */ #include "nscore.h" #include "jvmmgr.h" #include "nsISecureEnv.h" #include "nsIJVMPlugin.h" #include "nsHashtable.h" #include "nsVoidArray.h" #include "plstr.h" #include "ProxyClassLoader.h" #include "ProxyJNI.h" #include "nsDataHashtable.h" #ifdef DEBUG #include "nsDebug.h" #endif // Method Signature Processing. static jni_type get_jni_type(char sig) { switch (sig) { case 'L': case '[': return jobject_type; case 'Z': return jboolean_type; case 'B': return jbyte_type; case 'C': return jchar_type; case 'S': return jshort_type; case 'I': return jint_type; case 'J': return jlong_type; case 'F': return jfloat_type; case 'D': return jdouble_type; case 'V': return jvoid_type; } return jvoid_type; } static PRBool get_method_type(const char* sig, PRUint32& arg_count, jni_type*& arg_types, jni_type& return_type) { arg_count = 0; if (sig[0] == '(') { nsVoidArray vec; ++sig; while (*sig != ')' && *sig) { char arg_sig = *sig; jni_type arg_type = get_jni_type(arg_sig); if (arg_type == jobject_type) { // could be an array or an object. while (*sig == '[') ++sig; if (*sig == 'L') { // skip over "className;" ++sig; while (*sig != ';') ++sig; } } // skip over scalar or ';'. ++sig; vec.AppendElement((void *) arg_type); } arg_count = vec.Count(); arg_types = new jni_type[arg_count]; for (int index = arg_count - 1; index >= 0; --index) arg_types[index] = jni_type((jint)NS_PTR_TO_INT32(vec.ElementAt(index))); if (*sig == ')') { char return_sig = *++sig; return_type = get_jni_type(return_sig); } } return PR_FALSE; } struct JNIMember { char* mName; char* mSignature; JNIMember(const char* name, const char* sig); ~JNIMember(); }; JNIMember::JNIMember(const char* name, const char* sig) : mName(NULL), mSignature(NULL) { mName = PL_strdup(name); mSignature = PL_strdup(sig); } JNIMember::~JNIMember() { PL_strfree(mName); PL_strfree(mSignature); } struct JNIField : JNIMember { jfieldID mFieldID; jni_type mFieldType; JNIField(const char* name, const char* sig, jfieldID fieldID); }; JNIField::JNIField(const char* name, const char* sig, jfieldID fieldID) : JNIMember(name, sig), mFieldID(fieldID), mFieldType(get_jni_type(*sig)) { } struct JNIMethod : JNIMember { jmethodID mMethodID; PRUint32 mArgCount; jni_type* mArgTypes; jni_type mReturnType; JNIMethod(const char* name, const char* sig, jmethodID methodID); ~JNIMethod(); jvalue* marshallArgs(va_list args); }; JNIMethod::JNIMethod(const char* name, const char* sig, jmethodID methodID) : JNIMember(name, sig), mMethodID(methodID), mArgCount(0), mArgTypes(NULL), mReturnType(jvoid_type) { get_method_type(sig, mArgCount, mArgTypes, mReturnType); } JNIMethod::~JNIMethod() { if (mArgTypes != NULL) delete[] mArgTypes; } /** * Copies an argument list into a jvalue array. */ jvalue* JNIMethod::marshallArgs(va_list args) { jvalue* jargs = NULL; PRUint32 argCount = mArgCount; if (argCount > 0) { jni_type* argTypes = mArgTypes; jargs = new jvalue[argCount]; if (jargs != NULL) { for (PRUint32 i = 0; i < argCount; i++) { switch (argTypes[i]) { case jobject_type: jargs[i].l = static_cast(va_arg(args, void*)); break; case jboolean_type: jargs[i].z = static_cast(va_arg(args, jint)); break; case jbyte_type: jargs[i].b = static_cast(va_arg(args, jint)); break; case jchar_type: jargs[i].c = static_cast(va_arg(args, jint)); break; case jshort_type: jargs[i].s = static_cast(va_arg(args, jint)); break; case jint_type: jargs[i].i = va_arg(args, jint); break; case jlong_type: jargs[i].j = va_arg(args, jlong); break; case jfloat_type: jargs[i].f = static_cast(va_arg(args, jdouble)); break; case jdouble_type: jargs[i].d = va_arg(args, jdouble); break; } } } } return jargs; } struct JavaClassMember { jclass clazz; void* memberID; JavaClassMember(jclass cl, void* mID) { clazz = cl; memberID = mID;} }; class JavaClassMemberKey : public PLDHashEntryHdr { public: typedef const JavaClassMember& KeyType; typedef const JavaClassMember* KeyTypePointer; JavaClassMemberKey(KeyTypePointer aKey) : mValue(*aKey) { } JavaClassMemberKey(const JavaClassMemberKey& toCopy) : mValue(toCopy.mValue) { } ~JavaClassMemberKey() { } KeyType GetKey() const { return mValue; } PRBool KeyEquals(KeyTypePointer aKey) const { return aKey->clazz == mValue.clazz && aKey->memberID == mValue.memberID; } static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } static PLDHashNumber HashKey(KeyTypePointer aKey) { PRUint32 v1 = NS_PTR_TO_INT32(aKey->clazz); PRUint32 v2 = NS_PTR_TO_INT32(aKey->memberID); return v1 ^ v2; } enum { ALLOW_MEMMOVE = PR_TRUE }; private: const JavaClassMember mValue; }; /** * Marshalls a va_list into a jvalue array, and destructor automatically * deletes when the args go out of scope. */ class MarshalledArgs { public: MarshalledArgs(JNIMethod* forMethod, va_list args) : mArgs(forMethod->marshallArgs(args)) {} ~MarshalledArgs() { if (mArgs != NULL) delete[] mArgs; } operator jvalue* () { return mArgs; } private: jvalue* mArgs; }; static jvalue kErrorValue; class ProxyJNIEnv : public JNIEnv { private: static JNINativeInterface_ theFuncs; static nsDataHashtable* theIDTable; nsISecureEnv* mSecureEnv; nsISecurityContext* mContext; jbool mInProxyFindClass; static ProxyJNIEnv& GetProxyEnv(JNIEnv* env) { return *(ProxyJNIEnv*)env; } nsISecurityContext* getContext() { if (!mContext) { return JVM_GetJSSecurityContext(); } else { mContext->AddRef(); return mContext; } } static jint JNICALL GetVersion(JNIEnv* env) { jint version = 0; nsISecureEnv* secureEnv = GetSecureEnv(env); nsresult result; result = secureEnv->GetVersion(&version); return version; } static jclass JNICALL DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len) { jclass outClass = NULL; nsISecureEnv* secureEnv = GetSecureEnv(env); nsresult result; result = secureEnv->DefineClass(name, loader, buf, len, &outClass); return outClass; } static jclass JNICALL FindClass(JNIEnv *env, const char *name) { jclass outClass = NULL; ProxyJNIEnv& proxyEnv = GetProxyEnv(env); nsISecureEnv* secureEnv = proxyEnv.mSecureEnv; nsresult result; result = secureEnv->FindClass(name, &outClass); if ((NS_FAILED(result) || !outClass) && !proxyEnv.mInProxyFindClass) { proxyEnv.mInProxyFindClass = JNI_TRUE; outClass = ProxyFindClass(env, name); proxyEnv.mInProxyFindClass = JNI_FALSE; } return outClass; } #ifdef JDK1_2 static jmethodID JNICALL FromReflectedMethod(JNIEnv *env, jobject method) { return NULL; } static jfieldID JNICALL FromReflectedField(JNIEnv *env, jobject field) { return NULL; } static jobject JNICALL ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID methodID, jboolean isStatic) { return NULL; } #endif static jclass JNICALL GetSuperclass(JNIEnv *env, jclass sub) { nsISecureEnv* secureEnv = GetSecureEnv(env); jclass outSuper = NULL; nsresult result; result = secureEnv->GetSuperclass(sub, &outSuper); return outSuper; } static jboolean JNICALL IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup) { nsISecureEnv* secureEnv = GetSecureEnv(env); jboolean outIsAssignable = PR_FALSE; nsresult result; result = secureEnv->IsAssignableFrom(sub, sup, &outIsAssignable); return outIsAssignable; } #ifdef JDK1_2 static jobject JNICALL ToReflectedField(JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic) { return NULL; } #endif static jint JNICALL Throw(JNIEnv *env, jthrowable obj) { nsISecureEnv* secureEnv = GetSecureEnv(env); jint outStatus = PR_FALSE; nsresult result; result = secureEnv->Throw(obj, &outStatus); return outStatus; } static jint JNICALL ThrowNew(JNIEnv *env, jclass clazz, const char *msg) { nsISecureEnv* secureEnv = GetSecureEnv(env); jint outStatus = PR_FALSE; nsresult result; result = secureEnv->ThrowNew(clazz, msg, &outStatus); return outStatus; } static jthrowable JNICALL ExceptionOccurred(JNIEnv *env) { nsISecureEnv* secureEnv = GetSecureEnv(env); jthrowable outThrowable = NULL; nsresult result; result = secureEnv->ExceptionOccurred(&outThrowable); return outThrowable; } static void JNICALL ExceptionDescribe(JNIEnv *env) { nsISecureEnv* secureEnv = GetSecureEnv(env); nsresult result; result = secureEnv->ExceptionDescribe(); } static void JNICALL ExceptionClear(JNIEnv *env) { nsISecureEnv* secureEnv = GetSecureEnv(env); nsresult result; result = secureEnv->ExceptionClear(); } static void JNICALL FatalError(JNIEnv *env, const char *msg) { nsISecureEnv* secureEnv = GetSecureEnv(env); nsresult result; result = secureEnv->FatalError(msg); } #ifdef JDK1_2 static jint JNICALL PushLocalFrame(JNIEnv *env, jint capacity) { return 0; } static jobject JNICALL PopLocalFrame(JNIEnv *env, jobject result) { return NULL; } #endif static jobject JNICALL NewGlobalRef(JNIEnv *env, jobject lobj) { nsISecureEnv* secureEnv = GetSecureEnv(env); jobject outGlobalRef = NULL; nsresult result; result = secureEnv->NewGlobalRef(lobj, &outGlobalRef); return outGlobalRef; } static void JNICALL DeleteGlobalRef(JNIEnv *env, jobject gref) { nsISecureEnv* secureEnv = GetSecureEnv(env); nsresult result; result = secureEnv->DeleteGlobalRef(gref); } static void JNICALL DeleteLocalRef(JNIEnv *env, jobject obj) { nsISecureEnv* secureEnv = GetSecureEnv(env); nsresult result; result = secureEnv->DeleteLocalRef(obj); } static jboolean JNICALL IsSameObject(JNIEnv *env, jobject obj1, jobject obj2) { nsISecureEnv* secureEnv = GetSecureEnv(env); jboolean outIsSameObject = PR_FALSE; nsresult result; result = secureEnv->IsSameObject(obj1, obj2, &outIsSameObject); return outIsSameObject; } #ifdef JDK1_2 static jobject JNICALL NewLocalRef(JNIEnv *env, jobject ref) { return NULL; } static jint JNICALL EnsureLocalCapacity(JNIEnv *env, jint capacity) { return -1; } #endif static jobject JNICALL AllocObject(JNIEnv *env, jclass clazz) { nsISecureEnv* secureEnv = GetSecureEnv(env); jobject outObject = NULL; nsresult result; result = secureEnv->AllocObject(clazz, &outObject); return outObject; } static jobject JNICALL NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...) { va_list args; va_start(args, methodID); jobject outObject = NewObjectV(env, clazz, methodID, args); va_end(args); return outObject; } static jobject JNICALL NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) { jobject outObject = NULL; // convert the va_list into an array of jvalues. JNIMethod* method = (JNIMethod*)methodID; MarshalledArgs jargs(method, args); ProxyJNIEnv& proxyEnv = GetProxyEnv(env); nsISecureEnv* secureEnv = GetSecureEnv(env); nsISecurityContext* securityContext = proxyEnv.getContext(); nsresult result; result = secureEnv->NewObject(clazz, method->mMethodID, jargs, &outObject, securityContext); NS_IF_RELEASE(securityContext); return outObject; } static jobject JNICALL NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) { jobject outObject = NULL; ProxyJNIEnv& proxyEnv = GetProxyEnv(env); nsISecureEnv* secureEnv = GetSecureEnv(env); JNIMethod* method = (JNIMethod*)methodID; nsISecurityContext* securityContext = proxyEnv.getContext(); nsresult result; result = secureEnv->NewObject(clazz, method->mMethodID, args, &outObject, securityContext); NS_IF_RELEASE(securityContext); return outObject; } static jclass JNICALL GetObjectClass(JNIEnv *env, jobject obj) { jclass outClass = NULL; nsISecureEnv* secureEnv = GetSecureEnv(env); nsresult result; result = secureEnv->GetObjectClass(obj, &outClass); return outClass; } static jboolean JNICALL IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz) { nsISecureEnv* secureEnv = GetSecureEnv(env); jboolean outIsInstanceOf = PR_FALSE; nsresult result; result = secureEnv->IsInstanceOf(obj, clazz, &outIsInstanceOf); return outIsInstanceOf; } static jmethodID JNICALL GetMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig) { nsISecureEnv* secureEnv = GetSecureEnv(env); jmethodID outMethodID = NULL; nsresult result = secureEnv->GetMethodID(clazz, name, sig, &outMethodID); if (result == NS_OK && outMethodID != NULL) { JavaClassMember key(clazz, outMethodID); JNIMethod* method; PRBool bFound = theIDTable && theIDTable->Get(key, (void **)&method); if (!bFound) { method = new JNIMethod(name, sig, outMethodID); if (theIDTable) theIDTable->Put(key, method); } outMethodID = jmethodID(method); } return outMethodID; } /** * Bottleneck methods called by method families below. */ // Virtual Invokers. static jvalue InvokeMethod(JNIEnv *env, jobject obj, JNIMethod* method, jvalue* args) { jvalue outValue; ProxyJNIEnv& proxyEnv = GetProxyEnv(env); nsISecureEnv* secureEnv = GetSecureEnv(env); nsISecurityContext* securityContext = proxyEnv.getContext(); nsresult rv = secureEnv->CallMethod(method->mReturnType, obj, method->mMethodID, args, &outValue, securityContext); NS_IF_RELEASE(securityContext); return NS_SUCCEEDED(rv) ? outValue : kErrorValue; } static jvalue InvokeMethod(JNIEnv *env, jobject obj, JNIMethod* method, va_list args) { // convert the va_list into an array of jvalues. MarshalledArgs jargs(method, args); return InvokeMethod(env, obj, method, jargs); } static void InvokeVoidMethod(JNIEnv *env, jobject obj, JNIMethod* method, jvalue* args) { jvalue unusedValue; ProxyJNIEnv& proxyEnv = GetProxyEnv(env); nsISecureEnv* secureEnv = GetSecureEnv(env); nsISecurityContext* securityContext = proxyEnv.getContext(); nsresult result; result = secureEnv->CallMethod(jvoid_type, obj, method->mMethodID, args, &unusedValue, securityContext); NS_IF_RELEASE(securityContext); } static void InvokeVoidMethod(JNIEnv *env, jobject obj, JNIMethod* method, va_list args) { // convert the va_list into an array of jvalues. MarshalledArgs jargs(method, args); InvokeVoidMethod(env, obj, method, jargs); } #define IMPLEMENT_METHOD_FAMILY(methodName, returnType, jvalueField) \ static returnType JNICALL methodName(JNIEnv *env, jobject obj, jmethodID methodID, ...) \ { \ va_list args; va_start(args, methodID); \ returnType result = InvokeMethod(env, obj, (JNIMethod*)methodID, args).jvalueField; \ va_end(args); \ return result; \ } \ \ static returnType JNICALL methodName##V(JNIEnv *env, jobject obj, jmethodID methodID, va_list args) \ { \ return InvokeMethod(env, obj, (JNIMethod*)methodID, args).jvalueField; \ } \ \ static returnType JNICALL methodName##A(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args) \ { \ return InvokeMethod(env, obj, (JNIMethod*)methodID, args).jvalueField; \ } \ // Pattern on which IMPLEMENT_METHOD_FAMILY is based. /* static jobject JNICALL CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...) { va_list args; va_start(args, methodID); jobject outObject = InvokeMethod(env, obj, (JNIMethod*)methodID, args).l; va_end(args); return outObject; } static jobject JNICALL CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args) { return InvokeMethod(env, obj, (JNIMethod*)methodID, args).l; } static jobject JNICALL CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args) { return InvokeMethod(env, obj, (JNIMethod*)methodID, args).l; } */ IMPLEMENT_METHOD_FAMILY(CallObjectMethod, jobject, l) IMPLEMENT_METHOD_FAMILY(CallBooleanMethod, jboolean, z) IMPLEMENT_METHOD_FAMILY(CallByteMethod, jbyte, b) IMPLEMENT_METHOD_FAMILY(CallCharMethod, jchar, c) IMPLEMENT_METHOD_FAMILY(CallShortMethod, jshort, s) IMPLEMENT_METHOD_FAMILY(CallIntMethod, jint, i) IMPLEMENT_METHOD_FAMILY(CallLongMethod, jlong, j) IMPLEMENT_METHOD_FAMILY(CallFloatMethod, jfloat, f) IMPLEMENT_METHOD_FAMILY(CallDoubleMethod, jdouble, d) #undef IMPLEMENT_METHOD_FAMILY static void JNICALL CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...) { va_list args; va_start(args, methodID); InvokeVoidMethod(env, obj, (JNIMethod*)methodID, args); va_end(args); } static void JNICALL CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args) { InvokeVoidMethod(env, obj, (JNIMethod*)methodID, args); } static void JNICALL CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args) { InvokeVoidMethod(env, obj, (JNIMethod*)methodID, args); } // Non-virtual Invokers. static jvalue InvokeNonVirtualMethod(JNIEnv *env, jobject obj, jclass clazz, JNIMethod* method, jvalue* args) { jvalue outValue; ProxyJNIEnv& proxyEnv = GetProxyEnv(env); nsISecureEnv* secureEnv = GetSecureEnv(env); nsISecurityContext* securityContext = proxyEnv.getContext(); nsresult rv = secureEnv->CallNonvirtualMethod(method->mReturnType, obj, clazz, method->mMethodID, args, &outValue, securityContext); NS_IF_RELEASE(securityContext); return NS_SUCCEEDED(rv) ? outValue : kErrorValue; } static jvalue InvokeNonVirtualMethod(JNIEnv *env, jobject obj, jclass clazz, JNIMethod* method, va_list args) { // convert the va_list into an array of jvalues. MarshalledArgs jargs(method, args); return InvokeNonVirtualMethod(env, obj, clazz, method, jargs); } static void InvokeNonVirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz, JNIMethod* method, jvalue* args) { jvalue unusedValue; ProxyJNIEnv& proxyEnv = GetProxyEnv(env); nsISecureEnv* secureEnv = GetSecureEnv(env); nsISecurityContext* securityContext = proxyEnv.getContext(); nsresult result; result = secureEnv->CallNonvirtualMethod(jvoid_type, obj, clazz, method->mMethodID, args, &unusedValue, securityContext); NS_IF_RELEASE(securityContext); } static void InvokeNonVirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz, JNIMethod* method, va_list args) { // convert the va_list into an array of jvalues. MarshalledArgs jargs(method, args); InvokeNonVirtualVoidMethod(env, obj, clazz, method, jargs); } #define IMPLEMENT_METHOD_FAMILY(methodName, returnType, jvalueField) \ static returnType JNICALL methodName(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...) \ { \ va_list args; va_start(args, methodID); \ returnType result = InvokeNonVirtualMethod(env, obj, clazz, (JNIMethod*)methodID, args).jvalueField; \ va_end(args); \ return result; \ } \ \ static returnType JNICALL methodName##V(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args) \ { \ return InvokeNonVirtualMethod(env, obj, clazz, (JNIMethod*)methodID, args).jvalueField; \ } \ \ static returnType JNICALL methodName##A(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args) \ { \ return InvokeNonVirtualMethod(env, obj, clazz, (JNIMethod*)methodID, args).jvalueField; \ } \ IMPLEMENT_METHOD_FAMILY(CallNonvirtualObjectMethod, jobject, l) IMPLEMENT_METHOD_FAMILY(CallNonvirtualBooleanMethod, jboolean, z) IMPLEMENT_METHOD_FAMILY(CallNonvirtualByteMethod, jbyte, b) IMPLEMENT_METHOD_FAMILY(CallNonvirtualCharMethod, jchar, c) IMPLEMENT_METHOD_FAMILY(CallNonvirtualShortMethod, jshort, s) IMPLEMENT_METHOD_FAMILY(CallNonvirtualIntMethod, jint, i) IMPLEMENT_METHOD_FAMILY(CallNonvirtualLongMethod, jlong, j) IMPLEMENT_METHOD_FAMILY(CallNonvirtualFloatMethod, jfloat, f) IMPLEMENT_METHOD_FAMILY(CallNonvirtualDoubleMethod, jdouble, d) #undef IMPLEMENT_METHOD_FAMILY static void JNICALL CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...) { va_list args; va_start(args, methodID); InvokeNonVirtualVoidMethod(env, obj, clazz, (JNIMethod*)methodID, args); va_end(args); } static void JNICALL CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args) { InvokeNonVirtualVoidMethod(env, obj, clazz, (JNIMethod*)methodID, args); } static void JNICALL CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args) { InvokeNonVirtualVoidMethod(env, obj, clazz, (JNIMethod*)methodID, args); } // Instance Fields static jfieldID JNICALL GetFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig) { nsISecureEnv* secureEnv = GetSecureEnv(env); jfieldID outFieldID = NULL; nsresult result = secureEnv->GetFieldID(clazz, name, sig, &outFieldID); if (result == NS_OK && outFieldID != NULL) { JavaClassMember key(clazz, outFieldID); JNIField* field; PRBool bFound = theIDTable && theIDTable->Get(key, (void **)&field); if (!bFound) { field = new JNIField(name, sig, outFieldID); if (theIDTable) theIDTable->Put(key, field); } outFieldID = jfieldID(field); } return outFieldID; } static jvalue GetField(JNIEnv* env, jobject obj, JNIField* field) { jvalue outValue; ProxyJNIEnv& proxyEnv = GetProxyEnv(env); nsISecureEnv* secureEnv = GetSecureEnv(env); nsISecurityContext* securityContext = proxyEnv.getContext(); nsresult rv = secureEnv->GetField(field->mFieldType, obj, field->mFieldID, &outValue, securityContext); NS_IF_RELEASE(securityContext); return NS_SUCCEEDED(rv) ? outValue : kErrorValue; } #define IMPLEMENT_GET_FIELD(methodName, returnType, jvalueField) \ static returnType JNICALL methodName(JNIEnv *env, jobject obj, jfieldID fieldID) \ { \ return GetField(env, obj, (JNIField*)fieldID).jvalueField; \ } \ IMPLEMENT_GET_FIELD(GetObjectField, jobject, l) IMPLEMENT_GET_FIELD(GetBooleanField, jboolean, z) IMPLEMENT_GET_FIELD(GetByteField, jbyte, b) IMPLEMENT_GET_FIELD(GetCharField, jchar, c) IMPLEMENT_GET_FIELD(GetShortField, jshort, s) IMPLEMENT_GET_FIELD(GetIntField, jint, i) IMPLEMENT_GET_FIELD(GetLongField, jlong, j) IMPLEMENT_GET_FIELD(GetFloatField, jfloat, f) IMPLEMENT_GET_FIELD(GetDoubleField, jdouble, d) #undef IMPLEMENT_GET_FIELD static void SetField(JNIEnv* env, jobject obj, JNIField* field, jvalue value) { ProxyJNIEnv& proxyEnv = GetProxyEnv(env); nsISecureEnv* secureEnv = GetSecureEnv(env); nsISecurityContext* securityContext = proxyEnv.getContext(); nsresult result; result = secureEnv->SetField(field->mFieldType, obj, field->mFieldID, value, securityContext); NS_IF_RELEASE(securityContext); } #define IMPLEMENT_SET_FIELD(methodName, fieldType, jvalueField) \ static void JNICALL methodName(JNIEnv *env, jobject obj, jfieldID fieldID, fieldType value) \ { \ jvalue fieldValue; \ fieldValue.jvalueField = value; \ SetField(env, obj, (JNIField*)fieldID, fieldValue); \ } \ IMPLEMENT_SET_FIELD(SetObjectField, jobject, l) IMPLEMENT_SET_FIELD(SetBooleanField, jboolean, z) IMPLEMENT_SET_FIELD(SetByteField, jbyte, b) IMPLEMENT_SET_FIELD(SetCharField, jchar, c) IMPLEMENT_SET_FIELD(SetShortField, jshort, s) IMPLEMENT_SET_FIELD(SetIntField, jint, i) IMPLEMENT_SET_FIELD(SetLongField, jlong, j) IMPLEMENT_SET_FIELD(SetFloatField, jfloat, f) IMPLEMENT_SET_FIELD(SetDoubleField, jdouble, d) #undef IMPLEMENT_SET_FIELD // Static Methods static jmethodID JNICALL GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig) { nsISecureEnv* secureEnv = GetSecureEnv(env); jmethodID outMethodID = NULL; nsresult result = secureEnv->GetStaticMethodID(clazz, name, sig, &outMethodID); if (result == NS_OK && outMethodID != NULL) { JavaClassMember key(clazz, outMethodID); JNIMethod* method; PRBool bFound = theIDTable && theIDTable->Get(key, (void **)&method); if (!bFound) { method = new JNIMethod(name, sig, outMethodID); if (theIDTable) theIDTable->Put(key, method); } outMethodID = jmethodID(method); } return outMethodID; } // jobject (JNICALL *CallStaticObjectMethod) (JNIEnv *env, jclass clazz, jmethodID methodID, ...); // Static Invokers. static jvalue InvokeStaticMethod(JNIEnv *env, jclass clazz, JNIMethod* method, jvalue* args) { jvalue outValue; ProxyJNIEnv& proxyEnv = GetProxyEnv(env); nsISecureEnv* secureEnv = GetSecureEnv(env); nsISecurityContext* securityContext = proxyEnv.getContext(); nsresult rv = secureEnv->CallStaticMethod(method->mReturnType, clazz, method->mMethodID, args, &outValue, securityContext); NS_IF_RELEASE(securityContext); return NS_SUCCEEDED(rv) ? outValue : kErrorValue; } static jvalue InvokeStaticMethod(JNIEnv *env, jclass clazz, JNIMethod* method, va_list args) { // convert the va_list into an array of jvalues. MarshalledArgs jargs(method, args); return InvokeStaticMethod(env, clazz, method, jargs); } static void InvokeStaticVoidMethod(JNIEnv *env, jclass clazz, JNIMethod* method, jvalue* args) { jvalue unusedValue; ProxyJNIEnv& proxyEnv = GetProxyEnv(env); nsISecureEnv* secureEnv = GetSecureEnv(env); nsISecurityContext* securityContext = proxyEnv.getContext(); nsresult result; result = secureEnv->CallStaticMethod(jvoid_type, clazz, method->mMethodID, args, &unusedValue, securityContext); NS_IF_RELEASE(securityContext); } static void InvokeStaticVoidMethod(JNIEnv *env, jclass clazz, JNIMethod* method, va_list args) { // convert the va_list into an array of jvalues. MarshalledArgs jargs(method, args); InvokeStaticVoidMethod(env, clazz, method, jargs); } #define IMPLEMENT_METHOD_FAMILY(methodName, returnType, jvalueField) \ static returnType JNICALL methodName(JNIEnv *env, jclass clazz, jmethodID methodID, ...) \ { \ va_list args; va_start(args, methodID); \ returnType result = InvokeStaticMethod(env, clazz, (JNIMethod*)methodID, args).jvalueField; \ va_end(args); \ return result; \ } \ \ static returnType JNICALL methodName##V(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) \ { \ return InvokeStaticMethod(env, clazz, (JNIMethod*)methodID, args).jvalueField; \ } \ \ static returnType JNICALL methodName##A(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue * args) \ { \ return InvokeStaticMethod(env, clazz, (JNIMethod*)methodID, args).jvalueField; \ } \ IMPLEMENT_METHOD_FAMILY(CallStaticObjectMethod, jobject, l) IMPLEMENT_METHOD_FAMILY(CallStaticBooleanMethod, jboolean, z) IMPLEMENT_METHOD_FAMILY(CallStaticByteMethod, jbyte, b) IMPLEMENT_METHOD_FAMILY(CallStaticCharMethod, jchar, c) IMPLEMENT_METHOD_FAMILY(CallStaticShortMethod, jshort, s) IMPLEMENT_METHOD_FAMILY(CallStaticIntMethod, jint, i) IMPLEMENT_METHOD_FAMILY(CallStaticLongMethod, jlong, j) IMPLEMENT_METHOD_FAMILY(CallStaticFloatMethod, jfloat, f) IMPLEMENT_METHOD_FAMILY(CallStaticDoubleMethod, jdouble, d) #undef IMPLEMENT_METHOD_FAMILY static void JNICALL CallStaticVoidMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...) { va_list args; va_start(args, methodID); InvokeStaticVoidMethod(env, clazz, (JNIMethod*)methodID, args); va_end(args); } static void JNICALL CallStaticVoidMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) { InvokeStaticVoidMethod(env, clazz, (JNIMethod*)methodID, args); } static void JNICALL CallStaticVoidMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue * args) { InvokeStaticVoidMethod(env, clazz, (JNIMethod*)methodID, args); } // Static Fields static jfieldID JNICALL GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig) { nsISecureEnv* secureEnv = GetSecureEnv(env); jfieldID outFieldID = NULL; nsresult result = secureEnv->GetStaticFieldID(clazz, name, sig, &outFieldID); if (result == NS_OK && outFieldID != NULL) { JavaClassMember key(clazz, outFieldID); JNIField* field; PRBool bFound = theIDTable && theIDTable->Get(key, (void **)&field); if (!bFound) { field = new JNIField(name, sig, outFieldID); if (theIDTable) theIDTable->Put(key, field); } outFieldID = jfieldID(field); } return outFieldID; } static jvalue GetStaticField(JNIEnv* env, jclass clazz, JNIField* field) { jvalue outValue; ProxyJNIEnv& proxyEnv = GetProxyEnv(env); nsISecureEnv* secureEnv = GetSecureEnv(env); nsISecurityContext* securityContext = proxyEnv.getContext(); nsresult rv = secureEnv->GetStaticField(field->mFieldType, clazz, field->mFieldID, &outValue, securityContext); NS_IF_RELEASE(securityContext); return NS_SUCCEEDED(rv) ? outValue : kErrorValue; } #define IMPLEMENT_GET_FIELD(methodName, returnType, jvalueField) \ static returnType JNICALL methodName(JNIEnv *env, jclass clazz, jfieldID fieldID) \ { \ return GetStaticField(env, clazz, (JNIField*)fieldID).jvalueField; \ } \ IMPLEMENT_GET_FIELD(GetStaticObjectField, jobject, l) IMPLEMENT_GET_FIELD(GetStaticBooleanField, jboolean, z) IMPLEMENT_GET_FIELD(GetStaticByteField, jbyte, b) IMPLEMENT_GET_FIELD(GetStaticCharField, jchar, c) IMPLEMENT_GET_FIELD(GetStaticShortField, jshort, s) IMPLEMENT_GET_FIELD(GetStaticIntField, jint, i) IMPLEMENT_GET_FIELD(GetStaticLongField, jlong, j) IMPLEMENT_GET_FIELD(GetStaticFloatField, jfloat, f) IMPLEMENT_GET_FIELD(GetStaticDoubleField, jdouble, d) #undef IMPLEMENT_GET_FIELD static void SetStaticField(JNIEnv* env, jclass clazz, JNIField* field, jvalue value) { ProxyJNIEnv& proxyEnv = GetProxyEnv(env); nsISecureEnv* secureEnv = GetSecureEnv(env); nsISecurityContext* securityContext = proxyEnv.getContext(); nsresult result; result = secureEnv->SetStaticField(field->mFieldType, clazz, field->mFieldID, value, securityContext); NS_IF_RELEASE(securityContext); } #define IMPLEMENT_SET_FIELD(methodName, fieldType, jvalueField) \ static void JNICALL methodName(JNIEnv *env, jclass clazz, jfieldID fieldID, fieldType value) \ { \ jvalue fieldValue; \ fieldValue.jvalueField = value; \ SetStaticField(env, clazz, (JNIField*)fieldID, fieldValue); \ } \ IMPLEMENT_SET_FIELD(SetStaticObjectField, jobject, l) IMPLEMENT_SET_FIELD(SetStaticBooleanField, jboolean, z) IMPLEMENT_SET_FIELD(SetStaticByteField, jbyte, b) IMPLEMENT_SET_FIELD(SetStaticCharField, jchar, c) IMPLEMENT_SET_FIELD(SetStaticShortField, jshort, s) IMPLEMENT_SET_FIELD(SetStaticIntField, jint, i) IMPLEMENT_SET_FIELD(SetStaticLongField, jlong, j) IMPLEMENT_SET_FIELD(SetStaticFloatField, jfloat, f) IMPLEMENT_SET_FIELD(SetStaticDoubleField, jdouble, d) #undef IMPLEMENT_SET_FIELD static jstring JNICALL NewString(JNIEnv *env, const jchar *unicode, jsize len) { jstring outString; nsISecureEnv* secureEnv = GetSecureEnv(env); nsresult result; result = secureEnv->NewString(unicode, len, &outString); return outString; } static jsize JNICALL GetStringLength(JNIEnv *env, jstring str) { jsize outLength; nsISecureEnv* secureEnv = GetSecureEnv(env); nsresult result; result = secureEnv->GetStringLength(str, &outLength); return outLength; } static const jchar* JNICALL GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy) { const jchar* outChars = NULL; nsISecureEnv* secureEnv = GetSecureEnv(env); nsresult result; result = secureEnv->GetStringChars(str, isCopy, &outChars); return outChars; } static void JNICALL ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars) { nsISecureEnv* secureEnv = GetSecureEnv(env); nsresult result; result = secureEnv->ReleaseStringChars(str, chars); } static jstring JNICALL NewStringUTF(JNIEnv *env, const char *utf) { jstring outString; nsISecureEnv* secureEnv = GetSecureEnv(env); nsresult result; result = secureEnv->NewStringUTF(utf, &outString); return outString; } static jsize JNICALL GetStringUTFLength(JNIEnv *env, jstring str) { jsize outLength; nsISecureEnv* secureEnv = GetSecureEnv(env); nsresult result; result = secureEnv->GetStringUTFLength(str, &outLength); return outLength; } static const char* JNICALL GetStringUTFChars(JNIEnv *env, jstring str, jboolean *isCopy) { const char* outChars = NULL; nsISecureEnv* secureEnv = GetSecureEnv(env); nsresult result; result = secureEnv->GetStringUTFChars(str, isCopy, &outChars); return outChars; } static void JNICALL ReleaseStringUTFChars(JNIEnv *env, jstring str, const char* chars) { nsISecureEnv* secureEnv = GetSecureEnv(env); nsresult result; result = secureEnv->ReleaseStringUTFChars(str, chars); } static jsize JNICALL GetArrayLength(JNIEnv *env, jarray array) { jsize outLength; nsISecureEnv* secureEnv = GetSecureEnv(env); nsresult result; result = secureEnv->GetArrayLength(array, &outLength); return outLength; } static jobjectArray JNICALL NewObjectArray(JNIEnv *env, jsize len, jclass clazz, jobject initVal) { jobjectArray outArray = NULL; nsISecureEnv* secureEnv = GetSecureEnv(env); nsresult result; result = secureEnv->NewObjectArray(len, clazz, initVal, &outArray); return outArray; } static jobject JNICALL GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index) { jobject outObject = NULL; nsISecureEnv* secureEnv = GetSecureEnv(env); nsresult result; result = secureEnv->GetObjectArrayElement(array, index, &outObject); return outObject; } static void JNICALL SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val) { nsISecureEnv* secureEnv = GetSecureEnv(env); nsresult result; result = secureEnv->SetObjectArrayElement(array, index, val); } #define IMPLEMENT_NEW_ARRAY(methodName, type) \ static type##Array JNICALL methodName(JNIEnv *env, jsize len) \ { \ type##Array outArray = NULL; \ nsISecureEnv* secureEnv = GetSecureEnv(env); \ nsresult result; \ result = secureEnv->NewArray(type##_type, len, (jarray*)&outArray); \ return outArray; \ } \ IMPLEMENT_NEW_ARRAY(NewBooleanArray, jboolean) IMPLEMENT_NEW_ARRAY(NewByteArray, jbyte) IMPLEMENT_NEW_ARRAY(NewCharArray, jchar) IMPLEMENT_NEW_ARRAY(NewShortArray, jshort) IMPLEMENT_NEW_ARRAY(NewIntArray, jint) IMPLEMENT_NEW_ARRAY(NewLongArray, jlong) IMPLEMENT_NEW_ARRAY(NewFloatArray, jfloat) IMPLEMENT_NEW_ARRAY(NewDoubleArray, jdouble) #undef IMPLEMENT_NEW_ARRAY #define IMPLEMENT_GET_ARRAY_ELEMENTS(methodName, type) \ static type* JNICALL methodName(JNIEnv *env, type##Array array, jboolean *isCopy) \ { \ type* outElements = NULL; \ nsISecureEnv* secureEnv = GetSecureEnv(env); \ nsresult result; \ result = secureEnv->GetArrayElements(type##_type, array, isCopy, &outElements); \ return outElements; \ } \ IMPLEMENT_GET_ARRAY_ELEMENTS(GetBooleanArrayElements, jboolean) IMPLEMENT_GET_ARRAY_ELEMENTS(GetByteArrayElements, jbyte) IMPLEMENT_GET_ARRAY_ELEMENTS(GetCharArrayElements, jchar) IMPLEMENT_GET_ARRAY_ELEMENTS(GetShortArrayElements, jshort) IMPLEMENT_GET_ARRAY_ELEMENTS(GetIntArrayElements, jint) IMPLEMENT_GET_ARRAY_ELEMENTS(GetLongArrayElements, jlong) IMPLEMENT_GET_ARRAY_ELEMENTS(GetFloatArrayElements, jfloat) IMPLEMENT_GET_ARRAY_ELEMENTS(GetDoubleArrayElements, jdouble) #undef IMPLEMENT_GET_ARRAY_ELEMENTS #define IMPLEMENT_RELEASE_ARRAY_ELEMENTS(methodName, type) \ static void JNICALL methodName(JNIEnv *env, type##Array array, type* elems, jint mode) \ { \ nsISecureEnv* secureEnv = GetSecureEnv(env); \ nsresult result; \ result = secureEnv->ReleaseArrayElements(type##_type, array, elems, mode); \ } \ IMPLEMENT_RELEASE_ARRAY_ELEMENTS(ReleaseBooleanArrayElements, jboolean) IMPLEMENT_RELEASE_ARRAY_ELEMENTS(ReleaseByteArrayElements, jbyte) IMPLEMENT_RELEASE_ARRAY_ELEMENTS(ReleaseCharArrayElements, jchar) IMPLEMENT_RELEASE_ARRAY_ELEMENTS(ReleaseShortArrayElements, jshort) IMPLEMENT_RELEASE_ARRAY_ELEMENTS(ReleaseIntArrayElements, jint) IMPLEMENT_RELEASE_ARRAY_ELEMENTS(ReleaseLongArrayElements, jlong) IMPLEMENT_RELEASE_ARRAY_ELEMENTS(ReleaseFloatArrayElements, jfloat) IMPLEMENT_RELEASE_ARRAY_ELEMENTS(ReleaseDoubleArrayElements, jdouble) #undef IMPLEMENT_RELEASE_ARRAY_ELEMENTS #define IMPLEMENT_GET_ARRAY_REGION(methodName, type) \ static void JNICALL methodName(JNIEnv *env, type##Array array, jsize start, jsize len, type* buf) \ { \ nsISecureEnv* secureEnv = GetSecureEnv(env); \ nsresult result; \ result = secureEnv->GetArrayRegion(type##_type, array, start, len, buf); \ } \ IMPLEMENT_GET_ARRAY_REGION(GetBooleanArrayRegion, jboolean) IMPLEMENT_GET_ARRAY_REGION(GetByteArrayRegion, jbyte) IMPLEMENT_GET_ARRAY_REGION(GetCharArrayRegion, jchar) IMPLEMENT_GET_ARRAY_REGION(GetShortArrayRegion, jshort) IMPLEMENT_GET_ARRAY_REGION(GetIntArrayRegion, jint) IMPLEMENT_GET_ARRAY_REGION(GetLongArrayRegion, jlong) IMPLEMENT_GET_ARRAY_REGION(GetFloatArrayRegion, jfloat) IMPLEMENT_GET_ARRAY_REGION(GetDoubleArrayRegion, jdouble) #undef IMPLEMENT_GET_ARRAY_REGION #define IMPLEMENT_SET_ARRAY_REGION(methodName, type) \ static void JNICALL methodName(JNIEnv *env, type##Array array, jsize start, jsize len, type* buf) \ { \ nsISecureEnv* secureEnv = GetSecureEnv(env); \ nsresult result; \ result = secureEnv->SetArrayRegion(type##_type, array, start, len, buf); \ } \ IMPLEMENT_SET_ARRAY_REGION(SetBooleanArrayRegion, jboolean) IMPLEMENT_SET_ARRAY_REGION(SetByteArrayRegion, jbyte) IMPLEMENT_SET_ARRAY_REGION(SetCharArrayRegion, jchar) IMPLEMENT_SET_ARRAY_REGION(SetShortArrayRegion, jshort) IMPLEMENT_SET_ARRAY_REGION(SetIntArrayRegion, jint) IMPLEMENT_SET_ARRAY_REGION(SetLongArrayRegion, jlong) IMPLEMENT_SET_ARRAY_REGION(SetFloatArrayRegion, jfloat) IMPLEMENT_SET_ARRAY_REGION(SetDoubleArrayRegion, jdouble) #undef IMPLEMENT_SET_ARRAY_REGION static jint JNICALL RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods, jint nMethods) { jint outStatus = -1; nsISecureEnv* secureEnv = GetSecureEnv(env); nsresult result; result = secureEnv->RegisterNatives(clazz, methods, nMethods, &outStatus); return outStatus; } static jint JNICALL UnregisterNatives(JNIEnv *env, jclass clazz) { jint outStatus = -1; nsISecureEnv* secureEnv = GetSecureEnv(env); nsresult result; result = secureEnv->UnregisterNatives(clazz, &outStatus); return outStatus; } static jint JNICALL MonitorEnter(JNIEnv *env, jobject obj) { jint outStatus = -1; nsISecureEnv* secureEnv = GetSecureEnv(env); nsresult result; result = secureEnv->MonitorEnter(obj, &outStatus); return outStatus; } static jint JNICALL JNICALL MonitorExit(JNIEnv *env, jobject obj) { jint outStatus = -1; nsISecureEnv* secureEnv = GetSecureEnv(env); nsresult result; result = secureEnv->MonitorExit(obj, &outStatus); return outStatus; } static jint JNICALL GetJavaVM(JNIEnv *env, JavaVM **vm) { jint outStatus = -1; nsISecureEnv* secureEnv = GetSecureEnv(env); nsresult result; result = secureEnv->GetJavaVM(vm, &outStatus); return outStatus; } public: ProxyJNIEnv(nsIJVMPlugin* jvmPlugin, nsISecureEnv* secureEnv); ~ProxyJNIEnv(); nsISecureEnv* getSecureEnv() { return mSecureEnv; } void SetSecurityContext(nsISecurityContext *context) { if (mContext) mContext->Release(); mContext = context; mContext->AddRef(); } nsresult GetSecurityContext(nsISecurityContext **context) { if (!context) return NS_ERROR_FAILURE; *context = getContext(); return NS_OK; } }; JNINativeInterface_ ProxyJNIEnv::theFuncs = { NULL, // void *reserved0; NULL, // void *reserved1; NULL, // void *reserved2; NULL, // void *reserved3; // jint (JNICALL *GetVersion)(JNIEnv *env); &GetVersion, // jclass (JNICALL *DefineClass) (JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len); &DefineClass, // jclass (JNICALL *FindClass) (JNIEnv *env, const char *name); &FindClass, #ifdef JDK1_2 // jmethodID (JNICALL *FromReflectedMethod) (JNIEnv *env, jobject method); &FromReflectedMethod, // jfieldID (JNICALL *FromReflectedField) (JNIEnv *env, jobject field); &FromReflectedField, // jobject (JNICALL *ToReflectedMethod) (JNIEnv *env, jclass cls, jmethodID methodID, jboolean isStatic); &ToReflectedMethod, #else NULL, // void *reserved4; NULL, // void *reserved5; NULL, // void *reserved6; #endif // jclass (JNICALL *GetSuperclass) (JNIEnv *env, jclass sub); &GetSuperclass, // jboolean (JNICALL *IsAssignableFrom) (JNIEnv *env, jclass sub, jclass sup); &IsAssignableFrom, #ifdef JDK1_2 // jobject (JNICALL *ToReflectedField) (JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic); &ToReflectedField, #else NULL, // void *reserved7; #endif // jint (JNICALL *Throw) (JNIEnv *env, jthrowable obj); &Throw, // jint (JNICALL *ThrowNew) (JNIEnv *env, jclass clazz, const char *msg); &ThrowNew, // jthrowable (JNICALL *ExceptionOccurred) (JNIEnv *env); &ExceptionOccurred, // void (JNICALL *ExceptionDescribe) (JNIEnv *env); &ExceptionDescribe, // void (JNICALL *ExceptionClear) (JNIEnv *env); &ExceptionClear, // void (JNICALL *FatalError) (JNIEnv *env, const char *msg); &FatalError, #ifdef JDK1_2 // jint (JNICALL *PushLocalFrame) (JNIEnv *env, jint capacity); &PushLocalFrame, // jobject (JNICALL *PopLocalFrame) (JNIEnv *env, jobject result); &PopLocalFrame, #else NULL, // void *reserved8; NULL, // void *reserved9; #endif // jobject (JNICALL *NewGlobalRef) (JNIEnv *env, jobject lobj); &NewGlobalRef, // void (JNICALL *DeleteGlobalRef) (JNIEnv *env, jobject gref); &DeleteGlobalRef, // void (JNICALL *DeleteLocalRef) (JNIEnv *env, jobject obj); &DeleteLocalRef, // jboolean (JNICALL *IsSameObject) (JNIEnv *env, jobject obj1, jobject obj2); &IsSameObject, #ifdef JDK1_2 // jobject (JNICALL *NewLocalRef) (JNIEnv *env, jobject ref); &NewLocalRef, // jint (JNICALL *EnsureLocalCapacity) (JNIEnv *env, jint capacity); &EnsureLocalCapacity, #else NULL, // void *reserved10; NULL, // void *reserved11; #endif // jobject (JNICALL *AllocObject) (JNIEnv *env, jclass clazz); &AllocObject, #define REFERENCE_METHOD_FAMILY(methodName) &methodName, &methodName##V, &methodName##A, // jobject (JNICALL *NewObject) (JNIEnv *env, jclass clazz, jmethodID methodID, ...); // jobject (JNICALL *NewObjectV) (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); // jobject (JNICALL *NewObjectA) (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); REFERENCE_METHOD_FAMILY(NewObject) // jclass (JNICALL *GetObjectClass) (JNIEnv *env, jobject obj); &GetObjectClass, // jboolean (JNICALL *IsInstanceOf) (JNIEnv *env, jobject obj, jclass clazz); &IsInstanceOf, // jmethodID (JNICALL *GetMethodID)(JNIEnv *env, jclass clazz, const char *name, const char *sig); &GetMethodID, // jobject (JNICALL *CallObjectMethod) (JNIEnv *env, jobject obj, jmethodID methodID, ...); // jobject (JNICALL *CallObjectMethodV) (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); // jobject (JNICALL *CallObjectMethodA) (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args); REFERENCE_METHOD_FAMILY(CallObjectMethod) // jboolean (JNICALL *CallBooleanMethod) (JNIEnv *env, jobject obj, jmethodID methodID, ...); // jboolean (JNICALL *CallBooleanMethodV) (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); // jboolean (JNICALL *CallBooleanMethodA) (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args); REFERENCE_METHOD_FAMILY(CallBooleanMethod) // jbyte (JNICALL *CallByteMethod) (JNIEnv *env, jobject obj, jmethodID methodID, ...); // jbyte (JNICALL *CallByteMethodV) (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); // jbyte (JNICALL *CallByteMethodA) (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); REFERENCE_METHOD_FAMILY(CallByteMethod) // jchar (JNICALL *CallCharMethod) (JNIEnv *env, jobject obj, jmethodID methodID, ...); // jchar (JNICALL *CallCharMethodV) (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); // jchar (JNICALL *CallCharMethodA) (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); REFERENCE_METHOD_FAMILY(CallCharMethod) // jshort (JNICALL *CallShortMethod) (JNIEnv *env, jobject obj, jmethodID methodID, ...); // jshort (JNICALL *CallShortMethodV) (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); // jshort (JNICALL *CallShortMethodA) (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); REFERENCE_METHOD_FAMILY(CallShortMethod) // jint (JNICALL *CallIntMethod) (JNIEnv *env, jobject obj, jmethodID methodID, ...); // jint (JNICALL *CallIntMethodV) (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); // jint (JNICALL *CallIntMethodA) (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); REFERENCE_METHOD_FAMILY(CallIntMethod) // jlong (JNICALL *CallLongMethod) (JNIEnv *env, jobject obj, jmethodID methodID, ...); // jlong (JNICALL *CallLongMethodV) (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); // jlong (JNICALL *CallLongMethodA) (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); REFERENCE_METHOD_FAMILY(CallLongMethod) // jfloat (JNICALL *CallFloatMethod) (JNIEnv *env, jobject obj, jmethodID methodID, ...); // jfloat (JNICALL *CallFloatMethodV) (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); // jfloat (JNICALL *CallFloatMethodA) (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); REFERENCE_METHOD_FAMILY(CallFloatMethod) // jdouble (JNICALL *CallDoubleMethod) (JNIEnv *env, jobject obj, jmethodID methodID, ...); // jdouble (JNICALL *CallDoubleMethodV) (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); // jdouble (JNICALL *CallDoubleMethodA) (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); REFERENCE_METHOD_FAMILY(CallDoubleMethod) // void (JNICALL *CallVoidMethod) (JNIEnv *env, jobject obj, jmethodID methodID, ...); // void (JNICALL *CallVoidMethodV) (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); // void (JNICALL *CallVoidMethodA) (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args); REFERENCE_METHOD_FAMILY(CallVoidMethod) // jobject (JNICALL *CallNonvirtualObjectMethod) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); // jobject (JNICALL *CallNonvirtualObjectMethodV) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args); // jobject (JNICALL *CallNonvirtualObjectMethodA) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args); REFERENCE_METHOD_FAMILY(CallNonvirtualObjectMethod) // jboolean (JNICALL *CallNonvirtualBooleanMethod) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); // jboolean (JNICALL *CallNonvirtualBooleanMethodV) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args); // jboolean (JNICALL *CallNonvirtualBooleanMethodA) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args); REFERENCE_METHOD_FAMILY(CallNonvirtualBooleanMethod) // jbyte (JNICALL *CallNonvirtualByteMethod) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); // jbyte (JNICALL *CallNonvirtualByteMethodV) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args); // jbyte (JNICALL *CallNonvirtualByteMethodA) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args); REFERENCE_METHOD_FAMILY(CallNonvirtualByteMethod) // jchar (JNICALL *CallNonvirtualCharMethod) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); // jchar (JNICALL *CallNonvirtualCharMethodV) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args); // jchar (JNICALL *CallNonvirtualCharMethodA) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args); REFERENCE_METHOD_FAMILY(CallNonvirtualCharMethod) // jshort (JNICALL *CallNonvirtualShortMethod) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); // jshort (JNICALL *CallNonvirtualShortMethodV) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args); // jshort (JNICALL *CallNonvirtualShortMethodA) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args); REFERENCE_METHOD_FAMILY(CallNonvirtualShortMethod) // jint (JNICALL *CallNonvirtualIntMethod) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); // jint (JNICALL *CallNonvirtualIntMethodV) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args); // jint (JNICALL *CallNonvirtualIntMethodA) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args); REFERENCE_METHOD_FAMILY(CallNonvirtualIntMethod) // jlong (JNICALL *CallNonvirtualLongMethod) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); // jlong (JNICALL *CallNonvirtualLongMethodV) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args); // jlong (JNICALL *CallNonvirtualLongMethodA) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args); REFERENCE_METHOD_FAMILY(CallNonvirtualLongMethod) // jfloat (JNICALL *CallNonvirtualFloatMethod) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); // jfloat (JNICALL *CallNonvirtualFloatMethodV) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args); // jfloat (JNICALL *CallNonvirtualFloatMethodA) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args); REFERENCE_METHOD_FAMILY(CallNonvirtualFloatMethod) // jdouble (JNICALL *CallNonvirtualDoubleMethod) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); // jdouble (JNICALL *CallNonvirtualDoubleMethodV) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args); // jdouble (JNICALL *CallNonvirtualDoubleMethodA) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args); REFERENCE_METHOD_FAMILY(CallNonvirtualDoubleMethod) // void (JNICALL *CallNonvirtualVoidMethod) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); // void (JNICALL *CallNonvirtualVoidMethodV) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args); // void (JNICALL *CallNonvirtualVoidMethodA) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args); REFERENCE_METHOD_FAMILY(CallNonvirtualVoidMethod) // jfieldID (JNICALL *GetFieldID) (JNIEnv *env, jclass clazz, const char *name, const char *sig); &GetFieldID, // jobject (JNICALL *GetObjectField) (JNIEnv *env, jobject obj, jfieldID fieldID); // jboolean (JNICALL *GetBooleanField) (JNIEnv *env, jobject obj, jfieldID fieldID); // jbyte (JNICALL *GetByteField) (JNIEnv *env, jobject obj, jfieldID fieldID); // jchar (JNICALL *GetCharField) (JNIEnv *env, jobject obj, jfieldID fieldID); // jshort (JNICALL *GetShortField) (JNIEnv *env, jobject obj, jfieldID fieldID); // jint (JNICALL *GetIntField) (JNIEnv *env, jobject obj, jfieldID fieldID); // jlong (JNICALL *GetLongField) (JNIEnv *env, jobject obj, jfieldID fieldID); // jfloat (JNICALL *GetFloatField) (JNIEnv *env, jobject obj, jfieldID fieldID); // jdouble (JNICALL *GetDoubleField) (JNIEnv *env, jobject obj, jfieldID fieldID); &GetObjectField, &GetBooleanField, &GetByteField, &GetCharField, &GetShortField, &GetIntField, &GetLongField, &GetFloatField, &GetDoubleField, // void (JNICALL *SetObjectField) (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val); // void (JNICALL *SetBooleanField) (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val); // void (JNICALL *SetByteField) (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val); // void (JNICALL *SetCharField) (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val); // void (JNICALL *SetShortField) (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val); // void (JNICALL *SetIntField) (JNIEnv *env, jobject obj, jfieldID fieldID, jint val); // void (JNICALL *SetLongField) (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val); // void (JNICALL *SetFloatField) (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val); // void (JNICALL *SetDoubleField) (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val); &SetObjectField, &SetBooleanField, &SetByteField, &SetCharField, &SetShortField, &SetIntField, &SetLongField, &SetFloatField, &SetDoubleField, // jmethodID (JNICALL *GetStaticMethodID) (JNIEnv *env, jclass clazz, const char *name, const char *sig); &GetStaticMethodID, // jobject (JNICALL *CallStaticObjectMethod) (JNIEnv *env, jclass clazz, jmethodID methodID, ...); // jobject (JNICALL *CallStaticObjectMethodV) (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); // jobject (JNICALL *CallStaticObjectMethodA) (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); REFERENCE_METHOD_FAMILY(CallStaticObjectMethod) // jboolean (JNICALL *CallStaticBooleanMethod) (JNIEnv *env, jclass clazz, jmethodID methodID, ...); // jboolean (JNICALL *CallStaticBooleanMethodV) (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); // jboolean (JNICALL *CallStaticBooleanMethodA) (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); REFERENCE_METHOD_FAMILY(CallStaticBooleanMethod) // jbyte (JNICALL *CallStaticByteMethod) (JNIEnv *env, jclass clazz, jmethodID methodID, ...); // jbyte (JNICALL *CallStaticByteMethodV) (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); // jbyte (JNICALL *CallStaticByteMethodA) (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); REFERENCE_METHOD_FAMILY(CallStaticByteMethod) // jchar (JNICALL *CallStaticCharMethod) (JNIEnv *env, jclass clazz, jmethodID methodID, ...); // jchar (JNICALL *CallStaticCharMethodV) (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); // jchar (JNICALL *CallStaticCharMethodA) (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); REFERENCE_METHOD_FAMILY(CallStaticCharMethod) // jshort (JNICALL *CallStaticShortMethod) (JNIEnv *env, jclass clazz, jmethodID methodID, ...); // jshort (JNICALL *CallStaticShortMethodV) (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); // jshort (JNICALL *CallStaticShortMethodA) (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); REFERENCE_METHOD_FAMILY(CallStaticShortMethod) // jint (JNICALL *CallStaticIntMethod) (JNIEnv *env, jclass clazz, jmethodID methodID, ...); // jint (JNICALL *CallStaticIntMethodV) (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); // jint (JNICALL *CallStaticIntMethodA) (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); REFERENCE_METHOD_FAMILY(CallStaticIntMethod) // jlong (JNICALL *CallStaticLongMethod) (JNIEnv *env, jclass clazz, jmethodID methodID, ...); // jlong (JNICALL *CallStaticLongMethodV) (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); // jlong (JNICALL *CallStaticLongMethodA) (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); REFERENCE_METHOD_FAMILY(CallStaticLongMethod) // jfloat (JNICALL *CallStaticFloatMethod) (JNIEnv *env, jclass clazz, jmethodID methodID, ...); // jfloat (JNICALL *CallStaticFloatMethodV) (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); // jfloat (JNICALL *CallStaticFloatMethodA) (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); REFERENCE_METHOD_FAMILY(CallStaticFloatMethod) // jdouble (JNICALL *CallStaticDoubleMethod) (JNIEnv *env, jclass clazz, jmethodID methodID, ...); // jdouble (JNICALL *CallStaticDoubleMethodV) (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); // jdouble (JNICALL *CallStaticDoubleMethodA) (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); REFERENCE_METHOD_FAMILY(CallStaticDoubleMethod) // void (JNICALL *CallStaticVoidMethod) (JNIEnv *env, jclass cls, jmethodID methodID, ...); // void (JNICALL *CallStaticVoidMethodV) (JNIEnv *env, jclass cls, jmethodID methodID, va_list args); // void (JNICALL *CallStaticVoidMethodA) (JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args); REFERENCE_METHOD_FAMILY(CallStaticVoidMethod) // jfieldID (JNICALL *GetStaticFieldID) (JNIEnv *env, jclass clazz, const char *name, const char *sig); &GetStaticFieldID, // jobject (JNICALL *GetStaticObjectField) (JNIEnv *env, jclass clazz, jfieldID fieldID); // jboolean (JNICALL *GetStaticBooleanField) (JNIEnv *env, jclass clazz, jfieldID fieldID); // jbyte (JNICALL *GetStaticByteField) (JNIEnv *env, jclass clazz, jfieldID fieldID); // jchar (JNICALL *GetStaticCharField) (JNIEnv *env, jclass clazz, jfieldID fieldID); // jshort (JNICALL *GetStaticShortField) (JNIEnv *env, jclass clazz, jfieldID fieldID); // jint (JNICALL *GetStaticIntField) (JNIEnv *env, jclass clazz, jfieldID fieldID); // jlong (JNICALL *GetStaticLongField) (JNIEnv *env, jclass clazz, jfieldID fieldID); // jfloat (JNICALL *GetStaticFloatField) (JNIEnv *env, jclass clazz, jfieldID fieldID); // jdouble (JNICALL *GetStaticDoubleField) (JNIEnv *env, jclass clazz, jfieldID fieldID); &GetStaticObjectField, &GetStaticBooleanField, &GetStaticByteField, &GetStaticCharField, &GetStaticShortField, &GetStaticIntField, &GetStaticLongField, &GetStaticFloatField, &GetStaticDoubleField, // void (JNICALL *SetStaticObjectField) (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value); // void (JNICALL *SetStaticBooleanField) (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value); // void (JNICALL *SetStaticByteField) (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value); // void (JNICALL *SetStaticCharField) (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value); // void (JNICALL *SetStaticShortField) (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value); // void (JNICALL *SetStaticIntField) (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value); // void (JNICALL *SetStaticLongField) (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value); // void (JNICALL *SetStaticFloatField) (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value); // void (JNICALL *SetStaticDoubleField) (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value); &SetStaticObjectField, &SetStaticBooleanField, &SetStaticByteField, &SetStaticCharField, &SetStaticShortField, &SetStaticIntField, &SetStaticLongField, &SetStaticFloatField, &SetStaticDoubleField, // jstring (JNICALL *NewString) (JNIEnv *env, const jchar *unicode, jsize len); // jsize (JNICALL *GetStringLength) (JNIEnv *env, jstring str); // const jchar *(JNICALL *GetStringChars) (JNIEnv *env, jstring str, jboolean *isCopy); // void (JNICALL *ReleaseStringChars) (JNIEnv *env, jstring str, const jchar *chars); &NewString, &GetStringLength, &GetStringChars, &ReleaseStringChars, // jstring (JNICALL *NewStringUTF) (JNIEnv *env, const char *utf); // jsize (JNICALL *GetStringUTFLength) (JNIEnv *env, jstring str); // const char* (JNICALL *GetStringUTFChars) (JNIEnv *env, jstring str, jboolean *isCopy); // void (JNICALL *ReleaseStringUTFChars) (JNIEnv *env, jstring str, const char* chars); &NewStringUTF, &GetStringUTFLength, &GetStringUTFChars, &ReleaseStringUTFChars, // jsize (JNICALL *GetArrayLength) (JNIEnv *env, jarray array); &GetArrayLength, // jobjectArray (JNICALL *NewObjectArray) (JNIEnv *env, jsize len, jclass clazz, jobject init); // jobject (JNICALL *GetObjectArrayElement) (JNIEnv *env, jobjectArray array, jsize index); // void (JNICALL *SetObjectArrayElement) (JNIEnv *env, jobjectArray array, jsize index, jobject val); &NewObjectArray, &GetObjectArrayElement, &SetObjectArrayElement, // jbooleanArray (JNICALL *NewBooleanArray) (JNIEnv *env, jsize len); // jbyteArray (JNICALL *NewByteArray) (JNIEnv *env, jsize len); // jcharArray (JNICALL *NewCharArray) (JNIEnv *env, jsize len); // jshortArray (JNICALL *NewShortArray) (JNIEnv *env, jsize len); // jintArray (JNICALL *NewIntArray) (JNIEnv *env, jsize len); // jlongArray (JNICALL *NewLongArray) (JNIEnv *env, jsize len); // jfloatArray (JNICALL *NewFloatArray) (JNIEnv *env, jsize len); // jdoubleArray (JNICALL *NewDoubleArray) (JNIEnv *env, jsize len); &NewBooleanArray, &NewByteArray, &NewCharArray, &NewShortArray, &NewIntArray, &NewLongArray, &NewFloatArray, &NewDoubleArray, // jboolean * (JNICALL *GetBooleanArrayElements) (JNIEnv *env, jbooleanArray array, jboolean *isCopy); // jbyte * (JNICALL *GetByteArrayElements) (JNIEnv *env, jbyteArray array, jboolean *isCopy); // jchar * (JNICALL *GetCharArrayElements) (JNIEnv *env, jcharArray array, jboolean *isCopy); // jshort * (JNICALL *GetShortArrayElements) (JNIEnv *env, jshortArray array, jboolean *isCopy); // jint * (JNICALL *GetIntArrayElements) (JNIEnv *env, jintArray array, jboolean *isCopy); // jlong * (JNICALL *GetLongArrayElements) (JNIEnv *env, jlongArray array, jboolean *isCopy); // jfloat * (JNICALL *GetFloatArrayElements) (JNIEnv *env, jfloatArray array, jboolean *isCopy); // jdouble * (JNICALL *GetDoubleArrayElements) (JNIEnv *env, jdoubleArray array, jboolean *isCopy); &GetBooleanArrayElements, &GetByteArrayElements, &GetCharArrayElements, &GetShortArrayElements, &GetIntArrayElements, &GetLongArrayElements, &GetFloatArrayElements, &GetDoubleArrayElements, // void (JNICALL *ReleaseBooleanArrayElements)(JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode); // void (JNICALL *ReleaseByteArrayElements) (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode); // void (JNICALL *ReleaseCharArrayElements) (JNIEnv *env, jcharArray array, jchar *elems, jint mode); // void (JNICALL *ReleaseShortArrayElements) (JNIEnv *env, jshortArray array, jshort *elems, jint mode); // void (JNICALL *ReleaseIntArrayElements) (JNIEnv *env, jintArray array, jint *elems, jint mode); // void (JNICALL *ReleaseLongArrayElements) (JNIEnv *env, jlongArray array, jlong *elems, jint mode); // void (JNICALL *ReleaseFloatArrayElements) (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode); // void (JNICALL *ReleaseDoubleArrayElements) (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode); &ReleaseBooleanArrayElements, &ReleaseByteArrayElements, &ReleaseCharArrayElements, &ReleaseShortArrayElements, &ReleaseIntArrayElements, &ReleaseLongArrayElements, &ReleaseFloatArrayElements, &ReleaseDoubleArrayElements, // void (JNICALL *GetBooleanArrayRegion) (JNIEnv *env, jbooleanArray array, jsize start, jsize l, jboolean *buf); // void (JNICALL *GetByteArrayRegion) (JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf); // void (JNICALL *GetCharArrayRegion) (JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf); // void (JNICALL *GetShortArrayRegion) (JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf); // void (JNICALL *GetIntArrayRegion) (JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf); // void (JNICALL *GetLongArrayRegion) (JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf); // void (JNICALL *GetFloatArrayRegion) (JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf); // void (JNICALL *GetDoubleArrayRegion) (JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf); &GetBooleanArrayRegion, &GetByteArrayRegion, &GetCharArrayRegion, &GetShortArrayRegion, &GetIntArrayRegion, &GetLongArrayRegion, &GetFloatArrayRegion, &GetDoubleArrayRegion, // void (JNICALL *SetBooleanArrayRegion) (JNIEnv *env, jbooleanArray array, jsize start, jsize l, jboolean *buf); // void (JNICALL *SetByteArrayRegion) (JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf); // void (JNICALL *SetCharArrayRegion) (JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf); // void (JNICALL *SetShortArrayRegion) (JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf); // void (JNICALL *SetIntArrayRegion) (JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf); // void (JNICALL *SetLongArrayRegion) (JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf); // void (JNICALL *SetFloatArrayRegion) (JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf); // void (JNICALL *SetDoubleArrayRegion) (JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf); &SetBooleanArrayRegion, &SetByteArrayRegion, &SetCharArrayRegion, &SetShortArrayRegion, &SetIntArrayRegion, &SetLongArrayRegion, &SetFloatArrayRegion, &SetDoubleArrayRegion, // jint (JNICALL *RegisterNatives) (JNIEnv *env, jclass clazz, const JNINativeMethod *methods, jint nMethods); // jint (JNICALL *UnregisterNatives) (JNIEnv *env, jclass clazz); &RegisterNatives, &UnregisterNatives, // jint (JNICALL *MonitorEnter) (JNIEnv *env, jobject obj); // jint (JNICALL *MonitorExit) (JNIEnv *env, jobject obj); &MonitorEnter, &MonitorExit, // jint (JNICALL *GetJavaVM) (JNIEnv *env, JavaVM **vm); &GetJavaVM }; nsDataHashtable* ProxyJNIEnv::theIDTable = NULL; ProxyJNIEnv::ProxyJNIEnv(nsIJVMPlugin* jvmPlugin, nsISecureEnv* secureEnv) : mSecureEnv(secureEnv), mContext(NULL), mInProxyFindClass(JNI_FALSE) { this->functions = &theFuncs; if (theIDTable == NULL) { theIDTable = new nsDataHashtable; if (theIDTable) { if (!theIDTable->Init(16)) { delete theIDTable; theIDTable = NULL; NS_WARNING("theIDTable initialization FAILED"); } } else { NS_WARNING("theIDTable allocation FAILED"); } } // Ask the JVM for a new nsISecureEnv, if none provided. if (secureEnv == NULL) { nsresult rv = jvmPlugin->CreateSecureEnv(this, &mSecureEnv); #ifdef DEBUG if (NS_FAILED(rv)) NS_WARNING("CreateSecureEnv FAILED"); else NS_WARNING("CreateSecureEnv OK"); #endif } } ProxyJNIEnv::~ProxyJNIEnv() { this->functions = NULL; if (mSecureEnv != NULL) mSecureEnv->Release(); } JNIEnv* CreateProxyJNI(nsIJVMPlugin* jvmPlugin, nsISecureEnv* inSecureEnv) { ProxyJNIEnv* proxyEnv = new ProxyJNIEnv(jvmPlugin, inSecureEnv); if (proxyEnv->getSecureEnv() == NULL) { delete proxyEnv; return NULL; } return proxyEnv; } void DeleteProxyJNI(JNIEnv* env) { ProxyJNIEnv* proxyEnv = (ProxyJNIEnv*)env; if (proxyEnv != NULL) delete proxyEnv; } nsISecureEnv* GetSecureEnv(JNIEnv* env) { ProxyJNIEnv* proxyEnv = (ProxyJNIEnv*)env; return proxyEnv->getSecureEnv(); } PR_IMPLEMENT(void) SetSecurityContext(JNIEnv* env, nsISecurityContext *context) { ProxyJNIEnv* proxyEnv = (ProxyJNIEnv*)env; proxyEnv->SetSecurityContext(context); } PR_IMPLEMENT(nsresult) GetSecurityContext(JNIEnv* env, nsISecurityContext **context) { ProxyJNIEnv* proxyEnv = (ProxyJNIEnv*)env; return proxyEnv->GetSecurityContext(context); }