dom/bindings/Exceptions.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "mozilla/dom/Exceptions.h"
michael@0 7
michael@0 8 #include "js/GCAPI.h"
michael@0 9 #include "js/OldDebugAPI.h"
michael@0 10 #include "jsapi.h"
michael@0 11 #include "jsprf.h"
michael@0 12 #include "mozilla/CycleCollectedJSRuntime.h"
michael@0 13 #include "mozilla/dom/BindingUtils.h"
michael@0 14 #include "mozilla/dom/DOMException.h"
michael@0 15 #include "nsServiceManagerUtils.h"
michael@0 16 #include "nsThreadUtils.h"
michael@0 17 #include "XPCWrapper.h"
michael@0 18 #include "WorkerPrivate.h"
michael@0 19 #include "nsContentUtils.h"
michael@0 20
michael@0 21 namespace {
michael@0 22
michael@0 23 // We can't use nsContentUtils::IsCallerChrome because it might not exist in
michael@0 24 // xpcshell.
michael@0 25 bool
michael@0 26 IsCallerChrome()
michael@0 27 {
michael@0 28 nsCOMPtr<nsIScriptSecurityManager> secMan;
michael@0 29 secMan = XPCWrapper::GetSecurityManager();
michael@0 30
michael@0 31 if (!secMan) {
michael@0 32 return false;
michael@0 33 }
michael@0 34
michael@0 35 bool isChrome;
michael@0 36 return NS_SUCCEEDED(secMan->SubjectPrincipalIsSystem(&isChrome)) && isChrome;
michael@0 37 }
michael@0 38
michael@0 39 } // anonymous namespace
michael@0 40
michael@0 41 namespace mozilla {
michael@0 42 namespace dom {
michael@0 43
michael@0 44 bool
michael@0 45 ThrowExceptionObject(JSContext* aCx, nsIException* aException)
michael@0 46 {
michael@0 47 // See if we really have an Exception.
michael@0 48 nsCOMPtr<Exception> exception = do_QueryInterface(aException);
michael@0 49 if (exception) {
michael@0 50 return ThrowExceptionObject(aCx, exception);
michael@0 51 }
michael@0 52
michael@0 53 // We only have an nsIException (probably an XPCWrappedJS). Fall back on old
michael@0 54 // wrapping.
michael@0 55 MOZ_ASSERT(NS_IsMainThread());
michael@0 56
michael@0 57 JS::Rooted<JSObject*> glob(aCx, JS::CurrentGlobalOrNull(aCx));
michael@0 58 if (!glob) {
michael@0 59 // XXXbz Can this really be null here?
michael@0 60 return false;
michael@0 61 }
michael@0 62
michael@0 63 JS::Rooted<JS::Value> val(aCx);
michael@0 64 if (!WrapObject(aCx, aException, &NS_GET_IID(nsIException), &val)) {
michael@0 65 return false;
michael@0 66 }
michael@0 67
michael@0 68 JS_SetPendingException(aCx, val);
michael@0 69
michael@0 70 return true;
michael@0 71 }
michael@0 72
michael@0 73 bool
michael@0 74 ThrowExceptionObject(JSContext* aCx, Exception* aException)
michael@0 75 {
michael@0 76 JS::Rooted<JS::Value> thrown(aCx);
michael@0 77
michael@0 78 // If we stored the original thrown JS value in the exception
michael@0 79 // (see XPCConvert::ConstructException) and we are in a web context
michael@0 80 // (i.e., not chrome), rethrow the original value. This only applies to JS
michael@0 81 // implemented components so we only need to check for this on the main
michael@0 82 // thread.
michael@0 83 if (NS_IsMainThread() && !IsCallerChrome() &&
michael@0 84 aException->StealJSVal(thrown.address())) {
michael@0 85 if (!JS_WrapValue(aCx, &thrown)) {
michael@0 86 return false;
michael@0 87 }
michael@0 88 JS_SetPendingException(aCx, thrown);
michael@0 89 return true;
michael@0 90 }
michael@0 91
michael@0 92 JS::Rooted<JSObject*> glob(aCx, JS::CurrentGlobalOrNull(aCx));
michael@0 93 if (!glob) {
michael@0 94 // XXXbz Can this actually be null here?
michael@0 95 return false;
michael@0 96 }
michael@0 97
michael@0 98 if (!WrapNewBindingObject(aCx, aException, &thrown)) {
michael@0 99 return false;
michael@0 100 }
michael@0 101
michael@0 102 JS_SetPendingException(aCx, thrown);
michael@0 103 return true;
michael@0 104 }
michael@0 105
michael@0 106 bool
michael@0 107 Throw(JSContext* aCx, nsresult aRv, const char* aMessage)
michael@0 108 {
michael@0 109 if (JS_IsExceptionPending(aCx)) {
michael@0 110 // Don't clobber the existing exception.
michael@0 111 return false;
michael@0 112 }
michael@0 113
michael@0 114 CycleCollectedJSRuntime* runtime = CycleCollectedJSRuntime::Get();
michael@0 115 nsCOMPtr<nsIException> existingException = runtime->GetPendingException();
michael@0 116 if (existingException) {
michael@0 117 nsresult nr;
michael@0 118 if (NS_SUCCEEDED(existingException->GetResult(&nr)) &&
michael@0 119 aRv == nr) {
michael@0 120 // Reuse the existing exception.
michael@0 121
michael@0 122 // Clear pending exception
michael@0 123 runtime->SetPendingException(nullptr);
michael@0 124
michael@0 125 if (!ThrowExceptionObject(aCx, existingException)) {
michael@0 126 // If we weren't able to throw an exception we're
michael@0 127 // most likely out of memory
michael@0 128 JS_ReportOutOfMemory(aCx);
michael@0 129 }
michael@0 130 return false;
michael@0 131 }
michael@0 132 }
michael@0 133
michael@0 134 nsRefPtr<Exception> finalException = CreateException(aCx, aRv, aMessage);
michael@0 135
michael@0 136 MOZ_ASSERT(finalException);
michael@0 137 if (!ThrowExceptionObject(aCx, finalException)) {
michael@0 138 // If we weren't able to throw an exception we're
michael@0 139 // most likely out of memory
michael@0 140 JS_ReportOutOfMemory(aCx);
michael@0 141 }
michael@0 142
michael@0 143 return false;
michael@0 144 }
michael@0 145
michael@0 146 already_AddRefed<Exception>
michael@0 147 CreateException(JSContext* aCx, nsresult aRv, const char* aMessage)
michael@0 148 {
michael@0 149 // Do we use DOM exceptions for this error code?
michael@0 150 switch (NS_ERROR_GET_MODULE(aRv)) {
michael@0 151 case NS_ERROR_MODULE_DOM:
michael@0 152 case NS_ERROR_MODULE_SVG:
michael@0 153 case NS_ERROR_MODULE_DOM_XPATH:
michael@0 154 case NS_ERROR_MODULE_DOM_INDEXEDDB:
michael@0 155 case NS_ERROR_MODULE_DOM_FILEHANDLE:
michael@0 156 return DOMException::Create(aRv);
michael@0 157 default:
michael@0 158 break;
michael@0 159 }
michael@0 160
michael@0 161 // If not, use the default.
michael@0 162 // aMessage can be null, so we can't use nsDependentCString on it.
michael@0 163 nsRefPtr<Exception> exception =
michael@0 164 new Exception(nsCString(aMessage), aRv,
michael@0 165 EmptyCString(), nullptr, nullptr);
michael@0 166 return exception.forget();
michael@0 167 }
michael@0 168
michael@0 169 already_AddRefed<nsIStackFrame>
michael@0 170 GetCurrentJSStack()
michael@0 171 {
michael@0 172 // is there a current context available?
michael@0 173 JSContext* cx = nullptr;
michael@0 174
michael@0 175 if (NS_IsMainThread()) {
michael@0 176 // Note, in xpcshell nsContentUtils is never initialized, but we still need
michael@0 177 // to report exceptions.
michael@0 178 if (nsContentUtils::XPConnect()) {
michael@0 179 cx = nsContentUtils::XPConnect()->GetCurrentJSContext();
michael@0 180 } else {
michael@0 181 nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());
michael@0 182 cx = xpc->GetCurrentJSContext();
michael@0 183 }
michael@0 184 } else {
michael@0 185 cx = workers::GetCurrentThreadJSContext();
michael@0 186 }
michael@0 187
michael@0 188 if (!cx) {
michael@0 189 return nullptr;
michael@0 190 }
michael@0 191
michael@0 192 nsCOMPtr<nsIStackFrame> stack = exceptions::CreateStack(cx);
michael@0 193 if (!stack) {
michael@0 194 return nullptr;
michael@0 195 }
michael@0 196
michael@0 197 // peel off native frames...
michael@0 198 uint32_t language;
michael@0 199 nsCOMPtr<nsIStackFrame> caller;
michael@0 200 while (stack &&
michael@0 201 NS_SUCCEEDED(stack->GetLanguage(&language)) &&
michael@0 202 language != nsIProgrammingLanguage::JAVASCRIPT &&
michael@0 203 NS_SUCCEEDED(stack->GetCaller(getter_AddRefs(caller))) &&
michael@0 204 caller) {
michael@0 205 stack = caller;
michael@0 206 }
michael@0 207 return stack.forget();
michael@0 208 }
michael@0 209
michael@0 210 namespace exceptions {
michael@0 211
michael@0 212 class StackDescriptionOwner {
michael@0 213 public:
michael@0 214 StackDescriptionOwner(JS::StackDescription* aDescription)
michael@0 215 : mDescription(aDescription)
michael@0 216 {
michael@0 217 mozilla::HoldJSObjects(this);
michael@0 218 }
michael@0 219
michael@0 220 ~StackDescriptionOwner()
michael@0 221 {
michael@0 222 // Make sure to set mDescription to null before calling DropJSObjects, since
michael@0 223 // in debug builds DropJSObjects try to trace us and we don't want to trace
michael@0 224 // a dead StackDescription.
michael@0 225 if (mDescription) {
michael@0 226 JS::FreeStackDescription(nullptr, mDescription);
michael@0 227 mDescription = nullptr;
michael@0 228 }
michael@0 229 mozilla::DropJSObjects(this);
michael@0 230 }
michael@0 231
michael@0 232 NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(StackDescriptionOwner)
michael@0 233 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(StackDescriptionOwner)
michael@0 234
michael@0 235 JS::FrameDescription& FrameAt(size_t aIndex)
michael@0 236 {
michael@0 237 MOZ_ASSERT(aIndex < mDescription->nframes);
michael@0 238 return mDescription->frames[aIndex];
michael@0 239 }
michael@0 240
michael@0 241 unsigned NumFrames()
michael@0 242 {
michael@0 243 return mDescription->nframes;
michael@0 244 }
michael@0 245
michael@0 246 private:
michael@0 247 JS::StackDescription* mDescription;
michael@0 248 };
michael@0 249
michael@0 250 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(StackDescriptionOwner, AddRef)
michael@0 251 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(StackDescriptionOwner, Release)
michael@0 252
michael@0 253 NS_IMPL_CYCLE_COLLECTION_CLASS(StackDescriptionOwner)
michael@0 254 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(StackDescriptionOwner)
michael@0 255 if (tmp->mDescription) {
michael@0 256 JS::FreeStackDescription(nullptr, tmp->mDescription);
michael@0 257 tmp->mDescription = nullptr;
michael@0 258 }
michael@0 259 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
michael@0 260 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(StackDescriptionOwner)
michael@0 261 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
michael@0 262 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
michael@0 263 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(StackDescriptionOwner)
michael@0 264 JS::StackDescription* desc = tmp->mDescription;
michael@0 265 if (tmp->mDescription) {
michael@0 266 for (size_t i = 0; i < desc->nframes; ++i) {
michael@0 267 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mDescription->frames[i].markedLocation1());
michael@0 268 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mDescription->frames[i].markedLocation2());
michael@0 269 }
michael@0 270 }
michael@0 271 NS_IMPL_CYCLE_COLLECTION_TRACE_END
michael@0 272
michael@0 273 class JSStackFrame : public nsIStackFrame
michael@0 274 {
michael@0 275 public:
michael@0 276 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
michael@0 277 NS_DECL_CYCLE_COLLECTION_CLASS(JSStackFrame)
michael@0 278 NS_DECL_NSISTACKFRAME
michael@0 279
michael@0 280 // A null aStackDescription or an aIndex that's out of range for the
michael@0 281 // number of frames aStackDescription has will mean that the
michael@0 282 // JSStackFrame will never look at the stack description. Instead,
michael@0 283 // it is expected to be initialized by the caller as needed.
michael@0 284 JSStackFrame(StackDescriptionOwner* aStackDescription, size_t aIndex);
michael@0 285 virtual ~JSStackFrame();
michael@0 286
michael@0 287 static already_AddRefed<nsIStackFrame>
michael@0 288 CreateStack(JSContext* aCx, int32_t aMaxDepth = -1);
michael@0 289 static already_AddRefed<nsIStackFrame>
michael@0 290 CreateStackFrameLocation(uint32_t aLanguage,
michael@0 291 const char* aFilename,
michael@0 292 const char* aFunctionName,
michael@0 293 int32_t aLineNumber,
michael@0 294 nsIStackFrame* aCaller);
michael@0 295
michael@0 296 private:
michael@0 297 bool IsJSFrame() const {
michael@0 298 return mLanguage == nsIProgrammingLanguage::JAVASCRIPT;
michael@0 299 }
michael@0 300
michael@0 301 int32_t GetLineno();
michael@0 302
michael@0 303 nsRefPtr<StackDescriptionOwner> mStackDescription;
michael@0 304 nsCOMPtr<nsIStackFrame> mCaller;
michael@0 305
michael@0 306 // Cached values
michael@0 307 nsString mFilename;
michael@0 308 nsString mFunname;
michael@0 309 int32_t mLineno;
michael@0 310 uint32_t mLanguage;
michael@0 311
michael@0 312 size_t mIndex;
michael@0 313
michael@0 314 bool mFilenameInitialized;
michael@0 315 bool mFunnameInitialized;
michael@0 316 bool mLinenoInitialized;
michael@0 317 bool mCallerInitialized;
michael@0 318 };
michael@0 319
michael@0 320 JSStackFrame::JSStackFrame(StackDescriptionOwner* aStackDescription,
michael@0 321 size_t aIndex)
michael@0 322 : mLineno(0)
michael@0 323 {
michael@0 324 if (aStackDescription && aIndex < aStackDescription->NumFrames()) {
michael@0 325 mStackDescription = aStackDescription;
michael@0 326 mIndex = aIndex;
michael@0 327 mFilenameInitialized = false;
michael@0 328 mFunnameInitialized = false;
michael@0 329 mLinenoInitialized = false;
michael@0 330 mCallerInitialized = false;
michael@0 331 mLanguage = nsIProgrammingLanguage::JAVASCRIPT;
michael@0 332 } else {
michael@0 333 MOZ_ASSERT(!mStackDescription);
michael@0 334 mIndex = 0;
michael@0 335 mFilenameInitialized = true;
michael@0 336 mFunnameInitialized = true;
michael@0 337 mLinenoInitialized = true;
michael@0 338 mCallerInitialized = true;
michael@0 339 mLanguage = nsIProgrammingLanguage::UNKNOWN;
michael@0 340 }
michael@0 341 }
michael@0 342
michael@0 343 JSStackFrame::~JSStackFrame()
michael@0 344 {
michael@0 345 }
michael@0 346
michael@0 347 NS_IMPL_CYCLE_COLLECTION(JSStackFrame, mStackDescription, mCaller)
michael@0 348
michael@0 349 NS_IMPL_CYCLE_COLLECTING_ADDREF(JSStackFrame)
michael@0 350 NS_IMPL_CYCLE_COLLECTING_RELEASE(JSStackFrame)
michael@0 351
michael@0 352 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(JSStackFrame)
michael@0 353 NS_INTERFACE_MAP_ENTRY(nsIStackFrame)
michael@0 354 NS_INTERFACE_MAP_ENTRY(nsISupports)
michael@0 355 NS_INTERFACE_MAP_END
michael@0 356
michael@0 357 /* readonly attribute uint32_t language; */
michael@0 358 NS_IMETHODIMP JSStackFrame::GetLanguage(uint32_t* aLanguage)
michael@0 359 {
michael@0 360 *aLanguage = mLanguage;
michael@0 361 return NS_OK;
michael@0 362 }
michael@0 363
michael@0 364 /* readonly attribute string languageName; */
michael@0 365 NS_IMETHODIMP JSStackFrame::GetLanguageName(nsACString& aLanguageName)
michael@0 366 {
michael@0 367 static const char js[] = "JavaScript";
michael@0 368 static const char cpp[] = "C++";
michael@0 369
michael@0 370 if (IsJSFrame()) {
michael@0 371 aLanguageName.AssignASCII(js);
michael@0 372 } else {
michael@0 373 aLanguageName.AssignASCII(cpp);
michael@0 374 }
michael@0 375
michael@0 376 return NS_OK;
michael@0 377 }
michael@0 378
michael@0 379 /* readonly attribute AString filename; */
michael@0 380 NS_IMETHODIMP JSStackFrame::GetFilename(nsAString& aFilename)
michael@0 381 {
michael@0 382 if (!mFilenameInitialized) {
michael@0 383 JS::FrameDescription& desc = mStackDescription->FrameAt(mIndex);
michael@0 384 if (const char *filename = desc.filename()) {
michael@0 385 CopyUTF8toUTF16(filename, mFilename);
michael@0 386 }
michael@0 387 mFilenameInitialized = true;
michael@0 388 }
michael@0 389
michael@0 390 // The filename must be set to null if empty.
michael@0 391 if (mFilename.IsEmpty()) {
michael@0 392 aFilename.SetIsVoid(true);
michael@0 393 } else {
michael@0 394 aFilename.Assign(mFilename);
michael@0 395 }
michael@0 396
michael@0 397 return NS_OK;
michael@0 398 }
michael@0 399
michael@0 400 /* readonly attribute AString name; */
michael@0 401 NS_IMETHODIMP JSStackFrame::GetName(nsAString& aFunction)
michael@0 402 {
michael@0 403 if (!mFunnameInitialized) {
michael@0 404 JS::FrameDescription& desc = mStackDescription->FrameAt(mIndex);
michael@0 405 if (JSFlatString *name = desc.funDisplayName()) {
michael@0 406 mFunname.Assign(JS_GetFlatStringChars(name),
michael@0 407 // XXXbz Can't JS_GetStringLength on JSFlatString!
michael@0 408 JS_GetStringLength(JS_FORGET_STRING_FLATNESS(name)));
michael@0 409 }
michael@0 410 mFunnameInitialized = true;
michael@0 411 }
michael@0 412
michael@0 413 // The function name must be set to null if empty.
michael@0 414 if (mFunname.IsEmpty()) {
michael@0 415 aFunction.SetIsVoid(true);
michael@0 416 } else {
michael@0 417 aFunction.Assign(mFunname);
michael@0 418 }
michael@0 419
michael@0 420 return NS_OK;
michael@0 421 }
michael@0 422
michael@0 423 int32_t
michael@0 424 JSStackFrame::GetLineno()
michael@0 425 {
michael@0 426 if (!mLinenoInitialized) {
michael@0 427 JS::FrameDescription& desc = mStackDescription->FrameAt(mIndex);
michael@0 428 mLineno = desc.lineno();
michael@0 429 mLinenoInitialized = true;
michael@0 430 }
michael@0 431
michael@0 432 return mLineno;
michael@0 433 }
michael@0 434
michael@0 435 /* readonly attribute int32_t lineNumber; */
michael@0 436 NS_IMETHODIMP JSStackFrame::GetLineNumber(int32_t* aLineNumber)
michael@0 437 {
michael@0 438 *aLineNumber = GetLineno();
michael@0 439 return NS_OK;
michael@0 440 }
michael@0 441
michael@0 442 /* readonly attribute AUTF8String sourceLine; */
michael@0 443 NS_IMETHODIMP JSStackFrame::GetSourceLine(nsACString& aSourceLine)
michael@0 444 {
michael@0 445 aSourceLine.Truncate();
michael@0 446 return NS_OK;
michael@0 447 }
michael@0 448
michael@0 449 /* readonly attribute nsIStackFrame caller; */
michael@0 450 NS_IMETHODIMP JSStackFrame::GetCaller(nsIStackFrame** aCaller)
michael@0 451 {
michael@0 452 if (!mCallerInitialized) {
michael@0 453 mCaller = new JSStackFrame(mStackDescription, mIndex+1);
michael@0 454 mCallerInitialized = true;
michael@0 455 }
michael@0 456 NS_IF_ADDREF(*aCaller = mCaller);
michael@0 457 return NS_OK;
michael@0 458 }
michael@0 459
michael@0 460 /* AUTF8String toString (); */
michael@0 461 NS_IMETHODIMP JSStackFrame::ToString(nsACString& _retval)
michael@0 462 {
michael@0 463 _retval.Truncate();
michael@0 464
michael@0 465 const char* frametype = IsJSFrame() ? "JS" : "native";
michael@0 466
michael@0 467 nsString filename;
michael@0 468 nsresult rv = GetFilename(filename);
michael@0 469 NS_ENSURE_SUCCESS(rv, rv);
michael@0 470
michael@0 471 if (filename.IsEmpty()) {
michael@0 472 filename.AssignLiteral("<unknown filename>");
michael@0 473 }
michael@0 474
michael@0 475 nsString funname;
michael@0 476 rv = GetName(funname);
michael@0 477 NS_ENSURE_SUCCESS(rv, rv);
michael@0 478
michael@0 479 if (funname.IsEmpty()) {
michael@0 480 funname.AssignLiteral("<TOP_LEVEL>");
michael@0 481 }
michael@0 482 static const char format[] = "%s frame :: %s :: %s :: line %d";
michael@0 483 _retval.AppendPrintf(format, frametype,
michael@0 484 NS_ConvertUTF16toUTF8(filename).get(),
michael@0 485 NS_ConvertUTF16toUTF8(funname).get(),
michael@0 486 GetLineno());
michael@0 487 return NS_OK;
michael@0 488 }
michael@0 489
michael@0 490 /* static */ already_AddRefed<nsIStackFrame>
michael@0 491 JSStackFrame::CreateStack(JSContext* aCx, int32_t aMaxDepth)
michael@0 492 {
michael@0 493 static const unsigned MAX_FRAMES = 100;
michael@0 494 if (aMaxDepth < 0) {
michael@0 495 aMaxDepth = MAX_FRAMES;
michael@0 496 }
michael@0 497
michael@0 498 JS::StackDescription* desc = JS::DescribeStack(aCx, aMaxDepth);
michael@0 499 if (!desc) {
michael@0 500 return nullptr;
michael@0 501 }
michael@0 502
michael@0 503 nsRefPtr<StackDescriptionOwner> descOwner = new StackDescriptionOwner(desc);
michael@0 504
michael@0 505 nsRefPtr<JSStackFrame> first = new JSStackFrame(descOwner, 0);
michael@0 506 return first.forget();
michael@0 507 }
michael@0 508
michael@0 509 /* static */ already_AddRefed<nsIStackFrame>
michael@0 510 JSStackFrame::CreateStackFrameLocation(uint32_t aLanguage,
michael@0 511 const char* aFilename,
michael@0 512 const char* aFunctionName,
michael@0 513 int32_t aLineNumber,
michael@0 514 nsIStackFrame* aCaller)
michael@0 515 {
michael@0 516 nsRefPtr<JSStackFrame> self = new JSStackFrame(nullptr, 0);
michael@0 517
michael@0 518 self->mLanguage = aLanguage;
michael@0 519 self->mLineno = aLineNumber;
michael@0 520 CopyUTF8toUTF16(aFilename, self->mFilename);
michael@0 521 CopyUTF8toUTF16(aFunctionName, self->mFunname);
michael@0 522
michael@0 523 self->mCaller = aCaller;
michael@0 524
michael@0 525 return self.forget();
michael@0 526 }
michael@0 527
michael@0 528 already_AddRefed<nsIStackFrame>
michael@0 529 CreateStack(JSContext* aCx, int32_t aMaxDepth)
michael@0 530 {
michael@0 531 return JSStackFrame::CreateStack(aCx, aMaxDepth);
michael@0 532 }
michael@0 533
michael@0 534 already_AddRefed<nsIStackFrame>
michael@0 535 CreateStackFrameLocation(uint32_t aLanguage,
michael@0 536 const char* aFilename,
michael@0 537 const char* aFunctionName,
michael@0 538 int32_t aLineNumber,
michael@0 539 nsIStackFrame* aCaller)
michael@0 540 {
michael@0 541 return JSStackFrame::CreateStackFrameLocation(aLanguage, aFilename,
michael@0 542 aFunctionName, aLineNumber,
michael@0 543 aCaller);
michael@0 544 }
michael@0 545
michael@0 546 } // namespace exceptions
michael@0 547 } // namespace dom
michael@0 548 } // namespace mozilla

mercurial