From f6449a477023db15fce095e484d0a8ca30a94856 Mon Sep 17 00:00:00 2001 From: jnthn Date: Fri, 13 Mar 2009 16:13:31 +0100 Subject: [PATCH] Minor refactor of method dispatch so we can better handle foreign objects from outside Rakudo, as suggested by pmichaud++. --- src/builtins/guts.pir | 23 +++++++++++++++++++++++ src/parser/actions.pm | 20 ++++---------------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/builtins/guts.pir b/src/builtins/guts.pir index 5fa0ef2415c..fd46cb06253 100644 --- a/src/builtins/guts.pir +++ b/src/builtins/guts.pir @@ -88,6 +88,29 @@ from C. .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. diff --git a/src/parser/actions.pm b/src/parser/actions.pm index beeccca00a5..237d82ec0ac 100644 --- a/src/parser/actions.pm +++ b/src/parser/actions.pm @@ -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 := $inv_set_node[1]; + $past.name('!dispatch_method'); + $past.pasttype('call'); + $past := $past; } else { $past := $past;