pike.git / src / array.c

version» Context lines:

pike.git/src/array.c:1:   /*   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: array.c,v 1.138 2004/09/06 11:43:23 grubba Exp $ + || $Id: array.c,v 1.139 2004/09/16 12:59:25 grubba Exp $   */      #include "global.h"   #include "svalue.h"   #include "array.h"   #include "object.h"   #include "las.h"   #include "stralloc.h"   #include "interpret.h"   #include "opcodes.h"
pike.git/src/array.c:17:   #include "pike_types.h"   #include "fsort.h"   #include "builtin_functions.h"   #include "pike_memory.h"   #include "gc.h"   #include "main.h"   #include "security.h"   #include "stuff.h"   #include "bignum.h"   #include "cyclic.h" + #include "multiset.h" + #include "mapping.h"    - RCSID("$Id: array.c,v 1.138 2004/09/06 11:43:23 grubba Exp $"); + RCSID("$Id: array.c,v 1.139 2004/09/16 12:59:25 grubba Exp $");      PMOD_EXPORT struct array empty_array=   {    PIKE_CONSTANT_MEMOBJ_INIT(1), /* Never free */    &weak_empty_array, /* Next */    &weak_shrink_empty_array, /* previous (circular) */    0, /* Size = 0 */    0, /* malloced Size = 0 */    0, /* no types */    0, /* no flags */
pike.git/src/array.c:73:   {    struct array *v;    ptrdiff_t e;       if(size+extra_space == 0)    {    add_ref(&empty_array);    return &empty_array;    }    +  if( (size+extra_space-1) > +  (ULONG_MAX-sizeof(struct array))/sizeof(struct svalue) ) +  Pike_error("Too large array (memory size exceeds size of size_t)\n");    v=(struct array *)malloc(sizeof(struct array)+    (size+extra_space-1)*sizeof(struct svalue));    if(!v) -  Pike_error("Couldn't allocate array, out of memory.\n"); +  Pike_error(msg_out_of_mem);       GC_ALLOC(v);       -  +  if (size)    /* for now, we don't know what will go in here */ -  v->type_field=BIT_MIXED | BIT_UNFINISHED; +  v->type_field = BIT_MIXED | BIT_UNFINISHED; +  else +  v->type_field = 0;    v->flags=0;       v->malloced_size = DO_NOT_WARN((INT32)(size + extra_space));    v->item=v->real_item;    v->size = DO_NOT_WARN((INT32)size);    INIT_PIKE_MEMOBJ(v);    LINK_ARRAY(v);       for(e=0;e<v->size;e++)    {
pike.git/src/array.c:136:    }   #endif      #ifdef PIKE_DEBUG    if(d_flag > 1) array_check_type_field(v);   #endif       add_ref(v);    EXIT_PIKE_MEMOBJ(v);    free_svalues(ITEM(v), v->size, v->type_field); -  v->refs--; +  sub_ref(v);    array_free_no_free(v);   }      PMOD_EXPORT void do_free_array(struct array *a)   {    if (a)    free_array(a);   }      PMOD_EXPORT struct array *array_set_flags(struct array *a, int flags)
pike.git/src/array.c:185:   #endif       add_ref(v);    assign_svalue(s, ITEM(v) + index);    free_array(v);   }      PMOD_EXPORT void simple_array_index_no_free(struct svalue *s,    struct array *a,struct svalue *ind)   { -  INT32 i; +     switch(ind->type)    { -  case T_INT: -  i=ind->u.integer; -  if(i<0) i+=a->size; +  case T_INT: { +  INT_TYPE p = ind->u.integer; +  INT_TYPE i = p < 0 ? p + a->size : p;    if(i<0 || i>=a->size) {    struct svalue tmp;    tmp.type=T_ARRAY;    tmp.u.array=a;    if (a->size) { -  index_error(0,0,0,&tmp,ind,"Index %d is out of array range 0 - %d.\n", i, a->size-1); +  index_error(0,0,0,&tmp,ind, +  "Index %d is out of array range " +  "%d..%d.\n", +  p, -a->size, a->size-1);    } else { -  index_error(0,0,0,&tmp,ind,"Attempt to index the empty array with %d.\n", i); +  index_error(0,0,0,&tmp,ind, +  "Attempt to index the empty array with %d.\n", p);    }    }    array_index_no_free(s,a,i);    break; -  +  }       case T_STRING:    {    check_stack(4);    ref_push_array(a);    assign_svalue_no_free(Pike_sp++,ind);    f_column(2);    s[0]=Pike_sp[-1];    Pike_sp--;    dmalloc_touch_svalue(Pike_sp);
pike.git/src/array.c:242: Inside #if defined(PIKE_DEBUG)
   if(index<0 || index>=v->size)    Pike_fatal("Illegal index in low level free index routine.\n");   #endif       free_svalue(ITEM(v) + index);   }         PMOD_EXPORT void simple_set_index(struct array *a,struct svalue *ind,struct svalue *s)   { -  INT32 i; +     switch (ind->type) { -  case T_INT: -  i=ind->u.integer; -  if(i<0) i+=a->size; +  case T_INT: { +  INT_TYPE p = ind->u.integer; +  INT_TYPE i = p < 0 ? p + a->size : p;    if(i<0 || i>=a->size) {    if (a->size) { -  Pike_error("Index %d is out of array range 0 - %d.\n", i, a->size-1); +  Pike_error("Index %d is out of array range " +  "%d..%d.\n", +  p, -a->size, a->size-1);    } else { -  Pike_error("Attempt to index the empty array with %d.\n", i); +  Pike_error("Attempt to index the empty array with %d.\n", p);    }    }    array_set_index(a,i,s);    break; -  +  }       case T_STRING:    {    INT32 i, n;    check_stack(2);    Pike_sp++->type = T_VOID;    push_svalue(ind);    for (i = 0, n = a->size; i < n; i++) {    assign_svalue(Pike_sp-2, &a->item[i]);    assign_lvalue(Pike_sp-2, s);
pike.git/src/array.c:327:    free_array(v);    v=ret;    }       array_set_index(v,index,s);       return v;   }      /* +  * Shrink an array destructively +  */ + PMOD_EXPORT struct array *array_shrink(struct array *v, ptrdiff_t size) + { +  struct array *a; +  + #ifdef PIKE_DEBUG +  if(v->refs>2) /* Odd, but has to be two */ +  Pike_fatal("Array shrink on array with many references.\n"); +  +  if(size > v->size) +  Pike_fatal("Illegal argument to array_shrink.\n"); + #endif +  +  if(!size || (size*4 < v->malloced_size + 4)) /* Should we realloc it? */ +  { +  a = array_set_flags(allocate_array_no_init(size, 0), v->flags); +  if (a->size) { +  a->type_field = v->type_field; +  } +  +  free_svalues(ITEM(v) + size, v->size - size, v->type_field); +  MEMCPY(ITEM(a), ITEM(v), size*sizeof(struct svalue)); +  v->size=0; +  free_array(v); +  return a; +  }else{ +  free_svalues(ITEM(v) + size, v->size - size, v->type_field); +  v->size=size; +  return v; +  } + } +  + /*    * resize array, resize an array destructively    */   PMOD_EXPORT struct array *resize_array(struct array *a, INT32 size)   {   #ifdef PIKE_DEBUG    if(d_flag > 1) array_check_type_field(a);   #endif       if(a->size == size) return a;    if(size > a->size)
pike.git/src/array.c:350:    if(a->malloced_size >= size)    {    for(;a->size < size; a->size++)    {    ITEM(a)[a->size].type=T_INT;    ITEM(a)[a->size].subtype=NUMBER_NUMBER;    ITEM(a)[a->size].u.integer=0;    }    a->type_field |= BIT_INT;    return a; -  }else{ +  } else {    struct array *ret; -  ret=low_allocate_array(size, (size>>1) + 4); -  MEMCPY(ITEM(ret),ITEM(a),sizeof(struct svalue)*a->size); +  ret = array_set_flags(low_allocate_array(size, (size>>1) + 4), +  a->flags); +  MEMCPY(ITEM(ret), ITEM(a), sizeof(struct svalue)*a->size);    ret->type_field = DO_NOT_WARN((TYPE_FIELD)(a->type_field | BIT_INT));    a->size=0;    free_array(a);    return ret;    } -  }else{ -  /* We should shrink the array */ -  free_svalues(ITEM(a)+size, a->size - size, a->type_field); -  a->size = size; -  return a; +  } else { +  return array_shrink(a, size);    }   }      /* -  * Shrink an array destructively -  */ - PMOD_EXPORT struct array *array_shrink(struct array *v, ptrdiff_t size) - { -  struct array *a; -  - #ifdef PIKE_DEBUG -  if(v->refs>2) /* Odd, but has to be two */ -  Pike_fatal("Array shrink on array with many references.\n"); -  -  if(size > v->size) -  Pike_fatal("Illegal argument to array_shrink.\n"); - #endif -  -  if(size*2 < v->malloced_size + 4) /* Should we realloc it? */ -  { -  a=allocate_array_no_init(size,0); -  a->type_field = v->type_field; -  -  free_svalues(ITEM(v) + size, v->size - size, v->type_field); -  MEMCPY(ITEM(a), ITEM(v), size*sizeof(struct svalue)); -  v->size=0; -  free_array(v); -  return a; -  }else{ -  free_svalues(ITEM(v) + size, v->size - size, v->type_field); -  v->size=size; -  return v; -  } - } -  - /* +     * Remove an index from an array and shrink the array    */   PMOD_EXPORT struct array *array_remove(struct array *v,INT32 index)   {    struct array *a;      #ifdef PIKE_DEBUG    if(index<0 || index >= v->size)    Pike_fatal("Illegal argument to array_remove.\n");   #endif       array_free_index(v, index); -  if(v->size!=1 && -  v->size*2 + 4 < v->malloced_size ) /* Should we realloc it? */ +  if (v->size == 1) { +  v->size = 0; +  /* NOTE: The following uses the fact that array_set_flags() +  * will reallocate the array if it has zero size! +  */ +  return array_set_flags(v, v->flags); +  } else if(v->size*4 + 4 < v->malloced_size ) /* Should we realloc it? */    { -  a=allocate_array_no_init(v->size-1, 0); +  a = array_set_flags(allocate_array_no_init(v->size-1, 0), v->flags);    a->type_field = v->type_field;       if(index>0)    MEMCPY(ITEM(a), ITEM(v), index*sizeof(struct svalue));    if(v->size-index>1)    MEMCPY(ITEM(a)+index,    ITEM(v)+index+1,    (v->size-index-1)*sizeof(struct svalue));    v->size=0;    free_array(v);    return a; -  }else{ +  } else {    if(v->size-index>1)    {    MEMMOVE((char *)(ITEM(v)+index),    (char *)(ITEM(v)+index+1),    (v->size-index-1)*sizeof(struct svalue));    }    v->size--;    return v;    }   }
pike.git/src/array.c:484:    if(is_eq(ITEM(v)+e,s)) return e;    t |= 1<<ITEM(v)[e].type;    }    v->type_field=t;    }    }    return -1;   }      /* -  * Slice a pice of an array (nondestructively) +  * Slice a piece of an array (nondestructively)    * return an array consisting of v[start..end-1]    */   PMOD_EXPORT struct array *slice_array(struct array *v, ptrdiff_t start,    ptrdiff_t end)   {    struct array *a;      #ifdef PIKE_DEBUG    if(start > end || end>v->size || start<0)    Pike_fatal("Illegal arguments to slice_array()\n");
pike.git/src/array.c:522: Inside #if 1 and #if defined(PIKE_DEBUG)
  #ifdef PIKE_DEBUG    if(d_flag>1)    check_array(v);   #endif    return v;    }    }   #endif       a=allocate_array_no_init(end-start,0); +  if (end-start) {    a->type_field = v->type_field;       assign_svalues_no_free(ITEM(a), ITEM(v)+start, end-start, v->type_field); -  +  }       return a;   }      /* -  * Slice a pice of an array (nondestructively) +  * Slice a piece of an array (nondestructively)    * return an array consisting of v[start..end-1]    */   PMOD_EXPORT struct array *friendly_slice_array(struct array *v,    ptrdiff_t start,    ptrdiff_t end)   {    struct array *a;      #ifdef PIKE_DEBUG    if(start > end || end>v->size || start<0)
pike.git/src/array.c:835:    default:    return set_svalue_cmpfun(a,b);    }    }else{    return a->type - b->type;    }   }      static int alpha_svalue_cmpfun(const struct svalue *a, const struct svalue *b)   { -  if(a->type == b->type) +  if (a->type == b->type)    {    switch(a->type)    {    case T_INT:    if(a->u.integer < b->u.integer) return -1;    if(a->u.integer > b->u.integer) return 1;    return 0;       case T_FLOAT:    if(a->u.float_number < b->u.float_number) return -1;
pike.git/src/array.c:879:   }      #define CMP(X,Y) alpha_svalue_cmpfun(X,Y)   #define TYPE struct svalue   #define ID low_sort_svalues   #include "fsort_template.h"   #undef CMP   #undef TYPE   #undef ID    -  + /* This sort is unstable. */   PMOD_EXPORT void sort_array_destructively(struct array *v)   {    if(!v->size) return;    low_sort_svalues(ITEM(v), ITEM(v)+v->size-1);   }            /*    * return an 'order' suitable for making mappings and multisets
pike.git/src/array.c:986:    /* face it, it's not there */    if( ((BIT_MIXED << s->type) & BIT_MIXED & a->type_field) == 0)    return ~a->size;    }       return low_lookup(a,s,switch_svalue_cmpfun);   }         /* -  * reorganize an array in the order specifyed by 'order' +  * reorganize an array in the order specified by 'order'    */   PMOD_EXPORT struct array *order_array(struct array *v, INT32 *order)   {    reorder((char *)ITEM(v),v->size,sizeof(struct svalue),order);    return v;   }         /*    * copy and reorganize an array
pike.git/src/array.c:1064: Inside #if defined(PIKE_DEBUG)
      t |= 1 << ITEM(v)[e].type;    }       if(t & ~(v->type_field))    {    describe(v);    Pike_fatal("Type field out of order!\n");    }   } - #endif + #endif /* PIKE_DEBUG */      PMOD_EXPORT struct array *compact_array(struct array *v) { return v; }      /*    * Get a pointer to the 'union anything' specified IF it is of the specified    * type. The 'union anything' may be changed, but not the type.    */   PMOD_EXPORT union anything *low_array_get_item_ptr(struct array *a,    INT32 ind,    TYPE_T t)
pike.git/src/array.c:1090:   /*    * Get a pointer to the 'union anything' specified IF it is of the specified    * type. The 'union anything' may be changed, but not the type.    * The differance between this routine and the one above is that this takes    * the index as an svalue.    */   PMOD_EXPORT union anything *array_get_item_ptr(struct array *a,    struct svalue *ind,    TYPE_T t)   { -  INT32 i; +  INT_TYPE i, p;    if(ind->type != T_INT) -  Pike_error("Index is not an integer.\n"); -  i=ind->u.integer; -  if(i<0) i+=a->size; +  Pike_error("Expected integer as array index, got %s.\n", +  get_name_of_type (ind->type)); +  p = ind->u.integer; +  i = p < 0 ? p + a->size : p;    if(i<0 || i>=a->size) {    if (a->size) { -  Pike_error("Index %d is out of array range 0 - %d.\n", i, a->size-1); +  Pike_error("Index %d is out of array range " +  "%d..%d.\n", +  p, -a->size, a->size-1);    } else { -  Pike_error("Attempt to index the empty array with %d.\n", i); +  Pike_error("Attempt to index the empty array with %d.\n", p);    }    }    return low_array_get_item_ptr(a,i,t);   }      /*    * organize an array of INT32 to specify how to zip two arrays together    * to maintain the order.    * the first item in this array is the size of the result    * the rest is n >= 0 for a[ n ]
pike.git/src/array.c:1763:    my_putchar('\n');    for(e=2; e<indent; e++) my_putchar(' ');    my_strcat("})");   }      PMOD_EXPORT struct array *aggregate_array(INT32 args)   {    struct array *a;       a=allocate_array_no_init(args,0); +  if (args) {    MEMCPY((char *)ITEM(a),(char *)(Pike_sp-args),args*sizeof(struct svalue)); -  a->type_field=BIT_MIXED; +  array_fix_type_field (a);    Pike_sp-=args;    DO_IF_DMALLOC(while(args--) dmalloc_touch_svalue(Pike_sp + args)); -  +  }    return a;   }      PMOD_EXPORT struct array *append_array(struct array *a, struct svalue *s)   {    a=resize_array(a,a->size+1);    array_set_index(a, a->size-1, s);    return a;   }   
pike.git/src/array.c:1999:    *tmp1 = swap;    }       add_ref(a);    return a;    }       ret=allocate_array_no_init(a->size,0);    for(e=0;e<a->size;e++)    assign_svalue_no_free(ITEM(ret)+e,ITEM(a)+a->size+~e); +  ret->type_field = a->type_field;    return ret;   }      void array_replace(struct array *a,    struct svalue *from,    struct svalue *to)   {    ptrdiff_t i = -1;       while((i=array_search(a,from,i+1)) >= 0) array_set_index(a,i,to);
pike.git/src/array.c:2387:    }else{    check_stack(120);    BEGIN_AGGREGATE_ARRAY(a->size) {    for(e=0;e<a->size;e++) {    push_array(friendly_slice_array(a, e, e+1));    DO_AGGREGATE_ARRAY(120);    }    } END_AGGREGATE_ARRAY;    }    tmp=(--Pike_sp)->u.array; +  debug_malloc_touch(tmp);    if(tmp->size) tmp->type_field=BIT_ARRAY;    return tmp;   }      PMOD_EXPORT struct array *implode_array(struct array *a, struct array *b)   {    INT32 e, size;    struct array *ret;       if (!a->size) {