Backed out changeset 04b06ee60ebf (bug 857648)

This commit is contained in:
Carsten "Tomcat" Book 2014-07-04 08:23:34 +02:00
Родитель 0715e0d433
Коммит 747409b970
1 изменённых файлов: 101 добавлений и 90 удалений

Просмотреть файл

@ -188,6 +188,69 @@ GetCurrentJSStack()
namespace exceptions {
class StackDescriptionOwner {
public:
StackDescriptionOwner(JS::StackDescription* aDescription)
: mDescription(aDescription)
{
mozilla::HoldJSObjects(this);
}
protected:
~StackDescriptionOwner()
{
// Make sure to set mDescription to null before calling DropJSObjects, since
// in debug builds DropJSObjects try to trace us and we don't want to trace
// a dead StackDescription.
if (mDescription) {
JS::FreeStackDescription(nullptr, mDescription);
mDescription = nullptr;
}
mozilla::DropJSObjects(this);
}
public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(StackDescriptionOwner)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(StackDescriptionOwner)
JS::FrameDescription& FrameAt(size_t aIndex)
{
MOZ_ASSERT(aIndex < mDescription->nframes);
return mDescription->frames[aIndex];
}
unsigned NumFrames()
{
return mDescription->nframes;
}
private:
JS::StackDescription* mDescription;
};
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(StackDescriptionOwner, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(StackDescriptionOwner, Release)
NS_IMPL_CYCLE_COLLECTION_CLASS(StackDescriptionOwner)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(StackDescriptionOwner)
if (tmp->mDescription) {
JS::FreeStackDescription(nullptr, tmp->mDescription);
tmp->mDescription = nullptr;
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(StackDescriptionOwner)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(StackDescriptionOwner)
JS::StackDescription* desc = tmp->mDescription;
if (tmp->mDescription) {
for (size_t i = 0; i < desc->nframes; ++i) {
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mDescription->frames[i].markedLocation1());
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mDescription->frames[i].markedLocation2());
}
}
NS_IMPL_CYCLE_COLLECTION_TRACE_END
class StackFrame : public nsIStackFrame
{
public:
@ -221,10 +284,9 @@ protected:
return false;
}
virtual nsresult GetLineno(int32_t* aLineNo)
virtual int32_t GetLineno()
{
*aLineNo = mLineno;
return NS_OK;
return mLineno;
}
nsCOMPtr<nsIStackFrame> mCaller;
@ -264,11 +326,11 @@ class JSStackFrame : public StackFrame
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(JSStackFrame,
StackFrame)
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(JSStackFrame, StackFrame)
// aStack must not be null.
JSStackFrame(JS::Handle<JSObject*> aStack);
// aStackDescription must not be null. aIndex must be a valid index
// into aStackDescription.
JSStackFrame(StackDescriptionOwner* aStackDescription, size_t aIndex);
static already_AddRefed<nsIStackFrame>
CreateStack(JSContext* aCx, int32_t aMaxDepth = -1);
@ -283,12 +345,13 @@ protected:
return true;
}
virtual nsresult GetLineno(int32_t* aLineNo) MOZ_OVERRIDE;
virtual int32_t GetLineno() MOZ_OVERRIDE;
private:
virtual ~JSStackFrame();
JS::Heap<JSObject*> mStack;
nsRefPtr<StackDescriptionOwner> mStackDescription;
size_t mIndex;
bool mFilenameInitialized;
bool mFunnameInitialized;
@ -296,35 +359,26 @@ private:
bool mCallerInitialized;
};
JSStackFrame::JSStackFrame(JS::Handle<JSObject*> aStack)
: mStack(aStack)
JSStackFrame::JSStackFrame(StackDescriptionOwner* aStackDescription,
size_t aIndex)
: mStackDescription(aStackDescription)
, mIndex(aIndex)
, mFilenameInitialized(false)
, mFunnameInitialized(false)
, mLinenoInitialized(false)
, mCallerInitialized(false)
{
MOZ_ASSERT(mStack);
MOZ_ASSERT(aStackDescription && aIndex < aStackDescription->NumFrames());
mozilla::HoldJSObjects(this);
mLineno = 0;
mLanguage = nsIProgrammingLanguage::JAVASCRIPT;
}
JSStackFrame::~JSStackFrame()
{
mozilla::DropJSObjects(this);
}
NS_IMPL_CYCLE_COLLECTION_CLASS(JSStackFrame)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(JSStackFrame, StackFrame)
tmp->mStack = nullptr;
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(JSStackFrame, StackFrame)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(JSStackFrame, StackFrame)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mStack)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED(JSStackFrame, StackFrame, mStackDescription)
NS_IMPL_ADDREF_INHERITED(JSStackFrame, StackFrame)
NS_IMPL_RELEASE_INHERITED(JSStackFrame, StackFrame)
@ -356,20 +410,10 @@ NS_IMETHODIMP JSStackFrame::GetLanguageName(nsACString& aLanguageName)
NS_IMETHODIMP JSStackFrame::GetFilename(nsAString& aFilename)
{
if (!mFilenameInitialized) {
ThreadsafeAutoJSContext cx;
JS::Rooted<JSObject*> stack(cx, mStack);
JS::ExposeObjectToActiveJS(mStack);
JSAutoCompartment ac(cx, stack);
JS::Rooted<JS::Value> filenameVal(cx);
if (!JS_GetProperty(cx, stack, "source", &filenameVal) ||
!filenameVal.isString()) {
return NS_ERROR_UNEXPECTED;
JS::FrameDescription& desc = mStackDescription->FrameAt(mIndex);
if (const char *filename = desc.filename()) {
CopyUTF8toUTF16(filename, mFilename);
}
nsDependentJSString str;
if (!str.init(cx, filenameVal.toString())) {
return NS_ERROR_OUT_OF_MEMORY;
}
mFilename = str;
mFilenameInitialized = true;
}
@ -392,22 +436,11 @@ NS_IMETHODIMP StackFrame::GetFilename(nsAString& aFilename)
NS_IMETHODIMP JSStackFrame::GetName(nsAString& aFunction)
{
if (!mFunnameInitialized) {
ThreadsafeAutoJSContext cx;
JS::Rooted<JSObject*> stack(cx, mStack);
JS::ExposeObjectToActiveJS(mStack);
JSAutoCompartment ac(cx, stack);
JS::Rooted<JS::Value> nameVal(cx);
// functionDisplayName can be null
if (!JS_GetProperty(cx, stack, "functionDisplayName", &nameVal) ||
(!nameVal.isString() && !nameVal.isNull())) {
return NS_ERROR_UNEXPECTED;
}
if (nameVal.isString()) {
nsDependentJSString str;
if (!str.init(cx, nameVal.toString())) {
return NS_ERROR_OUT_OF_MEMORY;
}
mFunname = str;
JS::FrameDescription& desc = mStackDescription->FrameAt(mIndex);
if (JSFlatString *name = desc.funDisplayName()) {
mFunname.Assign(JS_GetFlatStringChars(name),
// XXXbz Can't JS_GetStringLength on JSFlatString!
JS_GetStringLength(JS_FORGET_STRING_FLATNESS(name)));
}
mFunnameInitialized = true;
}
@ -428,30 +461,23 @@ NS_IMETHODIMP StackFrame::GetName(nsAString& aFunction)
}
// virtual
nsresult
JSStackFrame::GetLineno(int32_t* aLineNo)
int32_t
JSStackFrame::GetLineno()
{
if (!mLinenoInitialized) {
ThreadsafeAutoJSContext cx;
JS::Rooted<JSObject*> stack(cx, mStack);
JS::ExposeObjectToActiveJS(mStack);
JSAutoCompartment ac(cx, stack);
JS::Rooted<JS::Value> lineVal(cx);
if (!JS_GetProperty(cx, stack, "line", &lineVal) ||
!lineVal.isNumber()) {
return NS_ERROR_UNEXPECTED;
}
mLineno = lineVal.toNumber();
JS::FrameDescription& desc = mStackDescription->FrameAt(mIndex);
mLineno = desc.lineno();
mLinenoInitialized = true;
}
return StackFrame::GetLineno(aLineNo);
return StackFrame::GetLineno();
}
/* readonly attribute int32_t lineNumber; */
NS_IMETHODIMP StackFrame::GetLineNumber(int32_t* aLineNumber)
{
return GetLineno(aLineNumber);
*aLineNumber = GetLineno();
return NS_OK;
}
/* readonly attribute AUTF8String sourceLine; */
@ -465,19 +491,8 @@ NS_IMETHODIMP StackFrame::GetSourceLine(nsACString& aSourceLine)
NS_IMETHODIMP JSStackFrame::GetCaller(nsIStackFrame** aCaller)
{
if (!mCallerInitialized) {
ThreadsafeAutoJSContext cx;
JS::Rooted<JSObject*> stack(cx, mStack);
JS::ExposeObjectToActiveJS(mStack);
JSAutoCompartment ac(cx, stack);
JS::Rooted<JS::Value> callerVal(cx);
if (!JS_GetProperty(cx, stack, "parent", &callerVal) ||
!callerVal.isObjectOrNull()) {
return NS_ERROR_UNEXPECTED;
}
if (callerVal.isObject()) {
JS::Rooted<JSObject*> caller(cx, &callerVal.toObject());
mCaller = new JSStackFrame(caller);
if (mIndex + 1 < mStackDescription->NumFrames()) {
mCaller = new JSStackFrame(mStackDescription, mIndex+1);
} else {
// Do we really need this dummy frame? If so, we should document why... I
// guess for symmetry with the "nothing on the stack" case, which returns
@ -517,16 +532,11 @@ NS_IMETHODIMP StackFrame::ToString(nsACString& _retval)
if (funname.IsEmpty()) {
funname.AssignLiteral("<TOP_LEVEL>");
}
int32_t lineno;
rv = GetLineno(&lineno);
NS_ENSURE_SUCCESS(rv, rv);
static const char format[] = "%s frame :: %s :: %s :: line %d";
_retval.AppendPrintf(format, frametype,
NS_ConvertUTF16toUTF8(filename).get(),
NS_ConvertUTF16toUTF8(funname).get(),
lineno);
GetLineno());
return NS_OK;
}
@ -538,16 +548,17 @@ JSStackFrame::CreateStack(JSContext* aCx, int32_t aMaxDepth)
aMaxDepth = MAX_FRAMES;
}
JS::Rooted<JSObject*> stack(aCx);
if (!JS::CaptureCurrentStack(aCx, &stack, aMaxDepth)) {
JS::StackDescription* desc = JS::DescribeStack(aCx, aMaxDepth);
if (!desc) {
return nullptr;
}
nsCOMPtr<nsIStackFrame> first;
if (!stack) {
if (desc->nframes == 0) {
first = new StackFrame();
} else {
first = new JSStackFrame(stack);
nsRefPtr<StackDescriptionOwner> descOwner = new StackDescriptionOwner(desc);
first = new JSStackFrame(descOwner, 0);
}
return first.forget();
}