Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sts=4 et sw=4 tw=99:
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 : #ifndef vm_ErrorObject_h_
8 : #define vm_ErrorObject_h_
9 :
10 : #include "mozilla/ArrayUtils.h"
11 :
12 : #include "vm/NativeObject.h"
13 : #include "vm/SavedStacks.h"
14 : #include "vm/Shape.h"
15 :
16 : namespace js {
17 :
18 : /*
19 : * Initialize the exception constructor/prototype hierarchy.
20 : */
21 : extern JSObject*
22 : InitExceptionClasses(JSContext* cx, HandleObject obj);
23 :
24 : class ErrorObject : public NativeObject
25 : {
26 : static JSObject*
27 : createProto(JSContext* cx, JSProtoKey key);
28 :
29 : static JSObject*
30 : createConstructor(JSContext* cx, JSProtoKey key);
31 :
32 : /* For access to createProto. */
33 : friend JSObject*
34 : js::InitExceptionClasses(JSContext* cx, HandleObject global);
35 :
36 : static bool
37 : init(JSContext* cx, Handle<ErrorObject*> obj, JSExnType type,
38 : ScopedJSFreePtr<JSErrorReport>* errorReport, HandleString fileName, HandleObject stack,
39 : uint32_t lineNumber, uint32_t columnNumber, HandleString message);
40 :
41 : static const ClassSpec classSpecs[JSEXN_ERROR_LIMIT];
42 : static const Class protoClasses[JSEXN_ERROR_LIMIT];
43 :
44 : protected:
45 : static const uint32_t EXNTYPE_SLOT = 0;
46 : static const uint32_t STACK_SLOT = EXNTYPE_SLOT + 1;
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 :
53 : static const uint32_t RESERVED_SLOTS = MESSAGE_SLOT + 1;
54 :
55 : public:
56 : static const Class classes[JSEXN_ERROR_LIMIT];
57 :
58 3 : static const Class * classForType(JSExnType type) {
59 3 : MOZ_ASSERT(type < JSEXN_WARN);
60 3 : return &classes[type];
61 : }
62 :
63 8833 : static bool isErrorClass(const Class* clasp) {
64 8833 : return &classes[0] <= clasp && clasp < &classes[0] + mozilla::ArrayLength(classes);
65 : }
66 :
67 : // Create an error of the given type corresponding to the provided location
68 : // info. If |message| is non-null, then the error will have a .message
69 : // property with that value; otherwise the error will have no .message
70 : // property.
71 : static ErrorObject*
72 : create(JSContext* cx, JSExnType type, HandleObject stack, HandleString fileName,
73 : uint32_t lineNumber, uint32_t columnNumber, ScopedJSFreePtr<JSErrorReport>* report,
74 : HandleString message, HandleObject proto = nullptr);
75 :
76 : /*
77 : * Assign the initial error shape to the empty object. (This shape does
78 : * *not* include .message, which must be added separately if needed; see
79 : * ErrorObject::init.)
80 : */
81 : static Shape*
82 : assignInitialShape(JSContext* cx, Handle<ErrorObject*> obj);
83 :
84 0 : JSExnType type() const {
85 0 : return JSExnType(getReservedSlot(EXNTYPE_SLOT).toInt32());
86 : }
87 :
88 0 : JSErrorReport * getErrorReport() const {
89 0 : const Value& slot = getReservedSlot(ERROR_REPORT_SLOT);
90 0 : if (slot.isUndefined())
91 0 : return nullptr;
92 0 : return static_cast<JSErrorReport*>(slot.toPrivate());
93 : }
94 :
95 : JSErrorReport * getOrCreateErrorReport(JSContext* cx);
96 :
97 : inline JSString * fileName(JSContext* cx) const;
98 : inline uint32_t lineNumber() const;
99 : inline uint32_t columnNumber() const;
100 : inline JSObject * stack() const;
101 :
102 0 : JSString * getMessage() const {
103 0 : const HeapSlot& slot = getReservedSlotRef(MESSAGE_SLOT);
104 0 : return slot.isString() ? slot.toString() : nullptr;
105 : }
106 :
107 : // Getter and setter for the Error.prototype.stack accessor.
108 : static bool getStack(JSContext* cx, unsigned argc, Value* vp);
109 : static bool getStack_impl(JSContext* cx, const CallArgs& args);
110 : static bool setStack(JSContext* cx, unsigned argc, Value* vp);
111 : static bool setStack_impl(JSContext* cx, const CallArgs& args);
112 : };
113 :
114 : } // namespace js
115 :
116 : template<>
117 : inline bool
118 22 : JSObject::is<js::ErrorObject>() const
119 : {
120 22 : return js::ErrorObject::isErrorClass(getClass());
121 : }
122 :
123 : #endif // vm_ErrorObject_h_
|