[NFC][sanitizer] Iterator adaptors for Leb128 encoding
It's similar to back_insert_iterator
Needed for D114924
Reviewed By: morehouse, kstoimenov
Differential Revision: https://reviews.llvm.org/D114980
GitOrigin-RevId: 5f1d1854eb1450d352663ee732235893c5782237
diff --git a/lib/sanitizer_common/sanitizer_stack_store.cpp b/lib/sanitizer_common/sanitizer_stack_store.cpp
index d371a4f..416e3b8 100644
--- a/lib/sanitizer_common/sanitizer_stack_store.cpp
+++ b/lib/sanitizer_common/sanitizer_stack_store.cpp
@@ -130,26 +130,76 @@
return Create();
}
+class SLeb128Encoder {
+ public:
+ SLeb128Encoder(u8 *begin, u8 *end) : begin(begin), end(end) {}
+
+ bool operator==(const SLeb128Encoder &other) const {
+ return begin == other.begin;
+ }
+
+ bool operator!=(const SLeb128Encoder &other) const {
+ return begin != other.begin;
+ }
+
+ SLeb128Encoder &operator=(uptr v) {
+ sptr diff = v - previous;
+ begin = EncodeSLEB128(diff, begin, end);
+ previous = v;
+ return *this;
+ }
+ SLeb128Encoder &operator*() { return *this; }
+ SLeb128Encoder &operator++() { return *this; }
+
+ u8 *base() const { return begin; }
+
+ private:
+ u8 *begin;
+ u8 *end;
+ uptr previous = 0;
+};
+
+class SLeb128Decoder {
+ public:
+ SLeb128Decoder(const u8 *begin, const u8 *end) : begin(begin), end(end) {}
+
+ bool operator==(const SLeb128Decoder &other) const {
+ return begin == other.begin;
+ }
+
+ bool operator!=(const SLeb128Decoder &other) const {
+ return begin != other.begin;
+ }
+
+ uptr operator*() {
+ sptr diff;
+ begin = DecodeSLEB128(begin, end, &diff);
+ previous += diff;
+ return previous;
+ }
+ SLeb128Decoder &operator++() { return *this; }
+
+ SLeb128Decoder operator++(int) { return *this; }
+
+ private:
+ const u8 *begin;
+ const u8 *end;
+ uptr previous = 0;
+};
+
static u8 *CompressDelta(const uptr *from, const uptr *from_end, u8 *to,
u8 *to_end) {
- uptr prev = 0;
- for (; from < from_end; ++from) {
- sptr diff = *from - prev;
- to = EncodeSLEB128(diff, to, to_end);
- prev += diff;
- }
- return to;
+ SLeb128Encoder encoder(to, to_end);
+ for (; from != from_end; ++from, ++encoder) *encoder = *from;
+ return encoder.base();
}
static uptr *UncompressDelta(const u8 *from, const u8 *from_end, uptr *to,
uptr *to_end) {
- uptr prev = 0;
- for (; to < to_end; ++to) {
- sptr diff;
- from = DecodeSLEB128<sptr>(from, from_end, &diff);
- prev += diff;
- *to = prev;
- }
+ SLeb128Decoder decoder(from, from_end);
+ SLeb128Decoder end(from_end, from_end);
+ for (; decoder != end; ++to, ++decoder) *to = *decoder;
+ CHECK_EQ(to, to_end);
return to;
}