1/* 2 * Copyright (C) 2003, 2008 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "jni_jsobject.h" 28 29#if ENABLE(MAC_JAVA_BRIDGE) 30 31#include "Frame.h" 32#include "JNIBridge.h" 33#include "JNIUtility.h" 34#include "JNIUtilityPrivate.h" 35#include "JSDOMBinding.h" 36#include "ScriptController.h" 37#include "StringSourceProvider.h" 38#include "WebCoreFrameView.h" 39#include "runtime_object.h" 40#include "runtime_root.h" 41#include <interpreter/CallFrame.h> 42#include <runtime/Completion.h> 43#include <runtime/JSGlobalObject.h> 44#include <runtime/JSLock.h> 45#include <wtf/Assertions.h> 46 47using WebCore::Frame; 48 49using namespace JSC::Bindings; 50using namespace JSC; 51 52#ifdef NDEBUG 53#define JS_LOG(formatAndArgs...) ((void)0) 54#else 55#define JS_LOG(formatAndArgs...) { \ 56 fprintf (stderr, "%s(%p,%p): ", __PRETTY_FUNCTION__, _performJavaScriptRunLoop, CFRunLoopGetCurrent()); \ 57 fprintf(stderr, formatAndArgs); \ 58} 59#endif 60 61#define UndefinedHandle 1 62 63static CFRunLoopSourceRef _performJavaScriptSource; 64static CFRunLoopRef _performJavaScriptRunLoop; 65 66// May only be set by dispatchToJavaScriptThread(). 67static CFRunLoopSourceRef completionSource; 68 69static void completedJavaScriptAccess (void *i) 70{ 71 assert (CFRunLoopGetCurrent() != _performJavaScriptRunLoop); 72 73 JSObjectCallContext *callContext = (JSObjectCallContext *)i; 74 CFRunLoopRef runLoop = (CFRunLoopRef)callContext->originatingLoop; 75 76 assert (CFRunLoopGetCurrent() == runLoop); 77 78 CFRunLoopStop(runLoop); 79} 80 81static pthread_once_t javaScriptAccessLockOnce = PTHREAD_ONCE_INIT; 82static pthread_mutex_t javaScriptAccessLock; 83static int javaScriptAccessLockCount = 0; 84 85static void initializeJavaScriptAccessLock() 86{ 87 pthread_mutexattr_t attr; 88 89 pthread_mutexattr_init(&attr); 90 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); 91 92 pthread_mutex_init(&javaScriptAccessLock, &attr); 93} 94 95static inline void lockJavaScriptAccess() 96{ 97 // Perhaps add deadlock detection? 98 pthread_once(&javaScriptAccessLockOnce, initializeJavaScriptAccessLock); 99 pthread_mutex_lock(&javaScriptAccessLock); 100 javaScriptAccessLockCount++; 101} 102 103static inline void unlockJavaScriptAccess() 104{ 105 javaScriptAccessLockCount--; 106 pthread_mutex_unlock(&javaScriptAccessLock); 107} 108 109static void dispatchToJavaScriptThread(JSObjectCallContext *context) 110{ 111 // This lock guarantees that only one thread can invoke 112 // at a time, and also guarantees that completionSource; 113 // won't get clobbered. 114 lockJavaScriptAccess(); 115 116 CFRunLoopRef currentRunLoop = CFRunLoopGetCurrent(); 117 118 assert (currentRunLoop != _performJavaScriptRunLoop); 119 120 // Setup a source to signal once the invocation of the JavaScript 121 // call completes. 122 // 123 // FIXME: This could be a potential performance issue. Creating and 124 // adding run loop sources is expensive. We could create one source 125 // per thread, as needed, instead. 126 context->originatingLoop = currentRunLoop; 127 CFRunLoopSourceContext sourceContext = {0, context, NULL, NULL, NULL, NULL, NULL, NULL, NULL, completedJavaScriptAccess}; 128 completionSource = CFRunLoopSourceCreate(NULL, 0, &sourceContext); 129 CFRunLoopAddSource(currentRunLoop, completionSource, kCFRunLoopDefaultMode); 130 131 // Wakeup JavaScript access thread and make it do its work. 132 CFRunLoopSourceSignal(_performJavaScriptSource); 133 if (CFRunLoopIsWaiting(_performJavaScriptRunLoop)) 134 CFRunLoopWakeUp(_performJavaScriptRunLoop); 135 136 // Wait until the JavaScript access thread is done. 137 CFRunLoopRun (); 138 139 CFRunLoopRemoveSource(currentRunLoop, completionSource, kCFRunLoopDefaultMode); 140 CFRelease (completionSource); 141 142 unlockJavaScriptAccess(); 143} 144 145static void performJavaScriptAccess(void*) 146{ 147 assert (CFRunLoopGetCurrent() == _performJavaScriptRunLoop); 148 149 // Dispatch JavaScript calls here. 150 CFRunLoopSourceContext sourceContext; 151 CFRunLoopSourceGetContext (completionSource, &sourceContext); 152 JSObjectCallContext *callContext = (JSObjectCallContext *)sourceContext.info; 153 CFRunLoopRef originatingLoop = callContext->originatingLoop; 154 155 JavaJSObject::invoke (callContext); 156 157 // Signal the originating thread that we're done. 158 CFRunLoopSourceSignal (completionSource); 159 if (CFRunLoopIsWaiting(originatingLoop)) 160 CFRunLoopWakeUp(originatingLoop); 161} 162 163// Must be called from the thread that will be used to access JavaScript. 164void JavaJSObject::initializeJNIThreading() { 165 // Should only be called once. 166 ASSERT(!_performJavaScriptRunLoop); 167 168 // Assume that we can retain this run loop forever. It'll most 169 // likely (always?) be the main loop. 170 _performJavaScriptRunLoop = (CFRunLoopRef)CFRetain(CFRunLoopGetCurrent()); 171 172 // Setup a source the other threads can use to signal the _runLoop 173 // thread that a JavaScript call needs to be invoked. 174 CFRunLoopSourceContext sourceContext = {0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, performJavaScriptAccess}; 175 _performJavaScriptSource = CFRunLoopSourceCreate(NULL, 0, &sourceContext); 176 CFRunLoopAddSource(_performJavaScriptRunLoop, _performJavaScriptSource, kCFRunLoopDefaultMode); 177} 178 179static bool isJavaScriptThread() 180{ 181 return (_performJavaScriptRunLoop == CFRunLoopGetCurrent()); 182} 183 184jvalue JavaJSObject::invoke(JSObjectCallContext *context) 185{ 186 jvalue result; 187 188 bzero ((void *)&result, sizeof(jvalue)); 189 190 if (!isJavaScriptThread()) { 191 // Send the call context to the thread that is allowed to 192 // call JavaScript. 193 dispatchToJavaScriptThread(context); 194 result = context->result; 195 } 196 else { 197 jlong nativeHandle = context->nativeHandle; 198 if (nativeHandle == UndefinedHandle || nativeHandle == 0) { 199 return result; 200 } 201 202 if (context->type == CreateNative) { 203 result.j = JavaJSObject::createNative(nativeHandle); 204 } 205 else { 206 JSObject *imp = jlong_to_impptr(nativeHandle); 207 if (!findProtectingRootObject(imp)) { 208 fprintf (stderr, "%s:%d: Attempt to access JavaScript from destroyed applet, type %d.\n", __FILE__, __LINE__, context->type); 209 return result; 210 } 211 212 switch (context->type){ 213 case Call: { 214 result.l = JavaJSObject(nativeHandle).call(context->string, context->args); 215 break; 216 } 217 218 case Eval: { 219 result.l = JavaJSObject(nativeHandle).eval(context->string); 220 break; 221 } 222 223 case GetMember: { 224 result.l = JavaJSObject(nativeHandle).getMember(context->string); 225 break; 226 } 227 228 case SetMember: { 229 JavaJSObject(nativeHandle).setMember(context->string, context->value); 230 break; 231 } 232 233 case RemoveMember: { 234 JavaJSObject(nativeHandle).removeMember(context->string); 235 break; 236 } 237 238 case GetSlot: { 239 result.l = JavaJSObject(nativeHandle).getSlot(context->index); 240 break; 241 } 242 243 case SetSlot: { 244 JavaJSObject(nativeHandle).setSlot(context->index, context->value); 245 break; 246 } 247 248 case ToString: { 249 result.l = (jobject) JavaJSObject(nativeHandle).toString(); 250 break; 251 } 252 253 case Finalize: { 254 JavaJSObject(nativeHandle).finalize(); 255 break; 256 } 257 258 default: { 259 fprintf (stderr, "%s: invalid JavaScript call\n", __PRETTY_FUNCTION__); 260 } 261 } 262 } 263 context->result = result; 264 } 265 266 return result; 267} 268 269 270JavaJSObject::JavaJSObject(jlong nativeJSObject) 271{ 272 _imp = jlong_to_impptr(nativeJSObject); 273 274 ASSERT(_imp); 275 _rootObject = findProtectingRootObject(_imp); 276 ASSERT(_rootObject); 277} 278 279RootObject* JavaJSObject::rootObject() const 280{ 281 return _rootObject && _rootObject->isValid() ? _rootObject.get() : 0; 282} 283 284jobject JavaJSObject::call(jstring methodName, jobjectArray args) const 285{ 286 JS_LOG ("methodName = %s\n", JavaString(methodName).UTF8String()); 287 288 RootObject* rootObject = this->rootObject(); 289 if (!rootObject) 290 return 0; 291 292 // Lookup the function object. 293 ExecState* exec = rootObject->globalObject()->globalExec(); 294 JSLock lock(SilenceAssertionsOnly); 295 296 Identifier identifier(exec, JavaString(methodName)); 297 JSValue function = _imp->get(exec, identifier); 298 CallData callData; 299 CallType callType = function.getCallData(callData); 300 if (callType == CallTypeNone) 301 return 0; 302 303 // Call the function object. 304 MarkedArgumentBuffer argList; 305 getListFromJArray(exec, args, argList); 306 rootObject->globalObject()->globalData()->timeoutChecker.start(); 307 JSValue result = JSC::call(exec, function, callType, callData, _imp, argList); 308 rootObject->globalObject()->globalData()->timeoutChecker.stop(); 309 310 return convertValueToJObject(result); 311} 312 313jobject JavaJSObject::eval(jstring script) const 314{ 315 JS_LOG ("script = %s\n", JavaString(script).UTF8String()); 316 317 JSValue result; 318 319 JSLock lock(SilenceAssertionsOnly); 320 321 RootObject* rootObject = this->rootObject(); 322 if (!rootObject) 323 return 0; 324 325 rootObject->globalObject()->globalData()->timeoutChecker.start(); 326 Completion completion = JSC::evaluate(rootObject->globalObject()->globalExec(), rootObject->globalObject()->globalScopeChain(), makeSource(JavaString(script)), JSC::JSValue()); 327 rootObject->globalObject()->globalData()->timeoutChecker.stop(); 328 ComplType type = completion.complType(); 329 330 if (type == Normal) { 331 result = completion.value(); 332 if (!result) 333 result = jsUndefined(); 334 } else 335 result = jsUndefined(); 336 337 return convertValueToJObject (result); 338} 339 340jobject JavaJSObject::getMember(jstring memberName) const 341{ 342 JS_LOG ("(%p) memberName = %s\n", _imp, JavaString(memberName).UTF8String()); 343 344 RootObject* rootObject = this->rootObject(); 345 if (!rootObject) 346 return 0; 347 348 ExecState* exec = rootObject->globalObject()->globalExec(); 349 350 JSLock lock(SilenceAssertionsOnly); 351 JSValue result = _imp->get(exec, Identifier(exec, JavaString(memberName))); 352 353 return convertValueToJObject(result); 354} 355 356void JavaJSObject::setMember(jstring memberName, jobject value) const 357{ 358 JS_LOG ("memberName = %s, value = %p\n", JavaString(memberName).UTF8String(), value); 359 360 RootObject* rootObject = this->rootObject(); 361 if (!rootObject) 362 return; 363 364 ExecState* exec = rootObject->globalObject()->globalExec(); 365 366 JSLock lock(SilenceAssertionsOnly); 367 PutPropertySlot slot; 368 _imp->put(exec, Identifier(exec, JavaString(memberName)), convertJObjectToValue(exec, value), slot); 369} 370 371 372void JavaJSObject::removeMember(jstring memberName) const 373{ 374 JS_LOG ("memberName = %s\n", JavaString(memberName).UTF8String()); 375 376 RootObject* rootObject = this->rootObject(); 377 if (!rootObject) 378 return; 379 380 ExecState* exec = rootObject->globalObject()->globalExec(); 381 JSLock lock(SilenceAssertionsOnly); 382 _imp->deleteProperty(exec, Identifier(exec, JavaString(memberName))); 383} 384 385 386jobject JavaJSObject::getSlot(jint index) const 387{ 388#ifdef __LP64__ 389 JS_LOG ("index = %d\n", index); 390#else 391 JS_LOG ("index = %ld\n", index); 392#endif 393 394 RootObject* rootObject = this->rootObject(); 395 if (!rootObject) 396 return 0; 397 398 ExecState* exec = rootObject->globalObject()->globalExec(); 399 400 JSLock lock(SilenceAssertionsOnly); 401 JSValue result = _imp->get(exec, index); 402 403 return convertValueToJObject(result); 404} 405 406 407void JavaJSObject::setSlot(jint index, jobject value) const 408{ 409#ifdef __LP64__ 410 JS_LOG ("index = %d, value = %p\n", index, value); 411#else 412 JS_LOG ("index = %ld, value = %p\n", index, value); 413#endif 414 415 RootObject* rootObject = this->rootObject(); 416 if (!rootObject) 417 return; 418 419 ExecState* exec = rootObject->globalObject()->globalExec(); 420 JSLock lock(SilenceAssertionsOnly); 421 _imp->put(exec, (unsigned)index, convertJObjectToValue(exec, value)); 422} 423 424 425jstring JavaJSObject::toString() const 426{ 427 JS_LOG ("\n"); 428 429 RootObject* rootObject = this->rootObject(); 430 if (!rootObject) 431 return 0; 432 433 JSLock lock(SilenceAssertionsOnly); 434 JSObject *thisObj = const_cast<JSObject*>(_imp); 435 ExecState* exec = rootObject->globalObject()->globalExec(); 436 437 return (jstring)convertValueToJValue (exec, thisObj, object_type, "java.lang.String").l; 438} 439 440void JavaJSObject::finalize() const 441{ 442 if (RootObject* rootObject = this->rootObject()) 443 rootObject->gcUnprotect(_imp); 444} 445 446static PassRefPtr<RootObject> createRootObject(void* nativeHandle) 447{ 448 Frame* frame = 0; 449 for (NSView *view = (NSView *)nativeHandle; view; view = [view superview]) { 450 if ([view conformsToProtocol:@protocol(WebCoreFrameView)]) { 451 NSView<WebCoreFrameView> *webCoreFrameView = static_cast<NSView<WebCoreFrameView>*>(view); 452 frame = [webCoreFrameView _web_frame]; 453 break; 454 } 455 } 456 if (!frame) 457 return 0; 458 return frame->script()->createRootObject(nativeHandle); 459} 460 461// We're either creating a 'Root' object (via a call to JavaJSObject.getWindow()), or 462// another JavaJSObject. 463jlong JavaJSObject::createNative(jlong nativeHandle) 464{ 465 JS_LOG ("nativeHandle = %d\n", (int)nativeHandle); 466 467 if (nativeHandle == UndefinedHandle) 468 return nativeHandle; 469 470 if (findProtectingRootObject(jlong_to_impptr(nativeHandle))) 471 return nativeHandle; 472 473 RefPtr<RootObject> rootObject = createRootObject(jlong_to_ptr(nativeHandle)); 474 475 // If rootObject is !NULL We must have been called via netscape.javascript.JavaJSObject.getWindow(), 476 // otherwise we are being called after creating a JavaJSObject in 477 // JavaJSObject::convertValueToJObject(). 478 if (rootObject) { 479 JSObject* globalObject = rootObject->globalObject(); 480 // We call gcProtect here to get the object into the root object's "protect set" which 481 // is used to test if a native handle is valid as well as getting the root object given the handle. 482 rootObject->gcProtect(globalObject); 483 return ptr_to_jlong(globalObject); 484 } 485 486 return nativeHandle; 487} 488 489jobject JavaJSObject::convertValueToJObject(JSValue value) const 490{ 491 JSLock lock(SilenceAssertionsOnly); 492 493 RootObject* rootObject = this->rootObject(); 494 if (!rootObject) 495 return 0; 496 497 ExecState* exec = rootObject->globalObject()->globalExec(); 498 JNIEnv *env = getJNIEnv(); 499 jobject result = 0; 500 501 // See section 22.7 of 'JavaScript: The Definitive Guide, 4th Edition', 502 // figure 22-5. 503 // number -> java.lang.Double 504 // string -> java.lang.String 505 // boolean -> java.lang.Boolean 506 // Java instance -> Java instance 507 // Everything else -> JavaJSObject 508 509 if (value.isNumber()) { 510 jclass JSObjectClass = env->FindClass ("java/lang/Double"); 511 jmethodID constructorID = env->GetMethodID (JSObjectClass, "<init>", "(D)V"); 512 if (constructorID != NULL) { 513 result = env->NewObject (JSObjectClass, constructorID, (jdouble)value.toNumber(exec)); 514 } 515 } else if (value.isString()) { 516 UString stringValue = value.toString(exec); 517 JNIEnv *env = getJNIEnv(); 518 result = env->NewString ((const jchar *)stringValue.data(), stringValue.size()); 519 } else if (value.isBoolean()) { 520 jclass JSObjectClass = env->FindClass ("java/lang/Boolean"); 521 jmethodID constructorID = env->GetMethodID (JSObjectClass, "<init>", "(Z)V"); 522 if (constructorID != NULL) { 523 result = env->NewObject (JSObjectClass, constructorID, (jboolean)value.toBoolean(exec)); 524 } 525 } 526 else { 527 // Create a JavaJSObject. 528 jlong nativeHandle; 529 530 if (value.isObject()) { 531 JSObject* imp = asObject(value); 532 533 // We either have a wrapper around a Java instance or a JavaScript 534 // object. If we have a wrapper around a Java instance, return that 535 // instance, otherwise create a new Java JavaJSObject with the JSObject* 536 // as its nativeHandle. 537 if (imp->classInfo() && strcmp(imp->classInfo()->className, "RuntimeObject") == 0) { 538 RuntimeObjectImp* runtimeImp = static_cast<RuntimeObjectImp*>(imp); 539 JavaInstance *runtimeInstance = static_cast<JavaInstance *>(runtimeImp->getInternalInstance()); 540 if (!runtimeInstance) 541 return 0; 542 543 return runtimeInstance->javaInstance(); 544 } 545 else { 546 nativeHandle = ptr_to_jlong(imp); 547 rootObject->gcProtect(imp); 548 } 549 } 550 // All other types will result in an undefined object. 551 else { 552 nativeHandle = UndefinedHandle; 553 } 554 555 // Now create the Java JavaJSObject. Look for the JavaJSObject in its new (Tiger) 556 // location and in the original Java 1.4.2 location. 557 jclass JSObjectClass; 558 559 JSObjectClass = env->FindClass ("sun/plugin/javascript/webkit/JSObject"); 560 if (!JSObjectClass) { 561 env->ExceptionDescribe(); 562 env->ExceptionClear(); 563 JSObjectClass = env->FindClass ("apple/applet/JSObject"); 564 } 565 566 jmethodID constructorID = env->GetMethodID (JSObjectClass, "<init>", "(J)V"); 567 if (constructorID != NULL) { 568 result = env->NewObject (JSObjectClass, constructorID, nativeHandle); 569 } 570 } 571 572 return result; 573} 574 575JSValue JavaJSObject::convertJObjectToValue(ExecState* exec, jobject theObject) const 576{ 577 // Instances of netscape.javascript.JSObject get converted back to 578 // JavaScript objects. All other objects are wrapped. It's not 579 // possible to pass primitive types from the Java to JavaScript. 580 // See section 22.7 of 'JavaScript: The Definitive Guide, 4th Edition', 581 // figure 22-4. 582 jobject classOfInstance = callJNIMethod<jobject>(theObject, "getClass", "()Ljava/lang/Class;"); 583 if (!classOfInstance) { 584 JSLock lock(SilenceAssertionsOnly); 585 return JavaInstance::create(theObject, _rootObject)->createRuntimeObject(exec); 586 } 587 588 // Only the sun.plugin.javascript.webkit.JSObject has a member called nativeJSObject. This class is 589 // created above to wrap internal browser objects. The constructor of this class takes the native 590 // pointer and stores it in this object, so that it can be retrieved below. 591 jstring className = (jstring)callJNIMethod<jobject>(classOfInstance, "getName", "()Ljava/lang/String;"); 592 if (!className || (strcmp(JavaString(className).UTF8String(), "sun.plugin.javascript.webkit.JSObject") != 0)) { 593 JSLock lock(SilenceAssertionsOnly); 594 return JavaInstance::create(theObject, _rootObject)->createRuntimeObject(exec); 595 } 596 597 // Pull the nativeJSObject value from the Java instance. This is a 598 // pointer to the JSObject. 599 JNIEnv *env = getJNIEnv(); 600 jfieldID fieldID = env->GetFieldID((jclass)classOfInstance, "nativeJSObject", "J"); 601 if (fieldID == NULL) 602 return jsUndefined(); 603 jlong nativeHandle = env->GetLongField(theObject, fieldID); 604 if (nativeHandle == UndefinedHandle) 605 return jsUndefined(); 606 JSObject *imp = static_cast<JSObject*>(jlong_to_impptr(nativeHandle)); 607 return imp; 608} 609 610void JavaJSObject::getListFromJArray(ExecState* exec, jobjectArray jArray, MarkedArgumentBuffer& list) const 611{ 612 JNIEnv *env = getJNIEnv(); 613 int numObjects = jArray ? env->GetArrayLength(jArray) : 0; 614 615 for (int i = 0; i < numObjects; i++) { 616 jobject anObject = env->GetObjectArrayElement ((jobjectArray)jArray, i); 617 if (anObject) { 618 list.append(convertJObjectToValue(exec, anObject)); 619 env->DeleteLocalRef (anObject); 620 } 621 else { 622 env->ExceptionDescribe(); 623 env->ExceptionClear(); 624 } 625 } 626} 627 628extern "C" { 629 630jlong KJS_JSCreateNativeJSObject (JNIEnv*, jclass, jstring, jlong nativeHandle, jboolean) 631{ 632 JSObjectCallContext context; 633 context.type = CreateNative; 634 context.nativeHandle = nativeHandle; 635 return JavaJSObject::invoke (&context).j; 636} 637 638void KJS_JSObject_JSFinalize (JNIEnv*, jclass, jlong nativeHandle) 639{ 640 JSObjectCallContext context; 641 context.type = Finalize; 642 context.nativeHandle = nativeHandle; 643 JavaJSObject::invoke (&context); 644} 645 646jobject KJS_JSObject_JSObjectCall (JNIEnv*, jclass, jlong nativeHandle, jstring, jstring methodName, jobjectArray args, jboolean) 647{ 648 JSObjectCallContext context; 649 context.type = Call; 650 context.nativeHandle = nativeHandle; 651 context.string = methodName; 652 context.args = args; 653 return JavaJSObject::invoke (&context).l; 654} 655 656jobject KJS_JSObject_JSObjectEval (JNIEnv*, jclass, jlong nativeHandle, jstring, jstring jscript, jboolean) 657{ 658 JSObjectCallContext context; 659 context.type = Eval; 660 context.nativeHandle = nativeHandle; 661 context.string = jscript; 662 return JavaJSObject::invoke (&context).l; 663} 664 665jobject KJS_JSObject_JSObjectGetMember (JNIEnv*, jclass, jlong nativeHandle, jstring, jstring jname, jboolean) 666{ 667 JSObjectCallContext context; 668 context.type = GetMember; 669 context.nativeHandle = nativeHandle; 670 context.string = jname; 671 return JavaJSObject::invoke (&context).l; 672} 673 674void KJS_JSObject_JSObjectSetMember (JNIEnv*, jclass, jlong nativeHandle, jstring, jstring jname, jobject value, jboolean) 675{ 676 JSObjectCallContext context; 677 context.type = SetMember; 678 context.nativeHandle = nativeHandle; 679 context.string = jname; 680 context.value = value; 681 JavaJSObject::invoke (&context); 682} 683 684void KJS_JSObject_JSObjectRemoveMember (JNIEnv*, jclass, jlong nativeHandle, jstring, jstring jname, jboolean) 685{ 686 JSObjectCallContext context; 687 context.type = RemoveMember; 688 context.nativeHandle = nativeHandle; 689 context.string = jname; 690 JavaJSObject::invoke (&context); 691} 692 693jobject KJS_JSObject_JSObjectGetSlot (JNIEnv*, jclass, jlong nativeHandle, jstring, jint jindex, jboolean) 694{ 695 JSObjectCallContext context; 696 context.type = GetSlot; 697 context.nativeHandle = nativeHandle; 698 context.index = jindex; 699 return JavaJSObject::invoke (&context).l; 700} 701 702void KJS_JSObject_JSObjectSetSlot (JNIEnv*, jclass, jlong nativeHandle, jstring, jint jindex, jobject value, jboolean) 703{ 704 JSObjectCallContext context; 705 context.type = SetSlot; 706 context.nativeHandle = nativeHandle; 707 context.index = jindex; 708 context.value = value; 709 JavaJSObject::invoke (&context); 710} 711 712jstring KJS_JSObject_JSObjectToString (JNIEnv*, jclass, jlong nativeHandle) 713{ 714 JSObjectCallContext context; 715 context.type = ToString; 716 context.nativeHandle = nativeHandle; 717 return (jstring)JavaJSObject::invoke (&context).l; 718} 719 720} 721 722#endif // ENABLE(MAC_JAVA_BRIDGE) 723