Skip to content

Commit 62dd72f

Browse files
committed
fix generated_body_to_codeinfo to avoid string (which is not always defined)
Fixes a discrepancy between the code in C before #57230 and in Julia afterwards, making sure to sequence these definitions correctly. Not sure how to write a reliable test since it is specific to when this generated function is defined relative to the helpers used by this thunk, but the issue/fix is visible with: ``` $ ./julia -e 'code_lowered(ntuple, (Returns{Nothing}, Val{1000000}))' ```
1 parent 2c7527b commit 62dd72f

File tree

4 files changed

+29
-22
lines changed

4 files changed

+29
-22
lines changed

base/Base_compiler.jl

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,31 @@ if false
158158
println(io::IO, x...) = Core.println(io, x...)
159159
end
160160

161+
## Load essential files and libraries
162+
include("essentials.jl")
163+
164+
# Because lowering inserts direct references, it is mandatory for this binding
165+
# to exist before we start inferring code.
166+
function string end
167+
import Core: String
168+
169+
# For OS specific stuff
170+
# We need to strcat things here, before strings are really defined
171+
function strcat(x::String, y::String)
172+
out = ccall(:jl_alloc_string, Ref{String}, (Int,), Core.sizeof(x) + Core.sizeof(y))
173+
gc_x = @_gc_preserve_begin(x)
174+
gc_y = @_gc_preserve_begin(y)
175+
gc_out = @_gc_preserve_begin(out)
176+
out_ptr = unsafe_convert(Ptr{UInt8}, out)
177+
unsafe_copyto!(out_ptr, unsafe_convert(Ptr{UInt8}, x), Core.sizeof(x))
178+
unsafe_copyto!(out_ptr + Core.sizeof(x), unsafe_convert(Ptr{UInt8}, y), Core.sizeof(y))
179+
@_gc_preserve_end(gc_x)
180+
@_gc_preserve_end(gc_y)
181+
@_gc_preserve_end(gc_out)
182+
return out
183+
end
184+
185+
161186
"""
162187
time_ns()::UInt64
163188
@@ -172,8 +197,6 @@ const _DOCS_ALIASING_WARNING = """
172197
Behavior can be unexpected when any mutated argument shares memory with any other argument.
173198
"""
174199

175-
## Load essential files and libraries
176-
include("essentials.jl")
177200
include("ctypes.jl")
178201
include("gcutils.jl")
179202
include("generator.jl")
@@ -284,7 +307,6 @@ include("rounding.jl")
284307
include("float.jl")
285308

286309
# Lazy strings
287-
import Core: String
288310
include("strings/lazy.jl")
289311

290312
function cld end
@@ -321,22 +343,6 @@ using .Order
321343
include("coreir.jl")
322344
include("invalidation.jl")
323345

324-
# Because lowering inserts direct references, it is mandatory for this binding
325-
# to exist before we start inferring code.
326-
function string end
327-
328-
# For OS specific stuff
329-
# We need to strcat things here, before strings are really defined
330-
function strcat(x::String, y::String)
331-
out = ccall(:jl_alloc_string, Ref{String}, (Csize_t,), Core.sizeof(x) + Core.sizeof(y))
332-
GC.@preserve x y out begin
333-
out_ptr = unsafe_convert(Ptr{UInt8}, out)
334-
unsafe_copyto!(out_ptr, unsafe_convert(Ptr{UInt8}, x), Core.sizeof(x))
335-
unsafe_copyto!(out_ptr + Core.sizeof(x), unsafe_convert(Ptr{UInt8}, y), Core.sizeof(y))
336-
end
337-
return out
338-
end
339-
340346
BUILDROOT::String = ""
341347
DATAROOT::String = ""
342348
const DL_LOAD_PATH = String[]

base/essentials.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,8 @@ cconvert(::Type{<:Ptr}, x) = x # but defer the conversion to Ptr to unsafe_conve
723723
unsafe_convert(::Type{T}, x::T) where {T} = x # unsafe_convert (like convert) defaults to assuming the convert occurred
724724
unsafe_convert(::Type{T}, x::T) where {T<:Ptr} = x # to resolve ambiguity with the next method
725725
unsafe_convert(::Type{P}, x::Ptr) where {P<:Ptr} = convert(P, x)
726+
unsafe_convert(::Type{Ptr{UInt8}}, s::String) = ccall(:jl_string_ptr, Ptr{UInt8}, (Any,), s)
727+
unsafe_convert(::Type{Ptr{Int8}}, s::String) = ccall(:jl_string_ptr, Ptr{Int8}, (Any,), s)
726728

727729
"""
728730
reinterpret(::Type{Out}, x::In)

base/expr.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1672,7 +1672,8 @@ function generated_body_to_codeinfo(ex::Expr, defmod::Module, isva::Bool)
16721672
ci = ccall(:jl_expand, Any, (Any, Any), ex, defmod)
16731673
if !isa(ci, CodeInfo)
16741674
if isa(ci, Expr) && ci.head === :error
1675-
error("syntax: $(ci.args[1])")
1675+
msg = ci.args[1]
1676+
error(msg isa String ? strcat("syntax: ", msg) : msg)
16761677
end
16771678
error("The function body AST defined by this @generated function is not pure. This likely means it contains a closure, a comprehension or a generator.")
16781679
end

base/pointer.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,6 @@ cconvert(::Type{Ptr{UInt8}}, s::AbstractString) = String(s)
5959
cconvert(::Type{Ptr{Int8}}, s::AbstractString) = String(s)
6060
unsafe_convert(::Type{Ptr{UInt8}}, x::Symbol) = ccall(:jl_symbol_name, Ptr{UInt8}, (Any,), x)
6161
unsafe_convert(::Type{Ptr{Int8}}, x::Symbol) = ccall(:jl_symbol_name, Ptr{Int8}, (Any,), x)
62-
unsafe_convert(::Type{Ptr{UInt8}}, s::String) = ccall(:jl_string_ptr, Ptr{UInt8}, (Any,), s)
63-
unsafe_convert(::Type{Ptr{Int8}}, s::String) = ccall(:jl_string_ptr, Ptr{Int8}, (Any,), s)
6462

6563
cconvert(::Type{<:Ptr}, a::Array) = getfield(a, :ref)
6664
unsafe_convert(::Type{Ptr{S}}, a::AbstractArray{T}) where {S,T} = convert(Ptr{S}, unsafe_convert(Ptr{T}, a))

0 commit comments

Comments
 (0)