Skip to content

Commit a3c48d7

Browse files
authored
fix generated_body_to_codeinfo to avoid string (which is not always defined) (#57925)
Fixes a discrepancy between the code in C before #57230 and in Julia afterwards, making sure to sequence these method 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}))' ``` Fix #57301
1 parent 1c3878c commit a3c48d7

File tree

5 files changed

+31
-22
lines changed

5 files changed

+31
-22
lines changed

base/Base_compiler.jl

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

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

174-
## Load essential files and libraries
175-
include("essentials.jl")
176199
include("ctypes.jl")
177200
include("gcutils.jl")
178201
include("generator.jl")
@@ -283,7 +306,6 @@ include("rounding.jl")
283306
include("float.jl")
284307

285308
# Lazy strings
286-
import Core: String
287309
include("strings/lazy.jl")
288310

289311
function cld end
@@ -320,22 +342,6 @@ using .Order
320342
include("coreir.jl")
321343
include("invalidation.jl")
322344

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

test/staged.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,3 +477,5 @@ module GeneratedScope57417
477477
end
478478
@test g() == 1
479479
end
480+
481+
@test_throws "syntax: expression too large" code_lowered(ntuple, (Returns{Nothing}, Val{1000000}))

0 commit comments

Comments
 (0)