From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Alan Mackenzie Newsgroups: gmane.emacs.bugs Subject: bug#66912: With `require', the byte compiler reports the wrong file for errors. Date: Mon, 4 Nov 2024 16:35:34 +0000 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="11536"; mail-complaints-to="usenet@ciao.gmane.io" Cc: acm@muc.de, 66912@debbugs.gnu.org To: Stefan Monnier Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Mon Nov 04 17:36:17 2024 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1t803t-0002nZ-JM for geb-bug-gnu-emacs@m.gmane-mx.org; Mon, 04 Nov 2024 17:36:17 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t803g-0008A1-Pv; Mon, 04 Nov 2024 11:36:04 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t803e-00089R-Ry for bug-gnu-emacs@gnu.org; Mon, 04 Nov 2024 11:36:02 -0500 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1t803e-00033S-JY for bug-gnu-emacs@gnu.org; Mon, 04 Nov 2024 11:36:02 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debbugs.gnu.org; s=debbugs-gnu-org; h=From:In-Reply-To:MIME-Version:References:Date:To:Subject; bh=lKoR9rxp+KMBmcyhz8NFi8M93Szn657VVSDv1xZQy8A=; b=mouOtDYhEVwY34mpeTXIBTMZQt1t81pAt1guOF94yLtJEfBOnvgdJ+XnSuTriWlP7jebK6gpo3isE+0y9e6IZJdyfiOMHQfbEtH5V8AZeV//49TFYZLsxpLBwGqOPoOPiziFMp1+D5MbpU3sX1PQcEiX0eiIq1okDPp9yHgrJDH4SPFDFjZuhYHykzCZUaWfR6aZ5oyZFNaUl4bvH9EDIRA1CpYXMqg7UfIEsTMaScE7FxJmgB80BsYa9iU5OO56SUFO9Q06Yp9+CbFh8uSDr/4YPo0FGINbVFVRejxTR2bh1yAAY5LYV5WUFZPqqw7872DmRO825BnWJycUGziduA==; Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1t803e-0000rA-6U for bug-gnu-emacs@gnu.org; Mon, 04 Nov 2024 11:36:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Alan Mackenzie Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 04 Nov 2024 16:36:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 66912 X-GNU-PR-Package: emacs Original-Received: via spool by 66912-submit@debbugs.gnu.org id=B66912.17307381463280 (code B ref 66912); Mon, 04 Nov 2024 16:36:02 +0000 Original-Received: (at 66912) by debbugs.gnu.org; 4 Nov 2024 16:35:46 +0000 Original-Received: from localhost ([127.0.0.1]:40970 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1t803O-0000qn-1x for submit@debbugs.gnu.org; Mon, 04 Nov 2024 11:35:46 -0500 Original-Received: from mail.muc.de ([193.149.48.3]:22979) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1t803K-0000qd-IS for 66912@debbugs.gnu.org; Mon, 04 Nov 2024 11:35:45 -0500 Original-Received: (qmail 17391 invoked by uid 3782); 4 Nov 2024 17:35:34 +0100 Original-Received: from muc.de (p4fe1531c.dip0.t-ipconnect.de [79.225.83.28]) (using STARTTLS) by colin.muc.de (tmda-ofmipd) with ESMTP; Mon, 04 Nov 2024 17:35:34 +0100 Original-Received: (qmail 17558 invoked by uid 1000); 4 Nov 2024 16:35:34 -0000 Content-Disposition: inline In-Reply-To: X-Submission-Agent: TMDA/1.3.x (Ph3nix) X-Primary-Address: acm@muc.de X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:294864 Archived-At: Hello again, Stefan. [ I've just got your latest post, answering my last one. Thanks! But I'm sending you this post anyway, which I'd almost finished. ] Progress! On Mon, Nov 04, 2024 at 12:52:10 +0000, Alan Mackenzie wrote: > On Sun, Nov 03, 2024 at 21:46:42 -0500, Stefan Monnier wrote: > > Hi Alan, [ .... ] > > I don't understand the above code: `handler-bind` is not supposed to > > call setjmp/longjmp: when the handler of a `handler-bind` gets > > called, the stack is not unwound. [ .... ] > Given HANDLER_BIND doesn't need the setjmp/longjmp mechanism, it would > seem there's no sense in combining the HANDLER_BIND and CONDITION_CASE > cases in internal_cc_hb and friends. I should just restore the > condition-case functions to what they were, and add separate new ones > for handler-bind. I've now done this. Possibly the new function internal_condition_case_1_voidstar is superfluous and should be deleted. Also, not all of the internal_handler_bind* functions are currently used. [ .... ] > > > + else > > > + call1 (h->val, error); > > > + unbind_to (count, Qnil); /* Removes SKIP_CONDITIONS handler. */ > > > + pop_handler (); /* Discards HANDLER_BIND handler. */ > > These comments don't match my understanding of the code: IIRC the > > `pop_handler` pops the `SKIP_CONDITIONS` handler. > I think I see now you're right. push_handler doesn't push an entry onto > the binding stack. I'll amend these comments as soon as I understand > the code. I think these lines definitely need comments. > > Also there's no reason to presume the HANDLER_BIND handler is at the > > top, so if we wanted to remove it, we'd have to work harder. > This code is difficult to understand. What is the purpose of the > binding block around the call of the handler function? I think a > comment here would help. I've worked this out. The binding block is to restore the size of the stack via the unwind_protect set up in the call to max_ensure_room. I've added a comment to say that. [ .... ] I've also amended the doc string of Fhandler_bind_1, saying that the return value from a handler gets ignored, and clarifying that a normal return from a handler means the error hasn't been handled. If you agree with this, I will make a corresponding amendment to the macro handler-bind. Here is the revised part of the patch, just for eval.c: diff --git a/src/eval.c b/src/eval.c index d0a2abf0089..79cf9115379 100644 --- a/src/eval.c +++ b/src/eval.c @@ -256,7 +256,7 @@ restore_stack_limits (Lisp_Object data) max_lisp_eval_depth = old_depth; } -/* Try and ensure that we have at least B dpeth available. */ +/* Try and ensure that we have at least B depth available. */ static void max_ensure_room (intmax_t b) @@ -1450,9 +1450,9 @@ DEFUN ("handler-bind-1", Fhandler_bind_1, Shandler_bind_1, 1, MANY, 0, error matches one of CONDITIONS, then the associated HANDLER is called with the error as argument. HANDLER should either transfer the control via a non-local exit, -or return normally. -If it returns normally, the search for an error handler continues -from where it left off. +or return normally, should it fail to handle the error. +If it returns normally, the returned value is ignored, and the +search for an error handler continues from where it left off. usage: (handler-bind BODYFUN [CONDITIONS HANDLER]...) */) (ptrdiff_t nargs, Lisp_Object *args) @@ -1583,7 +1583,7 @@ internal_lisp_condition_case (Lisp_Object var, Lisp_Object bodyform, /* Call the function BFUN with no arguments, catching errors within it according to HANDLERS. If there is an error, call HFUN with one argument which is the data that describes the error: - (SIGNALNAME . DATA) + (SIGNALNAME . DATA). HANDLERS can be a list of conditions to catch. If HANDLERS is Qt, catch all errors. @@ -1662,6 +1662,33 @@ internal_condition_case_2 (Lisp_Object (*bfun) (Lisp_Object, Lisp_Object), } } +/* Like internal_condition_case_2 but the second argument is an arbitrary + pointer. */ + +Lisp_Object +internal_condition_case_1_voidstar (Lisp_Object (*bfun) (Lisp_Object, void *), + Lisp_Object arg1, + void *arg2, + Lisp_Object handlers, + Lisp_Object (*hfun) (Lisp_Object)) +{ + struct handler *c = push_handler (handlers, CONDITION_CASE); + if (sys_setjmp (c->jmp)) + { + Lisp_Object val = handlerlist->val; + clobbered_eassert (handlerlist == c); + handlerlist = handlerlist->next; + return hfun (val); + } + else + { + Lisp_Object val = bfun (arg1, arg2); + eassert (handlerlist == c); + handlerlist = c->next; + return val; + } +} + /* Like internal_condition_case but call BFUN with NARGS as first, and ARGS as second argument. */ @@ -1691,6 +1718,137 @@ internal_condition_case_n (Lisp_Object (*bfun) (ptrdiff_t, Lisp_Object *), } } +/* Call the function BFUN with no arguments, catching errors within it + in a `handler-bind' construct according to HANDLERS. If there is an + error, call HFUN with one argument which is the data that describes + the error: (SIGNALNAME . DATA). + + HANDLERS is either a list of conditions to catch, or one of these + symbols: + If HANDLERS is Qt, catch all errors. + If HANDLERS is Qerror, catch all errors, but allow the debugger to + run if that is enabled. */ + +Lisp_Object +internal_handler_bind (Lisp_Object (*bfun) (void), Lisp_Object handlers, + Lisp_Object (*hfun) (Lisp_Object)) +{ + struct handler *c = push_handler (handlers, HANDLER_BIND); + /* if (NILP (Flistp (handlers))) */ + /* handlers = Fcons (handlers, Qnil); */ + c->val = Qnil; + c->bin_handler = hfun; + c->bytecode_dest = 0; + + { + Lisp_Object val = bfun (); + eassert (handlerlist == c); + handlerlist = c->next; + return val; + } +} + +/* Like internal_handler_bind, but call BFUN with ARG as its argument. */ + +Lisp_Object +internal_handler_bind_1 (Lisp_Object (*bfun) (Lisp_Object), Lisp_Object arg, + Lisp_Object handlers, + Lisp_Object (*hfun) (Lisp_Object)) +{ + struct handler *c = push_handler (handlers, HANDLER_BIND); + /* if (NILP (Flistp (handlers))) */ + /* handlers = Fcons (handlers, Qnil); */ + c->val = Qnil; + c->bin_handler = hfun; + c->bytecode_dest = 0; + { + Lisp_Object val = bfun (arg); + eassert (handlerlist == c); + handlerlist = c->next; + return val; + } +} + +/* Like internal_handler_bind_1, but call BFUN with ARG1 and ARG2 as + its arguments. */ + +Lisp_Object +internal_handler_bind_2 (Lisp_Object (*bfun) (Lisp_Object, Lisp_Object), + Lisp_Object arg1, + Lisp_Object arg2, + Lisp_Object handlers, + Lisp_Object (*hfun) (Lisp_Object)) +{ + struct handler *c = push_handler (handlers, HANDLER_BIND); + /* if (NILP (Flistp (handlers))) */ + /* handlers = Fcons (handlers, Qnil); */ + c->val = Qnil; + c->bin_handler = hfun; + c->bytecode_dest = 0; + { + Lisp_Object val = bfun (arg1, arg2); + eassert (handlerlist == c); + handlerlist = c->next; + return val; + } +} + +/* Like internal_handler_bind_2, but the second argument is an arbitrary + pointer. */ + +Lisp_Object +internal_handler_bind_1_voidstar (Lisp_Object (*bfun) (Lisp_Object, void *), + Lisp_Object arg1, + void *arg2, + Lisp_Object handlers, + Lisp_Object (*hfun) (Lisp_Object)) +{ + struct handler *c = push_handler (handlers, HANDLER_BIND); + /* if (NILP (Flistp (handlers))) */ + /* handlers = Fcons (handlers, Qnil); */ + c->val = Qnil; + c->bin_handler = hfun; + c->bytecode_dest = 0; + { + Lisp_Object val = bfun (arg1, arg2); + eassert (handlerlist == c); + handlerlist = c->next; + return val; + } +} + +/* Like internal_handler_bind, but call BFUN with NARGS as first, + and ARGS as second argument. */ + +Lisp_Object +internal_handler_bind_n (Lisp_Object (*bfun) (ptrdiff_t, Lisp_Object *), + ptrdiff_t nargs, + Lisp_Object *args, + Lisp_Object handlers, + Lisp_Object (*hfun) (Lisp_Object err)) +{ + struct handler *c = push_handler (handlers, HANDLER_BIND); + { + c->val = Qnil; + c->bin_handler = hfun; + c->bytecode_dest = 0; + } + if (sys_setjmp (c->jmp)) + { + Lisp_Object val = handlerlist->val; + clobbered_eassert (handlerlist == c); + handlerlist = handlerlist->next; + return hfun (val); + } + else + { + Lisp_Object val = bfun (nargs, args); + eassert (handlerlist == c); + handlerlist = c->next; + return val; + } +} + static Lisp_Object Qcatch_all_memory_full; /* Like a combination of internal_condition_case_1 and internal_catch. @@ -1900,9 +2058,12 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool continuable) max_ensure_room (20); push_handler (make_fixnum (skip + h->bytecode_dest), SKIP_CONDITIONS); - call1 (h->val, error); - unbind_to (count, Qnil); - pop_handler (); + if (NILP (h->val)) + h->bin_handler (error); + else + call1 (h->val, error); + unbind_to (count, Qnil); /* Restore after `max_ensure_room'. */ + pop_handler (); /* Remove SKIP_CONDITIONS handler. */ } continue; } > > Stefan > -- > Alan Mackenzie (Nuremberg, Germany).