📄 jni_jsobject.cpp
字号:
jstring JSObject::toString() const
{
JS_LOG ("\n");
Interpreter::lock();
Object thisObj = Object(const_cast<ObjectImp*>(_imp));
ExecState *exec = _root->interpreter()->globalExec();
jstring result = (jstring)convertValueToJValue (exec, thisObj, object_type, "java.lang.String").l;
Interpreter::unlock();
return result;
}
void JSObject::finalize() const
{
JS_LOG ("\n");
removeNativeReference (_imp);
}
// We're either creating a 'Root' object (via a call to JSObject.getWindow()), or
// another JSObject.
jlong JSObject::createNative(jlong nativeHandle)
{
JS_LOG ("nativeHandle = %d\n", (int)nativeHandle);
if (nativeHandle == UndefinedHandle)
return nativeHandle;
else if (rootForImp(jlong_to_impptr(nativeHandle))){
return nativeHandle;
}
FindRootObjectForNativeHandleFunctionPtr aFunc = RootObject::findRootObjectForNativeHandleFunction();
if (aFunc) {
Bindings::RootObject *root = aFunc(jlong_to_ptr(nativeHandle));
// If root is !NULL We must have been called via netscape.javascript.JSObject.getWindow(),
// otherwise we are being called after creating a JSObject in
// JSObject::convertValueToJObject().
if (root) {
addNativeReference (root, root->rootObjectImp());
return ptr_to_jlong(root->rootObjectImp());
}
else {
return nativeHandle;
}
}
return ptr_to_jlong(0);
}
jobject JSObject::convertValueToJObject (KJS::Value value) const
{
ExecState *exec = _root->interpreter()->globalExec();
JNIEnv *env = getJNIEnv();
jobject result = 0;
// See section 22.7 of 'JavaScript: The Definitive Guide, 4th Edition',
// figure 22-5.
// number -> java.lang.Double
// string -> java.lang.String
// boolean -> java.lang.Boolean
// Java instance -> Java instance
// Everything else -> JSObject
KJS::Type type = value.type();
if (type == KJS::NumberType) {
jclass JSObjectClass = env->FindClass ("java/lang/Double");
jmethodID constructorID = env->GetMethodID (JSObjectClass, "<init>", "(D)V");
if (constructorID != NULL) {
result = env->NewObject (JSObjectClass, constructorID, (jdouble)value.toNumber(exec));
}
}
else if (type == KJS::StringType) {
KJS::UString stringValue = value.toString(exec);
JNIEnv *env = getJNIEnv();
result = env->NewString ((const jchar *)stringValue.data(), stringValue.size());
}
else if (type == KJS::BooleanType) {
jclass JSObjectClass = env->FindClass ("java/lang/Boolean");
jmethodID constructorID = env->GetMethodID (JSObjectClass, "<init>", "(Z)V");
if (constructorID != NULL) {
result = env->NewObject (JSObjectClass, constructorID, (jboolean)value.toBoolean(exec));
}
}
else {
// Create a JSObject.
jlong nativeHandle;
if (type == KJS::ObjectType){
KJS::ObjectImp *imp = static_cast<KJS::ObjectImp*>(value.imp());
// We either have a wrapper around a Java instance or a JavaScript
// object. If we have a wrapper around a Java instance, return that
// instance, otherwise create a new Java JSObject with the ObjectImp*
// as it's nativeHandle.
if (imp->classInfo() && strcmp(imp->classInfo()->className, "RuntimeObject") == 0) {
KJS::RuntimeObjectImp *runtimeImp = static_cast<KJS::RuntimeObjectImp*>(value.imp());
Bindings::JavaInstance *runtimeInstance = static_cast<Bindings::JavaInstance *>(runtimeImp->getInternalInstance());
return runtimeInstance->javaInstance();
}
else {
nativeHandle = ptr_to_jlong(imp);
// Bump our 'meta' reference count for the imp. We maintain the reference
// until either finalize is called or the applet shuts down.
addNativeReference (_root, imp);
}
}
// All other types will result in an undefined object.
else {
nativeHandle = UndefinedHandle;
}
// Now create the Java JSObject. Look for the JSObject in it's new (Tiger)
// location and in the original Java 1.4.2 location.
jclass JSObjectClass;
JSObjectClass = env->FindClass ("sun/plugin/javascript/webkit/JSObject");
if (!JSObjectClass) {
env->ExceptionDescribe();
env->ExceptionClear();
JSObjectClass = env->FindClass ("apple/applet/JSObject");
}
jmethodID constructorID = env->GetMethodID (JSObjectClass, "<init>", "(J)V");
if (constructorID != NULL) {
result = env->NewObject (JSObjectClass, constructorID, nativeHandle);
}
}
return result;
}
KJS::Value JSObject::convertJObjectToValue (jobject theObject) const
{
// Instances of netscape.javascript.JSObject get converted back to
// JavaScript objects. All other objects are wrapped. It's not
// possible to pass primitive types from the Java to JavaScript.
// See section 22.7 of 'JavaScript: The Definitive Guide, 4th Edition',
// figure 22-4.
jobject classOfInstance = callJNIObjectMethod(theObject, "getClass", "()Ljava/lang/Class;");
jstring className = (jstring)callJNIObjectMethod(classOfInstance, "getName", "()Ljava/lang/String;");
JS_LOG ("converting instance of class %s\n", Bindings::JavaString(className).UTF8String());
if (strcmp(Bindings::JavaString(className).UTF8String(), "netscape.javascript.JSObject") == 0) {
// Pull the nativeJSObject value from the Java instance. This is a
// pointer to the ObjectImp.
JNIEnv *env = getJNIEnv();
jfieldID fieldID = env->GetFieldID((jclass)classOfInstance, "nativeJSObject", "long");
if (fieldID == NULL) {
return KJS::Undefined();
}
jlong nativeHandle = env->GetLongField(theObject, fieldID);
if (nativeHandle == UndefinedHandle) {
return KJS::Undefined();
}
KJS::ObjectImp *imp = static_cast<KJS::ObjectImp*>(jlong_to_impptr(nativeHandle));
return KJS::Object(const_cast<KJS::ObjectImp*>(imp));
}
Interpreter::lock();
KJS::RuntimeObjectImp *newImp = new KJS::RuntimeObjectImp(new Bindings::JavaInstance (theObject, _root));
Interpreter::unlock();
return KJS::Object(newImp);
}
KJS::List JSObject::listFromJArray(jobjectArray jArray) const
{
JNIEnv *env = getJNIEnv();
long i, numObjects = jArray ? env->GetArrayLength (jArray) : 0;
KJS::List aList;
for (i = 0; i < numObjects; i++) {
jobject anObject = env->GetObjectArrayElement ((jobjectArray)jArray, i);
aList.append (convertJObjectToValue(anObject));
env->DeleteLocalRef (anObject);
}
return aList;
}
extern "C" {
jlong KJS_JSCreateNativeJSObject (JNIEnv *env, jclass clazz, jstring jurl, jlong nativeHandle, jboolean ctx)
{
JSObjectCallContext context;
context.type = CreateNative;
context.nativeHandle = nativeHandle;
return JSObject::invoke (&context).j;
}
void KJS_JSObject_JSFinalize (JNIEnv *env, jclass jsClass, jlong nativeHandle)
{
JSObjectCallContext context;
context.type = Finalize;
context.nativeHandle = nativeHandle;
JSObject::invoke (&context);
}
jobject KJS_JSObject_JSObjectCall (JNIEnv *env, jclass jsClass, jlong nativeHandle, jstring jurl, jstring methodName, jobjectArray args, jboolean ctx)
{
JSObjectCallContext context;
context.type = Call;
context.nativeHandle = nativeHandle;
context.string = methodName;
context.args = args;
return JSObject::invoke (&context).l;
}
jobject KJS_JSObject_JSObjectEval (JNIEnv *env, jclass jsClass, jlong nativeHandle, jstring jurl, jstring jscript, jboolean ctx)
{
JSObjectCallContext context;
context.type = Eval;
context.nativeHandle = nativeHandle;
context.string = jscript;
return JSObject::invoke (&context).l;
}
jobject KJS_JSObject_JSObjectGetMember (JNIEnv *env, jclass jsClass, jlong nativeHandle, jstring jurl, jstring jname, jboolean ctx)
{
JSObjectCallContext context;
context.type = GetMember;
context.nativeHandle = nativeHandle;
context.string = jname;
return JSObject::invoke (&context).l;
}
void KJS_JSObject_JSObjectSetMember (JNIEnv *env, jclass jsClass, jlong nativeHandle, jstring jurl, jstring jname, jobject value, jboolean ctx)
{
JSObjectCallContext context;
context.type = SetMember;
context.nativeHandle = nativeHandle;
context.string = jname;
context.value = value;
JSObject::invoke (&context);
}
void KJS_JSObject_JSObjectRemoveMember (JNIEnv *env, jclass jsClass, jlong nativeHandle, jstring jurl, jstring jname, jboolean ctx)
{
JSObjectCallContext context;
context.type = RemoveMember;
context.nativeHandle = nativeHandle;
context.string = jname;
JSObject::invoke (&context);
}
jobject KJS_JSObject_JSObjectGetSlot (JNIEnv *env, jclass jsClass, jlong nativeHandle, jstring jurl, jint jindex, jboolean ctx)
{
JSObjectCallContext context;
context.type = GetSlot;
context.nativeHandle = nativeHandle;
context.index = jindex;
return JSObject::invoke (&context).l;
}
void KJS_JSObject_JSObjectSetSlot (JNIEnv *env, jclass jsClass, jlong nativeHandle, jstring jurl, jint jindex, jobject value, jboolean ctx)
{
JSObjectCallContext context;
context.type = SetSlot;
context.nativeHandle = nativeHandle;
context.index = jindex;
context.value = value;
JSObject::invoke (&context);
}
jstring KJS_JSObject_JSObjectToString (JNIEnv *env, jclass clazz, jlong nativeHandle)
{
JSObjectCallContext context;
context.type = ToString;
context.nativeHandle = nativeHandle;
return (jstring)JSObject::invoke (&context).l;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -