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