Line | Exclusive | Inclusive | Code |
---|---|---|---|
1 | # This file is a part of Julia. License is MIT: https://julialang.org/license | ||
2 | |||
3 | # commented-out definitions are implemented in C | ||
4 | |||
5 | #abstract type Any <: Any end | ||
6 | #abstract type Type{T} end | ||
7 | |||
8 | #abstract type Vararg{T} end | ||
9 | |||
10 | #mutable struct Symbol | ||
11 | # #opaque | ||
12 | #end | ||
13 | |||
14 | #mutable struct TypeName | ||
15 | # name::Symbol | ||
16 | #end | ||
17 | |||
18 | #mutable struct DataType <: Type | ||
19 | # name::TypeName | ||
20 | # super::Type | ||
21 | # parameters::Tuple | ||
22 | # names::Tuple | ||
23 | # types::Tuple | ||
24 | # ctor | ||
25 | # instance | ||
26 | # size::Int32 | ||
27 | # abstract::Bool | ||
28 | # mutable::Bool | ||
29 | # pointerfree::Bool | ||
30 | #end | ||
31 | |||
32 | #struct Union <: Type | ||
33 | # a | ||
34 | # b | ||
35 | #end | ||
36 | |||
37 | #mutable struct TypeVar | ||
38 | # name::Symbol | ||
39 | # lb::Type | ||
40 | # ub::Type | ||
41 | #end | ||
42 | |||
43 | #struct UnionAll | ||
44 | # var::TypeVar | ||
45 | # body | ||
46 | #end | ||
47 | |||
48 | #struct Nothing | ||
49 | #end | ||
50 | #const nothing = Nothing() | ||
51 | |||
52 | #abstract type AbstractArray{T,N} end | ||
53 | #abstract type DenseArray{T,N} <: AbstractArray{T,N} end | ||
54 | |||
55 | #mutable struct Array{T,N} <: DenseArray{T,N} | ||
56 | #end | ||
57 | |||
58 | #mutable struct Module | ||
59 | # name::Symbol | ||
60 | #end | ||
61 | |||
62 | #mutable struct Method | ||
63 | #end | ||
64 | |||
65 | #mutable struct MethodInstance | ||
66 | #end | ||
67 | |||
68 | #mutable struct CodeInfo | ||
69 | #end | ||
70 | |||
71 | #mutable struct TypeMapLevel | ||
72 | #end | ||
73 | |||
74 | #mutable struct TypeMapEntry | ||
75 | #end | ||
76 | |||
77 | #abstract type Ref{T} end | ||
78 | #primitive type Ptr{T} <: Ref{T} {32|64} end | ||
79 | |||
80 | # types for the front end | ||
81 | |||
82 | #mutable struct Expr | ||
83 | # head::Symbol | ||
84 | # args::Array{Any,1} | ||
85 | #end | ||
86 | |||
87 | #struct LineNumberNode | ||
88 | # line::Int | ||
89 | # file::Any # nominally Union{Symbol,Nothing} | ||
90 | #end | ||
91 | |||
92 | #struct LineInfoNode | ||
93 | # mod::Module | ||
94 | # method::Symbol | ||
95 | # file::Symbol | ||
96 | # line::Int | ||
97 | # inlined_at::Int | ||
98 | #end | ||
99 | |||
100 | #struct GotoNode | ||
101 | # label::Int | ||
102 | #end | ||
103 | |||
104 | #struct PiNode | ||
105 | # val | ||
106 | # typ | ||
107 | #end | ||
108 | |||
109 | #struct PhiNode | ||
110 | # edges::Vector{Any} | ||
111 | # values::Vector{Any} | ||
112 | #end | ||
113 | |||
114 | #struct PhiCNode | ||
115 | # values::Vector{Any} | ||
116 | #end | ||
117 | |||
118 | #struct UpsilonNode | ||
119 | # val | ||
120 | #end | ||
121 | |||
122 | #struct QuoteNode | ||
123 | # value | ||
124 | #end | ||
125 | |||
126 | #struct GlobalRef | ||
127 | # mod::Module | ||
128 | # name::Symbol | ||
129 | #end | ||
130 | |||
131 | #mutable struct Task | ||
132 | # parent::Task | ||
133 | # storage::Any | ||
134 | # state::Symbol | ||
135 | # donenotify::Any | ||
136 | # result::Any | ||
137 | # exception::Any | ||
138 | # backtrace::Any | ||
139 | # logstate::Any | ||
140 | # code::Any | ||
141 | #end | ||
142 | |||
143 | export | ||
144 | # key types | ||
145 | Any, DataType, Vararg, NTuple, | ||
146 | Tuple, Type, UnionAll, TypeVar, Union, Nothing, Cvoid, | ||
147 | AbstractArray, DenseArray, NamedTuple, | ||
148 | # special objects | ||
149 | Function, Method, | ||
150 | Module, Symbol, Task, Array, UndefInitializer, undef, WeakRef, VecElement, | ||
151 | # numeric types | ||
152 | Number, Real, Integer, Bool, Ref, Ptr, | ||
153 | AbstractFloat, Float16, Float32, Float64, | ||
154 | Signed, Int, Int8, Int16, Int32, Int64, Int128, | ||
155 | Unsigned, UInt, UInt8, UInt16, UInt32, UInt64, UInt128, | ||
156 | # string types | ||
157 | AbstractChar, Char, AbstractString, String, IO, | ||
158 | # errors | ||
159 | ErrorException, BoundsError, DivideError, DomainError, Exception, | ||
160 | InterruptException, InexactError, OutOfMemoryError, ReadOnlyMemoryError, | ||
161 | OverflowError, StackOverflowError, SegmentationFault, UndefRefError, UndefVarError, | ||
162 | TypeError, ArgumentError, MethodError, AssertionError, LoadError, InitError, | ||
163 | UndefKeywordError, | ||
164 | # AST representation | ||
165 | Expr, QuoteNode, LineNumberNode, GlobalRef, | ||
166 | # object model functions | ||
167 | fieldtype, getfield, setfield!, nfields, throw, tuple, ===, isdefined, eval, ifelse, | ||
168 | # sizeof # not exported, to avoid conflicting with Base.sizeof | ||
169 | # type reflection | ||
170 | <:, typeof, isa, typeassert, | ||
171 | # method reflection | ||
172 | applicable, invoke, | ||
173 | # constants | ||
174 | nothing, Main | ||
175 | |||
176 | const getproperty = getfield | ||
177 | const setproperty! = setfield! | ||
178 | |||
179 | abstract type Number end | ||
180 | abstract type Real <: Number end | ||
181 | abstract type AbstractFloat <: Real end | ||
182 | abstract type Integer <: Real end | ||
183 | abstract type Signed <: Integer end | ||
184 | abstract type Unsigned <: Integer end | ||
185 | |||
186 | primitive type Float16 <: AbstractFloat 16 end | ||
187 | primitive type Float32 <: AbstractFloat 32 end | ||
188 | primitive type Float64 <: AbstractFloat 64 end | ||
189 | |||
190 | #primitive type Bool <: Integer 8 end | ||
191 | abstract type AbstractChar end | ||
192 | primitive type Char <: AbstractChar 32 end | ||
193 | |||
194 | primitive type Int8 <: Signed 8 end | ||
195 | #primitive type UInt8 <: Unsigned 8 end | ||
196 | primitive type Int16 <: Signed 16 end | ||
197 | primitive type UInt16 <: Unsigned 16 end | ||
198 | #primitive type Int32 <: Signed 32 end | ||
199 | #primitive type UInt32 <: Unsigned 32 end | ||
200 | #primitive type Int64 <: Signed 64 end | ||
201 | #primitive type UInt64 <: Unsigned 64 end | ||
202 | primitive type Int128 <: Signed 128 end | ||
203 | primitive type UInt128 <: Unsigned 128 end | ||
204 | |||
205 | if Int === Int64 | ||
206 | const UInt = UInt64 | ||
207 | else | ||
208 | const UInt = UInt32 | ||
209 | end | ||
210 | |||
211 | function Typeof end | ||
212 | ccall(:jl_toplevel_eval_in, Any, (Any, Any), | ||
213 | Core, quote | ||
214 | (f::typeof(Typeof))(x) = ($(_expr(:meta,:nospecialize,:x)); isa(x,Type) ? Type{x} : typeof(x)) | ||
215 | end) | ||
216 | |||
217 | macro nospecialize(x) | ||
218 | _expr(:meta, :nospecialize, x) | ||
219 | end | ||
220 | |||
221 | Expr(@nospecialize args...) = _expr(args...) | ||
222 | |||
223 | abstract type Exception end | ||
224 | struct ErrorException <: Exception | ||
225 | msg::AbstractString | ||
226 | end | ||
227 | |||
228 | macro _inline_meta() | ||
229 | Expr(:meta, :inline) | ||
230 | end | ||
231 | |||
232 | macro _noinline_meta() | ||
233 | Expr(:meta, :noinline) | ||
234 | end | ||
235 | |||
236 | struct BoundsError <: Exception | ||
237 | a::Any | ||
238 | i::Any | ||
239 | BoundsError() = new() | ||
240 | BoundsError(@nospecialize(a)) = (@_noinline_meta; new(a)) | ||
241 | BoundsError(@nospecialize(a), i) = (@_noinline_meta; new(a,i)) | ||
242 | end | ||
243 | struct DivideError <: Exception end | ||
244 | struct OutOfMemoryError <: Exception end | ||
245 | struct ReadOnlyMemoryError <: Exception end | ||
246 | struct SegmentationFault <: Exception end | ||
247 | struct StackOverflowError <: Exception end | ||
248 | struct UndefRefError <: Exception end | ||
249 | struct UndefVarError <: Exception | ||
250 | var::Symbol | ||
251 | end | ||
252 | struct InterruptException <: Exception end | ||
253 | struct DomainError <: Exception | ||
254 | val | ||
255 | msg::AbstractString | ||
256 | DomainError(@nospecialize(val)) = (@_noinline_meta; new(val, "")) | ||
257 | DomainError(@nospecialize(val), @nospecialize(msg)) = (@_noinline_meta; new(val, msg)) | ||
258 | end | ||
259 | struct TypeError <: Exception | ||
260 | func::Symbol | ||
261 | context::AbstractString | ||
262 | expected::Type | ||
263 | got | ||
264 | end | ||
265 | struct InexactError <: Exception | ||
266 | func::Symbol | ||
267 | T # Type | ||
268 | val | ||
269 | InexactError(f::Symbol, @nospecialize(T), @nospecialize(val)) = (@_noinline_meta; new(f, T, val)) | ||
270 | end | ||
271 | struct OverflowError <: Exception | ||
272 | msg::AbstractString | ||
273 | end | ||
274 | |||
275 | struct ArgumentError <: Exception | ||
276 | msg::AbstractString | ||
277 | end | ||
278 | struct UndefKeywordError <: Exception | ||
279 | var::Symbol | ||
280 | end | ||
281 | |||
282 | struct MethodError <: Exception | ||
283 | f | ||
284 | args | ||
285 | world::UInt | ||
286 | MethodError(@nospecialize(f), @nospecialize(args), world::UInt) = new(f, args, world) | ||
287 | end | ||
288 | const typemax_UInt = ccall(:jl_typemax_uint, Any, (Any,), UInt) | ||
289 | MethodError(@nospecialize(f), @nospecialize(args)) = MethodError(f, args, typemax_UInt) | ||
290 | |||
291 | struct AssertionError <: Exception | ||
292 | msg::AbstractString | ||
293 | end | ||
294 | AssertionError() = AssertionError("") | ||
295 | |||
296 | abstract type WrappedException <: Exception end | ||
297 | |||
298 | struct LoadError <: WrappedException | ||
299 | file::AbstractString | ||
300 | line::Int | ||
301 | error | ||
302 | end | ||
303 | |||
304 | struct InitError <: WrappedException | ||
305 | mod::Symbol | ||
306 | error | ||
307 | end | ||
308 | |||
309 | String(s::String) = s # no constructor yet | ||
310 | |||
311 | const Cvoid = Nothing | ||
312 | Nothing() = nothing | ||
313 | |||
314 | # This should always be inlined | ||
315 | getptls() = ccall(:jl_get_ptls_states, Ptr{Cvoid}, ()) | ||
316 | |||
317 | 40 (95.24%) |
40 (95.24%) samples spent in include
0 (ex.), 40 (100.00%) (incl.) when called from include_relative line 1044
40 (100.00%)
samples spent calling
top-level scope
include(m::Module, fname::String) = ccall(:jl_load_, Any, (Any, Any), m, fname)
|
|
318 | |||
319 | eval(m::Module, @nospecialize(e)) = ccall(:jl_toplevel_eval_in, Any, (Any, Any), m, e) | ||
320 | |||
321 | kwfunc(@nospecialize(f)) = ccall(:jl_get_keyword_sorter, Any, (Any,), f) | ||
322 | |||
323 | kwftype(@nospecialize(t)) = typeof(ccall(:jl_get_kwsorter, Any, (Any,), t)) | ||
324 | |||
325 | mutable struct Box | ||
326 | contents::Any | ||
327 | Box(@nospecialize(x)) = new(x) | ||
328 | Box() = new() | ||
329 | end | ||
330 | |||
331 | # constructors for built-in types | ||
332 | |||
333 | mutable struct WeakRef | ||
334 | value | ||
335 | WeakRef() = WeakRef(nothing) | ||
336 | WeakRef(@nospecialize(v)) = ccall(:jl_gc_new_weakref_th, Ref{WeakRef}, | ||
337 | (Ptr{Cvoid}, Any), getptls(), v) | ||
338 | end | ||
339 | |||
340 | TypeVar(n::Symbol) = | ||
341 | ccall(:jl_new_typevar, Ref{TypeVar}, (Any, Any, Any), n, Union{}, Any) | ||
342 | TypeVar(n::Symbol, @nospecialize(ub)) = | ||
343 | ccall(:jl_new_typevar, Ref{TypeVar}, (Any, Any, Any), n, Union{}, ub) | ||
344 | TypeVar(n::Symbol, @nospecialize(lb), @nospecialize(ub)) = | ||
345 | ccall(:jl_new_typevar, Ref{TypeVar}, (Any, Any, Any), n, lb, ub) | ||
346 | |||
347 | UnionAll(v::TypeVar, @nospecialize(t)) = ccall(:jl_type_unionall, Any, (Any, Any), v, t) | ||
348 | |||
349 | (::Type{Tuple{}})() = () # Tuple{}() | ||
350 | |||
351 | struct VecElement{T} | ||
352 | value::T | ||
353 | VecElement{T}(value::T) where {T} = new(value) # disable converting constructor in Core | ||
354 | end | ||
355 | VecElement(arg::T) where {T} = VecElement{T}(arg) | ||
356 | |||
357 | _new(typ::Symbol, argty::Symbol) = eval(Core, :($typ(@nospecialize n::$argty) = $(Expr(:new, typ, :n)))) | ||
358 | _new(:GotoNode, :Int) | ||
359 | _new(:NewvarNode, :SlotNumber) | ||
360 | _new(:QuoteNode, :Any) | ||
361 | _new(:SSAValue, :Int) | ||
362 | eval(Core, :(LineNumberNode(l::Int) = $(Expr(:new, :LineNumberNode, :l, nothing)))) | ||
363 | eval(Core, :(LineNumberNode(l::Int, @nospecialize(f)) = $(Expr(:new, :LineNumberNode, :l, :f)))) | ||
364 | eval(Core, :(GlobalRef(m::Module, s::Symbol) = $(Expr(:new, :GlobalRef, :m, :s)))) | ||
365 | eval(Core, :(SlotNumber(n::Int) = $(Expr(:new, :SlotNumber, :n)))) | ||
366 | eval(Core, :(TypedSlot(n::Int, @nospecialize(t)) = $(Expr(:new, :TypedSlot, :n, :t)))) | ||
367 | eval(Core, :(PhiNode(edges::Array{Any, 1}, values::Array{Any, 1}) = $(Expr(:new, :PhiNode, :edges, :values)))) | ||
368 | eval(Core, :(PiNode(val, typ) = $(Expr(:new, :PiNode, :val, :typ)))) | ||
369 | eval(Core, :(PhiCNode(values::Array{Any, 1}) = $(Expr(:new, :PhiCNode, :values)))) | ||
370 | eval(Core, :(UpsilonNode(val) = $(Expr(:new, :UpsilonNode, :val)))) | ||
371 | eval(Core, :(UpsilonNode() = $(Expr(:new, :UpsilonNode)))) | ||
372 | eval(Core, :(LineInfoNode(mod::Module, method::Symbol, file::Symbol, line::Int, inlined_at::Int) = | ||
373 | $(Expr(:new, :LineInfoNode, :mod, :method, :file, :line, :inlined_at)))) | ||
374 | |||
375 | Module(name::Symbol=:anonymous, std_imports::Bool=true) = ccall(:jl_f_new_module, Ref{Module}, (Any, Bool), name, std_imports) | ||
376 | |||
377 | Task(@nospecialize(f)) = ccall(:jl_new_task, Ref{Task}, (Any, Int), f, 0) | ||
378 | |||
379 | # simple convert for use by constructors of types in Core | ||
380 | # note that there is no actual conversion defined here, | ||
381 | # so the methods and ccall's in Core aren't permitted to use convert | ||
382 | convert(::Type{Any}, @nospecialize(x)) = x | ||
383 | convert(::Type{T}, x::T) where {T} = x | ||
384 | cconvert(::Type{T}, x) where {T} = convert(T, x) | ||
385 | unsafe_convert(::Type{T}, x::T) where {T} = x | ||
386 | |||
387 | const NTuple{N,T} = Tuple{Vararg{T,N}} | ||
388 | |||
389 | |||
390 | ## primitive Array constructors | ||
391 | struct UndefInitializer end | ||
392 | const undef = UndefInitializer() | ||
393 | # type and dimensionality specified, accepting dims as series of Ints | ||
394 | Array{T,1}(::UndefInitializer, m::Int) where {T} = | ||
395 | ccall(:jl_alloc_array_1d, Array{T,1}, (Any, Int), Array{T,1}, m) | ||
396 | Array{T,2}(::UndefInitializer, m::Int, n::Int) where {T} = | ||
397 | ccall(:jl_alloc_array_2d, Array{T,2}, (Any, Int, Int), Array{T,2}, m, n) | ||
398 | Array{T,3}(::UndefInitializer, m::Int, n::Int, o::Int) where {T} = | ||
399 | ccall(:jl_alloc_array_3d, Array{T,3}, (Any, Int, Int, Int), Array{T,3}, m, n, o) | ||
400 | Array{T,N}(::UndefInitializer, d::Vararg{Int,N}) where {T,N} = | ||
401 | ccall(:jl_new_array, Array{T,N}, (Any, Any), Array{T,N}, d) | ||
402 | # type and dimensionality specified, accepting dims as tuples of Ints | ||
403 | Array{T,1}(::UndefInitializer, d::NTuple{1,Int}) where {T} = Array{T,1}(undef, getfield(d,1)) | ||
404 | Array{T,2}(::UndefInitializer, d::NTuple{2,Int}) where {T} = Array{T,2}(undef, getfield(d,1), getfield(d,2)) | ||
405 | Array{T,3}(::UndefInitializer, d::NTuple{3,Int}) where {T} = Array{T,3}(undef, getfield(d,1), getfield(d,2), getfield(d,3)) | ||
406 | Array{T,N}(::UndefInitializer, d::NTuple{N,Int}) where {T,N} = ccall(:jl_new_array, Array{T,N}, (Any, Any), Array{T,N}, d) | ||
407 | # type but not dimensionality specified | ||
408 | Array{T}(::UndefInitializer, m::Int) where {T} = Array{T,1}(undef, m) | ||
409 | Array{T}(::UndefInitializer, m::Int, n::Int) where {T} = Array{T,2}(undef, m, n) | ||
410 | Array{T}(::UndefInitializer, m::Int, n::Int, o::Int) where {T} = Array{T,3}(undef, m, n, o) | ||
411 | Array{T}(::UndefInitializer, d::NTuple{N,Int}) where {T,N} = Array{T,N}(undef, d) | ||
412 | # empty vector constructor | ||
413 | Array{T,1}() where {T} = Array{T,1}(undef, 0) | ||
414 | |||
415 | |||
416 | (::Type{Array{T,N} where T})(x::AbstractArray{S,N}) where {S,N} = Array{S,N}(x) | ||
417 | |||
418 | Array(A::AbstractArray{T,N}) where {T,N} = Array{T,N}(A) | ||
419 | Array{T}(A::AbstractArray{S,N}) where {T,N,S} = Array{T,N}(A) | ||
420 | |||
421 | AbstractArray{T}(A::AbstractArray{S,N}) where {T,S,N} = AbstractArray{T,N}(A) | ||
422 | |||
423 | # primitive Symbol constructors | ||
424 | function Symbol(s::String) | ||
425 | return ccall(:jl_symbol_n, Ref{Symbol}, (Ptr{UInt8}, Int), | ||
426 | ccall(:jl_string_ptr, Ptr{UInt8}, (Any,), s), | ||
427 | sizeof(s)) | ||
428 | end | ||
429 | function Symbol(a::Array{UInt8,1}) | ||
430 | return ccall(:jl_symbol_n, Ref{Symbol}, (Ptr{UInt8}, Int), | ||
431 | ccall(:jl_array_ptr, Ptr{UInt8}, (Any,), a), | ||
432 | Intrinsics.arraylen(a)) | ||
433 | end | ||
434 | Symbol(s::Symbol) = s | ||
435 | |||
436 | # module providing the IR object model | ||
437 | module IR | ||
438 | export CodeInfo, MethodInstance, GotoNode, | ||
439 | NewvarNode, SSAValue, Slot, SlotNumber, TypedSlot, | ||
440 | PiNode, PhiNode, PhiCNode, UpsilonNode, LineInfoNode | ||
441 | |||
442 | import Core: CodeInfo, MethodInstance, GotoNode, | ||
443 | NewvarNode, SSAValue, Slot, SlotNumber, TypedSlot, | ||
444 | PiNode, PhiNode, PhiCNode, UpsilonNode, LineInfoNode | ||
445 | |||
446 | end | ||
447 | |||
448 | # docsystem basics | ||
449 | const unescape = Symbol("hygienic-scope") | ||
450 | macro doc(x...) | ||
451 | docex = atdoc(__source__, __module__, x...) | ||
452 | isa(docex, Expr) && docex.head === :escape && return docex | ||
453 | return Expr(:escape, Expr(unescape, docex, typeof(atdoc).name.module)) | ||
454 | end | ||
455 | macro __doc__(x) | ||
456 | return Expr(:escape, Expr(:block, Expr(:meta, :doc), x)) | ||
457 | end | ||
458 | atdoc = (source, mod, str, expr) -> Expr(:escape, expr) | ||
459 | atdoc!(λ) = global atdoc = λ | ||
460 | |||
461 | |||
462 | # simple stand-alone print definitions for debugging | ||
463 | abstract type IO end | ||
464 | struct CoreSTDOUT <: IO end | ||
465 | struct CoreSTDERR <: IO end | ||
466 | const stdout = CoreSTDOUT() | ||
467 | const stderr = CoreSTDERR() | ||
468 | io_pointer(::CoreSTDOUT) = Intrinsics.pointerref(Intrinsics.cglobal(:jl_uv_stdout, Ptr{Cvoid}), 1, 1) | ||
469 | io_pointer(::CoreSTDERR) = Intrinsics.pointerref(Intrinsics.cglobal(:jl_uv_stderr, Ptr{Cvoid}), 1, 1) | ||
470 | |||
471 | unsafe_write(io::IO, x::Ptr{UInt8}, nb::UInt) = | ||
472 | (ccall(:jl_uv_puts, Cvoid, (Ptr{Cvoid}, Ptr{UInt8}, UInt), io_pointer(io), x, nb); nb) | ||
473 | unsafe_write(io::IO, x::Ptr{UInt8}, nb::Int) = | ||
474 | (ccall(:jl_uv_puts, Cvoid, (Ptr{Cvoid}, Ptr{UInt8}, Int), io_pointer(io), x, nb); nb) | ||
475 | write(io::IO, x::UInt8) = | ||
476 | (ccall(:jl_uv_putb, Cvoid, (Ptr{Cvoid}, UInt8), io_pointer(io), x); 1) | ||
477 | function write(io::IO, x::String) | ||
478 | nb = sizeof(x) | ||
479 | unsafe_write(io, ccall(:jl_string_ptr, Ptr{UInt8}, (Any,), x), nb) | ||
480 | return nb | ||
481 | end | ||
482 | |||
483 | show(io::IO, @nospecialize x) = ccall(:jl_static_show, Cvoid, (Ptr{Cvoid}, Any), io_pointer(io), x) | ||
484 | print(io::IO, x::AbstractChar) = ccall(:jl_uv_putc, Cvoid, (Ptr{Cvoid}, Char), io_pointer(io), x) | ||
485 | print(io::IO, x::String) = (write(io, x); nothing) | ||
486 | print(io::IO, @nospecialize x) = show(io, x) | ||
487 | print(io::IO, @nospecialize(x), @nospecialize a...) = (print(io, x); print(io, a...)) | ||
488 | println(io::IO) = (write(io, 0x0a); nothing) # 0x0a = '\n' | ||
489 | println(io::IO, @nospecialize x...) = (print(io, x...); println(io)) | ||
490 | |||
491 | show(@nospecialize a) = show(stdout, a) | ||
492 | print(@nospecialize a...) = print(stdout, a...) | ||
493 | println(@nospecialize a...) = println(stdout, a...) | ||
494 | |||
495 | struct GeneratedFunctionStub | ||
496 | gen | ||
497 | argnames::Array{Any,1} | ||
498 | spnames::Union{Nothing, Array{Any,1}} | ||
499 | line::Int | ||
500 | file::Symbol | ||
501 | expand_early::Bool | ||
502 | end | ||
503 | |||
504 | # invoke and wrap the results of @generated | ||
505 | function (g::GeneratedFunctionStub)(@nospecialize args...) | ||
506 | body = g.gen(args...) | ||
507 | if body isa CodeInfo | ||
508 | return body | ||
509 | end | ||
510 | lam = Expr(:lambda, g.argnames, | ||
511 | Expr(Symbol("scope-block"), | ||
512 | Expr(:block, | ||
513 | LineNumberNode(g.line, g.file), | ||
514 | Expr(:meta, :push_loc, g.file, Symbol("@generated body")), | ||
515 | Expr(:return, body), | ||
516 | Expr(:meta, :pop_loc)))) | ||
517 | if g.spnames === nothing | ||
518 | return lam | ||
519 | else | ||
520 | return Expr(Symbol("with-static-parameters"), lam, g.spnames...) | ||
521 | end | ||
522 | end | ||
523 | |||
524 | NamedTuple() = NamedTuple{(),Tuple{}}(()) | ||
525 | |||
526 | """ | ||
527 | NamedTuple{names}(args::Tuple) | ||
528 | |||
529 | Construct a named tuple with the given `names` (a tuple of Symbols) from a tuple of values. | ||
530 | """ | ||
531 | NamedTuple{names}(args::Tuple) where {names} = NamedTuple{names,typeof(args)}(args) | ||
532 | |||
533 | using .Intrinsics: sle_int, add_int | ||
534 | |||
535 | macro generated() | ||
536 | return Expr(:generated) | ||
537 | end | ||
538 | |||
539 | function NamedTuple{names,T}(args::T) where {names, T <: Tuple} | ||
540 | if @generated | ||
541 | N = nfields(names) | ||
542 | flds = Array{Any,1}(undef, N) | ||
543 | i = 1 | ||
544 | while sle_int(i, N) | ||
545 | arrayset(false, flds, :(getfield(args, $i)), i) | ||
546 | i = add_int(i, 1) | ||
547 | end | ||
548 | Expr(:new, :(NamedTuple{names,T}), flds...) | ||
549 | else | ||
550 | N = nfields(names) | ||
551 | NT = NamedTuple{names,T} | ||
552 | flds = Array{Any,1}(undef, N) | ||
553 | i = 1 | ||
554 | while sle_int(i, N) | ||
555 | arrayset(false, flds, getfield(args, i), i) | ||
556 | i = add_int(i, 1) | ||
557 | end | ||
558 | ccall(:jl_new_structv, Any, (Any, Ptr{Cvoid}, UInt32), NT, | ||
559 | ccall(:jl_array_ptr, Ptr{Cvoid}, (Any,), flds), toUInt32(N))::NT | ||
560 | end | ||
561 | end | ||
562 | |||
563 | # constructors for built-in types | ||
564 | |||
565 | import .Intrinsics: eq_int, trunc_int, lshr_int, sub_int, shl_int, bitcast, sext_int, zext_int, and_int | ||
566 | |||
567 | throw_inexacterror(f::Symbol, @nospecialize(T), val) = (@_noinline_meta; throw(InexactError(f, T, val))) | ||
568 | |||
569 | function is_top_bit_set(x) | ||
570 | @_inline_meta | ||
571 | eq_int(trunc_int(UInt8, lshr_int(x, sub_int(shl_int(sizeof(x), 3), 1))), trunc_int(UInt8, 1)) | ||
572 | end | ||
573 | |||
574 | function is_top_bit_set(x::Union{Int8,UInt8}) | ||
575 | @_inline_meta | ||
576 | eq_int(lshr_int(x, 7), trunc_int(typeof(x), 1)) | ||
577 | end | ||
578 | |||
579 | function check_top_bit(x) | ||
580 | @_inline_meta | ||
581 | is_top_bit_set(x) && throw_inexacterror(:check_top_bit, typeof(x), x) | ||
582 | x | ||
583 | end | ||
584 | |||
585 | function checked_trunc_sint(::Type{To}, x::From) where {To,From} | ||
586 | @_inline_meta | ||
587 | y = trunc_int(To, x) | ||
588 | back = sext_int(From, y) | ||
589 | eq_int(x, back) || throw_inexacterror(:trunc, To, x) | ||
590 | y | ||
591 | end | ||
592 | |||
593 | function checked_trunc_uint(::Type{To}, x::From) where {To,From} | ||
594 | @_inline_meta | ||
595 | y = trunc_int(To, x) | ||
596 | back = zext_int(From, y) | ||
597 | eq_int(x, back) || throw_inexacterror(:trunc, To, x) | ||
598 | y | ||
599 | end | ||
600 | |||
601 | toInt8(x::Int8) = x | ||
602 | toInt8(x::Int16) = checked_trunc_sint(Int8, x) | ||
603 | toInt8(x::Int32) = checked_trunc_sint(Int8, x) | ||
604 | toInt8(x::Int64) = checked_trunc_sint(Int8, x) | ||
605 | toInt8(x::Int128) = checked_trunc_sint(Int8, x) | ||
606 | toInt8(x::UInt8) = bitcast(Int8, check_top_bit(x)) | ||
607 | toInt8(x::UInt16) = checked_trunc_sint(Int8, check_top_bit(x)) | ||
608 | toInt8(x::UInt32) = checked_trunc_sint(Int8, check_top_bit(x)) | ||
609 | toInt8(x::UInt64) = checked_trunc_sint(Int8, check_top_bit(x)) | ||
610 | toInt8(x::UInt128) = checked_trunc_sint(Int8, check_top_bit(x)) | ||
611 | toInt8(x::Bool) = and_int(zext_int(Int8, x), Int8(1)) | ||
612 | toInt16(x::Int8) = sext_int(Int16, x) | ||
613 | toInt16(x::Int16) = x | ||
614 | toInt16(x::Int32) = checked_trunc_sint(Int16, x) | ||
615 | toInt16(x::Int64) = checked_trunc_sint(Int16, x) | ||
616 | toInt16(x::Int128) = checked_trunc_sint(Int16, x) | ||
617 | toInt16(x::UInt8) = zext_int(Int16, x) | ||
618 | toInt16(x::UInt16) = bitcast(Int16, check_top_bit(x)) | ||
619 | toInt16(x::UInt32) = checked_trunc_sint(Int16, check_top_bit(x)) | ||
620 | toInt16(x::UInt64) = checked_trunc_sint(Int16, check_top_bit(x)) | ||
621 | toInt16(x::UInt128) = checked_trunc_sint(Int16, check_top_bit(x)) | ||
622 | toInt16(x::Bool) = and_int(zext_int(Int16, x), Int16(1)) | ||
623 | toInt32(x::Int8) = sext_int(Int32, x) | ||
624 | toInt32(x::Int16) = sext_int(Int32, x) | ||
625 | toInt32(x::Int32) = x | ||
626 | toInt32(x::Int64) = checked_trunc_sint(Int32, x) | ||
627 | toInt32(x::Int128) = checked_trunc_sint(Int32, x) | ||
628 | toInt32(x::UInt8) = zext_int(Int32, x) | ||
629 | toInt32(x::UInt16) = zext_int(Int32, x) | ||
630 | toInt32(x::UInt32) = bitcast(Int32, check_top_bit(x)) | ||
631 | toInt32(x::UInt64) = checked_trunc_sint(Int32, check_top_bit(x)) | ||
632 | toInt32(x::UInt128) = checked_trunc_sint(Int32, check_top_bit(x)) | ||
633 | toInt32(x::Bool) = and_int(zext_int(Int32, x), Int32(1)) | ||
634 | toInt64(x::Int8) = sext_int(Int64, x) | ||
635 | toInt64(x::Int16) = sext_int(Int64, x) | ||
636 | toInt64(x::Int32) = sext_int(Int64, x) | ||
637 | toInt64(x::Int64) = x | ||
638 | toInt64(x::Int128) = checked_trunc_sint(Int64, x) | ||
639 | toInt64(x::UInt8) = zext_int(Int64, x) | ||
640 | toInt64(x::UInt16) = zext_int(Int64, x) | ||
641 | toInt64(x::UInt32) = zext_int(Int64, x) | ||
642 | toInt64(x::UInt64) = bitcast(Int64, check_top_bit(x)) | ||
643 | toInt64(x::UInt128) = checked_trunc_sint(Int64, check_top_bit(x)) | ||
644 | toInt64(x::Bool) = and_int(zext_int(Int64, x), Int64(1)) | ||
645 | toInt128(x::Int8) = sext_int(Int128, x) | ||
646 | toInt128(x::Int16) = sext_int(Int128, x) | ||
647 | toInt128(x::Int32) = sext_int(Int128, x) | ||
648 | toInt128(x::Int64) = sext_int(Int128, x) | ||
649 | toInt128(x::Int128) = x | ||
650 | toInt128(x::UInt8) = zext_int(Int128, x) | ||
651 | toInt128(x::UInt16) = zext_int(Int128, x) | ||
652 | toInt128(x::UInt32) = zext_int(Int128, x) | ||
653 | toInt128(x::UInt64) = zext_int(Int128, x) | ||
654 | toInt128(x::UInt128) = bitcast(Int128, check_top_bit(x)) | ||
655 | toInt128(x::Bool) = and_int(zext_int(Int128, x), Int128(1)) | ||
656 | toUInt8(x::Int8) = bitcast(UInt8, check_top_bit(x)) | ||
657 | toUInt8(x::Int16) = checked_trunc_uint(UInt8, x) | ||
658 | toUInt8(x::Int32) = checked_trunc_uint(UInt8, x) | ||
659 | toUInt8(x::Int64) = checked_trunc_uint(UInt8, x) | ||
660 | toUInt8(x::Int128) = checked_trunc_uint(UInt8, x) | ||
661 | toUInt8(x::UInt8) = x | ||
662 | toUInt8(x::UInt16) = checked_trunc_uint(UInt8, x) | ||
663 | toUInt8(x::UInt32) = checked_trunc_uint(UInt8, x) | ||
664 | toUInt8(x::UInt64) = checked_trunc_uint(UInt8, x) | ||
665 | toUInt8(x::UInt128) = checked_trunc_uint(UInt8, x) | ||
666 | toUInt8(x::Bool) = and_int(zext_int(UInt8, x), UInt8(1)) | ||
667 | toUInt16(x::Int8) = sext_int(UInt16, check_top_bit(x)) | ||
668 | toUInt16(x::Int16) = bitcast(UInt16, check_top_bit(x)) | ||
669 | toUInt16(x::Int32) = checked_trunc_uint(UInt16, x) | ||
670 | toUInt16(x::Int64) = checked_trunc_uint(UInt16, x) | ||
671 | toUInt16(x::Int128) = checked_trunc_uint(UInt16, x) | ||
672 | toUInt16(x::UInt8) = zext_int(UInt16, x) | ||
673 | toUInt16(x::UInt16) = x | ||
674 | toUInt16(x::UInt32) = checked_trunc_uint(UInt16, x) | ||
675 | toUInt16(x::UInt64) = checked_trunc_uint(UInt16, x) | ||
676 | toUInt16(x::UInt128) = checked_trunc_uint(UInt16, x) | ||
677 | toUInt16(x::Bool) = and_int(zext_int(UInt16, x), UInt16(1)) | ||
678 | toUInt32(x::Int8) = sext_int(UInt32, check_top_bit(x)) | ||
679 | toUInt32(x::Int16) = sext_int(UInt32, check_top_bit(x)) | ||
680 | toUInt32(x::Int32) = bitcast(UInt32, check_top_bit(x)) | ||
681 | toUInt32(x::Int64) = checked_trunc_uint(UInt32, x) | ||
682 | toUInt32(x::Int128) = checked_trunc_uint(UInt32, x) | ||
683 | toUInt32(x::UInt8) = zext_int(UInt32, x) | ||
684 | toUInt32(x::UInt16) = zext_int(UInt32, x) | ||
685 | toUInt32(x::UInt32) = x | ||
686 | toUInt32(x::UInt64) = checked_trunc_uint(UInt32, x) | ||
687 | toUInt32(x::UInt128) = checked_trunc_uint(UInt32, x) | ||
688 | toUInt32(x::Bool) = and_int(zext_int(UInt32, x), UInt32(1)) | ||
689 | toUInt64(x::Int8) = sext_int(UInt64, check_top_bit(x)) | ||
690 | toUInt64(x::Int16) = sext_int(UInt64, check_top_bit(x)) | ||
691 | toUInt64(x::Int32) = sext_int(UInt64, check_top_bit(x)) | ||
692 | toUInt64(x::Int64) = bitcast(UInt64, check_top_bit(x)) | ||
693 | toUInt64(x::Int128) = checked_trunc_uint(UInt64, x) | ||
694 | toUInt64(x::UInt8) = zext_int(UInt64, x) | ||
695 | toUInt64(x::UInt16) = zext_int(UInt64, x) | ||
696 | toUInt64(x::UInt32) = zext_int(UInt64, x) | ||
697 | toUInt64(x::UInt64) = x | ||
698 | toUInt64(x::UInt128) = checked_trunc_uint(UInt64, x) | ||
699 | toUInt64(x::Bool) = and_int(zext_int(UInt64, x), UInt64(1)) | ||
700 | toUInt128(x::Int8) = sext_int(UInt128, check_top_bit(x)) | ||
701 | toUInt128(x::Int16) = sext_int(UInt128, check_top_bit(x)) | ||
702 | toUInt128(x::Int32) = sext_int(UInt128, check_top_bit(x)) | ||
703 | toUInt128(x::Int64) = sext_int(UInt128, check_top_bit(x)) | ||
704 | toUInt128(x::Int128) = bitcast(UInt128, check_top_bit(x)) | ||
705 | toUInt128(x::UInt8) = zext_int(UInt128, x) | ||
706 | toUInt128(x::UInt16) = zext_int(UInt128, x) | ||
707 | toUInt128(x::UInt32) = zext_int(UInt128, x) | ||
708 | toUInt128(x::UInt64) = zext_int(UInt128, x) | ||
709 | toUInt128(x::UInt128) = x | ||
710 | toUInt128(x::Bool) = and_int(zext_int(UInt128, x), UInt128(1)) | ||
711 | |||
712 | # TODO: this is here to work around the 4 method limit in inference (#23210). | ||
713 | const BuiltinInts = Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8, Bool} | ||
714 | Int8(x::BuiltinInts) = toInt8(x)::Int8 | ||
715 | Int16(x::BuiltinInts) = toInt16(x)::Int16 | ||
716 | Int32(x::BuiltinInts) = toInt32(x)::Int32 | ||
717 | Int64(x::BuiltinInts) = toInt64(x)::Int64 | ||
718 | Int128(x::BuiltinInts) = toInt128(x)::Int128 | ||
719 | UInt8(x::BuiltinInts) = toUInt8(x)::UInt8 | ||
720 | UInt16(x::BuiltinInts) = toUInt16(x)::UInt16 | ||
721 | UInt32(x::BuiltinInts) = toUInt32(x)::UInt32 | ||
722 | UInt64(x::BuiltinInts) = toUInt64(x)::UInt64 | ||
723 | UInt128(x::BuiltinInts) = toUInt128(x)::UInt128 | ||
724 | |||
725 | (::Type{T})(x::T) where {T<:Number} = x | ||
726 | |||
727 | Int(x::Ptr) = bitcast(Int, x) | ||
728 | UInt(x::Ptr) = bitcast(UInt, x) | ||
729 | if Int === Int32 | ||
730 | Int64(x::Ptr) = Int64(UInt32(x)) | ||
731 | UInt64(x::Ptr) = UInt64(UInt32(x)) | ||
732 | end | ||
733 | Ptr{T}(x::Union{Int,UInt,Ptr}) where {T} = bitcast(Ptr{T}, x) | ||
734 | |||
735 | Signed(x::UInt8) = Int8(x) | ||
736 | Unsigned(x::Int8) = UInt8(x) | ||
737 | Signed(x::UInt16) = Int16(x) | ||
738 | Unsigned(x::Int16) = UInt16(x) | ||
739 | Signed(x::UInt32) = Int32(x) | ||
740 | Unsigned(x::Int32) = UInt32(x) | ||
741 | Signed(x::UInt64) = Int64(x) | ||
742 | Unsigned(x::Int64) = UInt64(x) | ||
743 | Signed(x::UInt128) = Int128(x) | ||
744 | Unsigned(x::Int128) = UInt128(x) | ||
745 | |||
746 | Signed(x::Union{Float32, Float64, Bool}) = Int(x) | ||
747 | Unsigned(x::Union{Float32, Float64, Bool}) = UInt(x) | ||
748 | |||
749 | Integer(x::Integer) = x | ||
750 | Integer(x::Union{Float32, Float64}) = Int(x) | ||
751 | |||
752 | ccall(:jl_set_istopmod, Cvoid, (Any, Bool), Core, true) |