Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Compute sig arity/count at compile time.
Before, probably for some historical reasons that are now gone, we did
this computation at runtime and cached it. This was bad for needing to
do the "did we compute it yet" check, but also because it triggered SC
write barriers, wasting time and bloating modules.
  • Loading branch information
jnthn committed Jan 24, 2014
1 parent 387664f commit 8004501
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 26 deletions.
33 changes: 31 additions & 2 deletions src/Perl6/World.nqp
Expand Up @@ -854,13 +854,42 @@ class Perl6::World is HLL::World {
my $signature := nqp::create($sig_type);
my @parameters := %signature_info<parameters>;
self.add_object($signature);

# Set parameters.
nqp::bindattr($signature, $sig_type, '$!params', @parameters);
if nqp::existskey(%signature_info, 'returns') {
nqp::bindattr($signature, $sig_type, '$!returns', %signature_info<returns>);
}


# Compute arity and count.
my $p_type := self.find_symbol(['Parameter']);
my int $arity := 0;
my int $count := 0;
my int $i := 0;
my int $n := nqp::elems(@parameters);
while $i < $n {
my $param := @parameters[$i];
my int $flags := nqp::getattr_i($param, $p_type, '$!flags');
if $flags +& ($SIG_ELEM_IS_CAPTURE +| $SIG_ELEM_SLURPY_POS +| $SIG_ELEM_SLURPY_LOL) {
$count := -1;
}
elsif !($flags +& $SIG_ELEM_SLURPY_NAMED) &&
nqp::isnull(nqp::getattr($param, $p_type, '$!named_names')) {
$count++;
$arity++ unless $flags +& $SIG_ELEM_IS_OPTIONAL;
}
$i++;
}
nqp::bindattr($signature, $sig_type, '$!arity',
$*W.add_constant('Int', 'int', $arity).value);
if $count == -1 {
nqp::bindattr($signature, $sig_type, '$!count',
$*W.add_constant('Num', 'num', nqp::inf()).value);
} else {
nqp::bindattr($signature, $sig_type, '$!count',
$*W.add_constant('Int', 'int', $count).value);
}

# Return created signature.
$signature
}
Expand Down
27 changes: 3 additions & 24 deletions src/core/Signature.pm
Expand Up @@ -2,8 +2,8 @@ my class Signature { # declared in BOOTSTRAP
# class Signature is Any {
# has Mu $!params; # VM's array of parameters
# has Mu $!returns; # return type
# has Mu $!arity; # cached arity
# has Mu $!count; # cached count
# has Mu $!arity; # arity
# has Mu $!count; # count
# has Mu $!code;

multi method ACCEPTS(Signature:D: Capture $topic) {
Expand Down Expand Up @@ -77,31 +77,10 @@ my class Signature { # declared in BOOTSTRAP
}

method arity() {
self.count if nqp::isnull($!arity) || !$!arity.defined;
$!arity;
$!arity
}

method count() {
if nqp::isnull($!count) || !$!count.defined {
# calculate the count and arity -- we keep them
# cached for when we're called the next time.
my $count = 0;
my $arity = 0;
my Mu $iter := nqp::iterator($!params);
my $param;
while $iter {
$param := nqp::shift($iter);
if $param.capture || $param.slurpy && !$param.named {
$count = Inf;
}
elsif $param.positional {
$count++;
$arity++ unless $param.optional;
}
}
nqp::bindattr(self, Signature, '$!arity', $arity);
nqp::bindattr(self, Signature, '$!count', $count);
}
$!count
}

Expand Down

0 comments on commit 8004501

Please sign in to comment.