Add portable dumper
Add a new portable dumper as an alternative to unexec. Use it by default. * src/dmpstruct.awk: New file. * src/doc.c (get_doc_string): use will_dump_p(). * src/editfns.c (styled_format): silence compiler warning with UNINIT. * src/emacs-module.c (syms_of_module): staticpro ltv_mark. * src/emacs.c (gflags): new variable. (init_cmdargs): unwrap (string_starts_with_p, find_argument, dump_error_to_string) (load_pdump): new functions. (main): detect pdumper and --temacs invocation; actually load portable dump when detected; set gflags as appropriate; changes to init functions throughout to avoid passing explicit 'initialized' argument. * src/eval.c (inhibit_lisp_code): remove unused variable. (init_eval_once_for_pdumper): new function. (init_eval_once): call it. * src/filelock.c: CANNOT_DUMP -> will_dump_p() * src/fingerprint-dummy.c: new file * src/fingerprint.h: new file * src/fns.c: CANNOT_DUMP -> will_dump_p(), etc. (weak_hash_tables): remove (hashfn_equal, hashfn_eql): un-staticify (make_hash_table): set new 'next_weak' hash table field; drop global weak_hash_tables logic. (copy_hash_table): drop global weak_hash_tables logic. (hash_table_rehash): new function. (hash_lookup, hash_put, hash_remove_from_table, hash_clear): rehash if needed. (sweep_weak_table): un-staticify; explain logic; bool-ify. (sweep_weak_hash_tables): remove function. * src/font.c (syms_of_font): remember pdumper stuff. * src/fontset.c (syms_of_fontset): remember pdumper stuff. * src/frame.c (make_initial_frame): don't reset Vframe_list. (init_frame_once_for_pdumper, init_frame_once): new functions. (syms_of_frame): remove redundant staticpro. * src/fringe.c (init_fringe_once_for_pdumper): new functin. (init_fringe_once): call it. * src/ftcrfont.c (syms_of_ftcrfont_for_pdumper): new function. (syms_of_ftcrfont): call it. * src/ftfont.c (syms_of_ftfont_for_pdumper): new function. (syms_of_ftfont): call it. * src/ftxont.c (syms_of_ftxfont_for_pdumper): new function. (syms_of_ftxfont): call it. * src/gmalloc.c: adjust for pdumper througout (DUMPED): remove weird custom dumped indicator. * src/gnutls.c (syms_of_gnutls): pdumper note for gnutls_global_initialized. * src/image.c (syms_of_image): add pdumper comment, initializer note. * src/insdel.c (prepare_to_modify_buffer_1): account for buffer contents possibly being in dump image. * src/keyboard.c (syms_of_keyboard_for_pdumper): new function. (syms_of_keyboard): staticpro more; call pdumper syms function. * src/lisp.h: add comments throughout (gflags): declare. (will_dump_p, will_bootstrap_p, will_dump_with_pdumper_p) (dumped_with_pdumper_p, will_dump_with_unexec_p) (dumped_with_unexec_p, definitely_will_not_unexec_p): new functions. (POWER_OF_2, ROUNDUP): move macros. (PSEUDOVECTOR_TYPE, PSEUDOVECTOR_TYPEP): take vectorlike header pointer instead of vector; constify. (Lisp_Hash_Table): add comment about need to rehash on access; add comment for next_weak. (HASH_KEY, HASH_VALUE, HASH_HASH, HASH_TABLE_SIZE): const-ify. (hash_table_rehash): declare. (hash_rehash_needed_p, hash_rehash_if_needed): new functions. (finalizers, doomed_finalizers): declare extern. (SUBR_SECTION_ATTRIBUTE): new macro. (staticvec, staticidx): un-static-ify. (sweep_weak_hash_tables): remove declaration. (sweep_weak_table): declare. (hashfn_eql, hashfn_equal): declare. (number_finalizers_run): new variable. (Vdead): externify when ENABLE_CHECKING. (gc_root_type): new enumeration. (gc_root_visitor): new struct. (visit_static_gc_roots): declare. (vectorlike_nbytes): declare. (vector_nbytes): define as trivial inline function wrapper for vectorlike_nbytes. (init_obarray_once): change signature. (primary_thread): extern-ify. (init_buffer): change signature. (init_frame_once): declare. * src/lread.c (readevalloop): adjust for new dumped predicates. (init_obarray_once): new function. (ndefsubr): new variable. (defsubr): increment it. (load_path_check): adjust for pdumper. (load_path_default): use pdumper functions; adjust for dump search. * src/macfont.m (macfont_init_font_change_handler): avoid shadowing global. (syms_of_macfont_for_pdumper): new function. (syms_of_macfont): call it. * src/menu.c (syms_of_menu): staticpro more stuff. * src/minibuf.c (Ftry_completion): rehash if needed. (init_minibuf_once_for_pdumper): new function. (init_minibuf_once): call it. * src/nsfont.m (syms_of_nsfns): staticpro more. * src/nsfont.m (syms_of_nsfont_for_pdumper): new function. (syms_of_nsfont): call it. * src/nsterm.m (syms_of_nsfont): remember pdumper stuff. * src/pdumper.c: new file. * src/pdumper.h: new file. * src/process.c (init_process_emacs): use new pdumper functions instead of CANNOT_DUMP. * src/profiler.c (syms_of_profiler_for_pdumper): new function. (syms_of_profiler_for_pdumper): call it. * src/search.c (syms_of_search_for_pdumper): new function. (syms_of_search_for_pdumper): call it. * src/sheap.c (bss_sbrk_did_unexec): remove. * src/sheap.h (bss_sbrk_did_unexec): remove. * src/syntax.c (syms_of_syntax): don't redundantly staticpro re_match_object. * src/sysdep.c: use will_dump_with_unexec_p() instead of bss hack thing. * src/syssignals.h (init_sigsegv): declare. * src/systime.h (init_timefns): remove bool from signature. * src/textprop.c (syms_of_textprop): move staticpro. * src/thread.c (main_thread_p): constify. * src/thread.h (main_thread_p): constify. * src/timefns.c (init_timefns): remove bool from signature. (syms_of_timefns_for_pdumper): new function. (syms_of_timefns): call it. * src/w32.c: rearrange code. * src/w32.h (w32_relocate): declare. * src/w32fns.c (syms_of_w32fns): add pdumper note. * src/w32font.c (syms_of_w32font_for_pdumper): new function. (syms_of_w32font): call it. * src/w32heap.c (using_dynamic_heap): new variable. (init_heap): use it. * src/w32menu.c (syms_of_w32menu): add pdumper note. * src/w32proc.c (ctrl_c_handler, mainCRTStartup, _start, open_input_file) (rva_to_section, close_file_data): move here. * src/w32uniscribe.c (syms_of_w32uniscribe_for_pdumper): new function. (syms_of_w32uniscribe): call it. * src/window.c (init_window_once_for_pdumper): new function. (init_window_once): call it; staticpro more stuff. * src/xfont.c (syms_of_xfont_for_pdumper): new function. (syms_of_xfont): call it. * src/xftfont.c (syms_of_xftfont_for_pdumper): new function. (syms_of_xftfont): call it. * src/xmenu.c (syms_of_xmenu_for_pdumper): new function. (syms_of_xmenu): call it. * src/xselect.c (syms_of_xselect_for_pdumper): new function. (syms_of_xselect): call it. * src/xsettings.c (syms_of_xsettings): add more pdumper notes. * src/term.c (syms_of_xterm): add pdumper note. * src/dispnew.c (init_faces_initial): new function. (init_display_interactive): rename from init_display; use will_dump_p instead of !initialized. Initialize faces early for pdumper if needed. (init_display): new function. (syms_of_display_for_pdumper): new function. (syms_of_display): call it. * src/dbusbind.c (syms_of_dbusbind): Add TODO for bus reset on pdumper load. * src/data.c (Fdefalias): Use will_dump_p instead of Vpurify_flag. (Fmake_variable_buffer_local): silence compiler warning with -Og by making valcontents UNINIT. (arith_driver): silence compiler warning with UNINIT. * src/conf_post.h (ATTRIBUTE_SECTION): new macro. * src/composite.c (composition_gstring_put_cache): rehash hash table if needed. * src/coding.c (init_coding_once, syms_of_coding): remember pdumper stuff. * src/charset.h (charset_table_size, charset_table_user): declare. * src/charset.c (charset_table_used, charset_table_size): un-static. (init_charset_oncem, syms_of_charset): remember pdumper stuff. * src/category.c (category_table_version): remove obsolete variable. * src/callint.c (syms_of_callint): staticpro 'preserved_fns' (init_callproc): use will_dump_p instead of !CANNOT_DUMP. * src/bytecode.c (exec_byte_code): rehash table tables if needed * src/buffer.c (alloc_buffer_text, free_buffer_text): account for pdumper (init_buffer_once): add TODO; remember stuff for pdumper. (init_buffer): don't take initialized argument; adjust for pdumper. * src/atimer.c (init_atimer): initialize subr only if !initialized. * src/alloc.c: (vector_marked_p, set_vector_marked) (vectorlike_marked_p, set_vectorlike_marked, cons_marked_p) (set_cons_marked, string_marked_p, set_string_marked) (symbol_marked_p, set_symbol_marked, interval_marked_p) (set_interval_marked): new accessor routines. Use them instead of raw GC access throughout. (Vdead): make non-static when ENABLE_CHECKING. (vectorlike_nbytes): rename of 'vector_nbytes'; take a vectorlike header as input instead of a vector. (number_finalizers_run): new internal C variable. (mark_maybe_object): check for pdumper objects. (valid_pointer_p): don't be gratuitously inefficient under rr(1). (make_pure_c_string): add support for size_byte = -2 mode indicating that string data points into Emacs image rodata. (visit_vectorlike_root): visits GC roots embedded in vectorlike objects. (visit_buffer_root): visits GC roots embedded in our totally-not-a-buffer buffer global objects. (visit_static_gc_roots): visit GC roots in the Emacs data section. (mark_object_root_visitor): root callback used for conventional GC marking (weak_hash_tables): new internal variable for tracking found weak hash tables during GC. (mark_and_sweep_weak_table_contents): new weak hash table marking. (garbage_collect_1): use new GC root visitor machinery. (mark_vectorlike): accept a vectorlike_header instead of a Lisp_Vector. (mark_frame, mark_window, mark_hash_table): new functions. (mark_object): initialize 'm'; check for pdumper objects and use new mark-bit accessors throughout. Remove some object-specific marking code and move to helper functions above. (survives_gc_p): check for pdumper objects. (gc-sweep): clear pdumper mark bits. (init_alloc_once_for_pdumper): new helper function for early init called both during normal init and pdumper load. (init_alloc_once): pdumper integration. * src/Makefile.in: Rewrite dumping for pdumper; add pdumper.o; invoke temacs with --temacs command line option; build dmpstruct.h from dmpstruct.awk; stop relying on CANNOT_DUMP; clean up pdumper intermediate files during build. * nextstep/Makefile.in: build emacs.pdmp into NS packages * lisp/startup.el: account for new '--temacs' and '--dump-file' command line option. * lisp/loadup.el: rewrite early init to account for pdumper; use injected 'dump-mode' variable (set via the new '--temacs' option) instead of parsing command line. * lisp/cus-start.el: Check 'dump-mode' instead of 'purify-flag', since the new 'dump-mode' * lib-src/make-fingerprint.c: new program * lib-src/Makefile.in: built make-fingerprint utility program * configure.ac: Add --with-pdumper toggle to control pdumper support; add --with-unexec toggle to control unexec support. Add --with-dumping option to control which dumping strategy we use by default. Adjust for pdumper throughout. Check for posix_madvise. * Makefile.in: Add @DUMPING@ substitution; add pdumper mode. * .gitignore: Add make-fingerprint, temacs.in, fingerprint.c, dmpstruct.h, and pdumper dump files.
This commit is contained in:
parent
2a3bd6798e
commit
d12e5d003d
92 changed files with 8312 additions and 965 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -171,6 +171,7 @@ lib-src/emacsclient
|
|||
lib-src/etags
|
||||
lib-src/hexl
|
||||
lib-src/make-docfile
|
||||
lib-src/make-fingerprint
|
||||
lib-src/movemail
|
||||
lib-src/profile
|
||||
lib-src/test-distrib
|
||||
|
@ -184,6 +185,10 @@ src/bootstrap-emacs
|
|||
src/emacs
|
||||
src/emacs-[0-9]*
|
||||
src/temacs
|
||||
src/temacs.in
|
||||
src/fingerprint.c
|
||||
src/dmpstruct.h
|
||||
src/*.pdmp
|
||||
|
||||
# Character-set info.
|
||||
admin/charsets/jisx2131-filter
|
||||
|
|
|
@ -66,6 +66,8 @@
|
|||
|
||||
SHELL = @SHELL@
|
||||
|
||||
DUMPING=@DUMPING@
|
||||
|
||||
# This only matters when inheriting a CDPATH not starting with the
|
||||
# current directory.
|
||||
CDPATH=
|
||||
|
@ -491,6 +493,9 @@ install-arch-dep: src install-arch-indep install-etcdoc install-$(NTDIR)
|
|||
$(MAKE) -C lib-src install
|
||||
ifeq (${ns_self_contained},no)
|
||||
${INSTALL_PROGRAM} $(INSTALL_STRIP) src/emacs${EXEEXT} "$(DESTDIR)${bindir}/$(EMACSFULL)"
|
||||
ifeq (${DUMPING},pdumper)
|
||||
${INSTALL_DATA} src/emacs.pdmp "$(DESTDIR)${libexecdir}/emacs/${version}/${configuration}"/emacs.pdmp
|
||||
endif
|
||||
-chmod 755 "$(DESTDIR)${bindir}/$(EMACSFULL)"
|
||||
ifndef NO_BIN_LINK
|
||||
rm -f "$(DESTDIR)${bindir}/$(EMACS)"
|
||||
|
|
140
configure.ac
140
configure.ac
|
@ -311,6 +311,87 @@ this option's value should be 'yes', 'no', 'alsa', 'oss', or 'bsd-ossaudio'.])
|
|||
],
|
||||
[with_sound=$with_features])
|
||||
|
||||
AC_ARG_WITH([pdumper],
|
||||
AS_HELP_STRING(
|
||||
[--with-pdumper=VALUE],
|
||||
[enable pdumper support unconditionally
|
||||
('yes', 'no', or 'auto': default 'auto')]),
|
||||
[ case "${withval}" in
|
||||
yes|no|auto) val=$withval ;;
|
||||
*) AC_MSG_ERROR(
|
||||
['--with-pdumper=$withval' is invalid;
|
||||
this option's value should be 'yes' or 'no'.]) ;;
|
||||
esac
|
||||
with_pdumper=$val
|
||||
],
|
||||
[with_pdumper=auto])
|
||||
|
||||
AC_ARG_WITH([unexec],
|
||||
AS_HELP_STRING(
|
||||
[--with-unexec=VALUE],
|
||||
[enable unexec support unconditionally
|
||||
('yes', 'no', or 'auto': default 'auto')]),
|
||||
[ case "${withval}" in
|
||||
yes|no|auto) val=$withval ;;
|
||||
*) AC_MSG_ERROR(
|
||||
['--with-unexec=$withval' is invalid;
|
||||
this option's value should be 'yes' or 'no'.]) ;;
|
||||
esac
|
||||
with_unexec=$val
|
||||
],
|
||||
[with_unexec=auto])
|
||||
|
||||
AC_ARG_WITH([dumping],[AS_HELP_STRING([--with-dumping=VALUE],
|
||||
[kind of dumping to use for initial Emacs build
|
||||
(VALUE one of: pdumper, unexec, none; default pdumper)])],
|
||||
[ case "${withval}" in
|
||||
pdumper|unexec|none) val=$withval ;;
|
||||
*) AC_MSG_ERROR(['--with-dumping=$withval is invalid;
|
||||
this option's value should be 'pdumper', 'unexec', or 'none'.])
|
||||
;;
|
||||
esac
|
||||
with_dumping=$val
|
||||
],
|
||||
[with_dumping=pdumper])
|
||||
|
||||
if test "$with_pdumper" = "auto"; then
|
||||
if test "$with_dumping" = "pdumper"; then
|
||||
with_pdumper=yes
|
||||
else
|
||||
with_pdumper=no
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$with_unexec" = "auto"; then
|
||||
if test "$with_dumping" = "unexec"; then
|
||||
with_unexec=yes
|
||||
else
|
||||
with_unexec=no
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$with_dumping" = "pdumper" && test "$with_pdumper" = "no"; then
|
||||
AC_MSG_ERROR(['--with-dumping=pdumper' requires pdumper support])
|
||||
fi
|
||||
|
||||
if test "$with_dumping" = "unexec" && test "$with_unexec" = "no"; then
|
||||
AC_MSG_ERROR(['--with-dumping=unexec' requires unexec support])
|
||||
fi
|
||||
|
||||
if test "$with_pdumper" = "yes"; then
|
||||
AC_DEFINE(HAVE_PDUMPER, 1, [Define to build with portable dumper support])
|
||||
fi
|
||||
|
||||
if test "$with_unexec" = "yes"; then
|
||||
CANNOT_DUMP=no
|
||||
else
|
||||
CANNOT_DUMP=yes
|
||||
fi
|
||||
|
||||
DUMPING=$with_dumping
|
||||
AC_SUBST(DUMPING)
|
||||
AC_SUBST(CANNOT_DUMP)
|
||||
|
||||
dnl FIXME currently it is not the last.
|
||||
dnl This should be the last --with option, because --with-x is
|
||||
dnl added later on when we find the file name of X, and it's best to
|
||||
|
@ -1215,6 +1296,10 @@ AC_PATH_PROG(GZIP_PROG, gzip)
|
|||
test $with_compress_install != yes && test -n "$GZIP_PROG" && \
|
||||
GZIP_PROG=" # $GZIP_PROG # (disabled by configure --without-compress-install)"
|
||||
|
||||
if test "$with_dumping" = "unexec" && test "$opsys" = "nacl"; then
|
||||
AC_MSG_ERROR([nacl is not compatible with --with-dumping=unexec])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for 'find' args to delete a file],
|
||||
[emacs_cv_find_delete],
|
||||
[if touch conftest.tmp && find conftest.tmp -delete 2>/dev/null &&
|
||||
|
@ -1227,25 +1312,21 @@ AC_SUBST([FIND_DELETE])
|
|||
|
||||
PAXCTL_dumped=
|
||||
PAXCTL_notdumped=
|
||||
if test "$CANNOT_DUMP" != yes; then
|
||||
if test $opsys = gnu-linux; then
|
||||
if test "${SETFATTR+set}" != set; then
|
||||
AC_CACHE_CHECK([for setfattr],
|
||||
[emacs_cv_prog_setfattr],
|
||||
[touch conftest.tmp
|
||||
if (setfattr -n user.pax.flags conftest.tmp) >/dev/null 2>&1; then
|
||||
emacs_cv_prog_setfattr=yes
|
||||
else
|
||||
emacs_cv_prog_setfattr=no
|
||||
fi])
|
||||
if test "$emacs_cv_prog_setfattr" = yes; then
|
||||
PAXCTL_notdumped='$(SETFATTR) -n user.pax.flags -v er'
|
||||
SETFATTR=setfattr
|
||||
else
|
||||
SETFATTR=
|
||||
fi
|
||||
rm -f conftest.tmp
|
||||
AC_SUBST([SETFATTR])
|
||||
if test "$CANNOT_DUMP" = "no" && test $opsys = gnu-linux; then
|
||||
if test "${SETFATTR+set}" != set; then
|
||||
AC_CACHE_CHECK([for setfattr],
|
||||
[emacs_cv_prog_setfattr],
|
||||
[touch conftest.tmp
|
||||
if (setfattr -n user.pax.flags conftest.tmp) >/dev/null 2>&1; then
|
||||
emacs_cv_prog_setfattr=yes
|
||||
else
|
||||
emacs_cv_prog_setfattr=no
|
||||
fi])
|
||||
if test "$emacs_cv_prog_setfattr" = yes; then
|
||||
PAXCTL_notdumped='$(SETFATTR) -n user.pax.flags -v er'
|
||||
SETFATTR=setfattr
|
||||
else
|
||||
SETFATTR=
|
||||
fi
|
||||
fi
|
||||
case $opsys,$PAXCTL_notdumped,$emacs_uname_r in
|
||||
|
@ -1382,22 +1463,12 @@ AC_CACHE_CHECK([whether addresses are sanitized],
|
|||
[emacs_cv_sanitize_address=yes],
|
||||
[emacs_cv_sanitize_address=no])])
|
||||
|
||||
dnl The function dump-emacs will not be defined and temacs will do
|
||||
dnl (load "loadup") automatically unless told otherwise.
|
||||
test "x$CANNOT_DUMP" = "x" && CANNOT_DUMP=no
|
||||
case "$opsys" in
|
||||
nacl) CANNOT_DUMP=yes ;;
|
||||
esac
|
||||
|
||||
if test "$CANNOT_DUMP" = "yes"; then
|
||||
AC_DEFINE(CANNOT_DUMP, 1, [Define if Emacs cannot be dumped on your system.])
|
||||
AC_DEFINE(CANNOT_DUMP, 1, [Define if Emacs should not support unexec.])
|
||||
elif test "$emacs_cv_sanitize_address" = yes; then
|
||||
AC_MSG_WARN([[Addresses are sanitized; suggest CANNOT_DUMP=yes]])
|
||||
fi
|
||||
|
||||
AC_SUBST(CANNOT_DUMP)
|
||||
|
||||
|
||||
UNEXEC_OBJ=unexelf.o
|
||||
case "$opsys" in
|
||||
# MSDOS uses unexcoff.o
|
||||
|
@ -1476,8 +1547,9 @@ case "$opsys" in
|
|||
LD_SWITCH_SYSTEM="\$(LD_SWITCH_X_SITE_RPATH) $LD_SWITCH_SYSTEM" ;;
|
||||
esac
|
||||
|
||||
|
||||
C_SWITCH_MACHINE=
|
||||
|
||||
test "$CANNOT_DUMP" = yes ||
|
||||
case $canonical in
|
||||
alpha*)
|
||||
AC_CHECK_DECL([__ELF__])
|
||||
|
@ -4064,6 +4136,9 @@ dnl No need to check for posix_memalign if aligned_alloc works.
|
|||
AC_CHECK_FUNCS([aligned_alloc posix_memalign], [break])
|
||||
AC_CHECK_DECLS([aligned_alloc], [], [], [[#include <stdlib.h>]])
|
||||
|
||||
# Dump loading
|
||||
AC_CHECK_FUNCS([posix_madvise])
|
||||
|
||||
dnl Cannot use AC_CHECK_FUNCS
|
||||
AC_CACHE_CHECK([for __builtin_frame_address],
|
||||
[emacs_cv_func___builtin_frame_address],
|
||||
|
@ -5540,6 +5615,9 @@ AS_ECHO([" Does Emacs use -lXaw3d? ${HAVE_XAW3D
|
|||
Does Emacs use toolkit scroll bars? ${USE_TOOLKIT_SCROLL_BARS}
|
||||
Does Emacs support Xwidgets (requires gtk3)? ${HAVE_XWIDGETS}
|
||||
Does Emacs have threading support in lisp? ${threads_enabled}
|
||||
Does Emacs support the portable dumper? ${with_pdumper}
|
||||
Does Emacs support legacy unexec dumping? ${with_unexec}
|
||||
Which dumping strategy does Emacs use? ${with_dumping}
|
||||
"])
|
||||
|
||||
if test -n "${EMACSDATA}"; then
|
||||
|
|
|
@ -167,7 +167,7 @@ UTILITIES = profile${EXEEXT} hexl${EXEEXT} \
|
|||
$(if $(with_mailutils), , movemail${EXEEXT}) \
|
||||
$(and $(use_gamedir), update-game-score${EXEEXT})
|
||||
|
||||
DONT_INSTALL= make-docfile${EXEEXT}
|
||||
DONT_INSTALL= make-docfile${EXEEXT} make-fingerprint${EXEEXT}
|
||||
|
||||
# Like UTILITIES, but they're not system-dependent, and should not be
|
||||
# deleted by the distclean target.
|
||||
|
@ -385,6 +385,9 @@ profile${EXEEXT}: ${srcdir}/profile.c $(NTLIB) $(config_h)
|
|||
make-docfile${EXEEXT}: ${srcdir}/make-docfile.c $(NTLIB) $(config_h)
|
||||
$(AM_V_CCLD)$(CC) ${ALL_CFLAGS} $< $(NTLIB) $(LOADLIBES) -o $@
|
||||
|
||||
make-fingerprint${EXEEXT}: ${srcdir}/make-fingerprint.c $(NTLIB) $(config_h)
|
||||
$(AM_V_CCLD)$(CC) ${ALL_CFLAGS} $< $(NTLIB) $(LOADLIBES) -o $@
|
||||
|
||||
movemail${EXEEXT}: ${srcdir}/movemail.c pop.o $(NTLIB) $(config_h)
|
||||
$(AM_V_CCLD)$(CC) ${ALL_CFLAGS} ${MOVE_FLAGS} $< pop.o \
|
||||
$(NTLIB) $(LOADLIBES) $(LIBS_MOVE) -o $@
|
||||
|
|
113
lib-src/make-fingerprint.c
Normal file
113
lib-src/make-fingerprint.c
Normal file
|
@ -0,0 +1,113 @@
|
|||
/* Hash inputs and generate C file with the digest.
|
||||
|
||||
Copyright (C) 1985-1986, 1992-1994, 1997, 1999-2016 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or (at
|
||||
your option) any later version.
|
||||
|
||||
GNU Emacs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
/* The arguments given to this program are all the object files that
|
||||
go into building GNU Emacs. There is no special search logic to find
|
||||
the files. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysstdio.h>
|
||||
#include <sha256.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#ifdef WINDOWSNT
|
||||
/* Defined to be sys_fopen in ms-w32.h, but only #ifdef emacs, so this
|
||||
is really just insurance. */
|
||||
#undef fopen
|
||||
#include <direct.h>
|
||||
#endif /* WINDOWSNT */
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
bool raw = false;
|
||||
while (0 <= (c = getopt (argc, argv, "rh")))
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'r':
|
||||
raw = true;
|
||||
break;
|
||||
case 'h':
|
||||
printf ("make-fingerprint [-r] FILES...: compute a hash\n");
|
||||
return 0;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
struct sha256_ctx ctx;
|
||||
sha256_init_ctx (&ctx);
|
||||
|
||||
for (int i = optind; i < argc; ++i)
|
||||
{
|
||||
FILE *f = fopen (argv[i], "r" FOPEN_BINARY);
|
||||
if (!f)
|
||||
{
|
||||
fprintf (stderr, "%s: Error: could not open %s\n",
|
||||
argv[0], argv[i]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char buf[128*1024];
|
||||
do
|
||||
{
|
||||
size_t chunksz = fread (buf, 1, sizeof (buf), f);
|
||||
if (ferror (f))
|
||||
{
|
||||
fprintf (stderr, "%s: Error: could not read %s\n",
|
||||
argv[0], argv[i]);
|
||||
return 1;
|
||||
}
|
||||
sha256_process_bytes (buf, chunksz, &ctx);
|
||||
} while (!feof (f));
|
||||
fclose (f);
|
||||
}
|
||||
|
||||
uint8_t digest[32];
|
||||
sha256_finish_ctx (&ctx, digest);
|
||||
|
||||
if (raw)
|
||||
{
|
||||
for (int i = 0; i < 32; ++i)
|
||||
printf ("%02X", digest[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("#include \"fingerprint.h\"\n");
|
||||
printf ("\n");
|
||||
printf ("const uint8_t fingerprint[32] = { ");
|
||||
for (int i = 0; i < 32; ++i)
|
||||
printf ("%s0x%02X", i ? ", " : "", digest[i]);
|
||||
printf (" };\n");
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* make-fingerprint.c ends here */
|
|
@ -730,7 +730,7 @@ since it could result in memory overflow and make Emacs crash."
|
|||
;; If this is NOT while dumping Emacs, set up the rest of the
|
||||
;; customization info. This is the stuff that is not needed
|
||||
;; until someone does M-x customize etc.
|
||||
(unless purify-flag
|
||||
(unless dump-mode
|
||||
;; Add it to the right group(s).
|
||||
(if (listp group)
|
||||
(dolist (g group)
|
||||
|
@ -752,7 +752,7 @@ since it could result in memory overflow and make Emacs crash."
|
|||
;; Record cus-start as loaded if we have set up all the info that we can.
|
||||
;; Don't record it as loaded if we have only set up the standard values
|
||||
;; and safe/risky properties.
|
||||
(unless purify-flag
|
||||
(unless dump-mode
|
||||
(provide 'cus-start))
|
||||
|
||||
;;; cus-start.el ends here
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
;; FIXME: Now that macroexpansion is also performed when loading an interpreted
|
||||
;; file, this is not a real problem any more.
|
||||
(defconst pcase--memoize (make-hash-table :weakness 'key :test 'eq))
|
||||
;; (defconst pcase--memoize (make-hash-table :test 'eq))
|
||||
;; (defconst pcase--memoize-1 (make-hash-table :test 'eq))
|
||||
;; (defconst pcase--memoize-2 (make-hash-table :weakness 'key :test 'equal))
|
||||
|
||||
|
|
|
@ -1009,7 +1009,7 @@ directory if it does not exist."
|
|||
;; Make sure `user-emacs-directory' exists,
|
||||
;; unless we're in batch mode or dumping Emacs.
|
||||
(or noninteractive
|
||||
purify-flag
|
||||
dump-mode
|
||||
(let (errtype)
|
||||
(if (file-directory-p user-emacs-directory)
|
||||
(or (file-accessible-directory-p user-emacs-directory)
|
||||
|
|
|
@ -1334,7 +1334,7 @@ Setup char-width-table appropriate for non-CJK language environment."
|
|||
|
||||
|
||||
;; Setting char-script-table.
|
||||
(if purify-flag
|
||||
(if dump-mode
|
||||
;; While dumping, we can't use require, and international is not
|
||||
;; in load-path.
|
||||
(load "international/charscript")
|
||||
|
|
|
@ -343,7 +343,7 @@ Return t if file exists."
|
|||
;; Have the original buffer current while we eval.
|
||||
(eval-buffer buffer nil
|
||||
;; This is compatible with what `load' does.
|
||||
(if purify-flag file fullname)
|
||||
(if dump-mode file fullname)
|
||||
nil t))
|
||||
(let (kill-buffer-hook kill-buffer-query-functions)
|
||||
(kill-buffer buffer)))
|
||||
|
|
168
lisp/loadup.el
168
lisp/loadup.el
|
@ -26,6 +26,9 @@
|
|||
|
||||
;; This is loaded into a bare Emacs to make a dumpable one.
|
||||
|
||||
;; Emacs injects the variable `dump-mode' to tell us how to dump.
|
||||
;; We unintern it before allowing user code to run.
|
||||
|
||||
;; If you add a file to be loaded here, keep the following points in mind:
|
||||
|
||||
;; i) If the file is no-byte-compile, explicitly load the .el version.
|
||||
|
@ -54,33 +57,58 @@
|
|||
;; bidi.c needs for its job.
|
||||
(setq redisplay--inhibit-bidi t)
|
||||
|
||||
(message "dump mode: %s" dump-mode)
|
||||
|
||||
;; Add subdirectories to the load-path for files that might get
|
||||
;; autoloaded when bootstrapping.
|
||||
;; autoloaded when bootstrapping or running Emacs normally.
|
||||
;; This is because PATH_DUMPLOADSEARCH is just "../lisp".
|
||||
(if (or (equal (member "bootstrap" command-line-args) '("bootstrap"))
|
||||
(if (or (member dump-mode '("bootstrap" "pbootstrap"))
|
||||
;; FIXME this is irritatingly fragile.
|
||||
(and (stringp (nth 4 command-line-args))
|
||||
(string-match "^unidata-gen\\(\\.elc?\\)?$"
|
||||
(nth 4 command-line-args)))
|
||||
(member (nth 7 command-line-args) '("unidata-gen-file"
|
||||
"unidata-gen-charprop"))
|
||||
(if (fboundp 'dump-emacs)
|
||||
(string-match "src/bootstrap-emacs" (nth 0 command-line-args))
|
||||
t))
|
||||
(let ((dir (car load-path)))
|
||||
(and (stringp (nth 4 command-line-args))
|
||||
(string-match "^unidata-gen\\(\\.elc?\\)?$"
|
||||
(nth 4 command-line-args)))
|
||||
(member (nth 7 command-line-args) '("unidata-gen-file"
|
||||
"unidata-gen-charprop"))
|
||||
(null dump-mode))
|
||||
(progn
|
||||
;; Find the entry in load-path that contains Emacs elisp and
|
||||
;; splice some additional directories in there for the benefit
|
||||
;; of autoload and regular Emacs use.
|
||||
(let ((subdirs '("emacs-lisp"
|
||||
"progmodes"
|
||||
"language"
|
||||
"international"
|
||||
"textmodes"
|
||||
"vc"))
|
||||
(iter load-path))
|
||||
(while iter
|
||||
(let ((dir (car iter))
|
||||
(subdirs subdirs)
|
||||
esubdirs esubdir)
|
||||
(while subdirs
|
||||
(setq esubdir (expand-file-name (car subdirs) dir))
|
||||
(setq subdirs (cdr subdirs))
|
||||
(if (file-directory-p esubdir)
|
||||
(setq esubdirs (cons esubdir esubdirs))
|
||||
(setq subdirs nil esubdirs nil)))
|
||||
(if esubdirs
|
||||
(progn
|
||||
(setcdr iter (nconc (nreverse esubdirs) (cdr iter)))
|
||||
(setq iter nil))
|
||||
(setq iter (cdr iter))
|
||||
(if (null iter)
|
||||
(signal
|
||||
'error (list
|
||||
(format-message
|
||||
"Could not find elisp load-path: searched %S"
|
||||
load-path))))))))
|
||||
;; We'll probably overflow the pure space.
|
||||
(setq purify-flag nil)
|
||||
;; Value of max-lisp-eval-depth when compiling initially.
|
||||
;; During bootstrapping the byte-compiler is run interpreted when
|
||||
;; compiling itself, which uses a lot more stack than usual.
|
||||
(setq max-lisp-eval-depth 2200)
|
||||
(setq load-path (list (expand-file-name "." dir)
|
||||
(expand-file-name "emacs-lisp" dir)
|
||||
(expand-file-name "progmodes" dir)
|
||||
(expand-file-name "language" dir)
|
||||
(expand-file-name "international" dir)
|
||||
(expand-file-name "textmodes" dir)
|
||||
(expand-file-name "vc" dir)))))
|
||||
;; During bootstrapping the byte-compiler is run interpreted
|
||||
;; when compiling itself, which uses a lot more stack
|
||||
;; than usual.
|
||||
(setq max-lisp-eval-depth 2200)))
|
||||
|
||||
(if (eq t purify-flag)
|
||||
;; Hash consing saved around 11% of pure space in my tests.
|
||||
|
@ -88,10 +116,7 @@
|
|||
|
||||
(message "Using load-path %s" load-path)
|
||||
|
||||
;; This is a poor man's `last', since we haven't loaded subr.el yet.
|
||||
(if (and (fboundp 'dump-emacs)
|
||||
(or (equal (member "bootstrap" command-line-args) '("bootstrap"))
|
||||
(equal (member "dump" command-line-args) '("dump"))))
|
||||
(if dump-mode
|
||||
(progn
|
||||
;; To reduce the size of dumped Emacs, we avoid making huge char-tables.
|
||||
(setq inhibit-load-charset-map t)
|
||||
|
@ -350,15 +375,16 @@ lost after dumping")))
|
|||
;; file primitive. So the only workable solution to support building
|
||||
;; in non-ASCII directories is to manipulate unibyte strings in the
|
||||
;; current locale's encoding.
|
||||
(if (and (member (car (last command-line-args)) '("dump" "bootstrap"))
|
||||
(fboundp 'dump-emacs)
|
||||
(multibyte-string-p default-directory))
|
||||
(if (and dump-mode (multibyte-string-p default-directory))
|
||||
(error "default-directory must be unibyte when dumping Emacs!"))
|
||||
|
||||
;; Determine which build number to use
|
||||
;; based on the executables that now exist.
|
||||
(if (and (equal (last command-line-args) '("dump"))
|
||||
(fboundp 'dump-emacs)
|
||||
(if (and (or
|
||||
(and (equal dump-mode "dump")
|
||||
(fboundp 'dump-emacs))
|
||||
(and (equal dump-mode "pdump")
|
||||
(fboundp 'dump-emacs-portable)))
|
||||
(not (eq system-type 'ms-dos)))
|
||||
(let* ((base (concat "emacs-" emacs-version "."))
|
||||
(exelen (if (eq system-type 'windows-nt) -4))
|
||||
|
@ -376,8 +402,10 @@ lost after dumping")))
|
|||
|
||||
|
||||
(message "Finding pointers to doc strings...")
|
||||
(if (and (fboundp 'dump-emacs)
|
||||
(equal (last command-line-args) '("dump")))
|
||||
(if (and (or (and (fboundp 'dump-emacs)
|
||||
(equal dump-mode "dump"))
|
||||
(and (fboundp 'dump-emacs-portable)
|
||||
(equal dump-mode "pdump"))))
|
||||
(Snarf-documentation "DOC")
|
||||
(condition-case nil
|
||||
(Snarf-documentation "DOC")
|
||||
|
@ -446,43 +474,55 @@ lost after dumping")))
|
|||
;; Make sure we will attempt bidi reordering henceforth.
|
||||
(setq redisplay--inhibit-bidi nil)
|
||||
|
||||
(if (and (fboundp 'dump-emacs)
|
||||
(member (car (last command-line-args)) '("dump" "bootstrap")))
|
||||
(progn
|
||||
;; Prevent build-time PATH getting stored in the binary.
|
||||
;; Mainly cosmetic, but helpful for Guix. (Bug#20330)
|
||||
;; Do this here, rather than earlier, so that the above code
|
||||
;; can invoke Git commands and the like.
|
||||
(setq exec-path nil)
|
||||
(message "Dumping under the name emacs")
|
||||
(if dump-mode
|
||||
(let ((output (cond ((equal dump-mode "pdump") "emacs.pdmp")
|
||||
((equal dump-mode "dump") "emacs")
|
||||
((equal dump-mode "bootstrap") "emacs")
|
||||
((equal dump-mode "pbootstrap") "bootstrap-emacs.pdmp")
|
||||
(t (error "unrecognized dump mode %s" dump-mode)))))
|
||||
(message "Dumping under the name %s" output)
|
||||
(condition-case ()
|
||||
(delete-file "emacs")
|
||||
(file-error nil))
|
||||
;; We used to dump under the name xemacs, but that occasionally
|
||||
;; confused people installing Emacs (they'd install the file
|
||||
;; under the name `xemacs'), and it's inconsistent with every
|
||||
;; other GNU program's build process.
|
||||
(dump-emacs "emacs" "temacs")
|
||||
(message "%d pure bytes used" pure-bytes-used)
|
||||
(delete-file output)
|
||||
(file-error nil))
|
||||
;; On MS-Windows, the current directory is not necessarily the
|
||||
;; same as invocation-directory.
|
||||
(let (success)
|
||||
(unwind-protect
|
||||
(progn
|
||||
(if (member dump-mode '("pdump" "pbootstrap"))
|
||||
(dump-emacs-portable (expand-file-name output invocation-directory))
|
||||
(dump-emacs output "temacs")
|
||||
(message "%d pure bytes used" pure-bytes-used))
|
||||
(setq success t))
|
||||
(unless success
|
||||
(ignore-errors
|
||||
(delete-file output)))))
|
||||
;; Recompute NAME now, so that it isn't set when we dump.
|
||||
(if (not (or (eq system-type 'ms-dos)
|
||||
;; Don't bother adding another name if we're just
|
||||
;; building bootstrap-emacs.
|
||||
(equal (last command-line-args) '("bootstrap"))))
|
||||
(let ((name (format "emacs-%s.%d" emacs-version emacs-build-number))
|
||||
(exe (if (eq system-type 'windows-nt) ".exe" "")))
|
||||
(while (string-match "[^-+_.a-zA-Z0-9]+" name)
|
||||
(setq name (concat (downcase (substring name 0 (match-beginning 0)))
|
||||
"-"
|
||||
(substring name (match-end 0)))))
|
||||
(setq name (concat name exe))
|
||||
(message "Adding name %s" name)
|
||||
;; When this runs on Windows, invocation-directory is not
|
||||
;; necessarily the current directory.
|
||||
(add-name-to-file (expand-file-name (concat "emacs" exe)
|
||||
invocation-directory)
|
||||
(expand-file-name name invocation-directory)
|
||||
t)))
|
||||
(member dump-mode '("pbootstrap" "bootstrap"))))
|
||||
(let ((name (format "emacs-%s.%d" emacs-version emacs-build-number))
|
||||
(exe (if (eq system-type 'windows-nt) ".exe" "")))
|
||||
(while (string-match "[^-+_.a-zA-Z0-9]+" name)
|
||||
(setq name (concat (downcase (substring name 0 (match-beginning 0)))
|
||||
"-"
|
||||
(substring name (match-end 0)))))
|
||||
(message "Adding name %s" (concat name exe))
|
||||
;; When this runs on Windows, invocation-directory is not
|
||||
;; necessarily the current directory.
|
||||
(add-name-to-file (expand-file-name (concat "emacs" exe)
|
||||
invocation-directory)
|
||||
(expand-file-name (concat name exe)
|
||||
invocation-directory)
|
||||
t)
|
||||
(when (equal dump-mode "pdump")
|
||||
(message "Adding name %s" (concat name ".pdmp"))
|
||||
(add-name-to-file (expand-file-name "emacs.pdmp"
|
||||
invocation-directory)
|
||||
(expand-file-name (concat name ".pdmp")
|
||||
invocation-directory)
|
||||
t))))
|
||||
(kill-emacs)))
|
||||
|
||||
;; For machines with CANNOT_DUMP defined in config.h,
|
||||
|
|
|
@ -1056,7 +1056,8 @@ please check its value")
|
|||
(let* ((longopts '(("--no-init-file") ("--no-site-file")
|
||||
("--no-x-resources") ("--debug-init")
|
||||
("--user") ("--iconic") ("--icon-type") ("--quick")
|
||||
("--no-blinking-cursor") ("--basic-display")))
|
||||
("--no-blinking-cursor") ("--basic-display")
|
||||
("--dump-file") ("--temacs")))
|
||||
(argi (pop args))
|
||||
(orig-argi argi)
|
||||
argval)
|
||||
|
@ -1108,6 +1109,9 @@ please check its value")
|
|||
(push '(visibility . icon) initial-frame-alist))
|
||||
((member argi '("-nbc" "-no-blinking-cursor"))
|
||||
(setq no-blinking-cursor t))
|
||||
((member argi '("-dump-file" "-temacs")) ; Handled in C
|
||||
(or argval (pop args))
|
||||
(setq argval nil))
|
||||
;; Push the popped arg back on the list of arguments.
|
||||
(t
|
||||
(push argi args)
|
||||
|
|
|
@ -44,7 +44,7 @@ ns_check_file = @ns_appdir@/@ns_check_file@
|
|||
|
||||
.PHONY: all
|
||||
|
||||
all: ${ns_appdir} ${ns_appbindir}/Emacs
|
||||
all: ${ns_appdir} ${ns_appbindir}/Emacs ${ns_appbindir}/emacs.pdmp
|
||||
|
||||
${ns_check_file} ${ns_appdir}: ${srcdir}/${ns_appsrc} ${ns_appsrc}
|
||||
rm -rf ${ns_appdir}
|
||||
|
@ -63,6 +63,10 @@ ${ns_appbindir}/Emacs: ${ns_appdir} ${ns_check_file} ../src/emacs${EXEEXT}
|
|||
${MKDIR_P} ${ns_appbindir}
|
||||
cp -f ../src/emacs${EXEEXT} $@
|
||||
|
||||
${ns_appbindir}/emacs.pdmp: ${ns_appdir} ${ns_check_file} ../src/emacs${EXEEXT}.pdmp
|
||||
${MKDIR_P} ${ns_appbindir}
|
||||
cp -f ../src/emacs${EXEEXT}.pdmp $@
|
||||
|
||||
.PHONY: FORCE
|
||||
|
||||
../src/emacs${EXEEXT}: FORCE
|
||||
|
|
103
src/Makefile.in
103
src/Makefile.in
|
@ -54,8 +54,6 @@ lwlibdir = ../lwlib
|
|||
# Configuration files for .o files to depend on.
|
||||
config_h = config.h $(srcdir)/conf_post.h
|
||||
|
||||
bootstrap_exe = ../src/bootstrap-emacs$(EXEEXT)
|
||||
|
||||
## ns-app if HAVE_NS, else empty.
|
||||
OTHER_FILES = @OTHER_FILES@
|
||||
|
||||
|
@ -332,7 +330,7 @@ BUILD_DETAILS = @BUILD_DETAILS@
|
|||
|
||||
UNEXEC_OBJ = @UNEXEC_OBJ@
|
||||
|
||||
CANNOT_DUMP=@CANNOT_DUMP@
|
||||
DUMPING=@DUMPING@
|
||||
|
||||
# 'make' verbosity.
|
||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||
|
@ -357,6 +355,15 @@ am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
|||
am__v_at_0 = @
|
||||
am__v_at_1 =
|
||||
|
||||
bootstrap_exe = ../src/bootstrap-emacs$(EXEEXT)
|
||||
ifeq ($(DUMPING),pdumper)
|
||||
bootstrap_pdmp := bootstrap-emacs.pdmp # Keep in sync with loadup.el
|
||||
pdmp := emacs.pdmp
|
||||
else
|
||||
bootstrap_pdmp :=
|
||||
pdmp :=
|
||||
endif
|
||||
|
||||
# Flags that might be in WARN_CFLAGS but are not valid for Objective C.
|
||||
NON_OBJC_CFLAGS = -Wignored-attributes -Wignored-qualifiers -Wopenmp-simd
|
||||
|
||||
|
@ -395,7 +402,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
|
|||
bignum.o buffer.o filelock.o insdel.o marker.o \
|
||||
minibuf.o fileio.o dired.o \
|
||||
cmds.o casetab.o casefiddle.o indent.o search.o regex-emacs.o undo.o \
|
||||
alloc.o data.o doc.o editfns.o callint.o \
|
||||
alloc.o pdumper.o data.o doc.o editfns.o callint.o \
|
||||
eval.o floatfns.o fns.o font.o print.o lread.o $(MODULES_OBJ) \
|
||||
syntax.o $(UNEXEC_OBJ) bytecode.o \
|
||||
process.o gnutls.o callproc.o \
|
||||
|
@ -446,9 +453,17 @@ FIRSTFILE_OBJ=@FIRSTFILE_OBJ@
|
|||
ALLOBJS = $(FIRSTFILE_OBJ) $(VMLIMIT_OBJ) $(obj) $(otherobj)
|
||||
|
||||
# Must be first, before dep inclusion!
|
||||
all: emacs$(EXEEXT) $(OTHER_FILES)
|
||||
all: emacs$(EXEEXT) $(pdmp) $(OTHER_FILES)
|
||||
.PHONY: all
|
||||
|
||||
dmpstruct_headers=$(srcdir)/lisp.h $(srcdir)/buffer.h \
|
||||
$(srcdir)/intervals.h $(srcdir)/charset.h $(srcdir)/bignum.h
|
||||
pdumper.o: dmpstruct.h
|
||||
dmpstruct.h: $(srcdir)/dmpstruct.awk
|
||||
dmpstruct.h: $(libsrc)/make-fingerprint$(EXEEXT) $(dmpstruct_headers)
|
||||
POSIXLY_CORRECT=1 awk -f $(srcdir)/dmpstruct.awk \
|
||||
$(dmpstruct_headers) > $@
|
||||
|
||||
AUTO_DEPEND = @AUTO_DEPEND@
|
||||
DEPDIR = deps
|
||||
ifeq ($(AUTO_DEPEND),yes)
|
||||
|
@ -511,7 +526,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \
|
|||
## and emacs (which recreates bootstrap-emacs) depends on charprop,
|
||||
## in practice this rule was always run anyway.
|
||||
$(srcdir)/macuvs.h $(lispsource)/international/charprop.el: \
|
||||
bootstrap-emacs$(EXEEXT) FORCE
|
||||
bootstrap-emacs$(EXEEXT) $(bootstrap_pdmp) FORCE
|
||||
$(MAKE) -C ../admin/unidata all EMACS="../$(bootstrap_exe)"
|
||||
|
||||
## We require charprop.el to exist before ucs-normalize.el is
|
||||
|
@ -542,14 +557,20 @@ ${lispintdir}/characters.elc: ${charscript:.el=.elc}
|
|||
emacs$(EXEEXT): temacs$(EXEEXT) \
|
||||
lisp.mk $(etc)/DOC $(lisp) \
|
||||
$(lispsource)/international/charprop.el ${charsets}
|
||||
ifeq ($(CANNOT_DUMP),yes)
|
||||
ln -f temacs$(EXEEXT) $@
|
||||
else
|
||||
LC_ALL=C $(RUN_TEMACS) -batch $(BUILD_DETAILS) -l loadup dump
|
||||
ifeq ($(DUMPING),unexec)
|
||||
LC_ALL=C $(RUN_TEMACS) -batch $(BUILD_DETAILS) -l loadup --temacs=dump
|
||||
ifneq ($(PAXCTL_dumped),)
|
||||
$(PAXCTL_dumped) $@
|
||||
$(PAXCTL_dumped) emacs$(EXEEXT)
|
||||
endif
|
||||
ln -f $@ bootstrap-emacs$(EXEEXT)
|
||||
cp -f $@ bootstrap-emacs$(EXEEXT)
|
||||
else
|
||||
cp -f temacs$(EXEEXT) emacs$(EXEEXT)
|
||||
endif
|
||||
|
||||
ifeq ($(DUMPING),pdumper)
|
||||
$(pdmp): emacs$(EXEEXT)
|
||||
LC_ALL=C $(RUN_TEMACS) -batch $(BUILD_DETAILS) -l loadup --temacs=pdump
|
||||
cp -f $@ $(bootstrap_pdmp)
|
||||
endif
|
||||
|
||||
## We run make-docfile twice because the command line may get too long
|
||||
|
@ -602,16 +623,30 @@ LIBEGNU_ARCHIVE = $(lib)/lib$(if $(HYBRID_MALLOC),e)gnu.a
|
|||
$(LIBEGNU_ARCHIVE): $(config_h)
|
||||
$(MAKE) -C $(lib) all
|
||||
|
||||
EMACS_DEPS_PRE=$(LIBXMENU) $(ALLOBJS)
|
||||
EMACS_DEPS_POST=$(LIBEGNU_ARCHIVE) $(EMACSRES) ${charsets} ${charscript}
|
||||
BUILD_EMACS_PRE=$(AM_V_CCLD)$(CC) $(ALL_CFLAGS) $(TEMACS_LDFLAGS) $(LDFLAGS) \
|
||||
-o $@ $(ALLOBJS)
|
||||
BUILD_EMACS_POST=$(LIBEGNU_ARCHIVE) $(W32_RES_LINK) $(LIBES)
|
||||
|
||||
## We hash this file to generate the build fingerprint
|
||||
temacs.in$(EXEEXT): $(EMACS_DEPS_PRE) fingerprint-dummy.o $(EMACS_DEPS_POST)
|
||||
$(BUILD_EMACS_PRE) fingerprint-dummy.o $(BUILD_EMACS_POST)
|
||||
|
||||
$(libsrc)/make-fingerprint$(EXEEXT): $(libsrc)/make-fingerprint.c $(lib)/libgnu.a
|
||||
$(MAKE) -C $(libsrc) make-fingerprint$(EXEEXT)
|
||||
|
||||
fingerprint.c: temacs.in$(EXEEXT) $(libsrc)/make-fingerprint$(EXEEXT)
|
||||
$(libsrc)/make-fingerprint$(EXEEXT) temacs.in$(EXEEXT) > fingerprint.c
|
||||
|
||||
## We have to create $(etc) here because init_cmdargs tests its
|
||||
## existence when setting Vinstallation_directory (FIXME?).
|
||||
## This goes on to affect various things, and the emacs binary fails
|
||||
## to start if Vinstallation_directory has the wrong value.
|
||||
temacs$(EXEEXT): $(LIBXMENU) $(ALLOBJS) \
|
||||
$(LIBEGNU_ARCHIVE) $(EMACSRES) ${charsets} ${charscript}
|
||||
$(AM_V_CCLD)$(CC) $(ALL_CFLAGS) $(TEMACS_LDFLAGS) $(LDFLAGS) \
|
||||
-o temacs $(ALLOBJS) $(LIBEGNU_ARCHIVE) $(W32_RES_LINK) $(LIBES)
|
||||
temacs$(EXEEXT): $(EMACS_DEPS_PRE) fingerprint.o $(EMACS_DEPS_POST)
|
||||
$(BUILD_EMACS_PRE) fingerprint.o $(BUILD_EMACS_POST)
|
||||
$(MKDIR_P) $(etc)
|
||||
ifneq ($(CANNOT_DUMP),yes)
|
||||
ifeq ($(DUMPING),unexec)
|
||||
ifneq ($(PAXCTL_notdumped),)
|
||||
$(PAXCTL_notdumped) $@
|
||||
endif
|
||||
|
@ -638,7 +673,7 @@ emacs.res: FORCE
|
|||
$(MAKE) -C ../nt ../src/emacs.res
|
||||
|
||||
.PHONY: ns-app
|
||||
ns-app: emacs$(EXEEXT)
|
||||
ns-app: emacs$(EXEEXT) $(pdmp)
|
||||
$(MAKE) -C ../nextstep all
|
||||
|
||||
.PHONY: mostlyclean clean bootstrap-clean distclean maintainer-clean
|
||||
|
@ -646,8 +681,11 @@ ns-app: emacs$(EXEEXT)
|
|||
|
||||
mostlyclean:
|
||||
rm -f temacs$(EXEEXT) core ./*.core \#* ./*.o
|
||||
rm -f temacs.in$(EXEEXT) fingerprint.c dmpstruct.h
|
||||
rm -f emacs.pdmp
|
||||
rm -f ../etc/DOC
|
||||
rm -f bootstrap-emacs$(EXEEXT) emacs-$(version)$(EXEEXT)
|
||||
rm -f bootstrap-emacs$(EXEEXT) $(bootstrap_pdmp)
|
||||
rm -f emacs-$(version)$(EXEEXT)
|
||||
rm -f buildobj.h
|
||||
rm -f globals.h gl-stamp
|
||||
rm -f ./*.res ./*.tmp
|
||||
|
@ -732,7 +770,7 @@ tags: TAGS ../lisp/TAGS $(lwlibdir)/TAGS
|
|||
## but now that we require GNU make, we can simply specify
|
||||
## bootstrap-emacs$(EXEEXT) as an order-only prerequisite.
|
||||
|
||||
%.elc: %.el | bootstrap-emacs$(EXEEXT)
|
||||
%.elc: %.el | bootstrap-emacs$(EXEEXT) $(bootstrap_pdmp)
|
||||
@$(MAKE) -C ../lisp EMACS="$(bootstrap_exe)" THEFILE=$< $<c
|
||||
|
||||
## VCSWITNESS points to the file that holds info about the current checkout.
|
||||
|
@ -740,24 +778,35 @@ tags: TAGS ../lisp/TAGS $(lwlibdir)/TAGS
|
|||
## If empty it is ignored; the parent makefile can set it to some other value.
|
||||
VCSWITNESS =
|
||||
|
||||
$(lispsource)/loaddefs.el: $(VCSWITNESS) | bootstrap-emacs$(EXEEXT)
|
||||
$(lispsource)/loaddefs.el: $(VCSWITNESS) | \
|
||||
bootstrap-emacs$(EXEEXT) $(bootstrap_pdmp)
|
||||
$(MAKE) -C ../lisp autoloads EMACS="$(bootstrap_exe)"
|
||||
|
||||
## Dump an Emacs executable named bootstrap-emacs containing the
|
||||
## files from loadup.el in source form.
|
||||
|
||||
bootstrap-emacs$(EXEEXT): temacs$(EXEEXT)
|
||||
$(MAKE) -C ../lisp update-subdirs
|
||||
ifeq ($(CANNOT_DUMP),yes)
|
||||
ln -f temacs$(EXEEXT) $@
|
||||
else
|
||||
$(RUN_TEMACS) --batch $(BUILD_DETAILS) --load loadup bootstrap
|
||||
ifeq ($(DUMPING),unexec)
|
||||
$(RUN_TEMACS) --batch $(BUILD_DETAILS) -l loadup --temacs=bootstrap
|
||||
ifneq ($(PAXCTL_dumped),)
|
||||
$(PAXCTL_dumped) emacs$(EXEEXT)
|
||||
endif
|
||||
mv -f emacs$(EXEEXT) $@
|
||||
endif
|
||||
mv -f emacs$(EXEEXT) bootstrap-emacs$(EXEEXT)
|
||||
@: Compile some files earlier to speed up further compilation.
|
||||
$(MAKE) -C ../lisp compile-first EMACS="$(bootstrap_exe)"
|
||||
else
|
||||
@: In the pdumper case, make compile-first after the dump
|
||||
cp -f temacs$(EXEEXT) bootstrap-emacs$(EXEEXT)
|
||||
endif
|
||||
|
||||
ifeq ($(DUMPING),pdumper)
|
||||
$(bootstrap_pdmp): bootstrap-emacs$(EXEEXT)
|
||||
rm -f $@
|
||||
$(RUN_TEMACS) --batch $(BUILD_DETAILS) -l loadup --temacs=pbootstrap
|
||||
@: Compile some files earlier to speed up further compilation.
|
||||
$(MAKE) -C ../lisp compile-first EMACS="$(bootstrap_exe)"
|
||||
endif
|
||||
|
||||
### Flymake support (for C only)
|
||||
check-syntax:
|
||||
|
|
809
src/alloc.c
809
src/alloc.c
File diff suppressed because it is too large
Load diff
|
@ -584,6 +584,7 @@ init_atimer (void)
|
|||
sigaction (SIGALRM, &action, 0);
|
||||
|
||||
#ifdef ENABLE_CHECKING
|
||||
defsubr (&Sdebug_timer_check);
|
||||
if (!initialized)
|
||||
defsubr (&Sdebug_timer_check);
|
||||
#endif
|
||||
}
|
||||
|
|
68
src/buffer.c
68
src/buffer.c
|
@ -44,6 +44,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "keymap.h"
|
||||
#include "frame.h"
|
||||
#include "xwidget.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
#ifdef WINDOWSNT
|
||||
#include "w32heap.h" /* for mmap_* */
|
||||
|
@ -529,6 +530,8 @@ even if it is dead. The return value is never nil. */)
|
|||
/* No one shows us now. */
|
||||
b->window_count = 0;
|
||||
|
||||
memset (&b->local_flags, 0, sizeof (b->local_flags));
|
||||
|
||||
BUF_GAP_SIZE (b) = 20;
|
||||
block_input ();
|
||||
/* We allocate extra 1-byte at the tail and keep it always '\0' for
|
||||
|
@ -781,6 +784,8 @@ CLONE nil means the indirect buffer's state is reset to default values. */)
|
|||
/* Always -1 for an indirect buffer. */
|
||||
b->window_count = -1;
|
||||
|
||||
memset (&b->local_flags, 0, sizeof (b->local_flags));
|
||||
|
||||
b->pt = b->base_buffer->pt;
|
||||
b->begv = b->base_buffer->begv;
|
||||
b->zv = b->base_buffer->zv;
|
||||
|
@ -5001,24 +5006,37 @@ alloc_buffer_text (struct buffer *b, ptrdiff_t nbytes)
|
|||
void
|
||||
enlarge_buffer_text (struct buffer *b, ptrdiff_t delta)
|
||||
{
|
||||
void *p;
|
||||
ptrdiff_t nbytes = (BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1
|
||||
+ delta);
|
||||
block_input ();
|
||||
void *p;
|
||||
unsigned char *old_beg = b->text->beg;
|
||||
ptrdiff_t old_nbytes =
|
||||
BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1;
|
||||
ptrdiff_t new_nbytes = old_nbytes + delta;
|
||||
|
||||
if (pdumper_object_p (old_beg))
|
||||
b->text->beg = NULL;
|
||||
else
|
||||
old_beg = NULL;
|
||||
|
||||
#if defined USE_MMAP_FOR_BUFFERS
|
||||
p = mmap_realloc ((void **) &b->text->beg, nbytes);
|
||||
p = mmap_realloc ((void **) &b->text->beg, new_nbytes);
|
||||
#elif defined REL_ALLOC
|
||||
p = r_re_alloc ((void **) &b->text->beg, nbytes);
|
||||
p = r_re_alloc ((void **) &b->text->beg, new_nbytes);
|
||||
#else
|
||||
p = xrealloc (b->text->beg, nbytes);
|
||||
p = xrealloc (b->text->beg, new_nbytes);
|
||||
#endif
|
||||
|
||||
if (p == NULL)
|
||||
{
|
||||
if (old_beg)
|
||||
b->text->beg = old_beg;
|
||||
unblock_input ();
|
||||
memory_full (nbytes);
|
||||
memory_full (new_nbytes);
|
||||
}
|
||||
|
||||
if (old_beg)
|
||||
memcpy (p, old_beg, min (old_nbytes, new_nbytes));
|
||||
|
||||
BUF_BEG_ADDR (b) = p;
|
||||
unblock_input ();
|
||||
}
|
||||
|
@ -5031,13 +5049,16 @@ free_buffer_text (struct buffer *b)
|
|||
{
|
||||
block_input ();
|
||||
|
||||
if (!pdumper_object_p (b->text->beg))
|
||||
{
|
||||
#if defined USE_MMAP_FOR_BUFFERS
|
||||
mmap_free ((void **) &b->text->beg);
|
||||
mmap_free ((void **) &b->text->beg);
|
||||
#elif defined REL_ALLOC
|
||||
r_alloc_free ((void **) &b->text->beg);
|
||||
r_alloc_free ((void **) &b->text->beg);
|
||||
#else
|
||||
xfree (b->text->beg);
|
||||
xfree (b->text->beg);
|
||||
#endif
|
||||
}
|
||||
|
||||
BUF_BEG_ADDR (b) = NULL;
|
||||
unblock_input ();
|
||||
|
@ -5048,14 +5069,25 @@ free_buffer_text (struct buffer *b)
|
|||
/***********************************************************************
|
||||
Initialization
|
||||
***********************************************************************/
|
||||
|
||||
void
|
||||
init_buffer_once (void)
|
||||
{
|
||||
/* TODO: clean up the buffer-local machinery. Right now,
|
||||
we have:
|
||||
|
||||
buffer_defaults: default values of buffer-locals
|
||||
buffer_local_flags: metadata
|
||||
buffer_permanent_local_flags: metadata
|
||||
buffer_local_symbols: metadata
|
||||
|
||||
There must be a simpler way to store the metadata.
|
||||
*/
|
||||
|
||||
int idx;
|
||||
|
||||
/* Items flagged permanent get an explicit permanent-local property
|
||||
added in bindings.el, for clarity. */
|
||||
PDUMPER_REMEMBER_SCALAR (buffer_permanent_local_flags);
|
||||
memset (buffer_permanent_local_flags, 0, sizeof buffer_permanent_local_flags);
|
||||
|
||||
/* 0 means not a lisp var, -1 means always local, else mask. */
|
||||
|
@ -5144,10 +5176,15 @@ init_buffer_once (void)
|
|||
XSETFASTINT (BVAR (&buffer_local_flags, extra_line_spacing), idx); ++idx;
|
||||
XSETFASTINT (BVAR (&buffer_local_flags, cursor_in_non_selected_windows), idx); ++idx;
|
||||
|
||||
/* buffer_local_flags contains no pointers, so it's safe to treat it
|
||||
as a blob for pdumper. */
|
||||
PDUMPER_REMEMBER_SCALAR (buffer_local_flags);
|
||||
|
||||
/* Need more room? */
|
||||
if (idx >= MAX_PER_BUFFER_VARS)
|
||||
emacs_abort ();
|
||||
last_per_buffer_idx = idx;
|
||||
PDUMPER_REMEMBER_SCALAR (last_per_buffer_idx);
|
||||
|
||||
/* Make sure all markable slots in buffer_defaults
|
||||
are initialized reasonably, so mark_buffer won't choke. */
|
||||
|
@ -5242,7 +5279,9 @@ init_buffer_once (void)
|
|||
|
||||
Vbuffer_alist = Qnil;
|
||||
current_buffer = 0;
|
||||
pdumper_remember_lv_ptr_raw (¤t_buffer, Lisp_Vectorlike);
|
||||
all_buffers = 0;
|
||||
pdumper_remember_lv_ptr_raw (&all_buffers, Lisp_Vectorlike);
|
||||
|
||||
QSFundamental = build_pure_c_string ("Fundamental");
|
||||
|
||||
|
@ -5266,12 +5305,12 @@ init_buffer_once (void)
|
|||
}
|
||||
|
||||
void
|
||||
init_buffer (int initialized)
|
||||
init_buffer (void)
|
||||
{
|
||||
Lisp_Object temp;
|
||||
|
||||
#ifdef USE_MMAP_FOR_BUFFERS
|
||||
if (initialized)
|
||||
if (dumped_with_unexec_p ())
|
||||
{
|
||||
struct buffer *b;
|
||||
|
||||
|
@ -5312,9 +5351,6 @@ init_buffer (int initialized)
|
|||
eassert (b->text->beg != NULL);
|
||||
}
|
||||
}
|
||||
#else /* not USE_MMAP_FOR_BUFFERS */
|
||||
/* Avoid compiler warnings. */
|
||||
(void) initialized;
|
||||
#endif /* USE_MMAP_FOR_BUFFERS */
|
||||
|
||||
AUTO_STRING (scratch, "*scratch*");
|
||||
|
|
|
@ -1398,10 +1398,11 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
|
|||
search as the jump table. */
|
||||
Lisp_Object jmp_table = POP;
|
||||
if (BYTE_CODE_SAFE && !HASH_TABLE_P (jmp_table))
|
||||
emacs_abort ();
|
||||
emacs_abort ();
|
||||
Lisp_Object v1 = POP;
|
||||
ptrdiff_t i;
|
||||
struct Lisp_Hash_Table *h = XHASH_TABLE (jmp_table);
|
||||
hash_rehash_if_needed (h);
|
||||
|
||||
/* h->count is a faster approximation for HASH_TABLE_SIZE (h)
|
||||
here. */
|
||||
|
|
|
@ -818,7 +818,8 @@ syms_of_callint (void)
|
|||
intern_c_string ("region-beginning"),
|
||||
intern_c_string ("region-end"),
|
||||
intern_c_string ("point"),
|
||||
intern_c_string ("mark"));
|
||||
intern_c_string ("mark"));
|
||||
staticpro (&preserved_fns);
|
||||
|
||||
DEFSYM (Qlist, "list");
|
||||
DEFSYM (Qlet, "let");
|
||||
|
|
|
@ -1588,9 +1588,7 @@ init_callproc (void)
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef CANNOT_DUMP
|
||||
if (initialized)
|
||||
#endif
|
||||
if (!will_dump_p ())
|
||||
{
|
||||
tempdir = Fdirectory_file_name (Vexec_directory);
|
||||
if (! file_accessible_directory_p (tempdir))
|
||||
|
|
|
@ -42,15 +42,6 @@ bset_category_table (struct buffer *b, Lisp_Object val)
|
|||
b->category_table_ = val;
|
||||
}
|
||||
|
||||
/* The version number of the latest category table. Each category
|
||||
table has a unique version number. It is assigned a new number
|
||||
also when it is modified. When a regular expression is compiled
|
||||
into the struct re_pattern_buffer, the version number of the
|
||||
category table (of the current buffer) at that moment is also
|
||||
embedded in the structure.
|
||||
|
||||
For the moment, we are not using this feature. */
|
||||
static int category_table_version;
|
||||
|
||||
/* Category set staff. */
|
||||
|
||||
|
@ -512,6 +503,4 @@ See the documentation of the variable `word-combining-categories'. */);
|
|||
defsubr (&Schar_category_set);
|
||||
defsubr (&Scategory_set_mnemonics);
|
||||
defsubr (&Smodify_category_entry);
|
||||
|
||||
category_table_version = 0;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "coding.h"
|
||||
#include "buffer.h"
|
||||
#include "sysstdio.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
/*** GENERAL NOTES on CODED CHARACTER SETS (CHARSETS) ***
|
||||
|
||||
|
@ -61,9 +62,8 @@ Lisp_Object Vcharset_hash_table;
|
|||
|
||||
/* Table of struct charset. */
|
||||
struct charset *charset_table;
|
||||
|
||||
static ptrdiff_t charset_table_size;
|
||||
static int charset_table_used;
|
||||
ptrdiff_t charset_table_size;
|
||||
int charset_table_used;
|
||||
|
||||
/* Special charsets corresponding to symbols. */
|
||||
int charset_ascii;
|
||||
|
@ -851,6 +851,8 @@ usage: (define-charset-internal ...) */)
|
|||
bool new_definition_p;
|
||||
int nchars;
|
||||
|
||||
memset (&charset, 0, sizeof (charset));
|
||||
|
||||
if (nargs != charset_arg_max)
|
||||
Fsignal (Qwrong_number_of_arguments,
|
||||
Fcons (intern ("define-charset-internal"),
|
||||
|
@ -1142,9 +1144,9 @@ usage: (define-charset-internal ...) */)
|
|||
struct charset *new_table =
|
||||
xpalloc (0, &new_size, 1,
|
||||
min (INT_MAX, MOST_POSITIVE_FIXNUM),
|
||||
sizeof *charset_table);
|
||||
memcpy (new_table, charset_table, old_size * sizeof *new_table);
|
||||
charset_table = new_table;
|
||||
sizeof *charset_table);
|
||||
memcpy (new_table, charset_table, old_size * sizeof *new_table);
|
||||
charset_table = new_table;
|
||||
charset_table_size = new_size;
|
||||
/* FIXME: This leaks memory, as the old charset_table becomes
|
||||
unreachable. If the old charset table is charset_table_init
|
||||
|
@ -2316,15 +2318,26 @@ init_charset_once (void)
|
|||
for (i = 0; i < ISO_MAX_DIMENSION; i++)
|
||||
for (j = 0; j < ISO_MAX_CHARS; j++)
|
||||
for (k = 0; k < ISO_MAX_FINAL; k++)
|
||||
iso_charset_table[i][j][k] = -1;
|
||||
iso_charset_table[i][j][k] = -1;
|
||||
|
||||
PDUMPER_REMEMBER_SCALAR (iso_charset_table);
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
emacs_mule_charset[i] = -1;
|
||||
|
||||
PDUMPER_REMEMBER_SCALAR (emacs_mule_charset);
|
||||
|
||||
charset_jisx0201_roman = -1;
|
||||
PDUMPER_REMEMBER_SCALAR (charset_jisx0201_roman);
|
||||
|
||||
charset_jisx0208_1978 = -1;
|
||||
PDUMPER_REMEMBER_SCALAR (charset_jisx0208_1978);
|
||||
|
||||
charset_jisx0208 = -1;
|
||||
PDUMPER_REMEMBER_SCALAR (charset_jisx0208);
|
||||
|
||||
charset_ksc5601 = -1;
|
||||
PDUMPER_REMEMBER_SCALAR (charset_ksc5601);
|
||||
}
|
||||
|
||||
/* Allocate an initial charset table that is large enough to handle
|
||||
|
@ -2365,7 +2378,9 @@ syms_of_charset (void)
|
|||
|
||||
charset_table = charset_table_init;
|
||||
charset_table_size = ARRAYELTS (charset_table_init);
|
||||
PDUMPER_REMEMBER_SCALAR (charset_table_size);
|
||||
charset_table_used = 0;
|
||||
PDUMPER_REMEMBER_SCALAR (charset_table_used);
|
||||
|
||||
defsubr (&Scharsetp);
|
||||
defsubr (&Smap_charset_chars);
|
||||
|
@ -2411,19 +2426,30 @@ the value may be a list of mnemonics. */);
|
|||
|
||||
charset_ascii
|
||||
= define_charset_internal (Qascii, 1, "\x00\x7F\0\0\0\0\0",
|
||||
0, 127, 'B', -1, 0, 1, 0, 0);
|
||||
0, 127, 'B', -1, 0, 1, 0, 0);
|
||||
PDUMPER_REMEMBER_SCALAR (charset_ascii);
|
||||
|
||||
charset_iso_8859_1
|
||||
= define_charset_internal (Qiso_8859_1, 1, "\x00\xFF\0\0\0\0\0",
|
||||
0, 255, -1, -1, -1, 1, 0, 0);
|
||||
0, 255, -1, -1, -1, 1, 0, 0);
|
||||
PDUMPER_REMEMBER_SCALAR (charset_iso_8859_1);
|
||||
|
||||
charset_unicode
|
||||
= define_charset_internal (Qunicode, 3, "\x00\xFF\x00\xFF\x00\x10\0",
|
||||
0, MAX_UNICODE_CHAR, -1, 0, -1, 1, 0, 0);
|
||||
0, MAX_UNICODE_CHAR, -1, 0, -1, 1, 0, 0);
|
||||
PDUMPER_REMEMBER_SCALAR (charset_unicode);
|
||||
|
||||
charset_emacs
|
||||
= define_charset_internal (Qemacs, 3, "\x00\xFF\x00\xFF\x00\x3F\0",
|
||||
0, MAX_5_BYTE_CHAR, -1, 0, -1, 1, 1, 0);
|
||||
0, MAX_5_BYTE_CHAR, -1, 0, -1, 1, 1, 0);
|
||||
PDUMPER_REMEMBER_SCALAR (charset_emacs);
|
||||
|
||||
charset_eight_bit
|
||||
= define_charset_internal (Qeight_bit, 1, "\x80\xFF\0\0\0\0\0",
|
||||
128, 255, -1, 0, -1, 0, 1,
|
||||
MAX_5_BYTE_CHAR + 1);
|
||||
MAX_5_BYTE_CHAR + 1);
|
||||
PDUMPER_REMEMBER_SCALAR (charset_eight_bit);
|
||||
|
||||
charset_unibyte = charset_iso_8859_1;
|
||||
PDUMPER_REMEMBER_SCALAR (charset_unibyte);
|
||||
}
|
||||
|
|
|
@ -248,6 +248,8 @@ extern Lisp_Object Vcharset_hash_table;
|
|||
|
||||
/* Table of struct charset. */
|
||||
extern struct charset *charset_table;
|
||||
extern ptrdiff_t charset_table_size;
|
||||
extern int charset_table_used;
|
||||
|
||||
#define CHARSET_FROM_ID(id) (charset_table + (id))
|
||||
|
||||
|
|
|
@ -298,6 +298,7 @@ encode_coding_XXX (struct coding_system *coding)
|
|||
#include "composite.h"
|
||||
#include "coding.h"
|
||||
#include "termhooks.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
Lisp_Object Vcoding_system_hash_table;
|
||||
|
||||
|
@ -10737,6 +10738,9 @@ init_coding_once (void)
|
|||
coding_priorities[i] = i;
|
||||
}
|
||||
|
||||
PDUMPER_REMEMBER_SCALAR (coding_categories);
|
||||
PDUMPER_REMEMBER_SCALAR (coding_priorities);
|
||||
|
||||
/* ISO2022 specific initialize routine. */
|
||||
for (i = 0; i < 0x20; i++)
|
||||
iso_code_class[i] = ISO_control_0;
|
||||
|
@ -10756,6 +10760,8 @@ init_coding_once (void)
|
|||
iso_code_class[ISO_CODE_SS3] = ISO_single_shift_3;
|
||||
iso_code_class[ISO_CODE_CSI] = ISO_control_sequence_introducer;
|
||||
|
||||
PDUMPER_REMEMBER_SCALAR (iso_code_class);
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
emacs_mule_bytes[i] = 1;
|
||||
|
@ -10764,6 +10770,8 @@ init_coding_once (void)
|
|||
emacs_mule_bytes[EMACS_MULE_LEADING_CODE_PRIVATE_12] = 3;
|
||||
emacs_mule_bytes[EMACS_MULE_LEADING_CODE_PRIVATE_21] = 4;
|
||||
emacs_mule_bytes[EMACS_MULE_LEADING_CODE_PRIVATE_22] = 4;
|
||||
|
||||
PDUMPER_REMEMBER_SCALAR (emacs_mule_bytes);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -10785,6 +10793,7 @@ syms_of_coding (void)
|
|||
Vcode_conversion_workbuf_name = build_pure_c_string (" *code-conversion-work*");
|
||||
|
||||
reused_workbuf_in_use = 0;
|
||||
PDUMPER_REMEMBER_SCALAR (reused_workbuf_in_use);
|
||||
|
||||
DEFSYM (Qcharset, "charset");
|
||||
DEFSYM (Qtarget_idx, "target-idx");
|
||||
|
|
|
@ -654,6 +654,7 @@ Lisp_Object
|
|||
composition_gstring_put_cache (Lisp_Object gstring, ptrdiff_t len)
|
||||
{
|
||||
struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table);
|
||||
hash_rehash_if_needed (h);
|
||||
Lisp_Object header = LGSTRING_HEADER (gstring);
|
||||
EMACS_UINT hash = h->test.hashfn (&h->test, header);
|
||||
if (len < 0)
|
||||
|
|
|
@ -299,8 +299,10 @@ extern int emacs_setenv_TZ (char const *);
|
|||
|
||||
#if 3 <= __GNUC__
|
||||
# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
|
||||
# define ATTRIBUTE_SECTION(name) __attribute__((section (name)))
|
||||
#else
|
||||
# define ATTRIBUTE_MALLOC
|
||||
#define ATTRIBUTE_SECTION(name)
|
||||
#endif
|
||||
|
||||
#if __has_attribute (alloc_size)
|
||||
|
|
|
@ -804,7 +804,7 @@ The return value is undefined. */)
|
|||
|
||||
{
|
||||
bool autoload = AUTOLOADP (definition);
|
||||
if (NILP (Vpurify_flag) || !autoload)
|
||||
if (!will_dump_p () || !autoload)
|
||||
{ /* Only add autoload entries after dumping, because the ones before are
|
||||
not useful and else we get loads of them from the loaddefs.el. */
|
||||
|
||||
|
@ -1826,7 +1826,7 @@ The function `default-value' gets the default value and `set-default' sets it.
|
|||
{
|
||||
struct Lisp_Symbol *sym;
|
||||
struct Lisp_Buffer_Local_Value *blv = NULL;
|
||||
union Lisp_Val_Fwd valcontents;
|
||||
union Lisp_Val_Fwd valcontents UNINIT;
|
||||
bool forwarded UNINIT;
|
||||
|
||||
CHECK_SYMBOL (variable);
|
||||
|
@ -1893,7 +1893,7 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */)
|
|||
{
|
||||
Lisp_Object tem;
|
||||
bool forwarded UNINIT;
|
||||
union Lisp_Val_Fwd valcontents;
|
||||
union Lisp_Val_Fwd valcontents UNINIT;
|
||||
struct Lisp_Symbol *sym;
|
||||
struct Lisp_Buffer_Local_Value *blv = NULL;
|
||||
|
||||
|
@ -2958,7 +2958,7 @@ arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args,
|
|||
/* Set ACCUM to the next operation's result if it fits,
|
||||
else exit the loop. */
|
||||
bool overflow = false;
|
||||
intmax_t a;
|
||||
intmax_t a UNINIT;
|
||||
switch (code)
|
||||
{
|
||||
case Aadd : overflow = INT_ADD_WRAPV (accum, next, &a); break;
|
||||
|
|
|
@ -1831,6 +1831,8 @@ be called when the D-Bus reply message arrives. */);
|
|||
xd_registered_buses = Qnil;
|
||||
staticpro (&xd_registered_buses);
|
||||
|
||||
// TODO: reset buses on dump load
|
||||
|
||||
Fprovide (intern_c_string ("dbusbind"), Qnil);
|
||||
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "systime.h"
|
||||
#include "tparam.h"
|
||||
#include "xwidget.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
#include TERM_HEADER
|
||||
|
@ -5987,12 +5988,24 @@ pass nil for VARIABLE. */)
|
|||
Initialization
|
||||
***********************************************************************/
|
||||
|
||||
static void
|
||||
init_faces_initial (void)
|
||||
{
|
||||
/* For the initial frame, we don't have any way of knowing what
|
||||
are the foreground and background colors of the terminal. */
|
||||
struct frame *sf = SELECTED_FRAME ();
|
||||
|
||||
FRAME_FOREGROUND_PIXEL (sf) = FACE_TTY_DEFAULT_FG_COLOR;
|
||||
FRAME_BACKGROUND_PIXEL (sf) = FACE_TTY_DEFAULT_BG_COLOR;
|
||||
call0 (intern ("tty-set-up-initial-frame-faces"));
|
||||
}
|
||||
|
||||
/* Initialization done when Emacs fork is started, before doing stty.
|
||||
Determine terminal type and set terminal_driver. Then invoke its
|
||||
decoding routine to set up variables in the terminal package. */
|
||||
|
||||
void
|
||||
init_display (void)
|
||||
static void
|
||||
init_display_interactive (void)
|
||||
{
|
||||
char *terminal_type;
|
||||
|
||||
|
@ -6012,9 +6025,7 @@ init_display (void)
|
|||
with. Otherwise newly opened tty frames will not resize
|
||||
automatically. */
|
||||
#ifdef SIGWINCH
|
||||
#ifndef CANNOT_DUMP
|
||||
if (initialized)
|
||||
#endif /* CANNOT_DUMP */
|
||||
if (!will_dump_p ())
|
||||
{
|
||||
struct sigaction action;
|
||||
emacs_sigaction_init (&action, deliver_window_change_signal);
|
||||
|
@ -6078,11 +6089,7 @@ init_display (void)
|
|||
#endif /* HAVE_NTGUI */
|
||||
|
||||
#ifdef HAVE_NS
|
||||
if (!inhibit_window_system
|
||||
#ifndef CANNOT_DUMP
|
||||
&& initialized
|
||||
#endif
|
||||
)
|
||||
if (!inhibit_window_system && !will_dump_p ())
|
||||
{
|
||||
Vinitial_window_system = Qns;
|
||||
Vwindow_system_version = make_fixnum (10);
|
||||
|
@ -6170,21 +6177,22 @@ init_display (void)
|
|||
|
||||
calculate_costs (XFRAME (selected_frame));
|
||||
|
||||
/* Set up faces of the initial terminal frame of a dumped Emacs. */
|
||||
if (initialized
|
||||
&& !noninteractive
|
||||
&& NILP (Vinitial_window_system))
|
||||
{
|
||||
/* For the initial frame, we don't have any way of knowing what
|
||||
are the foreground and background colors of the terminal. */
|
||||
struct frame *sf = SELECTED_FRAME ();
|
||||
|
||||
FRAME_FOREGROUND_PIXEL (sf) = FACE_TTY_DEFAULT_FG_COLOR;
|
||||
FRAME_BACKGROUND_PIXEL (sf) = FACE_TTY_DEFAULT_BG_COLOR;
|
||||
call0 (intern ("tty-set-up-initial-frame-faces"));
|
||||
}
|
||||
/* Set up faces of the initial terminal frame. */
|
||||
if (!noninteractive && NILP (Vinitial_window_system))
|
||||
init_faces_initial ();
|
||||
}
|
||||
|
||||
void
|
||||
init_display (void)
|
||||
{
|
||||
if (noninteractive)
|
||||
{
|
||||
if (dumped_with_pdumper_p ())
|
||||
init_faces_initial ();
|
||||
}
|
||||
else
|
||||
init_display_interactive ();
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -6220,6 +6228,8 @@ WINDOW nil or omitted means report on the selected window. */)
|
|||
Initialization
|
||||
***********************************************************************/
|
||||
|
||||
static void syms_of_display_for_pdumper (void);
|
||||
|
||||
void
|
||||
syms_of_display (void)
|
||||
{
|
||||
|
@ -6327,11 +6337,12 @@ See `buffer-display-table' for more information. */);
|
|||
beginning of the next redisplay). */
|
||||
redisplay_dont_pause = true;
|
||||
|
||||
#ifdef CANNOT_DUMP
|
||||
if (noninteractive)
|
||||
#endif
|
||||
{
|
||||
Vinitial_window_system = Qnil;
|
||||
Vwindow_system_version = Qnil;
|
||||
}
|
||||
pdumper_do_now_and_after_load (syms_of_display_for_pdumper);
|
||||
}
|
||||
|
||||
static void
|
||||
syms_of_display_for_pdumper (void)
|
||||
{
|
||||
Vinitial_window_system = Qnil;
|
||||
Vwindow_system_version = Qnil;
|
||||
}
|
||||
|
|
28
src/dmpstruct.awk
Executable file
28
src/dmpstruct.awk
Executable file
|
@ -0,0 +1,28 @@
|
|||
BEGIN {
|
||||
print "/* Generated by dmpstruct.awk */"
|
||||
print "#ifndef EMACS_DMPSTRUCT_H"
|
||||
print "#define EMACS_DMPSTRUCT_H"
|
||||
struct_name = ""
|
||||
tmpfile = "dmpstruct.tmp"
|
||||
}
|
||||
# Match a type followed by optional syntactic whitespace
|
||||
/^(enum|struct|union) [a-zA-Z0-9_]+([\t ]|\/\*.*\*\/)*$/ {
|
||||
struct_name = $2
|
||||
close (tmpfile)
|
||||
}
|
||||
/^(enum|struct|union) [a-zA-Z0-9_]+([\t ]|\/\*.*\*\/)*$/, /^( )?};$/ {
|
||||
print $0 > tmpfile
|
||||
}
|
||||
/^( )?} *(GCALIGNED_STRUCT)? *;$/ {
|
||||
if (struct_name != "") {
|
||||
fflush (tmpfile)
|
||||
cmd = "../lib-src/make-fingerprint -r " tmpfile
|
||||
cmd | getline hash
|
||||
close (cmd)
|
||||
printf "#define HASH_%s_%.10s\n", struct_name, hash
|
||||
struct_name = ""
|
||||
}
|
||||
}
|
||||
END {
|
||||
print "#endif /* EMACS_DMPSTRUCT_H */"
|
||||
}
|
16
src/doc.c
16
src/doc.c
|
@ -118,17 +118,15 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
|
|||
Lisp_Object docdir
|
||||
= NILP (tem) ? ENCODE_FILE (Vdoc_directory) : empty_unibyte_string;
|
||||
ptrdiff_t docdir_sizemax = SBYTES (docdir) + 1;
|
||||
#ifndef CANNOT_DUMP
|
||||
docdir_sizemax = max (docdir_sizemax, sizeof sibling_etc);
|
||||
#endif
|
||||
if (will_dump_p ())
|
||||
docdir_sizemax = max (docdir_sizemax, sizeof sibling_etc);
|
||||
name = SAFE_ALLOCA (docdir_sizemax + SBYTES (file));
|
||||
lispstpcpy (lispstpcpy (name, docdir), file);
|
||||
|
||||
fd = emacs_open (name, O_RDONLY, 0);
|
||||
if (fd < 0)
|
||||
{
|
||||
#ifndef CANNOT_DUMP
|
||||
if (!NILP (Vpurify_flag))
|
||||
if (will_dump_p ())
|
||||
{
|
||||
/* Preparing to dump; DOC file is probably not installed.
|
||||
So check in ../etc. */
|
||||
|
@ -136,7 +134,6 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
|
|||
|
||||
fd = emacs_open (name, O_RDONLY, 0);
|
||||
}
|
||||
#endif
|
||||
if (fd < 0)
|
||||
{
|
||||
if (errno == EMFILE || errno == ENFILE)
|
||||
|
@ -545,12 +542,7 @@ the same file name is found in the `doc-directory'. */)
|
|||
|
||||
CHECK_STRING (filename);
|
||||
|
||||
if
|
||||
#ifndef CANNOT_DUMP
|
||||
(!NILP (Vpurify_flag))
|
||||
#else /* CANNOT_DUMP */
|
||||
(0)
|
||||
#endif /* CANNOT_DUMP */
|
||||
if (will_dump_p ())
|
||||
{
|
||||
dirname = sibling_etc;
|
||||
dirlen = sizeof sibling_etc - 1;
|
||||
|
|
|
@ -3454,7 +3454,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
|
|||
|
||||
bool format_as_long_double = false;
|
||||
double darg;
|
||||
long double ldarg;
|
||||
long double ldarg UNINIT;
|
||||
|
||||
if (FLOATP (arg))
|
||||
darg = XFLOAT_DATA (arg);
|
||||
|
|
|
@ -1191,7 +1191,10 @@ void
|
|||
syms_of_module (void)
|
||||
{
|
||||
if (!plain_values)
|
||||
ltv_mark = Fcons (Qnil, Qnil);
|
||||
{
|
||||
ltv_mark = Fcons (Qnil, Qnil);
|
||||
staticpro (<v_mark);
|
||||
}
|
||||
eassert (NILP (value_to_lisp (module_nil)));
|
||||
|
||||
DEFSYM (Qmodule_refs_hash, "module-refs-hash");
|
||||
|
|
306
src/emacs.c
306
src/emacs.c
|
@ -118,6 +118,9 @@ extern char etext;
|
|||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#include "pdumper.h"
|
||||
#include "epaths.h"
|
||||
|
||||
static const char emacs_version[] = PACKAGE_VERSION;
|
||||
static const char emacs_copyright[] = COPYRIGHT;
|
||||
static const char emacs_bugreport[] = PACKAGE_BUGREPORT;
|
||||
|
@ -130,19 +133,9 @@ Lisp_Object empty_unibyte_string, empty_multibyte_string;
|
|||
Lisp_Object Vlibrary_cache;
|
||||
#endif
|
||||
|
||||
/* Set after Emacs has started up the first time.
|
||||
Prevents reinitialization of the Lisp world and keymaps
|
||||
on subsequent starts. */
|
||||
struct gflags gflags;
|
||||
bool initialized;
|
||||
|
||||
#ifndef CANNOT_DUMP
|
||||
/* Set to true if this instance of Emacs might dump. */
|
||||
# ifndef DOUG_LEA_MALLOC
|
||||
static
|
||||
# endif
|
||||
bool might_dump;
|
||||
#endif
|
||||
|
||||
/* If true, Emacs should not attempt to use a window-specific code,
|
||||
but instead should use the virtual terminal under which it was started. */
|
||||
bool inhibit_window_system;
|
||||
|
@ -519,8 +512,7 @@ init_cmdargs (int argc, char **argv, int skip_args, char const *original_pwd)
|
|||
etc_exists = Ffile_exists_p (tem);
|
||||
if (!NILP (etc_exists))
|
||||
{
|
||||
Vinstallation_directory
|
||||
= Ffile_name_as_directory (dir);
|
||||
Vinstallation_directory = Ffile_name_as_directory (dir);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -545,8 +537,7 @@ init_cmdargs (int argc, char **argv, int skip_args, char const *original_pwd)
|
|||
if (!NILP (etc_exists))
|
||||
{
|
||||
tem = Fexpand_file_name (build_string (".."), dir);
|
||||
Vinstallation_directory
|
||||
= Ffile_name_as_directory (tem);
|
||||
Vinstallation_directory = Ffile_name_as_directory (tem);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -659,6 +650,43 @@ argmatch (char **argv, int argc, const char *sstr, const char *lstr,
|
|||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
string_starts_with_p (const char* string, const char* prefix)
|
||||
{
|
||||
return strncmp (string, prefix, strlen (prefix)) == 0;
|
||||
}
|
||||
|
||||
/* Return the value of GNU-style long argument ARGUMENT if given on
|
||||
command line. ARGUMENT must begin with "-". If ARGUMENT is not
|
||||
given, return NULL. */
|
||||
static char *
|
||||
find_argument (const char *argument, int argc, char **argv)
|
||||
{
|
||||
char *found = NULL;
|
||||
int i;
|
||||
|
||||
eassert (argument[0] == '-');
|
||||
|
||||
for (i = 1; i < argc; ++i)
|
||||
if (string_starts_with_p (argv[i], argument) &&
|
||||
((argv[i] + strlen (argument))[0] == '=' ||
|
||||
(argv[i] + strlen (argument))[0] == '\0'))
|
||||
{
|
||||
int j = i;
|
||||
found = argv[j++] + strlen (argument);
|
||||
if (*found == '=')
|
||||
++found;
|
||||
else if (i < argc)
|
||||
found = argv[j++];
|
||||
else
|
||||
fatal ("no argument given for %s", argument);
|
||||
break;
|
||||
}
|
||||
else if (strcmp (argv[i], "--") == 0)
|
||||
break;
|
||||
return found;
|
||||
}
|
||||
|
||||
/* Close standard output and standard error, reporting any write
|
||||
errors as best we can. This is intended for use with atexit. */
|
||||
static void
|
||||
|
@ -677,6 +705,114 @@ close_output_streams (void)
|
|||
_exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#ifdef HAVE_PDUMPER
|
||||
|
||||
static const char *
|
||||
dump_error_to_string (enum pdumper_load_result result)
|
||||
{
|
||||
switch (result)
|
||||
{
|
||||
case PDUMPER_LOAD_SUCCESS:
|
||||
return "success";
|
||||
case PDUMPER_LOAD_OOM:
|
||||
return "out of memory";
|
||||
case PDUMPER_NOT_LOADED:
|
||||
return "not loaded";
|
||||
case PDUMPER_LOAD_FILE_NOT_FOUND:
|
||||
return "could not open file";
|
||||
case PDUMPER_LOAD_BAD_FILE_TYPE:
|
||||
return "not a dump file";
|
||||
case PDUMPER_LOAD_FAILED_DUMP:
|
||||
return "dump file is result of failed dump attempt";
|
||||
case PDUMPER_LOAD_VERSION_MISMATCH:
|
||||
return "not built for this Emacs executable";
|
||||
default:
|
||||
return "generic error";
|
||||
}
|
||||
}
|
||||
|
||||
#define PDUMP_FILE_ARG "--dump-file"
|
||||
|
||||
static enum pdumper_load_result
|
||||
load_pdump (int argc, char **argv)
|
||||
{
|
||||
const char *const suffix = ".pdmp";
|
||||
const char *const argv0_base = "emacs";
|
||||
enum pdumper_load_result result;
|
||||
#ifdef WINDOWSNT
|
||||
size_t argv0_len;
|
||||
#endif
|
||||
|
||||
/* TODO: maybe more thoroughly scrub process environment in order to
|
||||
make this use case (loading a pdumper image in an unexeced emacs)
|
||||
possible? Right now, we assume that things we don't touch are
|
||||
zero-initialized, and in an unexeced Emacs, this assumption
|
||||
doesn't hold. */
|
||||
if (initialized)
|
||||
fatal ("cannot load pdumper image in unexeced Emacs");
|
||||
|
||||
/* Look for an explicitly-specified dump file. */
|
||||
const char *path_exec = PATH_EXEC;
|
||||
char *dump_file = find_argument (PDUMP_FILE_ARG, argc, argv);
|
||||
|
||||
result = PDUMPER_NOT_LOADED;
|
||||
if (dump_file)
|
||||
result = pdumper_load (dump_file);
|
||||
|
||||
if (dump_file && result != PDUMPER_LOAD_SUCCESS)
|
||||
fatal ("could not load dump file \"%s\": %s",
|
||||
dump_file, dump_error_to_string (result));
|
||||
|
||||
if (result == PDUMPER_LOAD_SUCCESS)
|
||||
goto out;
|
||||
|
||||
/* Look for a dump file in the same directory as the executable; it
|
||||
should have the same basename. */
|
||||
|
||||
dump_file = alloca (strlen (argv[0]) + strlen (suffix) + 1);
|
||||
#ifdef WINDOWSNT
|
||||
/* Remove the .exe extension if present. */
|
||||
argv0_len = strlen (argv[0]);
|
||||
if (argv0_len >= 4 && c_strcasecmp (argv[0] + argv0_len - 4, ".exe") == 0)
|
||||
sprintf (dump_file, "%.*s%s", argv0_len - 4, argv[0], suffix);
|
||||
else
|
||||
#endif
|
||||
sprintf (dump_file, "%s%s", argv[0], suffix);
|
||||
|
||||
result = pdumper_load (dump_file);
|
||||
if (result == PDUMPER_LOAD_SUCCESS)
|
||||
goto out;
|
||||
|
||||
if (result != PDUMPER_LOAD_FILE_NOT_FOUND)
|
||||
fatal ("could not load dump file \"%s\": %s",
|
||||
dump_file, dump_error_to_string (result));
|
||||
|
||||
/* Finally, look for "emacs.pdmp" in PATH_EXEC. We hardcode
|
||||
"emacs" in "emacs.pdmp" so that the Emacs binary still works
|
||||
if the user copies and renames it.
|
||||
|
||||
FIXME: this doesn't work with emacs-XX.YY.ZZ.pdmp versioned files. */
|
||||
#ifdef WINDOWSNT
|
||||
/* On MS-Windows, PATH_EXEC normally starts with a literal
|
||||
"%emacs_dir%", so it will never work without some tweaking. */
|
||||
path_exec = w32_relocate (path_exec);
|
||||
#endif
|
||||
dump_file = alloca (strlen (path_exec)
|
||||
+ 1
|
||||
+ strlen (argv0_base)
|
||||
+ strlen (suffix)
|
||||
+ 1);
|
||||
sprintf (dump_file, "%s%c%s%s",
|
||||
path_exec, DIRECTORY_SEP, argv0_base, suffix);
|
||||
result = pdumper_load (dump_file);
|
||||
if (result != PDUMPER_LOAD_SUCCESS)
|
||||
dump_file = NULL;
|
||||
|
||||
out:
|
||||
return result;
|
||||
}
|
||||
#endif /* HAVE_PDUMPER */
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
|
@ -686,7 +822,6 @@ main (int argc, char **argv)
|
|||
void *stack_bottom_variable;
|
||||
|
||||
bool do_initial_setlocale;
|
||||
bool dumping;
|
||||
int skip_args = 0;
|
||||
bool no_loadup = false;
|
||||
char *junk = 0;
|
||||
|
@ -702,25 +837,62 @@ main (int argc, char **argv)
|
|||
/* Record (approximately) where the stack begins. */
|
||||
stack_bottom = (char *) &stack_bottom_variable;
|
||||
|
||||
#ifndef CANNOT_DUMP
|
||||
dumping = !initialized && (strcmp (argv[argc - 1], "dump") == 0
|
||||
|| strcmp (argv[argc - 1], "bootstrap") == 0);
|
||||
#else
|
||||
dumping = false;
|
||||
const char *dump_mode = NULL;
|
||||
const char *temacs = find_argument ("--temacs", argc, argv);
|
||||
#ifdef HAVE_PDUMPER
|
||||
bool attempt_load_pdump = false;
|
||||
#endif
|
||||
|
||||
argc = maybe_disable_address_randomization (dumping, argc, argv);
|
||||
/* Look for this argument first, before any heap allocation, so we
|
||||
can set heap flags properly if we're going to unexec. */
|
||||
if (!initialized && temacs)
|
||||
{
|
||||
#ifndef CANNOT_DUMP
|
||||
if (strcmp (temacs, "dump") == 0 ||
|
||||
strcmp (temacs, "bootstrap") == 0)
|
||||
gflags.will_dump_with_unexec_ = true;
|
||||
#endif
|
||||
#ifdef HAVE_PDUMPER
|
||||
if (strcmp (temacs, "pdump") == 0 ||
|
||||
strcmp (temacs, "pbootstrap") == 0)
|
||||
gflags.will_dump_with_pdumper_ = true;
|
||||
#endif
|
||||
#if defined (HAVE_PDUMPER) || !defined (CANNOT_DUMP)
|
||||
if (strcmp (temacs, "bootstrap") == 0 ||
|
||||
strcmp (temacs, "pbootstrap") == 0)
|
||||
gflags.will_bootstrap_ = true;
|
||||
gflags.will_dump_ =
|
||||
will_dump_with_pdumper_p () ||
|
||||
will_dump_with_unexec_p ();
|
||||
if (will_dump_p ())
|
||||
dump_mode = temacs;
|
||||
#endif
|
||||
if (!dump_mode)
|
||||
fatal ("Invalid temacs mode '%s'", temacs);
|
||||
}
|
||||
else if (temacs)
|
||||
{
|
||||
fatal ("--temacs not supported for unexeced emacs");
|
||||
}
|
||||
else if (initialized)
|
||||
{
|
||||
#ifdef HAVE_PDUMPER
|
||||
if (find_argument (PDUMP_FILE_ARG, argc, argv))
|
||||
fatal ("%s not supported in unexeced emacs", PDUMP_FILE_ARG);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
eassert (!initialized);
|
||||
eassert (!temacs);
|
||||
#ifdef PDUMP_FILE_ARG
|
||||
attempt_load_pdump = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef CANNOT_DUMP
|
||||
might_dump = !initialized;
|
||||
|
||||
# ifdef GNU_LINUX
|
||||
if (!initialized)
|
||||
{
|
||||
char *heap_start = my_heap_start ();
|
||||
heap_bss_diff = heap_start - max (my_endbss, my_endbss_static);
|
||||
}
|
||||
# endif
|
||||
if (!will_dump_with_unexec_p ())
|
||||
gflags.will_not_unexec_ = true;
|
||||
#endif
|
||||
|
||||
#if defined WINDOWSNT || defined HAVE_NTGUI
|
||||
|
@ -742,6 +914,22 @@ main (int argc, char **argv)
|
|||
w32_init_main_thread ();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PDUMPER
|
||||
if (attempt_load_pdump)
|
||||
load_pdump (argc, argv);
|
||||
#endif
|
||||
|
||||
argc = maybe_disable_address_randomization (
|
||||
will_dump_with_unexec_p (), argc, argv);
|
||||
|
||||
#if defined (GNU_LINUX) && !defined (CANNOT_DUMP)
|
||||
if (!initialized)
|
||||
{
|
||||
char *heap_start = my_heap_start ();
|
||||
heap_bss_diff = heap_start - max (my_endbss, my_endbss_static);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef RUN_TIME_REMAP
|
||||
if (initialized)
|
||||
run_time_remap (argv[0]);
|
||||
|
@ -850,10 +1038,7 @@ main (int argc, char **argv)
|
|||
frames. */
|
||||
int extra = (30 * 1000) * 50;
|
||||
|
||||
bool try_to_grow_stack = true;
|
||||
#ifndef CANNOT_DUMP
|
||||
try_to_grow_stack = !noninteractive || initialized;
|
||||
#endif
|
||||
bool try_to_grow_stack = !noninteractive || initialized;
|
||||
|
||||
if (try_to_grow_stack)
|
||||
{
|
||||
|
@ -1184,17 +1369,15 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
|
|||
|
||||
#if defined HAVE_PTHREAD && !defined SYSTEM_MALLOC \
|
||||
&& !defined DOUG_LEA_MALLOC && !defined HYBRID_MALLOC
|
||||
# ifndef CANNOT_DUMP
|
||||
/* Do not make gmalloc thread-safe when creating bootstrap-emacs, as
|
||||
that causes an infinite recursive loop with FreeBSD. See
|
||||
Bug#14569. The part of this bug involving Cygwin is no longer
|
||||
relevant, now that Cygwin defines HYBRID_MALLOC. */
|
||||
if (!noninteractive || initialized)
|
||||
# endif
|
||||
if (!noninteractive || !will_dump_p ())
|
||||
malloc_enable_thread ();
|
||||
#endif
|
||||
|
||||
init_signals (dumping);
|
||||
init_signals ();
|
||||
|
||||
noninteractive1 = noninteractive;
|
||||
|
||||
|
@ -1204,7 +1387,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
|
|||
{
|
||||
init_alloc_once ();
|
||||
init_threads_once ();
|
||||
init_obarray ();
|
||||
init_obarray_once ();
|
||||
init_eval_once ();
|
||||
init_charset_once ();
|
||||
init_coding_once ();
|
||||
|
@ -1242,7 +1425,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
|
|||
/* Before init_window_once, because it sets up the
|
||||
Vcoding_system_hash_table. */
|
||||
syms_of_coding (); /* This should be after syms_of_fileio. */
|
||||
|
||||
init_frame_once (); /* Before init_window_once. */
|
||||
init_window_once (); /* Init the window system. */
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
init_fringe_once (); /* Swap bitmaps if necessary. */
|
||||
|
@ -1282,7 +1465,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
|
|||
bool module_assertions
|
||||
= argmatch (argv, argc, "-module-assertions", "--module-assertions", 15,
|
||||
NULL, &skip_args);
|
||||
if (dumping && module_assertions)
|
||||
if (will_dump_p () && module_assertions)
|
||||
{
|
||||
fputs ("Module assertions are not supported during dumping\n", stderr);
|
||||
exit (1);
|
||||
|
@ -1419,7 +1602,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
|
|||
/* egetenv is a pretty low-level facility, which may get called in
|
||||
many circumstances; it seems flimsy to put off initializing it
|
||||
until calling init_callproc. Do not do it when dumping. */
|
||||
if (! dumping)
|
||||
if (!will_dump_p ())
|
||||
set_initial_environment ();
|
||||
|
||||
#ifdef WINDOWSNT
|
||||
|
@ -1433,7 +1616,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
|
|||
variables from the parent process without modifications from
|
||||
Emacs. */
|
||||
init_environment (argv);
|
||||
init_ntproc (dumping); /* must precede init_editfns. */
|
||||
init_ntproc (will_dump_p ()); /* must precede init_editfns. */
|
||||
#endif
|
||||
|
||||
/* AIX crashes are reported in system versions 3.2.3 and 3.2.4
|
||||
|
@ -1445,7 +1628,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
|
|||
#endif
|
||||
|
||||
/* Init buffer storage and default directory of main buffer. */
|
||||
init_buffer (initialized);
|
||||
init_buffer ();
|
||||
|
||||
init_callproc_1 (); /* Must precede init_cmdargs and init_sys_modes. */
|
||||
|
||||
|
@ -1620,6 +1803,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
|
|||
|
||||
syms_of_threads ();
|
||||
syms_of_profiler ();
|
||||
syms_of_pdumper ();
|
||||
|
||||
#ifdef HAVE_JSON
|
||||
syms_of_json ();
|
||||
|
@ -1650,7 +1834,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
|
|||
init_charset ();
|
||||
|
||||
/* This calls putenv and so must precede init_process_emacs. */
|
||||
init_timefns (dumping);
|
||||
init_timefns ();
|
||||
|
||||
/* This sets Voperating_system_release, which init_process_emacs uses. */
|
||||
init_editfns ();
|
||||
|
@ -1669,10 +1853,9 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
|
|||
init_process_emacs (sockfd);
|
||||
|
||||
init_keyboard (); /* This too must precede init_sys_modes. */
|
||||
if (!noninteractive)
|
||||
init_display (); /* Determine terminal type. Calls init_sys_modes. */
|
||||
init_display (); /* Determine terminal type. Calls init_sys_modes. */
|
||||
#if HAVE_W32NOTIFY
|
||||
else
|
||||
if (noninteractive)
|
||||
init_crit (); /* w32notify.c needs this in batch mode. */
|
||||
#endif /* HAVE_W32NOTIFY */
|
||||
init_xdisp ();
|
||||
|
@ -1716,7 +1899,10 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
|
|||
moncontrol (0);
|
||||
#endif
|
||||
|
||||
initialized = 1;
|
||||
initialized = true;
|
||||
|
||||
if (dump_mode)
|
||||
Vdump_mode = build_string (dump_mode);
|
||||
|
||||
/* Enter editor command loop. This never returns. */
|
||||
Frecursive_edit ();
|
||||
|
@ -2166,8 +2352,11 @@ You must run Emacs in batch mode in order to dump it. */)
|
|||
if (! noninteractive)
|
||||
error ("Dumping Emacs works only in batch mode");
|
||||
|
||||
if (!might_dump)
|
||||
error ("Emacs can be dumped only once");
|
||||
if (dumped_with_unexec_p ())
|
||||
error ("Emacs can be dumped using unexec only once");
|
||||
|
||||
if (definitely_will_not_unexec_p ())
|
||||
error ("This Emacs instance was not started in temacs mode");
|
||||
|
||||
#if defined GNU_LINUX && !defined CANNOT_DUMP
|
||||
|
||||
|
@ -2231,12 +2420,19 @@ You must run Emacs in batch mode in order to dump it. */)
|
|||
#endif /* not WINDOWSNT */
|
||||
#endif /* not SYSTEM_MALLOC and not HYBRID_MALLOC */
|
||||
|
||||
struct gflags old_gflags = gflags;
|
||||
gflags.will_dump_ = false;
|
||||
gflags.will_dump_with_unexec_ = false;
|
||||
gflags.dumped_with_unexec_ = true;
|
||||
|
||||
alloc_unexec_pre ();
|
||||
|
||||
unexec (SSDATA (filename), !NILP (symfile) ? SSDATA (symfile) : 0);
|
||||
|
||||
alloc_unexec_post ();
|
||||
|
||||
gflags = old_gflags;
|
||||
|
||||
#ifdef WINDOWSNT
|
||||
Vlibrary_cache = Qnil;
|
||||
#endif
|
||||
|
@ -2250,6 +2446,7 @@ You must run Emacs in batch mode in order to dump it. */)
|
|||
}
|
||||
|
||||
#endif /* not CANNOT_DUMP */
|
||||
|
||||
|
||||
#if HAVE_SETLOCALE
|
||||
/* Recover from setlocale (LC_ALL, ""). */
|
||||
|
@ -2585,7 +2782,7 @@ Don't rely on it for testing whether a feature you want to use is available. */
|
|||
Vsystem_configuration_features = build_string (EMACS_CONFIG_FEATURES);
|
||||
|
||||
DEFVAR_BOOL ("noninteractive", noninteractive1,
|
||||
doc: /* Non-nil means Emacs is running without interactive terminal. */);
|
||||
doc: /* Non-nil means Emacs is running without interactive terminal. */);
|
||||
|
||||
DEFVAR_LISP ("kill-emacs-hook", Vkill_emacs_hook,
|
||||
doc: /* Hook run when `kill-emacs' is called.
|
||||
|
@ -2670,6 +2867,9 @@ component .BUILD is present. This is now stored separately in
|
|||
doc: /* Address of mailing list for GNU Emacs bugs. */);
|
||||
Vreport_emacs_bug_address = build_string (emacs_bugreport);
|
||||
|
||||
DEFVAR_LISP ("dump-mode", Vdump_mode,
|
||||
doc: /* Non-nil when Emacs is dumping itself. */);
|
||||
|
||||
DEFVAR_LISP ("dynamic-library-alist", Vdynamic_library_alist,
|
||||
doc: /* Alist of dynamic libraries vs external files implementing them.
|
||||
Each element is a list (LIBRARY FILE...), where the car is a symbol
|
||||
|
|
30
src/eval.c
30
src/eval.c
|
@ -29,6 +29,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "keyboard.h"
|
||||
#include "dispextern.h"
|
||||
#include "buffer.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
/* CACHEABLE is ordinarily nothing, except it is 'volatile' if
|
||||
necessary to cajole GCC into not warning incorrectly that a
|
||||
|
@ -89,10 +90,6 @@ static EMACS_INT when_entered_debugger;
|
|||
/* FIXME: We should probably get rid of this! */
|
||||
Lisp_Object Vsignaling_function;
|
||||
|
||||
/* If non-nil, Lisp code must not be run since some part of Emacs is in
|
||||
an inconsistent state. Currently unused. */
|
||||
Lisp_Object inhibit_lisp_code;
|
||||
|
||||
/* These would ordinarily be static, but they need to be visible to GDB. */
|
||||
bool backtrace_p (union specbinding *) EXTERNALLY_VISIBLE;
|
||||
Lisp_Object *backtrace_args (union specbinding *) EXTERNALLY_VISIBLE;
|
||||
|
@ -235,6 +232,8 @@ backtrace_next (union specbinding *pdl)
|
|||
return pdl;
|
||||
}
|
||||
|
||||
static void init_eval_once_for_pdumper (void);
|
||||
|
||||
static union specbinding *
|
||||
backtrace_thread_next (struct thread_state *tstate, union specbinding *pdl)
|
||||
{
|
||||
|
@ -247,15 +246,20 @@ backtrace_thread_next (struct thread_state *tstate, union specbinding *pdl)
|
|||
void
|
||||
init_eval_once (void)
|
||||
{
|
||||
enum { size = 50 };
|
||||
union specbinding *pdlvec = xmalloc ((size + 1) * sizeof *specpdl);
|
||||
specpdl_size = size;
|
||||
specpdl = specpdl_ptr = pdlvec + 1;
|
||||
/* Don't forget to update docs (lispref node "Local Variables"). */
|
||||
max_specpdl_size = 1300; /* 1000 is not enough for CEDET's c-by.el. */
|
||||
max_lisp_eval_depth = 800;
|
||||
|
||||
Vrun_hooks = Qnil;
|
||||
pdumper_do_now_and_after_load (init_eval_once_for_pdumper);
|
||||
}
|
||||
|
||||
static void
|
||||
init_eval_once_for_pdumper (void)
|
||||
{
|
||||
enum { size = 50 };
|
||||
union specbinding *pdlvec = malloc ((size + 1) * sizeof *specpdl);
|
||||
specpdl_size = size;
|
||||
specpdl = specpdl_ptr = pdlvec + 1;
|
||||
}
|
||||
|
||||
/* static struct handler handlerlist_sentinel; */
|
||||
|
@ -2084,7 +2088,7 @@ it defines a macro. */)
|
|||
|
||||
/* This is to make sure that loadup.el gives a clear picture
|
||||
of what files are preloaded and when. */
|
||||
if (! NILP (Vpurify_flag))
|
||||
if (will_dump_p () && !will_bootstrap_p ())
|
||||
error ("Attempt to autoload %s while preparing to dump",
|
||||
SDATA (SYMBOL_NAME (funname)));
|
||||
|
||||
|
@ -4002,7 +4006,7 @@ mark_specpdl (union specbinding *first, union specbinding *ptr)
|
|||
for (pdl = first; pdl != ptr; pdl++)
|
||||
{
|
||||
switch (pdl->kind)
|
||||
{
|
||||
{
|
||||
case SPECPDL_UNWIND:
|
||||
mark_object (specpdl_arg (pdl));
|
||||
break;
|
||||
|
@ -4039,7 +4043,7 @@ mark_specpdl (union specbinding *first, union specbinding *ptr)
|
|||
|
||||
case SPECPDL_UNWIND_PTR:
|
||||
case SPECPDL_UNWIND_INT:
|
||||
case SPECPDL_UNWIND_VOID:
|
||||
case SPECPDL_UNWIND_VOID:
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -4225,8 +4229,6 @@ alist of active lexical bindings. */);
|
|||
staticpro (&Vsignaling_function);
|
||||
Vsignaling_function = Qnil;
|
||||
|
||||
inhibit_lisp_code = Qnil;
|
||||
|
||||
DEFSYM (Qcatch_all_memory_full, "catch-all-memory-full");
|
||||
Funintern (Qcatch_all_memory_full, Qnil);
|
||||
|
||||
|
|
|
@ -171,13 +171,10 @@ get_boot_time (void)
|
|||
}
|
||||
|
||||
#if defined (BOOT_TIME)
|
||||
#ifndef CANNOT_DUMP
|
||||
/* The utmp routines maintain static state.
|
||||
Don't touch that state unless we are initialized,
|
||||
since it might not survive dumping. */
|
||||
if (! initialized)
|
||||
/* The utmp routines maintain static state. Don't touch that state
|
||||
if we are going to dump, since it might not survive dumping. */
|
||||
if (will_dump_p ())
|
||||
return boot_time;
|
||||
#endif /* not CANNOT_DUMP */
|
||||
|
||||
/* Try to get boot time from utmp before wtmp,
|
||||
since utmp is typically much smaller than wtmp.
|
||||
|
@ -666,7 +663,7 @@ lock_file (Lisp_Object fn)
|
|||
/* Don't do locking while dumping Emacs.
|
||||
Uncompressing wtmp files uses call-process, which does not work
|
||||
in an uninitialized Emacs. */
|
||||
if (! NILP (Vpurify_flag))
|
||||
if (will_dump_p ())
|
||||
return;
|
||||
|
||||
orig_fn = fn;
|
||||
|
|
24
src/fingerprint-dummy.c
Normal file
24
src/fingerprint-dummy.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
/* Dummy fingerprint
|
||||
|
||||
Copyright (C) 2016 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or (at
|
||||
your option) any later version.
|
||||
|
||||
GNU Emacs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "fingerprint.h"
|
||||
|
||||
/* Dummy fingerprint to use as hash input. */
|
||||
const uint8_t fingerprint[32] = { 0 };
|
32
src/fingerprint.h
Normal file
32
src/fingerprint.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* Header file for the Emacs build fingerprint.
|
||||
|
||||
Copyright (C) 2016 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or (at
|
||||
your option) any later version.
|
||||
|
||||
GNU Emacs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef EMACS_FINGERPRINT_H
|
||||
#define EMACS_FINGERPRINT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* We generate fingerprint.c and fingerprint.o from all the sources in
|
||||
Emacs. This way, we have a unique value that we can use to pair
|
||||
data files (like a portable dump image) with a specific build of
|
||||
Emacs. */
|
||||
extern const uint8_t fingerprint[32];
|
||||
|
||||
#endif
|
139
src/fns.c
139
src/fns.c
|
@ -2949,7 +2949,7 @@ suppressed. */)
|
|||
|
||||
/* This is to make sure that loadup.el gives a clear picture
|
||||
of what files are preloaded and when. */
|
||||
if (! NILP (Vpurify_flag))
|
||||
if (will_dump_p () && !will_bootstrap_p ())
|
||||
error ("(require %s) while preparing to dump",
|
||||
SDATA (SYMBOL_NAME (feature)));
|
||||
|
||||
|
@ -3648,10 +3648,6 @@ base64_decode_1 (const char *from, char *to, ptrdiff_t length,
|
|||
if a `:linear-search t' argument is given to make-hash-table. */
|
||||
|
||||
|
||||
/* The list of all weak hash tables. Don't staticpro this one. */
|
||||
|
||||
static struct Lisp_Hash_Table *weak_hash_tables;
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
Utilities
|
||||
|
@ -3866,7 +3862,7 @@ hashfn_eq (struct hash_table_test *ht, Lisp_Object key)
|
|||
`equal' to compare keys. The hash code returned is guaranteed to fit
|
||||
in a Lisp integer. */
|
||||
|
||||
static EMACS_UINT
|
||||
EMACS_UINT
|
||||
hashfn_equal (struct hash_table_test *ht, Lisp_Object key)
|
||||
{
|
||||
return sxhash (key, 0);
|
||||
|
@ -3876,7 +3872,7 @@ hashfn_equal (struct hash_table_test *ht, Lisp_Object key)
|
|||
`eql' to compare keys. The hash code returned is guaranteed to fit
|
||||
in a Lisp integer. */
|
||||
|
||||
static EMACS_UINT
|
||||
EMACS_UINT
|
||||
hashfn_eql (struct hash_table_test *ht, Lisp_Object key)
|
||||
{
|
||||
return ((FLOATP (key) || BIGNUMP (key))
|
||||
|
@ -3984,6 +3980,7 @@ make_hash_table (struct hash_table_test test, EMACS_INT size,
|
|||
h->hash = make_nil_vector (size);
|
||||
h->next = make_vector (size, make_fixnum (-1));
|
||||
h->index = make_vector (index_size, make_fixnum (-1));
|
||||
h->next_weak = NULL;
|
||||
h->pure = pure;
|
||||
|
||||
/* Set up the free list. */
|
||||
|
@ -3995,13 +3992,6 @@ make_hash_table (struct hash_table_test test, EMACS_INT size,
|
|||
eassert (HASH_TABLE_P (table));
|
||||
eassert (XHASH_TABLE (table) == h);
|
||||
|
||||
/* Maybe add this hash table to the list of all weak hash tables. */
|
||||
if (! NILP (weak))
|
||||
{
|
||||
h->next_weak = weak_hash_tables;
|
||||
weak_hash_tables = h;
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
|
@ -4023,13 +4013,6 @@ copy_hash_table (struct Lisp_Hash_Table *h1)
|
|||
h2->index = Fcopy_sequence (h1->index);
|
||||
XSET_HASH_TABLE (table, h2);
|
||||
|
||||
/* Maybe add this hash table to the list of all weak hash tables. */
|
||||
if (!NILP (h2->weak))
|
||||
{
|
||||
h2->next_weak = h1->next_weak;
|
||||
h1->next_weak = h2;
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
|
@ -4115,6 +4098,43 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
hash_table_rehash (struct Lisp_Hash_Table *h)
|
||||
{
|
||||
ptrdiff_t size = HASH_TABLE_SIZE (h);
|
||||
|
||||
/* Recompute the actual hash codes for each entry in the table.
|
||||
Order is still invalid. */
|
||||
for (ptrdiff_t i = 0; i < size; ++i)
|
||||
if (!NILP (HASH_HASH (h, i)))
|
||||
{
|
||||
Lisp_Object key = HASH_KEY (h, i);
|
||||
EMACS_UINT hash_code = h->test.hashfn (&h->test, key);
|
||||
set_hash_hash_slot (h, i, make_fixnum (hash_code));
|
||||
}
|
||||
|
||||
/* Reset the index so that any slot we don't fill below is marked
|
||||
invalid. */
|
||||
Ffillarray (h->index, make_fixnum (-1));
|
||||
|
||||
/* Rebuild the collision chains. */
|
||||
for (ptrdiff_t i = 0; i < size; ++i)
|
||||
if (!NILP (HASH_HASH (h, i)))
|
||||
{
|
||||
EMACS_UINT hash_code = XUFIXNUM (HASH_HASH (h, i));
|
||||
ptrdiff_t start_of_bucket = hash_code % ASIZE (h->index);
|
||||
set_hash_next_slot (h, i, HASH_INDEX (h, start_of_bucket));
|
||||
set_hash_index_slot (h, start_of_bucket, i);
|
||||
eassert (HASH_NEXT (h, i) != i); /* Stop loops. */
|
||||
}
|
||||
|
||||
/* Finally, mark the hash table as having a valid hash order.
|
||||
Do this last so that if we're interrupted, we retry on next
|
||||
access. */
|
||||
eassert (h->count < 0);
|
||||
h->count = -h->count;
|
||||
eassert (!hash_rehash_needed_p (h));
|
||||
}
|
||||
|
||||
/* Lookup KEY in hash table H. If HASH is non-null, return in *HASH
|
||||
the hash code of KEY. Value is the index of the entry in H
|
||||
|
@ -4126,6 +4146,8 @@ hash_lookup (struct Lisp_Hash_Table *h, Lisp_Object key, EMACS_UINT *hash)
|
|||
EMACS_UINT hash_code;
|
||||
ptrdiff_t start_of_bucket, i;
|
||||
|
||||
hash_rehash_if_needed (h);
|
||||
|
||||
hash_code = h->test.hashfn (&h->test, key);
|
||||
eassert ((hash_code & ~INTMASK) == 0);
|
||||
if (hash)
|
||||
|
@ -4154,6 +4176,8 @@ hash_put (struct Lisp_Hash_Table *h, Lisp_Object key, Lisp_Object value,
|
|||
{
|
||||
ptrdiff_t start_of_bucket, i;
|
||||
|
||||
hash_rehash_if_needed (h);
|
||||
|
||||
eassert ((hash & ~INTMASK) == 0);
|
||||
|
||||
/* Increment count after resizing because resizing may fail. */
|
||||
|
@ -4187,6 +4211,8 @@ hash_remove_from_table (struct Lisp_Hash_Table *h, Lisp_Object key)
|
|||
ptrdiff_t start_of_bucket = hash_code % ASIZE (h->index);
|
||||
ptrdiff_t prev = -1;
|
||||
|
||||
hash_rehash_if_needed (h);
|
||||
|
||||
for (ptrdiff_t i = HASH_INDEX (h, start_of_bucket);
|
||||
0 <= i;
|
||||
i = HASH_NEXT (h, i))
|
||||
|
@ -4255,7 +4281,7 @@ hash_clear (struct Lisp_Hash_Table *h)
|
|||
!REMOVE_ENTRIES_P means mark entries that are in use. Value is
|
||||
true if anything was marked. */
|
||||
|
||||
static bool
|
||||
bool
|
||||
sweep_weak_table (struct Lisp_Hash_Table *h, bool remove_entries_p)
|
||||
{
|
||||
ptrdiff_t n = gc_asize (h->index);
|
||||
|
@ -4263,12 +4289,14 @@ sweep_weak_table (struct Lisp_Hash_Table *h, bool remove_entries_p)
|
|||
|
||||
for (ptrdiff_t bucket = 0; bucket < n; ++bucket)
|
||||
{
|
||||
/* Follow collision chain, removing entries that
|
||||
don't survive this garbage collection. */
|
||||
/* Follow collision chain, removing entries that don't survive
|
||||
this garbage collection. It's okay if hash_rehash_needed_p
|
||||
(h) is true, since we're operating entirely on the cached
|
||||
hash values. */
|
||||
ptrdiff_t prev = -1;
|
||||
ptrdiff_t next;
|
||||
for (ptrdiff_t i = HASH_INDEX (h, bucket); 0 <= i; i = next)
|
||||
{
|
||||
{
|
||||
bool key_known_to_survive_p = survives_gc_p (HASH_KEY (h, i));
|
||||
bool value_known_to_survive_p = survives_gc_p (HASH_VALUE (h, i));
|
||||
bool remove_p;
|
||||
|
@ -4303,10 +4331,11 @@ sweep_weak_table (struct Lisp_Hash_Table *h, bool remove_entries_p)
|
|||
/* Clear key, value, and hash. */
|
||||
set_hash_key_slot (h, i, Qnil);
|
||||
set_hash_value_slot (h, i, Qnil);
|
||||
set_hash_hash_slot (h, i, Qnil);
|
||||
set_hash_hash_slot (h, i, Qnil);
|
||||
|
||||
h->count--;
|
||||
}
|
||||
eassert (h->count != 0);
|
||||
h->count += h->count > 0 ? -1 : 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev = i;
|
||||
|
@ -4320,13 +4349,13 @@ sweep_weak_table (struct Lisp_Hash_Table *h, bool remove_entries_p)
|
|||
if (!key_known_to_survive_p)
|
||||
{
|
||||
mark_object (HASH_KEY (h, i));
|
||||
marked = 1;
|
||||
marked = true;
|
||||
}
|
||||
|
||||
if (!value_known_to_survive_p)
|
||||
{
|
||||
mark_object (HASH_VALUE (h, i));
|
||||
marked = 1;
|
||||
marked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4336,55 +4365,6 @@ sweep_weak_table (struct Lisp_Hash_Table *h, bool remove_entries_p)
|
|||
return marked;
|
||||
}
|
||||
|
||||
/* Remove elements from weak hash tables that don't survive the
|
||||
current garbage collection. Remove weak tables that don't survive
|
||||
from Vweak_hash_tables. Called from gc_sweep. */
|
||||
|
||||
NO_INLINE /* For better stack traces */
|
||||
void
|
||||
sweep_weak_hash_tables (void)
|
||||
{
|
||||
struct Lisp_Hash_Table *h, *used, *next;
|
||||
bool marked;
|
||||
|
||||
/* Mark all keys and values that are in use. Keep on marking until
|
||||
there is no more change. This is necessary for cases like
|
||||
value-weak table A containing an entry X -> Y, where Y is used in a
|
||||
key-weak table B, Z -> Y. If B comes after A in the list of weak
|
||||
tables, X -> Y might be removed from A, although when looking at B
|
||||
one finds that it shouldn't. */
|
||||
do
|
||||
{
|
||||
marked = 0;
|
||||
for (h = weak_hash_tables; h; h = h->next_weak)
|
||||
{
|
||||
if (h->header.size & ARRAY_MARK_FLAG)
|
||||
marked |= sweep_weak_table (h, 0);
|
||||
}
|
||||
}
|
||||
while (marked);
|
||||
|
||||
/* Remove tables and entries that aren't used. */
|
||||
for (h = weak_hash_tables, used = NULL; h; h = next)
|
||||
{
|
||||
next = h->next_weak;
|
||||
|
||||
if (h->header.size & ARRAY_MARK_FLAG)
|
||||
{
|
||||
/* TABLE is marked as used. Sweep its contents. */
|
||||
if (h->count > 0)
|
||||
sweep_weak_table (h, 1);
|
||||
|
||||
/* Add table to the list of used weak hash tables. */
|
||||
h->next_weak = used;
|
||||
used = h;
|
||||
}
|
||||
}
|
||||
|
||||
weak_hash_tables = used;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
Hash Code Computation
|
||||
|
@ -5294,6 +5274,7 @@ disregarding any coding systems. If nil, use the current buffer. */ )
|
|||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
syms_of_fns (void)
|
||||
{
|
||||
|
|
10
src/font.c
10
src/font.c
|
@ -38,6 +38,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "fontset.h"
|
||||
#include "font.h"
|
||||
#include "termhooks.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
#include TERM_HEADER
|
||||
|
@ -5309,9 +5310,10 @@ syms_of_font (void)
|
|||
sort_shift_bits[FONT_SIZE_INDEX] = 16;
|
||||
sort_shift_bits[FONT_WIDTH_INDEX] = 23;
|
||||
/* Note that the other elements in sort_shift_bits are not used. */
|
||||
PDUMPER_REMEMBER_SCALAR (sort_shift_bits);
|
||||
|
||||
staticpro (&font_charset_alist);
|
||||
font_charset_alist = Qnil;
|
||||
staticpro (&font_charset_alist);
|
||||
|
||||
DEFSYM (Qopentype, "opentype");
|
||||
|
||||
|
@ -5349,13 +5351,13 @@ syms_of_font (void)
|
|||
|
||||
DEFSYM (QCuser_spec, ":user-spec");
|
||||
|
||||
staticpro (&scratch_font_spec);
|
||||
scratch_font_spec = Ffont_spec (0, NULL);
|
||||
staticpro (&scratch_font_prefer);
|
||||
staticpro (&scratch_font_spec);
|
||||
scratch_font_prefer = Ffont_spec (0, NULL);
|
||||
staticpro (&scratch_font_prefer);
|
||||
|
||||
staticpro (&Vfont_log_deferred);
|
||||
Vfont_log_deferred = make_nil_vector (3);
|
||||
staticpro (&Vfont_log_deferred);
|
||||
|
||||
#if 0
|
||||
#ifdef HAVE_LIBOTF
|
||||
|
|
|
@ -39,6 +39,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include TERM_HEADER
|
||||
#endif /* HAVE_WINDOW_SYSTEM */
|
||||
#include "font.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
/* FONTSET
|
||||
|
||||
|
@ -2127,6 +2128,7 @@ syms_of_fontset (void)
|
|||
build_pure_c_string ("-*-*-*-*-*-*-*-*-*-*-*-*-fontset-default"));
|
||||
ASET (Vfontset_table, 0, Vdefault_fontset);
|
||||
next_fontset_id = 1;
|
||||
PDUMPER_REMEMBER_SCALAR (next_fontset_id);
|
||||
|
||||
auto_fontset_alist = Qnil;
|
||||
staticpro (&auto_fontset_alist);
|
||||
|
|
28
src/frame.c
28
src/frame.c
|
@ -53,6 +53,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#ifdef USE_X_TOOLKIT
|
||||
#include "widget.h"
|
||||
#endif
|
||||
#include "pdumper.h"
|
||||
|
||||
/* The currently selected frame. */
|
||||
Lisp_Object selected_frame;
|
||||
|
@ -1051,10 +1052,7 @@ make_initial_frame (void)
|
|||
Lisp_Object frame;
|
||||
|
||||
eassert (initial_kboard);
|
||||
|
||||
/* The first call must initialize Vframe_list. */
|
||||
if (! (NILP (Vframe_list) || CONSP (Vframe_list)))
|
||||
Vframe_list = Qnil;
|
||||
eassert (NILP (Vframe_list) || CONSP (Vframe_list));
|
||||
|
||||
terminal = init_initial_terminal ();
|
||||
|
||||
|
@ -5626,6 +5624,26 @@ make_monitor_attribute_list (struct MonitorInfo *monitors,
|
|||
Initialization
|
||||
***********************************************************************/
|
||||
|
||||
static void init_frame_once_for_pdumper (void);
|
||||
|
||||
void
|
||||
init_frame_once (void)
|
||||
{
|
||||
staticpro (&Vframe_list);
|
||||
staticpro (&selected_frame);
|
||||
PDUMPER_IGNORE (last_nonminibuf_frame);
|
||||
Vframe_list = Qnil;
|
||||
selected_frame = Qnil;
|
||||
pdumper_do_now_and_after_load (init_frame_once_for_pdumper);
|
||||
}
|
||||
|
||||
static void
|
||||
init_frame_once_for_pdumper (void)
|
||||
{
|
||||
PDUMPER_RESET_LV (Vframe_list, Qnil);
|
||||
PDUMPER_RESET_LV (selected_frame, Qnil);
|
||||
}
|
||||
|
||||
void
|
||||
syms_of_frame (void)
|
||||
{
|
||||
|
@ -6107,8 +6125,6 @@ making the child frame unresponsive to user actions, the default is to
|
|||
iconify the top level frame instead. */);
|
||||
iconify_child_frame = Qiconify_top_level;
|
||||
|
||||
staticpro (&Vframe_list);
|
||||
|
||||
defsubr (&Sframep);
|
||||
defsubr (&Sframe_live_p);
|
||||
defsubr (&Swindow_system);
|
||||
|
|
11
src/fringe.c
11
src/fringe.c
|
@ -30,6 +30,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "buffer.h"
|
||||
#include "blockinput.h"
|
||||
#include "termhooks.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
/* Fringe bitmaps are represented in three different ways:
|
||||
|
||||
|
@ -1739,12 +1740,18 @@ mark_fringe_data (void)
|
|||
|
||||
/* Initialize this module when Emacs starts. */
|
||||
|
||||
static void init_fringe_once_for_pdumper (void);
|
||||
|
||||
void
|
||||
init_fringe_once (void)
|
||||
{
|
||||
int bt;
|
||||
pdumper_do_now_and_after_load (init_fringe_once_for_pdumper);
|
||||
}
|
||||
|
||||
for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
|
||||
static void
|
||||
init_fringe_once_for_pdumper (void)
|
||||
{
|
||||
for (int bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
|
||||
init_fringe_bitmap (bt, &standard_bitmaps[bt], 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "blockinput.h"
|
||||
#include "font.h"
|
||||
#include "ftfont.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
/* FTCR font driver. */
|
||||
|
||||
|
@ -282,6 +283,8 @@ ftcrfont_draw (struct glyph_string *s,
|
|||
|
||||
|
||||
|
||||
static void syms_of_ftcrfont_for_pdumper (void);
|
||||
|
||||
struct font_driver const ftcrfont_driver =
|
||||
{
|
||||
.type = LISPSYM_INITIALLY (Qftcr),
|
||||
|
@ -317,5 +320,11 @@ syms_of_ftcrfont (void)
|
|||
abort ();
|
||||
|
||||
DEFSYM (Qftcr, "ftcr");
|
||||
pdumper_do_now_and_after_load (syms_of_ftcrfont_for_pdumper);
|
||||
}
|
||||
|
||||
static void
|
||||
syms_of_ftcrfont_for_pdumper (void)
|
||||
{
|
||||
register_font_driver (&ftcrfont_driver, NULL);
|
||||
}
|
||||
|
|
10
src/ftfont.c
10
src/ftfont.c
|
@ -34,6 +34,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "composite.h"
|
||||
#include "font.h"
|
||||
#include "ftfont.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
static struct font_driver const ftfont_driver;
|
||||
|
||||
|
@ -2701,6 +2702,8 @@ ftfont_combining_capability (struct font *font)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void syms_of_ftfont_for_pdumper (void);
|
||||
|
||||
static struct font_driver const ftfont_driver =
|
||||
{
|
||||
/* We can't draw a text without device dependent functions. */
|
||||
|
@ -2752,5 +2755,12 @@ syms_of_ftfont (void)
|
|||
staticpro (&ft_face_cache);
|
||||
ft_face_cache = Qnil;
|
||||
|
||||
pdumper_do_now_and_after_load (syms_of_ftfont_for_pdumper);
|
||||
}
|
||||
|
||||
static void
|
||||
syms_of_ftfont_for_pdumper (void)
|
||||
{
|
||||
PDUMPER_RESET_LV (ft_face_cache, Qnil);
|
||||
register_font_driver (&ftfont_driver, NULL);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "frame.h"
|
||||
#include "blockinput.h"
|
||||
#include "font.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
/* FTX font driver. */
|
||||
|
||||
|
@ -339,6 +340,8 @@ ftxfont_end_for_frame (struct frame *f)
|
|||
|
||||
|
||||
|
||||
static void syms_of_ftxfont_for_pdumper (void);
|
||||
|
||||
struct font_driver const ftxfont_driver =
|
||||
{
|
||||
/* We can't draw a text without device dependent functions. */
|
||||
|
@ -373,5 +376,11 @@ void
|
|||
syms_of_ftxfont (void)
|
||||
{
|
||||
DEFSYM (Qftx, "ftx");
|
||||
pdumper_do_now_and_after_load (syms_of_ftxfont_for_pdumper);
|
||||
}
|
||||
|
||||
static void
|
||||
syms_of_ftxfont_for_pdumper (void)
|
||||
{
|
||||
register_font_driver (&ftxfont_driver, NULL);
|
||||
}
|
||||
|
|
|
@ -76,7 +76,6 @@ extern void *(*__morecore) (ptrdiff_t);
|
|||
|
||||
#ifdef HYBRID_MALLOC
|
||||
# include "sheap.h"
|
||||
# define DUMPED bss_sbrk_did_unexec
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -1508,7 +1507,7 @@ static void *
|
|||
gdefault_morecore (ptrdiff_t increment)
|
||||
{
|
||||
#ifdef HYBRID_MALLOC
|
||||
if (!DUMPED)
|
||||
if (!definitely_will_not_unexec_p ())
|
||||
{
|
||||
return bss_sbrk (increment);
|
||||
}
|
||||
|
@ -1726,6 +1725,8 @@ extern int posix_memalign (void **memptr, size_t alignment, size_t size);
|
|||
static bool
|
||||
allocated_via_gmalloc (void *ptr)
|
||||
{
|
||||
if (!__malloc_initialized)
|
||||
return false;
|
||||
size_t block = BLOCK (ptr);
|
||||
size_t blockmax = _heaplimit - 1;
|
||||
return block <= blockmax && _heapinfo[block].busy.type != 0;
|
||||
|
@ -1737,7 +1738,7 @@ allocated_via_gmalloc (void *ptr)
|
|||
void *
|
||||
hybrid_malloc (size_t size)
|
||||
{
|
||||
if (DUMPED)
|
||||
if (definitely_will_not_unexec_p ())
|
||||
return malloc (size);
|
||||
return gmalloc (size);
|
||||
}
|
||||
|
@ -1745,7 +1746,7 @@ hybrid_malloc (size_t size)
|
|||
void *
|
||||
hybrid_calloc (size_t nmemb, size_t size)
|
||||
{
|
||||
if (DUMPED)
|
||||
if (definitely_will_not_unexec_p ())
|
||||
return calloc (nmemb, size);
|
||||
return gcalloc (nmemb, size);
|
||||
}
|
||||
|
@ -1763,7 +1764,7 @@ hybrid_free (void *ptr)
|
|||
void *
|
||||
hybrid_aligned_alloc (size_t alignment, size_t size)
|
||||
{
|
||||
if (!DUMPED)
|
||||
if (!definitely_will_not_unexec_p ())
|
||||
return galigned_alloc (alignment, size);
|
||||
/* The following is copied from alloc.c */
|
||||
#ifdef HAVE_ALIGNED_ALLOC
|
||||
|
@ -1786,7 +1787,7 @@ hybrid_realloc (void *ptr, size_t size)
|
|||
return hybrid_malloc (size);
|
||||
if (!allocated_via_gmalloc (ptr))
|
||||
return realloc (ptr, size);
|
||||
if (!DUMPED)
|
||||
if (!definitely_will_not_unexec_p ())
|
||||
return grealloc (ptr, size);
|
||||
|
||||
/* The dumped emacs is trying to realloc storage allocated before
|
||||
|
|
|
@ -25,6 +25,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "gnutls.h"
|
||||
#include "coding.h"
|
||||
#include "buffer.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
#if GNUTLS_VERSION_NUMBER >= 0x030014
|
||||
# define HAVE_GNUTLS_X509_SYSTEM_TRUST
|
||||
|
@ -2626,6 +2627,7 @@ syms_of_gnutls (void)
|
|||
);
|
||||
#ifdef HAVE_GNUTLS
|
||||
gnutls_global_initialized = 0;
|
||||
PDUMPER_IGNORE (gnutls_global_initialized);
|
||||
|
||||
DEFSYM (Qgnutls_code, "gnutls-code");
|
||||
DEFSYM (Qgnutls_anon, "gnutls-anon");
|
||||
|
|
|
@ -46,6 +46,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "coding.h"
|
||||
#include "termhooks.h"
|
||||
#include "font.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
|
@ -10003,7 +10004,9 @@ void
|
|||
syms_of_image (void)
|
||||
{
|
||||
/* Initialize this only once; it will be reset before dumping. */
|
||||
/* The portable dumper will just leave it NULL, so no need to reset. */
|
||||
image_types = NULL;
|
||||
PDUMPER_IGNORE (image_types);
|
||||
|
||||
/* Must be defined now because we're going to update it below, while
|
||||
defining the supported image types. */
|
||||
|
|
|
@ -29,6 +29,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "buffer.h"
|
||||
#include "window.h"
|
||||
#include "region-cache.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
static void insert_from_string_1 (Lisp_Object, ptrdiff_t, ptrdiff_t, ptrdiff_t,
|
||||
ptrdiff_t, bool, bool);
|
||||
|
@ -1927,6 +1928,14 @@ prepare_to_modify_buffer_1 (ptrdiff_t start, ptrdiff_t end,
|
|||
if (!NILP (BVAR (current_buffer, read_only)))
|
||||
Fbarf_if_buffer_read_only (temp);
|
||||
|
||||
/* If we're about to modify a buffer the contents of which come from
|
||||
a dump file, copy the contents to private storage first so we
|
||||
don't take a COW fault on the buffer text and keep it around
|
||||
forever. */
|
||||
if (pdumper_object_p (BEG_ADDR))
|
||||
enlarge_buffer_text (current_buffer, 0);
|
||||
eassert (!pdumper_object_p (BEG_ADDR));
|
||||
|
||||
run_undoable_change();
|
||||
|
||||
bset_redisplay (current_buffer);
|
||||
|
|
|
@ -29,7 +29,6 @@ INLINE_HEADER_BEGIN
|
|||
struct interval
|
||||
{
|
||||
/* The first group of entries deal with the tree structure. */
|
||||
|
||||
ptrdiff_t total_length; /* Length of myself and both children. */
|
||||
ptrdiff_t position; /* Cache of interval's character position. */
|
||||
/* This field is usually updated
|
||||
|
|
|
@ -68,6 +68,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
|
||||
#include <ignore-value.h>
|
||||
|
||||
#include "pdumper.h"
|
||||
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
#include TERM_HEADER
|
||||
#endif /* HAVE_WINDOW_SYSTEM */
|
||||
|
@ -10977,6 +10979,8 @@ static const struct event_head head_table[] = {
|
|||
{SYMBOL_INDEX (Qselect_window), SYMBOL_INDEX (Qswitch_frame)}
|
||||
};
|
||||
|
||||
static void syms_of_keyboard_for_pdumper (void);
|
||||
|
||||
void
|
||||
syms_of_keyboard (void)
|
||||
{
|
||||
|
@ -10987,9 +10991,11 @@ syms_of_keyboard (void)
|
|||
staticpro (&Vlispy_mouse_stem);
|
||||
|
||||
regular_top_level_message = build_pure_c_string ("Back to top level");
|
||||
staticpro (®ular_top_level_message);
|
||||
#ifdef HAVE_STACK_OVERFLOW_HANDLING
|
||||
recover_top_level_message
|
||||
= build_pure_c_string ("Re-entering top level after C stack overflow");
|
||||
staticpro (&recover_top_level_message);
|
||||
#endif
|
||||
DEFVAR_LISP ("internal--top-level-message", Vinternal__top_level_message,
|
||||
doc: /* Message displayed by `normal-top-level'. */);
|
||||
|
@ -11828,7 +11834,38 @@ preserve data in modified buffers that would otherwise be lost.
|
|||
If nil, Emacs crashes immediately in response to fatal signals. */);
|
||||
attempt_orderly_shutdown_on_fatal_signal = true;
|
||||
|
||||
pdumper_do_now_and_after_load (syms_of_keyboard_for_pdumper);
|
||||
}
|
||||
|
||||
static void
|
||||
syms_of_keyboard_for_pdumper (void)
|
||||
{
|
||||
/* Make sure input state is pristine when restoring from a dump.
|
||||
init_keyboard() also resets some of these, but the duplication
|
||||
doesn't hurt and makes sure that allocate_kboard and subsequent
|
||||
early init functions see the environment they expect. */
|
||||
|
||||
PDUMPER_RESET_LV (pending_funcalls, Qnil);
|
||||
PDUMPER_RESET_LV (unread_switch_frame, Qnil);
|
||||
PDUMPER_RESET_LV (internal_last_event_frame, Qnil);
|
||||
PDUMPER_RESET_LV (last_command_event, Qnil);
|
||||
PDUMPER_RESET_LV (last_nonmenu_event, Qnil);
|
||||
PDUMPER_RESET_LV (last_input_event, Qnil);
|
||||
PDUMPER_RESET_LV (Vunread_command_events, Qnil);
|
||||
PDUMPER_RESET_LV (Vunread_post_input_method_events, Qnil);
|
||||
PDUMPER_RESET_LV (Vunread_input_method_events, Qnil);
|
||||
PDUMPER_RESET_LV (Vthis_command, Qnil);
|
||||
PDUMPER_RESET_LV (Vreal_this_command, Qnil);
|
||||
PDUMPER_RESET_LV (Vthis_command_keys_shift_translated, Qnil);
|
||||
PDUMPER_RESET_LV (Vthis_original_command, Qnil);
|
||||
PDUMPER_RESET (num_input_keys, 0);
|
||||
PDUMPER_RESET (num_nonmacro_input_events, 0);
|
||||
PDUMPER_RESET_LV (Vlast_event_frame, Qnil);
|
||||
PDUMPER_RESET_LV (Vdeferred_action_list, Qnil);
|
||||
PDUMPER_RESET_LV (Vdelayed_warnings_list, Qnil);
|
||||
|
||||
/* Create the initial keyboard. Qt means 'unset'. */
|
||||
eassert (initial_kboard == NULL);
|
||||
initial_kboard = allocate_kboard (Qt);
|
||||
|
||||
DEFVAR_LISP ("while-no-input-ignore-events",
|
||||
|
@ -11940,8 +11977,8 @@ mark_kboards (void)
|
|||
for (kb = all_kboards; kb; kb = kb->next_kboard)
|
||||
{
|
||||
if (kb->kbd_macro_buffer)
|
||||
for (p = kb->kbd_macro_buffer; p < kb->kbd_macro_ptr; p++)
|
||||
mark_object (*p);
|
||||
for (p = kb->kbd_macro_buffer; p < kb->kbd_macro_ptr; p++)
|
||||
mark_object (*p);
|
||||
mark_object (KVAR (kb, Voverriding_terminal_local_map));
|
||||
mark_object (KVAR (kb, Vlast_command));
|
||||
mark_object (KVAR (kb, Vreal_last_command));
|
||||
|
|
225
src/lisp.h
225
src/lisp.h
|
@ -527,6 +527,7 @@ enum Lisp_Type
|
|||
/* Cons. XCONS (object) points to a struct Lisp_Cons. */
|
||||
Lisp_Cons = USE_LSB_TAG ? 3 : 6,
|
||||
|
||||
/* Must be last entry in Lisp_Type enumeration. */
|
||||
Lisp_Float = 7
|
||||
};
|
||||
|
||||
|
@ -623,16 +624,110 @@ extern void char_table_set (Lisp_Object, int, Lisp_Object);
|
|||
extern _Noreturn void wrong_type_argument (Lisp_Object, Lisp_Object);
|
||||
|
||||
|
||||
#ifdef CANNOT_DUMP
|
||||
enum { might_dump = false };
|
||||
#elif defined DOUG_LEA_MALLOC
|
||||
/* Defined in emacs.c. */
|
||||
extern bool might_dump;
|
||||
#endif
|
||||
/* True means Emacs has already been initialized.
|
||||
Used during startup to detect startup of dumped Emacs. */
|
||||
|
||||
/* Set after Emacs has started up the first time.
|
||||
Prevents reinitialization of the Lisp world and keymaps on
|
||||
subsequent starts. */
|
||||
extern bool initialized;
|
||||
|
||||
extern struct gflags {
|
||||
/* True means this Emacs instance was born to dump. */
|
||||
#if defined (HAVE_PDUMPER) || !defined (CANNOT_DUMP)
|
||||
bool will_dump_ : 1;
|
||||
bool will_bootstrap_ : 1;
|
||||
#endif
|
||||
#if defined (HAVE_PDUMPER)
|
||||
/* Set in an Emacs process that will likely dump with pdumper; all
|
||||
Emacs processes may dump with pdumper, however. */
|
||||
bool will_dump_with_pdumper_ : 1;
|
||||
/* Set in an Emacs process that has been restored from a portable
|
||||
dump. */
|
||||
bool dumped_with_pdumper_ : 1;
|
||||
#endif
|
||||
#ifndef CANNOT_DUMP
|
||||
bool will_dump_with_unexec_ : 1;
|
||||
/* Set in an Emacs process that has been restored from an unexec
|
||||
dump. */
|
||||
bool dumped_with_unexec_ : 1;
|
||||
/* We promise not to unexec: useful for hybrid malloc. */
|
||||
bool will_not_unexec_ : 1;
|
||||
#endif
|
||||
} gflags;
|
||||
|
||||
INLINE bool
|
||||
will_dump_p (void)
|
||||
{
|
||||
#if HAVE_PDUMPER || !defined (CANNOT_DUMP)
|
||||
return gflags.will_dump_;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
INLINE bool
|
||||
will_bootstrap_p (void)
|
||||
{
|
||||
#if HAVE_PDUMPER || !defined (CANNOT_DUMP)
|
||||
return gflags.will_bootstrap_;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
INLINE bool
|
||||
will_dump_with_pdumper_p (void)
|
||||
{
|
||||
#if HAVE_PDUMPER
|
||||
return gflags.will_dump_with_pdumper_;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
INLINE bool
|
||||
dumped_with_pdumper_p (void)
|
||||
{
|
||||
#if HAVE_PDUMPER
|
||||
return gflags.dumped_with_pdumper_;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
INLINE bool
|
||||
will_dump_with_unexec_p (void)
|
||||
{
|
||||
#ifdef CANNOT_DUMP
|
||||
return false;
|
||||
#else
|
||||
return gflags.will_dump_with_unexec_;
|
||||
#endif
|
||||
}
|
||||
|
||||
INLINE bool
|
||||
dumped_with_unexec_p (void)
|
||||
{
|
||||
#ifdef CANNOT_DUMP
|
||||
return false;
|
||||
#else
|
||||
return gflags.dumped_with_unexec_;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* This function is the opposite of will_dump_with_unexec_p(), except
|
||||
that it returns false before main runs. It's important to use
|
||||
gmalloc for any pre-main allocations if we're going to unexec. */
|
||||
INLINE bool
|
||||
definitely_will_not_unexec_p (void)
|
||||
{
|
||||
#ifdef CANNOT_DUMP
|
||||
return true;
|
||||
#else
|
||||
return gflags.will_not_unexec_;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Defined in floatfns.c. */
|
||||
extern double extract_float (Lisp_Object);
|
||||
|
||||
|
@ -862,6 +957,19 @@ typedef EMACS_UINT Lisp_Word_tag;
|
|||
# define DEFINE_NON_NIL_Q_SYMBOL_MACROS true
|
||||
#endif
|
||||
|
||||
/* True if N is a power of 2. N should be positive. */
|
||||
|
||||
#define POWER_OF_2(n) (((n) & ((n) - 1)) == 0)
|
||||
|
||||
/* Return X rounded to the next multiple of Y. Y should be positive,
|
||||
and Y - 1 + X should not overflow. Arguments should not have side
|
||||
effects, as they are evaluated more than once. Tune for Y being a
|
||||
power of 2. */
|
||||
|
||||
#define ROUNDUP(x, y) (POWER_OF_2 (y) \
|
||||
? ((y) - 1 + (x)) & ~ ((y) - 1) \
|
||||
: ((y) - 1 + (x)) - ((y) - 1 + (x)) % (y))
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
/* Header of vector-like objects. This documents the layout constraints on
|
||||
|
@ -1568,7 +1676,7 @@ CHECK_VECTOR (Lisp_Object x)
|
|||
/* A pseudovector is like a vector, but has other non-Lisp components. */
|
||||
|
||||
INLINE enum pvec_type
|
||||
PSEUDOVECTOR_TYPE (struct Lisp_Vector *v)
|
||||
PSEUDOVECTOR_TYPE (const struct Lisp_Vector *v)
|
||||
{
|
||||
ptrdiff_t size = v->header.size;
|
||||
return (size & PSEUDOVECTOR_FLAG
|
||||
|
@ -1578,7 +1686,7 @@ PSEUDOVECTOR_TYPE (struct Lisp_Vector *v)
|
|||
|
||||
/* Can't be used with PVEC_NORMAL_VECTOR. */
|
||||
INLINE bool
|
||||
PSEUDOVECTOR_TYPEP (union vectorlike_header *a, enum pvec_type code)
|
||||
PSEUDOVECTOR_TYPEP (const union vectorlike_header *a, enum pvec_type code)
|
||||
{
|
||||
/* We don't use PSEUDOVECTOR_TYPE here so as to avoid a shift
|
||||
* operation when `code' is known. */
|
||||
|
@ -2168,6 +2276,12 @@ struct hash_table_test
|
|||
|
||||
struct Lisp_Hash_Table
|
||||
{
|
||||
/* Change pdumper.c if you change the fields here.
|
||||
|
||||
IMPORTANT!!!!!!!
|
||||
|
||||
Call hash_rehash_if_needed() before accessing. */
|
||||
|
||||
/* This is for Lisp; the hash table code does not refer to it. */
|
||||
union vectorlike_header header;
|
||||
|
||||
|
@ -2224,8 +2338,9 @@ struct Lisp_Hash_Table
|
|||
/* The comparison and hash functions. */
|
||||
struct hash_table_test test;
|
||||
|
||||
/* Next weak hash table if this is a weak hash table. The head
|
||||
of the list is in weak_hash_tables. */
|
||||
/* Next weak hash table if this is a weak hash table. The head of
|
||||
the list is in weak_hash_tables. Used only during garbage
|
||||
collection --- at other times, it is NULL. */
|
||||
struct Lisp_Hash_Table *next_weak;
|
||||
} GCALIGNED_STRUCT;
|
||||
|
||||
|
@ -2250,32 +2365,47 @@ XHASH_TABLE (Lisp_Object a)
|
|||
|
||||
/* Value is the key part of entry IDX in hash table H. */
|
||||
INLINE Lisp_Object
|
||||
HASH_KEY (struct Lisp_Hash_Table *h, ptrdiff_t idx)
|
||||
HASH_KEY (const struct Lisp_Hash_Table *h, ptrdiff_t idx)
|
||||
{
|
||||
return AREF (h->key_and_value, 2 * idx);
|
||||
}
|
||||
|
||||
/* Value is the value part of entry IDX in hash table H. */
|
||||
INLINE Lisp_Object
|
||||
HASH_VALUE (struct Lisp_Hash_Table *h, ptrdiff_t idx)
|
||||
HASH_VALUE (const struct Lisp_Hash_Table *h, ptrdiff_t idx)
|
||||
{
|
||||
return AREF (h->key_and_value, 2 * idx + 1);
|
||||
}
|
||||
|
||||
/* Value is the hash code computed for entry IDX in hash table H. */
|
||||
INLINE Lisp_Object
|
||||
HASH_HASH (struct Lisp_Hash_Table *h, ptrdiff_t idx)
|
||||
HASH_HASH (const struct Lisp_Hash_Table *h, ptrdiff_t idx)
|
||||
{
|
||||
return AREF (h->hash, idx);
|
||||
}
|
||||
|
||||
/* Value is the size of hash table H. */
|
||||
INLINE ptrdiff_t
|
||||
HASH_TABLE_SIZE (struct Lisp_Hash_Table *h)
|
||||
HASH_TABLE_SIZE (const struct Lisp_Hash_Table *h)
|
||||
{
|
||||
return ASIZE (h->next);
|
||||
}
|
||||
|
||||
void hash_table_rehash (struct Lisp_Hash_Table *h);
|
||||
|
||||
INLINE bool
|
||||
hash_rehash_needed_p (const struct Lisp_Hash_Table *h)
|
||||
{
|
||||
return h->count < 0;
|
||||
}
|
||||
|
||||
INLINE void
|
||||
hash_rehash_if_needed (struct Lisp_Hash_Table *h)
|
||||
{
|
||||
if (hash_rehash_needed_p (h))
|
||||
hash_table_rehash (h);
|
||||
}
|
||||
|
||||
/* Default size for hash tables if not specified. */
|
||||
|
||||
enum DEFAULT_HASH_SIZE { DEFAULT_HASH_SIZE = 65 };
|
||||
|
@ -2441,6 +2571,9 @@ struct Lisp_Finalizer
|
|||
struct Lisp_Finalizer *next;
|
||||
} GCALIGNED_STRUCT;
|
||||
|
||||
extern struct Lisp_Finalizer finalizers;
|
||||
extern struct Lisp_Finalizer doomed_finalizers;
|
||||
|
||||
INLINE bool
|
||||
FINALIZERP (Lisp_Object x)
|
||||
{
|
||||
|
@ -2895,6 +3028,20 @@ CHECK_INTEGER (Lisp_Object x)
|
|||
CHECK_TYPE (INTEGERP (x), Qnumber_or_marker_p, x); \
|
||||
} while (false)
|
||||
|
||||
|
||||
/* If we're not dumping using the legacy dumper and we might be using
|
||||
the portable dumper, try to bunch all the subr structures together
|
||||
for more efficient dump loading. */
|
||||
#ifdef CANNOT_DUMP
|
||||
# ifdef DARWIN_OS
|
||||
# define SUBR_SECTION_ATTRIBUTE ATTRIBUTE_SECTION ("__DATA,subrs")
|
||||
# else
|
||||
# define SUBR_SECTION_ATTRIBUTE ATTRIBUTE_SECTION (".subrs")
|
||||
# endif
|
||||
#else
|
||||
# define SUBR_SECTION_ATTRIBUTE
|
||||
#endif
|
||||
|
||||
/* Define a built-in function for calling from Lisp.
|
||||
`lname' should be the name to give the function in Lisp,
|
||||
as a null-terminated C string.
|
||||
|
@ -2923,7 +3070,8 @@ CHECK_INTEGER (Lisp_Object x)
|
|||
/* This version of DEFUN declares a function prototype with the right
|
||||
arguments, so we can catch errors with maxargs at compile-time. */
|
||||
#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \
|
||||
static union Aligned_Lisp_Subr sname = \
|
||||
SUBR_SECTION_ATTRIBUTE \
|
||||
static union Aligned_Lisp_Subr sname = \
|
||||
{{{ PVEC_SUBR << PSEUDOVECTOR_AREA_BITS }, \
|
||||
{ .a ## maxargs = fnname }, \
|
||||
minargs, maxargs, lname, intspec, 0}}; \
|
||||
|
@ -3169,6 +3317,11 @@ extern Lisp_Object Vascii_canon_table;
|
|||
/* Call staticpro (&var) to protect static variable `var'. */
|
||||
|
||||
void staticpro (Lisp_Object *);
|
||||
|
||||
enum { NSTATICS = 2048 };
|
||||
extern Lisp_Object *staticvec[NSTATICS];
|
||||
extern int staticidx;
|
||||
|
||||
|
||||
/* Forward declarations for prototypes. */
|
||||
struct window;
|
||||
|
@ -3416,12 +3569,14 @@ enum { NEXT_ALMOST_PRIME_LIMIT = 11 };
|
|||
extern ptrdiff_t list_length (Lisp_Object);
|
||||
extern EMACS_INT next_almost_prime (EMACS_INT) ATTRIBUTE_CONST;
|
||||
extern Lisp_Object larger_vector (Lisp_Object, ptrdiff_t, ptrdiff_t);
|
||||
extern void sweep_weak_hash_tables (void);
|
||||
extern bool sweep_weak_table (struct Lisp_Hash_Table *, bool);
|
||||
extern char *extract_data_from_object (Lisp_Object, ptrdiff_t *, ptrdiff_t *);
|
||||
EMACS_UINT hash_string (char const *, ptrdiff_t);
|
||||
EMACS_UINT sxhash (Lisp_Object, int);
|
||||
EMACS_UINT hashfn_eql (struct hash_table_test *ht, Lisp_Object key);
|
||||
EMACS_UINT hashfn_equal (struct hash_table_test *ht, Lisp_Object key);
|
||||
Lisp_Object make_hash_table (struct hash_table_test, EMACS_INT, float, float,
|
||||
Lisp_Object, bool);
|
||||
Lisp_Object, bool);
|
||||
ptrdiff_t hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, EMACS_UINT *);
|
||||
ptrdiff_t hash_put (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object,
|
||||
EMACS_UINT);
|
||||
|
@ -3592,6 +3747,12 @@ typedef uintptr_t byte_ct; /* System byte counts reported by GC. */
|
|||
extern byte_ct consing_since_gc;
|
||||
extern byte_ct gc_relative_threshold;
|
||||
extern byte_ct memory_full_cons_threshold;
|
||||
#ifdef HAVE_PDUMPER
|
||||
extern int number_finalizers_run;
|
||||
#endif
|
||||
#ifdef ENABLE_CHECKING
|
||||
extern Lisp_Object Vdead;
|
||||
#endif
|
||||
extern Lisp_Object list1 (Lisp_Object);
|
||||
extern Lisp_Object list2 (Lisp_Object, Lisp_Object);
|
||||
extern Lisp_Object list3 (Lisp_Object, Lisp_Object, Lisp_Object);
|
||||
|
@ -3601,6 +3762,21 @@ extern Lisp_Object list5 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object,
|
|||
enum constype {CONSTYPE_HEAP, CONSTYPE_PURE};
|
||||
extern Lisp_Object listn (enum constype, ptrdiff_t, Lisp_Object, ...);
|
||||
|
||||
enum gc_root_type {
|
||||
GC_ROOT_STATICPRO,
|
||||
GC_ROOT_BUFFER_LOCAL_DEFAULT,
|
||||
GC_ROOT_BUFFER_LOCAL_NAME,
|
||||
GC_ROOT_C_SYMBOL
|
||||
};
|
||||
|
||||
struct gc_root_visitor {
|
||||
void (*visit)(Lisp_Object *root_ptr,
|
||||
enum gc_root_type type,
|
||||
void *data);
|
||||
void *data;
|
||||
};
|
||||
extern void visit_static_gc_roots (struct gc_root_visitor visitor);
|
||||
|
||||
/* Build a frequently used 2/3/4-integer lists. */
|
||||
|
||||
INLINE Lisp_Object
|
||||
|
@ -3629,6 +3805,13 @@ extern Lisp_Object make_string (const char *, ptrdiff_t);
|
|||
extern Lisp_Object make_formatted_string (char *, const char *, ...)
|
||||
ATTRIBUTE_FORMAT_PRINTF (2, 3);
|
||||
extern Lisp_Object make_unibyte_string (const char *, ptrdiff_t);
|
||||
extern ptrdiff_t vectorlike_nbytes (const union vectorlike_header *hdr);
|
||||
|
||||
INLINE ptrdiff_t
|
||||
vector_nbytes (const struct Lisp_Vector *v)
|
||||
{
|
||||
return vectorlike_nbytes (&v->header);
|
||||
}
|
||||
|
||||
/* Make unibyte string from C string when the length isn't known. */
|
||||
|
||||
|
@ -3824,7 +4007,7 @@ extern Lisp_Object string_to_number (char const *, int, ptrdiff_t *);
|
|||
extern void map_obarray (Lisp_Object, void (*) (Lisp_Object, Lisp_Object),
|
||||
Lisp_Object);
|
||||
extern void dir_warning (const char *, Lisp_Object);
|
||||
extern void init_obarray (void);
|
||||
extern void init_obarray_once (void);
|
||||
extern void init_lread (void);
|
||||
extern void syms_of_lread (void);
|
||||
|
||||
|
@ -3989,6 +4172,7 @@ extern void syms_of_module (void);
|
|||
#endif
|
||||
|
||||
/* Defined in thread.c. */
|
||||
extern struct thread_state primary_thread;
|
||||
extern void mark_threads (void);
|
||||
extern void unmark_main_thread (void);
|
||||
|
||||
|
@ -4017,7 +4201,7 @@ extern bool overlay_touches_p (ptrdiff_t);
|
|||
extern Lisp_Object other_buffer_safely (Lisp_Object);
|
||||
extern Lisp_Object get_truename_buffer (Lisp_Object);
|
||||
extern void init_buffer_once (void);
|
||||
extern void init_buffer (int);
|
||||
extern void init_buffer (void);
|
||||
extern void syms_of_buffer (void);
|
||||
extern void keys_of_buffer (void);
|
||||
|
||||
|
@ -4160,6 +4344,7 @@ extern void store_in_alist (Lisp_Object *, Lisp_Object, Lisp_Object);
|
|||
extern Lisp_Object do_switch_frame (Lisp_Object, int, int, Lisp_Object);
|
||||
extern Lisp_Object get_frame_param (struct frame *, Lisp_Object);
|
||||
extern void frames_discard_buffer (Lisp_Object);
|
||||
extern void init_frame_once (void);
|
||||
extern void syms_of_frame (void);
|
||||
|
||||
/* Defined in emacs.c. */
|
||||
|
|
209
src/lread.c
209
src/lread.c
|
@ -42,6 +42,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "systime.h"
|
||||
#include "termhooks.h"
|
||||
#include "blockinput.h"
|
||||
#include "pdumper.h"
|
||||
#include <c-ctype.h>
|
||||
|
||||
#ifdef MSDOS
|
||||
|
@ -1969,7 +1970,7 @@ readevalloop (Lisp_Object readcharfun,
|
|||
? Qnil : list1 (Qt)));
|
||||
|
||||
/* Try to ensure sourcename is a truename, except whilst preloading. */
|
||||
if (NILP (Vpurify_flag)
|
||||
if (!will_dump_p ()
|
||||
&& !NILP (sourcename) && !NILP (Ffile_name_absolute_p (sourcename))
|
||||
&& !NILP (Ffboundp (Qfile_truename)))
|
||||
sourcename = call1 (Qfile_truename, sourcename) ;
|
||||
|
@ -4373,7 +4374,7 @@ OBARRAY defaults to the value of `obarray'. */)
|
|||
#define OBARRAY_SIZE 15121
|
||||
|
||||
void
|
||||
init_obarray (void)
|
||||
init_obarray_once (void)
|
||||
{
|
||||
Vobarray = make_vector (OBARRAY_SIZE, make_fixnum (0));
|
||||
initial_obarray = Vobarray;
|
||||
|
@ -4394,12 +4395,15 @@ init_obarray (void)
|
|||
make_symbol_constant (Qt);
|
||||
XSYMBOL (Qt)->u.s.declared_special = true;
|
||||
|
||||
/* Qt is correct even if CANNOT_DUMP. loadup.el will set to nil at end. */
|
||||
/* Qt is correct even if not dumping. loadup.el will set to nil at end. */
|
||||
Vpurify_flag = Qt;
|
||||
|
||||
DEFSYM (Qvariable_documentation, "variable-documentation");
|
||||
}
|
||||
|
||||
|
||||
int ndefsubr;
|
||||
|
||||
void
|
||||
defsubr (union Aligned_Lisp_Subr *aname)
|
||||
{
|
||||
|
@ -4409,6 +4413,7 @@ defsubr (union Aligned_Lisp_Subr *aname)
|
|||
XSETPVECTYPE (sname, PVEC_SUBR);
|
||||
XSETSUBR (tem, sname);
|
||||
set_symbol_function (sym, tem);
|
||||
++ndefsubr;
|
||||
}
|
||||
|
||||
#ifdef NOTDEF /* Use fset in subr.el now! */
|
||||
|
@ -4526,11 +4531,9 @@ load_path_check (Lisp_Object lpath)
|
|||
are running uninstalled.
|
||||
|
||||
Uses the following logic:
|
||||
If CANNOT_DUMP:
|
||||
If Vinstallation_directory is not nil (ie, running uninstalled),
|
||||
use PATH_DUMPLOADSEARCH (ie, build path). Else use PATH_LOADSEARCH.
|
||||
The remainder is what happens when dumping works:
|
||||
If purify-flag (ie dumping) just use PATH_DUMPLOADSEARCH.
|
||||
If !will_dump: Use PATH_LOADSEARCH.
|
||||
The remainder is what happens when dumping is about to happen:
|
||||
If dumping, just use PATH_DUMPLOADSEARCH.
|
||||
Otherwise use PATH_LOADSEARCH.
|
||||
|
||||
If !initialized, then just return PATH_DUMPLOADSEARCH.
|
||||
|
@ -4553,131 +4556,109 @@ load_path_check (Lisp_Object lpath)
|
|||
static Lisp_Object
|
||||
load_path_default (void)
|
||||
{
|
||||
if (will_dump_p ())
|
||||
/* PATH_DUMPLOADSEARCH is the lisp dir in the source directory.
|
||||
We used to add ../lisp (ie the lisp dir in the build
|
||||
directory) at the front here, but that should not be
|
||||
necessary, since in out of tree builds lisp/ is empty, save
|
||||
for Makefile. */
|
||||
return decode_env_path (0, PATH_DUMPLOADSEARCH, 0);
|
||||
|
||||
Lisp_Object lpath = Qnil;
|
||||
const char *normal;
|
||||
const char *normal = PATH_LOADSEARCH;
|
||||
const char *loadpath = NULL;
|
||||
|
||||
#ifdef CANNOT_DUMP
|
||||
#ifdef HAVE_NS
|
||||
const char *loadpath = ns_load_path ();
|
||||
loadpath = ns_load_path ();
|
||||
#endif
|
||||
|
||||
normal = PATH_LOADSEARCH;
|
||||
if (!NILP (Vinstallation_directory)) normal = PATH_DUMPLOADSEARCH;
|
||||
|
||||
#ifdef HAVE_NS
|
||||
lpath = decode_env_path (0, loadpath ? loadpath : normal, 0);
|
||||
#else
|
||||
lpath = decode_env_path (0, normal, 0);
|
||||
#endif
|
||||
|
||||
#else /* !CANNOT_DUMP */
|
||||
|
||||
normal = NILP (Vpurify_flag) ? PATH_LOADSEARCH : PATH_DUMPLOADSEARCH;
|
||||
|
||||
if (initialized)
|
||||
if (!NILP (Vinstallation_directory))
|
||||
{
|
||||
#ifdef HAVE_NS
|
||||
const char *loadpath = ns_load_path ();
|
||||
lpath = decode_env_path (0, loadpath ? loadpath : normal, 0);
|
||||
#else
|
||||
lpath = decode_env_path (0, normal, 0);
|
||||
#endif
|
||||
if (!NILP (Vinstallation_directory))
|
||||
{
|
||||
Lisp_Object tem, tem1;
|
||||
Lisp_Object tem, tem1;
|
||||
|
||||
/* Add to the path the lisp subdir of the installation
|
||||
dir, if it is accessible. Note: in out-of-tree builds,
|
||||
this directory is empty save for Makefile. */
|
||||
tem = Fexpand_file_name (build_string ("lisp"),
|
||||
/* Add to the path the lisp subdir of the installation
|
||||
dir, if it is accessible. Note: in out-of-tree builds,
|
||||
this directory is empty save for Makefile. */
|
||||
tem = Fexpand_file_name (build_string ("lisp"),
|
||||
Vinstallation_directory);
|
||||
tem1 = Ffile_accessible_directory_p (tem);
|
||||
if (!NILP (tem1))
|
||||
{
|
||||
if (NILP (Fmember (tem, lpath)))
|
||||
{
|
||||
/* We are running uninstalled. The default load-path
|
||||
points to the eventual installed lisp directories.
|
||||
We should not use those now, even if they exist,
|
||||
so start over from a clean slate. */
|
||||
lpath = list1 (tem);
|
||||
}
|
||||
}
|
||||
else
|
||||
/* That dir doesn't exist, so add the build-time
|
||||
Lisp dirs instead. */
|
||||
{
|
||||
Lisp_Object dump_path =
|
||||
decode_env_path (0, PATH_DUMPLOADSEARCH, 0);
|
||||
lpath = nconc2 (lpath, dump_path);
|
||||
}
|
||||
|
||||
/* Add site-lisp under the installation dir, if it exists. */
|
||||
if (!no_site_lisp)
|
||||
{
|
||||
tem = Fexpand_file_name (build_string ("site-lisp"),
|
||||
Vinstallation_directory);
|
||||
tem1 = Ffile_accessible_directory_p (tem);
|
||||
if (!NILP (tem1))
|
||||
{
|
||||
if (NILP (Fmember (tem, lpath)))
|
||||
{
|
||||
/* We are running uninstalled. The default load-path
|
||||
points to the eventual installed lisp directories.
|
||||
We should not use those now, even if they exist,
|
||||
so start over from a clean slate. */
|
||||
lpath = list1 (tem);
|
||||
}
|
||||
}
|
||||
else
|
||||
/* That dir doesn't exist, so add the build-time
|
||||
Lisp dirs instead. */
|
||||
{
|
||||
Lisp_Object dump_path =
|
||||
decode_env_path (0, PATH_DUMPLOADSEARCH, 0);
|
||||
lpath = nconc2 (lpath, dump_path);
|
||||
lpath = Fcons (tem, lpath);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add site-lisp under the installation dir, if it exists. */
|
||||
if (!no_site_lisp)
|
||||
/* If Emacs was not built in the source directory,
|
||||
and it is run from where it was built, add to load-path
|
||||
the lisp and site-lisp dirs under that directory. */
|
||||
|
||||
if (NILP (Fequal (Vinstallation_directory, Vsource_directory)))
|
||||
{
|
||||
Lisp_Object tem2;
|
||||
|
||||
tem = Fexpand_file_name (build_string ("src/Makefile"),
|
||||
Vinstallation_directory);
|
||||
tem1 = Ffile_exists_p (tem);
|
||||
|
||||
/* Don't be fooled if they moved the entire source tree
|
||||
AFTER dumping Emacs. If the build directory is indeed
|
||||
different from the source dir, src/Makefile.in and
|
||||
src/Makefile will not be found together. */
|
||||
tem = Fexpand_file_name (build_string ("src/Makefile.in"),
|
||||
Vinstallation_directory);
|
||||
tem2 = Ffile_exists_p (tem);
|
||||
if (!NILP (tem1) && NILP (tem2))
|
||||
{
|
||||
tem = Fexpand_file_name (build_string ("site-lisp"),
|
||||
Vinstallation_directory);
|
||||
tem1 = Ffile_accessible_directory_p (tem);
|
||||
if (!NILP (tem1))
|
||||
tem = Fexpand_file_name (build_string ("lisp"),
|
||||
Vsource_directory);
|
||||
|
||||
if (NILP (Fmember (tem, lpath)))
|
||||
lpath = Fcons (tem, lpath);
|
||||
|
||||
if (!no_site_lisp)
|
||||
{
|
||||
if (NILP (Fmember (tem, lpath)))
|
||||
lpath = Fcons (tem, lpath);
|
||||
}
|
||||
}
|
||||
|
||||
/* If Emacs was not built in the source directory,
|
||||
and it is run from where it was built, add to load-path
|
||||
the lisp and site-lisp dirs under that directory. */
|
||||
|
||||
if (NILP (Fequal (Vinstallation_directory, Vsource_directory)))
|
||||
{
|
||||
Lisp_Object tem2;
|
||||
|
||||
tem = Fexpand_file_name (build_string ("src/Makefile"),
|
||||
Vinstallation_directory);
|
||||
tem1 = Ffile_exists_p (tem);
|
||||
|
||||
/* Don't be fooled if they moved the entire source tree
|
||||
AFTER dumping Emacs. If the build directory is indeed
|
||||
different from the source dir, src/Makefile.in and
|
||||
src/Makefile will not be found together. */
|
||||
tem = Fexpand_file_name (build_string ("src/Makefile.in"),
|
||||
Vinstallation_directory);
|
||||
tem2 = Ffile_exists_p (tem);
|
||||
if (!NILP (tem1) && NILP (tem2))
|
||||
{
|
||||
tem = Fexpand_file_name (build_string ("lisp"),
|
||||
tem = Fexpand_file_name (build_string ("site-lisp"),
|
||||
Vsource_directory);
|
||||
|
||||
if (NILP (Fmember (tem, lpath)))
|
||||
lpath = Fcons (tem, lpath);
|
||||
|
||||
if (!no_site_lisp)
|
||||
tem1 = Ffile_accessible_directory_p (tem);
|
||||
if (!NILP (tem1))
|
||||
{
|
||||
tem = Fexpand_file_name (build_string ("site-lisp"),
|
||||
Vsource_directory);
|
||||
tem1 = Ffile_accessible_directory_p (tem);
|
||||
if (!NILP (tem1))
|
||||
{
|
||||
if (NILP (Fmember (tem, lpath)))
|
||||
lpath = Fcons (tem, lpath);
|
||||
}
|
||||
if (NILP (Fmember (tem, lpath)))
|
||||
lpath = Fcons (tem, lpath);
|
||||
}
|
||||
}
|
||||
} /* Vinstallation_directory != Vsource_directory */
|
||||
}
|
||||
} /* Vinstallation_directory != Vsource_directory */
|
||||
|
||||
} /* if Vinstallation_directory */
|
||||
}
|
||||
else /* !initialized */
|
||||
{
|
||||
/* NORMAL refers to PATH_DUMPLOADSEARCH, ie the lisp dir in the
|
||||
source directory. We used to add ../lisp (ie the lisp dir in
|
||||
the build directory) at the front here, but that should not
|
||||
be necessary, since in out of tree builds lisp/ is empty, save
|
||||
for Makefile. */
|
||||
lpath = decode_env_path (0, normal, 0);
|
||||
}
|
||||
#endif /* !CANNOT_DUMP */
|
||||
} /* if Vinstallation_directory */
|
||||
|
||||
return lpath;
|
||||
}
|
||||
|
@ -4691,11 +4672,7 @@ init_lread (void)
|
|||
/* First, set Vload_path. */
|
||||
|
||||
/* Ignore EMACSLOADPATH when dumping. */
|
||||
#ifdef CANNOT_DUMP
|
||||
bool use_loadpath = true;
|
||||
#else
|
||||
bool use_loadpath = NILP (Vpurify_flag);
|
||||
#endif
|
||||
bool use_loadpath = !will_dump_p ();
|
||||
|
||||
if (use_loadpath && egetenv ("EMACSLOADPATH"))
|
||||
{
|
||||
|
@ -4746,7 +4723,7 @@ init_lread (void)
|
|||
load_path_check (Vload_path);
|
||||
|
||||
/* Add the site-lisp directories at the front. */
|
||||
if (initialized && !no_site_lisp && PATH_SITELOADSEARCH[0] != '\0')
|
||||
if (!will_dump_p () && !no_site_lisp && PATH_SITELOADSEARCH[0] != '\0')
|
||||
{
|
||||
Lisp_Object sitelisp;
|
||||
sitelisp = decode_env_path (0, PATH_SITELOADSEARCH, 0);
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "nsterm.h"
|
||||
#include "macfont.h"
|
||||
#include "macuvs.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
#include <libkern/OSByteOrder.h>
|
||||
|
||||
|
@ -1029,12 +1030,12 @@ sorted in the canonical order (CTFontManagerCompareFontFamilyNames on
|
|||
static void
|
||||
macfont_init_font_change_handler (void)
|
||||
{
|
||||
static bool initialized = false;
|
||||
static bool xinitialized = false;
|
||||
|
||||
if (initialized)
|
||||
if (xinitialized)
|
||||
return;
|
||||
|
||||
initialized = true;
|
||||
xinitialized = true;
|
||||
CFNotificationCenterAddObserver
|
||||
(CFNotificationCenterGetLocalCenter (), NULL,
|
||||
macfont_handle_font_change_notification,
|
||||
|
@ -1646,7 +1647,7 @@ static int macfont_variation_glyphs (struct font *, int c,
|
|||
unsigned variations[256]);
|
||||
static void macfont_filter_properties (Lisp_Object, Lisp_Object);
|
||||
|
||||
static struct font_driver const macfont_driver =
|
||||
static struct font_driver macfont_driver =
|
||||
{
|
||||
.type = LISPSYM_INITIALLY (Qmac_ct),
|
||||
.get_cache = macfont_get_cache,
|
||||
|
@ -4028,12 +4029,14 @@ So we use CTFontDescriptorCreateMatchingFontDescriptor (no
|
|||
}
|
||||
|
||||
|
||||
|
||||
static void syms_of_macfont_for_pdumper (void);
|
||||
|
||||
void
|
||||
syms_of_macfont (void)
|
||||
{
|
||||
/* Core Text, for macOS. */
|
||||
DEFSYM (Qmac_ct, "mac-ct");
|
||||
register_font_driver (&macfont_driver, NULL);
|
||||
|
||||
/* The font property key specifying the font design destination. The
|
||||
value is an unsigned integer code: 0 for WYSIWYG, and 1 for Video
|
||||
|
@ -4048,4 +4051,18 @@ So we use CTFontDescriptorCreateMatchingFontDescriptor (no
|
|||
|
||||
macfont_family_cache = Qnil;
|
||||
staticpro (&macfont_family_cache);
|
||||
|
||||
pdumper_do_now_and_after_load (syms_of_macfont_for_pdumper);
|
||||
}
|
||||
|
||||
static void
|
||||
syms_of_macfont_for_pdumper (void)
|
||||
{
|
||||
if (dumped_with_pdumper_p ())
|
||||
macfont_family_cache = Qnil;
|
||||
else
|
||||
eassert (NILP (macfont_family_cache));
|
||||
|
||||
macfont_driver.type = Qmac_ct;
|
||||
register_font_driver (&macfont_driver, NULL);
|
||||
}
|
||||
|
|
|
@ -1576,9 +1576,10 @@ for instance using the window manager, then this produces a quit and
|
|||
void
|
||||
syms_of_menu (void)
|
||||
{
|
||||
staticpro (&menu_items);
|
||||
menu_items = Qnil;
|
||||
staticpro (&menu_items);
|
||||
menu_items_inuse = Qnil;
|
||||
staticpro (&menu_items_inuse);
|
||||
|
||||
defsubr (&Sx_popup_menu);
|
||||
defsubr (&Sx_popup_dialog);
|
||||
|
|
|
@ -32,6 +32,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "keymap.h"
|
||||
#include "sysstdio.h"
|
||||
#include "systty.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
/* List of buffers for use as minibuffers.
|
||||
The first element of the list is used for the outermost minibuffer
|
||||
|
@ -1198,6 +1199,9 @@ is used to further constrain the set of candidates. */)
|
|||
bucket = AREF (collection, idx);
|
||||
}
|
||||
|
||||
if (HASH_TABLE_P (collection))
|
||||
hash_rehash_if_needed (XHASH_TABLE (collection));
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* Get the next element of the alist, obarray, or hash-table. */
|
||||
|
@ -1858,21 +1862,36 @@ If no minibuffer is active, return nil. */)
|
|||
}
|
||||
|
||||
|
||||
|
||||
static void init_minibuf_once_for_pdumper (void);
|
||||
|
||||
void
|
||||
init_minibuf_once (void)
|
||||
{
|
||||
Vminibuffer_list = Qnil;
|
||||
staticpro (&Vminibuffer_list);
|
||||
pdumper_do_now_and_after_load (init_minibuf_once_for_pdumper);
|
||||
}
|
||||
|
||||
static void
|
||||
init_minibuf_once_for_pdumper (void)
|
||||
{
|
||||
PDUMPER_IGNORE (minibuf_level);
|
||||
PDUMPER_IGNORE (minibuf_prompt_width);
|
||||
|
||||
/* We run this function on first initialization and whenever we
|
||||
restore from a pdumper image. pdumper doesn't try to preserve
|
||||
frames, windows, and so on, so reset everything related here. */
|
||||
Vminibuffer_list = Qnil;
|
||||
minibuf_level = 0;
|
||||
minibuf_prompt = Qnil;
|
||||
minibuf_save_list = Qnil;
|
||||
last_minibuf_string = Qnil;
|
||||
}
|
||||
|
||||
void
|
||||
syms_of_minibuf (void)
|
||||
{
|
||||
minibuf_level = 0;
|
||||
minibuf_prompt = Qnil;
|
||||
staticpro (&minibuf_prompt);
|
||||
|
||||
minibuf_save_list = Qnil;
|
||||
staticpro (&minibuf_save_list);
|
||||
|
||||
DEFSYM (Qcompletion_ignore_case, "completion-ignore-case");
|
||||
|
@ -1882,7 +1901,6 @@ syms_of_minibuf (void)
|
|||
DEFSYM (Qminibuffer_completion_table, "minibuffer-completion-table");
|
||||
|
||||
staticpro (&last_minibuf_string);
|
||||
last_minibuf_string = Qnil;
|
||||
|
||||
DEFSYM (Qcustom_variable_history, "custom-variable-history");
|
||||
Fset (Qcustom_variable_history, Qnil);
|
||||
|
|
|
@ -49,7 +49,6 @@ Updated by Christian Limpach (chris@nice.ch)
|
|||
#include "macfont.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_NS
|
||||
|
||||
static EmacsTooltip *ns_tooltip = nil;
|
||||
|
@ -3125,7 +3124,6 @@ - (NSString *)panel: (id)sender userEnteredFilename: (NSString *)filename
|
|||
|
||||
========================================================================== */
|
||||
|
||||
|
||||
void
|
||||
syms_of_nsfns (void)
|
||||
{
|
||||
|
@ -3215,5 +3213,6 @@ - (NSString *)panel: (id)sender userEnteredFilename: (NSString *)filename
|
|||
|
||||
as_status = 0;
|
||||
as_script = Qnil;
|
||||
staticpro (&as_script);
|
||||
as_result = 0;
|
||||
}
|
||||
|
|
13
src/nsfont.m
13
src/nsfont.m
|
@ -36,6 +36,7 @@
|
|||
#include "character.h"
|
||||
#include "font.h"
|
||||
#include "termchar.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
/* TODO: Drop once we can assume gnustep-gui 0.17.1. */
|
||||
#ifdef NS_IMPL_GNUSTEP
|
||||
|
@ -1483,6 +1484,8 @@ - (void)setIntAttribute: (NSInteger)attributeTag value: (NSInteger)val
|
|||
fprintf (stderr, "\n");
|
||||
}
|
||||
|
||||
static void syms_of_nsfont_for_pdumper (void);
|
||||
|
||||
struct font_driver const nsfont_driver =
|
||||
{
|
||||
.type = LISPSYM_INITIALLY (Qns),
|
||||
|
@ -1502,13 +1505,17 @@ - (void)setIntAttribute: (NSInteger)attributeTag value: (NSInteger)val
|
|||
void
|
||||
syms_of_nsfont (void)
|
||||
{
|
||||
register_font_driver (&nsfont_driver, NULL);
|
||||
DEFSYM (Qcondensed, "condensed");
|
||||
DEFSYM (Qexpanded, "expanded");
|
||||
DEFSYM (Qapple, "apple");
|
||||
DEFSYM (Qmedium, "medium");
|
||||
DEFVAR_LISP ("ns-reg-to-script", Vns_reg_to_script,
|
||||
doc: /* Internal use: maps font registry to Unicode script. */);
|
||||
|
||||
ascii_printable = NULL;
|
||||
pdumper_do_now_and_after_load (syms_of_nsfont_for_pdumper);
|
||||
}
|
||||
|
||||
static void
|
||||
syms_of_nsfont_for_pdumper (void)
|
||||
{
|
||||
register_font_driver (&nsfont_driver, NULL);
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "termhooks.h"
|
||||
#include "keyboard.h"
|
||||
#include "menu.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
#define NSMENUPROFILE 0
|
||||
|
||||
|
@ -1893,6 +1894,7 @@ - (Lisp_Object)runDialogAt: (NSPoint)p
|
|||
/* Don't know how to keep track of this in Next/Open/GNUstep. Always
|
||||
update menus there. */
|
||||
trackingMenu = 1;
|
||||
PDUMPER_REMEMBER_SCALAR (trackingMenu);
|
||||
#endif
|
||||
defsubr (&Sns_reset_menu);
|
||||
defsubr (&Smenu_or_popup_active_p);
|
||||
|
|
|
@ -60,6 +60,7 @@ Updated by Christian Limpach (chris@nice.ch)
|
|||
#include "keyboard.h"
|
||||
#include "buffer.h"
|
||||
#include "font.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
#ifdef NS_IMPL_GNUSTEP
|
||||
#include "process.h"
|
||||
|
@ -9326,6 +9327,7 @@ Convert an X font name (XLFD) to an NS font name.
|
|||
NSTRACE ("syms_of_nsterm");
|
||||
|
||||
ns_antialias_threshold = 10.0;
|
||||
PDUMPER_REMEMBER_SCALAR (ns_antialias_threshold);
|
||||
|
||||
/* From 23+ we need to tell emacs what modifiers there are. */
|
||||
DEFSYM (Qmodifier_value, "modifier-value");
|
||||
|
|
5593
src/pdumper.c
Normal file
5593
src/pdumper.c
Normal file
File diff suppressed because it is too large
Load diff
267
src/pdumper.h
Normal file
267
src/pdumper.h
Normal file
|
@ -0,0 +1,267 @@
|
|||
/* Header file for the portable dumper.
|
||||
|
||||
Copyright (C) 2016 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or (at
|
||||
your option) any later version.
|
||||
|
||||
GNU Emacs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef EMACS_PDUMPER_H
|
||||
#define EMACS_PDUMPER_H
|
||||
|
||||
#include "lisp.h"
|
||||
|
||||
INLINE_HEADER_BEGIN
|
||||
|
||||
#define PDUMPER_NO_OBJECT ((enum Lisp_Type) -1)
|
||||
|
||||
/* Indicate in source code that we're deliberately relying on pdumper
|
||||
not preserving the given value. Compiles to nothing --- for humans
|
||||
only. */
|
||||
#define PDUMPER_IGNORE(thing) ((void) &(thing))
|
||||
|
||||
/* The portable dumper automatically preserves the Lisp heap and any C
|
||||
variables to which the Lisp heap points. It doesn't know anything
|
||||
about other C variables. The functions below allow code from other
|
||||
parts of Emacs to tell the portable dumper about other bits of
|
||||
information to preserve in dumped images.
|
||||
|
||||
These memory-records are themselves preserved in the dump, so call
|
||||
the functions below only on the !initialized init path, just
|
||||
like staticpro.
|
||||
|
||||
There are no special functions to preserve a global Lisp_Object.
|
||||
You should just staticpro these. */
|
||||
|
||||
/* Remember the value of THING in dumped images. THING must not
|
||||
contain any pointers or Lisp_Object variables: these values are not
|
||||
valid across dump and load. */
|
||||
#define PDUMPER_REMEMBER_SCALAR(thing) \
|
||||
pdumper_remember_scalar (&(thing), sizeof (thing))
|
||||
|
||||
extern void pdumper_remember_scalar_impl (void *data, ptrdiff_t nbytes);
|
||||
|
||||
INLINE
|
||||
void
|
||||
pdumper_remember_scalar (void *data, ptrdiff_t nbytes)
|
||||
{
|
||||
#ifdef HAVE_PDUMPER
|
||||
pdumper_remember_scalar_impl (data, nbytes);
|
||||
#else
|
||||
(void) data;
|
||||
(void) nbytes;
|
||||
#endif
|
||||
}
|
||||
|
||||
extern void pdumper_remember_lv_ptr_raw_impl (
|
||||
void *ptr, enum Lisp_Type type);
|
||||
|
||||
/* Remember the pointer at *PTR. *PTR must be null or point to a Lisp
|
||||
object. TYPE is the rough type of Lisp object to which *PTR
|
||||
points. */
|
||||
INLINE
|
||||
void
|
||||
pdumper_remember_lv_ptr_raw (void* ptr, enum Lisp_Type type)
|
||||
{
|
||||
#ifdef HAVE_PDUMPER
|
||||
pdumper_remember_lv_ptr_raw_impl (ptr, type);
|
||||
#else
|
||||
(void) ptr;
|
||||
(void) type;
|
||||
#endif
|
||||
}
|
||||
|
||||
typedef void (*pdumper_hook)(void);
|
||||
extern void pdumper_do_now_and_after_load_impl (pdumper_hook hook);
|
||||
|
||||
INLINE void
|
||||
pdumper_do_now_and_after_load (pdumper_hook hook)
|
||||
{
|
||||
#ifdef HAVE_PDUMPER
|
||||
pdumper_do_now_and_after_load_impl (hook);
|
||||
#else
|
||||
hook ();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Macros useful in pdumper callback functions. Assign a value if
|
||||
we're loading a dump and the value needs to be reset to its
|
||||
original value, and if we're initializing for the first time,
|
||||
assert that the value has the expected original value. */
|
||||
|
||||
#define PDUMPER_RESET(variable, value) \
|
||||
do { \
|
||||
if (dumped_with_pdumper_p ()) \
|
||||
(variable) = (value); \
|
||||
else \
|
||||
eassert ((variable) == (value)); \
|
||||
} while (0)
|
||||
|
||||
#define PDUMPER_RESET_LV(variable, value) \
|
||||
do { \
|
||||
if (dumped_with_pdumper_p ()) \
|
||||
(variable) = (value); \
|
||||
else \
|
||||
eassert (EQ ((variable), (value))); \
|
||||
} while (0)
|
||||
|
||||
/* Actually load a dump. */
|
||||
|
||||
enum pdumper_load_result
|
||||
{
|
||||
PDUMPER_LOAD_SUCCESS,
|
||||
PDUMPER_NOT_LOADED /* Not returned: useful for callers */,
|
||||
PDUMPER_LOAD_FILE_NOT_FOUND,
|
||||
PDUMPER_LOAD_BAD_FILE_TYPE,
|
||||
PDUMPER_LOAD_FAILED_DUMP,
|
||||
PDUMPER_LOAD_OOM,
|
||||
PDUMPER_LOAD_VERSION_MISMATCH,
|
||||
PDUMPER_LOAD_ERROR,
|
||||
};
|
||||
|
||||
enum pdumper_load_result pdumper_load (const char *dump_filename);
|
||||
|
||||
struct pdumper_loaded_dump {
|
||||
uintptr_t start;
|
||||
uintptr_t end;
|
||||
};
|
||||
|
||||
#ifdef HAVE_PDUMPER
|
||||
extern struct pdumper_loaded_dump dump_public;
|
||||
#endif
|
||||
|
||||
/* Return whether the OBJ points somewhere into the loaded dump image.
|
||||
Works even when we have no dump loaded --- in this case, it just
|
||||
returns false. */
|
||||
INLINE _GL_ATTRIBUTE_CONST
|
||||
bool
|
||||
pdumper_object_p (const void *obj)
|
||||
{
|
||||
#ifdef HAVE_PDUMPER
|
||||
uintptr_t obj_addr = (uintptr_t) obj;
|
||||
return dump_public.start <= obj_addr && obj_addr < dump_public.end;
|
||||
#else
|
||||
(void) obj;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
extern bool pdumper_cold_object_p_impl (const void *obj);
|
||||
|
||||
/* Return whether the OBJ is in the cold section of the dump.
|
||||
Only bool-vectors and floats should end up there.
|
||||
pdumper_object_p() and pdumper_object_p_precise() must have
|
||||
returned true for OBJ before calling this function. */
|
||||
INLINE _GL_ATTRIBUTE_CONST
|
||||
bool
|
||||
pdumper_cold_object_p (const void *obj)
|
||||
{
|
||||
#ifdef HAVE_PDUMPER
|
||||
return pdumper_cold_object_p_impl (obj);
|
||||
#else
|
||||
(void) obj;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
extern enum Lisp_Type pdumper_find_object_type_impl (const void *obj);
|
||||
|
||||
/* Return the type of the dumped object that starts at OBJ. It is a
|
||||
programming error to call this routine for an OBJ for which
|
||||
pdumper_object_p would return false. */
|
||||
INLINE _GL_ATTRIBUTE_CONST
|
||||
enum Lisp_Type
|
||||
pdumper_find_object_type (const void *obj)
|
||||
{
|
||||
#ifdef HAVE_PDUMPER
|
||||
return pdumper_find_object_type_impl (obj);
|
||||
#else
|
||||
(void) obj;
|
||||
emacs_abort ();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return whether OBJ points exactly to the start of some object in
|
||||
the loaded dump image. It is a programming error to call this
|
||||
routine for an OBJ for which pdumper_object_p would return
|
||||
false. */
|
||||
INLINE _GL_ATTRIBUTE_CONST
|
||||
bool
|
||||
pdumper_object_p_precise (const void *obj)
|
||||
{
|
||||
#ifdef HAVE_PDUMPER
|
||||
return pdumper_find_object_type (obj) != PDUMPER_NO_OBJECT;
|
||||
#else
|
||||
(void) obj;
|
||||
emacs_abort ();
|
||||
#endif
|
||||
}
|
||||
|
||||
extern bool pdumper_marked_p_impl (const void *obj);
|
||||
|
||||
/* Return whether OBJ is marked according to the portable dumper.
|
||||
It is an error to call this routine for an OBJ for which
|
||||
pdumper_object_p_precise would return false. */
|
||||
INLINE
|
||||
bool
|
||||
pdumper_marked_p (const void *obj)
|
||||
{
|
||||
#ifdef HAVE_PDUMPER
|
||||
return pdumper_marked_p_impl (obj);
|
||||
#else
|
||||
(void) obj;
|
||||
emacs_abort ();
|
||||
#endif
|
||||
}
|
||||
|
||||
extern void pdumper_set_marked_impl (const void *obj);
|
||||
|
||||
/* Set the pdumper mark bit for OBJ. It is a programming error to
|
||||
call this function with an OBJ for which pdumper_object_p_precise
|
||||
would return false. */
|
||||
INLINE
|
||||
void
|
||||
pdumper_set_marked (const void *obj)
|
||||
{
|
||||
#ifdef HAVE_PDUMPER
|
||||
pdumper_set_marked_impl (obj);
|
||||
#else
|
||||
(void) obj;
|
||||
emacs_abort ();
|
||||
#endif
|
||||
}
|
||||
|
||||
extern void pdumper_clear_marks_impl (void);
|
||||
|
||||
/* Clear all the mark bits for pdumper objects. */
|
||||
INLINE
|
||||
void
|
||||
pdumper_clear_marks (void)
|
||||
{
|
||||
#ifdef HAVE_PDUMPER
|
||||
pdumper_clear_marks_impl ();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Handle a page fault that occurs when we access the portable dumper
|
||||
mapping. Return true iff the fault should be considered handled
|
||||
and execution should resume. */
|
||||
bool pdumper_handle_page_fault (void *fault_addr_ptr);
|
||||
|
||||
void syms_of_pdumper (void);
|
||||
|
||||
INLINE_HEADER_END
|
||||
#endif
|
|
@ -8028,9 +8028,7 @@ init_process_emacs (int sockfd)
|
|||
|
||||
inhibit_sentinels = 0;
|
||||
|
||||
#ifndef CANNOT_DUMP
|
||||
if (! noninteractive || initialized)
|
||||
#endif
|
||||
if (!will_dump_with_unexec_p ())
|
||||
{
|
||||
#if defined HAVE_GLIB && !defined WINDOWSNT
|
||||
/* Tickle glib's child-handling code. Ask glib to wait for Emacs itself;
|
||||
|
|
|
@ -21,6 +21,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "lisp.h"
|
||||
#include "syssignal.h"
|
||||
#include "systime.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
/* Return A + B, but return the maximum fixnum if the result would overflow.
|
||||
Assume A and B are nonnegative and in fixnum range. */
|
||||
|
@ -570,6 +571,8 @@ hashfn_profiler (struct hash_table_test *ht, Lisp_Object bt)
|
|||
return XHASH (bt);
|
||||
}
|
||||
|
||||
static void syms_of_profiler_for_pdumper (void);
|
||||
|
||||
void
|
||||
syms_of_profiler (void)
|
||||
{
|
||||
|
@ -608,4 +611,22 @@ to make room for new entries. */);
|
|||
defsubr (&Sprofiler_memory_stop);
|
||||
defsubr (&Sprofiler_memory_running_p);
|
||||
defsubr (&Sprofiler_memory_log);
|
||||
|
||||
pdumper_do_now_and_after_load (syms_of_profiler_for_pdumper);
|
||||
}
|
||||
|
||||
static void
|
||||
syms_of_profiler_for_pdumper (void)
|
||||
{
|
||||
if (dumped_with_pdumper_p ())
|
||||
{
|
||||
cpu_log = Qnil;
|
||||
memory_log = Qnil;
|
||||
}
|
||||
else
|
||||
{
|
||||
eassert (NILP (cpu_log));
|
||||
eassert (NILP (memory_log));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
35
src/search.c
35
src/search.c
|
@ -29,6 +29,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "region-cache.h"
|
||||
#include "blockinput.h"
|
||||
#include "intervals.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
#include "regex-emacs.h"
|
||||
|
||||
|
@ -3386,26 +3387,17 @@ the buffer. If the buffer doesn't have a cache, the value is nil. */)
|
|||
}
|
||||
|
||||
|
||||
static void syms_of_search_for_pdumper (void);
|
||||
|
||||
void
|
||||
syms_of_search (void)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < REGEXP_CACHE_SIZE; ++i)
|
||||
for (int i = 0; i < REGEXP_CACHE_SIZE; ++i)
|
||||
{
|
||||
searchbufs[i].buf.allocated = 100;
|
||||
searchbufs[i].buf.buffer = xmalloc (100);
|
||||
searchbufs[i].buf.fastmap = searchbufs[i].fastmap;
|
||||
searchbufs[i].regexp = Qnil;
|
||||
searchbufs[i].f_whitespace_regexp = Qnil;
|
||||
searchbufs[i].busy = false;
|
||||
searchbufs[i].syntax_table = Qnil;
|
||||
staticpro (&searchbufs[i].regexp);
|
||||
staticpro (&searchbufs[i].f_whitespace_regexp);
|
||||
staticpro (&searchbufs[i].syntax_table);
|
||||
searchbufs[i].next = (i == REGEXP_CACHE_SIZE-1 ? 0 : &searchbufs[i+1]);
|
||||
}
|
||||
searchbuf_head = &searchbufs[0];
|
||||
|
||||
/* Error condition used for failing searches. */
|
||||
DEFSYM (Qsearch_failed, "search-failed");
|
||||
|
@ -3476,4 +3468,23 @@ is to bind it with `let' around a small expression. */);
|
|||
defsubr (&Sset_match_data);
|
||||
defsubr (&Sregexp_quote);
|
||||
defsubr (&Snewline_cache_check);
|
||||
|
||||
pdumper_do_now_and_after_load (syms_of_search_for_pdumper);
|
||||
}
|
||||
|
||||
static void
|
||||
syms_of_search_for_pdumper (void)
|
||||
{
|
||||
for (int i = 0; i < REGEXP_CACHE_SIZE; ++i)
|
||||
{
|
||||
searchbufs[i].buf.allocated = 100;
|
||||
searchbufs[i].buf.buffer = xmalloc (100);
|
||||
searchbufs[i].buf.fastmap = searchbufs[i].fastmap;
|
||||
searchbufs[i].regexp = Qnil;
|
||||
searchbufs[i].f_whitespace_regexp = Qnil;
|
||||
searchbufs[i].busy = false;
|
||||
searchbufs[i].syntax_table = Qnil;
|
||||
searchbufs[i].next = (i == REGEXP_CACHE_SIZE-1 ? 0 : &searchbufs[i+1]);
|
||||
}
|
||||
searchbuf_head = &searchbufs[0];
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@ static int debug_sheap;
|
|||
|
||||
char bss_sbrk_buffer[STATIC_HEAP_SIZE];
|
||||
char *max_bss_sbrk_ptr;
|
||||
bool bss_sbrk_did_unexec;
|
||||
|
||||
void *
|
||||
bss_sbrk (ptrdiff_t request_size)
|
||||
|
|
|
@ -27,5 +27,4 @@ enum { STATIC_HEAP_SIZE = sizeof (Lisp_Object) << 22 };
|
|||
|
||||
extern char bss_sbrk_buffer[STATIC_HEAP_SIZE];
|
||||
extern char *max_bss_sbrk_ptr;
|
||||
extern bool bss_sbrk_did_unexec;
|
||||
extern void *bss_sbrk (ptrdiff_t);
|
||||
|
|
|
@ -3730,9 +3730,6 @@ syms_of_syntax (void)
|
|||
staticpro (&gl_state.current_syntax_table);
|
||||
staticpro (&gl_state.old_prop);
|
||||
|
||||
/* Defined in regex-emacs.c. */
|
||||
staticpro (&re_match_object);
|
||||
|
||||
DEFSYM (Qscan_error, "scan-error");
|
||||
Fput (Qscan_error, Qerror_conditions,
|
||||
listn (CONSTYPE_PURE, 2, Qscan_error, Qerror));
|
||||
|
|
15
src/sysdep.c
15
src/sysdep.c
|
@ -270,7 +270,7 @@ get_current_dir_name_or_unreachable (void)
|
|||
|
||||
# if HAVE_GET_CURRENT_DIR_NAME && !BROKEN_GET_CURRENT_DIR_NAME
|
||||
# ifdef HYBRID_MALLOC
|
||||
bool use_libc = bss_sbrk_did_unexec;
|
||||
bool use_libc = will_dump_with_unexec_p ();
|
||||
# else
|
||||
bool use_libc = true;
|
||||
# endif
|
||||
|
@ -1893,7 +1893,7 @@ handle_sigsegv (int sig, siginfo_t *siginfo, void *arg)
|
|||
/* Return true if we have successfully set up SIGSEGV handler on alternate
|
||||
stack. Otherwise we just treat SIGSEGV among the rest of fatal signals. */
|
||||
|
||||
static bool
|
||||
bool
|
||||
init_sigsegv (void)
|
||||
{
|
||||
struct sigaction sa;
|
||||
|
@ -1908,12 +1908,15 @@ init_sigsegv (void)
|
|||
sigfillset (&sa.sa_mask);
|
||||
sa.sa_sigaction = handle_sigsegv;
|
||||
sa.sa_flags = SA_SIGINFO | SA_ONSTACK | emacs_sigaction_flags ();
|
||||
return sigaction (SIGSEGV, &sa, NULL) < 0 ? 0 : 1;
|
||||
if (sigaction (SIGSEGV, &sa, NULL) < 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else /* not HAVE_STACK_OVERFLOW_HANDLING or WINDOWSNT */
|
||||
|
||||
static bool
|
||||
bool
|
||||
init_sigsegv (void)
|
||||
{
|
||||
return 0;
|
||||
|
@ -1963,7 +1966,7 @@ maybe_fatal_sig (int sig)
|
|||
}
|
||||
|
||||
void
|
||||
init_signals (bool dumping)
|
||||
init_signals (void)
|
||||
{
|
||||
struct sigaction thread_fatal_action;
|
||||
struct sigaction action;
|
||||
|
@ -2114,7 +2117,7 @@ init_signals (bool dumping)
|
|||
/* Don't alter signal handlers if dumping. On some machines,
|
||||
changing signal handlers sets static data that would make signals
|
||||
fail to work right when the dumped Emacs is run. */
|
||||
if (dumping)
|
||||
if (will_dump_p ())
|
||||
return;
|
||||
|
||||
sigfillset (&process_fatal_action.sa_mask);
|
||||
|
|
|
@ -22,7 +22,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
|
||||
#include <signal.h>
|
||||
|
||||
extern void init_signals (bool);
|
||||
extern void init_signals (void);
|
||||
extern bool init_sigsegv (void);
|
||||
extern void block_child_signal (sigset_t *);
|
||||
extern void unblock_child_signal (sigset_t const *);
|
||||
extern void block_interrupt_signal (sigset_t *);
|
||||
|
|
|
@ -93,7 +93,7 @@ extern bool list4_to_timespec (Lisp_Object, Lisp_Object, Lisp_Object,
|
|||
Lisp_Object, struct timespec *);
|
||||
extern struct timespec lisp_time_argument (Lisp_Object);
|
||||
extern _Noreturn void time_overflow (void);
|
||||
extern void init_timefns (bool);
|
||||
extern void init_timefns (void);
|
||||
extern void syms_of_timefns (void);
|
||||
|
||||
INLINE_HEADER_END
|
||||
|
|
|
@ -2319,11 +2319,10 @@ inherits it if NONSTICKINESS is nil. The `front-sticky' and
|
|||
Vtext_property_default_nonsticky
|
||||
= list2 (Fcons (Qsyntax_table, Qt), Fcons (Qdisplay, Qt));
|
||||
|
||||
staticpro (&interval_insert_behind_hooks);
|
||||
staticpro (&interval_insert_in_front_hooks);
|
||||
interval_insert_behind_hooks = Qnil;
|
||||
interval_insert_in_front_hooks = Qnil;
|
||||
|
||||
staticpro (&interval_insert_behind_hooks);
|
||||
staticpro (&interval_insert_in_front_hooks);
|
||||
|
||||
/* Common attributes one might give text. */
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "process.h"
|
||||
#include "coding.h"
|
||||
#include "syssignal.h"
|
||||
#include "pdumper.h"
|
||||
#include "keyboard.h"
|
||||
|
||||
union aligned_thread_state
|
||||
|
@ -1064,7 +1065,7 @@ init_main_thread (void)
|
|||
}
|
||||
|
||||
bool
|
||||
main_thread_p (void *ptr)
|
||||
main_thread_p (const void *ptr)
|
||||
{
|
||||
return ptr == &main_thread.s;
|
||||
}
|
||||
|
|
|
@ -295,7 +295,7 @@ extern void maybe_reacquire_global_lock (void);
|
|||
extern void init_threads_once (void);
|
||||
extern void init_threads (void);
|
||||
extern void syms_of_threads (void);
|
||||
extern bool main_thread_p (void *);
|
||||
extern bool main_thread_p (const void *);
|
||||
extern bool in_current_thread (void);
|
||||
|
||||
typedef int select_func (int, fd_set *, fd_set *, fd_set *,
|
||||
|
|
|
@ -25,6 +25,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "bignum.h"
|
||||
#include "coding.h"
|
||||
#include "lisp.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
#include <strftime.h>
|
||||
|
||||
|
@ -291,7 +292,7 @@ tzlookup (Lisp_Object zone, bool settz)
|
|||
}
|
||||
|
||||
void
|
||||
init_timefns (bool dumping)
|
||||
init_timefns (void)
|
||||
{
|
||||
#ifndef CANNOT_DUMP
|
||||
/* A valid but unlikely setting for the TZ environment variable.
|
||||
|
@ -300,7 +301,7 @@ init_timefns (bool dumping)
|
|||
|
||||
/* When just dumping out, set the time zone to a known unlikely value
|
||||
and skip the rest of this function. */
|
||||
if (dumping)
|
||||
if (will_dump_with_unexec_p ())
|
||||
{
|
||||
xputenv (dump_tz_string);
|
||||
tzset ();
|
||||
|
@ -1729,6 +1730,19 @@ emacs_setenv_TZ (const char *tzstring)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if (ULONG_MAX < TRILLION || !FASTER_TIMEFNS) && !defined ztrillion
|
||||
# define NEED_ZTRILLION_INIT 1
|
||||
#endif
|
||||
|
||||
#ifdef NEED_ZTRILLION_INIT
|
||||
static void
|
||||
syms_of_timefns_for_pdumper (void)
|
||||
{
|
||||
mpz_init_set_ui (ztrillion, 1000000);
|
||||
mpz_mul_ui (ztrillion, ztrillion, 1000000);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
syms_of_timefns (void)
|
||||
{
|
||||
|
@ -1740,10 +1754,6 @@ syms_of_timefns (void)
|
|||
trillion = make_int (1000000000000);
|
||||
staticpro (&trillion);
|
||||
#endif
|
||||
#if (ULONG_MAX < TRILLION || !FASTER_TIMEFNS) && !defined ztrillion
|
||||
mpz_init_set_ui (ztrillion, 1000000);
|
||||
mpz_mul_ui (ztrillion, ztrillion, 1000000);
|
||||
#endif
|
||||
|
||||
DEFSYM (Qencode_time, "encode-time");
|
||||
|
||||
|
@ -1759,4 +1769,7 @@ syms_of_timefns (void)
|
|||
defsubr (&Scurrent_time_string);
|
||||
defsubr (&Scurrent_time_zone);
|
||||
defsubr (&Sset_time_zone_rule);
|
||||
#ifdef NEED_ZTRILLION_INIT
|
||||
pdumper_do_now_and_after_load (syms_of_timefns_for_pdumper);
|
||||
#endif
|
||||
}
|
||||
|
|
116
src/unexw32.c
116
src/unexw32.c
|
@ -39,8 +39,6 @@ PIMAGE_NT_HEADERS (__stdcall * pfnCheckSumMappedFile) (LPVOID BaseAddress,
|
|||
LPDWORD HeaderSum,
|
||||
LPDWORD CheckSum);
|
||||
|
||||
extern BOOL ctrl_c_handler (unsigned long type);
|
||||
|
||||
extern char my_begdata[];
|
||||
extern char my_begbss[];
|
||||
extern char *my_begbss_static;
|
||||
|
@ -70,84 +68,10 @@ PCHAR bss_start_static = 0;
|
|||
DWORD_PTR bss_size_static = 0;
|
||||
DWORD_PTR extra_bss_size_static = 0;
|
||||
|
||||
/* MinGW64 doesn't add a leading underscore to external symbols,
|
||||
whereas configure.ac sets up LD_SWITCH_SYSTEM_TEMACS to force the
|
||||
entry point at __start, with two underscores. */
|
||||
#ifdef __MINGW64__
|
||||
#define _start __start
|
||||
#endif
|
||||
|
||||
extern void mainCRTStartup (void);
|
||||
|
||||
/* Startup code for running on NT. When we are running as the dumped
|
||||
version, we need to bootstrap our heap and .bss section into our
|
||||
address space before we can actually hand off control to the startup
|
||||
code supplied by NT (primarily because that code relies upon malloc ()). */
|
||||
void _start (void);
|
||||
|
||||
void
|
||||
_start (void)
|
||||
{
|
||||
|
||||
#if 1
|
||||
/* Give us a way to debug problems with crashes on startup when
|
||||
running under the MSVC profiler. */
|
||||
if (GetEnvironmentVariable ("EMACS_DEBUG", NULL, 0) > 0)
|
||||
DebugBreak ();
|
||||
#endif
|
||||
|
||||
/* Cache system info, e.g., the NT page size. */
|
||||
cache_system_info ();
|
||||
|
||||
/* Grab our malloc arena space now, before CRT starts up. */
|
||||
init_heap ();
|
||||
|
||||
/* This prevents ctrl-c's in shells running while we're suspended from
|
||||
having us exit. */
|
||||
SetConsoleCtrlHandler ((PHANDLER_ROUTINE) ctrl_c_handler, TRUE);
|
||||
|
||||
/* Prevent Emacs from being locked up (eg. in batch mode) when
|
||||
accessing devices that aren't mounted (eg. removable media drives). */
|
||||
SetErrorMode (SEM_FAILCRITICALERRORS);
|
||||
mainCRTStartup ();
|
||||
}
|
||||
|
||||
|
||||
/* File handling. */
|
||||
|
||||
/* Implementation note: this and the next functions work with ANSI
|
||||
codepage encoded file names! */
|
||||
int
|
||||
open_input_file (file_data *p_file, char *filename)
|
||||
{
|
||||
HANDLE file;
|
||||
HANDLE file_mapping;
|
||||
void *file_base;
|
||||
unsigned long size, upper_size;
|
||||
|
||||
file = CreateFileA (filename, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if (file == INVALID_HANDLE_VALUE)
|
||||
return FALSE;
|
||||
|
||||
size = GetFileSize (file, &upper_size);
|
||||
file_mapping = CreateFileMapping (file, NULL, PAGE_READONLY,
|
||||
0, size, NULL);
|
||||
if (!file_mapping)
|
||||
return FALSE;
|
||||
|
||||
file_base = MapViewOfFile (file_mapping, FILE_MAP_READ, 0, 0, size);
|
||||
if (file_base == 0)
|
||||
return FALSE;
|
||||
|
||||
p_file->name = filename;
|
||||
p_file->size = size;
|
||||
p_file->file = file;
|
||||
p_file->file_mapping = file_mapping;
|
||||
p_file->file_base = file_base;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
open_output_file (file_data *p_file, char *filename, unsigned long size)
|
||||
|
@ -187,18 +111,6 @@ open_output_file (file_data *p_file, char *filename, unsigned long size)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* Close the system structures associated with the given file. */
|
||||
void
|
||||
close_file_data (file_data *p_file)
|
||||
{
|
||||
UnmapViewOfFile (p_file->file_base);
|
||||
CloseHandle (p_file->file_mapping);
|
||||
/* For the case of output files, set final size. */
|
||||
SetFilePointer (p_file->file, p_file->size, NULL, FILE_BEGIN);
|
||||
SetEndOfFile (p_file->file);
|
||||
CloseHandle (p_file->file);
|
||||
}
|
||||
|
||||
|
||||
/* Routines to manipulate NT executable file sections. */
|
||||
|
||||
|
@ -220,34 +132,6 @@ find_section (const char * name, IMAGE_NT_HEADERS * nt_header)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Return pointer to section header for section containing the given
|
||||
relative virtual address. */
|
||||
IMAGE_SECTION_HEADER *
|
||||
rva_to_section (DWORD_PTR rva, IMAGE_NT_HEADERS * nt_header)
|
||||
{
|
||||
PIMAGE_SECTION_HEADER section;
|
||||
int i;
|
||||
|
||||
section = IMAGE_FIRST_SECTION (nt_header);
|
||||
|
||||
for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++)
|
||||
{
|
||||
/* Some linkers (eg. the NT SDK linker I believe) swapped the
|
||||
meaning of these two values - or rather, they ignored
|
||||
VirtualSize entirely and always set it to zero. This affects
|
||||
some very old exes (eg. gzip dated Dec 1993). Since
|
||||
w32_executable_type relies on this function to work reliably,
|
||||
we need to cope with this. */
|
||||
DWORD_PTR real_size = max (section->SizeOfRawData,
|
||||
section->Misc.VirtualSize);
|
||||
if (rva >= section->VirtualAddress
|
||||
&& rva < section->VirtualAddress + real_size)
|
||||
return section;
|
||||
section++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if 0 /* unused */
|
||||
/* Return pointer to section header for section containing the given
|
||||
offset in its raw data area. */
|
||||
|
|
34
src/w32.c
34
src/w32.c
|
@ -9926,6 +9926,40 @@ maybe_load_unicows_dll (void)
|
|||
}
|
||||
}
|
||||
|
||||
/* Relocate a directory specified by epaths.h, using the location of
|
||||
our binary as an anchor. Note: this runs early during startup, so
|
||||
we cannot rely on the usual file-related facilities, and in
|
||||
particular the argument is assumed to be a unibyte string in system
|
||||
codepage encoding. */
|
||||
const char *
|
||||
w32_relocate (const char *epath_dir)
|
||||
{
|
||||
if (strncmp (epath_dir, "%emacs_dir%/", 12) == 0)
|
||||
{
|
||||
static char relocated_dir[MAX_PATH];
|
||||
|
||||
/* Replace "%emacs_dir%" with the parent of the directory where
|
||||
our binary lives. Note that init_environment was not yet
|
||||
called, so we cannot rely on emacs_dir being set in the
|
||||
environment. */
|
||||
if (GetModuleFileNameA (NULL, relocated_dir, MAX_PATH))
|
||||
{
|
||||
char *p = _mbsrchr (relocated_dir, '\\');
|
||||
|
||||
if (p)
|
||||
{
|
||||
*p = '\0';
|
||||
if ((p = _mbsrchr (relocated_dir, '\\')) != NULL)
|
||||
{
|
||||
strcpy (p, epath_dir + 11);
|
||||
epath_dir = relocated_dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return epath_dir;
|
||||
}
|
||||
|
||||
/*
|
||||
globals_of_w32 is used to initialize those global variables that
|
||||
must always be initialized on startup even when the global variable
|
||||
|
|
|
@ -185,6 +185,8 @@ extern MultiByteToWideChar_Proc pMultiByteToWideChar;
|
|||
extern WideCharToMultiByte_Proc pWideCharToMultiByte;
|
||||
extern DWORD multiByteToWideCharFlags;
|
||||
|
||||
extern const char *w32_relocate (const char *);
|
||||
|
||||
extern void init_environment (char **);
|
||||
extern void check_windows_init_file (void);
|
||||
extern void syms_of_ntproc (void);
|
||||
|
|
|
@ -56,6 +56,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "w32.h"
|
||||
#endif
|
||||
|
||||
#include "pdumper.h"
|
||||
|
||||
#include <basetyps.h>
|
||||
#include <unknwn.h>
|
||||
#include <commctrl.h>
|
||||
|
@ -10209,6 +10211,7 @@ syms_of_w32fns (void)
|
|||
track_mouse_window = NULL;
|
||||
|
||||
w32_visible_system_caret_hwnd = NULL;
|
||||
PDUMPER_IGNORE (w32_visible_system_caret_hwnd);
|
||||
|
||||
DEFSYM (Qundefined_color, "undefined-color");
|
||||
DEFSYM (Qcancel_timer, "cancel-timer");
|
||||
|
|
|
@ -33,6 +33,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "w32.h"
|
||||
#endif
|
||||
|
||||
#include "pdumper.h"
|
||||
|
||||
/* Cleartype available on Windows XP, cleartype_natural from XP SP1.
|
||||
The latter does not try to fit cleartype smoothed fonts into the
|
||||
same bounding box as the non-antialiased version of the font.
|
||||
|
@ -2624,6 +2626,9 @@ struct font_driver w32font_driver =
|
|||
|
||||
/* Initialize state that does not change between invocations. This is only
|
||||
called when Emacs is dumped. */
|
||||
|
||||
static void syms_of_w32font_for_pdumper (void);
|
||||
|
||||
void
|
||||
syms_of_w32font (void)
|
||||
{
|
||||
|
@ -2803,6 +2808,12 @@ versions of Windows) characters. */);
|
|||
|
||||
defsubr (&Sx_select_font);
|
||||
|
||||
pdumper_do_now_and_after_load (syms_of_w32font_for_pdumper);
|
||||
}
|
||||
|
||||
static void
|
||||
syms_of_w32font_for_pdumper (void)
|
||||
{
|
||||
register_font_driver (&w32font_driver, NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -223,9 +223,16 @@ typedef enum _HEAP_INFORMATION_CLASS {
|
|||
typedef WINBASEAPI BOOL (WINAPI * HeapSetInformation_Proc)(HANDLE,HEAP_INFORMATION_CLASS,PVOID,SIZE_T);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PDUMPER
|
||||
BOOL using_dynamic_heap = FALSE;
|
||||
#endif
|
||||
|
||||
void
|
||||
init_heap (void)
|
||||
{
|
||||
#ifdef HAVE_PDUMPER
|
||||
using_dynamic_heap = TRUE;
|
||||
#endif
|
||||
if (using_dynamic_heap)
|
||||
{
|
||||
#ifndef MINGW_W64
|
||||
|
|
|
@ -30,6 +30,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "buffer.h"
|
||||
#include "coding.h" /* for ENCODE_SYSTEM */
|
||||
#include "menu.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
/* This may include sys/types.h, and that somehow loses
|
||||
if this is not done before the other system files. */
|
||||
|
@ -1586,6 +1587,7 @@ syms_of_w32menu (void)
|
|||
globals_of_w32menu ();
|
||||
|
||||
current_popup_menu = NULL;
|
||||
PDUMPER_IGNORE (current_popup_menu);
|
||||
|
||||
DEFSYM (Qdebug_on_next_call, "debug-on-next-call");
|
||||
DEFSYM (Qunsupported__w32_dialog, "unsupported--w32-dialog");
|
||||
|
|
117
src/w32proc.c
117
src/w32proc.c
|
@ -81,6 +81,51 @@ static sigset_t sig_mask;
|
|||
|
||||
static CRITICAL_SECTION crit_sig;
|
||||
|
||||
|
||||
extern BOOL ctrl_c_handler (unsigned long type);
|
||||
|
||||
/* MinGW64 doesn't add a leading underscore to external symbols,
|
||||
whereas configure.ac sets up LD_SWITCH_SYSTEM_TEMACS to force the
|
||||
entry point at __start, with two underscores. */
|
||||
#ifdef __MINGW64__
|
||||
#define _start __start
|
||||
#endif
|
||||
|
||||
extern void mainCRTStartup (void);
|
||||
|
||||
/* Startup code for running on NT. When we are running as the dumped
|
||||
version, we need to bootstrap our heap and .bss section into our
|
||||
address space before we can actually hand off control to the startup
|
||||
code supplied by NT (primarily because that code relies upon malloc ()). */
|
||||
void _start (void);
|
||||
|
||||
void
|
||||
_start (void)
|
||||
{
|
||||
|
||||
#if 1
|
||||
/* Give us a way to debug problems with crashes on startup when
|
||||
running under the MSVC profiler. */
|
||||
if (GetEnvironmentVariable ("EMACS_DEBUG", NULL, 0) > 0)
|
||||
DebugBreak ();
|
||||
#endif
|
||||
|
||||
/* Cache system info, e.g., the NT page size. */
|
||||
cache_system_info ();
|
||||
|
||||
/* Grab our malloc arena space now, before CRT starts up. */
|
||||
init_heap ();
|
||||
|
||||
/* This prevents ctrl-c's in shells running while we're suspended from
|
||||
having us exit. */
|
||||
SetConsoleCtrlHandler ((PHANDLER_ROUTINE) ctrl_c_handler, TRUE);
|
||||
|
||||
/* Prevent Emacs from being locked up (eg. in batch mode) when
|
||||
accessing devices that aren't mounted (eg. removable media drives). */
|
||||
SetErrorMode (SEM_FAILCRITICALERRORS);
|
||||
mainCRTStartup ();
|
||||
}
|
||||
|
||||
/* Improve on the CRT 'signal' implementation so that we could record
|
||||
the SIGCHLD handler and fake interval timers. */
|
||||
signal_handler
|
||||
|
@ -1528,6 +1573,78 @@ waitpid (pid_t pid, int *status, int options)
|
|||
return pid;
|
||||
}
|
||||
|
||||
int
|
||||
open_input_file (file_data *p_file, char *filename)
|
||||
{
|
||||
HANDLE file;
|
||||
HANDLE file_mapping;
|
||||
void *file_base;
|
||||
unsigned long size, upper_size;
|
||||
|
||||
file = CreateFileA (filename, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if (file == INVALID_HANDLE_VALUE)
|
||||
return FALSE;
|
||||
|
||||
size = GetFileSize (file, &upper_size);
|
||||
file_mapping = CreateFileMapping (file, NULL, PAGE_READONLY,
|
||||
0, size, NULL);
|
||||
if (!file_mapping)
|
||||
return FALSE;
|
||||
|
||||
file_base = MapViewOfFile (file_mapping, FILE_MAP_READ, 0, 0, size);
|
||||
if (file_base == 0)
|
||||
return FALSE;
|
||||
|
||||
p_file->name = filename;
|
||||
p_file->size = size;
|
||||
p_file->file = file;
|
||||
p_file->file_mapping = file_mapping;
|
||||
p_file->file_base = file_base;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Return pointer to section header for section containing the given
|
||||
relative virtual address. */
|
||||
IMAGE_SECTION_HEADER *
|
||||
rva_to_section (DWORD_PTR rva, IMAGE_NT_HEADERS * nt_header)
|
||||
{
|
||||
PIMAGE_SECTION_HEADER section;
|
||||
int i;
|
||||
|
||||
section = IMAGE_FIRST_SECTION (nt_header);
|
||||
|
||||
for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++)
|
||||
{
|
||||
/* Some linkers (eg. the NT SDK linker I believe) swapped the
|
||||
meaning of these two values - or rather, they ignored
|
||||
VirtualSize entirely and always set it to zero. This affects
|
||||
some very old exes (eg. gzip dated Dec 1993). Since
|
||||
w32_executable_type relies on this function to work reliably,
|
||||
we need to cope with this. */
|
||||
DWORD_PTR real_size = max (section->SizeOfRawData,
|
||||
section->Misc.VirtualSize);
|
||||
if (rva >= section->VirtualAddress
|
||||
&& rva < section->VirtualAddress + real_size)
|
||||
return section;
|
||||
section++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Close the system structures associated with the given file. */
|
||||
void
|
||||
close_file_data (file_data *p_file)
|
||||
{
|
||||
UnmapViewOfFile (p_file->file_base);
|
||||
CloseHandle (p_file->file_mapping);
|
||||
/* For the case of output files, set final size. */
|
||||
SetFilePointer (p_file->file, p_file->size, NULL, FILE_BEGIN);
|
||||
SetEndOfFile (p_file->file);
|
||||
CloseHandle (p_file->file);
|
||||
}
|
||||
|
||||
/* Old versions of w32api headers don't have separate 32-bit and
|
||||
64-bit defines, but the one they have matches the 32-bit variety. */
|
||||
#ifndef IMAGE_NT_OPTIONAL_HDR32_MAGIC
|
||||
|
|
|
@ -36,6 +36,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "composite.h"
|
||||
#include "font.h"
|
||||
#include "w32font.h"
|
||||
#include "pdumper.h"
|
||||
#include "w32common.h"
|
||||
|
||||
struct uniscribe_font_info
|
||||
|
@ -1176,8 +1177,16 @@ struct font_driver uniscribe_font_driver =
|
|||
as it needs to test for the existence of the Uniscribe library. */
|
||||
void syms_of_w32uniscribe (void);
|
||||
|
||||
static void syms_of_w32uniscribe_for_pdumper (void);
|
||||
|
||||
void
|
||||
syms_of_w32uniscribe (void)
|
||||
{
|
||||
pdumper_do_now_and_after_load (syms_of_w32uniscribe_for_pdumper);
|
||||
}
|
||||
|
||||
static void
|
||||
syms_of_w32uniscribe_for_pdumper (void)
|
||||
{
|
||||
HMODULE uniscribe;
|
||||
|
||||
|
|
60
src/window.c
60
src/window.c
|
@ -42,6 +42,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#ifdef MSDOS
|
||||
#include "msdos.h"
|
||||
#endif
|
||||
#include "pdumper.h"
|
||||
|
||||
static ptrdiff_t count_windows (struct window *);
|
||||
static ptrdiff_t get_leaf_windows (struct window *, struct window **,
|
||||
|
@ -7876,10 +7877,59 @@ and scrolling positions. */)
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
|
||||
static void init_window_once_for_pdumper (void);
|
||||
|
||||
void
|
||||
init_window_once (void)
|
||||
{
|
||||
minibuf_window = Qnil;
|
||||
staticpro (&minibuf_window);
|
||||
|
||||
selected_window = Qnil;
|
||||
staticpro (&selected_window);
|
||||
|
||||
Vwindow_list = Qnil;
|
||||
staticpro (&Vwindow_list);
|
||||
|
||||
minibuf_selected_window = Qnil;
|
||||
staticpro (&minibuf_selected_window);
|
||||
|
||||
pdumper_do_now_and_after_load (init_window_once_for_pdumper);
|
||||
}
|
||||
|
||||
static void init_window_once_for_pdumper (void)
|
||||
{
|
||||
window_scroll_pixel_based_preserve_x = -1;
|
||||
window_scroll_pixel_based_preserve_y = -1;
|
||||
window_scroll_preserve_hpos = -1;
|
||||
window_scroll_preserve_vpos = -1;
|
||||
PDUMPER_IGNORE (sequence_number);
|
||||
|
||||
PDUMPER_RESET_LV (minibuf_window, Qnil);
|
||||
PDUMPER_RESET_LV (selected_window, Qnil);
|
||||
PDUMPER_RESET_LV (Vwindow_list, Qnil);
|
||||
PDUMPER_RESET_LV (minibuf_selected_window, Qnil);
|
||||
|
||||
/* Hack: if mode_line_in_non_selected_windows is true (which it may
|
||||
be, if we're restoring from a dump) the guts of
|
||||
make_initial_frame will try to access selected_window, which is
|
||||
invalid at this point, and lose. For the purposes of creating
|
||||
the initial frame and window, this variable must be false. */
|
||||
bool old_mode_line_in_non_selected_windows;
|
||||
|
||||
/* Snapshot dumped_with_pdumper to suppress compiler warning. */
|
||||
bool saved_dumped_with_pdumper = dumped_with_pdumper_p ();
|
||||
if (saved_dumped_with_pdumper)
|
||||
{
|
||||
old_mode_line_in_non_selected_windows
|
||||
= mode_line_in_non_selected_windows;
|
||||
mode_line_in_non_selected_windows = false;
|
||||
}
|
||||
struct frame *f = make_initial_frame ();
|
||||
if (saved_dumped_with_pdumper)
|
||||
mode_line_in_non_selected_windows =
|
||||
old_mode_line_in_non_selected_windows;
|
||||
XSETFRAME (selected_frame, f);
|
||||
old_selected_frame = Vterminal_frame = selected_frame;
|
||||
minibuf_window = f->minibuffer_window;
|
||||
|
@ -7932,16 +7982,6 @@ syms_of_window (void)
|
|||
DEFSYM (Qmode_line_format, "mode-line-format");
|
||||
DEFSYM (Qheader_line_format, "header-line-format");
|
||||
|
||||
staticpro (&Vwindow_list);
|
||||
|
||||
minibuf_selected_window = Qnil;
|
||||
staticpro (&minibuf_selected_window);
|
||||
|
||||
window_scroll_pixel_based_preserve_x = -1;
|
||||
window_scroll_pixel_based_preserve_y = -1;
|
||||
window_scroll_preserve_hpos = -1;
|
||||
window_scroll_preserve_vpos = -1;
|
||||
|
||||
DEFVAR_LISP ("temp-buffer-show-function", Vtemp_buffer_show_function,
|
||||
doc: /* Non-nil means call as function to display a help buffer.
|
||||
The function is called with one argument, the buffer to be displayed.
|
||||
|
|
|
@ -31,6 +31,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "character.h"
|
||||
#include "charset.h"
|
||||
#include "font.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
|
||||
/* X core font driver. */
|
||||
|
@ -1077,6 +1078,7 @@ xfont_check (struct frame *f, struct font *font)
|
|||
}
|
||||
|
||||
|
||||
static void syms_of_xfont_for_pdumper (void);
|
||||
|
||||
struct font_driver const xfont_driver =
|
||||
{
|
||||
|
@ -1102,5 +1104,11 @@ syms_of_xfont (void)
|
|||
xfont_scripts_cache = CALLN (Fmake_hash_table, QCtest, Qequal);
|
||||
staticpro (&xfont_scratch_props);
|
||||
xfont_scratch_props = make_nil_vector (8);
|
||||
pdumper_do_now_and_after_load (syms_of_xfont_for_pdumper);
|
||||
}
|
||||
|
||||
static void
|
||||
syms_of_xfont_for_pdumper (void)
|
||||
{
|
||||
register_font_driver (&xfont_driver, NULL);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "composite.h"
|
||||
#include "font.h"
|
||||
#include "ftfont.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
/* Xft font driver. */
|
||||
|
||||
|
@ -751,6 +752,8 @@ xftfont_cached_font_ok (struct frame *f, Lisp_Object font_object,
|
|||
return ok;
|
||||
}
|
||||
|
||||
static void syms_of_xftfont_for_pdumper (void);
|
||||
|
||||
struct font_driver const xftfont_driver =
|
||||
{
|
||||
/* We can't draw a text without device dependent functions. */
|
||||
|
@ -802,7 +805,11 @@ syms_of_xftfont (void)
|
|||
This is needed with some fonts to correct vertical overlap of glyphs. */);
|
||||
xft_font_ascent_descent_override = 0;
|
||||
|
||||
ascii_printable[0] = 0;
|
||||
pdumper_do_now_and_after_load (syms_of_xftfont_for_pdumper);
|
||||
}
|
||||
|
||||
static void
|
||||
syms_of_xftfont_for_pdumper (void)
|
||||
{
|
||||
register_font_driver (&xftfont_driver, NULL);
|
||||
}
|
||||
|
|
22
src/xmenu.c
22
src/xmenu.c
|
@ -45,6 +45,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "buffer.h"
|
||||
#include "coding.h"
|
||||
#include "sysselect.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
#ifdef MSDOS
|
||||
#include "msdos.h"
|
||||
|
@ -2401,15 +2402,12 @@ DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_
|
|||
return (popup_activated ()) ? Qt : Qnil;
|
||||
}
|
||||
|
||||
|
||||
static void syms_of_xmenu_for_pdumper (void);
|
||||
|
||||
void
|
||||
syms_of_xmenu (void)
|
||||
{
|
||||
#ifdef USE_X_TOOLKIT
|
||||
enum { WIDGET_ID_TICK_START = 1 << 16 };
|
||||
widget_id_tick = WIDGET_ID_TICK_START;
|
||||
next_menubar_widget_id = 1;
|
||||
#endif
|
||||
|
||||
DEFSYM (Qdebug_on_next_call, "debug-on-next-call");
|
||||
defsubr (&Smenu_or_popup_active_p);
|
||||
|
||||
|
@ -2422,4 +2420,16 @@ syms_of_xmenu (void)
|
|||
Ffset (intern_c_string ("accelerate-menu"),
|
||||
intern_c_string (Sx_menu_bar_open_internal.s.symbol_name));
|
||||
#endif
|
||||
|
||||
pdumper_do_now_and_after_load (syms_of_xmenu_for_pdumper);
|
||||
}
|
||||
|
||||
static void
|
||||
syms_of_xmenu_for_pdumper (void)
|
||||
{
|
||||
#ifdef USE_X_TOOLKIT
|
||||
enum { WIDGET_ID_TICK_START = 1 << 16 };
|
||||
widget_id_tick = WIDGET_ID_TICK_START;
|
||||
next_menubar_widget_id = 1;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "blockinput.h"
|
||||
#include "termhooks.h"
|
||||
#include "keyboard.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
#include <X11/Xproto.h>
|
||||
|
||||
|
@ -2613,6 +2614,9 @@ x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from,
|
|||
}
|
||||
|
||||
|
||||
|
||||
static void syms_of_xselect_for_pdumper (void);
|
||||
|
||||
void
|
||||
syms_of_xselect (void)
|
||||
{
|
||||
|
@ -2628,17 +2632,9 @@ syms_of_xselect (void)
|
|||
|
||||
reading_selection_reply = Fcons (Qnil, Qnil);
|
||||
staticpro (&reading_selection_reply);
|
||||
reading_selection_window = 0;
|
||||
reading_which_selection = 0;
|
||||
|
||||
property_change_wait_list = 0;
|
||||
prop_location_identifier = 0;
|
||||
property_change_reply = Fcons (Qnil, Qnil);
|
||||
staticpro (&property_change_reply);
|
||||
|
||||
converted_selections = NULL;
|
||||
conversion_fail_tag = None;
|
||||
|
||||
/* FIXME: Duplicate definition in nsselect.c. */
|
||||
DEFVAR_LISP ("selection-converter-alist", Vselection_converter_alist,
|
||||
doc: /* An alist associating X Windows selection-types with functions.
|
||||
|
@ -2717,4 +2713,18 @@ A value of 0 means wait as long as necessary. This is initialized from the
|
|||
DEFSYM (Qforeign_selection, "foreign-selection");
|
||||
DEFSYM (Qx_lost_selection_functions, "x-lost-selection-functions");
|
||||
DEFSYM (Qx_sent_selection_functions, "x-sent-selection-functions");
|
||||
|
||||
pdumper_do_now_and_after_load (syms_of_xselect_for_pdumper);
|
||||
}
|
||||
|
||||
static void
|
||||
syms_of_xselect_for_pdumper (void)
|
||||
{
|
||||
reading_selection_window = 0;
|
||||
reading_which_selection = 0;
|
||||
property_change_wait_list = 0;
|
||||
prop_location_identifier = 0;
|
||||
property_change_reply = Fcons (Qnil, Qnil);
|
||||
converted_selections = NULL;
|
||||
conversion_fail_tag = None;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "keyboard.h"
|
||||
#include "blockinput.h"
|
||||
#include "termhooks.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
#include <X11/Xproto.h>
|
||||
|
||||
|
@ -1023,13 +1024,18 @@ void
|
|||
syms_of_xsettings (void)
|
||||
{
|
||||
current_mono_font = NULL;
|
||||
PDUMPER_IGNORE (current_mono_font);
|
||||
current_font = NULL;
|
||||
PDUMPER_IGNORE (current_font);
|
||||
first_dpyinfo = NULL;
|
||||
PDUMPER_IGNORE (first_dpyinfo);
|
||||
#ifdef HAVE_GSETTINGS
|
||||
gsettings_client = NULL;
|
||||
PDUMPER_IGNORE (gsettings_client);
|
||||
#endif
|
||||
#ifdef HAVE_GCONF
|
||||
gconf_client = NULL;
|
||||
PDUMPER_IGNORE (gconf_client);
|
||||
#endif
|
||||
|
||||
DEFSYM (Qmonospace_font_name, "monospace-font-name");
|
||||
|
|
|
@ -74,6 +74,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "xsettings.h"
|
||||
#include "sysselect.h"
|
||||
#include "menu.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
#ifdef USE_X_TOOLKIT
|
||||
#include <X11/Shell.h>
|
||||
|
@ -13298,6 +13299,7 @@ void
|
|||
syms_of_xterm (void)
|
||||
{
|
||||
x_error_message = NULL;
|
||||
PDUMPER_IGNORE (x_error_message);
|
||||
|
||||
DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms");
|
||||
DEFSYM (Qlatin_1, "latin-1");
|
||||
|
|
Loading…
Add table
Reference in a new issue