@@ -2,6 +2,7 @@ const compiled_calls = Dict{Any,Any}()
22
33# Pre-frame-construction lookup
44function lookup_stmt(stmts:: Vector{Any} , @nospecialize arg)
5+ # this converts a statement into something else, without the slightest interest in correctness:
56 if isa(arg, SSAValue)
67 arg = stmts[arg. id]
78 end
@@ -210,30 +211,31 @@ end
210211# Handle :llvmcall & :foreigncall (issue #28)
211212function build_compiled_foreigncall!(stmt:: Expr , code:: CodeInfo , sparams:: Vector{Symbol} , evalmod:: Module )
212213 TVal = evalmod == Core. Compiler ? Core. Compiler. Val : Val
213- cfuncarg = stmt. args[1 ]
214- while isa(cfuncarg, SSAValue)
215- cfuncarg = lookup_stmt(code. code, cfuncarg)
216- end
217214 RetType, ArgType = stmt. args[2 ], stmt. args[3 ]:: SimpleVector
218215
219216 dynamic_ccall = false
220- oldcfunc = nothing
221- if isa(cfuncarg, Expr) || isa(cfuncarg, GlobalRef) || isa(cfuncarg, Symbol) # specification by tuple, e.g., (:clock, "libc")
222- cfunc = something(try Core. eval(evalmod, cfuncarg) catch nothing end , cfuncarg)
223- elseif isa(cfuncarg, QuoteNode)
224- cfunc = cfuncarg. value
225- else
226- cfunc = cfuncarg
227- end
228- if isa(cfunc, Symbol)
229- cfunc = QuoteNode(cfunc)
230- elseif isa(cfunc, String) || isa(cfunc, Ptr) || isa(cfunc, Tuple)
231- # do nothing
217+ argcfunc = cfunc = stmt. args[1 ]
218+ if @isdefined(__has_internal_change) && __has_internal_change(v" 1.13.0" , :syntacticccall)
219+ if ! isexpr(cfunc, :tuple)
220+ dynamic_ccall = true
221+ cfunc = gensym(" ptr" )
222+ end
232223 else
233- dynamic_ccall = true
234- oldcfunc = cfunc
235- cfunc = gensym(" ptr" )
224+ while isa(cfunc, SSAValue)
225+ cfunc = lookup_stmt(code. code, cfunc)
226+ cfunc isa Symbol && (cfunc = QuoteNode(cfunc))
227+ end
228+ # n.b. Base.memhash is deprecated (continued use would cause serious faults) in the same version as the syntax is deprecated
229+ # so this is only needed as a legacy hack
230+ if isa(cfunc, Expr) || (cfunc isa GlobalRef && cfunc == GlobalRef(Base, :memhash))
231+ cfunc = something(try QuoteNode(Core. eval(evalmod, cfunc)) catch nothing end , cfunc)
232+ end
233+ if ! (isa(cfunc, Union{String, Tuple}) || (isa(cfunc, QuoteNode) && isa(cfunc. value, Union{String, Tuple, Symbol})))
234+ dynamic_ccall = true
235+ cfunc = gensym(" ptr" )
236+ end
236237 end
238+
237239 if isa(RetType, SimpleVector)
238240 @assert length(RetType) == 1
239241 RetType = RetType[1 ]
@@ -274,7 +276,7 @@ function build_compiled_foreigncall!(stmt::Expr, code::CodeInfo, sparams::Vector
274276 stmt. head = :call
275277 deleteat!(stmt. args, 2 : length(stmt. args))
276278 if dynamic_ccall
277- push!(stmt. args, oldcfunc )
279+ push!(stmt. args, argcfunc )
278280 end
279281 append!(stmt. args, args)
280282 for i in 1 : length(sparams)
0 commit comments