cvsuser     04/02/05 05:09:41

  Modified:    classes  unmanagedstruct.pmc
               docs/pmc struct.pod
               src      nci_test.c
               t/pmc    nci.t
  Log:
  add DATATYPE_CSTR to struct handling
  * please rebuild test lib:
    make libnci.so
  
  Revision  Changes    Path
  1.28      +64 -1     parrot/classes/unmanagedstruct.pmc
  
  Index: unmanagedstruct.pmc
  ===================================================================
  RCS file: /cvs/public/parrot/classes/unmanagedstruct.pmc,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -w -r1.27 -r1.28
  --- unmanagedstruct.pmc       5 Feb 2004 11:07:35 -0000       1.27
  +++ unmanagedstruct.pmc       5 Feb 2004 13:09:30 -0000       1.28
  @@ -1,7 +1,7 @@
   /*
    *  Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
    *  CVS Info
  - *     $Id: unmanagedstruct.pmc,v 1.27 2004/02/05 11:07:35 leo Exp $
  + *     $Id: unmanagedstruct.pmc,v 1.28 2004/02/05 13:09:30 leo Exp $
    *  Overview:
    *     PMC class to hold structs that parrot's not responsible for
    *     disposing of.
  @@ -123,6 +123,24 @@
       return -1.0;
   }
   
  +static STRING*
  +ret_string(Parrot_Interp interpreter, char *p, int type)
  +{
  +    char *cstr;
  +    size_t len;
  +
  +    switch (type) {
  +     case enum_type_cstr:
  +         cstr = *(char **) p;
  +         len = strlen(cstr);
  +         return string_make(interpreter, cstr, len, NULL,
  +                 PObj_external_FLAG, NULL);
  +     default:
  +         internal_exception(1, "returning unhandled string type in struct");
  +    }
  +    return NULL;
  +}
  +
   static void
   set_int(char *p, int type, INTVAL value)
   {
  @@ -163,6 +181,27 @@
        case enum_type_double:
            *(double*) p = (double) value;
            break;
  +     default:
  +         internal_exception(1, "setting unhandled float type in struct");
  +         break;
  +    }
  +}
  +
  +static void
  +set_string(char *p, int type, STRING* value)
  +{
  +    char *cstr;
  +    switch (type) {
  +     case enum_type_cstr:
  +         /* XXX assumes 0-terminate C-string here
  +          *     we can't use string_to_cstring easily
  +          */
  +         cstr = value->strstart;
  +         *(char **) p = cstr;
  +         break;
  +     default:
  +         internal_exception(1, "setting unhandled string type in struct");
  +         break;
       }
   }
   
  @@ -323,6 +362,18 @@
        return ret_float(p, type);
       }
   
  +    STRING* get_string_keyed_int (INTVAL key) {
  +     int type;
  +     char *p = char_offset_int(interpreter, pmc, key, &type);
  +     return ret_string(interpreter, p, type);
  +    }
  +
  +    STRING* get_string_keyed (PMC* key) {
  +     int type;
  +     char *p = char_offset_key(interpreter, pmc, key, &type);
  +     return ret_string(interpreter, p, type);
  +    }
  +
       INTVAL get_integer() {
          return (INTVAL)*(INTVAL *)PMC_data(SELF);
       }
  @@ -377,6 +428,18 @@
        int type;
        char *p = char_offset_key(interpreter, pmc, key, &type);
        set_float(p, type, value);
  +    }
  +
  +    void set_string_keyed_int (INTVAL key, STRING* value) {
  +     int type;
  +     char *p = char_offset_int(interpreter, pmc, key, &type);
  +     set_string(p, type, value);
  +    }
  +
  +    void set_string_keyed (PMC *key, STRING* value) {
  +     int type;
  +     char *p = char_offset_key(interpreter, pmc, key, &type);
  +     set_string(p, type, value);
       }
   
   }
  
  
  
  1.3       +30 -3     parrot/docs/pmc/struct.pod
  
  Index: struct.pod
  ===================================================================
  RCS file: /cvs/public/parrot/docs/pmc/struct.pod,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -w -r1.2 -r1.3
  --- struct.pod        5 Feb 2004 11:07:39 -0000       1.2
  +++ struct.pod        5 Feb 2004 13:09:33 -0000       1.3
  @@ -56,6 +56,7 @@
       double d;
       float  f;
       int    i[4];
  +    char  *s;
     };
   
   can be declared with this initializer:
  @@ -71,6 +72,9 @@
     push P2, .DATATYPE_INT
     push P2, 4 # 4 elem array
     push P2, 0
  +  push P2, .DATATYPE_CSTR
  +  push P2, 0
  +  push P2, 0
   
   =head2 Named Structure Elements
   
  @@ -104,6 +108,8 @@
     sizeof I7, .DATATYPE_INT
     mul I7, 4
     add I6, I7
  +  sizeof I7, .DATATYPE_CSTR
  +  add I6, I7
   
     set P5, I6 # allocate size
   
  @@ -116,9 +122,8 @@
   
   So for above example:
   
  -  set I6, P2[8]      # offset of 3rd struct element i[4]
  -  sizeof I7, .DATATYPE_INT
  -  mul I7, 4
  +  set I6, P2[11]     # offset of 4rd struct element *s
  +  sizeof I7, .DATATYPE_CSTR
     add I6, I7 # I6 is now the total size
   
   =head1 Accessing Structure Items
  @@ -142,6 +147,28 @@
     set I3, P5[2;3]    # get i[3]
   
     set P5["i"; 2]        # set i[2] if initializer is an OrderedHash
  +
  +  set S0, P5[3]         # get string at *s
  +  set S0, P5["s"]    # same
  +
  +=head2 Strings
  +
  +When passing a STRING to a structure that needs a 0-terminated
  +C-string (char *s), then you have to provide the terminating NUL char
  +in the string.
  +
  +  struct {
  +    ...
  +    char *s;
  +  };
  +
  +  set P5["s"], "a string\x0"
  +
  +Please also note, that the C function currently gets a pointer to string
  +memory, so any code that might trigger GC should be avoided (or GC turned off).
  +Passing constant strings like above is safe though.
  +
  +  set P5["s"], S0  # S0 shouldn't move until function call
   
   =head1 Passing A Structure to a C function
   
  
  
  
  1.16      +14 -0     parrot/src/nci_test.c
  
  Index: nci_test.c
  ===================================================================
  RCS file: /cvs/public/parrot/src/nci_test.c,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -w -r1.15 -r1.16
  --- nci_test.c        5 Feb 2004 10:24:14 -0000       1.15
  +++ nci_test.c        5 Feb 2004 13:09:37 -0000       1.16
  @@ -45,8 +45,11 @@
           double d;
           float f;
           int i;
  +        char *s;
       } dfi;
       dfi *sp = (dfi*) p;
  +    puts(sp->s);
  +    fflush(stdout);
       return (int) (sp->d + sp->f + sp->i);
   }
   
  @@ -127,6 +130,17 @@
                       int i;
                   } t = {
                        10,
  +                     20
  +                };
  +                return &t;
  +            }
  +        case 3:
  +            {
  +                static struct {
  +                    const char *c;
  +                    int i;
  +                } t = {
  +                     "hello",
                        20
                   };
                   return &t;
  
  
  
  1.22      +37 -2     parrot/t/pmc/nci.t
  
  Index: nci.t
  ===================================================================
  RCS file: /cvs/public/parrot/t/pmc/nci.t,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -w -r1.21 -r1.22
  --- nci.t     5 Feb 2004 10:24:18 -0000       1.21
  +++ nci.t     5 Feb 2004 13:09:40 -0000       1.22
  @@ -1,4 +1,4 @@
  -use Parrot::Test tests => 19;
  +use Parrot::Test tests => 20;
   use Parrot::Config;
   
   print STDERR $PConfig{jitcpuarch}, " JIT CPU\n";
  @@ -464,10 +464,38 @@
   /
   OUTPUT
   
  +output_is(<<'CODE', <<'OUTPUT', "nci_p_i - char*");
  +  loadlib P1, "libnci"
  +  dlfunc P0, P1, "nci_pi", "pi"
  +  # this test function returns a struct { char*; int }
  +  set I5, 3
  +  invoke
  +  new P2, .PerlArray
  +.include "datatypes.pasm"
  +  push P2, .DATATYPE_CSTR
  +  push P2, 0
  +  push P2, 0
  +  push P2, .DATATYPE_INT
  +  push P2, 0
  +  push P2, 0
  +  assign P5, P2
  +  set S0, P5[0]
  +  print S0
  +  print "\n"
  +  set I0, P5[1]
  +  print I0
  +  print "\n"
  +  end
  +CODE
  +hello
  +20
  +OUTPUT
  +
   output_is(<<'CODE', <<'OUTPUT', "nci_i_p");
     loadlib P1, "libnci"
     dlfunc P0, P1, "nci_ip", "ip"
  -  # this test function wants a struct { double d; float f; int i }
  +  # this test function wants a struct
  +  # { double d; float f; int i; char*}
     # and returns the sum of these values
     new P2, .PerlArray
   .include "datatypes.pasm"
  @@ -480,6 +508,9 @@
     push P2, .DATATYPE_INT
     push P2, 0 # 1 elem array
     push P2, 0
  +  push P2, .DATATYPE_CSTR
  +  push P2, 0 # 1 elem array
  +  push P2, 0
     new P5, .ManagedStruct, P2
     set I6, 0
     sizeof I7, .DATATYPE_DOUBLE
  @@ -488,16 +519,20 @@
     add I6, I7
     sizeof I7, .DATATYPE_INT
     add I6, I7
  +  sizeof I7, .DATATYPE_CSTR
  +  add I6, I7
     set P5, I6
     set P5[0], 10.0
     set P5[1], 4.0
     set P5[2], 17
  +  set P5[3], "hello from Parrot\x0"
     set I5, 1
     invoke
     print I5
     print "\n"
     end
   CODE
  +hello from Parrot
   31
   OUTPUT
   
  
  
  

Reply via email to