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");
  
  
  

Reply via email to