1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  * vim: set ts=8 sts=2 et sw=2 tw=80:
3  * This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include "js/Exception.h"
8 
9 #include "jsapi.h"  // AssertHeapIsIdle
10 #include "vm/JSContext.h"
11 #include "vm/SavedFrame.h"
12 
13 using namespace js;
14 
StealPendingExceptionStack(JSContext * cx,JS::ExceptionStack * exceptionStack)15 bool JS::StealPendingExceptionStack(JSContext* cx,
16                                     JS::ExceptionStack* exceptionStack) {
17   if (!GetPendingExceptionStack(cx, exceptionStack)) {
18     return false;
19   }
20 
21   // "Steal" exception by clearing it.
22   cx->clearPendingException();
23   return true;
24 }
25 
GetPendingExceptionStack(JSContext * cx,JS::ExceptionStack * exceptionStack)26 bool JS::GetPendingExceptionStack(JSContext* cx,
27                                   JS::ExceptionStack* exceptionStack) {
28   AssertHeapIsIdle();
29   CHECK_THREAD(cx);
30 
31   MOZ_ASSERT(exceptionStack);
32   MOZ_ASSERT(cx->isExceptionPending());
33 
34   RootedValue exception(cx);
35   if (!cx->getPendingException(&exception)) {
36     return false;
37   }
38 
39   RootedObject stack(cx, cx->getPendingExceptionStack());
40   exceptionStack->init(exception, stack);
41   return true;
42 }
43 
SetPendingExceptionStack(JSContext * cx,const JS::ExceptionStack & exceptionStack)44 void JS::SetPendingExceptionStack(JSContext* cx,
45                                   const JS::ExceptionStack& exceptionStack) {
46   AssertHeapIsIdle();
47   CHECK_THREAD(cx);
48 
49   // We don't check the compartments of `exception` and `stack` here,
50   // because we're not doing anything with them other than storing
51   // them, and stored exception values can be in an abitrary
52   // compartment while stored stack values are always the unwrapped
53   // object anyway.
54 
55   RootedSavedFrame nstack(cx);
56   if (exceptionStack.stack()) {
57     nstack = &UncheckedUnwrap(exceptionStack.stack())->as<SavedFrame>();
58   }
59   cx->setPendingException(exceptionStack.exception(), nstack);
60 }
61