From 5aa618b05807d560126dfd09b9c9cb6b957b98de Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Tue, 13 Jan 2015 19:16:51 +0200 Subject: [PATCH] Fix problems with 32-bit wide-int build exposed by MinGW lisp.h (XPNTR): Move definition to after XTYPE, to avoid compilation error in an unoptimized build when !USE_LSB_TAG. src/w32heap.c (DUMPED_HEAP_SIZE): For 32-bit wide-int build, use the same larger value as for the 64-bit build. src/w32term.h (SCROLL_BAR_PACK): Cast the result to UINT_PTR to avoid compiler warnings. src/w32proc.c (Fw32_get_codepage_charset, Fw32_set_keyboard_layout): Avoid compiler warnings about cast from integer to pointer of different size. src/w32menu.c (menubar_selection_callback, w32_menu_show): Cast to UINT_PTR instead of EMACS_INT, to avoid compiler warnings about casting from integer to pointer of different size. (add_menu_item): Pass the help-echo string as a pointer to Lisp_String, not as a Lisp_Object. (w32_menu_display_help): Use make_lisp_ptr to reconstruct a Lisp string object from its C pointer. src/w32fns.c (w32_msg_pump) : Use make_lisp_ptr instead of XIL, to reconstruct a Lisp_Cons from its C pointer. : msg.lparam is now a C integer. (Fx_create_frame): Type-cast the result of XFASTINT to avoild compiler warnings about size differences. (Fw32_unregister_hot_key): Pass the tail of w32_grabbed_keys as a pointer to a Lisp_Cons struct, not as a disguised EMACS_INT. (Fw32_toggle_lock_key): Pass the new state of the key as a C integer; use -1 for nil. Doc fix. src/.gdbinit (xgetsym): New subroutine. (xsymname, xsymbol): Use it. (xprintsym): No need to call xgetptr. --- src/.gdbinit | 21 ++++++++++++--------- src/ChangeLog | 39 +++++++++++++++++++++++++++++++++++++++ src/lisp.h | 6 +++--- src/w32fns.c | 42 +++++++++++++++++++++++++++--------------- src/w32heap.c | 2 +- src/w32menu.c | 23 +++++++++++++++-------- src/w32proc.c | 11 ++++++++--- src/w32term.h | 4 ++-- 8 files changed, 107 insertions(+), 41 deletions(-) diff --git a/src/.gdbinit b/src/.gdbinit index 1a2a973e694..91beaef8d73 100644 --- a/src/.gdbinit +++ b/src/.gdbinit @@ -70,14 +70,18 @@ define xgettype set $type = (enum Lisp_Type) (USE_LSB_TAG ? $bugfix & (1 << GCTYPEBITS) - 1 : (EMACS_UINT) $bugfix >> VALBITS) end +define xgetsym + xgetptr $arg0 + if (!USE_LSB_TAG) + set $ptr = ($ptr << GCTYPEBITS) + end + set $ptr = ((struct Lisp_Symbol *) ((char *)lispsym + $ptr)) +end + # Access the name of a symbol define xsymname - if (CHECK_LISP_OBJECT_TYPE) - set $bugfix = $arg0.i - else - set $bugfix = $arg0 - end - set $symname = ((struct Lisp_Symbol *) ((char *)lispsym + $bugfix))->name + xgetsym $arg0 + set $symname = $ptr->name end # Set up something to print out s-expressions. @@ -760,7 +764,7 @@ end define xsymbol set $sym = $ - xgetptr $sym + xgetsym $sym print (struct Lisp_Symbol *) $ptr xprintsym $sym echo \n @@ -1082,8 +1086,7 @@ define xprintstr end define xprintsym - xgetptr $arg0 - xsymname $ptr + xsymname $arg0 xgetptr $symname set $sym_name = (struct Lisp_String *) $ptr xprintstr $sym_name diff --git a/src/ChangeLog b/src/ChangeLog index 81d6772bc23..2f40a463ed4 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,42 @@ +2015-01-13 Eli Zaretskii + + Fix problems with 32-bit wide-int build exposed by MinGW. + * lisp.h (XPNTR): Move definition to after XTYPE, to avoid + compilation error in an unoptimized build when !USE_LSB_TAG. + + * w32heap.c (DUMPED_HEAP_SIZE): For 32-bit wide-int build, use the + same larger value as for the 64-bit build. + + * w32term.h (SCROLL_BAR_PACK): Cast the result to UINT_PTR to + avoid compiler warnings. + + * w32proc.c (Fw32_get_codepage_charset, Fw32_set_keyboard_layout): + Avoid compiler warnings about cast from integer to pointer of + different size. + + * w32menu.c (menubar_selection_callback, w32_menu_show): Cast to + UINT_PTR instead of EMACS_INT, to avoid compiler warnings about + casting from integer to pointer of different size. + (add_menu_item): Pass the help-echo string as a pointer to + Lisp_String, not as a Lisp_Object. + (w32_menu_display_help): Use make_lisp_ptr to reconstruct a Lisp + string object from its C pointer. + + * w32fns.c (w32_msg_pump) : Use + make_lisp_ptr instead of XIL, to reconstruct a Lisp_Cons from its + C pointer. + : msg.lparam is now a C integer. + (Fx_create_frame): Type-cast the result of XFASTINT to avoild + compiler warnings about size differences. + (Fw32_unregister_hot_key): Pass the tail of w32_grabbed_keys as a + pointer to a Lisp_Cons struct, not as a disguised EMACS_INT. + (Fw32_toggle_lock_key): Pass the new state of the key as a C + integer; use -1 for nil. Doc fix. + + * .gdbinit (xgetsym): New subroutine. + (xsymname, xsymbol): Use it. + (xprintsym): No need to call xgetptr. + 2015-01-13 Martin Rudalics * frame.c (adjust_frame_size): Make sure new numbers of diff --git a/src/lisp.h b/src/lisp.h index a11e61213dc..ba1aff8e796 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -820,9 +820,6 @@ DEFINE_GDB_SYMBOL_END (VALMASK) #define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS) #define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM) -/* Extract the pointer hidden within A. */ -LISP_MACRO_DEFUN (XPNTR, void *, (Lisp_Object a), (a)) - #if USE_LSB_TAG LISP_MACRO_DEFUN (make_number, Lisp_Object, (EMACS_INT n), (n)) @@ -912,6 +909,9 @@ XUNTAG (Lisp_Object a, int type) #endif /* ! USE_LSB_TAG */ +/* Extract the pointer hidden within A. */ +LISP_MACRO_DEFUN (XPNTR, void *, (Lisp_Object a), (a)) + /* Extract A's value as an unsigned integer. */ INLINE EMACS_UINT XUINT (Lisp_Object a) diff --git a/src/w32fns.c b/src/w32fns.c index 3b8346a07fd..2dd92ff8a3a 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -2543,7 +2543,7 @@ w32_msg_pump (deferred_msg * msg_buf) thread-safe. The next line is okay because the cons cell is never made into garbage and is not relocated by GC. */ - XSETCAR (XIL ((EMACS_INT) msg.lParam), Qnil); + XSETCAR (make_lisp_ptr ((void *)msg.lParam, Lisp_Cons), Qnil); if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0)) emacs_abort (); break; @@ -2551,16 +2551,10 @@ w32_msg_pump (deferred_msg * msg_buf) { int vk_code = (int) msg.wParam; int cur_state = (GetKeyState (vk_code) & 1); - Lisp_Object new_state = XIL ((EMACS_INT) msg.lParam); - - /* NB: This code must be thread-safe. It is safe to - call NILP because symbols are not relocated by GC, - and pointer here is not touched by GC (so the markbit - can't be set). Numbers are safe because they are - immediate values. */ - if (NILP (new_state) - || (NUMBERP (new_state) - && ((XUINT (new_state)) & 1) != cur_state)) + int new_state = msg.lParam; + + if (new_state == -1 + || ((new_state & 1) != cur_state)) { one_w32_display_info.faked_key = vk_code; @@ -4523,7 +4517,9 @@ This function is an internal primitive--use `make-frame' instead. */) /* Specify the parent under which to make this window. */ if (!NILP (parent)) { - f->output_data.w32->parent_desc = (Window) XFASTINT (parent); + /* Cast to UINT_PTR shuts up compiler warnings about cast to + pointer from integer of different size. */ + f->output_data.w32->parent_desc = (Window) (UINT_PTR) XFASTINT (parent); f->output_data.w32->explicit_parent = 1; } else @@ -7260,10 +7256,17 @@ DEFUN ("w32-unregister-hot-key", Fw32_unregister_hot_key, if (!NILP (item)) { + LPARAM lparam; + + eassert (CONSP (item)); + /* Pass the tail of the list as a pointer to a Lisp_Cons cell, + so that it works in a --with-wide-int build as well. */ + lparam = (LPARAM) XUNTAG (item, Lisp_Cons); + /* Notify input thread about hot-key definition being removed, so that it takes effect without needing focus switch. */ if (PostThreadMessage (dwWindowsThreadId, WM_EMACS_UNREGISTER_HOT_KEY, - (WPARAM) XINT (XCAR (item)), (LPARAM) XLI (item))) + (WPARAM) XINT (XCAR (item)), lparam)) { MSG msg; GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE); @@ -7318,10 +7321,15 @@ DEFUN ("w32-toggle-lock-key", Fw32_toggle_lock_key, doc: /* Toggle the state of the lock key KEY. KEY can be `capslock', `kp-numlock', or `scroll'. If the optional parameter NEW-STATE is a number, then the state of KEY -is set to off if the low bit of NEW-STATE is zero, otherwise on. */) +is set to off if the low bit of NEW-STATE is zero, otherwise on. +If NEW-STATE is omitted or nil, the function toggles the state, + +Value is the new state of the key, or nil if the function failed +to change the state. */) (Lisp_Object key, Lisp_Object new_state) { int vk_code; + LPARAM lparam; if (EQ (key, intern ("capslock"))) vk_code = VK_CAPITAL; @@ -7335,8 +7343,12 @@ is set to off if the low bit of NEW-STATE is zero, otherwise on. */) if (!dwWindowsThreadId) return make_number (w32_console_toggle_lock_key (vk_code, new_state)); + if (NILP (new_state)) + lparam = -1; + else + lparam = (XUINT (new_state)) & 1; if (PostThreadMessage (dwWindowsThreadId, WM_EMACS_TOGGLE_LOCK_KEY, - (WPARAM) vk_code, (LPARAM) XLI (new_state))) + (WPARAM) vk_code, lparam)) { MSG msg; GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE); diff --git a/src/w32heap.c b/src/w32heap.c index f68332319c1..d5a9dae0aa4 100644 --- a/src/w32heap.c +++ b/src/w32heap.c @@ -114,7 +114,7 @@ typedef struct _RTL_HEAP_PARAMETERS { than half of the size stated below. It would be nice to find a way to build only the first bootstrap-emacs.exe with the large size, and reset that to a lower value afterwards. */ -#ifdef _WIN64 +#if defined _WIN64 || defined WIDE_EMACS_INT # define DUMPED_HEAP_SIZE (18*1024*1024) #else # define DUMPED_HEAP_SIZE (11*1024*1024) diff --git a/src/w32menu.c b/src/w32menu.c index a65e399ba5b..2742276d3f6 100644 --- a/src/w32menu.c +++ b/src/w32menu.c @@ -217,9 +217,9 @@ menubar_selection_callback (struct frame *f, void * client_data) else { entry = AREF (vector, i + MENU_ITEMS_ITEM_VALUE); - /* The EMACS_INT cast avoids a warning. There's no problem + /* The UINT_PTR cast avoids a warning. There's no problem as long as pointers have enough bits to hold small integers. */ - if ((int) (EMACS_INT) client_data == i) + if ((int) (UINT_PTR) client_data == i) { int j; struct input_event buf; @@ -706,7 +706,7 @@ w32_menu_show (struct frame *f, int x, int y, int menuflags, wv->key = SSDATA (descrip); /* Use the contents index as call_data, since we are restricted to 16-bits. */ - wv->call_data = !NILP (def) ? (void *) (EMACS_INT) i : 0; + wv->call_data = !NILP (def) ? (void *) (UINT_PTR) i : 0; if (NILP (type)) wv->button_type = BUTTON_TYPE_NONE; @@ -1401,17 +1401,21 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item) info.cbSize = sizeof (info); info.fMask = MIIM_DATA; - /* Set help string for menu item. Leave it as a Lisp_Object - until it is ready to be displayed, since GC can happen while - menus are active. */ + /* Set help string for menu item. Leave it as a pointer to + a Lisp_String until it is ready to be displayed, since GC + can happen while menus are active. */ if (!NILP (wv->help)) { + /* We use XUNTAG below because in a 32-bit build + --with-wide-int we cannot pass a Lisp_Object + via a DWORD member of MENUITEMINFO. */ /* As of Jul-2012, w32api headers say that dwItemData has DWORD type, but that's a bug: it should actually be ULONG_PTR, which is correct for 32-bit and 64-bit Windows alike. MSVC headers get it right; hopefully, MinGW headers will, too. */ - info.dwItemData = (ULONG_PTR) XLI (wv->help); + eassert (STRINGP (wv->help)); + info.dwItemData = (ULONG_PTR) XUNTAG (wv->help, Lisp_String); } if (wv->button_type == BUTTON_TYPE_RADIO) { @@ -1487,7 +1491,10 @@ w32_menu_display_help (HWND owner, HMENU menu, UINT item, UINT flags) info.fMask = MIIM_DATA; get_menu_item_info (menu, item, FALSE, &info); - help = info.dwItemData ? XIL (info.dwItemData) : Qnil; + help = + info.dwItemData + ? make_lisp_ptr ((void *) info.dwItemData, Lisp_String) + : Qnil; } /* Store the help echo in the keyboard buffer as the X toolkit diff --git a/src/w32proc.c b/src/w32proc.c index 26cfa2996d0..74731db2426 100644 --- a/src/w32proc.c +++ b/src/w32proc.c @@ -3077,13 +3077,18 @@ yield nil. */) (Lisp_Object cp) { CHARSETINFO info; + DWORD dwcp; CHECK_NUMBER (cp); if (!IsValidCodePage (XINT (cp))) return Qnil; - if (TranslateCharsetInfo ((DWORD *) XINT (cp), &info, TCI_SRCCODEPAGE)) + /* Going through a temporary DWORD variable avoids compiler warning + about cast to pointer from integer of different size, when + building --with-wide-int. */ + dwcp = XINT (cp); + if (TranslateCharsetInfo ((DWORD *) dwcp, &info, TCI_SRCCODEPAGE)) return make_number (info.ciCharset); return Qnil; @@ -3142,8 +3147,8 @@ If successful, the new layout id is returned, otherwise nil. */) CHECK_NUMBER_CAR (layout); CHECK_NUMBER_CDR (layout); - kl = (HKL) ((XINT (XCAR (layout)) & 0xffff) - | (XINT (XCDR (layout)) << 16)); + kl = (HKL) (UINT_PTR) ((XINT (XCAR (layout)) & 0xffff) + | (XINT (XCDR (layout)) << 16)); /* Synchronize layout with input thread. */ if (dwWindowsThreadId) diff --git a/src/w32term.h b/src/w32term.h index 042d7abd945..c905ef15737 100644 --- a/src/w32term.h +++ b/src/w32term.h @@ -493,8 +493,8 @@ struct scroll_bar { (XSETINT ((low), ((DWORDLONG)(int64)) & 0xffffffff), \ XSETINT ((high), ((DWORDLONG)(int64) >> 32) & 0xffffffff)) #else /* not _WIN64 */ -/* Building a 32-bit C integer from two 16-bit lisp integers. */ -#define SCROLL_BAR_PACK(low, high) (XINT (high) << 16 | XINT (low)) +/* Building a 32-bit C unsigned integer from two 16-bit lisp integers. */ +#define SCROLL_BAR_PACK(low, high) ((UINT_PTR)(XINT (high) << 16 | XINT (low))) /* Setting two lisp integers to the low and high words of a 32-bit C int. */ #define SCROLL_BAR_UNPACK(low, high, int32) \ -- 2.39.2