Skip to content

Commit 2c944ff

Browse files
committed
Implement some operations for LLVMPtr.
1 parent 924dea1 commit 2c944ff

File tree

2 files changed

+88
-12
lines changed

2 files changed

+88
-12
lines changed

src/interop/pointer.jl

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,33 @@ Base.unsafe_load(ptr::Core.LLVMPtr, i::Integer=1, align::Val=Val(1)) =
9494

9595
Base.unsafe_store!(ptr::Core.LLVMPtr{T}, x, i::Integer=1, align::Val=Val(1)) where {T} =
9696
pointerset(ptr, convert(T, x), Int(i), align)
97+
98+
99+
# pointer operations
100+
101+
# NOTE: this is type-pirating; move functionality upstream
102+
103+
LLVMPtr{T,A}(x::Union{Int,UInt,Ptr}) where {T,A} = reinterpret(LLVMPtr{T,A}, x)
104+
LLVMPtr{T,A}() where {T,A} = LLVMPtr{T,A}(0)
105+
106+
# conversions from and to integers
107+
Base.UInt(x::LLVMPtr) = reinterpret(UInt, x)
108+
Base.Int(x::LLVMPtr) = reinterpret(Int, x)
109+
Base.convert(::Type{LLVMPtr{T,A}}, x::Union{Int,UInt}) where {T,A} =
110+
reinterpret(LLVMPtr{T,A}, x)
111+
112+
Base.isequal(x::LLVMPtr, y::LLVMPtr) = (x === y)
113+
Base.isless(x::LLVMPtr{T,A}, y::LLVMPtr{T,A}) where {T,A} = x < y
114+
115+
Base.:(==)(x::LLVMPtr{<:Any,A}, y::LLVMPtr{<:Any,A}) where {A} = UInt(x) == UInt(y)
116+
Base.:(<)(x::LLVMPtr{<:Any,A}, y::LLVMPtr{<:Any,A}) where {A} = UInt(x) < UInt(y)
117+
Base.:(==)(x::LLVMPtr, y::LLVMPtr) = false
118+
119+
Base.:(-)(x::LLVMPtr{<:Any,A}, y::LLVMPtr{<:Any,A}) where {A} = UInt(x) - UInt(y)
120+
121+
Base.:(+)(x::LLVMPtr, y::Integer) = oftype(x, Base.add_ptr(UInt(x), (y % UInt) % UInt))
122+
Base.:(-)(x::LLVMPtr, y::Integer) = oftype(x, Base.sub_ptr(UInt(x), (y % UInt) % UInt))
123+
Base.:(+)(x::Integer, y::LLVMPtr) = y + x
124+
125+
Base.unsigned(x::LLVMPtr) = UInt(x)
126+
Base.signed(x::LLVMPtr) = Int(x)

test/interop.jl

Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -129,18 +129,64 @@ end
129129

130130
VERSION >= v"1.5-" && @testset "pointer" begin
131131

132-
a = Int64[1]
133-
ptr = reinterpret(Core.LLVMPtr{Int64,0}, pointer(a))
134-
@test unsafe_load(ptr) == 1
135-
unsafe_store!(ptr, 2)
136-
@test unsafe_load(ptr) == 2
137-
138-
ir = sprint(io->code_llvm(io, unsafe_load, Tuple{typeof(ptr)}))
139-
@test contains(ir, r"@julia_unsafe_load_\d+\(i8\*\)")
140-
@test contains(ir, r"load i64, i64\* %\d+, align 1")
141-
142-
ir = sprint(io->code_llvm(io, unsafe_load, Tuple{typeof(ptr), Int, Val{4}}))
143-
@test contains(ir, r"load i64, i64\* %\d+, align 4")
132+
using Core: LLVMPtr
133+
134+
@testset "pointer operations" begin
135+
a = LLVMPtr{Int,0}(0)
136+
b = LLVMPtr{Int,0}(1)
137+
c = LLVMPtr{UInt,0}(0)
138+
d = LLVMPtr{UInt,0}(1)
139+
e = LLVMPtr{Int,1}(0)
140+
f = LLVMPtr{Int,1}(1)
141+
142+
@test UInt(a) == 0
143+
@test UInt(f) == 1
144+
145+
@test isequal(a,a)
146+
@test !isequal(a,b)
147+
@test !isequal(a,c)
148+
@test !isequal(a,d)
149+
@test !isequal(a,e)
150+
@test !isequal(a,f)
151+
152+
@test a == a
153+
@test a != b
154+
@test a == c
155+
@test a != d
156+
@test a != e
157+
@test a != f
158+
159+
@test a < b
160+
@test a < d
161+
@test_throws MethodError a < f
162+
163+
@test b - a == 1
164+
@test d - a == 1
165+
@test_throws MethodError f - a
166+
167+
@test a + 1 == b
168+
@test c + 1 == d
169+
@test e + 1 == f
170+
171+
@test b - 1 == a
172+
@test d - 1 == c
173+
@test f - 1 == e
174+
end
175+
176+
@testset "unsafe_load" begin
177+
a = Int64[1]
178+
ptr = reinterpret(Core.LLVMPtr{Int64,0}, pointer(a))
179+
@test unsafe_load(ptr) == 1
180+
unsafe_store!(ptr, 2)
181+
@test unsafe_load(ptr) == 2
182+
183+
ir = sprint(io->code_llvm(io, unsafe_load, Tuple{typeof(ptr)}))
184+
@test contains(ir, r"@julia_unsafe_load_\d+\(i8\*\)")
185+
@test contains(ir, r"load i64, i64\* %\d+, align 1")
186+
187+
ir = sprint(io->code_llvm(io, unsafe_load, Tuple{typeof(ptr), Int, Val{4}}))
188+
@test contains(ir, r"load i64, i64\* %\d+, align 4")
189+
end
144190

145191
@testset "reinterpret(Nothing, nothing)" begin
146192
ptr = reinterpret(Core.LLVMPtr{Nothing,0}, C_NULL)

0 commit comments

Comments
 (0)