Skip to content

Commit 8946f1f

Browse files
committed
More robust constructors
* Use cconvert instead of accessing the internal .ref field of Array. This is still not entirely stable API, but hopefully better * Do not use inbounds for substring of AbstractString, because the implementor of the AbstractString may lie about the codeunits, and I'm not confident the substring constructor will detect it * Use ncodeunits instead of reading the ncodeunit fields of substrings * Be slightly more conservative in what subarrays the constructor accepts.
1 parent dd53047 commit 8946f1f

File tree

1 file changed

+16
-9
lines changed

1 file changed

+16
-9
lines changed

src/construction.jl

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ MemoryView(v::MemoryView) = v
44
MemoryKind(::Type{<:Array{T}}) where {T} = IsMemory(MutableMemoryView{T})
55
MemoryKind(::Type{<:Memory{T}}) where {T} = IsMemory(MutableMemoryView{T})
66
MemoryView(A::Memory{T}) where {T} = MutableMemoryView{T}(unsafe, memoryref(A), length(A))
7-
MemoryView(A::Array{T}) where {T} = MutableMemoryView{T}(unsafe, A.ref, length(A))
7+
MemoryView(A::Array{T}) where {T} = MutableMemoryView{T}(unsafe, Base.cconvert(Ptr, A), length(A))
88

99
# Strings
1010
MemoryView(s::String) = ImmutableMemoryView(unsafe_wrap(Memory{UInt8}, s))
1111
function MemoryView(s::SubString)
1212
v = ImmutableMemoryView(parent(s))
13-
return @inbounds v[(s.offset + 1):(s.offset + s.ncodeunits)]
13+
return v[(s.offset + 1):(s.offset + ncodeunits(s))]
1414
end
1515

1616
# Special implementation for SubString{String}, which we can guarantee never
@@ -19,7 +19,7 @@ function MemoryView(s::SubString{String})
1919
memview = MemoryView(parent(s))
2020
isempty(memview) && return memview
2121
newref = @inbounds memoryref(memview.ref, s.offset + 1)
22-
return ImmutableMemoryView{UInt8}(unsafe, newref, s.ncodeunits)
22+
return ImmutableMemoryView{UInt8}(unsafe, newref, ncodeunits(s))
2323
end
2424

2525
# CodeUnits are semantically IsMemory, but only if the underlying string
@@ -33,15 +33,22 @@ end
3333
MemoryView(s::Base.CodeUnits) = MemoryView(s.s)
3434

3535
# SubArrays
36-
# TODO: Identical to FastContiguousSubArray in Base
36+
# This is quite tricky, because the indexing can be:
37+
# * <: AbstractUnitRange
38+
# * StepRange, with step == 1
39+
# * Integer (zero-dimensional along one axis)
40+
41+
# It can also be multidimensional, but if so, all axes but the last one
42+
# must span the entire dimension.
43+
# And if so, we would need to compute the linear indices.
44+
45+
# For now, I've only accepted 1-D views.
3746
const ContiguousSubArray = SubArray{
38-
T,
39-
N,
40-
P,
41-
<:Union{Tuple{Vararg{Real}}, Tuple{AbstractUnitRange, Vararg{Any}}},
42-
} where {T, N, P}
47+
T, N, P, I, true,
48+
} where {T, N, P, I <: Union{Tuple{Integer}, Tuple{AbstractUnitRange}}}
4349

4450
MemoryKind(::Type{<:ContiguousSubArray{T, N, P}}) where {T, N, P} = MemoryKind(P)
51+
4552
function MemoryView(s::ContiguousSubArray{T, N, P}) where {T, N, P}
4653
memview = MemoryView(parent(s)::P)
4754
inds = only(parentindices(s))

0 commit comments

Comments
 (0)