1 /* emacs-module.c - Module loading and runtime implementation
3 Copyright (C) 2015-2017 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/>. */
22 #include "emacs-module.h"
31 #include "syssignal.h"
39 #if __has_attribute (cleanup)
40 enum { module_has_cleanup
= true };
42 enum { module_has_cleanup
= false };
50 /* True if Lisp_Object and emacs_value have the same representation.
51 This is typically true unless WIDE_EMACS_INT. In practice, having
52 the same sizes and alignments and maximums should be a good enough
53 proxy for equality of representation. */
57 = (sizeof (Lisp_Object
) == sizeof (emacs_value
)
58 && alignof (Lisp_Object
) == alignof (emacs_value
)
59 && INTPTR_MAX
== EMACS_INT_MAX
)
62 /* Function prototype for the module init function. */
63 typedef int (*emacs_init_function
) (struct emacs_runtime
*);
65 /* Function prototype for the module Lisp functions. */
66 typedef emacs_value (*emacs_subr
) (emacs_env
*, ptrdiff_t,
67 emacs_value
[], void *);
69 /* Function prototype for module user-pointer finalizers. These
70 should not throw C++ exceptions, so emacs-module.h declares the
71 corresponding interfaces with EMACS_NOEXCEPT. There is only C code
72 in this module, though, so this constraint is not enforced here. */
73 typedef void (*emacs_finalizer_function
) (void *);
76 /* Private runtime and environment members. */
78 /* The private part of an environment stores the current non local exit state
79 and holds the `emacs_value' objects allocated during the lifetime
80 of the environment. */
81 struct emacs_env_private
83 enum emacs_funcall_exit pending_non_local_exit
;
85 /* Dedicated storage for non-local exit symbol and data so that
86 storage is always available for them, even in an out-of-memory
88 Lisp_Object non_local_exit_symbol
, non_local_exit_data
;
91 /* The private parts of an `emacs_runtime' object contain the initial
93 struct emacs_runtime_private
95 /* FIXME: Ideally, we would just define "struct emacs_runtime_private"
96 as a synonym of "emacs_env", but I don't know how to do that in C. */
101 /* Forward declarations. */
103 struct module_fun_env
;
105 static Lisp_Object
module_format_fun_env (const struct module_fun_env
*);
106 static Lisp_Object
value_to_lisp (emacs_value
);
107 static emacs_value
lisp_to_value (Lisp_Object
);
108 static enum emacs_funcall_exit
module_non_local_exit_check (emacs_env
*);
109 static void check_main_thread (void);
110 static void finalize_environment (struct emacs_env_private
*);
111 static void initialize_environment (emacs_env
*, struct emacs_env_private
*priv
);
112 static void module_handle_signal (emacs_env
*, Lisp_Object
);
113 static void module_handle_throw (emacs_env
*, Lisp_Object
);
114 static void module_non_local_exit_signal_1 (emacs_env
*, Lisp_Object
, Lisp_Object
);
115 static void module_non_local_exit_throw_1 (emacs_env
*, Lisp_Object
, Lisp_Object
);
116 static void module_out_of_memory (emacs_env
*);
117 static void module_reset_handlerlist (const int *);
119 /* We used to return NULL when emacs_value was a different type from
120 Lisp_Object, but nowadays we just use Qnil instead. Although they
121 happen to be the same thing in the current implementation, module
122 code should not assume this. */
123 verify (NIL_IS_ZERO
);
124 static emacs_value
const module_nil
= 0;
126 /* Convenience macros for non-local exit handling. */
128 /* FIXME: The following implementation for non-local exit handling
129 does not support recovery from stack overflow, see sysdep.c. */
131 /* Emacs uses setjmp and longjmp for non-local exits, but
132 module frames cannot be skipped because they are in general
133 not prepared for long jumps (e.g., the behavior in C++ is undefined
134 if objects with nontrivial destructors would be skipped).
135 Therefore, catch all non-local exits. There are two kinds of
136 non-local exits: `signal' and `throw'. The macros in this section
137 can be used to catch both. Use macros to avoid additional variants
138 of `internal_condition_case' etc., and to avoid worrying about
139 passing information to the handler functions. */
141 /* Place this macro at the beginning of a function returning a number
142 or a pointer to handle non-local exits. The function must have an
143 ENV parameter. The function will return the specified value if a
144 signal or throw is caught. */
145 /* TODO: Have Fsignal check for CATCHER_ALL so we only have to install
147 #define MODULE_HANDLE_NONLOCAL_EXIT(retval) \
148 MODULE_SETJMP (CONDITION_CASE, module_handle_signal, retval); \
149 MODULE_SETJMP (CATCHER_ALL, module_handle_throw, retval)
151 #define MODULE_SETJMP(handlertype, handlerfunc, retval) \
152 MODULE_SETJMP_1 (handlertype, handlerfunc, retval, \
153 internal_handler_##handlertype, \
154 internal_cleanup_##handlertype)
156 /* It is very important that pushing the handler doesn't itself raise
157 a signal. Install the cleanup only after the handler has been
158 pushed. Use __attribute__ ((cleanup)) to avoid
159 non-local-exit-prone manual cleanup.
161 The do-while forces uses of the macro to be followed by a semicolon.
162 This macro cannot enclose its entire body inside a do-while, as the
163 code after the macro may longjmp back into the macro, which means
164 its local variable C must stay live in later code. */
166 /* TODO: Make backtraces work if this macros is used. */
168 #define MODULE_SETJMP_1(handlertype, handlerfunc, retval, c, dummy) \
169 if (module_non_local_exit_check (env) != emacs_funcall_exit_return) \
171 struct handler *c = push_handler_nosignal (Qt, handlertype); \
174 module_out_of_memory (env); \
177 verify (module_has_cleanup); \
178 int dummy __attribute__ ((cleanup (module_reset_handlerlist))); \
179 if (sys_setjmp (c->jmp)) \
181 (handlerfunc) (env, c->val); \
187 /* Function environments. */
189 /* A function environment is an auxiliary structure used by
190 `module_make_function' to store information about a module
191 function. It is stored in a save pointer and retrieved by
192 `internal--module-call'. Its members correspond to the arguments
193 given to `module_make_function'. */
195 struct module_fun_env
197 ptrdiff_t min_arity
, max_arity
;
203 /* Implementation of runtime and environment functions.
205 These should abide by the following rules:
207 1. The first argument should always be a pointer to emacs_env.
209 2. Each function should first call check_main_thread. Note that
210 this function is a no-op unless Emacs was built with
213 3. The very next thing each function should do is check that the
214 emacs_env object does not have a non-local exit indication set,
215 by calling module_non_local_exit_check. If that returns
216 anything but emacs_funcall_exit_return, the function should do
217 nothing and return immediately with an error indication, without
218 clobbering the existing error indication in emacs_env. This is
219 needed for correct reporting of Lisp errors to the Emacs Lisp
222 4. Any function that needs to call Emacs facilities, such as
223 encoding or decoding functions, or 'intern', or 'make_string',
224 should protect itself from signals and 'throw' in the called
225 Emacs functions, by placing the macro
226 MODULE_HANDLE_NONLOCAL_EXIT right after the above 2 tests.
228 5. Do NOT use 'eassert' for checking validity of user code in the
229 module. Instead, make those checks part of the code, and if the
230 check fails, call 'module_non_local_exit_signal_1' or
231 'module_non_local_exit_throw_1' to report the error. This is
232 because using 'eassert' in these situations will abort Emacs
233 instead of reporting the error back to Lisp, and also because
234 'eassert' is compiled to nothing in the release version. */
236 /* Use MODULE_FUNCTION_BEGIN to implement steps 2 through 4 for most
237 environment functions. On error it will return its argument, which
238 should be a sentinel value. */
240 #define MODULE_FUNCTION_BEGIN(error_retval) \
241 check_main_thread (); \
242 if (module_non_local_exit_check (env) != emacs_funcall_exit_return) \
243 return error_retval; \
244 MODULE_HANDLE_NONLOCAL_EXIT (error_retval)
247 CHECK_USER_PTR (Lisp_Object obj
)
249 CHECK_TYPE (USER_PTRP (obj
), Quser_ptrp
, obj
);
252 /* Catch signals and throws only if the code can actually signal or
253 throw. If checking is enabled, abort if the current thread is not
254 the Emacs main thread. */
257 module_get_environment (struct emacs_runtime
*ert
)
259 check_main_thread ();
260 return &ert
->private_members
->pub
;
263 /* To make global refs (GC-protected global values) keep a hash that
264 maps global Lisp objects to reference counts. */
267 module_make_global_ref (emacs_env
*env
, emacs_value ref
)
269 MODULE_FUNCTION_BEGIN (module_nil
);
270 struct Lisp_Hash_Table
*h
= XHASH_TABLE (Vmodule_refs_hash
);
271 Lisp_Object new_obj
= value_to_lisp (ref
);
273 ptrdiff_t i
= hash_lookup (h
, new_obj
, &hashcode
);
277 Lisp_Object value
= HASH_VALUE (h
, i
);
278 EMACS_INT refcount
= XFASTINT (value
) + 1;
279 if (MOST_POSITIVE_FIXNUM
< refcount
)
280 xsignal0 (Qoverflow_error
);
281 value
= make_natnum (refcount
);
282 set_hash_value_slot (h
, i
, value
);
286 hash_put (h
, new_obj
, make_natnum (1), hashcode
);
289 return lisp_to_value (new_obj
);
293 module_free_global_ref (emacs_env
*env
, emacs_value ref
)
295 /* TODO: This probably never signals. */
296 /* FIXME: Wait a minute. Shouldn't this function report an error if
297 the hash lookup fails? */
298 MODULE_FUNCTION_BEGIN ();
299 struct Lisp_Hash_Table
*h
= XHASH_TABLE (Vmodule_refs_hash
);
300 Lisp_Object obj
= value_to_lisp (ref
);
302 ptrdiff_t i
= hash_lookup (h
, obj
, &hashcode
);
306 Lisp_Object value
= HASH_VALUE (h
, i
);
307 EMACS_INT refcount
= XFASTINT (value
) - 1;
310 value
= make_natnum (refcount
);
311 set_hash_value_slot (h
, i
, value
);
314 hash_remove_from_table (h
, value
);
318 static enum emacs_funcall_exit
319 module_non_local_exit_check (emacs_env
*env
)
321 check_main_thread ();
322 return env
->private_members
->pending_non_local_exit
;
326 module_non_local_exit_clear (emacs_env
*env
)
328 check_main_thread ();
329 env
->private_members
->pending_non_local_exit
= emacs_funcall_exit_return
;
332 static enum emacs_funcall_exit
333 module_non_local_exit_get (emacs_env
*env
, emacs_value
*sym
, emacs_value
*data
)
335 check_main_thread ();
336 struct emacs_env_private
*p
= env
->private_members
;
337 if (p
->pending_non_local_exit
!= emacs_funcall_exit_return
)
339 /* FIXME: lisp_to_value can exit non-locally. */
340 *sym
= lisp_to_value (p
->non_local_exit_symbol
);
341 *data
= lisp_to_value (p
->non_local_exit_data
);
343 return p
->pending_non_local_exit
;
346 /* Like for `signal', DATA must be a list. */
348 module_non_local_exit_signal (emacs_env
*env
, emacs_value sym
, emacs_value data
)
350 check_main_thread ();
351 if (module_non_local_exit_check (env
) == emacs_funcall_exit_return
)
352 module_non_local_exit_signal_1 (env
, value_to_lisp (sym
),
353 value_to_lisp (data
));
357 module_non_local_exit_throw (emacs_env
*env
, emacs_value tag
, emacs_value value
)
359 check_main_thread ();
360 if (module_non_local_exit_check (env
) == emacs_funcall_exit_return
)
361 module_non_local_exit_throw_1 (env
, value_to_lisp (tag
),
362 value_to_lisp (value
));
365 /* A module function is lambda function that calls
366 `internal--module-call', passing the function pointer of the module
367 function along with the module emacs_env pointer as arguments.
369 (function (lambda (&rest arglist)
370 (internal--module-call envobj arglist))) */
373 module_make_function (emacs_env
*env
, ptrdiff_t min_arity
, ptrdiff_t max_arity
,
374 emacs_subr subr
, const char *documentation
,
377 MODULE_FUNCTION_BEGIN (module_nil
);
379 if (! (0 <= min_arity
381 ? max_arity
== emacs_variadic_function
382 : min_arity
<= max_arity
)))
383 xsignal2 (Qinvalid_arity
, make_number (min_arity
), make_number (max_arity
));
385 /* FIXME: This should be freed when envobj is GC'd. */
386 struct module_fun_env
*envptr
= xmalloc (sizeof *envptr
);
387 envptr
->min_arity
= min_arity
;
388 envptr
->max_arity
= max_arity
;
392 Lisp_Object envobj
= make_save_ptr (envptr
);
393 Lisp_Object doc
= Qnil
;
396 AUTO_STRING (unibyte_doc
, documentation
);
397 doc
= code_convert_string_norecord (unibyte_doc
, Qutf_8
, false);
400 /* FIXME: Use a bytecompiled object, or even better a subr. */
401 Lisp_Object ret
= list4 (Qlambda
,
402 list2 (Qand_rest
, Qargs
),
405 list2 (Qfunction
, Qinternal__module_call
),
409 return lisp_to_value (ret
);
413 module_funcall (emacs_env
*env
, emacs_value fun
, ptrdiff_t nargs
,
416 MODULE_FUNCTION_BEGIN (module_nil
);
418 /* Make a new Lisp_Object array starting with the function as the
419 first arg, because that's what Ffuncall takes. */
420 Lisp_Object
*newargs
;
423 if (INT_ADD_WRAPV (nargs
, 1, &nargs1
))
424 xsignal0 (Qoverflow_error
);
425 SAFE_ALLOCA_LISP (newargs
, nargs1
);
426 newargs
[0] = value_to_lisp (fun
);
427 for (ptrdiff_t i
= 0; i
< nargs
; i
++)
428 newargs
[1 + i
] = value_to_lisp (args
[i
]);
429 emacs_value result
= lisp_to_value (Ffuncall (nargs1
, newargs
));
435 module_intern (emacs_env
*env
, const char *name
)
437 MODULE_FUNCTION_BEGIN (module_nil
);
438 return lisp_to_value (intern (name
));
442 module_type_of (emacs_env
*env
, emacs_value value
)
444 MODULE_FUNCTION_BEGIN (module_nil
);
445 return lisp_to_value (Ftype_of (value_to_lisp (value
)));
449 module_is_not_nil (emacs_env
*env
, emacs_value value
)
451 check_main_thread ();
452 if (module_non_local_exit_check (env
) != emacs_funcall_exit_return
)
454 return ! NILP (value_to_lisp (value
));
458 module_eq (emacs_env
*env
, emacs_value a
, emacs_value b
)
460 check_main_thread ();
461 if (module_non_local_exit_check (env
) != emacs_funcall_exit_return
)
463 return EQ (value_to_lisp (a
), value_to_lisp (b
));
467 module_extract_integer (emacs_env
*env
, emacs_value n
)
469 MODULE_FUNCTION_BEGIN (0);
470 Lisp_Object l
= value_to_lisp (n
);
476 module_make_integer (emacs_env
*env
, intmax_t n
)
478 MODULE_FUNCTION_BEGIN (module_nil
);
479 if (FIXNUM_OVERFLOW_P (n
))
480 xsignal0 (Qoverflow_error
);
481 return lisp_to_value (make_number (n
));
485 module_extract_float (emacs_env
*env
, emacs_value f
)
487 MODULE_FUNCTION_BEGIN (0);
488 Lisp_Object lisp
= value_to_lisp (f
);
489 CHECK_TYPE (FLOATP (lisp
), Qfloatp
, lisp
);
490 return XFLOAT_DATA (lisp
);
494 module_make_float (emacs_env
*env
, double d
)
496 MODULE_FUNCTION_BEGIN (module_nil
);
497 return lisp_to_value (make_float (d
));
501 module_copy_string_contents (emacs_env
*env
, emacs_value value
, char *buffer
,
504 MODULE_FUNCTION_BEGIN (false);
505 Lisp_Object lisp_str
= value_to_lisp (value
);
506 CHECK_STRING (lisp_str
);
508 Lisp_Object lisp_str_utf8
= ENCODE_UTF_8 (lisp_str
);
509 ptrdiff_t raw_size
= SBYTES (lisp_str_utf8
);
510 ptrdiff_t required_buf_size
= raw_size
+ 1;
512 eassert (length
!= NULL
);
516 *length
= required_buf_size
;
520 eassert (*length
>= 0);
522 if (*length
< required_buf_size
)
524 *length
= required_buf_size
;
525 xsignal0 (Qargs_out_of_range
);
528 *length
= required_buf_size
;
529 memcpy (buffer
, SDATA (lisp_str_utf8
), raw_size
+ 1);
535 module_make_string (emacs_env
*env
, const char *str
, ptrdiff_t length
)
537 MODULE_FUNCTION_BEGIN (module_nil
);
538 AUTO_STRING_WITH_LEN (lstr
, str
, length
);
539 return lisp_to_value (code_convert_string_norecord (lstr
, Qutf_8
, false));
543 module_make_user_ptr (emacs_env
*env
, emacs_finalizer_function fin
, void *ptr
)
545 MODULE_FUNCTION_BEGIN (module_nil
);
546 return lisp_to_value (make_user_ptr (fin
, ptr
));
550 module_get_user_ptr (emacs_env
*env
, emacs_value uptr
)
552 MODULE_FUNCTION_BEGIN (NULL
);
553 Lisp_Object lisp
= value_to_lisp (uptr
);
554 CHECK_USER_PTR (lisp
);
555 return XUSER_PTR (lisp
)->p
;
559 module_set_user_ptr (emacs_env
*env
, emacs_value uptr
, void *ptr
)
561 /* FIXME: This function should return bool because it can fail. */
562 MODULE_FUNCTION_BEGIN ();
563 Lisp_Object lisp
= value_to_lisp (uptr
);
564 CHECK_USER_PTR (lisp
);
565 XUSER_PTR (lisp
)->p
= ptr
;
568 static emacs_finalizer_function
569 module_get_user_finalizer (emacs_env
*env
, emacs_value uptr
)
571 MODULE_FUNCTION_BEGIN (NULL
);
572 Lisp_Object lisp
= value_to_lisp (uptr
);
573 CHECK_USER_PTR (lisp
);
574 return XUSER_PTR (lisp
)->finalizer
;
578 module_set_user_finalizer (emacs_env
*env
, emacs_value uptr
,
579 emacs_finalizer_function fin
)
581 /* FIXME: This function should return bool because it can fail. */
582 MODULE_FUNCTION_BEGIN ();
583 Lisp_Object lisp
= value_to_lisp (uptr
);
584 CHECK_USER_PTR (lisp
);
585 XUSER_PTR (lisp
)->finalizer
= fin
;
589 check_vec_index (Lisp_Object lvec
, ptrdiff_t i
)
592 if (! (0 <= i
&& i
< ASIZE (lvec
)))
593 args_out_of_range_3 (make_fixnum_or_float (i
),
594 make_number (0), make_number (ASIZE (lvec
) - 1));
598 module_vec_set (emacs_env
*env
, emacs_value vec
, ptrdiff_t i
, emacs_value val
)
600 /* FIXME: This function should return bool because it can fail. */
601 MODULE_FUNCTION_BEGIN ();
602 Lisp_Object lvec
= value_to_lisp (vec
);
603 check_vec_index (lvec
, i
);
604 ASET (lvec
, i
, value_to_lisp (val
));
608 module_vec_get (emacs_env
*env
, emacs_value vec
, ptrdiff_t i
)
610 MODULE_FUNCTION_BEGIN (module_nil
);
611 Lisp_Object lvec
= value_to_lisp (vec
);
612 check_vec_index (lvec
, i
);
613 return lisp_to_value (AREF (lvec
, i
));
617 module_vec_size (emacs_env
*env
, emacs_value vec
)
619 /* FIXME: Return a sentinel value (e.g., -1) on error. */
620 MODULE_FUNCTION_BEGIN (0);
621 Lisp_Object lvec
= value_to_lisp (vec
);
629 DEFUN ("module-load", Fmodule_load
, Smodule_load
, 1, 1, 0,
630 doc
: /* Load module FILE. */)
633 dynlib_handle_ptr handle
;
634 emacs_init_function module_init
;
638 handle
= dynlib_open (SSDATA (file
));
640 error ("Cannot load file %s: %s", SDATA (file
), dynlib_error ());
642 gpl_sym
= dynlib_sym (handle
, "plugin_is_GPL_compatible");
644 error ("Module %s is not GPL compatible", SDATA (file
));
646 module_init
= (emacs_init_function
) dynlib_func (handle
, "emacs_module_init");
648 error ("Module %s does not have an init function.", SDATA (file
));
650 struct emacs_runtime_private rt
; /* Includes the public emacs_env. */
651 struct emacs_env_private priv
;
652 initialize_environment (&rt
.pub
, &priv
);
653 struct emacs_runtime pub
=
656 .private_members
= &rt
,
657 .get_environment
= module_get_environment
659 int r
= module_init (&pub
);
660 finalize_environment (&priv
);
664 if (FIXNUM_OVERFLOW_P (r
))
665 xsignal0 (Qoverflow_error
);
666 xsignal2 (Qmodule_load_failed
, file
, make_number (r
));
672 DEFUN ("internal--module-call", Finternal_module_call
, Sinternal_module_call
, 1, MANY
, 0,
673 doc
: /* Internal function to call a module function.
674 ENVOBJ is a save pointer to a module_fun_env structure.
675 ARGLIST is a list of arguments passed to SUBRPTR.
676 usage: (module-call ENVOBJ &rest ARGLIST) */)
677 (ptrdiff_t nargs
, Lisp_Object
*arglist
)
679 Lisp_Object envobj
= arglist
[0];
680 /* FIXME: Rather than use a save_value, we should create a new object type.
681 Making save_value visible to Lisp is wrong. */
682 CHECK_TYPE (SAVE_VALUEP (envobj
), Qsave_value_p
, envobj
);
683 struct Lisp_Save_Value
*save_value
= XSAVE_VALUE (envobj
);
684 CHECK_TYPE (save_type (save_value
, 0) == SAVE_POINTER
, Qsave_pointer_p
, envobj
);
685 /* FIXME: We have no reason to believe that XSAVE_POINTER (envobj, 0)
686 is a module_fun_env pointer. If some other part of Emacs also
687 exports save_value objects to Elisp, than we may be getting here this
688 other kind of save_value which will likely hold something completely
689 different in this field. */
690 struct module_fun_env
*envptr
= XSAVE_POINTER (envobj
, 0);
691 EMACS_INT len
= nargs
- 1;
692 eassume (0 <= envptr
->min_arity
);
693 if (! (envptr
->min_arity
<= len
694 && len
<= (envptr
->max_arity
< 0 ? PTRDIFF_MAX
: envptr
->max_arity
)))
695 xsignal2 (Qwrong_number_of_arguments
, module_format_fun_env (envptr
),
699 struct emacs_env_private priv
;
700 initialize_environment (&pub
, &priv
);
705 args
= (emacs_value
*) arglist
+ 1;
708 args
= SAFE_ALLOCA (len
* sizeof *args
);
709 for (ptrdiff_t i
= 0; i
< len
; i
++)
710 args
[i
] = lisp_to_value (arglist
[i
+ 1]);
713 emacs_value ret
= envptr
->subr (&pub
, len
, args
, envptr
->data
);
716 eassert (&priv
== pub
.private_members
);
718 switch (priv
.pending_non_local_exit
)
720 case emacs_funcall_exit_return
:
721 finalize_environment (&priv
);
722 return value_to_lisp (ret
);
723 case emacs_funcall_exit_signal
:
725 Lisp_Object symbol
= priv
.non_local_exit_symbol
;
726 Lisp_Object data
= priv
.non_local_exit_data
;
727 finalize_environment (&priv
);
728 xsignal (symbol
, data
);
730 case emacs_funcall_exit_throw
:
732 Lisp_Object tag
= priv
.non_local_exit_symbol
;
733 Lisp_Object value
= priv
.non_local_exit_data
;
734 finalize_environment (&priv
);
743 /* Helper functions. */
746 check_main_thread (void)
749 eassert (pthread_equal (pthread_self (), main_thread_id
));
750 #elif defined WINDOWSNT
751 eassert (GetCurrentThreadId () == dwMainThreadId
);
756 module_non_local_exit_signal_1 (emacs_env
*env
, Lisp_Object sym
,
759 struct emacs_env_private
*p
= env
->private_members
;
760 if (p
->pending_non_local_exit
== emacs_funcall_exit_return
)
762 p
->pending_non_local_exit
= emacs_funcall_exit_signal
;
763 p
->non_local_exit_symbol
= sym
;
764 p
->non_local_exit_data
= data
;
769 module_non_local_exit_throw_1 (emacs_env
*env
, Lisp_Object tag
,
772 struct emacs_env_private
*p
= env
->private_members
;
773 if (p
->pending_non_local_exit
== emacs_funcall_exit_return
)
775 p
->pending_non_local_exit
= emacs_funcall_exit_throw
;
776 p
->non_local_exit_symbol
= tag
;
777 p
->non_local_exit_data
= value
;
781 /* Signal an out-of-memory condition to the caller. */
783 module_out_of_memory (emacs_env
*env
)
785 /* TODO: Reimplement this so it works even if memory-signal-data has
787 module_non_local_exit_signal_1 (env
, XCAR (Vmemory_signal_data
),
788 XCDR (Vmemory_signal_data
));
792 /* Value conversion. */
794 /* Unique Lisp_Object used to mark those emacs_values which are really
795 just containers holding a Lisp_Object that does not fit as an emacs_value,
796 either because it is an integer out of range, or is not properly aligned.
797 Used only if !plain_values. */
798 static Lisp_Object ltv_mark
;
800 /* Convert V to the corresponding internal object O, such that
801 V == lisp_to_value_bits (O). Never fails. */
803 value_to_lisp_bits (emacs_value v
)
805 intptr_t i
= (intptr_t) v
;
806 if (plain_values
|| USE_LSB_TAG
)
809 /* With wide EMACS_INT and when tag bits are the most significant,
810 reassembling integers differs from reassembling pointers in two
811 ways. First, save and restore the least-significant bits of the
812 integer, not the most-significant bits. Second, sign-extend the
813 integer when restoring, but zero-extend pointers because that
814 makes TAG_PTR faster. */
816 EMACS_UINT tag
= i
& (GCALIGNMENT
- 1);
817 EMACS_UINT untagged
= i
- tag
;
822 bool negative
= tag
& 1;
823 EMACS_UINT sign_extension
824 = negative
? VALMASK
& ~(INTPTR_MAX
>> INTTYPEBITS
): 0;
826 intptr_t all_but_sign
= u
>> GCTYPEBITS
;
827 untagged
= sign_extension
+ all_but_sign
;
832 return XIL ((tag
<< VALBITS
) + untagged
);
835 /* If V was computed from lisp_to_value (O), then return O.
836 Exits non-locally only if the stack overflows. */
838 value_to_lisp (emacs_value v
)
840 Lisp_Object o
= value_to_lisp_bits (v
);
841 if (! plain_values
&& CONSP (o
) && EQ (XCDR (o
), ltv_mark
))
846 /* Attempt to convert O to an emacs_value. Do not do any checking or
847 or allocate any storage; the caller should prevent or detect
848 any resulting bit pattern that is not a valid emacs_value. */
850 lisp_to_value_bits (Lisp_Object o
)
852 EMACS_UINT u
= XLI (o
);
854 /* Compress U into the space of a pointer, possibly losing information. */
855 uintptr_t p
= (plain_values
|| USE_LSB_TAG
857 : (INTEGERP (o
) ? u
<< VALBITS
: u
& VALMASK
) + XTYPE (o
));
858 return (emacs_value
) p
;
861 #ifndef HAVE_STRUCT_ATTRIBUTE_ALIGNED
862 enum { HAVE_STRUCT_ATTRIBUTE_ALIGNED
= 0 };
865 /* Convert O to an emacs_value. Allocate storage if needed; this can
866 signal if memory is exhausted. Must be an injective function. */
868 lisp_to_value (Lisp_Object o
)
870 emacs_value v
= lisp_to_value_bits (o
);
872 if (! EQ (o
, value_to_lisp_bits (v
)))
874 /* Package the incompressible object pointer inside a pair
875 that is compressible. */
876 Lisp_Object pair
= Fcons (o
, ltv_mark
);
878 if (! HAVE_STRUCT_ATTRIBUTE_ALIGNED
)
880 /* Keep calling Fcons until it returns a compressible pair.
881 This shouldn't take long. */
882 while ((intptr_t) XCONS (pair
) & (GCALIGNMENT
- 1))
883 pair
= Fcons (o
, pair
);
885 /* Plant the mark. The garbage collector will eventually
886 reclaim any just-allocated incompressible pairs. */
887 XSETCDR (pair
, ltv_mark
);
890 v
= (emacs_value
) ((intptr_t) XCONS (pair
) + Lisp_Cons
);
893 eassert (EQ (o
, value_to_lisp (v
)));
898 /* Environment lifetime management. */
900 /* Must be called before the environment can be used. */
902 initialize_environment (emacs_env
*env
, struct emacs_env_private
*priv
)
904 priv
->pending_non_local_exit
= emacs_funcall_exit_return
;
905 env
->size
= sizeof *env
;
906 env
->private_members
= priv
;
907 env
->make_global_ref
= module_make_global_ref
;
908 env
->free_global_ref
= module_free_global_ref
;
909 env
->non_local_exit_check
= module_non_local_exit_check
;
910 env
->non_local_exit_clear
= module_non_local_exit_clear
;
911 env
->non_local_exit_get
= module_non_local_exit_get
;
912 env
->non_local_exit_signal
= module_non_local_exit_signal
;
913 env
->non_local_exit_throw
= module_non_local_exit_throw
;
914 env
->make_function
= module_make_function
;
915 env
->funcall
= module_funcall
;
916 env
->intern
= module_intern
;
917 env
->type_of
= module_type_of
;
918 env
->is_not_nil
= module_is_not_nil
;
920 env
->extract_integer
= module_extract_integer
;
921 env
->make_integer
= module_make_integer
;
922 env
->extract_float
= module_extract_float
;
923 env
->make_float
= module_make_float
;
924 env
->copy_string_contents
= module_copy_string_contents
;
925 env
->make_string
= module_make_string
;
926 env
->make_user_ptr
= module_make_user_ptr
;
927 env
->get_user_ptr
= module_get_user_ptr
;
928 env
->set_user_ptr
= module_set_user_ptr
;
929 env
->get_user_finalizer
= module_get_user_finalizer
;
930 env
->set_user_finalizer
= module_set_user_finalizer
;
931 env
->vec_set
= module_vec_set
;
932 env
->vec_get
= module_vec_get
;
933 env
->vec_size
= module_vec_size
;
934 Vmodule_environments
= Fcons (make_save_ptr (env
), Vmodule_environments
);
937 /* Must be called before the lifetime of the environment object
940 finalize_environment (struct emacs_env_private
*env
)
942 Vmodule_environments
= XCDR (Vmodule_environments
);
946 /* Non-local exit handling. */
948 /* Must be called after setting up a handler immediately before
949 returning from the function. See the comments in lisp.h and the
950 code in eval.c for details. The macros below arrange for this
951 function to be called automatically. DUMMY is ignored. */
953 module_reset_handlerlist (const int *dummy
)
955 handlerlist
= handlerlist
->next
;
958 /* Called on `signal'. ERR is a pair (SYMBOL . DATA), which gets
959 stored in the environment. Set the pending non-local exit flag. */
961 module_handle_signal (emacs_env
*env
, Lisp_Object err
)
963 module_non_local_exit_signal_1 (env
, XCAR (err
), XCDR (err
));
966 /* Called on `throw'. TAG_VAL is a pair (TAG . VALUE), which gets
967 stored in the environment. Set the pending non-local exit flag. */
969 module_handle_throw (emacs_env
*env
, Lisp_Object tag_val
)
971 module_non_local_exit_throw_1 (env
, XCAR (tag_val
), XCDR (tag_val
));
975 /* Function environments. */
977 /* Return a string object that contains a user-friendly
978 representation of the function environment. */
980 module_format_fun_env (const struct module_fun_env
*env
)
982 /* Try to print a function name if possible. */
983 const char *path
, *sym
;
984 static char const noaddr_format
[] = "#<module function at %p>";
985 char buffer
[sizeof noaddr_format
+ INT_STRLEN_BOUND (intptr_t) + 256];
987 ptrdiff_t bufsize
= sizeof buffer
;
989 = (dynlib_addr (env
->subr
, &path
, &sym
)
990 ? exprintf (&buf
, &bufsize
, buffer
, -1,
991 "#<module function %s from %s>", sym
, path
)
992 : sprintf (buffer
, noaddr_format
, env
->subr
));
993 AUTO_STRING_WITH_LEN (unibyte_result
, buffer
, size
);
994 Lisp_Object result
= code_convert_string_norecord (unibyte_result
,
1002 /* Segment initializer. */
1005 syms_of_module (void)
1008 ltv_mark
= Fcons (Qnil
, Qnil
);
1009 eassert (NILP (value_to_lisp (module_nil
)));
1011 DEFSYM (Qmodule_refs_hash
, "module-refs-hash");
1012 DEFVAR_LISP ("module-refs-hash", Vmodule_refs_hash
,
1013 doc
: /* Module global reference table. */);
1016 = make_hash_table (hashtest_eq
, DEFAULT_HASH_SIZE
,
1017 DEFAULT_REHASH_SIZE
, DEFAULT_REHASH_THRESHOLD
,
1019 Funintern (Qmodule_refs_hash
, Qnil
);
1021 DEFSYM (Qmodule_environments
, "module-environments");
1022 DEFVAR_LISP ("module-environments", Vmodule_environments
,
1023 doc
: /* List of active module environments. */);
1024 Vmodule_environments
= Qnil
;
1025 /* Unintern `module-environments' because it is only used
1027 Funintern (Qmodule_environments
, Qnil
);
1029 DEFSYM (Qmodule_load_failed
, "module-load-failed");
1030 Fput (Qmodule_load_failed
, Qerror_conditions
,
1031 listn (CONSTYPE_PURE
, 2, Qmodule_load_failed
, Qerror
));
1032 Fput (Qmodule_load_failed
, Qerror_message
,
1033 build_pure_c_string ("Module load failed"));
1035 DEFSYM (Qinvalid_module_call
, "invalid-module-call");
1036 Fput (Qinvalid_module_call
, Qerror_conditions
,
1037 listn (CONSTYPE_PURE
, 2, Qinvalid_module_call
, Qerror
));
1038 Fput (Qinvalid_module_call
, Qerror_message
,
1039 build_pure_c_string ("Invalid module call"));
1041 DEFSYM (Qinvalid_arity
, "invalid-arity");
1042 Fput (Qinvalid_arity
, Qerror_conditions
,
1043 listn (CONSTYPE_PURE
, 2, Qinvalid_arity
, Qerror
));
1044 Fput (Qinvalid_arity
, Qerror_message
,
1045 build_pure_c_string ("Invalid function arity"));
1047 /* Unintern `module-refs-hash' because it is internal-only and Lisp
1048 code or modules should not access it. */
1049 Funintern (Qmodule_refs_hash
, Qnil
);
1051 DEFSYM (Qsave_value_p
, "save-value-p");
1052 DEFSYM (Qsave_pointer_p
, "save-pointer-p");
1054 defsubr (&Smodule_load
);
1056 DEFSYM (Qinternal__module_call
, "internal--module-call");
1057 defsubr (&Sinternal_module_call
);