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

C++ exceptions and tracemonkey

19 views
Skip to first unread message

itroot

unread,
Sep 11, 2009, 6:52:20 AM9/11/09
to
Hello.

Is it safe to throw exceptions inside JSNative, when it call from JS?

For example, if i ./configure tracemonkey with --enable-cpp-
exceptions, will it be ok?
Does tracemonkey support C++ exceptions (i mean correct memory
freeing, etc)?

If not, i assume that the strategy must be:

JSnative() {
try {

} catch {
JS_SendPengingException();
return JS_FALSE;
}
return JS_TRUE;
}

itroot

unread,
Sep 11, 2009, 8:15:57 AM9/11/09
to
And one more question: can i somehow get js exception after
JS_ExecuteScript?

Example:

script.js
throw "JS_EXCEPTION";

C code:
JS_ExecuteSqript(context, .../*precomiled script for scriptjs*/);
if (JS_IsExceptionPending(context)) {
// i think i must be there. but there is no exception on context.
}

Benjamin Smedberg

unread,
Sep 11, 2009, 9:08:07 AM9/11/09
to
On 9/11/09 6:52 AM, itroot wrote:

> Is it safe to throw exceptions inside JSNative, when it call from JS?

No. The Spidermonkey code is not C++-exception-safe at all.

> If not, i assume that the strategy must be:
>
> JSnative() {
> try {
>
> } catch {
> JS_SendPengingException();
> return JS_FALSE;
> }
> return JS_TRUE;
> }

Yes, exactly. Most SM embedders do not use C++ exceptions, and propagate
errors using return codes or other methods.

--BDS

itroot

unread,
Sep 11, 2009, 1:44:29 PM9/11/09
to
Ok, i just figured it out.

If you want to get exceptions from outermost API call, you must set
option JSOPTION_DONT_REPORT_UNCAUGHT.
https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JS_SetOptions

If this option is not set, then js exception will be reported and
cleared (as in following backtrace)

[Switching to Thread -1213303104 (LWP 14466)]

Breakpoint 3, JS_ClearPendingException (cx=0x8827b20) at jsapi.cpp:
5725
5725 cx->throwing = JS_FALSE;
(gdb) bt
#0 JS_ClearPendingException (cx=0x8827b20) at jsapi.cpp:5725
#1 0xb7ba4b4f in js_ReportUncaughtException (cx=0x8827b20) at
jsexn.cpp:1243
#2 0xb7b53f1c in JS_ExecuteScript (cx=0x8827b20, obj=0x8849000,
script=0x8858650, rval=0xbf8f476c) at jsapi.cpp:4946

itroot

unread,
Nov 5, 2009, 6:47:36 AM11/5/09
to
./configure script of tracemonkey supports '--enable-cpp-exceptions'
options, and on my OS (LINUX 2.6) practically all tracemonkey builds
with c++ compiler (g++). So, i assume the worst thing that can happen
by throwing exception from JSNative is memory leak. Is there any plans
to make tracemonkey/spidermonkey exception-safe? Can I help somehow
with that?

Jason Orendorff

unread,
Nov 5, 2009, 1:59:41 PM11/5/09
to
On 11/5/09 3:47 AM, itroot wrote:
> ./configure script of tracemonkey supports '--enable-cpp-exceptions'
> options, and on my OS (LINUX 2.6) practically all tracemonkey builds
> with c++ compiler (g++). So, i assume the worst thing that can happen
> by throwing exception from JSNative is memory leak.

That is definitely incorrect. Just because you can compile the code
with -fexceptions doesn't mean the API contract supports throwing
exceptions across API boundaries!

Throwing bypasses all cleanup actions, not just freeing memory. In
SpiderMonkey this includes things like unwinding the JS stack or
removing stack variables from the GC's root set. Skipping that kind of
cleanup would be Bad. So when the User Guide says, "JSAPI functions
never throw C++ exceptions, and when SpiderMonkey calls an application
callback, the callback must not throw a C++ exception.", it really
means that.

Why do we have --enable-cpp-exceptions then? I hacked it in because my
initial jsapi-tests runner used C++ exceptions (in code that was
outside all JSAPI calls).

> Is there any plans
> to make tracemonkey/spidermonkey exception-safe? Can I help somehow
> with that?

Well, there are no immediate plans, but it would be useful. The desired
semantics would be:

* JSAPI callbacks that currently can't fail, like JSClass.mark,
must not throw (we can enforce this with assertions in the engine)
* JSAPI callbacks like JSNative and JSPropertyOp may throw,
in which case the JS stack is unwound as for out-of-memory[1].
* The JS engine still never throws any exceptions of its own,
so the only way a JSAPI function can throw is if the application
threw that exception itself.
* The JS engine never catches any exceptions thrown by callbacks.

If you want to help, here's what a plan would look like:

1. Wait for bug 516832 and bug 523765 to be fixed. These will remove a
significant amount of post-error cleanup code.

2. RAII-ify the remaining TempValueRooter uses.

3. Look for other places where we do stuff after an error and find ways
to RAII-ify them. (Start by searching for goto; many but not all gotos
in SpiderMonkey are for cleanup.)

4. Write JSAPI tests for a variety of situations where C++ JSNatives
and other callbacks throw exceptions. Fuzz-test. Fix any remaining bugs.

Go for it.

-j

[1]
https://developer.mozilla.org/En/SpiderMonkey/JSAPI_User_Guide#Uncatchable_errors

0 new messages