A project I'm working on recently ran into a garbage collection crash
that caused us to get super paranoid about how we're retrieving values
from JavaScript. It's a multithreaded (JS_THREADSAFE) app, so we want
to be sure we're doing everything possible to avoid races/deadlocks/
etc.
We're pretty sure the crash turned out to be because of this bug:
- https://bugzilla.mozilla.org/show_bug.cgi?id=438633
We've found a workaround for it, but we've since been having some
internal debates about whether code like the following is okay w.r.t.
garbage collection:
// Note: The calling code has already called JS_BeginRequest() on
'cx',
// so we don't bother doing it again here...
JSBool setFileName(JSContext* cx,
JSObject*, uintN argc,
jsval* argv,
jsval*)
{
if (argc != 2 ||
!JSVAL_IS_STRING(argv[0]) ||
!JSVAL_IS_STRING(argv[1]) )
{
emitError(...);
return JS_FALSE;
}
std::string streamName =
JS_GetStringBytes(JSVAL_TO_STRING(argv[0]) );
std::string fileName = JS_GetStringBytes(JSVAL_TO_STRING(argv[1]) );
...
}
Specifically, the question is, can 'streamName' or 'fileName' ever get
garbage values? Or can the app *crash* because we didn't root the
temporaries?
It has been suggested that it would be safer to rewrite the above two
assignments as:
JSString* strStreamName = JS_ValueToString(cx, argv[0]);
if (!strStreamName) { emitError(...); return JS_FALSE; }
argv[0] = STRING_TO_JSVAL(strStreamName);
JSString* strFileName = JS_ValueToString(cx, argv[1]);
if (!strFileName) { emitError(...); return JS_FALSE; }
argv[1] = STRING_TO_JSVAL(strFileName);
std::string streamName = JS_GetStringBytes(strStreamName);
std::string fileName = JS_GetStringBytes(strFileName);
I suspect that the extra six lines are simply a waste of space in this
case, but I've been wrong about JSAPI questions like this often enough
that I no longer trust my own judgement. Is it okay to just say:
std::string streamName =
JS_GetStringBytes(JSVAL_TO_STRING(argv[0]) );
std::string fileName = JS_GetStringBytes(JSVAL_TO_STRING(argv[1]) );
and be done with it?
Any insight much appreciated...