]> code.delx.au - gnu-emacs/blob - src/emacs-module.c
Fix double-decrement bug when freeing global refs
[gnu-emacs] / src / emacs-module.c
1 /* emacs-module.c - Module loading and runtime implementation
2
3 Copyright (C) 2015 Free Software Foundation, Inc.
4
5 This file is part of GNU Emacs.
6
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
10 (at your option) any later version.
11
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.
16
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/>. */
19
20 #include <config.h>
21
22 #include "emacs-module.h"
23
24 #include <stdbool.h>
25 #include <stddef.h>
26 #include <stdint.h>
27 #include <stdio.h>
28
29 #include "lisp.h"
30 #include "dynlib.h"
31 #include "coding.h"
32 #include "verify.h"
33
34 \f
35 /* Feature tests. */
36
37 /* True if __attribute__ ((cleanup (...))) works, false otherwise. */
38 #ifdef HAVE_VAR_ATTRIBUTE_CLEANUP
39 enum { module_has_cleanup = true };
40 #else
41 enum { module_has_cleanup = false };
42 #endif
43
44 /* Handle to the main thread. Used to verify that modules call us in
45 the right thread. */
46 #ifdef HAVE_THREADS_H
47 # include <threads.h>
48 static thrd_t main_thread;
49 #elif defined HAVE_PTHREAD
50 # include <pthread.h>
51 static pthread_t main_thread;
52 #elif defined WINDOWSNT
53 # include <windows.h>
54 /* On Windows, store both a handle to the main thread and the
55 thread ID because the latter can be reused when a thread
56 terminates. */
57 static HANDLE main_thread;
58 static DWORD main_thread_id;
59 #endif
60
61 \f
62 /* Memory management. */
63
64 /* An `emacs_value' is just a pointer to a structure holding an
65 internal Lisp object. */
66 struct emacs_value_tag { Lisp_Object v; };
67
68 /* Local value objects use a simple fixed-sized block allocation
69 scheme without explicit deallocation. All local values are
70 deallocated when the lifetime of their environment ends. Keep
71 track of a current frame from which new values are allocated,
72 appending further dynamically-allocated frames if necessary. */
73
74 enum { value_frame_size = 512 };
75
76 /* A block from which `emacs_value' object can be allocated. */
77 struct emacs_value_frame
78 {
79 /* Storage for values. */
80 struct emacs_value_tag objects[value_frame_size];
81
82 /* Index of the next free value in `objects'. */
83 int offset;
84
85 /* Pointer to next frame, if any. */
86 struct emacs_value_frame *next;
87 };
88
89 /* A structure that holds an initial frame (so that the first local
90 values require no dynamic allocation) and keeps track of the
91 current frame. */
92 static struct emacs_value_storage
93 {
94 struct emacs_value_frame initial;
95 struct emacs_value_frame *current;
96 } global_storage;
97
98 \f
99 /* Private runtime and environment members. */
100
101 /* The private part of an environment stores the current non local exit state
102 and holds the `emacs_value' objects allocated during the lifetime
103 of the environment. */
104 struct emacs_env_private
105 {
106 enum emacs_funcall_exit pending_non_local_exit;
107
108 /* Dedicated storage for non-local exit symbol and data so that
109 storage is always available for them, even in an out-of-memory
110 situation. */
111 struct emacs_value_tag non_local_exit_symbol, non_local_exit_data;
112
113 struct emacs_value_storage storage;
114 };
115
116 /* Combine public and private parts in one structure. This structure
117 is used whenever an environment is created. */
118 struct env_storage
119 {
120 emacs_env pub;
121 struct emacs_env_private priv;
122 };
123
124 /* The private parts of an `emacs_runtime' object contain the initial
125 environment. */
126 struct emacs_runtime_private
127 {
128 struct env_storage environment;
129 };
130
131 \f
132
133 /* Forward declarations. */
134
135 struct module_fun_env;
136
137 static Lisp_Object module_format_fun_env (const struct module_fun_env *);
138 static Lisp_Object value_to_lisp (emacs_value);
139 static emacs_value allocate_emacs_value (emacs_env *, struct emacs_value_storage *, Lisp_Object);
140 static emacs_value lisp_to_value (emacs_env *, Lisp_Object);
141 static enum emacs_funcall_exit module_non_local_exit_check (emacs_env *);
142 static void check_main_thread (void);
143 static void finalize_environment (struct env_storage *);
144 static void initialize_environment (struct env_storage *);
145 static void module_args_out_of_range (emacs_env *, Lisp_Object, Lisp_Object);
146 static void module_handle_signal (emacs_env *, Lisp_Object);
147 static void module_handle_throw (emacs_env *, Lisp_Object);
148 static void module_non_local_exit_signal_1 (emacs_env *, Lisp_Object, Lisp_Object);
149 static void module_non_local_exit_throw_1 (emacs_env *, Lisp_Object, Lisp_Object);
150 static void module_out_of_memory (emacs_env *);
151 static void module_reset_handlerlist (const int *);
152 static void module_wrong_type (emacs_env *, Lisp_Object, Lisp_Object);
153
154 \f
155 /* Convenience macros for non-local exit handling. */
156
157 /* Emacs uses setjmp and longjmp for non-local exits, but
158 module frames cannot be skipped because they are in general
159 not prepared for long jumps (e.g., the behavior in C++ is undefined
160 if objects with nontrivial destructors would be skipped).
161 Therefore, catch all non-local exits. There are two kinds of
162 non-local exits: `signal' and `throw'. The macros in this section
163 can be used to catch both. Use macros to avoid additional variants
164 of `internal_condition_case' etc., and to avoid worrying about
165 passing information to the handler functions. */
166
167 /* Place this macro at the beginning of a function returning a number
168 or a pointer to handle signals. The function must have an ENV
169 parameter. The function will return 0 (or NULL) if a signal is
170 caught. */
171 #define MODULE_HANDLE_SIGNALS MODULE_HANDLE_SIGNALS_RETURN (0)
172
173 /* Place this macro at the beginning of a function returning void to
174 handle signals. The function must have an ENV parameter. */
175 #define MODULE_HANDLE_SIGNALS_VOID MODULE_HANDLE_SIGNALS_RETURN ()
176
177 #define MODULE_HANDLE_SIGNALS_RETURN(retval) \
178 MODULE_SETJMP (CONDITION_CASE, module_handle_signal, retval)
179
180 /* Place this macro at the beginning of a function returning a pointer
181 to handle non-local exits via `throw'. The function must have an
182 ENV parameter. The function will return NULL if a `throw' is
183 caught. */
184 #define MODULE_HANDLE_THROW \
185 MODULE_SETJMP (CATCHER_ALL, module_handle_throw, NULL)
186
187 #define MODULE_SETJMP(handlertype, handlerfunc, retval) \
188 MODULE_SETJMP_1 (handlertype, handlerfunc, retval, \
189 internal_handler_##handlertype, \
190 internal_cleanup_##handlertype)
191
192 /* It is very important that pushing the handler doesn't itself raise
193 a signal. Install the cleanup only after the handler has been
194 pushed. Use __attribute__ ((cleanup)) to avoid
195 non-local-exit-prone manual cleanup.
196
197 The do-while forces uses of the macro to be followed by a semicolon.
198 This macro cannot enclose its entire body inside a do-while, as the
199 code after the macro may longjmp back into the macro, which means
200 its local variable C must stay live in later code. */
201
202 #define MODULE_SETJMP_1(handlertype, handlerfunc, retval, c, dummy) \
203 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return); \
204 struct handler *c = push_handler_nosignal (Qt, handlertype); \
205 if (!c) \
206 { \
207 module_out_of_memory (env); \
208 return retval; \
209 } \
210 verify (module_has_cleanup); \
211 int dummy __attribute__ ((cleanup (module_reset_handlerlist))); \
212 if (sys_setjmp (c->jmp)) \
213 { \
214 (handlerfunc) (env, c->val); \
215 return retval; \
216 } \
217 do { } while (false)
218
219 \f
220 /* Function environments. */
221
222 /* A function environment is an auxiliary structure used by
223 `module_make_function' to store information about a module
224 function. It is stored in a save pointer and retrieved by
225 `module-call'. Its members correspond to the arguments given to
226 `module_make_function'. */
227
228 struct module_fun_env
229 {
230 ptrdiff_t min_arity, max_arity;
231 emacs_subr subr;
232 void *data;
233 };
234
235 /* The function definition of `module-call'. `module-call' is
236 uninterned because user code couldn't meaningfully use it, so keep
237 its definition around somewhere else. */
238 static Lisp_Object module_call_func;
239
240 \f
241 /* Implementation of runtime and environment functions. */
242
243 /* Catch signals and throws only if the code can actually signal or
244 throw. If checking is enabled, abort if the current thread is not
245 the Emacs main thread. */
246
247 static emacs_env *
248 module_get_environment (struct emacs_runtime *ert)
249 {
250 check_main_thread ();
251 return &ert->private_members->environment.pub;
252 }
253
254 /* To make global refs (GC-protected global values) keep a hash that
255 maps global Lisp objects to reference counts. */
256
257 static emacs_value
258 module_make_global_ref (emacs_env *env, emacs_value ref)
259 {
260 check_main_thread ();
261 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return);
262 MODULE_HANDLE_SIGNALS;
263 eassert (HASH_TABLE_P (Vmodule_refs_hash));
264 struct Lisp_Hash_Table *h = XHASH_TABLE (Vmodule_refs_hash);
265 Lisp_Object new_obj = value_to_lisp (ref);
266 EMACS_UINT hashcode;
267 ptrdiff_t i = hash_lookup (h, new_obj, &hashcode);
268
269 if (i >= 0)
270 {
271 Lisp_Object value = HASH_VALUE (h, i);
272 eassert (NATNUMP (value));
273 EMACS_INT refcount = XFASTINT (value) + 1;
274 if (refcount > MOST_POSITIVE_FIXNUM)
275 {
276 module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil);
277 return NULL;
278 }
279 value = make_natnum (refcount);
280 set_hash_value_slot (h, i, value);
281 }
282 else
283 {
284 hash_put (h, new_obj, make_natnum (1), hashcode);
285 }
286
287 return allocate_emacs_value (env, &global_storage, new_obj);
288 }
289
290 static void
291 module_free_global_ref (emacs_env *env, emacs_value ref)
292 {
293 check_main_thread ();
294 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return);
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_HANDLE_SIGNALS_VOID;
299 eassert (HASH_TABLE_P (Vmodule_refs_hash));
300 struct Lisp_Hash_Table *h = XHASH_TABLE (Vmodule_refs_hash);
301 Lisp_Object obj = value_to_lisp (ref);
302 EMACS_UINT hashcode;
303 ptrdiff_t i = hash_lookup (h, obj, &hashcode);
304
305 if (i >= 0)
306 {
307 Lisp_Object value = HASH_VALUE (h, i);
308 eassert (NATNUMP (value));
309 EMACS_INT refcount = XFASTINT (value) - 1;
310 if (refcount > 0)
311 {
312 value = make_natnum (refcount);
313 set_hash_value_slot (h, i, value);
314 }
315 else
316 {
317 eassert (refcount == 0);
318 hash_remove_from_table (h, value);
319 }
320 }
321 }
322
323 static enum emacs_funcall_exit
324 module_non_local_exit_check (emacs_env *env)
325 {
326 check_main_thread ();
327 return env->private_members->pending_non_local_exit;
328 }
329
330 static void
331 module_non_local_exit_clear (emacs_env *env)
332 {
333 check_main_thread ();
334 env->private_members->pending_non_local_exit = emacs_funcall_exit_return;
335 }
336
337 static enum emacs_funcall_exit
338 module_non_local_exit_get (emacs_env *env, emacs_value *sym, emacs_value *data)
339 {
340 check_main_thread ();
341 struct emacs_env_private *p = env->private_members;
342 if (p->pending_non_local_exit != emacs_funcall_exit_return)
343 {
344 *sym = &p->non_local_exit_symbol;
345 *data = &p->non_local_exit_data;
346 }
347 return p->pending_non_local_exit;
348 }
349
350 /* Like for `signal', DATA must be a list. */
351 static void
352 module_non_local_exit_signal (emacs_env *env, emacs_value sym, emacs_value data)
353 {
354 check_main_thread ();
355 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return);
356 module_non_local_exit_signal_1 (env, value_to_lisp (sym),
357 value_to_lisp (data));
358 }
359
360 static void
361 module_non_local_exit_throw (emacs_env *env, emacs_value tag, emacs_value value)
362 {
363 check_main_thread ();
364 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return);
365 module_non_local_exit_throw_1 (env, value_to_lisp (tag),
366 value_to_lisp (value));
367 }
368
369 /* A module function is lambda function that calls `module-call',
370 passing the function pointer of the module function along with the
371 module emacs_env pointer as arguments.
372
373 (function (lambda (&rest arglist)
374 (module-call envobj arglist))) */
375
376 static emacs_value
377 module_make_function (emacs_env *env, ptrdiff_t min_arity, ptrdiff_t max_arity,
378 emacs_subr subr, const char *documentation,
379 void *data)
380 {
381 check_main_thread ();
382 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return);
383 MODULE_HANDLE_SIGNALS;
384
385 if (! (0 <= min_arity
386 && (max_arity < 0
387 ? max_arity == emacs_variadic_function
388 : min_arity <= max_arity)))
389 xsignal2 (Qinvalid_arity, make_number (min_arity), make_number (max_arity));
390
391 /* FIXME: This should be freed when envobj is GC'd. */
392 struct module_fun_env *envptr = xmalloc (sizeof *envptr);
393 envptr->min_arity = min_arity;
394 envptr->max_arity = max_arity;
395 envptr->subr = subr;
396 envptr->data = data;
397
398 Lisp_Object envobj = make_save_ptr (envptr);
399 Lisp_Object ret = list4 (Qlambda,
400 list2 (Qand_rest, Qargs),
401 documentation ? build_string (documentation) : Qnil,
402 list3 (module_call_func,
403 envobj,
404 Qargs));
405
406 return lisp_to_value (env, ret);
407 }
408
409 static emacs_value
410 module_funcall (emacs_env *env, emacs_value fun, ptrdiff_t nargs,
411 emacs_value args[])
412 {
413 check_main_thread ();
414 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return);
415 MODULE_HANDLE_SIGNALS;
416 MODULE_HANDLE_THROW;
417
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;
421 USE_SAFE_ALLOCA;
422 SAFE_ALLOCA_LISP (newargs, nargs + 1);
423 newargs[0] = value_to_lisp (fun);
424 for (ptrdiff_t i = 0; i < nargs; i++)
425 newargs[1 + i] = value_to_lisp (args[i]);
426 emacs_value result = lisp_to_value (env, Ffuncall (nargs + 1, newargs));
427 SAFE_FREE ();
428 return result;
429 }
430
431 static emacs_value
432 module_intern (emacs_env *env, const char *name)
433 {
434 check_main_thread ();
435 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return);
436 MODULE_HANDLE_SIGNALS;
437 return lisp_to_value (env, intern (name));
438 }
439
440 static emacs_value
441 module_type_of (emacs_env *env, emacs_value value)
442 {
443 check_main_thread ();
444 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return);
445 return lisp_to_value (env, Ftype_of (value_to_lisp (value)));
446 }
447
448 static bool
449 module_is_not_nil (emacs_env *env, emacs_value value)
450 {
451 check_main_thread ();
452 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return);
453 return ! NILP (value_to_lisp (value));
454 }
455
456 static bool
457 module_eq (emacs_env *env, emacs_value a, emacs_value b)
458 {
459 check_main_thread ();
460 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return);
461 return EQ (value_to_lisp (a), value_to_lisp (b));
462 }
463
464 static intmax_t
465 module_extract_integer (emacs_env *env, emacs_value n)
466 {
467 check_main_thread ();
468 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return);
469 Lisp_Object l = value_to_lisp (n);
470 if (! INTEGERP (l))
471 {
472 module_wrong_type (env, Qintegerp, l);
473 return 0;
474 }
475 return XINT (l);
476 }
477
478 static emacs_value
479 module_make_integer (emacs_env *env, intmax_t n)
480 {
481 check_main_thread ();
482 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return);
483 if (! (MOST_NEGATIVE_FIXNUM <= n && n <= MOST_POSITIVE_FIXNUM))
484 {
485 module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil);
486 return NULL;
487 }
488 return lisp_to_value (env, make_number (n));
489 }
490
491 static double
492 module_extract_float (emacs_env *env, emacs_value f)
493 {
494 check_main_thread ();
495 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return);
496 Lisp_Object lisp = value_to_lisp (f);
497 if (! FLOATP (lisp))
498 {
499 module_wrong_type (env, Qfloatp, lisp);
500 return 0;
501 }
502 return XFLOAT_DATA (lisp);
503 }
504
505 static emacs_value
506 module_make_float (emacs_env *env, double d)
507 {
508 check_main_thread ();
509 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return);
510 MODULE_HANDLE_SIGNALS;
511 return lisp_to_value (env, make_float (d));
512 }
513
514 static bool
515 module_copy_string_contents (emacs_env *env, emacs_value value, char *buffer,
516 ptrdiff_t *length)
517 {
518 check_main_thread ();
519 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return);
520 MODULE_HANDLE_SIGNALS;
521 Lisp_Object lisp_str = value_to_lisp (value);
522 if (! STRINGP (lisp_str))
523 {
524 module_wrong_type (env, Qstringp, lisp_str);
525 return false;
526 }
527
528 ptrdiff_t raw_size = SBYTES (lisp_str);
529
530 /* Emacs internal encoding is more-or-less UTF8, let's assume utf8
531 encoded emacs string are the same byte size. */
532
533 if (!buffer || length == 0 || *length-1 < raw_size)
534 {
535 *length = raw_size + 1;
536 return false;
537 }
538
539 Lisp_Object lisp_str_utf8 = ENCODE_UTF_8 (lisp_str);
540 eassert (raw_size == SBYTES (lisp_str_utf8));
541 *length = raw_size + 1;
542 memcpy (buffer, SDATA (lisp_str_utf8), SBYTES (lisp_str_utf8));
543 buffer[raw_size] = 0;
544
545 return true;
546 }
547
548 static emacs_value
549 module_make_string (emacs_env *env, const char *str, ptrdiff_t length)
550 {
551 check_main_thread ();
552 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return);
553 MODULE_HANDLE_SIGNALS;
554 if (length > PTRDIFF_MAX)
555 {
556 module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil);
557 return NULL;
558 }
559 /* Assume STR is utf8 encoded. */
560 return lisp_to_value (env, make_string (str, length));
561 }
562
563 static emacs_value
564 module_make_user_ptr (emacs_env *env, emacs_finalizer_function fin, void *ptr)
565 {
566 check_main_thread ();
567 return lisp_to_value (env, make_user_ptr (fin, ptr));
568 }
569
570 static void *
571 module_get_user_ptr (emacs_env *env, emacs_value uptr)
572 {
573 check_main_thread ();
574 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return);
575 Lisp_Object lisp = value_to_lisp (uptr);
576 if (! USER_PTRP (lisp))
577 {
578 module_wrong_type (env, Quser_ptr, lisp);
579 return NULL;
580 }
581 return XUSER_PTR (lisp)->p;
582 }
583
584 static void
585 module_set_user_ptr (emacs_env *env, emacs_value uptr, void *ptr)
586 {
587 check_main_thread ();
588 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return);
589 Lisp_Object lisp = value_to_lisp (uptr);
590 if (! USER_PTRP (lisp))
591 module_wrong_type (env, Quser_ptr, lisp);
592 XUSER_PTR (lisp)->p = ptr;
593 }
594
595 static emacs_finalizer_function
596 module_get_user_finalizer (emacs_env *env, emacs_value uptr)
597 {
598 check_main_thread ();
599 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return);
600 Lisp_Object lisp = value_to_lisp (uptr);
601 if (! USER_PTRP (lisp))
602 {
603 module_wrong_type (env, Quser_ptr, lisp);
604 return NULL;
605 }
606 return XUSER_PTR (lisp)->finalizer;
607 }
608
609 static void
610 module_set_user_finalizer (emacs_env *env, emacs_value uptr,
611 emacs_finalizer_function fin)
612 {
613 check_main_thread ();
614 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return);
615 Lisp_Object lisp = value_to_lisp (uptr);
616 if (! USER_PTRP (lisp))
617 module_wrong_type (env, Quser_ptr, lisp);
618 XUSER_PTR (lisp)->finalizer = fin;
619 }
620
621 static void
622 module_vec_set (emacs_env *env, emacs_value vec, ptrdiff_t i, emacs_value val)
623 {
624 check_main_thread ();
625 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return);
626 Lisp_Object lvec = value_to_lisp (vec);
627 if (! VECTORP (lvec))
628 {
629 module_wrong_type (env, Qvectorp, lvec);
630 return;
631 }
632 if (! (0 <= i && i < ASIZE (lvec)))
633 {
634 if (MOST_NEGATIVE_FIXNUM <= i && i <= MOST_POSITIVE_FIXNUM)
635 module_args_out_of_range (env, lvec, make_number (i));
636 else
637 module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil);
638 return;
639 }
640 ASET (lvec, i, value_to_lisp (val));
641 }
642
643 static emacs_value
644 module_vec_get (emacs_env *env, emacs_value vec, ptrdiff_t i)
645 {
646 check_main_thread ();
647 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return);
648 Lisp_Object lvec = value_to_lisp (vec);
649 if (! VECTORP (lvec))
650 {
651 module_wrong_type (env, Qvectorp, lvec);
652 return NULL;
653 }
654 if (! (0 <= i && i < ASIZE (lvec)))
655 {
656 if (MOST_NEGATIVE_FIXNUM <= i && i <= MOST_POSITIVE_FIXNUM)
657 module_args_out_of_range (env, lvec, make_number (i));
658 else
659 module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil);
660 return NULL;
661 }
662 return lisp_to_value (env, AREF (lvec, i));
663 }
664
665 static ptrdiff_t
666 module_vec_size (emacs_env *env, emacs_value vec)
667 {
668 check_main_thread ();
669 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return);
670 Lisp_Object lvec = value_to_lisp (vec);
671 if (! VECTORP (lvec))
672 {
673 module_wrong_type (env, Qvectorp, lvec);
674 return 0;
675 }
676 eassert (ASIZE (lvec) >= 0);
677 return ASIZE (lvec);
678 }
679
680 \f
681 /* Subroutines. */
682
683 DEFUN ("module-load", Fmodule_load, Smodule_load, 1, 1, 0,
684 doc: /* Load module FILE. */)
685 (Lisp_Object file)
686 {
687 dynlib_handle_ptr handle;
688 emacs_init_function module_init;
689 void *gpl_sym;
690
691 CHECK_STRING (file);
692 handle = dynlib_open (SSDATA (file));
693 if (!handle)
694 error ("Cannot load file %s: %s", SDATA (file), dynlib_error ());
695
696 gpl_sym = dynlib_sym (handle, "plugin_is_GPL_compatible");
697 if (!gpl_sym)
698 error ("Module %s is not GPL compatible", SDATA (file));
699
700 module_init = (emacs_init_function) dynlib_sym (handle, "emacs_module_init");
701 if (!module_init)
702 error ("Module %s does not have an init function.", SDATA (file));
703
704 struct emacs_runtime_private priv;
705 struct emacs_runtime pub =
706 {
707 .size = sizeof pub,
708 .private_members = &priv,
709 .get_environment = module_get_environment
710 };
711 initialize_environment (&priv.environment);
712 int r = module_init (&pub);
713 finalize_environment (&priv.environment);
714
715 if (r != 0)
716 {
717 if (! (MOST_NEGATIVE_FIXNUM <= r && r <= MOST_POSITIVE_FIXNUM))
718 xsignal0 (Qoverflow_error);
719 xsignal2 (Qmodule_load_failed, file, make_number (r));
720 }
721
722 return Qt;
723 }
724
725 DEFUN ("module-call", Fmodule_call, Smodule_call, 2, 2, 0,
726 doc: /* Internal function to call a module function.
727 ENVOBJ is a save pointer to a module_fun_env structure.
728 ARGLIST is a list of arguments passed to SUBRPTR. */)
729 (Lisp_Object envobj, Lisp_Object arglist)
730 {
731 struct module_fun_env *envptr = XSAVE_POINTER (envobj, 0);
732 EMACS_INT len = XFASTINT (Flength (arglist));
733 eassume (0 <= envptr->min_arity);
734 if (! (envptr->min_arity <= len
735 && len <= (envptr->max_arity < 0 ? PTRDIFF_MAX : envptr->max_arity)))
736 xsignal2 (Qwrong_number_of_arguments, module_format_fun_env (envptr),
737 make_number (len));
738
739 struct env_storage env;
740 initialize_environment (&env);
741
742 emacs_value *args = xnmalloc (len, sizeof *args);
743
744 for (ptrdiff_t i = 0; i < len; i++)
745 {
746 args[i] = lisp_to_value (&env.pub, XCAR (arglist));
747 if (! args[i])
748 memory_full (sizeof *args[i]);
749 arglist = XCDR (arglist);
750 }
751
752 emacs_value ret = envptr->subr (&env.pub, len, args, envptr->data);
753 xfree (args);
754
755 switch (env.priv.pending_non_local_exit)
756 {
757 case emacs_funcall_exit_return:
758 finalize_environment (&env);
759 if (ret == NULL)
760 xsignal1 (Qinvalid_module_call, module_format_fun_env (envptr));
761 return value_to_lisp (ret);
762 case emacs_funcall_exit_signal:
763 {
764 Lisp_Object symbol = value_to_lisp (&env.priv.non_local_exit_symbol);
765 Lisp_Object data = value_to_lisp (&env.priv.non_local_exit_data);
766 finalize_environment (&env);
767 xsignal (symbol, data);
768 }
769 case emacs_funcall_exit_throw:
770 {
771 Lisp_Object tag = value_to_lisp (&env.priv.non_local_exit_symbol);
772 Lisp_Object value = value_to_lisp (&env.priv.non_local_exit_data);
773 finalize_environment (&env);
774 Fthrow (tag, value);
775 }
776 default:
777 eassume (false);
778 }
779 }
780
781 \f
782 /* Helper functions. */
783
784 static void
785 check_main_thread (void)
786 {
787 #ifdef HAVE_THREADS_H
788 eassert (thrd_equal (thdr_current (), main_thread));
789 #elif defined HAVE_PTHREAD
790 eassert (pthread_equal (pthread_self (), main_thread));
791 #elif defined WINDOWSNT
792 /* CompareObjectHandles would be perfect, but is only available in
793 Windows 10. Also check whether the thread is still running to
794 protect against thread identifier reuse. */
795 eassert (GetCurrentThreadId () == main_thread_id
796 && WaitForSingleObject (main_thread, 0) == WAIT_TIMEOUT);
797 #endif
798 }
799
800 static void
801 module_non_local_exit_signal_1 (emacs_env *env, Lisp_Object sym,
802 Lisp_Object data)
803 {
804 struct emacs_env_private *p = env->private_members;
805 eassert (p->pending_non_local_exit == emacs_funcall_exit_return);
806 p->pending_non_local_exit = emacs_funcall_exit_signal;
807 p->non_local_exit_symbol.v = sym;
808 p->non_local_exit_data.v = data;
809 }
810
811 static void
812 module_non_local_exit_throw_1 (emacs_env *env, Lisp_Object tag,
813 Lisp_Object value)
814 {
815 struct emacs_env_private *p = env->private_members;
816 eassert (p->pending_non_local_exit == emacs_funcall_exit_return);
817 p->pending_non_local_exit = emacs_funcall_exit_throw;
818 p->non_local_exit_symbol.v = tag;
819 p->non_local_exit_data.v = value;
820 }
821
822 /* Module version of `wrong_type_argument'. */
823 static void
824 module_wrong_type (emacs_env *env, Lisp_Object predicate, Lisp_Object value)
825 {
826 module_non_local_exit_signal_1 (env, Qwrong_type_argument,
827 list2 (predicate, value));
828 }
829
830 /* Signal an out-of-memory condition to the caller. */
831 static void
832 module_out_of_memory (emacs_env *env)
833 {
834 /* TODO: Reimplement this so it works even if memory-signal-data has
835 been modified. */
836 module_non_local_exit_signal_1 (env, XCAR (Vmemory_signal_data),
837 XCDR (Vmemory_signal_data));
838 }
839
840 /* Signal arguments are out of range. */
841 static void
842 module_args_out_of_range (emacs_env *env, Lisp_Object a1, Lisp_Object a2)
843 {
844 module_non_local_exit_signal_1 (env, Qargs_out_of_range, list2 (a1, a2));
845 }
846
847 \f
848 /* Value conversion. */
849
850 /* Convert an `emacs_value' to the corresponding internal object.
851 Never fails. */
852 static Lisp_Object
853 value_to_lisp (emacs_value v)
854 {
855 return v->v;
856 }
857
858 /* Convert an internal object to an `emacs_value'. Allocate storage
859 from the environment; return NULL if allocation fails. */
860 static emacs_value
861 lisp_to_value (emacs_env *env, Lisp_Object o)
862 {
863 struct emacs_env_private *p = env->private_members;
864 if (p->pending_non_local_exit != emacs_funcall_exit_return)
865 return NULL;
866 return allocate_emacs_value (env, &p->storage, o);
867 }
868
869 \f
870 /* Memory management. */
871
872 /* Must be called for each frame before it can be used for allocation. */
873 static void
874 initialize_frame (struct emacs_value_frame *frame)
875 {
876 frame->offset = 0;
877 frame->next = NULL;
878 }
879
880 /* Must be called for any storage object before it can be used for
881 allocation. */
882 static void
883 initialize_storage (struct emacs_value_storage *storage)
884 {
885 initialize_frame (&storage->initial);
886 storage->current = &storage->initial;
887 }
888
889 /* Must be called for any initialized storage object before its
890 lifetime ends. Free all dynamically-allocated frames. */
891 static void
892 finalize_storage (struct emacs_value_storage *storage)
893 {
894 struct emacs_value_frame *next = storage->initial.next;
895 while (next != NULL)
896 {
897 struct emacs_value_frame *current = next;
898 next = current->next;
899 free (current);
900 }
901 }
902
903 /* Allocate a new value from STORAGE and stores OBJ in it. Return
904 NULL if allocations fails and use ENV for non local exit reporting. */
905 static emacs_value
906 allocate_emacs_value (emacs_env *env, struct emacs_value_storage *storage,
907 Lisp_Object obj)
908 {
909 eassert (storage->current);
910 eassert (storage->current->offset < value_frame_size);
911 eassert (! storage->current->next);
912 if (storage->current->offset == value_frame_size - 1)
913 {
914 storage->current->next = malloc (sizeof *storage->current->next);
915 if (! storage->current->next)
916 {
917 module_out_of_memory (env);
918 return NULL;
919 }
920 initialize_frame (storage->current->next);
921 storage->current = storage->current->next;
922 }
923 emacs_value value = storage->current->objects + storage->current->offset;
924 value->v = obj;
925 ++storage->current->offset;
926 return value;
927 }
928
929 /* Mark all objects allocated from local environments so that they
930 don't get garbage-collected. */
931 void mark_modules (void)
932 {
933 for (Lisp_Object tem = Vmodule_environments; CONSP (tem); tem = XCDR (tem))
934 {
935 struct env_storage *env = XSAVE_POINTER (tem, 0);
936 for (struct emacs_value_frame *frame = &env->priv.storage.initial;
937 frame != NULL;
938 frame = frame->next)
939 for (int i = 0; i < frame->offset; ++i)
940 mark_object (frame->objects[i].v);
941 }
942 }
943
944 \f
945 /* Environment lifetime management. */
946
947 /* Must be called before the environment can be used. */
948 static void
949 initialize_environment (struct env_storage *env)
950 {
951 env->priv.pending_non_local_exit = emacs_funcall_exit_return;
952 initialize_storage (&env->priv.storage);
953 env->pub.size = sizeof env->pub;
954 env->pub.private_members = &env->priv;
955 env->pub.make_global_ref = module_make_global_ref;
956 env->pub.free_global_ref = module_free_global_ref;
957 env->pub.non_local_exit_check = module_non_local_exit_check;
958 env->pub.non_local_exit_clear = module_non_local_exit_clear;
959 env->pub.non_local_exit_get = module_non_local_exit_get;
960 env->pub.non_local_exit_signal = module_non_local_exit_signal;
961 env->pub.non_local_exit_throw = module_non_local_exit_throw;
962 env->pub.make_function = module_make_function;
963 env->pub.funcall = module_funcall;
964 env->pub.intern = module_intern;
965 env->pub.type_of = module_type_of;
966 env->pub.is_not_nil = module_is_not_nil;
967 env->pub.eq = module_eq;
968 env->pub.extract_integer = module_extract_integer;
969 env->pub.make_integer = module_make_integer;
970 env->pub.extract_float = module_extract_float;
971 env->pub.make_float = module_make_float;
972 env->pub.copy_string_contents = module_copy_string_contents;
973 env->pub.make_string = module_make_string;
974 env->pub.make_user_ptr = module_make_user_ptr;
975 env->pub.get_user_ptr = module_get_user_ptr;
976 env->pub.set_user_ptr = module_set_user_ptr;
977 env->pub.get_user_finalizer = module_get_user_finalizer;
978 env->pub.set_user_finalizer = module_set_user_finalizer;
979 env->pub.vec_set = module_vec_set;
980 env->pub.vec_get = module_vec_get;
981 env->pub.vec_size = module_vec_size;
982 Vmodule_environments = Fcons (make_save_ptr (env), Vmodule_environments);
983 }
984
985 /* Must be called before the lifetime of the environment object
986 ends. */
987 static void
988 finalize_environment (struct env_storage *env)
989 {
990 finalize_storage (&env->priv.storage);
991 Vmodule_environments = XCDR (Vmodule_environments);
992 }
993
994 \f
995 /* Non-local exit handling. */
996
997 /* Must be called after setting up a handler immediately before
998 returning from the function. See the comments in lisp.h and the
999 code in eval.c for details. The macros below arrange for this
1000 function to be called automatically. DUMMY is ignored. */
1001 static void
1002 module_reset_handlerlist (const int *dummy)
1003 {
1004 handlerlist = handlerlist->next;
1005 }
1006
1007 /* Called on `signal'. ERR is a pair (SYMBOL . DATA), which gets
1008 stored in the environment. Set the pending non-local exit flag. */
1009 static void
1010 module_handle_signal (emacs_env *env, Lisp_Object err)
1011 {
1012 module_non_local_exit_signal_1 (env, XCAR (err), XCDR (err));
1013 }
1014
1015 /* Called on `throw'. TAG_VAL is a pair (TAG . VALUE), which gets
1016 stored in the environment. Set the pending non-local exit flag. */
1017 static void
1018 module_handle_throw (emacs_env *env, Lisp_Object tag_val)
1019 {
1020 module_non_local_exit_throw_1 (env, XCAR (tag_val), XCDR (tag_val));
1021 }
1022
1023 \f
1024 /* Function environments. */
1025
1026 /* Return a string object that contains a user-friendly
1027 representation of the function environment. */
1028 static Lisp_Object
1029 module_format_fun_env (const struct module_fun_env *env)
1030 {
1031 /* Try to print a function name if possible. */
1032 const char *path, *sym;
1033 if (dynlib_addr (env->subr, &path, &sym))
1034 {
1035 static char const format[] = "#<module function %s from %s>";
1036 int size = snprintf (NULL, 0, format, sym, path);
1037 eassert (size > 0);
1038 char buffer[size + 1];
1039 snprintf (buffer, sizeof buffer, format, sym, path);
1040 return make_unibyte_string (buffer, size);
1041 }
1042 else
1043 {
1044 static char const format[] = "#<module function at %p>";
1045 void *subr = env->subr;
1046 int size = snprintf (NULL, 0, format, subr);
1047 eassert (size > 0);
1048 char buffer[size + 1];
1049 snprintf (buffer, sizeof buffer, format, subr);
1050 return make_unibyte_string (buffer, size);
1051 }
1052 }
1053
1054 \f
1055 /* Segment initializer. */
1056
1057 void
1058 syms_of_module (void)
1059 {
1060 DEFSYM (Qmodule_refs_hash, "module-refs-hash");
1061 DEFVAR_LISP ("module-refs-hash", Vmodule_refs_hash,
1062 doc: /* Module global referrence table. */);
1063
1064 Vmodule_refs_hash
1065 = make_hash_table (hashtest_eq, make_number (DEFAULT_HASH_SIZE),
1066 make_float (DEFAULT_REHASH_SIZE),
1067 make_float (DEFAULT_REHASH_THRESHOLD),
1068 Qnil);
1069 Funintern (Qmodule_refs_hash, Qnil);
1070
1071 DEFSYM (Qmodule_environments, "module-environments");
1072 DEFVAR_LISP ("module-environments", Vmodule_environments,
1073 doc: /* List of active module environments. */);
1074 Vmodule_environments = Qnil;
1075 /* Unintern `module-environments' because it is only used
1076 internally. */
1077 Funintern (Qmodule_environments, Qnil);
1078
1079 DEFSYM (Qmodule_load_failed, "module-load-failed");
1080 Fput (Qmodule_load_failed, Qerror_conditions,
1081 listn (CONSTYPE_PURE, 2, Qmodule_load_failed, Qerror));
1082 Fput (Qmodule_load_failed, Qerror_message,
1083 build_pure_c_string ("Module load failed"));
1084
1085 DEFSYM (Qinvalid_module_call, "invalid-module-call");
1086 Fput (Qinvalid_module_call, Qerror_conditions,
1087 listn (CONSTYPE_PURE, 2, Qinvalid_module_call, Qerror));
1088 Fput (Qinvalid_module_call, Qerror_message,
1089 build_pure_c_string ("Invalid module call"));
1090
1091 DEFSYM (Qinvalid_arity, "invalid-arity");
1092 Fput (Qinvalid_arity, Qerror_conditions,
1093 listn (CONSTYPE_PURE, 2, Qinvalid_arity, Qerror));
1094 Fput (Qinvalid_arity, Qerror_message,
1095 build_pure_c_string ("Invalid function arity"));
1096
1097 initialize_storage (&global_storage);
1098
1099 /* Unintern `module-refs-hash' because it is internal-only and Lisp
1100 code or modules should not access it. */
1101 Funintern (Qmodule_refs_hash, Qnil);
1102
1103 defsubr (&Smodule_load);
1104
1105 /* Don't call defsubr on `module-call' because that would intern it,
1106 but `module-call' is an internal function that users cannot
1107 meaningfully use. Instead, assign its definition to a private
1108 variable. */
1109 XSETPVECTYPE (&Smodule_call, PVEC_SUBR);
1110 XSETSUBR (module_call_func, &Smodule_call);
1111 }
1112
1113 /* Unlike syms_of_module, this initializer is called even from an
1114 initialized (dumped) Emacs. */
1115
1116 void
1117 module_init (void)
1118 {
1119 /* It is not guaranteed that dynamic initializers run in the main thread,
1120 therefore detect the main thread here. */
1121 #ifdef HAVE_THREADS_H
1122 main_thread = thrd_current ();
1123 #elif defined HAVE_PTHREAD
1124 main_thread = pthread_self ();
1125 #elif defined WINDOWSNT
1126 /* This calls APIs that are only available on Vista and later. */
1127 # if false
1128 /* GetCurrentProcess returns a pseudohandle, which must be duplicated. */
1129 if (! DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
1130 GetCurrentProcess (), &main_thread,
1131 SYNCHRONIZE | THREAD_QUERY_INFORMATION,
1132 FALSE, 0))
1133 emacs_abort ();
1134 # else
1135 /* GetCurrentThread returns a pseudohandle, which must be duplicated. */
1136 HANDLE th = GetCurrentThread ();
1137 if (!DuplicateHandle (GetCurrentProcess (), th,
1138 GetCurrentProcess (), &main_thread, 0, FALSE,
1139 DUPLICATE_SAME_ACCESS))
1140 emacs_abort ();
1141 main_thread_id = GetCurrentThreadId ();
1142 # endif
1143 #endif
1144 }