1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-10 11:57:35 +00:00

LibCrypto+LibJS: Better bigint bitwise_and binop

Bitwise and is defined in terms of two's complement, so some converting
needs to happen for SignedBigInteger's sign/magnitude representation to
work out.

UnsignedBigInteger::bitwise_not() is repurposed to convert all
high-order zero bits to ones up to a limit, for the two's complement
conversion to work.

Fixes test262/test/language/expressions/bitwise-and/bigint.js.
This commit is contained in:
Nico Weber 2022-01-17 19:54:02 -05:00 committed by Ali Mohammad Pur
parent 945d962322
commit 1f98639396
7 changed files with 52 additions and 23 deletions

View file

@ -7,6 +7,7 @@
#include "UnsignedBigIntegerAlgorithms.h"
#include <AK/BuiltinWrappers.h>
#include <AK/NumericLimits.h>
namespace Crypto {
@ -130,8 +131,9 @@ FLATTEN void UnsignedBigIntegerAlgorithms::bitwise_xor_without_allocation(
/**
* Complexity: O(N) where N is the number of words
*/
FLATTEN void UnsignedBigIntegerAlgorithms::bitwise_not_without_allocation(
FLATTEN void UnsignedBigIntegerAlgorithms::bitwise_not_fill_to_size_without_allocation(
UnsignedBigInteger const& right,
size_t size,
UnsignedBigInteger& output)
{
// If the value is invalid, the output value is invalid as well.
@ -139,22 +141,17 @@ FLATTEN void UnsignedBigIntegerAlgorithms::bitwise_not_without_allocation(
output.invalidate();
return;
}
if (right.length() == 0) {
if (size == 0) {
output.set_to_0();
return;
}
output.m_words.resize_and_keep_capacity(right.length());
if (right.length() > 1) {
for (size_t i = 0; i < right.length() - 1; ++i)
output.m_words[i] = ~right.words()[i];
}
auto last_word_index = right.length() - 1;
auto last_word = right.words()[last_word_index];
output.m_words[last_word_index] = ((u32)0xffffffffffffffff >> count_leading_zeroes(last_word)) & ~last_word;
output.m_words.resize_and_keep_capacity(size);
size_t i;
for (i = 0; i < min(size, right.length()); ++i)
output.m_words[i] = ~right.words()[i];
for (; i < size; ++i)
output.m_words[i] = NumericLimits<UnsignedBigInteger::Word>::max();
}
/**