Skip to content

Commit b7111e8

Browse files
committed
First pass at updating multi-subs. They get the same code object and signature handling as multi-methods now. Passes the tests, though some known incompleteness.
1 parent 567beb2 commit b7111e8

File tree

1 file changed

+24
-37
lines changed

1 file changed

+24
-37
lines changed

src/NQPQ/Actions.pm

Lines changed: 24 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -795,26 +795,22 @@ class NQP::Actions is HLL::Actions {
795795
$past.name($name);
796796
if $*SCOPE eq '' || $*SCOPE eq 'my' || $*SCOPE eq 'our' {
797797
if $*MULTINESS eq 'multi' {
798-
# Does the current block have a candidate holder in place?
799-
if $*SCOPE eq 'our' { nqp::die('our-scoped multis not yet implemented') }
800-
my $cholder;
798+
# Does the current block have a proto?
799+
if $*SCOPE eq 'our' { nqp::die('a multi can not be our-scoped') }
800+
my $proto;
801801
my %sym := $*W.cur_lexpad().symbol($name);
802-
if %sym<cholder> {
803-
$cholder := %sym<cholder>;
802+
if %sym<proto> {
803+
$proto := %sym<value>;
804804
}
805805

806806
# Otherwise, no candidate holder, so add one.
807807
else {
808808
# Check we have a proto in scope.
809-
if %sym<proto> {
810-
# WTF, a proto is in this scope, but didn't set up a
811-
# candidate holder?!
812-
$/.CURSOR.panic('Internal Error: Current scope has a proto, but no candidate list holder was set up. (This should never happen.)');
813-
}
814809
my $found_proto;
815810
for $*W.get_legacy_block_list() {
816811
my %sym := $_.symbol($name);
817-
if %sym<proto> || %sym<cholder> {
812+
if %sym<proto> {
813+
$proto := %sym<value>;
818814
$found_proto := 1;
819815
}
820816
elsif %sym {
@@ -828,42 +824,33 @@ class NQP::Actions is HLL::Actions {
828824
}
829825

830826
# Set up dispatch routine in this scope.
831-
my $BLOCK := $*W.cur_lexpad();
832-
$cholder := QAST::Op.new( :op('list') );
833-
my $dispatch_setup := PAST::Op.new(
834-
:pirop('create_dispatch_and_add_candidates PPP'),
835-
PAST::Var.new( :name($name), :scope('outer') ),
836-
$cholder
837-
);
838-
$BLOCK[0].push(PAST::Var.new( :name($name), :isdecl(1), :directaccess(1),
839-
:viviself($dispatch_setup), :scope('lexical') ) );
840-
$BLOCK.symbol($name, :scope('lexical'), :cholder($cholder) );
827+
nqp::die("Dispatcher derivation NYI");
841828
}
829+
830+
# Create a code object and attach the signature.
831+
my $code := $*W.create_code($past, $name, 0);
832+
attach_multi_signature($code, $past);
842833

843-
# Add this candidate to the holder.
844-
$cholder.push($past);
845-
846-
# Build a type signature object for the multi-dispatcher to use.
847-
attach_multi_signature_to_parrot_sub($past);
834+
# Add this candidate to the proto.
835+
$proto.add_dispatchee($code);
836+
837+
# Ensure we emit the code block.
838+
my $BLOCK := $*W.cur_lexpad();
839+
$BLOCK[0].push($past);
848840
}
849841
elsif $*MULTINESS eq 'proto' {
850842
# Create a candidate list holder for the dispatchees
851843
# this proto will work over, and install them along
852844
# with the proto.
853845
if $*SCOPE eq 'our' { nqp::die('our-scoped protos not yet implemented') }
854-
my $cholder := QAST::Op.new( :op('list') );
846+
my $code := $*W.create_code($past, $name, 1);
855847
my $BLOCK := $*W.cur_lexpad();
856-
$BLOCK[0].push(PAST::Var.new( :name($name), :isdecl(1), :directaccess(1),
857-
:viviself($past), :scope('lexical') ) );
858-
$BLOCK[0].push(PAST::Op.new(
859-
:pirop('set_dispatchees 0PP'),
860-
PAST::Var.new( :name($name) ),
861-
$cholder
848+
$BLOCK[0].push(QAST::Op.new(
849+
:op('bind'),
850+
QAST::Var.new( :name($name), :scope('lexical'), :decl('var') ),
851+
$past
862852
));
863-
$BLOCK.symbol($name, :scope('lexical'), :proto(1), :cholder($cholder) );
864-
865-
# Need it to be a DispatcherSub.
866-
$past.pirflags(':instanceof("DispatcherSub")');
853+
$BLOCK.symbol($name, :scope('lexical'), :proto(1), :value($code) );
867854
}
868855
else {
869856
my $BLOCK := $*W.cur_lexpad();

0 commit comments

Comments
 (0)