develooper Front page | perl.perl5.porters | Postings from December 2021

Re: "no snails"; or having signatured subs complain about @_

Thread Previous | Thread Next
From:
Paul "LeoNerd" Evans
Date:
December 7, 2021 00:28
Subject:
Re: "no snails"; or having signatured subs complain about @_
Message ID:
20211207002820.67b624a0@shy.leonerd.org.uk
I now have a partial attack on this, on a branch

  https://github.com/leonerd/perl5/tree/no-snails

On Sun, 5 Dec 2021 20:39:04 +0000
Nicholas Clark <nick@ccl4.org> wrote:

> > It seems to me we need four pieces. The first two of these should be
> > quite simple:
> > 
> >    1. Add a flag (maybe CvSIGNATURE(cv)) on CVs that is present when
> >       the sub has a signature. The parser can easily turn this one
> > on at the time it creates the CV.

Done, easy.

> >    2. Get pp_entersub to check that flag, and skip setting up the
> >       callee's @_ array if set. -- this is the core of the speedup.

TODO

> >    3. {handwavy something} to ensure that OP_ARGCHECK and OP_ARGELEM
> >       can look somewhere else to find the arguments, now they can no
> >       longer use GvAV(PL_defgv).

Done by just having them use PAD_SVl(0) instead of GvAV(PL_defgv). I'm
actually quite surprised how simple this was, and doesn't break any
tests :)

> >    4. {handwavy something else} to make accesses of @_ throw an
> > error at runtime.  

This part I'm in the middle of doing now:

> instead having GvAV(PL_defgv) pointing to a tied array singleton that
> is built to croak.

Actually rather than a tied array (because tie is so annoying to create
from inside core), I just created a new kind of magic; "forbid" magic.
This totally disallows any kind of access - all of its magic vtable
calls immediately croak.

And already this code has caught something. I can't even build perl
right now, because the build system makes miniperl and then uses
miniperl to build the unicore tables, getting as far as:

./miniperl -Ilib lib/unicore/mktables -C lib/unicore -P pod -maketest -makelist -p
Access to the @_ variable is forbidden (lenmagic) at lib/unicore/mktables line 1983.
make: *** [makefile:408: uni.data] Error 25

Hah! It really works :)

Lets peek at the source code:

  1883      sub set_access($name, $field, @accessors) {
...
  1983                  if (grep { /^a/i } @_
  1984                      or length($access) > length('readable_'))

Inside a real signatured sub, we already have code that tries to access
@_. Oops.

I suspect this code is supposed to read one of

  if(grep { /^a/i } @accessors

or

  if(grep { /^a/i } ($name, $field, @accessors)

but I can't immediately tell from context which. Perhaps someone
familiar with unicore can assist? For now I'll just rewrite it to my
best guess so I can get on with building perl. But it does appear that
overall this technique appears to have legs:

$ ./perl -Ilib -Mfeature=signatures -E 'sub f { say "slug0 is $_[0]" } f("hello")'
slug0 is hello

$ ./perl -Ilib -Mfeature=signatures -E 'sub f($x) { say "x is $x" } f("hello")'
The signatures feature is experimental at -e line 1.
x is hello

$ ./perl -Ilib -Mfeature=signatures -E 'sub f($x) { say "x is $x; slug0 is $_[0]" } f("hello")'
The signatures feature is experimental at -e line 1.
Access to the @_ variable is forbidden (getmagic) at -e line 1.

$ ./perl -Ilib -Mfeature=signatures -E 'sub f($x) { $_[0] = "boo" } f("hello")'
The signatures feature is experimental at -e line 1.
Access to the @_ variable is forbidden (getmagic) at -e line 1.

These are of course all runtime exceptions, and not compiletime ones,
but that's a further-out goal... :)

-- 
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk      |  https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/  |  https://www.tindie.com/stores/leonerd/

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About