Skip to content

Commit 1d3aa0d

Browse files
author
Jakob Nybo Andersen
committed
Remove unsafe_wrap
1 parent c62a395 commit 1d3aa0d

5 files changed

Lines changed: 19 additions & 23 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,16 @@ not be mentioned here, because they do not impact how the package is to be used.
88
### Breaking changes
99
* Removed the `Unsafe` trait type:
1010
- Instead of `MutableMemoryView(::Unsafe, ::MemoryView)`, use
11-
`unsafe_wrap(MutableMemoryView, ::MemoryView)`
11+
`unsafe_from_parts(::MemoryRef, ::Int)`
1212
- Using the inner constructor `MemoryView{T, M}(::Unsafe, ::MemoryRef{T}, ::Int)`
1313
was never documented API and is now removed.
1414

1515
* `MemoryView(::SubArray)` now accepts fewer subarray types. However, it is unlikely
1616
that any instance that is now no longer accepted worked previously, so it is
17-
unlikely to be breaking in practice.
17+
unlikely to be breaking in practice.
18+
19+
## Other
20+
* `parentindices` now works correctly for zero-sized structs.
1821

1922
## 0.3.5
2023
* Add method `MemoryKind{::Type{<:MemoryView}}`

src/MemoryViews.jl

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ julia> view = unsafe_from_parts(ref, 3)
111111
3
112112
```
113113
"""
114-
function unsafe_from_parts(ref::MemoryRef{T}, len::Int) where {T}
115-
return MemoryView{T, Mutable}(unsafe, ref, len)
114+
function unsafe_from_parts(ref::MemoryRef, len::Int)
115+
return unsafe_new_memoryview(Mutable, ref, len)
116116
end
117117

118118
_get_mutability(::MemoryView{T, M}) where {T, M} = M
@@ -123,17 +123,6 @@ function ImmutableMemoryView(x::MemoryView)
123123
return unsafe_new_memoryview(Immutable, x.ref, x.len)
124124
end
125125

126-
"""
127-
unsafe_wrap(MutableMemoryView, x::MemoryView)
128-
129-
Convert a memory view into a mutable memory view.
130-
Note that it may cause undefined behaviour, if supposedly immutable data
131-
is observed to be mutated.
132-
"""
133-
function Base.unsafe_wrap(::Type{MutableMemoryView}, x::MemoryView{T}) where {T}
134-
return unsafe_new_memoryview(Mutable, x.ref, x.len)
135-
end
136-
137126
# Constructors that allows users to specify eltype explicitly, e.g.
138127
# ImmutableMemoryView{UInt8}([0x01])
139128
# With mutability specified

src/basic.jl

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ end
3030
function Base.parentindices(x::MemoryView)
3131
elz = Base.elsize(x)
3232
return if iszero(elz)
33-
(1:(x.len),)
33+
offset = Int(x.ref.ptr_or_offset)
34+
((1 + offset):(x.len + offset),)
3435
else
3536
byte_offset = pointer(x.ref) - pointer(x.ref.mem)
3637
elem_offset = div(byte_offset % UInt, elz % UInt) % Int
@@ -112,21 +113,21 @@ function Base.getindex(v::MemoryView{T, M}, idx::AbstractUnitRange) where {T, M}
112113
isempty(idx) && return unsafe_new_memoryview(M, memoryref(v.ref.mem), 0)
113114
@boundscheck checkbounds(v, idx)
114115
newref = @inbounds memoryref(v.ref, Int(first(idx))::Int)
115-
return typeof(v)(unsafe, newref, Int(length(idx))::Int)
116+
return unsafe_new_memoryview(M, newref, Int(length(idx))::Int)
116117
end
117118

118-
function Base.getindex(v::MemoryView, idx::UnitRange{UInt})
119-
isempty(idx) && return typeof(v)(unsafe, memoryref(v.ref.mem), 0)
119+
function Base.getindex(v::MemoryView{T, M}, idx::UnitRange{UInt}) where {T, M}
120+
isempty(idx) && return unsafe_new_memoryview(M, v.ref, 0)
120121
@boundscheck checkbounds(v, idx)
121122
newref = @inbounds memoryref(v.ref, first(idx) % Int)
122-
return typeof(v)(unsafe, newref, length(idx) % Int)
123+
return unsafe_new_memoryview(M, newref, length(idx) % Int)
123124
end
124125

125126
# Faster method, because we don't need to create a new memoryref, and also don't
126127
# need to handle the empty case.
127-
function Base.getindex(v::MemoryView, idx::Base.OneTo)
128+
function Base.getindex(v::MemoryView{T, M}, idx::Base.OneTo) where {T, M}
128129
@boundscheck checkbounds(v, idx)
129-
return typeof(v)(unsafe, v.ref, last(idx))
130+
return unsafe_new_memoryview(M, v.ref, last(idx))
130131
end
131132

132133
Base.getindex(v::MemoryView, ::Colon) = v

src/experimental.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ If `v` is empty or already aligned, `a` will be empty.
9393
If no elements of `v` is aligned, `b` will be empty and `a` will be equal to `v`.
9494
The element type of `v` must be a bitstype.
9595
96+
!!! warning
97+
When using this function, make sure to `GC.@preserve v`, to make sure Julia
98+
does not move `v` in memory.
9699
97100
# Examples:
98101
```

test/runtests.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ MUT_BACKINGS = Any[
4141
@testset "Unsafe mutability" begin
4242
v = [1.0, 2.0, 3.0]
4343
m = ImmutableMemoryView(v)
44-
m2 = unsafe_wrap(MutableMemoryView, m)
44+
m2 = unsafe_from_parts(m.ref, 3)
4545
m2[2] = 5.0
4646
@test v == [1.0, 5.0, 3.0]
4747
end

0 commit comments

Comments
 (0)