From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Newsgroups: gmane.emacs.bugs Subject: bug#47677: [PATCH] condition-case success continuation Date: Thu, 22 Apr 2021 15:58:10 +0200 Message-ID: References: <219007D9-0FD0-4AC2-A8B0-24A0FC277AE8@acm.org> <87lf9nzy48.fsf@gnus.org> <87F315E7-7F8A-46C5-A71B-F090F067D0B8@acm.org> <87sg3uskgt.fsf@gnus.org> <87zgy1qkni.fsf@gnus.org> Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.17\)) Content-Type: multipart/mixed; boundary="Apple-Mail=_46565640-A5B4-47B1-93EE-1B08F34AD9DE" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="25511"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Lars Ingebrigtsen , Stefan Monnier , 47677@debbugs.gnu.org To: Stefan Kangas Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Thu Apr 22 15:59:18 2021 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 1lZZrR-0006Pz-OI for geb-bug-gnu-emacs@m.gmane-mx.org; Thu, 22 Apr 2021 15:59:17 +0200 Original-Received: from localhost ([::1]:49044 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lZZrQ-000530-RP for geb-bug-gnu-emacs@m.gmane-mx.org; Thu, 22 Apr 2021 09:59:16 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:46594) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lZZrD-00051q-3b for bug-gnu-emacs@gnu.org; Thu, 22 Apr 2021 09:59:03 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:51887) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lZZrC-0007kd-Cq for bug-gnu-emacs@gnu.org; Thu, 22 Apr 2021 09:59:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1lZZrC-0001jg-9q for bug-gnu-emacs@gnu.org; Thu, 22 Apr 2021 09:59:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 22 Apr 2021 13:59:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 47677 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 47677-submit@debbugs.gnu.org id=B47677.16190998976618 (code B ref 47677); Thu, 22 Apr 2021 13:59:02 +0000 Original-Received: (at 47677) by debbugs.gnu.org; 22 Apr 2021 13:58:17 +0000 Original-Received: from localhost ([127.0.0.1]:35200 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lZZqT-0001ig-0N for submit@debbugs.gnu.org; Thu, 22 Apr 2021 09:58:17 -0400 Original-Received: from mail173c50.megamailservers.eu ([91.136.10.183]:38858 helo=mail56c50.megamailservers.eu) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lZZqR-0001iY-HV for 47677@debbugs.gnu.org; Thu, 22 Apr 2021 09:58:16 -0400 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1619099893; bh=cPx7cxDgHPU5FlOgM/93gTQIw3Eqrl6zCUndj517B8A=; h=From:Subject:Date:In-Reply-To:Cc:To:References:From; b=aQ6gEkHY8Qo3gN0oY8Zfo10CTyreEpFMbe6i2+HLyUMXCiiX9AJHbbK8aWUQSBJEr YDk6vdyVjNRCVeMU41ymUkvJqMJUHLKyAna0RwOdmbKX31xGlVpZgxTFebrNOFfcY9 RSxVBnS3VdCQsTEYFfu+78/wBT/33qFvdMXPkIxY= Feedback-ID: mattiase@acm.or Original-Received: from [192.168.0.4] (c188-150-171-71.bredband.comhem.se [188.150.171.71]) (authenticated bits=0) by mail56c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id 13MDwBTm026308; Thu, 22 Apr 2021 13:58:12 +0000 In-Reply-To: X-Mailer: Apple Mail (2.3445.104.17) X-CTCH-RefID: str=0001.0A742F1F.608180F5.003E, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0 X-CTCH-VOD: Unknown X-CTCH-Spam: Unknown X-CTCH-Score: 0.000 X-CTCH-Flags: 0 X-CTCH-ScoreCust: 0.000 X-CSC: 0 X-CHA: v=2.3 cv=FblJO626 c=1 sm=1 tr=0 a=SF+I6pRkHZhrawxbOkkvaA==:117 a=SF+I6pRkHZhrawxbOkkvaA==:17 a=M51BFTxLslgA:10 a=GzfwrDjxe7EOOWsxUE0A:9 a=CjuIK1q_8ugA:10 a=weKScdL88ZS-fUvzyssA:9 a=B2y7HmGcmWMA:10 X-Origin-Country: SE 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" Xref: news.gmane.io gmane.emacs.bugs:204687 Archived-At: --Apple-Mail=_46565640-A5B4-47B1-93EE-1B08F34AD9DE Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii 21 apr. 2021 kl. 16.13 skrev Stefan Kangas : > Should this be closed, or is there more to do here? There's the business of fixing `catch` in the same way. (A new bug could = be opened for it, but since it's intimately related we might as well do = it here.) As mentioned, `catch` has three problems: - no way to execute code when a throw is caught - no way to execute code when the body terminates normally - no way to catch both throws and errors since neither `catch` nor `condition-case` compose with themselves or = each other. For example, it would be useful to have `pcase` match both the value of = an expression as well as throws and errors from it. Here is a proper patch, essentially a polished version of the previously = posted diff. It adds `condition-case` clauses on the form ((:catch TAG-EXPR) BODY...) where TAG-EXPR is evaluated before the protected form to a tag value, = and BODY is executed when that tag is thrown, with the variable bound to = the thrown value. --Apple-Mail=_46565640-A5B4-47B1-93EE-1B08F34AD9DE Content-Disposition: attachment; filename=0001-catch-handlers-in-condition-case-bug-47677.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="0001-catch-handlers-in-condition-case-bug-47677.patch" Content-Transfer-Encoding: quoted-printable =46rom=20218db91619430d0f26ca3e17839e6669fd291e76=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20=3D?UTF-8?q?Mattias=3D20Engdeg=3DC3=3DA5rd?=3D=20= =0ADate:=20Mon,=2012=20Apr=202021=2020:40:23=20+0200=0A= Subject:=20[PATCH]=20`catch`=20handlers=20in=20`condition-case`=20= (bug#47677)=0A=0AAdd=20handlers=20on=20the=20form=0A=0A=20=20((:catch=20= TAG)=20BODY...)=0A=0Awhere=20TAG=20is=20an=20expression=20that=20is=20= evaluated=20prior=20to=20the=20protected=0Aform=20and=20yields=20a=20= catch=20tag=20that=20is=20handled=20by=20BODY=20with=20the=20variable=0A= bound=20to=20the=20thrown=20value.=20=20For=20example,=0A=0A=20=20= (condition-case=20x=0A=20=20=20=20=20=20(throw=20'meep=202)=0A=20=20=20=20= ((:catch=20'meep)=20(+=20x=203)))=0A=20=20=3D>=205=0A=0AMultiple=20catch=20= and=20error=20handlers=20can=20be=20mixed=20freely=20in=20the=20same=0A= `condition-case`=20form,=20which=20can=20also=20include=20a=20:success=20= clause.=0A=0AIn=20other=20words,=20this=20change=20remedies=20three=20= problems:=20`catch`=20lacking=0Aseparate=20code=20branches=20for=20the=20= throw=20and=20fall-through=20cases,=20and=20the=0Alack=20of=20= composability=20with=20`condition-case`=20and=20`catch`.=0A=0A*=20= src/eval.c=20(internal_lisp_condition_case,=20syms_of_eval):=20Implement=0A= in=20interpreter.=0A*=20lisp/emacs-lisp/cconv.el=20(cconv-convert,=20= cconv-analyze-form):=0A*=20lisp/emacs-lisp/bytecomp.el=20= (byte-compile-condition-case):=20Implement=0Ain=20byte-compiler.=0A*=20= test/lisp/emacs-lisp/bytecomp-tests.el=20(bytecomp-tests--test-cases)=0A= (bytecomp-condition-case-success):=20Add=20tests.=0A---=0A=20= lisp/emacs-lisp/bytecomp.el=20=20=20=20=20=20=20=20=20=20=20=20|=2044=20= ++++++++-----=0A=20lisp/emacs-lisp/cconv.el=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20|=2024=20++++---=0A=20src/eval.c=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20|=2027=20= +++++++-=0A=20test/lisp/emacs-lisp/bytecomp-tests.el=20|=2091=20= +++++++++++++++++++++++++-=0A=204=20files=20changed,=20158=20= insertions(+),=2028=20deletions(-)=0A=0Adiff=20--git=20= a/lisp/emacs-lisp/bytecomp.el=20b/lisp/emacs-lisp/bytecomp.el=0Aindex=20= 4f91f0d5de..82e0edd772=20100644=0A---=20a/lisp/emacs-lisp/bytecomp.el=0A= +++=20b/lisp/emacs-lisp/bytecomp.el=0A@@=20-4636,22=20+4636,34=20@@=20= byte-compile-condition-case=0A=20=20=20=20=20=20=20(byte-compile-warn=0A=20= =20=20=20=20=20=20=20"`%s'=20is=20not=20a=20variable-name=20or=20nil=20= (in=20condition-case)"=20var))=0A=20=0A-=20=20=20=20(dolist=20(clause=20= (reverse=20clauses))=0A-=20=20=20=20=20=20(let=20((condition=20(nth=201=20= clause)))=0A-=20=20=20=20=20=20=20=20(unless=20(consp=20condition)=20= (setq=20condition=20(list=20condition)))=0A-=20=20=20=20=20=20=20=20= (dolist=20(c=20condition)=0A-=20=20=20=20=20=20=20=20=20=20(unless=20= (and=20c=20(symbolp=20c))=0A-=20=20=20=20=20=20=20=20=20=20=20=20= (byte-compile-warn=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20"`%S'=20is=20= not=20a=20condition=20name=20(in=20condition-case)"=20c))=0A-=20=20=20=20= =20=20=20=20=20=20;;=20In=20reality,=20the=20`error-conditions'=20= property=20is=20only=20required=0A-=20=20=20=20=20=20=20=20=20=20;;=20= for=20the=20argument=20to=20`signal',=20not=20to=20`condition-case'.=0A-=20= =20=20=20=20=20=20=20=20=20;;(unless=20(consp=20(get=20c=20= 'error-conditions))=0A-=20=20=20=20=20=20=20=20=20=20;;=20=20= (byte-compile-warn=0A-=20=20=20=20=20=20=20=20=20=20;;=20=20=20"`%s'=20= is=20not=20a=20known=20condition=20name=20(in=20condition-case)"=0A-=20=20= =20=20=20=20=20=20=20=20;;=20=20=20c))=0A-=20=20=20=20=20=20=20=20=20=20= )=0A-=20=20=20=20=20=20=20=20(byte-compile-push-constant=20condition))=0A= -=20=20=20=20=20=20(byte-compile-goto=20'byte-pushconditioncase=20(car=20= clause)))=0A+=20=20=20=20(let=20((initial-depth=20byte-compile-depth)=0A= +=20=20=20=20=20=20=20=20=20=20(push-ops=20nil))=0A+=20=20=20=20=20=20;;=20= Push=20all=20conditions=20and=20tags=20in=20left-to-right=20order=20= first,=0A+=20=20=20=20=20=20;;=20since=20tags=20need=20to=20be=20= evaluated=20outside=20the=20scope=20of=20the=20handlers.=0A+=20=20=20=20=20= =20(dolist=20(clause=20clauses)=0A+=20=20=20=20=20=20=20=20(let=20= ((condition=20(nth=201=20clause)))=0A+=20=20=20=20=20=20=20=20=20=20= (pcase=20condition=0A+=20=20=20=20=20=20=20=20=20=20=20=20(`(:catch=20= ,tag-expr)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20(byte-compile-form=20= tag-expr)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20(push=20(cons=20= 'byte-pushcatch=20(car=20clause))=20push-ops))=0A+=20=20=20=20=20=20=20=20= =20=20=20=20(`(:catch=20.=20,_)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= (error=20"malformed=20:catch=20clause:=20`%S'"=20(cdr=20clause)))=0A+=20=20= =20=20=20=20=20=20=20=20=20=20(_=20=20=20=20=20=20=20=20=20=20=20=20=20;=20= error=20clause=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20(unless=20= (consp=20condition)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (setq=20condition=20(list=20condition)))=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20(dolist=20(c=20condition)=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20(unless=20(and=20c=20(symbolp=20c))=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(byte-compile-warn=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20"`%S'=20is=20not=20a=20condition=20name=20(in=20= condition-case)"=20c)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= (byte-compile-push-constant=20condition)=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20(push=20(cons=20'byte-pushconditioncase=20(car=20clause))=20= push-ops)))))=0A+=20=20=20=20=20=20;;=20Then=20emit=20the=20handler=20= activations=20in=20reverse=20order=20so=20that=20the=0A+=20=20=20=20=20=20= ;;=20first=20handler=20becomes=20the=20innermost.=0A+=20=20=20=20=20=20= (dolist=20(op=20push-ops)=0A+=20=20=20=20=20=20=20=20;;=20Use=20the=20= depth=20at=20which=20the=20jumps=20will=20take=20place=20in=20the=20tag.=0A= +=20=20=20=20=20=20=20=20(setq=20byte-compile-depth=20(1+=20= initial-depth))=0A+=20=20=20=20=20=20=20=20(byte-compile-goto=20(car=20= op)=20(cdr=20op)))=0A+=20=20=20=20=20=20(cl-assert=20(equal=20= byte-compile-depth=20initial-depth)))=0A=20=0A=20=20=20=20=20= (byte-compile-form=20body)=20;;=20byte-compile--for-effect=0A=20=20=20=20= =20(dolist=20(_=20clauses)=20(byte-compile-out=20'byte-pophandler))=0A= diff=20--git=20a/lisp/emacs-lisp/cconv.el=20b/lisp/emacs-lisp/cconv.el=0A= index=20f663710902..f92f9b7ed8=20100644=0A---=20= a/lisp/emacs-lisp/cconv.el=0A+++=20b/lisp/emacs-lisp/cconv.el=0A@@=20= -510,14=20+510,18=20@@=20cconv-convert=0A=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20newprotform)=0A=20=20=20=20=20=20=20=20=20=20=20,@(mapcar=0A= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(lambda=20(handler)=0A-=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20`(,(car=20handler)=0A-=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20,@(let=20((body=0A-=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(mapcar=20= (lambda=20(form)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(cconv-convert=20= form=20newenv=20extend))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(cdr=20= handler))))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(if=20(not=20(eq=20class=20:captured+mutated))=0A-=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20body=0A-=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20`((let=20((,var=20= (list=20,var)))=20,@body))))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20(let=20((head=20(pcase=20(car=20handler)=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(`(:catch=20= ,tag-exp)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20`(:catch=20,(cconv-convert=20tag-exp=20env=20= extend)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(h=20h))))=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20`(,head=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20,@(let=20((body=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(mapcar=20(lambda=20(form)=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20(cconv-convert=20form=20newenv=20= extend))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(cdr=20handler))))=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(if=20= (not=20(eq=20class=20:captured+mutated))=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20body=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20`((let=20= ((,var=20(list=20,var)))=20,@body)))))))=0A=20=20=20=20=20=20=20=20=20=20= =20=20=20=20handlers))))=0A=20=0A=20=20=20=20=20(`(unwind-protect=20= ,form=20.=20,body)=0A@@=20-736,6=20+740,10=20@@=20cconv-analyze-form=0A=20= =20=20=20=20(`(function=20.=20,_)=20nil)=20=20=20=20=20=20=20=20=20=20=20= =20=20=20;=20same=20as=20quote=0A=20=0A=20=20=20=20=20(`(condition-case=20= ,var=20,protected-form=20.=20,handlers)=0A+=20=20=20=20=20(dolist=20= (handler=20handlers)=0A+=20=20=20=20=20=20=20(pcase=20handler=0A+=20=20=20= =20=20=20=20=20=20(`((:catch=20,tag-exp)=20.=20,_)=0A+=20=20=20=20=20=20=20= =20=20=20(cconv-analyze-form=20tag-exp=20env))))=0A=20=20=20=20=20=20= (cconv-analyze-form=20protected-form=20env)=0A=20=20=20=20=20=20(when=20= (and=20var=20(symbolp=20var)=20(byte-compile-not-lexical-var-p=20var))=0A= =20=20=20=20=20=20=20=20(byte-compile-warn=0Adiff=20--git=20a/src/eval.c=20= b/src/eval.c=0Aindex=20fd93f5b9e1..d4ed746458=20100644=0A---=20= a/src/eval.c=0A+++=20b/src/eval.c=0A@@=20-1351,6=20+1351,7=20@@=20= internal_lisp_condition_case=20(Lisp_Object=20var,=20Lisp_Object=20= bodyform,=0A=20=20=20CHECK_SYMBOL=20(var);=0A=20=0A=20=20=20Lisp_Object=20= success_handler=20=3D=20Qnil;=0A+=20=20Lisp_Object=20tags=20=3D=20Qnil;=09= /*=20Evaluated=20catch=20tags=20in=20reverse=20order.=20*/=0A=20=0A=20=20= =20for=20(Lisp_Object=20tail=20=3D=20handlers;=20CONSP=20(tail);=20tail=20= =3D=20XCDR=20(tail))=0A=20=20=20=20=20{=0A@@=20-1361,10=20+1362,21=20@@=20= internal_lisp_condition_case=20(Lisp_Object=20var,=20Lisp_Object=20= bodyform,=0A=20=09=09=20=20=20=20=20||=20CONSP=20(XCAR=20(tem))))))=0A=20= =09error=20("Invalid=20condition=20handler:=20%s",=0A=20=09=20=20=20=20=20= =20=20SDATA=20(Fprin1_to_string=20(tem,=20Qt)));=0A-=20=20=20=20=20=20if=20= (EQ=20(XCAR=20(tem),=20QCsuccess))=0A+=20=20=20=20=20=20Lisp_Object=20= head=20=3D=20XCAR=20(tem);=0A+=20=20=20=20=20=20if=20(EQ=20(head,=20= QCsuccess))=0A=20=09success_handler=20=3D=20XCDR=20(tem);=0A=20=20=20=20=20= =20=20else=0A-=09clausenb++;=0A+=09{=0A+=09=20=20if=20(CONSP=20(head)=20= &&=20EQ=20(XCAR=20(head),=20QCcatch))=0A+=09=20=20=20=20{=0A+=09=20=20=20= =20=20=20if=20(NILP=20(XCDR=20(head))=20||=20!NILP=20(XCDR=20(XCDR=20= (head))))=0A+=09=09error=20("Invalid=20catch=20handler:=20%s",=0A+=09=09=20= =20=20=20=20=20=20SDATA=20(Fprin1_to_string=20(tem,=20Qt)));=0A+=09=20=20= =20=20=20=20Lisp_Object=20tag=20=3D=20eval_sub=20(XCAR=20(XCDR=20= (head)));=0A+=09=20=20=20=20=20=20tags=20=3D=20Fcons=20(tag,=20tags);=0A= +=09=20=20=20=20}=0A+=09=20=20clausenb++;=0A+=09}=0A=20=20=20=20=20}=0A=20= =0A=20=20=20/*=20The=20first=20clause=20is=20the=20one=20that=20should=20= be=20checked=20first,=20so=20it=0A@@=20-1386,7=20+1398,15=20@@=20= internal_lisp_condition_case=20(Lisp_Object=20var,=20Lisp_Object=20= bodyform,=0A=20=20=20=20=20=20=20Lisp_Object=20condition=20=3D=20CONSP=20= (clause)=20?=20XCAR=20(clause)=20:=20Qnil;=0A=20=20=20=20=20=20=20if=20= (!CONSP=20(condition))=0A=20=09condition=20=3D=20list1=20(condition);=0A= -=20=20=20=20=20=20struct=20handler=20*c=20=3D=20push_handler=20= (condition,=20CONDITION_CASE);=0A+=20=20=20=20=20=20struct=20handler=20= *c;=0A+=20=20=20=20=20=20if=20(EQ=20(XCAR=20(condition),=20QCcatch))=0A+=09= {=0A+=09=20=20Lisp_Object=20tag=20=3D=20XCAR=20(tags);=0A+=09=20=20tags=20= =3D=20XCDR=20(tags);=0A+=09=20=20c=20=3D=20push_handler=20(tag,=20= CATCHER);=0A+=09}=0A+=20=20=20=20=20=20else=0A+=09c=20=3D=20push_handler=20= (condition,=20CONDITION_CASE);=0A=20=20=20=20=20=20=20if=20(sys_setjmp=20= (c->jmp))=0A=20=09{=0A=20=09=20=20Lisp_Object=20val=20=3D=20= handlerlist->val;=0A@@=20-4409,6=20+4429,7=20@@=20syms_of_eval=20(void)=0A= =20=20=20defsubr=20(&Sunwind_protect);=0A=20=20=20defsubr=20= (&Scondition_case);=0A=20=20=20DEFSYM=20(QCsuccess,=20":success");=0A+=20= =20DEFSYM=20(QCcatch,=20":catch");=0A=20=20=20defsubr=20(&Ssignal);=0A=20= =20=20defsubr=20(&Scommandp);=0A=20=20=20defsubr=20(&Sautoload);=0Adiff=20= --git=20a/test/lisp/emacs-lisp/bytecomp-tests.el=20= b/test/lisp/emacs-lisp/bytecomp-tests.el=0Aindex=20= c9ab3ec1f1..fb123ab600=20100644=0A---=20= a/test/lisp/emacs-lisp/bytecomp-tests.el=0A+++=20= b/test/lisp/emacs-lisp/bytecomp-tests.el=0A@@=20-503,6=20+503,46=20@@=20= bytecomp-tests--test-cases=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20(:success=20'good))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20(1+=20x))))=0A=20=20=20=20=20=20=20(funcall=20f=203))=0A+=0A+=20=20= =20=20;;=20Catching=20throws,=20simple.=0A+=20=20=20=20(condition-case=20= x=0A+=20=20=20=20=20=20=20=20(throw=20'z=207)=0A+=20=20=20=20=20=20= ((:catch=20'z)=20(list=20'got-z=20x)))=0A+=20=20=20=20(condition-case=20= x=0A+=20=20=20=20=20=20=20=20(list=208)=0A+=20=20=20=20=20=20((:catch=20= 'z)=20(list=20'got-z=20x)))=0A+=0A+=20=20=20=20;;=20Catching=20throws.=0A= +=20=20=20=20(let=20((g=20(lambda=20(f)=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(let=20((tags=20(list=20'a=20'b)))=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(condition-case=20x=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(funcall=20f)=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20((:catch=20(prog1=20(car=20= tags)=20(setq=20tags=20(cdr=20tags))))=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(list=20'catch-a=20x))=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20((:catch=20(prog1=20(car=20tags)=20= (setq=20tags=20(cdr=20tags))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(list=20'catch-b=20x))=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(:success=20(list=20'ok=20x)))))))=0A+=20=20= =20=20=20=20(list=20(funcall=20g=20(lambda=20()=202))=0A+=20=20=20=20=20=20= =20=20=20=20=20=20(funcall=20g=20(lambda=20()=20(throw=20'a=203)))=0A+=20= =20=20=20=20=20=20=20=20=20=20=20(funcall=20g=20(lambda=20()=20(throw=20= 'b=205)))))=0A+=0A+=20=20=20=20;;=20Catching=20throws=20and=20errors.=0A= +=20=20=20=20(let=20((g=20(lambda=20(f)=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(let=20((tags=20(list=20'a=20'b)))=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(condition-case=20x=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(funcall=20f)=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20((:catch=20(prog1=20(car=20= tags)=20(setq=20tags=20(cdr=20tags))))=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(list=20'catch-a=20x))=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20(arith-error=20(list=20'arith=20x))=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20((:catch=20= (prog1=20(car=20tags)=20(setq=20tags=20(cdr=20tags))))=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20'catch-b=20x))=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(error=20(list=20= 'err=20x))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (:success=20(list=20'ok=20x)))))))=0A+=20=20=20=20=20=20(list=20(funcall=20= g=20(lambda=20()=202))=0A+=20=20=20=20=20=20=20=20=20=20=20=20(funcall=20= g=20(lambda=20()=20(throw=20'a=203)))=0A+=20=20=20=20=20=20=20=20=20=20=20= =20(funcall=20g=20(lambda=20()=20(throw=20'b=205)))=0A+=20=20=20=20=20=20= =20=20=20=20=20=20(funcall=20g=20(lambda=20()=20(/=201=200)))=0A+=20=20=20= =20=20=20=20=20=20=20=20=20(funcall=20g=20(lambda=20()=20(signal=20= 'error=20nil)))))=0A=20=20=20=20=20)=0A=20=20=20"List=20of=20expressions=20= for=20cross-testing=20interpreted=20and=20compiled=20code.")=0A=20=0A@@=20= -1310,7=20+1350,56=20@@=20bytecomp-condition-case-success=0A=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(:success=20'good))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20(1+=20x))))=0A=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20(funcall=20f=203))=0A-=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=204)))=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=204))=0A+=0A+=20=20;;=20Catching=20throws,=20= simple.=0A+=20=20(should=20(equal=20(condition-case=20x=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(throw=20'z=207)=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20((:catch=20'z)=20= (list=20'got-z=20x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20'(got-z=207)))=0A+=0A+=20=20(should=20(equal=20(condition-case=20x=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20= 8)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20((:catch=20= 'z)=20(list=20'got-z=20x)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20'(8)))=0A+=0A+=20=20;;=20Catching=20throws.=0A+=20=20(should=20= (equal=0A+=20=20=20=20=20=20=20=20=20=20=20(let=20((g=20(lambda=20(f)=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20= ((tags=20(list=20'a=20'b)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(condition-case=20x=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(funcall=20= f)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20((:catch=20(prog1=20(car=20tags)=20(setq=20tags=20(cdr=20= tags))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(list=20'catch-a=20x))=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20((:catch=20(prog1=20(car=20= tags)=20(setq=20tags=20(cdr=20tags))))=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20'catch-b=20x))=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20(:success=20(list=20'ok=20x)))))))=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20(list=20(funcall=20g=20(lambda=20()=202))=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20(funcall=20g=20(lambda=20()=20(throw=20= 'a=203)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (funcall=20g=20(lambda=20()=20(throw=20'b=205)))))=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20'((ok=202)=20(catch-a=203)=20(catch-b=20= 5))))=0A+=0A+=20=20;;=20Catching=20throws=20and=20errors.=0A+=20=20= (should=20(equal=0A+=20=20=20=20=20=20=20=20=20=20=20(let=20((g=20= (lambda=20(f)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20(let=20((tags=20(list=20'a=20'b)))=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(condition-case=20x=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(funcall=20f)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20((:catch=20(prog1=20(car=20tags)=20(setq=20tags=20= (cdr=20tags))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(list=20'catch-a=20x))=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(arith-error=20= (list=20'arith=20x))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20((:catch=20(prog1=20(car=20tags)=20(setq=20= tags=20(cdr=20tags))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20(list=20'catch-b=20x))=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(error=20= (list=20'err=20x))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(:success=20(list=20'ok=20x)))))))=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20(list=20(funcall=20g=20(lambda=20()=202))=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(funcall=20g=20= (lambda=20()=20(throw=20'a=203)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(funcall=20g=20(lambda=20()=20(throw=20'b=205)))=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(funcall=20g=20= (lambda=20()=20(/=201=200)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(funcall=20g=20(lambda=20()=20(signal=20'error=20nil)))))=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20'((ok=202)=20= (catch-a=203)=20(catch-b=205)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(arith=20(arith-error))=20(err=20(error)))))=0A+=20=20)=0A= =20=0A=20;;=20Local=20Variables:=0A=20;;=20no-byte-compile:=20t=0A--=20=0A= 2.21.1=20(Apple=20Git-122.3)=0A=0A= --Apple-Mail=_46565640-A5B4-47B1-93EE-1B08F34AD9DE--