Skip to content

Commit

Permalink
fix rawbigints (JuliaLang#51122)
Browse files Browse the repository at this point in the history
Using `Ptr` like that was incorrect. Among other issues, a `Ptr` doesn't
own the data it points to, so hold a `String` instead.

Fixes JuliaLang#51111
  • Loading branch information
nsajko committed Sep 1, 2023
1 parent 4954af9 commit ec2f1d3
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 6 deletions.
2 changes: 1 addition & 1 deletion base/mpfr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ function to_ieee754(::Type{T}, x::BigFloat, rm) where {T<:AbstractFloat}
ret_u = if is_regular & !rounds_to_inf & !rounds_to_zero
if !exp_is_huge_p
# significand
v = RawBigInt(x.d, significand_limb_count(x))
v = RawBigInt{Limb}(x._d, significand_limb_count(x))
len = max(ieee_precision + min(exp_diff, 0), 0)::Int
signif = truncated(U, v, len) & significand_mask(T)

Expand Down
11 changes: 6 additions & 5 deletions base/rawbigints.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@ Segment of raw words of bits interpreted as a big integer. Less
significant words come first. Each word is in machine-native bit-order.
"""
struct RawBigInt{T<:Unsigned}
d::Ptr{T}
d::String
word_count::Int

function RawBigInt{T}(d::Ptr{T}, word_count::Int) where {T<:Unsigned}
function RawBigInt{T}(d::String, word_count::Int) where {T<:Unsigned}
new{T}(d, word_count)
end
end

RawBigInt(d::Ptr{T}, word_count::Int) where {T<:Unsigned} = RawBigInt{T}(d, word_count)
elem_count(x::RawBigInt, ::Val{:words}) = x.word_count
elem_count(x::Unsigned, ::Val{:bits}) = sizeof(x) * 8
word_length(::RawBigInt{T}) where {T} = elem_count(zero(T), Val(:bits))
Expand All @@ -26,8 +25,10 @@ split_bit_index(x::RawBigInt, i::Int) = divrem(i, word_length(x), RoundToZero)
`i` is the zero-based index of the wanted word in `x`, starting from
the less significant words.
"""
function get_elem(x::RawBigInt, i::Int, ::Val{:words}, ::Val{:ascending})
unsafe_load(x.d, i + 1)
function get_elem(x::RawBigInt{T}, i::Int, ::Val{:words}, ::Val{:ascending}) where {T}
# `i` must be nonnegative and less than `x.word_count`
d = x.d
(GC.@preserve d unsafe_load(Ptr{T}(pointer(d)), i + 1))::T
end

function get_elem(x, i::Int, v::Val, ::Val{:descending})
Expand Down
6 changes: 6 additions & 0 deletions test/precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,9 @@ precompile_test_harness(false) do dir
const abigint_f() = big"123"
const abigint_x = big"124"
# issue #51111
abigfloat_to_f32() = Float32(big"1.5")
# issue #31488
_v31488 = Base.StringVector(2)
resize!(_v31488, 0)
Expand Down Expand Up @@ -299,6 +302,9 @@ precompile_test_harness(false) do dir
@test Foo.abigint_f()::BigInt == big"123"
@test Foo.abigint_x::BigInt + 1 == big"125"

# Issue #51111
@test Foo.abigfloat_to_f32() == 1.5f0

@test Foo.x28297.result === missing

@test Foo.d29936a === Dict
Expand Down

0 comments on commit ec2f1d3

Please sign in to comment.