BytecodeOffset.h (3573B)
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/. */ 6 7 #ifndef frontend_BytecodeOffset_h 8 #define frontend_BytecodeOffset_h 9 10 #include "mozilla/Assertions.h" // MOZ_ASSERT 11 #include "mozilla/CheckedInt.h" // mozilla::CheckedInt 12 13 #include <compare> // std::strong_ordering 14 #include <stddef.h> // ptrdiff_t 15 16 namespace js { 17 namespace frontend { 18 19 class BytecodeOffsetDiff; 20 21 // The offset inside bytecode. 22 class BytecodeOffset { 23 private: 24 static const ptrdiff_t INVALID_OFFSET = -1; 25 26 ptrdiff_t value_ = 0; 27 28 struct Invalid {}; 29 explicit constexpr BytecodeOffset(Invalid) : value_(INVALID_OFFSET) {} 30 31 public: 32 constexpr BytecodeOffset() = default; 33 34 explicit BytecodeOffset(ptrdiff_t value) : value_(value) { 35 MOZ_ASSERT(value >= 0); 36 } 37 38 static constexpr BytecodeOffset invalidOffset() { 39 return BytecodeOffset(Invalid()); 40 } 41 42 constexpr bool operator==(const BytecodeOffset& rhs) const = default; 43 44 inline BytecodeOffsetDiff operator-(const BytecodeOffset& rhs) const; 45 inline BytecodeOffset operator+(const BytecodeOffsetDiff& diff) const; 46 47 inline BytecodeOffset& operator+=(const BytecodeOffsetDiff& diff); 48 inline BytecodeOffset& operator-=(const BytecodeOffsetDiff& diff); 49 50 auto operator<=>(const BytecodeOffset& rhs) const { 51 MOZ_ASSERT(valid()); 52 MOZ_ASSERT(rhs.valid()); 53 return value_ <=> rhs.value_; 54 } 55 56 ptrdiff_t value() const { return value_; } 57 uint32_t toUint32() const { 58 MOZ_ASSERT(size_t(uint32_t(value_)) == size_t(value_)); 59 return uint32_t(value_); 60 } 61 62 bool valid() const { return value_ != INVALID_OFFSET; } 63 }; 64 65 class BytecodeOffsetDiff { 66 private: 67 friend class BytecodeOffset; 68 69 ptrdiff_t value_ = 0; 70 71 public: 72 constexpr BytecodeOffsetDiff() = default; 73 74 explicit constexpr BytecodeOffsetDiff(ptrdiff_t value_) : value_(value_) {} 75 76 constexpr bool operator==(const BytecodeOffsetDiff& rhs) const = default; 77 78 BytecodeOffsetDiff operator+(const BytecodeOffsetDiff& rhs) const { 79 mozilla::CheckedInt<ptrdiff_t> result = value_; 80 result += rhs.value_; 81 return BytecodeOffsetDiff(result.value()); 82 } 83 84 ptrdiff_t value() const { return value_; } 85 uint32_t toUint32() const { 86 MOZ_ASSERT(size_t(uint32_t(value_)) == size_t(value_)); 87 return uint32_t(value_); 88 } 89 }; 90 91 inline BytecodeOffsetDiff BytecodeOffset::operator-( 92 const BytecodeOffset& rhs) const { 93 MOZ_ASSERT(valid()); 94 MOZ_ASSERT(rhs.valid()); 95 mozilla::CheckedInt<ptrdiff_t> result = value_; 96 result -= rhs.value_; 97 return BytecodeOffsetDiff(result.value()); 98 } 99 100 inline BytecodeOffset BytecodeOffset::operator+( 101 const BytecodeOffsetDiff& diff) const { 102 MOZ_ASSERT(valid()); 103 mozilla::CheckedInt<ptrdiff_t> result = value_; 104 result += diff.value_; 105 return BytecodeOffset(result.value()); 106 } 107 108 inline BytecodeOffset& BytecodeOffset::operator+=( 109 const BytecodeOffsetDiff& diff) { 110 MOZ_ASSERT(valid()); 111 mozilla::CheckedInt<ptrdiff_t> result = value_; 112 result += diff.value_; 113 value_ = result.value(); 114 return *this; 115 } 116 117 inline BytecodeOffset& BytecodeOffset::operator-=( 118 const BytecodeOffsetDiff& diff) { 119 MOZ_ASSERT(valid()); 120 mozilla::CheckedInt<ptrdiff_t> result = value_; 121 result -= diff.value_; 122 value_ = result.value(); 123 return *this; 124 } 125 126 } /* namespace frontend */ 127 } /* namespace js */ 128 129 #endif /* frontend_BytecodeOffset_h */