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 /* Array-related operations. */
7 
8 #ifndef js_Array_h
9 #define js_Array_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/TypeDecls.h"
17 
18 namespace JS {
19 
20 class HandleValueArray;
21 
22 /**
23  * Create an Array from the current realm with the given contents.
24  */
25 extern JS_PUBLIC_API JSObject* NewArrayObject(JSContext* cx,
26                                               const HandleValueArray& contents);
27 
28 /**
29  * Create an Array from the current realm with the given length and allocate
30  * memory for all its elements.  (The elements nonetheless will not exist as
31  * properties on the returned array until values have been assigned to them.)
32  */
33 extern JS_PUBLIC_API JSObject* NewArrayObject(JSContext* cx, size_t length);
34 
35 /**
36  * Determine whether |value| is an Array object or a wrapper around one.  (An
37  * ES6 proxy whose target is an Array object, e.g.
38  * |var target = [], handler = {}; Proxy.revocable(target, handler).proxy|, is
39  * not considered to be an Array.)
40  *
41  * On success set |*isArray| accordingly and return true; on failure return
42  * false.
43  */
44 extern JS_PUBLIC_API bool IsArrayObject(JSContext* cx, Handle<Value> value,
45                                         bool* isArray);
46 
47 /**
48  * Determine whether |obj| is an Array object or a wrapper around one.  (An
49  * ES6 proxy whose target is an Array object, e.g.
50  * |var target = [], handler = {}; Proxy.revocable(target, handler).proxy|, is
51  * not considered to be an Array.)
52  *
53  * On success set |*isArray| accordingly and return true; on failure return
54  * false.
55  */
56 extern JS_PUBLIC_API bool IsArrayObject(JSContext* cx, Handle<JSObject*> obj,
57                                         bool* isArray);
58 
59 /**
60  * Store |*lengthp = ToLength(obj.length)| and return true on success, else
61  * return false.
62  *
63  * If the length does not fit in |uint32_t|, an exception is reported and false
64  * is returned.
65  *
66  * |ToLength| converts its input to an integer usable to index an
67  * array-like object.
68  *
69  * If |obj| is an Array, this overall operation is the same as getting
70  * |obj.length|.
71  */
72 extern JS_PUBLIC_API bool GetArrayLength(JSContext* cx, Handle<JSObject*> obj,
73                                          uint32_t* lengthp);
74 
75 /**
76  * Perform |obj.length = length| as if in strict mode code, with a fast path for
77  * the case where |obj| is an Array.
78  *
79  * This operation is exactly and only assigning to a "length" property.  In
80  * general, it can invoke an existing "length" setter, throw if the property is
81  * non-writable, or do anything else a property-set operation might do.
82  */
83 extern JS_PUBLIC_API bool SetArrayLength(JSContext* cx, Handle<JSObject*> obj,
84                                          uint32_t length);
85 
86 /**
87  * The answer to a successful query as to whether an object is an Array per
88  * ES6's internal |IsArray| operation (as exposed by |Array.isArray|).
89  */
90 enum class IsArrayAnswer { Array, NotArray, RevokedProxy };
91 
92 /**
93  * ES6 7.2.2.
94  *
95  * Returns false on failure, otherwise returns true and sets |*isArray|
96  * indicating whether the object passes ECMAScript's IsArray test.  This is the
97  * same test performed by |Array.isArray|.
98  *
99  * This is NOT the same as asking whether |obj| is an Array or a wrapper around
100  * one.  If |obj| is a proxy created by |Proxy.revocable()| and has been
101  * revoked, or if |obj| is a proxy whose target (at any number of hops) is a
102  * revoked proxy, this method throws a TypeError and returns false.
103  */
104 extern JS_PUBLIC_API bool IsArray(JSContext* cx, Handle<JSObject*> obj,
105                                   bool* isArray);
106 
107 /**
108  * Identical to IsArray above, but the nature of the object (if successfully
109  * determined) is communicated via |*answer|.  In particular this method
110  * returns true and sets |*answer = IsArrayAnswer::RevokedProxy| when called on
111  * a revoked proxy.
112  *
113  * Most users will want the overload above, not this one.
114  */
115 extern JS_PUBLIC_API bool IsArray(JSContext* cx, Handle<JSObject*> obj,
116                                   IsArrayAnswer* answer);
117 
118 }  // namespace JS
119 
120 #endif  // js_Array_h
121