Bug 1874684 - Part 31: Correctly reject invalid durations in some RoundDuration calls...
[gecko.git] / js / public / ValueArray.h
blob734d8aca652e9e4c325e2b074d7b2d90a90c4d20
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
22 namespace js {
23 JS_PUBLIC_API void TraceValueArray(JSTracer* trc, size_t length,
24 JS::Value* elements);
25 } // namespace js
27 namespace JS {
29 /* A fixed-size array of values, for use inside Rooted<>. */
30 template <size_t N>
31 struct ValueArray {
32 Value elements[N];
33 void trace(JSTracer* trc) { js::TraceValueArray(trc, N, elements); }
36 /** RootedValueArray roots an internal fixed-size array of Values. */
37 template <size_t N>
38 using RootedValueArray = Rooted<ValueArray<N>>;
40 /**
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 {
47 const size_t length_;
48 const Value* const elements_;
50 HandleValueArray(size_t len, const Value* elements)
51 : length_(len), elements_(elements) {}
53 public:
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()) {}
63 template <size_t N>
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]);
94 } // namespace JS
96 namespace js {
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();
104 public:
105 size_t length() const { return N; }
106 const JS::Value* begin() const { return array().elements; }
108 JS::HandleValue operator[](size_t i) const {
109 MOZ_ASSERT(i < N);
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(); }
120 public:
121 using Base::begin;
122 JS::Value* begin() { return array().elements; }
124 using Base::operator[];
125 JS::MutableHandleValue operator[](size_t i) {
126 MOZ_ASSERT(i < N);
127 return JS::MutableHandleValue::fromMarkedLocation(&array().elements[i]);
131 } // namespace js
133 #endif // js_ValueArray_h