From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.devel Subject: Re: Contributing to Emacs Date: Fri, 09 Sep 2022 11:09:00 -0400 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="18601"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (gnu/linux) Cc: emacs-devel@gnu.org To: =?windows-1252?Q?Jo=E3o?= Paulo Labegalini de Carvalho Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Fri Sep 09 17:10:04 2022 Return-path: Envelope-to: ged-emacs-devel@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 1oWfdr-0004dA-T6 for ged-emacs-devel@m.gmane-mx.org; Fri, 09 Sep 2022 17:10:04 +0200 Original-Received: from localhost ([::1]:37004 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oWfdq-0006MJ-JF for ged-emacs-devel@m.gmane-mx.org; Fri, 09 Sep 2022 11:10:02 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:43716) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oWfcz-0004yP-DK for emacs-devel@gnu.org; Fri, 09 Sep 2022 11:09:09 -0400 Original-Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]:38589) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oWfcw-0002Ah-EK for emacs-devel@gnu.org; Fri, 09 Sep 2022 11:09:08 -0400 Original-Received: from pmg1.iro.umontreal.ca (localhost.localdomain [127.0.0.1]) by pmg1.iro.umontreal.ca (Proxmox) with ESMTP id 52EBC10010E; Fri, 9 Sep 2022 11:09:04 -0400 (EDT) Original-Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1]) by pmg1.iro.umontreal.ca (Proxmox) with ESMTP id 3A77710002F; Fri, 9 Sep 2022 11:09:02 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca; s=mail; t=1662736142; bh=Ld/ez/hYVeTZpOvoDhKXtgBb88Zj9gzG0H3zQsuZJCM=; h=From:To:Cc:Subject:In-Reply-To:References:Date:From; b=hHK2Cd8CBavScvFNtxcLOQzhrpvERLvpEbmM2BE2PS9lMgnALM3qydso5TVe9Q5VL SKRbD32QR69pA0SosiGcVo5jcCruVudJrc7s7zPUM8SYb7AcSBsNSP+T/alu3eVQko fEP/UzqfDNNNqsuceC9qGgVGHVs/KYpu5Egyl5gA0h4DuQvWo47izzPWnGuxSYmg+r zqdFLYmqNAfzScqF/yIQ/uUMRhIE9GyprBLE9PMhBdgp8QBZ2TdFccBBoac1bNSnux s8lFMaVk/GPr+CZP21swz7CWytWV8n/7eKQGohKlHXhP+ZCFZ5M/bgdO9kHEWSD9FK +05CQbEJo7jDQ== Original-Received: from alfajor (unknown [45.44.229.252]) by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id D235D1202E5; Fri, 9 Sep 2022 11:09:01 -0400 (EDT) In-Reply-To: (=?windows-1252?Q?=22Jo=E3o?= Paulo Labegalini de Carvalho"'s message of "Wed, 7 Sep 2022 14:01:06 -0600") Received-SPF: pass client-ip=132.204.25.50; envelope-from=monnier@iro.umontreal.ca; helo=mailscanner.iro.umontreal.ca X-Spam_score_int: -42 X-Spam_score: -4.3 X-Spam_bar: ---- X-Spam_report: (-4.3 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:295075 Archived-At: > I was looking at the file etc/TODO in the repo, and some items there > caught my attention. For example, under 'Important Features' I found 'Add > an "indirect goto" byte-code'. Is this still a desired feature or is it not > required due to recent efforts towards native compilation? (In the negative > case, please feel free to suggest another item for me to work on) I think I was the one to add this point to etc/TODO and AFAIK the need is pretty much still the same, yes. Part of the idea is to handle more efficiently code which uses local lambda expressions (like `cl-flet`). There's a lot of scope here. Some steps are easy but won't bring any (or very little) benefit, which others depend on those first steps and require much more extensive work. > If it is still desired I would like to work on it and would appreciate > guidance. After taking a look at lisp/emacs-lisp/bytecomp.el,it seems that > forms such as > > (let ((foo (lambda (x) bar))) > (dosomething > (funcall foo toto) > (blabla (funcall foo titi)))) > > are compiled by calling byte-compile-let. Before generating the binding for > foo, #'(lambda (x) bar) is compiled by calling > byte-compile-push-binding-init, which in turn compiles the lambda to > bytecode and pushes it to the stack. > > So to make it more concrete for my sake, I wrote the following form > > (let ((foo (lambda (x) (- x 1)))) > (* (funcall foo 2) > (- (funcall foo 3) 2))) Indeed, I think it might be fairly easy to handle this code more efficiently. Things become more ... interesting when we have code like: (let* ((count 0) (foo (lambda (x) (setq count (1+ count)) (+ x count)))) (* (funcall foo 2) (- (funcall foo 3) 2))) Where `cconv.el` turns the `count` into a one-element list and replaces the `setq` with a `setcar`, which wouldn't be needed if we could directly refer to the `count` var from the inner lambda using those new byte codes. Even more interesting would be (let* ((count 0) (foo (lambda (x) (setq count (1+ count)) (+ x count)))) (let ((bar (funcall foo 2))) (- (funcall foo 3) bar))) where the relative position of `count` on the stack is different in the two calls to `foo`. > and with disassemble inspected the generated bytecode by Emacs 28.1 > > byte code: > args: nil > 0 constant > args: (x) > 0 varref x > 1 sub1 > 2 return > > 1 dup > 2 varbind foo > 3 constant 2 > 4 call 1 > 5 varref foo > 6 constant 3 > 7 call 1 > 8 constant 2 > 9 diff > 10 mult > 11 unbind 1 > 12 return > > As far as I understood, the idea of the "indirect goto" here is to > eliminate the calls on lines 4 and 7 and replace them with an indirect > goto. The ones at 4 and 7 can stay as "normal" gotos but they need to pass to the function an additional argument which is the return address, and then the inner function would be the one which uses an indirect goto instead of "return". > stack* in line 0 (constant ). Thus, for the indirect > goto idea to work, the bytecode of the lambda would need to be part of the > bytecode of the let's body**. That way, a computed branch can branch into > the lambdas code and it is possible to branch out of it when returning. I guess in theory there could be cases where we could use a computed goto to jump into a function, but that needs probably too many stars to be aligned to be worth considering. The indirect goto is needed for "return", OTOH. > Aside from guidance on implementing this, I would appreciate any > pointers on how to adequately test it. I don't think there's currently many ways to test bytecode level operation, other than writing normal ELisp code which we expect will use those bytecodes and make sure they behave as expected. Stefan