pike.git / src / builtin_functions.c

version» Context lines:

pike.git/src/builtin_functions.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: builtin_functions.c,v 1.489 2003/04/27 20:12:11 mast Exp $ + || $Id: builtin_functions.c,v 1.490 2003/04/28 00:32:43 mast Exp $   */      #include "global.h" - RCSID("$Id: builtin_functions.c,v 1.489 2003/04/27 20:12:11 mast Exp $"); + RCSID("$Id: builtin_functions.c,v 1.490 2003/04/28 00:32:43 mast Exp $");   #include "interpret.h"   #include "svalue.h"   #include "pike_macros.h"   #include "object.h"   #include "program.h"   #include "array.h"   #include "pike_error.h"   #include "constants.h"   #include "mapping.h"   #include "stralloc.h"
pike.git/src/builtin_functions.c:1780:    *! @seealso    *! @[add_constant()]    */   PMOD_EXPORT void f_all_constants(INT32 args)   {    pop_n_elems(args);    ref_push_mapping(get_builtin_constants());   }      /*! @decl array allocate(int size) -  *! @decl array allocate(int size, mixed zero) +  *! @decl array allocate(int size, mixed init)    *! -  *! Allocate an array of @[size] elements and initialize them to @[zero]. +  *! Allocate an array of @[size] elements. If @[init] is specified +  *! then each element is initialized by copying that value +  *! recursively.    *!    *! @seealso    *! @[sizeof()], @[aggregate()], @[arrayp()]    */   PMOD_EXPORT void f_allocate(INT32 args)   {    INT32 size;    struct array *a;       if(args < 1)
pike.git/src/builtin_functions.c:1805:    if(Pike_sp[-args].type!=T_INT)    SIMPLE_BAD_ARG_ERROR("allocate",1,"int");       size=Pike_sp[-args].u.integer;    if(size < 0)    PIKE_ERROR("allocate", "Can't allocate array of negative size.\n", Pike_sp, args);    a=allocate_array(size);    if(args>1)    {    INT32 e; +  struct svalue *init = Pike_sp - args + 1; +  push_array (a);    for(e=0;e<a->size;e++) -  copy_svalues_recursively_no_free(a->item+e, Pike_sp-args+1, 1, 0); +  copy_svalues_recursively_no_free(a->item+e, init, 1, 0); +  a->type_field = 1 << init->type; +  stack_pop_n_elems_keep_top (args);    } -  +  else { +  a->type_field = BIT_INT;    pop_n_elems(args);    push_array(a);    } -  + }      /*! @decl object this_object(void|int level);    *!    *! Returns the object we are currently evaluating in.    *!    *! @[level] might be used to access the object of a surrounding    *! class: The object at level 0 is the current object, the object    *! at level 1 is the one belonging to the class surrounding the    *! current class, and so on.    */
pike.git/src/builtin_functions.c:2199:    size=Pike_sp[-args].u.string->len;    goto qjump;       case T_ARRAY:    size=Pike_sp[-args].u.array->size;       qjump:    a=allocate_array_no_init(size,0);    while(--size>=0)    { -  ITEM(a)[size].type=T_INT; -  ITEM(a)[size].subtype=NUMBER_NUMBER; +  /* Elements are already integers. */    ITEM(a)[size].u.integer = DO_NOT_WARN((INT_TYPE)size);    } -  +  a->type_field = BIT_INT;    break;       case T_MAPPING:    a=mapping_indices(Pike_sp[-args].u.mapping);    break;       case T_MULTISET:   #ifdef PIKE_NEW_MULTISETS    a = multiset_indices (Pike_sp[-args].u.multiset);   #else
pike.git/src/builtin_functions.c:2494:    if(args < 1)    SIMPLE_TOO_FEW_ARGS_ERROR("values", 1);       switch(Pike_sp[-args].type)    {    case T_STRING:    size = Pike_sp[-args].u.string->len;    a = allocate_array_no_init(size,0);    while(--size >= 0)    { -  ITEM(a)[size].type = T_INT; -  ITEM(a)[size].subtype = NUMBER_NUMBER; +  /* Elements are already integers. */    ITEM(a)[size].u.integer = index_shared_string(Pike_sp[-args].u.string, size);    } -  +  a->type_field = BIT_INT;    break;       case T_ARRAY:    a=copy_array(Pike_sp[-args].u.array);    break;       case T_MAPPING:    a=mapping_values(Pike_sp[-args].u.mapping);    break;       case T_MULTISET:   #ifdef PIKE_NEW_MULTISETS    a = multiset_values (Pike_sp[-args].u.multiset);   #else    size=Pike_sp[-args].u.multiset->ind->size;    a=allocate_array_no_init(size,0);    while(--size>=0)    { -  ITEM(a)[size].type=T_INT; -  ITEM(a)[size].subtype=NUMBER_NUMBER; +  /* Elements are already integers. */    ITEM(a)[size].u.integer=1;    } -  +  a->type_field = BIT_INT;   #endif    break;       case T_OBJECT:    a=object_values(Pike_sp[-args].u.object);    break;       case T_PROGRAM:    a = program_values(Pike_sp[-args].u.program);    break;
pike.git/src/builtin_functions.c:3841:    *! returns an array with the results.    *!    *! @seealso    *! @[column()]    */   PMOD_EXPORT void f_rows(INT32 args)   {    INT32 e;    struct array *a,*tmp;    struct svalue *val; +  TYPE_FIELD types;       get_all_args("rows", args, "%*%a", &val, &tmp);       /* Optimization */    if(tmp->refs == 1)    {    struct svalue sval;    tmp->type_field = BIT_MIXED | BIT_UNFINISHED; -  +  types = 0;    for(e=0;e<tmp->size;e++)    {    index_no_free(&sval, val, ITEM(tmp)+e); -  +  types |= 1 << sval.type;    free_svalue(ITEM(tmp)+e); -  ITEM(tmp)[e]=sval; +  move_svalue (ITEM(tmp) + e, &sval);    } -  +  tmp->type_field = types;    stack_swap();    pop_stack();    return;    }       push_array(a=allocate_array(tmp->size)); -  -  for(e=0;e<a->size;e++) +  types = 0; +  for(e=0;e<a->size;e++) {    index_no_free(ITEM(a)+e, val, ITEM(tmp)+e); -  +  types |= 1 << ITEM(a)[e].type; +  } +  a->type_field = types;       Pike_sp--;    dmalloc_touch_svalue(Pike_sp);    pop_n_elems(args);    push_array(a);   }      /*! @decl void verify_internals()    *! @belongs Debug    *!
pike.git/src/builtin_functions.c:4617:    if (low < 0) {    Pike_error("interleave_array(): Index %"PRINTPIKEINT"d in mapping %d is negative!\n",    low, i);    }    }    if (max < k->ind.u.integer) {    max = k->ind.u.integer;    }    nelems++;    } -  /* FIXME: Is this needed? Isn't T_INT default? */ +     ITEM(min)[i].u.integer = low;    }    -  +  min->type_field = T_INT;    ref_push_array(order);    f_sort(2); /* Sort the order array on the minimum index */       /* State on stack now:    *    * array(mapping(int:mixed)) arr    * array(int) order    * array(int) min (now sorted)    */   
pike.git/src/builtin_functions.c:4788:    links[i] = stack[pos-1];    else    links[i] = -1;    stack[pos] = i;    }       /* FIXME(?) memory unfreed upon error here */    res = low_allocate_array(top, 0);    while (ltop != -1)    { -  res->item[--top].u.integer = ltop; +  ITEM(res)[--top].u.integer = ltop;    ltop = links[ltop];    } -  +  res->type_field = T_INT;       UNSET_ONERROR(tmp2);    UNSET_ONERROR(tmp);       free(stack);    free(links);    return res;   }      /*! @decl array(int) longest_ordered_sequence(array a)
pike.git/src/builtin_functions.c:4839:   }      /**** diff ************************************************************/      static struct array* diff_compare_table(struct array *a,struct array *b,int *u)   {    struct array *res;    struct mapping *map;    struct svalue *pval;    int i; +  TYPE_FIELD types;       if (u) {    *u = 0; /* Unique rows in array b */    }       map=allocate_mapping(256);    push_mapping(map); /* in case of out of memory */       for (i=0; i<b->size; i++)    {    pval=low_mapping_lookup(map,b->item+i);    if (!pval)    {    struct svalue val;    val.type=T_ARRAY;    val.u.array=low_allocate_array(1,1); -  val.u.array->item[0].type=T_INT; -  val.u.array->item[0].subtype=NUMBER_NUMBER; -  val.u.array->item[0].u.integer=i; -  mapping_insert(map,b->item+i,&val); +  ITEM(val.u.array)[0].u.integer=i; +  val.u.array->type_field = BIT_INT; +  mapping_insert(map,ITEM(b)+i,&val);    free_svalue(&val);    if (u) {    (*u)++;    }    }    else    {    pval->u.array=resize_array(pval->u.array,pval->u.array->size+1);    pval->u.array->item[pval->u.array->size-1].type=T_INT;    pval->u.array->item[pval->u.array->size-1].subtype=NUMBER_NUMBER;    pval->u.array->item[pval->u.array->size-1].u.integer=i;    }    }       res=low_allocate_array(a->size,0); -  +  types = 0;       for (i=0; i<a->size; i++)    {    pval=low_mapping_lookup(map,a->item+i);    if (!pval)    { -  res->item[i].type=T_ARRAY; -  add_ref(res->item[i].u.array=&empty_array); +  ITEM(res)[i].type=T_ARRAY; +  add_ref(ITEM(res)[i].u.array=&empty_array); +  types |= BIT_ARRAY;    }    else    { -  assign_svalue(res->item+i,pval); +  assign_svalue(ITEM(res)+i,pval); +  types |= 1 << ITEM(res)[i].type;    }    }    -  +  res->type_field = types;    pop_stack();    return res;   }      struct diff_magic_link   {    int x;    int refs;    struct diff_magic_link *prev;   };
pike.git/src/builtin_functions.c:5249:       free(marks);       /* FIXME(?) memory unfreed upon error here. */    a=low_allocate_array(top,0);    if (top)    {    dml=stack[top-1];    while (dml)    { -  a->item[--top].u.integer=dml->x; +  ITEM(a)[--top].u.integer=dml->x;    dml=dml->prev;    } -  +  a->type_field = BIT_INT;    }       free(stack);    dml_free_pools(pools);    return a;   }      /*    * The dynamic programming Longest Common Sequence algorithm.    *
pike.git/src/builtin_functions.c:5403:    /* Convert table into res */    sz = table[off1].depth;    dml = table[off1].link;    free(table);   #ifdef DIFF_DEBUG    fprintf(stderr, "Result array size:%d\n", sz);   #endif /* DIFF_DEBUG */       res = allocate_array(sz);    if (!res) { +  /* FIXME: This is never called, so there should probably be +  * SET_ONERROR stuff somewhere. I can't find where dml_pool is +  * initialized, though. /mast */    int args = 0;    if (dml_pool) {    dml_free_pools(dml_pool);    }    SIMPLE_OUT_OF_MEMORY_ERROR("diff_dyn_longest_sequence",    sizeof(struct array) +    sz*sizeof(struct svalue));    }       i = 0;    while(dml) {   #ifdef PIKE_DEBUG    if (i >= sz) {    Pike_fatal("Consistency error in diff_dyn_longest_sequence()\n");    }   #endif /* PIKE_DEBUG */   #ifdef DIFF_DEBUG    fprintf(stderr, " %02d: %d\n", i, dml->x);   #endif /* DIFF_DEBUG */ -  res->item[i].type = T_INT; -  res->item[i].subtype = 0; +     res->item[i].u.integer = dml->x;    dml = dml->prev;    i++;    } -  +  res->type_field = BIT_INT;   #ifdef PIKE_DEBUG    if (i != sz) {    Pike_fatal("Consistency error in diff_dyn_longest_sequence()\n");    }   #endif /* PIKE_DEBUG */       dml_free_pools(dml_pool);    return(res);   }   
pike.git/src/builtin_functions.c:6277:   }      /*! @module Array    */      /*! @decl array uniq(array a)    *!    *! Remove elements that are duplicates.    *!    *! @returns -  *! This function returns an copy of the array @[a] with all duplicate -  *! values removed. The order of the values is kept in the result. +  *! This function returns an copy of the array @[a] with all +  *! duplicate values removed. The order of the values is kept in the +  *! result; it's always the first of several equal elements that is +  *! kept. +  *! +  *! @note +  *! Elements are compared with @[`==]. They are also hashed (see +  *! @[lfun::__hash] for further details if @[a] contains objects).    */   PMOD_EXPORT void f_uniq_array(INT32 args)   {    struct array *a, *b;    struct mapping *m;    struct svalue one;    int i, j=0,size=0;       get_all_args("uniq", args, "%a", &a);    push_mapping(m = allocate_mapping(a->size));
pike.git/src/builtin_functions.c:6304:    {    mapping_insert(m, ITEM(a)+i, &one);    if(m_sizeof(m) != size)    {    size=m_sizeof(m);    assign_svalue_no_free(ITEM(b)+ j++, ITEM(a)+i);    }    }    dmalloc_touch_svalue(Pike_sp-1);    Pike_sp--; /* keep the ref to 'b' */ +  ACCEPT_UNFINISHED_TYPE_FIELDS {    b=resize_array(b, j); -  +  } END_ACCEPT_UNFINISHED_TYPE_FIELDS; +  b->type_field = a->type_field;    pop_n_elems(args-1); /* pop args and the mapping */    push_array(b);   }      /*! @decl array(mixed) splice(array(mixed) arr1, array(mixed) arr2, @    *! array(mixed) ... more_arrays)    *!    *! Splice two or more arrays.    *! -  *! This means that the the array becomes an array of the first element -  *! in the first given array, the first argument in next array and so on -  *! for all arrays. Then the second elements are added, etc. +  *! This means that the returned array has the first element in the +  *! first given array, then the first argument in next array and so +  *! on for all arrays. Then the second elements are added, etc.    *!    *! @seealso    *! @[`/()], @[`*()], @[`+()], @[`-()], @[everynth()]    */   PMOD_EXPORT void f_splice(INT32 args)   {    struct array *out;    INT32 size=0x7fffffff;    INT32 i,j,k;    - #ifdef PIKE_DEBUG -  if(args < 0) Pike_fatal("Negative args to f_splice()\n"); - #endif -  +     for(i=0;i<args;i++)    if (Pike_sp[i-args].type!=T_ARRAY)    SIMPLE_BAD_ARG_ERROR("splice", i+1, "array");    else    if (Pike_sp[i-args].u.array->size < size)    size=Pike_sp[i-args].u.array->size;       out=allocate_array(args * size);    if (!args)    {
pike.git/src/builtin_functions.c:6373:    *!    *! @seealso    *! @[splice()], @[`/()]    */   void f_everynth(INT32 args)   {    INT32 k,n=2;    INT32 start=0;    struct array *a;    struct array *ina; +  TYPE_FIELD types;    INT32 size=0;   #ifdef PIKE_DEBUG    if(args < 0) Pike_fatal("Negative args to f_everynth()\n");   #endif       check_all_args("everynth", args,    BIT_ARRAY, BIT_INT | BIT_VOID, BIT_INT | BIT_VOID , 0);       switch(args)    {
pike.git/src/builtin_functions.c:6399:    case 2:    n=Pike_sp[1-args].u.integer;    if(n<1)    bad_arg_error("everynth", Pike_sp-args, args, 2, "int", Pike_sp+1-args,    "Argument negative.\n");    case 1:    ina=Pike_sp[-args].u.array;    }       a=allocate_array(((size=ina->size)-start+n-1)/n); -  for(k=0; start<size; start+=n) -  assign_svalue_no_free(a->item+(k++), ina->item+start); +  types = 0; +  for(k=0; start<size; k++, start+=n) { +  assign_svalue_no_free(ITEM(a) + k, ina->item+start); +  types |= 1 << ITEM(a)[k].type; +  } +  a->type_field=types;    -  a->type_field=ina->type_field; +     pop_n_elems(args);    push_array(a);    return;   }      /*! @decl array(array) transpose(array(array) matrix)    */   PMOD_EXPORT void f_transpose(INT32 args)   {    struct array *out;
pike.git/src/builtin_functions.c:6644:    *!    *! @seealso    *! @[map()]    */   PMOD_EXPORT void f_map_array(INT32 args)   {    ONERROR tmp;    INT32 e;    struct svalue *fun;    struct array *ret,*foo; +  TYPE_FIELD types;       if (args < 2)    SIMPLE_TOO_FEW_ARGS_ERROR("map_array", 2);       if(Pike_sp[-args].type != T_ARRAY)    SIMPLE_BAD_ARG_ERROR("map_array", 1, "array");       foo=Pike_sp[-args].u.array;    fun=Pike_sp-args+1;       ret=allocate_array(foo->size); -  +  types = 0;    SET_ONERROR(tmp, do_free_array, ret);    for(e=0;e<foo->size;e++)    { -  push_svalue(foo->item+e); +  push_svalue(ITEM(foo)+e);    assign_svalues_no_free(Pike_sp,fun+1,args-2,-1);    Pike_sp+=args-2;    apply_svalue(fun,args-1); -  ret->item[e]=*(--Pike_sp); -  dmalloc_touch_svalue(Pike_sp); +  stack_pop_to_no_free (ITEM(ret) + e); +  types |= 1 << ITEM(ret)[e].type;    } -  +  ret->type_field = types;    pop_n_elems(args);    UNSET_ONERROR(tmp);    push_array(ret);   }      /*! @decl mixed map(mixed arr, void|mixed fun, mixed ... extra)    *!    *! Applies @[fun] to the elements in @[arr] and collects the results.    *!    *! @[arr] is treated as a set of elements, as follows:
pike.git/src/builtin_functions.c:6743:    *! The function is never destructive on @[arr].    *!    *! @seealso    *! @[filter()], @[enumerate()], @[foreach()]    */   PMOD_EXPORT void f_map(INT32 args)   {    struct svalue *mysp;    struct array *a,*d;    int splice,i,n; +  TYPE_FIELD types;       if (args<1)    SIMPLE_TOO_FEW_ARGS_ERROR("map", 1);    else if (args<2)    { push_int(0); args++; }       switch (Pike_sp[-args].type)    {    case T_ARRAY:    break;
pike.git/src/builtin_functions.c:6894:    f_arrow(2);    if (!UNSAFE_IS_ZERO(Pike_sp-2)&&!UNSAFE_IS_ZERO(Pike_sp-1))    {    f_call_function(1);    if (Pike_sp[-1].type!=T_INT)    SIMPLE_BAD_ARG_ERROR("map", 1,    "object sizeof() returning integer");    n=Pike_sp[-1].u.integer;    pop_stack();    push_array(d=allocate_array(n)); +  types = 0;    stack_swap();    for (i=0; i<n; i++)    {    stack_dup(); /* `[] */    push_int(i);    f_call_function(2); -  d->item[i]=*(--Pike_sp); -  dmalloc_touch_svalue(Pike_sp); +  stack_pop_to_no_free (ITEM(d) + i); +  types |= 1 << ITEM(d)->type;    } -  +  d->type_field = types;    pop_stack();    free_svalue(mysp-3);    mysp[-3]=*(--Pike_sp);    dmalloc_touch_svalue(Pike_sp);    f_map(args);    return;    }    pop_stack();    pop_stack();   
pike.git/src/builtin_functions.c:6938:       switch (mysp[-2].type)    {    case T_FUNCTION:    case T_PROGRAM:    case T_OBJECT:    case T_ARRAY:    /* ret[i]=fun(arr[i],@extra); */    push_array(d=allocate_array(n));    d=Pike_sp[-1].u.array; +  types = 0;       if(mysp[-2].type == T_FUNCTION &&    mysp[-2].subtype == FUNCTION_BUILTIN)    {    c_fun fun=mysp[-2].u.efun->function;    struct svalue *spbase=Pike_sp;       if(splice)    {    for (i=0; i<n; i++)    {    push_svalue(a->item+i);    add_ref_svalue(mysp-1);    push_array_items(mysp[-1].u.array);    (* fun)(1+splice);    if(Pike_sp>spbase)    { -  dmalloc_touch_svalue(Pike_sp-1); -  d->item[i]=*--Pike_sp; +  stack_pop_to_no_free (ITEM(d) + i); +  types |= 1 << ITEM(d)[i].type;    pop_n_elems(Pike_sp-spbase);    }    }    }else{    for (i=0; i<n; i++)    { -  push_svalue(a->item+i); +  push_svalue(ITEM(a)+i);    (* fun)(1);    if(Pike_sp>spbase)    { -  dmalloc_touch_svalue(Pike_sp-1); -  d->item[i]=*--Pike_sp; +  stack_pop_to_no_free (ITEM(d) + i); +  types |= 1 << ITEM(d)[i].type;    pop_n_elems(Pike_sp-spbase);    }    }    }    }else{    for (i=0; i<n; i++)    { -  push_svalue(a->item+i); +  push_svalue(ITEM(a)+i);    if (splice)    {    add_ref_svalue(mysp-1);    push_array_items(mysp[-1].u.array);    apply_svalue(mysp-2,1+splice);    }    else    {    apply_svalue(mysp-2,1);    } -  dmalloc_touch_svalue(Pike_sp-1); -  d->item[i]=*--Pike_sp; +  stack_pop_to_no_free (ITEM(d) + i); +  types |= 1 << ITEM(d)[i].type;    }    } -  +  d->type_field = types;    stack_pop_n_elems_keep_top(3); /* fun arr extra d -> d */    return;       case T_MAPPING:    case T_MULTISET:    /* ret[i]=fun[arr[i]]; */    pop_stack();    stack_swap();    f_rows(2);    return;       case T_STRING:    /* ret[i]=arr[i][fun](@extra); */    push_array(d=allocate_array(n)); -  d=Pike_sp[-1].u.array; +  types = 0;    for (i=0; i<n; i++)    { -  push_svalue(a->item+i); +  push_svalue(ITEM(a)+i);    push_svalue(mysp-2);    f_arrow(2);    if(UNSAFE_IS_ZERO(Pike_sp-1))    {    pop_stack();    continue;    }    add_ref_svalue(mysp-1);    push_array_items(mysp[-1].u.array);    f_call_function(splice+1); -  d->item[i]=*--Pike_sp; -  dmalloc_touch_svalue(Pike_sp); +  stack_pop_to_no_free (ITEM(d) + i); +  types |= 1 << ITEM(d)[i].type;    } -  +  d->type_field = types;    stack_pop_n_elems_keep_top(3); /* fun arr extra d -> d */    return;       case T_INT:    if (mysp[-2].u.integer==0)    {    /* ret=arr(@extra); */    stack_swap(); /* arr fun extra -> arr extra fun */    pop_stack(); /* arr extra */    Pike_sp--;
pike.git/src/builtin_functions.c:7409:    INT_TYPE step,start;       get_all_args("enumerate", args, "%i%i%i", &n, &step, &start);    if (n<0)    SIMPLE_BAD_ARG_ERROR("enumerate",1,"int(0..)");       pop_n_elems(args);    push_array(d=allocate_array(n));    for (i=0; i<n; i++)    { -  d->item[i].u.integer=start; -  d->item[i].type=T_INT; -  d->item[i].subtype=NUMBER_NUMBER; +  ITEM(d)[i].u.integer=start;   #ifdef AUTO_BIGNUM    if ((step>0 && start+step<start) ||    (step<0 && start+step>start)) /* overflow */    {    pop_stack();    push_int(n);    push_int(step);    convert_stack_top_to_bignum();    push_int(start);    convert_stack_top_to_bignum();    f_enumerate(3);    return;    }   #endif    start+=step;    } -  +  d->type_field = BIT_INT;    }    else if (args<=3 &&    ((Pike_sp[1-args].type==T_INT ||    Pike_sp[1-args].type==T_FLOAT) &&    (Pike_sp[2-args].type==T_INT ||    Pike_sp[2-args].type==T_FLOAT) ) )    {    FLOAT_TYPE step, start;       get_all_args("enumerate", args, "%i%F%F", &n, &step, &start);
pike.git/src/builtin_functions.c:7450:       pop_n_elems(args);       push_array(d=allocate_array(n));    for (i=0; i<n; i++)    {    d->item[i].u.float_number=start;    d->item[i].type=T_FLOAT;    start+=step;    } +  d->type_field = BIT_FLOAT;    }    else    { -  +  TYPE_FIELD types = 0;    get_all_args("enumerate", args, "%i", &n);    if (n<0) SIMPLE_BAD_ARG_ERROR("enumerate",1,"int(0..)");    if (args>4) pop_n_elems(args-4); -  +  push_array(d=allocate_array(n));    if (args<4)    { -  push_array(d=allocate_array(n)); +     push_svalue(Pike_sp-2); /* start */    for (i=0; i<n; i++)    { -  assign_svalue_no_free(d->item+i,Pike_sp-1); +  assign_svalue_no_free(ITEM(d)+i,Pike_sp-1); +  types |= 1 << ITEM(d)[i].type;    if (i<n-1)    {    push_svalue(Pike_sp-4); /* step */    f_add(2);    }    }    }    else    { -  push_array(d=allocate_array(n)); +     push_svalue(Pike_sp-3); /* start */    for (i=0; i<n; i++)    { -  assign_svalue_no_free(d->item+i,Pike_sp-1); +  assign_svalue_no_free(ITEM(d)+i,Pike_sp-1); +  types |= 1 << ITEM(d)[i].type;    if (i<n-1)    {    push_svalue(Pike_sp-3); /* function */    stack_swap();    push_svalue(Pike_sp-6); /* step */    f_call_function(3);    }    }    } -  +  d->type_field = types;    pop_stack();    stack_pop_n_elems_keep_top(args);    }   }      /*! @module Program    */      /*! @decl array(program) inherit_list(program p)    *!