forked from mirrors/gecko-dev
		
	 07f19511ef
			
		
	
	
		07f19511ef
		
	
	
	
	
		
			
			clang is warning that C++20 expects comparison operators to be commutative: `a == b` and `b == a` should resolve to the same comparison operator function. Warnings about the comparison of const and non-const objects can be fixed by making the comparison operator function const. Depends on D179020 Differential Revision: https://phabricator.services.mozilla.com/D179021
		
			
				
	
	
		
			167 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			167 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- 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();
 | |
| }
 | |
| 
 | |
| static inline Result<Ok, nsresult> WritePadding(PRFileDesc* fd,
 | |
|                                                 uint8_t padding) {
 | |
|   static const char paddingBytes[8] = "PADBYTE";
 | |
|   MOZ_DIAGNOSTIC_ASSERT(padding <= sizeof(paddingBytes));
 | |
| 
 | |
|   if (padding == 0) {
 | |
|     return Ok();
 | |
|   }
 | |
| 
 | |
|   if (PR_Write(fd, static_cast<const void*>(paddingBytes), padding) !=
 | |
|       padding) {
 | |
|     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_;
 | |
|   Iterator iter_;
 | |
| 
 | |
|  public:
 | |
|   explicit HashElemIter(T& hash, Matcher<ElemType>* matcher = nullptr)
 | |
|       : hash_(hash), matcher_(matcher), iter_(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_; }
 | |
| 
 | |
|     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) const {
 | |
|       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
 |