PropertyAndElement.h (22581B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 /* Property and element API. */ 7 8 #ifndef js_PropertyAndElement_h 9 #define js_PropertyAndElement_h 10 11 #include <stddef.h> // size_t 12 #include <stdint.h> // uint32_t 13 14 #include "jstypes.h" // JS_PUBLIC_API 15 16 #include "js/CallArgs.h" // JSNative 17 #include "js/GCVector.h" // JS::GCVector 18 #include "js/Id.h" // jsid 19 #include "js/RootingAPI.h" // JS::Handle, JS::MutableHandle 20 21 struct JSContext; 22 class JSFunction; 23 class JSObject; 24 class JSString; 25 26 namespace JS { 27 28 class ObjectOpResult; 29 class JS_PUBLIC_API PropertyDescriptor; 30 31 using IdVector = JS::GCVector<jsid>; 32 33 } /* namespace JS */ 34 35 /** 36 * Define a property on obj. 37 * 38 * This function uses JS::ObjectOpResult to indicate conditions that ES6 39 * specifies as non-error failures. This is inconvenient at best, so use this 40 * function only if you are implementing a proxy handler's defineProperty() 41 * method. For all other purposes, use one of the many DefineProperty functions 42 * below that throw an exception in all failure cases. 43 * 44 * Implements: ES6 [[DefineOwnProperty]] internal method. 45 */ 46 extern JS_PUBLIC_API bool JS_DefinePropertyById( 47 JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, 48 JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& result); 49 50 /** 51 * Define a property on obj, throwing a TypeError if the attempt fails. 52 * This is the C++ equivalent of `Object.defineProperty(obj, id, desc)`. 53 */ 54 extern JS_PUBLIC_API bool JS_DefinePropertyById( 55 JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, 56 JS::Handle<JS::PropertyDescriptor> desc); 57 58 extern JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx, 59 JS::Handle<JSObject*> obj, 60 JS::Handle<jsid> id, 61 JS::Handle<JS::Value> value, 62 unsigned attrs); 63 64 extern JS_PUBLIC_API bool JS_DefinePropertyById( 65 JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, 66 JSNative getter, JSNative setter, unsigned attrs); 67 68 extern JS_PUBLIC_API bool JS_DefinePropertyById( 69 JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, 70 JS::Handle<JSObject*> getter, JS::Handle<JSObject*> setter, unsigned attrs); 71 72 extern JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx, 73 JS::Handle<JSObject*> obj, 74 JS::Handle<jsid> id, 75 JS::Handle<JSObject*> value, 76 unsigned attrs); 77 78 extern JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx, 79 JS::Handle<JSObject*> obj, 80 JS::Handle<jsid> id, 81 JS::Handle<JSString*> value, 82 unsigned attrs); 83 84 extern JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx, 85 JS::Handle<JSObject*> obj, 86 JS::Handle<jsid> id, 87 int32_t value, unsigned attrs); 88 89 extern JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx, 90 JS::Handle<JSObject*> obj, 91 JS::Handle<jsid> id, 92 uint32_t value, unsigned attrs); 93 94 extern JS_PUBLIC_API bool JS_DefinePropertyById(JSContext* cx, 95 JS::Handle<JSObject*> obj, 96 JS::Handle<jsid> id, 97 double value, unsigned attrs); 98 99 extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, 100 JS::Handle<JSObject*> obj, 101 const char* name, 102 JS::Handle<JS::Value> value, 103 unsigned attrs); 104 105 extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, 106 JS::Handle<JSObject*> obj, 107 const char* name, JSNative getter, 108 JSNative setter, unsigned attrs); 109 110 extern JS_PUBLIC_API bool JS_DefineProperty( 111 JSContext* cx, JS::Handle<JSObject*> obj, const char* name, 112 JS::Handle<JSObject*> getter, JS::Handle<JSObject*> setter, unsigned attrs); 113 114 extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, 115 JS::Handle<JSObject*> obj, 116 const char* name, 117 JS::Handle<JSObject*> value, 118 unsigned attrs); 119 120 extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, 121 JS::Handle<JSObject*> obj, 122 const char* name, 123 JS::Handle<JSString*> value, 124 unsigned attrs); 125 126 extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, 127 JS::Handle<JSObject*> obj, 128 const char* name, int32_t value, 129 unsigned attrs); 130 131 extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, 132 JS::Handle<JSObject*> obj, 133 const char* name, uint32_t value, 134 unsigned attrs); 135 136 extern JS_PUBLIC_API bool JS_DefineProperty(JSContext* cx, 137 JS::Handle<JSObject*> obj, 138 const char* name, double value, 139 unsigned attrs); 140 141 extern JS_PUBLIC_API bool JS_DefineUCProperty( 142 JSContext* cx, JS::Handle<JSObject*> obj, const char16_t* name, 143 size_t namelen, JS::Handle<JS::PropertyDescriptor> desc, 144 JS::ObjectOpResult& result); 145 146 extern JS_PUBLIC_API bool JS_DefineUCProperty( 147 JSContext* cx, JS::Handle<JSObject*> obj, const char16_t* name, 148 size_t namelen, JS::Handle<JS::PropertyDescriptor> desc); 149 150 extern JS_PUBLIC_API bool JS_DefineUCProperty( 151 JSContext* cx, JS::Handle<JSObject*> obj, const char16_t* name, 152 size_t namelen, JS::Handle<JS::Value> value, unsigned attrs); 153 154 extern JS_PUBLIC_API bool JS_DefineUCProperty( 155 JSContext* cx, JS::Handle<JSObject*> obj, const char16_t* name, 156 size_t namelen, JS::Handle<JSObject*> getter, JS::Handle<JSObject*> setter, 157 unsigned attrs); 158 159 extern JS_PUBLIC_API bool JS_DefineUCProperty( 160 JSContext* cx, JS::Handle<JSObject*> obj, const char16_t* name, 161 size_t namelen, JS::Handle<JSObject*> value, unsigned attrs); 162 163 extern JS_PUBLIC_API bool JS_DefineUCProperty( 164 JSContext* cx, JS::Handle<JSObject*> obj, const char16_t* name, 165 size_t namelen, JS::Handle<JSString*> value, unsigned attrs); 166 167 extern JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx, 168 JS::Handle<JSObject*> obj, 169 const char16_t* name, 170 size_t namelen, int32_t value, 171 unsigned attrs); 172 173 extern JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx, 174 JS::Handle<JSObject*> obj, 175 const char16_t* name, 176 size_t namelen, uint32_t value, 177 unsigned attrs); 178 179 extern JS_PUBLIC_API bool JS_DefineUCProperty(JSContext* cx, 180 JS::Handle<JSObject*> obj, 181 const char16_t* name, 182 size_t namelen, double value, 183 unsigned attrs); 184 185 extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, 186 JS::Handle<JSObject*> obj, 187 uint32_t index, 188 JS::Handle<JS::Value> value, 189 unsigned attrs); 190 191 extern JS_PUBLIC_API bool JS_DefineElement( 192 JSContext* cx, JS::Handle<JSObject*> obj, uint32_t index, 193 JS::Handle<JSObject*> getter, JS::Handle<JSObject*> setter, unsigned attrs); 194 195 extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, 196 JS::Handle<JSObject*> obj, 197 uint32_t index, 198 JS::Handle<JSObject*> value, 199 unsigned attrs); 200 201 extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, 202 JS::Handle<JSObject*> obj, 203 uint32_t index, 204 JS::Handle<JSString*> value, 205 unsigned attrs); 206 207 extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, 208 JS::Handle<JSObject*> obj, 209 uint32_t index, int32_t value, 210 unsigned attrs); 211 212 extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, 213 JS::Handle<JSObject*> obj, 214 uint32_t index, uint32_t value, 215 unsigned attrs); 216 217 extern JS_PUBLIC_API bool JS_DefineElement(JSContext* cx, 218 JS::Handle<JSObject*> obj, 219 uint32_t index, double value, 220 unsigned attrs); 221 222 /** 223 * Compute the expression `id in obj`. 224 * 225 * If obj has an own or inherited property obj[id], set *foundp = true and 226 * return true. If not, set *foundp = false and return true. On error, return 227 * false with an exception pending. 228 * 229 * Implements: ES6 [[Has]] internal method. 230 */ 231 extern JS_PUBLIC_API bool JS_HasPropertyById(JSContext* cx, 232 JS::Handle<JSObject*> obj, 233 JS::Handle<jsid> id, bool* foundp); 234 235 extern JS_PUBLIC_API bool JS_HasProperty(JSContext* cx, 236 JS::Handle<JSObject*> obj, 237 const char* name, bool* foundp); 238 239 extern JS_PUBLIC_API bool JS_HasUCProperty(JSContext* cx, 240 JS::Handle<JSObject*> obj, 241 const char16_t* name, size_t namelen, 242 bool* vp); 243 244 extern JS_PUBLIC_API bool JS_HasElement(JSContext* cx, 245 JS::Handle<JSObject*> obj, 246 uint32_t index, bool* foundp); 247 248 /** 249 * Determine whether obj has an own property with the key `id`. 250 * 251 * Implements: ES6 7.3.11 HasOwnProperty(O, P). 252 */ 253 extern JS_PUBLIC_API bool JS_HasOwnPropertyById(JSContext* cx, 254 JS::Handle<JSObject*> obj, 255 JS::Handle<jsid> id, 256 bool* foundp); 257 258 extern JS_PUBLIC_API bool JS_HasOwnProperty(JSContext* cx, 259 JS::Handle<JSObject*> obj, 260 const char* name, bool* foundp); 261 262 /** 263 * Get the value of the property `obj[id]`, or undefined if no such property 264 * exists. This is the C++ equivalent of `vp = Reflect.get(obj, id, receiver)`. 265 * 266 * Most callers don't need the `receiver` argument. Consider using 267 * JS_GetProperty instead. (But if you're implementing a proxy handler's set() 268 * method, it's often correct to call this function and pass the receiver 269 * through.) 270 * 271 * Implements: ES6 [[Get]] internal method. 272 */ 273 extern JS_PUBLIC_API bool JS_ForwardGetPropertyTo( 274 JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, 275 JS::Handle<JS::Value> receiver, JS::MutableHandleValue vp); 276 277 extern JS_PUBLIC_API bool JS_ForwardGetElementTo(JSContext* cx, 278 JS::Handle<JSObject*> obj, 279 uint32_t index, 280 JS::Handle<JSObject*> receiver, 281 JS::MutableHandleValue vp); 282 283 /** 284 * Get the value of the property `obj[id]`, or undefined if no such property 285 * exists. The result is stored in vp. 286 * 287 * Implements: ES6 7.3.1 Get(O, P). 288 */ 289 extern JS_PUBLIC_API bool JS_GetPropertyById(JSContext* cx, 290 JS::Handle<JSObject*> obj, 291 JS::Handle<jsid> id, 292 JS::MutableHandleValue vp); 293 294 extern JS_PUBLIC_API bool JS_GetProperty(JSContext* cx, 295 JS::Handle<JSObject*> obj, 296 const char* name, 297 JS::MutableHandleValue vp); 298 299 extern JS_PUBLIC_API bool JS_GetUCProperty(JSContext* cx, 300 JS::Handle<JSObject*> obj, 301 const char16_t* name, size_t namelen, 302 JS::MutableHandleValue vp); 303 304 extern JS_PUBLIC_API bool JS_GetElement(JSContext* cx, 305 JS::Handle<JSObject*> obj, 306 uint32_t index, 307 JS::MutableHandleValue vp); 308 309 /** 310 * Perform the same property assignment as `Reflect.set(obj, id, v, receiver)`. 311 * 312 * This function has a `receiver` argument that most callers don't need. 313 * Consider using JS_SetProperty instead. 314 * 315 * Implements: ES6 [[Set]] internal method. 316 */ 317 extern JS_PUBLIC_API bool JS_ForwardSetPropertyTo( 318 JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, 319 JS::Handle<JS::Value> v, JS::Handle<JS::Value> receiver, 320 JS::ObjectOpResult& result); 321 322 /** 323 * Perform the assignment `obj[id] = v`. 324 * 325 * This function performs non-strict assignment, so if the property is 326 * read-only, nothing happens and no error is thrown. 327 */ 328 extern JS_PUBLIC_API bool JS_SetPropertyById(JSContext* cx, 329 JS::Handle<JSObject*> obj, 330 JS::Handle<jsid> id, 331 JS::Handle<JS::Value> v); 332 333 extern JS_PUBLIC_API bool JS_SetProperty(JSContext* cx, 334 JS::Handle<JSObject*> obj, 335 const char* name, 336 JS::Handle<JS::Value> v); 337 338 extern JS_PUBLIC_API bool JS_SetUCProperty(JSContext* cx, 339 JS::Handle<JSObject*> obj, 340 const char16_t* name, size_t namelen, 341 JS::Handle<JS::Value> v); 342 343 extern JS_PUBLIC_API bool JS_SetElement(JSContext* cx, 344 JS::Handle<JSObject*> obj, 345 uint32_t index, 346 JS::Handle<JS::Value> v); 347 348 extern JS_PUBLIC_API bool JS_SetElement(JSContext* cx, 349 JS::Handle<JSObject*> obj, 350 uint32_t index, 351 JS::Handle<JSObject*> v); 352 353 extern JS_PUBLIC_API bool JS_SetElement(JSContext* cx, 354 JS::Handle<JSObject*> obj, 355 uint32_t index, 356 JS::Handle<JSString*> v); 357 358 extern JS_PUBLIC_API bool JS_SetElement(JSContext* cx, 359 JS::Handle<JSObject*> obj, 360 uint32_t index, int32_t v); 361 362 extern JS_PUBLIC_API bool JS_SetElement(JSContext* cx, 363 JS::Handle<JSObject*> obj, 364 uint32_t index, uint32_t v); 365 366 extern JS_PUBLIC_API bool JS_SetElement(JSContext* cx, 367 JS::Handle<JSObject*> obj, 368 uint32_t index, double v); 369 370 /** 371 * Delete a property. This is the C++ equivalent of 372 * `result = Reflect.deleteProperty(obj, id)`. 373 * 374 * This function has a `result` out parameter that most callers don't need. 375 * Unless you can pass through an ObjectOpResult provided by your caller, it's 376 * probably best to use the JS_DeletePropertyById signature with just 3 377 * arguments. 378 * 379 * Implements: ES6 [[Delete]] internal method. 380 */ 381 extern JS_PUBLIC_API bool JS_DeletePropertyById(JSContext* cx, 382 JS::Handle<JSObject*> obj, 383 JS::Handle<jsid> id, 384 JS::ObjectOpResult& result); 385 386 extern JS_PUBLIC_API bool JS_DeleteProperty(JSContext* cx, 387 JS::Handle<JSObject*> obj, 388 const char* name, 389 JS::ObjectOpResult& result); 390 391 extern JS_PUBLIC_API bool JS_DeleteUCProperty(JSContext* cx, 392 JS::Handle<JSObject*> obj, 393 const char16_t* name, 394 size_t namelen, 395 JS::ObjectOpResult& result); 396 397 extern JS_PUBLIC_API bool JS_DeleteElement(JSContext* cx, 398 JS::Handle<JSObject*> obj, 399 uint32_t index, 400 JS::ObjectOpResult& result); 401 402 /** 403 * Delete a property, ignoring strict failures. This is the C++ equivalent of 404 * the JS `delete obj[id]` in non-strict mode code. 405 */ 406 extern JS_PUBLIC_API bool JS_DeletePropertyById(JSContext* cx, 407 JS::Handle<JSObject*> obj, 408 JS::Handle<jsid> id); 409 410 extern JS_PUBLIC_API bool JS_DeleteProperty(JSContext* cx, 411 JS::Handle<JSObject*> obj, 412 const char* name); 413 414 extern JS_PUBLIC_API bool JS_DeleteElement(JSContext* cx, 415 JS::Handle<JSObject*> obj, 416 uint32_t index); 417 418 /** 419 * Get an array of the non-symbol enumerable properties of obj. 420 * This function is roughly equivalent to: 421 * 422 * var result = []; 423 * for (key in obj) { 424 * result.push(key); 425 * } 426 * return result; 427 * 428 * This is the closest thing we currently have to the ES6 [[Enumerate]] 429 * internal method. 430 * 431 * The array of ids returned by JS_Enumerate must be rooted to protect its 432 * contents from garbage collection. Use JS::Rooted<JS::IdVector>. 433 */ 434 extern JS_PUBLIC_API bool JS_Enumerate(JSContext* cx, JS::Handle<JSObject*> obj, 435 JS::MutableHandle<JS::IdVector> props); 436 437 /*** Other property-defining functions **************************************/ 438 439 extern JS_PUBLIC_API JSObject* JS_DefineObject(JSContext* cx, 440 JS::Handle<JSObject*> obj, 441 const char* name, 442 const JSClass* clasp = nullptr, 443 unsigned attrs = 0); 444 445 extern JS_PUBLIC_API bool JS_DefineProperties(JSContext* cx, 446 JS::Handle<JSObject*> obj, 447 const JSPropertySpec* ps); 448 449 /* * */ 450 451 extern JS_PUBLIC_API bool JS_AlreadyHasOwnPropertyById( 452 JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, 453 bool* foundp); 454 455 extern JS_PUBLIC_API bool JS_AlreadyHasOwnProperty(JSContext* cx, 456 JS::Handle<JSObject*> obj, 457 const char* name, 458 bool* foundp); 459 460 extern JS_PUBLIC_API bool JS_AlreadyHasOwnUCProperty(JSContext* cx, 461 JS::Handle<JSObject*> obj, 462 const char16_t* name, 463 size_t namelen, 464 bool* foundp); 465 466 extern JS_PUBLIC_API bool JS_AlreadyHasOwnElement(JSContext* cx, 467 JS::Handle<JSObject*> obj, 468 uint32_t index, bool* foundp); 469 470 extern JS_PUBLIC_API bool JS_DefineFunctions(JSContext* cx, 471 JS::Handle<JSObject*> obj, 472 const JSFunctionSpec* fs); 473 474 extern JS_PUBLIC_API JSFunction* JS_DefineFunction( 475 JSContext* cx, JS::Handle<JSObject*> obj, const char* name, JSNative call, 476 unsigned nargs, unsigned attrs); 477 478 extern JS_PUBLIC_API JSFunction* JS_DefineUCFunction( 479 JSContext* cx, JS::Handle<JSObject*> obj, const char16_t* name, 480 size_t namelen, JSNative call, unsigned nargs, unsigned attrs); 481 482 extern JS_PUBLIC_API JSFunction* JS_DefineFunctionById( 483 JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, 484 JSNative call, unsigned nargs, unsigned attrs); 485 486 #endif /* js_PropertyAndElement_h */