Skip to content

Commit

Permalink
Merge branch 'post-release-2018.06'
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexDaniel committed Jun 18, 2018
2 parents 61878c3 + 708c132 commit 6698b12
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 6 deletions.
46 changes: 46 additions & 0 deletions src/Perl6/Optimizer.nqp
Expand Up @@ -1397,6 +1397,9 @@ class Perl6::Optimizer {
elsif $op.name eq 'dispatch:<::>' {
return self.optimize_qual_method_call: $op;
}
elsif $op.name eq 'dispatch:<.?>' {
return self.optimize_maybe_method_call: $op;
}
}

if $op.op eq 'chain' {
Expand Down Expand Up @@ -2104,6 +2107,49 @@ class Perl6::Optimizer {
return $op;
}

method optimize_maybe_method_call($op) {
# Spesh plugins only available on MoarVM.
return $op unless nqp::getcomp('perl6').backend.name eq 'moar';

# We can only optimize if we have a compile-time-known name.
my $name_node := $op[1];
if nqp::istype($name_node, QAST::Want) && $name_node[1] eq 'Ss' {
$name_node := $name_node[2];
}
return $op unless nqp::istype($name_node, QAST::SVal);

# We need to evaluate the invocant only once, so will bind it into
# a temporary.
my $inv := $op.shift;
my $name := $op.shift;
my @args;
while $op.list {
nqp::push(@args, $op.shift);
}
my $temp := QAST::Node.unique('inv_once');
$op.op('stmts');
$op.push(QAST::Op.new(
:op('bind'),
QAST::Var.new( :name($temp), :scope('local'), :decl('var') ),
$inv
));
$op.push(QAST::Op.new(
:op('call'),
QAST::Op.new(
:op('speshresolve'),
QAST::SVal.new( :value('maybemeth') ),
QAST::Op.new(
:op('decont'),
QAST::Var.new( :name($temp), :scope('local') )
),
$name,
),
QAST::Var.new( :name($temp), :scope('local') ),
|@args
));
return $op;
}

method optimize_for_range($op, $callee, $c2) {
my $code := $callee.ann('code_object');
my $count := $code.count;
Expand Down
2 changes: 2 additions & 0 deletions src/core/Parameter.pm6
Expand Up @@ -36,6 +36,8 @@ my class Parameter { # declared in BOOTSTRAP

my constant $SIG_ELEM_IS_NOT_POSITIONAL = $SIG_ELEM_SLURPY_POS
+| $SIG_ELEM_SLURPY_NAMED
+| $SIG_ELEM_SLURPY_LOL
+| $SIG_ELEM_SLURPY_ONEARG
+| $SIG_ELEM_IS_CAPTURE;
my constant $SIG_ELEM_IS_SLURPY = $SIG_ELEM_SLURPY_POS
+| $SIG_ELEM_SLURPY_NAMED
Expand Down
15 changes: 10 additions & 5 deletions src/core/REPL.pm6
Expand Up @@ -384,16 +384,21 @@ do {
$*CTXSAVE := 0;
}

method input-incomplete(Mu $value) {
$value.WHERE == $!need-more-input.WHERE
method input-incomplete(Mu $value --> Bool:D) {
nqp::p6bool(nqp::can($value, 'WHERE'))
and $value.WHERE == $!need-more-input.WHERE
}

method input-toplevel-control(Mu $value) {
$value.WHERE == $!control-not-allowed.WHERE
method input-toplevel-control(Mu $value --> Bool:D) {
nqp::p6bool(nqp::can($value, 'WHERE'))
and $value.WHERE == $!control-not-allowed.WHERE
}

method repl-print(Mu $value --> Nil) {
say $value;
nqp::can($value, 'gist')
and $value.say
or say "(low-level object `$value.^name()`)";

CATCH {
default { say $_ }
}
Expand Down
19 changes: 19 additions & 0 deletions src/vm/moar/spesh-plugins.nqp
@@ -1,3 +1,6 @@
## Method plugins
## Only used when the name is a constant at the use site!

# Private method resolution can be specialized based on invocant type. This is
# used for speeding up resolution of private method calls in roles; those in
# classes can be resolved by static optimization.
Expand All @@ -24,3 +27,19 @@ nqp::speshreg('perl6', 'qualmeth', -> $obj, str $name, $type {
}
}
});

# A call like `$obj.?foo` is probably worth specializing via the plugin. In
# some cases, it will be code written to be generic that only hits one type
# of invocant under a given use case, so we can handle it via deopt. Even if
# there are a few different invocant types, the table lookup from the guard
# structure is still likely faster than the type lookup. (In the future, we
# should consider an upper limit on table size for the really polymorphic
# things).
sub discard-and-nil(*@pos, *%named) { Nil }
nqp::speshreg('perl6', 'maybemeth', -> $obj, str $name {
nqp::speshguardtype($obj, $obj.WHAT);
my $meth := $obj.HOW.find_method($obj, $name);
nqp::isconcrete($meth)
?? $meth
!! &discard-and-nil
});
6 changes: 5 additions & 1 deletion t/02-rakudo/repl.t
Expand Up @@ -3,7 +3,7 @@ use lib <t/packages>;
use Test;
use Test::Helpers;

plan 43;
plan 44;

my $*REPL-SCRUBBER = -> $_ is copy {
s/^^ "You may want to `zef install Readline` or `zef install Linenoise`"
Expand Down Expand Up @@ -303,3 +303,7 @@ is-run-repl 'say "b".subst(/(.)/,{$0~$0}); say "%20" ~~ /:i \%(<[0..9A..F]>**2)/
:out{.contains('bb') and .contains('aa') and not .contains('2020')},
:err(''),
no sticky $0 values across lines;

# https://github.com/rakudo/rakudo/issues/1925
is-run-repl '&say.package', :out{.contains: 'GLOBAL'}, :err(''),
REPL can auto-print non-Mu things that lack .WHERE and .gist;

0 comments on commit 6698b12

Please sign in to comment.