On Mon, May 03, 2004 at 10:46:28AM -0400, Dan Sugalski wrote:
> Okay, here's the rules for PMCs that live outside parrot, and calling
> into parrot from the outside.
>
> 1) *ALL* PMCs which are created outside parrot must be registered
> (unless they're otherwise anchored)
> 2) No call into parrot from the outside needs to pass in a stack top
> (though it may via a separate call if it so chooses)
> 3) The embedding wrapper is responsible for setting and resetting the
> top of stack.
With the appended hack patch which sets/clears the stack top pointer,
ponie will run with the default parrot gc (rather than gc=mallc)
Yes, no prototypes anywhere, no idea what the names should be,
not sure which file they should be in, and I only wrapped the minimal set
of functions that ponie is currently using.
Plus I called the function in the same file that I was wrapping, which
imposes a needles extra level of function call overhead. What would seem
more sane is a way to make two versions of all the extending/embedding
functions, one which sets/clears the stack top (for embedders' use) and
one which does not (for extenders' use, or anyone who is in a position to
structure their own code/project to set the stack top once and in the
correct place)
How should this be?
Nicholas Clark
diff -d -u -r1.26 extend.c
--- src/extend.c 3 May 2004 12:29:02 -0000 1.26
+++ src/extend.c 7 May 2004 20:15:20 -0000
@@ -789,6 +789,60 @@
dod_unregister_pmc(interpreter, pmc);
}
+
+void *
+Parrot_Embed_PMC_get_pointer(Parrot_Interp interp, Parrot_PMC pmc) {
+ if(interp->lo_var_ptr) {
+ return Parrot_PMC_get_pointer(interp, pmc);
+ } else {
+ void *result; /* Doubles up as an indicator of stack top. */
+ interp->lo_var_ptr=&result;
+ result = Parrot_PMC_get_pointer(interp, pmc);
+ interp->lo_var_ptr=NULL;
+ return result;
+ }
+}
+
+Parrot_PMC
+Parrot_Embed_PMC_new(Parrot_INTERP interp, Parrot_Int type) {
+ if(interp->lo_var_ptr) {
+ return Parrot_PMC_new(interp, type);
+ } else {
+ Parrot_PMC result;
+ interp->lo_var_ptr=&result;
+ result = Parrot_PMC_new(interp, type);
+ interp->lo_var_ptr=NULL;
+ return result;
+ }
+}
+
+void
+Parrot_Embed_register_pmc(Parrot_INTERP interp, Parrot_PMC pmc)
+{
+ if(interp->lo_var_ptr) {
+ Parrot_register_pmc(interp, pmc);
+ } else {
+ int top;
+ interp->lo_var_ptr=⊤
+ Parrot_register_pmc(interp, pmc);
+ interp->lo_var_ptr=NULL;
+ }
+}
+
+
+Parrot_Int
+Parrot_Extend_PMC_typenum(Parrot_INTERP interp, const char *class) {
+ if(interp->lo_var_ptr) {
+ return Parrot_PMC_typenum(interp, class);
+ } else {
+ Parrot_Int result;
+ interp->lo_var_ptr=&result;
+ result = Parrot_PMC_typenum(interp, class);
+ interp->lo_var_ptr=NULL;
+ return result;
+ }
+}
+
/*
=back