pike.git / src / pike_types.c

version» Context lines:

pike.git/src/pike_types.c:1:   /*\   ||| This file a part of Pike, and is copyright by Fredrik Hubinette   ||| Pike is distributed as GPL (General Public License)   ||| See the files COPYING and DISCLAIMER for more information.   \*/   /**/   #include "global.h" - RCSID("$Id: pike_types.c,v 1.171 2001/03/28 14:56:02 grubba Exp $"); + RCSID("$Id: pike_types.c,v 1.172 2001/03/29 20:19:16 grubba Exp $");   #include <ctype.h>   #include "svalue.h"   #include "pike_types.h"   #include "stralloc.h"   #include "stuff.h"   #include "array.h"   #include "program.h"   #include "constants.h"   #include "object.h"   #include "multiset.h"
pike.git/src/pike_types.c:187: Inside #if defined(USE_PIKE_TYPE)
   * TUPLE type type    * MAPPING index type value type    * OR type type    * AND type type    * ARRAY type -    * MULTISET type -    * NOT type -    * '0'-'9' - -    * FLOAT - -    * STRING - - -  * TYPE - - +  * TYPE type -    * PROGRAM type -    * MIXED - -    * VOID - -    * ZERO - -    * UNKNOWN - -    * INT min (int) max (int)    * OBJECT implements/is object id(int)    *    * Note that the cdr of a FUNCTION is a valid FUNCTION for the rest of    * the arguments.
pike.git/src/pike_types.c:209: Inside #if defined(USE_PIKE_TYPE)
   * Note also that functions that don't take any arguments, or just    * a many argument just have a MANY node, and no FUNCTION node.    *    */   #define PIKE_TYPE_CHUNK 128   BLOCK_ALLOC(pike_type, PIKE_TYPE_CHUNK)      static struct pike_type **pike_type_hash = NULL;   static size_t pike_type_hash_size = 0;    - void free_type(struct pike_type *t) + void debug_free_type(struct pike_type *t)   {    loop: -  if (!(--(t->refs))) { +  if (!(--(((struct pike_type *)debug_malloc_pass(t))->refs))) {    unsigned INT32 hash = t->hash % pike_type_hash_size;    struct pike_type **t2 = pike_type_hash + hash;    struct pike_type *car, *cdr;    unsigned INT32 type;    -  while (*t2 && *t2 != t) { -  t2 = &((*t2)->next); -  } -  if (*t2) { +  while (*t2) { +  if (*t2 == t) {    *t2 = t->next; -  +  break;    } -  +  t2 = &((*t2)->next); +  }       car = t->car;    cdr = t->cdr;    type = t->type;    -  really_free_pike_type(t); +  really_free_pike_type((struct pike_type *)debug_malloc_pass(t));       /* FIXME: Recursion: Should we use a stack? */    switch(type) {    case T_FUNCTION:    case T_MANY:    case T_TUPLE:    case T_MAPPING:    case T_OR:    case T_AND:    case PIKE_T_RING:    /* Free car & cdr */    free_type(car); -  t = cdr; +  t = (struct pike_type *)debug_malloc_pass(cdr);    goto loop;       case T_ARRAY:    case T_MULTISET:    case T_NOT: -  +  case T_TYPE: +  case T_PROGRAM:    /* Free car */ -  t = car; +  t = (struct pike_type *)debug_malloc_pass(car);    goto loop;       case T_SCOPE:    case T_ASSIGN:    /* Free cdr */ -  t = cdr; +  t = (struct pike_type *)debug_malloc_pass(cdr);    goto loop;       case PIKE_T_NAME:    free_string((struct pike_string *)car); -  t = cdr; +  t = (struct pike_type *)debug_malloc_pass(cdr);    goto loop; -  +  + #ifdef PIKE_DEBUG +  case '0': +  case '1': +  case '2': +  case '3': +  case '4': +  case '5': +  case '6': +  case '7': +  case '8': +  case '9': +  case T_FLOAT: +  case T_STRING: +  case T_MIXED: +  case T_VOID: +  case T_ZERO: +  case PIKE_T_UNKNOWN: +  case T_INT: +  case T_OBJECT: +  break; +  +  default: +  fatal("free_type(): Unhandled type-node: %d\n", type); +  break; + #endif /* PIKE_DEBUG */    }    }   }      /* Flags used as flag_method: */   #define PT_COPY_CAR 1   #define PT_COPY_CDR 2   #define PT_COPY_BOTH 3   #define PT_SET_MARKER 4    - static inline struct pike_type *mk_type(unsigned INT32 type, + static inline struct pike_type *debug_mk_type(unsigned INT32 type,    struct pike_type *car,    struct pike_type *cdr,    int flag_method)   {    unsigned INT32 hash = DO_NOT_WARN((unsigned INT32)    ((ptrdiff_t)type*0x10204081)^    (0x8003*(ptrdiff_t)car)^    ~(0x10001*(ptrdiff_t)cdr));    unsigned INT32 index = hash % pike_type_hash_size;    struct pike_type *t;       for(t = pike_type_hash[index]; t; t = t->next) {    if ((t->hash == hash) && (t->type == type) &&    (t->car == car) && (t->cdr == cdr)) { -  +  /* Free car & cdr as appropriate. */    switch(type) {    case T_FUNCTION:    case T_MANY:    case T_TUPLE:    case T_MAPPING:    case T_OR:    case T_AND:    case PIKE_T_RING:    /* Free car & cdr */ -  free_type(car); -  free_type(cdr); +  free_type((struct pike_type *)debug_malloc_pass(car)); +  free_type((struct pike_type *)debug_malloc_pass(cdr));    break;       case T_ARRAY:    case T_MULTISET:    case T_NOT:    case T_TYPE:    case T_PROGRAM:    /* Free car */ -  free_type(car); +  free_type((struct pike_type *)debug_malloc_pass(car));    break;       case T_SCOPE:    case T_ASSIGN:    /* Free cdr */ -  free_type(cdr); +  free_type((struct pike_type *)debug_malloc_pass(cdr));    break;       case PIKE_T_NAME: -  free_string((struct pike_string *)car); -  free_type(cdr); +  free_string((struct pike_string *)debug_malloc_pass(car)); +  free_type((struct pike_type *)debug_malloc_pass(cdr));    break; -  +  + #ifdef PIKE_DEBUG +  case '0': +  case '1': +  case '2': +  case '3': +  case '4': +  case '5': +  case '6': +  case '7': +  case '8': +  case '9': +  case T_FLOAT: +  case T_STRING: +  case T_MIXED: +  case T_VOID: +  case T_ZERO: +  case PIKE_T_UNKNOWN: +  case T_INT: +  case T_OBJECT: +  break; +  +  default: +  fatal("mk_type(): Unhandled type-node: %d\n", type); +  break; + #endif /* PIKE_DEBUG */    } -  /* FIXME: Free car & cdr as appropriate. */ -  add_ref(t); +  add_ref((struct pike_type *)debug_malloc_pass(t));    return t;    }    }    -  t = alloc_pike_type(); +  debug_malloc_pass(t = alloc_pike_type());       t->refs = 1;    t->type = type;    t->flags = 0;    t->car = car;    t->cdr = cdr;       t->hash = hash;    t->next = pike_type_hash[index];    pike_type_hash[index] = t;
pike.git/src/pike_types.c:351:    } else {    if (car && (flag_method & PT_COPY_CAR)) {    t->flags = car->flags;    }    if (cdr && (flag_method & PT_COPY_CDR)) {    t->flags |= cdr->flags;    }    }    }    + #ifdef DEBUG_MALLOC +  switch(type) { +  case T_FUNCTION: +  case T_MANY: +  case T_TUPLE: +  case T_MAPPING: +  case T_OR: +  case T_AND: +  case PIKE_T_RING: +  debug_malloc_pass(car); +  debug_malloc_pass(cdr); +  break; +  +  case T_ARRAY: +  case T_MULTISET: +  case T_NOT: +  case T_TYPE: +  case T_PROGRAM: +  debug_malloc_pass(car); +  break; +  +  case T_SCOPE: +  case T_ASSIGN: +  debug_malloc_pass(cdr); +  break; +  +  case PIKE_T_NAME: +  debug_malloc_pass(car); +  debug_malloc_pass(cdr); +  break; +  +  case '0': +  case '1': +  case '2': +  case '3': +  case '4': +  case '5': +  case '6': +  case '7': +  case '8': +  case '9': +  case T_FLOAT: +  case T_STRING: +  case T_MIXED: +  case T_VOID: +  case T_ZERO: +  case PIKE_T_UNKNOWN: +  case T_INT: +  case T_OBJECT: +  break; +  +  default: +  fatal("mk_type(): Unhandled type-node: %d\n", type); +  break; +  } + #endif /* DEBUG_MALLOC */ +     return t;   }    -  + #ifdef DEBUG_MALLOC + #define mk_type(T,CAR,CDR,FLAG) ((struct pike_type *)debug_malloc_pass(debug_mk_type(T,CAR,CDR,FLAG))) + #else /* !DEBUG_MALLOC */ + #define mk_type debug_mk_type + #endif /* DEBUG_MALLOC */ +    #ifdef PIKE_DEBUG - void check_type_string(struct pike_type *s) + void debug_check_type_string(struct pike_type *s)   {    /* FIXME: Add verification code here */   } -  +    #endif /* PIKE_DEBUG */      struct pike_type *type_stack[PIKE_TYPE_STACK_SIZE];   struct pike_type **pike_type_mark_stack[PIKE_TYPE_STACK_SIZE/4];      ptrdiff_t pop_stack_mark(void)   {    Pike_compiler->pike_type_mark_stackp--;    if(Pike_compiler->pike_type_mark_stackp<pike_type_mark_stack)    fatal("Type mark stack underflow\n");
pike.git/src/pike_types.c:384:      void type_stack_pop_to_mark(void)   {    pop_stack_mark();    while(Pike_compiler->type_stackp > *Pike_compiler->pike_type_mark_stackp)    pop_type_stack();       TYPE_STACK_DEBUG("type_stack_pop_to_mark");   }    - void push_int_type(INT32 min, INT32 max) + struct pike_type *debug_peek_type_stack(void)   { -  +  return *(Pike_compiler->type_stackp); + } +  + void debug_push_int_type(INT32 min, INT32 max) + {    *(++Pike_compiler->type_stackp) = mk_type(T_INT,    (void *)(ptrdiff_t)min,    (void *)(ptrdiff_t)max, 0);       TYPE_STACK_DEBUG("push_int_type");   }    - void push_object_type(int flag, INT32 id) + void debug_push_object_type(int flag, INT32 id)   {    *(++Pike_compiler->type_stackp) = mk_type(T_OBJECT,    (void *)(ptrdiff_t)flag,    (void *)(ptrdiff_t)id, 0);       TYPE_STACK_DEBUG("push_object_type");   }    - void push_object_type_backwards(int flag, INT32 id) + void debug_push_object_type_backwards(int flag, INT32 id)   {    push_object_type(flag, id);   }    - void push_scope_type(int level) + void debug_push_scope_type(int level)   {    *Pike_compiler->type_stackp = mk_type(T_SCOPE,    (void *)(ptrdiff_t)level,    *Pike_compiler->type_stackp,    PT_COPY_CDR);       TYPE_STACK_DEBUG("push_scope_type");   }    - void push_assign_type(int marker) + void debug_push_assign_type(int marker)   {    marker -= '0';   #ifdef PIKE_DEBUG    if ((marker < 0) || (marker > 9)) {    fatal("Bad assign marker: %ld\n", marker);    }   #endif /* PIKE_DEBUG */       *Pike_compiler->type_stackp = mk_type(T_ASSIGN,    (void *)(ptrdiff_t)marker,    *Pike_compiler->type_stackp,    PT_COPY_CDR);    TYPE_STACK_DEBUG("push_assign_type");   }    - void push_type_name(struct pike_string *name) + void debug_push_type_name(struct pike_string *name)   {    /* fprintf(stderr, "push_type_name(\"%s\")\n", name->str); */    add_ref(name);    *Pike_compiler->type_stackp = mk_type(PIKE_T_NAME,    (void *)name,    *Pike_compiler->type_stackp,    PT_COPY_CDR);    TYPE_STACK_DEBUG("push_type_name");   }    - void push_finished_type(struct pike_type *t) + void debug_push_finished_type(struct pike_type *t)   {    copy_type(*(++Pike_compiler->type_stackp), t);       TYPE_STACK_DEBUG("push_finished_type");   }    - void push_type(unsigned INT16 type) + void debug_push_type(unsigned INT16 type)   {    /* fprintf(stderr, "push_type(%d)\n", type); */       switch(type) {    case T_FUNCTION:    case T_MANY:    case T_TUPLE:    case T_MAPPING:    case T_OR:    case T_AND:
pike.git/src/pike_types.c:521:    case '9':    /* Marker. */    *(++Pike_compiler->type_stackp) = mk_type(type, NULL, NULL, PT_SET_MARKER);    break;    }       TYPE_STACK_DEBUG("push_type");   }      /* Pop one level of types. This is the inverse of push_type() */ - void pop_type_stack(void) + void debug_pop_type_stack(void)   {    struct pike_type *top;    if(Pike_compiler->type_stackp<type_stack)    fatal("Type stack underflow\n");       top = *(Pike_compiler->type_stackp--);    switch(top->type) {    case T_FUNCTION:    case T_MANY:    case T_TUPLE:
pike.git/src/pike_types.c:586:    pop_type_stack();    break;    default:    Pike_error("pop_type_stack(): Unhandled node type: %d\n", top->type);    }    free_type(top);       TYPE_STACK_DEBUG("pop_type_stack");   }    - void push_reverse_type(unsigned INT16 type) + void debug_push_reverse_type(unsigned INT16 type)   {    /* fprintf(stderr, "push_reverse_type(%d)\n", type); */       switch(type) {    case T_FUNCTION:    case T_MANY:    case T_TUPLE:    case T_MAPPING:    case T_OR:    case T_AND:
pike.git/src/pike_types.c:611:    Pike_compiler->type_stackp[0] = Pike_compiler->type_stackp[-1];    Pike_compiler->type_stackp[-1] = tmp;    break;    }    }    push_type(type);       TYPE_STACK_DEBUG("push_reverse_type");   }    - void push_finished_type_with_markers(struct pike_type *type, + void debug_push_finished_type_with_markers(struct pike_type *type,    struct pike_type **markers)   {    recurse:   #if 0    fprintf(stderr, "push_finished_type_with_markers((%d[%x]),...)...\n",    type->type, type->flags);   #endif /* 0 */    if (!(type->flags & PT_FLAG_MARKER)) {    /* No markers in this sub-tree */   #if 0
pike.git/src/pike_types.c:1193: Inside #if defined(PIKE_DEBUG)
   while(s->type == T_FUNCTION) {    simple_describe_type(s->car);    s = s->cdr;    if ((s->type == T_FUNCTION) ||    (s->car->type != T_VOID)) {    fprintf(stderr, ", ");    }    }    if (s->car->type != T_VOID) {    simple_describe_type(s->car); +  fprintf(stderr, "...");    }    fprintf(stderr, ":"); -  describe_type(s->cdr); +  simple_describe_type(s->cdr);    fprintf(stderr, ")");    break;    case T_ARRAY:    fprintf(stderr, "array(");    simple_describe_type(s->car);    fprintf(stderr, ")");    break;    case T_MAPPING:    fprintf(stderr, "mapping(");    simple_describe_type(s->car);
pike.git/src/pike_types.c:1256: Inside #if defined(PIKE_DEBUG)
      default:    fprintf(stderr, "Unknown type node: %d, %p:%p",    s->type, s->car, s->cdr);    break;    }    } else {    fprintf(stderr, "NULL");    }   } +  + #ifdef DEBUG_MALLOC + void describe_all_types(void) + { +  unsigned INT32 index; +  +  for(index = 0; index < pike_type_hash_size; index++) { +  struct pike_type *t; +  for (t = pike_type_hash[index]; t; t = t->next) { +  if (t->refs) { +  fprintf(stderr, "Type at 0x%p: ", t); +  simple_describe_type(t); +  fprintf(stderr, " (refs:%ld)\n", (long)t->refs); +  } +  } +  } + } + #endif /* DEBUG_MALLOC */   #endif      static void low_describe_type(struct pike_type *t)   {    /**** FIXME: ****/    switch(t->type)    {    case '0': case '1': case '2': case '3': case '4':    case '5': case '6': case '7': case '8': case '9':    my_putchar(t->type);
pike.git/src/pike_types.c:4037:    free_string(s2);    }       if(implements_a && implements_b)    yyexplain_not_implements(implements_a,implements_b,flags);   }         /******/    - static struct pike_type *low_make_pike_type(unsigned char *type_string, + #ifdef DEBUG_MALLOC + #define low_make_pike_type(T,C) ((struct pike_type *)debug_malloc_pass(debug_low_make_pike_type(T,C))) + #define low_make_function_type(T,C) ((struct pike_type *)debug_malloc_pass(debug_low_make_function_type(T,C))) + #else /* !DEBUG_MALLOC */ + #define low_make_pike_type debug_low_make_pike_type + #define low_make_function_type debug_low_make_function_type + #endif /* DEBUG_MALLOC */ +  + static struct pike_type *debug_low_make_pike_type(unsigned char *type_string,    unsigned char **cont);    - static struct pike_type *low_make_function_type(unsigned char *type_string, + static struct pike_type *debug_low_make_function_type(unsigned char *type_string,    unsigned char **cont)   {    if (*type_string == T_MANY) {    return mk_type(T_MANY, low_make_pike_type(type_string+1, cont),    low_make_pike_type(*cont, cont), PT_COPY_BOTH);    }    return mk_type(T_FUNCTION, low_make_pike_type(type_string, cont),    low_make_function_type(*cont, cont), PT_COPY_BOTH);   }    - static struct pike_type *low_make_pike_type(unsigned char *type_string, + static struct pike_type *debug_low_make_pike_type(unsigned char *type_string,    unsigned char **cont)   {    unsigned INT32 type;       switch(type = *type_string) {    case T_SCOPE:    case T_ASSIGN:    if ((type_string[1] < '0') || (type_string[1] > '9')) {    fatal("low_make_pike_type(): Bad marker: %d\n", type_string[1]);    }
pike.git/src/pike_types.c:4131:    default:    fatal("compile_type_string(): Error in type string %d.\n", type);    /* NOT_REACHED */    break;    }    /* NOT_REACHED */    return NULL;   }      /* Make a pike-type from a serialized (old-style) type. */ - struct pike_type *make_pike_type(const char *serialized_type) + struct pike_type *debug_make_pike_type(const char *serialized_type)   {    return low_make_pike_type((unsigned char *)serialized_type,    (unsigned char **)&serialized_type);   }      int pike_type_allow_premature_toss(struct pike_type *type)   {    again:   #if 0    fprintf(stderr, "pike_type_allow_premature_toss(): Type: %d\n",
pike.git/src/pike_types.c:4429:      ptrdiff_t pop_stack_mark(void)   {    Pike_compiler->pike_type_mark_stackp--;    if(Pike_compiler->pike_type_mark_stackp<pike_type_mark_stack)    fatal("Type mark stack underflow\n");       return Pike_compiler->type_stackp - *Pike_compiler->pike_type_mark_stackp;   }    - void pop_type_stack(void) + void debug_pop_type_stack(void)   {    Pike_compiler->type_stackp--;    if(Pike_compiler->type_stackp<type_stack)    fatal("Type stack underflow\n");   }         void type_stack_pop_to_mark(void)   {    Pike_compiler->type_stackp-=pop_stack_mark();
pike.git/src/pike_types.c:4467:    push_type(DO_NOT_WARN((unsigned char)((i>>(e*8)) & 0xff)));   }      static void push_type_int_backwards(INT32 i)   {    int e;    for(e=(int)sizeof(i);e-->0;)    push_type( (i>>(e*8)) & 0xff );   }    - void push_int_type(INT32 min, INT32 max) + void debug_push_int_type(INT32 min, INT32 max)   {    push_type_int(max);    push_type_int(min);    push_type(T_INT);   }    - void push_assign_type(int marker) + void debug_push_assign_type(int marker)   {    push_type(marker);    push_type(T_ASSIGN);   }    - void push_object_type(int flag, INT32 id) + void debug_push_object_type(int flag, INT32 id)   {    push_type_int(id);    push_type(flag);    push_type(T_OBJECT);   }    - void push_object_type_backwards(int flag, INT32 id) + void debug_push_object_type_backwards(int flag, INT32 id)   {    unsafe_push_type(T_OBJECT);    unsafe_push_type(flag);    push_type_int_backwards(id);   }      INT32 extract_type_int(char *p)   {    int e;    INT32 ret=0;    for(e=0;e<(int)sizeof(INT32);e++)    ret=(ret<<8) | EXTRACT_UCHAR(p+e);    return ret;   }    - void push_unfinished_type(char *s) + void debug_push_unfinished_type(char *s)   {    ptrdiff_t e;    e=type_length(s);    for(e--;e>=0;e--) push_type(s[e]);   }      static void push_unfinished_type_with_markers(char *s,    struct pike_type **am)   {    int d,e,c;
pike.git/src/pike_types.c:4559:    for(d=0;d<(int)sizeof(INT32)+1;d++) push_type(EXTRACT_UCHAR(s+ ++e));    break;       default:    push_type(c);    }    }    type_stack_reverse();   }    - void push_finished_type(struct pike_type *type) + void debug_push_finished_type(struct pike_type *type)   {    ptrdiff_t e;    check_type_string(type);    for(e=type->len-1;e>=0;e--) push_type(type->str[e]);   }    - void push_finished_type_backwards(struct pike_type *type) + void debug_push_finished_type_backwards(struct pike_type *type)   {    int e;    check_type_string(type);    MEMCPY(Pike_compiler->type_stackp, type->str, type->len);    Pike_compiler->type_stackp+=type->len;   }      struct pike_type *debug_pop_unfinished_type(void)   {    ptrdiff_t len, e;
pike.git/src/pike_types.c:7724:    }    free_string(s1);    free_string(s2);    }       if(implements_a && implements_b)    yyexplain_not_implements(implements_a,implements_b,flags);   }       - struct pike_type *make_pike_type(const char *t) + struct pike_type *debug_make_pike_type(const char *t)   {    return make_shared_binary_string(t, type_length(t));   }         static int low_pike_type_allow_premature_toss(char *type)   {    again:    switch(EXTRACT_UCHAR(type++))    {
pike.git/src/pike_types.c:7796:   }      void init_types(void)   {   #ifdef USE_PIKE_TYPE    /* Initialize hashtable here. */    pike_type_hash = (struct pike_type **)xalloc(sizeof(struct pike_type *) *    PIKE_TYPE_HASH_SIZE);    MEMSET(pike_type_hash, 0, sizeof(struct pike_type *) * PIKE_TYPE_HASH_SIZE);    pike_type_hash_size = PIKE_TYPE_HASH_SIZE; - #endif /* USE_PIKE_TYPE */ +     init_pike_type_blocks(); -  + #endif /* USE_PIKE_TYPE */    string_type_string = CONSTTYPE(tString);    int_type_string = CONSTTYPE(tInt);    object_type_string = CONSTTYPE(tObj);    program_type_string = CONSTTYPE(tPrg(tObj));    float_type_string = CONSTTYPE(tFloat);    mixed_type_string = CONSTTYPE(tMix);    array_type_string = CONSTTYPE(tArray);    multiset_type_string = CONSTTYPE(tMultiset);    mapping_type_string = CONSTTYPE(tMapping);    function_type_string = CONSTTYPE(tFunction);
pike.git/src/pike_types.c:7842:    free_type(program_type_string);    free_type(array_type_string);    free_type(multiset_type_string);    free_type(mapping_type_string);    free_type(type_type_string);    free_type(mixed_type_string);    free_type(void_type_string);    free_type(zero_type_string);    free_type(any_type_string);    free_type(weak_type_string); + } +  + void cleanup_pike_type_table(void) + {   #ifdef USE_PIKE_TYPE    /* Free the hashtable here. */    if (pike_type_hash) {    free(pike_type_hash);    /* Don't do this, it messes up stuff... */    /* pike_type_hash = NULL; */    }    /* Don't do this, it messes up stuff... */    /* pike_type_hash_size = 0; */ -  + #ifdef DEBUG_MALLOC +  free_all_pike_type_blocks(); + #endif /* DEBUG_MALLOC */   #endif /* USE_PIKE_TYPE */   }