cvsuser 03/10/04 04:11:24
Modified: classes unmanagedstruct.pmc
examples/assembly pcre.imc
. nci_test.c
t/pmc nci.t
Log:
array element access for struct
Revision Changes Path
1.17 +91 -25 parrot/classes/unmanagedstruct.pmc
Index: unmanagedstruct.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/unmanagedstruct.pmc,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -w -r1.16 -r1.17
--- unmanagedstruct.pmc 3 Oct 2003 15:17:06 -0000 1.16
+++ unmanagedstruct.pmc 4 Oct 2003 11:11:05 -0000 1.17
@@ -1,7 +1,7 @@
/*
* Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
* CVS Info
- * $Id: unmanagedstruct.pmc,v 1.16 2003/10/03 15:17:06 leo Exp $
+ * $Id: unmanagedstruct.pmc,v 1.17 2003/10/04 11:11:05 leo Exp $
* Overview:
* PMC class to hold structs that parrot's not responsible for
* disposing of.
@@ -24,6 +24,59 @@
PObj_UnManagedStruct_my_memory_FLAG = PObj_private0_FLAG
};
+static char *
+char_offset_int(Parrot_Interp interpreter, PMC *pmc, INTVAL ix, int *type)
+{
+ size_t offs, n;
+
+ ix *= 3;
+ n = (size_t)VTABLE_elements(interpreter, PMC_ptr2p(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_ptr2p(pmc), ix);
+ offs = (size_t) VTABLE_get_integer_keyed_int(interpreter, PMC_ptr2p(pmc), ix +
2);
+ return ((char *)PMC_data(pmc)) + offs;
+}
+
+static char *
+char_offset_key(Parrot_Interp interpreter, PMC *pmc, PMC *key, int *type)
+{
+ size_t offs, n, count, size, max;
+ PMC *next;
+ int ix = key_integer(interpreter, key);
+ char *p;
+
+ next = key_next(interpreter, key);
+ p = char_offset_int(interpreter, pmc, ix, type);
+ ix *= 3;
+ if (!next)
+ return p;
+ count = (size_t) key_integer(interpreter, next);
+ max = (size_t) VTABLE_get_integer_keyed_int(interpreter, PMC_ptr2p(pmc), ix +
1);
+ if (count >= max)
+ internal_exception(1, "Non existent array element in struct");
+ size = data_types[*type - enum_first_type].size;
+ return p + count * size;
+}
+
+static INTVAL
+ret_int(char *p, int type)
+{
+ switch (type) {
+ case enum_type_int:
+ return *(INTVAL*) p;
+ case enum_type_short:
+ return *(short*) p;
+ case enum_type_uchar:
+ case enum_type_char:
+ return *p;
+ default:
+ internal_exception(1, "unhandled type in struct");
+ }
+ return -1;
+}
+
pmclass UnManagedStruct extends default need_ext {
void init() {
@@ -66,11 +119,15 @@
else
toff = offs;
}
+ PObj_custom_mark_SET(SELF);
+ }
+
+ void mark() {
+ pobject_lives(interpreter, (PObj *) PMC_ptr2p(SELF));
}
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 () {
@@ -78,27 +135,19 @@
}
INTVAL get_integer_keyed_int(INTVAL ix) {
- size_t offs, n;
int type;
+ char *p;
if (ix < 0)
return -1;
/* assume char array */
- if (!PMC_ptr2p(SELF))
- return (unsigned char)((char *)PMC_data(SELF))[ix];
- n = (size_t)VTABLE_elements(interpreter, PMC_ptr2p(SELF));
- if ((size_t)ix * 3 >= n)
- internal_exception(1, "Non existend elements in struct");
- /* use structure init */
- type = (int) VTABLE_get_integer_keyed_int(interpreter, PMC_ptr2p(SELF), ix*3);
- offs = (int) VTABLE_get_integer_keyed_int(interpreter, PMC_ptr2p(SELF), ix*3 +
2);
- switch (type) {
- case enum_type_int:
- return (INTVAL) ((char *)PMC_data(SELF))[offs];
- default:
- internal_exception(1, "unhandled type in struct");
+ if (!PMC_ptr2p(SELF)) {
+ type = enum_type_char;
+ p = ((char *)PMC_data(SELF)) + ix;
}
- return -1;
+ else
+ p = char_offset_int(interpreter, pmc, ix, &type);
+ return ret_int(p, type);
}
@@ -106,11 +155,20 @@
/* May cause segfaults if value is out of bounds */
INTVAL get_integer_keyed(PMC* key) {
INTVAL ix;
+ int type;
+ char *p;
if (!key)
return -1;
+ /* assume char array */
+ if (!PMC_ptr2p(SELF)) {
ix = key_integer(INTERP, key);
- return SELF.get_integer_keyed_int(ix);
+ type = enum_type_char;
+ p = ((char *)PMC_data(SELF)) + ix;
+ }
+ else
+ p = char_offset_key(interpreter, pmc, key, &type);
+ return ret_int(p, type);
}
INTVAL get_integer() {
@@ -120,20 +178,28 @@
/* May cause segfaults if value is out of bounds */
void set_integer_keyed (PMC* key, INTVAL value) {
INTVAL ix;
+ int type;
+ char *p;
if (!key)
return;
ix = key_integer(INTERP, key);
if (ix < 0)
return;
+ if (!PMC_ptr2p(SELF)) {
((char *)PMC_data(SELF))[ix]=(0xff & value);
return;
}
+ p = char_offset_key(interpreter, pmc, key, &type);
+ switch (type) {
+ case enum_type_int:
+ *(INTVAL*) p = value;
+ default:
+ internal_exception(1, "unhandled type in struct");
+ }
+ }
void set_integer_native(INTVAL value) {
*(INTVAL *)PMC_data(SELF) = value;
}
-
-
-
}
1.3 +38 -26 parrot/examples/assembly/pcre.imc
Index: pcre.imc
===================================================================
RCS file: /cvs/public/parrot/examples/assembly/pcre.imc,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -w -r1.2 -r1.3
--- pcre.imc 3 Oct 2003 15:17:21 -0000 1.2
+++ pcre.imc 4 Oct 2003 11:11:11 -0000 1.3
@@ -77,41 +77,53 @@
.result ok
.pcc_end
- .local int ovec0s
- .local int ovec0e
+ if ok <= 0 goto nomatch
+
+ print "direct access\n"
+ # access unmananged struct directly
+ .local int ovecs
+ .local int ovece
.sym var struct
struct = new SArray
- struct = 6
+ struct = 3
.include "datatypes.pasm"
struct[0] = .DATATYPE_INT
- struct[1] = 1
+ $I0 = ok * 2
+ struct[1] = $I0
struct[2] = 0
- struct[3] = .DATATYPE_INT
- struct[4] = 1
- struct[5] = 0
assign ovector, struct
- ovec0s = ovector[0]
- ovec0e = ovector[1]
-
- if ok <= 0 goto nomatch
-
- print "ok: "
- print ok
- print " from "
- print ovec0s
- print " to "
- print ovec0e
- $I0 = ovec0e - ovec0s
- substr $S1, s, ovec0s, $I0
+ .sym int i
+ .sym string match
+ i = 0
+lp0:
+ $I0 = i * 2
+ ovecs = ovector[0;$I0]
+ inc $I0
+ ovece = ovector[0;$I0]
+ $I0 = ovece - ovecs
+ if ovecs >= 0 goto m1
+ match = ""
+ goto m0
+m1:
+ substr match, s, ovecs, $I0
+m0:
+ if i goto subp0
+ print "all "
+ goto all0
+subp0:
+ print "("
+ print i
+ print ") "
+all0:
print " matched: '"
- print $S1
+ print match
print "'\n"
+ inc i
+ if i < ok goto lp0
-no_hack:
-
- .sym int i
+ # or use convinience function
+ print "copy_substring\n"
i = 0
- .sym string match
repeat match, " ", 500
loop:
.pcc_begin prototyped
1.8 +15 -6 parrot/nci_test.c
Index: nci_test.c
===================================================================
RCS file: /cvs/public/parrot/nci_test.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -w -r1.7 -r1.8
--- nci_test.c 3 Oct 2003 16:06:30 -0000 1.7
+++ nci_test.c 4 Oct 2003 11:11:17 -0000 1.8
@@ -76,12 +76,21 @@
return r;
}
-int * nci_pi(int i) {
- int *a = calloc(i, sizeof(int));
- a[0] = 42;
- a[1] = 100;
- a[2] = 200;
- return a;
+void * nci_pi(int test) {
+ switch (test) {
+ case 0:
+ {
+ static struct {
+ int i[2];
+ char c;
+ } t = {
+ {42, 100},
+ 'B'
+ };
+ return &t;
+ }
+ }
+ return NULL;
}
#ifdef TEST
1.17 +11 -8 parrot/t/pmc/nci.t
Index: nci.t
===================================================================
RCS file: /cvs/public/parrot/t/pmc/nci.t,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -w -r1.16 -r1.17
--- nci.t 3 Oct 2003 16:06:38 -0000 1.16
+++ nci.t 4 Oct 2003 11:11:24 -0000 1.17
@@ -381,21 +381,23 @@
output_is(<<'CODE', <<'OUTPUT', "nci_p_i");
loadlib P1, "libnci"
- # this test function returns an array of int
dlfunc P0, P1, "nci_pi", "pi"
- set I5, 10
+ # this test function returns a struct { int[2]; char }
+ set I5, 0
invoke
new P2, .PerlArray
.include "datatypes.pasm"
push P2, .DATATYPE_INT
- push P2, 1
+ push P2, 2 # 2 elem array
+ push P2, 0
+ push P2, .DATATYPE_CHAR
+ push P2, 0
push P2, 0
- push P2, .DATATYPE_INT
- push P2, 1
- sizeof I10, .DATATYPE_INT
- push P2, I10
assign P5, P2
- set I0, P5[0]
+ set I0, P5[0;0]
+ print I0
+ print "\n"
+ set I0, P5[0;1]
print I0
print "\n"
set I0, P5[1]
@@ -405,6 +407,7 @@
CODE
42
100
+66
OUTPUT
} # SKIP