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/. */
6 /* Property and element API. */
8 #ifndef js_PropertyAndElement_h
9 #define js_PropertyAndElement_h
11 #include <stddef.h> // size_t
12 #include <stdint.h> // uint32_t
14 #include "jstypes.h" // JS_PUBLIC_API
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
29 class JS_PUBLIC_API PropertyDescriptor
;
31 using IdVector
= JS::GCVector
<jsid
>;
36 * Define a property on obj.
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.
44 * Implements: ES6 [[DefineOwnProperty]] internal method.
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
);
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)`.
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
);
58 extern JS_PUBLIC_API
bool JS_DefinePropertyById(JSContext
* cx
,
59 JS::Handle
<JSObject
*> obj
,
61 JS::Handle
<JS::Value
> value
,
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
);
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
);
72 extern JS_PUBLIC_API
bool JS_DefinePropertyById(JSContext
* cx
,
73 JS::Handle
<JSObject
*> obj
,
75 JS::Handle
<JSObject
*> value
,
78 extern JS_PUBLIC_API
bool JS_DefinePropertyById(JSContext
* cx
,
79 JS::Handle
<JSObject
*> obj
,
81 JS::Handle
<JSString
*> value
,
84 extern JS_PUBLIC_API
bool JS_DefinePropertyById(JSContext
* cx
,
85 JS::Handle
<JSObject
*> obj
,
87 int32_t value
, unsigned attrs
);
89 extern JS_PUBLIC_API
bool JS_DefinePropertyById(JSContext
* cx
,
90 JS::Handle
<JSObject
*> obj
,
92 uint32_t value
, unsigned attrs
);
94 extern JS_PUBLIC_API
bool JS_DefinePropertyById(JSContext
* cx
,
95 JS::Handle
<JSObject
*> obj
,
97 double value
, unsigned attrs
);
99 extern JS_PUBLIC_API
bool JS_DefineProperty(JSContext
* cx
,
100 JS::Handle
<JSObject
*> obj
,
102 JS::Handle
<JS::Value
> value
,
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
);
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
);
114 extern JS_PUBLIC_API
bool JS_DefineProperty(JSContext
* cx
,
115 JS::Handle
<JSObject
*> obj
,
117 JS::Handle
<JSObject
*> value
,
120 extern JS_PUBLIC_API
bool JS_DefineProperty(JSContext
* cx
,
121 JS::Handle
<JSObject
*> obj
,
123 JS::Handle
<JSString
*> value
,
126 extern JS_PUBLIC_API
bool JS_DefineProperty(JSContext
* cx
,
127 JS::Handle
<JSObject
*> obj
,
128 const char* name
, int32_t value
,
131 extern JS_PUBLIC_API
bool JS_DefineProperty(JSContext
* cx
,
132 JS::Handle
<JSObject
*> obj
,
133 const char* name
, uint32_t value
,
136 extern JS_PUBLIC_API
bool JS_DefineProperty(JSContext
* cx
,
137 JS::Handle
<JSObject
*> obj
,
138 const char* name
, double value
,
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
);
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
);
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
);
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
,
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
);
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
);
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
,
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
,
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
,
185 extern JS_PUBLIC_API
bool JS_DefineElement(JSContext
* cx
,
186 JS::Handle
<JSObject
*> obj
,
188 JS::Handle
<JS::Value
> value
,
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
);
195 extern JS_PUBLIC_API
bool JS_DefineElement(JSContext
* cx
,
196 JS::Handle
<JSObject
*> obj
,
198 JS::Handle
<JSObject
*> value
,
201 extern JS_PUBLIC_API
bool JS_DefineElement(JSContext
* cx
,
202 JS::Handle
<JSObject
*> obj
,
204 JS::Handle
<JSString
*> value
,
207 extern JS_PUBLIC_API
bool JS_DefineElement(JSContext
* cx
,
208 JS::Handle
<JSObject
*> obj
,
209 uint32_t index
, int32_t value
,
212 extern JS_PUBLIC_API
bool JS_DefineElement(JSContext
* cx
,
213 JS::Handle
<JSObject
*> obj
,
214 uint32_t index
, uint32_t value
,
217 extern JS_PUBLIC_API
bool JS_DefineElement(JSContext
* cx
,
218 JS::Handle
<JSObject
*> obj
,
219 uint32_t index
, double value
,
223 * Compute the expression `id in obj`.
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.
229 * Implements: ES6 [[Has]] internal method.
231 extern JS_PUBLIC_API
bool JS_HasPropertyById(JSContext
* cx
,
232 JS::Handle
<JSObject
*> obj
,
233 JS::Handle
<jsid
> id
, bool* foundp
);
235 extern JS_PUBLIC_API
bool JS_HasProperty(JSContext
* cx
,
236 JS::Handle
<JSObject
*> obj
,
237 const char* name
, bool* foundp
);
239 extern JS_PUBLIC_API
bool JS_HasUCProperty(JSContext
* cx
,
240 JS::Handle
<JSObject
*> obj
,
241 const char16_t
* name
, size_t namelen
,
244 extern JS_PUBLIC_API
bool JS_HasElement(JSContext
* cx
,
245 JS::Handle
<JSObject
*> obj
,
246 uint32_t index
, bool* foundp
);
249 * Determine whether obj has an own property with the key `id`.
251 * Implements: ES6 7.3.11 HasOwnProperty(O, P).
253 extern JS_PUBLIC_API
bool JS_HasOwnPropertyById(JSContext
* cx
,
254 JS::Handle
<JSObject
*> obj
,
258 extern JS_PUBLIC_API
bool JS_HasOwnProperty(JSContext
* cx
,
259 JS::Handle
<JSObject
*> obj
,
260 const char* name
, bool* foundp
);
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)`.
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
271 * Implements: ES6 [[Get]] internal method.
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
);
277 extern JS_PUBLIC_API
bool JS_ForwardGetElementTo(JSContext
* cx
,
278 JS::Handle
<JSObject
*> obj
,
280 JS::Handle
<JSObject
*> receiver
,
281 JS::MutableHandleValue vp
);
284 * Get the value of the property `obj[id]`, or undefined if no such property
285 * exists. The result is stored in vp.
287 * Implements: ES6 7.3.1 Get(O, P).
289 extern JS_PUBLIC_API
bool JS_GetPropertyById(JSContext
* cx
,
290 JS::Handle
<JSObject
*> obj
,
292 JS::MutableHandleValue vp
);
294 extern JS_PUBLIC_API
bool JS_GetProperty(JSContext
* cx
,
295 JS::Handle
<JSObject
*> obj
,
297 JS::MutableHandleValue vp
);
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
);
304 extern JS_PUBLIC_API
bool JS_GetElement(JSContext
* cx
,
305 JS::Handle
<JSObject
*> obj
,
307 JS::MutableHandleValue vp
);
310 * Perform the same property assignment as `Reflect.set(obj, id, v, receiver)`.
312 * This function has a `receiver` argument that most callers don't need.
313 * Consider using JS_SetProperty instead.
315 * Implements: ES6 [[Set]] internal method.
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
);
323 * Perform the assignment `obj[id] = v`.
325 * This function performs non-strict assignment, so if the property is
326 * read-only, nothing happens and no error is thrown.
328 extern JS_PUBLIC_API
bool JS_SetPropertyById(JSContext
* cx
,
329 JS::Handle
<JSObject
*> obj
,
331 JS::Handle
<JS::Value
> v
);
333 extern JS_PUBLIC_API
bool JS_SetProperty(JSContext
* cx
,
334 JS::Handle
<JSObject
*> obj
,
336 JS::Handle
<JS::Value
> v
);
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
);
343 extern JS_PUBLIC_API
bool JS_SetElement(JSContext
* cx
,
344 JS::Handle
<JSObject
*> obj
,
346 JS::Handle
<JS::Value
> v
);
348 extern JS_PUBLIC_API
bool JS_SetElement(JSContext
* cx
,
349 JS::Handle
<JSObject
*> obj
,
351 JS::Handle
<JSObject
*> v
);
353 extern JS_PUBLIC_API
bool JS_SetElement(JSContext
* cx
,
354 JS::Handle
<JSObject
*> obj
,
356 JS::Handle
<JSString
*> v
);
358 extern JS_PUBLIC_API
bool JS_SetElement(JSContext
* cx
,
359 JS::Handle
<JSObject
*> obj
,
360 uint32_t index
, int32_t v
);
362 extern JS_PUBLIC_API
bool JS_SetElement(JSContext
* cx
,
363 JS::Handle
<JSObject
*> obj
,
364 uint32_t index
, uint32_t v
);
366 extern JS_PUBLIC_API
bool JS_SetElement(JSContext
* cx
,
367 JS::Handle
<JSObject
*> obj
,
368 uint32_t index
, double v
);
371 * Delete a property. This is the C++ equivalent of
372 * `result = Reflect.deleteProperty(obj, id)`.
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
379 * Implements: ES6 [[Delete]] internal method.
381 extern JS_PUBLIC_API
bool JS_DeletePropertyById(JSContext
* cx
,
382 JS::Handle
<JSObject
*> obj
,
384 JS::ObjectOpResult
& result
);
386 extern JS_PUBLIC_API
bool JS_DeleteProperty(JSContext
* cx
,
387 JS::Handle
<JSObject
*> obj
,
389 JS::ObjectOpResult
& result
);
391 extern JS_PUBLIC_API
bool JS_DeleteUCProperty(JSContext
* cx
,
392 JS::Handle
<JSObject
*> obj
,
393 const char16_t
* name
,
395 JS::ObjectOpResult
& result
);
397 extern JS_PUBLIC_API
bool JS_DeleteElement(JSContext
* cx
,
398 JS::Handle
<JSObject
*> obj
,
400 JS::ObjectOpResult
& result
);
403 * Delete a property, ignoring strict failures. This is the C++ equivalent of
404 * the JS `delete obj[id]` in non-strict mode code.
406 extern JS_PUBLIC_API
bool JS_DeletePropertyById(JSContext
* cx
,
407 JS::Handle
<JSObject
*> obj
,
408 JS::Handle
<jsid
> id
);
410 extern JS_PUBLIC_API
bool JS_DeleteProperty(JSContext
* cx
,
411 JS::Handle
<JSObject
*> obj
,
414 extern JS_PUBLIC_API
bool JS_DeleteElement(JSContext
* cx
,
415 JS::Handle
<JSObject
*> obj
,
419 * Get an array of the non-symbol enumerable properties of obj.
420 * This function is roughly equivalent to:
428 * This is the closest thing we currently have to the ES6 [[Enumerate]]
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>.
434 extern JS_PUBLIC_API
bool JS_Enumerate(JSContext
* cx
, JS::Handle
<JSObject
*> obj
,
435 JS::MutableHandle
<JS::IdVector
> props
);
437 /*** Other property-defining functions **************************************/
439 extern JS_PUBLIC_API JSObject
* JS_DefineObject(JSContext
* cx
,
440 JS::Handle
<JSObject
*> obj
,
442 const JSClass
* clasp
= nullptr,
445 extern JS_PUBLIC_API
bool JS_DefineProperties(JSContext
* cx
,
446 JS::Handle
<JSObject
*> obj
,
447 const JSPropertySpec
* ps
);
451 extern JS_PUBLIC_API
bool JS_AlreadyHasOwnPropertyById(
452 JSContext
* cx
, JS::Handle
<JSObject
*> obj
, JS::Handle
<jsid
> id
,
455 extern JS_PUBLIC_API
bool JS_AlreadyHasOwnProperty(JSContext
* cx
,
456 JS::Handle
<JSObject
*> obj
,
460 extern JS_PUBLIC_API
bool JS_AlreadyHasOwnUCProperty(JSContext
* cx
,
461 JS::Handle
<JSObject
*> obj
,
462 const char16_t
* name
,
466 extern JS_PUBLIC_API
bool JS_AlreadyHasOwnElement(JSContext
* cx
,
467 JS::Handle
<JSObject
*> obj
,
468 uint32_t index
, bool* foundp
);
470 extern JS_PUBLIC_API
bool JS_DefineFunctions(JSContext
* cx
,
471 JS::Handle
<JSObject
*> obj
,
472 const JSFunctionSpec
* fs
);
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
);
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
);
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
);
486 #endif /* js_PropertyAndElement_h */