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