Skip to content

Commit

Permalink
Updates from code review
Browse files Browse the repository at this point in the history
  • Loading branch information
richard-viney committed Nov 20, 2024
1 parent 086cd1e commit 5b91a98
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 23 deletions.
25 changes: 10 additions & 15 deletions compiler-core/src/javascript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ mod tests;
mod typescript;

use num_bigint::BigInt;
use num_traits::{One, ToPrimitive};
use num_traits::ToPrimitive;

use crate::analyse::TargetSupport;
use crate::build::Target;
Expand Down Expand Up @@ -815,34 +815,29 @@ pub(crate) fn bit_array_segment_int_value_to_bytes(
mut value: BigInt,
size: BigInt,
endianness: endianness::Endianness,
location: SrcSpan,
) -> Result<Vec<u8>, Error> {
// Clamp negative sizes to zero
let size = size.max(BigInt::ZERO);

// The segment size in bits is not allowed to exceed the range of a u32. At runtime the
// limit is lower than this and depends on the JS engine. V8's limit is currently
// 2^30-1 bits.
let size = size.to_u32().ok_or_else(|| Error::Unsupported {
feature: "Integer segment size greater than 2^32-1".into(),
location,
})?;
// Convert size to u32. This is safe because this function isn't called with a size greater
// than `SAFE_INT_SEGMENT_MAX_SIZE`.
let size = size
.to_u32()
.expect("bit array segment size to be a valid u32");

// Convert negative number to two's complement representation
if value < BigInt::ZERO {
let value_modulus = BigInt::one() << size;
let value_modulus = BigInt::from(2).pow(size);
value = &value_modulus + (value % &value_modulus);
}

let byte_mask = BigInt::from(0xFF);

// Convert value to the desired number of bytes
let mut bytes = vec![0u8; size as usize / 8];
for byte in bytes.iter_mut() {
*byte = (&value & &byte_mask)
*byte = (&value % BigInt::from(256))
.to_u8()
.expect("bitwise and result to be a u8");
value >>= 8;
.expect("modulo result to be a valid u32");
value /= BigInt::from(256);
}

if endianness.is_big() {
Expand Down
14 changes: 7 additions & 7 deletions compiler-core/src/javascript/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,6 @@ impl<'module> Generator<'module> {
int_value.clone(),
size_value,
details.endianness,
segment.location,
)?;

Ok(u8_slice(&bytes))
Expand Down Expand Up @@ -367,9 +366,9 @@ impl<'module> Generator<'module> {
}
_ => {
let size_value = if segment.type_ == crate::type_::int() {
8usize
8
} else {
64usize
64
};

(Some(BigInt::from(size_value)), docvec![size_value])
Expand Down Expand Up @@ -1456,7 +1455,6 @@ fn bit_array<'a>(
int_value.clone(),
size_value,
details.endianness,
segment.location,
)?;

Ok(u8_slice(&bytes))
Expand Down Expand Up @@ -1523,7 +1521,9 @@ fn bit_array<'a>(
#[derive(Debug)]
struct SizedBitArraySegmentDetails<'a> {
size: Document<'a>,
size_value: Option<BigInt>, // This is set when the segment's size is known at compile time
/// The size of the bit array segment stored as a BigInt. This has a value when the segment's
/// size is known at compile time.
size_value: Option<BigInt>,
endianness: Endianness,
}

Expand Down Expand Up @@ -1580,9 +1580,9 @@ fn sized_bit_array_segment_details<'a>(
}
_ => {
let size_value = if segment.type_ == crate::type_::int() {
8usize
8
} else {
64usize
64
};

(Some(BigInt::from(size_value)), docvec![size_value])
Expand Down
1 change: 0 additions & 1 deletion compiler-core/src/javascript/pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,6 @@ impl<'module_ctx, 'expression_gen, 'a> Generator<'module_ctx, 'expression_gen, '
(*int_value).clone(),
BigInt::from(details.size),
details.endianness,
segment.location,
)?;

for byte in bytes {
Expand Down

0 comments on commit 5b91a98

Please sign in to comment.