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