mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
Fix undefined behavior code (#464)
* Fix UB in arithmetics * Fix misaligned allocations in validator sessions * Fix integer overflow in bigint.hpp * Fix potential UB Co-authored-by: SpyCheese <mikle98@yandex.ru>
This commit is contained in:
parent
440d06962a
commit
9c6787d2ff
8 changed files with 86 additions and 71 deletions
|
@ -982,7 +982,7 @@ struct ShardIdent::Record {
|
|||
int shard_pfx_bits;
|
||||
int workchain_id;
|
||||
unsigned long long shard_prefix;
|
||||
Record() : shard_pfx_bits(-1) {
|
||||
Record() : shard_pfx_bits(-1), workchain_id(ton::workchainInvalid), shard_prefix(0) {
|
||||
}
|
||||
Record(int _pfxlen, int _wcid, unsigned long long _pfx)
|
||||
: shard_pfx_bits(_pfxlen), workchain_id(_wcid), shard_prefix(_pfx) {
|
||||
|
|
|
@ -176,6 +176,7 @@ class AnyIntView {
|
|||
public:
|
||||
enum { word_bits = Tr::word_bits, word_shift = Tr::word_shift };
|
||||
typedef typename Tr::word_t word_t;
|
||||
typedef typename Tr::uword_t uword_t;
|
||||
int& n_;
|
||||
PropagateConstSpan<word_t> digits;
|
||||
|
||||
|
@ -320,7 +321,7 @@ class BigIntG {
|
|||
digits[0] = x;
|
||||
normalize_bool();
|
||||
} else {
|
||||
digits[0] = ((x + Tr::Half) & (Tr::Base - 1)) - Tr::Half;
|
||||
digits[0] = ((x ^ Tr::Half) & (Tr::Base - 1)) - Tr::Half;
|
||||
digits[n++] = (x >> Tr::word_shift) + (digits[0] < 0);
|
||||
}
|
||||
}
|
||||
|
@ -675,7 +676,7 @@ class BigIntG {
|
|||
return n > 0 && !(digits[0] & 1);
|
||||
}
|
||||
word_t mod_pow2_short(int pow) const {
|
||||
return n > 0 ? digits[0] & ((1 << pow) - 1) : 0;
|
||||
return n > 0 ? digits[0] & ((1ULL << pow) - 1) : 0;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -764,7 +765,7 @@ bool AnyIntView<Tr>::add_pow2_any(int exponent, int factor) {
|
|||
while (size() <= k) {
|
||||
digits[inc_size()] = 0;
|
||||
}
|
||||
digits[k] += ((word_t)factor << dm.rem);
|
||||
digits[k] += factor * ((word_t)1 << dm.rem);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -969,7 +970,7 @@ bool AnyIntView<Tr>::add_mul_any(const AnyIntView<Tr>& yp, const AnyIntView<Tr>&
|
|||
if (hi && hi != -1) {
|
||||
return invalidate_bool();
|
||||
}
|
||||
digits[size() - 1] += (hi << word_shift);
|
||||
digits[size() - 1] += ((uword_t)hi << word_shift);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -1014,7 +1015,7 @@ int AnyIntView<Tr>::sgn_un_any() const {
|
|||
}
|
||||
int i = size() - 2;
|
||||
do {
|
||||
v <<= word_shift;
|
||||
v *= Tr::Base;
|
||||
word_t w = digits[i];
|
||||
if (w >= -v + Tr::MaxDenorm) {
|
||||
return 1;
|
||||
|
@ -1059,7 +1060,7 @@ typename Tr::word_t AnyIntView<Tr>::to_long_any() const {
|
|||
} else if (size() == 1) {
|
||||
return digits[0];
|
||||
} else {
|
||||
word_t v = digits[0] + (digits[1] << word_shift); // approximation mod 2^64
|
||||
word_t v = (uword_t)digits[0] + ((uword_t)digits[1] << word_shift); // approximation mod 2^64
|
||||
word_t w = (v & (Tr::Base - 1)) - digits[0];
|
||||
w >>= word_shift;
|
||||
w += (v >> word_shift); // excess of approximation divided by Tr::Base
|
||||
|
@ -1120,7 +1121,7 @@ int AnyIntView<Tr>::cmp_un_any(const AnyIntView<Tr>& yp) const {
|
|||
return -1;
|
||||
}
|
||||
while (xn > yn) {
|
||||
v <<= word_shift;
|
||||
v *= Tr::Base;
|
||||
word_t w = T::eval(digits[--xn]);
|
||||
if (w >= -v + Tr::MaxDenorm) {
|
||||
return 1;
|
||||
|
@ -1137,7 +1138,7 @@ int AnyIntView<Tr>::cmp_un_any(const AnyIntView<Tr>& yp) const {
|
|||
return -1;
|
||||
}
|
||||
while (yn > xn) {
|
||||
v <<= word_shift;
|
||||
v *= Tr::Base;
|
||||
word_t w = yp.digits[--yn];
|
||||
if (w <= v - Tr::MaxDenorm) {
|
||||
return 1;
|
||||
|
@ -1150,7 +1151,7 @@ int AnyIntView<Tr>::cmp_un_any(const AnyIntView<Tr>& yp) const {
|
|||
v = 0;
|
||||
}
|
||||
while (--xn >= 0) {
|
||||
v <<= word_shift;
|
||||
v *= Tr::Base;
|
||||
word_t w = T::eval(digits[xn]) - yp.digits[xn];
|
||||
if (w >= -v + Tr::MaxDenorm) {
|
||||
return 1;
|
||||
|
@ -1197,7 +1198,7 @@ int AnyIntView<Tr>::divmod_tiny_any(int y) {
|
|||
}
|
||||
int rem = 0;
|
||||
for (int i = size() - 1; i >= 0; i--) {
|
||||
auto divmod = std::div(digits[i] + ((word_t)rem << word_shift), (word_t)y);
|
||||
auto divmod = std::div(digits[i] + ((uword_t)rem << word_shift), (word_t)y);
|
||||
digits[i] = divmod.quot;
|
||||
rem = (int)divmod.rem;
|
||||
if ((rem ^ y) < 0 && rem) {
|
||||
|
@ -1267,7 +1268,7 @@ bool AnyIntView<Tr>::mul_add_short_any(word_t y, word_t z) {
|
|||
z += (digits[size() - 1] >> word_shift);
|
||||
digits[size() - 1] &= Tr::Base - 1;
|
||||
if (!z || z == -1) {
|
||||
digits[size() - 1] += (z << word_shift);
|
||||
digits[size() - 1] += ((uword_t)z << word_shift);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -1338,7 +1339,7 @@ bool AnyIntView<Tr>::mod_div_any(const AnyIntView<Tr>& yp, AnyIntView<Tr>& quot,
|
|||
while (--i >= 0) {
|
||||
Tr::sub_mul(&digits[k + i + 1], &digits[k + i], q, yp.digits[i]);
|
||||
}
|
||||
digits[size() - 1] += (hi << word_shift);
|
||||
digits[size() - 1] += ((uword_t)hi << word_shift);
|
||||
}
|
||||
} else {
|
||||
quot.set_size(1);
|
||||
|
@ -1351,7 +1352,7 @@ bool AnyIntView<Tr>::mod_div_any(const AnyIntView<Tr>& yp, AnyIntView<Tr>& quot,
|
|||
Tr::sub_mul(&digits[k + i + 1], &digits[k + i], q, yp.digits[i]);
|
||||
}
|
||||
dec_size();
|
||||
digits[size() - 1] += (digits[size()] << word_shift);
|
||||
digits[size() - 1] += ((uword_t)digits[size()] << word_shift);
|
||||
}
|
||||
if (size() >= yp.size() - 1) {
|
||||
assert(size() <= yp.size());
|
||||
|
@ -1455,7 +1456,7 @@ bool AnyIntView<Tr>::mod_pow2_any(int exponent) {
|
|||
dec_size();
|
||||
q += word_shift;
|
||||
}
|
||||
word_t pow = ((word_t)1 << q);
|
||||
uword_t pow = ((uword_t)1 << q);
|
||||
word_t v = digits[size() - 1] & (pow - 1);
|
||||
if (!v) {
|
||||
int k = size() - 1;
|
||||
|
@ -1485,7 +1486,7 @@ bool AnyIntView<Tr>::mod_pow2_any(int exponent) {
|
|||
return true;
|
||||
} else if (v >= Tr::Half && size() < max_size()) {
|
||||
word_t w = (((v >> (word_shift - 1)) + 1) >> 1);
|
||||
digits[size() - 1] = v - (w << word_shift);
|
||||
digits[size() - 1] = (uword_t)v - ((uword_t)w << word_shift);
|
||||
digits[inc_size()] = w;
|
||||
return true;
|
||||
} else {
|
||||
|
@ -1623,7 +1624,7 @@ bool AnyIntView<Tr>::lshift_any(int exponent) {
|
|||
} else if (v != -1) {
|
||||
return invalidate_bool();
|
||||
} else {
|
||||
digits[size() - 1] += (v << word_shift);
|
||||
digits[size() - 1] += ((uword_t)v << word_shift);
|
||||
}
|
||||
}
|
||||
if (q) {
|
||||
|
@ -1750,7 +1751,7 @@ int AnyIntView<Tr>::bit_size_any(bool sgnd) const {
|
|||
int k = size() - 1;
|
||||
word_t q = digits[k];
|
||||
if (k > 0 && q < Tr::MaxDenorm / 2) {
|
||||
q <<= word_shift;
|
||||
q *= Tr::Base;
|
||||
q += digits[--k];
|
||||
}
|
||||
if (!k) {
|
||||
|
@ -1766,7 +1767,7 @@ int AnyIntView<Tr>::bit_size_any(bool sgnd) const {
|
|||
} else if (q <= -Tr::MaxDenorm / 2) {
|
||||
return s;
|
||||
}
|
||||
q <<= word_shift;
|
||||
q *= Tr::Base;
|
||||
q += digits[--k];
|
||||
}
|
||||
return q >= 0 ? s + 1 : s;
|
||||
|
@ -1774,7 +1775,7 @@ int AnyIntView<Tr>::bit_size_any(bool sgnd) const {
|
|||
int k = size() - 1;
|
||||
word_t q = digits[k];
|
||||
if (k > 0 && q > -Tr::MaxDenorm / 2) {
|
||||
q <<= word_shift;
|
||||
q *= Tr::Base;
|
||||
q += digits[--k];
|
||||
}
|
||||
if (!k) {
|
||||
|
@ -1790,7 +1791,7 @@ int AnyIntView<Tr>::bit_size_any(bool sgnd) const {
|
|||
} else if (q <= -Tr::MaxDenorm / 2) {
|
||||
return s + 1;
|
||||
}
|
||||
q <<= word_shift;
|
||||
q *= Tr::Base;
|
||||
q += digits[--k];
|
||||
}
|
||||
return q >= 0 ? s : s + 1;
|
||||
|
@ -1817,7 +1818,7 @@ bool AnyIntView<Tr>::export_bytes_any(unsigned char* buff, std::size_t buff_size
|
|||
for (int i = 0; i < size(); i++) {
|
||||
if ((word_shift & 7) && word_shift + 8 >= word_bits && k >= word_bits - word_shift - 1) {
|
||||
int k1 = 8 - k;
|
||||
v += (digits[i] << k) & 0xff;
|
||||
v += ((uword_t)digits[i] << k) & 0xff;
|
||||
if (ptr > buff) {
|
||||
*--ptr = (unsigned char)(v & 0xff);
|
||||
} else if ((unsigned char)(v & 0xff) != s) {
|
||||
|
@ -1827,7 +1828,7 @@ bool AnyIntView<Tr>::export_bytes_any(unsigned char* buff, std::size_t buff_size
|
|||
v += (digits[i] >> k1);
|
||||
k += word_shift - 8;
|
||||
} else {
|
||||
v += (digits[i] << k);
|
||||
v += ((uword_t)digits[i] << k);
|
||||
k += word_shift;
|
||||
}
|
||||
while (k >= 8) {
|
||||
|
@ -1868,7 +1869,7 @@ bool AnyIntView<Tr>::export_bytes_lsb_any(unsigned char* buff, std::size_t buff_
|
|||
for (int i = 0; i < size(); i++) {
|
||||
if ((word_shift & 7) && word_shift + 8 >= word_bits && k >= word_bits - word_shift - 1) {
|
||||
int k1 = 8 - k;
|
||||
v += (digits[i] << k) & 0xff;
|
||||
v += ((uword_t)digits[i] << k) & 0xff;
|
||||
if (buff < end) {
|
||||
*buff++ = (unsigned char)(v & 0xff);
|
||||
} else if ((unsigned char)(v & 0xff) != s) {
|
||||
|
@ -1878,7 +1879,7 @@ bool AnyIntView<Tr>::export_bytes_lsb_any(unsigned char* buff, std::size_t buff_
|
|||
v += (digits[i] >> k1);
|
||||
k += word_shift - 8;
|
||||
} else {
|
||||
v += (digits[i] << k);
|
||||
v += ((uword_t)digits[i] << k);
|
||||
k += word_shift;
|
||||
}
|
||||
while (k >= 8) {
|
||||
|
@ -1922,7 +1923,7 @@ bool AnyIntView<Tr>::export_bits_any(unsigned char* buff, int offs, unsigned bit
|
|||
return false;
|
||||
}
|
||||
}
|
||||
td::bitstring::bits_store_long_top(buff, offs, v << (64 - bits), bits);
|
||||
td::bitstring::bits_store_long_top(buff, offs, (unsigned long long)v << (64 - bits), bits);
|
||||
} else {
|
||||
if (!sgnd && v < 0) {
|
||||
return false;
|
||||
|
@ -1945,7 +1946,7 @@ bool AnyIntView<Tr>::export_bits_any(unsigned char* buff, int offs, unsigned bit
|
|||
for (int i = 0; i < size(); i++) {
|
||||
if (word_shift + 8 >= word_bits && k >= word_bits - word_shift - 1) {
|
||||
int k1 = 8 - k;
|
||||
v += (digits[i] << k) & 0xff;
|
||||
v += ((uword_t)digits[i] << k) & 0xff;
|
||||
if (ptr > buff) {
|
||||
if (--ptr > buff) {
|
||||
*ptr = (unsigned char)(v & 0xff);
|
||||
|
@ -1963,7 +1964,7 @@ bool AnyIntView<Tr>::export_bits_any(unsigned char* buff, int offs, unsigned bit
|
|||
v += (digits[i] >> k1);
|
||||
k += word_shift - 8;
|
||||
} else {
|
||||
v += (digits[i] << k);
|
||||
v += ((uword_t)digits[i] << k);
|
||||
k += word_shift;
|
||||
}
|
||||
while (k >= 8) {
|
||||
|
@ -2028,7 +2029,7 @@ bool AnyIntView<Tr>::import_bytes_any(const unsigned char* buff, std::size_t buf
|
|||
return invalidate_bool();
|
||||
}
|
||||
}
|
||||
v |= (((word_t) * --ptr) << k);
|
||||
v |= (((uword_t) * --ptr) << k);
|
||||
k += 8;
|
||||
}
|
||||
if (s) {
|
||||
|
@ -2043,7 +2044,9 @@ bool AnyIntView<Tr>::import_bits_any(const unsigned char* buff, int offs, unsign
|
|||
if (bits < word_shift) {
|
||||
set_size(1);
|
||||
unsigned long long val = td::bitstring::bits_load_long_top(buff, offs, bits);
|
||||
if (sgnd) {
|
||||
if (bits == 0) {
|
||||
digits[0] = 0;
|
||||
} else if (sgnd) {
|
||||
digits[0] = ((long long)val >> (64 - bits));
|
||||
} else {
|
||||
digits[0] = (val >> (64 - bits));
|
||||
|
|
|
@ -191,7 +191,7 @@ void bits_memcpy(unsigned char* to, int to_offs, const unsigned char* from, int
|
|||
*to++ = (unsigned char)(acc >> b);
|
||||
}
|
||||
if (b > 0) {
|
||||
*to = (unsigned char)((*to & (0xff >> b)) | ((int)acc << (8 - b)));
|
||||
*to = (unsigned char)((*to & (0xff >> b)) | ((unsigned)acc << (8 - b)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -301,7 +301,7 @@ std::size_t bits_memscan(const unsigned char* ptr, int offs, std::size_t bit_cou
|
|||
ptr++;
|
||||
}
|
||||
while (rem >= 8 && !td::is_aligned_pointer<8>(ptr)) {
|
||||
v = ((*ptr++ ^ xor_val) << 24);
|
||||
v = ((unsigned)(*ptr++ ^ xor_val) << 24);
|
||||
// std::cerr << "[B] rem=" << rem << " ptr=" << (const void*)(ptr - 1) << " v=" << std::hex << v << std::dec << std::endl;
|
||||
if (v) {
|
||||
return bit_count - rem + td::count_leading_zeroes_non_zero32(v);
|
||||
|
@ -319,7 +319,7 @@ std::size_t bits_memscan(const unsigned char* ptr, int offs, std::size_t bit_cou
|
|||
rem -= 64;
|
||||
}
|
||||
while (rem >= 8) {
|
||||
v = ((*ptr++ ^ xor_val) << 24);
|
||||
v = ((unsigned)(*ptr++ ^ xor_val) << 24);
|
||||
// std::cerr << "[D] rem=" << rem << " ptr=" << (const void*)(ptr - 1) << " v=" << std::hex << v << std::dec << std::endl;
|
||||
if (v) {
|
||||
return bit_count - rem + td::count_leading_zeroes_non_zero32(v);
|
||||
|
@ -327,7 +327,7 @@ std::size_t bits_memscan(const unsigned char* ptr, int offs, std::size_t bit_cou
|
|||
rem -= 8;
|
||||
}
|
||||
if (rem > 0) {
|
||||
v = ((*ptr ^ xor_val) << 24);
|
||||
v = ((unsigned)(*ptr ^ xor_val) << 24);
|
||||
// std::cerr << "[E] rem=" << rem << " ptr=" << (const void*)ptr << " v=" << std::hex << v << std::dec << std::endl;
|
||||
c = td::count_leading_zeroes32(v);
|
||||
return c < rem ? bit_count - rem + c : bit_count;
|
||||
|
@ -505,7 +505,7 @@ unsigned long long bits_load_long_top(ConstBitPtr from, unsigned top_bits) {
|
|||
}
|
||||
|
||||
unsigned long long bits_load_ulong(ConstBitPtr from, unsigned bits) {
|
||||
return bits_load_long_top(from, bits) >> (64 - bits);
|
||||
return bits == 0 ? 0 : bits_load_long_top(from, bits) >> (64 - bits);
|
||||
}
|
||||
|
||||
long long bits_load_long(ConstBitPtr from, unsigned bits) {
|
||||
|
|
|
@ -125,8 +125,11 @@ bool TupleT::validate_skip(int* ops, vm::CellSlice& cs, bool weak) const {
|
|||
}
|
||||
|
||||
bool TLB::validate_ref_internal(int* ops, Ref<vm::Cell> cell_ref, bool weak) const {
|
||||
if (ops && --*ops < 0) {
|
||||
return false;
|
||||
if (ops) {
|
||||
if (*ops <= 0) {
|
||||
return false;
|
||||
}
|
||||
--*ops;
|
||||
}
|
||||
bool is_special;
|
||||
auto cs = load_cell_slice_special(std::move(cell_ref), is_special);
|
||||
|
|
|
@ -335,7 +335,7 @@ bool CellBuilder::store_ulong_rchk_bool(unsigned long long val, unsigned val_bit
|
|||
}
|
||||
|
||||
CellBuilder& CellBuilder::store_long(long long val, unsigned val_bits) {
|
||||
return store_long_top(val << (64 - val_bits), val_bits);
|
||||
return store_long_top(val_bits == 0 ? 0 : (unsigned long long)val << (64 - val_bits), val_bits);
|
||||
}
|
||||
|
||||
CellBuilder& CellBuilder::store_long_top(unsigned long long val, unsigned top_bits) {
|
||||
|
|
|
@ -474,7 +474,7 @@ int exec_store_var_integer(VmState* st, int len_bits, bool sgnd, bool quiet) {
|
|||
stack.check_underflow(2);
|
||||
auto x = stack.pop_int();
|
||||
auto cbr = stack.pop_builder();
|
||||
unsigned len = ((x->bit_size(sgnd) + 7) >> 3);
|
||||
unsigned len = (((unsigned)x->bit_size(sgnd) + 7) >> 3);
|
||||
if (len >= (1u << len_bits)) {
|
||||
throw VmError{Excno::range_chk};
|
||||
}
|
||||
|
|
|
@ -4451,35 +4451,36 @@ td::Status TonlibClient::do_request(const tonlib_api::blocks_getMasterchainInfo&
|
|||
}
|
||||
|
||||
td::Status TonlibClient::do_request(const tonlib_api::blocks_getShards& request,
|
||||
td::Promise<object_ptr<tonlib_api::blocks_shards>>&& promise) {
|
||||
td::Promise<object_ptr<tonlib_api::blocks_shards>>&& promise) {
|
||||
TRY_RESULT(block, to_lite_api(*request.id_))
|
||||
client_.send_query(ton::lite_api::liteServer_getAllShardsInfo(std::move(block)),
|
||||
promise.wrap([](lite_api_ptr<ton::lite_api::liteServer_allShardsInfo>&& all_shards_info) {
|
||||
td::BufferSlice proof = std::move((*all_shards_info).proof_);
|
||||
td::BufferSlice data = std::move((*all_shards_info).data_);
|
||||
if (data.empty()) {
|
||||
//return td::Status::Error("shard configuration is empty");
|
||||
} else {
|
||||
auto R = vm::std_boc_deserialize(data.clone());
|
||||
if (R.is_error()) {
|
||||
//return td::Status::Error("cannot deserialize shard configuration");
|
||||
}
|
||||
auto root = R.move_as_ok();
|
||||
block::ShardConfig sh_conf;
|
||||
if (!sh_conf.unpack(vm::load_cell_slice_ref(root))) {
|
||||
//return td::Status::Error("cannot extract shard block list from shard configuration");
|
||||
} else {
|
||||
auto ids = sh_conf.get_shard_hash_ids(true);
|
||||
tonlib_api::blocks_shards shards;
|
||||
for (auto id : ids) {
|
||||
auto ref = sh_conf.get_shard_hash(ton::ShardIdFull(id));
|
||||
if (ref.not_null()) {
|
||||
shards.shards_.push_back(to_tonlib_api(ref->top_block_id()));
|
||||
}
|
||||
}
|
||||
promise.wrap([](lite_api_ptr<ton::lite_api::liteServer_allShardsInfo>&& all_shards_info)
|
||||
-> td::Result<object_ptr<tonlib_api::blocks_shards>> {
|
||||
td::BufferSlice proof = std::move((*all_shards_info).proof_);
|
||||
td::BufferSlice data = std::move((*all_shards_info).data_);
|
||||
if (data.empty()) {
|
||||
return td::Status::Error("shard configuration is empty");
|
||||
} else {
|
||||
auto R = vm::std_boc_deserialize(data.clone());
|
||||
if (R.is_error()) {
|
||||
return R.move_as_error_prefix("cannot deserialize shard configuration: ");
|
||||
}
|
||||
auto root = R.move_as_ok();
|
||||
block::ShardConfig sh_conf;
|
||||
if (!sh_conf.unpack(vm::load_cell_slice_ref(root))) {
|
||||
return td::Status::Error("cannot extract shard block list from shard configuration");
|
||||
} else {
|
||||
auto ids = sh_conf.get_shard_hash_ids(true);
|
||||
tonlib_api::blocks_shards shards;
|
||||
for (auto id : ids) {
|
||||
auto ref = sh_conf.get_shard_hash(ton::ShardIdFull(id));
|
||||
if (ref.not_null()) {
|
||||
shards.shards_.push_back(to_tonlib_api(ref->top_block_id()));
|
||||
}
|
||||
}
|
||||
return tonlib_api::make_object<tonlib_api::blocks_shards>(std::move(shards));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
return td::Status::OK();
|
||||
}
|
||||
|
|
|
@ -162,20 +162,28 @@ void ValidatorSessionDescriptionImpl::update_hash(const RootObject *obj, HashTyp
|
|||
}
|
||||
|
||||
void *ValidatorSessionDescriptionImpl::alloc(size_t size, size_t align, bool temp) {
|
||||
CHECK(align && !(align & (align - 1))); // align should be a power of 2
|
||||
auto get_padding = [&](const uint8_t* ptr) {
|
||||
return (-(size_t)ptr) & (align - 1);
|
||||
};
|
||||
if (temp) {
|
||||
pdata_temp_ptr_ += get_padding(pdata_temp_ + pdata_temp_ptr_);
|
||||
auto s = pdata_temp_ptr_;
|
||||
pdata_temp_ptr_ += size;
|
||||
CHECK(s + size <= pdata_temp_size_);
|
||||
return static_cast<void *>(pdata_temp_ + s);
|
||||
} else {
|
||||
while (true) {
|
||||
auto s = pdata_perm_ptr_;
|
||||
pdata_perm_ptr_ += size;
|
||||
|
||||
if (pdata_perm_ptr_ <= pdata_perm_.size() * pdata_perm_size_) {
|
||||
return static_cast<void *>(pdata_perm_[s / pdata_perm_size_] + (s % pdata_perm_size_));
|
||||
size_t idx = pdata_perm_ptr_ / pdata_perm_size_;
|
||||
if (idx < pdata_perm_.size()) {
|
||||
auto ptr = pdata_perm_[idx] + (pdata_perm_ptr_ % pdata_perm_size_);
|
||||
pdata_perm_ptr_ += get_padding(ptr);
|
||||
ptr += get_padding(ptr);
|
||||
pdata_perm_ptr_ += size;
|
||||
if (pdata_perm_ptr_ <= pdata_perm_.size() * pdata_perm_size_) {
|
||||
return static_cast<void *>(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
pdata_perm_.push_back(new td::uint8[pdata_perm_size_]);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue