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

JuliaLang / julia / #37999

02 Feb 2025 07:22AM UTC coverage: 17.218% (-8.3%) from 25.515%
#37999

push

local

web-flow
bpart: Start tracking backedges for bindings (#57213)

This PR adds limited backedge support for Bindings. There are two
classes of bindings that get backedges:

1. Cross-module `GlobalRef` bindings (new in this PR)
2. Any globals accesses through intrinsics (i.e. those with forward
edges from #57009)

This is a time/space trade-off for invalidation. As a result of the
first category, invalidating a binding now only needs to scan all the
methods defined in the same module as the binding. At the same time, it
is anticipated that most binding references are to bindings in the same
module, keeping the list of bindings that need explicit (back)edges
small.

7 of 30 new or added lines in 3 files covered. (23.33%)

4235 existing lines in 124 files now uncovered.

7882 of 45779 relevant lines covered (17.22%)

98289.89 hits per line

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

2.42
/stdlib/Sockets/src/IPAddr.jl
1
# This file is a part of Julia. License is MIT: https://julialang.org/license
2

3
"""
4
    IPAddr
5

6
Abstract supertype for IP addresses. [`IPv4`](@ref) and [`IPv6`](@ref) are subtypes of this.
7
"""
8
abstract type IPAddr end
9

10
Base.isless(a::T, b::T) where {T<:IPAddr} = isless(a.host, b.host)
×
11
(dt::Type{<:Integer})(ip::IPAddr) = dt(ip.host)::dt
×
12

13
# Allow IP addresses to broadcast as unwrapped scalars
14
Base.Broadcast.broadcastable(ip::IPAddr) = Ref(ip)
×
15

16
struct IPv4 <: IPAddr
17
    host::UInt32
UNCOV
18
    IPv4(host::UInt32) = new(host)
×
19
    IPv4(a::UInt8,b::UInt8,c::UInt8,d::UInt8) = new(UInt32(a)<<24|
×
20
                                                    UInt32(b)<<16|
21
                                                    UInt32(c)<<8|
22
                                                    d)
23
    function IPv4(a::Integer,b::Integer,c::Integer,d::Integer)
×
24
        if !(0<=a<=255 && 0<=b<=255 && 0<=c<=255 && 0<=d<=255)
×
25
            throw(ArgumentError("IPv4 field out of range (must be 0-255)"))
×
26
        end
27
        IPv4(UInt8(a),UInt8(b),UInt8(c),UInt8(d))
×
28
    end
29
end
30

31
"""
32
    IPv4(host::Integer) -> IPv4
33

34
Return an IPv4 object from IP address `host` formatted as an [`Integer`](@ref).
35

36
# Examples
37
```jldoctest
38
julia> IPv4(3223256218)
39
ip"192.30.252.154"
40
```
41
"""
UNCOV
42
function IPv4(host::Integer)
×
UNCOV
43
    if host < 0
×
44
        throw(ArgumentError("IPv4 address must be positive"))
×
UNCOV
45
    elseif typemax(typeof(host)) > typemax(UInt32) && host > typemax(UInt32)
×
46
        throw(ArgumentError("IPv4 address must fit within 32 bits"))
×
47
    else
UNCOV
48
        return IPv4(UInt32(host))
×
49
    end
50
end
51

52
"""
53
    IPv4(str::AbstractString) -> IPv4
54

55
Parse an IPv4 address string into an `IPv4` object.
56

57
# Examples
58
```jldoctest
59
julia> IPv4("127.0.0.1")
60
ip"127.0.0.1"
61
```
62
"""
63
IPv4(str::AbstractString) = parse(IPv4, str)
5✔
64

65
show(io::IO,ip::IPv4) = print(io,"ip\"",ip,"\"")
×
UNCOV
66
print(io::IO,ip::IPv4) = print(io,string((ip.host&(0xFF000000))>>24),".",
×
67
                                  string((ip.host&(0xFF0000))>>16),".",
68
                                  string((ip.host&(0xFF00))>>8),".",
69
                                  string(ip.host&0xFF))
70

71
struct IPv6 <: IPAddr
72
    host::UInt128
UNCOV
73
    IPv6(host::UInt128) = new(host)
×
74
    IPv6(a::UInt16,b::UInt16,c::UInt16,d::UInt16,
×
75
     e::UInt16,f::UInt16,g::UInt16,h::UInt16) = new(UInt128(a)<<(7*16)|
76
                            UInt128(b)<<(6*16)|
77
                            UInt128(c)<<(5*16)|
78
                            UInt128(d)<<(4*16)|
79
                            UInt128(e)<<(3*16)|
80
                            UInt128(f)<<(2*16)|
81
                            UInt128(g)<<(1*16)|
82
                            h)
83
    function IPv6(a::Integer,b::Integer,c::Integer,d::Integer,
×
84
          e::Integer,f::Integer,g::Integer,h::Integer)
85
        if !(0<=a<=0xFFFF && 0<=b<=0xFFFF && 0<=c<=0xFFFF && 0<=d<=0xFFFF &&
×
86
             0<=e<=0xFFFF && 0<=f<=0xFFFF && 0<=g<=0xFFFF && 0<=h<=0xFFFF)
87
            throw(ArgumentError("IPv6 field out of range (must be 0-65535)"))
×
88
        end
89
        IPv6(UInt16(a),UInt16(b),UInt16(c),UInt16(d),
×
90
             UInt16(e),UInt16(f),UInt16(g),UInt16(h))
91
    end
92
end
93

94
"""
95
    IPv6(host::Integer) -> IPv6
96

97
Return an IPv6 object from IP address `host` formatted as an [`Integer`](@ref).
98

99
# Examples
100
```jldoctest
101
julia> IPv6(3223256218)
102
ip"::c01e:fc9a"
103
```
104
"""
105
function IPv6(host::Integer)
×
106
    if host < 0
×
107
        throw(ArgumentError("IPv6 address must be positive"))
×
108
        # We allow passing bigger integer types, but need to be careful to avoid overflow
109
        # Let's hope promotion rules are sensible
110
    elseif typemax(typeof(host)) > typemax(UInt128) && host > typemax(UInt128)
×
111
        throw(ArgumentError("IPv6 address must fit within 128 bits"))
×
112
    else
113
        return IPv6(UInt128(host))
×
114
    end
115
end
116

117
"""
118
    IPv6(str::AbstractString) -> IPv6
119

120
Parse an IPv6 address string into an `IPv6` object.
121

122
# Examples
123
```jldoctest
124
julia> IPv6("::1")
125
ip"::1"
126
```
127
"""
128
IPv6(str::AbstractString) = parse(IPv6, str)
×
129

130
# Suppress leading '0's and "0x"
131
print_ipv6_field(io,field::UInt16) = print(io,string(field, base = 16))
×
132

133
print_ipv6_field(io,ip,i) = print_ipv6_field(io,ipv6_field(ip,i))
×
UNCOV
134
function ipv6_field(ip::IPv6,i)
×
135
    if i < 0 || i > 7
×
136
        throw(BoundsError())
×
137
    end
138
    UInt16((ip.host&(UInt128(0xFFFF)<<(i*16))) >> (i*16))
×
139
end
140

141
show(io::IO, ip::IPv6) = print(io,"ip\"",ip,"\"")
×
142
# RFC 5952 compliant show function
143
# https://tools.ietf.org/html/rfc5952
144
function print(io::IO,ip::IPv6)
×
145
    i = 8
×
146
    m = 0
×
147
    longest_sub_i = -1
×
148
    while i!=0
×
149
        i-=1
×
150
        field = ipv6_field(ip,i)
×
151
        if field == 0 && longest_sub_i == -1
×
152
            # Find longest subsequence of 0
153
            longest_sub_i,j,m,c = i,i,1,1
×
154
            while j != 0
×
155
                j-=1
×
156
                if ipv6_field(ip,j) == 0
×
157
                    c += 1
×
158
                else
159
                    c = 0
×
160
                end
161
                if c > m
×
162
                    if j+c != longest_sub_i+1
×
163
                        longest_sub_i = j+c-1
×
164
                    end
165
                    m = c
×
166
                end
167
            end
×
168
            # Prevent single 0 from contracting to :: as required
169
            if m == 1
×
170
                longest_sub_i = 9
×
171
            end
172
        end
173
        if i == longest_sub_i
×
174
            print(io,":")
×
175
            i -= m-1
×
176
            if i == 0
×
177
                print(io,":")
×
178
                break
×
179
            end
180
        else
181
            if i != 7
×
182
                print(io,":")
×
183
            end
184
            print_ipv6_field(io,field)
×
185
        end
186
    end
×
187
end
188

189
# Parsing
190

191
const ipv4_leading_zero_error = """
192
Leading zeros in IPv4 addresses are disallowed due to ambiguity.
193
If the address is in octal or hexadecimal, convert it to decimal, otherwise remove the leading zero.
194
"""
195

UNCOV
196
function parse(::Type{IPv4}, str::AbstractString)
×
UNCOV
197
    fields = split(str,'.')
×
198
    i = 1
×
199
    ret = 0
×
UNCOV
200
    for f in fields
×
UNCOV
201
        if isempty(f)
×
202
            throw(ArgumentError("empty field in IPv4 address"))
×
203
        end
UNCOV
204
        if length(f) > 1 && f[1] == '0'
×
205
            throw(ArgumentError(ipv4_leading_zero_error))
×
206
        else
UNCOV
207
            r = parse(Int, f, base = 10)
×
208
        end
UNCOV
209
        if i != length(fields)
×
UNCOV
210
            if r < 0 || r > 255
×
211
                throw(ArgumentError("IPv4 field out of range (must be 0-255)"))
×
212
            end
UNCOV
213
            ret |= UInt32(r) << ((4-i)*8)
×
214
        else
UNCOV
215
            if r > ((UInt64(1)<<((5-length(fields))*8))-1)
×
216
                throw(ArgumentError("IPv4 field too large"))
×
217
            end
UNCOV
218
            ret |= r
×
219
        end
UNCOV
220
        i+=1
×
UNCOV
221
    end
×
UNCOV
222
    IPv4(ret)
×
223
end
224

225
function parseipv6fields(fields,num_fields)
226
    if length(fields) > num_fields
×
227
        throw(ArgumentError("too many fields in IPv6 address"))
×
228
    end
229
    cf = 7
×
230
    ret = UInt128(0)
×
231
    for f in fields
×
232
        if isempty(f)
×
233
            # ::abc:... and ..:abc::
234
            if cf != 7 && cf != 0
×
235
                cf -= num_fields-length(fields)
×
236
            end
237
            cf -= 1
×
238
            continue
×
239
        end
240
        ret |= UInt128(parse(Int, f, base = 16))<<(cf*16)
×
241
        cf -= 1
×
242
    end
×
243
    ret
×
244
end
245
parseipv6fields(fields) = parseipv6fields(fields,8)
×
246

247
function parse(::Type{IPv6}, str::AbstractString)
×
248
    fields = split(str,':')
×
249
    if length(fields) > 8
×
250
        throw(ArgumentError("too many fields in IPv6 address"))
×
251
    elseif length(fields) == 8
×
252
        return IPv6(parseipv6fields(fields))
×
253
    elseif in('.',fields[end])
×
254
        return IPv6((parseipv6fields(fields[1:(end-1)],6))
×
255
            | parse(IPv4, fields[end]).host )
256
    else
257
        return IPv6(parseipv6fields(fields))
×
258
    end
259
end
260

261
#
262
# This supports IP addresses in the common dot (IPv4) or colon (IPv6)
263
# separated formats. Most other common formats use a standard integer encoding
264
# of the appropriate size and should use the appropriate constructor
265
#
266

267
function parse(::Type{IPAddr}, str::AbstractString)
268
    if ':' in str
8✔
269
        return parse(IPv6, str)
×
270
    else
271
        return parse(IPv4, str)
8✔
272
    end
273
end
274

275
"""
276
    @ip_str str -> IPAddr
277

278
Parse `str` as an IP address.
279

280
# Examples
281
```jldoctest
282
julia> ip"127.0.0.1"
283
ip"127.0.0.1"
284

285
julia> @ip_str "2001:db8:0:0:0:0:2:1"
286
ip"2001:db8::2:1"
287
```
288
"""
289
macro ip_str(str)
290
    return parse(IPAddr, str)
291
end
292

293
struct InetAddr{T<:IPAddr}
294
    host::T
×
295
    port::UInt16
296
end
297

298
"""
299
    InetAddr(ip::IPAddr, port) -> InetAddr
300

301
Return an `InetAddr` object from ip address `ip` and port number `port`.
302

303
# Examples
304
```jldoctest
305
julia> Sockets.InetAddr(ip"127.0.0.1", 8000)
306
Sockets.InetAddr{IPv4}(ip"127.0.0.1", 8000)
307
```
308
"""
309
InetAddr(ip::IPAddr, port) = InetAddr{typeof(ip)}(ip, port)
×
310

311
"""
312
    InetAddr(str::AbstractString, port) -> InetAddr
313

314
Return an `InetAddr` object from ip address `str` formatted as [`AbstractString`](@ref)
315
and port number `port`.
316

317
!!! compat "Julia 1.3"
318
    This constructor requires at least Julia 1.3.
319

320
# Examples
321
```jldoctest
322
julia> Sockets.InetAddr("127.0.0.1", 8000)
323
Sockets.InetAddr{IPv4}(ip"127.0.0.1", 8000)
324
```
325
"""
326
InetAddr(str::AbstractString, port) = InetAddr(parse(IPAddr, str), port)
×
327

328
function show(io::IO, addr::InetAddr)
×
329
    show(io, typeof(addr))
×
330
    print(io, "(")
×
331
    show(io, addr.host)
×
332
    print(io, ", ", Int(addr.port), ")")
×
333
end
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

© 2025 Coveralls, Inc