@@ -805,140 +805,6 @@ void jl_emit_codeinst_to_jit_impl(
805805}
806806
807807
808- const char *jl_generate_ccallable (Module *llvmmod, void *sysimg_handle, jl_value_t *declrt, jl_value_t *sigt, jl_codegen_params_t ¶ms);
809-
810- // compile a C-callable alias
811- extern " C" JL_DLLEXPORT_CODEGEN
812- int jl_compile_extern_c_impl (LLVMOrcThreadSafeModuleRef llvmmod, void *p, void *sysimg, jl_value_t *declrt, jl_value_t *sigt)
813- {
814- auto ct = jl_current_task;
815- bool timed = (ct->reentrant_timing & 1 ) == 0 ;
816- if (timed)
817- ct->reentrant_timing |= 1 ;
818- uint64_t compiler_start_time = 0 ;
819- uint8_t measure_compile_time_enabled = jl_atomic_load_relaxed (&jl_measure_compile_time_enabled);
820- if (measure_compile_time_enabled)
821- compiler_start_time = jl_hrtime ();
822- jl_codegen_params_t *pparams = (jl_codegen_params_t *)p;
823- DataLayout DL = pparams ? pparams->DL : jl_ExecutionEngine->getDataLayout ();
824- Triple TargetTriple = pparams ? pparams->TargetTriple : jl_ExecutionEngine->getTargetTriple ();
825- orc::ThreadSafeContext ctx;
826- auto into = unwrap (llvmmod);
827- orc::ThreadSafeModule backing;
828- bool success = true ;
829- const char *name = " " ;
830- if (into == NULL ) {
831- ctx = pparams ? pparams->tsctx : jl_ExecutionEngine->makeContext ();
832- backing = jl_create_ts_module (" cextern" , ctx, DL, TargetTriple);
833- into = &backing;
834- }
835- { // params scope
836- jl_codegen_params_t params (into->getContext (), DL, TargetTriple);
837- if (pparams == NULL ) {
838- params.cache = p == NULL ;
839- params.imaging_mode = 0 ;
840- params.tsctx .getContext ()->setDiscardValueNames (true );
841- pparams = ¶ms;
842- }
843- Module &M = *into->getModuleUnlocked ();
844- assert (pparams->tsctx .getContext () == &M.getContext ());
845- name = jl_generate_ccallable (&M, sysimg, declrt, sigt, *pparams);
846- if (!sysimg && !p) {
847- { // drop lock to keep analyzer happy (since it doesn't know we have the only reference to it)
848- auto release = std::move (params.tsctx_lock );
849- }
850- { // lock scope
851- jl_unique_gcsafe_lock lock (extern_c_lock);
852- if (jl_ExecutionEngine->getGlobalValueAddress (name))
853- success = false ;
854- }
855- params.tsctx_lock = params.tsctx .getLock (); // re-acquire lock
856- if (success && params.cache ) {
857- size_t newest_world = jl_atomic_load_acquire (&jl_world_counter);
858- for (auto &it : params.workqueue ) { // really just zero or one, and just the ABI not the rest of the metadata
859- jl_code_instance_t *codeinst = it.first ;
860- JL_GC_PROMISE_ROOTED (codeinst);
861- jl_code_instance_t *newest_ci = jl_type_infer (jl_get_ci_mi (codeinst), newest_world, SOURCE_MODE_ABI);
862- if (newest_ci) {
863- if (jl_egal (codeinst->rettype , newest_ci->rettype ))
864- it.first = codeinst;
865- jl_compile_codeinst_now (newest_ci);
866- }
867- }
868- jl_analyze_workqueue (nullptr , params, true );
869- assert (params.workqueue .empty ());
870- finish_params (&M, params, sharedmodules);
871- }
872- }
873- pparams = nullptr ;
874- }
875- if (!sysimg && success && llvmmod == NULL ) {
876- { // lock scope
877- jl_unique_gcsafe_lock lock (extern_c_lock);
878- if (!jl_ExecutionEngine->getGlobalValueAddress (name)) {
879- {
880- auto Lock = backing.getContext ().getLock ();
881- jl_ExecutionEngine->optimizeDLSyms (*backing.getModuleUnlocked ()); // safepoint
882- }
883- jl_ExecutionEngine->addModule (std::move (backing));
884- success = jl_ExecutionEngine->getGlobalValueAddress (name);
885- assert (success);
886- }
887- }
888- }
889- if (timed) {
890- if (measure_compile_time_enabled) {
891- auto end = jl_hrtime ();
892- jl_atomic_fetch_add_relaxed (&jl_cumulative_compile_time, end - compiler_start_time);
893- }
894- ct->reentrant_timing &= ~1ull ;
895- }
896- return success;
897- }
898-
899- // declare a C-callable entry point; called during code loading from the toplevel
900- extern " C" JL_DLLEXPORT_CODEGEN
901- void jl_extern_c_impl (jl_value_t *declrt, jl_tupletype_t *sigt)
902- {
903- // validate arguments. try to do as many checks as possible here to avoid
904- // throwing errors later during codegen.
905- JL_TYPECHK (@ccallable, type, declrt);
906- if (!jl_is_tuple_type (sigt))
907- jl_type_error (" @ccallable" , (jl_value_t *)jl_anytuple_type_type, (jl_value_t *)sigt);
908- // check that f is a guaranteed singleton type
909- jl_datatype_t *ft = (jl_datatype_t *)jl_tparam0 (sigt);
910- if (!jl_is_datatype (ft) || !jl_is_datatype_singleton (ft))
911- jl_error (" @ccallable: function object must be a singleton" );
912-
913- // compute / validate return type
914- if (!jl_is_concrete_type (declrt) || jl_is_kind (declrt))
915- jl_error (" @ccallable: return type must be concrete and correspond to a C type" );
916- if (!jl_type_mappable_to_c (declrt))
917- jl_error (" @ccallable: return type doesn't correspond to a C type" );
918-
919- // validate method signature
920- size_t i, nargs = jl_nparams (sigt);
921- for (i = 1 ; i < nargs; i++) {
922- jl_value_t *ati = jl_tparam (sigt, i);
923- if (!jl_is_concrete_type (ati) || jl_is_kind (ati) || !jl_type_mappable_to_c (ati))
924- jl_error (" @ccallable: argument types must be concrete" );
925- }
926-
927- // save a record of this so that the alias is generated when we write an object file
928- jl_method_t *meth = (jl_method_t *)jl_methtable_lookup (ft->name ->mt , (jl_value_t *)sigt, jl_atomic_load_acquire (&jl_world_counter));
929- if (!jl_is_method (meth))
930- jl_error (" @ccallable: could not find requested method" );
931- JL_GC_PUSH1 (&meth);
932- meth->ccallable = jl_svec2 (declrt, (jl_value_t *)sigt);
933- jl_gc_wb (meth, meth->ccallable );
934- JL_GC_POP ();
935-
936- // create the alias in the current runtime environment
937- int success = jl_compile_extern_c (NULL , NULL , NULL , declrt, (jl_value_t *)sigt);
938- if (!success)
939- jl_error (" @ccallable was already defined for this method name" );
940- }
941-
942808extern " C" JL_DLLEXPORT_CODEGEN
943809int jl_compile_codeinst_impl (jl_code_instance_t *ci)
944810{
0 commit comments