pike.git / src / las.c

version» Context lines:

pike.git/src/las.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: las.c,v 1.392 2007/09/06 13:24:01 grubba Exp $ + || $Id: las.c,v 1.393 2007/10/06 13:45:22 grubba Exp $   */      #include "global.h"   #include "interpret.h"   #include "las.h"   #include "array.h"   #include "object.h"   #include "stralloc.h"   #include "dynamic_buffer.h"   #include "lex.h"
pike.git/src/las.c:114: Inside #if defined(PIKE_DEBUG)
      if (!n) return;       parent = n->parent;    n->parent = NULL;       while(n) {    if(n->token==USHRT_MAX)    Pike_fatal("Free node in tree.\n");    -  check_node_hash(n); -  +     switch(n->token)    {    case F_EXTERNAL:    case F_GET_SET:    if(n->type)    {    int parent_id = n->u.integer.a;    int id_no = n->u.integer.b;    struct program_state *state = Pike_compiler;    while (state && (state->new_program->id != parent_id)) {
pike.git/src/las.c:166: Inside #if defined(PIKE_DEBUG)
   if(!(depth & 1023))    {    node *q;    for(q=n->parent;q;q=q->parent)    if(q->parent==n)    Pike_fatal("Cyclic node structure found.\n");    }       if(car_is_node(n))    { -  /* Check CAR */ - #ifdef SHARED_NODES +  /* Update parent for CAR */    CAR(n)->parent = n; - #else /* !SHARED_NODES */ -  if(CAR(n)->parent != n) -  Pike_fatal("Parent is wrong.\n"); - #endif /* SHARED_NODES */ -  +     depth++;    n = CAR(n);    continue;    }       if(cdr_is_node(n))    { -  /* Check CDR */ - #ifdef SHARED_NODES +  /* Update parent for CDR */    CDR(n)->parent = n; - #else /* !SHARED_NODES */ -  if(CDR(n)->parent != n) -  Pike_fatal("Parent is wrong.\n"); - #endif /* !SHARED_NODES */ -  +     depth++;    n = CDR(n);    continue;    }       while(n->parent &&    (!cdr_is_node(n->parent) || (CDR(n->parent) == n))) {    /* Backtrack */    n = n->parent;    depth--;    }       if (n->parent && cdr_is_node(n->parent)) {    /* Jump to the sibling */ - #ifdef SHARED_NODES +     CDR(n->parent)->parent = n->parent; - #else /* !SHARED_NODES */ -  if(CDR(n->parent)->parent != n->parent) -  Pike_fatal("Parent is wrong.\n"); - #endif /* !SHARED_NODES */ +     n = CDR(n->parent);    continue;    }    break;    }       if (n != orig_n) {    fputs("check_tree() lost track.\n", stderr);    d_flag = 0;    fputs("n:", stderr);
pike.git/src/las.c:390:    if (pike_types_le(n->type, t)) return 1;    if (!match_types(n->type, t)) {    yytype_error(msg, t, n->type, 0);    return 0;    }    if (lex.pragmas & ID_STRICT_TYPES) {    yytype_error(msg, t, n->type, YYTE_IS_WARNING);    }    if (runtime_options & RUNTIME_CHECK_TYPES) {    node *p = n->parent; -  p->node_info |= OPT_DEFROSTED; +     if (CAR(p) == n) {    (_CAR(p) = mksoftcastnode(t, n))->parent = p;    } else if (CDR(p) == n) {    (_CDR(p) = mksoftcastnode(t, n))->parent = p;    } else {    yywarning("Failed to find place to insert soft cast.");    }    }    return 1;   }
pike.git/src/las.c:417:    NODE->token = USHRT_MAX; \    } while (0)      BLOCK_ALLOC_FILL_PAGES(node_s, 2)      #define NODES (sizeof (((struct node_s_block *) NULL)->x) / sizeof (struct node_s))      #undef BLOCK_ALLOC_NEXT   #define BLOCK_ALLOC_NEXT next    - #ifdef SHARED_NODES -  - struct node_hash_table node_hash; -  - static INLINE size_t hash_node(node *n) - { -  size_t ret_; -  -  DO_HASHMEM(ret_, (unsigned char *)&(n->token), -  sizeof(node) - OFFSETOF(node_s, token), sizeof(node)); -  -  return ret_; - } -  - static void add_node(node *n) - { -  size_t hval = (n->hash % node_hash.size); -  - #ifdef PIKE_DEBUG -  node *probe = node_hash.table[hval]; -  while(probe) { -  if (probe == n) -  { -  fprintf(stderr, "add_node(%p == %p): Node already added!\n", -  (void *)probe, (void *)n); -  fprintf( stderr, " %ld <-> %ld\n", -  DO_NOT_WARN((long)hval), -  DO_NOT_WARN((long)(n->hash % node_hash.size)) ); -  probe = node_hash.table[hval]; -  while( probe ) -  { -  fprintf(stderr, " %p\n", (void *)probe); -  probe = probe->next; -  } -  Pike_fatal( "Node already added!\n" ); -  } -  probe = probe->next; -  } - #endif /* PIKE_DEBUG */ -  n->next = node_hash.table[hval]; -  node_hash.table[hval] = n; - } -  - static void sub_node(node *n) - { -  node *prior; -  - #ifdef PIKE_DEBUG -  if (!node_hash.size) { -  Pike_fatal("sub_node(): node_hash.size is zero.\n"); -  } - #endif /* PIKE_DEBUG */ -  -  prior = node_hash.table[n->hash % node_hash.size]; -  -  if (!prior) { -  return; -  } -  if (prior == n) { -  node_hash.table[n->hash % node_hash.size] = n->next; -  } else { -  while(prior && (prior->next != n)) { -  prior = prior->next; -  } -  if (!prior) { -  return; -  } -  prior->next = n->next; -  } -  n->next = NULL; - } -  - static node *freeze_node(node *orig) - { -  size_t hash; -  node *n; -  int found = 0; -  -  /* Defeat shared nodes since it messes up the line number info in -  * e.g. backtraces, which can be extremely annoying. Done the ugly -  * way for the time being since I've grown tired of waiting for the -  * issue to be resolved one way or the other. /mast */ -  orig->tree_info |= OPT_NOT_SHARED; -  orig->node_info |= OPT_NOT_SHARED; -  -  if (orig->tree_info & OPT_NOT_SHARED) { -  /* No need to have this node in the hash-table. */ -  /* add_node(orig); */ -  return orig; -  } -  -  /* free_node() wants a correct hash */ -  orig->hash = hash = hash_node(orig); -  -  /* Mark this node as a possible duplicate */ -  orig->node_info |= OPT_DEFROSTED; -  /* Make sure we don't find ourselves */ -  /* sub_node(orig); */ -  -  n = node_hash.table[hash % node_hash.size]; -  -  while (n) { -  if (n == orig) { -  found = 1; -  if (!(n = n->next)) { -  break; -  } -  } -  if ((n->hash == hash) && -  !MEMCMP(&(n->token), &(orig->token), -  sizeof(node) - OFFSETOF(node_s, token))) { -  if (orig->type && (orig->type != n->type)) { -  if (n->type) { -  /* Use the new type if it's stricter. */ -  if (pike_types_le(orig->type, n->type)) { -  free_type(n->type); -  copy_pike_type(n->type, orig->type); -  } -  } else { -  /* This probably doesn't happen, but... */ -  copy_pike_type(n->type, orig->type); -  } -  } -  if (!found) { -  node *scan = n; -  while(scan->next) { -  if (scan->next == orig) { -  scan->next = orig->next; -  break; -  } -  scan = scan->next; -  } -  } else { -  /* FIXME: sub_node() recalculates the hash index. -  * We might get better performance by using the one we already have. -  */ -  sub_node(orig); -  } -  /* Propagate the line-number information. */ -  n->line_number = orig->line_number; -  if (orig->current_file) { -  if (n->current_file) { -  free_string(n->current_file); -  } -  n->current_file = dmalloc_touch(struct pike_string *, -  orig->current_file); -  orig->current_file = NULL; -  } -  free_node(dmalloc_touch(node *, orig)); -  add_ref(n); -  return check_node_hash(dmalloc_touch(node *, n)); -  } -  n = n->next; -  } -  orig->node_info &= ~OPT_DEFROSTED; -  if (!found) { -  add_node(dmalloc_touch(node *, orig)); -  } -  check_tree(orig,0); -  return check_node_hash(orig); - } -  - #else /* !SHARED_NODES */ -  - #ifdef PIKE_DEBUG - static node *freeze_node(node *orig) - { -  check_tree(orig, 0); -  return orig; - } - #else /* !PIKE_DEBUG */ - #define freeze_node(X) (X) - #endif /* PIKE_DEBUG */ -  - #endif /* SHARED_NODES */ -  +    void free_all_nodes(void)   {    if(!Pike_compiler->previous)    {    node *tmp;    struct node_s_block *tmp2;    size_t e=0;      #ifndef PIKE_DEBUG    if(cumulative_parse_error)
pike.git/src/las.c:639: Inside #if defined(PIKE_DEBUG)
   tmp->token);       debug_malloc_dump_references(tmp,0,2,0);       if(tmp->token==F_CONSTANT)    print_tree(tmp);    }    /* else */   #endif    { - #ifdef SHARED_NODES -  /* Force the hashtable entry to be cleared. */ -  tmp->next = NULL; -  sub_node(tmp); - #endif /* SHARED_NODES */ +     /* Free the node and be happy */    /* Make sure we don't free any nodes twice */    if(car_is_node(tmp)) _CAR(tmp)=0;    if(cdr_is_node(tmp)) _CDR(tmp)=0; - #ifdef SHARED_NODES -  if (!(tmp->tree_info & OPT_NOT_SHARED)) { -  tmp->hash = hash_node(tmp); -  } +    #ifdef PIKE_DEBUG    if (l_flag > 3) {    fprintf(stderr, "Freeing node that had %d refs.\n",    tmp->refs);    }   #endif /* PIKE_DEBUG */    /* Force the node to be freed. */    tmp->refs = 1; - #endif /* SHARED_NODES */ +     debug_malloc_touch(tmp->type);    free_node(tmp);    --n;    }    }    }    }   #ifdef PIKE_DEBUG    if(!cumulative_parse_error)    Pike_fatal("Failed to free %"PRINTSIZET"d nodes when compiling!\n",e2);   #endif    }   #ifndef PIKE_DEBUG    }   #endif    free_all_node_s_blocks();    cumulative_parse_error=0; -  - #ifdef SHARED_NODES -  /* MEMSET(node_hash.table, 0, sizeof(node *) * node_hash.size); */ - #endif /* SHARED_NODES */ +     }   }      void debug_free_node(node *n)   {    if(!n) return;    - #ifdef SHARED_NODES +     if (sub_ref(n)) {   #ifdef PIKE_DEBUG    if(l_flag>9)    print_tree(n); -  -  if (!(n->tree_info & (OPT_NOT_SHARED | OPT_DEFROSTED))) { -  size_t hash; -  if ((hash = hash_node(n)) != n->hash) { -  fprintf(stderr, "Hash-value is bad 0x%08lx != 0x%08lx\n", -  DO_NOT_WARN((unsigned long)hash), -  DO_NOT_WARN((unsigned long)n->hash)); -  print_tree(n); -  Pike_fatal("token:%d, car:%p cdr:%p file:%s line:%d\n", -  n->token, _CAR(n), _CDR(n), n->current_file->str, n->line_number); -  } -  } +    #endif /* PIKE_DEBUG */    return;    } - #endif /* SHARED_NODES */ +        n->parent = NULL;       do {   #ifdef PIKE_DEBUG    if(l_flag>9)    print_tree(n); -  - #ifdef SHARED_NODES -  if (!(n->tree_info & (OPT_NOT_SHARED | OPT_DEFROSTED))) { -  size_t hash; -  if ((hash = hash_node(n)) != n->hash) { -  fprintf(stderr, "Hash-value is bad 0x%08lx != 0x%08lx\n", -  DO_NOT_WARN((unsigned long)hash), -  DO_NOT_WARN((unsigned long)n->hash)); -  print_tree(n); -  Pike_fatal("token:%d, car:%p cdr:%p file:%s line:%d\n", -  n->token, _CAR(n), _CDR(n), n->current_file->str, n->line_number); -  } -  } - #endif /* SHARED_NODES */ +    #endif /* PIKE_DEBUG */       debug_malloc_touch(n);    - #ifdef SHARED_NODES +    #ifdef PIKE_DEBUG    if (n->refs) {    Pike_fatal("Node with refs left about to be killed: %8p\n", n);    }   #endif /* PIKE_DEBUG */ -  sub_node(dmalloc_touch(node *, n)); - #endif /* SHARED_NODES */ +        switch(n->token)    {    case USHRT_MAX:    Pike_fatal("Freeing node again!\n");    break;       case F_CONSTANT:    free_svalue(&(n->u.sval));    break;    }       if (car_is_node(n)) {    /* Free CAR */    - #ifdef SHARED_NODES +     if (sub_ref(_CAR(n))) {    _CAR(n) = NULL;    } else { - #endif /* SHARED_NODES */ +     _CAR(n)->parent = n;    n = _CAR(n);    _CAR(n->parent) = NULL;    continue; - #ifdef SHARED_NODES +     } - #endif /* SHARED_NODES */ +     }    if (cdr_is_node(n)) {    /* Free CDR */    - #ifdef SHARED_NODES +     if (sub_ref(_CDR(n))) {    _CDR(n) = NULL;    } else { - #endif /* SHARED_NODES */ +     _CDR(n)->parent = n;    n = _CDR(n);    _CDR(n->parent) = NULL;    continue; - #ifdef SHARED_NODES +     } - #endif /* SHARED_NODES */ +     }    backtrack:    while (n->parent && !cdr_is_node(n->parent)) {    /* Kill the node and backtrack */    node *dead = n;    - #if defined(SHARED_NODES) && defined(PIKE_DEBUG) + #ifdef PIKE_DEBUG    if (dead->refs) { -  Pike_fatal("Killed node %p still has refs: %d\n", dead, dead->refs); +  print_tree(dead); +  Pike_fatal("Killed node %p (%d) still has refs: %d\n", +  dead, dead->token, dead->refs);    } - #endif /* SHARED_NODES && PIKE_DEBUG */ + #endif /* PIKE_DEBUG */       n = n->parent;       if(dead->type) free_type(dead->type);    if(dead->name) free_string(dead->name);    if(dead->current_file) free_string(dead->current_file);    dead->token=USHRT_MAX;    really_free_node_s(dead);    }    if (n->parent && cdr_is_node(n->parent)) {    /* Kill node and jump to the sibling. */    node *dead = n;    - #if defined(SHARED_NODES) && defined(PIKE_DEBUG) + #ifdef PIKE_DEBUG    if (dead->refs) {    Pike_fatal("Killed node %p still has refs: %d\n", dead, dead->refs);    } - #endif /* SHARED_NODES && PIKE_DEBUG */ + #endif /* PIKE_DEBUG */       n = n->parent;    if(dead->type) free_type(dead->type);    if(dead->name) free_string(dead->name);    if(dead->current_file) free_string(dead->current_file);    dead->token=USHRT_MAX;    really_free_node_s(dead);    - #ifdef SHARED_NODES +     if (sub_ref(_CDR(n))) {    _CDR(n) = NULL;    goto backtrack;    } else { - #endif /* SHARED_NODES */ +     _CDR(n)->parent = n;    n = _CDR(n);    _CDR(n->parent) = NULL;    continue; - #ifdef SHARED_NODES +     } - #endif /* SHARED_NODES */ +     }       /* Kill root node. */    - #if defined(SHARED_NODES) && defined(PIKE_DEBUG) + #ifdef PIKE_DEBUG    if (n->refs) {    Pike_fatal("Killed node %p still has refs: %d\n", n, n->refs);    } - #endif /* SHARE_NODES && PIKE_DEBUG */ + #endif /* PIKE_DEBUG */       if(n->type) free_type(n->type);    if(n->name) free_string(n->name);    if(n->current_file) free_string(n->current_file);       n->token=USHRT_MAX;    really_free_node_s(n);    break;    } while (n->parent);   }       - node *debug_check_node_hash(node *n) - { - #if defined(PIKE_DEBUG) && defined(SHARED_NODES) -  if (n && !(n->tree_info & (OPT_DEFROSTED|OPT_NOT_SHARED))) { -  if (n->hash != hash_node(n)) { -  fprintf(stderr,"Bad node hash at %p, (%s:%d) (token=%d).\n", -  (void *)n, n->current_file->str, n->line_number, -  n->token); -  debug_malloc_dump_references(n,0,0,0); -  print_tree(n); -  Pike_fatal("Bad node hash!\n"); -  } -  } - #endif /* PIKE_DEBUG && SHARED_NODES */ -  return n; - } -  +    /* here starts routines to make nodes */   static node *debug_mkemptynode(void)   {    node *res=alloc_node_s();    - #if defined(SHARED_NODES) || defined(__CHECKER__) + #ifdef __CHECKER__    MEMSET(res, 0, sizeof(node)); - #ifdef SHARED_NODES -  res->hash = 0; + #endif /* __CHECKER__ */ +     res->refs = 0;    add_ref(res); /* For DMALLOC... */ - #endif /* SHARED_NODES */ - #endif /* SHARED_NODES || __CHECKER__ */ -  +     res->token=0;    res->line_number=lex.current_line;    copy_shared_string(res->current_file, lex.current_file);    res->type=0;    res->name=0;    res->node_info=0;    res->tree_info=0;    res->parent=0;    return res;   }
pike.git/src/las.c:966: Inside #if defined(PIKE_DEBUG)
   Pike_fatal("Attempt to create an F_IDENTIFIER-node with mknode()!\n");    case F_TRAMPOLINE:    Pike_fatal("Attempt to create an F_TRAMPOLINE-node with mknode()!\n");    case F_EXTERNAL:    Pike_fatal("Attempt to create an F_EXTERNAL-node with mknode()!\n");    case F_GET_SET:    Pike_fatal("Attempt to create an F_GET_SET-node with mknode()!\n");   #endif /* PIKE_DEBUG */    }    - #if defined(PIKE_DEBUG) && !defined(SHARED_NODES) -  if(b && a==b) -  Pike_fatal("mknode: a and be are the same!\n"); - #endif -  +     check_tree(a,0);    check_tree(b,0);       res = mkemptynode();    _CAR(res) = dmalloc_touch(node *, a);    _CDR(res) = dmalloc_touch(node *, b); -  res->node_info = 0; -  res->tree_info = 0; +     if(a) {    a->parent = res;    }    if(b) {    b->parent = res;    }       res->token = token;    res->type = 0;   
pike.git/src/las.c:1177:    if(a) res->tree_info |= a->tree_info;    if(b) res->tree_info |= b->tree_info;    }       /* We try to optimize most things, but argument lists are hard... */    if((token != F_ARG_LIST) && (a || b))    res->node_info |= OPT_TRY_OPTIMIZE;       res->tree_info |= res->node_info;    - #ifdef SHARED_NODES -  /* No need to freeze the node if it can't be shared. */ -  if (!(res->tree_info & OPT_NOT_SHARED)) -  { -  node *res2 = freeze_node(res); -  -  if (res2 != res) { -  return dmalloc_touch(node *, res2); -  } -  } - #endif /* SHARED_NODES */ -  +    #ifdef PIKE_DEBUG    if(d_flag > 3)    verify_shared_strings_tables();   #endif       check_tree(res,0);    - #if 0 -  if(!Pike_compiler->num_parse_error && -  Pike_compiler->compiler_pass==2 && -  (res->node_info & OPT_TRY_OPTIMIZE)) -  { -  optimize(res); -  check_tree(res,0); -  } - #endif -  +    #ifdef PIKE_DEBUG    if(d_flag > 3)    verify_shared_strings_tables();   #endif       return res;   }      node *debug_mkstrnode(struct pike_string *str)   {    node *res = mkemptynode();    res->token = F_CONSTANT; -  res->node_info = 0; +     res->u.sval.type = T_STRING;   #ifdef __CHECKER__    res->u.sval.subtype = 0;   #endif    copy_shared_string(res->u.sval.u.string, str);    res->type = get_type_of_svalue(&res->u.sval); -  return freeze_node(res); +  return res;   }      node *debug_mkintnode(INT_TYPE nr)   {    node *res = mkemptynode();    res->token = F_CONSTANT; -  res->node_info = 0; +     res->u.sval.type = T_INT;    res->u.sval.subtype = NUMBER_NUMBER;    res->u.sval.u.integer = nr;    res->type=get_type_of_svalue( & res->u.sval);    -  return freeze_node(res); +  return res;   }      node *debug_mknewintnode(INT_TYPE nr)   {    node *res = mkemptynode();    res->token = F_CONSTANT; -  res->node_info = OPT_NOT_SHARED; -  res->tree_info = OPT_NOT_SHARED; +     res->u.sval.type = T_INT;    res->u.sval.subtype = NUMBER_NUMBER;    res->u.sval.u.integer = nr;    res->type=get_type_of_svalue( & res->u.sval); - #ifdef SHARED_NODES -  res->refs = 0; -  add_ref(res); /* For DMALLOC... */ -  /* res->hash = hash_node(res); */ - #endif /* SHARED_NODES */ -  +     return res;   }      node *debug_mkfloatnode(FLOAT_TYPE foo)   {    node *res = mkemptynode();    res->token = F_CONSTANT;    copy_pike_type(res->type, float_type_string);    res->u.sval.type = T_FLOAT;   #ifdef __CHECKER__    res->u.sval.subtype = 0;   #endif    res->u.sval.u.float_number = foo;    -  return freeze_node(res); +  return res;   }         node *debug_mkprgnode(struct program *p)   {    struct svalue s;    s.u.program=p;    s.type = T_PROGRAM;   #ifdef __CHECKER__    s.subtype = 0;
pike.git/src/las.c:1335:      node *debug_mkversionnode(int major, int minor)   {    node *res = mkemptynode();    res->token = F_VERSION;   #ifdef __CHECKER__    _CDR(res) = 0;   #endif    res->u.integer.a = major;    res->u.integer.b = minor; - #ifdef SHARED_NODES -  res->hash = hash_node(res); - #endif /* SHARED_NODES */ -  return freeze_node(res); +  return res;   }      node *debug_mklocalnode(int var, int depth)   {    struct compiler_frame *f;    int e;    node *res = mkemptynode();    res->token = F_LOCAL;       f=Pike_compiler->compiler_frame;    for(e=0;e<depth;e++) f=f->previous;    copy_pike_type(res->type, f->variable[var].type);    -  res->node_info = OPT_NOT_CONST | OPT_NOT_SHARED; +  res->node_info = OPT_NOT_CONST;    res->tree_info = res->node_info;   #ifdef __CHECKER__    _CDR(res) = 0;   #endif    res->u.integer.a = var;    if (depth < 0) {    /* First appearance of this variable.    * Add initialization code.    */    res->node_info |= OPT_ASSIGNMENT;    res->u.integer.b = 0;    } else {    res->u.integer.b = depth;    }    - #ifdef SHARED_NODES -  /* FIXME: Not common-subexpression optimized. -  * Node would need to contain a ref to the current function, -  * and to the current program. -  */ -  -  res->hash = hash_node(res); -  -  /* return freeze_node(res); */ - #endif /* SHARED_NODES */ -  +     return res;   }      node *debug_mkidentifiernode(int i)   {   #if 1    node *res = mkexternalnode(Pike_compiler->new_program, i);    check_tree(res,0);    return res;   #else
pike.git/src/las.c:1410:    res->tree_info=res->node_info;      #ifdef __CHECKER__    _CDR(res) = 0;   #endif    res->u.id.number = i;   #ifdef SHARED_NODES    res->u.id.prog = Pike_compiler->new_program;   #endif /* SHARED_NODES */    -  res = freeze_node(res); -  +     check_tree(res,0);    return res;   #endif   }      node *debug_mktrampolinenode(int i, struct compiler_frame *frame)   {    struct compiler_frame *f;    node *res = mkemptynode();   
pike.git/src/las.c:1448:    res->u.trampoline.frame=frame;       for(f=Pike_compiler->compiler_frame;f != frame;f=f->previous)    f->lexical_scope|=SCOPE_SCOPED;    f->lexical_scope|=SCOPE_SCOPE_USED;      #ifdef SHARED_NODES    res->u.trampoline.prog = Pike_compiler->new_program;   #endif /* SHARED_NODES */    -  res = freeze_node(res); -  +     check_tree(res,0);    return res;   }      node *debug_mkexternalnode(struct program *parent_prog, int i)   {   #if 0    return mkidentifiernode(add_ext_ref(Pike_compiler, parent_prog, i));      #else /* !0 */    struct program_state *state;    node *res = mkemptynode();    res->token = F_EXTERNAL;       if (i == IDREF_MAGIC_THIS) {    type_stack_mark();    push_object_type (0, parent_prog->id);    res->type = pop_unfinished_type();    res->node_info = OPT_NOT_CONST; -  +  Pike_compiler->compiler_frame->opt_flags |= OPT_EXTERNAL_DEPEND;    } -  +     else {    struct identifier *id = ID_FROM_INT(parent_prog, i);   #ifdef PIKE_DEBUG    if(d_flag)    {    check_type_string(id->type);    check_string(id->name);    }   #endif   
pike.git/src/las.c:1495:    {    res->node_info = OPT_EXTERNAL_DEPEND;    }else{    res->node_info = OPT_NOT_CONST;    if (IDENTIFIER_IS_VARIABLE(id->identifier_flags) &&    (id->run_time_type == PIKE_T_GET_SET)) {    /* Special case of F_EXTERNAL for ease of detection. */    res->token = F_GET_SET;    }    } +  if (i) { +  Pike_compiler->compiler_frame->opt_flags |= OPT_EXTERNAL_DEPEND;    } -  +  }    res->tree_info = res->node_info;      #ifdef __CHECKER__    _CDR(res) = 0;   #endif    res->u.integer.a = parent_prog->id;    res->u.integer.b = i;       /* Bzot-i-zot */    state = Pike_compiler;    while(parent_prog != state->new_program)    {    state->new_program->flags |= PROGRAM_USES_PARENT | PROGRAM_NEEDS_PARENT;    state=state->previous;    }    -  res=freeze_node(res); -  - #if 0 - #ifdef PIKE_DEBUG -  /* FIXME: This test crashes on valid code because the type of the -  * identifier can change in pass 2 -Hubbe -  */ -  if(d_flag && id->type != res->type) -  { -  printf("Type of external node is not matching it's identifier.\nid->type: "); -  simple_describe_type(id->type); -  printf("\nres->type : "); -  simple_describe_type(res->type); -  printf("\n"); -  -  Pike_fatal("Type of external node is not matching it's identifier.\n"); -  } - #endif - #endif -  +     return res;   #endif /* 0 */   }      node *debug_mkthisnode(struct program *parent_prog, int inherit_num)   {    struct program_state *state;    node *res;      #ifdef PIKE_DEBUG
pike.git/src/las.c:1568:    res->u.integer.b = inherit_num;       /* Bzot-i-zot */    state = Pike_compiler;    while(parent_prog != state->new_program)    {    state->new_program->flags |= PROGRAM_USES_PARENT | PROGRAM_NEEDS_PARENT;    state=state->previous;    }    -  return freeze_node(res); +  return res;   }      node *debug_mkcastnode(struct pike_type *type, node *n)   {    node *res;       if(!n) return 0;      #ifdef PIKE_DEBUG    if (!type) {
pike.git/src/las.c:1608:    match_types(program_type_string, type))    res->node_info |= OPT_SIDE_EFFECT;       res->tree_info |= n->tree_info;       _CAR(res) = n;    _CDR(res) = mktypenode(type);       n->parent = res;    -  return freeze_node(res); +  return res;   }      node *debug_mksoftcastnode(struct pike_type *type, node *n)   {    node *res;    struct pike_type *result_type = NULL;       if(!n) return 0;      #ifdef PIKE_DEBUG
pike.git/src/las.c:1686:    copy_pike_type(res->type, type);    }       res->tree_info |= n->tree_info;       _CAR(res) = n;    _CDR(res) = mktypenode(type);       n->parent = res;    -  return freeze_node(res); +  return res;   }      void resolv_constant(node *n)   {    struct identifier *i;    struct program *p;    INT32 numid;       check_tree(n,0);   
pike.git/src/las.c:2082:   {    node *res = mkemptynode();    res->token = F_CONSTANT;    copy_pike_type(res->u.sval.u.type, t);    res->u.sval.type = T_TYPE;    /* FIXME: Should be type(val) */    type_stack_mark();    push_finished_type(t);    push_type(T_TYPE);    res->type = pop_unfinished_type(); -  return freeze_node(res); +  return res;   }      node *low_mkconstantsvaluenode(struct svalue *s)   {    node *res = mkemptynode();    res->token = F_CONSTANT; - #ifdef SHARED_NODES -  /* We need to ensure that all bytes in the svalue struct have well -  * defined values, including any padding between the subtype and the -  * union. */ -  switch (res->u.sval.type = s->type) { -  case T_INT: -  res->u.sval.u.integer = s->u.integer; -  res->u.sval.subtype = s->subtype; -  break; -  case T_FLOAT: -  res->u.sval.u.float_number = s->u.float_number; -  break; -  case T_FUNCTION: -  res->u.sval.subtype = s->subtype; -  /* FALL THROUGH */ -  default: -  res->u.sval.u.ptr = s->u.ptr; -  } -  add_ref_svalue (&res->u.sval); - #else +     assign_svalue_no_free(& res->u.sval, s); - #endif +     if(s->type == T_OBJECT ||    (s->type==T_FUNCTION && s->subtype!=FUNCTION_BUILTIN))    {    if(!(s->u.object->prog && (s->u.object->prog->flags & PROGRAM_CONSTANT)))    res->node_info|=OPT_EXTERNAL_DEPEND;    }    res->type = get_type_of_svalue(s);    return res;   }      node *debug_mkconstantsvaluenode(struct svalue *s)   { -  return freeze_node(low_mkconstantsvaluenode(s)); +  return low_mkconstantsvaluenode(s);   }      node *debug_mkliteralsvaluenode(struct svalue *s)   {    node *res = low_mkconstantsvaluenode(s);       if(s->type!=T_STRING && s->type!=T_INT && s->type!=T_FLOAT)    res->node_info|=OPT_EXTERNAL_DEPEND;    -  return freeze_node(res); +  return res;   }      node *debug_mksvaluenode(struct svalue *s)   {    switch(s->type)    {    case T_ARRAY:    return make_node_from_array(s->u.array);       case T_MULTISET:
pike.git/src/las.c:2233:    case F_LOCAL:    case F_IDENTIFIER:    case F_TRAMPOLINE:    b=mknewintnode(0);    if(b->type) free_type(b->type);    *b=*n;    copy_pike_type(b->type, n->type);    return b;       default: - #ifdef SHARED_NODES +     add_ref(n);    return n; - #else /* !SHARED_NODES */ -  -  fatal_check_c_stack(16384); -  -  switch((car_is_node(n) << 1) | cdr_is_node(n)) -  { -  default: Pike_fatal("fooo?\n"); -  -  case 3: -  b=mknode(n->token, copy_node(CAR(n)), copy_node(CDR(n))); -  break; -  case 2: -  b=mknode(n->token, copy_node(CAR(n)), CDR(n)); -  break; -  -  case 1: -  b=mknode(n->token, CAR(n), copy_node(CDR(n))); -  break; -  -  case 0: -  b=mknode(n->token, CAR(n), CDR(n)); +     } -  if(n->type) -  copy_pike_type(b->type, n->type); -  else -  b->type=0; -  -  break; -  -  case F_CAST: -  b=mkcastnode(n->type,copy_node(CAR(n))); -  break; -  -  case F_SOFT_CAST: -  b=mksoftcastnode(n->type,copy_node(CAR(n))); -  break; -  -  case F_CONSTANT: -  b=mkconstantsvaluenode(&(n->u.sval)); -  break; - #endif /* SHARED_NODES */ -  } +     if(n->name)    {    if(b->name) free_string(b->name);    add_ref(b->name=n->name);    }    /* FIXME: Should b->name be kept if n->name is NULL?    * /grubba 1999-09-22    */    b->line_number = n->line_number;    b->node_info = n->node_info;    b->tree_info = n->tree_info;    return b;   }    - /* -  * Defrost a node, beware that this is not -  * a recursive function -  */ - #ifdef SHARED_NODES - node *defrost_node(node *n) - { -  node *b; -  debug_malloc_touch(n); -  debug_malloc_touch(n->type); -  debug_malloc_touch(n->u.node.a); -  debug_malloc_touch(n->u.node.b); -  check_tree(n,0); -  if(!n) return n; -  -  if(n->refs == 1) -  { -  sub_node(n); -  n->node_info |= OPT_DEFROSTED; -  n->node_info &=~ OPT_OPTIMIZED; -  n->tree_info &=~ OPT_OPTIMIZED; -  return n; -  } -  -  switch(n->token) -  { -  case F_LOCAL: -  case F_IDENTIFIER: -  case F_TRAMPOLINE: -  b=mknewintnode(0); -  if(b->type) free_type(b->type); -  *b=*n; -  copy_pike_type(b->type, n->type); -  return b; -  -  default: -  fatal_check_c_stack(16384); -  -  b=mkemptynode(); -  if(car_is_node(n)) _CAR(b)=copy_node(CAR(n)); -  if(cdr_is_node(n)) _CDR(b)=copy_node(CDR(n)); -  -  if(n->type) -  copy_pike_type(b->type, n->type); -  else -  b->type=0; -  -  break; -  -  case F_CAST: -  case F_SOFT_CAST: -  b=mkemptynode(); -  _CAR(b)=copy_node(CAR(n)); -  _CDR(b)=copy_node(CDR(n)); -  if(n->type) -  copy_pike_type(b->type, n->type); -  else -  b->type=0; -  break; -  -  case F_CONSTANT: -  b=low_mkconstantsvaluenode(&(n->u.sval)); -  break; -  } -  if(n->name) -  { -  if(b->name) free_string(b->name); -  add_ref(b->name=n->name); -  } -  /* FIXME: Should b->name be kept if n->name is NULL? -  * /grubba 1999-09-22 -  */ -  b->line_number = n->line_number; -  b->node_info = n->node_info & ~OPT_OPTIMIZED; -  b->tree_info = n->tree_info & ~OPT_OPTIMIZED; -  b->node_info |= OPT_DEFROSTED; -  free_node(n); -  return b; - } - #endif -  -  +    int is_const(node *n)   {    if(!n) return 1;    return !(n->tree_info & (OPT_SIDE_EFFECT |    OPT_NOT_CONST |    OPT_ASSIGNMENT |    OPT_CASE |    OPT_CONTINUE |    OPT_BREAK |    OPT_RETURN
pike.git/src/las.c:3824: Inside #if defined(PIKE_DEBUG)
   fputs("Warning: Invalid assignment: ", stderr);    print_tree(n);    }   #endif /* PIKE_DEBUG */    yywarning("An expression of type %S cannot be assigned to "    "a variable of type %S.", t1, t2);    free_string(t2);    free_string(t1);    }    if (runtime_options & RUNTIME_CHECK_TYPES) { -  n->node_info |= OPT_DEFROSTED; +     _CAR(n) = mksoftcastnode(CDR(n)->type, CAR(n));    }    }    }   #endif /* 0 */    n->type = and_pike_types(CAR(n)->type, CDR(n)->type);    }    break;       case F_ARRAY_LVALUE:
pike.git/src/las.c:4314:    /* FIXME: Ought to strip non-applicable subtypes from the type. */    copy_pike_type(n->type, CAR(n)->type);    } else {    copy_pike_type(n->type, mixed_type_string);    }    break;       case F_RETURN:    if (!CAR(n) || (CAR(n)->type == void_type_string)) {    yywarning("Returning a void expression. Converted to zero."); - #ifdef SHARED_NODES -  sub_node(n); - #endif /* SHARED_NODES */ +     if (!CAR(n)) {    _CAR(n) = mkintnode(0);    copy_pike_type(n->type, CAR(n)->type);    } else {    _CAR(n) = mknode(F_COMMA_EXPR, CAR(n), mkintnode(0));    copy_pike_type(n->type, CDAR(n)->type);    } - #ifdef SHARED_NODES -  if (!(n->tree_info & OPT_NOT_SHARED)) { -  n->hash = hash_node(n); -  } -  n->node_info |= OPT_DEFROSTED; -  add_node(n); - #endif /* SHARED_NODES */ +     break;    } else if(Pike_compiler->compiler_frame &&    Pike_compiler->compiler_frame->current_return_type) {    if ((Pike_compiler->compiler_frame->current_return_type !=    void_type_string) ||    (CAR(n)->token != F_CONSTANT) ||    !SAFE_IS_ZERO(& CAR(n)->u.sval)) {    check_node_type(CAR(n),    Pike_compiler->compiler_frame->current_return_type,    "Wrong return type.");
pike.git/src/las.c:5400:      static void optimize(node *n)   {    node *tmp1, *tmp2, *tmp3;    struct pike_string *save_file =    dmalloc_touch(struct pike_string *, lex.current_file);    INT32 save_line = lex.current_line;       do    { -  if(car_is_node(n) && -  ((CAR(n)->node_info & (OPT_OPTIMIZED|OPT_DEFROSTED)) != OPT_OPTIMIZED)) +  if(car_is_node(n) && !(CAR(n)->node_info & OPT_OPTIMIZED))    {    CAR(n)->parent = n;    n = CAR(n);    continue;    } -  if(cdr_is_node(n) && -  ((CDR(n)->node_info & (OPT_OPTIMIZED|OPT_DEFROSTED)) != OPT_OPTIMIZED)) +  if(cdr_is_node(n) && !(CDR(n)->node_info & OPT_OPTIMIZED))    {    CDR(n)->parent = n;    n = CDR(n);    continue;    }    - #if defined(SHARED_NODES) -  if ((n->node_info & OPT_DEFROSTED) && (n->parent)) { -  /* Add ref since both freeze_node() and use_tmp1 will free it. */ -  ADD_NODE_REF(n); -  /* We don't want freeze_node() to find this node in the hash-table. */ -  tmp1 = freeze_node(n); -  if (tmp1 != n) { -  /* n was a duplicate node. Use the original. */ -  /* Make sure the original isn't defrosted too. */ -  tmp1->node_info &= ~OPT_DEFROSTED; -  goto use_tmp1; -  } -  /* Remove the extra ref from n */ -  free_node(n); -  n->node_info &= ~OPT_DEFROSTED; -  if (n->node_info & OPT_OPTIMIZED) { -  /* No need to check this node any more. */ -  n = n->parent; -  continue; -  } -  } - #endif /* SHARED_NODES */ -  +     lex.current_line = n->line_number;    lex.current_file = dmalloc_touch(struct pike_string *, n->current_file);    - #ifdef SHARED_NODES -  if (n->tree_info & OPT_NOT_SHARED) { +     n->tree_info = n->node_info;    if(car_is_node(n)) n->tree_info |= CAR(n)->tree_info;    if(cdr_is_node(n)) n->tree_info |= CDR(n)->tree_info; -  if(!(n->tree_info & OPT_NOT_SHARED)) { -  /* We need to fix the hash for this node. */ -  n->hash = hash_node(n); -  /* FIXME: Should probably add the node to the hashtable here. */ -  } -  } else { - #endif /* SHARED_NODES */ -  n->tree_info = n->node_info; -  if(car_is_node(n)) n->tree_info |= CAR(n)->tree_info; -  if(cdr_is_node(n)) n->tree_info |= CDR(n)->tree_info; - #ifdef SHARED_NODES -  if (n->tree_info & OPT_NOT_SHARED) { -  /* No need to have it in the hashtable anymore. */ -  sub_node(n); -  } -  } - #endif /* SHARED_NODES */ +        if(!n->parent) break;       if(n->tree_info & (OPT_NOT_CONST|    OPT_SIDE_EFFECT|    OPT_EXTERNAL_DEPEND|    OPT_ASSIGNMENT|    OPT_RETURN|    OPT_FLAG_NODE))    {    if(car_is_node(n) &&    !(CAR(n)->tree_info & (OPT_NOT_CONST|    OPT_SIDE_EFFECT|    OPT_EXTERNAL_DEPEND|    OPT_ASSIGNMENT|    OPT_RETURN|    OPT_FLAG_NODE)) &&    (CAR(n)->tree_info & OPT_TRY_OPTIMIZE) &&    CAR(n)->token != F_VAL_LVAL)    { - #ifdef SHARED_NODES -  sub_node(n); - #endif /* SHARED_NODES */ +     _CAR(n) = eval(CAR(n)); - #ifdef SHARED_NODES -  n->node_info |= OPT_DEFROSTED; -  if (!(n->tree_info & OPT_NOT_SHARED)) { -  n->hash = hash_node(n); -  add_node(n); -  } - #endif /* SHARED_NODES */ +     if(CAR(n)) CAR(n)->parent = n;    zapp_try_optimize(CAR(n)); /* avoid infinite loops */    continue;    }    if(cdr_is_node(n) &&    !(CDR(n)->tree_info & (OPT_NOT_CONST|    OPT_SIDE_EFFECT|    OPT_EXTERNAL_DEPEND|    OPT_ASSIGNMENT|    OPT_RETURN|    OPT_FLAG_NODE)) &&    (CDR(n)->tree_info & OPT_TRY_OPTIMIZE))    { - #ifdef SHARED_NODES -  sub_node(n); - #endif /* SHARED_NODES */ +     _CDR(n) = eval(CDR(n)); - #ifdef SHARED_NODES -  n->node_info |= OPT_DEFROSTED; -  if (!(n->tree_info & OPT_NOT_SHARED)) { -  n->hash = hash_node(n); -  add_node(n); -  } - #endif /* SHARED_NODES */ +     if(CDR(n)) CDR(n)->parent = n;    zapp_try_optimize(CDR(n)); /* avoid infinite loops */    continue;    }    }    if (!n->type || (n->node_info & OPT_TYPE_NOT_FIXED)) {    fix_type_field(n);    }    debug_malloc_touch(n->type);   
pike.git/src/las.c:5561: Inside #if defined(PIKE_DEBUG)
   use_tmp1:   #ifdef PIKE_DEBUG    if (l_flag > 4) {    fputs("Optimized: ", stderr);    print_tree(n);    fputs("Result: ", stderr);    print_tree(tmp1);    }   #endif /* PIKE_DEBUG */    - #ifdef SHARED_NODES -  sub_node(n->parent); - #endif /* SHARED_NODES */ -  +     if(CAR(n->parent) == n)    _CAR(n->parent) = tmp1;    else    _CDR(n->parent) = tmp1;       if (!tmp1 || (tmp1->type != n->type)) {    n->parent->node_info |= OPT_TYPE_NOT_FIXED;    }    - #ifdef SHARED_NODES -  n->parent->node_info |= OPT_DEFROSTED; -  if (!(n->tree_info & OPT_NOT_SHARED)) { -  n->parent->hash = hash_node(n->parent); -  add_node(n->parent); -  } - #endif /* SHARED_NODES */ -  +     if(tmp1)    tmp1->parent = n->parent;    else    tmp1 = n->parent;       free_node(n);    n = tmp1;      #ifdef PIKE_DEBUG    if(l_flag > 3)
pike.git/src/las.c:5689:       tmp_callback=add_to_callback(&evaluator_callbacks,    check_evaluation_time,    (void *)&foo,0);       if(apply_low_safe_and_stupid(Pike_compiler->fake_object, jump))    {    if(print_error)    /* Generate error message */    if(!Pike_compiler->catch_level) -  handle_compile_exception ("Error evaluating constant.\n"); +  handle_compile_exception("Error evaluating constant.");    else {    free_svalue(&throw_value);    throw_value.type = T_INT;    }    else {    free_svalue(&throw_value);    throw_value.type = T_INT;    /* Assume the node will throw errors at runtime too. */    n->tree_info |= OPT_SIDE_EFFECT;    n->node_info |= OPT_SIDE_EFFECT;
pike.git/src/las.c:5920:    node *n,    struct pike_type *type,    int modifiers)   {    union idptr tmp;    int args, vargs, ret;    struct svalue *foo;       optimize_node(n);    -  check_tree(check_node_hash(n),0); +  check_tree(n, 0);      #ifdef PIKE_DEBUG    if(a_flag > 1)    fprintf(stderr, "Doing function '%s' at %lx\n", name->str,    DO_NOT_WARN((unsigned long)PIKE_PC));   #endif       args=count_arguments(type);    if(args < 0)    {
pike.git/src/las.c:5961: Inside #if defined(PIKE_DEBUG)
  #ifdef PIKE_DEBUG    if(a_flag > 4)    {    fputs("Making prototype (pass 1) for: ", stderr);    print_tree(n);    }   #endif    }else{   #if defined(SHARED_NODES) && 0    /* Try the local variable usage analyser. */ -  n = localopt(check_node_hash(n)); +  n = localopt(n);    /* Try optimizing some more. */    optimize(n);   #endif /* SHARED_NODES && 0 */ -  n = mknode(F_ARG_LIST,check_node_hash(n),0); +  n = mknode(F_ARG_LIST, n, 0);    -  if((foo=is_stupid_func(check_node_hash(n), args, vargs, type))) +  if((foo=is_stupid_func(n, args, vargs, type)))    {    if(foo->type == T_FUNCTION && foo->subtype==FUNCTION_BUILTIN)    {    tmp.c_fun=foo->u.efun->function;    if(tmp.c_fun != f_destruct &&    tmp.c_fun != f_this_object &&    tmp.c_fun != f_backtrace)    {   #ifdef PIKE_DEBUG    if(a_flag > 1)
pike.git/src/las.c:6005:    }    }       tmp.offset=PIKE_PC;    Pike_compiler->compiler_frame->num_args=args;      #ifdef PIKE_DEBUG    if(a_flag > 2)    {    fputs("Coding: ", stderr); -  /*print_tree(check_node_hash(n));*/ +  /*print_tree(n);*/    }   #endif    if(!Pike_compiler->num_parse_error)    {    extern int remove_clear_locals;    remove_clear_locals=args;    if(vargs) remove_clear_locals++; -  tmp.offset=do_code_block(check_node_hash(n)); +  tmp.offset=do_code_block(n);    remove_clear_locals=0x7fffffff;    }    }       ret=define_function(name,    type,    (unsigned INT16)modifiers,    (unsigned INT8)(IDENTIFIER_PIKE_FUNCTION |    IDENTIFIER_HAS_BODY |    vargs),