diff --git a/NEWS.md b/NEWS.md index 5a518104d3770..404b2b11687af 100644 --- a/NEWS.md +++ b/NEWS.md @@ -44,6 +44,7 @@ New library functions * `tanpi` is now defined. It computes tan(πx) more accurately than `tan(pi*x)` ([#48575]). * `fourthroot(x)` is now defined in `Base.Math` and can be used to compute the fourth root of `x`. It can also be accessed using the unicode character `∜`, which can be typed by `\fourthroot` ([#48899]). +* `Libc.memmove`, `Libc.memset`, and `Libc.memcpy` are now defined, whose functionality matches that of their respective C calls. New library features -------------------- diff --git a/base/Base.jl b/base/Base.jl index 06df2edb276fd..65abe47f33d2d 100644 --- a/base/Base.jl +++ b/base/Base.jl @@ -163,6 +163,7 @@ include("int.jl") include("operators.jl") include("pointer.jl") include("refvalue.jl") +include("cmem.jl") include("refpointer.jl") # now replace the Pair constructor (relevant for NamedTuples) with one that calls our Base.convert @@ -316,7 +317,7 @@ include("version.jl") # system & environment include("sysinfo.jl") include("libc.jl") -using .Libc: getpid, gethostname, time +using .Libc: getpid, gethostname, time, memcpy, memset, memmove, memcmp # These used to be in build_h.jl and are retained for backwards compatibility. # NOTE: keep in sync with `libblastrampoline_jll.libblastrampoline`. diff --git a/base/array.jl b/base/array.jl index 68e3e38992731..ce400a7fa7154 100644 --- a/base/array.jl +++ b/base/array.jl @@ -280,8 +280,7 @@ segfault your program, in the same manner as C. function unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, n) where T # Do not use this to copy data between pointer arrays. # It can't be made safe no matter how carefully you checked. - ccall(:memmove, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t), - dest, src, n * aligned_sizeof(T)) + memmove(dest, src, n * aligned_sizeof(T)) return dest end @@ -328,13 +327,11 @@ function unsafe_copyto!(dest::Array{T}, doffs, src::Array{T}, soffs, n) where T ccall(:jl_array_ptr_copy, Cvoid, (Any, Ptr{Cvoid}, Any, Ptr{Cvoid}, Int), dest, destp, src, srcp, n) elseif isbitstype(T) - ccall(:memmove, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t), - destp, srcp, n * aligned_sizeof(T)) + memmove(destp, srcp, n * aligned_sizeof(T)) elseif isbitsunion(T) - ccall(:memmove, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t), - destp, srcp, n * aligned_sizeof(T)) + memmove(destp, srcp, n * aligned_sizeof(T)) # copy selector bytes - ccall(:memmove, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t), + memmove( ccall(:jl_array_typetagdata, Ptr{UInt8}, (Any,), dest) + doffs - 1, ccall(:jl_array_typetagdata, Ptr{UInt8}, (Any,), src) + soffs - 1, n) @@ -467,7 +464,10 @@ end getindex(::Type{Any}) = Vector{Any}() function fill!(a::Union{Array{UInt8}, Array{Int8}}, x::Integer) - ccall(:memset, Ptr{Cvoid}, (Ptr{Cvoid}, Cint, Csize_t), a, x isa eltype(a) ? x : convert(eltype(a), x), length(a)) + t = @_gc_preserve_begin a + p = unsafe_convert(Ptr{Cvoid}, a) + memset(p, x isa eltype(a) ? x : convert(eltype(a), x), length(a)) + @_gc_preserve_end t return a end @@ -1834,23 +1834,50 @@ function empty!(a::Vector) return a end -_memcmp(a, b, len) = ccall(:memcmp, Cint, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t), a, b, len % Csize_t) % Int - # use memcmp for cmp on byte arrays function cmp(a::Array{UInt8,1}, b::Array{UInt8,1}) - c = _memcmp(a, b, min(length(a),length(b))) + ta = @_gc_preserve_begin a + tb = @_gc_preserve_begin b + pa = unsafe_convert(Ptr{Cvoid}, a) + pb = unsafe_convert(Ptr{Cvoid}, b) + c = memcmp(pa, pb, min(length(a),length(b))) + @_gc_preserve_end ta + @_gc_preserve_end tb return c < 0 ? -1 : c > 0 ? +1 : cmp(length(a),length(b)) end const BitIntegerArray{N} = Union{map(T->Array{T,N}, BitInteger_types)...} where N # use memcmp for == on bit integer types -==(a::Arr, b::Arr) where {Arr <: BitIntegerArray} = - size(a) == size(b) && 0 == _memcmp(a, b, sizeof(eltype(Arr)) * length(a)) +function ==(a::Arr, b::Arr) where {Arr <: BitIntegerArray} + if size(a) == size(b) + ta = @_gc_preserve_begin a + tb = @_gc_preserve_begin b + pa = unsafe_convert(Ptr{Cvoid}, a) + pb = unsafe_convert(Ptr{Cvoid}, b) + c = memcmp(pa, pb, sizeof(eltype(Arr)) * length(a)) + @_gc_preserve_end ta + @_gc_preserve_end tb + return c == 0 + else + return false + end +end -# this is ~20% faster than the generic implementation above for very small arrays function ==(a::Arr, b::Arr) where Arr <: BitIntegerArray{1} len = length(a) - len == length(b) && 0 == _memcmp(a, b, sizeof(eltype(Arr)) * len) + if len == length(b) + ta = @_gc_preserve_begin a + tb = @_gc_preserve_begin b + T = eltype(Arr) + pa = unsafe_convert(Ptr{T}, a) + pb = unsafe_convert(Ptr{T}, b) + c = memcmp(pa, pb, sizeof(T) * len) + @_gc_preserve_end ta + @_gc_preserve_end tb + return c == 0 + else + return false + end end """ diff --git a/base/bitset.jl b/base/bitset.jl index 5ce07389c771e..240be822fa263 100644 --- a/base/bitset.jl +++ b/base/bitset.jl @@ -391,7 +391,7 @@ function ==(s1::BitSet, s2::BitSet) if overlap > 0 t1 = @_gc_preserve_begin a1 t2 = @_gc_preserve_begin a2 - _memcmp(pointer(a1, b2-b1+1), pointer(a2), overlap<<3) == 0 || return false + memcmp(pointer(a1, b2-b1+1), pointer(a2), overlap<<3) == 0 || return false @_gc_preserve_end t2 @_gc_preserve_end t1 end diff --git a/base/cmem.jl b/base/cmem.jl new file mode 100644 index 0000000000000..8b0b99b3a6ebd --- /dev/null +++ b/base/cmem.jl @@ -0,0 +1,53 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +""" + memcpy(dst::Ptr, src::Ptr, n::Integer) -> Ptr{Cvoid} + +Call `memcpy` from the C standard library. + +!!! compat "Julia 1.10" + Support for `memcpy` requires at least Julia 1.10. + +""" +function memcpy(dst::Ptr, src::Ptr, n::Integer) + ccall(:memcpy, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t), dst, src, n) +end + +""" + memmove(dst::Ptr, src::Ptr, n::Integer) -> Ptr{Cvoid} + +Call `memmove` from the C standard library. + +!!! compat "Julia 1.10" + Support for `memmove` requires at least Julia 1.10. + +""" +function memmove(dst::Ptr, src::Ptr, n::Integer) + ccall(:memmove, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t), dst, src, n) +end + +""" + memset(dst::Ptr, val, n::Integer) -> Ptr{Cvoid} + +Call `memset` from the C standard library. + +!!! compat "Julia 1.10" + Support for `memset` requires at least Julia 1.10. + +""" +function memset(p::Ptr, val, n::Integer) + ccall(:memset, Ptr{Cvoid}, (Ptr{Cvoid}, Cint, Csize_t), p, val, n) +end + +""" + memcmp(a::Ptr, b::Ptr, n::Integer) -> Int + +Call `memcmp` from the C standard library. + +!!! compat "Julia 1.10" + Support for `memcmp` requires at least Julia 1.9. + +""" +function memcmp(a::Ptr, b::Ptr, n::Integer) + ccall(:memcmp, Cint, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t), a, b, n % Csize_t) % Int +end diff --git a/base/compiler/compiler.jl b/base/compiler/compiler.jl index 74814733f088d..58f77078ddb5e 100644 --- a/base/compiler/compiler.jl +++ b/base/compiler/compiler.jl @@ -100,6 +100,7 @@ add_with_overflow(x::T, y::T) where {T<:SignedInt} = checked_sadd_int(x, y) add_with_overflow(x::T, y::T) where {T<:UnsignedInt} = checked_uadd_int(x, y) add_with_overflow(x::Bool, y::Bool) = (x+y, false) +include("cmem.jl") include("strings/lazy.jl") # core array operations diff --git a/base/iddict.jl b/base/iddict.jl index 99710fbb3491e..01ff213305d7b 100644 --- a/base/iddict.jl +++ b/base/iddict.jl @@ -134,7 +134,10 @@ end function empty!(d::IdDict) resize!(d.ht, 32) - ccall(:memset, Ptr{Cvoid}, (Ptr{Cvoid}, Cint, Csize_t), d.ht, 0, sizeof(d.ht)) + ht = d.ht + t = @_gc_preserve_begin ht + memset(unsafe_convert(Ptr{Cvoid}, ht), 0, sizeof(ht)) + @_gc_preserve_end t d.ndel = 0 d.count = 0 return d diff --git a/base/libc.jl b/base/libc.jl index 82286fbf01af6..99e8dce6b87e5 100644 --- a/base/libc.jl +++ b/base/libc.jl @@ -6,10 +6,13 @@ Interface to libc, the C standard library. """ Libc import Base: transcode, windowserror, show +# these need to be defined seperately for bootstrapping but belong to Libc +import Base: memcpy, memmove, memset, memcmp import Core.Intrinsics: bitcast -export FILE, TmStruct, strftime, strptime, getpid, gethostname, free, malloc, calloc, realloc, - errno, strerror, flush_cstdio, systemsleep, time, transcode +export FILE, TmStruct, strftime, strptime, getpid, gethostname, free, malloc, memcpy, + memmove, memset, calloc, realloc, errno, strerror, flush_cstdio, systemsleep, time, + transcode if Sys.iswindows() export GetLastError, FormatMessage end @@ -336,7 +339,6 @@ if Sys.iswindows() end ## Memory related ## - """ free(addr::Ptr) @@ -346,6 +348,8 @@ be freed by the free functions defined in that library, to avoid assertion failu multiple `libc` libraries exist on the system. """ free(p::Ptr) = ccall(:free, Cvoid, (Ptr{Cvoid},), p) +free(p::Cstring) = free(convert(Ptr{UInt8}, p)) +free(p::Cwstring) = free(convert(Ptr{Cwchar_t}, p)) """ malloc(size::Integer) -> Ptr{Cvoid} @@ -371,8 +375,7 @@ Call `calloc` from the C standard library. """ calloc(num::Integer, size::Integer) = ccall(:calloc, Ptr{Cvoid}, (Csize_t, Csize_t), num, size) -free(p::Cstring) = free(convert(Ptr{UInt8}, p)) -free(p::Cwstring) = free(convert(Ptr{Cwchar_t}, p)) + ## Random numbers ## diff --git a/base/mpfr.jl b/base/mpfr.jl index ff85fc6155df4..2e03018f7669f 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -19,6 +19,8 @@ import isone, big, _string_n, decompose, minmax, sinpi, cospi, sincospi, tanpi, sind, cosd, tand, asind, acosd, atand + +using .Base.Libc import ..Rounding: rounding_raw, setrounding_raw import ..GMP: ClongMax, CulongMax, CdoubleMax, Limb, libgmp @@ -1140,7 +1142,7 @@ function decompose(x::BigFloat)::Tuple{BigInt, Int, Int} s.size = cld(x.prec, 8*sizeof(Limb)) # limbs b = s.size * sizeof(Limb) # bytes ccall((:__gmpz_realloc2, libgmp), Cvoid, (Ref{BigInt}, Culong), s, 8b) # bits - ccall(:memcpy, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t), s.d, x.d, b) # bytes + memcpy(s.d, x.d, b) s, x.exp - 8b, x.sign end diff --git a/base/parse.jl b/base/parse.jl index d800e54258b0d..f6a93e56369b7 100644 --- a/base/parse.jl +++ b/base/parse.jl @@ -210,9 +210,11 @@ function tryparse_internal(::Type{Bool}, sbuff::AbstractString, len = endpos - startpos + 1 if sbuff isa Union{String, SubString{String}} p = pointer(sbuff) + startpos - 1 - GC.@preserve sbuff begin - (len == 4) && (0 == _memcmp(p, "true", 4)) && (return true) - (len == 5) && (0 == _memcmp(p, "false", 5)) && (return false) + truestr = "true" + falsestr = "false" + GC.@preserve sbuff truestr falsestr begin + (len == 4) && (0 == memcmp(p, unsafe_convert(Ptr{UInt8}, truestr), 4)) && (return true) + (len == 5) && (0 == memcmp(p, unsafe_convert(Ptr{UInt8}, falsestr), 5)) && (return false) end else (len == 4) && (SubString(sbuff, startpos:startpos+3) == "true") && (return true) diff --git a/base/refpointer.jl b/base/refpointer.jl index 0cb2df6d24bce..ad74763ff8286 100644 --- a/base/refpointer.jl +++ b/base/refpointer.jl @@ -83,6 +83,7 @@ else primitive type Cwstring 32 end end + ### General Methods for Ref{T} type eltype(x::Type{<:Ref{T}}) where {T} = @isdefined(T) ? T : Any diff --git a/base/reinterpretarray.jl b/base/reinterpretarray.jl index 2fc246f86fa96..830bac90d86e9 100644 --- a/base/reinterpretarray.jl +++ b/base/reinterpretarray.jl @@ -387,8 +387,6 @@ end end end -@inline _memcpy!(dst, src, n) = ccall(:memcpy, Cvoid, (Ptr{UInt8}, Ptr{UInt8}, Csize_t), dst, src, n) - @inline @propagate_inbounds function _getindex_ra(a::NonReshapedReinterpretArray{T,N,S}, i1::Int, tailinds::TT) where {T,N,S,TT} # Make sure to match the scalar reinterpret if that is applicable if sizeof(T) == sizeof(S) && (fieldcount(T) + fieldcount(S)) == 0 @@ -434,7 +432,7 @@ end while nbytes_copied < sizeof(T) s[] = a.parent[ind_start + i, tailinds...] nb = min(sizeof(S) - sidx, sizeof(T)-nbytes_copied) - _memcpy!(tptr + nbytes_copied, sptr + sidx, nb) + memcpy(tptr + nbytes_copied, sptr + sidx, nb) nbytes_copied += nb sidx = 0 i += 1 @@ -574,7 +572,7 @@ end if sidx != 0 s[] = a.parent[ind_start + i, tailinds...] nb = min((sizeof(S) - sidx) % UInt, sizeof(T) % UInt) - _memcpy!(sptr + sidx, tptr, nb) + memcpy(sptr + sidx, tptr, nb) nbytes_copied += nb a.parent[ind_start + i, tailinds...] = s[] i += 1 @@ -583,7 +581,7 @@ end # Deal with the main body of elements while nbytes_copied < sizeof(T) && (sizeof(T) - nbytes_copied) > sizeof(S) nb = min(sizeof(S), sizeof(T) - nbytes_copied) - _memcpy!(sptr, tptr + nbytes_copied, nb) + memcpy(sptr, tptr + nbytes_copied, nb) nbytes_copied += nb a.parent[ind_start + i, tailinds...] = s[] i += 1 @@ -592,7 +590,7 @@ end if nbytes_copied < sizeof(T) s[] = a.parent[ind_start + i, tailinds...] nb = min(sizeof(S), sizeof(T) - nbytes_copied) - _memcpy!(sptr, tptr + nbytes_copied, nb) + memcpy(sptr, tptr + nbytes_copied, nb) a.parent[ind_start + i, tailinds...] = s[] end end diff --git a/base/ryu/Ryu.jl b/base/ryu/Ryu.jl index 81d1c41f4c19f..9b236caeb6ff1 100644 --- a/base/ryu/Ryu.jl +++ b/base/ryu/Ryu.jl @@ -1,5 +1,6 @@ module Ryu +using .Base.Libc import .Base: significand_bits, significand_mask, exponent_bits, exponent_mask, exponent_bias, exponent_max, uinttype include("utils.jl") diff --git a/base/ryu/shortest.jl b/base/ryu/shortest.jl index f95c09d235e6d..aaa62ba33c703 100644 --- a/base/ryu/shortest.jl +++ b/base/ryu/shortest.jl @@ -363,10 +363,10 @@ function writeshortest(buf::Vector{UInt8}, pos, x::T, c1 = (c ÷ 100) << 1 d0 = (d % 100) << 1 d1 = (d ÷ 100) << 1 - memcpy(ptr, pos + olength - 2, ptr2, c0 + 1, 2) - memcpy(ptr, pos + olength - 4, ptr2, c1 + 1, 2) - memcpy(ptr, pos + olength - 6, ptr2, d0 + 1, 2) - memcpy(ptr, pos + olength - 8, ptr2, d1 + 1, 2) + memcpy(ptr + pos + olength - 3, ptr2 + c0, 2) + memcpy(ptr + pos + olength - 5, ptr2 + c1, 2) + memcpy(ptr + pos + olength - 7, ptr2 + d0, 2) + memcpy(ptr + pos + olength - 9, ptr2 + d1, 2) i += 8 end output2 = output % UInt32 @@ -375,14 +375,14 @@ function writeshortest(buf::Vector{UInt8}, pos, x::T, output2 = div(output2, UInt32(10000)) c0 = (c % 100) << 1 c1 = (c ÷ 100) << 1 - memcpy(ptr, pos + olength - i - 2, ptr2, c0 + 1, 2) - memcpy(ptr, pos + olength - i - 4, ptr2, c1 + 1, 2) + memcpy(ptr + pos + olength - i - 3, ptr2 + c0, 2) + memcpy(ptr + pos + olength - i - 5, ptr2 + c1, 2) i += 4 end if output2 >= 100 c = (output2 % UInt32(100)) << 1 output2 = div(output2, UInt32(100)) - memcpy(ptr, pos + olength - i - 2, ptr2, c + 1, 2) + memcpy(ptr + pos + olength - i - 3, ptr2 + c, 2) i += 2 end if output2 >= 10 @@ -425,7 +425,7 @@ function writeshortest(buf::Vector{UInt8}, pos, x::T, end else pointoff = olength - abs(nexp) - memmove(ptr, pos + pointoff + 1, ptr, pos + pointoff, olength - pointoff + 1) + memmove(ptr + pos + pointoff, ptr + pos + pointoff - 1, olength - pointoff + 1) buf[pos + pointoff] = decchar pos += olength + 1 precision -= olength @@ -470,11 +470,11 @@ function writeshortest(buf::Vector{UInt8}, pos, x::T, if exp2 >= 100 c = exp2 % 10 - memcpy(ptr, pos, ptr2, 2 * div(exp2, 10) + 1, 2) + memcpy(ptr + pos - 1, ptr2 + 2 * div(exp2, 10), 2) buf[pos + 2] = UInt8('0') + (c % UInt8) pos += 3 elseif exp2 >= 10 - memcpy(ptr, pos, ptr2, 2 * exp2 + 1, 2) + memcpy(ptr + pos - 1, ptr2 + 2 * exp2, 2) pos += 2 else if padexp diff --git a/base/ryu/utils.jl b/base/ryu/utils.jl index 4fe0b7d397d07..f5a88c057e2b3 100644 --- a/base/ryu/utils.jl +++ b/base/ryu/utils.jl @@ -1,9 +1,6 @@ const MANTISSA_MASK = Base.significand_mask(Float64) const EXP_MASK = Base.exponent_mask(Float64) >> Base.significand_bits(Float64) -memcpy(d, doff, s, soff, n) = (ccall(:memcpy, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t), d + doff - 1, s + soff - 1, n); nothing) -memmove(d, doff, s, soff, n) = (ccall(:memmove, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t), d + doff - 1, s + soff - 1, n); nothing) - # Note: these are smaller than the values given in Figure 4 from the paper # see https://github.com/ulfjack/ryu/issues/119 pow5_bitcount(::Type{Float16}) = 30 diff --git a/base/strings/string.jl b/base/strings/string.jl index 9716d06deefdf..a26791958cd50 100644 --- a/base/strings/string.jl +++ b/base/strings/string.jl @@ -127,7 +127,11 @@ end _memcmp(a::Union{Ptr{UInt8},AbstractString}, b::Union{Ptr{UInt8},AbstractString}) = _memcmp(a, b, min(sizeof(a), sizeof(b))) function _memcmp(a::Union{Ptr{UInt8},AbstractString}, b::Union{Ptr{UInt8},AbstractString}, len::Int) - ccall(:memcmp, Cint, (Ptr{UInt8}, Ptr{UInt8}, Csize_t), a, b, len % Csize_t) % Int + GC.@preserve a b begin + pa = unsafe_convert(Ptr{UInt8}, a) + pb = unsafe_convert(Ptr{UInt8}, b) + memcmp(pa, pb, len % Csize_t) % Int + end end function cmp(a::String, b::String) @@ -542,7 +546,7 @@ function repeat(c::AbstractChar, r::Integer) s = _string_n(n*r) p = pointer(s) GC.@preserve s if n == 1 - ccall(:memset, Ptr{Cvoid}, (Ptr{UInt8}, Cint, Csize_t), p, u % UInt8, r) + memset(p, u % UInt8, r) elseif n == 2 p16 = reinterpret(Ptr{UInt16}, p) for i = 1:r diff --git a/base/strings/substring.jl b/base/strings/substring.jl index 6c169624c72f5..792925f24b12b 100644 --- a/base/strings/substring.jl +++ b/base/strings/substring.jl @@ -267,7 +267,7 @@ function repeat(s::Union{String, SubString{String}}, r::Integer) out = _string_n(n*r) if n == 1 # common case: repeating a single-byte string @inbounds b = codeunit(s, 1) - ccall(:memset, Ptr{Cvoid}, (Ptr{UInt8}, Cint, Csize_t), out, b, r) + memset(unsafe_convert(Ptr{UInt8}, out), b, r) else for i = 0:r-1 GC.@preserve s out unsafe_copyto!(pointer(out, i*n+1), pointer(s), n) diff --git a/base/util.jl b/base/util.jl index 6f424f80d13b6..c7a036a6dff69 100644 --- a/base/util.jl +++ b/base/util.jl @@ -268,7 +268,7 @@ will always be called. function securezero! end @noinline securezero!(a::AbstractArray{<:Number}) = fill!(a, 0) @noinline unsafe_securezero!(p::Ptr{T}, len::Integer=1) where {T} = - ccall(:memset, Ptr{T}, (Ptr{T}, Cint, Csize_t), p, 0, len*sizeof(T)) + memset(p, 0, len*sizeof(T)) unsafe_securezero!(p::Ptr{Cvoid}, len::Integer=1) = Ptr{Cvoid}(unsafe_securezero!(Ptr{UInt8}(p), len)) """ diff --git a/doc/src/base/libc.md b/doc/src/base/libc.md index 0af1b74a79a71..08d2670123234 100644 --- a/doc/src/base/libc.md +++ b/doc/src/base/libc.md @@ -4,6 +4,10 @@ Base.Libc.malloc Base.Libc.calloc Base.Libc.realloc +Base.Libc.memcpy +Base.Libc.memmove +Base.Libc.memset +Base.Libc.memcmp Base.Libc.free Base.Libc.errno Base.Libc.strerror diff --git a/stdlib/InteractiveUtils/src/InteractiveUtils.jl b/stdlib/InteractiveUtils/src/InteractiveUtils.jl index 48fc2b7dafe8f..5fbe19ac4efce 100644 --- a/stdlib/InteractiveUtils/src/InteractiveUtils.jl +++ b/stdlib/InteractiveUtils/src/InteractiveUtils.jl @@ -12,7 +12,7 @@ import Base.Docs.apropos using Base: unwrap_unionall, rewrap_unionall, isdeprecated, Bottom, show_unquoted, summarysize, signature_type, format_bytes - +using Base.Libc using Markdown include("editless.jl") diff --git a/stdlib/InteractiveUtils/src/clipboard.jl b/stdlib/InteractiveUtils/src/clipboard.jl index a4a5118acf8d7..c2abda9a60cc3 100644 --- a/stdlib/InteractiveUtils/src/clipboard.jl +++ b/stdlib/InteractiveUtils/src/clipboard.jl @@ -100,7 +100,7 @@ elseif Sys.iswindows() pdata == C_NULL && return cleanup(:GlobalAlloc) plock = ccall((:GlobalLock, "kernel32"), stdcall, Ptr{UInt16}, (Ptr{UInt16},), pdata) plock == C_NULL && return cleanup(:GlobalLock) - ccall(:memcpy, Ptr{UInt16}, (Ptr{UInt16}, Ptr{UInt16}, Csize_t), plock, x_u16, sizeof(x_u16)) + GC.@preserve x_u16 memcpy(plock, Base.unsafe_convert(Ptr{UInt16}, x_u16), sizeof(x_u16)) unlock = ccall((:GlobalUnlock, "kernel32"), stdcall, Cint, (Ptr{UInt16},), pdata) (unlock == 0 && Libc.GetLastError() == 0) || return cleanup(:GlobalUnlock) # this should never fail pset = ccall((:SetClipboardData, "user32"), stdcall, Ptr{UInt16}, (Cuint, Ptr{UInt16}), 13, pdata) # CF_UNICODETEXT diff --git a/stdlib/Random/src/DSFMT.jl b/stdlib/Random/src/DSFMT.jl index f72a9dd5e9a0a..4c5cb8c522667 100644 --- a/stdlib/Random/src/DSFMT.jl +++ b/stdlib/Random/src/DSFMT.jl @@ -194,8 +194,11 @@ function dsfmt_jump(s::DSFMT_state, jp::GF2X) work = zeros(Int32, JN32) rwork = reinterpret(UInt64, work) dsfmt = Vector{UInt64}(undef, nval >> 1) - ccall(:memcpy, Ptr{Cvoid}, (Ptr{UInt64}, Ptr{Int32}, Csize_t), - dsfmt, val, (nval - 1) * sizeof(Int32)) + GC.@preserve dsfmt val begin + pdsfmt = Base.unsafe_convert(Ptr{Cvoid}, dsfmt) + pval = Base.unsafe_convert(Ptr{Cvoid}, val) + Base.Libc.memcpy(pdsfmt, pval, (nval - 1) * sizeof(Int32)) + end dsfmt[end] = UInt64(N*2) for i in 0:degree(jp) diff --git a/stdlib/Random/src/Random.jl b/stdlib/Random/src/Random.jl index 8da2dd6f3e9c7..89bb51516c106 100644 --- a/stdlib/Random/src/Random.jl +++ b/stdlib/Random/src/Random.jl @@ -16,7 +16,6 @@ using Base.GMP: Limb import SHA using Base: BitInteger, BitInteger_types, BitUnsigned, require_one_based_indexing - import Base: copymutable, copy, copy!, ==, hash, convert, rand, randn, show diff --git a/stdlib/Random/src/XoshiroSimd.jl b/stdlib/Random/src/XoshiroSimd.jl index 9fb03f9572688..1a16baa4bce28 100644 --- a/stdlib/Random/src/XoshiroSimd.jl +++ b/stdlib/Random/src/XoshiroSimd.jl @@ -5,6 +5,7 @@ module XoshiroSimd import ..Random: TaskLocalRNG, rand, rand!, Xoshiro, CloseOpen01, UnsafeView, SamplerType, SamplerTrivial using Base: BitInteger_types +using Base.Libc: memcpy using Core.Intrinsics: llvmcall # Vector-width. Influences random stream. @@ -180,7 +181,7 @@ end s3 = _rotl45(s3) ref = Ref(f(res, T)) # TODO: This may make the random-stream dependent on system endianness - ccall(:memcpy, Ptr{Cvoid}, (Ptr{UInt8}, Ptr{UInt64}, Csize_t), dst+i, ref, len-i) + GC.@preserve ref memcpy(dst+i, Base.unsafe_convert(Ptr{Cvoid}, ref), len-i) end if rng isa TaskLocalRNG task.rngState0, task.rngState1, task.rngState2, task.rngState3 = s0, s1, s2, s3 @@ -222,7 +223,7 @@ end res = _plus(_rotl23(_plus(s0,s3)),s0) resLoc = _and(res, 0x0101010101010101) ref = Ref(resLoc) - ccall(:memcpy, Ptr{Cvoid}, (Ptr{UInt8}, Ptr{UInt64}, Csize_t), dst+i, ref, len-i) + GC.@preserve ref memcpy(dst+i, Base.unsafe_convert(Ptr{Cvoid}, ref), len-i) t = _shl17(s1) s2 = _xor(s2, s0) s3 = _xor(s3, s1)