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