Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 104 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ bitvec = "1.0.1"
arbitrary = { version = "1.4.2", features = ["derive"] }
bumpalo = "3.19.0"
anyhow = "1.0.100"
malachite-bigint = "0.9.1"

[dependencies]
bitflags = { workspace = true }
Expand All @@ -90,6 +91,7 @@ hex = { workspace = true }
sha1 = { workspace = true }
bumpalo = { workspace = true }
thiserror = "1.0.69"
malachite-bigint = { workspace = true }


[dev-dependencies]
Expand Down
56 changes: 50 additions & 6 deletions src/allocator.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::error::{EvalErr, Result};
use crate::number::{Number, number_from_u8};
use crate::number::{Malachite, Number, malachite_number_from_u8, number_from_u8};
use chia_bls::{G1Element, G2Element};
use num_traits::ToPrimitive;
use std::borrow::Borrow;
use std::fmt;
use std::hash::Hash;
Expand Down Expand Up @@ -472,22 +473,47 @@ impl Allocator {
}

pub fn new_number(&mut self, v: Number) -> Result<NodePtr> {
use num_traits::ToPrimitive;
if let Some(val) = v.to_u32()
if let Some(ptr) = self.new_small_number_from_bigint(&v)? {
return Ok(ptr);
}

let bytes = v.to_signed_bytes_be();

self.new_atom_from_bigint_bytes(bytes.as_slice())
}

pub fn new_malachite_number(&mut self, v: Malachite) -> Result<NodePtr> {
if let Some(ptr) = self.new_small_number_from_bigint(&v)? {
return Ok(ptr);
}

let bytes = v.to_signed_bytes_be();

self.new_atom_from_bigint_bytes(bytes.as_slice())
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicated new_number and new_malachite_number implementations

Low Severity

new_malachite_number is an exact copy of new_number with only the parameter type changed. Similarly, malachite_number_from_u8 duplicates number_from_u8, and malachite_number duplicates number. Both Number and Malachite already share ToPrimitive (used in new_small_number_from_bigint); a similar trait-based approach for to_signed_bytes_be/from_signed_bytes_be could unify these three pairs of functions.

Additional Locations (2)

Fix in Cursor Fix in Web


fn new_small_number_from_bigint(
&mut self,
value: &impl ToPrimitive,
) -> Result<Option<NodePtr>> {
if let Some(val) = value.to_u32()
&& val <= NODE_PTR_IDX_MASK
{
return self.new_small_number(val);
return Ok(Some(self.new_small_number(val)?));
}
let bytes: Vec<u8> = v.to_signed_bytes_be();
let mut slice = bytes.as_slice();

Ok(None)
}

fn new_atom_from_bigint_bytes(&mut self, mut slice: &[u8]) -> Result<NodePtr> {
// make number minimal by removing leading zeros
while (!slice.is_empty()) && (slice[0] == 0) {
if slice.len() > 1 && (slice[1] & 0x80 == 0x80) {
break;
}
slice = &slice[1..];
}

self.new_atom(slice)
}

Expand Down Expand Up @@ -831,6 +857,24 @@ impl Allocator {
}
}

pub fn malachite_number(&self, node: NodePtr) -> Malachite {
#[cfg(feature = "allocator-debug")]
self.validate_node(node);

let index = node.index();

match node.object_type() {
ObjectType::Bytes => {
let atom = self.atom_vec[index as usize];
malachite_number_from_u8(&self.u8_vec[atom.start as usize..atom.end as usize])
}
ObjectType::SmallAtom => Malachite::from(index),
_ => {
panic!("number() called on pair");
}
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused public malachite_number method on Allocator

Low Severity

The newly added pub fn malachite_number on Allocator has no callers anywhere in the codebase. A grep for .malachite_number( returns zero matches. While new_malachite_number is called from op_add and malachite_number_from_u8 is used in more_ops.rs, the reader counterpart malachite_number is dead code.

Fix in Cursor Fix in Web


pub fn g1(&self, node: NodePtr) -> Result<G1Element> {
#[cfg(feature = "allocator-debug")]
self.validate_node(node);
Expand Down
13 changes: 7 additions & 6 deletions src/more_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ use std::ops::BitXorAssign;
use crate::allocator::{Allocator, NodePtr, NodeVisitor, SExp, len_for_value};
use crate::cost::{Cost, check_cost};
use crate::error::EvalErr;
use crate::number::Malachite;
use crate::number::Number;
use crate::number::malachite_number_from_u8;
use crate::op_utils::{
MALLOC_COST_PER_BYTE, atom, atom_len, get_args, get_varargs, i32_atom, int_atom, match_args,
mod_group_order, new_atom_and_cost, nilp, u32_from_u8,
Expand Down Expand Up @@ -402,7 +404,7 @@ pub fn op_sha256(a: &mut Allocator, mut input: NodePtr, max_cost: Cost) -> Respo

pub fn op_add(a: &mut Allocator, mut input: NodePtr, max_cost: Cost) -> Response {
let mut cost = ARITH_BASE_COST;
let mut total: Number = 0.into();
let mut total: Malachite = 0.into();
while let Some((arg, rest)) = a.next(input) {
input = rest;
cost += ARITH_COST_PER_ARG;
Expand All @@ -412,8 +414,7 @@ pub fn op_add(a: &mut Allocator, mut input: NodePtr, max_cost: Cost) -> Response
cost += ARITH_COST_PER_BYTE * (buf.len() as Cost);
check_cost(cost, max_cost)?;

use crate::number::number_from_u8;
total += number_from_u8(buf);
total += malachite_number_from_u8(buf);
}
NodeVisitor::U32(val) => {
cost += len_for_value(val) as Cost * ARITH_COST_PER_BYTE;
Expand All @@ -428,7 +429,7 @@ pub fn op_add(a: &mut Allocator, mut input: NodePtr, max_cost: Cost) -> Response
}
}
}
let total = a.new_number(total)?;
let total = a.new_malachite_number(total)?;
Ok(malloc_cost(a, cost, total))
}

Expand Down Expand Up @@ -740,7 +741,7 @@ fn test_op_ash() {
));

let node = test_shift(op_ash, &mut a, &[1], &[0x80, 0]).unwrap().1;
assert_eq!(a.atom(node).as_ref(), &[]);
assert_eq!(a.atom(node).as_ref(), &[0; 0]);

assert!(matches!(
test_shift(op_ash, &mut a, &[1], &[0x7f, 0, 0, 0]).unwrap_err(),
Expand Down Expand Up @@ -795,7 +796,7 @@ fn test_op_lsh() {
));

let node = test_shift(op_lsh, &mut a, &[1], &[0x80, 0]).unwrap().1;
assert_eq!(a.atom(node).as_ref(), &[]);
assert_eq!(a.atom(node).as_ref(), &[0; 0]);

assert!(matches!(
test_shift(op_lsh, &mut a, &[1], &[0x7f, 0, 0, 0]).unwrap_err(),
Expand Down
10 changes: 10 additions & 0 deletions src/number.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use num_bigint::BigInt;

pub type Number = BigInt;
pub type Malachite = malachite_bigint::BigInt;

// This low-level conversion function is meant to be used by the Allocator, for
// logic interacting with the CLVM heap/allocator, use new_number() and number()
Expand All @@ -14,6 +15,15 @@ pub fn number_from_u8(v: &[u8]) -> Number {
}
}

pub fn malachite_number_from_u8(v: &[u8]) -> Malachite {
let len = v.len();
if len == 0 {
0.into()
} else {
Malachite::from_signed_bytes_be(v)
}
}

#[cfg(test)]
mod tests {
use num_bigint::{BigUint, Sign};
Expand Down
2 changes: 1 addition & 1 deletion src/serde/write_atom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ mod tests {
for v in 0..0x7f {
let mut buf = Vec::<u8>::new();
assert!(write_atom_encoding_prefix_with_size(&mut buf, v, 1).is_ok());
assert_eq!(buf, vec![]);
assert_eq!(buf, vec![0; 0]);
}

for v in 0x80..0xff {
Expand Down
Loading