If a QI method throws anything other than NS_NOINTERFACE, we should just report
it and propagate NS_NOINTERFACE out to callers. And if it throws
NS_NOINTERFACE, then we already clear the pending exception in
nsXPCWrappedJSClass::CallQueryInterfaceOnJSObject, then turn the null return
value into a C++ NS_NOINTERFACE return.
The code as it stood is a bit weird. It sets up an AutoJSAPI that takes
ownership of error reporting. Then later it also sets up an
AutoEntryScript... but keeps using the JSContext it got from the AutoJSAPI.
It's not obvious that there is any guarantee that this matches the JSContext
from the AutoEntryScript!
So we go ahead and change the things that are nominally using the
AutoEntryScript to use it JSContext and take ownership of error reporting on it
explicitly. If the JSContext is the same as that of the AutoJSAPI, then we were
getting backstopped by its taking ownership of error reporting anyway. If it's
not, we don't want to leave exceptions dangling on it.
There are several cases to consider in terms of where exceptions might come from
here:
1) We could have an exception on the JSContext already when we set up the
AutoEntryScript. In practice this does not happen, and once this change is made
we will add an assert to that effect in AutoJSAPI::InitInternal. See bug 1112920.
2) We could have an exception thrown by the XPCCallContext constructor, but it
never does that when initialized, as here, without a JSObject*.
3) We can have an exception thrown by CallMethod itself, if the callee method
wants a JSContext or optional argc. This patch switches that to using
CheckForException, which means it will behave exactly like exceptions thrown
from the actual implementation of the method we're calling in terms of how it's
reported and whether it's rethrown to callers, if any.
4) We can have exceptions thrown various places (e.g. during argument and
retval/outparam conversions) after this point, but those are all under the scope
of the AutoScriptEvaluate, whose destructor will restore the JSContext state to whatever it
was when the AutoScriptEvaluate was created. Since the AutoScriptEvaluate goes
out of scope before the AutoEntryScript does, there will be no dangling
exception on the JSContext at that point.
5) We can have exceptions thrown by the actual method call. Those are
reported, as needed, via CheckForException, and will continue to be so reported.
So in general there are two behavior changes here:
* We now treat the "callee wants JSContext or argc" case as the same as an
exception from the callee, which is not what we used to do.
* If the object we're calling comes from an inner window whose outer window has
been torn down, we will now correctly report the exception against that inner
window. Before this patch, what happend is that we would init the
AutoEntryScript with the inner window, but FindJSContext would not find an
nsIScriptContext on it (since its outer has been torn down), so we would use
the safe JS context. Then in xpc::SystemErrorReporter we would check for a
window associated with the JSContext, not find one, check for an addon sandbox
current compartment, see we're not in one, and then use the privileged junk
scope for its error reporting. The new setup in AutoJSAPI::ReportError checks
for the current compartent being a window, which of course it is.
The dtor for PersistentRooted<> removes it from a linked list, which means we
need a static ctor to register that dtor with the atexit machinary. So the
easiest thing to do is make sScriptedInterruptCallback a pointer that points to
a PersistentRootedValue we allocate on the heap.
Redoes object element measurement and reporting:
- Adds "non-heap/elements/shared", which reports a (size / refcount)
measurement. Previously these measurements went into
"non-heap/elements/mapped" and the full size would be erroneously reported
for every thread sharing the buffer.
- Renames "non-heap/elements/mapped" as "non-heap/elements/normal".
- Renames "malloc-heap/elements/non-asm.js" as "malloc-heap/elements/normal".
- Leaves "{malloc,non}-heap/elements/asm.js" unchanged.
--HG--
extra : rebase_source : cd1a660000fcb95674b317098be2dfec792b2c8e
It's gone from 4,096 bytes per JS thread to 72 bytes per thread. (Also, the
old code only measured the DtoaState for the main thread.)
--HG--
extra : rebase_source : bfe0772b8c760a45ca3665e2c0939b121189520a