The invoke vtable method is supposed to take one argument - the
address of the opcode immediately following the invokecc opcode, so we
can return to it later.  It then returns the address of the subroutine
to jump into.  The problem is that, in C, the invoke method takes and
returns an opcode_t*, and PIR can't handle that, so I've attached a
patch correcting the problem by converting the argument and return
value so the PIR plays nice.

Any ParrotObject overriding the invoke vtable method is probably not
going to care about addresses.  Luckily, all we have to do is return
the address we're given, so everything goes back to normal after the
method's finished.  The downside is that you're going to have to come
with a more creative workaround in order to be passed any arguments
that the method is called with.

.namespace ['Foo']

.sub __invoke :method
   .param int address
   say "you invoked me!"
   .return(address)
.end

.sub main :main
   $P0 = newclass "Foo"
   $P1 = new "Foo"
   $P1()
   say "got here"
.end

Thanks,
Alek Storm

On 3/7/07, via RT richard @ hive-systems. com
<[EMAIL PROTECTED]> wrote:
# New Ticket Created by  [EMAIL PROTECTED]
# Please include the string:  [perl #41733]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=41733 >


Hi There,

Given the following (latest svn today - parrot 0.49+):


.namespace ['Foo']

.sub invoke :vtable
    say "you invoked me!"
    .return()
.end

.sub main :main
    $P0 = newclass "Foo"
    $P1 = new "Foo"
    $P1()
    say "got here"
.end

The final "got here" is never printed.

Also parrot segfaults with the signature:
.sub invoke :vtable :method
    ...
.end

Not sure if that's allowed (:vtable :method), though.

Cheers,
Rich


--- src/pmc/delegate.pmc	2007-02-24 13:38:07.000000000 +0000
+++ src/pmc/delegate.pmc	2007-03-07 17:51:42.000000000 +0000
@@ -167,6 +167,19 @@
         /* don't delegate mark */
     }
 
+    void* invoke(void* next) {
+        STRING *meth = CONST_STRING(interp, "__invoke");
+        STRING *meth_v = CONST_STRING(interp, "invoke");
+        PMC *sub = Parrot_find_vtable_meth(INTERP, SELF, meth_v);
+        if (PMC_IS_NULL(sub))
+            sub = find_or_die(interp, SELF, meth);
+
+        /* convert argument from ptr into int for passing into PIR, then
+           convert return value back from int into ptr */
+        return INTVAL2PTR(opcode_t *, Parrot_run_meth_fromc_args_reti(interp, sub,
+            pmc, meth, "II", PTR2INTVAL(next)));
+    }
+
     PMC* instantiate(PMC* sig) {
         STRING *meth = const_string(INTERP,
                 PARROT_VTABLE_INSTANTIATE_METHNAME);

Reply via email to