📄 jni_runtime.cpp
字号:
/* * Copyright (C) 2003 Apple Computer, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include "config.h"#include <jni_runtime.h>#if ENABLE(MAC_JAVA_BRIDGE)#include <jni_utility.h>#include "runtime_array.h"#include "runtime_object.h"#include "runtime_root.h"#include <runtime/Error.h>#include <runtime/JSLock.h>#ifdef NDEBUG#define JS_LOG(formatAndArgs...) ((void)0)#else#define JS_LOG(formatAndArgs...) { \ fprintf (stderr, "%s:%d -- %s: ", __FILE__, __LINE__, __FUNCTION__); \ fprintf(stderr, formatAndArgs); \}#endifusing namespace JSC;using namespace JSC::Bindings;JavaParameter::JavaParameter (JNIEnv *env, jstring type){ _type = JavaString (env, type); _JNIType = JNITypeFromClassName (_type.UTF8String());}JavaField::JavaField (JNIEnv *env, jobject aField){ // Get field type jobject fieldType = callJNIMethod<jobject>(aField, "getType", "()Ljava/lang/Class;"); jstring fieldTypeName = (jstring)callJNIMethod<jobject>(fieldType, "getName", "()Ljava/lang/String;"); _type = JavaString(env, fieldTypeName); _JNIType = JNITypeFromClassName (_type.UTF8String()); // Get field name jstring fieldName = (jstring)callJNIMethod<jobject>(aField, "getName", "()Ljava/lang/String;"); _name = JavaString(env, fieldName); _field = new JObjectWrapper(aField);}JSValuePtr JavaArray::convertJObjectToArray(ExecState* exec, jobject anObject, const char* type, PassRefPtr<RootObject> rootObject){ if (type[0] != '[') return jsUndefined(); return new (exec) RuntimeArray(exec, new JavaArray((jobject)anObject, type, rootObject));}jvalue JavaField::dispatchValueFromInstance(ExecState *exec, const JavaInstance *instance, const char *name, const char *sig, JNIType returnType) const{ jobject jinstance = instance->javaInstance(); jobject fieldJInstance = _field->_instance; JNIEnv *env = getJNIEnv(); jvalue result; bzero (&result, sizeof(jvalue)); jclass cls = env->GetObjectClass(fieldJInstance); if ( cls != NULL ) { jmethodID mid = env->GetMethodID(cls, name, sig); if ( mid != NULL ) { RootObject* rootObject = instance->rootObject(); if (rootObject && rootObject->nativeHandle()) { JSValuePtr exceptionDescription = noValue(); jvalue args[1]; args[0].l = jinstance; dispatchJNICall(exec, rootObject->nativeHandle(), fieldJInstance, false, returnType, mid, args, result, 0, exceptionDescription); if (exceptionDescription) throwError(exec, GeneralError, exceptionDescription.toString(exec)); } } } return result;}JSValuePtr JavaField::valueFromInstance(ExecState* exec, const Instance* i) const { const JavaInstance *instance = static_cast<const JavaInstance *>(i); JSValuePtr jsresult = jsUndefined(); switch (_JNIType) { case array_type: case object_type: { jvalue result = dispatchValueFromInstance (exec, instance, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", object_type); jobject anObject = result.l; const char *arrayType = type(); if (arrayType[0] == '[') { jsresult = JavaArray::convertJObjectToArray(exec, anObject, arrayType, instance->rootObject()); } else if (anObject != 0){ jsresult = JavaInstance::create(anObject, instance->rootObject())->createRuntimeObject(exec); } } break; case boolean_type: jsresult = jsBoolean(dispatchValueFromInstance(exec, instance, "getBoolean", "(Ljava/lang/Object;)Z", boolean_type).z); break; case byte_type: case char_type: case short_type: case int_type: { jint value; jvalue result = dispatchValueFromInstance (exec, instance, "getInt", "(Ljava/lang/Object;)I", int_type); value = result.i; jsresult = jsNumber(exec, (int)value); } break; case long_type: case float_type: case double_type: { jdouble value; jvalue result = dispatchValueFromInstance (exec, instance, "getDouble", "(Ljava/lang/Object;)D", double_type); value = result.i; jsresult = jsNumber(exec, (double)value); } break; default: break; } JS_LOG ("getting %s = %s\n", UString(name()).UTF8String().c_str(), jsresult.toString(exec).ascii()); return jsresult;}void JavaField::dispatchSetValueToInstance(ExecState *exec, const JavaInstance *instance, jvalue javaValue, const char *name, const char *sig) const{ jobject jinstance = instance->javaInstance(); jobject fieldJInstance = _field->_instance; JNIEnv *env = getJNIEnv(); jclass cls = env->GetObjectClass(fieldJInstance); if ( cls != NULL ) { jmethodID mid = env->GetMethodID(cls, name, sig); if ( mid != NULL ) { RootObject* rootObject = instance->rootObject(); if (rootObject && rootObject->nativeHandle()) { JSValuePtr exceptionDescription = noValue(); jvalue args[2]; jvalue result; args[0].l = jinstance; args[1] = javaValue; dispatchJNICall(exec, rootObject->nativeHandle(), fieldJInstance, false, void_type, mid, args, result, 0, exceptionDescription); if (exceptionDescription) throwError(exec, GeneralError, exceptionDescription.toString(exec)); } } }}void JavaField::setValueToInstance(ExecState* exec, const Instance* i, JSValuePtr aValue) const{ const JavaInstance *instance = static_cast<const JavaInstance *>(i); jvalue javaValue = convertValueToJValue (exec, aValue, _JNIType, type()); JS_LOG ("setting value %s to %s\n", UString(name()).UTF8String().c_str(), aValue.toString(exec).ascii()); switch (_JNIType) { case array_type: case object_type: { dispatchSetValueToInstance (exec, instance, javaValue, "set", "(Ljava/lang/Object;Ljava/lang/Object;)V"); } break; case boolean_type: { dispatchSetValueToInstance (exec, instance, javaValue, "setBoolean", "(Ljava/lang/Object;Z)V"); } break; case byte_type: { dispatchSetValueToInstance (exec, instance, javaValue, "setByte", "(Ljava/lang/Object;B)V"); } break; case char_type: { dispatchSetValueToInstance (exec, instance, javaValue, "setChar", "(Ljava/lang/Object;C)V"); } break; case short_type: { dispatchSetValueToInstance (exec, instance, javaValue, "setShort", "(Ljava/lang/Object;S)V"); } break; case int_type: { dispatchSetValueToInstance (exec, instance, javaValue, "setInt", "(Ljava/lang/Object;I)V"); } break; case long_type: { dispatchSetValueToInstance (exec, instance, javaValue, "setLong", "(Ljava/lang/Object;J)V"); } break; case float_type: { dispatchSetValueToInstance (exec, instance, javaValue, "setFloat", "(Ljava/lang/Object;F)V"); } break; case double_type: { dispatchSetValueToInstance (exec, instance, javaValue, "setDouble", "(Ljava/lang/Object;D)V"); } break; default: break; }}JavaMethod::JavaMethod (JNIEnv *env, jobject aMethod){ // Get return type jobject returnType = callJNIMethod<jobject>(aMethod, "getReturnType", "()Ljava/lang/Class;"); jstring returnTypeName = (jstring)callJNIMethod<jobject>(returnType, "getName", "()Ljava/lang/String;"); _returnType =JavaString (env, returnTypeName); _JNIReturnType = JNITypeFromClassName (_returnType.UTF8String()); env->DeleteLocalRef (returnType); env->DeleteLocalRef (returnTypeName); // Get method name jstring methodName = (jstring)callJNIMethod<jobject>(aMethod, "getName", "()Ljava/lang/String;"); _name = JavaString (env, methodName); env->DeleteLocalRef (methodName); // Get parameters jarray jparameters = (jarray)callJNIMethod<jobject>(aMethod, "getParameterTypes", "()[Ljava/lang/Class;"); _numParameters = env->GetArrayLength (jparameters); _parameters = new JavaParameter[_numParameters]; int i; for (i = 0; i < _numParameters; i++) { jobject aParameter = env->GetObjectArrayElement ((jobjectArray)jparameters, i); jstring parameterName = (jstring)callJNIMethod<jobject>(aParameter, "getName", "()Ljava/lang/String;"); _parameters[i] = JavaParameter(env, parameterName);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -