1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* JS runtime exception classes.
*/
#ifndef jsexn_h
#define jsexn_h
#include "jsapi.h"
#include "NamespaceImports.h"
namespace js {
class ErrorObject;
JSErrorReport*
CopyErrorReport(JSContext* cx, JSErrorReport* report);
JSString*
ComputeStackString(JSContext* cx);
}
/*
* Given a JSErrorReport, check to see if there is an exception associated with
* the error number. If there is, then create an appropriate exception object,
* set it as the pending exception, and set the JSREPORT_EXCEPTION flag on the
* error report. Exception-aware host error reporters should probably ignore
* error reports so flagged.
*
* Return true if cx->throwing and cx->exception were set.
*
* This means that:
*
* - If the error is successfully converted to an exception and stored in
* cx->exception, the return value is true. This is the "normal", happiest
* case for the caller.
*
* - If we try to convert, but fail with OOM or some other error that ends up
* setting cx->throwing to true and setting cx->exception, then we also
* return true (because callers want to treat that case the same way).
* The original error described by *reportp typically won't be reported
* anywhere; instead OOM is reported.
*
* - If *reportp is just a warning, or the error code is unrecognized, or if
* we decided to do nothing in order to avoid recursion, then return
* false. In those cases, this error is just being swept under the rug
* unless the caller decides to call CallErrorReporter explicitly.
*/
extern bool
js_ErrorToException(JSContext* cx, const char* message, JSErrorReport* reportp,
JSErrorCallback callback, void* userRef);
/*
* Called if a JS API call to js_Execute or js_InternalCall fails; calls the
* error reporter with the error report associated with any uncaught exception
* that has been raised. Returns true if there was an exception pending, and
* the error reporter was actually called.
*
* The JSErrorReport * that the error reporter is called with is currently
* associated with a JavaScript object, and is not guaranteed to persist after
* the object is collected. Any persistent uses of the JSErrorReport contents
* should make their own copy.
*
* The flags field of the JSErrorReport will have the JSREPORT_EXCEPTION flag
* set; embeddings that want to silently propagate JavaScript exceptions to
* other contexts may want to use an error reporter that ignores errors with
* this flag.
*/
extern bool
js_ReportUncaughtException(JSContext* cx);
extern JSErrorReport*
js_ErrorFromException(JSContext* cx, js::HandleObject obj);
/*
* Make a copy of errobj parented to cx's compartment's global.
*
* errobj may be in a different compartment than cx, but it must be an Error
* object (not a wrapper of one) and it must not be one of the standard error
* prototype objects (errobj->getPrivate() must not be nullptr).
*/
extern JSObject*
js_CopyErrorObject(JSContext* cx, JS::Handle<js::ErrorObject*> errobj);
static_assert(JSEXN_ERR == 0 &&
JSProto_Error + JSEXN_INTERNALERR == JSProto_InternalError &&
JSProto_Error + JSEXN_EVALERR == JSProto_EvalError &&
JSProto_Error + JSEXN_RANGEERR == JSProto_RangeError &&
JSProto_Error + JSEXN_REFERENCEERR == JSProto_ReferenceError &&
JSProto_Error + JSEXN_SYNTAXERR == JSProto_SyntaxError &&
JSProto_Error + JSEXN_TYPEERR == JSProto_TypeError &&
JSProto_Error + JSEXN_URIERR == JSProto_URIError &&
JSEXN_URIERR + 1 == JSEXN_LIMIT,
"GetExceptionProtoKey and ExnTypeFromProtoKey require that "
"each corresponding JSExnType and JSProtoKey value be separated "
"by the same constant value");
static inline JSProtoKey
GetExceptionProtoKey(JSExnType exn)
{
MOZ_ASSERT(JSEXN_ERR <= exn);
MOZ_ASSERT(exn < JSEXN_LIMIT);
return JSProtoKey(JSProto_Error + int(exn));
}
static inline JSExnType
ExnTypeFromProtoKey(JSProtoKey key)
{
JSExnType type = static_cast<JSExnType>(key - JSProto_Error);
MOZ_ASSERT(type >= JSEXN_ERR);
MOZ_ASSERT(type < JSEXN_LIMIT);
return type;
}
class AutoClearPendingException
{
JSContext *cx;
public:
explicit AutoClearPendingException(JSContext *cxArg)
: cx(cxArg)
{ }
~AutoClearPendingException() {
cx->clearPendingException();
}
};
#endif /* jsexn_h */
|