Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Setting JavaScript properties for an XUL dialog from C++ causes a JS_ASSERT

5 views
Skip to first unread message

David Wimsey

unread,
Apr 22, 2008, 1:13:12 AM4/22/08
to
I've embedded gecko into my application, I use a function to display
an XUL dialog to the user (below). The function sets up the window,
and then sets some java script properties and defines a function in
the windows context in order to pass a return value back out of the
window, as well as pass some arguments into the javascript within the
XUL window.

All was fine and good in the 1.8 branch we were using previously.
However, it would be rather silly to continue using the 1.8 branch on
a project which hasn't been released yet, so I've been updating the
embedding code to use the 1.9 branch (HEAD). Minor changes were
needed to get the code to compile and work, had to remove
NS_STATIC_CAST as this seems to have went away, and update the
references for the ASCII to UTF8/16 string conversion functions.
Simple enough.

The JavaScript portion seems to be a problem however. In the code
below, everything looks and works find up until the JS_SetProperty
call is made (if the JS_SetProperty call and related error checking is
commented out, the same problem occurs at the JS_DefineFunction line
following after it).

When JS_SetProperty is called, if I step into the function in the
debugger, I see that on line 3531 of jsapi.c there is a call to
CHECK_REQUEST(cx) which expands to (note cx is jscx from my function
at the end of this message when JS_SetProperty is called):

#define
CHECK_REQUEST(cx) \
JS_ASSERT((cx)->requestDepth || (cx)->thread == (cx)->runtime-
>gcThread)

At the time of failure, the variables are:
cx->requestDepth = 0
cx->thread = (pointer value which appears to be valid by visual
inspection)
cx->runtime->gcThread = 0x0

In every other call to JS_SetProperty I see from the debugger, cx-
>requestDepth seems to be 3.

While this is bad, it does not suprise me. I always had the feeling
when this code was writen that it wasn't being done the right way.
I've googled and looked for changes in 1.9 that would indicate this
sort of breakage and have found nothing, which leads me to believe
that no one does it that way I am, likely because its not the right
way to go about it.

So if anyone has an idea about how to make the code below actually
work correctly, what what the correct way to get variables into the
javascript context of a xul window before the scripts in it are run,
as well as get a 'return' value out of it afterwords, I'd love to hear
it.

---------------------------------------------------------------------------------
int Gecko_OpenDialog(void *nativeParentWindow, const wchar_t *url, int
width, int height, BOOL isModal, unsigned int argc, ...)
{
va_list arg_list;
nsresult rv;
JSContext *jscx = 0;

nsCOMPtr<nsIWebBrowserChrome> chrome;

rv = OpenWindow(nsnull, nsIWebBrowserChrome::CHROME_OPENAS_CHROME|
nsIWebBrowserChrome::CHROME_OPENAS_DIALOG|
nsIWebBrowserChrome::CHROME_TITLEBAR|( isModal!=FALSE ?
nsIWebBrowserChrome::CHROME_MODAL : 0), url, getter_AddRefs(chrome),
nativeParentWindow);
if(!NS_SUCCEEDED(rv)) {
return(-2);
}

nsCOMPtr<nsIWebBrowser> webBrowser;
rv = chrome->GetWebBrowser(getter_AddRefs(webBrowser));
if(!NS_SUCCEEDED(rv)) {
return(-3);
}

nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(webBrowser));
if(webNav==NULL) {
return(-4);
}

nsCOMPtr<nsIDOMWindow> dwindow;
rv = webBrowser->GetContentDOMWindow(getter_AddRefs(dwindow));
if(!NS_SUCCEEDED(rv)) {
return(-5);
}

int retVal = -1; // the default value is 'canceled'

// BEGIN JAVASCRIPT SETUP
nsCOMPtr<nsIScriptGlobalObject> scriptGlobalObj =
do_QueryInterface(dwindow);
if(scriptGlobalObj) {
nsCOMPtr<nsIScriptContext> scriptcx;
scriptcx = scriptGlobalObj->GetContext();
if(scriptcx) {
jscx = (JSContext *)scriptcx->GetNativeContext();
} else {
return(-6);
}
} else {
return(-7);
}

// if everything went as planned...
JSBool w;
jsval val;
JSFunction *jfunc;
if(jscx) {
JSObject *jswindow = scriptGlobalObj->GetGlobalJSObject();
int i = (int)&retVal;
val = INT_TO_JSVAL(i);
w = JS_SetProperty(jscx, jswindow, "retValPtr", &val);
if(w==JS_FALSE) {
return(-8);
}
jfunc = JS_DefineFunction(jscx, jswindow, "setDialogReturnValue",
jsSetDialogReturnValue, 1, 0);
if(jfunc==NULL) {
return(-9);
}

// Add the arguments
va_start(arg_list, argc);
char *nameStr;
char *argStr;
JSString *str;
while(argc>1) {
nameStr = va_arg(arg_list, char *);
argc--;
argStr = va_arg(arg_list, char *);
argc--;
str = JS_NewStringCopyN(jscx, argStr, strlen(argStr));
val = STRING_TO_JSVAL(str);
w = JS_SetProperty(jscx, jswindow, nameStr, &val);
}
va_end(arg_list);
} else {
return(-10);
}
// END JAVASCRIPT SETUP

if((width>0)&&(height>0)) {
chrome->SizeBrowserTo(width, height);
// since we set the size manually, we have to force visibility
nsCOMPtr<nsIEmbeddingSiteWindow> embeddedWindow =
do_QueryInterface(chrome);
embeddedWindow->SetVisibility(PR_TRUE);
}
chrome->ShowAsModal();
return(retVal);
}


Boris Zbarsky

unread,
Apr 22, 2008, 1:29:58 AM4/22/08
to
David Wimsey wrote:
> The JavaScript portion seems to be a problem however. In the code
> below, everything looks and works find up until the JS_SetProperty
...

> When JS_SetProperty is called, if I step into the function in the
> debugger, I see that on line 3531 of jsapi.c there is a call to
> CHECK_REQUEST(cx)

See <http://developer.mozilla.org/en/docs/JS_BeginRequest>. Basically, you need
to call JS_BeginRequest/JS_EndRequest around JSAPI calls.

-Boris

David Wimsey

unread,
Apr 22, 2008, 1:51:05 AM4/22/08
to

Thanks, I didn't expect an answer so quick! I was hoping it would be
something simple. I just wrapped the portion of the function that
deals with javascript in those calls and everything looks good.

Are these functions required now due to Gecko 1.9 using JS_THREADSAFE,
and that the 1.8 branch did not?

Boris Zbarsky

unread,
Apr 22, 2008, 11:58:20 AM4/22/08
to
David Wimsey wrote:
> Are these functions required now due to Gecko 1.9 using JS_THREADSAFE,
> and that the 1.8 branch did not?

No, I think both used JS_THREADSAFE... I'm not sure what the change was that
cause the change in behavior you see.

-Boris

0 new messages