Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Calling PIR from a PMC

4 views
Skip to first unread message

William Coleda

unread,
Mar 14, 2005, 9:58:49 PM3/14/05
to Perl 6 Internals
How does one call a PIR-defined sub from C?

My current best guess is, to invoke the PIR sub "Tcl::Joe":

PMC *invokeme;
STRING *Tcl,*joe;
Tcl = string_from_const_cstring(INTERP, "Tcl", 3);
joe = string_from_const_cstring(INTERP, "joe", 3);
invokeme = Parrot_find_global(INTERP, Tcl, joe);
VTABLE_invoke(INTERP,invokeme,????);

But I don't know what to put as the argument for "next" to VTABLE_invoke - I see some items in dynclasses/*.pmc use the string "next", the code seems to allow for NULL - neither of them seem to actually invoke my method. (a .sub with a single "print" statement)

Do I need to be setting up the calling conventions in my calling code? Is there some other step I'm missing? Is this already documented somewhere?

Jeff Horwitz

unread,
Mar 14, 2005, 11:25:39 PM3/14/05
to William Coleda, Perl 6 Internals
On Mon, 14 Mar 2005, William Coleda wrote:

> How does one call a PIR-defined sub from C?

use the Parrot_call_sub_* API.

here's how i do it in mod_parrot, using the Parrot_* datatypes and the
Parrot_call_sub_* API. some of the logic has been factored out into
different functions for code reuse, but you get the idea:

Parrot_PMC get_sub_pmc(Parrot_Interp interp, char *namespace, char *name)
{
Parrot_PMC sub;

sub = Parrot_find_global(
interp,
namespace ? MAKE_PARROT_STRING(namespace) : NULL,
MAKE_PARROT_STRING(name)
);
return(sub);
}

int modparrot_call_sub(Parrot_Interp interp, char *namespace, char *name,
int *ret)
{
Parrot_PMC sub;

sub = get_sub_pmc(interp, namespace, name);
if (!sub) {
return(0);
}
*ret = Parrot_call_sub_ret_int(interp, sub, "Iv");
return(1);
}

-jeff


William Coleda

unread,
Mar 15, 2005, 12:31:59 AM3/15/05
to Jeff Horwitz, Perl 6 Internals

Jeff Horwitz wrote:
> On Mon, 14 Mar 2005, William Coleda wrote:
>
>
>>How does one call a PIR-defined sub from C?
>
>
> use the Parrot_call_sub_* API.

Ah, thank you, much better.

Now, given the perldoc for src/extend.c,

"void* Parrot_call_sub(Parrot_INTERP interpreter, Parrot_PMC sub, const
char *signature, ...)"
Call a parrot subroutine the given function signature. The first
char in "signature" denotes the return value. Next chars are argu-
ments.

The return value of this function can be void or a pointer type.


If only the first character is the return value, how does one deal with subroutines that return multiple values?

Leopold Toetsch

unread,
Mar 15, 2005, 3:03:42 AM3/15/05
to William Coleda, perl6-i...@perl.org
William Coleda <wi...@coleda.com> wrote:

> If only the first character is the return value, how does one deal
> with subroutines that return multiple values?

Well, you can't access multiple return values from within the C
function, where you are calling the PIR code. OTOH, if the PIR code did
return more values, we should get them back to the caller.

We should probably have a new return signature for this, e.g.

"@" - collect all return values, stuff them into an array and return
that.

OTOH you could use Parrot_runops_fromc() and pick up return values from
the returned frame pointer C<bp>.

leo

0 new messages