cvsuser 04/05/06 08:07:15
Modified: classes unmanagedstruct.pmc
src nci_test.c
t/pmc nci.t
Log:
[perl #29385] [PROPOSED PATCH] Return Nested Structs from Structs
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
Courtesy of Chromatic <[EMAIL PROTECTED]>
Revision Changes Path
1.42 +23 -1 parrot/classes/unmanagedstruct.pmc
Index: unmanagedstruct.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/unmanagedstruct.pmc,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -w -r1.41 -r1.42
--- unmanagedstruct.pmc 4 May 2004 07:59:15 -0000 1.41
+++ unmanagedstruct.pmc 6 May 2004 15:07:06 -0000 1.42
@@ -1,6 +1,6 @@
/*
Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-$Id: unmanagedstruct.pmc,v 1.41 2004/05/04 07:59:15 leo Exp $
+$Id: unmanagedstruct.pmc,v 1.42 2004/05/06 15:07:06 leo Exp $
=head1 NAME
@@ -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");
}
1.27 +19 -0 parrot/src/nci_test.c
Index: nci_test.c
===================================================================
RCS file: /cvs/public/parrot/src/nci_test.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -w -r1.26 -r1.27
--- nci_test.c 4 May 2004 07:48:52 -0000 1.26
+++ nci_test.c 6 May 2004 15:07:11 -0000 1.27
@@ -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");
}
1.41 +79 -4 parrot/t/pmc/nci.t
Index: nci.t
===================================================================
RCS file: /cvs/public/parrot/t/pmc/nci.t,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -w -r1.40 -r1.41
--- nci.t 6 May 2004 07:12:53 -0000 1.40
+++ nci.t 6 May 2004 15:07:15 -0000 1.41
@@ -1,6 +1,6 @@
#! perl -w
# Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-# $Id: nci.t,v 1.40 2004/05/06 07:12:53 leo Exp $
+# $Id: nci.t,v 1.41 2004/05/06 15:07:15 leo Exp $
=head1 NAME
@@ -17,7 +17,7 @@
=cut
-use Parrot::Test tests => 33;
+use Parrot::Test tests => 34;
use Parrot::Config;
SKIP: {
@@ -586,6 +586,75 @@
200.000000
OUTPUT
+output_is(<<'CODE', <<'OUTPUT', "nci_p_i - nested struct * w named access");
+ loadlib P1, "libnci"
+ dlfunc P0, P1, "nci_pi", "pi"
+ set I5, 8 # test fun number
+ 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"
@@ -1196,19 +1265,25 @@
invoke
set I0, P5[ 'x' ]
- set I1, P5[ 'nested'; 'y' ]
+ set P6, P5[ 'nested' ]
+ set I1, P6[ 'y' ]
print "X: "
print I0
print "\nY: "
print I1
print "\n"
-
+ # extract struct
+ set P6, P5[ 'nested' ]
+ set I1, P6[ 'y' ]
+ print I1
+ print "\n"
end
CODE
Old X: 100
Old Y: 200
X: 1
Y: 2
+2
OUTPUT
} # SKIP