@@ -370,9 +370,41 @@ function generate_opaque_closure(config::CompilerConfig, src::CodeInfo,
370
370
return OpaqueClosure {id, typeof(env), sig, rt} (env)
371
371
end
372
372
373
+ # generated function `ccall`, working around the restriction that ccall type
374
+ # tuples need to be literals. this relies on ccall internals...
375
+ @inline @generated function generated_ccall (f:: Ptr , _rettyp, _types, vals... )
376
+ ex = quote end
377
+
378
+ rettyp = _rettyp. parameters[1 ]
379
+ types = _types. parameters[1 ]. parameters
380
+ args = [:(vals[$ i]) for i in 1 : length (vals)]
381
+
382
+ # cconvert
383
+ cconverted = [Symbol (" cconverted_$i " ) for i in 1 : length (vals)]
384
+ for (dst, typ, src) in zip (cconverted, types, args)
385
+ append! (ex. args, (quote
386
+ $ dst = Base. cconvert ($ typ, $ src)
387
+ end ). args)
388
+ end
389
+
390
+ # unsafe_convert
391
+ unsafe_converted = [Symbol (" unsafe_converted_$i " ) for i in 1 : length (vals)]
392
+ for (dst, typ, src) in zip (unsafe_converted, types, cconverted)
393
+ append! (ex. args, (quote
394
+ $ dst = Base. unsafe_convert ($ typ, $ src)
395
+ end ). args)
396
+ end
397
+
398
+ call = Expr (:foreigncall , :f , rettyp, Core. svec (types... ), 0 ,
399
+ QuoteNode (:ccall ), unsafe_converted... , cconverted... )
400
+ push! (ex. args, call)
401
+ return ex
402
+ end
403
+
373
404
# device-side call to an opaque closure
374
- function (oc:: OpaqueClosure{F} )(a, b ) where F
405
+ function (oc:: OpaqueClosure{F,E,A,R } )(args ... ) where {F,E,A,R}
375
406
ptr = ccall (" extern deferred_codegen" , llvmcall, Ptr{Cvoid}, (Int,), F)
376
407
assume (ptr != C_NULL )
377
- return ccall (ptr, Int, (Int, Int), a, b)
408
+ # ccall(ptr, R, (A...), args...)
409
+ generated_ccall (ptr, R, A, args... )
378
410
end
0 commit comments