Subj : Calling non-existent object function crashes engine To : netscape.public.mozilla.jseng From : Syd Logan Date : Mon Sep 05 2005 03:38 pm I'm working on code that, like xpconnect, bridges JavaScript code and and C++ code found in a shared library component. In doing so, JavaScript code makes a call to obtain an object for a C++ class it is interested in using, and then calls functions on it. For example: componentmgr.getComponent("94981D9E-FC99-11D9-8BDE-F66BAD1E3F3A"); function Button1Click() { dump("Inside of Button1Click\n"); dump(170 + "\n"); var component = componentmgr.getComponent("94981D9E-FC99-11D9-8BDE-F66BAD1E3F3A"); if (component) { dump("Button1Click got the component\n"); var anobject = component.getObject("2ABDF00B-025E-11DA-BFFE-000A27942344"); if (anobject) { dump("Button1Click got the object\n"); anobject.Hello("Syd"); // a function that does exist anobject.Foobar(); // a function that doesn't exist, crash .... To handle the request by the above code for a class object, a JavaScript object is created and populated with pointers to extern "C" functions that wrap the object, using JS_DefineFunction(). This JavaScript object is then returned to the caller. Here's the relevant code: JSClass objectClass = { name.c_str(), JSCLASS_NEW_RESOLVE, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub }; m_jsObj = JS_DefineObject(ctx, obj, name.c_str(), &objectClass, NULL, 0); .... list args = func->GetArgumentList(); int size = args.size(); // query the component for the proxy lib entry point JSNative fptr = (JSNative) lib->FindSymbol(name2); if (fptr) { JSFunction *func = JS_DefineFunction(ctx, m_jsObj, fnName.c_str(), fptr, // JSNative size, 0); .... Here is the problem: if the JavaScript function calls functions that were explicitly added to the object via JS_DefineFunction(), things work great. However, if I call a function that was not added this way, the JavaScript engine crashes hard: #0 0xa30a353c in gNotifyRef () #1 0x00672854 in js_LookupPropertyWithFlags (cx=0x3e2950, obj=0x3e5a80, id=4678032, flags=1, objp=0xbfffdbc0, propp=0xbfffdbc4) at jsobj.c:2542 #2 0x0067235c in js_LookupProperty (cx=0x3e2950, obj=0x3e5a80, id=4678032, objp=0xbfffdbc0, propp=0xbfffdbc4) at jsobj.c:2447 #3 0x0067378c in js_GetProperty (cx=0x3e2950, obj=0x3e5a80, id=4678032, vp=0xbfffdd1c) at jsobj.c:2732 #4 0x00655874 in js_Interpret (cx=0x3e2950, pc=0x47921b "5", result=0xbfffe3b0) at jsinterp.c:3290 #5 0x00644fac in js_Invoke (cx=0x3e2950, argc=0, flags=2) at jsinterp.c:1193 #6 0x00645414 in js_InternalInvoke (cx=0x3e2950, obj=0x3e3fc0, fval=4086384, flags=0, argc=0, argv=0x0, rval=0xbfffe664) at jsinterp.c:1270 #7 0x005fd0fc in JS_CallFunction (cx=0x3e2950, obj=0x3e3fc0, fun=0x44a7a0, argc=0, argv=0x0, rval=0xbfffe664) at jsapi.c:3867 #8 0x000066f8 in Button::ButtonPressed() (this=0x4650d0) at button.cpp:129 #9 0x002cebf0 in ButtonPressSubject::NotifyButtonPress() (this=0x465108) at ../subject.cpp:13 #10 0x002cd4d0 in CocoaButtonImpl::HandleCommand() (this=0x465100) at cocoabuttonimpl.mm:55 #11 0x002ce28c in -[ButtonAction onClick:] (self=0x546050, _cmd=0x2d9f84, sender=0x5463b0) at cocoabuttonaction.mm:15 #12 0x930f9f5c in -[NSApplication sendAction:to:from:] () #13 0x9311a718 in -[NSControl sendAction:to:] () #14 0x9315eea4 in -[NSCell _sendActionFrom:] () #15 0x930f3968 in -[NSCell trackMouse:inRect:ofView:untilMouseUp:] () #16 0x9315eac0 in -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] () #17 0x9312e6b4 in -[NSControl mouseDown:] () #18 0x930c1698 in -[NSWindow sendEvent:] () #19 0x930a94ec in -[NSApplication sendEvent:] () #20 0x930b2418 in -[NSApplication run] () #21 0x002ce1b4 in CocoaAppImpl::MainLoop() (this=0x45fb50) at cocoaappimpl.mm:28 #22 0x00008200 in App::MainLoop() (this=0x45fad0) at app.cpp:23 #23 0x00003bec in main (argc=0, argv=0xbffffb90) at layout.cpp:305 I'm wondering, is there something that needs to be done to protect calling applications from tubing the JavaScript engine in this way? I'm still getting my feet wet with JavaScript engine embedding, though I have made great progress, this is stumping me a bit. More details on the design/evolution of this software can be read about at http://sydlogan.blogspot.com. Thanks, syd .