📄 jni_jsobject.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 <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 + -