Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
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/. */
7 #ifndef jit_Compactbuffer_h
8 #define jit_Compactbuffer_h
10 #include "jsalloc.h"
12 #include "jit/IonTypes.h"
13 #include "js/Vector.h"
15 namespace js {
16 namespace jit {
18 class CompactBufferWriter;
20 // CompactBuffers are byte streams designed for compressable integers. It has
21 // helper functions for writing bytes, fixed-size integers, and variable-sized
22 // integers. Variable sized integers are encoded in 1-5 bytes, each byte
23 // containing 7 bits of the integer and a bit which specifies whether the next
24 // byte is also part of the integer.
25 //
26 // Fixed-width integers are also available, in case the actual value will not
27 // be known until later.
29 class CompactBufferReader
30 {
31 const uint8_t *buffer_;
32 const uint8_t *end_;
34 uint32_t readVariableLength() {
35 uint32_t val = 0;
36 uint32_t shift = 0;
37 uint8_t byte;
38 while (true) {
39 JS_ASSERT(shift < 32);
40 byte = readByte();
41 val |= (uint32_t(byte) >> 1) << shift;
42 shift += 7;
43 if (!(byte & 1))
44 return val;
45 }
46 MOZ_ASSUME_UNREACHABLE("unreachable");
47 }
49 public:
50 CompactBufferReader(const uint8_t *start, const uint8_t *end)
51 : buffer_(start),
52 end_(end)
53 { }
54 inline CompactBufferReader(const CompactBufferWriter &writer);
55 uint8_t readByte() {
56 JS_ASSERT(buffer_ < end_);
57 return *buffer_++;
58 }
59 uint32_t readFixedUint32_t() {
60 uint32_t b0 = readByte();
61 uint32_t b1 = readByte();
62 uint32_t b2 = readByte();
63 uint32_t b3 = readByte();
64 return b0 | (b1 << 8) | (b2 << 16) | (b3 << 24);
65 }
66 uint16_t readFixedUint16_t() {
67 uint32_t b0 = readByte();
68 uint32_t b1 = readByte();
69 return b0 | (b1 << 8);
70 }
71 uint32_t readUnsigned() {
72 return readVariableLength();
73 }
74 int32_t readSigned() {
75 uint8_t b = readByte();
76 bool isNegative = !!(b & (1 << 0));
77 bool more = !!(b & (1 << 1));
78 int32_t result = b >> 2;
79 if (more)
80 result |= readUnsigned() << 6;
81 if (isNegative)
82 return -result;
83 return result;
84 }
86 bool more() const {
87 JS_ASSERT(buffer_ <= end_);
88 return buffer_ < end_;
89 }
91 void seek(const uint8_t *start, uint32_t offset) {
92 buffer_ = start + offset;
93 MOZ_ASSERT(start < end_);
94 MOZ_ASSERT(buffer_ < end_);
95 }
96 };
98 class CompactBufferWriter
99 {
100 js::Vector<uint8_t, 32, SystemAllocPolicy> buffer_;
101 bool enoughMemory_;
103 public:
104 CompactBufferWriter()
105 : enoughMemory_(true)
106 { }
108 // Note: writeByte() takes uint32 to catch implicit casts with a runtime
109 // assert.
110 void writeByte(uint32_t byte) {
111 JS_ASSERT(byte <= 0xFF);
112 enoughMemory_ &= buffer_.append(byte);
113 }
114 void writeUnsigned(uint32_t value) {
115 do {
116 uint8_t byte = ((value & 0x7F) << 1) | (value > 0x7F);
117 writeByte(byte);
118 value >>= 7;
119 } while (value);
120 }
121 void writeSigned(int32_t v) {
122 bool isNegative = v < 0;
123 uint32_t value = isNegative ? -v : v;
124 uint8_t byte = ((value & 0x3F) << 2) | ((value > 0x3F) << 1) | uint32_t(isNegative);
125 writeByte(byte);
127 // Write out the rest of the bytes, if needed.
128 value >>= 6;
129 if (value == 0)
130 return;
131 writeUnsigned(value);
132 }
133 void writeFixedUint32_t(uint32_t value) {
134 writeByte(value & 0xFF);
135 writeByte((value >> 8) & 0xFF);
136 writeByte((value >> 16) & 0xFF);
137 writeByte((value >> 24) & 0xFF);
138 }
139 void writeFixedUint16_t(uint16_t value) {
140 writeByte(value & 0xFF);
141 writeByte(value >> 8);
142 }
143 size_t length() const {
144 return buffer_.length();
145 }
146 uint8_t *buffer() {
147 return &buffer_[0];
148 }
149 const uint8_t *buffer() const {
150 return &buffer_[0];
151 }
152 bool oom() const {
153 return !enoughMemory_;
154 }
155 };
157 CompactBufferReader::CompactBufferReader(const CompactBufferWriter &writer)
158 : buffer_(writer.buffer()),
159 end_(writer.buffer() + writer.length())
160 {
161 }
163 } // namespace jit
164 } // namespace js
166 #endif /* jit_Compactbuffer_h */