pike.git / src / las.c

version» Context lines:

pike.git/src/las.c:23:   #include "operators.h"   #include "callback.h"   #include "pike_macros.h"   #include "peep.h"   #include "builtin_functions.h"   #include "cyclic.h"   #include "opcodes.h"   #include "pikecode.h"   #include "gc.h"   #include "pike_compiler.h" - #include "block_alloc.h" + #include "block_allocator.h"      /* Define this if you want the optimizer to be paranoid about aliasing    * effects to to indexing.    */   /* #define PARANOID_INDEXING */      /* #define NEW_ARG_CHECK */      static node *eval(node *);   static void optimize(node *n);
pike.git/src/las.c:211: Inside #if defined(PIKE_DEBUG)
   fputs("n:", stderr);    print_tree(n);    fputs("orig_n:", stderr);    print_tree(orig_n);    Pike_fatal("check_tree() lost track.\n");    }    n->parent = parent;   }   #endif    - /* FIXME: Ought to use parent pointer to avoid recursion. */ - INT32 count_args(node *n) + static int low_count_args(node *n)   {    int a,b; -  check_tree(n,0); +     -  fatal_check_c_stack(16384); -  +     if(!n) return 0;    switch(n->token)    {    case F_COMMA_EXPR:    case F_VAL_LVAL:    case F_ARG_LIST:    a=count_args(CAR(n));    if(a==-1) return -1;    b=count_args(CDR(n));    if(b==-1) return -1;    return a+b;       case F_CAST:    if(n->type == void_type_string)    return 0; -  else +     return count_args(CAR(n));       case F_SOFT_CAST:    return count_args(CAR(n));       case F_CASE:    case F_CASE_RANGE:    case F_FOR:    case F_DO:    case F_LOOP:
pike.git/src/las.c:260:    case F_RETURN:    case F_CONTINUE:    case F_FOREACH:    return 0;       case '?':    {    int tmp1,tmp2;    tmp1=count_args(CADR(n));    tmp2=count_args(CDDR(n)); -  if(tmp1==-1 || tmp2==-1) return -1; +     if(tmp1 < tmp2) return tmp1;    return tmp2;    }       case F_PUSH_ARRAY:    return -1;       case F_APPLY:    if(CAR(n)->token == F_CONSTANT &&    TYPEOF(CAR(n)->u.sval) == T_FUNCTION &&
pike.git/src/las.c:286:    case F_RANGE_FROM_BEG:    case F_RANGE_FROM_END:    return 1;    case F_RANGE_OPEN:    return 0;       default:    if(n->type == void_type_string) return 0;    return 1;    } +  /* NOT_REACHED */   }    -  + INT32 count_args(node *n) + { +  int total = 0; +  int a,b; +  node *orig = n; +  node *orig_parent; +  node *prev = NULL; +  check_tree(n,0); +  +  fatal_check_c_stack(16384); +  +  if(!n) return 0; +  +  orig_parent = n->parent; +  n->parent = NULL; +  +  while(1) { +  int val; +  while ((n->token == F_COMMA_EXPR) || +  (n->token == F_VAL_LVAL) || +  (n->token == F_ARG_LIST)) { +  if (CAR(n)) { +  CAR(n)->parent = n; +  n = CAR(n); +  } else if (CDR(n)) { +  CDR(n)->parent = n; +  n = CDR(n); +  } else { +  /* Unlikely, but... */ +  goto backtrack; +  } +  } +  +  /* Leaf. */ +  val = low_count_args(n); +  if (val == -1) { +  total = -1; +  break; +  } +  if (n->parent && (CAR(n->parent) == CDR(n->parent))) { +  /* Same node in both CDR and CAR ==> count twice. */ +  val *= 2; +  } +  total += val; +  +  backtrack: +  while (n->parent && +  (!CDR(n->parent) || (n == CDR(n->parent)))) { +  n = n->parent; +  } +  if (!(n = n->parent)) break; +  /* Found a parent where we haven't visited CDR. */ +  CDR(n)->parent = n; +  n = CDR(n); +  } +  +  orig->parent = orig_parent; +  +  return total; + } +    /* FIXME: Ought to use parent pointer to avoid recursion. */   struct pike_type *find_return_type(node *n)   {    struct pike_type *a, *b;       check_tree(n,0);       fatal_check_c_stack(16384);       if(!n) return 0;
pike.git/src/las.c:380:    if (!match_types(n->type, t)) {    yytype_report(REPORT_ERROR, NULL, 0, t, NULL, 0, n->type, 0, msg);    return 0;    }    if (THIS_COMPILATION->lex.pragmas & ID_STRICT_TYPES) {    yytype_report(REPORT_WARNING, NULL, 0, t, NULL, 0, n->type, 0, msg);    }    if (runtime_options & RUNTIME_CHECK_TYPES) {    node *p = n->parent;    if (CAR(p) == n) { -  (_CAR(p) = mksoftcastnode(t, n))->parent = p; +  (_CAR(p) = mksoftcastnode(t, mkcastnode(mixed_type_string, n))) +  ->parent = p;    } else if (CDR(p) == n) { -  (_CDR(p) = mksoftcastnode(t, n))->parent = p; +  (_CDR(p) = mksoftcastnode(t, mkcastnode(mixed_type_string, n))) +  ->parent = p;    } else {    yywarning("Failed to find place to insert soft cast.");    }    }    return 1;   }    - #undef BLOCK_ALLOC_NEXT - #define BLOCK_ALLOC_NEXT u.node.a + void init_node_s_blocks() { }    - #undef PRE_INIT_BLOCK - #define PRE_INIT_BLOCK(NODE) do { \ -  NODE->token = USHRT_MAX; \ -  } while (0) + void really_free_node_s(node * n) { +  ba_free(&Pike_compiler->node_allocator, n); + }    - BLOCK_ALLOC_FILL_PAGES(node_s, 2) + MALLOC_FUNCTION + node * alloc_node_s() { +  return (node*)ba_alloc(&Pike_compiler->node_allocator); + }    - #define NODES (sizeof (((struct node_s_block *) NULL)->x) / sizeof (struct node_s)) + void count_memory_in_node_ss(size_t * num, size_t * size) { +  struct program_state * state = Pike_compiler;    - #undef BLOCK_ALLOC_NEXT - #define BLOCK_ALLOC_NEXT next +  *num = 0; +  *size = 0;    - void free_all_nodes(void) - { -  if(!Pike_compiler->previous) -  { -  node *tmp; -  struct node_s_block *tmp2; -  size_t e=0; +  while (state) { +  size_t _num, _size; +  ba_count_all(&state->node_allocator, &_num, &_size); +  *num += _num; +  *size += _size; +  state = state->previous; +  } + }    - #ifndef PIKE_DEBUG -  if(cumulative_parse_error) -  { - #endif + void node_walker(struct ba_iterator * it, void * UNUSED(data)) { +  do { +  node * tmp = ba_it_val(it);    -  for(tmp2=node_s_blocks;tmp2;tmp2=tmp2->next) e+=tmp2->used; -  if(e) -  { -  size_t e2=e; -  struct node_s_block *nextblk; -  for(tmp2=node_s_blocks;tmp2;tmp2=nextblk) -  { -  int n = tmp2->used; -  nextblk = tmp2->next; -  /* We want to be able to access the token field of all -  * the blocks... +  /* +  * since we free nodes from here, we might iterate over them again. +  * to avoid that we check for the free mark.    */ -  PIKE_MEM_RW(tmp2->x); -  for(e=0;n && e<NODES;e++) -  { -  if (tmp2->x[e].token != USHRT_MAX) -  { -  tmp=tmp2->x+e; +  if (tmp->token == USHRT_MAX) continue; +    #ifdef PIKE_DEBUG    if(!cumulative_parse_error)    {    fprintf(stderr,"Free node at %p, (%s:%ld) (token=%d).\n",    (void *)tmp,    tmp->current_file->str, (long)tmp->line_number,    tmp->token);       debug_malloc_dump_references(tmp,0,2,0);   
pike.git/src/las.c:466: Inside #if defined(PIKE_DEBUG)
  #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;    debug_malloc_touch(tmp->type);    free_node(tmp); -  --n; +     } -  +  } while (ba_it_step(it));   } -  } -  } - #ifdef PIKE_DEBUG -  if(!cumulative_parse_error) -  Pike_fatal("Failed to free %"PRINTSIZET"d nodes when compiling!\n",e2); +  + void free_all_nodes(void) + { +  node *tmp; +  + #ifndef PIKE_DEBUG +  if(cumulative_parse_error) {   #endif -  +  ba_walk(&Pike_compiler->node_allocator, &node_walker, NULL); + #ifdef PIKE_DEBUG +  if(!cumulative_parse_error) { +  size_t n, s; +  ba_count_all(&Pike_compiler->node_allocator, &n, &s); +  if (n) +  Pike_fatal("Failed to free %"PRINTSIZET"d nodes when compiling!\n",n);    } - #ifndef PIKE_DEBUG + #else    }   #endif -  free_all_node_s_blocks(); +     cumulative_parse_error=0;   } - } +       void debug_free_node(node *n)   {    if(!n) return;       if (sub_ref(n)) {   #ifdef PIKE_DEBUG    if(l_flag>9)    print_tree(n);   #endif /* PIKE_DEBUG */
pike.git/src/las.c:1337:    free_string(t1);    return n;    }       if (n->type) {   #ifdef NEW_ARG_CHECK    if (!(result_type = soft_cast(type, n->type, 0))) {    ref_push_type_value(n->type);    ref_push_type_value(type);    yytype_report(REPORT_ERROR, -  NULL, 0, NULL, -  NULL, 0, NULL, +  NULL, 0, type, +  NULL, 0, n->type,    2, "Soft cast of %O to %O isn't a valid cast.");    } else if (result_type == n->type) {    ref_push_type_value(n->type);    ref_push_type_value(type);    yytype_report(REPORT_WARNING,    NULL, 0, NULL,    NULL, 0, NULL,    2, "Soft cast of %O to %O is a noop.");    }   #else /* !NEW_ARG_CHECK */
pike.git/src/las.c:3409: 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) { -  _CAR(n) = mksoftcastnode(CDR(n)->type, CAR(n)); +  _CAR(n) = mksoftcastnode(CDR(n)->type, +  mkcastnode(mixed_type_string, 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:3950:    check_node_type(CAR(n),    Pike_compiler->compiler_frame->current_return_type,    "Wrong return type.");    }    }    copy_pike_type(n->type, void_type_string);    break;       case F_CASE_RANGE:    if (CDR(n) && CAR(n) && !TEST_COMPAT(0,6)) { +  fix_type_field(CAR(n)); +  fix_type_field(CDR(n));    /* case 1 .. 2: */    if (!match_types(CAR(n)->type, CDR(n)->type)) {    if (!match_types(CAR(n)->type, int_type_string) ||    !match_types(CDR(n)->type, int_type_string)) {    yytype_report(REPORT_ERROR,    NULL, 0, CAR(n)->type,    NULL, 0, CDR(n)->type,    0, "Type mismatch in case range.");    }    } else if ((c->lex.pragmas & ID_STRICT_TYPES) &&
pike.git/src/las.c:3982:    if (!(CDR(n)->type == zero_type_string) ||    !(pike_types_le(CAR(n)->type, int_type_string))) {    yytype_report(REPORT_WARNING,    NULL, 0, CAR(n)->type,    NULL, 0, CDR(n)->type,    0, "Type mismatch in case range.");    }    }    }    } +  if (CDR(n) && (Pike_compiler->compiler_pass == 2)) { +  fix_type_field(CDR(n)); +  if (!match_types(CDR(n)->type, enumerable_type_string)) { +  yytype_report(REPORT_WARNING, +  NULL, 0, enumerable_type_string, +  NULL, 0, CDR(n)->type, +  0, "Case value is not an enumerable type."); +  } +  }    /* FALL_THROUGH */    case F_CASE: -  +  if (CAR(n) && (Pike_compiler->compiler_pass == 2)) { +  fix_type_field(CAR(n)); +  if (!match_types(CAR(n)->type, enumerable_type_string)) { +  yytype_report(REPORT_WARNING, +  NULL, 0, enumerable_type_string, +  NULL, 0, CAR(n)->type, +  0, "Case value is not an enumerable type."); +  } +  } +  /* FALL_THROUGH */    case F_INC_LOOP:    case F_DEC_LOOP:    case F_DEC_NEQ_LOOP:    case F_INC_NEQ_LOOP:    case F_LOOP:    case F_CONTINUE:    case F_BREAK:    case F_DEFAULT:    case F_POP_VALUE:    copy_pike_type(n->type, void_type_string);
pike.git/src/las.c:4263:    if (n->token == F_ARG_LIST) {    n->type = or_pike_types(CAR(n)->type, CDR(n)->type, 0);    } else {    copy_pike_type(n->type, CDR(n)->type);    }    break;       case F_MAGIC_INDEX:    /* FIXME: Could have a stricter type for ::`->(). */    /* FIXME: */ -  MAKE_CONSTANT_TYPE(n->type, tFunc(tMix tOr(tVoid,tInt),tMix)); +  MAKE_CONSTANT_TYPE(n->type, tFunc(tStr tOr3(tVoid,tObj,tDeprecated(tInt)) +  tOr(tVoid,tInt), tMix));    break;    case F_MAGIC_SET_INDEX:    /* FIXME: Could have a stricter type for ::`->=(). */    /* FIXME: */    MAKE_CONSTANT_TYPE(n->type, tFunc(tMix tSetvar(0,tMix) tOr(tVoid,tInt), tVar(0)));    break;    case F_MAGIC_INDICES:    MAKE_CONSTANT_TYPE(n->type, tFunc(tOr(tVoid,tInt), tArr(tString)));    break;    case F_MAGIC_VALUES:
pike.git/src/las.c:5218:    check_tree(n,0);    }   }      struct timer_oflo   {    INT32 counter;    int yes;   };    - static void check_evaluation_time(struct callback *cb,void *tmp,void *ignored) + static void check_evaluation_time(struct callback *UNUSED(cb), void *tmp, void *UNUSED(ignored))   {    struct timer_oflo *foo=(struct timer_oflo *)tmp;    if(foo->counter-- < 0)    {    foo->yes=1;    pike_throw();    }   }      ptrdiff_t eval_low(node *n,int print_error)
pike.git/src/las.c:5248:   #endif /* PIKE_USE_MACHINE_CODE */      #ifdef PIKE_DEBUG    if(l_flag > 3 && n)    {    fprintf(stderr,"Evaluating (tree info=%x):",n->tree_info);    print_tree(n);    }   #endif    +  fix_type_field(n); +     if(Pike_compiler->num_parse_error) {    return -1;    }       num_strings = prog->num_strings;    num_constants = prog->num_constants;    num_program = prog->num_program;   #ifdef PIKE_USE_MACHINE_CODE    num_relocations = prog->num_relocations;   #endif /* PIKE_USE_MACHINE_CODE */