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


The attached patch allows you to fetch nested structs from their
enclosing structs.

It has two limitations:

        - it reuses the PMC from the struct initializer, so there's a
possibility of yanking the rug out from someone else
        - it only handles pointers to structs

Neither is difficult to work around, but I wanted to solicit feedback
before doing much more work on this.

-- c


Index: t/pmc/nci.t
===================================================================
RCS file: /cvs/public/parrot/t/pmc/nci.t,v
retrieving revision 1.39
diff -u -u -r1.39 nci.t
--- t/pmc/nci.t	4 May 2004 12:55:33 -0000	1.39
+++ t/pmc/nci.t	6 May 2004 06:50:24 -0000
@@ -17,7 +17,7 @@
 
 =cut
 
-use Parrot::Test tests => 32;
+use Parrot::Test tests => 33;
 use Parrot::Config;
 
 SKIP: {
@@ -568,6 +568,75 @@
 200.000000
 OUTPUT
 
+output_is(<<'CODE', <<'OUTPUT', "nci_p_i - nested struct * with named access");
+  loadlib P1, "libnci"
+  dlfunc P0, P1, "nci_pi", "pi"
+  set I5, 8
+  invoke
+.include "datatypes.pasm"
+  # the contained structure pointer
+  new  P6, .OrderedHash
+  set  P6[ 'i' ], .DATATYPE_INT
+  push P6, 0
+  push P6, 0
+  set  P6[ 'j' ], .DATATYPE_INT
+  push P6, 0
+  push P6, 0
+  new P7, .UnManagedStruct, P6
+  # the contained structure
+  new  P3, .OrderedHash
+  set  P3[ 'i'  ], .DATATYPE_INT
+  push P3, 0
+  push P3, 0
+  set  P3[ 'j'  ], .DATATYPE_INT
+  push P3, 0
+  push P3, 0
+  set  P3[ '_z' ], .DATATYPE_STRUCT_PTR
+  set  P1, P3[-1]
+  setprop P1, "_struct", P7
+  push P3, 0
+  push P3, 0
+  new P4, .UnManagedStruct, P3
+  # outer structure
+  new P2, .OrderedHash
+  set  P2[ 'x'  ], .DATATYPE_INT
+  push P2, 0
+  push P2, 0
+  set  P2[ '_y' ], .DATATYPE_STRUCT
+  # attach the unmanged struct as property
+  set P1, P2[-1]
+  setprop P1, "_struct", P4
+  push P2, 0
+  push P2, 0
+  set  P2[ 'z'  ], .DATATYPE_INT
+  push P2, 0
+  push P2, 0
+  # attach struct initializer
+  assign P5, P2
+  set I0, P5[ 'x' ]
+  print I0
+  print "\n"
+  set I0, P5[ '_y'; 'i' ]
+  print I0
+  print "\n"
+  set I0, P5[ '_y'; 'j' ]
+  print I0
+  print "\n"
+  set I0, P5[ '_y'; '_z'; 'i' ]
+  print I0
+  print "\n"
+  set I0, P5[ '_y'; '_z'; 'j' ]
+  print I0
+  print "\n"
+  end
+CODE
+32
+127
+12345
+100
+77
+OUTPUT
+
 output_is(<<'CODE', <<'OUTPUT', "nci_p_i - func_ptr*");
   loadlib P1, "libnci"
   dlfunc P0, P1, "nci_pi", "pi"
@@ -1178,7 +1247,8 @@
   invoke
 
   set I0, P5[ 'x' ]
-  set I1, P5[ 'nested'; 'y' ]
+  set P6, P5[ 'nested' ]
+  set I1, P6[ 'y' ]
   print "X: "
   print I0
   print "\nY: "
Index: classes/unmanagedstruct.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/unmanagedstruct.pmc,v
retrieving revision 1.41
diff -u -u -r1.41 unmanagedstruct.pmc
--- classes/unmanagedstruct.pmc	4 May 2004 07:59:15 -0000	1.41
+++ classes/unmanagedstruct.pmc	6 May 2004 06:50:36 -0000
@@ -323,6 +323,28 @@
                 }
             }
             return ret;
+		case enum_type_struct_ptr:
+
+			/* check the metadata for an initializer */
+			init = PMC_pmc_val( pmc ); 
+           ptr  = VTABLE_get_pmc_keyed_int( interpreter, init, idx * 3 );
+
+			/* grab the struct from the metadata */
+           if (ptr->pmc_ext && PMC_metadata( ptr ))
+			{
+                ret = VTABLE_getprop( interpreter, ptr,
+                    string_from_cstring(interpreter, "_struct", 0 ));
+			}
+			else
+			{
+            	internal_exception( 1,
+					"no initializer available for nested struct\n" );
+			}
+
+			/* assign the pointer */
+			PMC_data( ret ) = *(void**)p;
+
+			return ret;
         default:
             internal_exception(1, "returning unhandled pmc type in struct");
     }
Index: src/nci_test.c
===================================================================
RCS file: /cvs/public/parrot/src/nci_test.c,v
retrieving revision 1.26
diff -u -u -r1.26 nci_test.c
--- src/nci_test.c	4 May 2004 07:48:52 -0000	1.26
+++ src/nci_test.c	6 May 2004 06:50:47 -0000
@@ -239,6 +239,25 @@
                 };
                 return &_x;
             }
+		case 8:
+            {
+                static struct _z {
+                    int i;
+                    int j;
+                } zz = { 100, 77 };
+                static struct xt {
+                    int x;
+                    struct yt {
+                        int i;
+                        int j;
+                    	struct _z *z;
+                    } _y;
+                } _x = {
+                    32,
+                    { 127, 12345, &zz },
+                };
+                return &_x;
+            }
         default:
             fprintf(stderr, "unknown test number\n");
     }

Reply via email to