summaryrefslogtreecommitdiffstats
path: root/js/xpconnect/loader/ScriptPreloader-inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/xpconnect/loader/ScriptPreloader-inl.h')
-rw-r--r--js/xpconnect/loader/ScriptPreloader-inl.h153
1 files changed, 153 insertions, 0 deletions
diff --git a/js/xpconnect/loader/ScriptPreloader-inl.h b/js/xpconnect/loader/ScriptPreloader-inl.h
new file mode 100644
index 0000000000..86422ad084
--- /dev/null
+++ b/js/xpconnect/loader/ScriptPreloader-inl.h
@@ -0,0 +1,153 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef ScriptPreloader_inl_h
+#define ScriptPreloader_inl_h
+
+#include "mozilla/Attributes.h"
+#include "mozilla/Assertions.h"
+#include "mozilla/CheckedInt.h"
+#include "mozilla/EndianUtils.h"
+#include "mozilla/EnumSet.h"
+#include "mozilla/Range.h"
+#include "mozilla/ResultExtensions.h"
+#include "mozilla/Unused.h"
+#include "mozilla/dom/ScriptSettings.h"
+#include "nsString.h"
+#include "nsTArray.h"
+
+#include <prio.h>
+
+namespace mozilla {
+
+namespace loader {
+
+using mozilla::dom::AutoJSAPI;
+
+static inline Result<Ok, nsresult> Write(PRFileDesc* fd, const void* data,
+ int32_t len) {
+ if (PR_Write(fd, data, len) != len) {
+ return Err(NS_ERROR_FAILURE);
+ }
+ return Ok();
+}
+
+struct MOZ_RAII AutoSafeJSAPI : public AutoJSAPI {
+ AutoSafeJSAPI() { Init(); }
+};
+
+template <typename T>
+struct Matcher;
+
+// Wraps the iterator for a nsTHashTable so that it may be used as a range
+// iterator. Each iterator result acts as a smart pointer to the hash element,
+// and has a Remove() method which will remove the element from the hash.
+//
+// It also accepts an optional Matcher instance against which to filter the
+// elements which should be iterated over.
+//
+// Example:
+//
+// for (auto& elem : HashElemIter<HashType>(hash)) {
+// if (elem->IsDead()) {
+// elem.Remove();
+// }
+// }
+template <typename T>
+class HashElemIter {
+ using Iterator = typename T::Iterator;
+ using ElemType = typename T::UserDataType;
+
+ T& hash_;
+ Matcher<ElemType>* matcher_;
+ Maybe<Iterator> iter_;
+
+ public:
+ explicit HashElemIter(T& hash, Matcher<ElemType>* matcher = nullptr)
+ : hash_(hash), matcher_(matcher) {
+ iter_.emplace(std::move(hash.Iter()));
+ }
+
+ class Elem {
+ friend class HashElemIter<T>;
+
+ HashElemIter<T>& iter_;
+ bool done_;
+
+ Elem(HashElemIter& iter, bool done) : iter_(iter), done_(done) {
+ skipNonMatching();
+ }
+
+ Iterator& iter() { return iter_.iter_.ref(); }
+
+ void skipNonMatching() {
+ if (iter_.matcher_) {
+ while (!done_ && !iter_.matcher_->Matches(get())) {
+ iter().Next();
+ done_ = iter().Done();
+ }
+ }
+ }
+
+ public:
+ Elem& operator*() { return *this; }
+
+ ElemType get() {
+ if (done_) {
+ return nullptr;
+ }
+ return iter().UserData();
+ }
+
+ const ElemType get() const { return const_cast<Elem*>(this)->get(); }
+
+ ElemType operator->() { return get(); }
+
+ const ElemType operator->() const { return get(); }
+
+ operator ElemType() { return get(); }
+
+ void Remove() { iter().Remove(); }
+
+ Elem& operator++() {
+ MOZ_ASSERT(!done_);
+
+ iter().Next();
+ done_ = iter().Done();
+
+ skipNonMatching();
+ return *this;
+ }
+
+ bool operator!=(Elem& other) {
+ return done_ != other.done_ || this->get() != other.get();
+ }
+ };
+
+ Elem begin() { return Elem(*this, iter_->Done()); }
+
+ Elem end() { return Elem(*this, true); }
+};
+
+template <typename T>
+HashElemIter<T> IterHash(T& hash,
+ Matcher<typename T::UserDataType>* matcher = nullptr) {
+ return HashElemIter<T>(hash, matcher);
+}
+
+template <typename T, typename F>
+bool Find(T&& iter, F&& match) {
+ for (auto& elem : iter) {
+ if (match(elem)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+}; // namespace loader
+}; // namespace mozilla
+
+#endif // ScriptPreloader_inl_h