Skip to content

Commit

Permalink
Minor refactor of method dispatch so we can better handle foreign obj…
Browse files Browse the repository at this point in the history
…ects from outside Rakudo, as suggested by pmichaud++.
  • Loading branch information
jnthn committed Mar 13, 2009
1 parent 76b2652 commit f6449a4
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 16 deletions.
23 changes: 23 additions & 0 deletions src/builtins/guts.pir
Expand Up @@ -88,6 +88,29 @@ from C<Any>.
.end


=item !dispatch_method

Does a method dispatch. If it's a foregin object, just calls it the Parrot
way. Otherwise, it uses .^dispatch from the metaclass.
=cut
.sub '!dispatch_method'
.param pmc obj
.param string name
.param pmc pos_args :slurpy
.param pmc name_args :slurpy :named
$I0 = can obj, 'HOW'
unless $I0 goto foreign
$P0 = obj.'HOW'()
.tailcall $P0.'dispatch'(obj, name, pos_args :flat, name_args :flat :named)
foreign:
.tailcall obj.name(pos_args :flat, name_args :flat :named)
.end
=item !VAR
Helper function for implementing the VAR and .VAR macros.
Expand Down
20 changes: 4 additions & 16 deletions src/parser/actions.pm
Expand Up @@ -1431,24 +1431,12 @@ method dotty($/, $key) {
}

# We actually need to send dispatches for named method calls (other than .*)
# through .HOW.dispatch.
# through the.dispatcher.
if $key ne '.*' && $past.pasttype() eq 'callmethod' && $past.name() ne "" {
$past.unshift($past.name());
$past.name('dispatch');
my $inv_var := PAST::Var.new( :scope('register') );
$past.unshift($inv_var);
$past.unshift(PAST::Op.new(
:pasttype('callmethod'),
:name('HOW'),
$inv_var
));
my $inv_set_node := PAST::Op.new(
:pasttype('bind'),
$inv_var,
PAST::Stmts.new()
);
$past := PAST::Stmts.new( $inv_set_node, $past );
$past<invocant_holder> := $inv_set_node[1];
$past.name('!dispatch_method');
$past.pasttype('call');
$past<invocant_holder> := $past;
}
else {
$past<invocant_holder> := $past;
Expand Down

0 comments on commit f6449a4

Please sign in to comment.