# 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"); }