1
1
# This file generates builtins.jl.
2
2
3
3
function scopedname (f)
4
- fstr = string (f)
4
+ io = IOBuffer ()
5
+ show (io, f)
6
+ fstr = String (take! (io))
5
7
occursin (' .' , fstr) && return fstr
6
8
tn = typeof (f). name
7
9
Base. isexported (tn. module, Symbol (fstr)) && return fstr
8
- return string (tn. module) * ' .' * fstr
10
+ fsym = Symbol (fstr)
11
+ isdefined (tn. module, fsym) && return string (tn. module) * ' .' * fstr
12
+ return " Base." * fstr
9
13
end
10
14
11
- # Look up the expected number of arguments in Core.Compiler.tfunc data
12
- function generate_fcall (f, table, id)
15
+ function nargs (f, table, id)
16
+ # Look up the expected number of arguments in Core.Compiler.tfunc data
13
17
if id != = nothing
14
18
minarg, maxarg, tfunc = table[id]
15
19
else
16
20
minarg = 0
17
21
maxarg = typemax (Int)
18
22
end
19
- # The tfunc tables are wrong for fptoui and fptosi
23
+ # The tfunc tables are wrong for fptoui and fptosi (fixed in https://github.com/JuliaLang/julia/pull/30787)
20
24
if f == " Base.fptoui" || f == " Base.fptosi"
21
25
minarg = 2
22
26
end
27
+ return minarg, maxarg
28
+ end
29
+
30
+ function generate_fcall_nargs (fname, minarg, maxarg)
23
31
# Generate a separate call for each number of arguments
24
- fname = scopedname (f)
25
- if maxarg < typemax (Int)
26
- wrapper = minarg == maxarg ? " " : " if nargs == "
27
- for nargs = minarg: maxarg
28
- if minarg < maxarg
29
- wrapper *= " $nargs \n "
30
- end
31
- argcall = " "
32
- for i = 1 : nargs
33
- argcall *= " @lookup(frame, args[$(i+ 1 ) ])"
34
- if i < nargs
35
- argcall *= " , "
36
- end
37
- end
38
- wrapper *= " return Some{Any}($fname ($argcall ))"
39
- if nargs < maxarg
40
- wrapper *= " \n elseif nargs == "
32
+ maxarg < typemax (Int) || error (" call this only for constrained number of arguments" )
33
+ wrapper = minarg == maxarg ? " " : " if nargs == "
34
+ for nargs = minarg: maxarg
35
+ if minarg < maxarg
36
+ wrapper *= " $nargs \n "
37
+ end
38
+ argcall = " "
39
+ for i = 1 : nargs
40
+ argcall *= " @lookup(frame, args[$(i+ 1 ) ])"
41
+ if i < nargs
42
+ argcall *= " , "
41
43
end
42
44
end
43
- if minarg < maxarg
44
- wrapper *= " \n end"
45
+ wrapper *= " return Some{Any}($fname ($argcall ))"
46
+ if nargs < maxarg
47
+ wrapper *= " \n elseif nargs == "
45
48
end
46
- return wrapper
49
+ end
50
+ if minarg < maxarg
51
+ wrapper *= " \n end"
52
+ end
53
+ return wrapper
54
+ end
55
+
56
+ function generate_fcall (f, table, id)
57
+ minarg, maxarg = nargs (f, table, id)
58
+ fname = scopedname (f)
59
+ if maxarg < typemax (Int)
60
+ return generate_fcall_nargs (fname, minarg, maxarg)
47
61
end
48
62
# A built-in with arbitrary or unknown number of arguments.
49
63
# This will (unfortunately) use dynamic dispatch.
@@ -124,13 +138,7 @@ function maybe_evaluate_builtin(frame, call_expr)
124
138
"""
125
139
# Intrinsics
126
140
""" )
127
- for fsym in names (Core. Intrinsics)
128
- fsym == :Intrinsics && continue
129
- isdefined (Base, fsym) || (println (" skipping " , fname); continue )
130
- f = getfield (Base, fsym)
131
- f isa Core. IntrinsicFunction || error (" not an intrinsic" )
132
- if f == cglobal
133
- print (io,
141
+ print (io,
134
142
"""
135
143
elseif f === Base.cglobal
136
144
if nargs == 1
@@ -141,18 +149,40 @@ function maybe_evaluate_builtin(frame, call_expr)
141
149
return Some{Any}(Core.eval(moduleof(frame), call_expr))
142
150
end
143
151
""" )
144
- continue
152
+ # Extract any intrinsics that support varargs
153
+ fva = []
154
+ minmin, maxmax = typemax (Int), 0
155
+ for fsym in names (Core. Intrinsics)
156
+ fsym == :Intrinsics && continue
157
+ isdefined (Base, fsym) || continue
158
+ f = getfield (Base, fsym)
159
+ id = reinterpret (Int32, f) + 1
160
+ minarg, maxarg = nargs (f, Core. Compiler. T_IFUNC, id)
161
+ if maxarg == typemax (Int)
162
+ push! (fva, f)
163
+ else
164
+ minmin = min (minmin, minarg)
165
+ maxmax = max (maxmax, maxarg)
145
166
end
167
+ end
168
+ for f in fva
146
169
id = reinterpret (Int32, f) + 1
147
- f = isdefined (Base, fsym) ? " Base.$fsym " :
148
- isdefined (Core, fsym) ? " Core.$fsym " : error (" whoops on $f " )
170
+ fname = scopedname (f)
149
171
fcall = generate_fcall (f, Core. Compiler. T_IFUNC, id)
150
172
print (io,
151
173
"""
152
- elseif f === $f
174
+ elseif f === $fname
153
175
$fcall
176
+ end
154
177
""" )
155
178
end
179
+ # Now handle calls with bounded numbers of args
180
+ fcall = generate_fcall_nargs (" f" , minmin, maxmax)
181
+ print (io,
182
+ """
183
+ if isa(f, Core.IntrinsicFunction)
184
+ $fcall
185
+ """ )
156
186
print (io,
157
187
"""
158
188
end
0 commit comments