1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
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/. */
7 /** GC-safe representations of consecutive JS::Value in memory. */
9 #ifndef js_ValueArray_h
10 #define js_ValueArray_h
12 #include "mozilla/Assertions.h" // MOZ_ASSERT
13 #include "mozilla/Attributes.h" // MOZ_IMPLICIT, MOZ_RAII
15 #include <stdint.h> // size_t
17 #include "js/CallArgs.h" // JS::CallArgs
18 #include "js/GCVector.h" // JS::RootedVector
19 #include "js/RootingAPI.h" // JS::AutoGCRooter, JS::{,Mutable}Handle
20 #include "js/Value.h" // JS::Value
23 JS_PUBLIC_API
void TraceValueArray(JSTracer
* trc
, size_t length
,
29 /* A fixed-size array of values, for use inside Rooted<>. */
33 void trace(JSTracer
* trc
) { js::TraceValueArray(trc
, N
, elements
); }
36 /** RootedValueArray roots an internal fixed-size array of Values. */
38 using RootedValueArray
= Rooted
<ValueArray
<N
>>;
41 * A generic handle to an array of rooted values.
43 * The rooted array refernced can take several forms, therfore this is not the
44 * same as Handle<js::ValueArray>.
46 class HandleValueArray
{
48 const Value
* const elements_
;
50 HandleValueArray(size_t len
, const Value
* elements
)
51 : length_(len
), elements_(elements
) {}
54 explicit HandleValueArray(Handle
<Value
> value
)
55 : length_(1), elements_(value
.address()) {}
57 MOZ_IMPLICIT
HandleValueArray(const RootedVector
<Value
>& values
)
58 : length_(values
.length()), elements_(values
.begin()) {}
60 MOZ_IMPLICIT
HandleValueArray(const PersistentRootedVector
<Value
>& values
)
61 : length_(values
.length()), elements_(values
.begin()) {}
64 MOZ_IMPLICIT
HandleValueArray(const RootedValueArray
<N
>& values
)
65 : length_(N
), elements_(values
.begin()) {}
67 /** CallArgs must already be rooted somewhere up the stack. */
68 MOZ_IMPLICIT
HandleValueArray(const JS::CallArgs
& args
)
69 : length_(args
.length()), elements_(args
.array()) {}
71 /** Use with care! Only call this if the data is guaranteed to be marked. */
72 static HandleValueArray
fromMarkedLocation(size_t len
,
73 const Value
* elements
) {
74 return HandleValueArray(len
, elements
);
77 static HandleValueArray
subarray(const HandleValueArray
& values
,
78 size_t startIndex
, size_t len
) {
79 MOZ_ASSERT(startIndex
+ len
<= values
.length());
80 return HandleValueArray(len
, values
.begin() + startIndex
);
83 static HandleValueArray
empty() { return HandleValueArray(0, nullptr); }
85 size_t length() const { return length_
; }
86 const Value
* begin() const { return elements_
; }
88 Handle
<Value
> operator[](size_t i
) const {
89 MOZ_ASSERT(i
< length_
);
90 return Handle
<Value
>::fromMarkedLocation(&elements_
[i
]);
98 template <size_t N
, typename Container
>
99 class WrappedPtrOperations
<JS::ValueArray
<N
>, Container
> {
100 const JS::ValueArray
<N
>& array() const {
101 return static_cast<const Container
*>(this)->get();
105 size_t length() const { return N
; }
106 const JS::Value
* begin() const { return array().elements
; }
108 JS::HandleValue
operator[](size_t i
) const {
110 return JS::HandleValue::fromMarkedLocation(&array().elements
[i
]);
114 template <size_t N
, typename Container
>
115 class MutableWrappedPtrOperations
<JS::ValueArray
<N
>, Container
>
116 : public WrappedPtrOperations
<JS::ValueArray
<N
>, Container
> {
117 using Base
= WrappedPtrOperations
<JS::ValueArray
<N
>, Container
>;
118 JS::ValueArray
<N
>& array() { return static_cast<Container
*>(this)->get(); }
122 JS::Value
* begin() { return array().elements
; }
124 using Base::operator[];
125 JS::MutableHandleValue
operator[](size_t i
) {
127 return JS::MutableHandleValue::fromMarkedLocation(&array().elements
[i
]);
133 #endif // js_ValueArray_h