Bug 1257919 part 6. Make the filename getter on JSStackFrame take an explicit JSContext. r=khuey

This commit is contained in:
Boris Zbarsky 2016-03-22 13:50:31 -04:00
parent ecd56b7ee6
commit efa07c06d1
11 changed files with 38 additions and 32 deletions

View File

@ -1033,12 +1033,12 @@ Console::NoopMethod()
static
nsresult
StackFrameToStackEntry(nsIStackFrame* aStackFrame,
StackFrameToStackEntry(JSContext* aCx, nsIStackFrame* aStackFrame,
ConsoleStackEntry& aStackEntry)
{
MOZ_ASSERT(aStackFrame);
nsresult rv = aStackFrame->GetFilename(aStackEntry.mFilename);
nsresult rv = aStackFrame->GetFilename(aCx, aStackEntry.mFilename);
NS_ENSURE_SUCCESS(rv, rv);
int32_t lineNumber;
@ -1069,13 +1069,14 @@ StackFrameToStackEntry(nsIStackFrame* aStackFrame,
static
nsresult
ReifyStack(nsIStackFrame* aStack, nsTArray<ConsoleStackEntry>& aRefiedStack)
ReifyStack(JSContext* aCx, nsIStackFrame* aStack,
nsTArray<ConsoleStackEntry>& aRefiedStack)
{
nsCOMPtr<nsIStackFrame> stack(aStack);
while (stack) {
ConsoleStackEntry& data = *aRefiedStack.AppendElement();
nsresult rv = StackFrameToStackEntry(stack, data);
nsresult rv = StackFrameToStackEntry(aCx, stack, data);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIStackFrame> caller;
@ -1124,7 +1125,7 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
if (stack) {
callData->mTopStackFrame.emplace();
nsresult rv = StackFrameToStackEntry(stack,
nsresult rv = StackFrameToStackEntry(aCx, stack,
*callData->mTopStackFrame);
if (NS_FAILED(rv)) {
return;
@ -1137,7 +1138,7 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
// nsIStackFrame is not threadsafe, so we need to snapshot it now,
// before we post our runnable to the main thread.
callData->mReifiedStack.emplace();
nsresult rv = ReifyStack(stack, *callData->mReifiedStack);
nsresult rv = ReifyStack(aCx, stack, *callData->mReifiedStack);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
@ -1270,7 +1271,7 @@ LazyStackGetter(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
nsIStackFrame* stack = reinterpret_cast<nsIStackFrame*>(v.toPrivate());
nsTArray<ConsoleStackEntry> reifiedStack;
nsresult rv = ReifyStack(stack, reifiedStack);
nsresult rv = ReifyStack(aCx, stack, reifiedStack);
if (NS_FAILED(rv)) {
Throw(aCx, rv);
return false;

View File

@ -308,12 +308,12 @@ Exception::GetName(nsACString& aName)
}
NS_IMETHODIMP
Exception::GetFilename(nsAString& aFilename)
Exception::GetFilename(JSContext* aCx, nsAString& aFilename)
{
NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
if (mLocation) {
return mLocation->GetFilename(aFilename);
return mLocation->GetFilename(aCx, aFilename);
}
aFilename.Assign(mFilename);

View File

@ -211,11 +211,16 @@ class BlobURLsReporter final : public nsIMemoryReporter
principalURI->GetPrePath(origin);
}
// If we got a frame, we better have a current JSContext. This is cheating
// a bit; ideally we'd have our caller pass in a JSContext, or have
// GetCurrentJSStack() hand out the JSContext it found.
JSContext* cx = frame ? nsContentUtils::GetCurrentJSContext() : nullptr;
for (uint32_t i = 0; frame; ++i) {
nsString fileNameUTF16;
int32_t lineNumber = 0;
frame->GetFilename(fileNameUTF16);
frame->GetFilename(cx, fileNameUTF16);
frame->GetLineNumber(&lineNumber);
if (!fileNameUTF16.IsEmpty()) {

View File

@ -409,6 +409,7 @@ DOMInterfaces = {
'binaryNames': {
'message': 'messageMoz',
},
'implicitJSContext': [ 'filename' ],
},
'DOMMatrixReadOnly': {
@ -478,7 +479,7 @@ DOMInterfaces = {
'binaryNames': {
'message': 'messageMoz',
},
'implicitJSContext': [ '__stringifier' ],
'implicitJSContext': [ '__stringifier', 'filename' ],
},
'ExtendableEvent': {

View File

@ -178,14 +178,7 @@ already_AddRefed<nsIStackFrame>
GetCurrentJSStack(int32_t aMaxDepth)
{
// is there a current context available?
JSContext* cx = nullptr;
if (NS_IsMainThread()) {
MOZ_ASSERT(nsContentUtils::XPConnect());
cx = nsContentUtils::GetCurrentJSContext();
} else {
cx = workers::GetCurrentThreadJSContext();
}
JSContext* cx = nsContentUtils::GetCurrentJSContextForThread();
if (!cx || !js::GetContextCompartment(cx)) {
return nullptr;
@ -343,17 +336,17 @@ GetValueIfNotCached(JSContext* aCx, JSObject* aStack,
aPropGetter(aCx, stack, aValue, JS::SavedFrameSelfHosted::Exclude);
}
NS_IMETHODIMP JSStackFrame::GetFilename(nsAString& aFilename)
NS_IMETHODIMP JSStackFrame::GetFilename(JSContext* aCx, nsAString& aFilename)
{
if (!mStack) {
aFilename.Truncate();
return NS_OK;
}
ThreadsafeAutoJSContext cx;
JS::Rooted<JSString*> filename(cx);
JS::Rooted<JSString*> filename(aCx);
bool canCache = false, useCachedValue = false;
GetValueIfNotCached(cx, mStack, JS::GetSavedFrameSource, mFilenameInitialized,
GetValueIfNotCached(aCx, mStack, JS::GetSavedFrameSource,
mFilenameInitialized,
&canCache, &useCachedValue, &filename);
if (useCachedValue) {
aFilename = mFilename;
@ -361,8 +354,8 @@ NS_IMETHODIMP JSStackFrame::GetFilename(nsAString& aFilename)
}
nsAutoJSString str;
if (!str.init(cx, filename)) {
JS_ClearPendingException(cx);
if (!str.init(aCx, filename)) {
JS_ClearPendingException(aCx);
aFilename.Truncate();
return NS_OK;
}
@ -643,7 +636,7 @@ NS_IMETHODIMP JSStackFrame::ToString(JSContext* aCx, nsACString& _retval)
_retval.Truncate();
nsString filename;
nsresult rv = GetFilename(filename);
nsresult rv = GetFilename(aCx, filename);
NS_ENSURE_SUCCESS(rv, rv);
if (filename.IsEmpty()) {

View File

@ -428,7 +428,7 @@ ExtractErrorValues(JSContext* aCx, JS::Handle<JS::Value> aValue,
else if(NS_SUCCEEDED(UNWRAP_OBJECT(DOMException, obj, domException))) {
nsAutoString filename;
domException->GetFilename(filename);
domException->GetFilename(aCx, filename);
if (!filename.IsEmpty()) {
CopyUTF16toUTF8(filename, aSourceSpecOut);
*aLineOut = domException->LineNumber();

View File

@ -1579,7 +1579,7 @@ AssembleSandboxMemoryReporterName(JSContext* cx, nsCString& sandboxName)
if (frame) {
nsString location;
int32_t lineNumber = 0;
frame->GetFilename(location);
frame->GetFilename(cx, location);
frame->GetLineNumber(&lineNumber);
sandboxName.AppendLiteral(" (from: ");

View File

@ -2322,7 +2322,7 @@ nsXPCComponents_Utils::ReportError(HandleValue error, JSContext* cx)
if (!scripterr) {
nsCOMPtr<nsIStackFrame> frame = dom::GetCurrentJSStack();
if (frame) {
frame->GetFilename(fileName);
frame->GetFilename(cx, fileName);
frame->GetLineNumber(&lineNo);
JS::Rooted<JS::Value> stack(cx);
nsresult rv = frame->GetNativeSavedFrame(&stack);
@ -2429,7 +2429,7 @@ nsXPCComponents_Utils::EvalInSandbox(const nsAString& source,
xpc->GetCurrentJSStack(getter_AddRefs(frame));
if (frame) {
nsString frameFile;
frame->GetFilename(frameFile);
frame->GetFilename(cx, frameFile);
CopyUTF16toUTF8(frameFile, filename);
frame->GetLineNumber(&lineNo);
}

View File

@ -920,7 +920,7 @@ nsXPCWrappedJSClass::CheckForException(XPCCallContext & ccx,
location->GetLineNumber(&lineNumber);
// get a filename.
rv = location->GetFilename(sourceName);
rv = location->GetFilename(cx, sourceName);
}
rv = scriptError->InitWithWindowID(NS_ConvertUTF8toUTF16(newMessage),

View File

@ -45,13 +45,17 @@ SandboxLogJSStack(void)
return;
}
nsCOMPtr<nsIStackFrame> frame = dom::GetCurrentJSStack();
// If we got a stack, we must have a current JSContext. This is icky. :(
// Would be better if GetCurrentJSStack() handed out the JSContext it ended up
// using or something.
JSContext* cx = frame ? nsContentUtils::GetCurrentJSContext() : nullptr;
for (int i = 0; frame != nullptr; ++i) {
nsAutoString fileName, funName;
int32_t lineNumber;
// Don't stop unwinding if an attribute can't be read.
fileName.SetIsVoid(true);
Unused << frame->GetFilename(fileName);
Unused << frame->GetFilename(cx, fileName);
lineNumber = 0;
Unused << frame->GetLineNumber(&lineNumber);
funName.SetIsVoid(true);

View File

@ -16,6 +16,7 @@ interface nsIStackFrame : nsISupports
// see nsIProgrammingLanguage for list of language consts
readonly attribute uint32_t language;
readonly attribute AUTF8String languageName;
[implicit_jscontext]
readonly attribute AString filename;
readonly attribute AString name;
// Valid line numbers begin at '1'. '0' indicates unknown.
@ -57,6 +58,7 @@ interface nsIException : nsISupports
// etc.
// null indicates "no data"
[implicit_jscontext]
readonly attribute AString filename;
// Valid line numbers begin at '1'. '0' indicates unknown.
readonly attribute uint32_t lineNumber;