зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1708740 - Move exception APIs from jsapi.h to public Exception.h header r=nbp
Differential Revision: https://phabricator.services.mozilla.com/D113996
This commit is contained in:
Родитель
4be051558e
Коммит
60db3d641e
|
@ -15,6 +15,42 @@
|
|||
#include "js/TypeDecls.h"
|
||||
#include "js/Value.h" // JS::Value, JS::Handle<JS::Value>
|
||||
|
||||
class JSErrorReport;
|
||||
|
||||
namespace JS {
|
||||
enum class ExceptionStackBehavior : bool {
|
||||
// Do not capture any stack.
|
||||
DoNotCapture,
|
||||
|
||||
// Capture the current JS stack when setting the exception. It may be
|
||||
// retrieved by JS::GetPendingExceptionStack.
|
||||
Capture
|
||||
};
|
||||
} // namespace JS
|
||||
|
||||
extern JS_PUBLIC_API bool JS_IsExceptionPending(JSContext* cx);
|
||||
|
||||
extern JS_PUBLIC_API bool JS_IsThrowingOutOfMemory(JSContext* cx);
|
||||
|
||||
extern JS_PUBLIC_API bool JS_GetPendingException(JSContext* cx,
|
||||
JS::MutableHandleValue vp);
|
||||
|
||||
extern JS_PUBLIC_API void JS_SetPendingException(
|
||||
JSContext* cx, JS::HandleValue v,
|
||||
JS::ExceptionStackBehavior behavior = JS::ExceptionStackBehavior::Capture);
|
||||
|
||||
extern JS_PUBLIC_API void JS_ClearPendingException(JSContext* cx);
|
||||
|
||||
/**
|
||||
* If the given object is an exception object, the exception will have (or be
|
||||
* able to lazily create) an error report struct, and this function will return
|
||||
* the address of that struct. Otherwise, it returns nullptr. The lifetime
|
||||
* of the error report struct that might be returned is the same as the
|
||||
* lifetime of the exception object.
|
||||
*/
|
||||
extern JS_PUBLIC_API JSErrorReport* JS_ErrorFromException(JSContext* cx,
|
||||
JS::HandleObject obj);
|
||||
|
||||
namespace JS {
|
||||
|
||||
// This class encapsulates a (pending) exception and the corresponding optional
|
||||
|
@ -49,6 +85,54 @@ class MOZ_STACK_CLASS ExceptionStack {
|
|||
HandleObject stack() const { return stack_; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Save and later restore the current exception state of a given JSContext.
|
||||
* This is useful for implementing behavior in C++ that's like try/catch
|
||||
* or try/finally in JS.
|
||||
*
|
||||
* Typical usage:
|
||||
*
|
||||
* bool ok = JS::Evaluate(cx, ...);
|
||||
* AutoSaveExceptionState savedExc(cx);
|
||||
* ... cleanup that might re-enter JS ...
|
||||
* return ok;
|
||||
*/
|
||||
class JS_PUBLIC_API AutoSaveExceptionState {
|
||||
private:
|
||||
JSContext* context;
|
||||
bool wasPropagatingForcedReturn;
|
||||
bool wasOverRecursed;
|
||||
bool wasThrowing;
|
||||
RootedValue exceptionValue;
|
||||
RootedObject exceptionStack;
|
||||
|
||||
public:
|
||||
/*
|
||||
* Take a snapshot of cx's current exception state. Then clear any current
|
||||
* pending exception in cx.
|
||||
*/
|
||||
explicit AutoSaveExceptionState(JSContext* cx);
|
||||
|
||||
/*
|
||||
* If neither drop() nor restore() was called, restore the exception
|
||||
* state only if no exception is currently pending on cx.
|
||||
*/
|
||||
~AutoSaveExceptionState();
|
||||
|
||||
/*
|
||||
* Discard any stored exception state.
|
||||
* If this is called, the destructor is a no-op.
|
||||
*/
|
||||
void drop();
|
||||
|
||||
/*
|
||||
* Replace cx's exception state with the stored exception state. Then
|
||||
* discard the stored exception state. If this is called, the
|
||||
* destructor is a no-op.
|
||||
*/
|
||||
void restore();
|
||||
};
|
||||
|
||||
// Get the current pending exception value and stack.
|
||||
// This function asserts that there is a pending exception.
|
||||
// If this function returns false, then retrieving the current pending exception
|
||||
|
@ -66,6 +150,15 @@ extern JS_PUBLIC_API bool StealPendingExceptionStack(
|
|||
extern JS_PUBLIC_API void SetPendingExceptionStack(
|
||||
JSContext* cx, const JS::ExceptionStack& exceptionStack);
|
||||
|
||||
/**
|
||||
* If the given object is an exception object (or an unwrappable
|
||||
* cross-compartment wrapper for one), return the stack for that exception, if
|
||||
* any. Will return null if the given object is not an exception object
|
||||
* (including if it's null or a security wrapper that can't be unwrapped) or if
|
||||
* the exception has no stack.
|
||||
*/
|
||||
extern JS_PUBLIC_API JSObject* ExceptionStackOrNull(JS::HandleObject obj);
|
||||
|
||||
} // namespace JS
|
||||
|
||||
#endif // js_Exception_h
|
||||
|
|
101
js/src/jsapi.h
101
js/src/jsapi.h
|
@ -32,6 +32,7 @@
|
|||
#include "js/Class.h"
|
||||
#include "js/CompileOptions.h"
|
||||
#include "js/ErrorReport.h"
|
||||
#include "js/Exception.h"
|
||||
#include "js/GCVector.h"
|
||||
#include "js/HashTable.h"
|
||||
#include "js/Id.h"
|
||||
|
@ -2058,106 +2059,6 @@ extern JS_PUBLIC_API bool CreateError(
|
|||
|
||||
/************************************************************************/
|
||||
|
||||
extern JS_PUBLIC_API bool JS_IsExceptionPending(JSContext* cx);
|
||||
|
||||
extern JS_PUBLIC_API bool JS_IsThrowingOutOfMemory(JSContext* cx);
|
||||
|
||||
extern JS_PUBLIC_API bool JS_GetPendingException(JSContext* cx,
|
||||
JS::MutableHandleValue vp);
|
||||
|
||||
namespace JS {
|
||||
|
||||
enum class ExceptionStackBehavior : bool {
|
||||
// Do not capture any stack.
|
||||
DoNotCapture,
|
||||
|
||||
// Capture the current JS stack when setting the exception. It may be
|
||||
// retrieved by JS::GetPendingExceptionStack.
|
||||
Capture
|
||||
};
|
||||
|
||||
} // namespace JS
|
||||
|
||||
extern JS_PUBLIC_API void JS_SetPendingException(
|
||||
JSContext* cx, JS::HandleValue v,
|
||||
JS::ExceptionStackBehavior behavior = JS::ExceptionStackBehavior::Capture);
|
||||
|
||||
extern JS_PUBLIC_API void JS_ClearPendingException(JSContext* cx);
|
||||
|
||||
namespace JS {
|
||||
|
||||
/**
|
||||
* Save and later restore the current exception state of a given JSContext.
|
||||
* This is useful for implementing behavior in C++ that's like try/catch
|
||||
* or try/finally in JS.
|
||||
*
|
||||
* Typical usage:
|
||||
*
|
||||
* bool ok = JS::Evaluate(cx, ...);
|
||||
* AutoSaveExceptionState savedExc(cx);
|
||||
* ... cleanup that might re-enter JS ...
|
||||
* return ok;
|
||||
*/
|
||||
class JS_PUBLIC_API AutoSaveExceptionState {
|
||||
private:
|
||||
JSContext* context;
|
||||
bool wasPropagatingForcedReturn;
|
||||
bool wasOverRecursed;
|
||||
bool wasThrowing;
|
||||
RootedValue exceptionValue;
|
||||
RootedObject exceptionStack;
|
||||
|
||||
public:
|
||||
/*
|
||||
* Take a snapshot of cx's current exception state. Then clear any current
|
||||
* pending exception in cx.
|
||||
*/
|
||||
explicit AutoSaveExceptionState(JSContext* cx);
|
||||
|
||||
/*
|
||||
* If neither drop() nor restore() was called, restore the exception
|
||||
* state only if no exception is currently pending on cx.
|
||||
*/
|
||||
~AutoSaveExceptionState();
|
||||
|
||||
/*
|
||||
* Discard any stored exception state.
|
||||
* If this is called, the destructor is a no-op.
|
||||
*/
|
||||
void drop();
|
||||
|
||||
/*
|
||||
* Replace cx's exception state with the stored exception state. Then
|
||||
* discard the stored exception state. If this is called, the
|
||||
* destructor is a no-op.
|
||||
*/
|
||||
void restore();
|
||||
};
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
/**
|
||||
* If the given object is an exception object, the exception will have (or be
|
||||
* able to lazily create) an error report struct, and this function will return
|
||||
* the address of that struct. Otherwise, it returns nullptr. The lifetime
|
||||
* of the error report struct that might be returned is the same as the
|
||||
* lifetime of the exception object.
|
||||
*/
|
||||
extern JS_PUBLIC_API JSErrorReport* JS_ErrorFromException(JSContext* cx,
|
||||
JS::HandleObject obj);
|
||||
|
||||
namespace JS {
|
||||
/**
|
||||
* If the given object is an exception object (or an unwrappable
|
||||
* cross-compartment wrapper for one), return the stack for that exception, if
|
||||
* any. Will return null if the given object is not an exception object
|
||||
* (including if it's null or a security wrapper that can't be unwrapped) or if
|
||||
* the exception has no stack.
|
||||
*/
|
||||
extern JS_PUBLIC_API JSObject* ExceptionStackOrNull(JS::HandleObject obj);
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
/**
|
||||
* A JS context always has an "owner thread". The owner thread is set when the
|
||||
* context is created (to the current thread) and practically all entry points
|
||||
|
|
Загрузка…
Ссылка в новой задаче