|
| 1 | +#include "dom-exception.h" |
| 2 | +#include "builtin.h" |
| 3 | +#include "js-compute-builtins.h" |
| 4 | +#include "js/Context.h" |
| 5 | + |
| 6 | +namespace builtins { |
| 7 | + |
| 8 | +bool DOMException::name_get(JSContext *cx, unsigned argc, JS::Value *vp) { |
| 9 | + METHOD_HEADER(0); |
| 10 | + if (self == proto_obj) { |
| 11 | + JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, |
| 12 | + JSBuiltinErrNum::JSMSG_INVALID_INTERFACE, "name get", "DOMException"); |
| 13 | + return false; |
| 14 | + } |
| 15 | + args.rval().setString(JS::GetReservedSlot(self, Slots::Name).toString()); |
| 16 | + return true; |
| 17 | +} |
| 18 | + |
| 19 | +bool DOMException::message_get(JSContext *cx, unsigned argc, JS::Value *vp) { |
| 20 | + METHOD_HEADER(0); |
| 21 | + if (self == proto_obj) { |
| 22 | + JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, |
| 23 | + JSBuiltinErrNum::JSMSG_INVALID_INTERFACE, "name get", "DOMException"); |
| 24 | + return false; |
| 25 | + } |
| 26 | + args.rval().setString(JS::GetReservedSlot(self, Slots::Message).toString()); |
| 27 | + return true; |
| 28 | +} |
| 29 | + |
| 30 | +bool DOMException::code_get(JSContext *cx, unsigned argc, JS::Value *vp) { |
| 31 | + METHOD_HEADER(0); |
| 32 | + if (self == proto_obj) { |
| 33 | + JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, |
| 34 | + JSBuiltinErrNum::JSMSG_INVALID_INTERFACE, "name get", "DOMException"); |
| 35 | + return false; |
| 36 | + } |
| 37 | + size_t length; |
| 38 | + JS::RootedString name_string(cx, JS::GetReservedSlot(self, Slots::Name).toString()); |
| 39 | + auto chars = encode(cx, name_string, &length); |
| 40 | + if (!chars) { |
| 41 | + return false; |
| 42 | + } |
| 43 | + std::string_view name(chars.get(), length); |
| 44 | + int32_t code = 0; |
| 45 | + if (name == "IndexSizeError") { |
| 46 | + code = 1; |
| 47 | + } else if (name == "HierarchyRequestError") { |
| 48 | + code = 3; |
| 49 | + } else if (name == "WrongDocumentError") { |
| 50 | + code = 4; |
| 51 | + } else if (name == "InvalidCharacterError") { |
| 52 | + code = 5; |
| 53 | + } else if (name == "NoModificationAllowedError") { |
| 54 | + code = 7; |
| 55 | + } else if (name == "NotFoundError") { |
| 56 | + code = 8; |
| 57 | + } else if (name == "NotSupportedError") { |
| 58 | + code = 9; |
| 59 | + } else if (name == "InUseAttributeError") { |
| 60 | + code = 10; |
| 61 | + } else if (name == "InvalidStateError") { |
| 62 | + code = 11; |
| 63 | + } else if (name == "SyntaxError") { |
| 64 | + code = 12; |
| 65 | + } else if (name == "InvalidModificationError") { |
| 66 | + code = 13; |
| 67 | + } else if (name == "NamespaceError") { |
| 68 | + code = 14; |
| 69 | + } else if (name == "InvalidAccessError") { |
| 70 | + code = 15; |
| 71 | + } else if (name == "TypeMismatchError") { |
| 72 | + code = 17; |
| 73 | + } else if (name == "SecurityError") { |
| 74 | + code = 18; |
| 75 | + } else if (name == "NetworkError") { |
| 76 | + code = 19; |
| 77 | + } else if (name == "AbortError") { |
| 78 | + code = 20; |
| 79 | + } else if (name == "URLMismatchError") { |
| 80 | + code = 21; |
| 81 | + } else if (name == "QuotaExceededError") { |
| 82 | + code = 22; |
| 83 | + } else if (name == "TimeoutError") { |
| 84 | + code = 23; |
| 85 | + } else if (name == "InvalidNodeTypeError") { |
| 86 | + code = 24; |
| 87 | + } else if (name == "DataCloneError") { |
| 88 | + code = 25; |
| 89 | + } |
| 90 | + |
| 91 | + args.rval().setInt32(code); |
| 92 | + return true; |
| 93 | +} |
| 94 | + |
| 95 | +const JSFunctionSpec DOMException::methods[] = {JS_FS_END}; |
| 96 | +const JSFunctionSpec DOMException::static_methods[] = {JS_FS_END}; |
| 97 | + |
| 98 | +const JSPropertySpec DOMException::properties[] = { |
| 99 | + JS_PSG("code", code_get, JSPROP_ENUMERATE), |
| 100 | + JS_PSG("message", message_get, JSPROP_ENUMERATE), |
| 101 | + JS_PSG("name", name_get, JSPROP_ENUMERATE), |
| 102 | + JS_INT32_PS("INDEX_SIZE_ERR", 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 103 | + JS_INT32_PS("DOMSTRING_SIZE_ERR", 2, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 104 | + JS_INT32_PS("HIERARCHY_REQUEST_ERR", 3, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 105 | + JS_INT32_PS("WRONG_DOCUMENT_ERR", 4, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 106 | + JS_INT32_PS("INVALID_CHARACTER_ERR", 5, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 107 | + JS_INT32_PS("NO_DATA_ALLOWED_ERR", 6, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 108 | + JS_INT32_PS("NO_MODIFICATION_ALLOWED_ERR", 7, |
| 109 | + JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 110 | + JS_INT32_PS("NOT_FOUND_ERR", 8, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 111 | + JS_INT32_PS("NOT_SUPPORTED_ERR", 9, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 112 | + JS_INT32_PS("INUSE_ATTRIBUTE_ERR", 10, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 113 | + JS_INT32_PS("INVALID_STATE_ERR", 11, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 114 | + JS_INT32_PS("SYNTAX_ERR", 12, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 115 | + JS_INT32_PS("INVALID_MODIFICATION_ERR", 13, |
| 116 | + JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 117 | + JS_INT32_PS("NAMESPACE_ERR", 14, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 118 | + JS_INT32_PS("INVALID_ACCESS_ERR", 15, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 119 | + JS_INT32_PS("VALIDATION_ERR", 16, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 120 | + JS_INT32_PS("TYPE_MISMATCH_ERR", 17, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 121 | + JS_INT32_PS("SECURITY_ERR", 18, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 122 | + JS_INT32_PS("NETWORK_ERR", 19, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 123 | + JS_INT32_PS("ABORT_ERR", 20, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 124 | + JS_INT32_PS("URL_MISMATCH_ERR", 21, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 125 | + JS_INT32_PS("QUOTA_EXCEEDED_ERR", 22, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 126 | + JS_INT32_PS("TIMEOUT_ERR", 23, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 127 | + JS_INT32_PS("INVALID_NODE_TYPE_ERR", 24, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 128 | + JS_INT32_PS("DATA_CLONE_ERR", 25, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 129 | + JS_STRING_SYM_PS(toStringTag, "DOMException", |
| 130 | + JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 131 | + JS_PS_END}; |
| 132 | +const JSPropertySpec DOMException::static_properties[] = { |
| 133 | + JS_INT32_PS("INDEX_SIZE_ERR", 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 134 | + JS_INT32_PS("DOMSTRING_SIZE_ERR", 2, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 135 | + JS_INT32_PS("HIERARCHY_REQUEST_ERR", 3, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 136 | + JS_INT32_PS("WRONG_DOCUMENT_ERR", 4, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 137 | + JS_INT32_PS("INVALID_CHARACTER_ERR", 5, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 138 | + JS_INT32_PS("NO_DATA_ALLOWED_ERR", 6, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 139 | + JS_INT32_PS("NO_MODIFICATION_ALLOWED_ERR", 7, |
| 140 | + JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 141 | + JS_INT32_PS("NOT_FOUND_ERR", 8, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 142 | + JS_INT32_PS("NOT_SUPPORTED_ERR", 9, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 143 | + JS_INT32_PS("INUSE_ATTRIBUTE_ERR", 10, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 144 | + JS_INT32_PS("INVALID_STATE_ERR", 11, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 145 | + JS_INT32_PS("SYNTAX_ERR", 12, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 146 | + JS_INT32_PS("INVALID_MODIFICATION_ERR", 13, |
| 147 | + JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 148 | + JS_INT32_PS("NAMESPACE_ERR", 14, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 149 | + JS_INT32_PS("INVALID_ACCESS_ERR", 15, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 150 | + JS_INT32_PS("VALIDATION_ERR", 16, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 151 | + JS_INT32_PS("TYPE_MISMATCH_ERR", 17, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 152 | + JS_INT32_PS("SECURITY_ERR", 18, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 153 | + JS_INT32_PS("NETWORK_ERR", 19, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 154 | + JS_INT32_PS("ABORT_ERR", 20, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 155 | + JS_INT32_PS("URL_MISMATCH_ERR", 21, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 156 | + JS_INT32_PS("QUOTA_EXCEEDED_ERR", 22, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 157 | + JS_INT32_PS("TIMEOUT_ERR", 23, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 158 | + JS_INT32_PS("INVALID_NODE_TYPE_ERR", 24, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 159 | + JS_INT32_PS("DATA_CLONE_ERR", 25, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT), |
| 160 | + JS_PS_END}; |
| 161 | + |
| 162 | +JSObject *DOMException::create(JSContext *cx, std::string_view message, std::string_view name) { |
| 163 | + JS::RootedValueArray<2> args(cx); |
| 164 | + args[0].setString(JS_NewStringCopyN(cx, message.data(), message.size())); |
| 165 | + args[1].setString(JS_NewStringCopyN(cx, name.data(), name.size())); |
| 166 | + JS::RootedObject instance(cx); |
| 167 | + JS::RootedObject ctorObj(cx, JS_GetConstructor(cx, proto_obj)); |
| 168 | + JS::RootedValue ctor(cx, JS::ObjectValue(*ctorObj)); |
| 169 | + if (!JS::Construct(cx, ctor, args, &instance)) { |
| 170 | + return nullptr; |
| 171 | + } |
| 172 | + if (!instance) { |
| 173 | + return nullptr; |
| 174 | + } |
| 175 | + auto message_str = JS_NewStringCopyN(cx, message.data(), message.size()); |
| 176 | + if (!message_str) { |
| 177 | + return nullptr; |
| 178 | + } |
| 179 | + JS::SetReservedSlot(instance, Slots::Message, JS::StringValue(message_str)); |
| 180 | + auto name_str = JS_NewStringCopyN(cx, name.data(), name.size()); |
| 181 | + if (!name_str) { |
| 182 | + return nullptr; |
| 183 | + } |
| 184 | + JS::SetReservedSlot(instance, Slots::Name, JS::StringValue(name_str)); |
| 185 | + |
| 186 | + return instance; |
| 187 | +} |
| 188 | + |
| 189 | +void DOMException::raise(JSContext *cx, std::string_view message, std::string_view name) { |
| 190 | + JS::RootedObject errorObj(cx); |
| 191 | + errorObj.set(DOMException::create(cx, message, name)); |
| 192 | + JS::RootedValue er(cx, JS::ObjectValue(*errorObj)); |
| 193 | + JS_SetPendingException(cx, er); |
| 194 | +} |
| 195 | + |
| 196 | +// constructor(optional DOMString message = "", optional DOMString name = "Error"); |
| 197 | +bool DOMException::constructor(JSContext *cx, unsigned argc, JS::Value *vp) { |
| 198 | + CTOR_HEADER("DOMException", 0); |
| 199 | + |
| 200 | + JS::RootedObject instance(cx, JS_NewObjectForConstructor(cx, &class_, args)); |
| 201 | + if (!instance) { |
| 202 | + return false; |
| 203 | + } |
| 204 | + if (args.hasDefined(0)) { |
| 205 | + auto message = JS::ToString(cx, args.get(0)); |
| 206 | + if (!message) { |
| 207 | + return false; |
| 208 | + } |
| 209 | + JS::SetReservedSlot(instance, Slots::Message, JS::StringValue(message)); |
| 210 | + } else { |
| 211 | + JS::SetReservedSlot(instance, Slots::Message, JS_GetEmptyStringValue(cx)); |
| 212 | + } |
| 213 | + if (args.hasDefined(1)) { |
| 214 | + auto name = JS::ToString(cx, args.get(1)); |
| 215 | + if (!name) { |
| 216 | + return false; |
| 217 | + } |
| 218 | + JS::SetReservedSlot(instance, Slots::Name, JS::StringValue(name)); |
| 219 | + } else { |
| 220 | + JS::SetReservedSlot(instance, Slots::Name, JS::StringValue(JS_NewStringCopyZ(cx, "Error"))); |
| 221 | + } |
| 222 | + |
| 223 | + args.rval().setObject(*instance); |
| 224 | + return true; |
| 225 | +} |
| 226 | + |
| 227 | +bool DOMException::init_class(JSContext *cx, JS::HandleObject global) { |
| 228 | + JS::RootedObject proto(cx, JS::GetRealmErrorPrototype(cx)); |
| 229 | + if (!proto) { |
| 230 | + return false; |
| 231 | + } |
| 232 | + |
| 233 | + return init_class_impl(cx, global, proto); |
| 234 | +} |
| 235 | + |
| 236 | +} // namespace builtins |
0 commit comments