⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jni_jsobject.cpp

📁 It is Java script interpreter for Nokia browser with source code
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
 * 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 <CoreFoundation/CoreFoundation.h>

#include <assert.h>

#include <identifier.h>
#include <internal.h>
#include <interpreter.h>
#include <list.h>
#include <jni_jsobject.h>
#include <jni_runtime.h>
#include <jni_utility.h>
#include <runtime_object.h>
#include <runtime_root.h>

using namespace KJS::Bindings;
using namespace KJS;

#ifdef NDEBUG
#define JS_LOG(formatAndArgs...) ((void)0)
#else
#define JS_LOG(formatAndArgs...) { \
    fprintf (stderr, "%s(%p,%p):  ", __PRETTY_FUNCTION__, RootObject::runLoop(), CFRunLoopGetCurrent()); \
    fprintf(stderr, formatAndArgs); \
}
#endif

#define UndefinedHandle 1

static bool isJavaScriptThread()
{
    return (RootObject::runLoop() == CFRunLoopGetCurrent());
}

jvalue JSObject::invoke (JSObjectCallContext *context)
{
    jvalue result;

    bzero ((void *)&result, sizeof(jvalue));
    
    if (!isJavaScriptThread()) {        
        // Send the call context to the thread that is allowed to
        // call JavaScript.
        RootObject::dispatchToJavaScriptThread(context);
        result = context->result;
    }
    else {
        jlong nativeHandle = context->nativeHandle;
        if (nativeHandle == UndefinedHandle || nativeHandle == 0) {
            return result;
        }

        if (context->type == CreateNative) {
            result.j = JSObject::createNative(nativeHandle);
        }
        else {
            KJS::ObjectImp *imp = jlong_to_impptr(nativeHandle);
            if (!rootForImp(imp)) {
                fprintf (stderr, "%s:%d:  Attempt to access JavaScript from destroyed applet, type %d.\n", __FILE__, __LINE__, context->type);
                return result;
            }

            switch (context->type){            
                case Call: {
                    result.l = JSObject(nativeHandle).call(context->string, context->args);
                    break;
                }
                
                case Eval: {
                    result.l = JSObject(nativeHandle).eval(context->string);
                    break;
                }
            
                case GetMember: {
                    result.l = JSObject(nativeHandle).getMember(context->string);
                    break;
                }
                
                case SetMember: {
                    JSObject(nativeHandle).setMember(context->string, context->value);
                    break;
                }
                
                case RemoveMember: {
                    JSObject(nativeHandle).removeMember(context->string);
                    break;
                }
            
                case GetSlot: {
                    result.l = JSObject(nativeHandle).getSlot(context->index);
                    break;
                }
                
                case SetSlot: {
                    JSObject(nativeHandle).setSlot(context->index, context->value);
                    break;
                }
            
                case ToString: {
                    result.l = (jobject) JSObject(nativeHandle).toString();
                    break;
                }
    
                case Finalize: {
                    ObjectImp *imp = jlong_to_impptr(nativeHandle);
                    if (findReferenceDictionary(imp) == 0) {
                        // We may have received a finalize method call from the VM 
                        // AFTER removing our last reference to the Java instance.
                        JS_LOG ("finalize called on instance we have already removed.\n");
                    }
                    else {
                        JSObject(nativeHandle).finalize();
                    }
                    break;
                }
                
                default: {
                    fprintf (stderr, "%s:  invalid JavaScript call\n", __PRETTY_FUNCTION__);
                }
            }
        }
        context->result = result;
    }

    return result;
}


JSObject::JSObject(jlong nativeJSObject)
{
    _imp = jlong_to_impptr(nativeJSObject);
    
    // If we are unable to cast the nativeJSObject to an ObjectImp something is
    // terribly wrong.
    assert (_imp != 0);
    
    _root = rootForImp(_imp);
    
    // If we can't find the root for the object something is terribly wrong.
    assert (_root != 0);
}


jobject JSObject::call(jstring methodName, jobjectArray args) const
{
    JS_LOG ("methodName = %s\n", JavaString(methodName).UTF8String());

    // Lookup the function object.
    ExecState *exec = _root->interpreter()->globalExec();
    Interpreter::lock();
    
    Identifier identifier(JavaString(methodName).ustring());
    Value func = _imp->get (exec, identifier);
    Interpreter::unlock();
    if (func.isNull() || func.type() == UndefinedType) {
        // Maybe throw an exception here?
        return 0;
    }

    // Call the function object.
    ObjectImp *funcImp = static_cast<ObjectImp*>(func.imp());
    Object thisObj = Object(const_cast<ObjectImp*>(_imp));
    List argList = listFromJArray(args);
    Interpreter::lock();
    Value result = funcImp->call (exec, thisObj, argList);
    Interpreter::unlock();

    // Convert and return the result of the function call.
    return convertValueToJObject (result);
}

jobject JSObject::eval(jstring script) const
{
    JS_LOG ("script = %s\n", JavaString(script).UTF8String());

    Object thisObj = Object(const_cast<ObjectImp*>(_imp));
    Value result;
    
    Interpreter::lock();

    Completion completion = _root->interpreter()->evaluate(UString(), 0, JavaString(script).ustring(),thisObj);
    ComplType type = completion.complType();
    
    if (type == Normal) {
        result = completion.value();
        if (result.isNull()) {
            result = Undefined();
        }
    }
    else
        result = Undefined();

    Interpreter::unlock();
    
    return convertValueToJObject (result);
}

jobject JSObject::getMember(jstring memberName) const
{
    JS_LOG ("(%p) memberName = %s\n", _imp, JavaString(memberName).UTF8String());

    ExecState *exec = _root->interpreter()->globalExec();

    Interpreter::lock();
    Value result = _imp->get (exec, Identifier (JavaString(memberName).ustring()));
    Interpreter::unlock();

    return convertValueToJObject (result);
}

void JSObject::setMember(jstring memberName, jobject value) const
{
    JS_LOG ("memberName = %s, value = %p\n", JavaString(memberName).UTF8String(), value);
    ExecState *exec = _root->interpreter()->globalExec();
    Interpreter::lock();
    _imp->put (exec, Identifier (JavaString(memberName).ustring()), convertJObjectToValue(value));
    Interpreter::unlock();
}


void JSObject::removeMember(jstring memberName) const
{
    JS_LOG ("memberName = %s\n", JavaString(memberName).UTF8String());

    ExecState *exec = _root->interpreter()->globalExec();
    Interpreter::lock();
    _imp->deleteProperty (exec, Identifier (JavaString(memberName).ustring()));
    Interpreter::unlock();
}


jobject JSObject::getSlot(jint index) const
{
    JS_LOG ("index = %d\n", index);

    ExecState *exec = _root->interpreter()->globalExec();
    Interpreter::lock();
    Value result = _imp->get (exec, (unsigned)index);
    Interpreter::unlock();

    return convertValueToJObject (result);
}


void JSObject::setSlot(jint index, jobject value) const
{
    JS_LOG ("index = %d, value = %p\n", index, value);

    ExecState *exec = _root->interpreter()->globalExec();
    Interpreter::lock();
    _imp->put (exec, (unsigned)index, convertJObjectToValue(value));
    Interpreter::unlock();
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -