• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

JuliaLang / julia / #37575

pending completion
#37575

push

local

web-flow
Name LLVM variables from codegen (#50094)

72701 of 84227 relevant lines covered (86.32%)

33561253.47 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.96
/base/pointer.jl
1
# This file is a part of Julia. License is MIT: https://julialang.org/license
2

3
"""
4
    Ptr{T}
5

6
A memory address referring to data of type `T`.  However, there is no guarantee that the
7
memory is actually valid, or that it actually represents data of the specified type.
8
"""
9
Ptr
10

11
## converting pointers to an appropriate unsigned ##
12

13
"""
14
    C_NULL
15

16
The C null pointer constant, sometimes used when calling external code.
17
"""
18
const C_NULL = bitcast(Ptr{Cvoid}, 0)
19

20
# TODO: deprecate these conversions. C doesn't even allow them.
21

22
# pointer to integer
23
convert(::Type{T}, x::Ptr) where {T<:Integer} = T(UInt(x))::T
21,532✔
24

25
# integer to pointer
26
convert(::Type{Ptr{T}}, x::Union{Int,UInt}) where {T} = Ptr{T}(x)
1,206,553,311✔
27

28
# pointer to pointer
29
convert(::Type{Ptr{T}}, p::Ptr{T}) where {T} = p
54✔
30
convert(::Type{Ptr{T}}, p::Ptr) where {T} = bitcast(Ptr{T}, p)::Ptr{T}
1,126,430,142✔
31

32
# object to pointer (when used with ccall)
33

34
"""
35
    unsafe_convert(T, x)
36

37
Convert `x` to a C argument of type `T`
38
where the input `x` must be the return value of `cconvert(T, ...)`.
39

40
In cases where [`convert`](@ref) would need to take a Julia object
41
and turn it into a `Ptr`, this function should be used to define and perform
42
that conversion.
43

44
Be careful to ensure that a Julia reference to `x` exists as long as the result of this
45
function will be used. Accordingly, the argument `x` to this function should never be an
46
expression, only a variable name or field reference. For example, `x=a.b.c` is acceptable,
47
but `x=[a,b,c]` is not.
48

49
The `unsafe` prefix on this function indicates that using the result of this function after
50
the `x` argument to this function is no longer accessible to the program may cause undefined
51
behavior, including program corruption or segfaults, at any later time.
52

53
See also [`cconvert`](@ref)
54
"""
55
function unsafe_convert end
56

57
unsafe_convert(::Type{Ptr{UInt8}}, x::Symbol) = ccall(:jl_symbol_name, Ptr{UInt8}, (Any,), x)
1,009,114✔
58
unsafe_convert(::Type{Ptr{Int8}}, x::Symbol) = ccall(:jl_symbol_name, Ptr{Int8}, (Any,), x)
21,441,761✔
59
unsafe_convert(::Type{Ptr{UInt8}}, s::String) = ccall(:jl_string_ptr, Ptr{UInt8}, (Any,), s)
475,660,465✔
60
unsafe_convert(::Type{Ptr{Int8}}, s::String) = ccall(:jl_string_ptr, Ptr{Int8}, (Any,), s)
2,859,613✔
61
# convert strings to String etc. to pass as pointers
62
cconvert(::Type{Ptr{UInt8}}, s::AbstractString) = String(s)
53✔
63
cconvert(::Type{Ptr{Int8}}, s::AbstractString) = String(s)
×
64

65
unsafe_convert(::Type{Ptr{T}}, a::Array{T}) where {T} = ccall(:jl_array_ptr, Ptr{T}, (Any,), a)
681,437,163✔
66
unsafe_convert(::Type{Ptr{S}}, a::AbstractArray{T}) where {S,T} = convert(Ptr{S}, unsafe_convert(Ptr{T}, a))
161,886,090✔
67
unsafe_convert(::Type{Ptr{T}}, a::AbstractArray{T}) where {T} = error("conversion to pointer not defined for $(typeof(a))")
9✔
68

69
# unsafe pointer to array conversions
70
"""
71
    unsafe_wrap(Array, pointer::Ptr{T}, dims; own = false)
72

73
Wrap a Julia `Array` object around the data at the address given by `pointer`,
74
without making a copy.  The pointer element type `T` determines the array
75
element type. `dims` is either an integer (for a 1d array) or a tuple of the array dimensions.
76
`own` optionally specifies whether Julia should take ownership of the memory,
77
calling `free` on the pointer when the array is no longer referenced.
78

79
This function is labeled "unsafe" because it will crash if `pointer` is not
80
a valid memory address to data of the requested length. Unlike [`unsafe_load`](@ref)
81
and [`unsafe_store!`](@ref), the programmer is responsible also for ensuring that the
82
underlying data is not accessed through two arrays of different element type, similar
83
to the strict aliasing rule in C.
84
"""
85
function unsafe_wrap(::Union{Type{Array},Type{Array{T}},Type{Array{T,N}}},
8,380✔
86
                     p::Ptr{T}, dims::NTuple{N,Int}; own::Bool = false) where {T,N}
87
    ccall(:jl_ptr_to_array, Array{T,N}, (Any, Ptr{Cvoid}, Any, Int32),
4,191✔
88
          Array{T,N}, p, dims, own)
89
end
90
function unsafe_wrap(::Union{Type{Array},Type{Array{T}},Type{Array{T,1}}},
52,371✔
91
                     p::Ptr{T}, d::Integer; own::Bool = false) where {T}
92
    ccall(:jl_ptr_to_array_1d, Array{T,1},
52,142✔
93
          (Any, Ptr{Cvoid}, Csize_t, Cint), Array{T,1}, p, d, own)
94
end
95
unsafe_wrap(Atype::Union{Type{Array},Type{Array{T}},Type{Array{T,N}}},
×
96
            p::Ptr{T}, dims::NTuple{N,<:Integer}; own::Bool = false) where {T,N} =
7,852✔
97
    unsafe_wrap(Atype, p, convert(Tuple{Vararg{Int}}, dims), own = own)
98

99
"""
100
    unsafe_load(p::Ptr{T}, i::Integer=1)
101
    unsafe_load(p::Ptr{T}, order::Symbol)
102
    unsafe_load(p::Ptr{T}, i::Integer, order::Symbol)
103

104
Load a value of type `T` from the address of the `i`th element (1-indexed) starting at `p`.
105
This is equivalent to the C expression `p[i-1]`. Optionally, an atomic memory ordering can
106
be provided.
107

108
The `unsafe` prefix on this function indicates that no validation is performed on the
109
pointer `p` to ensure that it is valid. Like C, the programmer is responsible for ensuring
110
that referenced memory is not freed or garbage collected while invoking this function.
111
Incorrect usage may segfault your program or return garbage answers. Unlike C, dereferencing
112
memory region allocated as different type may be valid provided that the types are compatible.
113

114
!!! compat "Julia 1.10"
115
     The `order` argument is available as of Julia 1.10.
116

117
See also: [`atomic`](@ref)
118
"""
119
unsafe_load(p::Ptr, i::Integer=1) = pointerref(p, Int(i), 1)
1,817,645,473✔
120
unsafe_load(p::Ptr, order::Symbol) = atomic_pointerref(p, order)
55✔
121
function unsafe_load(p::Ptr, i::Integer, order::Symbol)
×
122
    unsafe_load(p + (elsize(typeof(p)) * (Int(i) - 1)), order)
×
123
end
124

125
"""
126
    unsafe_store!(p::Ptr{T}, x, i::Integer=1)
127
    unsafe_store!(p::Ptr{T}, x, order::Symbol)
128
    unsafe_store!(p::Ptr{T}, x, i::Integer, order::Symbol)
129

130
Store a value of type `T` to the address of the `i`th element (1-indexed) starting at `p`.
131
This is equivalent to the C expression `p[i-1] = x`. Optionally, an atomic memory ordering
132
can be provided.
133

134
The `unsafe` prefix on this function indicates that no validation is performed on the
135
pointer `p` to ensure that it is valid. Like C, the programmer is responsible for ensuring
136
that referenced memory is not freed or garbage collected while invoking this function.
137
Incorrect usage may segfault your program. Unlike C, storing memory region allocated as
138
different type may be valid provided that that the types are compatible.
139

140
!!! compat "Julia 1.10"
141
     The `order` argument is available as of Julia 1.10.
142

143
See also: [`atomic`](@ref)
144
"""
145
unsafe_store!(p::Ptr{Any}, @nospecialize(x), i::Integer=1) = pointerset(p, x, Int(i), 1)
1✔
146
unsafe_store!(p::Ptr{T}, x, i::Integer=1) where {T} = pointerset(p, convert(T,x), Int(i), 1)
174,638,762✔
147
unsafe_store!(p::Ptr{T}, x, order::Symbol) where {T} = atomic_pointerset(p, x isa T ? x : convert(T,x), order)
13✔
148
function unsafe_store!(p::Ptr, x, i::Integer, order::Symbol)
×
149
    unsafe_store!(p + (elsize(typeof(p)) * (Int(i) - 1)), x, order)
×
150
end
151

152
"""
153
    unsafe_modify!(p::Ptr{T}, op, x, [order::Symbol]) -> Pair
154

155
These atomically perform the operations to get and set a memory address after applying
156
the function `op`. If supported by the hardware (for example, atomic increment), this may be
157
optimized to the appropriate hardware instruction, otherwise its execution will be
158
similar to:
159

160
    y = unsafe_load(p)
161
    z = op(y, x)
162
    unsafe_store!(p, z)
163
    return y => z
164

165
The `unsafe` prefix on this function indicates that no validation is performed on the
166
pointer `p` to ensure that it is valid. Like C, the programmer is responsible for ensuring
167
that referenced memory is not freed or garbage collected while invoking this function.
168
Incorrect usage may segfault your program.
169

170
!!! compat "Julia 1.10"
171
     This function requires at least Julia 1.10.
172

173
See also: [`modifyproperty!`](@ref Base.modifyproperty!), [`atomic`](@ref)
174
"""
175
function unsafe_modify!(p::Ptr, op, x, order::Symbol=:not_atomic)
30✔
176
    return atomic_pointermodify(p, op, x, order)
30✔
177
end
178

179
"""
180
    unsafe_replace!(p::Ptr{T}, expected, desired,
181
                   [success_order::Symbol[, fail_order::Symbol=success_order]]) -> (; old, success::Bool)
182

183
These atomically perform the operations to get and conditionally set a memory address to
184
a given value. If supported by the hardware, this may be optimized to the appropriate
185
hardware instruction, otherwise its execution will be similar to:
186

187
    y = unsafe_load(p, fail_order)
188
    ok = y === expected
189
    if ok
190
        unsafe_store!(p, desired, success_order)
191
    end
192
    return (; old = y, success = ok)
193

194
The `unsafe` prefix on this function indicates that no validation is performed on the
195
pointer `p` to ensure that it is valid. Like C, the programmer is responsible for ensuring
196
that referenced memory is not freed or garbage collected while invoking this function.
197
Incorrect usage may segfault your program.
198

199
!!! compat "Julia 1.10"
200
     This function requires at least Julia 1.10.
201

202
See also: [`replaceproperty!`](@ref Base.replaceproperty!), [`atomic`](@ref)
203
"""
204
function unsafe_replace!(p::Ptr{T}, expected, desired, success_order::Symbol=:not_atomic, fail_order::Symbol=success_order) where {T}
28✔
205
    @inline
28✔
206
    xT = desired isa T ? desired : convert(T, desired)
28✔
207
    return atomic_pointerreplace(p, expected, xT, success_order, fail_order)
28✔
208
end
209
function unsafe_replace!(p::Ptr{Any}, @nospecialize(expected), @nospecialize(desired), success_order::Symbol=:not_atomic, fail_order::Symbol=success_order)
5✔
210
    return atomic_pointerreplace(p, expected, desired, success_order, fail_order)
5✔
211
end
212

213
"""
214
    unsafe_swap!(p::Ptr{T}, x, [order::Symbol])
215

216
These atomically perform the operations to simultaneously get and set a memory address.
217
If supported by the hardware, this may be optimized to the appropriate hardware
218
instruction, otherwise its execution will be similar to:
219

220
    y = unsafe_load(p)
221
    unsafe_store!(p, x)
222
    return y
223

224
The `unsafe` prefix on this function indicates that no validation is performed on the
225
pointer `p` to ensure that it is valid. Like C, the programmer is responsible for ensuring
226
that referenced memory is not freed or garbage collected while invoking this function.
227
Incorrect usage may segfault your program.
228

229
!!! compat "Julia 1.10"
230
     This function requires at least Julia 1.10.
231

232
See also: [`swapproperty!`](@ref Base.swapproperty!), [`atomic`](@ref)
233
"""
234
function unsafe_swap!(p::Ptr{Any}, x, order::Symbol=:not_atomic)
2✔
235
    return atomic_pointerswap(p, x, order)
2✔
236
end
237
function unsafe_swap!(p::Ptr{T}, x, order::Symbol=:not_atomic) where {T}
11✔
238
    @inline
11✔
239
    xT = x isa T ? x : convert(T, x)
11✔
240
    return atomic_pointerswap(p, xT, order)
11✔
241
end
242

243
# convert a raw Ptr to an object reference, and vice-versa
244
"""
245
    unsafe_pointer_to_objref(p::Ptr)
246

247
Convert a `Ptr` to an object reference. Assumes the pointer refers to a valid heap-allocated
248
Julia object. If this is not the case, undefined behavior results, hence this function is
249
considered "unsafe" and should be used with care.
250

251
See also [`pointer_from_objref`](@ref).
252
"""
253
unsafe_pointer_to_objref(x::Ptr) = ccall(:jl_value_ptr, Any, (Ptr{Cvoid},), x)
2,108,038✔
254

255
"""
256
    pointer_from_objref(x)
257

258
Get the memory address of a Julia object as a `Ptr`. The existence of the resulting `Ptr`
259
will not protect the object from garbage collection, so you must ensure that the object
260
remains referenced for the whole time that the `Ptr` will be used.
261

262
This function may not be called on immutable objects, since they do not have
263
stable memory addresses.
264

265
See also [`unsafe_pointer_to_objref`](@ref).
266
"""
267
function pointer_from_objref(@nospecialize(x))
13,294,353✔
268
    @inline
13,294,223✔
269
    ismutable(x) || error("pointer_from_objref cannot be used on immutable objects")
13,293,896✔
270
    ccall(:jl_value_ptr, Ptr{Cvoid}, (Any,), x)
815,767,880✔
271
end
272

273
## limited pointer arithmetic & comparison ##
274

275
isequal(x::Ptr, y::Ptr) = (x === y)
1✔
276
isless(x::Ptr{T}, y::Ptr{T}) where {T} = x < y
1✔
277

278
==(x::Ptr, y::Ptr) = UInt(x) == UInt(y)
600,904,910✔
279
<(x::Ptr,  y::Ptr) = UInt(x) < UInt(y)
47,980,213✔
280
-(x::Ptr,  y::Ptr) = UInt(x) - UInt(y)
3,640,848✔
281

282
+(x::Ptr, y::Integer) = oftype(x, add_ptr(UInt(x), (y % UInt) % UInt))
874,541,243✔
283
-(x::Ptr, y::Integer) = oftype(x, sub_ptr(UInt(x), (y % UInt) % UInt))
332,083,217✔
284
+(x::Integer, y::Ptr) = y + x
1✔
285

286
unsigned(x::Ptr) = UInt(x)
×
287
signed(x::Ptr) = Int(x)
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc