unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: "Mattias Engdegård" <mattiase@acm.org>
To: Lars Ingebrigtsen <larsi@gnus.org>
Cc: Emacs developers <emacs-devel@gnu.org>
Subject: Re: master 5252c45: Initialise unread buffer
Date: Mon, 20 Sep 2021 12:16:24 +0200	[thread overview]
Message-ID: <0344BE6C-99E1-4DBB-ABD7-454DCF6C012B@acm.org> (raw)
In-Reply-To: <87sfy0mv33.fsf@gnus.org>

19 sep. 2021 kl. 17.41 skrev Lars Ingebrigtsen <larsi@gnus.org>:

> I'm not absolutely sure that it's your change that's causing this weird
> error, but it seemed the most likely.  :-/  And reverting back to the
> checkout before yours made the problem go away.

It's more fun actually. Thanks to the fixed reader bug, the lexical-binding cookie is now honoured in loadup.el. That causes Emacs to be dumped with `lexical-binding` set to t which as a consequence becomes the new default.

It's a testament to the sterling work by Stefan, Stefan, you, and everybody else that Emacs seems to work almost flawlessly anyway, but as it really wasn't our intention to do the switch now I've pushed an explicit binding of lexical-binding around the actual dumping so we're now back to normal.

What about the failing eval-tests then? They check, among other things, that

 (lambda (&rest) 'ok)

can be interpreted, byte-compiled, and returns `ok` when called. This fails with lexical binding enabled but works with dynamic binding, so when the default was inadvertently switched to lexical, the test started failing.

But wait, you protest. eval-tests.el is marked with -*- lexical-binding: t -*-. Surely? No?

Actually, any code in `ert-deftest` uses dynamic binding (until the accidental switch), regardless of the file cookie. Not many people know that.

So what is this bug that is still present? Let's take a look:

(byte-compile (lambda (&rest) 'ok))
=>
#[128 "\300\207" [ok] 1 "..."]

Let's pick it apart:
- The number 128 means that there are no positional args but a single &rest argument.
- The "\300\207" are the two byte-ops
   constant ok   ; push `ok` on the stack
   return        ; return the value on top of the stack
- The number 1 is the maximum stack size required.

When byte-code execution starts, the arguments are pushed on the stack -- in this case, a single nil for the &rest. The first byte-op then pushes the constant `ok`. But the stack is only sized for one element so that overwrites what follows, which is a copy of the byte-code. The smashed ops are then executed: if we are lucky we get an error, if unlucky an Emacs abort or crash.

I'm not sure why the byte-code interpreter makes a copy of the byte code for each function call. It certainly doesn't help the lamentably high function call overhead a bit. Most likely it's programmer, not code, efficiency that was optimised: since GC can move string data, the pc would need to be rebased each time that can occur, and that might need to be done in a lot of places. We should probably do something about that.

If the argument is named, then we get:

(byte-compile (lambda (&rest _x) 'ok))
=>
#[128 "\300\207" [ok] 2 "..."]

Note the max depth 2 here which gives a sufficiently big stack.

There's a number of things to fix here, but this message is too long already. Thanks for your interest! There are books for sale in the foyer.




  reply	other threads:[~2021-09-20 10:16 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20210919142251.2698.98689@vcs0.savannah.gnu.org>
     [not found] ` <20210919142252.B0B1520ABE@vcs0.savannah.gnu.org>
2021-09-19 14:26   ` master 5252c45: Initialise unread buffer Lars Ingebrigtsen
2021-09-19 14:56     ` Lars Ingebrigtsen
2021-09-19 15:39       ` Mattias Engdegård
2021-09-19 15:41         ` Lars Ingebrigtsen
2021-09-20 10:16           ` Mattias Engdegård [this message]
2021-09-20 10:30             ` tomas
2021-09-20 14:44             ` Lars Ingebrigtsen
2021-10-01 19:59             ` Stefan Monnier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0344BE6C-99E1-4DBB-ABD7-454DCF6C012B@acm.org \
    --to=mattiase@acm.org \
    --cc=emacs-devel@gnu.org \
    --cc=larsi@gnus.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).