# New Ticket Created by  Sam Ruby 
# Please include the string:  [perl #32322]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org:80/rt3/Ticket/Display.html?id=32322 >


Parts of this should have been done in my previous patch, but at the 
time wasn't needed.  As the first to need it, I guess I get to implement 
it.  ;-)

- Sam Ruby
Index: lib/Parrot/Pmc2c.pm
===================================================================
RCS file: /cvs/public/parrot/lib/Parrot/Pmc2c.pm,v
retrieving revision 1.49
diff -u -r1.49 Pmc2c.pm
--- lib/Parrot/Pmc2c.pm 4 Nov 2004 09:07:20 -0000       1.49
+++ lib/Parrot/Pmc2c.pm 4 Nov 2004 16:23:44 -0000
@@ -126,17 +126,8 @@
  * This load function will be called to do global (once) setup
  * whatever is needed to get this extension running
  */
-#include "parrot/parrot.h"
-#include "parrot/extend.h"
-#include "parrot/dynext.h"
 
 EOC
-    for my $class (keys %classes) {
-        my $lc_class = lc $class;
-        $cout .= <<"EOC";
-#include "pmc_${lc_class}.h"
-EOC
-    }
     $cout .= <<"EOC";
 
 extern Parrot_PMC Parrot_lib_${lc_libname}_load(Parrot_INTERP interpreter); /* don't 
warn */
@@ -372,6 +363,11 @@
 sub includes() {
     my $self = shift;
     my $cout = "";
+    $cout .= <<"EOC";
+#include "parrot/parrot.h"
+#include "parrot/extend.h"
+#include "parrot/dynext.h"
+EOC
     foreach my $parents ($self->{class}, @{ $self->{parents} } ) {
        my $name = lc $parents;
        $cout .= <<"EOC";
@@ -740,6 +736,8 @@
     /*  Dynamic classes need the runtime type
        which is passed in entry to class_init.
     */
+    MMD_init *mmd_clone = mem_sys_allocate(sizeof(_temp_mmd_init));
+    memcpy(mmd_clone, _temp_mmd_init, sizeof(_temp_mmd_init));
 EOC
     # declare auxiliary variables for dyncpmc IDs
     foreach my $dynclass (keys %init_mmds) {
@@ -752,12 +750,12 @@
     foreach my $entry (@init_mmds) {
         if ($entry->[1] eq $classname) {
             $cout .= <<"EOC";
-    _temp_mmd_init[$entry->[0]].right = entry;
+    mmd_clone[$entry->[0]].right = entry;
 EOC
         }
         else {
             $cout .= <<"EOC";
-    _temp_mmd_init[$entry->[0]].right = my_enum_class_$entry->[1];
+    mmd_clone[$entry->[0]].right = my_enum_class_$entry->[1];
 EOC
         }
     }
@@ -812,14 +810,26 @@
 
     # declare each nci method for this class
     my $firstnci = 1;
+    my $my_enum_class;
+    if ($self->{flags}{dynpmc}) {
+       $my_enum_class = "my_enum_class_${classname}";
+    }
+    else {
+       $my_enum_class = "enum_class_${classname}";
+    }
     foreach my $method (@{ $self->{methods} }) {
       next unless $method->{loc} eq 'nci';
       my $proto = proto($method->{type}, $method->{parameters});
-      $cout .= <<"EOC" if $firstnci;
+      if ($firstnci) {
+          $cout .= <<"EOC";
     if (pass) {
 EOC
+          $cout .= <<"EOC" if $self->{flags}{dynpmc};
+        int my_enum_class_$classname = Parrot_PMC_typenum(interp, "$classname");
+EOC
+      }
       $cout .= <<"EOC";
-        enter_nci_method(interp, enum_class_${classname},
+        enter_nci_method(interp, $my_enum_class,
                 F2DPTR(Parrot_${classname}_$method->{meth}),
                 "$method->{meth}", "$proto");
 EOC
@@ -846,12 +856,12 @@
     foreach my $entry (@init_mmds) {
         if ($entry->[1] eq $classname) {
             $cout .= <<"EOC";
-        _temp_mmd_init[$entry->[0]].right = entry;
+        mmd_clone[$entry->[0]].right = entry;
 EOC
         }
         else {
             $cout .= <<"EOC";
-        _temp_mmd_init[$entry->[0]].right = my_enum_class_$entry->[1];
+        mmd_clone[$entry->[0]].right = my_enum_class_$entry->[1];
 EOC
         }
     }
@@ -865,7 +875,7 @@
     $cout .= <<"EOC";
 #define N_MMD_INIT (sizeof(_temp_mmd_init)/sizeof(_temp_mmd_init[0]))
         Parrot_mmd_register_parents(interp, entry,
-            _temp_mmd_init, N_MMD_INIT);
+            mmd_clone, N_MMD_INIT);
     }
 } /* Parrot_${classname}_class_init */
 EOC
@@ -1647,6 +1657,7 @@
     my ($self, $file) = @_;
     my $cout = Parrot::Pmc2c->dont_edit('various files');
 
+    $cout .= $self->includes;
     $cout .= Parrot::Pmc2c::dynext_load_code($self->{opt}{library},
                                              map { $_->{class} => $_ }
                                                  values %{$self->{pmcs}} );
@@ -1654,6 +1665,29 @@
     return $cout;
 }
 
+=item C<includes()>
+
+Returns the set of C C<#include>s for the library.
+
+=cut
+
+sub includes() {
+    my $self = shift;
+    my $cout = "";
+    $cout .= <<"EOC";
+#include "parrot/parrot.h"
+#include "parrot/extend.h"
+#include "parrot/dynext.h"
+EOC
+    foreach my $pmc (values %{$self->{pmcs}}) {
+       my $name = lc $pmc->{class};
+       $cout .= <<"EOC";
+#include "pmc_$name.h"
+EOC
+    }
+    "$cout\n";
+}
+
 =back
 
 =head1 SEE ALSO

Reply via email to