123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101open!Coreopen!ImportmoduleScheduler=Async_unix.Async_unix_private.Raw_schedulerletscheduler=Scheduler.t()moduleArity=structtype'callbackt=|Arity1:('a1->'r)t|Arity2:('a1->'a2->'r)t[@@derivingsexp_of]endopenAritytype'callbackt={arity:'callbackArity.t;name:string}[@@derivingsexp_of]letreport_exn_when_calling_callback=letout_of_memory_message="Ecaml received Out_of_memory"inletout_of_memory_value=out_of_memory_message|>Value.of_utf8_bytesinfunction|Out_of_memory->(tryValue.Private.message_zero_allocout_of_memory_valuewith|_->eprintf"%s"out_of_memory_message)|exn->letsexp=[%message"Ecaml callback handling raised"(exn:Exn.t)]in(tryValue.message_ssexpwith|_->eprint_ssexp);;letregistered_callbacks:Source_code_position.tString.Table.t=String.Table.create()letregister(typecallback)(t:callbackt)here~(f:callback)~should_run_holding_async_lock=(matchHashtbl.findregistered_callbackst.namewith|Somealready_registered_at->raise_s[%sexp"Multiple registrations for ecaml callback",{name:string=t.name;already_registered_at:Source_code_position.t;repeat_registration_at:Source_code_position.t=here}]|None->Hashtbl.setregistered_callbacks~key:t.name~data:here);letwith_lockf=ifScheduler.am_holding_lockschedulerthenf()elseScheduler.with_lockschedulerfinletcallback:callback=matcht.aritywith|Arity1->funa1->(tryifnotshould_run_holding_async_lockthenfa1elsewith_lock(fun()->fa1)with|exn->report_exn_when_calling_callbackexn;raiseexn)|Arity2->funa1a2->(tryifnotshould_run_holding_async_lockthenfa1a2elsewith_lock(fun()->fa1a2)with|exn->report_exn_when_calling_callbackexn;raiseexn)inCaml.Callback.registert.namecallback;;letdispatch_function={arity=Arity2;name="dispatch_function"}letend_of_module_initialization={arity=Arity1;name="end_of_module_initialization"};;(** [no_active_env] is used when the C code detects that OCaml is attempting to call an
Emacs function but there is no active env. It prints a message that includes an
OCaml backtrace, which may be useful in debugging. *)let()=register{arity=Arity1;name="no_active_env"}[%here]~f:(fun()->eprint_s[%message"Ecaml called with no active env"~backtrace:(Backtrace.get():Backtrace.t)])~should_run_holding_async_lock:true;;letfree_embedded_caml_values={arity=Arity1;name="free_embedded_caml_values"}