On 5/10/07, via RT Alek Storm <[EMAIL PROTECTED]> wrote:
# New Ticket Created by  "Alek Storm"
# Please include the string:  [perl #42919]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=42919 >


Because PIR can't tell the difference between invoking an object PMC and
invoking a sub PMC, it doesn't generate a correct set_args when an object is
invoked.  Since the 'invoke' override is a method, it expects the current
object to be the first parameter.  There are currently two workarounds: pass
the current object explicitly as the first parameter, or don't declare
'invoke' as a :method.  The first is inconvenient and unintuitive, and the
second means 'invoke' doesn't get access to its own object.

Example code for bug:
.sub _ :main
  $P0 = newclass "Foo"
  $P1 = new "Foo"
  $P1("bar")
.end

.namespace ["Foo"]
.sub 'invoke' :method :vtable
  .param string bar
  say bar
  self.'baz'()
.end

.sub 'baz' :method
  say "baz"
.end

Output:
too few arguments passed (1) - 2 params expected
current instr.: 'parrot;Foo;invoke' pc 16 (/home/alek/test2.pir:8)
called from Sub '_' pc 11 (/home/alek/test2.pir:4)

I've attached a patch that fixes this by grabbing the args signature inside
delegate.invoke() and unshifting an arg of type PARROT_ARG_PMC |
PARROT_ARG_OBJECT.  It also modifies src/inter_call.c to handle this by
setting the arg equal to interp->current_object, and enums.h to add the new
argument flag.  The tests in t/pmc/parrotobject.t have been changed to
include :method on the 'invoke' overrides, and to remove the test for
#41732, which is no longer applicable.

--
Alek Storm

Should we not be able to use an object that implements 'invoke' as a
method of another object? There is some strange behaviour when I try
to.


.sub main :main
   $P0 = newclass 'Func'
   $P1 = newclass 'Obj'
   $P2 = new 'Obj'
   $P2.'some_method'()
.end

.namespace ['Func']

.sub invoke :vtable :method
   .param pmc an_arg

   print 'vtable invoke with self = "'
   print self
   print '", arg = "'
   print an_arg
   say '"'
.end

.sub get_string :vtable
   .return ('an instance of Func')
.end

.namespace ['Obj']

.sub find_method :vtable :method
   .param string meth_name

   print 'find_method "'
   print meth_name
   print '" from "'
   print self
   say '" (***)'


   .local pmc func
   func = new 'Func'
   .return (func)
.end

.sub get_string :vtable
   .return ('an instance of Obj')
.end

=====

I expect as output:

find_method "some_method" from "an instance of Obj" (***)
vtable invoke with self = "an instance of Func", arg = "an instance of Obj"

I don't know about the internals of parameter passing, it could be
that it's not possible.


The current output is:

find_method "some_method" from "an instance of Obj" (***)
vtable invoke with self = "an instance of Func", arg = "" (***)"

Some strange things are happening with registers.

--
Mehmet

Reply via email to