Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / js / src / vm / ErrorObject.h
blobaf9689a5188db45f2dee6e5f934d3c21be7e2998
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/. */
7 #ifndef vm_ErrorObject_h_
8 #define vm_ErrorObject_h_
10 #include "mozilla/Assertions.h"
11 #include "mozilla/Maybe.h"
13 #include <iterator>
14 #include <stdint.h>
16 #include "jspubtd.h"
17 #include "NamespaceImports.h"
19 #include "js/Class.h"
20 #include "js/ColumnNumber.h" // JS::ColumnNumberOneOrigin
21 #include "js/ErrorReport.h"
22 #include "js/RootingAPI.h"
23 #include "js/TypeDecls.h"
24 #include "js/UniquePtr.h"
25 #include "js/Value.h"
26 #include "vm/JSObject.h"
27 #include "vm/NativeObject.h"
29 namespace js {
31 class ErrorObject : public NativeObject {
32 static JSObject* createProto(JSContext* cx, JSProtoKey key);
34 static JSObject* createConstructor(JSContext* cx, JSProtoKey key);
36 static bool init(JSContext* cx, Handle<ErrorObject*> obj, JSExnType type,
37 UniquePtr<JSErrorReport> errorReport, HandleString fileName,
38 HandleObject stack, uint32_t sourceId, uint32_t lineNumber,
39 JS::ColumnNumberOneOrigin columnNumber, HandleString message,
40 Handle<mozilla::Maybe<JS::Value>> cause);
42 static const ClassSpec classSpecs[JSEXN_ERROR_LIMIT];
43 static const JSClass protoClasses[JSEXN_ERROR_LIMIT];
45 protected:
46 static const uint32_t STACK_SLOT = 0;
47 static const uint32_t ERROR_REPORT_SLOT = STACK_SLOT + 1;
48 static const uint32_t FILENAME_SLOT = ERROR_REPORT_SLOT + 1;
49 static const uint32_t LINENUMBER_SLOT = FILENAME_SLOT + 1;
50 static const uint32_t COLUMNNUMBER_SLOT = LINENUMBER_SLOT + 1;
51 static const uint32_t MESSAGE_SLOT = COLUMNNUMBER_SLOT + 1;
52 static const uint32_t CAUSE_SLOT = MESSAGE_SLOT + 1;
53 static const uint32_t SOURCEID_SLOT = CAUSE_SLOT + 1;
55 static const uint32_t RESERVED_SLOTS = SOURCEID_SLOT + 1;
57 // This slot is only used for errors that could be Wasm traps.
58 static const uint32_t WASM_TRAP_SLOT = SOURCEID_SLOT + 1;
59 static const uint32_t RESERVED_SLOTS_MAYBE_WASM_TRAP = WASM_TRAP_SLOT + 1;
61 public:
62 static const JSClass classes[JSEXN_ERROR_LIMIT];
64 static const JSClass* classForType(JSExnType type) {
65 MOZ_ASSERT(type < JSEXN_ERROR_LIMIT);
66 return &classes[type];
69 static bool isErrorClass(const JSClass* clasp) {
70 return &classes[0] <= clasp && clasp < &classes[0] + std::size(classes);
73 // Create an error of the given type corresponding to the provided location
74 // info. If |message| is non-null, then the error will have a .message
75 // property with that value; otherwise the error will have no .message
76 // property.
77 static ErrorObject* create(JSContext* cx, JSExnType type, HandleObject stack,
78 HandleString fileName, uint32_t sourceId,
79 uint32_t lineNumber,
80 JS::ColumnNumberOneOrigin columnNumber,
81 UniquePtr<JSErrorReport> report,
82 HandleString message,
83 Handle<mozilla::Maybe<JS::Value>> cause,
84 HandleObject proto = nullptr);
87 * Assign the initial error shape to the empty object. (This shape does
88 * *not* include .message, which must be added separately if needed; see
89 * ErrorObject::init.)
91 static SharedShape* assignInitialShape(JSContext* cx,
92 Handle<ErrorObject*> obj);
94 JSExnType type() const {
95 MOZ_ASSERT(isErrorClass(getClass()));
96 return static_cast<JSExnType>(getClass() - &classes[0]);
99 JSErrorReport* getErrorReport() const {
100 const Value& slot = getReservedSlot(ERROR_REPORT_SLOT);
101 if (slot.isUndefined()) {
102 return nullptr;
104 return static_cast<JSErrorReport*>(slot.toPrivate());
107 JSErrorReport* getOrCreateErrorReport(JSContext* cx);
109 inline JSString* fileName(JSContext* cx) const;
110 inline uint32_t sourceId() const;
112 // Line number (1-origin).
113 inline uint32_t lineNumber() const;
115 // Column number in UTF-16 code units.
116 inline JS::ColumnNumberOneOrigin columnNumber() const;
118 // Returns nullptr or a (possibly wrapped) SavedFrame object.
119 inline JSObject* stack() const;
121 JSString* getMessage() const {
122 Value val = getReservedSlot(MESSAGE_SLOT);
123 return val.isString() ? val.toString() : nullptr;
127 * Return Nothing if the error was created without an initial cause or if the
128 * initial cause data property has been redefined to an accessor property.
130 mozilla::Maybe<Value> getCause() const {
131 const auto& value = getReservedSlot(CAUSE_SLOT);
132 if (value.isMagic(JS_ERROR_WITHOUT_CAUSE) || value.isPrivateGCThing()) {
133 return mozilla::Nothing();
135 return mozilla::Some(value);
138 void setStackSlot(const Value& stack) {
139 MOZ_ASSERT(stack.isObjectOrNull());
140 setReservedSlot(STACK_SLOT, stack);
143 void setCauseSlot(const Value& cause) {
144 MOZ_ASSERT(!cause.isMagic());
145 MOZ_ASSERT(getCause().isSome());
146 setReservedSlot(CAUSE_SLOT, cause);
149 // Getter and setter for the Error.prototype.stack accessor.
150 static bool getStack(JSContext* cx, unsigned argc, Value* vp);
151 static bool getStack_impl(JSContext* cx, const CallArgs& args);
152 static bool setStack(JSContext* cx, unsigned argc, Value* vp);
153 static bool setStack_impl(JSContext* cx, const CallArgs& args);
155 // Used to distinguish errors created from Wasm traps.
156 bool mightBeWasmTrap() const {
157 return type() == JSEXN_WASMRUNTIMEERROR || type() == JSEXN_INTERNALERR;
159 bool fromWasmTrap() const {
160 if (!mightBeWasmTrap()) {
161 return false;
162 } else {
163 MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(getClass()) > WASM_TRAP_SLOT);
164 return getReservedSlot(WASM_TRAP_SLOT).toBoolean();
167 void setFromWasmTrap();
170 JSString* ErrorToSource(JSContext* cx, HandleObject obj);
172 } // namespace js
174 template <>
175 inline bool JSObject::is<js::ErrorObject>() const {
176 return js::ErrorObject::isErrorClass(getClass());
179 #endif // vm_ErrorObject_h_