cvsuser 04/02/05 07:41:24
Modified: classes unmanagedstruct.pmc
src nci_test.c
t/pmc nci.t
Log:
pointers to contained structs
Revision Changes Path
1.29 +43 -10 parrot/classes/unmanagedstruct.pmc
Index: unmanagedstruct.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/unmanagedstruct.pmc,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -w -r1.28 -r1.29
--- unmanagedstruct.pmc 5 Feb 2004 13:09:30 -0000 1.28
+++ unmanagedstruct.pmc 5 Feb 2004 15:41:17 -0000 1.29
@@ -1,7 +1,7 @@
/*
* Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
* CVS Info
- * $Id: unmanagedstruct.pmc,v 1.28 2004/02/05 13:09:30 leo Exp $
+ * $Id: unmanagedstruct.pmc,v 1.29 2004/02/05 15:41:17 leo Exp $
* Overview:
* PMC class to hold structs that parrot's not responsible for
* disposing of.
@@ -18,6 +18,8 @@
*/
#include "parrot/parrot.h"
+#include <assert.h>
+
INTVAL key_2_idx(Parrot_Interp interpreter, PMC *pmc, PMC *key);
@@ -27,12 +29,16 @@
size_t offs, n;
ix *= 3;
+ if (!PMC_pmc_val(pmc))
+ internal_exception(1, "Missing struct initializer");
n = (size_t)VTABLE_elements(interpreter, PMC_pmc_val(pmc));
if ((size_t)ix >= n)
internal_exception(1, "Non existent elements in struct");
/* use structure init */
- *type = (int) VTABLE_get_integer_keyed_int(interpreter, PMC_pmc_val(pmc), ix);
- offs = (size_t) VTABLE_get_integer_keyed_int(interpreter, PMC_pmc_val(pmc), ix
+ 2);
+ *type = (int) VTABLE_get_integer_keyed_int(interpreter,
+ PMC_pmc_val(pmc), ix);
+ offs = (size_t) VTABLE_get_integer_keyed_int(interpreter,
+ PMC_pmc_val(pmc), ix + 2);
return ((char *)PMC_data(pmc)) + offs;
}
@@ -40,6 +46,9 @@
key_2_idx(Parrot_Interp interpreter, PMC *pmc, PMC *key)
{
int ix;
+
+ if (!PMC_pmc_val(pmc))
+ internal_exception(1, "Missing struct initializer");
if (PObj_get_FLAGS(key) & KEY_string_FLAG) {
PMC *types = PMC_pmc_val(pmc);
if (types->vtable->base_type == enum_class_OrderedHash) {
@@ -63,7 +72,7 @@
char_offset_key(Parrot_Interp interpreter, PMC *pmc, PMC *key, int *type)
{
size_t offs, n, count, size, max;
- PMC *next;
+ PMC *next, *init;
int ix;
char *p;
@@ -74,7 +83,26 @@
if (!next)
return p;
count = (size_t) key_integer(interpreter, next);
- max = (size_t) VTABLE_get_integer_keyed_int(interpreter, PMC_pmc_val(pmc), ix +
1);
+ init = PMC_pmc_val(pmc);
+ max = (size_t) VTABLE_get_integer_keyed_int(interpreter, init, ix + 1);
+ /* TODO make that _struct_ptr */
+ if (*type == enum_type_ptr) {
+ PMC *ptr;
+ /* for now ignore count */
+ assert((int)max <= 1);
+ /* the struct PMC is hanging off the initializer element
+ * as property "_struct"
+ */
+ ptr = VTABLE_get_pmc_keyed_int(interpreter, init, ix);
+ init = VTABLE_getprop(interpreter, ptr,
+ string_from_cstring(interpreter, "_struct", 0));
+ assert(init && init->vtable->base_type == enum_class_UnManagedStruct);
+ /*
+ * now point PMC_data of this struct to the real data
+ */
+ PMC_data(init) = *(void**)p;
+ return char_offset_key(interpreter, init, next, type);
+ }
if (count >= max)
internal_exception(1, "Non existent array element in struct");
size = data_types[*type - enum_first_type].size;
@@ -277,9 +305,12 @@
PMC_pmc_val(SELF) = value;
for (i = 0; i < n; i += 3) {
- int type = (int) VTABLE_get_integer_keyed_int(interpreter, value, i);
- int count= (int) VTABLE_get_integer_keyed_int(interpreter, value, i+1);
- int offs = (int) VTABLE_get_integer_keyed_int(interpreter, value, i+2);
+ int type = (int) VTABLE_get_integer_keyed_int(interpreter,
+ value, i);
+ int count= (int) VTABLE_get_integer_keyed_int(interpreter,
+ value, i+1);
+ int offs = (int) VTABLE_get_integer_keyed_int(interpreter,
+ value, i+2);
if (type < enum_first_type || type >= enum_last_type)
internal_exception(1, "Illegal type in initializer for struct");
@@ -294,7 +325,8 @@
else
toff = offs;
toff += count * (data_types[type - enum_first_type].size);
- if (i == n - 3 && pmc->vtable->base_type == enum_class_ManagedStruct)
+ if (i == n - 3 &&
+ pmc->vtable->base_type == enum_class_ManagedStruct)
DYNSELF.set_integer_native(toff);
}
PObj_custom_mark_SET(SELF);
@@ -306,7 +338,8 @@
}
INTVAL is_equal (PMC* value) {
- return (SELF->vtable == value->vtable && PMC_data(SELF) == PMC_data(value));
+ return (SELF->vtable == value->vtable &&
+ PMC_data(SELF) == PMC_data(value));
}
INTVAL defined () {
1.17 +16 -0 parrot/src/nci_test.c
Index: nci_test.c
===================================================================
RCS file: /cvs/public/parrot/src/nci_test.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -w -r1.16 -r1.17
--- nci_test.c 5 Feb 2004 13:09:37 -0000 1.16
+++ nci_test.c 5 Feb 2004 15:41:21 -0000 1.17
@@ -145,6 +145,22 @@
};
return &t;
}
+ case 4:
+ {
+ static struct _x {
+ int i;
+ int j;
+ double d;
+ } xx = { 100, 77, 200.0 };
+ static struct {
+ char c;
+ struct _x *x;
+ } t = {
+ 10,
+ &xx
+ };
+ return &t;
+ }
}
return NULL;
}
1.23 +55 -1 parrot/t/pmc/nci.t
Index: nci.t
===================================================================
RCS file: /cvs/public/parrot/t/pmc/nci.t,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -w -r1.22 -r1.23
--- nci.t 5 Feb 2004 13:09:40 -0000 1.22
+++ nci.t 5 Feb 2004 15:41:24 -0000 1.23
@@ -1,4 +1,4 @@
-use Parrot::Test tests => 20;
+use Parrot::Test tests => 21;
use Parrot::Config;
print STDERR $PConfig{jitcpuarch}, " JIT CPU\n";
@@ -489,6 +489,60 @@
CODE
hello
20
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "nci_p_i - nested struct *");
+ loadlib P1, "libnci"
+ dlfunc P0, P1, "nci_pi", "pi"
+ # this test function returns a struct { char; x->{int, double} }
+ set I5, 4
+ invoke
+.include "datatypes.pasm"
+ # the contained structure
+ new P3, .PerlArray
+ push P3, .DATATYPE_INT
+ push P3, 0
+ push P3, 0
+ push P3, .DATATYPE_INT
+ push P3, 0
+ push P3, 0
+ push P3, .DATATYPE_DOUBLE
+ push P3, 0
+ push P3, 0
+ new P4, .UnManagedStruct, P3
+ # outer structure
+ new P2, .PerlArray
+ push P2, .DATATYPE_CHAR
+ push P2, 0
+ push P2, 0
+ push P2, .DATATYPE_PTR
+ # attach the unmanged struct as property
+ set P1, P2[-1]
+ setprop P1, "_struct", P4
+ push P2, 0
+ push P2, 0
+ # attach struct initializer
+ assign P5, P2
+ set I0, P5[0]
+ print I0
+ print "\n"
+ # get item x->int
+ set I0, P5[1;0]
+ print I0
+ print "\n"
+ set I0, P5[1;1]
+ print I0
+ print "\n"
+ # get item x->double
+ set N0, P5[1;2]
+ print N0
+ print "\n"
+ end
+CODE
+10
+100
+77
+200.000000
OUTPUT
output_is(<<'CODE', <<'OUTPUT', "nci_i_p");