From 310677969f7ab4a5b2c31e49c44503e3f838a1bf Mon Sep 17 00:00:00 2001 From: Simon Byrne Date: Thu, 10 Aug 2023 09:25:44 -0700 Subject: [PATCH 01/56] Avoid race conditions with recursive rm (#50842) If two processes attempt to recursively delete a directory at the same time, then we can end up in a state where the initial `isdir` is `true`, but by the time it actually deletes the directory it is already gone. e.g. - https://buildkite.com/clima/climacore-ci/builds/2460#0189d254-76a9-474b-ad25-e5b16440d629/140-142 which is triggered by https://github.com/cjdoris/PackageExtensionCompat.jl/blob/636eb5a14ddf9134d004c93f598515903af26443/src/PackageExtensionCompat.jl#L59 - https://buildkite.com/clima/climacore-ci/builds/2457#0189c7fe-8872-40c5-9106-da2e621ff55a/139-150 which is triggered by https://github.com/JuliaGPU/GPUCompiler.jl/blob/06e670657d7ceebc1845d7c9534a8352c33490de/src/rtlib.jl#L152 I've been conservative and only applied this when `force=true`, but perhaps it should apply generally? (cherry picked from commit cbd3c89875afb0892c4e9e7559bca0254b2781d4) --- base/file.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/base/file.jl b/base/file.jl index 866e82b6e39c2..d6373c07e993a 100644 --- a/base/file.jl +++ b/base/file.jl @@ -303,7 +303,9 @@ function rm(path::AbstractString; force::Bool=false, recursive::Bool=false) try ret = ccall(:uv_fs_rmdir, Cint, (Ptr{Cvoid}, Ptr{Cvoid}, Cstring, Ptr{Cvoid}), C_NULL, req, path, C_NULL) uv_fs_req_cleanup(req) - ret < 0 && uv_error("rm($(repr(path)))", ret) + if ret < 0 && !(force && ret == Base.UV_ENOENT) + uv_error("rm($(repr(path)))", ret) + end nothing finally Libc.free(req) From 7e92d1499d9056bc00f4ba78736a904bf4453979 Mon Sep 17 00:00:00 2001 From: Kiran Date: Fri, 11 Aug 2023 09:29:07 -0400 Subject: [PATCH 02/56] Add a `threadpool` parameter to `Channel` constructor (#50858) Without this, the task created by a `Channel` will run in the threadpool of the creating task; in the REPL, this could be the interactive threadpool. On 1.8, without threadpools: ```julia % julia +1.8 -t 8 _ _ _ _(_)_ | Documentation: https://docs.julialang.org (_) | (_) (_) | _ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help. | | | | | | |/ _` | | | | |_| | | | (_| | | Version 1.8.5 (2023-01-08) _/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release |__/ | julia> for _ in 1:10 Channel{Int}(1; spawn=true) do _ Core.print("threadid=$(Threads.threadid())\n") end end threadid=2 threadid=5 threadid=2 threadid=2 threadid=1 threadid=6 threadid=7 threadid=8 threadid=3 threadid=4 ``` On 1.9, with no interactive threads: ```julia % julia +1.9 -t 8 _ _ _ _(_)_ | Documentation: https://docs.julialang.org (_) | (_) (_) | _ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help. | | | | | | |/ _` | | | | |_| | | | (_| | | Version 1.9.2 (2023-07-05) _/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release |__/ | julia> for _ in 1:10 Channel{Int}(1; spawn=true) do _ Core.print("threadid=$(Threads.threadid())\n") end end threadid=4 threadid=4 threadid=4 threadid=2 threadid=3 threadid=1 threadid=7 threadid=5 threadid=8 threadid=6 ``` On 1.9, with an interactive thread: ```julia % julia +1.9 -t 7,1 _ _ _ _(_)_ | Documentation: https://docs.julialang.org (_) | (_) (_) | _ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help. | | | | | | |/ _` | | | | |_| | | | (_| | | Version 1.9.2 (2023-07-05) _/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release |__/ | julia> for _ in 1:10 Channel{Int}(1; spawn=true) do _ Core.print("threadid=$(Threads.threadid())\n") end end threadid=1 threadid=1 threadid=1 threadid=1 threadid=1 threadid=1 threadid=1 threadid=1 threadid=1 threadid=1 ``` With this PR, the `:default` threadpool is used instead. ```julia % julia +master -t7,1 _ _ _ _(_)_ | Documentation: https://docs.julialang.org (_) | (_) (_) | _ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help. | | | | | | |/ _` | | | | |_| | | | (_| | | Version 1.11.0-DEV.244 (2023-08-09) _/ |\__'_|_|_|\__'_| | Commit d99f2496ff* (0 days old master) |__/ | julia> for _ in 1:10 Channel{Int}(1; spawn=true) do _ Core.print("threadid=$(Threads.threadid())\n") end end threadid=7 threadid=6 threadid=7 threadid=7 threadid=6 threadid=3 threadid=5 threadid=2 threadid=4 threadid=8 ``` And, the behavior can be overridden. ```julia % julia +master -t7,1 _ _ _ _(_)_ | Documentation: https://docs.julialang.org (_) | (_) (_) | _ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help. | | | | | | |/ _` | | | | |_| | | | (_| | | Version 1.11.0-DEV.244 (2023-08-09) _/ |\__'_|_|_|\__'_| | Commit d99f2496ff* (0 days old master) |__/ | julia> for _ in 1:10 Channel{Int}(1; spawn=true, threadpool=:interactive) do _ Core.print("threadid=$(Threads.threadid())\n") end end threadid=1 threadid=1 threadid=1 threadid=1 threadid=1 threadid=1 threadid=1 threadid=1 threadid=1 threadid=1 ``` --------- Co-authored-by: Nathan Daly (cherry picked from commit 555cd2304fb72669cc2cd92adb485306cc0caa7e) --- base/channels.jl | 28 +++++++++++++++++++++------- test/channel_threadpool.jl | 14 ++++++++++++++ test/channels.jl | 5 +++++ 3 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 test/channel_threadpool.jl diff --git a/base/channels.jl b/base/channels.jl index 1b5b427f92671..90dac37f41cb6 100644 --- a/base/channels.jl +++ b/base/channels.jl @@ -59,7 +59,7 @@ Channel(sz=0) = Channel{Any}(sz) # special constructors """ - Channel{T=Any}(func::Function, size=0; taskref=nothing, spawn=false) + Channel{T=Any}(func::Function, size=0; taskref=nothing, spawn=false, threadpool=nothing) Create a new task from `func`, bind it to a new channel of type `T` and size `size`, and schedule the task, all in a single call. @@ -70,9 +70,14 @@ The channel is automatically closed when the task terminates. If you need a reference to the created task, pass a `Ref{Task}` object via the keyword argument `taskref`. -If `spawn = true`, the Task created for `func` may be scheduled on another thread +If `spawn=true`, the `Task` created for `func` may be scheduled on another thread in parallel, equivalent to creating a task via [`Threads.@spawn`](@ref). +If `spawn=true` and the `threadpool` argument is not set, it defaults to `:default`. + +If the `threadpool` argument is set (to `:default` or `:interactive`), this implies +that `spawn=true` and the new Task is spawned to the specified threadpool. + Return a `Channel`. # Examples @@ -117,6 +122,9 @@ true In earlier versions of Julia, Channel used keyword arguments to set `size` and `T`, but those constructors are deprecated. +!!! compat "Julia 1.9" + The `threadpool=` argument was added in Julia 1.9. + ```jldoctest julia> chnl = Channel{Char}(1, spawn=true) do ch for c in "hello world" @@ -129,12 +137,18 @@ julia> String(collect(chnl)) "hello world" ``` """ -function Channel{T}(func::Function, size=0; taskref=nothing, spawn=false) where T +function Channel{T}(func::Function, size=0; taskref=nothing, spawn=false, threadpool=nothing) where T chnl = Channel{T}(size) task = Task(() -> func(chnl)) + if threadpool === nothing + threadpool = :default + else + spawn = true + end task.sticky = !spawn bind(chnl, task) if spawn + Threads._spawn_set_thrpool(task, threadpool) schedule(task) # start it on (potentially) another thread else yield(task) # immediately start it, yielding the current thread @@ -149,17 +163,17 @@ Channel(func::Function, args...; kwargs...) = Channel{Any}(func, args...; kwargs # of course not deprecated.) # We use `nothing` default values to check which arguments were set in order to throw the # deprecation warning if users try to use `spawn=` with `ctype=` or `csize=`. -function Channel(func::Function; ctype=nothing, csize=nothing, taskref=nothing, spawn=nothing) +function Channel(func::Function; ctype=nothing, csize=nothing, taskref=nothing, spawn=nothing, threadpool=nothing) # The spawn= keyword argument was added in Julia v1.3, and cannot be used with the # deprecated keyword arguments `ctype=` or `csize=`. - if (ctype !== nothing || csize !== nothing) && spawn !== nothing - throw(ArgumentError("Cannot set `spawn=` in the deprecated constructor `Channel(f; ctype=Any, csize=0)`. Please use `Channel{T=Any}(f, size=0; taskref=nothing, spawn=false)` instead!")) + if (ctype !== nothing || csize !== nothing) && (spawn !== nothing || threadpool !== nothing) + throw(ArgumentError("Cannot set `spawn=` or `threadpool=` in the deprecated constructor `Channel(f; ctype=Any, csize=0)`. Please use `Channel{T=Any}(f, size=0; taskref=nothing, spawn=false, threadpool=nothing)` instead!")) end # Set the actual default values for the arguments. ctype === nothing && (ctype = Any) csize === nothing && (csize = 0) spawn === nothing && (spawn = false) - return Channel{ctype}(func, csize; taskref=taskref, spawn=spawn) + return Channel{ctype}(func, csize; taskref=taskref, spawn=spawn, threadpool=threadpool) end closed_exception() = InvalidStateException("Channel is closed.", :closed) diff --git a/test/channel_threadpool.jl b/test/channel_threadpool.jl new file mode 100644 index 0000000000000..4509604087fa8 --- /dev/null +++ b/test/channel_threadpool.jl @@ -0,0 +1,14 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +using Test +using Base.Threads + +@testset "Task threadpools" begin + c = Channel{Symbol}() do c; put!(c, threadpool(current_task())); end + @test take!(c) === threadpool(current_task()) + c = Channel{Symbol}(spawn = true) do c; put!(c, threadpool(current_task())); end + @test take!(c) === :default + c = Channel{Symbol}(threadpool = :interactive) do c; put!(c, threadpool(current_task())); end + @test take!(c) === :interactive + @test_throws ArgumentError Channel{Symbol}(threadpool = :foo) do c; put!(c, :foo); end +end diff --git a/test/channels.jl b/test/channels.jl index dbda5cf069081..36fec7b842de1 100644 --- a/test/channels.jl +++ b/test/channels.jl @@ -107,6 +107,11 @@ end @test taskref[].sticky == false @test collect(c) == [0] end +let cmd = `$(Base.julia_cmd()) --depwarn=error --rr-detach --startup-file=no channel_threadpool.jl` + new_env = copy(ENV) + new_env["JULIA_NUM_THREADS"] = "1,1" + run(pipeline(setenv(cmd, new_env), stdout = stdout, stderr = stderr)) +end @testset "multiple concurrent put!/take! on a channel for different sizes" begin function testcpt(sz) From 48746e98b9fb8e2a5ebecd755a5bf4e83eb76829 Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Mon, 14 Aug 2023 13:37:10 +0200 Subject: [PATCH 03/56] Fix integer overflow in `isapprox` (#50730) Ensure that `isapprox` gives correct results when comparing an integer with another integer or with a float. For comparison between integers, the fix only works when keeping default values for `rtol` and `norm`, and with `atol < 1`. It is not possible to handle the (atypical) case where `norm !== abs`, but that's OK since the user is responsible for providing a safe function. It would be possible to handle the case where `rtol > 0` or `atol >= 1`, but with complex code which would check for overflow and handle all possible corner cases; it would work only for types defined in Base and would not be extensible by packages. So I'm not sure that's worth it. At least with PR fixes the most common case. Fixes https://github.com/JuliaLang/julia/issues/50380. (cherry picked from commit 5f03a18c615526348ef06bd0144a1498cb0b13a7) --- base/floatfuncs.jl | 15 ++++++++++++++- test/floatfuncs.jl | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/base/floatfuncs.jl b/base/floatfuncs.jl index 9b8ca4b04ee28..bac500955d916 100644 --- a/base/floatfuncs.jl +++ b/base/floatfuncs.jl @@ -304,7 +304,20 @@ true function isapprox(x::Number, y::Number; atol::Real=0, rtol::Real=rtoldefault(x,y,atol), nans::Bool=false, norm::Function=abs) - x == y || (isfinite(x) && isfinite(y) && norm(x-y) <= max(atol, rtol*max(norm(x), norm(y)))) || (nans && isnan(x) && isnan(y)) + x′, y′ = promote(x, y) # to avoid integer overflow + x == y || + (isfinite(x) && isfinite(y) && norm(x-y) <= max(atol, rtol*max(norm(x′), norm(y′)))) || + (nans && isnan(x) && isnan(y)) +end + +function isapprox(x::Integer, y::Integer; + atol::Real=0, rtol::Real=rtoldefault(x,y,atol), + nans::Bool=false, norm::Function=abs) + if norm === abs && atol < 1 && rtol == 0 + return x == y + else + return norm(x - y) <= max(atol, rtol*max(norm(x), norm(y))) + end end """ diff --git a/test/floatfuncs.jl b/test/floatfuncs.jl index 7e9d8021ac5df..321f1881371a3 100644 --- a/test/floatfuncs.jl +++ b/test/floatfuncs.jl @@ -209,3 +209,47 @@ end struct CustomNumber <: Number end @test !isnan(CustomNumber()) end + +@testset "isapprox and integer overflow" begin + for T in (Int8, Int16, Int32) + T === Int && continue + @test !isapprox(typemin(T), T(0)) + @test !isapprox(typemin(T), unsigned(T)(0)) + @test !isapprox(typemin(T), 0) + @test !isapprox(typemin(T), T(0), atol=0.99) + @test !isapprox(typemin(T), unsigned(T)(0), atol=0.99) + @test !isapprox(typemin(T), 0, atol=0.99) + @test_broken !isapprox(typemin(T), T(0), atol=1) + @test_broken !isapprox(typemin(T), unsigned(T)(0), atol=1) + @test !isapprox(typemin(T), 0, atol=1) + + @test !isapprox(typemin(T)+T(10), T(10)) + @test !isapprox(typemin(T)+T(10), unsigned(T)(10)) + @test !isapprox(typemin(T)+T(10), 10) + @test !isapprox(typemin(T)+T(10), T(10), atol=0.99) + @test !isapprox(typemin(T)+T(10), unsigned(T)(10), atol=0.99) + @test !isapprox(typemin(T)+T(10), 10, atol=0.99) + @test_broken !isapprox(typemin(T)+T(10), T(10), atol=1) + @test !isapprox(typemin(T)+T(10), unsigned(T)(10), atol=1) + @test !isapprox(typemin(T)+T(10), 10, atol=1) + + @test isapprox(typemin(T), 0.0, rtol=1) + end + for T in (Int, Int64, Int128) + @test !isapprox(typemin(T), T(0)) + @test !isapprox(typemin(T), unsigned(T)(0)) + @test !isapprox(typemin(T), T(0), atol=0.99) + @test !isapprox(typemin(T), unsigned(T)(0), atol=0.99) + @test_broken !isapprox(typemin(T), T(0), atol=1) + @test_broken !isapprox(typemin(T), unsigned(T)(0), atol=1) + + @test !isapprox(typemin(T)+T(10), T(10)) + @test !isapprox(typemin(T)+T(10), unsigned(T)(10)) + @test !isapprox(typemin(T)+T(10), T(10), atol=0.99) + @test !isapprox(typemin(T)+T(10), unsigned(T)(10), atol=0.99) + @test_broken !isapprox(typemin(T)+T(10), T(10), atol=1) + @test !isapprox(typemin(T)+T(10), unsigned(T)(10), atol=1) + + @test isapprox(typemin(T), 0.0, rtol=1) + end +end From 111dc03f1c3b54a0098c5be316238c4b51d63796 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Wed, 16 Aug 2023 15:27:18 -0400 Subject: [PATCH 04/56] Add note the `Task` about sticky bit (#50915) Update the docs for `Task` to mention the fact that they default to sticky. Co-authored-by: Gabriel Baraldi (cherry picked from commit 5466d3d082e0dd1608351fb5f9be6d5ec3ae7056) --- base/docs/basedocs.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/base/docs/basedocs.jl b/base/docs/basedocs.jl index fd8c35a5fdf76..b0aadb2b97fff 100644 --- a/base/docs/basedocs.jl +++ b/base/docs/basedocs.jl @@ -1744,6 +1744,12 @@ Create a `Task` (i.e. coroutine) to execute the given function `func` (which must be callable with no arguments). The task exits when this function returns. The task will run in the "world age" from the parent at construction when [`schedule`](@ref)d. +!!! warning + By default tasks will have the sticky bit set to true `t.sticky`. This models the + historic default for [`@async`](@ref). Sticky tasks can only be run on the worker thread + they are first scheduled on. To obtain the behavior of [`Threads.@spawn`](@ref) set the sticky + bit manually to `false`. + # Examples ```jldoctest julia> a() = sum(i for i in 1:1000); From ca5236166b631d95aa8d9b9b2951f697c33389a7 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Fri, 18 Aug 2023 15:54:26 -0400 Subject: [PATCH 05/56] Fix Pkg branch (release-1.10) --- stdlib/Pkg.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index 6551c7e24049f..06a2bfac5ebc8 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,4 +1,4 @@ -PKG_BRANCH = master +PKG_BRANCH = release-1.10 PKG_SHA1 = e8197dd0ed8132d4a7619f3657363c8415249c47 PKG_GIT_URL := https://github.com/JuliaLang/Pkg.jl.git PKG_TAR_URL = https://api.github.com/repos/JuliaLang/Pkg.jl/tarball/$1 From 747dea667da9fd59b08a502b5b4b0bdcf1f46c4b Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Fri, 18 Aug 2023 21:21:27 -0400 Subject: [PATCH 06/56] =?UTF-8?q?=F0=9F=A4=96=20[backports-release-1.10]?= =?UTF-8?q?=20Bump=20the=20Pkg=20stdlib=20from=20e8197dd0e=20to=2085d6ac61?= =?UTF-8?q?7=20(#50973)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Dilum Aluthge fix inference of PackageSpec constructor in presence of imprecise input types (#3585) --- .../Pkg-85d6ac617442c13eda85a5782a197b81ee86003a.tar.gz/md5 | 1 + .../Pkg-85d6ac617442c13eda85a5782a197b81ee86003a.tar.gz/sha512 | 1 + .../Pkg-e8197dd0ed8132d4a7619f3657363c8415249c47.tar.gz/md5 | 1 - .../Pkg-e8197dd0ed8132d4a7619f3657363c8415249c47.tar.gz/sha512 | 1 - stdlib/Pkg.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 deps/checksums/Pkg-85d6ac617442c13eda85a5782a197b81ee86003a.tar.gz/md5 create mode 100644 deps/checksums/Pkg-85d6ac617442c13eda85a5782a197b81ee86003a.tar.gz/sha512 delete mode 100644 deps/checksums/Pkg-e8197dd0ed8132d4a7619f3657363c8415249c47.tar.gz/md5 delete mode 100644 deps/checksums/Pkg-e8197dd0ed8132d4a7619f3657363c8415249c47.tar.gz/sha512 diff --git a/deps/checksums/Pkg-85d6ac617442c13eda85a5782a197b81ee86003a.tar.gz/md5 b/deps/checksums/Pkg-85d6ac617442c13eda85a5782a197b81ee86003a.tar.gz/md5 new file mode 100644 index 0000000000000..95df34217f215 --- /dev/null +++ b/deps/checksums/Pkg-85d6ac617442c13eda85a5782a197b81ee86003a.tar.gz/md5 @@ -0,0 +1 @@ +c46326a7aea479157b132517b0c88043 diff --git a/deps/checksums/Pkg-85d6ac617442c13eda85a5782a197b81ee86003a.tar.gz/sha512 b/deps/checksums/Pkg-85d6ac617442c13eda85a5782a197b81ee86003a.tar.gz/sha512 new file mode 100644 index 0000000000000..ed5e0ab33ac9f --- /dev/null +++ b/deps/checksums/Pkg-85d6ac617442c13eda85a5782a197b81ee86003a.tar.gz/sha512 @@ -0,0 +1 @@ +9b0460ee2bdc4b2844cff95425d46fdd0087f759dcd616c08e1c2c821244399744d0ba2f979034b744491fc84118984f5517874e040256e9b33b670a828188b9 diff --git a/deps/checksums/Pkg-e8197dd0ed8132d4a7619f3657363c8415249c47.tar.gz/md5 b/deps/checksums/Pkg-e8197dd0ed8132d4a7619f3657363c8415249c47.tar.gz/md5 deleted file mode 100644 index 8710722b5409c..0000000000000 --- a/deps/checksums/Pkg-e8197dd0ed8132d4a7619f3657363c8415249c47.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -f0e62f7b63dc9400caa2fec1b91b7889 diff --git a/deps/checksums/Pkg-e8197dd0ed8132d4a7619f3657363c8415249c47.tar.gz/sha512 b/deps/checksums/Pkg-e8197dd0ed8132d4a7619f3657363c8415249c47.tar.gz/sha512 deleted file mode 100644 index c92e62d861633..0000000000000 --- a/deps/checksums/Pkg-e8197dd0ed8132d4a7619f3657363c8415249c47.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -e48ee01791f58d41715fd44e16238d835315e930d3ef529dd3f3b5660935f7f0ca2c5163ec9c4e4d90e4ead5328f39e0bfffa88223c2094c8727460eac022cc1 diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index 06a2bfac5ebc8..27e21eb49b6f9 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,4 +1,4 @@ PKG_BRANCH = release-1.10 -PKG_SHA1 = e8197dd0ed8132d4a7619f3657363c8415249c47 +PKG_SHA1 = 85d6ac617442c13eda85a5782a197b81ee86003a PKG_GIT_URL := https://github.com/JuliaLang/Pkg.jl.git PKG_TAR_URL = https://api.github.com/repos/JuliaLang/Pkg.jl/tarball/$1 From 10cbf3cc855d4c6cfccd3144f07c7095927a2cdf Mon Sep 17 00:00:00 2001 From: Jeremie Knuesel Date: Sat, 8 Jul 2023 00:14:40 +0200 Subject: [PATCH 07/56] Improve documentation of sort-related functions (#48387) * document the `order` keyword in `sort!` * list explicitly the required properties of `lt` in `sort!` * clarify the sequence of "by" transformations if both `by` and `order` are given * show default values in the signatures for `searchsorted` and related functions * note that `by` is also applied to searched value in `searchsorted` and related * add `isunordered` to the manual (it's already exported) --------- Co-authored-by: Lilith Orion Hafner (cherry picked from commit a660798e47ed38c1f8039b0d7af3ff5a451f53e8) --- base/operators.jl | 12 +-- base/ordering.jl | 8 +- base/sort.jl | 209 +++++++++++++++++++++++++++----------- doc/src/base/base.md | 1 + doc/src/base/sort.md | 2 +- doc/src/manual/missing.md | 2 +- 6 files changed, 161 insertions(+), 73 deletions(-) diff --git a/base/operators.jl b/base/operators.jl index 3f51be737ca5c..3f0f8bc49b164 100644 --- a/base/operators.jl +++ b/base/operators.jl @@ -143,7 +143,7 @@ isequal(x::AbstractFloat, y::Real ) = (isnan(x) & isnan(y)) | signequal( isless(x, y) Test whether `x` is less than `y`, according to a fixed total order (defined together with -[`isequal`](@ref)). `isless` is not defined on all pairs of values `(x, y)`. However, if it +[`isequal`](@ref)). `isless` is not defined for pairs `(x, y)` of all types. However, if it is defined, it is expected to satisfy the following: - If `isless(x, y)` is defined, then so is `isless(y, x)` and `isequal(x, y)`, and exactly one of those three yields `true`. @@ -154,13 +154,13 @@ Values that are normally unordered, such as `NaN`, are ordered after regular values. [`missing`](@ref) values are ordered last. -This is the default comparison used by [`sort`](@ref). +This is the default comparison used by [`sort!`](@ref). # Implementation Non-numeric types with a total order should implement this function. Numeric types only need to implement it if they have special values such as `NaN`. Types with a partial order should implement [`<`](@ref). -See the documentation on [Alternate orderings](@ref) for how to define alternate +See the documentation on [Alternate Orderings](@ref) for how to define alternate ordering methods that can be used in sorting and related functions. # Examples @@ -335,6 +335,8 @@ New types with a canonical partial order should implement this function for two arguments of the new type. Types with a canonical total order should implement [`isless`](@ref) instead. +See also [`isunordered`](@ref). + # Examples ```jldoctest julia> 'a' < 'b' @@ -1352,7 +1354,7 @@ corresponding position in `collection`. To get a vector indicating whether each in `items` is in `collection`, wrap `collection` in a tuple or a `Ref` like this: `in.(items, Ref(collection))` or `items .∈ Ref(collection)`. -See also: [`∉`](@ref). +See also: [`∉`](@ref), [`insorted`](@ref), [`contains`](@ref), [`occursin`](@ref), [`issubset`](@ref). # Examples ```jldoctest @@ -1390,8 +1392,6 @@ julia> [1, 2] .∈ ([2, 3],) 0 1 ``` - -See also: [`insorted`](@ref), [`contains`](@ref), [`occursin`](@ref), [`issubset`](@ref). """ in diff --git a/base/ordering.jl b/base/ordering.jl index d0c9cb99f9c72..5383745b1dd1f 100644 --- a/base/ordering.jl +++ b/base/ordering.jl @@ -87,8 +87,8 @@ By(by) = By(by, Forward) """ Lt(lt) -`Ordering` which calls `lt(a, b)` to compare elements. `lt` should -obey the same rules as implementations of [`isless`](@ref). +`Ordering` that calls `lt(a, b)` to compare elements. `lt` must +obey the same rules as the `lt` parameter of [`sort!`](@ref). """ struct Lt{T} <: Ordering lt::T @@ -146,8 +146,8 @@ Construct an [`Ordering`](@ref) object from the same arguments used by Elements are first transformed by the function `by` (which may be [`identity`](@ref)) and are then compared according to either the function `lt` or an existing ordering `order`. `lt` should be [`isless`](@ref) or a function -which obeys similar rules. Finally, the resulting order is reversed if -`rev=true`. +that obeys the same rules as the `lt` parameter of [`sort!`](@ref). Finally, +the resulting order is reversed if `rev=true`. Passing an `lt` other than `isless` along with an `order` other than [`Base.Order.Forward`](@ref) or [`Base.Order.Reverse`](@ref) is not permitted, diff --git a/base/sort.jl b/base/sort.jl index 90f8755d3b1a4..786d8e110e6e2 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -65,8 +65,8 @@ end """ issorted(v, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward) -Test whether a vector is in sorted order. The `lt`, `by` and `rev` keywords modify what -order is considered to be sorted just as they do for [`sort`](@ref). +Test whether a collection is in sorted order. The keywords modify what +order is considered sorted, as described in the [`sort!`](@ref) documentation. # Examples ```jldoctest @@ -81,6 +81,9 @@ false julia> issorted([(1, "b"), (2, "a")], by = x -> x[2], rev=true) true + +julia> issorted([1, 2, -2, 3], by=abs) +true ``` """ issorted(itr; @@ -96,14 +99,17 @@ maybeview(v, k) = view(v, k) maybeview(v, k::Integer) = v[k] """ - partialsort!(v, k; by=, lt=, rev=false) + partialsort!(v, k; by=identity, lt=isless, rev=false) -Partially sort the vector `v` in place, according to the order specified by `by`, `lt` and -`rev` so that the value at index `k` (or range of adjacent values if `k` is a range) occurs +Partially sort the vector `v` in place so that the value at index `k` (or +range of adjacent values if `k` is a range) occurs at the position where it would appear if the array were fully sorted. If `k` is a single index, that value is returned; if `k` is a range, an array of values at those indices is returned. Note that `partialsort!` may not fully sort the input array. +For the keyword arguments, see the documentation of [`sort!`](@ref). + + # Examples ```jldoctest julia> a = [1, 2, 4, 3, 4] @@ -150,9 +156,9 @@ partialsort!(v::AbstractVector, k::Union{Integer,OrdinalRange}; partialsort!(v, k, ord(lt,by,rev,order)) """ - partialsort(v, k, by=, lt=, rev=false) + partialsort(v, k, by=identity, lt=isless, rev=false) -Variant of [`partialsort!`](@ref) which copies `v` before partially sorting it, thereby returning the +Variant of [`partialsort!`](@ref) that copies `v` before partially sorting it, thereby returning the same thing as `partialsort!` but leaving `v` unmodified. """ partialsort(v::AbstractVector, k::Union{Integer,OrdinalRange}; kws...) = @@ -161,7 +167,7 @@ partialsort(v::AbstractVector, k::Union{Integer,OrdinalRange}; kws...) = # reference on sorted binary search: # http://www.tbray.org/ongoing/When/200x/2003/03/22/Binary -# index of the first value of vector a that is greater than or equal to x; +# index of the first value of vector a that is greater than or equivalent to x; # returns lastindex(v)+1 if x is greater than all values in v. function searchsortedfirst(v::AbstractVector, x, lo::T, hi::T, o::Ordering)::keytype(v) where T<:Integer hi = hi + T(1) @@ -180,7 +186,7 @@ function searchsortedfirst(v::AbstractVector, x, lo::T, hi::T, o::Ordering)::key return lo end -# index of the last value of vector a that is less than or equal to x; +# index of the last value of vector a that is less than or equivalent to x; # returns firstindex(v)-1 if x is less than all values of v. function searchsortedlast(v::AbstractVector, x, lo::T, hi::T, o::Ordering)::keytype(v) where T<:Integer u = T(1) @@ -197,7 +203,7 @@ function searchsortedlast(v::AbstractVector, x, lo::T, hi::T, o::Ordering)::keyt return lo end -# returns the range of indices of v equal to x +# returns the range of indices of v equivalent to x # if v does not contain x, returns a 0-length range # indicating the insertion point of x function searchsorted(v::AbstractVector, x, ilo::T, ihi::T, o::Ordering)::UnitRange{keytype(v)} where T<:Integer @@ -290,16 +296,19 @@ for s in [:searchsortedfirst, :searchsortedlast, :searchsorted] end """ - searchsorted(a, x; by=, lt=, rev=false) + searchsorted(v, x; by=identity, lt=isless, rev=false) -Return the range of indices of `a` which compare as equal to `x` (using binary search) -according to the order specified by the `by`, `lt` and `rev` keywords, assuming that `a` -is already sorted in that order. Return an empty range located at the insertion point -if `a` does not contain values equal to `x`. +Return the range of indices in `v` where values are equivalent to `x`, or an +empty range located at the insertion point if `v` does not contain values +equivalent to `x`. The vector `v` must be sorted according to the order defined +by the keywords. Refer to [`sort!`](@ref) for the meaning of the keywords and +the definition of equivalence. Note that the `by` function is applied to the +searched value `x` as well as the values in `v`. -See [`sort!`](@ref) for an explanation of the keyword arguments `by`, `lt` and `rev`. +The range is generally found using binary search, but there are optimized +implementations for some inputs. -See also: [`insorted`](@ref), [`searchsortedfirst`](@ref), [`sort`](@ref), [`findall`](@ref). +See also: [`searchsortedfirst`](@ref), [`sort!`](@ref), [`insorted`](@ref), [`findall`](@ref). # Examples ```jldoctest @@ -324,15 +333,19 @@ julia> searchsorted([1=>"one", 2=>"two", 2=>"two", 4=>"four"], 2=>"two", by=firs """ searchsorted """ - searchsortedfirst(a, x; by=, lt=, rev=false) + searchsortedfirst(v, x; by=identity, lt=isless, rev=false) -Return the index of the first value in `a` greater than or equal to `x`, according to the -specified order. Return `lastindex(a) + 1` if `x` is greater than all values in `a`. -`a` is assumed to be sorted. +Return the index of the first value in `v` greater than or equivalent to `x`. +If `x` is greater than all values in `v`, return `lastindex(v) + 1`. -`insert!`ing `x` at this index will maintain sorted order. +The vector `v` must be sorted according to the order defined by the keywords. +`insert!`ing `x` at the returned index will maintain the sorted order. Refer to +[`sort!`](@ref) for the meaning of the keywords and the definition of +"greater than" and equivalence. Note that the `by` function is applied to the +searched value `x` as well as the values in `v`. -See [`sort!`](@ref) for an explanation of the keyword arguments `by`, `lt` and `rev`. +The index is generally found using binary search, but there are optimized +implementations for some inputs. See also: [`searchsortedlast`](@ref), [`searchsorted`](@ref), [`findfirst`](@ref). @@ -353,19 +366,24 @@ julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 9) # no match, insert at end julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 0) # no match, insert at start 1 -julia> searchsortedfirst([1=>"one", 2=>"two", 4=>"four"], 3=>"three", by=first) # Compare the keys of the pairs +julia> searchsortedfirst([1=>"one", 2=>"two", 4=>"four"], 3=>"three", by=first) # compare the keys of the pairs 3 ``` """ searchsortedfirst """ - searchsortedlast(a, x; by=, lt=, rev=false) + searchsortedlast(v, x; by=identity, lt=isless, rev=false) + +Return the index of the last value in `v` less than or equivalent to `x`. +If `x` is less than all values in `v` the function returns `firstindex(v) - 1`. -Return the index of the last value in `a` less than or equal to `x`, according to the -specified order. Return `firstindex(a) - 1` if `x` is less than all values in `a`. `a` is -assumed to be sorted. +The vector `v` must be sorted according to the order defined by the keywords. +Refer to [`sort!`](@ref) for the meaning of the keywords and the definition of +"less than" and equivalence. Note that the `by` function is applied to the +searched value `x` as well as the values in `v`. -See [`sort!`](@ref) for an explanation of the keyword arguments `by`, `lt` and `rev`. +The index is generally found using binary search, but there are optimized +implementations for some inputs # Examples ```jldoctest @@ -390,12 +408,16 @@ julia> searchsortedlast([1=>"one", 2=>"two", 4=>"four"], 3=>"three", by=first) # """ searchsortedlast """ - insorted(x, a; by=, lt=, rev=false) -> Bool + insorted(x, v; by=identity, lt=isless, rev=false) -> Bool + +Determine whether a vector `v` contains any value equivalent to `x`. +The vector `v` must be sorted according to the order defined by the keywords. +Refer to [`sort!`](@ref) for the meaning of the keywords and the definition of +equivalence. Note that the `by` function is applied to the searched value `x` +as well as the values in `v`. -Determine whether an item `x` is in the sorted collection `a`, in the sense that -it is [`==`](@ref) to one of the values of the collection according to the order -specified by the `by`, `lt` and `rev` keywords, assuming that `a` is already -sorted in that order, see [`sort`](@ref) for the keywords. +The check is generally done using binary search, but there are optimized +implementations for some inputs. See also [`in`](@ref). @@ -415,6 +437,9 @@ false julia> insorted(0, [1, 2, 4, 5, 5, 7]) # no match false + +julia> insorted(2=>"TWO", [1=>"one", 2=>"two", 4=>"four"], by=first) # compare the keys of the pairs +true ``` !!! compat "Julia 1.6" @@ -741,8 +766,8 @@ Insertion sort traverses the collection one element at a time, inserting each element into its correct, sorted position in the output vector. Characteristics: -* *stable*: preserves the ordering of elements which compare equal -(e.g. "a" and "A" in a sort of letters which ignores case). +* *stable*: preserves the ordering of elements that compare equal +(e.g. "a" and "A" in a sort of letters that ignores case). * *in-place* in memory. * *quadratic performance* in the number of elements to be sorted: it is well-suited to small collections but should not be used for large ones. @@ -981,8 +1006,8 @@ is treated as the first or last index of the input, respectively. `lo` and `hi` may be specified together as an `AbstractUnitRange`. Characteristics: - * *stable*: preserves the ordering of elements which compare equal - (e.g. "a" and "A" in a sort of letters which ignores case). + * *stable*: preserves the ordering of elements that compare equal + (e.g. "a" and "A" in a sort of letters that ignores case). * *not in-place* in memory. * *divide-and-conquer*: sort strategy similar to [`QuickSort`](@ref). * *linear runtime* if `length(lo:hi)` is constant @@ -1330,16 +1355,54 @@ defalg(v::AbstractArray{Union{}}) = DEFAULT_UNSTABLE # for method disambiguation """ sort!(v; alg::Algorithm=defalg(v), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward) -Sort the vector `v` in place. A stable algorithm is used by default. You can select a -specific algorithm to use via the `alg` keyword (see [Sorting Algorithms](@ref) for -available algorithms). The `by` keyword lets you provide a function that will be applied to -each element before comparison; the `lt` keyword allows providing a custom "less than" -function (note that for every `x` and `y`, only one of `lt(x,y)` and `lt(y,x)` can return -`true`); use `rev=true` to reverse the sorting order. `rev=true` preserves forward stability: -Elements that compare equal are not reversed. These options are independent and can -be used together in all possible combinations: if both `by` and `lt` are specified, the `lt` -function is applied to the result of the `by` function; `rev=true` reverses whatever -ordering specified via the `by` and `lt` keywords. +Sort the vector `v` in place. A stable algorithm is used by default: the +ordering of elements that compare equal is preserved. A specific algorithm can +be selected via the `alg` keyword (see [Sorting Algorithms](@ref) for available +algorithms). + +Elements are first transformed with the function `by` and then compared +according to either the function `lt` or the ordering `order`. Finally, the +resulting order is reversed if `rev=true` (this preserves forward stability: +elements that compare equal are not reversed). The current implemention applies +the `by` transformation before each comparison rather than once per element. + +Passing an `lt` other than `isless` along with an `order` other than +[`Base.Order.Forward`](@ref) or [`Base.Order.Reverse`](@ref) is not permitted, +otherwise all options are independent and can be used together in all possible +combinations. Note that `order` can also include a "by" transformation, in +which case it is applied after that defined with the `by` keyword. For more +information on `order` values see the documentation on [Alternate +Orderings](@ref). + +Relations between two elements are defined as follows (with "less" and +"greater" exchanged when `rev=true`): + +* `x` is less than `y` if `lt(by(x), by(y))` (or `Base.Order.lt(order, by(x), by(y))`) yields true. +* `x` is greater than `y` if `y` is less than `x`. +* `x` and `y` are equivalent if neither is less than the other ("incomparable" + is sometimes used as a synonym for "equivalent"). + +The result of `sort!` is sorted in the sense that every element is greater than +or equivalent to the previous one. + +The `lt` function must define a strict weak order, that is, it must be + +* irreflexive: `lt(x, x)` always yields `false`, +* asymmetric: if `lt(x, y)` yields `true` then `lt(y, x)` yields `false`, +* transitive: `lt(x, y) && lt(y, z)` implies `lt(x, z)`, +* transitive in equivalence: `!lt(x, y) && !lt(y, x)` and `!lt(y, z) && !lt(z, + y)` together imply `!lt(x, z) && !lt(z, x)`. In words: if `x` and `y` are + equivalent and `y` and `z` are equivalent then `x` and `z` must be + equivalent. + +For example `<` is a valid `lt` function for `Int` values but `≤` is not: it +violates irreflexivity. For `Float64` values even `<` is invalid as it violates +the fourth condition: `1.0` and `NaN` are equivalent and so are `NaN` and `2.0` +but `1.0` and `2.0` are not equivalent. + +See also [`sort`](@ref), [`sortperm`](@ref), [`sortslices`](@ref), +[`partialsort!`](@ref), [`partialsortperm`](@ref), [`issorted`](@ref), +[`searchsorted`](@ref), [`insorted`](@ref), [`Base.Order.ord`](@ref). # Examples ```jldoctest @@ -1366,6 +1429,29 @@ julia> v = [(1, "c"), (3, "a"), (2, "b")]; sort!(v, by = x -> x[2]); v (3, "a") (2, "b") (1, "c") + +julia> sort(0:3, by=x->x-2, order=Base.Order.By(abs)) # same as sort(0:3, by=abs(x->x-2)) +4-element Vector{Int64}: + 2 + 1 + 3 + 0 + +julia> sort([2, NaN, 1, NaN, 3]) # correct sort with default lt=isless +5-element Vector{Float64}: + 1.0 + 2.0 + 3.0 + NaN + NaN + +julia> sort([2, NaN, 1, NaN, 3], lt=<) # wrong sort due to invalid lt. This behavior is undefined. +5-element Vector{Float64}: + 2.0 + NaN + 1.0 + NaN + 3.0 ``` """ function sort!(v::AbstractVector{T}; @@ -1443,15 +1529,15 @@ merge(x::NTuple, y::NTuple, o::Ordering) = ## partialsortperm: the permutation to sort the first k elements of an array ## """ - partialsortperm(v, k; by=, lt=, rev=false) + partialsortperm(v, k; by=ientity, lt=isless, rev=false) Return a partial permutation `I` of the vector `v`, so that `v[I]` returns values of a fully sorted version of `v` at index `k`. If `k` is a range, a vector of indices is returned; if `k` is an integer, a single index is returned. The order is specified using the same -keywords as `sort!`. The permutation is stable, meaning that indices of equal elements -appear in ascending order. +keywords as `sort!`. The permutation is stable: the indices of equal elements +will appear in ascending order. -Note that this function is equivalent to, but more efficient than, calling `sortperm(...)[k]`. +This function is equivalent to, but more efficient than, calling `sortperm(...)[k]`. # Examples ```jldoctest @@ -1477,7 +1563,7 @@ partialsortperm(v::AbstractVector, k::Union{Integer,OrdinalRange}; kwargs...) = partialsortperm!(similar(Vector{eltype(k)}, axes(v,1)), v, k; kwargs...) """ - partialsortperm!(ix, v, k; by=, lt=, rev=false) + partialsortperm!(ix, v, k; by=identity, lt=isless, rev=false) Like [`partialsortperm`](@ref), but accepts a preallocated index vector `ix` the same size as `v`, which is used to store (a permutation of) the indices of `v`. @@ -1543,7 +1629,7 @@ end Return a permutation vector or array `I` that puts `A[I]` in sorted order along the given dimension. If `A` has more than one dimension, then the `dims` keyword argument must be specified. The order is specified using the same keywords as [`sort!`](@ref). The permutation is guaranteed to be stable even -if the sorting algorithm is unstable, meaning that indices of equal elements appear in +if the sorting algorithm is unstable: the indices of equal elements will appear in ascending order. See also [`sortperm!`](@ref), [`partialsortperm`](@ref), [`invperm`](@ref), [`indexin`](@ref). @@ -1777,7 +1863,8 @@ end sort!(A; dims::Integer, alg::Algorithm=defalg(A), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward) Sort the multidimensional array `A` along dimension `dims`. -See [`sort!`](@ref) for a description of possible keyword arguments. +See the one-dimensional version of [`sort!`](@ref) for a description of +possible keyword arguments. To sort slices of an array, refer to [`sortslices`](@ref). @@ -1931,8 +2018,8 @@ algorithm. Partial quick sort returns the smallest `k` elements sorted from smal to largest, finding them and sorting them using [`QuickSort`](@ref). Characteristics: - * *not stable*: does not preserve the ordering of elements which - compare equal (e.g. "a" and "A" in a sort of letters which + * *not stable*: does not preserve the ordering of elements that + compare equal (e.g. "a" and "A" in a sort of letters that ignores case). * *in-place* in memory. * *divide-and-conquer*: sort strategy similar to [`MergeSort`](@ref). @@ -1969,8 +2056,8 @@ Indicate that a sorting function should use the quick sort algorithm, which is *not* stable. Characteristics: - * *not stable*: does not preserve the ordering of elements which - compare equal (e.g. "a" and "A" in a sort of letters which + * *not stable*: does not preserve the ordering of elements that + compare equal (e.g. "a" and "A" in a sort of letters that ignores case). * *in-place* in memory. * *divide-and-conquer*: sort strategy similar to [`MergeSort`](@ref). @@ -1988,8 +2075,8 @@ subcollection at each step, until the entire collection has been recombined in sorted form. Characteristics: - * *stable*: preserves the ordering of elements which compare - equal (e.g. "a" and "A" in a sort of letters which ignores + * *stable*: preserves the ordering of elements that compare + equal (e.g. "a" and "A" in a sort of letters that ignores case). * *not in-place* in memory. * *divide-and-conquer* sort strategy. diff --git a/doc/src/base/base.md b/doc/src/base/base.md index 5851439408775..a4f90ba6c6d0a 100644 --- a/doc/src/base/base.md +++ b/doc/src/base/base.md @@ -129,6 +129,7 @@ Core.:(===) Core.isa Base.isequal Base.isless +Base.isunordered Base.ifelse Core.typeassert Core.typeof diff --git a/doc/src/base/sort.md b/doc/src/base/sort.md index 16e1839cf64a2..455a95d39617c 100644 --- a/doc/src/base/sort.md +++ b/doc/src/base/sort.md @@ -163,7 +163,7 @@ Base.Sort.defalg(::AbstractArray{<:Union{SmallInlineStrings, Missing}}) = Inline be stable since Julia 1.9. Previous versions had unstable edge cases when sorting numeric arrays. -## Alternate orderings +## Alternate Orderings By default, `sort` and related functions use [`isless`](@ref) to compare two elements in order to determine which should come first. The diff --git a/doc/src/manual/missing.md b/doc/src/manual/missing.md index 9bddcdfbb2ac2..8c8e801ccac9a 100644 --- a/doc/src/manual/missing.md +++ b/doc/src/manual/missing.md @@ -88,7 +88,7 @@ true ``` The [`isless`](@ref) operator is another exception: `missing` is considered -as greater than any other value. This operator is used by [`sort`](@ref), +as greater than any other value. This operator is used by [`sort!`](@ref), which therefore places `missing` values after all other values: ```jldoctest From 86f75bf1829d960173a9d508e1fb65bdf25d1d0f Mon Sep 17 00:00:00 2001 From: Lilith Orion Hafner Date: Mon, 10 Jul 2023 17:30:48 -0500 Subject: [PATCH 08/56] Revise sort.md and docstrings in sort.jl (#48363) Co-authored-by: Jeremie Knuesel (cherry picked from commit a134076bc85c78c4e46fa9a69b67665651a02a4d) --- base/sort.jl | 8 ++++---- doc/src/base/sort.md | 48 +++++++++++++++++++++----------------------- 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/base/sort.jl b/base/sort.jl index 786d8e110e6e2..abf0b9ed07682 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -2013,9 +2013,9 @@ struct MergeSortAlg <: Algorithm end """ PartialQuickSort{T <: Union{Integer,OrdinalRange}} -Indicate that a sorting function should use the partial quick sort -algorithm. Partial quick sort returns the smallest `k` elements sorted from smallest -to largest, finding them and sorting them using [`QuickSort`](@ref). +Indicate that a sorting function should use the partial quick sort algorithm. +`PartialQuickSort(k)` is like `QuickSort`, but is only required to find and +sort the elements that would end up in `v[k]` were `v` fully sorted. Characteristics: * *not stable*: does not preserve the ordering of elements that @@ -2024,7 +2024,7 @@ Characteristics: * *in-place* in memory. * *divide-and-conquer*: sort strategy similar to [`MergeSort`](@ref). - Note that `PartialQuickSort(k)` does not necessarily sort the whole array. For example, +Note that `PartialQuickSort(k)` does not necessarily sort the whole array. For example, ```jldoctest julia> x = rand(100); diff --git a/doc/src/base/sort.md b/doc/src/base/sort.md index 455a95d39617c..b9d333ef2a939 100644 --- a/doc/src/base/sort.md +++ b/doc/src/base/sort.md @@ -1,7 +1,7 @@ # Sorting and Related Functions -Julia has an extensive, flexible API for sorting and interacting with already-sorted arrays of -values. By default, Julia picks reasonable algorithms and sorts in standard ascending order: +Julia has an extensive, flexible API for sorting and interacting with already-sorted arrays +of values. By default, Julia picks reasonable algorithms and sorts in ascending order: ```jldoctest julia> sort([2,3,1]) @@ -11,7 +11,7 @@ julia> sort([2,3,1]) 3 ``` -You can easily sort in reverse order as well: +You can sort in reverse order as well: ```jldoctest julia> sort([2,3,1], rev=true) @@ -36,8 +36,8 @@ julia> a 3 ``` -Instead of directly sorting an array, you can compute a permutation of the array's indices that -puts the array into sorted order: +Instead of directly sorting an array, you can compute a permutation of the array's +indices that puts the array into sorted order: ```julia-repl julia> v = randn(5) @@ -65,7 +65,7 @@ julia> v[p] 0.382396 ``` -Arrays can easily be sorted according to an arbitrary transformation of their values: +Arrays can be sorted according to an arbitrary transformation of their values: ```julia-repl julia> sort(v, by=abs) @@ -101,9 +101,12 @@ julia> sort(v, alg=InsertionSort) 0.382396 ``` -All the sorting and order related functions rely on a "less than" relation defining a total order -on the values to be manipulated. The `isless` function is invoked by default, but the relation -can be specified via the `lt` keyword. +All the sorting and order related functions rely on a "less than" relation defining a +[strict weak order](https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings) +on the values to be manipulated. The `isless` function is invoked by default, but the +relation can be specified via the `lt` keyword, a function that takes two array elements +and returns `true` if and only if the first argument is "less than" the second. See +[`sort!`](@ref) and [Alternate Orderings](@ref) for more information. ## Sorting Functions @@ -165,22 +168,17 @@ Base.Sort.defalg(::AbstractArray{<:Union{SmallInlineStrings, Missing}}) = Inline ## Alternate Orderings -By default, `sort` and related functions use [`isless`](@ref) to compare two -elements in order to determine which should come first. The -[`Base.Order.Ordering`](@ref) abstract type provides a mechanism for defining -alternate orderings on the same set of elements: when calling a sorting function like -`sort`, an instance of `Ordering` can be provided with the keyword argument `order`. - -Instances of `Ordering` define a [total order](https://en.wikipedia.org/wiki/Total_order) -on a set of elements, so that for any elements `a`, `b`, `c` the following hold: - -* Exactly one of the following is true: `a` is less than `b`, `b` is less than - `a`, or `a` and `b` are equal (according to [`isequal`](@ref)). -* The relation is transitive - if `a` is less than `b` and `b` is less than `c` - then `a` is less than `c`. - -The [`Base.Order.lt`](@ref) function works as a generalization of `isless` to -test whether `a` is less than `b` according to a given order. +By default, `sort`, `searchsorted`, and related functions use [`isless`](@ref) to compare +two elements in order to determine which should come first. The +[`Base.Order.Ordering`](@ref) abstract type provides a mechanism for defining alternate +orderings on the same set of elements: when calling a sorting function like +`sort!`, an instance of `Ordering` can be provided with the keyword argument `order`. + +Instances of `Ordering` define an order through the [`Base.Order.lt`](@ref) +function, which works as a generalization of `isless`. +This function's behavior on custom `Ordering`s must satisfy all the conditions of a +[strict weak order](https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings). +See [`sort!`](@ref) for details and examples of valid and invalid `lt` functions. ```@docs Base.Order.Ordering From 344ef77c7d0f91ece2de2958a9baf5919341715e Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Mon, 31 Jul 2023 12:40:41 -0400 Subject: [PATCH 09/56] fix `CyclePadding(::DataType)` (#50719) We probably want to add a test for this code path. (cherry picked from commit f4cb8bc014f21e7066c72ca4f2c32c14fdf7a59f) --- base/reinterpretarray.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/base/reinterpretarray.jl b/base/reinterpretarray.jl index 74b888a39fd76..3844edc331c7c 100644 --- a/base/reinterpretarray.jl +++ b/base/reinterpretarray.jl @@ -720,7 +720,9 @@ function CyclePadding(T::DataType) a, s = datatype_alignment(T), sizeof(T) as = s + (a - (s % a)) % a pad = padding(T) - s != as && push!(pad, Padding(s, as - s)) + if s != as + pad = Core.svec(pad..., Padding(s, as - s)) + end CyclePadding(pad, as) end From 6867fa6c93db5b3cd55225436287012341c301c4 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 1 Aug 2023 23:32:13 -0400 Subject: [PATCH 10/56] inference: permit recursive type traits (#50694) We had a special case for Type that disallowed type trait recursion in favor of a pattern that almost never appears in code (only once in the compiler by accident where it doesn't matter). This was unnecessarily confusing and unexpected to predict what can infer, and made traits harder than necessary (such as Broadcast.ndims since 70fc3cdc11b). Fix #43296 Fix #43368 (cherry picked from commit 33e3d9f7de229a109cc2afeb72be2bb7931d3e79) --- base/compiler/typelimits.jl | 45 +++++++++++++++++++-------------- test/compiler/inference.jl | 50 +++++++++++++++++++++++++++++++++---- 2 files changed, 71 insertions(+), 24 deletions(-) diff --git a/base/compiler/typelimits.jl b/base/compiler/typelimits.jl index b648144ea3bd1..e24fd257f02a6 100644 --- a/base/compiler/typelimits.jl +++ b/base/compiler/typelimits.jl @@ -116,15 +116,32 @@ function _limit_type_size(@nospecialize(t), @nospecialize(c), sources::SimpleVec return Union{a, b} end elseif isa(t, DataType) - if isType(t) # see equivalent case in type_more_complex - tt = unwrap_unionall(t.parameters[1]) - if isa(tt, Union) || isa(tt, TypeVar) || isType(tt) - is_derived_type_from_any(tt, sources, depth + 1) && return t + if isType(t) + # Type is fairly important, so do not widen it as fast as other types if avoidable + tt = t.parameters[1] + ttu = unwrap_unionall(tt) # TODO: use argument_datatype(tt) after #50692 fixed + # must forbid nesting through this if we detect that potentially occurring + # we already know !is_derived_type_from_any so refuse to recurse here + if !isa(ttu, DataType) + return Type + elseif isType(ttu) + return Type{<:Type} + end + # try to peek into c to get a comparison object, but if we can't perhaps t is already simple enough on its own + # (this is slightly more permissive than type_more_complex implements for the same case). + if isType(c) + ct = c.parameters[1] else - isType(c) && (c = unwrap_unionall(c.parameters[1])) - type_more_complex(tt, c, sources, depth, 0, 0) || return t + ct = Union{} end - return Type + Qt = __limit_type_size(tt, ct, sources, depth + 1, 0) + Qt === Any && return Type + Qt === tt && return t + # Can't form Type{<:Qt} just yet, without first make sure we limited the depth + # enough, since this moves Qt outside of Type for is_derived_type_from_any + Qt = __limit_type_size(tt, ct, sources, depth + 2, 0) + Qt === Any && return Type + return Type{<:Qt} elseif isa(c, DataType) tP = t.parameters cP = c.parameters @@ -157,6 +174,7 @@ function _limit_type_size(@nospecialize(t), @nospecialize(c), sources::SimpleVec end end if allowed_tuplelen < 1 && t.name === Tuple.name + # forbid nesting Tuple{Tuple{Tuple...}} through this return Any end widert = t.name.wrapper @@ -247,18 +265,7 @@ function type_more_complex(@nospecialize(t), @nospecialize(c), sources::SimpleVe # base case for data types if isa(t, DataType) tP = t.parameters - if isType(t) - # Treat Type{T} and T as equivalent to allow taking typeof any - # source type (DataType) anywhere as Type{...}, as long as it isn't - # nesting as Type{Type{...}} - tt = unwrap_unionall(t.parameters[1]) - if isa(tt, Union) || isa(tt, TypeVar) || isType(tt) - return !is_derived_type_from_any(tt, sources, depth + 1) - else - isType(c) && (c = unwrap_unionall(c.parameters[1])) - return type_more_complex(tt, c, sources, depth, 0, 0) - end - elseif isa(c, DataType) && t.name === c.name + if isa(c, DataType) && t.name === c.name cP = c.parameters length(cP) < length(tP) && return true isempty(tP) && return false diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index 2ef172b3e3643..a34ba18e0d04e 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -60,7 +60,8 @@ end # issue #42835 @test !Core.Compiler.type_more_complex(Int, Any, Core.svec(), 1, 1, 1) @test !Core.Compiler.type_more_complex(Int, Type{Int}, Core.svec(), 1, 1, 1) -@test !Core.Compiler.type_more_complex(Type{Int}, Any, Core.svec(), 1, 1, 1) +@test Core.Compiler.type_more_complex(Type{Int}, Any, Core.svec(), 1, 1, 1) # maybe should be fixed? +@test Core.Compiler.limit_type_size(Type{Int}, Any, Union{}, 0, 0) == Type{Int} @test Core.Compiler.type_more_complex(Type{Type{Int}}, Type{Int}, Core.svec(Type{Int}), 1, 1, 1) @test Core.Compiler.type_more_complex(Type{Type{Int}}, Int, Core.svec(Type{Int}), 1, 1, 1) @test Core.Compiler.type_more_complex(Type{Type{Int}}, Any, Core.svec(), 1, 1, 1) @@ -71,22 +72,23 @@ end @test Core.Compiler.type_more_complex(ComplexF32, Type{ComplexF32}, Core.svec(), 1, 1, 1) @test !Core.Compiler.type_more_complex(Type{ComplexF32}, Any, Core.svec(Type{Type{ComplexF32}}), 1, 1, 1) @test Core.Compiler.type_more_complex(Type{ComplexF32}, Type{Type{ComplexF32}}, Core.svec(), 1, 1, 1) -@test !Core.Compiler.type_more_complex(Type{ComplexF32}, ComplexF32, Core.svec(), 1, 1, 1) +@test Core.Compiler.type_more_complex(Type{ComplexF32}, ComplexF32, Core.svec(), 1, 1, 1) +@test Core.Compiler.limit_type_size(Type{ComplexF32}, ComplexF32, Union{}, 1, 1) == Type{<:Complex} @test Core.Compiler.type_more_complex(Type{ComplexF32}, Any, Core.svec(), 1, 1, 1) @test Core.Compiler.type_more_complex(Type{Type{ComplexF32}}, Type{ComplexF32}, Core.svec(Type{ComplexF32}), 1, 1, 1) @test Core.Compiler.type_more_complex(Type{Type{ComplexF32}}, ComplexF32, Core.svec(ComplexF32), 1, 1, 1) @test Core.Compiler.type_more_complex(Type{Type{Type{ComplexF32}}}, Type{Type{ComplexF32}}, Core.svec(Type{ComplexF32}), 1, 1, 1) # n.b. Type{Type{Union{}} === Type{Core.TypeofBottom} -@test !Core.Compiler.type_more_complex(Type{Union{}}, Any, Core.svec(), 1, 1, 1) -@test !Core.Compiler.type_more_complex(Type{Type{Union{}}}, Any, Core.svec(), 1, 1, 1) +@test Core.Compiler.type_more_complex(Type{Union{}}, Any, Core.svec(), 1, 1, 1) +@test Core.Compiler.type_more_complex(Type{Type{Union{}}}, Any, Core.svec(), 1, 1, 1) @test Core.Compiler.type_more_complex(Type{Type{Type{Union{}}}}, Any, Core.svec(), 1, 1, 1) @test Core.Compiler.type_more_complex(Type{Type{Type{Union{}}}}, Type{Type{Union{}}}, Core.svec(Type{Type{Union{}}}), 1, 1, 1) @test Core.Compiler.type_more_complex(Type{Type{Type{Type{Union{}}}}}, Type{Type{Type{Union{}}}}, Core.svec(Type{Type{Type{Union{}}}}), 1, 1, 1) @test !Core.Compiler.type_more_complex(Type{1}, Type{2}, Core.svec(), 1, 1, 1) @test Core.Compiler.type_more_complex(Type{Union{Float32,Float64}}, Union{Float32,Float64}, Core.svec(Union{Float32,Float64}), 1, 1, 1) -@test !Core.Compiler.type_more_complex(Type{Union{Float32,Float64}}, Union{Float32,Float64}, Core.svec(Union{Float32,Float64}), 0, 1, 1) +@test Core.Compiler.type_more_complex(Type{Union{Float32,Float64}}, Union{Float32,Float64}, Core.svec(Union{Float32,Float64}), 0, 1, 1) @test Core.Compiler.type_more_complex(Type{<:Union{Float32,Float64}}, Type{Union{Float32,Float64}}, Core.svec(Union{Float32,Float64}), 1, 1, 1) @test Core.Compiler.type_more_complex(Type{<:Union{Float32,Float64}}, Any, Core.svec(Union{Float32,Float64}), 1, 1, 1) @@ -101,6 +103,44 @@ let # 40336 @test t !== r && t <: r end +@test Core.Compiler.limit_type_size(Type{Type{Type{Int}}}, Type, Union{}, 0, 0) == Type{<:Type} +@test Core.Compiler.limit_type_size(Type{Type{Int}}, Type, Union{}, 0, 0) == Type{<:Type} +@test Core.Compiler.limit_type_size(Type{Int}, Type, Union{}, 0, 0) == Type{Int} +@test Core.Compiler.limit_type_size(Type{<:Int}, Type, Union{}, 0, 0) == Type{<:Int} +@test Core.Compiler.limit_type_size(Type{ComplexF32}, ComplexF32, Union{}, 0, 0) == Type{<:Complex} # added nesting +@test Core.Compiler.limit_type_size(Type{ComplexF32}, Type{ComplexF64}, Union{}, 0, 0) == Type{ComplexF32} # base matches +@test Core.Compiler.limit_type_size(Type{ComplexF32}, Type, Union{}, 0, 0) == Type{<:Complex} +@test_broken Core.Compiler.limit_type_size(Type{<:ComplexF64}, Type, Union{}, 0, 0) == Type{<:Complex} +@test Core.Compiler.limit_type_size(Type{<:ComplexF64}, Type, Union{}, 0, 0) == Type #50692 +@test Core.Compiler.limit_type_size(Type{Union{ComplexF32,ComplexF64}}, Type, Union{}, 0, 0) == Type +@test_broken Core.Compiler.limit_type_size(Type{Union{ComplexF32,ComplexF64}}, Type, Union{}, 0, 0) == Type{<:Complex} #50692 +@test Core.Compiler.limit_type_size(Type{Union{Float32,Float64}}, Type, Union{}, 0, 0) == Type +@test Core.Compiler.limit_type_size(Type{Union{Int,Type{Int}}}, Type{Type{Int}}, Union{}, 0, 0) == Type +@test Core.Compiler.limit_type_size(Type{Union{Int,Type{Int}}}, Union{Type{Int},Type{Type{Int}}}, Union{}, 0, 0) == Type +@test Core.Compiler.limit_type_size(Type{Union{Int,Type{Int}}}, Type{Union{Type{Int},Type{Type{Int}}}}, Union{}, 0, 0) == Type{Union{Int, Type{Int}}} +@test Core.Compiler.limit_type_size(Type{Union{Int,Type{Int}}}, Type{Type{Int}}, Union{}, 0, 0) == Type + + +# issue #43296 #43296 +struct C43296{t,I} end +r43296(b) = r43296(typeof(b)) +r43296(::Type) = nothing +r43296(::Nothing) = nonexistent +r43296(::Type{C43296{c,d}}) where {c,d} = f43296(r43296(c), e) +f43296(::Nothing, :) = nothing +f43296(g, :) = h +k43296(b, j, :) = l +k43296(b, j, ::Nothing) = b +i43296(b, j) = k43296(b, j, r43296(j)) +@test only(Base.return_types(i43296, (Int, C43296{C43296{C43296{Val, Tuple}, Tuple}}))) == Int + +abstract type e43296{a, j} <: AbstractArray{a, j} end +abstract type b43296{a, j, c, d} <: e43296{a, j} end +struct h43296{a, j, f, d, i} <: b43296{a, j, f, d} end +Base.ndims(::Type{f}) where {f<:e43296} = ndims(supertype(f)) +Base.ndims(g::e43296) = ndims(typeof(g)) +@test only(Base.return_types(ndims, (h43296{Any, 0, Any, Int, Any},))) == Int + @test Core.Compiler.unionlen(Union{}) == 1 @test Core.Compiler.unionlen(Int8) == 1 @test Core.Compiler.unionlen(Union{Int8, Int16}) == 2 From 843937b0ba36c0cd2ffe6a76835f1ae2b72116b9 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Thu, 10 Aug 2023 13:28:14 +0400 Subject: [PATCH 11/56] Disallow non-index Integer types in isassigned (#50594) Extend #50587 to more general `AbstractArray`s. This is mainly to disallow `Bool` as an index in `isassigned`, as this isn't supported by `getindex`. After this ```julia julia> isassigned(rand(2,2), 1, true) ERROR: ArgumentError: invalid index: true of type Bool ``` which matches the behavior on v1.9. (cherry picked from commit b9913973f84b80e9125e37a0312a44bb38239b10) --- base/multidimensional.jl | 2 +- test/abstractarray.jl | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/base/multidimensional.jl b/base/multidimensional.jl index ba4e6eb12695a..2b4bf54d88826 100644 --- a/base/multidimensional.jl +++ b/base/multidimensional.jl @@ -1564,7 +1564,7 @@ end isassigned(a::AbstractArray, i::CartesianIndex) = isassigned(a, Tuple(i)...) function isassigned(A::AbstractArray, i::Union{Integer, CartesianIndex}...) - isa(i, Tuple{Vararg{Int}}) || return isassigned(A, CartesianIndex(i...)) + isa(i, Tuple{Vararg{Int}}) || return isassigned(A, CartesianIndex(to_indices(A, i))) @boundscheck checkbounds(Bool, A, i...) || return false S = IndexStyle(A) ninds = length(i) diff --git a/test/abstractarray.jl b/test/abstractarray.jl index 6e2294fec1f64..8a74f90f2d553 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -1844,3 +1844,9 @@ end # type stable [x;;] (https://github.com/JuliaLang/julia/issues/45952) f45952(x) = [x;;] @inferred f45952(1.0) + +@testset "isassigned with a Bool index" begin + A = zeros(2,2) + @test_throws "invalid index: true of type Bool" isassigned(A, 1, true) + @test_throws "invalid index: true of type Bool" isassigned(A, true) +end From 9477e1b0e9b2de03968f677da8f43fdfe3f84cae Mon Sep 17 00:00:00 2001 From: pchintalapudi <34727397+pchintalapudi@users.noreply.github.com> Date: Fri, 11 Aug 2023 14:15:23 +0000 Subject: [PATCH 12/56] Restrict COFF to a single thread when symbol count is high (#50874) (cherry picked from commit eb4416b16b8a865376da5c76451a4d60516e2c4a) --- src/aotcompile.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index 55d02edf7e3dd..d288586916560 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -650,6 +650,7 @@ static FunctionInfo getFunctionWeight(const Function &F) } struct ModuleInfo { + Triple triple; size_t globals; size_t funcs; size_t bbs; @@ -660,6 +661,7 @@ struct ModuleInfo { ModuleInfo compute_module_info(Module &M) { ModuleInfo info; + info.triple = Triple(M.getTargetTriple()); info.globals = 0; info.funcs = 0; info.bbs = 0; @@ -1406,6 +1408,13 @@ static unsigned compute_image_thread_count(const ModuleInfo &info) { LLVM_DEBUG(dbgs() << "32-bit systems are restricted to a single thread\n"); return 1; #endif + // COFF has limits on external symbols (even hidden) up to 65536. We reserve the last few + // for any of our other symbols that we insert during compilation. + if (info.triple.isOSBinFormatCOFF() && info.globals > 64000) { + LLVM_DEBUG(dbgs() << "COFF is restricted to a single thread for large images\n"); + return 1; + } + // This is not overridable because empty modules do occasionally appear, but they'll be very small and thus exit early to // known easy behavior. Plus they really don't warrant multiple threads if (info.weight < 1000) { From 03108f25a065e54956e9d8ded6fadebd50d528e8 Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Fri, 11 Aug 2023 16:20:48 -0300 Subject: [PATCH 13/56] Add default method for setmodifiers! (#50822) Fixes #50690 (cherry picked from commit 0eb13d70a3ea2419f96fd5db5676db91a54ede32) --- stdlib/REPL/src/REPL.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/stdlib/REPL/src/REPL.jl b/stdlib/REPL/src/REPL.jl index 218f89de798c8..efef8f1f9d459 100644 --- a/stdlib/REPL/src/REPL.jl +++ b/stdlib/REPL/src/REPL.jl @@ -519,6 +519,8 @@ active_module((; mistate)::LineEditREPL) = mistate === nothing ? Main : mistate. active_module(::AbstractREPL) = Main active_module(d::REPLDisplay) = active_module(d.repl) +setmodifiers!(c::CompletionProvider, m::LineEdit.Modifiers) = nothing + setmodifiers!(c::REPLCompletionProvider, m::LineEdit.Modifiers) = c.modifiers = m """ From 19fdccea42835f7ebc4b23486cba454f961ff5ac Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Mon, 14 Aug 2023 09:50:02 -0300 Subject: [PATCH 14/56] Remove weird Rational dispatch and add pi functions to list (#50850) Should fix https://github.com/JuliaLang/julia/issues/48735 (cherry picked from commit b7637287c50e1568582baea1f85b1b202c6d3f97) --- base/math.jl | 2 +- base/special/trig.jl | 32 ++++++++++++-------------------- test/math.jl | 6 ++++++ 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/base/math.jl b/base/math.jl index 71bd4949498b5..0f917dce7c99c 100644 --- a/base/math.jl +++ b/base/math.jl @@ -1571,7 +1571,7 @@ sincos(a::Float16) = Float16.(sincos(Float32(a))) for f in (:sin, :cos, :tan, :asin, :atan, :acos, :sinh, :cosh, :tanh, :asinh, :acosh, :atanh, :exp, :exp2, :exp10, :expm1, :log, :log2, :log10, :log1p, - :exponent, :sqrt, :cbrt) + :exponent, :sqrt, :cbrt, :sinpi, :cospi, :sincospi, :tanpi) @eval function ($f)(x::Real) xf = float(x) x === xf && throw(MethodError($f, (x,))) diff --git a/base/special/trig.jl b/base/special/trig.jl index 6463560caa3e5..50d3d69585217 100644 --- a/base/special/trig.jl +++ b/base/special/trig.jl @@ -789,16 +789,14 @@ Compute ``\\sin(\\pi x)`` more accurately than `sin(pi*x)`, especially for large See also [`sind`](@ref), [`cospi`](@ref), [`sincospi`](@ref). """ -function sinpi(_x::T) where T<:Union{IEEEFloat, Rational} +function sinpi(_x::T) where T<:IEEEFloat x = abs(_x) if !isfinite(x) isnan(x) && return x throw(DomainError(x, "`x` cannot be infinite.")) end # For large x, answers are all 1 or zero. - if T <: AbstractFloat - x >= maxintfloat(T) && return copysign(zero(T), _x) - end + x >= maxintfloat(T) && return copysign(zero(T), _x) # reduce to interval [0, 0.5] n = round(2*x) @@ -820,16 +818,14 @@ end Compute ``\\cos(\\pi x)`` more accurately than `cos(pi*x)`, especially for large `x`. """ -function cospi(x::T) where T<:Union{IEEEFloat, Rational} +function cospi(x::T) where T<:IEEEFloat x = abs(x) if !isfinite(x) isnan(x) && return x throw(DomainError(x, "`x` cannot be infinite.")) end # For large x, answers are all 1 or zero. - if T <: AbstractFloat - x >= maxintfloat(T) && return one(T) - end + x >= maxintfloat(T) && return one(T) # reduce to interval [0, 0.5] n = round(2*x) @@ -856,16 +852,14 @@ where `x` is in radians), returning a tuple `(sine, cosine)`. See also: [`cispi`](@ref), [`sincosd`](@ref), [`sinpi`](@ref). """ -function sincospi(_x::T) where T<:Union{IEEEFloat, Rational} +function sincospi(_x::T) where T<:IEEEFloat x = abs(_x) if !isfinite(x) isnan(x) && return x, x throw(DomainError(x, "`x` cannot be infinite.")) end # For large x, answers are all 1 or zero. - if T <: AbstractFloat - x >= maxintfloat(T) && return (copysign(zero(T), _x), one(T)) - end + x >= maxintfloat(T) && return (copysign(zero(T), _x), one(T)) # reduce to interval [0, 0.5] n = round(2*x) @@ -895,7 +889,7 @@ Compute ``\\tan(\\pi x)`` more accurately than `tan(pi*x)`, especially for large See also [`tand`](@ref), [`sinpi`](@ref), [`cospi`](@ref), [`sincospi`](@ref). """ -function tanpi(_x::T) where T<:Union{IEEEFloat, Rational} +function tanpi(_x::T) where T<:IEEEFloat # This is modified from sincospi. # Would it be faster or more accurate to make a tanpi_kernel? x = abs(_x) @@ -905,9 +899,7 @@ function tanpi(_x::T) where T<:Union{IEEEFloat, Rational} end # For large x, answers are all zero. # All integer values for floats larger than maxintfloat are even. - if T <: AbstractFloat - x >= maxintfloat(T) && return copysign(zero(T), _x) - end + x >= maxintfloat(T) && return copysign(zero(T), _x) # reduce to interval [0, 0.5] n = round(2*x) @@ -932,10 +924,10 @@ cospi(x::Integer) = isodd(x) ? -one(float(x)) : one(float(x)) tanpi(x::Integer) = x >= 0 ? (isodd(x) ? -zero(float(x)) : zero(float(x))) : (isodd(x) ? zero(float(x)) : -zero(float(x))) sincospi(x::Integer) = (sinpi(x), cospi(x)) -sinpi(x::Real) = sin(pi*x) -cospi(x::Real) = cos(pi*x) -sincospi(x::Real) = sincos(pi*x) -tanpi(x::Real) = tan(pi*x) +sinpi(x::AbstractFloat) = sin(pi*x) +cospi(x::AbstractFloat) = cos(pi*x) +sincospi(x::AbstractFloat) = sincos(pi*x) +tanpi(x::AbstractFloat) = tan(pi*x) tanpi(x::Complex) = sinpi(x) / cospi(x) # Is there a better way to do this? function sinpi(z::Complex{T}) where T diff --git a/test/math.jl b/test/math.jl index 19d9f7893a496..8e6afba0acfce 100644 --- a/test/math.jl +++ b/test/math.jl @@ -1558,3 +1558,9 @@ for T in (Float16, Float32, Float64) @test Core.Compiler.is_foldable(Base.infer_effects(^, (T,Int))) @test Core.Compiler.is_foldable(Base.infer_effects(^, (T,T))) end + +@testset "BigInt Rationals with special funcs" begin + @test sinpi(big(1//1)) == big(0.0) + @test tanpi(big(1//1)) == big(0.0) + @test cospi(big(1//1)) == big(-1.0) +end From 24f34d899d7ad8cf3fb0066ed196cd13364193f7 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Wed, 16 Aug 2023 06:36:38 -0400 Subject: [PATCH 15/56] Limit type-printing in MethodError (#50809) This applies the same `...` depth-based parametric truncation to the signature in `MethodError` that we use in printing stacktraces. Fixes #50803 (cherry picked from commit 90b4eedbf4b2beae0b12e6b8317e15ef0bb91126) --- base/client.jl | 4 ++-- base/errorshow.jl | 20 ++++++++++++-------- base/show.jl | 11 ++++++++--- test/errorshow.jl | 19 +++++++++++++++++++ 4 files changed, 41 insertions(+), 13 deletions(-) diff --git a/base/client.jl b/base/client.jl index 6e30c9991e45e..264c91cbabde7 100644 --- a/base/client.jl +++ b/base/client.jl @@ -103,8 +103,8 @@ scrub_repl_backtrace(stack::ExceptionStack) = ExceptionStack(Any[(;x.exception, backtrace = scrub_repl_backtrace(x.backtrace)) for x in stack]) istrivialerror(stack::ExceptionStack) = - length(stack) == 1 && length(stack[1].backtrace) ≤ 1 - # frame 1 = top level; assumes already went through scrub_repl_backtrace + length(stack) == 1 && length(stack[1].backtrace) ≤ 1 && !isa(stack[1].exception, MethodError) + # frame 1 = top level; assumes already went through scrub_repl_backtrace; MethodError see #50803 function display_error(io::IO, stack::ExceptionStack) printstyled(io, "ERROR: "; bold=true, color=Base.error_color()) diff --git a/base/errorshow.jl b/base/errorshow.jl index 2a02747dc2a2b..dd199f808e7ad 100644 --- a/base/errorshow.jl +++ b/base/errorshow.jl @@ -268,20 +268,24 @@ function showerror(io::IO, ex::MethodError) f_is_function = true end print(io, "no method matching ") - show_signature_function(io, isa(f, Type) ? Type{f} : typeof(f)) - print(io, "(") + iob = IOContext(IOBuffer(), io) # for type abbreviation as in #49795; some, like `convert(T, x)`, should not abbreviate + show_signature_function(iob, isa(f, Type) ? Type{f} : typeof(f)) + print(iob, "(") for (i, typ) in enumerate(arg_types_param) - print(io, "::", typ) - i == length(arg_types_param) || print(io, ", ") + print(iob, "::", typ) + i == length(arg_types_param) || print(iob, ", ") end if !isempty(kwargs) - print(io, "; ") + print(iob, "; ") for (i, (k, v)) in enumerate(kwargs) - print(io, k, "::", typeof(v)) - i == length(kwargs)::Int || print(io, ", ") + print(iob, k, "::", typeof(v)) + i == length(kwargs)::Int || print(iob, ", ") end end - print(io, ")") + print(iob, ")") + str = String(take!(unwrapcontext(iob)[1])) + str = type_limited_string_from_context(io, str) + print(io, str) end # catch the two common cases of element-wise addition and subtraction if (f === Base.:+ || f === Base.:-) && length(arg_types_param) == 2 diff --git a/base/show.jl b/base/show.jl index b259e95e54720..6db661879f791 100644 --- a/base/show.jl +++ b/base/show.jl @@ -2557,17 +2557,22 @@ function show_tuple_as_call(out::IO, name::Symbol, sig::Type; print_within_stacktrace(io, ")", bold=true) show_method_params(io, tv) str = String(take!(unwrapcontext(io)[1])) + str = type_limited_string_from_context(out, str) + print(out, str) + nothing +end + +function type_limited_string_from_context(out::IO, str::String) typelimitflag = get(out, :stacktrace_types_limited, nothing) if typelimitflag isa RefValue{Bool} - sz = get(out, :displaysize, (typemax(Int), typemax(Int)))::Tuple{Int, Int} + sz = get(out, :displaysize, displaysize(out))::Tuple{Int, Int} str_lim = type_depth_limit(str, max(sz[2], 120)) if sizeof(str_lim) < sizeof(str) typelimitflag[] = true end str = str_lim end - print(out, str) - nothing + return str end # limit nesting depth of `{ }` until string textwidth is less than `n` diff --git a/test/errorshow.jl b/test/errorshow.jl index 28ae3fd32365a..861d7dd0d68e3 100644 --- a/test/errorshow.jl +++ b/test/errorshow.jl @@ -549,6 +549,25 @@ foo_9965(x::Int) = 2x @test occursin("got unsupported keyword argument \"w\"", String(take!(io))) end +@testset "MethodError with long types (#50803)" begin + a = view(reinterpret(reshape, UInt8, PermutedDimsArray(rand(5, 7), (2, 1))), 2:3, 2:4, 1:4) # a mildly-complex type + function f50803 end + ex50803 = try + f50803(a, a, a, a, a, a) + catch e + e + end::MethodError + tlf = Ref(false) + str = sprint(Base.showerror, ex50803; context=(:displaysize=>(1000, 120), :stacktrace_types_limited=>tlf)) + @test tlf[] + @test occursin("::SubArray{…}", str) + tlf[] = false + str = sprint(Base.showerror, ex50803; context=(:displaysize=>(1000, 10000), :stacktrace_types_limited=>tlf)) + @test !tlf[] + str = sprint(Base.showerror, ex50803; context=(:displaysize=>(1000, 120))) + @test !occursin("::SubArray{…}", str) +end + # Issue #20556 import REPL module EnclosingModule From 0737e800d20011d964c1041d1d26328b7032c063 Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Thu, 17 Aug 2023 14:21:09 -0400 Subject: [PATCH 16/56] when widening tuple types in tmerge, only widen the complex parts (#50929) This is the part of https://github.com/JuliaLang/julia/pull/50927 required to fix https://github.com/JuliaLang/julia/issues/49249. Specifically, before this change `tmerge(Tuple{Any, Int}, Nothing)` would be `Union{Nothing, Tuple{Any, Int}}` but `tmerge(Tuple{BIG_UNION, Int}, Nothing)` would be `Union{Nothing, Tuple{Any, Any}}`. This feels bad intuitively because giving the compiler more type information led it to forget type information that it already knew about, and is especially damaging because it led to unnecessary type instability when iterating tuples with complex element types (because the iterator state should be inferrable as an `Int` even if you have no idea what the tuple type is). This is tagged for backport to 1.10 since it is a relatively unobtrusive change and it fixes the string regression in a more proper way. (cherry picked from commit 6e2e6d00258b930f5909d576f2b3510ffa49c4bf) --- base/compiler/typelimits.jl | 25 +++++++++++++------------ test/compiler/inference.jl | 15 +++++++++++++++ 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/base/compiler/typelimits.jl b/base/compiler/typelimits.jl index e24fd257f02a6..4552c4f815337 100644 --- a/base/compiler/typelimits.jl +++ b/base/compiler/typelimits.jl @@ -764,23 +764,24 @@ end return u end # don't let the slow widening of Tuple cause the whole type to grow too fast + # Specifically widen Tuple{..., Union{lots of stuff}...} to Tuple{..., Any, ...} for i in 1:length(types) if typenames[i] === Tuple.name - widen = unwrap_unionall(types[i]) - if isa(widen, DataType) && !isvatuple(widen) - widen = NTuple{length(widen.parameters), Any} - else - widen = Tuple - end - types[i] = widen - u = Union{types...} - if issimpleenoughtype(u) - return u + ti = types[i] + tip = (unwrap_unionall(types[i])::DataType).parameters + lt = length(tip) + p = Vector{Any}(undef, lt) + for j = 1:lt + ui = tip[j] + p[j] = (unioncomplexity(ui)==0) ? ui : isvarargtype(ui) ? Vararg : Any end - break + types[i] = rewrap_unionall(Tuple{p...}, ti) end end - # finally, just return the widest possible type + u = Union{types...} + if issimpleenoughtype(u) + return u + end return Any end diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index a34ba18e0d04e..1799dd94de74f 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -213,6 +213,21 @@ tmerge_test(Tuple{}, Tuple{Complex, Vararg{Union{ComplexF32, ComplexF64}}}, @test Core.Compiler.tmerge(Base.BitIntegerType, Union{}) === Base.BitIntegerType @test Core.Compiler.tmerge(Union{}, Base.BitIntegerType) === Base.BitIntegerType @test Core.Compiler.tmerge(Core.Compiler.fallback_ipo_lattice, Core.Compiler.InterConditional(1, Int, Union{}), Core.Compiler.InterConditional(2, String, Union{})) === Core.Compiler.Const(true) +# test issue behind https://github.com/JuliaLang/julia/issues/50458 +@test Core.Compiler.tmerge(Nothing, Tuple{Base.BitInteger, Int}) == Union{Nothing, Tuple{Any, Int}} +@test Core.Compiler.tmerge(Nothing, Tuple{Union{Char, String, SubString{String}, Symbol}, Int}) == Union{Nothing, Tuple{Any, Int}} +@test Core.Compiler.tmerge(Nothing, Tuple{Integer, Int}) == Union{Nothing, Tuple{Integer, Int}} + +# test that recursively more complicated types don't widen all the way to Any when there is a useful valid type upper bound +# Specificially test with base types of a trivial type, a simple union, a complicated union, and a tuple. +for T in (Nothing, Base.BitInteger, Union{Int, Int32, Int16, Int8}, Tuple{Int, Int}) + Ta, Tb = T, T + for i in 1:10 + Ta = Union{Tuple{Ta}, Nothing} + Tb = Core.Compiler.tmerge(Tuple{Tb}, Nothing) + @test Ta <: Tb <: Union{Nothing, Tuple} + end +end struct SomethingBits x::Base.BitIntegerType From cd69cc40b9a76bb6da0a4d1999297c830a116b59 Mon Sep 17 00:00:00 2001 From: Claire Foster Date: Fri, 18 Aug 2023 18:51:38 +1000 Subject: [PATCH 17/56] Bump JuliaSyntax to 0.4.6 (#50928) This is just a minor update fixing several small but annoying bugs people have noticed since JuliaSyntax was integrated. (cherry picked from commit 43164cfad745d31f11525e6a2229d3f63adfb3cf) --- deps/JuliaSyntax.version | 2 +- .../md5 | 1 + .../sha512 | 1 + .../md5 | 1 - .../sha512 | 1 - 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 deps/checksums/JuliaSyntax-045d156c44dbb87769c7416d049a7c08908539d4.tar.gz/md5 create mode 100644 deps/checksums/JuliaSyntax-045d156c44dbb87769c7416d049a7c08908539d4.tar.gz/sha512 delete mode 100644 deps/checksums/JuliaSyntax-8731bab86f14762cca8cf24224d8c7a6a89c21c5.tar.gz/md5 delete mode 100644 deps/checksums/JuliaSyntax-8731bab86f14762cca8cf24224d8c7a6a89c21c5.tar.gz/sha512 diff --git a/deps/JuliaSyntax.version b/deps/JuliaSyntax.version index b604eedaa43dd..e726eea3656fc 100644 --- a/deps/JuliaSyntax.version +++ b/deps/JuliaSyntax.version @@ -1,4 +1,4 @@ JULIASYNTAX_BRANCH = main -JULIASYNTAX_SHA1 = 8731bab86f14762cca8cf24224d8c7a6a89c21c5 +JULIASYNTAX_SHA1 = 045d156c44dbb87769c7416d049a7c08908539d4 JULIASYNTAX_GIT_URL := https://github.com/JuliaLang/JuliaSyntax.jl.git JULIASYNTAX_TAR_URL = https://api.github.com/repos/JuliaLang/JuliaSyntax.jl/tarball/$1 diff --git a/deps/checksums/JuliaSyntax-045d156c44dbb87769c7416d049a7c08908539d4.tar.gz/md5 b/deps/checksums/JuliaSyntax-045d156c44dbb87769c7416d049a7c08908539d4.tar.gz/md5 new file mode 100644 index 0000000000000..387ff43532a6e --- /dev/null +++ b/deps/checksums/JuliaSyntax-045d156c44dbb87769c7416d049a7c08908539d4.tar.gz/md5 @@ -0,0 +1 @@ +ac6d344a55ec798abd2b4fb68304794e diff --git a/deps/checksums/JuliaSyntax-045d156c44dbb87769c7416d049a7c08908539d4.tar.gz/sha512 b/deps/checksums/JuliaSyntax-045d156c44dbb87769c7416d049a7c08908539d4.tar.gz/sha512 new file mode 100644 index 0000000000000..a43f4dfd4bcae --- /dev/null +++ b/deps/checksums/JuliaSyntax-045d156c44dbb87769c7416d049a7c08908539d4.tar.gz/sha512 @@ -0,0 +1 @@ +89cf036193135337ae722e05dccbcd6535d2fa54316ae801a8c764f5f4eaf90fa95a644d024dbefb09433781043dfb4830a1679a049e47b7b35e9acd1e834b90 diff --git a/deps/checksums/JuliaSyntax-8731bab86f14762cca8cf24224d8c7a6a89c21c5.tar.gz/md5 b/deps/checksums/JuliaSyntax-8731bab86f14762cca8cf24224d8c7a6a89c21c5.tar.gz/md5 deleted file mode 100644 index 8bec9dde7fbae..0000000000000 --- a/deps/checksums/JuliaSyntax-8731bab86f14762cca8cf24224d8c7a6a89c21c5.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -6fdeb9332af478502be39af642027387 diff --git a/deps/checksums/JuliaSyntax-8731bab86f14762cca8cf24224d8c7a6a89c21c5.tar.gz/sha512 b/deps/checksums/JuliaSyntax-8731bab86f14762cca8cf24224d8c7a6a89c21c5.tar.gz/sha512 deleted file mode 100644 index 50c676f808c5c..0000000000000 --- a/deps/checksums/JuliaSyntax-8731bab86f14762cca8cf24224d8c7a6a89c21c5.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -fbb4ab0b99de7e1f86b918b401c2d42883a2bf8e80f6af4d6b85b7ca263d97cca1c47b25aca48359f14dee91b658684c0c590b7f20240bd9e0ce6e960ccf6647 From 1da3068401c60c31534fd2957ed911df2b987fa9 Mon Sep 17 00:00:00 2001 From: Alex Arslan Date: Fri, 18 Aug 2023 09:06:44 -0700 Subject: [PATCH 18/56] Update libssh2 patches (#50959) We're now using libssh2 v1.11.0 which includes the two patches we were carrying. The patches need to be dropped in order to build with `USE_BINARYBUILDER=0`. (This was my bad, I should have made this change as part of #50826, which updated libssh2 to v1.11.0.) (cherry picked from commit 315ff53a37556ae0d26188d73f97325be44c26de) --- deps/libssh2.mk | 16 +-- .../patches/libssh2-fix-import-lib-name.patch | 26 ----- deps/patches/libssh2-mbedtls-size_t.patch | 105 ++++++++++++++++++ deps/patches/libssh2-userauth-check.patch | 30 ----- 4 files changed, 109 insertions(+), 68 deletions(-) delete mode 100644 deps/patches/libssh2-fix-import-lib-name.patch create mode 100644 deps/patches/libssh2-mbedtls-size_t.patch delete mode 100644 deps/patches/libssh2-userauth-check.patch diff --git a/deps/libssh2.mk b/deps/libssh2.mk index d0174c0c090e2..3f9738515e4a1 100644 --- a/deps/libssh2.mk +++ b/deps/libssh2.mk @@ -30,21 +30,13 @@ endif LIBSSH2_SRC_PATH := $(SRCCACHE)/$(LIBSSH2_SRC_DIR) - # Apply patch to fix v1.10.0 CVE (https://github.com/libssh2/libssh2/issues/649), drop with v1.11 -$(LIBSSH2_SRC_PATH)/libssh2-userauth-check.patch-applied: $(LIBSSH2_SRC_PATH)/source-extracted +$(LIBSSH2_SRC_PATH)/libssh2-mbedtls-size_t.patch-applied: $(LIBSSH2_SRC_PATH)/source-extracted cd $(LIBSSH2_SRC_PATH) && \ - patch -p1 -f < $(SRCDIR)/patches/libssh2-userauth-check.patch - echo 1 > $@ - -# issue: https://github.com/JuliaLang/julia/issues/45645#issuecomment-1153214379 -# fix pr: https://github.com/libssh2/libssh2/pull/711 -$(LIBSSH2_SRC_PATH)/libssh2-fix-import-lib-name.patch-applied: $(LIBSSH2_SRC_PATH)/libssh2-userauth-check.patch-applied - cd $(LIBSSH2_SRC_PATH) && \ - patch -p1 -f < $(SRCDIR)/patches/libssh2-fix-import-lib-name.patch + patch -p1 -f < $(SRCDIR)/patches/libssh2-mbedtls-size_t.patch echo 1 > $@ $(BUILDDIR)/$(LIBSSH2_SRC_DIR)/build-configured: \ - $(LIBSSH2_SRC_PATH)/libssh2-fix-import-lib-name.patch-applied + $(LIBSSH2_SRC_PATH)/libssh2-mbedtls-size_t.patch-applied $(BUILDDIR)/$(LIBSSH2_SRC_DIR)/build-configured: $(LIBSSH2_SRC_PATH)/source-extracted mkdir -p $(dir $@) @@ -53,7 +45,7 @@ $(BUILDDIR)/$(LIBSSH2_SRC_DIR)/build-configured: $(LIBSSH2_SRC_PATH)/source-extr echo 1 > $@ $(BUILDDIR)/$(LIBSSH2_SRC_DIR)/build-compiled: $(BUILDDIR)/$(LIBSSH2_SRC_DIR)/build-configured - $(MAKE) -C $(dir $<) libssh2 + $(MAKE) -C $(dir $<) echo 1 > $@ $(BUILDDIR)/$(LIBSSH2_SRC_DIR)/build-checked: $(BUILDDIR)/$(LIBSSH2_SRC_DIR)/build-compiled diff --git a/deps/patches/libssh2-fix-import-lib-name.patch b/deps/patches/libssh2-fix-import-lib-name.patch deleted file mode 100644 index 15aafb58d2736..0000000000000 --- a/deps/patches/libssh2-fix-import-lib-name.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 3732420725efbf410df5863b91a09ca214ee18ba Mon Sep 17 00:00:00 2001 -From: "Y. Yang" -Date: Thu, 16 Jun 2022 19:16:37 +0800 -Subject: [PATCH] Fix DLL import library name - -https://aur.archlinux.org/packages/mingw-w64-libssh2 -https://cmake.org/cmake/help/latest/prop_tgt/IMPORT_PREFIX.html ---- - src/CMakeLists.txt | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt -index cb8fee1..17ecefd 100644 ---- a/src/CMakeLists.txt -+++ b/src/CMakeLists.txt -@@ -220,6 +220,7 @@ endif() - add_library(libssh2 ${SOURCES}) - # we want it to be called libssh2 on all platforms - set_target_properties(libssh2 PROPERTIES PREFIX "") -+set_target_properties(libssh2 PROPERTIES IMPORT_PREFIX "") - - target_compile_definitions(libssh2 PRIVATE ${PRIVATE_COMPILE_DEFINITIONS}) - target_include_directories(libssh2 --- -2.36.1 - diff --git a/deps/patches/libssh2-mbedtls-size_t.patch b/deps/patches/libssh2-mbedtls-size_t.patch new file mode 100644 index 0000000000000..502adf6bdf439 --- /dev/null +++ b/deps/patches/libssh2-mbedtls-size_t.patch @@ -0,0 +1,105 @@ +From 6cad964056848d3d78ccc74600fbff6298baddcb Mon Sep 17 00:00:00 2001 +From: Viktor Szakats +Date: Tue, 30 May 2023 17:28:03 +0000 +Subject: [PATCH 1/1] mbedtls: use more size_t to sync up with crypto.h + +Ref: 5a96f494ee0b00282afb2db2e091246fc5e1774a #846 #879 + +Fixes #1053 +Closes #1054 +--- + src/mbedtls.c | 14 ++++++++------ + src/mbedtls.h | 13 ++++++------- + 2 files changed, 14 insertions(+), 13 deletions(-) + +diff --git a/src/mbedtls.c b/src/mbedtls.c +index e387cdb..cd14a4b 100644 +--- a/src/mbedtls.c ++++ b/src/mbedtls.c +@@ -186,7 +186,7 @@ _libssh2_mbedtls_cipher_dtor(_libssh2_cipher_ctx *ctx) + int + _libssh2_mbedtls_hash_init(mbedtls_md_context_t *ctx, + mbedtls_md_type_t mdtype, +- const unsigned char *key, unsigned long keylen) ++ const unsigned char *key, size_t keylen) + { + const mbedtls_md_info_t *md_info; + int ret, hmac; +@@ -221,7 +221,7 @@ _libssh2_mbedtls_hash_final(mbedtls_md_context_t *ctx, unsigned char *hash) + } + + int +-_libssh2_mbedtls_hash(const unsigned char *data, unsigned long datalen, ++_libssh2_mbedtls_hash(const unsigned char *data, size_t datalen, + mbedtls_md_type_t mdtype, unsigned char *hash) + { + const mbedtls_md_info_t *md_info; +@@ -497,8 +497,9 @@ int + _libssh2_mbedtls_rsa_sha2_verify(libssh2_rsa_ctx * rsactx, + size_t hash_len, + const unsigned char *sig, +- unsigned long sig_len, +- const unsigned char *m, unsigned long m_len) ++ size_t sig_len, ++ const unsigned char *m, ++ size_t m_len) + { + int ret; + int md_type; +@@ -548,8 +549,9 @@ _libssh2_mbedtls_rsa_sha2_verify(libssh2_rsa_ctx * rsactx, + int + _libssh2_mbedtls_rsa_sha1_verify(libssh2_rsa_ctx * rsactx, + const unsigned char *sig, +- unsigned long sig_len, +- const unsigned char *m, unsigned long m_len) ++ size_t sig_len, ++ const unsigned char *m, ++ size_t m_len) + { + return _libssh2_mbedtls_rsa_sha2_verify(rsactx, SHA_DIGEST_LENGTH, + sig, sig_len, m, m_len); +diff --git a/src/mbedtls.h b/src/mbedtls.h +index d9592f7..03484da 100644 +--- a/src/mbedtls.h ++++ b/src/mbedtls.h +@@ -478,12 +478,12 @@ _libssh2_mbedtls_cipher_dtor(_libssh2_cipher_ctx *ctx); + int + _libssh2_mbedtls_hash_init(mbedtls_md_context_t *ctx, + mbedtls_md_type_t mdtype, +- const unsigned char *key, unsigned long keylen); ++ const unsigned char *key, size_t keylen); + + int + _libssh2_mbedtls_hash_final(mbedtls_md_context_t *ctx, unsigned char *hash); + int +-_libssh2_mbedtls_hash(const unsigned char *data, unsigned long datalen, ++_libssh2_mbedtls_hash(const unsigned char *data, size_t datalen, + mbedtls_md_type_t mdtype, unsigned char *hash); + + _libssh2_bn * +@@ -526,9 +526,8 @@ _libssh2_mbedtls_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa, + int + _libssh2_mbedtls_rsa_sha1_verify(libssh2_rsa_ctx *rsa, + const unsigned char *sig, +- unsigned long sig_len, +- const unsigned char *m, +- unsigned long m_len); ++ size_t sig_len, ++ const unsigned char *m, size_t m_len); + int + _libssh2_mbedtls_rsa_sha1_sign(LIBSSH2_SESSION *session, + libssh2_rsa_ctx *rsa, +@@ -540,8 +539,8 @@ int + _libssh2_mbedtls_rsa_sha2_verify(libssh2_rsa_ctx * rsactx, + size_t hash_len, + const unsigned char *sig, +- unsigned long sig_len, +- const unsigned char *m, unsigned long m_len); ++ size_t sig_len, ++ const unsigned char *m, size_t m_len); + int + _libssh2_mbedtls_rsa_sha2_sign(LIBSSH2_SESSION *session, + libssh2_rsa_ctx *rsa, +-- +2.31.0 + diff --git a/deps/patches/libssh2-userauth-check.patch b/deps/patches/libssh2-userauth-check.patch deleted file mode 100644 index 1dc6108ebece7..0000000000000 --- a/deps/patches/libssh2-userauth-check.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 37ee0aa214655b63e7869d1d74ff1ec9f9818a5e Mon Sep 17 00:00:00 2001 -From: Daniel Stenberg -Date: Fri, 17 Dec 2021 17:46:29 +0100 -Subject: [PATCH] userauth: check for too large userauth_kybd_auth_name_len - (#650) - -... before using it. - -Reported-by: MarcoPoloPie -Fixes #649 ---- - src/userauth.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/src/userauth.c b/src/userauth.c -index 40ef915..caa5635 100644 ---- a/src/userauth.c -+++ b/src/userauth.c -@@ -1769,6 +1769,11 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session, - if(session->userauth_kybd_data_len >= 5) { - /* string name (ISO-10646 UTF-8) */ - session->userauth_kybd_auth_name_len = _libssh2_ntohu32(s); -+ if(session->userauth_kybd_auth_name_len > -+ session->userauth_kybd_data_len - 5) -+ return _libssh2_error(session, -+ LIBSSH2_ERROR_OUT_OF_BOUNDARY, -+ "Bad keyboard auth name"); - s += 4; - } - else { From 1094763035de2762b507a38c796eae4679371ed3 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Thu, 29 Jun 2023 20:12:42 -0400 Subject: [PATCH 19/56] Add docs on task-specific buffering using multithreading (#48542) Co-authored-by: Mason Protter (cherry picked from commit 02f80c6bdf87edd90898f0af5828d68343340afa) From 3fa49905ba86165e202d7337ea451923e3b6c2b5 Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Mon, 14 Aug 2023 11:06:51 -0300 Subject: [PATCH 20/56] Make ranges more robust with unsigned indexes. (#50823) Fixes #44895 (cherry picked from commit 91093fe5b4bb4095ebb66698792631befe530a3c) --- base/range.jl | 4 ++-- base/twiceprecision.jl | 4 ++-- test/ranges.jl | 7 +++++++ test/testhelpers/OffsetArrays.jl | 4 ++-- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/base/range.jl b/base/range.jl index 356ae8ab49e57..67735ad930a2c 100644 --- a/base/range.jl +++ b/base/range.jl @@ -959,13 +959,13 @@ end # This is separate to make it useful even when running with --check-bounds=yes function unsafe_getindex(r::StepRangeLen{T}, i::Integer) where T i isa Bool && throw(ArgumentError("invalid index: $i of type Bool")) - u = i - r.offset + u = oftype(r.offset, i) - r.offset T(r.ref + u*r.step) end function _getindex_hiprec(r::StepRangeLen, i::Integer) # without rounding by T i isa Bool && throw(ArgumentError("invalid index: $i of type Bool")) - u = i - r.offset + u = oftype(r.offset, i) - r.offset r.ref + u*r.step end diff --git a/base/twiceprecision.jl b/base/twiceprecision.jl index d91a04371230c..5c10b1d2b5027 100644 --- a/base/twiceprecision.jl +++ b/base/twiceprecision.jl @@ -478,7 +478,7 @@ function unsafe_getindex(r::StepRangeLen{T,<:TwicePrecision,<:TwicePrecision}, i # Very similar to _getindex_hiprec, but optimized to avoid a 2nd call to add12 @inline i isa Bool && throw(ArgumentError("invalid index: $i of type Bool")) - u = i - r.offset + u = oftype(r.offset, i) - r.offset shift_hi, shift_lo = u*r.step.hi, u*r.step.lo x_hi, x_lo = add12(r.ref.hi, shift_hi) T(x_hi + (x_lo + (shift_lo + r.ref.lo))) @@ -486,7 +486,7 @@ end function _getindex_hiprec(r::StepRangeLen{<:Any,<:TwicePrecision,<:TwicePrecision}, i::Integer) i isa Bool && throw(ArgumentError("invalid index: $i of type Bool")) - u = i - r.offset + u = oftype(r.offset, i) - r.offset shift_hi, shift_lo = u*r.step.hi, u*r.step.lo x_hi, x_lo = add12(r.ref.hi, shift_hi) x_hi, x_lo = add12(x_hi, x_lo + (shift_lo + r.ref.lo)) diff --git a/test/ranges.jl b/test/ranges.jl index 94548a76326d8..85f6a04634a14 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -2510,3 +2510,10 @@ end @test collect(r) isa Vector{Int} @test collect(r) == r end + +@testset "unsigned index #44895" begin + x = range(-1,1,length=11) + @test x[UInt(1)] == -1.0 + a = StepRangeLen(1,2,3,2) + @test a[UInt(1)] == -1 +end diff --git a/test/testhelpers/OffsetArrays.jl b/test/testhelpers/OffsetArrays.jl index 705bd07b2878c..2f7d29b53a199 100644 --- a/test/testhelpers/OffsetArrays.jl +++ b/test/testhelpers/OffsetArrays.jl @@ -142,7 +142,7 @@ end @inline function Base.getindex(r::IdOffsetRange, i::Integer) i isa Bool && throw(ArgumentError("invalid index: $i of type Bool")) @boundscheck checkbounds(r, i) - @inbounds eltype(r)(r.parent[i - r.offset] + r.offset) + @inbounds eltype(r)(r.parent[oftype(r.offset, i) - r.offset] + r.offset) end # Logical indexing following https://github.com/JuliaLang/julia/pull/31829 @@ -592,7 +592,7 @@ Base.fill!(A::OffsetArray, x) = parent_call(Ap -> fill!(Ap, x), A) # Δi = i - first(r) # i′ = first(r.parent) + Δi # and one obtains the result below. -parentindex(r::IdOffsetRange, i) = i - r.offset +parentindex(r::IdOffsetRange, i) = oftype(r.offset, i) - r.offset @propagate_inbounds Base.getindex(A::OffsetArray{<:Any,0}) = A.parent[] From 07faa2296a13b9cebb0ea3e5a8b44693f4234f8b Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Fri, 18 Aug 2023 23:58:20 -0400 Subject: [PATCH 21/56] =?UTF-8?q?=F0=9F=A4=96=20[backports-release-1.10]?= =?UTF-8?q?=20Bump=20the=20Pkg=20stdlib=20from=2085d6ac617=20to=2061257864?= =?UTF-8?q?f=20(#50978)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Dilum Aluthge --- .../Pkg-61257864fe97ef14ad13eca3b6e0ac1a040c9236.tar.gz/md5 | 1 + .../Pkg-61257864fe97ef14ad13eca3b6e0ac1a040c9236.tar.gz/sha512 | 1 + .../Pkg-85d6ac617442c13eda85a5782a197b81ee86003a.tar.gz/md5 | 1 - .../Pkg-85d6ac617442c13eda85a5782a197b81ee86003a.tar.gz/sha512 | 1 - stdlib/Pkg.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 deps/checksums/Pkg-61257864fe97ef14ad13eca3b6e0ac1a040c9236.tar.gz/md5 create mode 100644 deps/checksums/Pkg-61257864fe97ef14ad13eca3b6e0ac1a040c9236.tar.gz/sha512 delete mode 100644 deps/checksums/Pkg-85d6ac617442c13eda85a5782a197b81ee86003a.tar.gz/md5 delete mode 100644 deps/checksums/Pkg-85d6ac617442c13eda85a5782a197b81ee86003a.tar.gz/sha512 diff --git a/deps/checksums/Pkg-61257864fe97ef14ad13eca3b6e0ac1a040c9236.tar.gz/md5 b/deps/checksums/Pkg-61257864fe97ef14ad13eca3b6e0ac1a040c9236.tar.gz/md5 new file mode 100644 index 0000000000000..d8580f44b07fd --- /dev/null +++ b/deps/checksums/Pkg-61257864fe97ef14ad13eca3b6e0ac1a040c9236.tar.gz/md5 @@ -0,0 +1 @@ +a913b67362f54d8ad7b1721f84ca15bf diff --git a/deps/checksums/Pkg-61257864fe97ef14ad13eca3b6e0ac1a040c9236.tar.gz/sha512 b/deps/checksums/Pkg-61257864fe97ef14ad13eca3b6e0ac1a040c9236.tar.gz/sha512 new file mode 100644 index 0000000000000..c7626f9c0e0cf --- /dev/null +++ b/deps/checksums/Pkg-61257864fe97ef14ad13eca3b6e0ac1a040c9236.tar.gz/sha512 @@ -0,0 +1 @@ +6c7efb3c1972e576e2a0aac3992e468047ab67b02bdfacf94fc42d77a9d7cd3c06df54c54b31427abe751d480eafcd0ef47ed388ee08e3eafd932cd3d23e09c8 diff --git a/deps/checksums/Pkg-85d6ac617442c13eda85a5782a197b81ee86003a.tar.gz/md5 b/deps/checksums/Pkg-85d6ac617442c13eda85a5782a197b81ee86003a.tar.gz/md5 deleted file mode 100644 index 95df34217f215..0000000000000 --- a/deps/checksums/Pkg-85d6ac617442c13eda85a5782a197b81ee86003a.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -c46326a7aea479157b132517b0c88043 diff --git a/deps/checksums/Pkg-85d6ac617442c13eda85a5782a197b81ee86003a.tar.gz/sha512 b/deps/checksums/Pkg-85d6ac617442c13eda85a5782a197b81ee86003a.tar.gz/sha512 deleted file mode 100644 index ed5e0ab33ac9f..0000000000000 --- a/deps/checksums/Pkg-85d6ac617442c13eda85a5782a197b81ee86003a.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -9b0460ee2bdc4b2844cff95425d46fdd0087f759dcd616c08e1c2c821244399744d0ba2f979034b744491fc84118984f5517874e040256e9b33b670a828188b9 diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index 27e21eb49b6f9..62468ccf4f6d9 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,4 +1,4 @@ PKG_BRANCH = release-1.10 -PKG_SHA1 = 85d6ac617442c13eda85a5782a197b81ee86003a +PKG_SHA1 = 61257864fe97ef14ad13eca3b6e0ac1a040c9236 PKG_GIT_URL := https://github.com/JuliaLang/Pkg.jl.git PKG_TAR_URL = https://api.github.com/repos/JuliaLang/Pkg.jl/tarball/$1 From 972259ee378a8f6b7ffb88050c63078a89ff0259 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Fri, 18 Aug 2023 12:09:43 -0400 Subject: [PATCH 22/56] types: fix hash values of Vararg (#50932) Fixes #50455 (cherry picked from commit c239e9966a30797949d856c18b14e4e5421a90e9) --- src/jltypes.c | 15 ++++++++------- test/tuple.jl | 5 +++++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/jltypes.c b/src/jltypes.c index 444923f600569..024d0be74e659 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -1593,19 +1593,20 @@ static unsigned typekey_hash(jl_typename_t *tn, jl_value_t **key, size_t n, int int failed = nofail; for (j = 0; j < n; j++) { jl_value_t *p = key[j]; + size_t repeats = 1; if (jl_is_vararg(p)) { jl_vararg_t *vm = (jl_vararg_t*)p; - if (!nofail && vm->N) - return 0; - // 0x064eeaab is just a randomly chosen constant - hash = bitmix(vm->N ? type_hash(vm->N, &failed) : 0x064eeaab, hash); - if (failed && !nofail) - return 0; + if (vm->N && jl_is_long(vm->N)) + repeats = jl_unbox_long(vm->N); + else + hash = bitmix(0x064eeaab, hash); // 0x064eeaab is just a randomly chosen constant p = vm->T ? vm->T : (jl_value_t*)jl_any_type; } - hash = bitmix(type_hash(p, &failed), hash); + unsigned hashp = type_hash(p, &failed); if (failed && !nofail) return 0; + while (repeats--) + hash = bitmix(hashp, hash); } hash = bitmix(~tn->hash, hash); return hash ? hash : 1; diff --git a/test/tuple.jl b/test/tuple.jl index 71770b6a553c2..8ff311928b6b8 100644 --- a/test/tuple.jl +++ b/test/tuple.jl @@ -796,3 +796,8 @@ namedtup = (;a=1, b=2, c=3) @test_throws ErrorException("Tuple field type cannot be Union{}") Tuple{Vararg{Union{},1}} @test Tuple{} <: Tuple{Vararg{Union{},N}} where N @test !(Tuple{} >: Tuple{Vararg{Union{},N}} where N) + +@test Val{Tuple{T,T,T} where T} === Val{Tuple{Vararg{T,3}} where T} +@test Val{Tuple{Vararg{T,4}} where T} === Val{Tuple{T,T,T,T} where T} +@test Val{Tuple{Int64, Vararg{Int32,N}} where N} === Val{Tuple{Int64, Vararg{Int32}}} +@test Val{Tuple{Int32, Vararg{Int64}}} === Val{Tuple{Int32, Vararg{Int64,N}} where N} From f58e1ebe0803e3ad09afd31e167509690a2d69c3 Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Sun, 20 Aug 2023 23:29:14 -0400 Subject: [PATCH 23/56] fix incorrect results in `expm1(::Union{Float16, Float32})` (#50989) `unsafe_trunc(UInt, -1.0)` is unspecified behavior but worked fine on apple and AMD so we didn't notice??? This has been very broken since 1.7. (cherry picked from commit 61ebaf6643c57cef8b3bb4013b75931608ac6344) --- base/special/exp.jl | 4 ++-- test/math.jl | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/base/special/exp.jl b/base/special/exp.jl index 9cca6f568305f..8e940a4d85ad9 100644 --- a/base/special/exp.jl +++ b/base/special/exp.jl @@ -460,7 +460,7 @@ function expm1(x::Float32) end x = Float64(x) N_float = round(x*Ln2INV(Float64)) - N = unsafe_trunc(UInt64, N_float) + N = unsafe_trunc(Int64, N_float) r = muladd(N_float, Ln2(Float64), x) hi = evalpoly(r, (1.0, .5, 0.16666667546642386, 0.041666183019487026, 0.008332997481506921, 0.0013966479175977883, 0.0002004037059220124)) @@ -477,7 +477,7 @@ function expm1(x::Float16) return Float16(x*evalpoly(x, (1f0, .5f0, 0.16666628f0, 0.04166785f0, 0.008351848f0, 0.0013675707f0))) end N_float = round(x*Ln2INV(Float32)) - N = unsafe_trunc(UInt32, N_float) + N = unsafe_trunc(Int32, N_float) r = muladd(N_float, Ln2(Float32), x) hi = evalpoly(r, (1f0, .5f0, 0.16666667f0, 0.041665863f0, 0.008333111f0, 0.0013981499f0, 0.00019983904f0)) small_part = r*hi diff --git a/test/math.jl b/test/math.jl index 8e6afba0acfce..6a41fa55c4f47 100644 --- a/test/math.jl +++ b/test/math.jl @@ -188,6 +188,7 @@ end @test exp10(x) ≈ exp10(big(x)) @test exp2(x) ≈ exp2(big(x)) @test expm1(x) ≈ expm1(big(x)) + @test expm1(T(-1.1)) ≈ expm1(big(T(-1.1))) @test hypot(x,y) ≈ hypot(big(x),big(y)) @test hypot(x,x,y) ≈ hypot(hypot(big(x),big(x)),big(y)) @test hypot(x,x,y,y) ≈ hypot(hypot(big(x),big(x)),hypot(big(y),big(y))) From 13ec3ceb57c5392d0e556d1d35b26966c6b8f16d Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Mon, 21 Aug 2023 09:06:00 -0400 Subject: [PATCH 24/56] Separate foreign threads into a :foreign threadpool (#50912) Co-authored-by: Gabriel Baraldi Co-authored-by: Dilum Aluthge (cherry picked from commit 8be469e275a455ca894fdc5fad8a80aafb359544) --- base/partr.jl | 7 +++++++ base/task.jl | 2 +- base/threadingconstructs.jl | 14 ++++++++++---- src/partr.c | 2 +- src/threading.c | 2 +- 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/base/partr.jl b/base/partr.jl index a02272ceab202..c77a24bdcc003 100644 --- a/base/partr.jl +++ b/base/partr.jl @@ -95,6 +95,7 @@ end function multiq_insert(task::Task, priority::UInt16) tpid = ccall(:jl_get_task_threadpoolid, Int8, (Any,), task) + @assert tpid > -1 heap_p = multiq_size(tpid) tp = tpid + 1 @@ -131,6 +132,9 @@ function multiq_deletemin() tid = Threads.threadid() tp = ccall(:jl_threadpoolid, Int8, (Int16,), tid-1) + 1 + if tp == 0 # Foreign thread + return nothing + end tpheaps = heaps[tp] @label retry @@ -182,6 +186,9 @@ end function multiq_check_empty() tid = Threads.threadid() tp = ccall(:jl_threadpoolid, Int8, (Int16,), tid-1) + 1 + if tp == 0 # Foreign thread + return true + end for i = UInt32(1):length(heaps[tp]) if heaps[tp][i].ntasks != 0 return false diff --git a/base/task.jl b/base/task.jl index db2f7e22bce67..137b0f7c4a3f6 100644 --- a/base/task.jl +++ b/base/task.jl @@ -794,7 +794,7 @@ function enq_work(t::Task) else @label not_sticky tp = Threads.threadpool(t) - if Threads.threadpoolsize(tp) == 1 + if tp === :foreign || Threads.threadpoolsize(tp) == 1 # There's only one thread in the task's assigned thread pool; # use its work queue. tid = (tp === :interactive) ? 1 : Threads.threadpoolsize(:interactive)+1 diff --git a/base/threadingconstructs.jl b/base/threadingconstructs.jl index 7a70132a9dccc..a5a1294be049b 100644 --- a/base/threadingconstructs.jl +++ b/base/threadingconstructs.jl @@ -63,6 +63,8 @@ function _tpid_to_sym(tpid::Int8) return :interactive elseif tpid == 1 return :default + elseif tpid == -1 + return :foreign else throw(ArgumentError("Unrecognized threadpool id $tpid")) end @@ -73,6 +75,8 @@ function _sym_to_tpid(tp::Symbol) return Int8(0) elseif tp === :default return Int8(1) + elseif tp == :foreign + return Int8(-1) else throw(ArgumentError("Unrecognized threadpool name `$(repr(tp))`")) end @@ -81,7 +85,7 @@ end """ Threads.threadpool(tid = threadid()) -> Symbol -Returns the specified thread's threadpool; either `:default` or `:interactive`. +Returns the specified thread's threadpool; either `:default`, `:interactive`, or `:foreign`. """ function threadpool(tid = threadid()) tpid = ccall(:jl_threadpoolid, Int8, (Int16,), tid-1) @@ -108,6 +112,8 @@ See also: `BLAS.get_num_threads` and `BLAS.set_num_threads` in the function threadpoolsize(pool::Symbol = :default) if pool === :default || pool === :interactive tpid = _sym_to_tpid(pool) + elseif pool == :foreign + error("Threadpool size of `:foreign` is indeterminant") else error("invalid threadpool specified") end @@ -151,7 +157,7 @@ function threading_run(fun, static) else # TODO: this should be the current pool (except interactive) if there # are ever more than two pools. - ccall(:jl_set_task_threadpoolid, Cint, (Any, Int8), t, _sym_to_tpid(:default)) + @assert ccall(:jl_set_task_threadpoolid, Cint, (Any, Int8), t, _sym_to_tpid(:default)) == 1 end tasks[i] = t schedule(t) @@ -357,10 +363,10 @@ end function _spawn_set_thrpool(t::Task, tp::Symbol) tpid = _sym_to_tpid(tp) - if _nthreads_in_pool(tpid) == 0 + if tpid == -1 || _nthreads_in_pool(tpid) == 0 tpid = _sym_to_tpid(:default) end - ccall(:jl_set_task_threadpoolid, Cint, (Any, Int8), t, tpid) + @assert ccall(:jl_set_task_threadpoolid, Cint, (Any, Int8), t, tpid) == 1 nothing end diff --git a/src/partr.c b/src/partr.c index 428389db7f218..0f3b581f5122f 100644 --- a/src/partr.c +++ b/src/partr.c @@ -70,7 +70,7 @@ JL_DLLEXPORT int jl_set_task_tid(jl_task_t *task, int16_t tid) JL_NOTSAFEPOINT JL_DLLEXPORT int jl_set_task_threadpoolid(jl_task_t *task, int8_t tpid) JL_NOTSAFEPOINT { - if (tpid < 0 || tpid >= jl_n_threadpools) + if (tpid < -1 || tpid >= jl_n_threadpools) return 0; task->threadpoolid = tpid; return 1; diff --git a/src/threading.c b/src/threading.c index e2eb686e3061a..4faa8a0a2dc46 100644 --- a/src/threading.c +++ b/src/threading.c @@ -332,7 +332,7 @@ JL_DLLEXPORT int8_t jl_threadpoolid(int16_t tid) JL_NOTSAFEPOINT if (tid < n) return (int8_t)i; } - return 0; // everything else uses threadpool 0 (though does not become part of any threadpool) + return -1; // everything else uses threadpool -1 (does not belong to any threadpool) } jl_ptls_t jl_init_threadtls(int16_t tid) From c1126a3475fb62aa611ef543223fe28e7a37f357 Mon Sep 17 00:00:00 2001 From: Wimmerer Date: Tue, 22 Aug 2023 17:49:53 -0400 Subject: [PATCH 25/56] add ORIGIN to rpath on Linux/FreeBSD (cherry picked from commit 89a7c953b23f1ddfe5b3a4de6fdf9194a2b5edea) --- deps/libsuitesparse.mk | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/deps/libsuitesparse.mk b/deps/libsuitesparse.mk index 16d4919031ca5..e547030c16a08 100644 --- a/deps/libsuitesparse.mk +++ b/deps/libsuitesparse.mk @@ -24,6 +24,10 @@ LIBSUITESPARSE_CMAKE_FLAGS := $(CMAKE_COMMON) \ -DLAPACK_LIBRARIES="$(build_shlibdir)/libblastrampoline.$(SHLIB_EXT)" \ -DLAPACK_LINKER_FLAGS="blastrampoline" +ifneq (,$(findstring $(OS),Linux FreeBSD)) +LIBSUITESPARSE_CMAKE_FLAGS += -DCMAKE_INSTALL_RPATH="\$$ORIGIN" +endif + $(SRCCACHE)/SuiteSparse-$(LIBSUITESPARSE_VER).tar.gz: | $(SRCCACHE) $(JLDOWNLOAD) $@ https://github.com/Wimmerer/SuiteSparse/archive/v$(LIBSUITESPARSE_VER).tar.gz From 0e01cb5ff7176cd5cd43b73ef7f45d320174e148 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Wed, 2 Aug 2023 11:41:19 -0400 Subject: [PATCH 26/56] cat: remove unused promote_eltype methods that confuse inference (#50753) These cannot be reached, but they would imply this function might return Bottom, which it cannot. Fix #50550 (cherry picked from commit edff86adfa870b4d7ab86e94c9b1291e3796c5de) --- base/abstractarray.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index cfc5078cb005e..8f1274d960e41 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -1584,10 +1584,12 @@ replace_in_print_matrix(A::AbstractVector,i::Integer,j::Integer,s::AbstractStrin eltypeof(x) = typeof(x) eltypeof(x::AbstractArray) = eltype(x) -promote_eltypeof() = Bottom +promote_eltypeof() = error() +promote_eltypeof(v1) = eltypeof(v1) promote_eltypeof(v1, vs...) = promote_type(eltypeof(v1), promote_eltypeof(vs...)) -promote_eltype() = Bottom +promote_eltype() = error() +promote_eltype(v1) = eltype(v1) promote_eltype(v1, vs...) = promote_type(eltype(v1), promote_eltype(vs...)) #TODO: ERROR CHECK From 77900dcb9331703fdd6a1f61aa1842ce94763eeb Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Thu, 24 Aug 2023 14:12:05 -0400 Subject: [PATCH 27/56] fix #50562, regression in `in` of tuple of Symbols (#51009) fix #50562 --- base/tuple.jl | 1 - test/tuple.jl | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/base/tuple.jl b/base/tuple.jl index 59fe2c1e531e1..ae5de41586848 100644 --- a/base/tuple.jl +++ b/base/tuple.jl @@ -607,7 +607,6 @@ any(x::Tuple{Bool, Bool, Bool}) = x[1]|x[2]|x[3] # a version of `in` esp. for NamedTuple, to make it pure, and not compiled for each tuple length function sym_in(x::Symbol, @nospecialize itr::Tuple{Vararg{Symbol}}) - @noinline @_total_meta for y in itr y === x && return true diff --git a/test/tuple.jl b/test/tuple.jl index 8ff311928b6b8..b806667fd9d0a 100644 --- a/test/tuple.jl +++ b/test/tuple.jl @@ -763,6 +763,12 @@ g42457(a, b) = Base.isequal(a, b) ? 1 : 2.0 # issue #46049: setindex(::Tuple) regression @inferred Base.setindex((1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16), 42, 1) +# issue #50562 +f50562(r) = in(:i_backward, r[]) +r50562 = Ref((:b_back, :foofakgka, :i_backw)) +f50562(r50562) +@test @allocated(f50562(r50562)) == 0 + # issue #47326 function fun1_47326(args...) head..., tail = args From 27f60cda79cc5af2fc7ce2650f1e5a74ae5b7c6f Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Fri, 25 Aug 2023 21:28:34 +0200 Subject: [PATCH 28/56] Bump Statistics stdlib (#51053) For some reason we haven't updated Statistics since April. Diff: https://github.com/JuliaStats/Statistics.jl/compare/a3feba2bb63f06b7f40024185e9fa5f6385e2510...08562cb8abbe67829e437aa8533994121c350c05 --- .../md5 | 1 + .../sha512 | 1 + .../md5 | 1 - .../sha512 | 1 - stdlib/Statistics.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 deps/checksums/Statistics-08562cb8abbe67829e437aa8533994121c350c05.tar.gz/md5 create mode 100644 deps/checksums/Statistics-08562cb8abbe67829e437aa8533994121c350c05.tar.gz/sha512 delete mode 100644 deps/checksums/Statistics-a3feba2bb63f06b7f40024185e9fa5f6385e2510.tar.gz/md5 delete mode 100644 deps/checksums/Statistics-a3feba2bb63f06b7f40024185e9fa5f6385e2510.tar.gz/sha512 diff --git a/deps/checksums/Statistics-08562cb8abbe67829e437aa8533994121c350c05.tar.gz/md5 b/deps/checksums/Statistics-08562cb8abbe67829e437aa8533994121c350c05.tar.gz/md5 new file mode 100644 index 0000000000000..42034e9a42a7b --- /dev/null +++ b/deps/checksums/Statistics-08562cb8abbe67829e437aa8533994121c350c05.tar.gz/md5 @@ -0,0 +1 @@ +735ae885122f81261ecf152853ce0b42 diff --git a/deps/checksums/Statistics-08562cb8abbe67829e437aa8533994121c350c05.tar.gz/sha512 b/deps/checksums/Statistics-08562cb8abbe67829e437aa8533994121c350c05.tar.gz/sha512 new file mode 100644 index 0000000000000..dbec046cef091 --- /dev/null +++ b/deps/checksums/Statistics-08562cb8abbe67829e437aa8533994121c350c05.tar.gz/sha512 @@ -0,0 +1 @@ +42dd950bd59fa91540806f9c1b26c391373ef4508106e59f875ca256805951784fe4469b834978a6d20ab340eb979da97b0f4b32c8f53626b03d7b3f84e4cb5a diff --git a/deps/checksums/Statistics-a3feba2bb63f06b7f40024185e9fa5f6385e2510.tar.gz/md5 b/deps/checksums/Statistics-a3feba2bb63f06b7f40024185e9fa5f6385e2510.tar.gz/md5 deleted file mode 100644 index 7e7a889eecd29..0000000000000 --- a/deps/checksums/Statistics-a3feba2bb63f06b7f40024185e9fa5f6385e2510.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -6564297a5f5971231809bf9940f68b98 diff --git a/deps/checksums/Statistics-a3feba2bb63f06b7f40024185e9fa5f6385e2510.tar.gz/sha512 b/deps/checksums/Statistics-a3feba2bb63f06b7f40024185e9fa5f6385e2510.tar.gz/sha512 deleted file mode 100644 index bbe9b8bed6371..0000000000000 --- a/deps/checksums/Statistics-a3feba2bb63f06b7f40024185e9fa5f6385e2510.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -22d14c82a30f3ec7af09028423cc823808abf86918d5707fd1fcf6ca20dea7871589da9b22e462d194e86fcee380f549aeb65f585048f00bf23281786b17e040 diff --git a/stdlib/Statistics.version b/stdlib/Statistics.version index 27197b12be54c..05d7839223924 100644 --- a/stdlib/Statistics.version +++ b/stdlib/Statistics.version @@ -1,4 +1,4 @@ STATISTICS_BRANCH = master -STATISTICS_SHA1 = a3feba2bb63f06b7f40024185e9fa5f6385e2510 +STATISTICS_SHA1 = 08562cb8abbe67829e437aa8533994121c350c05 STATISTICS_GIT_URL := https://github.com/JuliaStats/Statistics.jl.git STATISTICS_TAR_URL = https://api.github.com/repos/JuliaStats/Statistics.jl/tarball/$1 From 25d58ad4f6c3c39bfb01f70deaed00a788b9e4d9 Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Sun, 27 Aug 2023 22:46:12 -0400 Subject: [PATCH 29/56] =?UTF-8?q?=F0=9F=A4=96=20[backports-release-1.10]?= =?UTF-8?q?=20Bump=20the=20Pkg=20stdlib=20from=2061257864f=20to=20a3621e97?= =?UTF-8?q?8=20(#51076)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Pkg-61257864fe97ef14ad13eca3b6e0ac1a040c9236.tar.gz/md5 | 1 - .../Pkg-61257864fe97ef14ad13eca3b6e0ac1a040c9236.tar.gz/sha512 | 1 - .../Pkg-a3621e97860bd26955dbbe7282c443882f43d9c3.tar.gz/md5 | 1 + .../Pkg-a3621e97860bd26955dbbe7282c443882f43d9c3.tar.gz/sha512 | 1 + stdlib/Pkg.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 deps/checksums/Pkg-61257864fe97ef14ad13eca3b6e0ac1a040c9236.tar.gz/md5 delete mode 100644 deps/checksums/Pkg-61257864fe97ef14ad13eca3b6e0ac1a040c9236.tar.gz/sha512 create mode 100644 deps/checksums/Pkg-a3621e97860bd26955dbbe7282c443882f43d9c3.tar.gz/md5 create mode 100644 deps/checksums/Pkg-a3621e97860bd26955dbbe7282c443882f43d9c3.tar.gz/sha512 diff --git a/deps/checksums/Pkg-61257864fe97ef14ad13eca3b6e0ac1a040c9236.tar.gz/md5 b/deps/checksums/Pkg-61257864fe97ef14ad13eca3b6e0ac1a040c9236.tar.gz/md5 deleted file mode 100644 index d8580f44b07fd..0000000000000 --- a/deps/checksums/Pkg-61257864fe97ef14ad13eca3b6e0ac1a040c9236.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -a913b67362f54d8ad7b1721f84ca15bf diff --git a/deps/checksums/Pkg-61257864fe97ef14ad13eca3b6e0ac1a040c9236.tar.gz/sha512 b/deps/checksums/Pkg-61257864fe97ef14ad13eca3b6e0ac1a040c9236.tar.gz/sha512 deleted file mode 100644 index c7626f9c0e0cf..0000000000000 --- a/deps/checksums/Pkg-61257864fe97ef14ad13eca3b6e0ac1a040c9236.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -6c7efb3c1972e576e2a0aac3992e468047ab67b02bdfacf94fc42d77a9d7cd3c06df54c54b31427abe751d480eafcd0ef47ed388ee08e3eafd932cd3d23e09c8 diff --git a/deps/checksums/Pkg-a3621e97860bd26955dbbe7282c443882f43d9c3.tar.gz/md5 b/deps/checksums/Pkg-a3621e97860bd26955dbbe7282c443882f43d9c3.tar.gz/md5 new file mode 100644 index 0000000000000..83c24e02ad0a1 --- /dev/null +++ b/deps/checksums/Pkg-a3621e97860bd26955dbbe7282c443882f43d9c3.tar.gz/md5 @@ -0,0 +1 @@ +704f13debf1a844f4393ada0bc22ef67 diff --git a/deps/checksums/Pkg-a3621e97860bd26955dbbe7282c443882f43d9c3.tar.gz/sha512 b/deps/checksums/Pkg-a3621e97860bd26955dbbe7282c443882f43d9c3.tar.gz/sha512 new file mode 100644 index 0000000000000..07336b42ee45c --- /dev/null +++ b/deps/checksums/Pkg-a3621e97860bd26955dbbe7282c443882f43d9c3.tar.gz/sha512 @@ -0,0 +1 @@ +0aa0b9ceb18b4f410c23994467e30bb0c53a81f6d388f158598c5d74c3907565b5bf1646a900621f90175649e559971eea9a9d8d4102a4aa444552c1782de247 diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index 62468ccf4f6d9..6a653fdae1ba9 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,4 +1,4 @@ PKG_BRANCH = release-1.10 -PKG_SHA1 = 61257864fe97ef14ad13eca3b6e0ac1a040c9236 +PKG_SHA1 = a3621e97860bd26955dbbe7282c443882f43d9c3 PKG_GIT_URL := https://github.com/JuliaLang/Pkg.jl.git PKG_TAR_URL = https://api.github.com/repos/JuliaLang/Pkg.jl/tarball/$1 From 4545f0ba0c4fc01389ff3caaeef2022dc3b5a00d Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Tue, 12 Sep 2023 16:59:02 -0400 Subject: [PATCH 30/56] =?UTF-8?q?=F0=9F=A4=96=20[backports-release-1.10]?= =?UTF-8?q?=20Bump=20the=20Pkg=20stdlib=20from=20a3621e978=20to=20484bc3ec?= =?UTF-8?q?0=20(#51285)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Dilum Aluthge --- .../Pkg-484bc3ec08a77b71693e2c6aa502a96f0d8ae31f.tar.gz/md5 | 1 + .../Pkg-484bc3ec08a77b71693e2c6aa502a96f0d8ae31f.tar.gz/sha512 | 1 + .../Pkg-a3621e97860bd26955dbbe7282c443882f43d9c3.tar.gz/md5 | 1 - .../Pkg-a3621e97860bd26955dbbe7282c443882f43d9c3.tar.gz/sha512 | 1 - stdlib/Pkg.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 deps/checksums/Pkg-484bc3ec08a77b71693e2c6aa502a96f0d8ae31f.tar.gz/md5 create mode 100644 deps/checksums/Pkg-484bc3ec08a77b71693e2c6aa502a96f0d8ae31f.tar.gz/sha512 delete mode 100644 deps/checksums/Pkg-a3621e97860bd26955dbbe7282c443882f43d9c3.tar.gz/md5 delete mode 100644 deps/checksums/Pkg-a3621e97860bd26955dbbe7282c443882f43d9c3.tar.gz/sha512 diff --git a/deps/checksums/Pkg-484bc3ec08a77b71693e2c6aa502a96f0d8ae31f.tar.gz/md5 b/deps/checksums/Pkg-484bc3ec08a77b71693e2c6aa502a96f0d8ae31f.tar.gz/md5 new file mode 100644 index 0000000000000..2deaaffefaee3 --- /dev/null +++ b/deps/checksums/Pkg-484bc3ec08a77b71693e2c6aa502a96f0d8ae31f.tar.gz/md5 @@ -0,0 +1 @@ +6325a13a4b6925907528131f19076e86 diff --git a/deps/checksums/Pkg-484bc3ec08a77b71693e2c6aa502a96f0d8ae31f.tar.gz/sha512 b/deps/checksums/Pkg-484bc3ec08a77b71693e2c6aa502a96f0d8ae31f.tar.gz/sha512 new file mode 100644 index 0000000000000..d8c8a9d320f71 --- /dev/null +++ b/deps/checksums/Pkg-484bc3ec08a77b71693e2c6aa502a96f0d8ae31f.tar.gz/sha512 @@ -0,0 +1 @@ +3c0f55fed47c6e99f471a8d666d6c3347f6ebffd8b41be3134b942e9b315f4ad7f5229a7151e4dea4741d93d2d639213ece32479db5016236e7dab8aa80db92b diff --git a/deps/checksums/Pkg-a3621e97860bd26955dbbe7282c443882f43d9c3.tar.gz/md5 b/deps/checksums/Pkg-a3621e97860bd26955dbbe7282c443882f43d9c3.tar.gz/md5 deleted file mode 100644 index 83c24e02ad0a1..0000000000000 --- a/deps/checksums/Pkg-a3621e97860bd26955dbbe7282c443882f43d9c3.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -704f13debf1a844f4393ada0bc22ef67 diff --git a/deps/checksums/Pkg-a3621e97860bd26955dbbe7282c443882f43d9c3.tar.gz/sha512 b/deps/checksums/Pkg-a3621e97860bd26955dbbe7282c443882f43d9c3.tar.gz/sha512 deleted file mode 100644 index 07336b42ee45c..0000000000000 --- a/deps/checksums/Pkg-a3621e97860bd26955dbbe7282c443882f43d9c3.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -0aa0b9ceb18b4f410c23994467e30bb0c53a81f6d388f158598c5d74c3907565b5bf1646a900621f90175649e559971eea9a9d8d4102a4aa444552c1782de247 diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index 6a653fdae1ba9..61511df893558 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,4 +1,4 @@ PKG_BRANCH = release-1.10 -PKG_SHA1 = a3621e97860bd26955dbbe7282c443882f43d9c3 +PKG_SHA1 = 484bc3ec08a77b71693e2c6aa502a96f0d8ae31f PKG_GIT_URL := https://github.com/JuliaLang/Pkg.jl.git PKG_TAR_URL = https://api.github.com/repos/JuliaLang/Pkg.jl/tarball/$1 From e5e91421929033707c8e49a1a17230f9a4e06ad6 Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Wed, 23 Aug 2023 21:59:06 -0300 Subject: [PATCH 31/56] Implement realloc accounting correctly (#51027) This was potentially making us getting wrong results. (cherry picked from commit ce8acdd4d9cd8321141c37ddafb63062191418f4) --- src/gc.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/gc.c b/src/gc.c index ad0c545c13e8d..0d285b7251589 100644 --- a/src/gc.c +++ b/src/gc.c @@ -3711,11 +3711,12 @@ JL_DLLEXPORT void *jl_gc_counted_realloc_with_old_size(void *p, size_t old, size int64_t diff = sz - old; if (diff < 0) { + diff = -diff; uint64_t free_acc = jl_atomic_load_relaxed(&ptls->gc_num.free_acc); if (free_acc + diff < 16*1024) - jl_atomic_store_relaxed(&ptls->gc_num.free_acc, free_acc + (-diff)); + jl_atomic_store_relaxed(&ptls->gc_num.free_acc, free_acc + diff); else { - jl_atomic_fetch_add_relaxed(&gc_heap_stats.heap_size, -(free_acc + (-diff))); + jl_atomic_fetch_add_relaxed(&gc_heap_stats.heap_size, -(free_acc + diff)); jl_atomic_store_relaxed(&ptls->gc_num.free_acc, 0); } } @@ -3847,11 +3848,12 @@ static void *gc_managed_realloc_(jl_ptls_t ptls, void *d, size_t sz, size_t olds int64_t diff = allocsz - oldsz; if (diff < 0) { + diff = -diff; uint64_t free_acc = jl_atomic_load_relaxed(&ptls->gc_num.free_acc); if (free_acc + diff < 16*1024) - jl_atomic_store_relaxed(&ptls->gc_num.free_acc, free_acc + (-diff)); + jl_atomic_store_relaxed(&ptls->gc_num.free_acc, free_acc + diff); else { - jl_atomic_fetch_add_relaxed(&gc_heap_stats.heap_size, -(free_acc + (-diff))); + jl_atomic_fetch_add_relaxed(&gc_heap_stats.heap_size, -(free_acc + diff)); jl_atomic_store_relaxed(&ptls->gc_num.free_acc, 0); } } From 78c8cf1b354525ab0777531378444b01b6a3f080 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Thu, 24 Aug 2023 14:33:32 +0200 Subject: [PATCH 32/56] fix a case of potentially use of undefined variable when handling error in distributed message processing (#51019) There is a use of `oldstate` on line 244 which has the possibility of being undefined. This bug seems to have been introduced in https://github.com/JuliaLang/julia/commit/40c622b7e66a88c05d8892222126f1d13851bc62#diff-39fa44ff86c5b38bd6b9e7f60733b25724a9efd9221ca38f776ed3f3ab01dec2. I don't have a repro for this but this PR reverts back to the situation where `oldstate` is defined at the topmost level of the catch block as it was before the offending commit. (cherry picked from commit 777b784dde077defd0aea58b598241f95146152a) --- stdlib/Distributed/src/process_messages.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stdlib/Distributed/src/process_messages.jl b/stdlib/Distributed/src/process_messages.jl index 7bbf7cfde943b..e68e05b9db52b 100644 --- a/stdlib/Distributed/src/process_messages.jl +++ b/stdlib/Distributed/src/process_messages.jl @@ -210,6 +210,9 @@ function message_handler_loop(r_stream::IO, w_stream::IO, incoming::Bool) handle_msg(msg, header, r_stream, w_stream, version) end catch e + werr = worker_from_id(wpid) + oldstate = werr.state + # Check again as it may have been set in a message handler but not propagated to the calling block above if wpid < 1 wpid = worker_id_from_socket(r_stream) @@ -219,8 +222,6 @@ function message_handler_loop(r_stream::IO, w_stream::IO, incoming::Bool) println(stderr, e, CapturedException(e, catch_backtrace())) println(stderr, "Process($(myid())) - Unknown remote, closing connection.") elseif !(wpid in map_del_wrkr) - werr = worker_from_id(wpid) - oldstate = werr.state set_worker_state(werr, W_TERMINATED) # If unhandleable error occurred talking to pid 1, exit From aa115080feb08b614d01b7cf62e054f2831bf29e Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Fri, 25 Aug 2023 06:18:22 -0400 Subject: [PATCH 33/56] Revert "Optimize findall(f, ::AbstractArray{Bool}) (#42202)" (#51039) This reverts commit 4c4c94f4781da4f4109086368205db8a2f7ec7c4. (Except keeps the tests and adds a new one) fixes #46425 (cherry picked from commit defe187ed5b4f274778c964f979138334a2d1dfb) --- base/array.jl | 39 ++++++++------------------------------- test/arrayops.jl | 9 +++++++++ 2 files changed, 17 insertions(+), 31 deletions(-) diff --git a/base/array.jl b/base/array.jl index 825b5f9f7e206..7fb3d0501bb7b 100644 --- a/base/array.jl +++ b/base/array.jl @@ -2487,42 +2487,19 @@ function findall(A) end # Allocating result upfront is faster (possible only when collection can be iterated twice) -function _findall(f::Function, A::AbstractArray{Bool}) - n = count(f, A) +function findall(A::AbstractArray{Bool}) + n = count(A) I = Vector{eltype(keys(A))}(undef, n) - isempty(I) && return I - _findall(f, I, A) -end - -function _findall(f::Function, I::Vector, A::AbstractArray{Bool}) - cnt = 1 - len = length(I) - for (k, v) in pairs(A) - @inbounds I[cnt] = k - cnt += f(v) - cnt > len && return I - end - # In case of impure f, this line could potentially be hit. In that case, - # we can't assume I is the correct length. - resize!(I, cnt - 1) -end - -function _findall(f::Function, I::Vector, A::AbstractVector{Bool}) - i = firstindex(A) cnt = 1 - len = length(I) - while cnt ≤ len - @inbounds I[cnt] = i - cnt += f(@inbounds A[i]) - i = nextind(A, i) + for (i,a) in pairs(A) + if a + I[cnt] = i + cnt += 1 + end end - cnt - 1 == len ? I : resize!(I, cnt - 1) + I end -findall(f::Function, A::AbstractArray{Bool}) = _findall(f, A) -findall(f::Fix2{typeof(in)}, A::AbstractArray{Bool}) = _findall(f, A) -findall(A::AbstractArray{Bool}) = _findall(identity, A) - findall(x::Bool) = x ? [1] : Vector{Int}() findall(testf::Function, x::Number) = testf(x) ? [1] : Vector{Int}() findall(p::Fix2{typeof(in)}, x::Number) = x in p.x ? [1] : Vector{Int}() diff --git a/test/arrayops.jl b/test/arrayops.jl index 770cec3705038..ba02847094b0e 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -604,6 +604,15 @@ end @testset "issue 43078" begin @test_throws TypeError findall([1]) end + + @testset "issue #46425" begin + counter = 0 + function pred46425(x) + counter += 1 + counter < 4 && x + end + @test findall(pred46425, [false, false, true, true]) == [3] + end end @testset "find with Matrix" begin A = [1 2 0; 3 4 0] From 210fb22edd285925df15b5040dc1156e7c0cbb6a Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Sat, 26 Aug 2023 13:00:49 -0400 Subject: [PATCH 34/56] add missing invoke edge for nospecialize targets (#51036) We need 2 edges: one for the lookup (which uses the call signature) and one for the invoke (which uses the invoke signature). It is hard to make a small example for this, but the test case demonstrated this issue, particularly if inspected by `SnoopCompile.@snoopr`. Additionally, we can do some easy optimizations on the invoke invalidation, since in most cases we know from subtyping transativity that it is only invalid if the method callee target is actually deleted, and otherwise it cannot ever be partially replaced. Fixes: #50091 Likely introduced by #49404, so marking for v1.10 backport only (cherry picked from commit 6097140fdd7ed3523b1a80dd78a6c6a0a81c99ed) --- base/compiler/ssair/inlining.jl | 5 ++-- src/gf.c | 5 +++- src/staticdata_utils.c | 44 +++++++++++++++++++-------------- test/worlds.jl | 37 +++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 22 deletions(-) diff --git a/base/compiler/ssair/inlining.jl b/base/compiler/ssair/inlining.jl index 304a5e78a13e1..639a7fcc09c5b 100644 --- a/base/compiler/ssair/inlining.jl +++ b/base/compiler/ssair/inlining.jl @@ -817,8 +817,8 @@ end function compileable_specialization(mi::MethodInstance, effects::Effects, et::InliningEdgeTracker, @nospecialize(info::CallInfo); compilesig_invokes::Bool=true) mi_invoke = mi + method, atype, sparams = mi.def::Method, mi.specTypes, mi.sparam_vals if compilesig_invokes - method, atype, sparams = mi.def::Method, mi.specTypes, mi.sparam_vals new_atype = get_compileable_sig(method, atype, sparams) new_atype === nothing && return nothing if atype !== new_atype @@ -836,7 +836,8 @@ function compileable_specialization(mi::MethodInstance, effects::Effects, return nothing end end - add_inlining_backedge!(et, mi) + add_inlining_backedge!(et, mi) # to the dispatch lookup + push!(et.edges, method.sig, mi_invoke) # add_inlining_backedge to the invoke call return InvokeCase(mi_invoke, effects, info) end diff --git a/src/gf.c b/src/gf.c index 935fd1e60db78..9ee77a8426432 100644 --- a/src/gf.c +++ b/src/gf.c @@ -2130,7 +2130,10 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method int replaced_edge; if (invokeTypes) { // n.b. normally we must have mi.specTypes <: invokeTypes <: m.sig (though it might not strictly hold), so we only need to check the other subtypes - replaced_edge = jl_subtype(invokeTypes, type) && is_replacing(ambig, type, m, d, n, invokeTypes, NULL, morespec); + if (jl_egal(invokeTypes, caller->def.method->sig)) + replaced_edge = 0; // if invokeTypes == m.sig, then the only way to change this invoke is to replace the method itself + else + replaced_edge = jl_subtype(invokeTypes, type) && is_replacing(ambig, type, m, d, n, invokeTypes, NULL, morespec); } else { replaced_edge = replaced_dispatch; diff --git a/src/staticdata_utils.c b/src/staticdata_utils.c index bf1a830b608de..ed80a1f6278f4 100644 --- a/src/staticdata_utils.c +++ b/src/staticdata_utils.c @@ -505,19 +505,17 @@ static void jl_collect_edges(jl_array_t *edges, jl_array_t *ext_targets, jl_arra size_t max_valid = ~(size_t)0; if (invokeTypes) { assert(jl_is_method_instance(callee)); - jl_methtable_t *mt = jl_method_get_table(((jl_method_instance_t*)callee)->def.method); - if ((jl_value_t*)mt == jl_nothing) { - callee_ids = NULL; // invalid - break; - } - else { + jl_method_t *m = ((jl_method_instance_t*)callee)->def.method; + matches = (jl_value_t*)m; // valid because there is no method replacement permitted +#ifndef NDEBUG + jl_methtable_t *mt = jl_method_get_table(m); + if ((jl_value_t*)mt != jl_nothing) { matches = jl_gf_invoke_lookup_worlds(invokeTypes, (jl_value_t*)mt, world, &min_valid, &max_valid); - if (matches == jl_nothing) { - callee_ids = NULL; // invalid - break; + if (matches != jl_nothing) { + assert(m == ((jl_method_match_t*)matches)->method); } - matches = (jl_value_t*)((jl_method_match_t*)matches)->method; } +#endif } else { if (jl_is_method_instance(callee)) { @@ -855,19 +853,27 @@ static jl_array_t *jl_verify_edges(jl_array_t *targets, size_t minworld) size_t max_valid = ~(size_t)0; if (invokesig) { assert(callee && "unsupported edge"); - jl_methtable_t *mt = jl_method_get_table(((jl_method_instance_t*)callee)->def.method); - if ((jl_value_t*)mt == jl_nothing) { - max_valid = 0; + jl_method_t *m = ((jl_method_instance_t*)callee)->def.method; + if (jl_egal(invokesig, m->sig)) { + // the invoke match is `m` for `m->sig`, unless `m` is invalid + if (m->deleted_world < max_valid) + max_valid = 0; } else { - matches = jl_gf_invoke_lookup_worlds(invokesig, (jl_value_t*)mt, minworld, &min_valid, &max_valid); - if (matches == jl_nothing) { - max_valid = 0; + jl_methtable_t *mt = jl_method_get_table(m); + if ((jl_value_t*)mt == jl_nothing) { + max_valid = 0; } else { - matches = (jl_value_t*)((jl_method_match_t*)matches)->method; - if (matches != expected) { - max_valid = 0; + matches = jl_gf_invoke_lookup_worlds(invokesig, (jl_value_t*)mt, minworld, &min_valid, &max_valid); + if (matches == jl_nothing) { + max_valid = 0; + } + else { + matches = (jl_value_t*)((jl_method_match_t*)matches)->method; + if (matches != expected) { + max_valid = 0; + } } } } diff --git a/test/worlds.jl b/test/worlds.jl index b5a8f1c5449ac..8e820bdab88df 100644 --- a/test/worlds.jl +++ b/test/worlds.jl @@ -419,3 +419,40 @@ ccall(:jl_debug_method_invalidation, Any, (Cint,), 0) which(mc48954, (AbstractFloat, Int)), "jl_method_table_insert" ] + +# issue #50091 -- missing invoke edge affecting nospecialized dispatch +module ExceptionUnwrapping +@nospecialize +unwrap_exception(@nospecialize(e)) = e +unwrap_exception(e::Base.TaskFailedException) = e.task.exception +@noinline function _summarize_task_exceptions(io::IO, exc, prefix = nothing) + _summarize_exception((;prefix,), io, exc) + nothing +end +@noinline function _summarize_exception(kws, io::IO, e::TaskFailedException) + _summarize_task_exceptions(io, e.task, kws.prefix) +end +# This is the overload that prints the actual exception that occurred. +result = Bool[] +@noinline function _summarize_exception(kws, io::IO, @nospecialize(exc)) + global result + push!(result, unwrap_exception(exc) === exc) + if unwrap_exception(exc) !== exc # something uninferrable + return _summarize_exception(kws, io, unwrap_exception(exc)) + end +end +struct X; x; end +end +let e = ExceptionUnwrapping.X(nothing) + @test ExceptionUnwrapping.unwrap_exception(e) === e + ExceptionUnwrapping._summarize_task_exceptions(devnull, e) + @test ExceptionUnwrapping.result == [true] + empty!(ExceptionUnwrapping.result) +end +ExceptionUnwrapping.unwrap_exception(e::ExceptionUnwrapping.X) = e.x +let e = ExceptionUnwrapping.X(nothing) + @test !(ExceptionUnwrapping.unwrap_exception(e) === e) + ExceptionUnwrapping._summarize_task_exceptions(devnull, e) + @test ExceptionUnwrapping.result == [false, true] + empty!(ExceptionUnwrapping.result) +end From d889379a0337ff0ba78d8ac199a826e52d0a361b Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Sun, 27 Aug 2023 01:08:19 -0400 Subject: [PATCH 35/56] inference: fix return_type_tfunc modeling of concrete functions (#51042) The `aft` parameter is a value already, so we should be checking it in the value domain, not the type domain like `tt`. That check happens to already be done (somewhat unnecessarily) earlier in the function. Fixes #40606 --------- Co-authored-by: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> (cherry picked from commit f24a93a3f6607f569c739cbcd3a84d21bdc6c908) --- base/compiler/tfuncs.jl | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/base/compiler/tfuncs.jl b/base/compiler/tfuncs.jl index bc5c4240ac222..eae04021342d0 100644 --- a/base/compiler/tfuncs.jl +++ b/base/compiler/tfuncs.jl @@ -2620,13 +2620,15 @@ function return_type_tfunc(interp::AbstractInterpreter, argtypes::Vector{Any}, s if length(argtypes) == 3 aft = widenslotwrapper(argtypes[2]) - if !isa(aft, Const) && !(isType(aft) && !has_free_typevars(aft)) && - !(isconcretetype(aft) && !(aft <: Builtin)) - return UNKNOWN - end argtypes_vec = Any[aft, af_argtype.parameters...] else argtypes_vec = Any[af_argtype.parameters...] + isempty(argtypes_vec) && push!(argtypes_vec, Union{}) + aft = argtypes_vec[1] + end + if !(isa(aft, Const) || (isType(aft) && !has_free_typevars(aft)) || + (isconcretetype(aft) && !(aft <: Builtin) && !iskindtype(aft))) + return UNKNOWN end if contains_is(argtypes_vec, Union{}) @@ -2659,8 +2661,7 @@ function return_type_tfunc(interp::AbstractInterpreter, argtypes::Vector{Any}, s # in two ways: both as being a subtype of this, and # because of LimitedAccuracy causes return CallMeta(Type{<:rt}, EFFECTS_TOTAL, info) - elseif (isa(tt, Const) || isconstType(tt)) && - (isa(aft, Const) || isconstType(aft)) + elseif isa(tt, Const) || isconstType(tt) # input arguments were known for certain # XXX: this doesn't imply we know anything about rt return CallMeta(Const(rt), EFFECTS_TOTAL, info) From 15359fa7a61e358e3c9164fdc785850bd3372701 Mon Sep 17 00:00:00 2001 From: Cody Tapscott <84105208+topolarity@users.noreply.github.com> Date: Wed, 30 Aug 2023 21:58:57 -0400 Subject: [PATCH 36/56] Workaround upstream FreeBSD issue #272992 (#51114) ELF doesn't handle WEAK symbols dynamically the way it handles them statically. Looking up overloaded WEAK symbols via a library-specific handle will often give you the empty stub (in `libc.so.7` in this case) instead of the strong implementation elsewhere (`ld-elf.so.1` here). Even after the [upstream fix](https://cgit.freebsd.org/src/commit/?id=21a52f99440c9bec7679f3b0c5c9d888901c3694), `dlsym`, `dladdr` and a ton of other symbols still have stubs with no trampoline in FreeBSD's libc: https://cgit.freebsd.org/src/tree/lib/libc/gen/dlfcn.c?id=21a52f99440c9bec7679f3b0c5c9d888901c3694 Thankfully `dl_iterate_phdr` appears to be the only function that we directly `ccall` from Julia's Libdl so we can leave this fix incomplete for now. Resolves #50846. (cherry picked from commit c65901171a30b261f063c6a56c4a58a36d492be0) --- src/dlload.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/dlload.c b/src/dlload.c index ffa9a053d5f1c..8124605880b5e 100644 --- a/src/dlload.c +++ b/src/dlload.c @@ -435,6 +435,13 @@ JL_DLLEXPORT int jl_dlsym(void *handle, const char *symbol, void ** value, int t // Look for symbols in internal libraries JL_DLLEXPORT const char *jl_dlfind(const char *f_name) { +#ifdef _OS_FREEBSD_ + // This is a workaround for FreeBSD <= 13.2 which do not have + // https://cgit.freebsd.org/src/commit/?id=21a52f99440c9bec7679f3b0c5c9d888901c3694 + // (See https://github.com/JuliaLang/julia/issues/50846) + if (strcmp(f_name, "dl_iterate_phdr") == 0) + return JL_EXE_LIBNAME; +#endif void * dummy; if (jl_dlsym(jl_libjulia_internal_handle, f_name, &dummy, 0)) return JL_LIBJULIA_INTERNAL_DL_LIBNAME; From 70937646c4ecbf10ae7db1e9de791a4f4215a9e4 Mon Sep 17 00:00:00 2001 From: Cody Tapscott <84105208+topolarity@users.noreply.github.com> Date: Fri, 1 Sep 2023 14:46:25 -0400 Subject: [PATCH 37/56] Add `JL_DLLIMPORT` to `small_typeof` declaration (#50892) Resolves #50714 (cherry picked from commit 91b8c9b99f05b99db8b259257adeb1997f8c4415) --- cli/jl_exports.h | 2 +- src/Makefile | 7 ++++++- src/aotcompile.cpp | 20 ++++++++++---------- src/builtins.c | 2 +- src/cgutils.cpp | 6 +++--- src/codegen.cpp | 6 +++--- src/gc.c | 4 ++-- src/jltypes.c | 20 ++++++++------------ src/julia.expmap.in | 1 - src/julia.h | 16 +++++++++++++--- src/processor.cpp | 2 +- src/processor.h | 6 +++--- src/staticdata.c | 8 ++++---- test/embedding/embedding.c | 6 ++++++ 14 files changed, 61 insertions(+), 45 deletions(-) diff --git a/cli/jl_exports.h b/cli/jl_exports.h index d28958c097edb..f1a05b504d9da 100644 --- a/cli/jl_exports.h +++ b/cli/jl_exports.h @@ -18,7 +18,7 @@ JL_EXPORTED_DATA_SYMBOLS(XX) // define a copy of exported data #define jl_max_tags 64 -JL_DLLEXPORT void *small_typeof[(jl_max_tags << 4) / sizeof(void*)]; // 16-bit aligned, like the GC +JL_DLLEXPORT void *jl_small_typeof[(jl_max_tags << 4) / sizeof(void*)]; // 16-bit aligned, like the GC // Declare list of exported functions (sans type) #define XX(name) JL_DLLEXPORT void name(void); diff --git a/src/Makefile b/src/Makefile index 9e34dfda1c4ed..3ea28e7c40324 100644 --- a/src/Makefile +++ b/src/Makefile @@ -520,7 +520,12 @@ clang-tidy-%: $(SRCDIR)/%.cpp $(build_shlibdir)/libImplicitAtomicsPlugin.$(SHLIB -- $(CLANGSA_FLAGS) $(CLANGSA_CXXFLAGS) $(LLVM_CXXFLAGS) $(JCPPFLAGS_CLANG) $(JCXXFLAGS_CLANG) $(JL_CXXFLAGS) $(DEBUGFLAGS_CLANG) -fcolor-diagnostics --system-header-prefix=llvm -Wno-deprecated-declarations -fno-caret-diagnostics -x c++) # set the exports for the source files based on where they are getting linked -clang-sa-% clang-sagc-% clang-tidy-%: DEBUGFLAGS_CLANG += -DJL_LIBRARY_EXPORTS +$(addprefix clang-sa-,$(SRCS)): DEBUGFLAGS_CLANG += -DJL_LIBRARY_EXPORTS_INTERNAL +$(addprefix clang-sagc-,$(SRCS)): DEBUGFLAGS_CLANG += -DJL_LIBRARY_EXPORTS_INTERNAL +$(addprefix clang-tidy-,$(SRCS)): DEBUGFLAGS_CLANG += -DJL_LIBRARY_EXPORTS_INTERNAL +$(addprefix clang-sa-,$(CODEGEN_SRCS)): DEBUGFLAGS_CLANG += -DJL_LIBRARY_EXPORTS_CODEGEN +$(addprefix clang-sagc-,$(CODEGEN_SRCS)): DEBUGFLAGS_CLANG += -DJL_LIBRARY_EXPORTS_CODEGEN +$(addprefix clang-tidy-,$(CODEGEN_SRCS)): DEBUGFLAGS_CLANG += -DJL_LIBRARY_EXPORTS_CODEGEN # Add C files as a target of `analyzesrc` and `analyzegc` and `tidysrc` tidysrc: $(addprefix clang-tidy-,$(filter-out $(basename $(SKIP_IMPLICIT_ATOMICS)),$(CODEGEN_SRCS) $(SRCS))) diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index d288586916560..05088394500c1 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -1621,10 +1621,10 @@ void jl_dump_native_impl(void *native_code, // let the compiler know we are going to internalize a copy of this, // if it has a current usage with ExternalLinkage - auto small_typeof_copy = dataM.getGlobalVariable("small_typeof"); - if (small_typeof_copy) { - small_typeof_copy->setVisibility(GlobalValue::HiddenVisibility); - small_typeof_copy->setDSOLocal(true); + auto jl_small_typeof_copy = dataM.getGlobalVariable("jl_small_typeof"); + if (jl_small_typeof_copy) { + jl_small_typeof_copy->setVisibility(GlobalValue::HiddenVisibility); + jl_small_typeof_copy->setDSOLocal(true); } } @@ -1698,13 +1698,13 @@ void jl_dump_native_impl(void *native_code, auto shards = emit_shard_table(metadataM, T_size, T_psize, threads); auto ptls = emit_ptls_table(metadataM, T_size, T_psize); auto header = emit_image_header(metadataM, threads, nfvars, ngvars); - auto AT = ArrayType::get(T_size, sizeof(small_typeof) / sizeof(void*)); - auto small_typeof_copy = new GlobalVariable(metadataM, AT, false, + auto AT = ArrayType::get(T_size, sizeof(jl_small_typeof) / sizeof(void*)); + auto jl_small_typeof_copy = new GlobalVariable(metadataM, AT, false, GlobalVariable::ExternalLinkage, Constant::getNullValue(AT), - "small_typeof"); - small_typeof_copy->setVisibility(GlobalValue::HiddenVisibility); - small_typeof_copy->setDSOLocal(true); + "jl_small_typeof"); + jl_small_typeof_copy->setVisibility(GlobalValue::HiddenVisibility); + jl_small_typeof_copy->setDSOLocal(true); AT = ArrayType::get(T_psize, 5); auto pointers = new GlobalVariable(metadataM, AT, false, GlobalVariable::ExternalLinkage, @@ -1712,7 +1712,7 @@ void jl_dump_native_impl(void *native_code, ConstantExpr::getBitCast(header, T_psize), ConstantExpr::getBitCast(shards, T_psize), ConstantExpr::getBitCast(ptls, T_psize), - ConstantExpr::getBitCast(small_typeof_copy, T_psize), + ConstantExpr::getBitCast(jl_small_typeof_copy, T_psize), ConstantExpr::getBitCast(target_ids, T_psize) }), "jl_image_pointers"); diff --git a/src/builtins.c b/src/builtins.c index 4f75fd79eadcc..e2169abb704fc 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -222,7 +222,7 @@ JL_DLLEXPORT int jl_egal__unboxed(const jl_value_t *a JL_MAYBE_UNROOTED, const j JL_DLLEXPORT int jl_egal__bitstag(const jl_value_t *a JL_MAYBE_UNROOTED, const jl_value_t *b JL_MAYBE_UNROOTED, uintptr_t dtag) JL_NOTSAFEPOINT { if (dtag < jl_max_tags << 4) { - switch ((enum jlsmall_typeof_tags)(dtag >> 4)) { + switch ((enum jl_small_typeof_tags)(dtag >> 4)) { case jl_int8_tag: case jl_uint8_tag: return *(uint8_t*)a == *(uint8_t*)b; diff --git a/src/cgutils.cpp b/src/cgutils.cpp index 326e4823d6c34..69f620869df93 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -411,7 +411,7 @@ static Constant *literal_pointer_val_slot(jl_codectx_t &ctx, jl_value_t *p) if (addr->smalltag) { // some common builtin datatypes have a special pool for accessing them by smalltag id Constant *tag = ConstantInt::get(getInt32Ty(ctx.builder.getContext()), addr->smalltag << 4); - Constant *smallp = ConstantExpr::getInBoundsGetElementPtr(getInt8Ty(ctx.builder.getContext()), prepare_global_in(jl_Module, jlsmall_typeof_var), tag); + Constant *smallp = ConstantExpr::getInBoundsGetElementPtr(getInt8Ty(ctx.builder.getContext()), prepare_global_in(jl_Module, jl_small_typeof_var), tag); return ConstantExpr::getBitCast(smallp, ctx.types().T_ppjlvalue); } // DataTypes are prefixed with a + @@ -1096,7 +1096,7 @@ static Value *emit_typeof(jl_codectx_t &ctx, const jl_cgval_t &p, bool maybenull if (jl_has_intersect_type_not_kind(typ)) return false; for (size_t i = 0; i < jl_tags_count; i++) { - jl_datatype_t *dt = small_typeof[(i << 4) / sizeof(*small_typeof)]; + jl_datatype_t *dt = jl_small_typeof[(i << 4) / sizeof(*jl_small_typeof)]; if (dt && !jl_has_empty_intersection((jl_value_t*)dt, typ)) return false; } @@ -1457,7 +1457,7 @@ static Value *emit_typeof(jl_codectx_t &ctx, Value *v, bool maybenull, bool just // we lied a bit: this wasn't really an object (though it was valid for GC rooting) // and we need to use it as an index to get the real object now Module *M = jl_Module; - Value *smallp = ctx.builder.CreateInBoundsGEP(getInt8Ty(ctx.builder.getContext()), prepare_global_in(M, jlsmall_typeof_var), tag); + Value *smallp = ctx.builder.CreateInBoundsGEP(getInt8Ty(ctx.builder.getContext()), prepare_global_in(M, jl_small_typeof_var), tag); smallp = ctx.builder.CreateBitCast(smallp, typetag->getType()->getPointerTo(0)); jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const); auto small = ctx.builder.CreateAlignedLoad(typetag->getType(), smallp, M->getDataLayout().getPointerABIAlignment(0)); diff --git a/src/codegen.cpp b/src/codegen.cpp index 5ad4eb4e6e9a4..f72c2ae2056b9 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -649,8 +649,8 @@ static const auto jldlli_var = new JuliaVariable{ true, [](Type *T_size) -> Type * { return getInt8PtrTy(T_size->getContext()); }, }; -static const auto jlsmall_typeof_var = new JuliaVariable{ - XSTR(small_typeof), +static const auto jl_small_typeof_var = new JuliaVariable{ + XSTR(jl_small_typeof), true, [](Type *T_size) -> Type * { return getInt8Ty(T_size->getContext()); }, }; @@ -9032,7 +9032,7 @@ static void init_f16_funcs(void) static void init_jit_functions(void) { - add_named_global(jlsmall_typeof_var, &small_typeof); + add_named_global(jl_small_typeof_var, &jl_small_typeof); add_named_global(jlstack_chk_guard_var, &__stack_chk_guard); add_named_global(jlRTLD_DEFAULT_var, &jl_RTLD_DEFAULT_handle); add_named_global(jlexe_var, &jl_exe_handle); diff --git a/src/gc.c b/src/gc.c index 0d285b7251589..7d847195dce8c 100644 --- a/src/gc.c +++ b/src/gc.c @@ -2422,7 +2422,7 @@ FORCE_INLINE void gc_mark_outrefs(jl_ptls_t ptls, jl_gc_markqueue_t *mq, void *_ vtag == (jl_vararg_tag << 4)) { // these objects have pointers in them, but no other special handling // so we want these to fall through to the end - vtag = (uintptr_t)small_typeof[vtag / sizeof(*small_typeof)]; + vtag = (uintptr_t)ijl_small_typeof[vtag / sizeof(*ijl_small_typeof)]; } else if (vtag < jl_max_tags << 4) { // these objects either have specialing handling @@ -2532,7 +2532,7 @@ FORCE_INLINE void gc_mark_outrefs(jl_ptls_t ptls, jl_gc_markqueue_t *mq, void *_ objprofile_count(jl_string_type, bits == GC_OLD_MARKED, dtsz); } else { - jl_datatype_t *vt = small_typeof[vtag / sizeof(*small_typeof)]; + jl_datatype_t *vt = ijl_small_typeof[vtag / sizeof(*ijl_small_typeof)]; size_t dtsz = jl_datatype_size(vt); if (update_meta) gc_setmark(ptls, o, bits, dtsz); diff --git a/src/jltypes.c b/src/jltypes.c index 024d0be74e659..8da119248203a 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -20,7 +20,7 @@ extern "C" { #endif _Atomic(jl_value_t*) cmpswap_names JL_GLOBALLY_ROOTED; -jl_datatype_t *small_typeof[(jl_max_tags << 4) / sizeof(*small_typeof)]; // 16-bit aligned, like the GC +jl_datatype_t *ijl_small_typeof[(jl_max_tags << 4) / sizeof(*ijl_small_typeof)]; // 16-bit aligned, like the GC // compute empirical max-probe for a given size #define max_probe(size) ((size) <= 1024 ? 16 : (size) >> 6) @@ -2525,19 +2525,13 @@ static jl_tvar_t *tvar(const char *name) (jl_value_t*)jl_any_type); } -void export_small_typeof(void) +void export_jl_small_typeof(void) { - void *copy; -#ifdef _OS_WINDOWS_ - jl_dlsym(jl_libjulia_handle, "small_typeof", ©, 1); -#else - jl_dlsym(jl_libjulia_internal_handle, "small_typeof", ©, 1); -#endif - memcpy(copy, &small_typeof, sizeof(small_typeof)); + memcpy(&jl_small_typeof, &ijl_small_typeof, sizeof(jl_small_typeof)); } #define XX(name) \ - small_typeof[(jl_##name##_tag << 4) / sizeof(*small_typeof)] = jl_##name##_type; \ + ijl_small_typeof[(jl_##name##_tag << 4) / sizeof(*ijl_small_typeof)] = jl_##name##_type; \ jl_##name##_type->smalltag = jl_##name##_tag; void jl_init_types(void) JL_GC_DISABLED { @@ -3357,7 +3351,8 @@ void jl_init_types(void) JL_GC_DISABLED // override the preferred layout for a couple types jl_lineinfonode_type->name->mayinlinealloc = 0; // FIXME: assumed to be a pointer by codegen - export_small_typeof(); + + export_jl_small_typeof(); } static jl_value_t *core(const char *name) @@ -3438,7 +3433,8 @@ void post_boot_hooks(void) } } } - export_small_typeof(); + + export_jl_small_typeof(); } #undef XX diff --git a/src/julia.expmap.in b/src/julia.expmap.in index 484c83a4b16b2..213d087fdc2ad 100644 --- a/src/julia.expmap.in +++ b/src/julia.expmap.in @@ -7,7 +7,6 @@ ios_*; arraylist_grow; small_arraylist_grow; - small_typeof; jl_*; ijl_*; _jl_mutex_*; diff --git a/src/julia.h b/src/julia.h index 5af8a5bc1a170..f4229eae909ac 100644 --- a/src/julia.h +++ b/src/julia.h @@ -740,7 +740,7 @@ typedef struct { /* XX(slotnumber) */ \ /* XX(ssavalue) */ \ /* end of JL_SMALL_TYPEOF */ -enum jlsmall_typeof_tags { +enum jl_small_typeof_tags { jl_null_tag = 0, #define XX(name) jl_##name##_tag, JL_SMALL_TYPEOF(XX) @@ -749,13 +749,23 @@ enum jlsmall_typeof_tags { jl_bitstags_first = jl_char_tag, // n.b. bool is not considered a bitstype, since it can be compared by pointer jl_max_tags = 64 }; -extern jl_datatype_t *small_typeof[(jl_max_tags << 4) / sizeof(jl_datatype_t*)]; +extern JL_DLLIMPORT jl_datatype_t *jl_small_typeof[(jl_max_tags << 4) / sizeof(jl_datatype_t*)]; +#ifndef JL_LIBRARY_EXPORTS_INTERNAL static inline jl_value_t *jl_to_typeof(uintptr_t t) { if (t < (jl_max_tags << 4)) - return (jl_value_t*)small_typeof[t / sizeof(*small_typeof)]; + return (jl_value_t*)jl_small_typeof[t / sizeof(*jl_small_typeof)]; return (jl_value_t*)t; } +#else +extern JL_HIDDEN jl_datatype_t *ijl_small_typeof[(jl_max_tags << 4) / sizeof(jl_datatype_t*)]; +static inline jl_value_t *jl_to_typeof(uintptr_t t) +{ + if (t < (jl_max_tags << 4)) + return (jl_value_t*)ijl_small_typeof[t / sizeof(*ijl_small_typeof)]; + return (jl_value_t*)t; +} +#endif // kinds diff --git a/src/processor.cpp b/src/processor.cpp index 9a602ba836f89..d2d91d3cd9966 100644 --- a/src/processor.cpp +++ b/src/processor.cpp @@ -812,7 +812,7 @@ static inline jl_image_t parse_sysimg(void *hdl, F &&callback) *tls_offset_idx = (uintptr_t)(jl_tls_offset == -1 ? 0 : jl_tls_offset); } - res.small_typeof = pointers->small_typeof; + res.jl_small_typeof = pointers->jl_small_typeof; return res; } diff --git a/src/processor.h b/src/processor.h index 74610cbe64b28..a3ebdf4f8c605 100644 --- a/src/processor.h +++ b/src/processor.h @@ -88,7 +88,7 @@ typedef struct { const int32_t *gvars_offsets; uint32_t ngvars; jl_image_fptrs_t fptrs; - void **small_typeof; + void **jl_small_typeof; } jl_image_t; // The header for each image @@ -197,8 +197,8 @@ typedef struct { const jl_image_shard_t *shards; // points to header->nshards length array // The TLS data pointer const jl_image_ptls_t *ptls; - // A copy of small_typeof[] - void **small_typeof; + // A copy of jl_small_typeof[] + void **jl_small_typeof; // serialized target data // This contains the number of targets diff --git a/src/staticdata.c b/src/staticdata.c index c05422fd10969..a974d98a39835 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -1984,7 +1984,7 @@ static void jl_update_all_fptrs(jl_serializer_state *s, jl_image_t *image) if (fvars.base == NULL) return; - memcpy(image->small_typeof, &small_typeof, sizeof(small_typeof)); + memcpy(image->jl_small_typeof, &jl_small_typeof, sizeof(jl_small_typeof)); int img_fvars_max = s->fptr_record->size / sizeof(void*); size_t i; @@ -2838,7 +2838,7 @@ JL_DLLEXPORT void jl_set_sysimg_so(void *handle) #endif extern void rebuild_image_blob_tree(void); -extern void export_small_typeof(void); +extern void export_jl_small_typeof(void); static void jl_restore_system_image_from_stream_(ios_t *f, jl_image_t *image, jl_array_t *depmods, uint64_t checksum, /* outputs */ jl_array_t **restored, jl_array_t **init_order, @@ -2914,10 +2914,10 @@ static void jl_restore_system_image_from_stream_(ios_t *f, jl_image_t *image, jl *tag = jl_read_value(&s); } #define XX(name) \ - small_typeof[(jl_##name##_tag << 4) / sizeof(*small_typeof)] = jl_##name##_type; + ijl_small_typeof[(jl_##name##_tag << 4) / sizeof(*ijl_small_typeof)] = jl_##name##_type; JL_SMALL_TYPEOF(XX) #undef XX - export_small_typeof(); + export_jl_small_typeof(); jl_global_roots_table = (jl_array_t*)jl_read_value(&s); // set typeof extra-special values now that we have the type set by tags above jl_astaggedvalue(jl_nothing)->header = (uintptr_t)jl_nothing_type | jl_astaggedvalue(jl_nothing)->header; diff --git a/test/embedding/embedding.c b/test/embedding/embedding.c index 1294d4cdafb45..c5b8845b7c823 100644 --- a/test/embedding/embedding.c +++ b/test/embedding/embedding.c @@ -192,6 +192,12 @@ int main() checked_eval_string("f28825()"); } + { + // jl_typeof works (#50714) + jl_value_t *v = checked_eval_string("sqrt(2.0)"); + jl_value_t *t = jl_typeof(v); + } + JL_TRY { jl_error("exception thrown"); } From 8332712e46416d56024ea97f455d218a18704e9f Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Sat, 2 Sep 2023 22:11:55 -0400 Subject: [PATCH 38/56] broadcast: use recursion rather than ntuple to map over a tuple (#51154) Inference seems to have trouble with the anonymous function version, so go back to the recursive version. Fixes #51129 Probably also fixes #50859 (cherry picked from commit d949bb4332c5b18c93c428094b3b1a83190029ad) --- base/broadcast.jl | 4 ++-- test/broadcast.jl | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/base/broadcast.jl b/base/broadcast.jl index 1e057789509ed..a1a86bfb3f59c 100644 --- a/base/broadcast.jl +++ b/base/broadcast.jl @@ -750,8 +750,8 @@ _broadcast_getindex_eltype(A) = eltype(A) # Tuple, Array, etc. eltypes(::Tuple{}) = Tuple{} eltypes(t::Tuple{Any}) = Iterators.TupleOrBottom(_broadcast_getindex_eltype(t[1])) eltypes(t::Tuple{Any,Any}) = Iterators.TupleOrBottom(_broadcast_getindex_eltype(t[1]), _broadcast_getindex_eltype(t[2])) -# eltypes(t::Tuple) = (TT = eltypes(tail(t)); TT === Union{} ? Union{} : Iterators.TupleOrBottom(_broadcast_getindex_eltype(t[1]), TT.parameters...)) -eltypes(t::Tuple) = Iterators.TupleOrBottom(ntuple(i -> _broadcast_getindex_eltype(t[i]), Val(length(t)))...) +eltypes(t::Tuple) = (TT = eltypes(tail(t)); TT === Union{} ? Union{} : Iterators.TupleOrBottom(_broadcast_getindex_eltype(t[1]), TT.parameters...)) +# eltypes(t::Tuple) = Iterators.TupleOrBottom(ntuple(i -> _broadcast_getindex_eltype(t[i]), Val(length(t)))...) # Inferred eltype of result of broadcast(f, args...) function combine_eltypes(f, args::Tuple) diff --git a/test/broadcast.jl b/test/broadcast.jl index 87858dd0f08fc..5e737a63e24dc 100644 --- a/test/broadcast.jl +++ b/test/broadcast.jl @@ -1133,3 +1133,6 @@ end import Base.Broadcast: BroadcastStyle, DefaultArrayStyle @test Base.infer_effects(BroadcastStyle, (DefaultArrayStyle{1},DefaultArrayStyle{2},)) |> Core.Compiler.is_foldable + +f51129(v, x) = (1 .- (v ./ x) .^ 2) +@test @inferred(f51129([13.0], 6.5)) == [-3.0] From 0e7eed85b558c03da7e223c0a36627a9328c3484 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Sat, 2 Sep 2023 22:12:28 -0400 Subject: [PATCH 39/56] fix debug typo in "add missing invoke edge for nospecialize targets (#51036)" (#51153) Causes `matches` to get replaced with `MethodMatch` instead, which then later will fail to match with the expected value. Fixes #51146 Co-authored-by: Dilum Aluthge (cherry picked from commit da86735259702850ee7a66c58021c1d6e0ad259e) --- src/staticdata_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/staticdata_utils.c b/src/staticdata_utils.c index ed80a1f6278f4..a4cbc3fd5ebc4 100644 --- a/src/staticdata_utils.c +++ b/src/staticdata_utils.c @@ -510,7 +510,7 @@ static void jl_collect_edges(jl_array_t *edges, jl_array_t *ext_targets, jl_arra #ifndef NDEBUG jl_methtable_t *mt = jl_method_get_table(m); if ((jl_value_t*)mt != jl_nothing) { - matches = jl_gf_invoke_lookup_worlds(invokeTypes, (jl_value_t*)mt, world, &min_valid, &max_valid); + jl_value_t *matches = jl_gf_invoke_lookup_worlds(invokeTypes, (jl_value_t*)mt, world, &min_valid, &max_valid); if (matches != jl_nothing) { assert(m == ((jl_method_match_t*)matches)->method); } From 0c0638dbd424b8e70a92c67960302af5b3a0e423 Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Thu, 7 Sep 2023 18:55:47 -0300 Subject: [PATCH 40/56] Check again if the tty is open inside the IO lock (#51222) This can cause segfaults when exiting julia. Co-authored-by: Valentin Churavy (cherry picked from commit b3741c01f2e2d4956be3ba41858c4065c6fbc7e8) --- base/stream.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/stream.jl b/base/stream.jl index 0b6c9a93777f6..22af8d59359f3 100644 --- a/base/stream.jl +++ b/base/stream.jl @@ -565,7 +565,6 @@ displaysize() = (parse(Int, get(ENV, "LINES", "24")), parse(Int, get(ENV, "COLUMNS", "80")))::Tuple{Int, Int} function displaysize(io::TTY) - # A workaround for #34620 and #26687 (this still has the TOCTOU problem). check_open(io) local h::Int, w::Int @@ -588,6 +587,7 @@ function displaysize(io::TTY) s1 = Ref{Int32}(0) s2 = Ref{Int32}(0) iolock_begin() + check_open(io) Base.uv_error("size (TTY)", ccall(:uv_tty_get_winsize, Int32, (Ptr{Cvoid}, Ptr{Int32}, Ptr{Int32}), io, s1, s2) != 0) From 81c9a3cddb5ce813d1c2de426ce12bd59f49ae3f Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Sat, 9 Sep 2023 17:43:01 -0300 Subject: [PATCH 41/56] Add lock around uv_unref during init (#51236) This is not a legal operation outside the lock because it's not atomic Co-authored-by: Valentin Churavy (cherry picked from commit bbbcc4fed67337c038b485f00677e2e88d24becd) --- base/libuv.jl | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/base/libuv.jl b/base/libuv.jl index 24a04f5bcad78..4c56af29e7e60 100644 --- a/base/libuv.jl +++ b/base/libuv.jl @@ -103,8 +103,17 @@ uv_error(prefix::AbstractString, c::Integer) = c < 0 ? throw(_UVError(prefix, c) eventloop() = ccall(:jl_global_event_loop, Ptr{Cvoid}, ()) -uv_unref(h::Ptr{Cvoid}) = ccall(:uv_unref, Cvoid, (Ptr{Cvoid},), h) -uv_ref(h::Ptr{Cvoid}) = ccall(:uv_ref, Cvoid, (Ptr{Cvoid},), h) +function uv_unref(h::Ptr{Cvoid}) + iolock_begin() + ccall(:uv_unref, Cvoid, (Ptr{Cvoid},), h) + iolock_end() +end + +function uv_ref(h::Ptr{Cvoid}) + iolock_begin() + ccall(:uv_ref, Cvoid, (Ptr{Cvoid},), h) + iolock_end() +end function process_events() return ccall(:jl_process_events, Int32, ()) From c12e85155c4bdec251fe564ea3033427619d1be3 Mon Sep 17 00:00:00 2001 From: Tim Besard Date: Mon, 11 Sep 2023 16:39:29 +0200 Subject: [PATCH 42/56] GMP: Gracefully handle more overflows. (#51243) Fixes https://github.com/JuliaLang/julia/issues/8286, which regressed due to a GMP upgrade in https://github.com/JuliaLang/julia/pull/45375. (cherry picked from commit 10974814b3faa1dea140062cfe1f3e63962074d5) --- deps/checksums/gmp | 116 ++++++++++----------- deps/gmp.mk | 7 +- deps/patches/gmp-more_alloc_overflow.patch | 37 +++++++ stdlib/GMP_jll/Project.toml | 2 +- test/gmp.jl | 5 + 5 files changed, 107 insertions(+), 60 deletions(-) create mode 100644 deps/patches/gmp-more_alloc_overflow.patch diff --git a/deps/checksums/gmp b/deps/checksums/gmp index 312f79dfc1d6a..c9f6deac6e19b 100644 --- a/deps/checksums/gmp +++ b/deps/checksums/gmp @@ -1,60 +1,60 @@ -GMP.v6.2.1+5.aarch64-apple-darwin.tar.gz/md5/56a01b4c21e4bc3ef3014f162c78e0a7 -GMP.v6.2.1+5.aarch64-apple-darwin.tar.gz/sha512/4c0e31f03965602b811be25847b94e227c63f66a152225477468303a44dd0f148970aaaf00e9cf800ba7df602b31b75f64c28e509362bf82b9c9f341b044a20d -GMP.v6.2.1+5.aarch64-linux-gnu-cxx03.tar.gz/md5/a1beafc662eaf934dfb3cec74ea8fe6b -GMP.v6.2.1+5.aarch64-linux-gnu-cxx03.tar.gz/sha512/370de52ddaa4e744bb6cc8eb61bc369e4e96dccdff6b1a65f21d30d4a19d0dbe41c068c8867c0fcd2bffee9aaf375c60050263dcf7c10b215b290253a7654c71 -GMP.v6.2.1+5.aarch64-linux-gnu-cxx11.tar.gz/md5/afaca916697bcdac17f4dba7444cd467 -GMP.v6.2.1+5.aarch64-linux-gnu-cxx11.tar.gz/sha512/cd7bf7c502e927a05ecde303733240c0245b239447ed4c8c3d13a52b42e47cde48264726321ff318ad6f8c08e8cf4e0c85ac875dade355720fbd7e8b33392092 -GMP.v6.2.1+5.aarch64-linux-musl-cxx03.tar.gz/md5/1d7b2be36a999f2b991abae4b9a350c9 -GMP.v6.2.1+5.aarch64-linux-musl-cxx03.tar.gz/sha512/6e4f04980a2d326a2ec2ba9b52cb4143fc227459c936706cac9f19c67607019927dc8d9f4822a73c885eb3ab2c37c6af806bff50e1e76d546274979d2589e140 -GMP.v6.2.1+5.aarch64-linux-musl-cxx11.tar.gz/md5/d114c9a351854c62b4f4724302a61677 -GMP.v6.2.1+5.aarch64-linux-musl-cxx11.tar.gz/sha512/1a0d4e3ef9fd4e2bf17cf0d90b262c1cd4f684e1ed31b6e040afe59cc13ec3dc3ce274f55c62c19217bffdd847850fe55a607f616422e2c31d92d7553100ee98 -GMP.v6.2.1+5.armv6l-linux-gnueabihf-cxx03.tar.gz/md5/3e5989fb44bc6e2cb4054e885e931cc6 -GMP.v6.2.1+5.armv6l-linux-gnueabihf-cxx03.tar.gz/sha512/b42884d9a8d9a7a63f51f602c3cc1c2b80a6fd4aaaa47eebcf89a42443b25ba9691da844d2ac69a46b4099a5bdb34c8089f4efd8ca213d6d9866c2076d1fe061 -GMP.v6.2.1+5.armv6l-linux-gnueabihf-cxx11.tar.gz/md5/c65ae9faa092285cc4082bfd585e7b03 -GMP.v6.2.1+5.armv6l-linux-gnueabihf-cxx11.tar.gz/sha512/74ab5afd05de93315d3e2b7f2ee6b86a2dbc165621e98cbc08b9c61146d595189b641f2bb8af4cd17d868325fa2a193b9f350e0ed457ca8bc9b96bdfb72c51e6 -GMP.v6.2.1+5.armv6l-linux-musleabihf-cxx03.tar.gz/md5/cc8e27fc3ec1c1f9e044c9d918d8cfb6 -GMP.v6.2.1+5.armv6l-linux-musleabihf-cxx03.tar.gz/sha512/59ae96ed0571ce64a44798767c389f4822222d9519422b5050d22ada68d57371583d4de82c6d22d9636aa2e25cfd9528151364fbf207fdb391bc61d4ad3265e1 -GMP.v6.2.1+5.armv6l-linux-musleabihf-cxx11.tar.gz/md5/e5eb9e0084bf9b4b28c7d1060893159f -GMP.v6.2.1+5.armv6l-linux-musleabihf-cxx11.tar.gz/sha512/3befcb4638d29e4d05ba1bc438e5f861a69385f5a3aa2a331194bed8f7f69331ebc61577dadec97a7c2c42e53a6dd240e30c19d4854af0670b98b02f11afc35d -GMP.v6.2.1+5.armv7l-linux-gnueabihf-cxx03.tar.gz/md5/a3feda2d30469e8980f7c1d1694f2a65 -GMP.v6.2.1+5.armv7l-linux-gnueabihf-cxx03.tar.gz/sha512/d6787b7beca9c98e1e8771842052e5f332dc4d34a1d53968704cc54056477072a7cf0c87ae4c9a51ea35c4b4de14cad6f67579469bb802e50eb6d49d65bd0540 -GMP.v6.2.1+5.armv7l-linux-gnueabihf-cxx11.tar.gz/md5/989a83feae172a0f01670d89065ac58c -GMP.v6.2.1+5.armv7l-linux-gnueabihf-cxx11.tar.gz/sha512/331a08346f8fd7d70a3cd40b1f9c6e7790751cadc9f3027bb1a815314c2e54bae5268a2ecca53a1a5086366641ef7389cb9574cd5f0431dee70ddedff7870b6c -GMP.v6.2.1+5.armv7l-linux-musleabihf-cxx03.tar.gz/md5/705e406788adacc5d73746306215e412 -GMP.v6.2.1+5.armv7l-linux-musleabihf-cxx03.tar.gz/sha512/32fa29cb8abcb823cc1e170c4e1ea09b1f970207279c88ac78df352bb3969590e50fc9eb6446d9c5044f5fae2168878614b189cb1cc612ae8b8afe820b83778a -GMP.v6.2.1+5.armv7l-linux-musleabihf-cxx11.tar.gz/md5/2fff6e51075ce3b64c7684451d3a057c -GMP.v6.2.1+5.armv7l-linux-musleabihf-cxx11.tar.gz/sha512/266036a380e3e58e799f1f03129321345a0c4d9db60b88d12166c7c6d817279239aa2e2cbf2442435e12bba8cef18c48fe9844d0b88f0026be67378e18f135c2 -GMP.v6.2.1+5.i686-linux-gnu-cxx03.tar.gz/md5/7f07924e4a691436727621e2fd1ff349 -GMP.v6.2.1+5.i686-linux-gnu-cxx03.tar.gz/sha512/3e33534fd8ba681c9e4dddd0dbb1c287b1fcb284a55ae13ac685b73d79036fb9de39443e4fbba9f7d3e804ad85c6128ce2e138f92e19df17cda51297089be300 -GMP.v6.2.1+5.i686-linux-gnu-cxx11.tar.gz/md5/5882ef18722ca8ea83fc64796ac9a6fc -GMP.v6.2.1+5.i686-linux-gnu-cxx11.tar.gz/sha512/45a25dc59060640accbb9d09574f769da05c448891a7e00b608ec3349c3d05b41710c49cd7d7fa4c5101adc9db1625ff19082715d1a9296e9da957520cca8e9e -GMP.v6.2.1+5.i686-linux-musl-cxx03.tar.gz/md5/dbf0e6f7b74e48ff63e136b4703a92df -GMP.v6.2.1+5.i686-linux-musl-cxx03.tar.gz/sha512/69321bd73da7271147f6cb073c9c8e853ab5b6b84d2cf196df197121a6fe0f6c1c64839bfd1106bba7e547b02f9dd32be9603d76be270e1e22854c600141e80f -GMP.v6.2.1+5.i686-linux-musl-cxx11.tar.gz/md5/94204c12eba64544f58a3dc0b8afc43e -GMP.v6.2.1+5.i686-linux-musl-cxx11.tar.gz/sha512/734b529a24b85eca85b3a95a3df9673a5aa51e2c61456557d273c122870018b574b09a678263c122bcef706c47dc69b142aeb688ccdcd39761eb8ca45e635a3f -GMP.v6.2.1+5.i686-w64-mingw32-cxx03.tar.gz/md5/327155a11581b319a58e780eb97628ad -GMP.v6.2.1+5.i686-w64-mingw32-cxx03.tar.gz/sha512/32c6eaaa3e2d6cc354d7c8cd8cd3b348d560d818f8af0fe8d738b8476e811d38c0d85d4dad9433ce9915322ce2c7634480340c0aace987eebeffd692f4a325d0 -GMP.v6.2.1+5.i686-w64-mingw32-cxx11.tar.gz/md5/d7ae966f2ffef8abfb731579c4ef5fb0 -GMP.v6.2.1+5.i686-w64-mingw32-cxx11.tar.gz/sha512/ebf234e3dd983d49f68ea2322d2658f9cad53de4ec94a0db33f47860331991ca765ec86a646242fdbbeb36051a182767de75ad47e7808bcbac32b196cbc538b3 -GMP.v6.2.1+5.powerpc64le-linux-gnu-cxx03.tar.gz/md5/96bab6f8a36d110065cbe06d8fa654ef -GMP.v6.2.1+5.powerpc64le-linux-gnu-cxx03.tar.gz/sha512/d5472ea1a16ec2312e96b85cba9209eb543abca1b07c48fd7a31c42892fe4a9a2368edbb2f2410580a9ff3337a6b9dbb6cad377fc2ffa66746d4a25fb2da4d46 -GMP.v6.2.1+5.powerpc64le-linux-gnu-cxx11.tar.gz/md5/41704d02be36f94086f8e79124c15410 -GMP.v6.2.1+5.powerpc64le-linux-gnu-cxx11.tar.gz/sha512/dc1800a7e796b4e5dea7c7136545a3120b619f25e28b3aa7e2478dc27d4224160bfc0e03875c4fdd6703c854a8851b27b0f23fd2f5470450230bfb33e337a420 -GMP.v6.2.1+5.x86_64-apple-darwin.tar.gz/md5/ec93617dd921d13eeccf946aeda3bdab -GMP.v6.2.1+5.x86_64-apple-darwin.tar.gz/sha512/a1c490e969d2d747d81016381bbabd6c07915ceca456e4fa77f0bb473193fa013dc185ae4b8bb8bd3451a25d9779f90039ac362d8c911fc307928af22e79a50c -GMP.v6.2.1+5.x86_64-linux-gnu-cxx03.tar.gz/md5/899dadfaaf4cd1d787ac6a905c108a02 -GMP.v6.2.1+5.x86_64-linux-gnu-cxx03.tar.gz/sha512/d304e85f17503a8e9472b69e908f04c6c3e8e3a88f3692f86c0e1e8d5576620b9b144e2224111a7e6f0eb5a58c6f1cb536803764fc8be13a8ef3147f3bbf779a -GMP.v6.2.1+5.x86_64-linux-gnu-cxx11.tar.gz/md5/ece1ecee696e47609ab06b6463f3ede2 -GMP.v6.2.1+5.x86_64-linux-gnu-cxx11.tar.gz/sha512/7fee1caf74f01d2ac9538642901f969f1715ce84199dccd17e016fdeab22fa5dc7a6865e1b5ebf7f54b287d51f7eb48eba4a0b7eb80b8fc4485e49198b914531 -GMP.v6.2.1+5.x86_64-linux-musl-cxx03.tar.gz/md5/aff0fb74a84d0867f2692bf61787bfd1 -GMP.v6.2.1+5.x86_64-linux-musl-cxx03.tar.gz/sha512/057d552a433f0f4e8d1f5cc1c3f1125f5096a7de72ce41ecb1ab2b7e378e0e39f323a4c50f8875c8ba1a5b66541b83e0841fe60f0ece168aeb3a9b63d3eac68f -GMP.v6.2.1+5.x86_64-linux-musl-cxx11.tar.gz/md5/89f6a22a065acbb2366076b271949141 -GMP.v6.2.1+5.x86_64-linux-musl-cxx11.tar.gz/sha512/93cdb3b1ccfbc7c0aca1f9497022d2ea69a023142d59144853300f02b5a25a8f6eacb5da68ff6dc6e969bc315d14386c75aedb828670e96fe84ccb83591bbde4 -GMP.v6.2.1+5.x86_64-unknown-freebsd.tar.gz/md5/285707b8dedcee127959bde79d6ad622 -GMP.v6.2.1+5.x86_64-unknown-freebsd.tar.gz/sha512/77d70f2b29d0bc1fd6c2d938db5b1883697b181d05491931c53eb6d23d84560743fb069ed3b8b9374fdf7d3c37b1f8f732d038e133e38fd3f42a8182ef50fc20 -GMP.v6.2.1+5.x86_64-w64-mingw32-cxx03.tar.gz/md5/fe8257f44266f6741eca3ff288048725 -GMP.v6.2.1+5.x86_64-w64-mingw32-cxx03.tar.gz/sha512/225bf51c55de35cf81e36d848e2fae2646722ceea2e72d66d6d476422df2f5960819db4f3d8a89428fe4d865a657ee4313398109f6fe688971d151cbcd69a279 -GMP.v6.2.1+5.x86_64-w64-mingw32-cxx11.tar.gz/md5/cfb3c9a7a015a271f50dd2a55b55297e -GMP.v6.2.1+5.x86_64-w64-mingw32-cxx11.tar.gz/sha512/a8b6587d9e6a8964d1ff914402b48a6f8ad52cbca96ba5bf732e4e232bf0c942d535926e755983c5e4cc4aa90b473edeac44742ef498963d1276f1ff3c49fa98 +GMP.v6.2.1+6.aarch64-apple-darwin.tar.gz/md5/8123f7925ae9aa60b6998313b21a9db9 +GMP.v6.2.1+6.aarch64-apple-darwin.tar.gz/sha512/5c7927ecfd47409dd4116cd4209768294ba229b51472ed220da498823dc1e7f9100292ec4b3a990491acd27f16ce3a3dce7a7c6e20dcd515982a9c8e364d91bc +GMP.v6.2.1+6.aarch64-linux-gnu-cxx03.tar.gz/md5/0d0d2ee67cff251941e3474341280b34 +GMP.v6.2.1+6.aarch64-linux-gnu-cxx03.tar.gz/sha512/69fb2f1476e0bb73f89ad2f73b58ec4da1b99e099124666e6da93b7705fde23913daa59f2ad479f99fcb4f0df152603bb0ba4875420b583f01fded0fec280a15 +GMP.v6.2.1+6.aarch64-linux-gnu-cxx11.tar.gz/md5/86ba1313c8ab4ca1ae8313cbf96e1e7d +GMP.v6.2.1+6.aarch64-linux-gnu-cxx11.tar.gz/sha512/05c306c01d1b0e9e4dc7ce937075eeaede4e5e0791826a8892fae2eb73cdb7f22c4873cf31cea3cfe3db996ac77387346f4f8a851ce52c29883146678f3851fd +GMP.v6.2.1+6.aarch64-linux-musl-cxx03.tar.gz/md5/2fbbb9adee7db794f5888442b7b7688c +GMP.v6.2.1+6.aarch64-linux-musl-cxx03.tar.gz/sha512/d8a1719e529374d00ba6372013d0c7ddc9f44f9f6ee0f966b4ed16d731ce74c26b6e6a807403b3396bed67dd3e775e18c1e70c247a371d622a6e7013eb6b8905 +GMP.v6.2.1+6.aarch64-linux-musl-cxx11.tar.gz/md5/b6a8c494d4c90decb6eacbca3ce3f22a +GMP.v6.2.1+6.aarch64-linux-musl-cxx11.tar.gz/sha512/6798406e20cc4d58647c266a2b1b8d0670e62f19bf4bff991c39eef13cf92c043f00717e7289bcc00007d7e248e943b37ba2eef89c9e68c42e30f0e2be9dd589 +GMP.v6.2.1+6.armv6l-linux-gnueabihf-cxx03.tar.gz/md5/a6866ee9784e9359e32dc18f417b2be7 +GMP.v6.2.1+6.armv6l-linux-gnueabihf-cxx03.tar.gz/sha512/548953ccc8444886316d4dfd7081783e397ec180e88a1d17a464e4b1d0a27f51ee7f6a1936ddab499db192d3cdfdc87d572731c5ab2f87d528609dabfccad2d3 +GMP.v6.2.1+6.armv6l-linux-gnueabihf-cxx11.tar.gz/md5/6b78c826a4aedc8107c1bbfccbe5c097 +GMP.v6.2.1+6.armv6l-linux-gnueabihf-cxx11.tar.gz/sha512/e8c075c29e4d8a916f087faeb2db50168e1a5546fcb02fc841477cf82a39188c3b9e7703b5354d4842880b5ac7215a32d022abe08aacc5e23238b63c6b994af4 +GMP.v6.2.1+6.armv6l-linux-musleabihf-cxx03.tar.gz/md5/57e1a6c71b3c5b4047bf08bfc4d4f22d +GMP.v6.2.1+6.armv6l-linux-musleabihf-cxx03.tar.gz/sha512/0f72c675ab3005ea183393bc4e5b4a157c13042367fd1bb3b03b3f7742e09604bddffb89f1478dc0dab4d992939519578549d05f9885b89319b0b51678b8a619 +GMP.v6.2.1+6.armv6l-linux-musleabihf-cxx11.tar.gz/md5/65a13f49cbdaa9d3a8e20d0b84bbc701 +GMP.v6.2.1+6.armv6l-linux-musleabihf-cxx11.tar.gz/sha512/0487b18d1c9c59d990e6c4ec435b8dff91ae02d5d56c665b12aaaea105f7d2ab5beae9dfcbb133c990f70774b0d32e55df7f2e91e2d0a85c391a4090dcadf080 +GMP.v6.2.1+6.armv7l-linux-gnueabihf-cxx03.tar.gz/md5/30e20c183153f8ce60e564b35e4b54bd +GMP.v6.2.1+6.armv7l-linux-gnueabihf-cxx03.tar.gz/sha512/41bdabc2610b46b215043e98eaddb2e2ad0695ae15f3088c9beef24a97864dce4088ae68993de928d952baaf123f279d74705664fffbf96be9b7436f1ba7692b +GMP.v6.2.1+6.armv7l-linux-gnueabihf-cxx11.tar.gz/md5/5f2cba31677e6681666c0b6ebd33c3ad +GMP.v6.2.1+6.armv7l-linux-gnueabihf-cxx11.tar.gz/sha512/a89399bf84bebf4b8432e48aae6dce5547bb6f1c048364697c577541c4f1a555b976370634624e9cf039fcbcb70e449a2f55563f0a4f48e60ee4653a185cf7dd +GMP.v6.2.1+6.armv7l-linux-musleabihf-cxx03.tar.gz/md5/4a682d832109d7ab5743832f73ca33d2 +GMP.v6.2.1+6.armv7l-linux-musleabihf-cxx03.tar.gz/sha512/d5062bd8eee926eb1177e70e5d9e8d6ed7a00a17c25d2b165b974c01aa79d45ca97e219b26ded752b5f323546192d595b838b474c61bdd87e641549db9e9ef5d +GMP.v6.2.1+6.armv7l-linux-musleabihf-cxx11.tar.gz/md5/caa51529cb1b6dc8db765e202e1b7737 +GMP.v6.2.1+6.armv7l-linux-musleabihf-cxx11.tar.gz/sha512/d11ae870e68ca8d28bbcdf799a04769c3df2fbd169f6f2b16d88a556c40866b39636820ac3497e869086e638ba31dc1c87ec780add2d1aafe5e4ca178641678e +GMP.v6.2.1+6.i686-linux-gnu-cxx03.tar.gz/md5/dfcb024b9cfba37f80da5b7cc0c5b1ad +GMP.v6.2.1+6.i686-linux-gnu-cxx03.tar.gz/sha512/10eb086228b4250ecce11ad5bbec15e2bfff2429530cfd700602ead7f108163bc48fc83d9714443cbf5a93e7dd5f9046bdc15ef324486475f6b4be1cf34bad4b +GMP.v6.2.1+6.i686-linux-gnu-cxx11.tar.gz/md5/e889c1d65c9ca710c859129ae99ef322 +GMP.v6.2.1+6.i686-linux-gnu-cxx11.tar.gz/sha512/4d97ebdd6a12d39907ccc9bad00266e286c949b3f99a306c1c4a4380a292694d944f275c351d9ddf465d020c8197b3b19dfccb5080249c75e3f5ffb9aa77a1c4 +GMP.v6.2.1+6.i686-linux-musl-cxx03.tar.gz/md5/d57b3948e7a120bafeae67c28fe40869 +GMP.v6.2.1+6.i686-linux-musl-cxx03.tar.gz/sha512/88165c809a73007d2b5e750d23c619fbb088f6de200aae1dee34b5e3783949150d91b94774cd1881d2a621d092c0e7e7332707ed4737ff8426686dfce7e0313a +GMP.v6.2.1+6.i686-linux-musl-cxx11.tar.gz/md5/e3c53fc468a9f48f9d06fdf51eafae62 +GMP.v6.2.1+6.i686-linux-musl-cxx11.tar.gz/sha512/3c6a99acd84c226d7a48177c8e18624a677ea2a3df15fb2d54002eb5a6d55144b6f51f82ff491373366f32e92252fd14747503166621c2d2359029bdb1b20741 +GMP.v6.2.1+6.i686-w64-mingw32-cxx03.tar.gz/md5/64b9bed188f9a300200659efdb9facef +GMP.v6.2.1+6.i686-w64-mingw32-cxx03.tar.gz/sha512/f7ed47cc29be31f99e612abd1db0d806ece84c117677cd639e04e2f6b08bbbfa4056ed9504bb073ec5f722de6955db668934f3d3ca05ddde0f22b096afcea2e3 +GMP.v6.2.1+6.i686-w64-mingw32-cxx11.tar.gz/md5/a8f38cefb46dc9c3faddfd597d0e1a4c +GMP.v6.2.1+6.i686-w64-mingw32-cxx11.tar.gz/sha512/f02c3458c05869fab493d9be5ea98390baf6eed136fe2916cd6214c4f24a6f22d0716d59f352454fd4c799df71a8fd90e3a169644e1c6ffe89f3620f2a52f158 +GMP.v6.2.1+6.powerpc64le-linux-gnu-cxx03.tar.gz/md5/7f8da2b7e16ef4cb593fea4bdb2e43eb +GMP.v6.2.1+6.powerpc64le-linux-gnu-cxx03.tar.gz/sha512/d0105fe7dfcc1daf7024d2f58b53240bab473c3ae44a904833d009beeb8e41f5487430f68e79bd79fc5c74b55f1111eb7479fedc84bcb45fe4dff3d8c3ac3e4f +GMP.v6.2.1+6.powerpc64le-linux-gnu-cxx11.tar.gz/md5/31fb7b6e37c650f0b8c3a2d475cb2b5b +GMP.v6.2.1+6.powerpc64le-linux-gnu-cxx11.tar.gz/sha512/d03f3f1303996008ff267682de5b9d6e3be78ca1b0d6aa7cadbf4a612b331fe70460b689125f4ededa1c6078092ad3dafaad32c68a98d31713764a7a7461cf98 +GMP.v6.2.1+6.x86_64-apple-darwin.tar.gz/md5/9276d90b4f850f167f673f731c7d3781 +GMP.v6.2.1+6.x86_64-apple-darwin.tar.gz/sha512/f914452a49988b0694915483547c2f878c0ba71be2079fd1228b3e583cb08e92d8c958a052f29025054ded74cacb699893a5a6ef27749c851e83607ad3f1fe8f +GMP.v6.2.1+6.x86_64-linux-gnu-cxx03.tar.gz/md5/cded149fcef93ab1ba89c51d7cc58b73 +GMP.v6.2.1+6.x86_64-linux-gnu-cxx03.tar.gz/sha512/8f97582d6323df6f86e3079b9a2534425bd4e64bb4cec337c21059605d50c1220fd006e55bdb34e8aa7195cd79ef518f1541c1b1a92187ed928f7939b3128dd6 +GMP.v6.2.1+6.x86_64-linux-gnu-cxx11.tar.gz/md5/0529bb60dcf584222cd91e9e11510f24 +GMP.v6.2.1+6.x86_64-linux-gnu-cxx11.tar.gz/sha512/0532821e81a4e51363570f87ec59c37dea24cab59a94e43127837ce4b388d1951853d50e52d4c9f30b4a21cfe222e368207239ce8ac0f1ee1e9375f51fb10127 +GMP.v6.2.1+6.x86_64-linux-musl-cxx03.tar.gz/md5/2d332d096da5515581ee92128aff88ab +GMP.v6.2.1+6.x86_64-linux-musl-cxx03.tar.gz/sha512/b17f7b762bd4d61fa4c4be8124275c2b337383da167bdeaca34e44d71f20716b182b46bc5a6714a798a0951d73b335ab9c87f451cf4c5456edbe76cf3ad36ba4 +GMP.v6.2.1+6.x86_64-linux-musl-cxx11.tar.gz/md5/a9dae953f9d59589162a3ea149c46d1e +GMP.v6.2.1+6.x86_64-linux-musl-cxx11.tar.gz/sha512/31e568aba38a29ec6713dda9eb1c7d7b50c2a736e8883ae8ff2eaf16840b15c93e6dc53025e7750d3ac3e4ffc7d2c91787bda5b799ecfdeea3d928657176b1b3 +GMP.v6.2.1+6.x86_64-unknown-freebsd.tar.gz/md5/6f42d7486fa85ce1bf0cac409d1dd5ae +GMP.v6.2.1+6.x86_64-unknown-freebsd.tar.gz/sha512/5111751619388e51d1b3c0e32548a6de0aa02b7967994a4b4b78cdc9e0e852dae9d78bf48a503a6fb67e3b08343ddcf5a9f0b7a64a803c4d5067d69e4cb2edee +GMP.v6.2.1+6.x86_64-w64-mingw32-cxx03.tar.gz/md5/39cca70db2d23bc73a47870a0ee5156c +GMP.v6.2.1+6.x86_64-w64-mingw32-cxx03.tar.gz/sha512/a2877a6641e4cccd39e7ef093dd9ba7501c6e312f160b2924880d129195aadb74badfbf198fd6ee11035a6a7c99d64c0965c44526104a43569ca0d97fa565b5a +GMP.v6.2.1+6.x86_64-w64-mingw32-cxx11.tar.gz/md5/e2e03ed150558405ca1993ca14488662 +GMP.v6.2.1+6.x86_64-w64-mingw32-cxx11.tar.gz/sha512/50995f6382ed2a4c425097e7abf762b847872734c104847f6a042090be132c68e864d34bb24baf64832d3636810cb631464767949eb2df2fedaa7ccd9824f78b gmp-6.2.1.tar.bz2/md5/28971fc21cf028042d4897f02fd355ea gmp-6.2.1.tar.bz2/sha512/8904334a3bcc5c896ececabc75cda9dec642e401fb5397c4992c4fabea5e962c9ce8bd44e8e4233c34e55c8010cc28db0545f5f750cbdbb5f00af538dc763be9 diff --git a/deps/gmp.mk b/deps/gmp.mk index 12ba15f8aa0f6..0ebabe53acf8d 100644 --- a/deps/gmp.mk +++ b/deps/gmp.mk @@ -57,7 +57,12 @@ $(SRCCACHE)/gmp-$(GMP_VER)/gmp-CVE-2021-43618.patch-applied: $(SRCCACHE)/gmp-$(G patch -p1 < $(SRCDIR)/patches/gmp-CVE-2021-43618.patch echo 1 > $@ -$(SRCCACHE)/gmp-$(GMP_VER)/source-patched: $(SRCCACHE)/gmp-$(GMP_VER)/gmp-CVE-2021-43618.patch-applied +$(SRCCACHE)/gmp-$(GMP_VER)/gmp-more_alloc_overflow.patch-applied: $(SRCCACHE)/gmp-$(GMP_VER)/gmp-CVE-2021-43618.patch-applied + cd $(dir $@) && \ + patch -p1 < $(SRCDIR)/patches/gmp-more_alloc_overflow.patch + echo 1 > $@ + +$(SRCCACHE)/gmp-$(GMP_VER)/source-patched: $(SRCCACHE)/gmp-$(GMP_VER)/gmp-more_alloc_overflow.patch-applied echo 1 > $@ $(BUILDDIR)/gmp-$(GMP_VER)/build-configured: $(SRCCACHE)/gmp-$(GMP_VER)/source-patched diff --git a/deps/patches/gmp-more_alloc_overflow.patch b/deps/patches/gmp-more_alloc_overflow.patch new file mode 100644 index 0000000000000..09d07d7dbd8d5 --- /dev/null +++ b/deps/patches/gmp-more_alloc_overflow.patch @@ -0,0 +1,37 @@ +diff -ur gmp-6.2.1.orig/mpz/n_pow_ui.c gmp-6.2.1/mpz/n_pow_ui.c +--- gmp-6.2.1.orig/mpz/n_pow_ui.c 2023-09-08 11:41:16.620551175 +0200 ++++ gmp-6.2.1/mpz/n_pow_ui.c 2023-09-08 12:49:29.650492180 +0200 +@@ -220,8 +220,7 @@ + umul_ppmm (ovfl, rtwos_bits, e, btwos); + if (ovfl) + { +- fprintf (stderr, "gmp: overflow in mpz type\n"); +- abort (); ++ __GMP_ALLOC_OVERFLOW_FUNC (); + } + + rtwos_limbs += rtwos_bits / GMP_NUMB_BITS; +@@ -382,8 +381,7 @@ + umul_ppmm (ovfl, ralloc, (bsize*GMP_NUMB_BITS - cnt + GMP_NAIL_BITS), e); + if (ovfl) + { +- fprintf (stderr, "gmp: overflow in mpz type\n"); +- abort (); ++ __GMP_ALLOC_OVERFLOW_FUNC (); + } + ralloc = ralloc / GMP_NUMB_BITS + 5; + +diff -ur gmp-6.2.1.orig/tal-reent.c gmp-6.2.1/tal-reent.c +--- gmp-6.2.1.orig/tal-reent.c 2020-11-14 19:45:09.000000000 +0100 ++++ gmp-6.2.1/tal-reent.c 2023-09-08 12:10:34.061357613 +0200 +@@ -61,6 +61,11 @@ + + total_size = size + HSIZ; + p = __GMP_ALLOCATE_FUNC_TYPE (total_size, char); ++ if (!p) ++ { ++ __GMP_ALLOC_OVERFLOW_FUNC (); ++ } + P->size = total_size; + P->next = *markp; + *markp = P; diff --git a/stdlib/GMP_jll/Project.toml b/stdlib/GMP_jll/Project.toml index e4af2a8674a51..9f3b917257bfa 100644 --- a/stdlib/GMP_jll/Project.toml +++ b/stdlib/GMP_jll/Project.toml @@ -1,6 +1,6 @@ name = "GMP_jll" uuid = "781609d7-10c4-51f6-84f2-b8444358ff6d" -version = "6.2.1+5" +version = "6.2.1+6" [deps] Artifacts = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" diff --git a/test/gmp.jl b/test/gmp.jl index 8f6be13c38054..6efc349ca2ba1 100644 --- a/test/gmp.jl +++ b/test/gmp.jl @@ -11,6 +11,11 @@ ee = typemax(Int64) @test BigInt <: Signed @test big(1) isa Signed + if sizeof(Culong) >= 8 + @test_throws OutOfMemoryError big(96608869069402268615522366320733234710)^16374500563449903721 + @test_throws OutOfMemoryError 555555555555555555555555555555555555555555555555555^55555555555555555 + end + let x = big(1) @test signed(x) === x @test convert(Signed, x) === x From 2e14912310c3b5fe47a51489589496e8e5db2546 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 12 Sep 2023 12:23:19 -0400 Subject: [PATCH 43/56] Ryu: make sure adding zeros does not overwrite trailing dot (#51254) Fix #43129 (cherry picked from commit 832e46d923d4cf81351038a046e22f221b5e6120) --- base/ryu/exp.jl | 2 +- base/ryu/fixed.jl | 12 ++++++------ test/ryu.jl | 5 +++++ 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/base/ryu/exp.jl b/base/ryu/exp.jl index 30291212d014d..90c6869f8847f 100644 --- a/base/ryu/exp.jl +++ b/base/ryu/exp.jl @@ -147,7 +147,7 @@ function writeexp(buf, pos, v::T, end roundUp = 0 if lastDigit != 5 - roundUp = lastDigit > 5 + roundUp = lastDigit > 5 ? 1 : 0 else rexp = precision - e requiredTwos = -e2 - rexp diff --git a/base/ryu/fixed.jl b/base/ryu/fixed.jl index e0085f5c66dab..f0b96fef966f0 100644 --- a/base/ryu/fixed.jl +++ b/base/ryu/fixed.jl @@ -38,7 +38,7 @@ function writefixed(buf, pos, v::T, mant = bits & MANTISSA_MASK exp = Int((bits >> 52) & EXP_MASK) - if exp == 0 + if exp == 0 # subnormal e2 = 1 - 1023 - 52 m2 = mant else @@ -53,7 +53,7 @@ function writefixed(buf, pos, v::T, i = len - 1 while i >= 0 j = p10bits - e2 - #=@inbounds=# mula, mulb, mulc = POW10_SPLIT[POW10_OFFSET[idx + 1] + i + 1] + mula, mulb, mulc = POW10_SPLIT[POW10_OFFSET[idx + 1] + i + 1] digits = mulshiftmod1e9(m2 << 8, mula, mulb, mulc, j + 8) if nonzero pos = append_nine_digits(digits, buf, pos) @@ -103,7 +103,7 @@ function writefixed(buf, pos, v::T, end break end - #=@inbounds=# mula, mulb, mulc = POW10_SPLIT_2[p + 1] + mula, mulb, mulc = POW10_SPLIT_2[p + 1] digits = mulshiftmod1e9(m2 << 8, mula, mulb, mulc, j + 8) if i < blocks - 1 pos = append_nine_digits(digits, buf, pos) @@ -118,11 +118,11 @@ function writefixed(buf, pos, v::T, k += 1 end if lastDigit != 5 - roundUp = lastDigit > 5 + roundUp = lastDigit > 5 ? 1 : 0 else requiredTwos = -e2 - precision - 1 trailingZeros = requiredTwos <= 0 || (requiredTwos < 60 && pow2(m2, requiredTwos)) - roundUp = trailingZeros ? 2 : 1 + roundUp = trailingZeros ? 2 : 1 # 2 means round only if odd end if maximum > 0 pos = append_c_digits(maximum, digits, buf, pos) @@ -137,13 +137,13 @@ function writefixed(buf, pos, v::T, while true roundPos -= 1 if roundPos == (startpos - 1) || (buf[roundPos] == UInt8('-')) || (plus && buf[roundPos] == UInt8('+')) || (space && buf[roundPos] == UInt8(' ')) + buf[pos] = UInt8('0') buf[roundPos + 1] = UInt8('1') if dotPos > 1 buf[dotPos] = UInt8('0') buf[dotPos + 1] = decchar hasfractional = true end - buf[pos] = UInt8('0') pos += 1 break end diff --git a/test/ryu.jl b/test/ryu.jl index 0b10bd7e49ba5..4acd2fd08df50 100644 --- a/test/ryu.jl +++ b/test/ryu.jl @@ -558,6 +558,11 @@ end # Float16 @test Ryu.writefixed(1.25e+5, 1, false, false, false, UInt8('.'), true) == "125000" @test Ryu.writefixed(1.25e+5, 2, false, false, false, UInt8('.'), true) == "125000" end + + @test Ryu.writefixed(100.0-eps(100.0), 0, false, false, true, UInt8('.'), false) == "100." + @test Ryu.writefixed(-100.0+eps(-100.0), 0, false, false, true, UInt8('.'), false) == "-100." + @test Ryu.writefixed(100.0-eps(100.0), 1, false, false, true, UInt8('.'), false) == "100.0" + @test Ryu.writefixed(-100.0+eps(-100.0), 1, false, false, true, UInt8('.'), false) == "-100.0" end # fixed @testset "Ryu.writeexp" begin From de20256209ec9531bac8d45735aa1720beafc888 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Tue, 12 Sep 2023 23:19:26 +0100 Subject: [PATCH 44/56] shorten stale_age for cachefile lock (#51175) (cherry picked from commit 4af6be80f238fce9cd124925d488a4c7171cf74a) --- base/loading.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/base/loading.jl b/base/loading.jl index 90f549b7a5cb9..dd7038845f4f8 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -2968,11 +2968,13 @@ global parse_pidfile_hook compilecache_pidfile_path(pkg::PkgId) = compilecache_path(pkg, UInt64(0); project="") * ".pidfile" # Allows processes to wait if another process is precompiling a given source already. -# The lock file is deleted and precompilation will proceed after `stale_age` seconds if +# The lock file mtime will be updated when held every `stale_age/2` seconds. +# After `stale_age` seconds beyond the mtime of the lock file, the lock file is deleted and +# precompilation will proceed if # - the locking process no longer exists # - the lock is held by another host, since processes cannot be checked remotely # or after `stale_age * 25` seconds if the process does still exist. -function maybe_cachefile_lock(f, pkg::PkgId, srcpath::String; stale_age=300) +function maybe_cachefile_lock(f, pkg::PkgId, srcpath::String; stale_age=10) if @isdefined(mkpidlock_hook) && @isdefined(trymkpidlock_hook) && @isdefined(parse_pidfile_hook) pidfile = compilecache_pidfile_path(pkg) cachefile = invokelatest(trymkpidlock_hook, f, pidfile; stale_age) From 503a44f77cb28818fe0828049872c4116a735da4 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Wed, 13 Sep 2023 17:36:52 -0400 Subject: [PATCH 45/56] fix method definition error for bad vararg (#51300) We had the ordering of tests incorrect, so Vararg was not correctly checked for validity during method definition. Fixes #51228 (cherry picked from commit 34e603503853ec16f6d2f8877c212d9029bb8f06) --- src/method.c | 19 ++++++++++--------- test/syntax.jl | 4 ++++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/method.c b/src/method.c index 06a05361a927d..e96d1008e3056 100644 --- a/src/method.c +++ b/src/method.c @@ -1039,9 +1039,16 @@ JL_DLLEXPORT jl_method_t* jl_method_def(jl_svec_t *argdata, for (i = 0; i < na; i++) { jl_value_t *elt = jl_svecref(atypes, i); - int isvalid = jl_is_type(elt) || jl_is_typevar(elt) || jl_is_vararg(elt); - if (elt == jl_bottom_type || (jl_is_vararg(elt) && jl_unwrap_vararg(elt) == jl_bottom_type)) - isvalid = 0; + if (jl_is_vararg(elt)) { + if (i < na-1) + jl_exceptionf(jl_argumenterror_type, + "Vararg on non-final argument in method definition for %s at %s:%d", + jl_symbol_name(name), + jl_symbol_name(file), + line); + elt = jl_unwrap_vararg(elt); + } + int isvalid = (jl_is_type(elt) || jl_is_typevar(elt) || jl_is_vararg(elt)) && elt != jl_bottom_type; if (!isvalid) { jl_sym_t *argname = (jl_sym_t*)jl_array_ptr_ref(f->slotnames, i); if (argname == jl_unused_sym) @@ -1059,12 +1066,6 @@ JL_DLLEXPORT jl_method_t* jl_method_def(jl_svec_t *argdata, jl_symbol_name(file), line); } - if (jl_is_vararg(elt) && i < na-1) - jl_exceptionf(jl_argumenterror_type, - "Vararg on non-final argument in method definition for %s at %s:%d", - jl_symbol_name(name), - jl_symbol_name(file), - line); } for (i = jl_svec_len(tvars); i > 0; i--) { jl_value_t *tv = jl_svecref(tvars, i - 1); diff --git a/test/syntax.jl b/test/syntax.jl index 4d1b167693adb..36f0f50c376c4 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -501,6 +501,10 @@ let m_error, error_out, filename = Base.source_path() m_error = try @eval foo(types::NTuple{N}, values::Vararg{Any,N}, c) where {N} = nothing; catch e; e; end error_out = sprint(showerror, m_error) @test startswith(error_out, "ArgumentError: Vararg on non-final argument") + + m_error = try @eval method_c6(a::Vararg{:A}) = 1; catch e; e; end + error_out = sprint(showerror, m_error) + @test startswith(error_out, "ArgumentError: invalid type for argument a in method definition for method_c6 at $filename:") end # issue #7272 From ea93115ebc6257a4d11aedc6a341c5df67c2badd Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 14 Sep 2023 10:35:50 -0400 Subject: [PATCH 46/56] fix force-throw ctrl-C on Windows (#51307) This was getting current-task on the wrong thread, which resulted in the value being NULL and crashing. Fixes #50325 (cherry picked from commit 5090bc05f01728ffaa7ab028611eb9df3159fbef) --- src/signals-win.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/signals-win.c b/src/signals-win.c index 5dd6b34558ca6..7cd3b02462851 100644 --- a/src/signals-win.c +++ b/src/signals-win.c @@ -124,10 +124,8 @@ void restore_signals(void) SetConsoleCtrlHandler(NULL, 0); } -void jl_throw_in_ctx(jl_value_t *excpt, PCONTEXT ctxThread) +void jl_throw_in_ctx(jl_task_t *ct, jl_value_t *excpt, PCONTEXT ctxThread) { - jl_task_t *ct = jl_current_task; - jl_ptls_t ptls = ct->ptls; #if defined(_CPU_X86_64_) DWORD64 Rsp = (ctxThread->Rsp & (DWORD64)-16) - 8; #elif defined(_CPU_X86_) @@ -135,8 +133,9 @@ void jl_throw_in_ctx(jl_value_t *excpt, PCONTEXT ctxThread) #else #error WIN16 not supported :P #endif - if (!jl_get_safe_restore()) { + if (ct && !jl_get_safe_restore()) { assert(excpt != NULL); + jl_ptls_t ptls = ct->ptls; ptls->bt_size = 0; if (excpt != jl_stackovf_exception) { ptls->bt_size = rec_backtrace_ctx(ptls->bt_data, JL_MAX_BT_SIZE, ctxThread, @@ -193,7 +192,8 @@ static void jl_try_deliver_sigint(void) jl_safe_printf("error: GetThreadContext failed\n"); return; } - jl_throw_in_ctx(jl_interrupt_exception, &ctxThread); + jl_task_t *ct = jl_atomic_load_relaxed(&ptls2->current_task); + jl_throw_in_ctx(ct, jl_interrupt_exception, &ctxThread); ctxThread.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; if (!SetThreadContext(hMainThread, &ctxThread)) { jl_safe_printf("error: SetThreadContext failed\n"); @@ -237,14 +237,14 @@ LONG WINAPI jl_exception_handler(struct _EXCEPTION_POINTERS *ExceptionInfo) case EXCEPTION_INT_DIVIDE_BY_ZERO: if (ct->eh != NULL) { fpreset(); - jl_throw_in_ctx(jl_diverror_exception, ExceptionInfo->ContextRecord); + jl_throw_in_ctx(ct, jl_diverror_exception, ExceptionInfo->ContextRecord); return EXCEPTION_CONTINUE_EXECUTION; } break; case EXCEPTION_STACK_OVERFLOW: if (ct->eh != NULL) { ptls->needs_resetstkoflw = 1; - jl_throw_in_ctx(jl_stackovf_exception, ExceptionInfo->ContextRecord); + jl_throw_in_ctx(ct, jl_stackovf_exception, ExceptionInfo->ContextRecord); return EXCEPTION_CONTINUE_EXECUTION; } break; @@ -259,17 +259,17 @@ LONG WINAPI jl_exception_handler(struct _EXCEPTION_POINTERS *ExceptionInfo) } else if (jl_safepoint_consume_sigint()) { jl_clear_force_sigint(); - jl_throw_in_ctx(jl_interrupt_exception, ExceptionInfo->ContextRecord); + jl_throw_in_ctx(ct, jl_interrupt_exception, ExceptionInfo->ContextRecord); } return EXCEPTION_CONTINUE_EXECUTION; } if (jl_get_safe_restore()) { - jl_throw_in_ctx(NULL, ExceptionInfo->ContextRecord); + jl_throw_in_ctx(NULL, NULL, ExceptionInfo->ContextRecord); return EXCEPTION_CONTINUE_EXECUTION; } if (ct->eh != NULL) { if (ExceptionInfo->ExceptionRecord->ExceptionInformation[0] == 1) { // writing to read-only memory (e.g. mmap) - jl_throw_in_ctx(jl_readonlymemory_exception, ExceptionInfo->ContextRecord); + jl_throw_in_ctx(ct, jl_readonlymemory_exception, ExceptionInfo->ContextRecord); return EXCEPTION_CONTINUE_EXECUTION; } } From 0eff9d86fdc159412250bd31188093311796c5f1 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 14 Sep 2023 10:36:19 -0400 Subject: [PATCH 47/56] jltypes: ensure revising structs is safe (#51303) (cherry picked from commit 11427597eb8e51afe4d31681c8ffde443ff44e10) --- src/jltypes.c | 6 ++++++ test/core.jl | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/jltypes.c b/src/jltypes.c index 8da119248203a..a39bc935fb181 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -2491,6 +2491,8 @@ void jl_reinstantiate_inner_types(jl_datatype_t *t) // can throw! for (j = 0; j < jl_array_len(partial); j++) { jl_datatype_t *ndt = (jl_datatype_t*)jl_array_ptr_ref(partial, j); + if (ndt == NULL) + continue; assert(jl_unwrap_unionall(ndt->name->wrapper) == (jl_value_t*)t); for (i = 0; i < n; i++) env[i].val = jl_svecref(ndt->parameters, i); @@ -2502,6 +2504,8 @@ void jl_reinstantiate_inner_types(jl_datatype_t *t) // can throw! if (t->types != jl_emptysvec) { for (j = 0; j < jl_array_len(partial); j++) { jl_datatype_t *ndt = (jl_datatype_t*)jl_array_ptr_ref(partial, j); + if (ndt == NULL) + continue; for (i = 0; i < n; i++) env[i].val = jl_svecref(ndt->parameters, i); assert(ndt->types == NULL); @@ -2510,7 +2514,9 @@ void jl_reinstantiate_inner_types(jl_datatype_t *t) // can throw! if (ndt->isconcretetype) { // cacheable jl_compute_field_offsets(ndt); } + jl_array_ptr_set(partial, j, NULL); } + t->name->partial = NULL; } else { assert(jl_field_names(t) == jl_emptysvec); diff --git a/test/core.jl b/test/core.jl index 087234abe1a94..0e58b7e157fde 100644 --- a/test/core.jl +++ b/test/core.jl @@ -7544,6 +7544,19 @@ end struct T36104 # check that redefining it works, issue #21816 v::Vector{T36104} end +struct S36104{K,V} + v::S36104{K,V} + S36104{K,V}() where {K,V} = new() + S36104{K,V}(x::S36104) where {K,V} = new(x) +end +@test !isdefined(Base.unwrap_unionall(Base.ImmutableDict).name, :partial) +@test !isdefined(S36104.body.body.name, :partial) +@test hasfield(typeof(S36104.body.body.name), :partial) +struct S36104{K,V} # check that redefining it works + v::S36104{K,V} + S36104{K,V}() where {K,V} = new() + S36104{K,V}(x::S36104) where {K,V} = new(x) +end # with a gensymmed unionall struct Symmetric{T,S<:AbstractMatrix{<:T}} <: AbstractMatrix{T} data::S From 763ec695a746102c8ebc6c0575af02aa1db3e43f Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Thu, 31 Aug 2023 14:57:50 -0400 Subject: [PATCH 48/56] inference: type bound error due to free typevar in sparam env (#51013) Fix #50709 This issue *appears* fixed on master due to #50432, which simply removed the error. This fixes the underlying cause, which is that we sometimes return typevars in the environment from intersection that have free vars in their bounds. I think it's reasonable to just widen these aggressively, since we usually cannot do much with these kinds of unknown static parameters anyway. (cherry picked from commit a3e23161b60e51d7aaa1183559dc70b9c28426e6) --- base/compiler/abstractinterpretation.jl | 6 ++++++ test/compiler/inference.jl | 3 +++ 2 files changed, 9 insertions(+) diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 48b6a234d13ba..973c7dc6f879b 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -2182,6 +2182,12 @@ function sp_type_rewrap(@nospecialize(T), linfo::MethodInstance, isreturn::Bool) T = UnionAll(v, T) end end + if has_free_typevars(T) + fv = ccall(:jl_find_free_typevars, Vector{Any}, (Any,), T) + for v in fv + T = UnionAll(v, T) + end + end else T = rewrap_unionall(T, spsig) end diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index 1799dd94de74f..8b980f1fdb17c 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -5086,6 +5086,9 @@ let x = Issue50544((1, Issue50544((2.0, 'x')))) @test only(Base.return_types(h_issue50544, (typeof(x),))) == Type{Issue50544{Tuple{Int,Float64}}} end +# issue #50709 +@test Base.code_typed_by_type(Tuple{Type{Vector{S}} where {T, S<:AbstractVector{T}}, UndefInitializer, Int})[1][2] == Vector{<:AbstractVector{T}} where T + # override const-prop' return type with the concrete-eval result # if concrete-eval returns non-inlineable constant Base.@assume_effects :foldable function continue_const_prop(i, j) From 76277febc5c232525b1afe2ba1fceaf3a8809dfc Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 14 Sep 2023 10:36:30 -0400 Subject: [PATCH 49/56] reduce test time for rounding and floatfuncs (#51305) These test were taking on the order of 5 minutes and 10-100s of GB, but they really did not need to. (cherry picked from commit bab20f492a61d49e7a2af9289c156e75ebcecf5e) --- test/floatfuncs.jl | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/test/floatfuncs.jl b/test/floatfuncs.jl index 321f1881371a3..a0d6e8743514b 100644 --- a/test/floatfuncs.jl +++ b/test/floatfuncs.jl @@ -139,9 +139,10 @@ end end @testset "literal pow matches runtime pow matches optimized pow" begin - two = 2 - @test 1.0000000105367122^2 == 1.0000000105367122^two - @test 1.0041504f0^2 == 1.0041504f0^two + let two = 2 + @test 1.0000000105367122^2 == 1.0000000105367122^two + @test 1.0041504f0^2 == 1.0041504f0^two + end function g2(start, two, N) x = start @@ -192,11 +193,13 @@ end finv(x) = f(x, -1) f2(x) = f(x, 2) f3(x) = f(x, 3) - x = 1.0000000105367122 - @test x^2 == f(x, 2) == f2(x) == x*x == Float64(big(x)*big(x)) - @test x^3 == f(x, 3) == f3(x) == x*x*x == Float64(big(x)*big(x)*big(x)) - x = 1.000000007393669 - @test x^-1 == f(x, -1) == finv(x) == 1/x == inv(x) == Float64(1/big(x)) == Float64(inv(big(x))) + let x = 1.0000000105367122 + @test x^2 == f(x, 2) == f2(x) == x*x == Float64(big(x)*big(x)) + @test x^3 == f(x, 3) == f3(x) == x*x*x == Float64(big(x)*big(x)*big(x)) + end + let x = 1.000000007393669 + @test x^-1 == f(x, -1) == finv(x) == 1/x == inv(x) == Float64(1/big(x)) == Float64(inv(big(x))) + end end @testset "curried approximation" begin From eea947798da08ca8911938e0947fa37a5577f872 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Wed, 13 Sep 2023 22:20:46 +0200 Subject: [PATCH 50/56] use LibGit2_jll for LibGit2 library (#51294) Fixes https://github.com/JuliaLang/julia/issues/51293 (cherry picked from commit 377f9dfb2dd8be2f2c3d80db7a397150dde53311) --- pkgimage.mk | 8 ++--- stdlib/LibGit2/Project.toml | 1 + stdlib/LibGit2/src/LibGit2.jl | 10 +++--- stdlib/LibGit2/src/blame.jl | 6 ++-- stdlib/LibGit2/src/blob.jl | 8 ++--- stdlib/LibGit2/src/callbacks.jl | 16 +++++----- stdlib/LibGit2/src/commit.jl | 10 +++--- stdlib/LibGit2/src/config.jl | 38 +++++++++++----------- stdlib/LibGit2/src/diff.jl | 18 +++++------ stdlib/LibGit2/src/error.jl | 3 +- stdlib/LibGit2/src/index.jl | 24 +++++++------- stdlib/LibGit2/src/merge.jl | 14 ++++---- stdlib/LibGit2/src/oid.jl | 20 ++++++------ stdlib/LibGit2/src/rebase.jl | 16 +++++----- stdlib/LibGit2/src/reference.jl | 46 +++++++++++++------------- stdlib/LibGit2/src/remote.jl | 34 ++++++++++---------- stdlib/LibGit2/src/repository.jl | 48 ++++++++++++++-------------- stdlib/LibGit2/src/signature.jl | 6 ++-- stdlib/LibGit2/src/status.jl | 8 ++--- stdlib/LibGit2/src/tag.jl | 10 +++--- stdlib/LibGit2/src/tree.jl | 20 ++++++------ stdlib/LibGit2/src/types.jl | 12 +++---- stdlib/LibGit2/src/utils.jl | 4 +-- stdlib/LibGit2/src/walker.jl | 12 +++---- stdlib/LibGit2/test/libgit2-tests.jl | 7 ++-- test/precompile.jl | 18 ++++------- 26 files changed, 209 insertions(+), 208 deletions(-) diff --git a/pkgimage.mk b/pkgimage.mk index 8b127173b4e05..f6afc0a9ab6cc 100644 --- a/pkgimage.mk +++ b/pkgimage.mk @@ -83,7 +83,7 @@ $(eval $(call pkgimg_builder,GMP_jll,Artifacts Libdl)) $(eval $(call pkgimg_builder,LLVMLibUnwind_jll,Artifacts Libdl)) $(eval $(call pkgimg_builder,LibUV_jll,Artifacts Libdl)) $(eval $(call pkgimg_builder,LibUnwind_jll,Artifacts Libdl)) -$(eval $(call pkgimg_builder,MbedTLS_jll,Artifacts Libdl)) +$(eval $(call sysimg_builder,MbedTLS_jll,Artifacts Libdl)) $(eval $(call pkgimg_builder,nghttp2_jll,Artifacts Libdl)) $(eval $(call pkgimg_builder,OpenLibm_jll,Artifacts Libdl)) $(eval $(call pkgimg_builder,PCRE2_jll,Artifacts Libdl)) @@ -100,18 +100,17 @@ $(eval $(call pkgimg_builder,DelimitedFiles,Mmap)) # 2-depth packages $(eval $(call pkgimg_builder,LLD_jll,Zlib_jll libLLVM_jll Artifacts Libdl)) -$(eval $(call pkgimg_builder,LibSSH2_jll,Artifacts Libdl MbedTLS_jll)) +$(eval $(call sysimg_builder,LibSSH2_jll,Artifacts Libdl MbedTLS_jll)) $(eval $(call pkgimg_builder,MPFR_jll,Artifacts Libdl GMP_jll)) $(eval $(call sysimg_builder,LinearAlgebra,Libdl libblastrampoline_jll OpenBLAS_jll)) $(eval $(call sysimg_builder,Dates,Printf)) $(eval $(call pkgimg_builder,Distributed,Random Serialization Sockets)) $(eval $(call sysimg_builder,Future,Random)) $(eval $(call sysimg_builder,InteractiveUtils,Markdown)) -$(eval $(call sysimg_builder,LibGit2,NetworkOptions Printf SHA Base64)) $(eval $(call sysimg_builder,UUIDs,Random SHA)) # 3-depth packages - # LibGit2_jll +$(eval $(call sysimg_builder,LibGit2_jll,MbedTLS_jll LibSSH2_jll Artifacts Libdl)) $(eval $(call pkgimg_builder,LibCURL_jll,LibSSH2_jll nghttp2_jll MbedTLS_jll Zlib_jll Artifacts Libdl)) $(eval $(call sysimg_builder,REPL,InteractiveUtils Markdown Sockets Unicode)) $(eval $(call pkgimg_builder,SharedArrays,Distributed Mmap Random Serialization)) @@ -119,6 +118,7 @@ $(eval $(call sysimg_builder,TOML,Dates)) $(eval $(call pkgimg_builder,Test,Logging Random Serialization InteractiveUtils)) # 4-depth packages +$(eval $(call sysimg_builder,LibGit2,LibGit2_jll NetworkOptions Printf SHA Base64)) $(eval $(call sysimg_builder,LibCURL,LibCURL_jll MozillaCACerts_jll)) # 5-depth packages diff --git a/stdlib/LibGit2/Project.toml b/stdlib/LibGit2/Project.toml index da78f70fa1005..1205716369e09 100644 --- a/stdlib/LibGit2/Project.toml +++ b/stdlib/LibGit2/Project.toml @@ -3,6 +3,7 @@ uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" [deps] Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +LibGit2_jll = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" NetworkOptions = "ca575930-c2e3-43a9-ace4-1e988b2c1908" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" SHA = "ea8e919c-243c-51af-8825-aaa63cd721ce" diff --git a/stdlib/LibGit2/src/LibGit2.jl b/stdlib/LibGit2/src/LibGit2.jl index 6a797937ccf0b..13b78c1046490 100644 --- a/stdlib/LibGit2/src/LibGit2.jl +++ b/stdlib/LibGit2/src/LibGit2.jl @@ -14,6 +14,8 @@ using SHA: sha1, sha256 export with, GitRepo, GitConfig +using LibGit2_jll + const GITHUB_REGEX = r"^(?:(?:ssh://)?git@|git://|https://(?:[\w\.\+\-]+@)?)github.com[:/](([^/].+)/(.+?))(?:\.git)?$"i @@ -983,7 +985,7 @@ function ensure_initialized() end @noinline function initialize() - @check ccall((:git_libgit2_init, :libgit2), Cint, ()) + @check ccall((:git_libgit2_init, libgit2), Cint, ()) cert_loc = NetworkOptions.ca_roots() cert_loc !== nothing && set_ssl_cert_locations(cert_loc) @@ -991,7 +993,7 @@ end atexit() do # refcount zero, no objects to be finalized if Threads.atomic_sub!(REFCOUNT, 1) == 1 - ccall((:git_libgit2_shutdown, :libgit2), Cint, ()) + ccall((:git_libgit2_shutdown, libgit2), Cint, ()) end end end @@ -1003,7 +1005,7 @@ function set_ssl_cert_locations(cert_loc) else # files, /dev/null, non-existent paths, etc. cert_file = cert_loc end - ret = @ccall "libgit2".git_libgit2_opts( + ret = @ccall libgit2.git_libgit2_opts( Consts.SET_SSL_CERT_LOCATIONS::Cint; cert_file::Cstring, cert_dir::Cstring)::Cint @@ -1029,7 +1031,7 @@ end Sets the system tracing configuration to the specified level. """ function trace_set(level::Union{Integer,Consts.GIT_TRACE_LEVEL}, cb=trace_cb()) - @check @ccall "libgit2".git_trace_set(level::Cint, cb::Ptr{Cvoid})::Cint + @check @ccall libgit2.git_trace_set(level::Cint, cb::Ptr{Cvoid})::Cint end end # module diff --git a/stdlib/LibGit2/src/blame.jl b/stdlib/LibGit2/src/blame.jl index 3aa94e30200b4..89071ea9c6f79 100644 --- a/stdlib/LibGit2/src/blame.jl +++ b/stdlib/LibGit2/src/blame.jl @@ -11,7 +11,7 @@ which commits to probe - see [`BlameOptions`](@ref) for more information. function GitBlame(repo::GitRepo, path::AbstractString; options::BlameOptions=BlameOptions()) ensure_initialized() blame_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_blame_file, :libgit2), Cint, + @check ccall((:git_blame_file, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Cstring, Ptr{BlameOptions}), blame_ptr_ptr, repo.ptr, path, Ref(options)) return GitBlame(repo, blame_ptr_ptr[]) @@ -27,7 +27,7 @@ that function later. """ function counthunks(blame::GitBlame) ensure_initialized() - return ccall((:git_blame_get_hunk_count, :libgit2), Int32, (Ptr{Cvoid},), blame.ptr) + return ccall((:git_blame_get_hunk_count, libgit2), Int32, (Ptr{Cvoid},), blame.ptr) end function Base.getindex(blame::GitBlame, i::Integer) @@ -36,7 +36,7 @@ function Base.getindex(blame::GitBlame, i::Integer) end ensure_initialized() GC.@preserve blame begin - hunk_ptr = ccall((:git_blame_get_hunk_byindex, :libgit2), + hunk_ptr = ccall((:git_blame_get_hunk_byindex, libgit2), Ptr{BlameHunk}, (Ptr{Cvoid}, Csize_t), blame.ptr, i-1) elem = unsafe_load(hunk_ptr) diff --git a/stdlib/LibGit2/src/blob.jl b/stdlib/LibGit2/src/blob.jl index efd7a14c9c6f7..1941989b5f529 100644 --- a/stdlib/LibGit2/src/blob.jl +++ b/stdlib/LibGit2/src/blob.jl @@ -2,7 +2,7 @@ function Base.length(blob::GitBlob) ensure_initialized() - return ccall((:git_blob_rawsize, :libgit2), Int64, (Ptr{Cvoid},), blob.ptr) + return ccall((:git_blob_rawsize, libgit2), Int64, (Ptr{Cvoid},), blob.ptr) end """ @@ -20,7 +20,7 @@ is binary and not valid Unicode. """ function rawcontent(blob::GitBlob) ensure_initialized() - ptr = ccall((:git_blob_rawcontent, :libgit2), Ptr{UInt8}, (Ptr{Cvoid},), blob.ptr) + ptr = ccall((:git_blob_rawcontent, libgit2), Ptr{UInt8}, (Ptr{Cvoid},), blob.ptr) copy(unsafe_wrap(Array, ptr, (length(blob),), own = false)) end @@ -47,7 +47,7 @@ the first 8000 bytes. """ function isbinary(blob::GitBlob) ensure_initialized() - bin_flag = ccall((:git_blob_is_binary, :libgit2), Cint, (Ptr{Cvoid},), blob.ptr) + bin_flag = ccall((:git_blob_is_binary, libgit2), Cint, (Ptr{Cvoid},), blob.ptr) return bin_flag == 1 end @@ -67,7 +67,7 @@ id = LibGit2.addblob!(repo, blob_file) function addblob!(repo::GitRepo, path::AbstractString) ensure_initialized() id_ref = Ref{GitHash}() - @check ccall((:git_blob_create_from_disk, :libgit2), Cint, + @check ccall((:git_blob_create_from_disk, libgit2), Cint, (Ptr{GitHash}, Ptr{Cvoid}, Cstring), id_ref, repo.ptr, path) return id_ref[] diff --git a/stdlib/LibGit2/src/callbacks.jl b/stdlib/LibGit2/src/callbacks.jl index 3bc6463140d5f..f4df26cdc30d8 100644 --- a/stdlib/LibGit2/src/callbacks.jl +++ b/stdlib/LibGit2/src/callbacks.jl @@ -9,7 +9,7 @@ function mirror_callback(remote::Ptr{Ptr{Cvoid}}, repo_ptr::Ptr{Cvoid}, ensure_initialized() # Create the remote with a mirroring url fetch_spec = "+refs/*:refs/*" - err = ccall((:git_remote_create_with_fetchspec, :libgit2), Cint, + err = ccall((:git_remote_create_with_fetchspec, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Cstring, Cstring, Cstring), remote, repo_ptr, name, url, fetch_spec) err != 0 && return Cint(err) @@ -43,7 +43,7 @@ end function user_abort() ensure_initialized() # Note: Potentially it could be better to just throw a Julia error. - ccall((:giterr_set_str, :libgit2), Cvoid, + ccall((:giterr_set_str, libgit2), Cvoid, (Cint, Cstring), Cint(Error.Callback), "Aborting, user cancelled credential request.") return Cint(Error.EUSER) @@ -51,7 +51,7 @@ end function prompt_limit() ensure_initialized() - ccall((:giterr_set_str, :libgit2), Cvoid, + ccall((:giterr_set_str, libgit2), Cvoid, (Cint, Cstring), Cint(Error.Callback), "Aborting, maximum number of prompts reached.") return Cint(Error.EAUTH) @@ -59,7 +59,7 @@ end function exhausted_abort() ensure_initialized() - ccall((:giterr_set_str, :libgit2), Cvoid, + ccall((:giterr_set_str, libgit2), Cvoid, (Cint, Cstring), Cint(Error.Callback), "All authentication methods have failed.") return Cint(Error.EAUTH) @@ -79,7 +79,7 @@ function authenticate_ssh(libgit2credptr::Ptr{Ptr{Cvoid}}, p::CredentialPayload, # first try ssh-agent if credentials support its usage if p.use_ssh_agent && username_ptr != Cstring(C_NULL) && (!revised || !isfilled(cred)) - err = ccall((:git_cred_ssh_key_from_agent, :libgit2), Cint, + err = ccall((:git_cred_ssh_key_from_agent, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Cstring), libgit2credptr, username_ptr) p.use_ssh_agent = false # use ssh-agent only one time @@ -175,7 +175,7 @@ function authenticate_ssh(libgit2credptr::Ptr{Ptr{Cvoid}}, p::CredentialPayload, if !revised return exhausted_abort() end - return ccall((:git_cred_ssh_key_new, :libgit2), Cint, + return ccall((:git_cred_ssh_key_new, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Cstring, Cstring, Cstring, Cstring), libgit2credptr, cred.user, cred.pubkey, cred.prvkey, cred.pass) end @@ -235,7 +235,7 @@ function authenticate_userpass(libgit2credptr::Ptr{Ptr{Cvoid}}, p::CredentialPay return exhausted_abort() end - return ccall((:git_cred_userpass_plaintext_new, :libgit2), Cint, + return ccall((:git_cred_userpass_plaintext_new, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Cstring, Cstring), libgit2credptr, cred.user, cred.pass) end @@ -339,7 +339,7 @@ function credentials_callback(libgit2credptr::Ptr{Ptr{Cvoid}}, url_ptr::Cstring, if err == 0 if p.explicit !== nothing ensure_initialized() - ccall((:giterr_set_str, :libgit2), Cvoid, (Cint, Cstring), Cint(Error.Callback), + ccall((:giterr_set_str, libgit2), Cvoid, (Cint, Cstring), Cint(Error.Callback), "The explicitly provided credential is incompatible with the requested " * "authentication methods.") end diff --git a/stdlib/LibGit2/src/commit.jl b/stdlib/LibGit2/src/commit.jl index 5d3c666af4bbb..0ec670e16376b 100644 --- a/stdlib/LibGit2/src/commit.jl +++ b/stdlib/LibGit2/src/commit.jl @@ -14,8 +14,8 @@ function message(c::GitCommit, raw::Bool=false) ensure_initialized() GC.@preserve c begin local msg_ptr::Cstring - msg_ptr = raw ? ccall((:git_commit_message_raw, :libgit2), Cstring, (Ptr{Cvoid},), c.ptr) : - ccall((:git_commit_message, :libgit2), Cstring, (Ptr{Cvoid},), c.ptr) + msg_ptr = raw ? ccall((:git_commit_message_raw, libgit2), Cstring, (Ptr{Cvoid},), c.ptr) : + ccall((:git_commit_message, libgit2), Cstring, (Ptr{Cvoid},), c.ptr) if msg_ptr == C_NULL return nothing end @@ -33,7 +33,7 @@ the person who made changes to the relevant file(s). See also [`committer`](@ref function author(c::GitCommit) ensure_initialized() GC.@preserve c begin - ptr = ccall((:git_commit_author, :libgit2), Ptr{SignatureStruct}, (Ptr{Cvoid},), c.ptr) + ptr = ccall((:git_commit_author, libgit2), Ptr{SignatureStruct}, (Ptr{Cvoid},), c.ptr) @assert ptr != C_NULL sig = Signature(ptr) end @@ -51,7 +51,7 @@ a `committer` who committed it. function committer(c::GitCommit) ensure_initialized() GC.@preserve c begin - ptr = ccall((:git_commit_committer, :libgit2), Ptr{SignatureStruct}, (Ptr{Cvoid},), c.ptr) + ptr = ccall((:git_commit_committer, libgit2), Ptr{SignatureStruct}, (Ptr{Cvoid},), c.ptr) sig = Signature(ptr) end return sig @@ -74,7 +74,7 @@ function commit(repo::GitRepo, commit_id_ptr = Ref(GitHash()) nparents = length(parents) parentptrs = Ptr{Cvoid}[c.ptr for c in parents] - @check ccall((:git_commit_create, :libgit2), Cint, + @check ccall((:git_commit_create, libgit2), Cint, (Ptr{GitHash}, Ptr{Cvoid}, Ptr{UInt8}, Ptr{SignatureStruct}, Ptr{SignatureStruct}, Ptr{UInt8}, Ptr{UInt8}, Ptr{Cvoid}, diff --git a/stdlib/LibGit2/src/config.jl b/stdlib/LibGit2/src/config.jl index a54cd352aa063..affe881abde08 100644 --- a/stdlib/LibGit2/src/config.jl +++ b/stdlib/LibGit2/src/config.jl @@ -13,7 +13,7 @@ function GitConfig(path::AbstractString, ensure_initialized() # create new config object cfg_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_config_new, :libgit2), Cint, (Ptr{Ptr{Cvoid}},), cfg_ptr_ptr) + @check ccall((:git_config_new, libgit2), Cint, (Ptr{Ptr{Cvoid}},), cfg_ptr_ptr) cfg = GitConfig(cfg_ptr_ptr[]) try addfile(cfg, path, level, repo, force) @@ -34,7 +34,7 @@ used. function GitConfig(repo::GitRepo) ensure_initialized() cfg_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_repository_config, :libgit2), Cint, + @check ccall((:git_repository_config, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}), cfg_ptr_ptr, repo.ptr) return GitConfig(repo, cfg_ptr_ptr[]) end @@ -49,14 +49,14 @@ options outside a specific git repository. function GitConfig(level::Consts.GIT_CONFIG = Consts.CONFIG_LEVEL_DEFAULT) ensure_initialized() cfg_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_config_open_default, :libgit2), Cint, + @check ccall((:git_config_open_default, libgit2), Cint, (Ptr{Ptr{Cvoid}},), cfg_ptr_ptr) cfg = GitConfig(cfg_ptr_ptr[]) if level != Consts.CONFIG_LEVEL_DEFAULT glb_cfg_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) tmpcfg = cfg try - @check ccall((:git_config_open_level, :libgit2), Cint, + @check ccall((:git_config_open_level, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Cint), glb_cfg_ptr_ptr, cfg.ptr, Cint(level)) cfg = GitConfig(glb_cfg_ptr_ptr[]) @@ -90,12 +90,12 @@ function addfile(cfg::GitConfig, path::AbstractString, force::Bool=false) ensure_initialized() @static if LibGit2.VERSION >= v"0.27.0" - @check ccall((:git_config_add_file_ondisk, :libgit2), Cint, + @check ccall((:git_config_add_file_ondisk, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Cstring, Cint, Ptr{Cvoid}, Cint), cfg.ptr, path, Cint(level), isa(repo, GitRepo) ? repo.ptr : C_NULL, Cint(force)) else repo === nothing || error("repo argument is not supported in this version of LibGit2") - @check ccall((:git_config_add_file_ondisk, :libgit2), Cint, + @check ccall((:git_config_add_file_ondisk, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Cstring, Cint, Cint), cfg.ptr, path, Cint(level), Cint(force)) end @@ -104,7 +104,7 @@ end function get(::Type{<:AbstractString}, c::GitConfig, name::AbstractString) ensure_initialized() buf_ref = Ref(Buffer()) - @check ccall((:git_config_get_string_buf, :libgit2), Cint, + @check ccall((:git_config_get_string_buf, libgit2), Cint, (Ptr{Buffer}, Ptr{Cvoid}, Cstring), buf_ref, c.ptr, name) buf = buf_ref[] str = unsafe_string(buf.ptr, buf.size) @@ -115,7 +115,7 @@ end function get(::Type{Bool}, c::GitConfig, name::AbstractString) ensure_initialized() val_ptr = Ref(Cint(0)) - @check ccall((:git_config_get_bool, :libgit2), Cint, + @check ccall((:git_config_get_bool, libgit2), Cint, (Ptr{Cint}, Ptr{Cvoid}, Cstring), val_ptr, c.ptr, name) return Bool(val_ptr[]) end @@ -123,7 +123,7 @@ end function get(::Type{Int32}, c::GitConfig, name::AbstractString) ensure_initialized() val_ptr = Ref(Cint(0)) - @check ccall((:git_config_get_int32, :libgit2), Cint, + @check ccall((:git_config_get_int32, libgit2), Cint, (Ptr{Cint}, Ptr{Cvoid}, Cstring), val_ptr, c.ptr, name) return val_ptr[] end @@ -131,7 +131,7 @@ end function get(::Type{Int64}, c::GitConfig, name::AbstractString) ensure_initialized() val_ptr = Ref(Cintmax_t(0)) - @check ccall((:git_config_get_int64, :libgit2), Cint, + @check ccall((:git_config_get_int64, libgit2), Cint, (Ptr{Cintmax_t}, Ptr{Cvoid}, Cstring), val_ptr, c.ptr, name) return val_ptr[] end @@ -164,33 +164,33 @@ end function set!(c::GitConfig, name::AbstractString, value::AbstractString) ensure_initialized() - @check ccall((:git_config_set_string, :libgit2), Cint, + @check ccall((:git_config_set_string, libgit2), Cint, (Ptr{Cvoid}, Cstring, Cstring), c.ptr, name, value) end function set!(c::GitConfig, name::AbstractString, value::Bool) ensure_initialized() bval = Int32(value) - @check ccall((:git_config_set_bool, :libgit2), Cint, + @check ccall((:git_config_set_bool, libgit2), Cint, (Ptr{Cvoid}, Cstring, Cint), c.ptr, name, bval) end function set!(c::GitConfig, name::AbstractString, value::Int32) ensure_initialized() - @check ccall((:git_config_set_int32, :libgit2), Cint, + @check ccall((:git_config_set_int32, libgit2), Cint, (Ptr{Cvoid}, Cstring, Cint), c.ptr, name, value) end function set!(c::GitConfig, name::AbstractString, value::Int64) ensure_initialized() - @check ccall((:git_config_set_int64, :libgit2), Cint, + @check ccall((:git_config_set_int64, libgit2), Cint, (Ptr{Cvoid}, Cstring, Cintmax_t), c.ptr, name, value) end function GitConfigIter(cfg::GitConfig) ensure_initialized() ci_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_config_iterator_new, :libgit2), Cint, + @check ccall((:git_config_iterator_new, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}), ci_ptr, cfg.ptr) return GitConfigIter(ci_ptr[]) end @@ -198,7 +198,7 @@ end function GitConfigIter(cfg::GitConfig, name::AbstractString) ensure_initialized() ci_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_config_multivar_iterator_new, :libgit2), Cint, + @check ccall((:git_config_multivar_iterator_new, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Cstring, Cstring), ci_ptr, cfg.ptr, name, C_NULL) return GitConfigIter(ci_ptr[]) @@ -207,7 +207,7 @@ end function GitConfigIter(cfg::GitConfig, name::AbstractString, value::Regex) ensure_initialized() ci_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_config_multivar_iterator_new, :libgit2), Cint, + @check ccall((:git_config_multivar_iterator_new, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Cstring, Cstring), ci_ptr, cfg.ptr, name, value.pattern) return GitConfigIter(ci_ptr[]) @@ -216,7 +216,7 @@ end function GitConfigIter(cfg::GitConfig, name::Regex) ensure_initialized() ci_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_config_iterator_glob_new, :libgit2), Cint, + @check ccall((:git_config_iterator_glob_new, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Cstring), ci_ptr, cfg.ptr, name.pattern) return GitConfigIter(ci_ptr[]) @@ -225,7 +225,7 @@ end function Base.iterate(ci::GitConfigIter, state=nothing) ensure_initialized() entry_ptr_ptr = Ref{Ptr{ConfigEntry}}(C_NULL) - err = ccall((:git_config_next, :libgit2), Cint, + err = ccall((:git_config_next, libgit2), Cint, (Ptr{Ptr{ConfigEntry}}, Ptr{Cvoid}), entry_ptr_ptr, ci.ptr) if err == Cint(Error.GIT_OK) return (unsafe_load(entry_ptr_ptr[]), nothing) diff --git a/stdlib/LibGit2/src/diff.jl b/stdlib/LibGit2/src/diff.jl index f2aa2feb2c2e9..044c6331dc1f1 100644 --- a/stdlib/LibGit2/src/diff.jl +++ b/stdlib/LibGit2/src/diff.jl @@ -27,11 +27,11 @@ function diff_tree(repo::GitRepo, tree::GitTree, pathspecs::AbstractString=""; c ensure_initialized() diff_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) if cached - @check ccall((:git_diff_tree_to_index, :libgit2), Cint, + @check ccall((:git_diff_tree_to_index, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{DiffOptionsStruct}), diff_ptr_ptr, repo.ptr, tree.ptr, C_NULL, isempty(pathspecs) ? C_NULL : pathspecs) else - @check ccall((:git_diff_tree_to_workdir_with_index, :libgit2), Cint, + @check ccall((:git_diff_tree_to_workdir_with_index, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{DiffOptionsStruct}), diff_ptr_ptr, repo.ptr, tree.ptr, isempty(pathspecs) ? C_NULL : pathspecs) end @@ -51,7 +51,7 @@ to compare a commit on another branch with the current latest commit on `master` function diff_tree(repo::GitRepo, oldtree::GitTree, newtree::GitTree) ensure_initialized() diff_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_diff_tree_to_tree, :libgit2), Cint, + @check ccall((:git_diff_tree_to_tree, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{DiffOptionsStruct}), diff_ptr_ptr, repo.ptr, oldtree.ptr, newtree.ptr, C_NULL) return GitDiff(repo, diff_ptr_ptr[]) @@ -67,7 +67,7 @@ files were changed, how many insertions were made, and how many deletions were m function GitDiffStats(diff::GitDiff) ensure_initialized() diff_stat_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_diff_get_stats, :libgit2), Cint, + @check ccall((:git_diff_get_stats, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}), diff_stat_ptr_ptr, diff.ptr) return GitDiffStats(diff.owner, diff_stat_ptr_ptr[]) @@ -83,7 +83,7 @@ are to be included or not). """ function files_changed(diff_stat::GitDiffStats) ensure_initialized() - return ccall((:git_diff_stats_files_changed, :libgit2), Csize_t, (Ptr{Cvoid},), diff_stat.ptr) + return ccall((:git_diff_stats_files_changed, libgit2), Csize_t, (Ptr{Cvoid},), diff_stat.ptr) end """ @@ -96,7 +96,7 @@ are to be included or not). """ function insertions(diff_stat::GitDiffStats) ensure_initialized() - return ccall((:git_diff_stats_insertions, :libgit2), Csize_t, (Ptr{Cvoid},), diff_stat.ptr) + return ccall((:git_diff_stats_insertions, libgit2), Csize_t, (Ptr{Cvoid},), diff_stat.ptr) end """ @@ -109,12 +109,12 @@ are to be included or not). """ function deletions(diff_stat::GitDiffStats) ensure_initialized() - return ccall((:git_diff_stats_deletions, :libgit2), Csize_t, (Ptr{Cvoid},), diff_stat.ptr) + return ccall((:git_diff_stats_deletions, libgit2), Csize_t, (Ptr{Cvoid},), diff_stat.ptr) end function count(diff::GitDiff) ensure_initialized() - return ccall((:git_diff_num_deltas, :libgit2), Cint, (Ptr{Cvoid},), diff.ptr) + return ccall((:git_diff_num_deltas, libgit2), Cint, (Ptr{Cvoid},), diff.ptr) end function Base.getindex(diff::GitDiff, i::Integer) @@ -122,7 +122,7 @@ function Base.getindex(diff::GitDiff, i::Integer) throw(BoundsError(diff, (i,))) end ensure_initialized() - delta_ptr = ccall((:git_diff_get_delta, :libgit2), + delta_ptr = ccall((:git_diff_get_delta, libgit2), Ptr{DiffDelta}, (Ptr{Cvoid}, Csize_t), diff.ptr, i-1) return unsafe_load(delta_ptr) diff --git a/stdlib/LibGit2/src/error.jl b/stdlib/LibGit2/src/error.jl index 219b8cdf88e69..fd70ed8ce5706 100644 --- a/stdlib/LibGit2/src/error.jl +++ b/stdlib/LibGit2/src/error.jl @@ -3,6 +3,7 @@ module Error import ..LibGit2: ensure_initialized +using LibGit2_jll export GitError @@ -84,7 +85,7 @@ Base.show(io::IO, err::GitError) = print(io, "GitError(Code:$(err.code), Class:$ function last_error() ensure_initialized() - err = ccall((:giterr_last, :libgit2), Ptr{ErrorStruct}, ()) + err = ccall((:giterr_last, libgit2), Ptr{ErrorStruct}, ()) if err != C_NULL err_obj = unsafe_load(err) err_class = Class(err_obj.class) diff --git a/stdlib/LibGit2/src/index.jl b/stdlib/LibGit2/src/index.jl index b8baf624540b0..15e04d16b5756 100644 --- a/stdlib/LibGit2/src/index.jl +++ b/stdlib/LibGit2/src/index.jl @@ -8,7 +8,7 @@ Load the index file for the repository `repo`. function GitIndex(repo::GitRepo) ensure_initialized() idx_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_repository_index, :libgit2), Cint, + @check ccall((:git_repository_index, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}), idx_ptr_ptr, repo.ptr) return GitIndex(repo, idx_ptr_ptr[]) end @@ -25,7 +25,7 @@ has changed since the last time it was loaded into `idx`. """ function read!(idx::GitIndex, force::Bool = false) ensure_initialized() - @check ccall((:git_index_read, :libgit2), Cint, (Ptr{Cvoid}, Cint), idx.ptr, Cint(force)) + @check ccall((:git_index_read, libgit2), Cint, (Ptr{Cvoid}, Cint), idx.ptr, Cint(force)) return idx end @@ -36,7 +36,7 @@ Write the state of index `idx` to disk using a file lock. """ function write!(idx::GitIndex) ensure_initialized() - @check ccall((:git_index_write, :libgit2), Cint, (Ptr{Cvoid},), idx.ptr) + @check ccall((:git_index_write, libgit2), Cint, (Ptr{Cvoid},), idx.ptr) return idx end @@ -51,7 +51,7 @@ repository cannot be bare. `idx` must not contain any files with conflicts. function write_tree!(idx::GitIndex) ensure_initialized() oid_ptr = Ref(GitHash()) - @check ccall((:git_index_write_tree, :libgit2), Cint, + @check ccall((:git_index_write_tree, libgit2), Cint, (Ptr{GitHash}, Ptr{Cvoid}), oid_ptr, idx.ptr) return oid_ptr[] end @@ -73,7 +73,7 @@ Read the tree `tree` (or the tree pointed to by `treehash` in the repository own """ function read_tree!(idx::GitIndex, tree::GitTree) ensure_initialized() - @check ccall((:git_index_read_tree, :libgit2), Cint, + @check ccall((:git_index_read_tree, libgit2), Cint, (Ptr{Cvoid}, Ptr{Cvoid}), idx.ptr, tree.ptr) end read_tree!(idx::GitIndex, hash::AbstractGitHash) = @@ -104,7 +104,7 @@ with respect to ignored files: function add!(idx::GitIndex, files::AbstractString...; flags::Cuint = Consts.INDEX_ADD_DEFAULT) ensure_initialized() - @check ccall((:git_index_add_all, :libgit2), Cint, + @check ccall((:git_index_add_all, libgit2), Cint, (Ptr{Cvoid}, Ptr{StrArrayStruct}, Cuint, Ptr{Cvoid}, Ptr{Cvoid}), idx.ptr, collect(files), flags, C_NULL, C_NULL) end @@ -120,7 +120,7 @@ database. """ function update!(idx::GitIndex, files::AbstractString...) ensure_initialized() - @check ccall((:git_index_update_all, :libgit2), Cint, + @check ccall((:git_index_update_all, libgit2), Cint, (Ptr{Cvoid}, Ptr{StrArrayStruct}, Ptr{Cvoid}, Ptr{Cvoid}), idx.ptr, collect(files), C_NULL, C_NULL) end @@ -134,7 +134,7 @@ of the `repo`). """ function remove!(idx::GitIndex, files::AbstractString...) ensure_initialized() - @check ccall((:git_index_remove_all, :libgit2), Cint, + @check ccall((:git_index_remove_all, libgit2), Cint, (Ptr{Cvoid}, Ptr{StrArrayStruct}, Ptr{Cvoid}, Ptr{Cvoid}), idx.ptr, collect(files), C_NULL, C_NULL) end @@ -173,13 +173,13 @@ end function count(idx::GitIndex) ensure_initialized() - return ccall((:git_index_entrycount, :libgit2), Csize_t, (Ptr{Cvoid},), idx.ptr) + return ccall((:git_index_entrycount, libgit2), Csize_t, (Ptr{Cvoid},), idx.ptr) end function Base.getindex(idx::GitIndex, i::Integer) ensure_initialized() GC.@preserve idx begin - ie_ptr = ccall((:git_index_get_byindex, :libgit2), + ie_ptr = ccall((:git_index_get_byindex, libgit2), Ptr{IndexEntry}, (Ptr{Cvoid}, Csize_t), idx.ptr, i-1) ie_ptr == C_NULL && return nothing @@ -191,7 +191,7 @@ end function Base.findall(path::String, idx::GitIndex) ensure_initialized() pos_ref = Ref{Csize_t}(0) - ret = ccall((:git_index_find, :libgit2), Cint, + ret = ccall((:git_index_find, libgit2), Cint, (Ref{Csize_t}, Ptr{Cvoid}, Cstring), pos_ref, idx.ptr, path) ret == Cint(Error.ENOTFOUND) && return nothing return pos_ref[]+1 @@ -210,7 +210,7 @@ of a multi-branch "octopus" merge, stages `2`, `3`, and `4` might be used). """ function stage(ie::IndexEntry) ensure_initialized() - return ccall((:git_index_entry_stage, :libgit2), Cint, (Ptr{IndexEntry},), Ref(ie)) + return ccall((:git_index_entry_stage, libgit2), Cint, (Ptr{IndexEntry},), Ref(ie)) end function Base.show(io::IO, idx::GitIndex) diff --git a/stdlib/LibGit2/src/merge.jl b/stdlib/LibGit2/src/merge.jl index 0b2ddab1e8512..7c946315fdd86 100644 --- a/stdlib/LibGit2/src/merge.jl +++ b/stdlib/LibGit2/src/merge.jl @@ -16,7 +16,7 @@ branch head described using `GitReference`. function GitAnnotated(repo::GitRepo, commit_id::GitHash) ensure_initialized() ann_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_annotated_commit_lookup, :libgit2), Cint, + @check ccall((:git_annotated_commit_lookup, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Ptr{GitHash}), ann_ptr_ptr, repo.ptr, Ref(commit_id)) return GitAnnotated(repo, ann_ptr_ptr[]) @@ -25,7 +25,7 @@ end function GitAnnotated(repo::GitRepo, ref::GitReference) ensure_initialized() ann_ref_ref = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_annotated_commit_from_ref, :libgit2), Cint, + @check ccall((:git_annotated_commit_from_ref, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Ptr{Cvoid}), ann_ref_ref, repo.ptr, ref.ptr) return GitAnnotated(repo, ann_ref_ref[]) @@ -34,7 +34,7 @@ end function GitAnnotated(repo::GitRepo, fh::FetchHead) ensure_initialized() ann_ref_ref = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_annotated_commit_from_fetchhead, :libgit2), Cint, + @check ccall((:git_annotated_commit_from_fetchhead, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Cstring, Cstring, Ptr{GitHash}), ann_ref_ref, repo.ptr, fh.name, fh.url, Ref(fh.oid)) return GitAnnotated(repo, ann_ref_ref[]) @@ -49,7 +49,7 @@ end function GitHash(ann::GitAnnotated) ensure_initialized() GC.@preserve ann begin - oid = unsafe_load(ccall((:git_annotated_commit_id, :libgit2), Ptr{GitHash}, (Ptr{Cvoid},), ann.ptr)) + oid = unsafe_load(ccall((:git_annotated_commit_id, libgit2), Ptr{GitHash}, (Ptr{Cvoid},), ann.ptr)) end return oid end @@ -88,7 +88,7 @@ function merge_analysis(repo::GitRepo, anns::Vector{GitAnnotated}) preference = Ref{Cint}(0) anns_ref = Ref(Base.map(a->a.ptr, anns), 1) anns_size = Csize_t(length(anns)) - @check ccall((:git_merge_analysis, :libgit2), Cint, + @check ccall((:git_merge_analysis, libgit2), Cint, (Ptr{Cint}, Ptr{Cint}, Ptr{Cvoid}, Ptr{Ptr{Cvoid}}, Csize_t), analysis, preference, repo.ptr, anns_ref, anns_size) return analysis[], preference[] @@ -147,7 +147,7 @@ function merge!(repo::GitRepo, anns::Vector{GitAnnotated}; checkout_opts::CheckoutOptions = CheckoutOptions()) ensure_initialized() anns_size = Csize_t(length(anns)) - @check ccall((:git_merge, :libgit2), Cint, + @check ccall((:git_merge, libgit2), Cint, (Ptr{Cvoid}, Ptr{Ptr{Cvoid}}, Csize_t, Ptr{MergeOptions}, Ptr{CheckoutOptions}), repo.ptr, Base.map(x->x.ptr, anns), anns_size, @@ -261,7 +261,7 @@ function merge_base(repo::GitRepo, one::AbstractString, two::AbstractString) oid2_ptr = Ref(GitHash(two)) moid_ptr = Ref(GitHash()) moid = try - @check ccall((:git_merge_base, :libgit2), Cint, + @check ccall((:git_merge_base, libgit2), Cint, (Ptr{GitHash}, Ptr{Cvoid}, Ptr{GitHash}, Ptr{GitHash}), moid_ptr, repo.ptr, oid1_ptr, oid2_ptr) moid_ptr[] diff --git a/stdlib/LibGit2/src/oid.jl b/stdlib/LibGit2/src/oid.jl index 937684439419f..be4944791f55c 100644 --- a/stdlib/LibGit2/src/oid.jl +++ b/stdlib/LibGit2/src/oid.jl @@ -13,7 +13,7 @@ function GitHash(ptr::Ptr{UInt8}) end ensure_initialized() oid_ptr = Ref(GitHash()) - @check ccall((:git_oid_fromraw, :libgit2), Cint, + @check ccall((:git_oid_fromraw, libgit2), Cint, (Ptr{GitHash}, Ptr{UInt8}), oid_ptr, ptr) return oid_ptr[] end @@ -43,7 +43,7 @@ function GitHash(id::AbstractString) end ensure_initialized() oid_ptr = Ref{GitHash}() - @check ccall((:git_oid_fromstrn, :libgit2), Cint, + @check ccall((:git_oid_fromstrn, libgit2), Cint, (Ptr{GitHash}, Ptr{UInt8}, Csize_t), oid_ptr, bstr, len) return oid_ptr[] end @@ -56,7 +56,7 @@ Construct a `GitShortHash` from the data stored in the given [`Buffer`](@ref). function GitShortHash(buf::Buffer) ensure_initialized() oid_ptr = Ref{GitHash}() - @check ccall((:git_oid_fromstrn, :libgit2), Cint, + @check ccall((:git_oid_fromstrn, libgit2), Cint, (Ptr{GitHash}, Ptr{UInt8}, Csize_t), oid_ptr, buf.ptr, buf.size) GitShortHash(oid_ptr[], buf.size) end @@ -71,7 +71,7 @@ function GitShortHash(id::AbstractString) bstr = String(id) len = sizeof(bstr) oid_ptr = Ref{GitHash}() - @check ccall((:git_oid_fromstrn, :libgit2), Cint, + @check ccall((:git_oid_fromstrn, libgit2), Cint, (Ptr{GitHash}, Ptr{UInt8}, Csize_t), oid_ptr, bstr, len) GitShortHash(oid_ptr[], len) end @@ -113,7 +113,7 @@ function GitHash(ref::GitReference) reftype(ref) != Consts.REF_OID && return GitHash() ensure_initialized() GC.@preserve ref begin - oid_ptr = ccall((:git_reference_target, :libgit2), Ptr{UInt8}, (Ptr{Cvoid},), ref.ptr) + oid_ptr = ccall((:git_reference_target, libgit2), Ptr{UInt8}, (Ptr{Cvoid},), ref.ptr) oid_ptr == C_NULL && return GitHash() oid = GitHash(oid_ptr) end @@ -131,7 +131,7 @@ function GitHash(repo::GitRepo, ref_name::AbstractString) isempty(repo) && return GitHash() ensure_initialized() oid_ptr = Ref(GitHash()) - @check ccall((:git_reference_name_to_id, :libgit2), Cint, + @check ccall((:git_reference_name_to_id, libgit2), Cint, (Ptr{GitHash}, Ptr{Cvoid}, Cstring), oid_ptr, repo.ptr, ref_name) return oid_ptr[] @@ -144,7 +144,7 @@ Get the identifier (`GitHash`) of `obj`. """ function GitHash(obj::GitObject) ensure_initialized() - GitHash(ccall((:git_object_id, :libgit2), Ptr{UInt8}, (Ptr{Cvoid},), obj.ptr)) + GitHash(ccall((:git_object_id, libgit2), Ptr{UInt8}, (Ptr{Cvoid},), obj.ptr)) end ==(obj1::GitObject, obj2::GitObject) = GitHash(obj1) == GitHash(obj2) @@ -159,7 +159,7 @@ unambiguously identify the object in the repository. function GitShortHash(obj::GitObject) ensure_initialized() buf_ref = Ref(Buffer()) - @check ccall((:git_object_short_id, :libgit2), Cint, + @check ccall((:git_object_short_id, libgit2), Cint, (Ptr{Buffer},Ptr{Cvoid}), buf_ref, obj.ptr) sid = GitShortHash(buf_ref[]) free(buf_ref) @@ -187,7 +187,7 @@ Base.hash(id::GitHash, h::UInt) = hash(id.val, h) function Base.cmp(id1::GitHash, id2::GitHash) ensure_initialized() - Int(ccall((:git_oid_cmp, :libgit2), Cint, + Int(ccall((:git_oid_cmp, libgit2), Cint, (Ptr{GitHash}, Ptr{GitHash}), Ref(id1), Ref(id2))) end @@ -195,7 +195,7 @@ function Base.cmp(id1::GitShortHash, id2::GitShortHash) ensure_initialized() # shortened hashes appear at the beginning of the order, i.e. # 000 < 01 < 010 < 011 < 0112 - c = Int(ccall((:git_oid_ncmp, :libgit2), Cint, + c = Int(ccall((:git_oid_ncmp, libgit2), Cint, (Ptr{GitHash}, Ptr{GitHash}, Csize_t), Ref(id1.hash), Ref(id2.hash), min(id1.len, id2.len))) return c == 0 ? cmp(id1.len, id2.len) : c diff --git a/stdlib/LibGit2/src/rebase.jl b/stdlib/LibGit2/src/rebase.jl index 51b52ef006c38..b36c2f3f475cf 100644 --- a/stdlib/LibGit2/src/rebase.jl +++ b/stdlib/LibGit2/src/rebase.jl @@ -5,7 +5,7 @@ function GitRebase(repo::GitRepo, branch::GitAnnotated, upstream::GitAnnotated; opts::RebaseOptions = RebaseOptions()) ensure_initialized() rebase_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_rebase_init, :libgit2), Cint, + @check ccall((:git_rebase_init, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{RebaseOptions}), rebase_ptr_ptr, repo.ptr, branch.ptr, upstream.ptr, @@ -15,7 +15,7 @@ end function count(rb::GitRebase) ensure_initialized() - return ccall((:git_rebase_operation_entrycount, :libgit2), Csize_t, (Ptr{Cvoid},), rb.ptr) + return ccall((:git_rebase_operation_entrycount, libgit2), Csize_t, (Ptr{Cvoid},), rb.ptr) end """ @@ -28,7 +28,7 @@ has not yet been called or iteration over `rb` has not yet begun), return """ function current(rb::GitRebase) ensure_initialized() - return ccall((:git_rebase_operation_current, :libgit2), Csize_t, (Ptr{Cvoid},), rb.ptr) + return ccall((:git_rebase_operation_current, libgit2), Csize_t, (Ptr{Cvoid},), rb.ptr) end function Base.getindex(rb::GitRebase, i::Integer) @@ -37,7 +37,7 @@ function Base.getindex(rb::GitRebase, i::Integer) end ensure_initialized() GC.@preserve rb begin - rb_op_ptr = ccall((:git_rebase_operation_byindex, :libgit2), + rb_op_ptr = ccall((:git_rebase_operation_byindex, libgit2), Ptr{RebaseOperation}, (Ptr{Cvoid}, Csize_t), rb.ptr, i-1) rb_op = unsafe_load(rb_op_ptr) @@ -49,7 +49,7 @@ function Base.iterate(rb::GitRebase, state=nothing) ensure_initialized() rb_op_ptr_ptr = Ref{Ptr{RebaseOperation}}(C_NULL) GC.@preserve rb begin - err = ccall((:git_rebase_next, :libgit2), Cint, + err = ccall((:git_rebase_next, libgit2), Cint, (Ptr{Ptr{RebaseOperation}}, Ptr{Cvoid}), rb_op_ptr_ptr, rb.ptr) if err == Cint(Error.GIT_OK) @@ -78,7 +78,7 @@ function commit(rb::GitRebase, sig::GitSignature) ensure_initialized() oid_ptr = Ref(GitHash()) try - @check ccall((:git_rebase_commit, :libgit2), Error.Code, + @check ccall((:git_rebase_commit, libgit2), Error.Code, (Ptr{GitHash}, Ptr{Cvoid}, Ptr{SignatureStruct}, Ptr{SignatureStruct}, Ptr{UInt8}, Ptr{UInt8}), oid_ptr, rb.ptr, C_NULL, sig.ptr, C_NULL, C_NULL) catch err @@ -100,7 +100,7 @@ rebase had completed), and `-1` for other errors. """ function abort(rb::GitRebase) ensure_initialized() - return ccall((:git_rebase_abort, :libgit2), Csize_t, + return ccall((:git_rebase_abort, libgit2), Csize_t, (Ptr{Cvoid},), rb.ptr) end @@ -113,7 +113,7 @@ rebase finishes successfully, `-1` if there is an error. """ function finish(rb::GitRebase, sig::GitSignature) ensure_initialized() - return ccall((:git_rebase_finish, :libgit2), Csize_t, + return ccall((:git_rebase_finish, libgit2), Csize_t, (Ptr{Cvoid}, Ptr{SignatureStruct}), rb.ptr, sig.ptr) end diff --git a/stdlib/LibGit2/src/reference.jl b/stdlib/LibGit2/src/reference.jl index c05b09ddfc518..9f849ed01a00f 100644 --- a/stdlib/LibGit2/src/reference.jl +++ b/stdlib/LibGit2/src/reference.jl @@ -3,7 +3,7 @@ function GitReference(repo::GitRepo, refname::AbstractString) ensure_initialized() ref_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_reference_lookup, :libgit2), Cint, + @check ccall((:git_reference_lookup, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Cstring), ref_ptr_ptr, repo.ptr, refname) return GitReference(repo, ref_ptr_ptr[]) @@ -13,7 +13,7 @@ function GitReference(repo::GitRepo, obj_oid::GitHash, refname::AbstractString = force::Bool=false, msg::AbstractString="") ensure_initialized() ref_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_reference_create, :libgit2), Cint, + @check ccall((:git_reference_create, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Ptr{UInt8}, Ptr{GitHash}, Cint, Cstring), ref_ptr_ptr, repo.ptr, refname, Ref(obj_oid), Cint(force), isempty(msg) ? C_NULL : msg) @@ -28,7 +28,7 @@ to this branch will have no parents. """ function isorphan(repo::GitRepo) ensure_initialized() - r = @check ccall((:git_repository_head_unborn, :libgit2), Cint, + r = @check ccall((:git_repository_head_unborn, libgit2), Cint, (Ptr{Cvoid},), repo.ptr) r != 0 end @@ -41,7 +41,7 @@ Return a `GitReference` to the current HEAD of `repo`. function head(repo::GitRepo) ensure_initialized() head_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_repository_head, :libgit2), Cint, + @check ccall((:git_repository_head, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}), head_ptr_ptr, repo.ptr) return GitReference(repo, head_ptr_ptr[]) end @@ -68,7 +68,7 @@ function shortname(ref::GitReference) isempty(ref) && return "" ensure_initialized() GC.@preserve ref begin - name_ptr = ccall((:git_reference_shorthand, :libgit2), Cstring, (Ptr{Cvoid},), ref.ptr) + name_ptr = ccall((:git_reference_shorthand, libgit2), Cstring, (Ptr{Cvoid},), ref.ptr) name_ptr == C_NULL && return "" name = unsafe_string(name_ptr) end @@ -85,7 +85,7 @@ Return a `Cint` corresponding to the type of `ref`: """ function reftype(ref::GitReference) ensure_initialized() - return ccall((:git_reference_type, :libgit2), Cint, (Ptr{Cvoid},), ref.ptr) + return ccall((:git_reference_type, libgit2), Cint, (Ptr{Cvoid},), ref.ptr) end """ @@ -100,7 +100,7 @@ function fullname(ref::GitReference) reftype(ref) == Consts.REF_OID && return "" ensure_initialized() GC.@preserve ref begin - rname = ccall((:git_reference_symbolic_target, :libgit2), Cstring, (Ptr{Cvoid},), ref.ptr) + rname = ccall((:git_reference_symbolic_target, libgit2), Cstring, (Ptr{Cvoid},), ref.ptr) rname == C_NULL && return "" name = unsafe_string(rname) end @@ -116,7 +116,7 @@ function name(ref::GitReference) isempty(ref) && return "" ensure_initialized() GC.@preserve ref begin - name_ptr = ccall((:git_reference_name, :libgit2), Cstring, (Ptr{Cvoid},), ref.ptr) + name_ptr = ccall((:git_reference_name, libgit2), Cstring, (Ptr{Cvoid},), ref.ptr) name_ptr == C_NULL && return "" name = unsafe_string(name_ptr) end @@ -128,7 +128,7 @@ function branch(ref::GitReference) ensure_initialized() str_ptr_ptr = Ref{Cstring}() GC.@preserve ref begin - @check ccall((:git_branch_name, :libgit2), Cint, + @check ccall((:git_branch_name, libgit2), Cint, (Ptr{Cstring}, Ptr{Cvoid},), str_ptr_ptr, ref.ptr) str = unsafe_string(str_ptr_ptr[]) end @@ -138,7 +138,7 @@ end function ishead(ref::GitReference) isempty(ref) && return false ensure_initialized() - err = ccall((:git_branch_is_head, :libgit2), Cint, + err = ccall((:git_branch_is_head, libgit2), Cint, (Ptr{Cvoid},), ref.ptr) return err == 1 end @@ -146,7 +146,7 @@ end function isbranch(ref::GitReference) isempty(ref) && return false ensure_initialized() - err = ccall((:git_reference_is_branch, :libgit2), Cint, + err = ccall((:git_reference_is_branch, libgit2), Cint, (Ptr{Cvoid},), ref.ptr) return err == 1 end @@ -154,7 +154,7 @@ end function istag(ref::GitReference) isempty(ref) && return false ensure_initialized() - err = ccall((:git_reference_is_tag, :libgit2), Cint, + err = ccall((:git_reference_is_tag, libgit2), Cint, (Ptr{Cvoid},), ref.ptr) return err == 1 end @@ -162,7 +162,7 @@ end function isremote(ref::GitReference) isempty(ref) && return false ensure_initialized() - err = ccall((:git_reference_is_remote, :libgit2), Cint, + err = ccall((:git_reference_is_remote, libgit2), Cint, (Ptr{Cvoid},), ref.ptr) return err == 1 end @@ -199,7 +199,7 @@ then `ref` will be peeled until an object other than a [`GitTag`](@ref) is obtai function peel(::Type{T}, ref::GitReference) where T<:GitObject ensure_initialized() obj_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_reference_peel, :libgit2), Cint, + @check ccall((:git_reference_peel, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Cint), obj_ptr_ptr, ref.ptr, Consts.OBJECT(T)) return T(ref.owner, obj_ptr_ptr[]) end @@ -213,7 +213,7 @@ Get a list of all reference names in the `repo` repository. function ref_list(repo::GitRepo) ensure_initialized() sa_ref = Ref(StrArrayStruct()) - @check ccall((:git_reference_list, :libgit2), Cint, + @check ccall((:git_reference_list, libgit2), Cint, (Ptr{StrArrayStruct}, Ptr{Cvoid}), sa_ref, repo.ptr) res = convert(Vector{String}, sa_ref[]) free(sa_ref) @@ -235,7 +235,7 @@ function create_branch(repo::GitRepo, force::Bool=false) ensure_initialized() ref_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_branch_create, :libgit2), Cint, + @check ccall((:git_branch_create, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Cstring, Ptr{Cvoid}, Cint), ref_ptr_ptr, repo.ptr, bname, commit_obj.ptr, Cint(force)) return GitReference(repo, ref_ptr_ptr[]) @@ -248,7 +248,7 @@ Delete the branch pointed to by `branch`. """ function delete_branch(branch::GitReference) ensure_initialized() - @check ccall((:git_branch_delete, :libgit2), Cint, (Ptr{Cvoid},), branch.ptr) + @check ccall((:git_branch_delete, libgit2), Cint, (Ptr{Cvoid},), branch.ptr) end """ @@ -259,7 +259,7 @@ Set the HEAD of `repo` to the object pointed to by `ref`. function head!(repo::GitRepo, ref::GitReference) ensure_initialized() ref_name = name(ref) - @check ccall((:git_repository_set_head, :libgit2), Cint, + @check ccall((:git_repository_set_head, libgit2), Cint, (Ptr{Cvoid}, Cstring), repo.ptr, ref_name) return ref end @@ -280,7 +280,7 @@ function lookup_branch(repo::GitRepo, ensure_initialized() ref_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) branch_type = remote ? Consts.BRANCH_REMOTE : Consts.BRANCH_LOCAL - err = ccall((:git_branch_lookup, :libgit2), Cint, + err = ccall((:git_branch_lookup, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Ptr{UInt8}, Cint), ref_ptr_ptr, repo.ptr, branch_name, branch_type) if err != Int(Error.GIT_OK) @@ -307,7 +307,7 @@ function upstream(ref::GitReference) isempty(ref) && return nothing ensure_initialized() ref_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - err = ccall((:git_branch_upstream, :libgit2), Cint, + err = ccall((:git_branch_upstream, libgit2), Cint, (Ref{Ptr{Cvoid}}, Ptr{Cvoid},), ref_ptr_ptr, ref.ptr) if err != Int(Error.GIT_OK) if err == Int(Error.ENOTFOUND) @@ -326,7 +326,7 @@ repository(ref::GitReference) = ref.owner function target!(ref::GitReference, new_oid::GitHash; msg::AbstractString="") ensure_initialized() ref_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_reference_set_target, :libgit2), Cint, + @check ccall((:git_reference_set_target, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Ptr{GitHash}, Cstring), ref_ptr_ptr, ref.ptr, Ref(new_oid), isempty(msg) ? C_NULL : msg) return GitReference(ref.owner, ref_ptr_ptr[]) @@ -335,7 +335,7 @@ end function GitBranchIter(repo::GitRepo, flags::Cint=Cint(Consts.BRANCH_LOCAL)) ensure_initialized() bi_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_branch_iterator_new, :libgit2), Cint, + @check ccall((:git_branch_iterator_new, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Cint), bi_ptr, repo.ptr, flags) return GitBranchIter(repo, bi_ptr[]) end @@ -344,7 +344,7 @@ function Base.iterate(bi::GitBranchIter, state=nothing) ensure_initialized() ref_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) btype = Ref{Cint}() - err = ccall((:git_branch_next, :libgit2), Cint, + err = ccall((:git_branch_next, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cint}, Ptr{Cvoid}), ref_ptr_ptr, btype, bi.ptr) if err == Cint(Error.GIT_OK) diff --git a/stdlib/LibGit2/src/remote.jl b/stdlib/LibGit2/src/remote.jl index 384a3b21bdbfa..f5be4499d227e 100644 --- a/stdlib/LibGit2/src/remote.jl +++ b/stdlib/LibGit2/src/remote.jl @@ -14,7 +14,7 @@ remote = LibGit2.GitRemote(repo, "upstream", repo_url) function GitRemote(repo::GitRepo, rmt_name::AbstractString, rmt_url::AbstractString) ensure_initialized() rmt_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_remote_create, :libgit2), Cint, + @check ccall((:git_remote_create, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Cstring, Cstring), rmt_ptr_ptr, repo.ptr, rmt_name, rmt_url) return GitRemote(repo, rmt_ptr_ptr[]) @@ -37,7 +37,7 @@ remote = LibGit2.GitRemote(repo, "upstream", repo_url, refspec) function GitRemote(repo::GitRepo, rmt_name::AbstractString, rmt_url::AbstractString, fetch_spec::AbstractString) ensure_initialized() rmt_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_remote_create_with_fetchspec, :libgit2), Cint, + @check ccall((:git_remote_create_with_fetchspec, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Cstring, Cstring, Cstring), rmt_ptr_ptr, repo.ptr, rmt_name, rmt_url, fetch_spec) return GitRemote(repo, rmt_ptr_ptr[]) @@ -57,7 +57,7 @@ remote = LibGit2.GitRemoteAnon(repo, repo_url) function GitRemoteAnon(repo::GitRepo, url::AbstractString) ensure_initialized() rmt_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_remote_create_anonymous, :libgit2), Cint, + @check ccall((:git_remote_create_anonymous, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Cstring), rmt_ptr_ptr, repo.ptr, url) return GitRemote(repo, rmt_ptr_ptr[]) @@ -80,7 +80,7 @@ LibGit2.lookup_remote(repo, remote_name) # will return nothing function lookup_remote(repo::GitRepo, remote_name::AbstractString) ensure_initialized() rmt_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - err = ccall((:git_remote_lookup, :libgit2), Cint, + err = ccall((:git_remote_lookup, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Cstring), rmt_ptr_ptr, repo.ptr, remote_name) if err == Int(Error.GIT_OK) @@ -95,7 +95,7 @@ end function get(::Type{GitRemote}, repo::GitRepo, rmt_name::AbstractString) ensure_initialized() rmt_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_remote_lookup, :libgit2), Cint, + @check ccall((:git_remote_lookup, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Cstring), rmt_ptr_ptr, repo.ptr, rmt_name) return GitRemote(repo, rmt_ptr_ptr[]) @@ -120,7 +120,7 @@ julia> LibGit2.url(remote) """ function url(rmt::GitRemote) ensure_initialized() - url_ptr = ccall((:git_remote_url, :libgit2), Cstring, (Ptr{Cvoid},), rmt.ptr) + url_ptr = ccall((:git_remote_url, libgit2), Cstring, (Ptr{Cvoid},), rmt.ptr) url_ptr == C_NULL && return "" return unsafe_string(url_ptr) end @@ -144,7 +144,7 @@ julia> LibGit2.push_url(LibGit2.get(LibGit2.GitRemote, repo, "origin")) """ function push_url(rmt::GitRemote) ensure_initialized() - url_ptr = ccall((:git_remote_pushurl, :libgit2), Cstring, (Ptr{Cvoid},), rmt.ptr) + url_ptr = ccall((:git_remote_pushurl, libgit2), Cstring, (Ptr{Cvoid},), rmt.ptr) url_ptr == C_NULL && return "" return unsafe_string(url_ptr) end @@ -170,7 +170,7 @@ julia> name(remote) """ function name(rmt::GitRemote) ensure_initialized() - name_ptr = ccall((:git_remote_name, :libgit2), Cstring, (Ptr{Cvoid},), rmt.ptr) + name_ptr = ccall((:git_remote_name, libgit2), Cstring, (Ptr{Cvoid},), rmt.ptr) name_ptr == C_NULL && return "" return unsafe_string(name_ptr) end @@ -194,7 +194,7 @@ String["+refs/heads/*:refs/remotes/upstream/*"] function fetch_refspecs(rmt::GitRemote) ensure_initialized() sa_ref = Ref(StrArrayStruct()) - @check ccall((:git_remote_get_fetch_refspecs, :libgit2), Cint, + @check ccall((:git_remote_get_fetch_refspecs, libgit2), Cint, (Ptr{StrArrayStruct}, Ptr{Cvoid}), sa_ref, rmt.ptr) res = convert(Vector{String}, sa_ref[]) free(sa_ref) @@ -224,7 +224,7 @@ String["refs/heads/master"] function push_refspecs(rmt::GitRemote) ensure_initialized() sa_ref = Ref(StrArrayStruct()) - @check ccall((:git_remote_get_push_refspecs, :libgit2), Cint, + @check ccall((:git_remote_get_push_refspecs, libgit2), Cint, (Ptr{StrArrayStruct}, Ptr{Cvoid}), sa_ref, rmt.ptr) res = convert(Vector{String}, sa_ref[]) free(sa_ref) @@ -247,7 +247,7 @@ String["+refs/heads/*:refs/remotes/upstream/*"] """ function add_fetch!(repo::GitRepo, rmt::GitRemote, fetch_spec::String) ensure_initialized() - @check ccall((:git_remote_add_fetch, :libgit2), Cint, + @check ccall((:git_remote_add_fetch, libgit2), Cint, (Ptr{Cvoid}, Cstring, Cstring), repo.ptr, name(rmt), fetch_spec) end @@ -276,7 +276,7 @@ String["refs/heads/master"] """ function add_push!(repo::GitRepo, rmt::GitRemote, push_spec::String) ensure_initialized() - @check ccall((:git_remote_add_push, :libgit2), Cint, + @check ccall((:git_remote_add_push, libgit2), Cint, (Ptr{Cvoid}, Cstring, Cstring), repo.ptr, name(rmt), push_spec) end @@ -296,7 +296,7 @@ function fetch(rmt::GitRemote, refspecs::Vector{<:AbstractString}; msg::AbstractString="") ensure_initialized() msg = "libgit2.fetch: $msg" - @check ccall((:git_remote_fetch, :libgit2), Cint, + @check ccall((:git_remote_fetch, libgit2), Cint, (Ptr{Cvoid}, Ptr{StrArrayStruct}, Ptr{FetchOptions}, Cstring), rmt.ptr, isempty(refspecs) ? C_NULL : refspecs, Ref(options), msg) end @@ -321,7 +321,7 @@ The keyword arguments are: function push(rmt::GitRemote, refspecs::Vector{<:AbstractString}; force::Bool = false, options::PushOptions = PushOptions()) ensure_initialized() - @check ccall((:git_remote_push, :libgit2), Cint, + @check ccall((:git_remote_push, libgit2), Cint, (Ptr{Cvoid}, Ptr{StrArrayStruct}, Ptr{PushOptions}), rmt.ptr, isempty(refspecs) ? C_NULL : refspecs, Ref(options)) end @@ -333,7 +333,7 @@ Delete the `remote_name` from the git `repo`. """ function remote_delete(repo::GitRepo, remote_name::AbstractString) ensure_initialized() - @check ccall((:git_remote_delete, :libgit2), Cint, + @check ccall((:git_remote_delete, libgit2), Cint, (Ptr{Cvoid}, Cstring), repo.ptr, remote_name) end @@ -352,7 +352,7 @@ function set_remote_fetch_url end function set_remote_fetch_url(repo::GitRepo, remote_name::AbstractString, url::AbstractString) ensure_initialized() - @check ccall((:git_remote_set_url, :libgit2), Cint, + @check ccall((:git_remote_set_url, libgit2), Cint, (Ptr{Cvoid}, Cstring, Cstring), repo.ptr, remote_name, url) end @@ -375,7 +375,7 @@ function set_remote_push_url end function set_remote_push_url(repo::GitRepo, remote_name::AbstractString, url::AbstractString) ensure_initialized() - @check ccall((:git_remote_set_pushurl, :libgit2), Cint, + @check ccall((:git_remote_set_pushurl, libgit2), Cint, (Ptr{Cvoid}, Cstring, Cstring), repo.ptr, remote_name, url) end diff --git a/stdlib/LibGit2/src/repository.jl b/stdlib/LibGit2/src/repository.jl index 994d0a9f32875..8297ae92a6a00 100644 --- a/stdlib/LibGit2/src/repository.jl +++ b/stdlib/LibGit2/src/repository.jl @@ -8,7 +8,7 @@ Open a git repository at `path`. function GitRepo(path::AbstractString) ensure_initialized() repo_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_repository_open, :libgit2), Cint, + @check ccall((:git_repository_open, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Cstring), repo_ptr_ptr, path) return GitRepo(repo_ptr_ptr[]) end @@ -23,7 +23,7 @@ function GitRepoExt(path::AbstractString, flags::Cuint = Cuint(Consts.REPOSITORY ensure_initialized() separator = @static Sys.iswindows() ? ";" : ":" repo_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_repository_open_ext, :libgit2), Cint, + @check ccall((:git_repository_open_ext, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Cstring, Cuint, Cstring), repo_ptr_ptr, path, flags, separator) return GitRepo(repo_ptr_ptr[]) @@ -32,7 +32,7 @@ end function cleanup(r::GitRepo) if r.ptr != C_NULL ensure_initialized() - @check ccall((:git_repository__cleanup, :libgit2), Cint, (Ptr{Cvoid},), r.ptr) + @check ccall((:git_repository__cleanup, libgit2), Cint, (Ptr{Cvoid},), r.ptr) end end @@ -46,7 +46,7 @@ is `true`, no working directory will be created. function init(path::AbstractString, bare::Bool=false) ensure_initialized() repo_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_repository_init, :libgit2), Cint, + @check ccall((:git_repository_init, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Cstring, Cuint), repo_ptr_ptr, path, bare) return GitRepo(repo_ptr_ptr[]) end @@ -97,7 +97,7 @@ tree, and no tracking information for remote branches or configurations is prese function isbare(repo::GitRepo) ensure_initialized() @assert repo.ptr != C_NULL - return ccall((:git_repository_is_bare, :libgit2), Cint, (Ptr{Cvoid},), repo.ptr) == 1 + return ccall((:git_repository_is_bare, libgit2), Cint, (Ptr{Cvoid},), repo.ptr) == 1 end """ @@ -109,7 +109,7 @@ Determine if `repo` is detached - that is, whether its HEAD points to a commit function isattached(repo::GitRepo) ensure_initialized() @assert repo.ptr != C_NULL - ccall((:git_repository_head_detached, :libgit2), Cint, (Ptr{Cvoid},), repo.ptr) != 1 + ccall((:git_repository_head_detached, libgit2), Cint, (Ptr{Cvoid},), repo.ptr) != 1 end @doc """ @@ -139,7 +139,7 @@ function (::Type{T})(repo::GitRepo, spec::AbstractString) where T<:GitObject ensure_initialized() obj_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) @assert repo.ptr != C_NULL - @check ccall((:git_revparse_single, :libgit2), Cint, + @check ccall((:git_revparse_single, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Cstring), obj_ptr_ptr, repo.ptr, spec) # check object is of correct type if T != GitObject && T != GitUnknownObject @@ -155,7 +155,7 @@ function (::Type{T})(repo::GitRepo, oid::GitHash) where T<:GitObject obj_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) @assert repo.ptr != C_NULL - @check ccall((:git_object_lookup, :libgit2), Cint, + @check ccall((:git_object_lookup, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Ptr{GitHash}, Consts.OBJECT), obj_ptr_ptr, repo.ptr, oid_ptr, Consts.OBJECT(T)) @@ -167,7 +167,7 @@ function (::Type{T})(repo::GitRepo, oid::GitShortHash) where T<:GitObject obj_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) @assert repo.ptr != C_NULL - @check ccall((:git_object_lookup_prefix, :libgit2), Cint, + @check ccall((:git_object_lookup_prefix, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Ptr{GitHash}, Csize_t, Consts.OBJECT), obj_ptr_ptr, repo.ptr, oid_ptr, oid.len, Consts.OBJECT(T)) @@ -190,7 +190,7 @@ See also [`workdir`](@ref), [`path`](@ref). function gitdir(repo::GitRepo) ensure_initialized() @assert repo.ptr != C_NULL - return unsafe_string(ccall((:git_repository_path, :libgit2), Cstring, + return unsafe_string(ccall((:git_repository_path, libgit2), Cstring, (Ptr{Cvoid},), repo.ptr)) end @@ -211,7 +211,7 @@ See also [`gitdir`](@ref), [`path`](@ref). function workdir(repo::GitRepo) ensure_initialized() @assert repo.ptr != C_NULL - sptr = ccall((:git_repository_workdir, :libgit2), Cstring, + sptr = ccall((:git_repository_workdir, libgit2), Cstring, (Ptr{Cvoid},), repo.ptr) sptr == C_NULL && throw(GitError(Error.Object, Error.ERROR, "No working directory found.")) return unsafe_string(sptr) @@ -255,7 +255,7 @@ function peel(::Type{T}, obj::GitObject) where T<:GitObject ensure_initialized() new_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_object_peel, :libgit2), Cint, + @check ccall((:git_object_peel, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Cint), new_ptr_ptr, obj.ptr, Consts.OBJECT(T)) return T(obj.owner, new_ptr_ptr[]) @@ -285,7 +285,7 @@ function GitDescribeResult(committish::GitObject; options::DescribeOptions=DescribeOptions()) ensure_initialized() result_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_describe_commit, :libgit2), Cint, + @check ccall((:git_describe_commit, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Ptr{DescribeOptions}), result_ptr_ptr, committish.ptr, Ref(options)) return GitDescribeResult(committish.owner, result_ptr_ptr[]) @@ -312,7 +312,7 @@ function GitDescribeResult(repo::GitRepo; options::DescribeOptions=DescribeOptio ensure_initialized() result_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) @assert repo.ptr != C_NULL - @check ccall((:git_describe_workdir, :libgit2), Cint, + @check ccall((:git_describe_workdir, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Ptr{DescribeOptions}), result_ptr_ptr, repo.ptr, Ref(options)) return GitDescribeResult(repo, result_ptr_ptr[]) @@ -329,7 +329,7 @@ Formatting options are controlled by the keyword argument: function format(result::GitDescribeResult; options::DescribeFormatOptions=DescribeFormatOptions()) ensure_initialized() buf_ref = Ref(Buffer()) - @check ccall((:git_describe_format, :libgit2), Cint, + @check ccall((:git_describe_format, libgit2), Cint, (Ptr{Buffer}, Ptr{Cvoid}, Ptr{DescribeFormatOptions}), buf_ref, result.ptr, Ref(options)) buf = buf_ref[] @@ -355,7 +355,7 @@ function checkout_tree(repo::GitRepo, obj::GitObject; options::CheckoutOptions = CheckoutOptions()) ensure_initialized() @assert repo.ptr != C_NULL - @check ccall((:git_checkout_tree, :libgit2), Cint, + @check ccall((:git_checkout_tree, libgit2), Cint, (Ptr{Cvoid}, Ptr{Cvoid}, Ptr{CheckoutOptions}), repo.ptr, obj.ptr, Ref(options)) end @@ -371,7 +371,7 @@ function checkout_index(repo::GitRepo, idx::Union{GitIndex, Nothing} = nothing; options::CheckoutOptions = CheckoutOptions()) ensure_initialized() @assert repo.ptr != C_NULL - @check ccall((:git_checkout_index, :libgit2), Cint, + @check ccall((:git_checkout_index, libgit2), Cint, (Ptr{Cvoid}, Ptr{Cvoid}, Ptr{CheckoutOptions}), repo.ptr, idx === nothing ? C_NULL : idx.ptr, @@ -391,7 +391,7 @@ Update the index and working tree of `repo` to match the commit pointed to by HE function checkout_head(repo::GitRepo; options::CheckoutOptions = CheckoutOptions()) ensure_initialized() @assert repo.ptr != C_NULL - @check ccall((:git_checkout_head, :libgit2), Cint, + @check ccall((:git_checkout_head, libgit2), Cint, (Ptr{Cvoid}, Ptr{CheckoutOptions}), repo.ptr, Ref(options)) end @@ -410,7 +410,7 @@ The keyword argument `options` sets checkout and merge options for the cherrypic function cherrypick(repo::GitRepo, commit::GitCommit; options::CherrypickOptions = CherrypickOptions()) ensure_initialized() @assert repo.ptr != C_NULL - @check ccall((:git_cherrypick, :libgit2), Cint, + @check ccall((:git_cherrypick, libgit2), Cint, (Ptr{Cvoid}, Ptr{Cvoid}, Ptr{CherrypickOptions}), repo.ptr, commit.ptr, Ref(options)) end @@ -419,7 +419,7 @@ end function reset!(repo::GitRepo, obj::Union{GitObject, Nothing}, pathspecs::AbstractString...) ensure_initialized() @assert repo.ptr != C_NULL - @check ccall((:git_reset_default, :libgit2), Cint, + @check ccall((:git_reset_default, libgit2), Cint, (Ptr{Cvoid}, Ptr{Cvoid}, Ptr{StrArrayStruct}), repo.ptr, obj === nothing ? C_NULL : obj.ptr, @@ -432,7 +432,7 @@ function reset!(repo::GitRepo, obj::GitObject, mode::Cint; checkout_opts::CheckoutOptions = CheckoutOptions()) ensure_initialized() @assert repo.ptr != C_NULL - @check ccall((:git_reset, :libgit2), Cint, + @check ccall((:git_reset, libgit2), Cint, (Ptr{Cvoid}, Ptr{Cvoid}, Cint, Ptr{CheckoutOptions}), repo.ptr, obj.ptr, mode, Ref(checkout_opts)) return head_oid(repo) @@ -456,7 +456,7 @@ function clone(repo_url::AbstractString, repo_path::AbstractString, ensure_initialized() clone_opts_ref = Ref(clone_opts) repo_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_clone, :libgit2), Cint, + @check ccall((:git_clone, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Cstring, Cstring, Ref{CloneOptions}), repo_ptr_ptr, repo_url, repo_path, clone_opts_ref) return GitRepo(repo_ptr_ptr[]) @@ -490,7 +490,7 @@ function fetchheads(repo::GitRepo) fh = FetchHead[] ffcb = fetchhead_foreach_cb() @assert repo.ptr != C_NULL - @check ccall((:git_repository_fetchhead_foreach, :libgit2), Cint, + @check ccall((:git_repository_fetchhead_foreach, libgit2), Cint, (Ptr{Cvoid}, Ptr{Cvoid}, Any), repo.ptr, ffcb, fh) return fh @@ -505,7 +505,7 @@ function remotes(repo::GitRepo) ensure_initialized() sa_ref = Ref(StrArrayStruct()) @assert repo.ptr != C_NULL - @check ccall((:git_remote_list, :libgit2), Cint, + @check ccall((:git_remote_list, libgit2), Cint, (Ptr{StrArrayStruct}, Ptr{Cvoid}), sa_ref, repo.ptr) res = convert(Vector{String}, sa_ref[]) free(sa_ref) diff --git a/stdlib/LibGit2/src/signature.jl b/stdlib/LibGit2/src/signature.jl index 9c13bc2256ef5..85e62cd8c2b7e 100644 --- a/stdlib/LibGit2/src/signature.jl +++ b/stdlib/LibGit2/src/signature.jl @@ -13,7 +13,7 @@ Signature(sig::GitSignature) = Signature(sig.ptr) function Signature(name::AbstractString, email::AbstractString) ensure_initialized() sig_ptr_ptr = Ref{Ptr{SignatureStruct}}(C_NULL) - @check ccall((:git_signature_now, :libgit2), Cint, + @check ccall((:git_signature_now, libgit2), Cint, (Ptr{Ptr{SignatureStruct}}, Cstring, Cstring), sig_ptr_ptr, name, email) sig = GitSignature(sig_ptr_ptr[]) s = Signature(sig.ptr) @@ -31,7 +31,7 @@ end function Base.convert(::Type{GitSignature}, sig::Signature) ensure_initialized() sig_ptr_ptr = Ref{Ptr{SignatureStruct}}(C_NULL) - @check ccall((:git_signature_new, :libgit2), Cint, + @check ccall((:git_signature_new, libgit2), Cint, (Ptr{Ptr{SignatureStruct}}, Cstring, Cstring, Int64, Cint), sig_ptr_ptr, sig.name, sig.email, sig.time, sig.time_offset) return GitSignature(sig_ptr_ptr[]) @@ -66,7 +66,7 @@ end function default_signature(repo::GitRepo) ensure_initialized() sig_ptr_ptr = Ref{Ptr{SignatureStruct}}(C_NULL) - @check ccall((:git_signature_default, :libgit2), Cint, + @check ccall((:git_signature_default, libgit2), Cint, (Ptr{Ptr{SignatureStruct}}, Ptr{Cvoid}), sig_ptr_ptr, repo.ptr) return GitSignature(sig_ptr_ptr[]) end diff --git a/stdlib/LibGit2/src/status.jl b/stdlib/LibGit2/src/status.jl index cd871681e4ae9..c1cb2fb1c5a9c 100644 --- a/stdlib/LibGit2/src/status.jl +++ b/stdlib/LibGit2/src/status.jl @@ -12,7 +12,7 @@ submodules or not. See [`StatusOptions`](@ref) for more information. function GitStatus(repo::GitRepo; status_opts=StatusOptions()) ensure_initialized() stat_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_status_list_new, :libgit2), Cint, + @check ccall((:git_status_list_new, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Ptr{StatusOptions}), stat_ptr_ptr, repo.ptr, Ref(status_opts)) return GitStatus(repo, stat_ptr_ptr[]) @@ -20,7 +20,7 @@ end function Base.length(status::GitStatus) ensure_initialized() - return Int(ccall((:git_status_list_entrycount, :libgit2), Csize_t, + return Int(ccall((:git_status_list_entrycount, libgit2), Csize_t, (Ptr{Ptr{Cvoid}},), status.ptr)) end @@ -28,7 +28,7 @@ function Base.getindex(status::GitStatus, i::Integer) 1 <= i <= length(status) || throw(BoundsError()) ensure_initialized() GC.@preserve status begin - entry_ptr = ccall((:git_status_byindex, :libgit2), + entry_ptr = ccall((:git_status_byindex, libgit2), Ptr{StatusEntry}, (Ptr{Cvoid}, Csize_t), status.ptr, i-1) @@ -49,7 +49,7 @@ and needs to be staged and committed. function status(repo::GitRepo, path::String) ensure_initialized() status_ptr = Ref{Cuint}(0) - ret = ccall((:git_status_file, :libgit2), Cint, + ret = ccall((:git_status_file, libgit2), Cint, (Ref{Cuint}, Ptr{Cvoid}, Cstring), status_ptr, repo.ptr, path) (ret == Cint(Error.ENOTFOUND) || ret == Cint(Error.EAMBIGUOUS)) && return nothing diff --git a/stdlib/LibGit2/src/tag.jl b/stdlib/LibGit2/src/tag.jl index 4209a4e2f917d..0e3d2b398a835 100644 --- a/stdlib/LibGit2/src/tag.jl +++ b/stdlib/LibGit2/src/tag.jl @@ -8,7 +8,7 @@ Get a list of all tags in the git repository `repo`. function tag_list(repo::GitRepo) ensure_initialized() sa_ref = Ref(StrArrayStruct()) - @check ccall((:git_tag_list, :libgit2), Cint, + @check ccall((:git_tag_list, libgit2), Cint, (Ptr{StrArrayStruct}, Ptr{Cvoid}), sa_ref, repo.ptr) res = convert(Vector{String}, sa_ref[]) free(sa_ref) @@ -22,7 +22,7 @@ Remove the git tag `tag` from the repository `repo`. """ function tag_delete(repo::GitRepo, tag::AbstractString) ensure_initialized() - @check ccall((:git_tag_delete, :libgit2), Cint, + @check ccall((:git_tag_delete, libgit2), Cint, (Ptr{Cvoid}, Cstring), repo.ptr, tag) end @@ -46,7 +46,7 @@ function tag_create(repo::GitRepo, tag::AbstractString, commit::Union{AbstractSt commit_obj === nothing && return oid_ptr[] # return empty oid with(convert(GitSignature, sig)) do git_sig ensure_initialized() - @check ccall((:git_tag_create, :libgit2), Cint, + @check ccall((:git_tag_create, libgit2), Cint, (Ptr{GitHash}, Ptr{Cvoid}, Cstring, Ptr{Cvoid}, Ptr{SignatureStruct}, Cstring, Cint), oid_ptr, repo.ptr, tag, commit_obj.ptr, git_sig.ptr, msg, Cint(force)) end @@ -62,7 +62,7 @@ The name of `tag` (e.g. `"v0.5"`). function name(tag::GitTag) ensure_initialized() GC.@preserve tag begin - str_ptr = ccall((:git_tag_name, :libgit2), Cstring, (Ptr{Cvoid},), tag.ptr) + str_ptr = ccall((:git_tag_name, libgit2), Cstring, (Ptr{Cvoid},), tag.ptr) str_ptr == C_NULL && throw(Error.GitError(Error.ERROR)) str = unsafe_string(str_ptr) end @@ -78,7 +78,7 @@ The `GitHash` of the target object of `tag`. function target(tag::GitTag) ensure_initialized() GC.@preserve tag begin - oid_ptr = ccall((:git_tag_target_id, :libgit2), Ptr{GitHash}, (Ptr{Cvoid},), tag.ptr) + oid_ptr = ccall((:git_tag_target_id, libgit2), Ptr{GitHash}, (Ptr{Cvoid},), tag.ptr) oid_ptr == C_NULL && throw(Error.GitError(Error.ERROR)) str = unsafe_load(oid_ptr) end diff --git a/stdlib/LibGit2/src/tree.jl b/stdlib/LibGit2/src/tree.jl index 1ef8a2eb75003..1aeeec96ea778 100644 --- a/stdlib/LibGit2/src/tree.jl +++ b/stdlib/LibGit2/src/tree.jl @@ -2,7 +2,7 @@ function GitTree(c::GitCommit) tree_out = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_commit_tree, :libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}), tree_out, c) + @check ccall((:git_commit_tree, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}), tree_out, c) GitTree(repository(c), tree_out[]) end @@ -35,7 +35,7 @@ function treewalk(f, tree::GitTree, post::Bool = false) entry = GitTreeEntry(tree, entry_ptr, false) return f(root, entry) end, Cint, (Cstring, Ptr{Cvoid}, Ref{Vector{Any}})) - err = ccall((:git_tree_walk, :libgit2), Cint, + err = ccall((:git_tree_walk, libgit2), Cint, (Ptr{Cvoid}, Cint, Ptr{Cvoid}, Any), tree.ptr, post, cbf, payload) if err < 0 @@ -58,7 +58,7 @@ Return the filename of the object on disk to which `te` refers. """ function filename(te::GitTreeEntry) ensure_initialized() - str = ccall((:git_tree_entry_name, :libgit2), Cstring, (Ptr{Cvoid},), te.ptr) + str = ccall((:git_tree_entry_name, libgit2), Cstring, (Ptr{Cvoid},), te.ptr) str != C_NULL && return unsafe_string(str) return nothing end @@ -70,7 +70,7 @@ Return the UNIX filemode of the object on disk to which `te` refers as an intege """ function filemode(te::GitTreeEntry) ensure_initialized() - return ccall((:git_tree_entry_filemode, :libgit2), Cint, (Ptr{Cvoid},), te.ptr) + return ccall((:git_tree_entry_filemode, libgit2), Cint, (Ptr{Cvoid},), te.ptr) end """ @@ -81,7 +81,7 @@ one of the types which [`objtype`](@ref) returns, e.g. a `GitTree` or `GitBlob`. """ function entrytype(te::GitTreeEntry) ensure_initialized() - otype = ccall((:git_tree_entry_type, :libgit2), Cint, (Ptr{Cvoid},), te.ptr) + otype = ccall((:git_tree_entry_type, libgit2), Cint, (Ptr{Cvoid},), te.ptr) return objtype(Consts.OBJECT(otype)) end @@ -93,7 +93,7 @@ Return the [`GitHash`](@ref) of the object to which `te` refers. function entryid(te::GitTreeEntry) ensure_initialized() GC.@preserve te begin - oid_ptr = ccall((:git_tree_entry_id, :libgit2), Ptr{UInt8}, (Ptr{Cvoid},), te.ptr) + oid_ptr = ccall((:git_tree_entry_id, libgit2), Ptr{UInt8}, (Ptr{Cvoid},), te.ptr) oid = GitHash(oid_ptr) end return oid @@ -101,7 +101,7 @@ end function count(tree::GitTree) ensure_initialized() - return ccall((:git_tree_entrycount, :libgit2), Csize_t, (Ptr{Cvoid},), tree.ptr) + return ccall((:git_tree_entrycount, libgit2), Csize_t, (Ptr{Cvoid},), tree.ptr) end function Base.getindex(tree::GitTree, i::Integer) @@ -109,7 +109,7 @@ function Base.getindex(tree::GitTree, i::Integer) throw(BoundsError(tree, i)) end ensure_initialized() - te_ptr = ccall((:git_tree_entry_byindex, :libgit2), + te_ptr = ccall((:git_tree_entry_byindex, libgit2), Ptr{Cvoid}, (Ptr{Cvoid}, Csize_t), tree.ptr, i-1) return GitTreeEntry(tree, te_ptr, false) @@ -133,7 +133,7 @@ function (::Type{T})(te::GitTreeEntry) where T<:GitObject ensure_initialized() repo = repository(te) obj_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_tree_entry_to_object, :libgit2), Cint, + @check ccall((:git_tree_entry_to_object, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Ptr{Cvoid}), obj_ptr_ptr, repo, te) return T(repo, obj_ptr_ptr[]) @@ -162,7 +162,7 @@ function _getindex(tree::GitTree, target::AbstractString) end entry = Ref{Ptr{Cvoid}}(C_NULL) - err = ccall((:git_tree_entry_bypath, :libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Cstring), entry, tree, target) + err = ccall((:git_tree_entry_bypath, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Cstring), entry, tree, target) err == Int(Error.ENOTFOUND) && return nothing err < 0 && throw(Error.GitError(err)) entry = GitTreeEntry(tree, entry[], true #= N.B.: Most other lookups need false here =#) diff --git a/stdlib/LibGit2/src/types.jl b/stdlib/LibGit2/src/types.jl index 0b653f9b6ad21..6af95b894f1ca 100644 --- a/stdlib/LibGit2/src/types.jl +++ b/stdlib/LibGit2/src/types.jl @@ -99,7 +99,7 @@ StrArrayStruct() = StrArrayStruct(C_NULL, 0) function free(sa_ref::Base.Ref{StrArrayStruct}) ensure_initialized() - ccall((:git_strarray_free, :libgit2), Cvoid, (Ptr{StrArrayStruct},), sa_ref) + ccall((:git_strarray_free, libgit2), Cvoid, (Ptr{StrArrayStruct},), sa_ref) end """ @@ -126,7 +126,7 @@ Buffer() = Buffer(C_NULL, 0, 0) function free(buf_ref::Base.Ref{Buffer}) ensure_initialized() - ccall((:git_buf_free, :libgit2), Cvoid, (Ptr{Buffer},), buf_ref) + ccall((:git_buf_free, libgit2), Cvoid, (Ptr{Buffer},), buf_ref) end """ @@ -1064,11 +1064,11 @@ for (typ, owntyp, sup, cname) in Tuple{Symbol,Any,Symbol,Symbol}[ @eval function Base.close(obj::$typ) if obj.ptr != C_NULL ensure_initialized() - ccall(($(string(cname, :_free)), :libgit2), Cvoid, (Ptr{Cvoid},), obj.ptr) + ccall(($(string(cname, :_free)), libgit2), Cvoid, (Ptr{Cvoid},), obj.ptr) obj.ptr = C_NULL if Threads.atomic_sub!(REFCOUNT, 1) == 1 # will the last finalizer please turn out the lights? - ccall((:git_libgit2_shutdown, :libgit2), Cint, ()) + ccall((:git_libgit2_shutdown, libgit2), Cint, ()) end end end @@ -1098,7 +1098,7 @@ end function Base.close(obj::GitSignature) if obj.ptr != C_NULL ensure_initialized() - ccall((:git_signature_free, :libgit2), Cvoid, (Ptr{SignatureStruct},), obj.ptr) + ccall((:git_signature_free, libgit2), Cvoid, (Ptr{SignatureStruct},), obj.ptr) obj.ptr = C_NULL end end @@ -1197,7 +1197,7 @@ Consts.OBJECT(::Type{GitObject}) = Consts.OBJ_ANY function Consts.OBJECT(ptr::Ptr{Cvoid}) ensure_initialized() - ccall((:git_object_type, :libgit2), Consts.OBJECT, (Ptr{Cvoid},), ptr) + ccall((:git_object_type, libgit2), Consts.OBJECT, (Ptr{Cvoid},), ptr) end """ diff --git a/stdlib/LibGit2/src/utils.jl b/stdlib/LibGit2/src/utils.jl index 5234e9b6fc291..f62663a6ea4ca 100644 --- a/stdlib/LibGit2/src/utils.jl +++ b/stdlib/LibGit2/src/utils.jl @@ -37,7 +37,7 @@ function version() major = Ref{Cint}(0) minor = Ref{Cint}(0) patch = Ref{Cint}(0) - @check ccall((:git_libgit2_version, :libgit2), Cint, + @check ccall((:git_libgit2_version, libgit2), Cint, (Ref{Cint}, Ref{Cint}, Ref{Cint}), major, minor, patch) return VersionNumber(major[], minor[], patch[]) end @@ -72,7 +72,7 @@ Return a list of git features the current version of libgit2 supports, such as threading or using HTTPS or SSH. """ function features() - feat = ccall((:git_libgit2_features, :libgit2), Cint, ()) + feat = ccall((:git_libgit2_features, libgit2), Cint, ()) res = Consts.GIT_FEATURE[] for f in instances(Consts.GIT_FEATURE) isset(feat, Cuint(f)) && Base.push!(res, f) diff --git a/stdlib/LibGit2/src/walker.jl b/stdlib/LibGit2/src/walker.jl index 468e6899a7aa8..e43687b014226 100644 --- a/stdlib/LibGit2/src/walker.jl +++ b/stdlib/LibGit2/src/walker.jl @@ -21,7 +21,7 @@ Since the `GitHash` is unique to a commit, `cnt` will be `1`. function GitRevWalker(repo::GitRepo) ensure_initialized() w_ptr = Ref{Ptr{Cvoid}}(C_NULL) - @check ccall((:git_revwalk_new, :libgit2), Cint, + @check ccall((:git_revwalk_new, libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}), w_ptr, repo.ptr) return GitRevWalker(repo, w_ptr[]) end @@ -29,7 +29,7 @@ end function Base.iterate(w::GitRevWalker, state=nothing) ensure_initialized() id_ptr = Ref(GitHash()) - err = ccall((:git_revwalk_next, :libgit2), Cint, + err = ccall((:git_revwalk_next, libgit2), Cint, (Ptr{GitHash}, Ptr{Cvoid}), id_ptr, w.ptr) if err == Cint(Error.GIT_OK) return (id_ptr[], nothing) @@ -51,7 +51,7 @@ during the walk. """ function push_head!(w::GitRevWalker) ensure_initialized() - @check ccall((:git_revwalk_push_head, :libgit2), Cint, (Ptr{Cvoid},), w.ptr) + @check ccall((:git_revwalk_push_head, libgit2), Cint, (Ptr{Cvoid},), w.ptr) return w end @@ -64,20 +64,20 @@ of that year as `cid` and then passing the resulting `w` to [`LibGit2.map`](@ref """ function push!(w::GitRevWalker, cid::GitHash) ensure_initialized() - @check ccall((:git_revwalk_push, :libgit2), Cint, (Ptr{Cvoid}, Ptr{GitHash}), w.ptr, Ref(cid)) + @check ccall((:git_revwalk_push, libgit2), Cint, (Ptr{Cvoid}, Ptr{GitHash}), w.ptr, Ref(cid)) return w end function push!(w::GitRevWalker, range::AbstractString) ensure_initialized() - @check ccall((:git_revwalk_push_range, :libgit2), Cint, (Ptr{Cvoid}, Ptr{UInt8}), w.ptr, range) + @check ccall((:git_revwalk_push_range, libgit2), Cint, (Ptr{Cvoid}, Ptr{UInt8}), w.ptr, range) return w end function Base.sort!(w::GitRevWalker; by::Cint = Consts.SORT_NONE, rev::Bool=false) ensure_initialized() rev && (by |= Consts.SORT_REVERSE) - @check ccall((:git_revwalk_sorting, :libgit2), Cint, (Ptr{Cvoid}, Cint), w.ptr, by) + @check ccall((:git_revwalk_sorting, libgit2), Cint, (Ptr{Cvoid}, Cint), w.ptr, by) return w end diff --git a/stdlib/LibGit2/test/libgit2-tests.jl b/stdlib/LibGit2/test/libgit2-tests.jl index 7dbbd10af6f67..d2f2fc050dcd4 100644 --- a/stdlib/LibGit2/test/libgit2-tests.jl +++ b/stdlib/LibGit2/test/libgit2-tests.jl @@ -3,6 +3,7 @@ module LibGit2Tests import LibGit2 +using LibGit2_jll using Test using Random, Serialization, Sockets @@ -129,7 +130,7 @@ end function get_global_dir() buf = Ref(LibGit2.Buffer()) - LibGit2.@check @ccall "libgit2".git_libgit2_opts( + LibGit2.@check @ccall libgit2.git_libgit2_opts( LibGit2.Consts.GET_SEARCH_PATH::Cint; LibGit2.Consts.CONFIG_LEVEL_GLOBAL::Cint, buf::Ptr{LibGit2.Buffer})::Cint @@ -139,7 +140,7 @@ function get_global_dir() end function set_global_dir(dir) - LibGit2.@check @ccall "libgit2".git_libgit2_opts( + LibGit2.@check @ccall libgit2.git_libgit2_opts( LibGit2.Consts.SET_SEARCH_PATH::Cint; LibGit2.Consts.CONFIG_LEVEL_GLOBAL::Cint, dir::Cstring)::Cint @@ -1163,7 +1164,7 @@ mktempdir() do dir # test workaround for git_tree_walk issue # https://github.com/libgit2/libgit2/issues/4693 - ccall((:giterr_set_str, :libgit2), Cvoid, (Cint, Cstring), + ccall((:giterr_set_str, libgit2), Cvoid, (Cint, Cstring), Cint(LibGit2.Error.Invalid), "previous error") try # file needs to exist in tree in order to trigger the stop walk condition diff --git a/test/precompile.jl b/test/precompile.jl index d76a5a9a16f85..82f445a115fee 100644 --- a/test/precompile.jl +++ b/test/precompile.jl @@ -388,25 +388,21 @@ precompile_test_harness(false) do dir @test_throws ErrorException Base.read_dependency_src(cachefile, joinpath(dir, "foo.jl")) modules, deps1 = Base.cache_dependencies(cachefile) - @test Dict(modules) == merge( + modules_ok = merge( Dict(let m = Base.PkgId(s) m => Base.module_build_id(Base.root_module(m)) end for s in [ "Base", "Core", "Main", - string(Foo2_module), string(FooBase_module) ]), + string(Foo2_module), string(FooBase_module),]), # plus modules included in the system image Dict(let m = Base.root_module(Base, s) Base.PkgId(m) => Base.module_build_id(m) - end for s in - [:ArgTools, :Artifacts, :Base64, :CRC32c, :Dates, - :Downloads, :FileWatching, :Future, :InteractiveUtils, :libblastrampoline_jll, - :LibCURL, :LibCURL_jll, :LibGit2, :Libdl, :LinearAlgebra, - :Logging, :Markdown, :Mmap, :MozillaCACerts_jll, :NetworkOptions, :OpenBLAS_jll, :Pkg, :Printf, - :p7zip_jll, :REPL, :Random, :SHA, :Serialization, :Sockets, - :TOML, :Tar, :Test, :UUIDs, :Unicode, - :nghttp2_jll] - ), + end for s in [Symbol(x.name) for x in Base._sysimage_modules if !(x.name in ["Base", "Core", "Main"])]), + # plus test module, + Dict(Base.PkgId(Base.root_module(Base, :Test)) => Base.module_build_id(Base.root_module(Base, :Test))) ) + @test Dict(modules) == modules_ok + @test discard_module.(deps) == deps1 modules, (deps, requires), required_modules, _... = Base.parse_cache_header(cachefile; srcfiles_only=true) @test map(x -> x.filename, deps) == [Foo_file] From f0758b02a2371b354f551c5529c35f33f2372638 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Sun, 17 Sep 2023 10:08:37 -0400 Subject: [PATCH 51/56] Precompile pidlocks: add to NEWS and docs (#50385) --- NEWS.md | 3 +++ doc/src/manual/environment-variables.md | 2 +- doc/src/manual/faq.md | 20 +++++++++----------- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/NEWS.md b/NEWS.md index 713d28d2b9036..576c38e79cefc 100644 --- a/NEWS.md +++ b/NEWS.md @@ -37,6 +37,9 @@ Compiler/Runtime improvements * The mark phase of the garbage collector is now multi-threaded ([#48600]). * [JITLink](https://llvm.org/docs/JITLink.html) is enabled by default on Linux aarch64 when Julia is linked to LLVM 15 or later versions ([#49745]). This should resolve many segmentation faults previously observed on this platform. +* The precompilation process now uses pidfile locks and orchestrates multiple julia processes to only have one process + spend effort precompiling while the others wait. Previously all would do the work and race to overwrite the cache files. + ([#49052]) Command-line option changes --------------------------- diff --git a/doc/src/manual/environment-variables.md b/doc/src/manual/environment-variables.md index eb26063a5e61e..ce6d628b2f0e7 100644 --- a/doc/src/manual/environment-variables.md +++ b/doc/src/manual/environment-variables.md @@ -378,7 +378,7 @@ should have at the terminal. ## System and Package Image Building -### `JULIA_CPU_TARGET` +### [`JULIA_CPU_TARGET`](@id JULIA_CPU_TARGET) Modify the target machine architecture for (pre)compiling [system](@ref sysimg-multi-versioning) and [package images](@ref pkgimgs-multi-versioning). diff --git a/doc/src/manual/faq.md b/doc/src/manual/faq.md index bdecb5ecf106f..b04c9585e30f3 100644 --- a/doc/src/manual/faq.md +++ b/doc/src/manual/faq.md @@ -1035,17 +1035,15 @@ Modifying OpenBLAS settings or compiling Julia with a different BLAS library, eg ### How do I manage precompilation caches in distributed file systems? -When using `julia` in high-performance computing (HPC) facilities, invoking -_n_ `julia` processes simultaneously creates at most _n_ temporary copies of -precompilation cache files. If this is an issue (slow and/or small distributed -file system), you may: - -1. Use `julia` with `--compiled-modules=no` flag to turn off precompilation. -2. Configure a private writable depot using `pushfirst!(DEPOT_PATH, private_path)` - where `private_path` is a path unique to this `julia` process. This - can also be done by setting environment variable `JULIA_DEPOT_PATH` to - `$private_path:$HOME/.julia`. -3. Create a symlink from `~/.julia/compiled` to a directory in a scratch space. +When using Julia in high-performance computing (HPC) facilities with shared filesystems, it is recommended to use a shared +depot (via the `JULIA_DEPOT_PATH` environment variable). Since Julia v1.10, multiple Julia processes on functionally similar +workers and using the same depot will coordinate via pidfile locks to only spend effort precompiling on one process while the +others wait. The precompilation process will indicate when the process is precompiling or waiting for another that is +precompiling. If non-interactive the messages are via `@debug`. + +However, due to caching of binary code, the cache rejection since v1.9 is more strict and users may need to set the +[`JULIA_CPU_TARGET`](@ref JULIA_CPU_TARGET) environment variable appropriately to get a single cache that is usable throughout the HPC +environment. ## Julia Releases From b407e1b2d4e77a4a2660a3dc847c19cf2dfb61ef Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Sun, 17 Sep 2023 22:15:27 -0400 Subject: [PATCH 52/56] testdefs: make sure that if a test set changes the active project, they change it back when they're done (#51029) We already check the following for mutation by a test set: 1. DEPOT_PATH 2. LOAD_PATH 3. ENV So this PR just adds the active project to the list of things we check. Changing the active project during a test set can definitely have negative effects on subsequent test sets that are run on the same worker, so we want to make sure if a test set changes the active project, that they change it back when they're done. (cherry picked from commit 106e867e6c28347e42b91905d526cc4908e50ec3) --- test/testdefs.jl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/testdefs.jl b/test/testdefs.jl index 4aac988cda7fb..8417fb09cca5b 100644 --- a/test/testdefs.jl +++ b/test/testdefs.jl @@ -25,6 +25,7 @@ function runtests(name, path, isolate=true; seed=nothing) original_depot_path = copy(Base.DEPOT_PATH) original_load_path = copy(Base.LOAD_PATH) original_env = copy(ENV) + original_project = Base.active_project() Base.include(m, "$path.jl") @@ -63,6 +64,17 @@ function runtests(name, path, isolate=true; seed=nothing) error(msg) end end + if Base.active_project() != original_project + msg = "The `$(name)` test set changed the active project and did not restore the original value" + @error( + msg, + original_project, + Base.active_project(), + testset_name = name, + testset_path = path, + ) + error(msg) + end end rss = Sys.maxrss() #res_and_time_data[1] is the testset From 491dfb5f30f590842c9e3da419cbfce3ae0217b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Drvo=C5=A1t=C4=9Bp?= Date: Mon, 25 Sep 2023 12:56:49 +0200 Subject: [PATCH 53/56] Backport a fix for GMP patches to `backports-release-1.10` (#51445) This backports `Fixes and improvements for source builds (#51422)` PR to the `backports-release-1.10` branch to make it buildable without binary builder (we are monitoring that branch in our CI to make sure we are up to date with the upcoming 1.10 release). Co-authored-by: Tim Besard --- Make.inc | 2 +- deps/gmp.mk | 10 +++++----- deps/llvm.mk | 6 +++--- deps/patches/gmp-more_alloc_overflow.patch | 14 +++++++------- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Make.inc b/Make.inc index 4eacd49e5155a..1163f66c2fdbd 100644 --- a/Make.inc +++ b/Make.inc @@ -1171,7 +1171,7 @@ endif # We need python for things like BB triplet recognition. We don't really care # about version, generally, so just find something that works: -PYTHON := "$(shell which python 2>/dev/null || which python3 2>/dev/null || which python2 2>/dev/null || echo not found)" +PYTHON := $(shell which python 2>/dev/null || which python3 2>/dev/null || which python2 2>/dev/null || echo not found) PYTHON_SYSTEM := $(shell $(PYTHON) -c 'from __future__ import print_function; import platform; print(platform.system())') # If we're running on Cygwin, but using a native-windows Python, we need to use cygpath -w diff --git a/deps/gmp.mk b/deps/gmp.mk index 0ebabe53acf8d..491d649e9202f 100644 --- a/deps/gmp.mk +++ b/deps/gmp.mk @@ -39,27 +39,27 @@ checksum-gmp: $(SRCCACHE)/gmp-$(GMP_VER).tar.bz2 # Necessary for version 6.2.1, remove after next gmp release $(SRCCACHE)/gmp-$(GMP_VER)/gmp-HG-changeset.patch-applied: $(SRCCACHE)/gmp-$(GMP_VER)/source-extracted cd $(dir $@) && \ - patch -p1 < $(SRCDIR)/patches/gmp-HG-changeset.patch + patch -p1 -f < $(SRCDIR)/patches/gmp-HG-changeset.patch echo 1 > $@ $(SRCCACHE)/gmp-$(GMP_VER)/gmp-exception.patch-applied: $(SRCCACHE)/gmp-$(GMP_VER)/gmp-HG-changeset.patch-applied cd $(dir $@) && \ - patch -p1 < $(SRCDIR)/patches/gmp-exception.patch + patch -p1 -f < $(SRCDIR)/patches/gmp-exception.patch echo 1 > $@ $(SRCCACHE)/gmp-$(GMP_VER)/gmp_alloc_overflow_func.patch-applied: $(SRCCACHE)/gmp-$(GMP_VER)/gmp-exception.patch-applied cd $(dir $@) && \ - patch -p1 < $(SRCDIR)/patches/gmp_alloc_overflow_func.patch + patch -p1 -f < $(SRCDIR)/patches/gmp_alloc_overflow_func.patch echo 1 > $@ $(SRCCACHE)/gmp-$(GMP_VER)/gmp-CVE-2021-43618.patch-applied: $(SRCCACHE)/gmp-$(GMP_VER)/gmp_alloc_overflow_func.patch-applied cd $(dir $@) && \ - patch -p1 < $(SRCDIR)/patches/gmp-CVE-2021-43618.patch + patch -p1 -f < $(SRCDIR)/patches/gmp-CVE-2021-43618.patch echo 1 > $@ $(SRCCACHE)/gmp-$(GMP_VER)/gmp-more_alloc_overflow.patch-applied: $(SRCCACHE)/gmp-$(GMP_VER)/gmp-CVE-2021-43618.patch-applied cd $(dir $@) && \ - patch -p1 < $(SRCDIR)/patches/gmp-more_alloc_overflow.patch + patch -p1 -f < $(SRCDIR)/patches/gmp-more_alloc_overflow.patch echo 1 > $@ $(SRCCACHE)/gmp-$(GMP_VER)/source-patched: $(SRCCACHE)/gmp-$(GMP_VER)/gmp-more_alloc_overflow.patch-applied diff --git a/deps/llvm.mk b/deps/llvm.mk index 2a8365dd73e75..a06db1fb0781b 100644 --- a/deps/llvm.mk +++ b/deps/llvm.mk @@ -214,7 +214,7 @@ LLVM_CMAKE += -DLLVM_SHLIB_SYMBOL_VERSION:STRING="JL_LLVM_$(LLVM_VER_SHORT)" LLVM_PATCH_PREV := define LLVM_PATCH $$(SRCCACHE)/$$(LLVM_SRC_DIR)/$1.patch-applied: $$(SRCCACHE)/$$(LLVM_SRC_DIR)/source-extracted | $$(SRCDIR)/patches/$1.patch $$(LLVM_PATCH_PREV) - cd $$(SRCCACHE)/$$(LLVM_SRC_DIR)/llvm && patch -p1 < $$(SRCDIR)/patches/$1.patch + cd $$(SRCCACHE)/$$(LLVM_SRC_DIR)/llvm && patch -p1 -f < $$(SRCDIR)/patches/$1.patch echo 1 > $$@ # declare that applying any patch must re-run the compile step $$(LLVM_BUILDDIR_withtype)/build-compiled: $$(SRCCACHE)/$$(LLVM_SRC_DIR)/$1.patch-applied @@ -223,7 +223,7 @@ endef define LLVM_PROJ_PATCH $$(SRCCACHE)/$$(LLVM_SRC_DIR)/$1.patch-applied: $$(SRCCACHE)/$$(LLVM_SRC_DIR)/source-extracted | $$(SRCDIR)/patches/$1.patch $$(LLVM_PATCH_PREV) - cd $$(SRCCACHE)/$$(LLVM_SRC_DIR) && patch -p1 < $$(SRCDIR)/patches/$1.patch + cd $$(SRCCACHE)/$$(LLVM_SRC_DIR) && patch -p1 -f < $$(SRCDIR)/patches/$1.patch echo 1 > $$@ # declare that applying any patch must re-run the compile step $$(LLVM_BUILDDIR_withtype)/build-compiled: $$(SRCCACHE)/$$(LLVM_SRC_DIR)/$1.patch-applied @@ -249,7 +249,7 @@ $(BUILDDIR)/julia-patches.patch: # Apply the patch. $(SRCCACHE)/$(LLVM_SRC_DIR)/julia-patches.patch-applied: $(BUILDDIR)/julia-patches.patch $(SRCCACHE)/$(LLVM_SRC_DIR)/source-extracted - cd $(SRCCACHE)/$(LLVM_SRC_DIR) && patch -p1 < $(realpath $<) + cd $(SRCCACHE)/$(LLVM_SRC_DIR) && patch -p1 -f < $(realpath $<) echo 1 > $@ # Require application of Julia's patchset before configuring LLVM. diff --git a/deps/patches/gmp-more_alloc_overflow.patch b/deps/patches/gmp-more_alloc_overflow.patch index 09d07d7dbd8d5..597f0d52d73e7 100644 --- a/deps/patches/gmp-more_alloc_overflow.patch +++ b/deps/patches/gmp-more_alloc_overflow.patch @@ -1,6 +1,6 @@ -diff -ur gmp-6.2.1.orig/mpz/n_pow_ui.c gmp-6.2.1/mpz/n_pow_ui.c ---- gmp-6.2.1.orig/mpz/n_pow_ui.c 2023-09-08 11:41:16.620551175 +0200 -+++ gmp-6.2.1/mpz/n_pow_ui.c 2023-09-08 12:49:29.650492180 +0200 +diff -ur a/mpz/n_pow_ui.c b/mpz/n_pow_ui.c +--- a/mpz/n_pow_ui.c ++++ b/mpz/n_pow_ui.c @@ -220,8 +220,7 @@ umul_ppmm (ovfl, rtwos_bits, e, btwos); if (ovfl) @@ -21,10 +21,10 @@ diff -ur gmp-6.2.1.orig/mpz/n_pow_ui.c gmp-6.2.1/mpz/n_pow_ui.c } ralloc = ralloc / GMP_NUMB_BITS + 5; -diff -ur gmp-6.2.1.orig/tal-reent.c gmp-6.2.1/tal-reent.c ---- gmp-6.2.1.orig/tal-reent.c 2020-11-14 19:45:09.000000000 +0100 -+++ gmp-6.2.1/tal-reent.c 2023-09-08 12:10:34.061357613 +0200 -@@ -61,6 +61,11 @@ +diff -ur a/tal-reent.c b/tal-reent.c +--- a/tal-reent.c ++++ b/tal-reent.c +@@ -61,6 +61,10 @@ total_size = size + HSIZ; p = __GMP_ALLOCATE_FUNC_TYPE (total_size, char); From f9ef654b6393e54ad6284d36a32f1fc56af17b05 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Wed, 20 Sep 2023 12:58:54 +0900 Subject: [PATCH 54/56] inference: handle `Vararg` in `abstract_call_unionall` for `argtypes` computed by `abstract_apply` (#51393) This commit adds special handling for `Vararg` types that may appear at the end of `argtypes`, as computed by `abstract_apply`. Even though PR within the abstract state, they can still be part of `argtypes`. As a result, this kind of special handling is still necessary. It remains an open question whether we can refactor `abstract_apply` to prevent `Vararg`s from appearing in `argtypes` in the first place. --- base/compiler/abstractinterpretation.jl | 7 ++++++- test/compiler/inference.jl | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 973c7dc6f879b..f256f5438bb90 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -1874,7 +1874,12 @@ function abstract_call_unionall(interp::AbstractInterpreter, argtypes::Vector{An a2 = argtypes[2] a3 = argtypes[3] ⊑ᵢ = ⊑(typeinf_lattice(interp)) - nothrow = a2 ⊑ᵢ TypeVar && (a3 ⊑ᵢ Type || a3 ⊑ᵢ TypeVar) + if isvarargtype(a3) + a3 = unwrapva(a3) + nothrow = false + else + nothrow = a2 ⊑ᵢ TypeVar && (a3 ⊑ᵢ Type || a3 ⊑ᵢ TypeVar) + end if isa(a3, Const) body = a3.val elseif isType(a3) diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index 8b980f1fdb17c..25190fe0c16ff 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -5,7 +5,7 @@ import Core.Compiler: Const, Conditional, ⊑, ReturnNode, GotoIfNot isdispatchelem(@nospecialize x) = !isa(x, Type) || Core.Compiler.isdispatchelem(x) using Random, Core.IR -using InteractiveUtils: code_llvm +using InteractiveUtils include("irutils.jl") @@ -5101,3 +5101,8 @@ end |> only === Val{5} @test fully_eliminated() do length(continue_const_prop(1, 5)) end + +# https://github.com/JuliaLang/julia/issues/51310 +@test code_typed() do + b{c} = d... +end |> only |> first isa Core.CodeInfo From ae8f9ad5b8c5f5b0c217d99e83657405dbeb1913 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Fri, 22 Sep 2023 02:28:46 +0900 Subject: [PATCH 55/56] inference: follow up the `Vararg` fix in `abstract_call_unionall` (#51403) --- base/compiler/abstractinterpretation.jl | 66 ++++++++++++++----------- test/compiler/inference.jl | 8 +++ 2 files changed, 44 insertions(+), 30 deletions(-) diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index f256f5438bb90..11d81dc3d0935 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -1869,44 +1869,50 @@ function abstract_call_builtin(interp::AbstractInterpreter, f::Builtin, (; fargs end function abstract_call_unionall(interp::AbstractInterpreter, argtypes::Vector{Any}) - if length(argtypes) == 3 - canconst = true + na = length(argtypes) + if isvarargtype(argtypes[end]) + if na ≤ 2 + return CallMeta(Any, EFFECTS_THROWS, NoCallInfo()) + elseif na > 4 + return CallMeta(Bottom, EFFECTS_THROWS, NoCallInfo()) + end + a2 = argtypes[2] + a3 = unwrapva(argtypes[3]) + nothrow = false + elseif na == 3 a2 = argtypes[2] a3 = argtypes[3] ⊑ᵢ = ⊑(typeinf_lattice(interp)) - if isvarargtype(a3) - a3 = unwrapva(a3) - nothrow = false - else - nothrow = a2 ⊑ᵢ TypeVar && (a3 ⊑ᵢ Type || a3 ⊑ᵢ TypeVar) - end - if isa(a3, Const) - body = a3.val - elseif isType(a3) - body = a3.parameters[1] + nothrow = a2 ⊑ᵢ TypeVar && (a3 ⊑ᵢ Type || a3 ⊑ᵢ TypeVar) + else + return CallMeta(Bottom, EFFECTS_THROWS, NoCallInfo()) + end + canconst = true + if isa(a3, Const) + body = a3.val + elseif isType(a3) + body = a3.parameters[1] + canconst = false + else + return CallMeta(Any, Effects(EFFECTS_TOTAL; nothrow), NoCallInfo()) + end + if !(isa(body, Type) || isa(body, TypeVar)) + return CallMeta(Any, EFFECTS_THROWS, NoCallInfo()) + end + if has_free_typevars(body) + if isa(a2, Const) + tv = a2.val + elseif isa(a2, PartialTypeVar) + tv = a2.tv canconst = false else - return CallMeta(Any, Effects(EFFECTS_TOTAL; nothrow), NoCallInfo()) - end - if !(isa(body, Type) || isa(body, TypeVar)) return CallMeta(Any, EFFECTS_THROWS, NoCallInfo()) end - if has_free_typevars(body) - if isa(a2, Const) - tv = a2.val - elseif isa(a2, PartialTypeVar) - tv = a2.tv - canconst = false - else - return CallMeta(Any, EFFECTS_THROWS, NoCallInfo()) - end - isa(tv, TypeVar) || return CallMeta(Any, EFFECTS_THROWS, NoCallInfo()) - body = UnionAll(tv, body) - end - ret = canconst ? Const(body) : Type{body} - return CallMeta(ret, Effects(EFFECTS_TOTAL; nothrow), NoCallInfo()) + isa(tv, TypeVar) || return CallMeta(Any, EFFECTS_THROWS, NoCallInfo()) + body = UnionAll(tv, body) end - return CallMeta(Bottom, EFFECTS_THROWS, NoCallInfo()) + ret = canconst ? Const(body) : Type{body} + return CallMeta(ret, Effects(EFFECTS_TOTAL; nothrow), NoCallInfo()) end function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgInfo, si::StmtInfo, sv::AbsIntState) diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index 25190fe0c16ff..d767b2cfe3eb3 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -5106,3 +5106,11 @@ end @test code_typed() do b{c} = d... end |> only |> first isa Core.CodeInfo + +abstract_call_unionall_vararg(some::Some{Any}) = UnionAll(some.value...) +@test only(Base.return_types(abstract_call_unionall_vararg)) !== Union{} +let TV = TypeVar(:T) + t = Vector{TV} + some = Some{Any}((TV, t)) + @test abstract_call_unionall_vararg(some) isa UnionAll +end From e084a4013a3b8e1944dac199a5a92c2035cefffe Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Tue, 26 Sep 2023 14:28:20 -0300 Subject: [PATCH 56/56] Check if malloc has succeeded before updating GC counters (#51247) --- src/gc.c | 66 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/src/gc.c b/src/gc.c index 7d847195dce8c..1984c92ec3c14 100644 --- a/src/gc.c +++ b/src/gc.c @@ -3639,7 +3639,8 @@ JL_DLLEXPORT void *jl_gc_counted_malloc(size_t sz) { jl_gcframe_t **pgcstack = jl_get_pgcstack(); jl_task_t *ct = jl_current_task; - if (pgcstack != NULL && ct->world_age) { + void *data = malloc(sz); + if (data != NULL && pgcstack != NULL && ct->world_age) { jl_ptls_t ptls = ct->ptls; maybe_collect(ptls); jl_atomic_store_relaxed(&ptls->gc_num.allocd, @@ -3654,14 +3655,15 @@ JL_DLLEXPORT void *jl_gc_counted_malloc(size_t sz) jl_atomic_store_relaxed(&ptls->gc_num.alloc_acc, 0); } } - return malloc(sz); + return data; } JL_DLLEXPORT void *jl_gc_counted_calloc(size_t nm, size_t sz) { jl_gcframe_t **pgcstack = jl_get_pgcstack(); jl_task_t *ct = jl_current_task; - if (pgcstack != NULL && ct->world_age) { + void *data = calloc(nm, sz); + if (data != NULL && pgcstack != NULL && ct->world_age) { jl_ptls_t ptls = ct->ptls; maybe_collect(ptls); jl_atomic_store_relaxed(&ptls->gc_num.allocd, @@ -3676,7 +3678,7 @@ JL_DLLEXPORT void *jl_gc_counted_calloc(size_t nm, size_t sz) jl_atomic_store_relaxed(&ptls->gc_num.alloc_acc, 0); } } - return calloc(nm, sz); + return data; } JL_DLLEXPORT void jl_gc_counted_free_with_size(void *p, size_t sz) @@ -3700,7 +3702,8 @@ JL_DLLEXPORT void *jl_gc_counted_realloc_with_old_size(void *p, size_t old, size { jl_gcframe_t **pgcstack = jl_get_pgcstack(); jl_task_t *ct = jl_current_task; - if (pgcstack != NULL && ct->world_age) { + void *data = realloc(p, sz); + if (data != NULL && pgcstack != NULL && ct->world_age) { jl_ptls_t ptls = ct->ptls; maybe_collect(ptls); if (!(sz < old)) @@ -3730,7 +3733,7 @@ JL_DLLEXPORT void *jl_gc_counted_realloc_with_old_size(void *p, size_t old, size } } } - return realloc(p, sz); + return data; } // allocation wrappers that save the size of allocations, to allow using @@ -3799,6 +3802,15 @@ JL_DLLEXPORT void *jl_gc_managed_malloc(size_t sz) size_t allocsz = LLT_ALIGN(sz, JL_CACHE_BYTE_ALIGNMENT); if (allocsz < sz) // overflow in adding offs, size was "negative" jl_throw(jl_memory_exception); + + int last_errno = errno; +#ifdef _OS_WINDOWS_ + DWORD last_error = GetLastError(); +#endif + void *b = malloc_cache_align(allocsz); + if (b == NULL) + jl_throw(jl_memory_exception); + jl_atomic_store_relaxed(&ptls->gc_num.allocd, jl_atomic_load_relaxed(&ptls->gc_num.allocd) + allocsz); jl_atomic_store_relaxed(&ptls->gc_num.malloc, @@ -3810,13 +3822,6 @@ JL_DLLEXPORT void *jl_gc_managed_malloc(size_t sz) jl_atomic_fetch_add_relaxed(&gc_heap_stats.heap_size, alloc_acc + allocsz); jl_atomic_store_relaxed(&ptls->gc_num.alloc_acc, 0); } - int last_errno = errno; -#ifdef _OS_WINDOWS_ - DWORD last_error = GetLastError(); -#endif - void *b = malloc_cache_align(allocsz); - if (b == NULL) - jl_throw(jl_memory_exception); #ifdef _OS_WINDOWS_ SetLastError(last_error); #endif @@ -3831,12 +3836,28 @@ static void *gc_managed_realloc_(jl_ptls_t ptls, void *d, size_t sz, size_t olds { if (can_collect) maybe_collect(ptls); - + int is_old_marked = jl_astaggedvalue(owner)->bits.gc == GC_OLD_MARKED; size_t allocsz = LLT_ALIGN(sz, JL_CACHE_BYTE_ALIGNMENT); if (allocsz < sz) // overflow in adding offs, size was "negative" jl_throw(jl_memory_exception); - if (jl_astaggedvalue(owner)->bits.gc == GC_OLD_MARKED) { + int last_errno = errno; +#ifdef _OS_WINDOWS_ + DWORD last_error = GetLastError(); +#endif + void *b; + if (isaligned) + b = realloc_cache_align(d, allocsz, oldsz); + else + b = realloc(d, allocsz); + if (b == NULL) + jl_throw(jl_memory_exception); +#ifdef _OS_WINDOWS_ + SetLastError(last_error); +#endif + errno = last_errno; + // gc_managed_realloc_ is currently used exclusively for resizing array buffers. + if (is_old_marked) { ptls->gc_cache.perm_scanned_bytes += allocsz - oldsz; inc_live_bytes(allocsz - oldsz); } @@ -3867,21 +3888,6 @@ static void *gc_managed_realloc_(jl_ptls_t ptls, void *d, size_t sz, size_t olds } } - int last_errno = errno; -#ifdef _OS_WINDOWS_ - DWORD last_error = GetLastError(); -#endif - void *b; - if (isaligned) - b = realloc_cache_align(d, allocsz, oldsz); - else - b = realloc(d, allocsz); - if (b == NULL) - jl_throw(jl_memory_exception); -#ifdef _OS_WINDOWS_ - SetLastError(last_error); -#endif - errno = last_errno; maybe_record_alloc_to_profile((jl_value_t*)b, sz, jl_gc_unknown_type_tag); return b; }