cvsuser 04/02/05 02:24:18
Modified: classes unmanagedstruct.pmc
src nci_test.c
t/pmc nci.t
Log:
align struct items
Revision Changes Path
1.26 +48 -2 parrot/classes/unmanagedstruct.pmc
Index: unmanagedstruct.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/unmanagedstruct.pmc,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -w -r1.25 -r1.26
--- unmanagedstruct.pmc 31 Jan 2004 14:29:46 -0000 1.25
+++ unmanagedstruct.pmc 5 Feb 2004 10:24:02 -0000 1.26
@@ -1,7 +1,7 @@
/*
* Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
* CVS Info
- * $Id: unmanagedstruct.pmc,v 1.25 2004/01/31 14:29:46 leo Exp $
+ * $Id: unmanagedstruct.pmc,v 1.26 2004/02/05 10:24:02 leo Exp $
* Overview:
* PMC class to hold structs that parrot's not responsible for
* disposing of.
@@ -165,6 +165,52 @@
}
}
+/*
+ * XXX
+ * this does only minimal alignment
+ * gcc-2.95, -3.3 /i386
+ *
+ #include <stddef.h>
+ struct xt {
+ char x; // 0
+ struct yt {
+ char y; // 4
+ char i; // 5
+ int j; // 8
+ } _y;
+ char z; // 12
+ } _x;
+
+ ...
+ printf("i : %d\n", offsetof(struct xt, _y.i));
+
+ *
+ * *BUT* if the nested structure contains only char - then
+ * all is char aligned
+ * if the nested structure contains a short then align is 2
+ *
+ * long long is aligned on 4
+ */
+
+static int
+calc_align(int type, int offs)
+{
+ int align = data_types[type - enum_first_type].size;
+
+ if (offs % align) {
+ int diff;
+ if ((type == enum_type_ulonglong ||
+ type == enum_type_longlong ||
+ type == enum_type_int64 ||
+ type == enum_type_uint64) &&
+ !strcmp(PARROT_CPU_ARCH, "i386"))
+ align = 4;
+ diff = align - (offs % align);
+ offs += diff;
+ }
+ return offs;
+}
+
pmclass UnManagedStruct extends default need_ext {
void init() {
@@ -202,7 +248,7 @@
VTABLE_set_integer_keyed_int(interpreter, value, i+1, count);
}
if (offs <= 0) {
- offs = toff;
+ offs = toff = calc_align(type, toff);
VTABLE_set_integer_keyed_int(interpreter, value, i+2, offs);
}
else
1.15 +11 -0 parrot/src/nci_test.c
Index: nci_test.c
===================================================================
RCS file: /cvs/public/parrot/src/nci_test.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -w -r1.14 -r1.15
--- nci_test.c 5 Jan 2004 14:44:52 -0000 1.14
+++ nci_test.c 5 Feb 2004 10:24:14 -0000 1.15
@@ -120,6 +120,17 @@
};
return &t;
}
+ case 2:
+ {
+ static struct {
+ char c;
+ int i;
+ } t = {
+ 10,
+ 20
+ };
+ return &t;
+ }
}
return NULL;
}
1.21 +34 -1 parrot/t/pmc/nci.t
Index: nci.t
===================================================================
RCS file: /cvs/public/parrot/t/pmc/nci.t,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -w -r1.20 -r1.21
--- nci.t 25 Dec 2003 12:02:28 -0000 1.20
+++ nci.t 5 Feb 2004 10:24:18 -0000 1.21
@@ -1,4 +1,4 @@
-use Parrot::Test tests => 18;
+use Parrot::Test tests => 19;
use Parrot::Config;
print STDERR $PConfig{jitcpuarch}, " JIT CPU\n";
@@ -429,6 +429,39 @@
42.000000
100.000000
47.110000
+OUTPUT
+
+output_like(<<'CODE', <<'OUTPUT', "nci_p_i - align");
+ loadlib P1, "libnci"
+ dlfunc P0, P1, "nci_pi", "pi"
+ # this test function returns a struct { char; int }
+ set I5, 2
+ invoke
+ new P2, .PerlArray
+.include "datatypes.pasm"
+ push P2, .DATATYPE_CHAR
+ push P2, 0
+ push P2, 0
+ push P2, .DATATYPE_INT
+ push P2, 0
+ push P2, 0
+ assign P5, P2
+ set I0, P5[0]
+ print I0
+ print "\n"
+ set I0, P5[1]
+ print I0
+ print "\n"
+ # check the offset of the int
+ set I0, P2[5]
+ print I0
+ print "\n"
+ end
+CODE
+/10
+20
+(4|8)
+/
OUTPUT
output_is(<<'CODE', <<'OUTPUT', "nci_i_p");