Avoid compiler warnings
[emacs.git] / src / emacs-module.c
blob724d24a77688aa0249006e92e2f66d5ae2ab9b42
1 /* emacs-module.c - Module loading and runtime implementation
3 Copyright (C) 2015-2016 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or (at
10 your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 #include <config.h>
22 #include "emacs-module.h"
24 #include <stdbool.h>
25 #include <stddef.h>
26 #include <stdint.h>
27 #include <stdio.h>
28 #include <string.h>
30 #include "lisp.h"
31 #include "dynlib.h"
32 #include "coding.h"
33 #include "verify.h"
36 /* Feature tests. */
38 #if __has_attribute (cleanup)
39 enum { module_has_cleanup = true };
40 #else
41 enum { module_has_cleanup = false };
42 #endif
44 /* Handle to the main thread. Used to verify that modules call us in
45 the right thread. */
46 #ifdef HAVE_PTHREAD
47 # include <pthread.h>
48 static pthread_t main_thread;
49 #elif defined WINDOWSNT
50 #include <windows.h>
51 #include "w32term.h"
52 static DWORD main_thread;
53 #endif
55 /* True if Lisp_Object and emacs_value have the same representation.
56 This is typically true unless WIDE_EMACS_INT. In practice, having
57 the same sizes and alignments and maximums should be a good enough
58 proxy for equality of representation. */
59 enum
61 plain_values
62 = (sizeof (Lisp_Object) == sizeof (emacs_value)
63 && alignof (Lisp_Object) == alignof (emacs_value)
64 && INTPTR_MAX == EMACS_INT_MAX)
67 /* Function prototype for the module init function. */
68 typedef int (*emacs_init_function) (struct emacs_runtime *);
70 /* Function prototype for the module Lisp functions. */
71 typedef emacs_value (*emacs_subr) (emacs_env *, ptrdiff_t,
72 emacs_value [], void *);
74 /* Function prototype for module user-pointer finalizers. These
75 should not throw C++ exceptions, so emacs-module.h declares the
76 corresponding interfaces with EMACS_NOEXCEPT. There is only C code
77 in this module, though, so this constraint is not enforced here. */
78 typedef void (*emacs_finalizer_function) (void *);
81 /* Private runtime and environment members. */
83 /* The private part of an environment stores the current non local exit state
84 and holds the `emacs_value' objects allocated during the lifetime
85 of the environment. */
86 struct emacs_env_private
88 enum emacs_funcall_exit pending_non_local_exit;
90 /* Dedicated storage for non-local exit symbol and data so that
91 storage is always available for them, even in an out-of-memory
92 situation. */
93 Lisp_Object non_local_exit_symbol, non_local_exit_data;
96 /* The private parts of an `emacs_runtime' object contain the initial
97 environment. */
98 struct emacs_runtime_private
100 /* FIXME: Ideally, we would just define "struct emacs_runtime_private"
101 as a synonym of "emacs_env", but I don't know how to do that in C. */
102 emacs_env pub;
106 /* Forward declarations. */
108 struct module_fun_env;
110 static Lisp_Object module_format_fun_env (const struct module_fun_env *);
111 static Lisp_Object value_to_lisp (emacs_value);
112 static emacs_value lisp_to_value (Lisp_Object);
113 static enum emacs_funcall_exit module_non_local_exit_check (emacs_env *);
114 static void check_main_thread (void);
115 static void finalize_environment (struct emacs_env_private *);
116 static void initialize_environment (emacs_env *, struct emacs_env_private *priv);
117 static void module_handle_signal (emacs_env *, Lisp_Object);
118 static void module_handle_throw (emacs_env *, Lisp_Object);
119 static void module_non_local_exit_signal_1 (emacs_env *, Lisp_Object, Lisp_Object);
120 static void module_non_local_exit_throw_1 (emacs_env *, Lisp_Object, Lisp_Object);
121 static void module_out_of_memory (emacs_env *);
122 static void module_reset_handlerlist (const int *);
124 /* We used to return NULL when emacs_value was a different type from
125 Lisp_Object, but nowadays we just use Qnil instead. Although they
126 happen to be the same thing in the current implementation, module
127 code should not assume this. */
128 verify (NIL_IS_ZERO);
129 static emacs_value const module_nil = 0;
131 /* Convenience macros for non-local exit handling. */
133 /* FIXME: The following implementation for non-local exit handling
134 does not support recovery from stack overflow, see sysdep.c. */
136 /* Emacs uses setjmp and longjmp for non-local exits, but
137 module frames cannot be skipped because they are in general
138 not prepared for long jumps (e.g., the behavior in C++ is undefined
139 if objects with nontrivial destructors would be skipped).
140 Therefore, catch all non-local exits. There are two kinds of
141 non-local exits: `signal' and `throw'. The macros in this section
142 can be used to catch both. Use macros to avoid additional variants
143 of `internal_condition_case' etc., and to avoid worrying about
144 passing information to the handler functions. */
146 /* Place this macro at the beginning of a function returning a number
147 or a pointer to handle non-local exits. The function must have an
148 ENV parameter. The function will return the specified value if a
149 signal or throw is caught. */
150 // TODO: Have Fsignal check for CATCHER_ALL so we only have to install
151 // one handler.
152 #define MODULE_HANDLE_NONLOCAL_EXIT(retval) \
153 MODULE_SETJMP (CONDITION_CASE, module_handle_signal, retval); \
154 MODULE_SETJMP (CATCHER_ALL, module_handle_throw, retval)
156 #define MODULE_SETJMP(handlertype, handlerfunc, retval) \
157 MODULE_SETJMP_1 (handlertype, handlerfunc, retval, \
158 internal_handler_##handlertype, \
159 internal_cleanup_##handlertype)
161 /* It is very important that pushing the handler doesn't itself raise
162 a signal. Install the cleanup only after the handler has been
163 pushed. Use __attribute__ ((cleanup)) to avoid
164 non-local-exit-prone manual cleanup.
166 The do-while forces uses of the macro to be followed by a semicolon.
167 This macro cannot enclose its entire body inside a do-while, as the
168 code after the macro may longjmp back into the macro, which means
169 its local variable C must stay live in later code. */
171 // TODO: Make backtraces work if this macros is used.
173 #define MODULE_SETJMP_1(handlertype, handlerfunc, retval, c, dummy) \
174 if (module_non_local_exit_check (env) != emacs_funcall_exit_return) \
175 return retval; \
176 struct handler *c = push_handler_nosignal (Qt, handlertype); \
177 if (!c) \
179 module_out_of_memory (env); \
180 return retval; \
182 verify (module_has_cleanup); \
183 int dummy __attribute__ ((cleanup (module_reset_handlerlist))); \
184 if (sys_setjmp (c->jmp)) \
186 (handlerfunc) (env, c->val); \
187 return retval; \
189 do { } while (false)
192 /* Function environments. */
194 /* A function environment is an auxiliary structure used by
195 `module_make_function' to store information about a module
196 function. It is stored in a save pointer and retrieved by
197 `internal--module-call'. Its members correspond to the arguments
198 given to `module_make_function'. */
200 struct module_fun_env
202 ptrdiff_t min_arity, max_arity;
203 emacs_subr subr;
204 void *data;
208 /* Implementation of runtime and environment functions.
210 These should abide by the following rules:
212 1. The first argument should always be a pointer to emacs_env.
214 2. Each function should first call check_main_thread. Note that
215 this function is a no-op unless Emacs was built with
216 --enable-checking.
218 3. The very next thing each function should do is check that the
219 emacs_env object does not have a non-local exit indication set,
220 by calling module_non_local_exit_check. If that returns
221 anything but emacs_funcall_exit_return, the function should do
222 nothing and return immediately with an error indication, without
223 clobbering the existing error indication in emacs_env. This is
224 needed for correct reporting of Lisp errors to the Emacs Lisp
225 interpreter.
227 4. Any function that needs to call Emacs facilities, such as
228 encoding or decoding functions, or 'intern', or 'make_string',
229 should protect itself from signals and 'throw' in the called
230 Emacs functions, by placing the macro
231 MODULE_HANDLE_NONLOCAL_EXIT right after the above 2 tests.
233 5. Do NOT use 'eassert' for checking validity of user code in the
234 module. Instead, make those checks part of the code, and if the
235 check fails, call 'module_non_local_exit_signal_1' or
236 'module_non_local_exit_throw_1' to report the error. This is
237 because using 'eassert' in these situations will abort Emacs
238 instead of reporting the error back to Lisp, and also because
239 'eassert' is compiled to nothing in the release version. */
241 /* Use MODULE_FUNCTION_BEGIN to implement steps 2 through 4 for most
242 environment functions. On error it will return its argument, which
243 should be a sentinel value. */
245 #define MODULE_FUNCTION_BEGIN(error_retval) \
246 check_main_thread (); \
247 if (module_non_local_exit_check (env) != emacs_funcall_exit_return) \
248 return error_retval; \
249 MODULE_HANDLE_NONLOCAL_EXIT (error_retval)
251 static void
252 CHECK_USER_PTR (Lisp_Object obj)
254 CHECK_TYPE (USER_PTRP (obj), Quser_ptrp, obj);
257 /* Catch signals and throws only if the code can actually signal or
258 throw. If checking is enabled, abort if the current thread is not
259 the Emacs main thread. */
261 static emacs_env *
262 module_get_environment (struct emacs_runtime *ert)
264 check_main_thread ();
265 return &ert->private_members->pub;
268 /* To make global refs (GC-protected global values) keep a hash that
269 maps global Lisp objects to reference counts. */
271 static emacs_value
272 module_make_global_ref (emacs_env *env, emacs_value ref)
274 MODULE_FUNCTION_BEGIN (module_nil);
275 struct Lisp_Hash_Table *h = XHASH_TABLE (Vmodule_refs_hash);
276 Lisp_Object new_obj = value_to_lisp (ref);
277 EMACS_UINT hashcode;
278 ptrdiff_t i = hash_lookup (h, new_obj, &hashcode);
280 if (i >= 0)
282 Lisp_Object value = HASH_VALUE (h, i);
283 EMACS_INT refcount = XFASTINT (value) + 1;
284 if (MOST_POSITIVE_FIXNUM < refcount)
285 xsignal0 (Qoverflow_error);
286 value = make_natnum (refcount);
287 set_hash_value_slot (h, i, value);
289 else
291 hash_put (h, new_obj, make_natnum (1), hashcode);
294 return lisp_to_value (new_obj);
297 static void
298 module_free_global_ref (emacs_env *env, emacs_value ref)
300 /* TODO: This probably never signals. */
301 /* FIXME: Wait a minute. Shouldn't this function report an error if
302 the hash lookup fails? */
303 MODULE_FUNCTION_BEGIN ();
304 struct Lisp_Hash_Table *h = XHASH_TABLE (Vmodule_refs_hash);
305 Lisp_Object obj = value_to_lisp (ref);
306 EMACS_UINT hashcode;
307 ptrdiff_t i = hash_lookup (h, obj, &hashcode);
309 if (i >= 0)
311 Lisp_Object value = HASH_VALUE (h, i);
312 EMACS_INT refcount = XFASTINT (value) - 1;
313 if (refcount > 0)
315 value = make_natnum (refcount);
316 set_hash_value_slot (h, i, value);
318 else
319 hash_remove_from_table (h, value);
323 static enum emacs_funcall_exit
324 module_non_local_exit_check (emacs_env *env)
326 check_main_thread ();
327 return env->private_members->pending_non_local_exit;
330 static void
331 module_non_local_exit_clear (emacs_env *env)
333 check_main_thread ();
334 env->private_members->pending_non_local_exit = emacs_funcall_exit_return;
337 static enum emacs_funcall_exit
338 module_non_local_exit_get (emacs_env *env, emacs_value *sym, emacs_value *data)
340 check_main_thread ();
341 struct emacs_env_private *p = env->private_members;
342 if (p->pending_non_local_exit != emacs_funcall_exit_return)
344 /* FIXME: lisp_to_value can exit non-locally. */
345 *sym = lisp_to_value (p->non_local_exit_symbol);
346 *data = lisp_to_value (p->non_local_exit_data);
348 return p->pending_non_local_exit;
351 /* Like for `signal', DATA must be a list. */
352 static void
353 module_non_local_exit_signal (emacs_env *env, emacs_value sym, emacs_value data)
355 check_main_thread ();
356 if (module_non_local_exit_check (env) == emacs_funcall_exit_return)
357 module_non_local_exit_signal_1 (env, value_to_lisp (sym),
358 value_to_lisp (data));
361 static void
362 module_non_local_exit_throw (emacs_env *env, emacs_value tag, emacs_value value)
364 check_main_thread ();
365 if (module_non_local_exit_check (env) == emacs_funcall_exit_return)
366 module_non_local_exit_throw_1 (env, value_to_lisp (tag),
367 value_to_lisp (value));
370 /* A module function is lambda function that calls
371 `internal--module-call', passing the function pointer of the module
372 function along with the module emacs_env pointer as arguments.
374 (function (lambda (&rest arglist)
375 (internal--module-call envobj arglist))) */
377 static emacs_value
378 module_make_function (emacs_env *env, ptrdiff_t min_arity, ptrdiff_t max_arity,
379 emacs_subr subr, const char *documentation,
380 void *data)
382 MODULE_FUNCTION_BEGIN (module_nil);
384 if (! (0 <= min_arity
385 && (max_arity < 0
386 ? max_arity == emacs_variadic_function
387 : min_arity <= max_arity)))
388 xsignal2 (Qinvalid_arity, make_number (min_arity), make_number (max_arity));
390 /* FIXME: This should be freed when envobj is GC'd. */
391 struct module_fun_env *envptr = xmalloc (sizeof *envptr);
392 envptr->min_arity = min_arity;
393 envptr->max_arity = max_arity;
394 envptr->subr = subr;
395 envptr->data = data;
397 Lisp_Object envobj = make_save_ptr (envptr);
398 Lisp_Object doc = Qnil;
399 if (documentation)
401 AUTO_STRING (unibyte_doc, documentation);
402 doc = code_convert_string_norecord (unibyte_doc, Qutf_8, false);
405 /* FIXME: Use a bytecompiled object, or even better a subr. */
406 Lisp_Object ret = list4 (Qlambda,
407 list2 (Qand_rest, Qargs),
408 doc,
409 list4 (Qapply,
410 list2 (Qfunction, Qinternal__module_call),
411 envobj,
412 Qargs));
414 return lisp_to_value (ret);
417 static emacs_value
418 module_funcall (emacs_env *env, emacs_value fun, ptrdiff_t nargs,
419 emacs_value args[])
421 MODULE_FUNCTION_BEGIN (module_nil);
423 /* Make a new Lisp_Object array starting with the function as the
424 first arg, because that's what Ffuncall takes. */
425 Lisp_Object *newargs;
426 USE_SAFE_ALLOCA;
427 if (nargs == PTRDIFF_MAX)
428 xsignal0 (Qoverflow_error);
429 SAFE_ALLOCA_LISP (newargs, nargs + 1);
430 newargs[0] = value_to_lisp (fun);
431 for (ptrdiff_t i = 0; i < nargs; i++)
432 newargs[1 + i] = value_to_lisp (args[i]);
433 emacs_value result = lisp_to_value (Ffuncall (nargs + 1, newargs));
434 SAFE_FREE ();
435 return result;
438 static emacs_value
439 module_intern (emacs_env *env, const char *name)
441 MODULE_FUNCTION_BEGIN (module_nil);
442 return lisp_to_value (intern (name));
445 static emacs_value
446 module_type_of (emacs_env *env, emacs_value value)
448 MODULE_FUNCTION_BEGIN (module_nil);
449 return lisp_to_value (Ftype_of (value_to_lisp (value)));
452 static bool
453 module_is_not_nil (emacs_env *env, emacs_value value)
455 check_main_thread ();
456 if (module_non_local_exit_check (env) != emacs_funcall_exit_return)
457 return false;
458 return ! NILP (value_to_lisp (value));
461 static bool
462 module_eq (emacs_env *env, emacs_value a, emacs_value b)
464 check_main_thread ();
465 if (module_non_local_exit_check (env) != emacs_funcall_exit_return)
466 return false;
467 return EQ (value_to_lisp (a), value_to_lisp (b));
470 static intmax_t
471 module_extract_integer (emacs_env *env, emacs_value n)
473 MODULE_FUNCTION_BEGIN (0);
474 Lisp_Object l = value_to_lisp (n);
475 CHECK_NUMBER (l);
476 return XINT (l);
479 static emacs_value
480 module_make_integer (emacs_env *env, intmax_t n)
482 MODULE_FUNCTION_BEGIN (module_nil);
483 if (FIXNUM_OVERFLOW_P (n))
484 xsignal0 (Qoverflow_error);
485 return lisp_to_value (make_number (n));
488 static double
489 module_extract_float (emacs_env *env, emacs_value f)
491 MODULE_FUNCTION_BEGIN (0);
492 Lisp_Object lisp = value_to_lisp (f);
493 CHECK_TYPE (FLOATP (lisp), Qfloatp, lisp);
494 return XFLOAT_DATA (lisp);
497 static emacs_value
498 module_make_float (emacs_env *env, double d)
500 MODULE_FUNCTION_BEGIN (module_nil);
501 return lisp_to_value (make_float (d));
504 static bool
505 module_copy_string_contents (emacs_env *env, emacs_value value, char *buffer,
506 ptrdiff_t *length)
508 MODULE_FUNCTION_BEGIN (false);
509 Lisp_Object lisp_str = value_to_lisp (value);
510 CHECK_STRING (lisp_str);
512 Lisp_Object lisp_str_utf8 = ENCODE_UTF_8 (lisp_str);
513 ptrdiff_t raw_size = SBYTES (lisp_str_utf8);
514 ptrdiff_t required_buf_size = raw_size + 1;
516 eassert (length != NULL);
518 if (buffer == NULL)
520 *length = required_buf_size;
521 return true;
524 eassert (*length >= 0);
526 if (*length < required_buf_size)
528 *length = required_buf_size;
529 xsignal0 (Qargs_out_of_range);
532 *length = required_buf_size;
533 memcpy (buffer, SDATA (lisp_str_utf8), raw_size + 1);
535 return true;
538 static emacs_value
539 module_make_string (emacs_env *env, const char *str, ptrdiff_t length)
541 MODULE_FUNCTION_BEGIN (module_nil);
542 AUTO_STRING_WITH_LEN (lstr, str, length);
543 return lisp_to_value (code_convert_string_norecord (lstr, Qutf_8, false));
546 static emacs_value
547 module_make_user_ptr (emacs_env *env, emacs_finalizer_function fin, void *ptr)
549 MODULE_FUNCTION_BEGIN (module_nil);
550 return lisp_to_value (make_user_ptr (fin, ptr));
553 static void *
554 module_get_user_ptr (emacs_env *env, emacs_value uptr)
556 MODULE_FUNCTION_BEGIN (NULL);
557 Lisp_Object lisp = value_to_lisp (uptr);
558 CHECK_USER_PTR (lisp);
559 return XUSER_PTR (lisp)->p;
562 static void
563 module_set_user_ptr (emacs_env *env, emacs_value uptr, void *ptr)
565 /* FIXME: This function should return bool because it can fail. */
566 MODULE_FUNCTION_BEGIN ();
567 Lisp_Object lisp = value_to_lisp (uptr);
568 CHECK_USER_PTR (lisp);
569 XUSER_PTR (lisp)->p = ptr;
572 static emacs_finalizer_function
573 module_get_user_finalizer (emacs_env *env, emacs_value uptr)
575 MODULE_FUNCTION_BEGIN (NULL);
576 Lisp_Object lisp = value_to_lisp (uptr);
577 CHECK_USER_PTR (lisp);
578 return XUSER_PTR (lisp)->finalizer;
581 static void
582 module_set_user_finalizer (emacs_env *env, emacs_value uptr,
583 emacs_finalizer_function fin)
585 /* FIXME: This function should return bool because it can fail. */
586 MODULE_FUNCTION_BEGIN ();
587 Lisp_Object lisp = value_to_lisp (uptr);
588 CHECK_USER_PTR (lisp);
589 XUSER_PTR (lisp)->finalizer = fin;
592 static void
593 check_vec_index (Lisp_Object lvec, ptrdiff_t i)
595 CHECK_VECTOR (lvec);
596 if (! (0 <= i && i < ASIZE (lvec)))
597 args_out_of_range_3 (make_fixnum_or_float (i),
598 make_number (0), make_number (ASIZE (lvec) - 1));
601 static void
602 module_vec_set (emacs_env *env, emacs_value vec, ptrdiff_t i, emacs_value val)
604 /* FIXME: This function should return bool because it can fail. */
605 MODULE_FUNCTION_BEGIN ();
606 Lisp_Object lvec = value_to_lisp (vec);
607 check_vec_index (lvec, i);
608 ASET (lvec, i, value_to_lisp (val));
611 static emacs_value
612 module_vec_get (emacs_env *env, emacs_value vec, ptrdiff_t i)
614 MODULE_FUNCTION_BEGIN (module_nil);
615 Lisp_Object lvec = value_to_lisp (vec);
616 check_vec_index (lvec, i);
617 return lisp_to_value (AREF (lvec, i));
620 static ptrdiff_t
621 module_vec_size (emacs_env *env, emacs_value vec)
623 /* FIXME: Return a sentinel value (e.g., -1) on error. */
624 MODULE_FUNCTION_BEGIN (0);
625 Lisp_Object lvec = value_to_lisp (vec);
626 CHECK_VECTOR (lvec);
627 return ASIZE (lvec);
631 /* Subroutines. */
633 DEFUN ("module-load", Fmodule_load, Smodule_load, 1, 1, 0,
634 doc: /* Load module FILE. */)
635 (Lisp_Object file)
637 dynlib_handle_ptr handle;
638 emacs_init_function module_init;
639 void *gpl_sym;
641 CHECK_STRING (file);
642 handle = dynlib_open (SSDATA (file));
643 if (!handle)
644 error ("Cannot load file %s: %s", SDATA (file), dynlib_error ());
646 gpl_sym = dynlib_sym (handle, "plugin_is_GPL_compatible");
647 if (!gpl_sym)
648 error ("Module %s is not GPL compatible", SDATA (file));
650 module_init = (emacs_init_function) dynlib_func (handle, "emacs_module_init");
651 if (!module_init)
652 error ("Module %s does not have an init function.", SDATA (file));
654 struct emacs_runtime_private rt; /* Includes the public emacs_env. */
655 struct emacs_env_private priv;
656 initialize_environment (&rt.pub, &priv);
657 struct emacs_runtime pub =
659 .size = sizeof pub,
660 .private_members = &rt,
661 .get_environment = module_get_environment
663 int r = module_init (&pub);
664 finalize_environment (&priv);
666 if (r != 0)
668 if (! (MOST_NEGATIVE_FIXNUM <= r && r <= MOST_POSITIVE_FIXNUM))
669 xsignal0 (Qoverflow_error);
670 xsignal2 (Qmodule_load_failed, file, make_number (r));
673 return Qt;
676 DEFUN ("internal--module-call", Finternal_module_call, Sinternal_module_call, 1, MANY, 0,
677 doc: /* Internal function to call a module function.
678 ENVOBJ is a save pointer to a module_fun_env structure.
679 ARGLIST is a list of arguments passed to SUBRPTR.
680 usage: (module-call ENVOBJ &rest ARGLIST) */)
681 (ptrdiff_t nargs, Lisp_Object *arglist)
683 Lisp_Object envobj = arglist[0];
684 /* FIXME: Rather than use a save_value, we should create a new object type.
685 Making save_value visible to Lisp is wrong. */
686 CHECK_TYPE (SAVE_VALUEP (envobj), Qsave_value_p, envobj);
687 struct Lisp_Save_Value *save_value = XSAVE_VALUE (envobj);
688 CHECK_TYPE (save_type (save_value, 0) == SAVE_POINTER, Qsave_pointer_p, envobj);
689 /* FIXME: We have no reason to believe that XSAVE_POINTER (envobj, 0)
690 is a module_fun_env pointer. If some other part of Emacs also
691 exports save_value objects to Elisp, than we may be getting here this
692 other kind of save_value which will likely hold something completely
693 different in this field. */
694 struct module_fun_env *envptr = XSAVE_POINTER (envobj, 0);
695 EMACS_INT len = nargs - 1;
696 eassume (0 <= envptr->min_arity);
697 if (! (envptr->min_arity <= len
698 && len <= (envptr->max_arity < 0 ? PTRDIFF_MAX : envptr->max_arity)))
699 xsignal2 (Qwrong_number_of_arguments, module_format_fun_env (envptr),
700 make_number (len));
702 emacs_env pub;
703 struct emacs_env_private priv;
704 initialize_environment (&pub, &priv);
706 USE_SAFE_ALLOCA;
707 emacs_value *args;
708 if (plain_values)
709 args = (emacs_value *) arglist + 1;
710 else
712 args = SAFE_ALLOCA (len * sizeof *args);
713 for (ptrdiff_t i = 0; i < len; i++)
714 args[i] = lisp_to_value (arglist[i + 1]);
717 emacs_value ret = envptr->subr (&pub, len, args, envptr->data);
718 SAFE_FREE ();
720 eassert (&priv == pub.private_members);
722 switch (priv.pending_non_local_exit)
724 case emacs_funcall_exit_return:
725 finalize_environment (&priv);
726 return value_to_lisp (ret);
727 case emacs_funcall_exit_signal:
729 Lisp_Object symbol = priv.non_local_exit_symbol;
730 Lisp_Object data = priv.non_local_exit_data;
731 finalize_environment (&priv);
732 xsignal (symbol, data);
734 case emacs_funcall_exit_throw:
736 Lisp_Object tag = priv.non_local_exit_symbol;
737 Lisp_Object value = priv.non_local_exit_data;
738 finalize_environment (&priv);
739 Fthrow (tag, value);
741 default:
742 eassume (false);
747 /* Helper functions. */
749 static void
750 check_main_thread (void)
752 #ifdef HAVE_PTHREAD
753 eassert (pthread_equal (pthread_self (), main_thread));
754 #elif defined WINDOWSNT
755 eassert (GetCurrentThreadId () == main_thread);
756 #endif
759 static void
760 module_non_local_exit_signal_1 (emacs_env *env, Lisp_Object sym,
761 Lisp_Object data)
763 struct emacs_env_private *p = env->private_members;
764 if (p->pending_non_local_exit == emacs_funcall_exit_return)
766 p->pending_non_local_exit = emacs_funcall_exit_signal;
767 p->non_local_exit_symbol = sym;
768 p->non_local_exit_data = data;
772 static void
773 module_non_local_exit_throw_1 (emacs_env *env, Lisp_Object tag,
774 Lisp_Object value)
776 struct emacs_env_private *p = env->private_members;
777 if (p->pending_non_local_exit == emacs_funcall_exit_return)
779 p->pending_non_local_exit = emacs_funcall_exit_throw;
780 p->non_local_exit_symbol = tag;
781 p->non_local_exit_data = value;
785 /* Signal an out-of-memory condition to the caller. */
786 static void
787 module_out_of_memory (emacs_env *env)
789 /* TODO: Reimplement this so it works even if memory-signal-data has
790 been modified. */
791 module_non_local_exit_signal_1 (env, XCAR (Vmemory_signal_data),
792 XCDR (Vmemory_signal_data));
796 /* Value conversion. */
798 /* Unique Lisp_Object used to mark those emacs_values which are really
799 just containers holding a Lisp_Object that does not fit as an emacs_value,
800 either because it is an integer out of range, or is not properly aligned.
801 Used only if !plain_values. */
802 static Lisp_Object ltv_mark;
804 /* Convert V to the corresponding internal object O, such that
805 V == lisp_to_value_bits (O). Never fails. */
806 static Lisp_Object
807 value_to_lisp_bits (emacs_value v)
809 intptr_t i = (intptr_t) v;
810 if (plain_values || USE_LSB_TAG)
811 return XIL (i);
813 /* With wide EMACS_INT and when tag bits are the most significant,
814 reassembling integers differs from reassembling pointers in two
815 ways. First, save and restore the least-significant bits of the
816 integer, not the most-significant bits. Second, sign-extend the
817 integer when restoring, but zero-extend pointers because that
818 makes TAG_PTR faster. */
820 EMACS_UINT tag = i & (GCALIGNMENT - 1);
821 EMACS_UINT untagged = i - tag;
822 switch (tag)
824 case_Lisp_Int:
826 bool negative = tag & 1;
827 EMACS_UINT sign_extension
828 = negative ? VALMASK & ~(INTPTR_MAX >> INTTYPEBITS): 0;
829 uintptr_t u = i;
830 intptr_t all_but_sign = u >> GCTYPEBITS;
831 untagged = sign_extension + all_but_sign;
832 break;
836 return XIL ((tag << VALBITS) + untagged);
839 /* If V was computed from lisp_to_value (O), then return O.
840 Exits non-locally only if the stack overflows. */
841 static Lisp_Object
842 value_to_lisp (emacs_value v)
844 Lisp_Object o = value_to_lisp_bits (v);
845 if (! plain_values && CONSP (o) && EQ (XCDR (o), ltv_mark))
846 o = XCAR (o);
847 return o;
850 /* Attempt to convert O to an emacs_value. Do not do any checking or
851 or allocate any storage; the caller should prevent or detect
852 any resulting bit pattern that is not a valid emacs_value. */
853 static emacs_value
854 lisp_to_value_bits (Lisp_Object o)
856 EMACS_UINT u = XLI (o);
858 /* Compress U into the space of a pointer, possibly losing information. */
859 uintptr_t p = (plain_values || USE_LSB_TAG
861 : (INTEGERP (o) ? u << VALBITS : u & VALMASK) + XTYPE (o));
862 return (emacs_value) p;
865 #ifndef HAVE_STRUCT_ATTRIBUTE_ALIGNED
866 enum { HAVE_STRUCT_ATTRIBUTE_ALIGNED = 0 };
867 #endif
869 /* Convert O to an emacs_value. Allocate storage if needed; this can
870 signal if memory is exhausted. Must be an injective function. */
871 static emacs_value
872 lisp_to_value (Lisp_Object o)
874 emacs_value v = lisp_to_value_bits (o);
876 if (! EQ (o, value_to_lisp_bits (v)))
878 /* Package the incompressible object pointer inside a pair
879 that is compressible. */
880 Lisp_Object pair = Fcons (o, ltv_mark);
882 if (! HAVE_STRUCT_ATTRIBUTE_ALIGNED)
884 /* Keep calling Fcons until it returns a compressible pair.
885 This shouldn't take long. */
886 while ((intptr_t) XCONS (pair) & (GCALIGNMENT - 1))
887 pair = Fcons (o, pair);
889 /* Plant the mark. The garbage collector will eventually
890 reclaim any just-allocated incompressible pairs. */
891 XSETCDR (pair, ltv_mark);
894 v = (emacs_value) ((intptr_t) XCONS (pair) + Lisp_Cons);
897 eassert (EQ (o, value_to_lisp (v)));
898 return v;
902 /* Environment lifetime management. */
904 /* Must be called before the environment can be used. */
905 static void
906 initialize_environment (emacs_env *env, struct emacs_env_private *priv)
908 priv->pending_non_local_exit = emacs_funcall_exit_return;
909 env->size = sizeof *env;
910 env->private_members = priv;
911 env->make_global_ref = module_make_global_ref;
912 env->free_global_ref = module_free_global_ref;
913 env->non_local_exit_check = module_non_local_exit_check;
914 env->non_local_exit_clear = module_non_local_exit_clear;
915 env->non_local_exit_get = module_non_local_exit_get;
916 env->non_local_exit_signal = module_non_local_exit_signal;
917 env->non_local_exit_throw = module_non_local_exit_throw;
918 env->make_function = module_make_function;
919 env->funcall = module_funcall;
920 env->intern = module_intern;
921 env->type_of = module_type_of;
922 env->is_not_nil = module_is_not_nil;
923 env->eq = module_eq;
924 env->extract_integer = module_extract_integer;
925 env->make_integer = module_make_integer;
926 env->extract_float = module_extract_float;
927 env->make_float = module_make_float;
928 env->copy_string_contents = module_copy_string_contents;
929 env->make_string = module_make_string;
930 env->make_user_ptr = module_make_user_ptr;
931 env->get_user_ptr = module_get_user_ptr;
932 env->set_user_ptr = module_set_user_ptr;
933 env->get_user_finalizer = module_get_user_finalizer;
934 env->set_user_finalizer = module_set_user_finalizer;
935 env->vec_set = module_vec_set;
936 env->vec_get = module_vec_get;
937 env->vec_size = module_vec_size;
938 Vmodule_environments = Fcons (make_save_ptr (env), Vmodule_environments);
941 /* Must be called before the lifetime of the environment object
942 ends. */
943 static void
944 finalize_environment (struct emacs_env_private *env)
946 Vmodule_environments = XCDR (Vmodule_environments);
950 /* Non-local exit handling. */
952 /* Must be called after setting up a handler immediately before
953 returning from the function. See the comments in lisp.h and the
954 code in eval.c for details. The macros below arrange for this
955 function to be called automatically. DUMMY is ignored. */
956 static void
957 module_reset_handlerlist (const int *dummy)
959 handlerlist = handlerlist->next;
962 /* Called on `signal'. ERR is a pair (SYMBOL . DATA), which gets
963 stored in the environment. Set the pending non-local exit flag. */
964 static void
965 module_handle_signal (emacs_env *env, Lisp_Object err)
967 module_non_local_exit_signal_1 (env, XCAR (err), XCDR (err));
970 /* Called on `throw'. TAG_VAL is a pair (TAG . VALUE), which gets
971 stored in the environment. Set the pending non-local exit flag. */
972 static void
973 module_handle_throw (emacs_env *env, Lisp_Object tag_val)
975 module_non_local_exit_throw_1 (env, XCAR (tag_val), XCDR (tag_val));
979 /* Function environments. */
981 /* Return a string object that contains a user-friendly
982 representation of the function environment. */
983 static Lisp_Object
984 module_format_fun_env (const struct module_fun_env *env)
986 /* Try to print a function name if possible. */
987 const char *path, *sym;
988 static char const noaddr_format[] = "#<module function at %p>";
989 char buffer[sizeof noaddr_format + INT_STRLEN_BOUND (intptr_t) + 256];
990 char *buf = buffer;
991 ptrdiff_t bufsize = sizeof buffer;
992 ptrdiff_t size
993 = (dynlib_addr (env->subr, &path, &sym)
994 ? exprintf (&buf, &bufsize, buffer, -1,
995 "#<module function %s from %s>", sym, path)
996 : sprintf (buffer, noaddr_format, env->subr));
997 AUTO_STRING_WITH_LEN (unibyte_result, buffer, size);
998 Lisp_Object result = code_convert_string_norecord (unibyte_result,
999 Qutf_8, false);
1000 if (buf != buffer)
1001 xfree (buf);
1002 return result;
1006 /* Segment initializer. */
1008 void
1009 syms_of_module (void)
1011 if (!plain_values)
1012 ltv_mark = Fcons (Qnil, Qnil);
1013 eassert (NILP (value_to_lisp (module_nil)));
1015 DEFSYM (Qmodule_refs_hash, "module-refs-hash");
1016 DEFVAR_LISP ("module-refs-hash", Vmodule_refs_hash,
1017 doc: /* Module global reference table. */);
1019 Vmodule_refs_hash
1020 = make_hash_table (hashtest_eq, make_number (DEFAULT_HASH_SIZE),
1021 make_float (DEFAULT_REHASH_SIZE),
1022 make_float (DEFAULT_REHASH_THRESHOLD),
1023 Qnil);
1024 Funintern (Qmodule_refs_hash, Qnil);
1026 DEFSYM (Qmodule_environments, "module-environments");
1027 DEFVAR_LISP ("module-environments", Vmodule_environments,
1028 doc: /* List of active module environments. */);
1029 Vmodule_environments = Qnil;
1030 /* Unintern `module-environments' because it is only used
1031 internally. */
1032 Funintern (Qmodule_environments, Qnil);
1034 DEFSYM (Qmodule_load_failed, "module-load-failed");
1035 Fput (Qmodule_load_failed, Qerror_conditions,
1036 listn (CONSTYPE_PURE, 2, Qmodule_load_failed, Qerror));
1037 Fput (Qmodule_load_failed, Qerror_message,
1038 build_pure_c_string ("Module load failed"));
1040 DEFSYM (Qinvalid_module_call, "invalid-module-call");
1041 Fput (Qinvalid_module_call, Qerror_conditions,
1042 listn (CONSTYPE_PURE, 2, Qinvalid_module_call, Qerror));
1043 Fput (Qinvalid_module_call, Qerror_message,
1044 build_pure_c_string ("Invalid module call"));
1046 DEFSYM (Qinvalid_arity, "invalid-arity");
1047 Fput (Qinvalid_arity, Qerror_conditions,
1048 listn (CONSTYPE_PURE, 2, Qinvalid_arity, Qerror));
1049 Fput (Qinvalid_arity, Qerror_message,
1050 build_pure_c_string ("Invalid function arity"));
1052 /* Unintern `module-refs-hash' because it is internal-only and Lisp
1053 code or modules should not access it. */
1054 Funintern (Qmodule_refs_hash, Qnil);
1056 DEFSYM (Qsave_value_p, "save-value-p");
1057 DEFSYM (Qsave_pointer_p, "save-pointer-p");
1059 defsubr (&Smodule_load);
1061 DEFSYM (Qinternal__module_call, "internal--module-call");
1062 defsubr (&Sinternal_module_call);
1065 /* Unlike syms_of_module, this initializer is called even from an
1066 initialized (dumped) Emacs. */
1068 void
1069 module_init (void)
1071 /* It is not guaranteed that dynamic initializers run in the main thread,
1072 therefore detect the main thread here. */
1073 #ifdef HAVE_PTHREAD
1074 main_thread = pthread_self ();
1075 #elif defined WINDOWSNT
1076 /* The 'main' function already recorded the main thread's thread ID,
1077 so we need just to use it . */
1078 main_thread = dwMainThreadId;
1079 #endif