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
  
  
  

Reply via email to