Function: module-load

module-load is a function defined in emacs-module.c.

Signature

(module-load FILE)

Documentation

Load module FILE.

Source Code

// Defined in /usr/src/emacs/src/emacs-module.c
{
  dynlib_handle_ptr handle;
  emacs_init_function module_init;
  void *gpl_sym;

  CHECK_STRING (file);
  handle = dynlib_open (SSDATA (file));
  if (!handle)
    xsignal2 (Qmodule_open_failed, file, build_string (dynlib_error ()));

  gpl_sym = dynlib_sym (handle, "plugin_is_GPL_compatible");
  if (!gpl_sym)
    xsignal1 (Qmodule_not_gpl_compatible, file);

  module_init = (emacs_init_function) dynlib_func (handle, "emacs_module_init");
  if (!module_init)
    xsignal1 (Qmissing_module_init_function, file);

  struct emacs_runtime rt_pub;
  struct emacs_runtime_private rt_priv;
  emacs_env env_pub;
  struct emacs_env_private env_priv;
  rt_priv.env = initialize_environment (&env_pub, &env_priv);

  /* If we should use module assertions, reallocate the runtime object
     from the free store, but never free it.  That way the addresses
     for two different runtime objects are guaranteed to be distinct,
     which we can use for checking the liveness of runtime
     pointers.  */
  struct emacs_runtime *rt;
  if (module_assertions)
    {
      rt = xmalloc (sizeof *rt);
      __lsan_ignore_object (rt);
    }
  else
    rt = &rt_pub;
  rt->size = sizeof *rt;
  rt->private_members = &rt_priv;
  rt->get_environment = module_get_environment;

  ptrdiff_t count = SPECPDL_INDEX ();
  record_unwind_protect_module (SPECPDL_MODULE_RUNTIME, rt);
  record_unwind_protect_module (SPECPDL_MODULE_ENVIRONMENT, rt_priv.env);

  int r = module_init (rt);

  /* Process the quit flag first, so that quitting doesn't get
     overridden by other non-local exits.  */
  maybe_quit ();

  if (r != 0)
    xsignal2 (Qmodule_init_failed, file, INT_TO_INTEGER (r));

  module_signal_or_throw (&env_priv);
  return unbind_to (count, Qt);
}