DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (b6d82b1a6b02)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: set ts=8 sts=2 et sw=2 tw=80:
 * 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 frontend_BytecodeOffset_h
#define frontend_BytecodeOffset_h

#include "mozilla/Assertions.h"  // MOZ_ASSERT
#include "mozilla/CheckedInt.h"  // mozilla::CheckedInt

#include <stddef.h>  // ptrdiff_t

namespace js {
namespace frontend {

class BytecodeOffsetDiff;

// The offset inside bytecode.
class BytecodeOffset {
 private:
  static const ptrdiff_t INVALID_OFFSET = -1;

  ptrdiff_t value_ = 0;

  struct Invalid {};
  explicit constexpr BytecodeOffset(Invalid) : value_(INVALID_OFFSET) {}

 public:
  constexpr BytecodeOffset() = default;

  explicit BytecodeOffset(ptrdiff_t value) : value_(value) {
    MOZ_ASSERT(value >= 0);
  }

  static constexpr BytecodeOffset invalidOffset() {
    return BytecodeOffset(Invalid());
  }

  bool operator==(const BytecodeOffset& rhs) const {
    return value_ == rhs.value_;
  }

  bool operator!=(const BytecodeOffset& rhs) const { return !(*this == rhs); }

  inline BytecodeOffsetDiff operator-(const BytecodeOffset& rhs) const;
  inline BytecodeOffset operator+(const BytecodeOffsetDiff& diff) const;

  inline BytecodeOffset& operator+=(const BytecodeOffsetDiff& diff);
  inline BytecodeOffset& operator-=(const BytecodeOffsetDiff& diff);

  bool operator<(const BytecodeOffset& rhs) const {
    MOZ_ASSERT(valid());
    MOZ_ASSERT(rhs.valid());
    return value_ < rhs.value_;
  }
  bool operator<=(const BytecodeOffset& rhs) const {
    MOZ_ASSERT(valid());
    MOZ_ASSERT(rhs.valid());
    return value_ <= rhs.value_;
  }
  bool operator>(const BytecodeOffset& rhs) const {
    MOZ_ASSERT(valid());
    MOZ_ASSERT(rhs.valid());
    return value_ > rhs.value_;
  }
  bool operator>=(const BytecodeOffset& rhs) const {
    MOZ_ASSERT(valid());
    MOZ_ASSERT(rhs.valid());
    return value_ >= rhs.value_;
  }

  ptrdiff_t value() const { return value_; }
  uint32_t toUint32() const {
    MOZ_ASSERT(size_t(uint32_t(value_)) == size_t(value_));
    return uint32_t(value_);
  }

  bool valid() const { return value_ != INVALID_OFFSET; }
};

class BytecodeOffsetDiff {
 private:
  friend class BytecodeOffset;

  ptrdiff_t value_ = 0;

 public:
  constexpr BytecodeOffsetDiff() = default;

  explicit constexpr BytecodeOffsetDiff(ptrdiff_t value_) : value_(value_) {}

  bool operator==(const BytecodeOffsetDiff& rhs) const {
    return value_ == rhs.value_;
  }

  bool operator!=(const BytecodeOffsetDiff& rhs) const {
    return !(*this == rhs);
  }

  BytecodeOffsetDiff operator+(const BytecodeOffsetDiff& rhs) const {
    mozilla::CheckedInt<ptrdiff_t> result = value_;
    result += rhs.value_;
    return BytecodeOffsetDiff(result.value());
  }

  ptrdiff_t value() const { return value_; }
  uint32_t toUint32() const {
    MOZ_ASSERT(size_t(uint32_t(value_)) == size_t(value_));
    return uint32_t(value_);
  }
};

inline BytecodeOffsetDiff BytecodeOffset::operator-(
    const BytecodeOffset& rhs) const {
  MOZ_ASSERT(valid());
  MOZ_ASSERT(rhs.valid());
  mozilla::CheckedInt<ptrdiff_t> result = value_;
  result -= rhs.value_;
  return BytecodeOffsetDiff(result.value());
}

inline BytecodeOffset BytecodeOffset::operator+(
    const BytecodeOffsetDiff& diff) const {
  MOZ_ASSERT(valid());
  mozilla::CheckedInt<ptrdiff_t> result = value_;
  result += diff.value_;
  return BytecodeOffset(result.value());
}

inline BytecodeOffset& BytecodeOffset::operator+=(
    const BytecodeOffsetDiff& diff) {
  MOZ_ASSERT(valid());
  mozilla::CheckedInt<ptrdiff_t> result = value_;
  result += diff.value_;
  value_ = result.value();
  return *this;
}

inline BytecodeOffset& BytecodeOffset::operator-=(
    const BytecodeOffsetDiff& diff) {
  MOZ_ASSERT(valid());
  mozilla::CheckedInt<ptrdiff_t> result = value_;
  result -= diff.value_;
  value_ = result.value();
  return *this;
}

} /* namespace frontend */
} /* namespace js */

#endif /* frontend_BytecodeOffset_h */