e576bb2002-10-11Martin Nilsson /* || 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.
2d76f22005-05-20Martin Stjernholm || $Id: las.c,v 1.364 2005/05/19 22:35:29 mast Exp $
e576bb2002-10-11Martin Nilsson */
aedfb12002-10-09Martin Nilsson 
5267b71995-08-09Fredrik Hübinette (Hubbe) #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"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "pike_types.h" #include "constants.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "mapping.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "multiset.h"
b2d3e42000-12-01Fredrik Hübinette (Hubbe) #include "pike_error.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "docode.h" #include "main.h"
9aa6fa1997-05-19Fredrik Hübinette (Hubbe) #include "pike_memory.h"
6891181996-08-06Fredrik Hübinette (Hubbe) #include "operators.h"
a29e021996-10-15Fredrik Hübinette (Hubbe) #include "callback.h"
bb55f81997-03-16Fredrik Hübinette (Hubbe) #include "pike_macros.h"
9c6f7d1997-04-15Fredrik Hübinette (Hubbe) #include "peep.h"
5d2bb21998-01-26Henrik Grubbström (Grubba) #include "builtin_functions.h"
63c6751998-04-09Fredrik Hübinette (Hubbe) #include "cyclic.h"
011ad31999-10-22Fredrik Hübinette (Hubbe) #include "block_alloc.h"
f76b4c2000-05-11Henrik Grubbström (Grubba) #include "opcodes.h"
acae272001-07-20Henrik Grubbström (Grubba) #include "pikecode.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) 
9d91c72002-12-25Henrik Grubbström (Grubba) /* Define this if you want the optimizer to be paranoid about aliasing * effects to to indexing. */ /* #define PARANOID_INDEXING */
5267b71995-08-09Fredrik Hübinette (Hubbe) static node *eval(node *); static void optimize(node *n);
969a291999-11-17Henrik Grubbström (Grubba) static node *localopt(node *n);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
c3c7031996-12-04Fredrik Hübinette (Hubbe) int cumulative_parse_error=0;
5267b71995-08-09Fredrik Hübinette (Hubbe) extern char *get_type_name(int);
e82b301997-01-29Fredrik Hübinette (Hubbe) #define MAX_GLOBAL 2048
5267b71995-08-09Fredrik Hübinette (Hubbe) 
84191b1999-11-23Henrik Grubbström (Grubba) /* #define yywarning my_yyerror */
55a20a1999-11-17Henrik Grubbström (Grubba) int car_is_node(node *n)
5267b71995-08-09Fredrik Hübinette (Hubbe) { switch(n->token) {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case F_EXTERNAL:
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_IDENTIFIER:
4218011999-01-31Fredrik Hübinette (Hubbe)  case F_TRAMPOLINE:
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_CONSTANT: case F_LOCAL:
c21ee82004-12-18Henrik Grubbström (Grubba)  case F_THIS:
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; default:
046afe1999-11-11Henrik Grubbström (Grubba)  return !!_CAR(n);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
55a20a1999-11-17Henrik Grubbström (Grubba) int cdr_is_node(node *n)
5267b71995-08-09Fredrik Hübinette (Hubbe) { switch(n->token) {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case F_EXTERNAL:
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_IDENTIFIER:
4218011999-01-31Fredrik Hübinette (Hubbe)  case F_TRAMPOLINE:
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_CONSTANT: case F_LOCAL:
c21ee82004-12-18Henrik Grubbström (Grubba)  case F_THIS:
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; default:
046afe1999-11-11Henrik Grubbström (Grubba)  return !!_CDR(n);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
cbe8f32000-07-10Henrik Grubbström (Grubba) int node_is_leaf(node *n) { switch(n->token) { case F_EXTERNAL: case F_IDENTIFIER: case F_TRAMPOLINE: case F_CONSTANT: case F_LOCAL: return 1; } return 0; }
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
3c0c281998-01-26Fredrik Hübinette (Hubbe) void check_tree(node *n, int depth) {
ae7cc02000-09-12Henrik Grubbström (Grubba)  node *orig_n = n; node *parent;
3c0c281998-01-26Fredrik Hübinette (Hubbe)  if(!d_flag) return;
ae7cc02000-09-12Henrik Grubbström (Grubba)  if (!n) return;
046afe1999-11-11Henrik Grubbström (Grubba) 
ae7cc02000-09-12Henrik Grubbström (Grubba)  parent = n->parent; n->parent = NULL; while(n) { if(n->token==USHRT_MAX)
5aad932002-08-15Marcus Comstedt  Pike_fatal("Free node in tree.\n");
ae7cc02000-09-12Henrik Grubbström (Grubba)  check_node_hash(n); switch(n->token) {
01d4902000-07-11Fredrik Hübinette (Hubbe)  case F_EXTERNAL: if(n->type) {
ff88db2000-07-12Henrik Grubbström (Grubba)  int parent_id = n->u.integer.a;
01d4902000-07-11Fredrik Hübinette (Hubbe)  int id_no = n->u.integer.b;
da77e22000-09-08Fredrik Hübinette (Hubbe)  struct program_state *state = Pike_compiler;
ff88db2000-07-12Henrik Grubbström (Grubba)  while (state && (state->new_program->id != parent_id)) { state = state->previous; }
5d642e2003-08-03Martin Stjernholm  if (state && id_no != IDREF_MAGIC_THIS) {
ff88db2000-07-12Henrik Grubbström (Grubba)  struct identifier *id = ID_FROM_INT(state->new_program, id_no);
01d4902000-07-11Fredrik Hübinette (Hubbe)  if (id) {
f1bc3d2002-03-04Martin Stjernholm #if 0
01d4902000-07-11Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
cfe1fe2000-09-09Fredrik Hübinette (Hubbe)  /* FIXME: This test crashes on valid code because the type of the * identifier can change in pass 2 - Hubbe */
01d4902000-07-11Fredrik Hübinette (Hubbe)  if(id->type != n->type) {
fa74242004-07-06Martin Nilsson  fputs("Type of external node " "is not matching its identifier.\nid->type: ",stderr);
01d4902000-07-11Fredrik Hübinette (Hubbe)  simple_describe_type(id->type);
fa74242004-07-06Martin Nilsson  fputs("\nn->type : ", stderr);
01d4902000-07-11Fredrik Hübinette (Hubbe)  simple_describe_type(n->type);
fa74242004-07-06Martin Nilsson  fputc('\n', stderr);
01d4902000-07-11Fredrik Hübinette (Hubbe) 
5aad932002-08-15Marcus Comstedt  Pike_fatal("Type of external node is not matching its identifier.\n");
01d4902000-07-11Fredrik Hübinette (Hubbe)  }
f1bc3d2002-03-04Martin Stjernholm #endif
01d4902000-07-11Fredrik Hübinette (Hubbe) #endif } } }
ae7cc02000-09-12Henrik Grubbström (Grubba)  } if(d_flag<2) break;
01d4902000-07-11Fredrik Hübinette (Hubbe) 
0e58d22000-09-12Henrik Grubbström (Grubba)  if(!(depth & 1023)) { node *q; for(q=n->parent;q;q=q->parent) if(q->parent==n)
5aad932002-08-15Marcus Comstedt  Pike_fatal("Cyclic node structure found.\n");
ae7cc02000-09-12Henrik Grubbström (Grubba)  }
889d232000-09-12Henrik Grubbström (Grubba) 
ae7cc02000-09-12Henrik Grubbström (Grubba)  if(car_is_node(n))
889d232000-09-12Henrik Grubbström (Grubba)  {
ae7cc02000-09-12Henrik Grubbström (Grubba)  /* Check CAR */ #ifdef SHARED_NODES CAR(n)->parent = n; #else /* !SHARED_NODES */ if(CAR(n)->parent != n)
5aad932002-08-15Marcus Comstedt  Pike_fatal("Parent is wrong.\n");
ae7cc02000-09-12Henrik Grubbström (Grubba) #endif /* SHARED_NODES */ depth++; n = CAR(n); continue;
889d232000-09-12Henrik Grubbström (Grubba)  }
3c0c281998-01-26Fredrik Hübinette (Hubbe) 
ae7cc02000-09-12Henrik Grubbström (Grubba)  if(cdr_is_node(n)) { /* Check CDR */ #ifdef SHARED_NODES CDR(n)->parent = n; #else /* !SHARED_NODES */ if(CDR(n)->parent != n)
5aad932002-08-15Marcus Comstedt  Pike_fatal("Parent is wrong.\n");
f1af891999-12-14Henrik Grubbström (Grubba) #endif /* !SHARED_NODES */
3c0c281998-01-26Fredrik Hübinette (Hubbe) 
ae7cc02000-09-12Henrik Grubbström (Grubba)  depth++; n = CDR(n); continue; }
3c0c281998-01-26Fredrik Hübinette (Hubbe) 
ae7cc02000-09-12Henrik Grubbström (Grubba)  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)
5aad932002-08-15Marcus Comstedt  Pike_fatal("Parent is wrong.\n");
f1af891999-12-14Henrik Grubbström (Grubba) #endif /* !SHARED_NODES */
ae7cc02000-09-12Henrik Grubbström (Grubba)  n = CDR(n->parent); continue; } break; }
3c0c281998-01-26Fredrik Hübinette (Hubbe) 
ae7cc02000-09-12Henrik Grubbström (Grubba)  if (n != orig_n) {
fa74242004-07-06Martin Nilsson  fputs("check_tree() lost track.\n", stderr);
ae7cc02000-09-12Henrik Grubbström (Grubba)  d_flag = 0;
fa74242004-07-06Martin Nilsson  fputs("n:", stderr);
ae7cc02000-09-12Henrik Grubbström (Grubba)  print_tree(n);
fa74242004-07-06Martin Nilsson  fputs("orig_n:", stderr);
ae7cc02000-09-12Henrik Grubbström (Grubba)  print_tree(orig_n);
5aad932002-08-15Marcus Comstedt  Pike_fatal("check_tree() lost track.\n");
3c0c281998-01-26Fredrik Hübinette (Hubbe)  }
ae7cc02000-09-12Henrik Grubbström (Grubba)  n->parent = parent;
3c0c281998-01-26Fredrik Hübinette (Hubbe) } #endif
889d232000-09-12Henrik Grubbström (Grubba) /* FIXME: Ought to use parent pointer to avoid recursion. */
5267b71995-08-09Fredrik Hübinette (Hubbe) INT32 count_args(node *n) {
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  int a,b;
3c0c281998-01-26Fredrik Hübinette (Hubbe)  check_tree(n,0);
aee2d32000-09-12Henrik Grubbström (Grubba)  fatal_check_c_stack(16384);
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!n) return 0; switch(n->token) {
920d201999-11-06Henrik Grubbström (Grubba)  case F_COMMA_EXPR:
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_VAL_LVAL: case F_ARG_LIST:
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  a=count_args(CAR(n)); if(a==-1) return -1; b=count_args(CDR(n)); if(b==-1) return -1; return a+b;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_CAST: if(n->type == void_type_string) return 0; else return count_args(CAR(n));
84191b1999-11-23Henrik Grubbström (Grubba)  case F_SOFT_CAST: return count_args(CAR(n));
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_CASE:
9abda42002-03-02Martin Stjernholm  case F_CASE_RANGE:
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_FOR: case F_DO:
7daa182001-02-23Henrik Grubbström (Grubba)  case F_LOOP:
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_INC_LOOP: case F_DEC_LOOP: case F_DEC_NEQ_LOOP: case F_INC_NEQ_LOOP: case F_BREAK: case F_RETURN: case F_CONTINUE: case F_FOREACH: return 0; case '?': { int tmp1,tmp2;
e260681996-04-11Fredrik Hübinette (Hubbe)  tmp1=count_args(CADR(n)); tmp2=count_args(CDDR(n));
ae7cc02000-09-12Henrik Grubbström (Grubba)  if(tmp1==-1 || tmp2==-1) return -1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(tmp1 < tmp2) return tmp1; return tmp2; }
b95bef1996-03-29Fredrik Hübinette (Hubbe)  case F_PUSH_ARRAY: return -1;
cd06162000-03-01Fredrik Hübinette (Hubbe)  case F_APPLY: if(CAR(n)->token == F_CONSTANT && CAR(n)->u.sval.type == T_FUNCTION && CAR(n)->u.sval.subtype == FUNCTION_BUILTIN && n->type == void_type_string) return 0; return 1;
408a1e2004-10-30Martin Stjernholm  case F_RANGE_FROM_BEG: case F_RANGE_FROM_END: return 1; case F_RANGE_OPEN: return 0;
5267b71995-08-09Fredrik Hübinette (Hubbe)  default: if(n->type == void_type_string) return 0; return 1; } }
889d232000-09-12Henrik Grubbström (Grubba) /* FIXME: Ought to use parent pointer to avoid recursion. */
d68a072001-02-20Henrik Grubbström (Grubba) struct pike_type *find_return_type(node *n)
61e9a01998-01-25Fredrik Hübinette (Hubbe) {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *a, *b;
61e9a01998-01-25Fredrik Hübinette (Hubbe) 
3c0c281998-01-26Fredrik Hübinette (Hubbe)  check_tree(n,0);
aee2d32000-09-12Henrik Grubbström (Grubba)  fatal_check_c_stack(16384);
61e9a01998-01-25Fredrik Hübinette (Hubbe)  if(!n) return 0;
5aff211999-12-14Henrik Grubbström (Grubba) 
0e17982003-03-07Henrik Grubbström (Grubba)  optimize(n);
5aff211999-12-14Henrik Grubbström (Grubba)  if (n->token == F_RETURN) { if (CAR(n)) { if (CAR(n)->type) {
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(a, CAR(n)->type);
5aff211999-12-14Henrik Grubbström (Grubba)  } else { #ifdef PIKE_DEBUG if (l_flag > 2) {
fa74242004-07-06Martin Nilsson  fputs("Return with untyped argument.\n", stderr);
5aff211999-12-14Henrik Grubbström (Grubba)  print_tree(n); } #endif /* PIKE_DEBUG */
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(a, mixed_type_string);
5aff211999-12-14Henrik Grubbström (Grubba)  } } else {
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(a, zero_type_string);
5aff211999-12-14Henrik Grubbström (Grubba)  } return a; }
61e9a01998-01-25Fredrik Hübinette (Hubbe)  if(!(n->tree_info & OPT_RETURN)) return 0;
5aff211999-12-14Henrik Grubbström (Grubba) 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  if(car_is_node(n)) a=find_return_type(CAR(n)); else a=0; if(cdr_is_node(n)) b=find_return_type(CDR(n)); else b=0; if(a) {
33b4a61999-12-14Henrik Grubbström (Grubba)  if(b) { if (a != b) {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *res = or_pike_types(a, b, 1); free_type(a); free_type(b);
33b4a61999-12-14Henrik Grubbström (Grubba)  return res; }
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(b);
5aff211999-12-14Henrik Grubbström (Grubba)  }
61e9a01998-01-25Fredrik Hübinette (Hubbe)  return a; }
5aff211999-12-14Henrik Grubbström (Grubba)  return b;
61e9a01998-01-25Fredrik Hübinette (Hubbe) }
d4a1362001-02-09Fredrik Hübinette (Hubbe) int check_tailrecursion(void) { int e; if(debug_options & NO_TAILRECURSION) return 0; for(e=0;e<Pike_compiler->compiler_frame->max_number_of_locals;e++) { if(!pike_type_allow_premature_toss(
7daa182001-02-23Henrik Grubbström (Grubba)  Pike_compiler->compiler_frame->variable[e].type))
d4a1362001-02-09Fredrik Hübinette (Hubbe)  return 0; } return 1; }
a8ef6e1996-12-03Fredrik Hübinette (Hubbe) 
011ad31999-10-22Fredrik Hübinette (Hubbe) #undef BLOCK_ALLOC_NEXT #define BLOCK_ALLOC_NEXT u.node.a
1982302002-06-06Martin Stjernholm #undef PRE_INIT_BLOCK #define PRE_INIT_BLOCK(NODE) do { \ NODE->token = USHRT_MAX; \ } while (0)
3aab372002-11-24Martin Stjernholm BLOCK_ALLOC_FILL_PAGES(node_s, 2) #define NODES (sizeof (((struct node_s_block *) NULL)->x) / sizeof (struct node_s))
a8ef6e1996-12-03Fredrik Hübinette (Hubbe) 
011ad31999-10-22Fredrik Hübinette (Hubbe) #undef BLOCK_ALLOC_NEXT #define BLOCK_ALLOC_NEXT next
a8ef6e1996-12-03Fredrik Hübinette (Hubbe) 
046afe1999-11-11Henrik Grubbström (Grubba) #ifdef SHARED_NODES struct node_hash_table node_hash;
e8bf0a2000-12-01Henrik Grubbström (Grubba) static INLINE size_t hash_node(node *n)
046afe1999-11-11Henrik Grubbström (Grubba) {
e8bf0a2000-12-01Henrik Grubbström (Grubba)  size_t ret_; DO_HASHMEM(ret_, (unsigned char *)&(n->token),
b1db572000-12-01Henrik Grubbström (Grubba)  sizeof(node) - OFFSETOF(node_s, token), sizeof(node));
e8bf0a2000-12-01Henrik Grubbström (Grubba)  return ret_;
046afe1999-11-11Henrik Grubbström (Grubba) } static void add_node(node *n) {
52ca662000-10-01Per Hedbor  size_t hval = (n->hash % node_hash.size);
046afe1999-11-11Henrik Grubbström (Grubba) 
08f6992000-09-30Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG node *probe = node_hash.table[hval]; while(probe) {
52ca662000-10-01Per Hedbor  if (probe == n) {
be6fec2001-04-01Henrik Grubbström (Grubba)  fprintf(stderr, "add_node(%p == %p): Node already added!\n", (void *)probe, (void *)n);
ff06b72000-10-02Henrik Grubbström (Grubba)  fprintf( stderr, " %ld <-> %ld\n", DO_NOT_WARN((long)hval), DO_NOT_WARN((long)(n->hash % node_hash.size)) );
52ca662000-10-01Per Hedbor  probe = node_hash.table[hval]; while( probe ) {
be6fec2001-04-01Henrik Grubbström (Grubba)  fprintf(stderr, " %p\n", (void *)probe);
52ca662000-10-01Per Hedbor  probe = probe->next; }
5aad932002-08-15Marcus Comstedt  Pike_fatal( "Node already added!\n" );
08f6992000-09-30Henrik Grubbström (Grubba)  } probe = probe->next; } #endif /* PIKE_DEBUG */
046afe1999-11-11Henrik Grubbström (Grubba)  n->next = node_hash.table[hval]; node_hash.table[hval] = n; } static void sub_node(node *n) { node *prior;
6633f52000-11-25Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG
046afe1999-11-11Henrik Grubbström (Grubba)  if (!node_hash.size) { return; }
6633f52000-11-25Henrik Grubbström (Grubba) #endif /* PIKE_DEBUG */
046afe1999-11-11Henrik Grubbström (Grubba)  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; }
08f6992000-09-30Henrik Grubbström (Grubba)  n->next = NULL;
046afe1999-11-11Henrik Grubbström (Grubba) } static node *freeze_node(node *orig) {
a7988a2000-11-26Henrik Grubbström (Grubba)  size_t hash;
969a291999-11-17Henrik Grubbström (Grubba)  node *n;
6633f52000-11-25Henrik Grubbström (Grubba)  int found = 0;
046afe1999-11-11Henrik Grubbström (Grubba) 
f1bc3d2002-03-04Martin Stjernholm  /* 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;
6633f52000-11-25Henrik Grubbström (Grubba)  if (orig->tree_info & OPT_NOT_SHARED) {
a836c01999-11-12Henrik Grubbström (Grubba)  /* No need to have this node in the hash-table. */ /* add_node(orig); */
c3b17f2000-11-27Henrik Grubbström (Grubba)  return orig;
a836c01999-11-12Henrik Grubbström (Grubba)  }
a7988a2000-11-26Henrik Grubbström (Grubba)  /* free_node() wants a correct hash */ orig->hash = hash = hash_node(orig);
969a291999-11-17Henrik Grubbström (Grubba)  /* Mark this node as a possible duplicate */ orig->node_info |= OPT_DEFROSTED; /* Make sure we don't find ourselves */
6633f52000-11-25Henrik Grubbström (Grubba)  /* sub_node(orig); */
969a291999-11-17Henrik Grubbström (Grubba)  n = node_hash.table[hash % node_hash.size];
046afe1999-11-11Henrik Grubbström (Grubba)  while (n) {
6633f52000-11-25Henrik Grubbström (Grubba)  if (n == orig) { found = 1; if (!(n = n->next)) { break; } }
046afe1999-11-11Henrik Grubbström (Grubba)  if ((n->hash == hash) && !MEMCMP(&(n->token), &(orig->token), sizeof(node) - OFFSETOF(node_s, token))) {
889d232000-09-12Henrik Grubbström (Grubba)  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)) {
07f5432001-02-21Henrik Grubbström (Grubba)  free_type(n->type);
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, orig->type);
889d232000-09-12Henrik Grubbström (Grubba)  } } else { /* This probably doesn't happen, but... */
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, orig->type);
889d232000-09-12Henrik Grubbström (Grubba)  } }
6633f52000-11-25Henrik Grubbström (Grubba)  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); }
d83bff2001-07-13Henrik Grubbström (Grubba)  /* 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 = orig->current_file; orig->current_file = NULL; }
a836c01999-11-12Henrik Grubbström (Grubba)  free_node(dmalloc_touch(node *, orig));
50ea682003-03-14Henrik Grubbström (Grubba)  add_ref(n);
bf4f7d1999-11-12Henrik Grubbström (Grubba)  return check_node_hash(dmalloc_touch(node *, n));
046afe1999-11-11Henrik Grubbström (Grubba)  } n = n->next; }
969a291999-11-17Henrik Grubbström (Grubba)  orig->node_info &= ~OPT_DEFROSTED;
6633f52000-11-25Henrik Grubbström (Grubba)  if (!found) { add_node(dmalloc_touch(node *, orig)); }
da77e22000-09-08Fredrik Hübinette (Hubbe)  check_tree(orig,0);
bf4f7d1999-11-12Henrik Grubbström (Grubba)  return check_node_hash(orig);
046afe1999-11-11Henrik Grubbström (Grubba) } #else /* !SHARED_NODES */
01d4902000-07-11Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG static node *freeze_node(node *orig) {
2cb6782000-07-18Henrik Grubbström (Grubba)  check_tree(orig, 0);
01d4902000-07-11Fredrik Hübinette (Hubbe)  return orig; }
ff88db2000-07-12Henrik Grubbström (Grubba) #else /* !PIKE_DEBUG */
01d4902000-07-11Fredrik Hübinette (Hubbe) #define freeze_node(X) (X)
ff88db2000-07-12Henrik Grubbström (Grubba) #endif /* PIKE_DEBUG */
046afe1999-11-11Henrik Grubbström (Grubba) #endif /* SHARED_NODES */
a44a2c1998-05-01Henrik Grubbström (Grubba) void free_all_nodes(void)
a8ef6e1996-12-03Fredrik Hübinette (Hubbe) {
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(!Pike_compiler->compiler_frame)
a8ef6e1996-12-03Fredrik Hübinette (Hubbe)  { node *tmp;
011ad31999-10-22Fredrik Hübinette (Hubbe)  struct node_s_block *tmp2;
3aab372002-11-24Martin Stjernholm  size_t e=0;
c3c7031996-12-04Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifndef PIKE_DEBUG
c3c7031996-12-04Fredrik Hübinette (Hubbe)  if(cumulative_parse_error)
a8ef6e1996-12-03Fredrik Hübinette (Hubbe)  {
3c0c281998-01-26Fredrik Hübinette (Hubbe) #endif
c3c7031996-12-04Fredrik Hübinette (Hubbe) 
379b682002-09-30Marcus Comstedt  for(tmp2=node_s_blocks;tmp2;tmp2=tmp2->next) e+=tmp2->used;
c3c7031996-12-04Fredrik Hübinette (Hubbe)  if(e)
a8ef6e1996-12-03Fredrik Hübinette (Hubbe)  {
3aab372002-11-24Martin Stjernholm  size_t e2=e;
c303252002-10-07Marcus Comstedt  struct node_s_block *nextblk; for(tmp2=node_s_blocks;tmp2;tmp2=nextblk)
a8ef6e1996-12-03Fredrik Hübinette (Hubbe)  {
c303252002-10-07Marcus Comstedt  int n = tmp2->used; nextblk = tmp2->next;
62f6f62002-11-21Henrik Grubbström (Grubba)  /* We want to be able to access the token field of all * the blocks... */
7ca8592002-11-23Martin Stjernholm  PIKE_MEM_RW(tmp2->x);
c303252002-10-07Marcus Comstedt  for(e=0;n && e<NODES;e++)
c3c7031996-12-04Fredrik Hübinette (Hubbe)  {
1982302002-06-06Martin Stjernholm  if (tmp2->x[e].token != USHRT_MAX)
c3c7031996-12-04Fredrik Hübinette (Hubbe)  {
011ad31999-10-22Fredrik Hübinette (Hubbe)  tmp=tmp2->x+e;
cbe8f32000-07-10Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG
c3c7031996-12-04Fredrik Hübinette (Hubbe)  if(!cumulative_parse_error) {
046afe1999-11-11Henrik Grubbström (Grubba)  fprintf(stderr,"Free node at %p, (%s:%d) (token=%d).\n",
be6fec2001-04-01Henrik Grubbström (Grubba)  (void *)tmp, tmp->current_file->str, tmp->line_number,
046afe1999-11-11Henrik Grubbström (Grubba)  tmp->token);
011ad31999-10-22Fredrik Hübinette (Hubbe) 
a4033e2000-04-14Fredrik Hübinette (Hubbe)  debug_malloc_dump_references(tmp,0,2,0);
011ad31999-10-22Fredrik Hübinette (Hubbe) 
3c0c281998-01-26Fredrik Hübinette (Hubbe)  if(tmp->token==F_CONSTANT) print_tree(tmp);
c3c7031996-12-04Fredrik Hübinette (Hubbe)  }
046afe1999-11-11Henrik Grubbström (Grubba)  /* else */
c3c7031996-12-04Fredrik Hübinette (Hubbe) #endif {
6633f52000-11-25Henrik Grubbström (Grubba) #ifdef SHARED_NODES
b1db572000-12-01Henrik Grubbström (Grubba)  /* Force the hashtable entry to be cleared. */
6633f52000-11-25Henrik Grubbström (Grubba)  tmp->next = NULL; sub_node(tmp); #endif /* SHARED_NODES */
b1db572000-12-01Henrik Grubbström (Grubba)  /* Free the node and be happy */
c3c7031996-12-04Fredrik Hübinette (Hubbe)  /* Make sure we don't free any nodes twice */
046afe1999-11-11Henrik Grubbström (Grubba)  if(car_is_node(tmp)) _CAR(tmp)=0; if(cdr_is_node(tmp)) _CDR(tmp)=0; #ifdef SHARED_NODES
a7988a2000-11-26Henrik Grubbström (Grubba)  if (!(tmp->tree_info & OPT_NOT_SHARED)) { tmp->hash = hash_node(tmp); }
cf4df01999-11-12Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG if (l_flag > 3) { fprintf(stderr, "Freeing node that had %d refs.\n", tmp->refs); } #endif /* PIKE_DEBUG */
046afe1999-11-11Henrik Grubbström (Grubba)  /* Force the node to be freed. */ tmp->refs = 1; #endif /* SHARED_NODES */
3c0c281998-01-26Fredrik Hübinette (Hubbe)  debug_malloc_touch(tmp->type);
c3c7031996-12-04Fredrik Hübinette (Hubbe)  free_node(tmp);
c303252002-10-07Marcus Comstedt  --n;
c3c7031996-12-04Fredrik Hübinette (Hubbe)  } } }
a8ef6e1996-12-03Fredrik Hübinette (Hubbe)  }
c303252002-10-07Marcus Comstedt #ifdef PIKE_DEBUG
c3c7031996-12-04Fredrik Hübinette (Hubbe)  if(!cumulative_parse_error)
2d76f22005-05-20Martin Stjernholm  Pike_fatal("Failed to free %"PRINTSIZET"d nodes when compiling!\n",e2);
c3c7031996-12-04Fredrik Hübinette (Hubbe) #endif
a8ef6e1996-12-03Fredrik Hübinette (Hubbe)  }
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifndef PIKE_DEBUG
a8ef6e1996-12-03Fredrik Hübinette (Hubbe)  }
3c0c281998-01-26Fredrik Hübinette (Hubbe) #endif
011ad31999-10-22Fredrik Hübinette (Hubbe)  free_all_node_s_blocks();
c3c7031996-12-04Fredrik Hübinette (Hubbe)  cumulative_parse_error=0;
046afe1999-11-11Henrik Grubbström (Grubba)  #ifdef SHARED_NODES
6633f52000-11-25Henrik Grubbström (Grubba)  /* MEMSET(node_hash.table, 0, sizeof(node *) * node_hash.size); */
046afe1999-11-11Henrik Grubbström (Grubba) #endif /* SHARED_NODES */
a8ef6e1996-12-03Fredrik Hübinette (Hubbe)  } }
a836c01999-11-12Henrik Grubbström (Grubba) void debug_free_node(node *n)
5267b71995-08-09Fredrik Hübinette (Hubbe) { if(!n) return;
046afe1999-11-11Henrik Grubbström (Grubba)  #ifdef SHARED_NODES
50ea682003-03-14Henrik Grubbström (Grubba)  if (sub_ref(n)) {
03ef8b2000-09-13Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG if(l_flag>9)
046afe1999-11-11Henrik Grubbström (Grubba)  print_tree(n);
03ef8b2000-09-13Henrik Grubbström (Grubba) 
71bde82001-03-16Fredrik Hübinette (Hubbe)  if (!(n->tree_info & (OPT_NOT_SHARED | OPT_DEFROSTED))) {
03ef8b2000-09-13Henrik Grubbström (Grubba)  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);
5aad932002-08-15Marcus Comstedt  Pike_fatal("token:%d, car:%p cdr:%p file:%s line:%d\n",
03ef8b2000-09-13Henrik Grubbström (Grubba)  n->token, _CAR(n), _CDR(n), n->current_file->str, n->line_number); }
046afe1999-11-11Henrik Grubbström (Grubba)  }
03ef8b2000-09-13Henrik Grubbström (Grubba) #endif /* PIKE_DEBUG */ return;
046afe1999-11-11Henrik Grubbström (Grubba)  } #endif /* SHARED_NODES */
03ef8b2000-09-13Henrik Grubbström (Grubba)  n->parent = NULL; do { #ifdef PIKE_DEBUG
52ca662000-10-01Per Hedbor  if(l_flag>9)
03ef8b2000-09-13Henrik Grubbström (Grubba)  print_tree(n); #ifdef SHARED_NODES
71bde82001-03-16Fredrik Hübinette (Hubbe)  if (!(n->tree_info & (OPT_NOT_SHARED | OPT_DEFROSTED))) {
03ef8b2000-09-13Henrik Grubbström (Grubba)  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);
5aad932002-08-15Marcus Comstedt  Pike_fatal("token:%d, car:%p cdr:%p file:%s line:%d\n",
03ef8b2000-09-13Henrik Grubbström (Grubba)  n->token, _CAR(n), _CDR(n), n->current_file->str, n->line_number); } } #endif /* SHARED_NODES */
046afe1999-11-11Henrik Grubbström (Grubba) #endif /* PIKE_DEBUG */
b97d172000-09-14Henrik Grubbström (Grubba)  debug_malloc_touch(n);
03ef8b2000-09-13Henrik Grubbström (Grubba) 
f96c422000-09-15Henrik Grubbström (Grubba) #ifdef SHARED_NODES #ifdef PIKE_DEBUG
03ef8b2000-09-13Henrik Grubbström (Grubba)  if (n->refs) {
5aad932002-08-15Marcus Comstedt  Pike_fatal("Node with refs left about to be killed: %8p\n", n);
03ef8b2000-09-13Henrik Grubbström (Grubba)  }
f96c422000-09-15Henrik Grubbström (Grubba) #endif /* PIKE_DEBUG */
03ef8b2000-09-13Henrik Grubbström (Grubba)  sub_node(dmalloc_touch(node *, n)); #endif /* SHARED_NODES */ switch(n->token) { case USHRT_MAX:
5aad932002-08-15Marcus Comstedt  Pike_fatal("Freeing node again!\n");
03ef8b2000-09-13Henrik Grubbström (Grubba)  break; case F_CONSTANT: free_svalue(&(n->u.sval)); break; } if (car_is_node(n)) { /* Free CAR */
046afe1999-11-11Henrik Grubbström (Grubba) #ifdef SHARED_NODES
50ea682003-03-14Henrik Grubbström (Grubba)  if (sub_ref(_CAR(n))) {
03ef8b2000-09-13Henrik Grubbström (Grubba)  _CAR(n) = NULL; } else {
046afe1999-11-11Henrik Grubbström (Grubba) #endif /* SHARED_NODES */
03ef8b2000-09-13Henrik Grubbström (Grubba)  _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 */
1b5eb41998-11-17Fredrik Hübinette (Hubbe) 
03ef8b2000-09-13Henrik Grubbström (Grubba) #ifdef SHARED_NODES
50ea682003-03-14Henrik Grubbström (Grubba)  if (sub_ref(_CDR(n))) {
03ef8b2000-09-13Henrik Grubbström (Grubba)  _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) if (dead->refs) {
5aad932002-08-15Marcus Comstedt  Pike_fatal("Killed node %p still has refs: %d\n", dead, dead->refs);
03ef8b2000-09-13Henrik Grubbström (Grubba)  } #endif /* SHARED_NODES && PIKE_DEBUG */
aee2d32000-09-12Henrik Grubbström (Grubba) 
03ef8b2000-09-13Henrik Grubbström (Grubba)  n = n->parent;
a8ef6e1996-12-03Fredrik Hübinette (Hubbe) 
07f5432001-02-21Henrik Grubbström (Grubba)  if(dead->type) free_type(dead->type);
03ef8b2000-09-13Henrik Grubbström (Grubba)  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;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
03ef8b2000-09-13Henrik Grubbström (Grubba) #if defined(SHARED_NODES) && defined(PIKE_DEBUG) if (dead->refs) {
5aad932002-08-15Marcus Comstedt  Pike_fatal("Killed node %p still has refs: %d\n", dead, dead->refs);
03ef8b2000-09-13Henrik Grubbström (Grubba)  } #endif /* SHARED_NODES && PIKE_DEBUG */ n = n->parent;
07f5432001-02-21Henrik Grubbström (Grubba)  if(dead->type) free_type(dead->type);
03ef8b2000-09-13Henrik Grubbström (Grubba)  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
50ea682003-03-14Henrik Grubbström (Grubba)  if (sub_ref(_CDR(n))) {
03ef8b2000-09-13Henrik Grubbström (Grubba)  _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) if (n->refs) {
5aad932002-08-15Marcus Comstedt  Pike_fatal("Killed node %p still has refs: %d\n", n, n->refs);
03ef8b2000-09-13Henrik Grubbström (Grubba)  } #endif /* SHARE_NODES && PIKE_DEBUG */
07f5432001-02-21Henrik Grubbström (Grubba)  if(n->type) free_type(n->type);
03ef8b2000-09-13Henrik Grubbström (Grubba)  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);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
046afe1999-11-11Henrik Grubbström (Grubba) node *debug_check_node_hash(node *n) { #if defined(PIKE_DEBUG) && defined(SHARED_NODES)
71bde82001-03-16Fredrik Hübinette (Hubbe)  if (n && !(n->tree_info & (OPT_DEFROSTED|OPT_NOT_SHARED)) && (n->hash != hash_node(n))) {
bf4f7d1999-11-12Henrik Grubbström (Grubba)  fprintf(stderr,"Bad node hash at %p, (%s:%d) (token=%d).\n",
be6fec2001-04-01Henrik Grubbström (Grubba)  (void *)n, n->current_file->str, n->line_number,
bf4f7d1999-11-12Henrik Grubbström (Grubba)  n->token);
f76b4c2000-05-11Henrik Grubbström (Grubba)  debug_malloc_dump_references(n,0,0,0);
bf4f7d1999-11-12Henrik Grubbström (Grubba)  print_tree(n);
5aad932002-08-15Marcus Comstedt  Pike_fatal("Bad node hash!\n");
046afe1999-11-11Henrik Grubbström (Grubba)  } #endif /* PIKE_DEBUG && SHARED_NODES */ return n; }
5267b71995-08-09Fredrik Hübinette (Hubbe) /* here starts routines to make nodes */
a836c01999-11-12Henrik Grubbström (Grubba) static node *debug_mkemptynode(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
011ad31999-10-22Fredrik Hübinette (Hubbe)  node *res=alloc_node_s();
046afe1999-11-11Henrik Grubbström (Grubba) 
9d91c72002-12-25Henrik Grubbström (Grubba) #if defined(SHARED_NODES) || defined(__CHECKER__)
046afe1999-11-11Henrik Grubbström (Grubba)  MEMSET(res, 0, sizeof(node));
9d91c72002-12-25Henrik Grubbström (Grubba) #ifdef SHARED_NODES
046afe1999-11-11Henrik Grubbström (Grubba)  res->hash = 0;
50ea682003-03-14Henrik Grubbström (Grubba)  res->refs = 0; add_ref(res); /* For DMALLOC... */
046afe1999-11-11Henrik Grubbström (Grubba) #endif /* SHARED_NODES */
9d91c72002-12-25Henrik Grubbström (Grubba) #endif /* SHARED_NODES || __CHECKER__ */
046afe1999-11-11Henrik Grubbström (Grubba) 
a8ef6e1996-12-03Fredrik Hübinette (Hubbe)  res->token=0;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  res->line_number=lex.current_line;
3c0c281998-01-26Fredrik Hübinette (Hubbe)  copy_shared_string(res->current_file, lex.current_file);
5267b71995-08-09Fredrik Hübinette (Hubbe)  res->type=0;
454d541999-09-18Fredrik Hübinette (Hubbe)  res->name=0;
5267b71995-08-09Fredrik Hübinette (Hubbe)  res->node_info=0; res->tree_info=0; res->parent=0; return res; }
a836c01999-11-12Henrik Grubbström (Grubba) #define mkemptynode() dmalloc_touch(node *, debug_mkemptynode())
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  static int is_automap_arg_list(node *n) { if(!n) return 0; switch(n->token) { default: return 0; case F_ARG_LIST: return is_automap_arg_list(CAR(n)) || is_automap_arg_list(CDR(n)); case F_AUTO_MAP_MARKER: return 1; } }
7e877a2003-04-02Martin Stjernholm node *debug_mknode(int token, node *a, node *b)
5267b71995-08-09Fredrik Hübinette (Hubbe) { node *res;
046afe1999-11-11Henrik Grubbström (Grubba) 
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  switch(token) { case F_APPLY: if(is_automap_arg_list(b)) token=F_AUTO_MAP; break; case F_INDEX: switch((is_automap_arg_list(a) << 1) | is_automap_arg_list(b)) { case 1: res=mkefuncallnode("rows",mknode(F_ARG_LIST,a,copy_node(CAR(b)))); free_node(b); return res; case 2: res=mkefuncallnode("column",mknode(F_ARG_LIST,copy_node(CAR(a)),b)); free_node(a); return res; case 3: return mkefuncallnode("`[]",mknode(F_ARG_LIST,a,b)); }
88bc272002-08-12Henrik Grubbström (Grubba)  break; #ifdef PIKE_DEBUG case F_CAST: case F_SOFT_CAST:
5aad932002-08-15Marcus Comstedt  Pike_fatal("Attempt to create a cast-node with mknode()!\n");
88bc272002-08-12Henrik Grubbström (Grubba)  case F_CONSTANT:
5aad932002-08-15Marcus Comstedt  Pike_fatal("Attempt to create an F_CONSTANT-node with mknode()!\n");
88bc272002-08-12Henrik Grubbström (Grubba)  case F_LOCAL:
5aad932002-08-15Marcus Comstedt  Pike_fatal("Attempt to create an F_LOCAL-node with mknode()!\n");
88bc272002-08-12Henrik Grubbström (Grubba)  case F_IDENTIFIER:
5aad932002-08-15Marcus Comstedt  Pike_fatal("Attempt to create an F_IDENTIFIER-node with mknode()!\n");
88bc272002-08-12Henrik Grubbström (Grubba)  case F_TRAMPOLINE:
5aad932002-08-15Marcus Comstedt  Pike_fatal("Attempt to create an F_TRAMPOLINE-node with mknode()!\n");
88bc272002-08-12Henrik Grubbström (Grubba)  case F_EXTERNAL:
5aad932002-08-15Marcus Comstedt  Pike_fatal("Attempt to create an F_EXTERNAL-node with mknode()!\n");
88bc272002-08-12Henrik Grubbström (Grubba) #endif /* PIKE_DEBUG */
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  }
046afe1999-11-11Henrik Grubbström (Grubba) #if defined(PIKE_DEBUG) && !defined(SHARED_NODES)
a836c01999-11-12Henrik Grubbström (Grubba)  if(b && a==b)
5aad932002-08-15Marcus Comstedt  Pike_fatal("mknode: a and be are the same!\n");
32e2af1998-11-17Fredrik Hübinette (Hubbe) #endif
3c0c281998-01-26Fredrik Hübinette (Hubbe)  check_tree(a,0); check_tree(b,0);
046afe1999-11-11Henrik Grubbström (Grubba) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  res = mkemptynode();
a836c01999-11-12Henrik Grubbström (Grubba)  _CAR(res) = dmalloc_touch(node *, a); _CDR(res) = dmalloc_touch(node *, b);
5267b71995-08-09Fredrik Hübinette (Hubbe)  res->node_info = 0; res->tree_info = 0;
046afe1999-11-11Henrik Grubbström (Grubba)  if(a) { a->parent = res; } if(b) { b->parent = res; }
ba6d6c1998-04-19Fredrik Hübinette (Hubbe) 
046afe1999-11-11Henrik Grubbström (Grubba)  res->token = token; res->type = 0;
5267b71995-08-09Fredrik Hübinette (Hubbe)  switch(token) { case F_CATCH: res->node_info |= OPT_SIDE_EFFECT;
b464611999-11-14Henrik Grubbström (Grubba)  if (a) { res->tree_info |= a->tree_info & ~OPT_BREAK; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  case F_AUTO_MAP:
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_APPLY:
e260681996-04-11Fredrik Hübinette (Hubbe)  {
1ef5572000-08-30Henrik Grubbström (Grubba)  unsigned INT16 opt_flags = OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND; struct identifier *i = NULL; if (a) { switch(a->token) { case F_CONSTANT:
f3c7152001-04-14Fredrik Hübinette (Hubbe)  switch(a->u.sval.type) { case T_FUNCTION: if (a->u.sval.subtype == FUNCTION_BUILTIN) { opt_flags = a->u.sval.u.efun->flags; } else if (a->u.sval.u.object->prog) { i = ID_FROM_INT(a->u.sval.u.object->prog, a->u.sval.subtype); } else { yyerror("Calling function in destructed module."); } break; case T_PROGRAM:
e940752001-12-06Henrik Grubbström (Grubba)  if(a->u.sval.u.program->flags & PROGRAM_CONSTANT) {
f3c7152001-04-14Fredrik Hübinette (Hubbe)  opt_flags=0;
e940752001-12-06Henrik Grubbström (Grubba)  } if (a->u.sval.u.program->flags & PROGRAM_USES_PARENT) { yyerror("Can not clone program without parent context."); }
f3c7152001-04-14Fredrik Hübinette (Hubbe)  break;
1ef5572000-08-30Henrik Grubbström (Grubba)  } break; case F_EXTERNAL:
5d642e2003-08-03Martin Stjernholm  if (a->u.integer.b != IDREF_MAGIC_THIS) {
1ef5572000-08-30Henrik Grubbström (Grubba)  struct program_state *state = Pike_compiler; int program_id = a->u.integer.a; while (state && (state->new_program->id != program_id)) { state = state->previous; } if (state) { i = ID_FROM_INT(state->new_program, a->u.integer.b); } else { yyerror("Parent has left."); } } break; case F_LOCAL: /* FIXME: Should lookup functions in the local scope. */ default: res->tree_info |= a->tree_info; } if (i && IDENTIFIER_IS_FUNCTION(i->identifier_flags)) { res->node_info |= i->opt_flags; } else { res->node_info |= opt_flags; } } else { res->node_info |= opt_flags; }
5974b02001-01-12Martin Stjernholm  res->node_info |= OPT_APPLY;
1ef5572000-08-30Henrik Grubbström (Grubba)  if(b) res->tree_info |= b->tree_info;
e260681996-04-11Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
2a8cd81999-11-18Henrik Grubbström (Grubba)  case F_POP_VALUE:
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(res->type, void_type_string);
2a8cd81999-11-18Henrik Grubbström (Grubba)  if(a) res->tree_info |= a->tree_info; if(b) res->tree_info |= b->tree_info; break;
6369f61999-03-11Fredrik Hübinette (Hubbe)  case F_MAGIC_SET_INDEX:
b464611999-11-14Henrik Grubbström (Grubba)  res->node_info |= OPT_ASSIGNMENT; /* FALL_THROUGH */ case F_MAGIC_INDEX:
cbe1132001-12-16Martin Stjernholm  case F_MAGIC_INDICES: case F_MAGIC_VALUES:
1c1c5e2001-04-08Fredrik Hübinette (Hubbe)  { int e; struct program_state *state = Pike_compiler; res->node_info |= OPT_EXTERNAL_DEPEND; for(e=0;e<b->u.sval.u.integer;e++) {
22d7992001-06-23Fredrik Hübinette (Hubbe)  state->new_program->flags |= PROGRAM_USES_PARENT | PROGRAM_NEEDS_PARENT;
1c1c5e2001-04-08Fredrik Hübinette (Hubbe)  state=state->previous; }
f9abcf1999-09-16Fredrik Hübinette (Hubbe)  break;
1c1c5e2001-04-08Fredrik Hübinette (Hubbe)  }
6369f61999-03-11Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case F_UNDEFINED: res->node_info |= OPT_EXTERNAL_DEPEND | OPT_SIDE_EFFECT; break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_RETURN: res->node_info |= OPT_RETURN; break; case F_BREAK: res->node_info |= OPT_BREAK; break; case F_CONTINUE: res->node_info |= OPT_CONTINUE; break; case F_DEFAULT: case F_CASE:
9abda42002-03-02Martin Stjernholm  case F_CASE_RANGE:
5267b71995-08-09Fredrik Hübinette (Hubbe)  res->node_info |= OPT_CASE; break;
b464611999-11-14Henrik Grubbström (Grubba)  case F_INC_LOOP: case F_INC_NEQ_LOOP: case F_DEC_LOOP: case F_DEC_NEQ_LOOP: res->node_info |= OPT_ASSIGNMENT; if (a) { res->tree_info |= a->tree_info; } if (b) { res->tree_info |= (b->tree_info & ~(OPT_BREAK|OPT_CONTINUE)); } break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_SSCANF: if(!b || count_args(b) == 0) break;
b464611999-11-14Henrik Grubbström (Grubba)  res->node_info |= OPT_ASSIGNMENT; break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_ASSIGN:
b464611999-11-14Henrik Grubbström (Grubba)  case F_MOD_EQ: case F_AND_EQ: case F_MULT_EQ: case F_ADD_EQ: case F_SUB_EQ: case F_DIV_EQ: case F_LSH_EQ: case F_RSH_EQ: case F_XOR_EQ: case F_OR_EQ: res->node_info |= OPT_ASSIGNMENT; if (a) { res->tree_info |= a->tree_info; } if (b) { res->tree_info |= b->tree_info; } break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_INC: case F_DEC: case F_POST_INC: case F_POST_DEC: res->node_info |= OPT_ASSIGNMENT;
b464611999-11-14Henrik Grubbström (Grubba)  if (a) { res->tree_info |= a->tree_info; }
ba6d6c1998-04-19Fredrik Hübinette (Hubbe)  break;
408a1e2004-10-30Martin Stjernholm  case ':': case F_RANGE_FROM_BEG: case F_RANGE_FROM_END: case F_RANGE_OPEN: res->node_info |= OPT_FLAG_NODE; break;
046afe1999-11-11Henrik Grubbström (Grubba)  default: if(a) res->tree_info |= a->tree_info; if(b) res->tree_info |= b->tree_info;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
f68afd1999-11-20Henrik Grubbström (Grubba)  /* We try to optimize most things, but argument lists are hard... */
945f9c2000-10-03Henrik Grubbström (Grubba)  if((token != F_ARG_LIST) && (a || b))
f68afd1999-11-20Henrik Grubbström (Grubba)  res->node_info |= OPT_TRY_OPTIMIZE;
b464611999-11-14Henrik Grubbström (Grubba)  res->tree_info |= res->node_info;
6633f52000-11-25Henrik Grubbström (Grubba) #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 */
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
9e52381998-03-01Fredrik Hübinette (Hubbe)  if(d_flag > 3) verify_shared_strings_tables(); #endif
01d4902000-07-11Fredrik Hübinette (Hubbe)  check_tree(res,0);
71bde82001-03-16Fredrik Hübinette (Hubbe)  #if 0 if(!Pike_compiler->num_parse_error && Pike_compiler->compiler_pass==2 &&
945f9c2000-10-03Henrik Grubbström (Grubba)  (res->node_info & OPT_TRY_OPTIMIZE))
3c0c281998-01-26Fredrik Hübinette (Hubbe)  {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  optimize(res);
3c0c281998-01-26Fredrik Hübinette (Hubbe)  check_tree(res,0); }
71bde82001-03-16Fredrik Hübinette (Hubbe) #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
66d51c1997-03-04Fredrik Hübinette (Hubbe)  if(d_flag > 3) verify_shared_strings_tables(); #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  return res; }
a836c01999-11-12Henrik Grubbström (Grubba) node *debug_mkstrnode(struct pike_string *str)
5267b71995-08-09Fredrik Hübinette (Hubbe) { node *res = mkemptynode(); res->token = F_CONSTANT;
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(res->type, string_type_string);
5267b71995-08-09Fredrik Hübinette (Hubbe)  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);
046afe1999-11-11Henrik Grubbström (Grubba)  return freeze_node(res);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
69aa4b2003-01-26Mirar (Pontus Hagland) node *debug_mkintnode(INT_TYPE nr)
5267b71995-08-09Fredrik Hübinette (Hubbe) { 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;
b660c81999-03-01Fredrik Hübinette (Hubbe)  res->type=get_type_of_svalue( & res->u.sval);
046afe1999-11-11Henrik Grubbström (Grubba)  return freeze_node(res); }
69aa4b2003-01-26Mirar (Pontus Hagland) node *debug_mknewintnode(INT_TYPE nr)
046afe1999-11-11Henrik Grubbström (Grubba) { node *res = mkemptynode(); res->token = F_CONSTANT;
a836c01999-11-12Henrik Grubbström (Grubba)  res->node_info = OPT_NOT_SHARED;
6633f52000-11-25Henrik Grubbström (Grubba)  res->tree_info = OPT_NOT_SHARED;
046afe1999-11-11Henrik Grubbström (Grubba)  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
50ea682003-03-14Henrik Grubbström (Grubba)  res->refs = 0; add_ref(res); /* For DMALLOC... */
a7988a2000-11-26Henrik Grubbström (Grubba)  /* res->hash = hash_node(res); */
046afe1999-11-11Henrik Grubbström (Grubba) #endif /* SHARED_NODES */
5267b71995-08-09Fredrik Hübinette (Hubbe)  return res; }
a836c01999-11-12Henrik Grubbström (Grubba) node *debug_mkfloatnode(FLOAT_TYPE foo)
5267b71995-08-09Fredrik Hübinette (Hubbe) { node *res = mkemptynode(); res->token = F_CONSTANT;
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(res->type, float_type_string);
5267b71995-08-09Fredrik Hübinette (Hubbe)  res->u.sval.type = T_FLOAT; #ifdef __CHECKER__ res->u.sval.subtype = 0; #endif res->u.sval.u.float_number = foo;
046afe1999-11-11Henrik Grubbström (Grubba)  return freeze_node(res);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
a5787d1999-03-03Fredrik Hübinette (Hubbe) 
a836c01999-11-12Henrik Grubbström (Grubba) node *debug_mkprgnode(struct program *p)
a5787d1999-03-03Fredrik Hübinette (Hubbe) { struct svalue s; s.u.program=p;
046afe1999-11-11Henrik Grubbström (Grubba)  s.type = T_PROGRAM; #ifdef __CHECKER__ s.subtype = 0; #endif
a5787d1999-03-03Fredrik Hübinette (Hubbe)  return mkconstantsvaluenode(&s); }
a836c01999-11-12Henrik Grubbström (Grubba) node *debug_mkapplynode(node *func,node *args)
5267b71995-08-09Fredrik Hübinette (Hubbe) { return mknode(F_APPLY, func, args); }
a836c01999-11-12Henrik Grubbström (Grubba) node *debug_mkefuncallnode(char *function, node *args)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *name;
45e8a81997-01-26Fredrik Hübinette (Hubbe)  node *n;
e82a872002-03-04Martin Stjernholm  /* Force resolving since we don't want to get tangled up in the * placeholder object here. The problem is really that the * placeholder purport itself to contain every identifier, which * makes it hide the real ones in find_module_identifier. This * kludge will fail if the class being placeholded actually contains * these identifiers, but then again I think it's a bit odd in the * first place to look up these efuns in the module being compiled. * Wouldn't it be better if this function consulted * compiler_handler->get_default_module? /mast */
2ebdad2004-03-16Henrik Grubbström (Grubba)  int orig_flags; SET_FORCE_RESOLVE(orig_flags); name = findstring(function);
2816052000-03-30Fredrik Hübinette (Hubbe)  if(!name || !(n=find_module_identifier(name,0)))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
2ebdad2004-03-16Henrik Grubbström (Grubba)  UNSET_FORCE_RESOLVE(orig_flags);
5267b71995-08-09Fredrik Hübinette (Hubbe)  my_yyerror("Internally used efun undefined: %s",function); return mkintnode(0); }
2ebdad2004-03-16Henrik Grubbström (Grubba)  UNSET_FORCE_RESOLVE(orig_flags);
046afe1999-11-11Henrik Grubbström (Grubba)  n = mkapplynode(n, args);
45e8a81997-01-26Fredrik Hübinette (Hubbe)  return n;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
a836c01999-11-12Henrik Grubbström (Grubba) node *debug_mkopernode(char *oper_id, node *arg1, node *arg2)
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) { if(arg1 && arg2) arg1=mknode(F_ARG_LIST,arg1,arg2); return mkefuncallnode(oper_id, arg1); }
a836c01999-11-12Henrik Grubbström (Grubba) node *debug_mklocalnode(int var, int depth)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
4218011999-01-31Fredrik Hübinette (Hubbe)  struct compiler_frame *f; int e;
5267b71995-08-09Fredrik Hübinette (Hubbe)  node *res = mkemptynode(); res->token = F_LOCAL;
4218011999-01-31Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  f=Pike_compiler->compiler_frame;
4218011999-01-31Fredrik Hübinette (Hubbe)  for(e=0;e<depth;e++) f=f->previous;
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(res->type, f->variable[var].type);
4218011999-01-31Fredrik Hübinette (Hubbe) 
a836c01999-11-12Henrik Grubbström (Grubba)  res->node_info = OPT_NOT_CONST | OPT_NOT_SHARED; res->tree_info = res->node_info;
5267b71995-08-09Fredrik Hübinette (Hubbe) #ifdef __CHECKER__
046afe1999-11-11Henrik Grubbström (Grubba)  _CDR(res) = 0;
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif
4218011999-01-31Fredrik Hübinette (Hubbe)  res->u.integer.a = var; res->u.integer.b = depth;
046afe1999-11-11Henrik Grubbström (Grubba)  #ifdef SHARED_NODES
a836c01999-11-12Henrik Grubbström (Grubba)  /* FIXME: Not common-subexpression optimized. * Node would need to contain a ref to the current function, * and to the current program. */
046afe1999-11-11Henrik Grubbström (Grubba)  res->hash = hash_node(res); /* return freeze_node(res); */ #endif /* SHARED_NODES */
5267b71995-08-09Fredrik Hübinette (Hubbe)  return res; }
a836c01999-11-12Henrik Grubbström (Grubba) node *debug_mkidentifiernode(int i)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
342fef2000-08-23Fredrik Hübinette (Hubbe) #if 1
da77e22000-09-08Fredrik Hübinette (Hubbe)  node *res = mkexternalnode(Pike_compiler->new_program, i); check_tree(res,0); return res;
342fef2000-08-23Fredrik Hübinette (Hubbe) #else
5267b71995-08-09Fredrik Hübinette (Hubbe)  node *res = mkemptynode(); res->token = F_IDENTIFIER;
bad5162000-06-23Fredrik Hübinette (Hubbe)  copy_shared_string(res->type, ID_FROM_INT(Pike_compiler->new_program, i)->type);
5267b71995-08-09Fredrik Hübinette (Hubbe)  /* FIXME */
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(IDENTIFIER_IS_CONSTANT(ID_FROM_INT(Pike_compiler->new_program, i)->identifier_flags))
3856c31996-11-25Fredrik Hübinette (Hubbe)  { res->node_info = OPT_EXTERNAL_DEPEND; }else{ res->node_info = OPT_NOT_CONST; }
66d51c1997-03-04Fredrik Hübinette (Hubbe)  res->tree_info=res->node_info;
5267b71995-08-09Fredrik Hübinette (Hubbe)  #ifdef __CHECKER__
588aa31999-11-11Henrik Grubbström (Grubba)  _CDR(res) = 0;
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif
046afe1999-11-11Henrik Grubbström (Grubba)  res->u.id.number = i; #ifdef SHARED_NODES
bad5162000-06-23Fredrik Hübinette (Hubbe)  res->u.id.prog = Pike_compiler->new_program;
046afe1999-11-11Henrik Grubbström (Grubba) #endif /* SHARED_NODES */ res = freeze_node(res);
3c0c281998-01-26Fredrik Hübinette (Hubbe)  check_tree(res,0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return res;
342fef2000-08-23Fredrik Hübinette (Hubbe) #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) }
8c70ba2001-09-28Fredrik Hübinette (Hubbe) node *debug_mktrampolinenode(int i, struct compiler_frame *frame)
bf4f7d1999-11-12Henrik Grubbström (Grubba) {
8c70ba2001-09-28Fredrik Hübinette (Hubbe)  struct compiler_frame *f;
bf4f7d1999-11-12Henrik Grubbström (Grubba)  node *res = mkemptynode();
8c70ba2001-09-28Fredrik Hübinette (Hubbe) 
bf4f7d1999-11-12Henrik Grubbström (Grubba)  res->token = F_TRAMPOLINE;
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(res->type, ID_FROM_INT(Pike_compiler->new_program, i)->type);
bf4f7d1999-11-12Henrik Grubbström (Grubba)  /* FIXME */
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(IDENTIFIER_IS_CONSTANT(ID_FROM_INT(Pike_compiler->new_program, i)->identifier_flags))
bf4f7d1999-11-12Henrik Grubbström (Grubba)  { res->node_info = OPT_EXTERNAL_DEPEND; }else{ res->node_info = OPT_NOT_CONST; } res->tree_info=res->node_info; #ifdef __CHECKER__ _CDR(res) = 0; #endif
8c70ba2001-09-28Fredrik Hübinette (Hubbe)  res->u.trampoline.ident=i; 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;
bf4f7d1999-11-12Henrik Grubbström (Grubba) #ifdef SHARED_NODES
8c70ba2001-09-28Fredrik Hübinette (Hubbe)  res->u.trampoline.prog = Pike_compiler->new_program;
bf4f7d1999-11-12Henrik Grubbström (Grubba) #endif /* SHARED_NODES */ res = freeze_node(res); check_tree(res,0); return res; }
ff88db2000-07-12Henrik Grubbström (Grubba) node *debug_mkexternalnode(struct program *parent_prog, int i)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) {
ee6a782003-11-19Henrik Grubbström (Grubba) #if 0 return mkidentifiernode(add_ext_ref(Pike_compiler, parent_prog, i)); #else /* !0 */
1c1c5e2001-04-08Fredrik Hübinette (Hubbe)  struct program_state *state;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  node *res = mkemptynode(); res->token = F_EXTERNAL;
5c604d2000-07-12Martin Stjernholm 
5d642e2003-08-03Martin Stjernholm  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;
01d4902000-07-11Fredrik Hübinette (Hubbe)  }
5d642e2003-08-03Martin Stjernholm  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); }
01d4902000-07-11Fredrik Hübinette (Hubbe) #endif
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
5d642e2003-08-03Martin Stjernholm  copy_pike_type(res->type, id->type);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
5d642e2003-08-03Martin Stjernholm  /* FIXME */ if(IDENTIFIER_IS_CONSTANT(id->identifier_flags)) { res->node_info = OPT_EXTERNAL_DEPEND; }else{ res->node_info = OPT_NOT_CONST; }
6d22541998-01-28Fredrik Hübinette (Hubbe)  }
046afe1999-11-11Henrik Grubbström (Grubba)  res->tree_info = res->node_info;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  #ifdef __CHECKER__
046afe1999-11-11Henrik Grubbström (Grubba)  _CDR(res) = 0;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #endif
ff88db2000-07-12Henrik Grubbström (Grubba)  res->u.integer.a = parent_prog->id;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  res->u.integer.b = i;
1994251999-09-06Fredrik Hübinette (Hubbe)  /* Bzot-i-zot */
1c1c5e2001-04-08Fredrik Hübinette (Hubbe)  state = Pike_compiler; while(parent_prog != state->new_program) {
22d7992001-06-23Fredrik Hübinette (Hubbe)  state->new_program->flags |= PROGRAM_USES_PARENT | PROGRAM_NEEDS_PARENT;
1c1c5e2001-04-08Fredrik Hübinette (Hubbe)  state=state->previous; }
1994251999-09-06Fredrik Hübinette (Hubbe) 
da77e22000-09-08Fredrik Hübinette (Hubbe)  res=freeze_node(res);
f1bc3d2002-03-04Martin Stjernholm #if 0
da77e22000-09-08Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
cfe1fe2000-09-09Fredrik Hübinette (Hubbe)  /* 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)
da77e22000-09-08Fredrik Hübinette (Hubbe)  { 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");
5aad932002-08-15Marcus Comstedt  Pike_fatal("Type of external node is not matching it's identifier.\n");
da77e22000-09-08Fredrik Hübinette (Hubbe)  }
f1bc3d2002-03-04Martin Stjernholm #endif
da77e22000-09-08Fredrik Hübinette (Hubbe) #endif return res;
ee6a782003-11-19Henrik Grubbström (Grubba) #endif /* 0 */
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) }
c21ee82004-12-18Henrik Grubbström (Grubba) node *debug_mkthisnode(struct program *parent_prog, int inherit_num) {
36a1132004-12-18Henrik Grubbström (Grubba)  struct program_state *state;
c21ee82004-12-18Henrik Grubbström (Grubba)  node *res; #ifdef PIKE_DEBUG if ((inherit_num < 0) || (inherit_num > 65535)) { Pike_fatal("This is bad: %p, %d\n", parent_prog, inherit_num); } #endif /* PIKE_DEBUG */ res = mkemptynode(); res->token = F_THIS; type_stack_mark();
3eafed2004-12-19Henrik Grubbström (Grubba)  push_object_type(!!inherit_num, parent_prog->inherits[inherit_num].prog->id);
c21ee82004-12-18Henrik Grubbström (Grubba)  res->type = pop_unfinished_type(); res->tree_info = res->node_info = OPT_NOT_CONST; #ifdef __CHECKER__ _CDR(res) = 0; #endif res->u.integer.a = parent_prog->id; res->u.integer.b = inherit_num;
36a1132004-12-18Henrik Grubbström (Grubba)  /* 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; }
c21ee82004-12-18Henrik Grubbström (Grubba)  return freeze_node(res); }
d68a072001-02-20Henrik Grubbström (Grubba) node *debug_mkcastnode(struct pike_type *type, node *n)
5267b71995-08-09Fredrik Hübinette (Hubbe) { node *res;
046afe1999-11-11Henrik Grubbström (Grubba) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!n) return 0;
046afe1999-11-11Henrik Grubbström (Grubba) 
1d480f1999-11-23Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG
f68afd1999-11-20Henrik Grubbström (Grubba)  if (!type) {
5aad932002-08-15Marcus Comstedt  Pike_fatal("Casting to no type!\n");
f68afd1999-11-20Henrik Grubbström (Grubba)  }
1d480f1999-11-23Henrik Grubbström (Grubba) #endif /* PIKE_DEBUG */
f68afd1999-11-20Henrik Grubbström (Grubba) 
22dd601999-11-18Henrik Grubbström (Grubba)  if (type == void_type_string) return mknode(F_POP_VALUE, n, 0);
0255202003-07-30Martin Stjernholm #if 0 /* It's not always safe to ignore the cast in this case. E.g. if n * has type program, the value can contain a function style program * pointer which the cast will turn into a real program * reference. */
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(type==n->type) return n;
0255202003-07-30Martin Stjernholm #endif
046afe1999-11-11Henrik Grubbström (Grubba) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  res = mkemptynode(); res->token = F_CAST;
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(res->type, type);
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(match_types(object_type_string, type) ||
561a2e2001-01-17Fredrik Hübinette (Hubbe)  match_types(program_type_string, type))
5267b71995-08-09Fredrik Hübinette (Hubbe)  res->node_info |= OPT_SIDE_EFFECT;
7cbf2c1999-12-14Henrik Grubbström (Grubba)  res->tree_info |= n->tree_info;
046afe1999-11-11Henrik Grubbström (Grubba)  _CAR(res) = n;
cbe8f32000-07-10Henrik Grubbström (Grubba)  _CDR(res) = mktypenode(type);
046afe1999-11-11Henrik Grubbström (Grubba) 
bf4f7d1999-11-12Henrik Grubbström (Grubba)  n->parent = res;
046afe1999-11-11Henrik Grubbström (Grubba)  return freeze_node(res);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
d68a072001-02-20Henrik Grubbström (Grubba) node *debug_mksoftcastnode(struct pike_type *type, node *n)
1d480f1999-11-23Henrik Grubbström (Grubba) { node *res; if(!n) return 0; #ifdef PIKE_DEBUG if (!type) {
5aad932002-08-15Marcus Comstedt  Pike_fatal("Soft cast to no type!\n");
1d480f1999-11-23Henrik Grubbström (Grubba)  } #endif /* PIKE_DEBUG */
bad5162000-06-23Fredrik Hübinette (Hubbe)  if (Pike_compiler->compiler_pass == 2) {
1fcad41999-12-30Henrik Grubbström (Grubba)  if (type == void_type_string) { yywarning("Soft cast to void."); return mknode(F_POP_VALUE, n, 0); }
1d480f1999-11-23Henrik Grubbström (Grubba) 
1fcad41999-12-30Henrik Grubbström (Grubba)  if(type==n->type) {
1d480f1999-11-23Henrik Grubbström (Grubba)  struct pike_string *t1 = describe_type(type);
ce060e2004-06-30Martin Nilsson  yywarning("Soft cast to %S is a noop.", t1);
1d480f1999-11-23Henrik Grubbström (Grubba)  free_string(t1);
1fcad41999-12-30Henrik Grubbström (Grubba)  return n; } if (n->type) { if (!check_soft_cast(type, n->type)) { struct pike_string *t1 = describe_type(type); struct pike_string *t2 = describe_type(n->type);
ce060e2004-06-30Martin Nilsson  yywarning("Soft cast to %S isn't a restriction of %S.", t1, t2);
1fcad41999-12-30Henrik Grubbström (Grubba)  free_string(t2); free_string(t1); } /* FIXME: check_soft_cast() is weaker than pike_types_le() * The resulting type should probably be the and between the old * and the new type. */
1d480f1999-11-23Henrik Grubbström (Grubba)  } }
1fcad41999-12-30Henrik Grubbström (Grubba) 
1d480f1999-11-23Henrik Grubbström (Grubba)  res = mkemptynode(); res->token = F_SOFT_CAST;
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(res->type, type);
1d480f1999-11-23Henrik Grubbström (Grubba) 
7cbf2c1999-12-14Henrik Grubbström (Grubba)  res->tree_info |= n->tree_info;
1d480f1999-11-23Henrik Grubbström (Grubba)  _CAR(res) = n;
cbe8f32000-07-10Henrik Grubbström (Grubba)  _CDR(res) = mktypenode(type);
1d480f1999-11-23Henrik Grubbström (Grubba)  n->parent = res; return freeze_node(res); }
591c0c1997-01-19Fredrik Hübinette (Hubbe) void resolv_constant(node *n) { struct identifier *i;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  struct program *p; INT32 numid;
3c0c281998-01-26Fredrik Hübinette (Hubbe)  check_tree(n,0);
591c0c1997-01-19Fredrik Hübinette (Hubbe)  if(!n) { push_int(0); }else{ switch(n->token) { case F_CONSTANT: push_svalue(& n->u.sval);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  return;
591c0c1997-01-19Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case F_EXTERNAL:
5d642e2003-08-03Martin Stjernholm  if (n->u.integer.b == IDREF_MAGIC_THIS) { yyerror ("Expected constant, got reference to this"); push_int (0); return; }
ff88db2000-07-12Henrik Grubbström (Grubba) 
5d642e2003-08-03Martin Stjernholm  else { struct program_state *state = Pike_compiler;
ff88db2000-07-12Henrik Grubbström (Grubba)  while (state && (state->new_program->id != n->u.integer.a)) { state = state->previous; } if(!state) {
8dc0e92001-12-13Martin Stjernholm  yyerror("Failed to resolve external constant");
ff88db2000-07-12Henrik Grubbström (Grubba)  push_int(0); return; } p = state->new_program; numid=n->u.integer.b;
591c0c1997-01-19Fredrik Hübinette (Hubbe)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  break; case F_IDENTIFIER:
bad5162000-06-23Fredrik Hübinette (Hubbe)  p=Pike_compiler->new_program;
046afe1999-11-11Henrik Grubbström (Grubba)  numid=n->u.id.number;
591c0c1997-01-19Fredrik Hübinette (Hubbe)  break; case F_LOCAL:
9250a61998-07-20Henrik Grubbström (Grubba)  /* FIXME: Ought to have the name of the identifier in the message. */
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  yyerror("Expected constant, got local variable"); push_int(0); return;
591c0c1997-01-19Fredrik Hübinette (Hubbe)  case F_GLOBAL:
9250a61998-07-20Henrik Grubbström (Grubba)  /* FIXME: Ought to have the name of the identifier in the message. */
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  yyerror("Expected constant, got global variable"); push_int(0); return;
b69ede1998-04-09Fredrik Hübinette (Hubbe)  case F_UNDEFINED:
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->compiler_pass==2) {
9250a61998-07-20Henrik Grubbström (Grubba)  /* FIXME: Ought to have the name of the identifier in the message. */
b69ede1998-04-09Fredrik Hübinette (Hubbe)  yyerror("Expected constant, got undefined identifier");
9250a61998-07-20Henrik Grubbström (Grubba)  }
b69ede1998-04-09Fredrik Hübinette (Hubbe)  push_int(0); return;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  default:
c5c2ff1999-07-06Fredrik Hübinette (Hubbe)  { if(is_const(n)) {
9f85c32002-10-25Marcus Comstedt  ptrdiff_t args=eval_low(n,1);
c5c2ff1999-07-06Fredrik Hübinette (Hubbe)  if(args==1) return; if(args!=-1) { if(!args) { yyerror("Expected constant, got void expression"); }else{
a4a1722000-12-05Per Hedbor  yyerror("Possible internal error!!!");
93b7202000-08-14Henrik Grubbström (Grubba)  pop_n_elems(DO_NOT_WARN(args-1));
c5c2ff1999-07-06Fredrik Hübinette (Hubbe)  return; } } }
ce060e2004-06-30Martin Nilsson  my_yyerror("Expected constant, got something else (%d)",n->token);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  push_int(0); return; }
c5c2ff1999-07-06Fredrik Hübinette (Hubbe)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  i=ID_FROM_INT(p, numid);
086acc1999-09-11Fredrik Hübinette (Hubbe)  /* Warning: * This code doesn't produce function pointers for class constants, * which can be harmful... * /Hubbe */
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(IDENTIFIER_IS_CONSTANT(i->identifier_flags)) {
e945ee2000-02-09Fredrik Hübinette (Hubbe)  if(i->func.offset != -1) { push_svalue(&PROG_FROM_INT(p, numid)->constants[i->func.offset].sval); }else{
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->compiler_pass!=1)
e945ee2000-02-09Fredrik Hübinette (Hubbe)  yyerror("Constant is not defined yet."); push_int(0); }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }else{
ce060e2004-06-30Martin Nilsson  my_yyerror("Identifier %S is not a constant", i->name);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  push_int(0);
591c0c1997-01-19Fredrik Hübinette (Hubbe)  } } }
086acc1999-09-11Fredrik Hübinette (Hubbe) /* Leaves a function or object on the stack */ void resolv_class(node *n)
61e9a01998-01-25Fredrik Hübinette (Hubbe) {
3c0c281998-01-26Fredrik Hübinette (Hubbe)  check_tree(n,0);
61e9a01998-01-25Fredrik Hübinette (Hubbe)  resolv_constant(n);
cd86322000-07-06Fredrik Hübinette (Hubbe)  switch(Pike_sp[-1].type)
61e9a01998-01-25Fredrik Hübinette (Hubbe)  { case T_OBJECT:
cd86322000-07-06Fredrik Hübinette (Hubbe)  if(!Pike_sp[-1].u.object->prog)
61e9a01998-01-25Fredrik Hübinette (Hubbe)  { pop_stack(); push_int(0); }else{ f_object_program(1); } break;
01a9572000-02-03Henrik Grubbström (Grubba) 
086acc1999-09-11Fredrik Hübinette (Hubbe)  default:
bad5162000-06-23Fredrik Hübinette (Hubbe)  if (Pike_compiler->compiler_pass!=1)
a786431999-11-18Martin Stjernholm  yyerror("Illegal program identifier");
086acc1999-09-11Fredrik Hübinette (Hubbe)  pop_stack(); push_int(0); case T_FUNCTION: case T_PROGRAM: break; } } /* This one always leaves a program if possible */ void resolv_program(node *n) { check_tree(n,0); resolv_class(n);
cd86322000-07-06Fredrik Hübinette (Hubbe)  switch(Pike_sp[-1].type)
086acc1999-09-11Fredrik Hübinette (Hubbe)  {
61e9a01998-01-25Fredrik Hübinette (Hubbe)  case T_FUNCTION:
cd86322000-07-06Fredrik Hübinette (Hubbe)  if(program_from_function(Pike_sp-1))
61e9a01998-01-25Fredrik Hübinette (Hubbe)  break; default:
bad5162000-06-23Fredrik Hübinette (Hubbe)  if (Pike_compiler->compiler_pass!=1)
a786431999-11-18Martin Stjernholm  yyerror("Illegal program identifier");
61e9a01998-01-25Fredrik Hübinette (Hubbe)  pop_stack(); push_int(0); case T_PROGRAM: break; } }
fae37d1998-08-30Henrik Grubbström (Grubba) node *index_node(node *n, char *node_name, struct pike_string *id)
591c0c1997-01-19Fredrik Hübinette (Hubbe) { node *ret; JMP_BUF tmp;
3c0c281998-01-26Fredrik Hübinette (Hubbe)  check_tree(n,0);
591c0c1997-01-19Fredrik Hübinette (Hubbe)  if(SETJMP(tmp)) {
fae37d1998-08-30Henrik Grubbström (Grubba)  if (node_name) {
37dd922003-11-14Martin Stjernholm  handle_compile_exception ("Couldn't index module '%s'.", node_name);
fae37d1998-08-30Henrik Grubbström (Grubba)  } else {
37dd922003-11-14Martin Stjernholm  handle_compile_exception ("Couldn't index module.");
fae37d1998-08-30Henrik Grubbström (Grubba)  }
591c0c1997-01-19Fredrik Hübinette (Hubbe)  }else{ resolv_constant(n);
cd86322000-07-06Fredrik Hübinette (Hubbe)  switch(Pike_sp[-1].type)
d6aef21997-02-27Fredrik Hübinette (Hubbe)  {
1470d81997-02-27Fredrik Hübinette (Hubbe)  case T_INT:
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(!Pike_compiler->num_parse_error) {
fae37d1998-08-30Henrik Grubbström (Grubba)  if (node_name) {
ce060e2004-06-30Martin Nilsson  my_yyerror("Failed to index module \"%s\" with %S "
16addb1999-12-10Henrik Grubbström (Grubba)  "(module doesn't exist?)",
ce060e2004-06-30Martin Nilsson  node_name, id);
fae37d1998-08-30Henrik Grubbström (Grubba)  } else {
ce060e2004-06-30Martin Nilsson  my_yyerror("Failed to index module with %S "
16addb1999-12-10Henrik Grubbström (Grubba)  "(module doesn't exist?)",
ce060e2004-06-30Martin Nilsson  id);
fae37d1998-08-30Henrik Grubbström (Grubba)  } }
1470d81997-02-27Fredrik Hübinette (Hubbe)  break; case T_FLOAT: case T_STRING: case T_ARRAY:
fae37d1998-08-30Henrik Grubbström (Grubba)  if (node_name) { my_yyerror("Failed to index module '%s' (Not a module?)", node_name); } else { yyerror("Failed to index module (Not a module?)"); }
e319bb1997-02-28Fredrik Hübinette (Hubbe)  pop_stack(); push_int(0);
1470d81997-02-27Fredrik Hübinette (Hubbe)  break;
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  case T_OBJECT: case T_PROGRAM:
c914bd2003-03-09Henrik Grubbström (Grubba)  if(!(Pike_compiler->new_program->flags & PROGRAM_PASS_1_DONE))
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  { struct program *p; if(Pike_sp[-1].type == T_OBJECT) p=Pike_sp[-1].u.object->prog; else p=Pike_sp[-1].u.program;
a6ceda2003-03-08Henrik Grubbström (Grubba) 
c914bd2003-03-09Henrik Grubbström (Grubba)  if(p && !(p->flags & PROGRAM_PASS_1_DONE))
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  {
c914bd2003-03-09Henrik Grubbström (Grubba)  if(report_compiler_dependency(p))
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  {
c914bd2003-03-09Henrik Grubbström (Grubba)  pop_stack();
e82a872002-03-04Martin Stjernholm #if 0
19e3192003-03-27Martin Stjernholm  fprintf(stderr, "Placeholder deployed for %p when indexing ", p); print_tree(n); fprintf(stderr, "with %s\n", id->str);
e82a872002-03-04Martin Stjernholm #endif
c914bd2003-03-09Henrik Grubbström (Grubba)  ref_push_object(placeholder_object); break;
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  } } }
1470d81997-02-27Fredrik Hübinette (Hubbe)  default:
63c6751998-04-09Fredrik Hübinette (Hubbe)  {
93b7202000-08-14Henrik Grubbström (Grubba)  ptrdiff_t c;
63c6751998-04-09Fredrik Hübinette (Hubbe)  DECLARE_CYCLIC();
d2361e2003-06-30Martin Stjernholm  c = PTR_TO_INT(BEGIN_CYCLIC(Pike_sp[-1].u.refs, id));
14bb592000-05-06Fredrik Hübinette (Hubbe)  if(c>1)
7485201997-02-27Fredrik Hübinette (Hubbe)  {
ce060e2004-06-30Martin Nilsson  my_yyerror("Recursive module dependency in %S.", id);
63c6751998-04-09Fredrik Hübinette (Hubbe)  pop_stack(); push_int(0); }else{
766bc82004-10-16Marcus Agehall  volatile int exception = 0;
14bb592000-05-06Fredrik Hübinette (Hubbe)  SET_CYCLIC_RET(c+1);
63c6751998-04-09Fredrik Hübinette (Hubbe)  ref_push_string(id);
a70ee01999-05-01Henrik Grubbström (Grubba)  { JMP_BUF recovery;
3601d32002-11-23Martin Stjernholm  STACK_LEVEL_START(2); if (SETJMP_SP(recovery, 2)) {
37dd922003-11-14Martin Stjernholm  if (node_name) { handle_compile_exception ("Error looking up '%s' in module '%s'.", id->str, node_name); } else { handle_compile_exception ("Error looking up '%s' in module.", id->str); }
89af492001-08-16Martin Stjernholm  push_undefined();
37dd922003-11-14Martin Stjernholm  exception = 1;
a70ee01999-05-01Henrik Grubbström (Grubba)  } else { f_index(2); }
3601d32002-11-23Martin Stjernholm  STACK_LEVEL_DONE(1);
cc20e31999-05-01Henrik Grubbström (Grubba)  UNSETJMP(recovery);
a70ee01999-05-01Henrik Grubbström (Grubba)  }
63c6751998-04-09Fredrik Hübinette (Hubbe) 
cd86322000-07-06Fredrik Hübinette (Hubbe)  if(Pike_sp[-1].type == T_INT && !Pike_sp[-1].u.integer && Pike_sp[-1].subtype==NUMBER_UNDEFINED)
63c6751998-04-09Fredrik Hübinette (Hubbe)  {
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  if(Pike_compiler->new_program->flags & PROGRAM_PASS_1_DONE) {
37dd922003-11-14Martin Stjernholm  if (!exception) { if (node_name) {
ce060e2004-06-30Martin Nilsson  my_yyerror("Index %S not present in module \"%s\".", id, node_name);
37dd922003-11-14Martin Stjernholm  } else {
ce060e2004-06-30Martin Nilsson  my_yyerror("Index %S not present in module.", id);
37dd922003-11-14Martin Stjernholm  }
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  }
cd2be32004-03-13Henrik Grubbström (Grubba)  }else if (!(Pike_compiler->flags & COMPILATION_FORCE_RESOLVE)) {
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  /* Hope it's there in pass 2 */
89af492001-08-16Martin Stjernholm  pop_stack();
e82a872002-03-04Martin Stjernholm #if 0 fprintf(stderr, "Placeholder deployed when indexing "); print_tree(n); fprintf(stderr, "with %s\n", id->str); #endif
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  ref_push_object(placeholder_object);
89af492001-08-16Martin Stjernholm  }
63c6751998-04-09Fredrik Hübinette (Hubbe)  }
bd537b2002-12-10Martin Stjernholm  else if ((Pike_compiler->new_program->flags & PROGRAM_PASS_1_DONE) && ((Pike_sp[-1].type == T_OBJECT && Pike_sp[-1].u.object == placeholder_object) || (Pike_sp[-1].type == T_PROGRAM && Pike_sp[-1].u.program == placeholder_program)) && /* Ugly special case: We must be able to get * predef::__placeholder_object. */ (!node_name || strcmp (node_name, "predef"))) { if (node_name) my_yyerror("Got placeholder %s (resolver problem) "
ce060e2004-06-30Martin Nilsson  "when indexing module \"%s\" with %S.",
bd537b2002-12-10Martin Stjernholm  get_name_of_type (Pike_sp[-1].type),
ce060e2004-06-30Martin Nilsson  node_name, id);
bd537b2002-12-10Martin Stjernholm  else my_yyerror("Got placeholder %s (resolver problem) "
ce060e2004-06-30Martin Nilsson  "when indexing a module with %S.",
bd537b2002-12-10Martin Stjernholm  get_name_of_type (Pike_sp[-1].type),
ce060e2004-06-30Martin Nilsson  id);
bd537b2002-12-10Martin Stjernholm  }
7485201997-02-27Fredrik Hübinette (Hubbe)  }
14bb592000-05-06Fredrik Hübinette (Hubbe)  END_CYCLIC();
d6aef21997-02-27Fredrik Hübinette (Hubbe)  }
63c6751998-04-09Fredrik Hübinette (Hubbe)  }
591c0c1997-01-19Fredrik Hübinette (Hubbe)  } UNSETJMP(tmp);
cd86322000-07-06Fredrik Hübinette (Hubbe)  ret=mkconstantsvaluenode(Pike_sp-1);
591c0c1997-01-19Fredrik Hübinette (Hubbe)  pop_stack(); return ret; }
889d232000-09-12Henrik Grubbström (Grubba) /* FIXME: Ought to use parent pointer to avoid recursion. */
5267b71995-08-09Fredrik Hübinette (Hubbe) int node_is_eq(node *a,node *b) {
3c0c281998-01-26Fredrik Hübinette (Hubbe)  check_tree(a,0); check_tree(b,0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(a == b) return 1; if(!a || !b) return 0; if(a->token != b->token) return 0;
aee2d32000-09-12Henrik Grubbström (Grubba)  fatal_check_c_stack(16384);
5267b71995-08-09Fredrik Hübinette (Hubbe)  switch(a->token) {
8c70ba2001-09-28Fredrik Hübinette (Hubbe)  case F_TRAMPOLINE: /* FIXME, the context has to be the same! */ #ifdef SHARED_NODES if(a->u.trampoline.prog != b->u.trampoline.prog) return 0; #endif return a->u.trampoline.ident == b->u.trampoline.ident && a->u.trampoline.frame == b->u.trampoline.frame;
4e77462001-06-07Fredrik Hübinette (Hubbe)  case F_EXTERNAL:
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_LOCAL:
7d7d7e1999-01-31Fredrik Hübinette (Hubbe)  return a->u.integer.a == b->u.integer.a && a->u.integer.b == b->u.integer.b;
4218011999-01-31Fredrik Hübinette (Hubbe) 
afa3651996-02-10Fredrik Hübinette (Hubbe)  case F_IDENTIFIER:
046afe1999-11-11Henrik Grubbström (Grubba)  return a->u.id.number == b->u.id.number;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_CAST:
84191b1999-11-23Henrik Grubbström (Grubba)  case F_SOFT_CAST:
5267b71995-08-09Fredrik Hübinette (Hubbe)  return a->type == b->type && node_is_eq(CAR(a), CAR(b)); case F_CONSTANT: return is_equal(&(a->u.sval), &(b->u.sval)); default: if( a->type != b->type ) return 0; if(car_is_node(a) && !node_is_eq(CAR(a), CAR(b))) return 0; if(cdr_is_node(a) && !node_is_eq(CDR(a), CDR(b))) return 0; return 1; } }
d68a072001-02-20Henrik Grubbström (Grubba) node *debug_mktypenode(struct pike_type *t)
0592971999-12-15Henrik Grubbström (Grubba) { node *res = mkemptynode(); res->token = F_CONSTANT;
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(res->u.sval.u.type, t);
0592971999-12-15Henrik Grubbström (Grubba)  res->u.sval.type = T_TYPE;
be6fec2001-04-01Henrik Grubbström (Grubba)  /* FIXME: Should be type(val) */ copy_pike_type(res->type, type_type_string);
0592971999-12-15Henrik Grubbström (Grubba)  return freeze_node(res); }
71bde82001-03-16Fredrik Hübinette (Hubbe) node *low_mkconstantsvaluenode(struct svalue *s)
5267b71995-08-09Fredrik Hübinette (Hubbe) { node *res = mkemptynode(); res->token = F_CONSTANT; assign_svalue_no_free(& res->u.sval, s);
0f5ee72002-11-18Martin Stjernholm #ifdef SHARED_NODES
f73a402002-11-19Martin Stjernholm  if (s->type != T_INT && s->type != T_FUNCTION)
0f5ee72002-11-18Martin Stjernholm  /* The subtype is part of the hash, so make sure it got a defined * value here. */ res->u.sval.subtype = 0; #endif
046afe1999-11-11Henrik Grubbström (Grubba)  if(s->type == T_OBJECT || (s->type==T_FUNCTION && s->subtype!=FUNCTION_BUILTIN))
e82b301997-01-29Fredrik Hübinette (Hubbe)  {
f3c7152001-04-14Fredrik Hübinette (Hubbe)  if(!(s->u.object->prog && (s->u.object->prog->flags & PROGRAM_CONSTANT))) res->node_info|=OPT_EXTERNAL_DEPEND;
e82b301997-01-29Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  res->type = get_type_of_svalue(s);
71bde82001-03-16Fredrik Hübinette (Hubbe)  return res; } node *debug_mkconstantsvaluenode(struct svalue *s) { return freeze_node(low_mkconstantsvaluenode(s));
5267b71995-08-09Fredrik Hübinette (Hubbe) }
a836c01999-11-12Henrik Grubbström (Grubba) node *debug_mkliteralsvaluenode(struct svalue *s)
5683de1995-11-06Fredrik Hübinette (Hubbe) {
71bde82001-03-16Fredrik Hübinette (Hubbe)  node *res = low_mkconstantsvaluenode(s);
5683de1995-11-06Fredrik Hübinette (Hubbe)  if(s->type!=T_STRING && s->type!=T_INT && s->type!=T_FLOAT) res->node_info|=OPT_EXTERNAL_DEPEND;
71bde82001-03-16Fredrik Hübinette (Hubbe)  return freeze_node(res);
5683de1995-11-06Fredrik Hübinette (Hubbe) }
a836c01999-11-12Henrik Grubbström (Grubba) node *debug_mksvaluenode(struct svalue *s)
5267b71995-08-09Fredrik Hübinette (Hubbe) { switch(s->type) { case T_ARRAY: return make_node_from_array(s->u.array);
06983f1996-09-22Fredrik Hübinette (Hubbe)  case T_MULTISET: return make_node_from_multiset(s->u.multiset);
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_MAPPING: return make_node_from_mapping(s->u.mapping); case T_OBJECT:
f6b1172002-12-09Martin Stjernholm #ifdef PIKE_DEBUG if (s->u.object->prog == placeholder_program && Pike_compiler->compiler_pass == 2) Pike_fatal("Got placeholder object in second pass.\n"); #endif
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(s->u.object == Pike_compiler->fake_object)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { return mkefuncallnode("this_object", 0);
6d22541998-01-28Fredrik Hübinette (Hubbe)  } if(s->u.object->next == s->u.object) { int x=0; node *n=mkefuncallnode("this_object", 0);
f3c7152001-04-14Fredrik Hübinette (Hubbe) #ifndef PARENT_INFO struct object *o;
bad5162000-06-23Fredrik Hübinette (Hubbe)  for(o=Pike_compiler->fake_object;o!=s->u.object;o=o->parent)
6d22541998-01-28Fredrik Hübinette (Hubbe)  { n=mkefuncallnode("function_object", mkefuncallnode("object_program",n)); }
f3c7152001-04-14Fredrik Hübinette (Hubbe) #else struct program_state *state=Pike_compiler;; for(;state->fake_object!=s->u.object;state=state->previous) {
22d7992001-06-23Fredrik Hübinette (Hubbe)  state->new_program->flags |= PROGRAM_USES_PARENT | PROGRAM_NEEDS_PARENT;
f3c7152001-04-14Fredrik Hübinette (Hubbe)  n=mkefuncallnode("function_object", mkefuncallnode("object_program",n)); } #endif
6d22541998-01-28Fredrik Hübinette (Hubbe)  return n;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } break; case T_FUNCTION: {
bdb5091996-09-25Fredrik Hübinette (Hubbe)  if(s->subtype != FUNCTION_BUILTIN)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(s->u.object == Pike_compiler->fake_object)
5267b71995-08-09Fredrik Hübinette (Hubbe)  return mkidentifiernode(s->subtype);
6d22541998-01-28Fredrik Hübinette (Hubbe)  if(s->u.object->next == s->u.object) {
ff88db2000-07-12Henrik Grubbström (Grubba)  return mkexternalnode(s->u.object->prog, s->subtype);
6d22541998-01-28Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe) /* yyerror("Non-constant function pointer! (should not happen!)"); */ } } } return mkconstantsvaluenode(s); } /* these routines operates on parsetrees and are mostly used by the * optimizer */
046afe1999-11-11Henrik Grubbström (Grubba) 
889d232000-09-12Henrik Grubbström (Grubba) /* FIXME: Ought to use parent pointer to avoid recursion. * In the SHARED_NODES case there's no need of course. */
5267b71995-08-09Fredrik Hübinette (Hubbe) node *copy_node(node *n) { node *b;
a566ca1999-12-14Fredrik Hübinette (Hubbe)  debug_malloc_touch(n); debug_malloc_touch(n->type); debug_malloc_touch(n->u.node.a); debug_malloc_touch(n->u.node.b);
3c0c281998-01-26Fredrik Hübinette (Hubbe)  check_tree(n,0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!n) return n; switch(n->token) { case F_LOCAL:
06983f1996-09-22Fredrik Hübinette (Hubbe)  case F_IDENTIFIER:
4218011999-01-31Fredrik Hübinette (Hubbe)  case F_TRAMPOLINE:
046afe1999-11-11Henrik Grubbström (Grubba)  b=mknewintnode(0);
07f5432001-02-21Henrik Grubbström (Grubba)  if(b->type) free_type(b->type);
5267b71995-08-09Fredrik Hübinette (Hubbe)  *b=*n;
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(b->type, n->type);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return b;
046afe1999-11-11Henrik Grubbström (Grubba)  default: #ifdef SHARED_NODES
50ea682003-03-14Henrik Grubbström (Grubba)  add_ref(n);
046afe1999-11-11Henrik Grubbström (Grubba)  return n; #else /* !SHARED_NODES */
5267b71995-08-09Fredrik Hübinette (Hubbe) 
aee2d32000-09-12Henrik Grubbström (Grubba)  fatal_check_c_stack(16384);
71bde82001-03-16Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  switch((car_is_node(n) << 1) | cdr_is_node(n)) {
5aad932002-08-15Marcus Comstedt  default: Pike_fatal("fooo?\n");
5267b71995-08-09Fredrik Hübinette (Hubbe)  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)
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(b->type, n->type);
5267b71995-08-09Fredrik Hübinette (Hubbe)  else b->type=0;
a566ca1999-12-14Fredrik Hübinette (Hubbe)  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:
71bde82001-03-16Fredrik Hübinette (Hubbe)  b=mkconstantsvaluenode(&(n->u.sval));
a566ca1999-12-14Fredrik Hübinette (Hubbe)  break;
046afe1999-11-11Henrik Grubbström (Grubba) #endif /* SHARED_NODES */
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
43fc171999-09-19Fredrik Hübinette (Hubbe)  if(n->name) { if(b->name) free_string(b->name); add_ref(b->name=n->name); }
48bd9c1999-09-22Henrik Grubbström (Grubba)  /* FIXME: Should b->name be kept if n->name is NULL? * /grubba 1999-09-22 */
5267b71995-08-09Fredrik Hübinette (Hubbe)  b->line_number = n->line_number; b->node_info = n->node_info; b->tree_info = n->tree_info; return b; }
71bde82001-03-16Fredrik Hübinette (Hubbe) /* * 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;
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(b->type, n->type);
71bde82001-03-16Fredrik Hübinette (Hubbe)  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)
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(b->type, n->type);
71bde82001-03-16Fredrik Hübinette (Hubbe)  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)
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(b->type, n->type);
71bde82001-03-16Fredrik Hübinette (Hubbe)  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
046afe1999-11-11Henrik Grubbström (Grubba) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  int is_const(node *n) {
05533f1997-02-06Fredrik Hübinette (Hubbe)  if(!n) return 1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  return !(n->tree_info & (OPT_SIDE_EFFECT | OPT_NOT_CONST | OPT_ASSIGNMENT | OPT_CASE | OPT_CONTINUE | OPT_BREAK | OPT_RETURN )); } int node_is_tossable(node *n) { return !(n->tree_info & (OPT_SIDE_EFFECT | OPT_ASSIGNMENT | OPT_CASE | OPT_CONTINUE | OPT_BREAK | OPT_RETURN )); } /* this one supposes that the value is optimized */ int node_is_true(node *n) { if(!n) return 0; switch(n->token) {
9f516a2001-12-16Martin Stjernholm  case F_CONSTANT: return !SAFE_IS_ZERO(& n->u.sval);
5267b71995-08-09Fredrik Hübinette (Hubbe)  default: return 0; } } /* this one supposes that the value is optimized */ int node_is_false(node *n) { if(!n) return 0; switch(n->token) {
9f516a2001-12-16Martin Stjernholm  case F_CONSTANT: return SAFE_IS_ZERO(& n->u.sval);
5267b71995-08-09Fredrik Hübinette (Hubbe)  default: return 0; } }
cc5e511998-06-05Fredrik Hübinette (Hubbe) int node_may_overload(node *n, int lfun) { if(!n) return 0; if(!n->type) return 1;
7daa182001-02-23Henrik Grubbström (Grubba)  return type_may_overload(n->type, lfun);
cc5e511998-06-05Fredrik Hübinette (Hubbe) }
09667e2000-09-12Henrik Grubbström (Grubba) /* FIXME: Ought to use parent pointer to avoid recursion. */
6930181996-02-25Fredrik Hübinette (Hubbe) node **last_cmd(node **a)
5267b71995-08-09Fredrik Hübinette (Hubbe) { node **n; if(!a || !*a) return (node **)NULL;
aee2d32000-09-12Henrik Grubbström (Grubba)  fatal_check_c_stack(16384);
2a8cd81999-11-18Henrik Grubbström (Grubba)  if(((*a)->token == F_CAST) ||
84191b1999-11-23Henrik Grubbström (Grubba)  ((*a)->token == F_SOFT_CAST) ||
2a8cd81999-11-18Henrik Grubbström (Grubba)  ((*a)->token == F_POP_VALUE)) return last_cmd(&_CAR(*a));
920d201999-11-06Henrik Grubbström (Grubba)  if(((*a)->token != F_ARG_LIST) && ((*a)->token != F_COMMA_EXPR)) return a;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(CDR(*a)) {
2a8cd81999-11-18Henrik Grubbström (Grubba)  if(CDR(*a)->token != F_CAST &&
84191b1999-11-23Henrik Grubbström (Grubba)  CDR(*a)->token != F_SOFT_CAST &&
2a8cd81999-11-18Henrik Grubbström (Grubba)  CDR(*a)->token != F_POP_VALUE &&
4b2e0c2000-09-12Henrik Grubbström (Grubba)  CDR(*a)->token != F_ARG_LIST && CDR(*a)->token != F_COMMA_EXPR)
046afe1999-11-11Henrik Grubbström (Grubba)  return &_CDR(*a); if((n=last_cmd(&_CDR(*a))))
5267b71995-08-09Fredrik Hübinette (Hubbe)  return n; } if(CAR(*a)) {
2a8cd81999-11-18Henrik Grubbström (Grubba)  if(CAR(*a)->token != F_CAST &&
84191b1999-11-23Henrik Grubbström (Grubba)  CAR(*a)->token != F_SOFT_CAST &&
2a8cd81999-11-18Henrik Grubbström (Grubba)  CAR(*a)->token != F_POP_VALUE && CAR(*a)->token != F_ARG_LIST &&
920d201999-11-06Henrik Grubbström (Grubba)  CAR(*a)->token != F_COMMA_EXPR)
046afe1999-11-11Henrik Grubbström (Grubba)  return &_CAR(*a); if((n=last_cmd(&_CAR(*a))))
5267b71995-08-09Fredrik Hübinette (Hubbe)  return n; } return 0; }
889d232000-09-12Henrik Grubbström (Grubba) /* FIXME: Ought to use parent pointer to avoid recursion. */
5267b71995-08-09Fredrik Hübinette (Hubbe) static node **low_get_arg(node **a,int *nr) { node **n;
8db95f2000-03-13Henrik Grubbström (Grubba)  if (!a[0]) return NULL;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(a[0]->token != F_ARG_LIST) { if(!(*nr)--) return a; else return NULL; }
aee2d32000-09-12Henrik Grubbström (Grubba)  fatal_check_c_stack(16384);
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(CAR(*a))
046afe1999-11-11Henrik Grubbström (Grubba)  if((n=low_get_arg(&_CAR(*a),nr)))
5267b71995-08-09Fredrik Hübinette (Hubbe)  return n; if(CDR(*a))
046afe1999-11-11Henrik Grubbström (Grubba)  if((n=low_get_arg(&_CDR(*a),nr)))
5267b71995-08-09Fredrik Hübinette (Hubbe)  return n; return 0; }
6930181996-02-25Fredrik Hübinette (Hubbe) node **my_get_arg(node **a,int n) { return low_get_arg(a,&n); }
cc5e511998-06-05Fredrik Hübinette (Hubbe)  node **is_call_to(node *n, c_fun f) { switch(n->token) {
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  case F_AUTO_MAP:
cc5e511998-06-05Fredrik Hübinette (Hubbe)  case F_APPLY: if(CAR(n) && CAR(n)->token == F_CONSTANT && CAR(n)->u.sval.type == T_FUNCTION && CAR(n)->u.sval.subtype == FUNCTION_BUILTIN && CAR(n)->u.sval.u.efun->function == f)
046afe1999-11-11Henrik Grubbström (Grubba)  return &_CDR(n);
cc5e511998-06-05Fredrik Hübinette (Hubbe)  } return 0; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
889d232000-09-12Henrik Grubbström (Grubba) /* FIXME: Ought to use parent pointer to avoid recursion. */
5267b71995-08-09Fredrik Hübinette (Hubbe) static void low_print_tree(node *foo,int needlval) { if(!foo) return;
32e2af1998-11-17Fredrik Hübinette (Hubbe)  if(l_flag>9)
5219721998-11-06Fredrik Hübinette (Hubbe)  {
046afe1999-11-11Henrik Grubbström (Grubba)  fprintf(stderr, "/*%x*/",foo->tree_info);
5219721998-11-06Fredrik Hübinette (Hubbe)  }
aee2d32000-09-12Henrik Grubbström (Grubba)  fatal_check_c_stack(16384);
2e91222000-03-30Fredrik Hübinette (Hubbe)  switch(l_flag > 99 ? -1 : foo->token)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
046afe1999-11-11Henrik Grubbström (Grubba)  case USHRT_MAX:
fa74242004-07-06Martin Nilsson  fputs("FREED_NODE", stderr);
046afe1999-11-11Henrik Grubbström (Grubba)  break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_LOCAL:
046afe1999-11-11Henrik Grubbström (Grubba)  if(needlval) fputc('&', stderr);
4218011999-01-31Fredrik Hübinette (Hubbe)  if(foo->u.integer.b) {
046afe1999-11-11Henrik Grubbström (Grubba)  fprintf(stderr, "$<%ld>%ld",(long)foo->u.integer.b,(long)foo->u.integer.a);
4218011999-01-31Fredrik Hübinette (Hubbe)  }else{
046afe1999-11-11Henrik Grubbström (Grubba)  fprintf(stderr, "$%ld",(long)foo->u.integer.a);
4218011999-01-31Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; case '?':
fa74242004-07-06Martin Nilsson  fputc('(', stderr);
046afe1999-11-11Henrik Grubbström (Grubba)  low_print_tree(_CAR(foo),0);
fa74242004-07-06Martin Nilsson  fputs(")?(", stderr);
a836c01999-11-12Henrik Grubbström (Grubba)  if (_CDR(foo)) { low_print_tree(_CADR(foo),0);
fa74242004-07-06Martin Nilsson  fputs("):(", stderr);
a836c01999-11-12Henrik Grubbström (Grubba)  low_print_tree(_CDDR(foo),0); } else {
fa74242004-07-06Martin Nilsson  fputs("0:0", stderr);
a836c01999-11-12Henrik Grubbström (Grubba)  }
fa74242004-07-06Martin Nilsson  fputc(')', stderr);
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; case F_IDENTIFIER:
046afe1999-11-11Henrik Grubbström (Grubba)  if(needlval) fputc('&', stderr);
bad5162000-06-23Fredrik Hübinette (Hubbe)  if (Pike_compiler->new_program) {
d6dbb42002-05-12Martin Stjernholm  fprintf(stderr, "id(%s)",ID_FROM_INT(Pike_compiler->new_program, foo->u.id.number)->name->str);
046afe1999-11-11Henrik Grubbström (Grubba)  } else {
fa74242004-07-06Martin Nilsson  fputs("unknown identifier", stderr);
046afe1999-11-11Henrik Grubbström (Grubba)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
d1ae4f2000-08-27Henrik Grubbström (Grubba)  case F_EXTERNAL: if(needlval) fputc('&', stderr); { struct program_state *state = Pike_compiler;
d6dbb42002-05-12Martin Stjernholm  char *name = "?";
d1ae4f2000-08-27Henrik Grubbström (Grubba)  int program_id = foo->u.integer.a;
d6dbb42002-05-12Martin Stjernholm  int level = 0;
5d642e2003-08-03Martin Stjernholm  int id_no = foo->u.integer.b;
d1ae4f2000-08-27Henrik Grubbström (Grubba)  while(state && (state->new_program->id != program_id)) { state = state->previous;
d6dbb42002-05-12Martin Stjernholm  level++;
d1ae4f2000-08-27Henrik Grubbström (Grubba)  }
5d642e2003-08-03Martin Stjernholm  if (id_no == IDREF_MAGIC_THIS) name = "this"; else if (state) {
d1ae4f2000-08-27Henrik Grubbström (Grubba)  struct identifier *id = ID_FROM_INT(state->new_program, id_no); if (id && id->name) { name = id->name->str; } }
d6dbb42002-05-12Martin Stjernholm  fprintf(stderr, "ext(%d:%s)", level, name);
d1ae4f2000-08-27Henrik Grubbström (Grubba)  } break;
4218011999-01-31Fredrik Hübinette (Hubbe)  case F_TRAMPOLINE:
bad5162000-06-23Fredrik Hübinette (Hubbe)  if (Pike_compiler->new_program) {
046afe1999-11-11Henrik Grubbström (Grubba)  fprintf(stderr, "trampoline<%s>",
8c70ba2001-09-28Fredrik Hübinette (Hubbe)  ID_FROM_INT(Pike_compiler->new_program, foo->u.trampoline.ident)->name->str);
046afe1999-11-11Henrik Grubbström (Grubba)  } else {
fa74242004-07-06Martin Nilsson  fputs("trampoline<unknown identifier>", stderr);
046afe1999-11-11Henrik Grubbström (Grubba)  }
4218011999-01-31Fredrik Hübinette (Hubbe)  break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_ASSIGN:
046afe1999-11-11Henrik Grubbström (Grubba)  low_print_tree(_CDR(foo),1);
fa74242004-07-06Martin Nilsson  fputc('=', stderr);
046afe1999-11-11Henrik Grubbström (Grubba)  low_print_tree(_CAR(foo),0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
2a8cd81999-11-18Henrik Grubbström (Grubba)  case F_POP_VALUE:
fa74242004-07-06Martin Nilsson  fputc('{', stderr);
2a8cd81999-11-18Henrik Grubbström (Grubba)  low_print_tree(_CAR(foo), 0);
fa74242004-07-06Martin Nilsson  fputc('}', stderr);
2a8cd81999-11-18Henrik Grubbström (Grubba)  break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_CAST: {
9fa0ee2003-11-09Martin Stjernholm  dynamic_buffer save_buf;
5267b71995-08-09Fredrik Hübinette (Hubbe)  char *s;
9fa0ee2003-11-09Martin Stjernholm  init_buf(&save_buf);
3496412001-02-25Henrik Grubbström (Grubba)  my_describe_type(foo->type);
9fa0ee2003-11-09Martin Stjernholm  s=simple_free_buf(&save_buf);
046afe1999-11-11Henrik Grubbström (Grubba)  fprintf(stderr, "(%s){",s);
5267b71995-08-09Fredrik Hübinette (Hubbe)  free(s);
046afe1999-11-11Henrik Grubbström (Grubba)  low_print_tree(_CAR(foo),0);
fa74242004-07-06Martin Nilsson  fputc('}', stderr);
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; }
84191b1999-11-23Henrik Grubbström (Grubba)  case F_SOFT_CAST: {
9fa0ee2003-11-09Martin Stjernholm  dynamic_buffer save_buf;
84191b1999-11-23Henrik Grubbström (Grubba)  char *s;
9fa0ee2003-11-09Martin Stjernholm  init_buf(&save_buf);
3496412001-02-25Henrik Grubbström (Grubba)  my_describe_type(foo->type);
9fa0ee2003-11-09Martin Stjernholm  s=simple_free_buf(&save_buf);
84191b1999-11-23Henrik Grubbström (Grubba)  fprintf(stderr, "[%s]{",s); free(s); low_print_tree(_CAR(foo),0);
fa74242004-07-06Martin Nilsson  fputc('}', stderr);
84191b1999-11-23Henrik Grubbström (Grubba)  break; }
920d201999-11-06Henrik Grubbström (Grubba)  case F_COMMA_EXPR:
a2196f1999-11-21Henrik Grubbström (Grubba)  low_print_tree(_CAR(foo),0); if(_CAR(foo) && _CDR(foo)) { if(_CAR(foo)->type == void_type_string && _CDR(foo)->type == void_type_string)
fa74242004-07-06Martin Nilsson  fputs(";\n", stderr);
a2196f1999-11-21Henrik Grubbström (Grubba)  else
fa74242004-07-06Martin Nilsson  fputs(",\n", stderr);
a2196f1999-11-21Henrik Grubbström (Grubba)  } low_print_tree(_CDR(foo),needlval); return;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_ARG_LIST:
046afe1999-11-11Henrik Grubbström (Grubba)  low_print_tree(_CAR(foo),0); if(_CAR(foo) && _CDR(foo))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
046afe1999-11-11Henrik Grubbström (Grubba)  if(_CAR(foo)->type == void_type_string && _CDR(foo)->type == void_type_string)
fa74242004-07-06Martin Nilsson  fputs(";\n", stderr);
5267b71995-08-09Fredrik Hübinette (Hubbe)  else
046afe1999-11-11Henrik Grubbström (Grubba)  fputc(',', stderr);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
046afe1999-11-11Henrik Grubbström (Grubba)  low_print_tree(_CDR(foo),needlval);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return;
2a32691998-01-31Fredrik Hübinette (Hubbe)  case F_ARRAY_LVALUE:
046afe1999-11-11Henrik Grubbström (Grubba)  fputc('[', stderr); low_print_tree(_CAR(foo),1); fputc(']', stderr);
2a32691998-01-31Fredrik Hübinette (Hubbe)  break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_LVALUE_LIST:
046afe1999-11-11Henrik Grubbström (Grubba)  low_print_tree(_CAR(foo),1); if(_CAR(foo) && _CDR(foo)) fputc(',', stderr); low_print_tree(_CDR(foo),1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return; case F_CONSTANT: {
9fa0ee2003-11-09Martin Stjernholm  dynamic_buffer save_buf;
5267b71995-08-09Fredrik Hübinette (Hubbe)  char *s;
9fa0ee2003-11-09Martin Stjernholm  init_buf(&save_buf);
5267b71995-08-09Fredrik Hübinette (Hubbe)  describe_svalue(& foo->u.sval, 0, 0);
9fa0ee2003-11-09Martin Stjernholm  s=simple_free_buf(&save_buf);
d6dbb42002-05-12Martin Stjernholm  fprintf(stderr, "const(%s)",s);
5267b71995-08-09Fredrik Hübinette (Hubbe)  free(s); break; } case F_VAL_LVAL:
046afe1999-11-11Henrik Grubbström (Grubba)  low_print_tree(_CAR(foo),0);
fa74242004-07-06Martin Nilsson  fputs(",&", stderr);
046afe1999-11-11Henrik Grubbström (Grubba)  low_print_tree(_CDR(foo),0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return;
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  case F_AUTO_MAP:
fa74242004-07-06Martin Nilsson  fputs("__automap__ ", stderr);
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  low_print_tree(_CAR(foo),0);
fa74242004-07-06Martin Nilsson  fputc('(', stderr);
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  low_print_tree(_CDR(foo),0);
fa74242004-07-06Martin Nilsson  fputc(')', stderr);
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  return; case F_AUTO_MAP_MARKER: low_print_tree(_CAR(foo),0);
fa74242004-07-06Martin Nilsson  fputs("[*]", stderr);
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  return;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_APPLY:
046afe1999-11-11Henrik Grubbström (Grubba)  low_print_tree(_CAR(foo),0);
fa74242004-07-06Martin Nilsson  fputc('(', stderr);
046afe1999-11-11Henrik Grubbström (Grubba)  low_print_tree(_CDR(foo),0);
fa74242004-07-06Martin Nilsson  fputc(')', stderr);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return;
ca34ce2001-01-12Martin Stjernholm  case F_NORMAL_STMT_LABEL: case F_CUSTOM_STMT_LABEL: fprintf(stderr, "%s:", _CAR(foo)->u.sval.u.string->str); low_print_tree(_CDR(foo),0); return;
226e1a2001-03-20Henrik Grubbström (Grubba)  case F_LOOP:
fa74242004-07-06Martin Nilsson  fputs("loop(", stderr);
226e1a2001-03-20Henrik Grubbström (Grubba)  if(car_is_node(foo)) low_print_tree(_CAR(foo),0);
fa74242004-07-06Martin Nilsson  fputs(",{", stderr);
226e1a2001-03-20Henrik Grubbström (Grubba)  if(cdr_is_node(foo)) low_print_tree(_CDR(foo),0);
fa74242004-07-06Martin Nilsson  fputs("})", stderr);
226e1a2001-03-20Henrik Grubbström (Grubba)  return;
5267b71995-08-09Fredrik Hübinette (Hubbe)  default: if(!car_is_node(foo) && !cdr_is_node(foo)) {
fa74242004-07-06Martin Nilsson  fputs(get_token_name(foo->token), stderr);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return; } if(foo->token<256) {
fa74242004-07-06Martin Nilsson  fputc(foo->token, stderr);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }else{
fa74242004-07-06Martin Nilsson  fputs(get_token_name(foo->token), stderr);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
fa74242004-07-06Martin Nilsson  fputc('(', stderr);
046afe1999-11-11Henrik Grubbström (Grubba)  if(car_is_node(foo)) low_print_tree(_CAR(foo),0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(car_is_node(foo) && cdr_is_node(foo))
046afe1999-11-11Henrik Grubbström (Grubba)  fputc(',', stderr); if(cdr_is_node(foo)) low_print_tree(_CDR(foo),0);
fa74242004-07-06Martin Nilsson  fputc(')', stderr);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return; } } void print_tree(node *n) {
3c0c281998-01-26Fredrik Hübinette (Hubbe)  check_tree(n,0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  low_print_tree(n,0);
fa74242004-07-06Martin Nilsson  fputc('\n', stderr);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
2ee5cb2000-08-27Henrik Grubbström (Grubba) /* The following routines need much better commenting. */ /* They also needed to support lexical scoping and external variables.
e674e72000-08-27Henrik Grubbström (Grubba)  * /grubba 2000-08-27 */
30ff0e2000-08-28Henrik Grubbström (Grubba) /* * Known bugs: * * Aliasing is not handled. * * Called functions are assumed not to use lexical scoping. */
e674e72000-08-27Henrik Grubbström (Grubba) #if MAX_LOCAL > MAX_GLOBAL #define MAX_VAR MAX_LOCAL #else /* MAX_LOCAL <= MAX_GLOBAL */ #define MAX_VAR MAX_GLOBAL #endif /* MAX_LOCAL > MAX_GLOBAL */
2ee5cb2000-08-27Henrik Grubbström (Grubba) /* FIXME: Should perhaps use BLOCK_ALLOC for struct scope_info? */
e674e72000-08-27Henrik Grubbström (Grubba) struct scope_info { struct scope_info *next; int scope_id; char vars[MAX_VAR]; };
5267b71995-08-09Fredrik Hübinette (Hubbe) struct used_vars {
e82b301997-01-29Fredrik Hübinette (Hubbe)  int err;
e674e72000-08-27Henrik Grubbström (Grubba)  int ext_flags;
2ee5cb2000-08-27Henrik Grubbström (Grubba)  /* Note that the locals and externals linked lists are sorted on scope_id. */ struct scope_info *locals; /* Lexical scopes. scope_id == depth */ struct scope_info *externals; /* External scopes. scope_id == program_id */
5267b71995-08-09Fredrik Hübinette (Hubbe) }; #define VAR_BLOCKED 0 #define VAR_UNUSED 1 #define VAR_USED 3
2ee5cb2000-08-27Henrik Grubbström (Grubba) /* FIXME: Shouldn't the following two functions be named "*_or_vars"? */ /* Perform a merge into a. * Note that b is freed. */
e674e72000-08-27Henrik Grubbström (Grubba) static void low_and_vars(struct scope_info **a, struct scope_info *b) { while (*a && b) { if ((*a)->scope_id < b->scope_id) { a = &((*a)->next); } else if ((*a)->scope_id > b->scope_id) { struct scope_info *tmp = *a; *a = b; b = b->next; (*a)->next = tmp; } else { struct scope_info *tmp = b; int e; for (e = 0; e < MAX_VAR; e++) { (*a)->vars[e] |= b->vars[e]; } a = &((*a)->next); b = b->next; free(tmp); } } if (!*a) { *a = b; } } /* NOTE: The second argument will be freed. */
5267b71995-08-09Fredrik Hübinette (Hubbe) static void do_and_vars(struct used_vars *a,struct used_vars *b) {
e674e72000-08-27Henrik Grubbström (Grubba)  low_and_vars(&(a->locals), b->locals); low_and_vars(&(a->externals), b->externals); a->err |= b->err; a->ext_flags |= b->ext_flags; free(b);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
2ee5cb2000-08-27Henrik Grubbström (Grubba) /* Makes a copy of a. * Note: Can throw errors on out of memory. */
5267b71995-08-09Fredrik Hübinette (Hubbe) static struct used_vars *copy_vars(struct used_vars *a) { struct used_vars *ret;
e674e72000-08-27Henrik Grubbström (Grubba)  struct scope_info *src; struct scope_info **dst;
5267b71995-08-09Fredrik Hübinette (Hubbe)  ret=(struct used_vars *)xalloc(sizeof(struct used_vars));
e674e72000-08-27Henrik Grubbström (Grubba)  src = a->locals; dst = &(ret->locals); *dst = NULL; while (src) { *dst = malloc(sizeof(struct scope_info)); if (!*dst) { src = ret->locals; while(src) { struct scope_info *tmp = src->next; free(src); src = tmp; } free(ret);
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Out of memory in copy_vars.\n");
e674e72000-08-27Henrik Grubbström (Grubba)  return NULL; /* Make sure that the optimizer knows we exit here. */ } MEMCPY(*dst, src, sizeof(struct scope_info));
e3131f2000-08-27Henrik Grubbström (Grubba)  src = src->next;
e674e72000-08-27Henrik Grubbström (Grubba)  dst = &((*dst)->next); *dst = NULL; } src = a->externals; dst = &(ret->externals); *dst = NULL; while (src) { *dst = malloc(sizeof(struct scope_info)); if (!*dst) { src = ret->locals; while(src) { struct scope_info *tmp = src->next; free(src); src = tmp; } src = ret->externals; while(src) { struct scope_info *tmp = src->next; free(src); src = tmp; } free(ret);
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Out of memory in copy_vars.\n");
e674e72000-08-27Henrik Grubbström (Grubba)  return NULL; /* Make sure that the optimizer knows we exit here. */ } MEMCPY(*dst, src, sizeof(struct scope_info));
e3131f2000-08-27Henrik Grubbström (Grubba)  src = src->next;
e674e72000-08-27Henrik Grubbström (Grubba)  dst = &((*dst)->next); *dst = NULL; } ret->err = a->err; ret->ext_flags = a->ext_flags;
5267b71995-08-09Fredrik Hübinette (Hubbe)  return ret; }
2ee5cb2000-08-27Henrik Grubbström (Grubba) /* Find the insertion point for the variable a:scope_id:num. * Allocates a new scope if needed. * Can throw errors on out of memory. */
e674e72000-08-27Henrik Grubbström (Grubba) char *find_q(struct scope_info **a, int num, int scope_id) { struct scope_info *new; #ifdef PIKE_DEBUG if (l_flag > 3) { fprintf(stderr, "find_q %d:%d\n", scope_id, num); } #endif /* PIKE_DEBUG */ while (*a && ((*a)->scope_id < scope_id)) { a = &((*a)->next); } if ((*a) && ((*a)->scope_id == scope_id)) { #ifdef PIKE_DEBUG if (l_flag > 4) {
fa74242004-07-06Martin Nilsson  fputs("scope found.\n", stderr);
e674e72000-08-27Henrik Grubbström (Grubba)  } #endif /* PIKE_DEBUG */ return (*a)->vars + num; } #ifdef PIKE_DEBUG if (l_flag > 4) {
fa74242004-07-06Martin Nilsson  fputs("Creating new scope.\n", stderr);
e674e72000-08-27Henrik Grubbström (Grubba)  } #endif /* PIKE_DEBUG */ new = (struct scope_info *)xalloc(sizeof(struct scope_info)); MEMSET(new, VAR_UNUSED, sizeof(struct scope_info)); new->next = *a; new->scope_id = scope_id; *a = new; return new->vars + num; }
889d232000-09-12Henrik Grubbström (Grubba) /* FIXME: Ought to use parent pointer to avoid recursion. */
2ee5cb2000-08-27Henrik Grubbström (Grubba) /* Find the variables that are used in the tree n. */
9d91c72002-12-25Henrik Grubbström (Grubba) /* noblock: Don't mark unused variables that are written to as blocked. * overwrite: n is an lvalue that is overwritten. */
5267b71995-08-09Fredrik Hübinette (Hubbe) static int find_used_variables(node *n, struct used_vars *p, int noblock, int overwrite) { struct used_vars *a; char *q; if(!n) return 0;
aee2d32000-09-12Henrik Grubbström (Grubba)  fatal_check_c_stack(16384);
5267b71995-08-09Fredrik Hübinette (Hubbe)  switch(n->token) { case F_LOCAL:
e674e72000-08-27Henrik Grubbström (Grubba)  q = find_q(&(p->locals), n->u.integer.a, n->u.integer.b); #ifdef PIKE_DEBUG if (l_flag > 2) { fprintf(stderr, "local %d:%d is ", n->u.integer.b, n->u.integer.a); } #endif /* PIKE_DEBUG */ goto set_pointer; case F_EXTERNAL: q = find_q(&(p->externals), n->u.integer.b, n->u.integer.a); #ifdef PIKE_DEBUG if (l_flag > 2) { fprintf(stderr, "external %d:%d is ", n->u.integer.a, n->u.integer.b); } #endif /* PIKE_DEBUG */
5267b71995-08-09Fredrik Hübinette (Hubbe)  goto set_pointer; case F_IDENTIFIER:
e674e72000-08-27Henrik Grubbström (Grubba)  q = find_q(&(p->externals), n->u.id.number, Pike_compiler->new_program->id);
046afe1999-11-11Henrik Grubbström (Grubba)  if(n->u.id.number > MAX_GLOBAL)
e82b301997-01-29Fredrik Hübinette (Hubbe)  { p->err=1; return 0; }
e674e72000-08-27Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG if (l_flag > 2) { fprintf(stderr, "external %d:%d is ", Pike_compiler->new_program->id, n->u.id.number); } #endif /* PIKE_DEBUG */
5267b71995-08-09Fredrik Hübinette (Hubbe)  set_pointer: if(overwrite) {
e674e72000-08-27Henrik Grubbström (Grubba)  if(*q == VAR_UNUSED && !noblock) { *q = VAR_BLOCKED; #ifdef PIKE_DEBUG if (l_flag > 2) {
fa74242004-07-06Martin Nilsson  fputs("blocked\n", stderr);
e674e72000-08-27Henrik Grubbström (Grubba)  } } else { if (l_flag > 2) {
fa74242004-07-06Martin Nilsson  fputs("overwritten\n", stderr);
e674e72000-08-27Henrik Grubbström (Grubba)  } #endif /* PIKE_DEBUG */ }
5267b71995-08-09Fredrik Hübinette (Hubbe)  } else {
e674e72000-08-27Henrik Grubbström (Grubba)  if(*q == VAR_UNUSED) { *q = VAR_USED; #ifdef PIKE_DEBUG if (l_flag > 2) {
fa74242004-07-06Martin Nilsson  fputs("used\n", stderr);
e674e72000-08-27Henrik Grubbström (Grubba)  } } else { if (l_flag > 2) {
fa74242004-07-06Martin Nilsson  fputs("kept\n", stderr);
e674e72000-08-27Henrik Grubbström (Grubba)  } #endif /* PIKE_DEBUG */ }
5267b71995-08-09Fredrik Hübinette (Hubbe)  } break;
4aac102002-12-20Henrik Grubbström (Grubba)  case F_ARROW: case F_INDEX:
9d91c72002-12-25Henrik Grubbström (Grubba) #ifdef PARANOID_INDEXING /* Be paranoid, and assume aliasing. */
ed369b2002-12-20Henrik Grubbström (Grubba)  p->ext_flags = VAR_USED;
9d91c72002-12-25Henrik Grubbström (Grubba) #endif /* PARANOID_INDEXING */
4aac102002-12-20Henrik Grubbström (Grubba)  if(car_is_node(n)) find_used_variables(CAR(n),p,noblock,0); if(cdr_is_node(n)) find_used_variables(CDR(n),p,noblock,0); break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_ASSIGN: find_used_variables(CAR(n),p,noblock,0); find_used_variables(CDR(n),p,noblock,1); break; case '?': find_used_variables(CAR(n),p,noblock,0); a=copy_vars(p); find_used_variables(CADR(n),a,noblock,0); find_used_variables(CDDR(n),p,noblock,0);
e674e72000-08-27Henrik Grubbström (Grubba)  do_and_vars(p, a);
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; case F_INC_NEQ_LOOP: case F_DEC_NEQ_LOOP: case F_INC_LOOP: case F_DEC_LOOP:
7daa182001-02-23Henrik Grubbström (Grubba)  case F_LOOP:
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_FOREACH: case F_FOR: find_used_variables(CAR(n),p,noblock,0); a=copy_vars(p); find_used_variables(CDR(n),a,noblock,0);
e674e72000-08-27Henrik Grubbström (Grubba)  do_and_vars(p, a);
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; case F_SWITCH: find_used_variables(CAR(n),p,noblock,0); a=copy_vars(p); find_used_variables(CDR(n),a,1,0);
e674e72000-08-27Henrik Grubbström (Grubba)  do_and_vars(p, a);
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; case F_DO: a=copy_vars(p); find_used_variables(CAR(n),a,noblock,0);
e674e72000-08-27Henrik Grubbström (Grubba)  do_and_vars(p, a);
5267b71995-08-09Fredrik Hübinette (Hubbe)  find_used_variables(CDR(n),p,noblock,0); break; default: if(car_is_node(n)) find_used_variables(CAR(n),p,noblock,0); if(cdr_is_node(n)) find_used_variables(CDR(n),p,noblock,0); } return 0; }
889d232000-09-12Henrik Grubbström (Grubba) /* FIXME: Ought to use parent pointer to avoid recursion. */
5267b71995-08-09Fredrik Hübinette (Hubbe) /* no subtility needed */ static void find_written_vars(node *n, struct used_vars *p, int lvalue) { if(!n) return;
aee2d32000-09-12Henrik Grubbström (Grubba)  fatal_check_c_stack(16384);
5267b71995-08-09Fredrik Hübinette (Hubbe)  switch(n->token) { case F_LOCAL:
e674e72000-08-27Henrik Grubbström (Grubba)  if(lvalue) { #ifdef PIKE_DEBUG if (l_flag > 2) { fprintf(stderr, "local %d:%d is written\n", n->u.integer.b, n->u.integer.a); } #endif /* PIKE_DEBUG */ *find_q(&(p->locals), n->u.integer.a, n->u.integer.b) = VAR_USED; } break; case F_EXTERNAL: if(lvalue) { #ifdef PIKE_DEBUG if (l_flag > 2) { fprintf(stderr, "external %d:%d is written\n", n->u.integer.a, n->u.integer.b); } #endif /* PIKE_DEBUG */ *find_q(&(p->externals), n->u.integer.b, n->u.integer.a) = VAR_USED; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
587a7c1998-08-05Fredrik Hübinette (Hubbe)  case F_IDENTIFIER:
e674e72000-08-27Henrik Grubbström (Grubba)  if(lvalue) { if(n->u.id.number >= MAX_VAR) { p->err=1; return; } #ifdef PIKE_DEBUG if (l_flag > 2) { fprintf(stderr, "external %d:%d is written\n", Pike_compiler->new_program->id, n->u.id.number); } #endif /* PIKE_DEBUG */ *find_q(&(p->externals), n->u.id.number, Pike_compiler->new_program->id) = VAR_USED; }
e82b301997-01-29Fredrik Hübinette (Hubbe)  break; case F_APPLY:
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  case F_AUTO_MAP:
e674e72000-08-27Henrik Grubbström (Grubba)  if(n->tree_info & OPT_SIDE_EFFECT) { p->ext_flags = VAR_USED; }
fa88962003-03-20Henrik Grubbström (Grubba)  find_written_vars(CAR(n), p, 0); find_written_vars(CDR(n), p, 0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  case F_AUTO_MAP_MARKER: find_written_vars(CAR(n), p, lvalue); break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_INDEX:
dffa011997-01-15Fredrik Hübinette (Hubbe)  case F_ARROW:
9d91c72002-12-25Henrik Grubbström (Grubba) #ifdef PARANOID_INDEXING /* Be paranoid and assume aliasing. */
4aac102002-12-20Henrik Grubbström (Grubba)  if (lvalue) p->ext_flags = VAR_USED; find_written_vars(CAR(n), p, 0);
9d91c72002-12-25Henrik Grubbström (Grubba) #else /* !PARAONID_INDEXING */ /* Propagate the change to the indexed value. * Note: This is sensitive to aliasing effects. */ find_written_vars(CAR(n), p, lvalue); #endif /* PARANOID_INDEXING */
5267b71995-08-09Fredrik Hübinette (Hubbe)  find_written_vars(CDR(n), p, 0); break;
9d91c72002-12-25Henrik Grubbström (Grubba)  case F_SOFT_CAST: find_written_vars(CAR(n), p, lvalue); break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_INC: case F_DEC: case F_POST_INC: case F_POST_DEC: find_written_vars(CAR(n), p, 1); break; case F_ASSIGN: find_written_vars(CAR(n), p, 0); find_written_vars(CDR(n), p, 1); break;
5219721998-11-06Fredrik Hübinette (Hubbe)  case F_AND_EQ: case F_OR_EQ: case F_XOR_EQ: case F_LSH_EQ: case F_RSH_EQ: case F_ADD_EQ: case F_SUB_EQ: case F_MULT_EQ: case F_MOD_EQ: case F_DIV_EQ: find_written_vars(CAR(n), p, 1); find_written_vars(CDR(n), p, 0); break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_SSCANF: find_written_vars(CAR(n), p, 0);
408db92003-03-20Henrik Grubbström (Grubba)  /* FIXME: Marks arg 2 as written for now. */
5267b71995-08-09Fredrik Hübinette (Hubbe)  find_written_vars(CDR(n), p, 1); break;
2a32691998-01-31Fredrik Hübinette (Hubbe)  case F_ARRAY_LVALUE: find_written_vars(CAR(n), p, 1); break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_LVALUE_LIST: find_written_vars(CAR(n), p, 1); find_written_vars(CDR(n), p, 1); break; case F_VAL_LVAL: find_written_vars(CAR(n), p, 0); find_written_vars(CDR(n), p, 1); break; default: if(car_is_node(n)) find_written_vars(CAR(n), p, 0); if(cdr_is_node(n)) find_written_vars(CDR(n), p, 0); } }
e674e72000-08-27Henrik Grubbström (Grubba) void free_vars(struct used_vars *a) { struct scope_info *tmp; tmp = a->locals; while(tmp) { struct scope_info *next = tmp->next; free(tmp); tmp = next; } tmp = a->externals; while(tmp) { struct scope_info *next = tmp->next; free(tmp); tmp = next; } }
5267b71995-08-09Fredrik Hübinette (Hubbe) /* return 1 if A depends on B */
e674e72000-08-27Henrik Grubbström (Grubba) static int depend_p2(node *a, node *b)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
e674e72000-08-27Henrik Grubbström (Grubba)  struct used_vars aa, bb;
5267b71995-08-09Fredrik Hübinette (Hubbe)  int e;
e674e72000-08-27Henrik Grubbström (Grubba)  ONERROR free_aa; ONERROR free_bb;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!a || !b || is_const(a)) return 0;
e674e72000-08-27Henrik Grubbström (Grubba)  aa.err = 0; bb.err = 0; aa.ext_flags = 0; bb.ext_flags = 0; aa.locals = NULL; bb.locals = NULL; aa.externals = NULL; bb.externals = NULL; SET_ONERROR(free_aa, free_vars, &aa); SET_ONERROR(free_bb, free_vars, &bb);
4aac102002-12-20Henrik Grubbström (Grubba)  /* A depends on B if A uses stuff that is written to by B. */
e674e72000-08-27Henrik Grubbström (Grubba)  find_used_variables(a, &aa, 0, 0); find_written_vars(b, &bb, 0);
fa88962003-03-20Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG if (l_flag > 2) { struct scope_info *aaa = aa.locals; while (aaa) {
fa74242004-07-06Martin Nilsson  fputs("Used locals:\n", stderr);
fa88962003-03-20Henrik Grubbström (Grubba)  for (e = 0; e < MAX_VAR; e++) { if (aaa->vars[e] == VAR_USED) { fprintf(stderr, "\t%d:%d\n", aaa->scope_id, e); } } aaa = aaa->next; } aaa = bb.locals; while (aaa) {
fa74242004-07-06Martin Nilsson  fputs("Written locals:\n", stderr);
fa88962003-03-20Henrik Grubbström (Grubba)  for (e = 0; e < MAX_VAR; e++) { if (aaa->vars[e] != VAR_UNUSED) { fprintf(stderr, "\t%d:%d\n", aaa->scope_id, e); } } aaa = aaa->next; } } #endif /* PIKE_DEBUG */
e674e72000-08-27Henrik Grubbström (Grubba)  UNSET_ONERROR(free_bb); UNSET_ONERROR(free_aa);
ed369b2002-12-20Henrik Grubbström (Grubba)  /* If there was an error or * If A has external dependencies due to indexing, we won't * investigate further. */ if(aa.err || bb.err || aa.ext_flags == VAR_USED) {
e674e72000-08-27Henrik Grubbström (Grubba)  free_vars(&aa); free_vars(&bb); return 1; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
4aac102002-12-20Henrik Grubbström (Grubba)  /* Check for overlap in locals. */
e674e72000-08-27Henrik Grubbström (Grubba)  { struct scope_info *aaa = aa.locals; struct scope_info *bbb = bb.locals;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
e674e72000-08-27Henrik Grubbström (Grubba)  while (aaa) { while (bbb && (bbb->scope_id < aaa->scope_id)) { bbb = bbb->next; } if (!bbb) break; if (bbb->scope_id == aaa->scope_id) { for (e = 0; e < MAX_VAR; e++) { if ((aaa->vars[e] == VAR_USED) && (bbb->vars[e] != VAR_UNUSED)) { free_vars(&aa); free_vars(&bb); return 1; } } } aaa = aaa->next; } } if (bb.ext_flags == VAR_USED) {
4aac102002-12-20Henrik Grubbström (Grubba)  /* B has side effects. * * A is dependant if A uses any externals at all. */
e674e72000-08-27Henrik Grubbström (Grubba)  /* No need to look closer at b */ struct scope_info *aaa = aa.externals;
e82b301997-01-29Fredrik Hübinette (Hubbe) 
e674e72000-08-27Henrik Grubbström (Grubba)  /* FIXME: Probably only needed to check if aaa is NULL or not. */
5267b71995-08-09Fredrik Hübinette (Hubbe) 
e674e72000-08-27Henrik Grubbström (Grubba)  while (aaa) { for (e = 0; e < MAX_VAR; e++) { if (aaa->vars[e] == VAR_USED) { free_vars(&aa); free_vars(&bb); return 1; } } aaa = aaa->next; } } else {
4aac102002-12-20Henrik Grubbström (Grubba)  /* Otherwise check for overlaps. */
e674e72000-08-27Henrik Grubbström (Grubba)  struct scope_info *aaa = aa.externals; struct scope_info *bbb = bb.externals; while (aaa) { while (bbb && (bbb->scope_id < aaa->scope_id)) { bbb = bbb->next; } if (!bbb) break; if (bbb->scope_id == aaa->scope_id) { for (e = 0; e < MAX_VAR; e++) { if ((aaa->vars[e] == VAR_USED) && (bbb->vars[e] != VAR_UNUSED)) { free_vars(&aa); free_vars(&bb); return 1; } } } aaa = aaa->next; } } free_vars(&aa); free_vars(&bb);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; }
5219721998-11-06Fredrik Hübinette (Hubbe) static int depend_p3(node *a,node *b)
5267b71995-08-09Fredrik Hübinette (Hubbe) { if(!b) return 0;
e82b301997-01-29Fredrik Hübinette (Hubbe) #if 0
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!(b->tree_info & OPT_SIDE_EFFECT) && (b->tree_info & OPT_EXTERNAL_DEPEND)) return 1;
e82b301997-01-29Fredrik Hübinette (Hubbe) #endif if((a->tree_info & OPT_EXTERNAL_DEPEND)) return 1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  return depend_p2(a,b); }
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
5219721998-11-06Fredrik Hübinette (Hubbe) static int depend_p(node *a,node *b) { int ret; if(l_flag > 3) {
fa74242004-07-06Martin Nilsson  fputs("Checking if: ", stderr);
5219721998-11-06Fredrik Hübinette (Hubbe)  print_tree(a);
fa74242004-07-06Martin Nilsson  fputs("Depends on: ", stderr);
5219721998-11-06Fredrik Hübinette (Hubbe)  print_tree(b); if(depend_p3(a,b)) {
fa74242004-07-06Martin Nilsson  fputs("The answer is (drumroll) : yes\n", stderr);
5219721998-11-06Fredrik Hübinette (Hubbe)  return 1; }else{
fa74242004-07-06Martin Nilsson  fputs("The answer is (drumroll) : no\n", stderr);
5219721998-11-06Fredrik Hübinette (Hubbe)  return 0; } } return depend_p3(a,b); } #else #define depend_p depend_p3 #endif
226e1a2001-03-20Henrik Grubbström (Grubba) /* Check if n depends on the lvalue lval */ static int depend2_p(node *n, node *lval) { node *tmp; int ret; /* Make a temporary node (lval = 0), so that we can use depend_p(). */ ADD_NODE_REF2(lval, tmp = mknode(F_ASSIGN, mkintnode(0), lval)); ret = depend_p(n, tmp); free_node(tmp); return ret; }
086acc1999-09-11Fredrik Hübinette (Hubbe) static int function_type_max=0;
889d232000-09-12Henrik Grubbström (Grubba) /* FIXME: Ought to use parent pointer to avoid recursion. */
5267b71995-08-09Fredrik Hübinette (Hubbe) static void low_build_function_type(node *n) { if(!n) return;
086acc1999-09-11Fredrik Hübinette (Hubbe)  if(function_type_max++ > 999) { reset_type_stack();
327c051999-11-24Fredrik Hübinette (Hubbe)  push_type(T_MIXED); push_type(T_VOID); push_type(T_OR); /* return type is void or mixed */
086acc1999-09-11Fredrik Hübinette (Hubbe)  push_type(T_MIXED);
327c051999-11-24Fredrik Hübinette (Hubbe)  push_type(T_VOID); push_type(T_OR); /* varargs */
086acc1999-09-11Fredrik Hübinette (Hubbe)  push_type(T_MANY); return; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  switch(n->token) {
920d201999-11-06Henrik Grubbström (Grubba)  case F_COMMA_EXPR:
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_ARG_LIST:
aee2d32000-09-12Henrik Grubbström (Grubba)  fatal_check_c_stack(16384);
5267b71995-08-09Fredrik Hübinette (Hubbe)  low_build_function_type(CDR(n)); low_build_function_type(CAR(n)); break;
1b49ef2002-05-23Henrik Grubbström (Grubba)  case F_PUSH_ARRAY: { struct pike_type *so_far; struct pike_type *arg_type; struct pike_type *tmp;
327c051999-11-24Fredrik Hübinette (Hubbe) 
1b49ef2002-05-23Henrik Grubbström (Grubba)  so_far = pop_type();
327c051999-11-24Fredrik Hübinette (Hubbe) 
1b49ef2002-05-23Henrik Grubbström (Grubba)  copy_pike_type(arg_type, void_type_string);
327c051999-11-24Fredrik Hübinette (Hubbe) 
1b49ef2002-05-23Henrik Grubbström (Grubba)  /* Convert fun(a,b,c...:d) to fun(a|b|c|void...:d) */ while(so_far->type == T_FUNCTION) { tmp = or_pike_types(arg_type, so_far->car, 1); free_type(arg_type); arg_type = tmp; copy_pike_type(tmp, so_far->cdr); free_type(so_far); so_far = tmp; } tmp = or_pike_types(arg_type, so_far->car, 1); free_type(arg_type); arg_type = tmp; push_finished_type(so_far->cdr); /* Return type */ free_type(so_far); so_far = index_type(CAR(n)->type, int_type_string, n); tmp = or_pike_types(arg_type, so_far, 1); push_finished_type(tmp); if (tmp == mixed_type_string) { /* Ensure "or void"... */ push_type(T_VOID); push_type(T_OR); } free_type(arg_type); free_type(so_far); free_type(tmp); push_type(T_MANY); }
5267b71995-08-09Fredrik Hübinette (Hubbe)  return; default: if(n->type) { if(n->type == void_type_string) return; push_finished_type(n->type); }else{ push_type(T_MIXED); }
dfed932001-03-03Henrik Grubbström (Grubba)  push_type(T_FUNCTION);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
d68a072001-02-20Henrik Grubbström (Grubba) void yytype_error(char *msg, struct pike_type *expected_t, struct pike_type *got_t, unsigned int flags)
edcd891999-12-23Henrik Grubbström (Grubba) {
03318e2000-03-16Fredrik Hübinette (Hubbe)  if (msg) { if (flags & YYTE_IS_WARNING)
edcd891999-12-23Henrik Grubbström (Grubba)  yywarning("%s", msg);
03318e2000-03-16Fredrik Hübinette (Hubbe)  else
2c448d2004-11-05Henrik Grubbström (Grubba)  yyerror(msg);
edcd891999-12-23Henrik Grubbström (Grubba)  }
03318e2000-03-16Fredrik Hübinette (Hubbe)  yyexplain_nonmatching_types(expected_t, got_t, flags);
edcd891999-12-23Henrik Grubbström (Grubba) }
5267b71995-08-09Fredrik Hübinette (Hubbe)  void fix_type_field(node *n) {
7daa182001-02-23Henrik Grubbström (Grubba)  struct pike_type *type_a, *type_b;
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *old_type;
f68afd1999-11-20Henrik Grubbström (Grubba)  if (n->type && !(n->node_info & OPT_TYPE_NOT_FIXED)) return; /* assume it is correct */
5267b71995-08-09Fredrik Hübinette (Hubbe) 
f68afd1999-11-20Henrik Grubbström (Grubba)  old_type = n->type; n->type = 0; n->node_info &= ~OPT_TYPE_NOT_FIXED;
5267b71995-08-09Fredrik Hübinette (Hubbe)  switch(n->token) {
1d480f1999-11-23Henrik Grubbström (Grubba)  case F_SOFT_CAST: if (CAR(n) && CAR(n)->type) {
5986041999-12-21Henrik Grubbström (Grubba)  if (!check_soft_cast(old_type, CAR(n)->type)) {
1d480f1999-11-23Henrik Grubbström (Grubba)  struct pike_string *t1 = describe_type(old_type); struct pike_string *t2 = describe_type(CAR(n)->type);
ce060e2004-06-30Martin Nilsson  yywarning("Soft cast to %S isn't a restriction of %S.", t1, t2);
1d480f1999-11-23Henrik Grubbström (Grubba)  free_string(t2); free_string(t1); }
5986041999-12-21Henrik Grubbström (Grubba)  /* FIXME: check_soft_cast() is weaker than pike_types_le()
60a75b2002-06-07Martin Nilsson  * The resulting type should probably be the AND between the old
5986041999-12-21Henrik Grubbström (Grubba)  * and the new type. */
1d480f1999-11-23Henrik Grubbström (Grubba)  } /* FALL_THROUGH */
f68afd1999-11-20Henrik Grubbström (Grubba)  case F_CAST: /* Type-field is correct by definition. */
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, old_type);
f68afd1999-11-20Henrik Grubbström (Grubba)  break;
cb22561995-10-11Fredrik Hübinette (Hubbe)  case F_LAND: case F_LOR:
60ca281999-12-03Martin Stjernholm  if (!CAR(n) || CAR(n)->type == void_type_string) { yyerror("Conditional uses void expression.");
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, mixed_type_string);
8521291999-11-20Henrik Grubbström (Grubba)  break;
e9b1771999-11-18Henrik Grubbström (Grubba)  }
7daa182001-02-23Henrik Grubbström (Grubba)  if(!match_types(CAR(n)->type, mixed_type_string))
9a78b21999-11-18Henrik Grubbström (Grubba)  yyerror("Bad conditional expression.");
cb22561995-10-11Fredrik Hübinette (Hubbe) 
60ca281999-12-03Martin Stjernholm  if (!CDR(n) || CDR(n)->type == void_type_string)
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, void_type_string);
8886701999-12-05Martin Stjernholm  else if(n->token == F_LAND || CAR(n)->type == CDR(n)->type)
cb22561995-10-11Fredrik Hübinette (Hubbe)  {
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, CDR(n)->type);
cb22561995-10-11Fredrik Hübinette (Hubbe)  }else{
4d7b181999-12-07Fredrik Hübinette (Hubbe)  n->type = or_pike_types(CAR(n)->type, CDR(n)->type, 0);
cb22561995-10-11Fredrik Hübinette (Hubbe)  } break;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
da55f91996-05-03Fredrik Hübinette (Hubbe)  case F_ASSIGN:
e9b1771999-11-18Henrik Grubbström (Grubba)  if (!CAR(n) || (CAR(n)->type == void_type_string)) {
2c448d2004-11-05Henrik Grubbström (Grubba)  yyerror("Assigning a void expression.");
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, void_type_string);
e9b1771999-11-18Henrik Grubbström (Grubba)  break;
f68afd1999-11-20Henrik Grubbström (Grubba)  } else if(CAR(n) && CDR(n)) {
84191b1999-11-23Henrik Grubbström (Grubba)  /* Ensure that the type-fields are up to date. */
f68afd1999-11-20Henrik Grubbström (Grubba)  fix_type_field(CAR(n)); fix_type_field(CDR(n));
84191b1999-11-23Henrik Grubbström (Grubba)  if (!pike_types_le(CAR(n)->type, CDR(n)->type)) {
57fa292005-02-15Henrik Grubbström (Grubba)  /* a["b"]=c and a->b=c can be valid when a is an array. * * FIXME: Exactly what case is the problem? * /grubba 2005-02-15 */ if (((CDR(n)->token != F_INDEX && CDR(n)->token != F_ARROW) || !match_types(array_type_string, CADR(n)->type)) &&
84191b1999-11-23Henrik Grubbström (Grubba)  !match_types(CDR(n)->type,CAR(n)->type)) {
edcd891999-12-23Henrik Grubbström (Grubba)  yytype_error("Bad type in assignment.", CDR(n)->type, CAR(n)->type, 0);
84191b1999-11-23Henrik Grubbström (Grubba)  } else if (lex.pragmas & ID_STRICT_TYPES) { struct pike_string *t1 = describe_type(CAR(n)->type); struct pike_string *t2 = describe_type(CDR(n)->type);
49a0961999-11-24Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG if (l_flag > 0) {
fa74242004-07-06Martin Nilsson  fputs("Warning: Invalid assignment: ", stderr);
49a0961999-11-24Henrik Grubbström (Grubba)  print_tree(n); } #endif /* PIKE_DEBUG */
ce060e2004-06-30Martin Nilsson  yywarning("An expression type %S cannot be assigned to " "a variable of type %S.", t1, t2);
84191b1999-11-23Henrik Grubbström (Grubba)  free_string(t2); free_string(t1); }
f68afd1999-11-20Henrik Grubbström (Grubba)  }
e9b1771999-11-18Henrik Grubbström (Grubba)  }
f77d7e1999-11-21Henrik Grubbström (Grubba)  n->type = and_pike_types(CAR(n)->type, CDR(n)->type);
da55f91996-05-03Fredrik Hübinette (Hubbe)  break;
1276fa2002-06-03Henrik Grubbström (Grubba)  case F_ARRAY_LVALUE: { node *lval_list; if (!(lval_list = CAR(n))) { copy_pike_type(n->type, mixed_type_string); } else { struct pike_type *t; node *n2; if (lval_list->token == F_LVALUE_LIST) { n2 = CAR(lval_list); } else { n2 = lval_list; } if (n2) { copy_pike_type(t, n2->type); } else { copy_pike_type(t, zero_type_string); } while ((n2 != lval_list) && (lval_list = CDR(lval_list))) { if (lval_list->token == F_LVALUE_LIST) { n2 = CAR(lval_list); } else { n2 = lval_list; } if (n2) { struct pike_type *tmp = or_pike_types(t, n2->type, 1); free_type(t); t = tmp; } } type_stack_mark(); push_finished_type(t); push_type(T_ARRAY); free_type(t); n->type = pop_unfinished_type(); } } break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_INDEX:
dffa011997-01-15Fredrik Hübinette (Hubbe)  case F_ARROW:
e9b1771999-11-18Henrik Grubbström (Grubba)  if (!CAR(n) || (CAR(n)->type == void_type_string)) {
2c448d2004-11-05Henrik Grubbström (Grubba)  yyerror("Indexing a void expression.");
e9b1771999-11-18Henrik Grubbström (Grubba)  /* The optimizer converts this to an expression returning 0. */
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, zero_type_string);
e9b1771999-11-18Henrik Grubbström (Grubba)  } else { type_a=CAR(n)->type; type_b=CDR(n)->type; if(!check_indexing(type_a, type_b, n))
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(!Pike_compiler->catch_level)
2c448d2004-11-05Henrik Grubbström (Grubba)  yyerror("Indexing on illegal type.");
4d7b181999-12-07Fredrik Hübinette (Hubbe)  n->type=index_type(type_a, type_b,n);
e9b1771999-11-18Henrik Grubbström (Grubba)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
408a1e2004-10-30Martin Stjernholm  case F_RANGE: if (!CAR(n)) { /* Unlikely to occur, and if it does, it has probably * already been complained about. */ copy_pike_type(n->type, mixed_type_string); } else { node *low = CADR (n), *high = CDDR (n); n->type = range_type(CAR(n)->type, low->token == F_RANGE_OPEN ? NULL : CAR (low)->type, high->token == F_RANGE_OPEN ? NULL : CAR (high)->type);
73ff6a2002-05-15Henrik Grubbström (Grubba)  } break;
408a1e2004-10-30Martin Stjernholm 
6f1e962005-03-20Henrik Grubbström (Grubba)  case F_PUSH_ARRAY: if (CAR(n)) { struct pike_type *array_type; MAKE_CONSTANT_TYPE(array_type, tArr(tZero)); if (!pike_types_le(array_type, CAR(n)->type)) { yytype_error("Bad argument to splice operator.", array_type, CAR(n)->type, 0); }
3bb2452005-04-06Henrik Grubbström (Grubba)  free_type(array_type);
6f1e962005-03-20Henrik Grubbström (Grubba)  } /* FIXME: The type field of the splice operator is not yet utilized. * * It probably ought to be something similar to MANY(..., VOID). */ copy_pike_type(n->type, mixed_type_string); break;
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  case F_AUTO_MAP_MARKER: if (!CAR(n) || (CAR(n)->type == void_type_string)) {
2c448d2004-11-05Henrik Grubbström (Grubba)  yyerror("Indexing a void expression.");
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  /* The optimizer converts this to an expression returning 0. */ copy_pike_type(n->type, zero_type_string); } else { type_a=CAR(n)->type;
8c70ba2001-09-28Fredrik Hübinette (Hubbe)  if(!match_types(type_a, array_type_string))
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  if(!Pike_compiler->catch_level)
2c448d2004-11-05Henrik Grubbström (Grubba)  yyerror("[*] on non-array.");
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  n->type=index_type(type_a, int_type_string, n); } break; case F_AUTO_MAP:
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_APPLY:
e9b1771999-11-18Henrik Grubbström (Grubba)  if (!CAR(n) || (CAR(n)->type == void_type_string)) {
2c448d2004-11-05Henrik Grubbström (Grubba)  yyerror("Calling a void expression.");
e9b1771999-11-18Henrik Grubbström (Grubba)  } else {
335eb52001-03-28Henrik Grubbström (Grubba)  struct pike_type *f; /* Expected type. */ struct pike_type *s; /* Actual type */
2c448d2004-11-05Henrik Grubbström (Grubba)  struct pike_string *name = NULL; char *alternate_name;
f68afd1999-11-20Henrik Grubbström (Grubba)  INT32 max_args,args;
3913502002-06-25Henrik Grubbström (Grubba) #ifdef NEW_ARG_CHECK
335eb52001-03-28Henrik Grubbström (Grubba)  args = 0;
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(f, CAR(n)->type);
335eb52001-03-28Henrik Grubbström (Grubba)  f = new_check_call(CAR(n), &args, f, CDR(n)); if (f && (n->type = get_ret_type(f))) { /* Type/argument-check OK. */ free_type(f);
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  if(n->token == F_AUTO_MAP) { push_finished_type(n->type); push_type(T_ARRAY); free_type(n->type); n->type = pop_type(); }
335eb52001-03-28Henrik Grubbström (Grubba)  break; }
3913502002-06-25Henrik Grubbström (Grubba) #else /* !NEW_ARG_CHECK */
335eb52001-03-28Henrik Grubbström (Grubba) 
327c051999-11-24Fredrik Hübinette (Hubbe)  push_type(T_MIXED); /* match any return type */ push_type(T_VOID); /* even void */ push_type(T_OR);
f68afd1999-11-20Henrik Grubbström (Grubba)  push_type(T_VOID); /* not varargs */ push_type(T_MANY); function_type_max=0; low_build_function_type(CDR(n));
acb9de1999-11-20Henrik Grubbström (Grubba)  s = pop_type(); f = CAR(n)->type?CAR(n)->type:mixed_type_string;
13eb3e1999-12-29Henrik Grubbström (Grubba)  n->type = check_call(s, f, (lex.pragmas & ID_STRICT_TYPES) && !(n->node_info & OPT_WEAK_TYPE));
acb9de1999-11-20Henrik Grubbström (Grubba)  args = count_arguments(s); max_args = count_arguments(f); if(max_args<0) max_args = 0x7fffffff;
7704531999-11-20Henrik Grubbström (Grubba) 
acb9de1999-11-20Henrik Grubbström (Grubba)  if (n->type) { /* Type/argument-check OK. */
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(s);
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  if(n->token == F_AUTO_MAP) { push_finished_type(n->type); push_type(T_ARRAY); free_type(n->type); n->type = pop_type(); }
acb9de1999-11-20Henrik Grubbström (Grubba)  break; }
f68afd1999-11-20Henrik Grubbström (Grubba) 
1b49ef2002-05-23Henrik Grubbström (Grubba)  if (!pike_types_le(f, function_type_string)) { yytype_error("Calling non function value.", f, s, 0); copy_pike_type(n->type, mixed_type_string); /* print_tree(n); */ free_type(s); break; }
3856c31996-11-25Fredrik Hübinette (Hubbe)  switch(CAR(n)->token) {
4218011999-01-31Fredrik Hübinette (Hubbe) #if 0 /* FIXME */
f68afd1999-11-20Henrik Grubbström (Grubba)  case F_TRAMPOLINE:
4218011999-01-31Fredrik Hübinette (Hubbe) #endif
3856c31996-11-25Fredrik Hübinette (Hubbe)  case F_IDENTIFIER:
2c448d2004-11-05Henrik Grubbström (Grubba)  name=ID_FROM_INT(Pike_compiler->new_program, CAR(n)->u.id.number)->name;
3856c31996-11-25Fredrik Hübinette (Hubbe)  break;
a566ca1999-12-14Fredrik Hübinette (Hubbe)  case F_ARROW: case F_INDEX: if(CDAR(n)->token == F_CONSTANT && CDAR(n)->u.sval.type == T_STRING) {
2c448d2004-11-05Henrik Grubbström (Grubba)  name=CDAR(n)->u.sval.u.string;
a566ca1999-12-14Fredrik Hübinette (Hubbe)  }else{
2c448d2004-11-05Henrik Grubbström (Grubba)  alternate_name="dynamically resolved function";
a566ca1999-12-14Fredrik Hübinette (Hubbe)  } break;
3856c31996-11-25Fredrik Hübinette (Hubbe)  case F_CONSTANT:
0d3ea51998-01-19Fredrik Hübinette (Hubbe)  switch(CAR(n)->u.sval.type) {
f68afd1999-11-20Henrik Grubbström (Grubba)  case T_FUNCTION: if(CAR(n)->u.sval.subtype == FUNCTION_BUILTIN) {
2c448d2004-11-05Henrik Grubbström (Grubba)  name=CAR(n)->u.sval.u.efun->name;
f68afd1999-11-20Henrik Grubbström (Grubba)  }else{ name=ID_FROM_INT(CAR(n)->u.sval.u.object->prog,
2c448d2004-11-05Henrik Grubbström (Grubba)  CAR(n)->u.sval.subtype)->name;
f68afd1999-11-20Henrik Grubbström (Grubba)  } break;
0d3ea51998-01-19Fredrik Hübinette (Hubbe) 
f68afd1999-11-20Henrik Grubbström (Grubba)  case T_ARRAY:
2c448d2004-11-05Henrik Grubbström (Grubba)  alternate_name="array call";
f68afd1999-11-20Henrik Grubbström (Grubba)  break;
0d3ea51998-01-19Fredrik Hübinette (Hubbe) 
f68afd1999-11-20Henrik Grubbström (Grubba)  case T_PROGRAM:
2c448d2004-11-05Henrik Grubbström (Grubba)  alternate_name="clone call";
f68afd1999-11-20Henrik Grubbström (Grubba)  break;
0d3ea51998-01-19Fredrik Hübinette (Hubbe) 
f68afd1999-11-20Henrik Grubbström (Grubba)  default:
2c448d2004-11-05Henrik Grubbström (Grubba)  alternate_name="`() (function call)";
f68afd1999-11-20Henrik Grubbström (Grubba)  break;
0d3ea51998-01-19Fredrik Hübinette (Hubbe)  }
5b4dd31998-02-23Fredrik Hübinette (Hubbe)  break;
cbe8f32000-07-10Henrik Grubbström (Grubba)  case F_EXTERNAL: { int id_no = CAR(n)->u.integer.b;
ff88db2000-07-12Henrik Grubbström (Grubba) 
5d642e2003-08-03Martin Stjernholm  if (id_no == IDREF_MAGIC_THIS)
2c448d2004-11-05Henrik Grubbström (Grubba)  alternate_name = "this"; /* Should perhaps qualify it. */
ff88db2000-07-12Henrik Grubbström (Grubba) 
5d642e2003-08-03Martin Stjernholm  else { int program_id = CAR(n)->u.integer.a; struct program_state *state = Pike_compiler;
2c448d2004-11-05Henrik Grubbström (Grubba)  alternate_name="external symbol";
ff88db2000-07-12Henrik Grubbström (Grubba) 
5d642e2003-08-03Martin Stjernholm  while (state && (state->new_program->id != program_id)) { state = state->previous; } if (state) { struct identifier *id = ID_FROM_INT(state->new_program, id_no); if (id && id->name) {
a694802004-11-06Martin Nilsson  name = id->name;
f1bc3d2002-03-04Martin Stjernholm #if 0
01d4902000-07-11Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
5d642e2003-08-03Martin Stjernholm  /* FIXME: This test crashes on valid code because the type of the * identifier can change in pass 2 -Hubbe */ if(id->type != f) { printf("Type of external node is not matching it's identifier.\nid->type: "); simple_describe_type(id->type); printf("\nf : "); simple_describe_type(f); printf("\n"); Pike_fatal("Type of external node is not matching it's identifier.\n"); }
f1bc3d2002-03-04Martin Stjernholm #endif
01d4902000-07-11Fredrik Hübinette (Hubbe) #endif
5d642e2003-08-03Martin Stjernholm  }
cbe8f32000-07-10Henrik Grubbström (Grubba)  } } } break;
f68afd1999-11-20Henrik Grubbström (Grubba) 
3856c31996-11-25Fredrik Hübinette (Hubbe)  default:
2c448d2004-11-05Henrik Grubbström (Grubba)  alternate_name="unknown function";
b8cda21997-01-21Fredrik Hübinette (Hubbe)  }
5b4dd31998-02-23Fredrik Hübinette (Hubbe)  if(max_args < args) {
b8cd052000-09-26Fredrik Hübinette (Hubbe)  if(TEST_COMPAT(0,6)) {
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(s);
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, mixed_type_string);
b8cd052000-09-26Fredrik Hübinette (Hubbe)  break; }
2c448d2004-11-05Henrik Grubbström (Grubba)  if (name) { my_yyerror("Too many arguments to %S.", name); } else { my_yyerror("Too many arguments to %s.", alternate_name); }
5b4dd31998-02-23Fredrik Hübinette (Hubbe)  } else if(max_correct_args == args)
b8cda21997-01-21Fredrik Hübinette (Hubbe)  {
2c448d2004-11-05Henrik Grubbström (Grubba)  if (name) { my_yyerror("Too few arguments to %S.", name); } else { my_yyerror("Too few arguments to %s.", alternate_name); } } else if (name) { my_yyerror("Bad argument %d to %S.",
b8cda21997-01-21Fredrik Hübinette (Hubbe)  max_correct_args+1, name);
2c448d2004-11-05Henrik Grubbström (Grubba)  } else { my_yyerror("Bad argument %d to %s.", max_correct_args+1, alternate_name);
3856c31996-11-25Fredrik Hübinette (Hubbe)  }
93b07d1999-11-24Fredrik Hübinette (Hubbe) 
edcd891999-12-23Henrik Grubbström (Grubba)  yytype_error(NULL, f, s, 0);
cbe8f32000-07-10Henrik Grubbström (Grubba)  /* print_tree(n); */
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(s);
3913502002-06-25Henrik Grubbström (Grubba) #endif /* NEW_ARG_CHECK */
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, mixed_type_string);
cb22561995-10-11Fredrik Hübinette (Hubbe)  break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case '?':
e9b1771999-11-18Henrik Grubbström (Grubba)  if (!CAR(n) || (CAR(n)->type == void_type_string)) {
9a78b21999-11-18Henrik Grubbström (Grubba)  yyerror("Conditional expression is void.");
7daa182001-02-23Henrik Grubbström (Grubba)  } else if(!match_types(CAR(n)->type, mixed_type_string))
9a78b21999-11-18Henrik Grubbström (Grubba)  yyerror("Bad conditional expression.");
cb22561995-10-11Fredrik Hübinette (Hubbe) 
60ca281999-12-03Martin Stjernholm  if(!CDR(n) || !CADR(n) || !CDDR(n) || CADR(n)->type == void_type_string || CDDR(n)->type == void_type_string)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, void_type_string);
f68afd1999-11-20Henrik Grubbström (Grubba)  break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } if(CADR(n)->type == CDDR(n)->type) {
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, CADR(n)->type);
f68afd1999-11-20Henrik Grubbström (Grubba)  break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
4d7b181999-12-07Fredrik Hübinette (Hubbe)  n->type = or_pike_types(CADR(n)->type, CDDR(n)->type, 0);
cb22561995-10-11Fredrik Hübinette (Hubbe)  break;
42379f1999-11-21Henrik Grubbström (Grubba)  case F_AND_EQ: case F_OR_EQ: case F_XOR_EQ: case F_LSH_EQ: case F_RSH_EQ: case F_ADD_EQ: case F_SUB_EQ: case F_MULT_EQ: case F_MOD_EQ: case F_DIV_EQ:
d2f3302001-02-21Henrik Grubbström (Grubba)  if (CAR(n)) {
9b9fd92001-03-13Henrik Grubbström (Grubba)  struct pike_string *op_string = NULL;
d2f3302001-02-21Henrik Grubbström (Grubba)  struct pike_type *call_type; node *op_node; /* Go via var = OP(var, expr); * * FIXME: To restrict the type further: * type = typeof(OP(var, expr)) AND typeof(var); */ switch(n->token) { case F_AND_EQ:
de56ec2003-02-08Martin Stjernholm  MAKE_CONST_STRING(op_string, "`&");
d2f3302001-02-21Henrik Grubbström (Grubba)  break; case F_OR_EQ:
de56ec2003-02-08Martin Stjernholm  MAKE_CONST_STRING(op_string, "`|");
d2f3302001-02-21Henrik Grubbström (Grubba)  break; case F_XOR_EQ:
de56ec2003-02-08Martin Stjernholm  MAKE_CONST_STRING(op_string, "`^");
d2f3302001-02-21Henrik Grubbström (Grubba)  break; case F_LSH_EQ:
de56ec2003-02-08Martin Stjernholm  MAKE_CONST_STRING(op_string, "`<<");
d2f3302001-02-21Henrik Grubbström (Grubba)  break; case F_RSH_EQ:
de56ec2003-02-08Martin Stjernholm  MAKE_CONST_STRING(op_string, "`>>");
d2f3302001-02-21Henrik Grubbström (Grubba)  break; case F_ADD_EQ:
de56ec2003-02-08Martin Stjernholm  MAKE_CONST_STRING(op_string, "`+");
d2f3302001-02-21Henrik Grubbström (Grubba)  break; case F_SUB_EQ:
de56ec2003-02-08Martin Stjernholm  MAKE_CONST_STRING(op_string, "`-");
d2f3302001-02-21Henrik Grubbström (Grubba)  break; case F_MULT_EQ:
de56ec2003-02-08Martin Stjernholm  MAKE_CONST_STRING(op_string, "`*");
d2f3302001-02-21Henrik Grubbström (Grubba)  break; case F_MOD_EQ:
de56ec2003-02-08Martin Stjernholm  MAKE_CONST_STRING(op_string, "`%");
d2f3302001-02-21Henrik Grubbström (Grubba)  break; case F_DIV_EQ:
de56ec2003-02-08Martin Stjernholm  MAKE_CONST_STRING(op_string, "`/");
d2f3302001-02-21Henrik Grubbström (Grubba)  break; default:
5aad932002-08-15Marcus Comstedt  Pike_fatal("fix_type_field(): Unhandled token: %d\n", n->token);
d2f3302001-02-21Henrik Grubbström (Grubba)  break; } if (!(op_node = find_module_identifier(op_string, 0))) {
ce060e2004-06-30Martin Nilsson  my_yyerror("Internally used efun undefined for token %d: %S", n->token, op_string);
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, mixed_type_string);
d2f3302001-02-21Henrik Grubbström (Grubba)  break; }
5d72d62005-04-06Henrik Grubbström (Grubba) 
d2f3302001-02-21Henrik Grubbström (Grubba)  if (!op_node->type) { fix_type_field(op_node); } push_finished_type(CAR(n)->type); push_type(T_VOID); push_type(T_MANY); push_finished_type(CDR(n)->type);
dfed932001-03-03Henrik Grubbström (Grubba)  push_type(T_FUNCTION);
d2f3302001-02-21Henrik Grubbström (Grubba)  push_finished_type(CAR(n)->type); push_type(T_FUNCTION); call_type = pop_type(); n->type = check_call(call_type, op_node->type ? op_node->type : mixed_type_string, (lex.pragmas & ID_STRICT_TYPES) && !(op_node->node_info & OPT_WEAK_TYPE)); if (n->type) { /* Type check ok. */ free_node(op_node); free_type(call_type); break; }
ce060e2004-06-30Martin Nilsson  my_yyerror("Bad arguments to %S.", op_string);
d2f3302001-02-21Henrik Grubbström (Grubba)  yytype_error(NULL, op_node->type ? op_node->type : mixed_type_string, call_type, 0); free_node(op_node); free_type(call_type); }
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, mixed_type_string);
d2f3302001-02-21Henrik Grubbström (Grubba)  break;
73ff6a2002-05-15Henrik Grubbström (Grubba) 
d00b001999-11-21Henrik Grubbström (Grubba)  case F_INC: case F_DEC: case F_POST_INC: case F_POST_DEC: if (CAR(n)) { /* The expression gets the type from the variable. */ /* FIXME: Ought to strip non-applicable subtypes from the type. */
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, CAR(n)->type);
d00b001999-11-21Henrik Grubbström (Grubba)  } else {
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, mixed_type_string);
d00b001999-11-21Henrik Grubbström (Grubba)  } break;
cb22561995-10-11Fredrik Hübinette (Hubbe)  case F_RETURN:
e9b1771999-11-18Henrik Grubbström (Grubba)  if (!CAR(n) || (CAR(n)->type == void_type_string)) {
c2134c2002-05-14Henrik Grubbström (Grubba)  yywarning("Returning a void expression. Converted to zero.");
a2196f1999-11-21Henrik Grubbström (Grubba) #ifdef SHARED_NODES
c2134c2002-05-14Henrik Grubbström (Grubba)  sub_node(n);
a2196f1999-11-21Henrik Grubbström (Grubba) #endif /* SHARED_NODES */
c2134c2002-05-14Henrik Grubbström (Grubba)  if (!CAR(n)) {
a2196f1999-11-21Henrik Grubbström (Grubba)  _CAR(n) = mkintnode(0);
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, CAR(n)->type);
c2134c2002-05-14Henrik Grubbström (Grubba)  } else { _CAR(n) = mknode(F_COMMA_EXPR, CAR(n), mkintnode(0)); copy_pike_type(n->type, CDAR(n)->type); }
a2196f1999-11-21Henrik Grubbström (Grubba) #ifdef SHARED_NODES
c2134c2002-05-14Henrik Grubbström (Grubba)  if (!(n->tree_info & OPT_NOT_SHARED)) { n->hash = hash_node(n);
a2196f1999-11-21Henrik Grubbström (Grubba)  }
c2134c2002-05-14Henrik Grubbström (Grubba)  n->node_info |= OPT_DEFROSTED; add_node(n); #endif /* SHARED_NODES */ break;
d68a072001-02-20Henrik Grubbström (Grubba)  } else if(Pike_compiler->compiler_frame && Pike_compiler->compiler_frame->current_return_type) { if (!pike_types_le(CAR(n)->type, Pike_compiler->compiler_frame->current_return_type) && !( Pike_compiler->compiler_frame->current_return_type==void_type_string && CAR(n)->token == F_CONSTANT &&
9f516a2001-12-16Martin Stjernholm  SAFE_IS_ZERO(& CAR(n)->u.sval)
d68a072001-02-20Henrik Grubbström (Grubba)  )
84191b1999-11-23Henrik Grubbström (Grubba)  ) {
d68a072001-02-20Henrik Grubbström (Grubba)  if (!match_types(Pike_compiler->compiler_frame->current_return_type, CAR(n)->type))
84191b1999-11-23Henrik Grubbström (Grubba)  { yyerror("Wrong return type.");
bad5162000-06-23Fredrik Hübinette (Hubbe)  yyexplain_nonmatching_types(Pike_compiler->compiler_frame->current_return_type,
7daa182001-02-23Henrik Grubbström (Grubba)  CAR(n)->type, 0);
84191b1999-11-23Henrik Grubbström (Grubba)  } else if (lex.pragmas & ID_STRICT_TYPES) {
edcd891999-12-23Henrik Grubbström (Grubba)  yytype_error("Return type mismatch.",
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->compiler_frame->current_return_type,
edcd891999-12-23Henrik Grubbström (Grubba)  CAR(n)->type, YYTE_IS_WARNING);
84191b1999-11-23Henrik Grubbström (Grubba)  } }
cb22561995-10-11Fredrik Hübinette (Hubbe)  }
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, void_type_string);
c9cfae2000-01-04Henrik Grubbström (Grubba)  break;
cb22561995-10-11Fredrik Hübinette (Hubbe) 
9abda42002-03-02Martin Stjernholm  case F_CASE_RANGE:
b8cd052000-09-26Fredrik Hübinette (Hubbe)  if (CDR(n) && CAR(n) && !TEST_COMPAT(0,6)) {
c9cfae2000-01-04Henrik Grubbström (Grubba)  /* case 1 .. 2: */ if (!match_types(CAR(n)->type, CDR(n)->type)) {
5ba7062000-01-04Henrik Grubbström (Grubba)  if (!match_types(CAR(n)->type, int_type_string) || !match_types(CDR(n)->type, int_type_string)) { yytype_error("Type mismatch in case range.", CAR(n)->type, CDR(n)->type, 0); }
c9cfae2000-01-04Henrik Grubbström (Grubba)  } else if ((lex.pragmas & ID_STRICT_TYPES) && (CAR(n)->type != CDR(n)->type)) { /* The type should be the same for both CAR & CDR. */ if (!pike_types_le(CDR(n)->type, CAR(n)->type)) {
cbe8f32000-07-10Henrik Grubbström (Grubba)  /* Note that zero should be handled as int(0..0) here. */ if (!(CAR(n)->type == zero_type_string) || !(pike_types_le(CDR(n)->type, int_type_string))) { yytype_error("Type mismatch in case range.", CAR(n)->type, CDR(n)->type, YYTE_IS_WARNING); }
c9cfae2000-01-04Henrik Grubbström (Grubba)  } else if (!pike_types_le(CAR(n)->type, CDR(n)->type)) {
cbe8f32000-07-10Henrik Grubbström (Grubba)  if (!(CDR(n)->type == zero_type_string) || !(pike_types_le(CAR(n)->type, int_type_string))) { yytype_error("Type mismatch in case range.", CDR(n)->type, CAR(n)->type, YYTE_IS_WARNING); }
c9cfae2000-01-04Henrik Grubbström (Grubba)  } } } /* FALL_THROUGH */
9abda42002-03-02Martin Stjernholm  case F_CASE:
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_INC_LOOP: case F_DEC_LOOP: case F_DEC_NEQ_LOOP: case F_INC_NEQ_LOOP:
7daa182001-02-23Henrik Grubbström (Grubba)  case F_LOOP:
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_CONTINUE: case F_BREAK:
e9b1771999-11-18Henrik Grubbström (Grubba)  case F_DEFAULT:
f68afd1999-11-20Henrik Grubbström (Grubba)  case F_POP_VALUE:
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, void_type_string);
cb22561995-10-11Fredrik Hübinette (Hubbe)  break; case F_DO:
e9b1771999-11-18Henrik Grubbström (Grubba)  if (!CDR(n) || (CDR(n)->type == void_type_string)) {
9a78b21999-11-18Henrik Grubbström (Grubba)  yyerror("do - while(): Conditional expression is void.");
7daa182001-02-23Henrik Grubbström (Grubba)  } else if(!match_types(CDR(n)->type, mixed_type_string))
9a78b21999-11-18Henrik Grubbström (Grubba)  yyerror("Bad conditional expression do - while().");
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, void_type_string);
cb22561995-10-11Fredrik Hübinette (Hubbe)  break; case F_FOR:
e9b1771999-11-18Henrik Grubbström (Grubba)  if (!CAR(n) || (CAR(n)->type == void_type_string)) {
9a78b21999-11-18Henrik Grubbström (Grubba)  yyerror("for(): Conditional expression is void.");
7daa182001-02-23Henrik Grubbström (Grubba)  } else if(!match_types(CAR(n)->type, mixed_type_string))
9a78b21999-11-18Henrik Grubbström (Grubba)  yyerror("Bad conditional expression for().");
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, void_type_string);
cb22561995-10-11Fredrik Hübinette (Hubbe)  break; case F_SWITCH:
e9b1771999-11-18Henrik Grubbström (Grubba)  if (!CAR(n) || (CAR(n)->type == void_type_string)) {
9a78b21999-11-18Henrik Grubbström (Grubba)  yyerror("switch(): Conditional expression is void.");
7daa182001-02-23Henrik Grubbström (Grubba)  } else if(!match_types(CAR(n)->type, mixed_type_string))
9a78b21999-11-18Henrik Grubbström (Grubba)  yyerror("Bad switch expression.");
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, void_type_string);
cb22561995-10-11Fredrik Hübinette (Hubbe)  break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_CONSTANT: n->type = get_type_of_svalue(& n->u.sval);
cb22561995-10-11Fredrik Hübinette (Hubbe)  break;
22a6d91999-12-19Henrik Grubbström (Grubba)  case F_FOREACH: if (!CAR(n) || (CAR(n)->token != F_VAL_LVAL)) { yyerror("foreach(): No expression to loop over."); } else { if (!CAAR(n) || pike_types_le(CAAR(n)->type, void_type_string)) { yyerror("foreach(): Looping over a void expression."); } else {
77d58c2001-02-24Henrik Grubbström (Grubba)  if(CDAR(n) && CDAR(n)->token == ':')
4cdb802001-02-23Fredrik Hübinette (Hubbe)  {
77d58c2001-02-24Henrik Grubbström (Grubba)  /* Check the iterator type */ struct pike_type *iterator_type; struct pike_type *foreach_call_type;
8a2a522001-03-03Henrik Grubbström (Grubba)  MAKE_CONSTANT_TYPE(iterator_type, tOr5(tArray, tStr, tObj, tMapping, tMultiset));
77d58c2001-02-24Henrik Grubbström (Grubba)  if (!pike_types_le(CAAR(n)->type, iterator_type)) { if (!match_types(CAAR(n)->type, iterator_type)) { yytype_error("Bad argument 1 to foreach()", iterator_type, CAAR(n)->type, 0); /* No use checking the index and value types if * the iterator type is bad. */ free_type(iterator_type); goto foreach_type_check_done;
9459a92001-03-11Henrik Grubbström (Grubba)  } else if (lex.pragmas & ID_STRICT_TYPES) {
77d58c2001-02-24Henrik Grubbström (Grubba)  yytype_error("Iterator type mismatch in foreach()", iterator_type, CAAR(n)->type, YYTE_IS_WARNING); } } free_type(iterator_type); push_type(T_MIXED); push_type(T_VOID); push_type(T_MANY); push_finished_type(CAAR(n)->type); push_type(T_FUNCTION); foreach_call_type = pop_type(); if (CADAR(n)) { /* Check the index type */ struct pike_type *index_fun_type; struct pike_type *index_type;
8a2a522001-03-03Henrik Grubbström (Grubba)  MAKE_CONSTANT_TYPE(index_fun_type, tOr4(tFunc(tOr(tArray, tStr), tZero), tFunc(tMap(tSetvar(0, tMix), tMix), tVar(0)), tFunc(tSet(tSetvar(1, tMix)), tVar(1)), tFunc(tObj, tZero)));
77d58c2001-02-24Henrik Grubbström (Grubba)  index_type = check_call(foreach_call_type, index_fun_type, 0); if (!index_type) { /* Should not happen. */ yyerror("Bad iterator type for index in foreach()."); } else { if (!pike_types_le(index_type, CADAR(n)->type)) { if (!match_types(CADAR(n)->type, index_type)) { yytype_error("Type mismatch for index in foreach().", index_type, CADAR(n)->type, 0);
9459a92001-03-11Henrik Grubbström (Grubba)  } else if (lex.pragmas & ID_STRICT_TYPES) {
77d58c2001-02-24Henrik Grubbström (Grubba)  yytype_error("Type mismatch for index in foreach().", index_type, CADAR(n)->type, YYTE_IS_WARNING); } } free_type(index_type); } free_type(index_fun_type); } if (CDDAR(n)) { /* Check the value type */ struct pike_type *value_fun_type; struct pike_type *value_type;
8a2a522001-03-03Henrik Grubbström (Grubba)  MAKE_CONSTANT_TYPE(value_fun_type, tOr5(tFunc(tArr(tSetvar(0, tMix)), tVar(0)), tFunc(tStr, tZero), tFunc(tMap(tMix,tSetvar(1, tMix)), tVar(1)), tFunc(tMultiset, tInt1), tFunc(tObj, tZero)));
77d58c2001-02-24Henrik Grubbström (Grubba)  value_type = check_call(foreach_call_type, value_fun_type, 0); if (!value_type) { /* Should not happen. */ yyerror("Bad iterator type for value in foreach()."); } else { if (!pike_types_le(value_type, CDDAR(n)->type)) { if (!match_types(CDDAR(n)->type, value_type)) { yytype_error("Type mismatch for value in foreach().", value_type, CDDAR(n)->type, 0);
9459a92001-03-11Henrik Grubbström (Grubba)  } else if (lex.pragmas & ID_STRICT_TYPES) {
77d58c2001-02-24Henrik Grubbström (Grubba)  yytype_error("Type mismatch for value in foreach().", value_type, CDDAR(n)->type, YYTE_IS_WARNING); } } free_type(value_type); } free_type(value_fun_type); } free_type(foreach_call_type); } else { /* Old-style foreach */
4cdb802001-02-23Fredrik Hübinette (Hubbe)  struct pike_type *array_zero;
8a2a522001-03-03Henrik Grubbström (Grubba)  MAKE_CONSTANT_TYPE(array_zero, tArr(tZero));
4cdb802001-02-23Fredrik Hübinette (Hubbe)  if (!pike_types_le(array_zero, CAAR(n)->type)) { yyerror("Bad argument 1 to foreach().");
22a6d91999-12-19Henrik Grubbström (Grubba)  } else {
4cdb802001-02-23Fredrik Hübinette (Hubbe)  if ((lex.pragmas & ID_STRICT_TYPES) && !pike_types_le(CAAR(n)->type, array_type_string)) { struct pike_string *t = describe_type(CAAR(n)->type); yywarning("Argument 1 to foreach() is not always an array.");
ce060e2004-06-30Martin Nilsson  yywarning("Got: %S", t);
4cdb802001-02-23Fredrik Hübinette (Hubbe)  free_string(t); } if (!CDAR(n) || pike_types_le(CDAR(n)->type, void_type_string)) { yyerror("Bad argument 2 to foreach()."); } else { struct pike_type *value_type = array_value_type(CAAR(n)->type); if (!pike_types_le(value_type, CDAR(n)->type)) { if (!match_types(value_type, CDAR(n)->type)) { yytype_error("Variable type mismatch in foreach().", value_type, CDAR(n)->type, 0); } else if (lex.pragmas & ID_STRICT_TYPES) { yytype_error("Variable type mismatch in foreach().", value_type, CDAR(n)->type, YYTE_IS_WARNING); }
22a6d91999-12-19Henrik Grubbström (Grubba)  }
4cdb802001-02-23Fredrik Hübinette (Hubbe)  free_type(value_type);
22a6d91999-12-19Henrik Grubbström (Grubba)  } }
4cdb802001-02-23Fredrik Hübinette (Hubbe)  free_type(array_zero);
22a6d91999-12-19Henrik Grubbström (Grubba)  } } }
77d58c2001-02-24Henrik Grubbström (Grubba)  foreach_type_check_done:
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, void_type_string);
22a6d91999-12-19Henrik Grubbström (Grubba)  break;
30c3b71999-11-22Henrik Grubbström (Grubba)  case F_SSCANF:
16addb1999-12-10Henrik Grubbström (Grubba)  if (!CAR(n) || (CAR(n)->token != F_ARG_LIST) || !CAAR(n) || !CDAR(n)) { yyerror("Too few arguments to sscanf()."); } else { if (!pike_types_le(CAAR(n)->type, string_type_string)) { if (!match_types(CAAR(n)->type, string_type_string)) {
edcd891999-12-23Henrik Grubbström (Grubba)  yytype_error("Bad argument 1 to sscanf().", string_type_string, CAAR(n)->type, 0);
16addb1999-12-10Henrik Grubbström (Grubba)  } else if (lex.pragmas & ID_STRICT_TYPES) {
edcd891999-12-23Henrik Grubbström (Grubba)  yytype_error("Argument 1 to sscanf() has bad type.", string_type_string, CAAR(n)->type, YYTE_IS_WARNING);
16addb1999-12-10Henrik Grubbström (Grubba)  } } if (!pike_types_le(CDAR(n)->type, string_type_string)) { if (!match_types(CDAR(n)->type, string_type_string)) {
edcd891999-12-23Henrik Grubbström (Grubba)  yytype_error("Bad argument 2 to sscanf().", string_type_string, CDAR(n)->type, 0);
16addb1999-12-10Henrik Grubbström (Grubba)  } else if (lex.pragmas & ID_STRICT_TYPES) {
edcd891999-12-23Henrik Grubbström (Grubba)  yytype_error("Argument 2 to sscanf() has bad type.", string_type_string, CDAR(n)->type, YYTE_IS_WARNING);
16addb1999-12-10Henrik Grubbström (Grubba)  } } }
7daa182001-02-23Henrik Grubbström (Grubba)  /* FIXME: */
8a2a522001-03-03Henrik Grubbström (Grubba)  MAKE_CONSTANT_TYPE(n->type, tIntPos);
30c3b71999-11-22Henrik Grubbström (Grubba)  break; case F_UNDEFINED:
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, zero_type_string);
30c3b71999-11-22Henrik Grubbström (Grubba)  break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_ARG_LIST:
f68afd1999-11-20Henrik Grubbström (Grubba)  if (n->parent) { /* Propagate the changed type all the way up to the apply node. */ n->parent->node_info |= OPT_TYPE_NOT_FIXED; } /* FALL_THROUGH */ case F_COMMA_EXPR:
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!CAR(n) || CAR(n)->type==void_type_string) { if(CDR(n))
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, CDR(n)->type);
5267b71995-08-09Fredrik Hübinette (Hubbe)  else
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, void_type_string);
f68afd1999-11-20Henrik Grubbström (Grubba)  break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
7daa182001-02-23Henrik Grubbström (Grubba)  if(!CDR(n) || CDR(n)->type == void_type_string)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { if(CAR(n))
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, CAR(n)->type);
5267b71995-08-09Fredrik Hübinette (Hubbe)  else
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, void_type_string);
f68afd1999-11-20Henrik Grubbström (Grubba)  break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
16addb1999-12-10Henrik Grubbström (Grubba)  if (n->token == F_ARG_LIST) { n->type = or_pike_types(CAR(n)->type, CDR(n)->type, 0); } else {
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, CDR(n)->type);
16addb1999-12-10Henrik Grubbström (Grubba)  } break;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
d00b001999-11-21Henrik Grubbström (Grubba)  case F_MAGIC_INDEX:
e948371999-12-29Henrik Grubbström (Grubba)  /* FIXME: Could have a stricter type for ::`->(). */
7daa182001-02-23Henrik Grubbström (Grubba)  /* FIXME: */
1ba3e52001-12-19Martin Stjernholm  MAKE_CONSTANT_TYPE(n->type, tFunc(tMix tOr(tVoid,tInt),tMix));
e948371999-12-29Henrik Grubbström (Grubba)  break;
d00b001999-11-21Henrik Grubbström (Grubba)  case F_MAGIC_SET_INDEX:
e948371999-12-29Henrik Grubbström (Grubba)  /* FIXME: Could have a stricter type for ::`->=(). */
7daa182001-02-23Henrik Grubbström (Grubba)  /* FIXME: */
1ba3e52001-12-19Martin Stjernholm  MAKE_CONSTANT_TYPE(n->type, tFunc(tMix tSetvar(0,tMix) tOr(tVoid,tInt), tVar(0)));
e948371999-12-29Henrik Grubbström (Grubba)  break;
cbe1132001-12-16Martin Stjernholm  case F_MAGIC_INDICES:
1ba3e52001-12-19Martin Stjernholm  MAKE_CONSTANT_TYPE(n->type, tFunc(tOr(tVoid,tInt), tArr(tString)));
cbe1132001-12-16Martin Stjernholm  break; case F_MAGIC_VALUES: /* FIXME: Could have a stricter type for ::_values. */
1ba3e52001-12-19Martin Stjernholm  MAKE_CONSTANT_TYPE(n->type, tFunc(tOr(tVoid,tInt), tArray));
cbe1132001-12-16Martin Stjernholm  break;
e948371999-12-29Henrik Grubbström (Grubba) 
d00b001999-11-21Henrik Grubbström (Grubba)  case F_CATCH:
e948371999-12-29Henrik Grubbström (Grubba)  /* FALL_THROUGH */
5267b71995-08-09Fredrik Hübinette (Hubbe)  default:
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(n->type, mixed_type_string);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
f68afd1999-11-20Henrik Grubbström (Grubba)  if (n->type != old_type) { if (n->parent) { n->parent->node_info |= OPT_TYPE_NOT_FIXED; } } if (old_type) {
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(old_type);
f68afd1999-11-20Henrik Grubbström (Grubba)  }
ba0ca21999-11-22Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG check_type_string(n->type); #endif /* PIKE_DEBUG */
5267b71995-08-09Fredrik Hübinette (Hubbe) } static void zapp_try_optimize(node *n) {
d618e52000-09-13Henrik Grubbström (Grubba)  node *parent; node *orig_n = n;
86bea91997-01-31Fredrik Hübinette (Hubbe)  if(!n) return;
aee2d32000-09-12Henrik Grubbström (Grubba) 
d618e52000-09-13Henrik Grubbström (Grubba)  parent = n->parent; n->parent = NULL; while(1) { n->node_info &= ~OPT_TRY_OPTIMIZE; n->tree_info &= ~OPT_TRY_OPTIMIZE;
aee2d32000-09-12Henrik Grubbström (Grubba) 
d618e52000-09-13Henrik Grubbström (Grubba)  if (car_is_node(n)) { CAR(n)->parent = n; n = CAR(n); continue; } if (cdr_is_node(n)) { CDR(n)->parent = n; n = CDR(n); continue; } while (n->parent && (!cdr_is_node(n->parent) || (CDR(n->parent) == n))) { n = n->parent; } if (n->parent && cdr_is_node(n->parent)) { CDR(n->parent)->parent = n->parent; n = CDR(n->parent); continue; } break; } #ifdef PIKE_DEBUG if (n != orig_n) {
5aad932002-08-15Marcus Comstedt  Pike_fatal("zzap_try_optimize() lost track of parent.\n");
d618e52000-09-13Henrik Grubbström (Grubba)  } #endif /* PIKE_DEBUG */ n->parent = parent;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
bf2a352003-04-02Martin Nilsson #if defined(SHARED_NODES)
889d232000-09-12Henrik Grubbström (Grubba) /* FIXME: Ought to use parent pointer to avoid recursion. */
36dd451999-11-17Henrik Grubbström (Grubba) static void find_usage(node *n, unsigned char *usage,
969a291999-11-17Henrik Grubbström (Grubba)  unsigned char *switch_u, const unsigned char *cont_u,
36dd451999-11-17Henrik Grubbström (Grubba)  const unsigned char *break_u, const unsigned char *catch_u)
969a291999-11-17Henrik Grubbström (Grubba) { if (!n) return;
aee2d32000-09-12Henrik Grubbström (Grubba)  fatal_check_c_stack(16384);
969a291999-11-17Henrik Grubbström (Grubba)  switch(n->token) { case F_ASSIGN: if ((CDR(n)->token == F_LOCAL) && (!CDR(n)->u.integer.b)) { usage[CDR(n)->u.integer.a] = 0;
55a20a1999-11-17Henrik Grubbström (Grubba)  } else if (CDR(n)->token == F_ARRAY_LVALUE) {
36dd451999-11-17Henrik Grubbström (Grubba)  find_usage(CDR(n), usage, switch_u, cont_u, break_u, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  }
36dd451999-11-17Henrik Grubbström (Grubba)  find_usage(CAR(n), usage, switch_u, cont_u, break_u, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  return;
36dd451999-11-17Henrik Grubbström (Grubba)  case F_SSCANF: { int i;
a4a1722000-12-05Per Hedbor  /* catch_usage is restored if sscanf throws an error. */
36dd451999-11-17Henrik Grubbström (Grubba)  for (i=0; i < MAX_LOCAL; i++) { usage[i] |= catch_u[i]; } /* Only the first two arguments are evaluated. */ if (CAR(n)) { find_usage(CDAR(n), usage, switch_u, cont_u, break_u, catch_u); find_usage(CAAR(n), usage, switch_u, cont_u, break_u, catch_u); } return; } case F_CATCH: { unsigned char catch_usage[MAX_LOCAL]; int i; MEMCPY(catch_usage, usage, MAX_LOCAL); find_usage(CAR(n), usage, switch_u, cont_u, catch_usage, catch_usage); for(i=0; i < MAX_LOCAL; i++) { usage[i] |= catch_usage[i]; } return; }
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  case F_AUTO_MAP:
36dd451999-11-17Henrik Grubbström (Grubba)  case F_APPLY: { int i;
a4a1722000-12-05Per Hedbor  /* catch_usage is restored if the function throws an error. */
36dd451999-11-17Henrik Grubbström (Grubba)  for (i=0; i < MAX_LOCAL; i++) { usage[i] |= catch_u[i]; } find_usage(CDR(n), usage, switch_u, cont_u, break_u, catch_u); find_usage(CAR(n), usage, switch_u, cont_u, break_u, catch_u); return; }
55a20a1999-11-17Henrik Grubbström (Grubba)  case F_LVALUE_LIST:
36dd451999-11-17Henrik Grubbström (Grubba)  find_usage(CDR(n), usage, switch_u, cont_u, break_u, catch_u);
55a20a1999-11-17Henrik Grubbström (Grubba)  if (CAR(n)) { if ((CAR(n)->token == F_LOCAL) && (!CAR(n)->u.integer.b)) { usage[CAR(n)->u.integer.a] = 0; } } return; case F_ARRAY_LVALUE:
36dd451999-11-17Henrik Grubbström (Grubba)  find_usage(CAR(n), usage, switch_u, cont_u, break_u, catch_u);
55a20a1999-11-17Henrik Grubbström (Grubba)  return;
969a291999-11-17Henrik Grubbström (Grubba)  case F_CONTINUE: MEMCPY(usage, cont_u, MAX_LOCAL); return; case F_BREAK: MEMCPY(usage, break_u, MAX_LOCAL); return; case F_DEFAULT: case F_CASE:
9abda42002-03-02Martin Stjernholm  case F_CASE_RANGE:
969a291999-11-17Henrik Grubbström (Grubba)  { int i;
36dd451999-11-17Henrik Grubbström (Grubba)  find_usage(CDR(n), usage, switch_u, cont_u, break_u, catch_u); find_usage(CAR(n), usage, switch_u, cont_u, break_u, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  for(i = 0; i < MAX_LOCAL; i++) { switch_u[i] |= usage[i]; } return; } case F_SWITCH: { unsigned char break_usage[MAX_LOCAL]; unsigned char switch_usage[MAX_LOCAL]; int i; MEMSET(switch_usage, 0, MAX_LOCAL); MEMCPY(break_usage, usage, MAX_LOCAL);
36dd451999-11-17Henrik Grubbström (Grubba)  find_usage(CDR(n), usage, switch_usage, cont_u, break_usage, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  for(i = 0; i < MAX_LOCAL; i++) { usage[i] |= switch_usage[i]; }
36dd451999-11-17Henrik Grubbström (Grubba)  find_usage(CAR(n), usage, switch_u, cont_u, break_u, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  return; } case F_RETURN: MEMSET(usage, 0, MAX_LOCAL); /* FIXME: The function arguments should be marked "used", since * they are seen in backtraces. */ return; case F_LOR: case F_LAND: { unsigned char trail_usage[MAX_LOCAL]; int i; MEMCPY(trail_usage, usage, MAX_LOCAL);
36dd451999-11-17Henrik Grubbström (Grubba)  find_usage(CDR(n), usage, switch_u, cont_u, break_u, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  for(i=0; i < MAX_LOCAL; i++) { usage[i] |= trail_usage[i]; }
36dd451999-11-17Henrik Grubbström (Grubba)  find_usage(CAR(n), usage, switch_u, cont_u, break_u, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  return; } case '?': { unsigned char cadr_usage[MAX_LOCAL]; unsigned char cddr_usage[MAX_LOCAL]; int i; MEMCPY(cadr_usage, usage, MAX_LOCAL); MEMCPY(cddr_usage, usage, MAX_LOCAL);
36dd451999-11-17Henrik Grubbström (Grubba)  find_usage(CADR(n), cadr_usage, switch_u, cont_u, break_u, catch_u); find_usage(CDDR(n), cddr_usage, switch_u, cont_u, break_u, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  for (i=0; i < MAX_LOCAL; i++) { usage[i] = cadr_usage[i] | cddr_usage[i]; }
36dd451999-11-17Henrik Grubbström (Grubba)  find_usage(CAR(n), usage, switch_u, cont_u, break_u, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  return; } case F_DO: { unsigned char break_usage[MAX_LOCAL]; unsigned char continue_usage[MAX_LOCAL]; MEMCPY(break_usage, usage, MAX_LOCAL);
36dd451999-11-17Henrik Grubbström (Grubba)  find_usage(CDR(n), usage, switch_u, cont_u, break_usage, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  MEMCPY(continue_usage, usage, MAX_LOCAL);
36dd451999-11-17Henrik Grubbström (Grubba)  find_usage(CAR(n), usage, switch_u, break_usage, continue_usage, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  return; } case F_FOR: {
36dd451999-11-17Henrik Grubbström (Grubba)  unsigned char loop_usage[MAX_LOCAL];
969a291999-11-17Henrik Grubbström (Grubba)  unsigned char break_usage[MAX_LOCAL]; unsigned char continue_usage[MAX_LOCAL];
55a20a1999-11-17Henrik Grubbström (Grubba)  int i;
969a291999-11-17Henrik Grubbström (Grubba)  MEMCPY(break_usage, usage, MAX_LOCAL); /* for(;a;b) c; is handled like: * * if (a) { do { c; b; } while(a); } */
36dd451999-11-17Henrik Grubbström (Grubba)  MEMSET(loop_usage, 0, MAX_LOCAL); find_usage(CAR(n), loop_usage, switch_u, cont_u, break_u, catch_u); if (CDR(n)) { find_usage(CDDR(n), loop_usage, switch_u, cont_u, break_usage, catch_u);
969a291999-11-17Henrik Grubbström (Grubba) 
36dd451999-11-17Henrik Grubbström (Grubba)  MEMCPY(continue_usage, loop_usage, MAX_LOCAL); find_usage(CADR(n), loop_usage, switch_u, continue_usage, break_usage, catch_u); }
969a291999-11-17Henrik Grubbström (Grubba) 
55a20a1999-11-17Henrik Grubbström (Grubba)  for (i = 0; i < MAX_LOCAL; i++) {
36dd451999-11-17Henrik Grubbström (Grubba)  usage[i] |= loop_usage[i];
55a20a1999-11-17Henrik Grubbström (Grubba)  }
36dd451999-11-17Henrik Grubbström (Grubba)  find_usage(CAR(n), usage, switch_u, cont_u, break_u, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  return; } case F_FOREACH: {
36dd451999-11-17Henrik Grubbström (Grubba)  unsigned char loop_usage[MAX_LOCAL];
969a291999-11-17Henrik Grubbström (Grubba)  unsigned char break_usage[MAX_LOCAL]; unsigned char continue_usage[MAX_LOCAL];
36dd451999-11-17Henrik Grubbström (Grubba)  int i;
969a291999-11-17Henrik Grubbström (Grubba)  MEMCPY(break_usage, usage, MAX_LOCAL);
36dd451999-11-17Henrik Grubbström (Grubba)  /* Find the usage from the loop */ MEMSET(loop_usage, 0, MAX_LOCAL);
969a291999-11-17Henrik Grubbström (Grubba)  MEMCPY(continue_usage, usage, MAX_LOCAL);
36dd451999-11-17Henrik Grubbström (Grubba)  find_usage(CDR(n), loop_usage, switch_u, continue_usage, break_usage, catch_u); if (CDAR(n)->token == F_LOCAL) { if (!(CDAR(n)->u.integer.b)) { loop_usage[CDAR(n)->u.integer.a] = 0; } } else if (CDAR(n)->token == F_LVALUE_LIST) { find_usage(CDAR(n), loop_usage, switch_u, cont_u, break_u, catch_u); } for(i=0; i < MAX_LOCAL; i++) { usage[i] |= loop_usage[i]; } find_usage(CAAR(n), usage, switch_u, cont_u, break_u, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  return; } case F_LOCAL: /* Use of local variable. */ if (!n->u.integer.b) { /* Recently used, and used at all */ usage[n->u.integer.a] = 3; } return; default: if (cdr_is_node(n)) {
36dd451999-11-17Henrik Grubbström (Grubba)  find_usage(CDR(n), usage, switch_u, cont_u, break_u, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  } if (car_is_node(n)) {
36dd451999-11-17Henrik Grubbström (Grubba)  find_usage(CAR(n), usage, switch_u, cont_u, break_u, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  } return; } } /* Note: Always builds a new tree. */ static node *low_localopt(node *n, unsigned char *usage, unsigned char *switch_u, const unsigned char *cont_u,
36dd451999-11-17Henrik Grubbström (Grubba)  const unsigned char *break_u, const unsigned char *catch_u)
969a291999-11-17Henrik Grubbström (Grubba) { node *car, *cdr; if (!n) return NULL; switch(n->token) {
7daa182001-02-23Henrik Grubbström (Grubba)  /* FIXME: Does not support F_LOOP yet. */
969a291999-11-17Henrik Grubbström (Grubba)  case F_ASSIGN: if ((CDR(n)->token == F_LOCAL) && (!CDR(n)->u.integer.b)) { /* Assignment of local variable */ if (!(usage[CDR(n)->u.integer.a] & 1)) { /* Value isn't used. */
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *ref_type;
8a2a522001-03-03Henrik Grubbström (Grubba)  MAKE_CONSTANT_TYPE(ref_type, tOr(tComplex, tString));
1aac411999-11-19Henrik Grubbström (Grubba)  if (!match_types(CDR(n)->type, ref_type)) { /* The variable doesn't hold a refcounted value. */
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(ref_type);
1aac411999-11-19Henrik Grubbström (Grubba)  return low_localopt(CAR(n), usage, switch_u, cont_u, break_u, catch_u); }
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(ref_type);
969a291999-11-17Henrik Grubbström (Grubba)  } usage[CDR(n)->u.integer.a] = 0;
55a20a1999-11-17Henrik Grubbström (Grubba)  cdr = CDR(n); ADD_NODE_REF(cdr); } else if (CDR(n)->token == F_ARRAY_LVALUE) {
36dd451999-11-17Henrik Grubbström (Grubba)  cdr = low_localopt(CDR(n), usage, switch_u, cont_u, break_u, catch_u);
55a20a1999-11-17Henrik Grubbström (Grubba)  } else { cdr = CDR(n); ADD_NODE_REF(cdr);
969a291999-11-17Henrik Grubbström (Grubba)  } return mknode(F_ASSIGN, low_localopt(CAR(n), usage, switch_u, cont_u,
36dd451999-11-17Henrik Grubbström (Grubba)  break_u, catch_u), cdr); case F_SSCANF: { int i;
a4a1722000-12-05Per Hedbor  /* catch_usage is restored if sscanf throws an error. */
36dd451999-11-17Henrik Grubbström (Grubba)  for (i=0; i < MAX_LOCAL; i++) { usage[i] |= catch_u[i]; } /* Only the first two arguments are evaluated. */ if (CAR(n)) { cdr = low_localopt(CDAR(n), usage, switch_u, cont_u, break_u, catch_u); car = low_localopt(CAAR(n), usage, switch_u, cont_u, break_u, catch_u); if (CDR(n)) { ADD_NODE_REF(CDR(n)); } return mknode(F_SSCANF, mknode(F_ARG_LIST, car, cdr), CDR(n)); } ADD_NODE_REF(n); return n; } case F_CATCH: { unsigned char catch_usage[MAX_LOCAL]; int i; MEMCPY(catch_usage, usage, MAX_LOCAL); car = low_localopt(CAR(n), usage, switch_u, cont_u, catch_usage, catch_usage); for(i=0; i < MAX_LOCAL; i++) { usage[i] |= catch_usage[i]; } return mknode(F_CATCH, car, 0); } break;
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  case F_AUTO_MAP:
36dd451999-11-17Henrik Grubbström (Grubba)  case F_APPLY: { int i;
a4a1722000-12-05Per Hedbor  /* catch_usage is restored if the function throws an error. */
36dd451999-11-17Henrik Grubbström (Grubba)  for (i=0; i < MAX_LOCAL; i++) { usage[i] |= catch_u[i]; } cdr = low_localopt(CDR(n), usage, switch_u, cont_u, break_u, catch_u); car = low_localopt(CAR(n), usage, switch_u, cont_u, break_u, catch_u);
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  return mknode(n->token, car, cdr);
36dd451999-11-17Henrik Grubbström (Grubba)  }
55a20a1999-11-17Henrik Grubbström (Grubba)  case F_LVALUE_LIST:
36dd451999-11-17Henrik Grubbström (Grubba)  cdr = low_localopt(CDR(n), usage, switch_u, cont_u, break_u, catch_u);
55a20a1999-11-17Henrik Grubbström (Grubba)  if (CAR(n)) { if ((CAR(n)->token == F_LOCAL) && (!CAR(n)->u.integer.b)) { /* Array assignment of local variable. */ if (!(usage[CDR(n)->u.integer.a] & 1)) { /* Variable isn't used. */ /* FIXME: Warn? */ } usage[CAR(n)->u.integer.a] = 0; } ADD_NODE_REF(CAR(n)); } return mknode(F_LVALUE_LIST, CAR(n), cdr); case F_ARRAY_LVALUE: return mknode(F_ARRAY_LVALUE, low_localopt(CAR(n), usage, switch_u, cont_u,
36dd451999-11-17Henrik Grubbström (Grubba)  break_u, catch_u), 0);
55a20a1999-11-17Henrik Grubbström (Grubba) 
969a291999-11-17Henrik Grubbström (Grubba)  case F_CAST: return mkcastnode(n->type, low_localopt(CAR(n), usage, switch_u, cont_u,
36dd451999-11-17Henrik Grubbström (Grubba)  break_u, catch_u));
969a291999-11-17Henrik Grubbström (Grubba) 
84191b1999-11-23Henrik Grubbström (Grubba)  case F_SOFT_CAST: return mksoftcastnode(n->type, low_localopt(CAR(n), usage, switch_u, cont_u, break_u, catch_u));
969a291999-11-17Henrik Grubbström (Grubba)  case F_CONTINUE: MEMCPY(usage, cont_u, MAX_LOCAL); ADD_NODE_REF(n); return n; case F_BREAK: MEMCPY(usage, break_u, MAX_LOCAL); ADD_NODE_REF(n); return n; case F_DEFAULT: case F_CASE:
9abda42002-03-02Martin Stjernholm  case F_CASE_RANGE:
969a291999-11-17Henrik Grubbström (Grubba)  { int i;
36dd451999-11-17Henrik Grubbström (Grubba)  cdr = low_localopt(CDR(n), usage, switch_u, cont_u, break_u, catch_u); car = low_localopt(CAR(n), usage, switch_u, cont_u, break_u, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  for(i = 0; i < MAX_LOCAL; i++) { switch_u[i] |= usage[i]; } return mknode(n->token, car, cdr); } case F_SWITCH: { unsigned char break_usage[MAX_LOCAL]; unsigned char switch_usage[MAX_LOCAL]; int i; MEMSET(switch_usage, 0, MAX_LOCAL); MEMCPY(break_usage, usage, MAX_LOCAL);
36dd451999-11-17Henrik Grubbström (Grubba)  cdr = low_localopt(CDR(n), usage, switch_usage, cont_u, break_usage, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  for(i = 0; i < MAX_LOCAL; i++) { usage[i] |= switch_usage[i]; }
36dd451999-11-17Henrik Grubbström (Grubba)  car = low_localopt(CAR(n), usage, switch_u, cont_u, break_u, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  return mknode(F_SWITCH, car, cdr); } case F_RETURN: MEMSET(usage, 0, MAX_LOCAL); /* FIXME: The function arguments should be marked "used", since * they are seen in backtraces. */ return mknode(F_RETURN, low_localopt(CAR(n), usage, switch_u, cont_u,
36dd451999-11-17Henrik Grubbström (Grubba)  break_u, catch_u), 0);
969a291999-11-17Henrik Grubbström (Grubba)  case F_LOR: case F_LAND: { unsigned char trail_usage[MAX_LOCAL]; int i; MEMCPY(trail_usage, usage, MAX_LOCAL);
36dd451999-11-17Henrik Grubbström (Grubba)  cdr = low_localopt(CDR(n), usage, switch_u, cont_u, break_u, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  for(i=0; i < MAX_LOCAL; i++) { usage[i] |= trail_usage[i]; }
36dd451999-11-17Henrik Grubbström (Grubba)  car = low_localopt(CAR(n), usage, switch_u, cont_u, break_u, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  return mknode(n->token, car, cdr); } case '?': { unsigned char cadr_usage[MAX_LOCAL]; unsigned char cddr_usage[MAX_LOCAL]; int i; MEMCPY(cadr_usage, usage, MAX_LOCAL); MEMCPY(cddr_usage, usage, MAX_LOCAL);
36dd451999-11-17Henrik Grubbström (Grubba)  car = low_localopt(CADR(n), cadr_usage, switch_u, cont_u, break_u, catch_u); cdr = low_localopt(CDDR(n), cddr_usage, switch_u, cont_u, break_u, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  for (i=0; i < MAX_LOCAL; i++) { usage[i] = cadr_usage[i] | cddr_usage[i]; } cdr = mknode(':', car, cdr);
36dd451999-11-17Henrik Grubbström (Grubba)  car = low_localopt(CAR(n), usage, switch_u, cont_u, break_u, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  return mknode('?', car, cdr); } case F_DO: { unsigned char break_usage[MAX_LOCAL]; unsigned char continue_usage[MAX_LOCAL];
36dd451999-11-17Henrik Grubbström (Grubba)  int i;
969a291999-11-17Henrik Grubbström (Grubba)  MEMCPY(break_usage, usage, MAX_LOCAL);
36dd451999-11-17Henrik Grubbström (Grubba)  /* Find the usage from the loop */ find_usage(CDR(n), usage, switch_u, cont_u, break_u, catch_u); MEMCPY(continue_usage, usage, MAX_LOCAL); find_usage(CAR(n), usage, switch_u, continue_usage, break_usage, catch_u); for (i = 0; i < MAX_LOCAL; i++) { usage[i] |= break_usage[i]; } cdr = low_localopt(CDR(n), usage, switch_u, cont_u, break_usage, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  MEMCPY(continue_usage, usage, MAX_LOCAL);
36dd451999-11-17Henrik Grubbström (Grubba)  car = low_localopt(CAR(n), usage, switch_u, continue_usage, break_usage, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  return mknode(F_DO, car, cdr); } case F_FOR: {
36dd451999-11-17Henrik Grubbström (Grubba)  unsigned char loop_usage[MAX_LOCAL];
969a291999-11-17Henrik Grubbström (Grubba)  unsigned char break_usage[MAX_LOCAL]; unsigned char continue_usage[MAX_LOCAL];
55a20a1999-11-17Henrik Grubbström (Grubba)  int i;
969a291999-11-17Henrik Grubbström (Grubba)  MEMCPY(break_usage, usage, MAX_LOCAL);
36dd451999-11-17Henrik Grubbström (Grubba)  /* * if (a A|B) { * B * do { * B * c; * continue: * D * b; * C * } while (a A|B); * A * } * break: * A
969a291999-11-17Henrik Grubbström (Grubba)  */
36dd451999-11-17Henrik Grubbström (Grubba)  /* Find the usage from the loop. */ MEMSET(loop_usage, 0, MAX_LOCAL); find_usage(CAR(n), loop_usage, switch_u, cont_u, break_u, catch_u); if (CDR(n)) { find_usage(CDDR(n), loop_usage, switch_u, cont_u, break_usage, catch_u); MEMCPY(continue_usage, loop_usage, MAX_LOCAL); find_usage(CADR(n), loop_usage, switch_u, continue_usage, break_usage, catch_u); } for (i = 0; i < MAX_LOCAL; i++) { usage[i] |= loop_usage[i]; } /* The last thing to be evaluated is the conditional */ car = low_localopt(CAR(n), usage, switch_u, cont_u, break_u, catch_u); if (CDR(n)) { node *cadr, *cddr;
969a291999-11-17Henrik Grubbström (Grubba) 
36dd451999-11-17Henrik Grubbström (Grubba)  /* The incrementor */ cddr = low_localopt(CDDR(n), usage, switch_u, cont_u, break_usage, catch_u); MEMCPY(continue_usage, usage, MAX_LOCAL); /* The body */ cadr = low_localopt(CADR(n), usage, switch_u, continue_usage, break_usage, catch_u); cdr = mknode(':', cadr, cddr); } else { cdr = 0; }
969a291999-11-17Henrik Grubbström (Grubba) 
55a20a1999-11-17Henrik Grubbström (Grubba)  for (i = 0; i < MAX_LOCAL; i++) { usage[i] |= break_usage[i]; }
36dd451999-11-17Henrik Grubbström (Grubba)  /* The conditional is also the first thing to be evaluated. */ find_usage(car, usage, switch_u, cont_u, break_u, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  return mknode(F_FOR, car, cdr); } case F_FOREACH: {
36dd451999-11-17Henrik Grubbström (Grubba)  unsigned char loop_usage[MAX_LOCAL];
969a291999-11-17Henrik Grubbström (Grubba)  unsigned char break_usage[MAX_LOCAL]; unsigned char continue_usage[MAX_LOCAL];
36dd451999-11-17Henrik Grubbström (Grubba)  int i;
969a291999-11-17Henrik Grubbström (Grubba)  MEMCPY(break_usage, usage, MAX_LOCAL);
36dd451999-11-17Henrik Grubbström (Grubba)  /* * D * arr = copy_value(arr); * int i = 0; * A|B * while (i < sizeof(arr)) { * B * loopvar = arr[i]; * C * body; * continue: * A|B * } * break: * A */ /* Find the usage from the loop */ MEMSET(loop_usage, 0, MAX_LOCAL);
969a291999-11-17Henrik Grubbström (Grubba)  MEMCPY(continue_usage, usage, MAX_LOCAL);
36dd451999-11-17Henrik Grubbström (Grubba)  find_usage(CDR(n), loop_usage, switch_u, continue_usage, break_usage, catch_u); if (CDAR(n)->token == F_LOCAL) { if (!(CDAR(n)->u.integer.b)) { loop_usage[CDAR(n)->u.integer.a] = 0; } } else if (CDAR(n)->token == F_LVALUE_LIST) { find_usage(CDAR(n), loop_usage, switch_u, cont_u, break_u, catch_u); } for (i = 0; i < MAX_LOCAL; i++) { usage[i] |= loop_usage[i]; } MEMCPY(continue_usage, usage, MAX_LOCAL); cdr = low_localopt(CDR(n), usage, switch_u, continue_usage, break_usage, catch_u); if (CDAR(n)->token == F_LOCAL) { if (!(CDAR(n)->u.integer.b)) { usage[CDAR(n)->u.integer.a] = 0; } } else if (CDAR(n)->token == F_LVALUE_LIST) { find_usage(CDAR(n), usage, switch_u, cont_u, break_u, catch_u); } for (i = 0; i < MAX_LOCAL; i++) { usage[i] |= break_usage[i]; } car = low_localopt(CAAR(n), usage, switch_u, cont_u, break_u, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  ADD_NODE_REF(CDAR(n)); return mknode(F_FOREACH, mknode(F_VAL_LVAL, car, CDAR(n)), cdr); } case F_LOCAL: /* Use of local variable. */ if (!n->u.integer.b) { /* Recently used, and used at all */ usage[n->u.integer.a] = 3; } ADD_NODE_REF(n); return n; default: if (cdr_is_node(n)) {
36dd451999-11-17Henrik Grubbström (Grubba)  cdr = low_localopt(CDR(n), usage, switch_u, cont_u, break_u, catch_u);
969a291999-11-17Henrik Grubbström (Grubba)  return mknode(n->token, low_localopt(CAR(n), usage, switch_u, cont_u,
36dd451999-11-17Henrik Grubbström (Grubba)  break_u, catch_u),
969a291999-11-17Henrik Grubbström (Grubba)  cdr); } if (car_is_node(n)) { ADD_NODE_REF(CDR(n)); return mknode(n->token, low_localopt(CAR(n), usage, switch_u, cont_u,
36dd451999-11-17Henrik Grubbström (Grubba)  break_u, catch_u),
969a291999-11-17Henrik Grubbström (Grubba)  CDR(n)); } ADD_NODE_REF(n); return n; } } static node *localopt(node *n) { unsigned char usage[MAX_LOCAL]; unsigned char b_usage[MAX_LOCAL]; unsigned char c_usage[MAX_LOCAL]; unsigned char s_usage[MAX_LOCAL];
36dd451999-11-17Henrik Grubbström (Grubba)  unsigned char catch_usage[MAX_LOCAL];
969a291999-11-17Henrik Grubbström (Grubba)  node *n2; MEMSET(usage, 0, MAX_LOCAL); MEMSET(b_usage, 0, MAX_LOCAL); MEMSET(c_usage, 0, MAX_LOCAL); MEMSET(s_usage, 0, MAX_LOCAL);
36dd451999-11-17Henrik Grubbström (Grubba)  MEMSET(catch_usage, 0, MAX_LOCAL);
969a291999-11-17Henrik Grubbström (Grubba) 
36dd451999-11-17Henrik Grubbström (Grubba)  n2 = low_localopt(n, usage, s_usage, c_usage, b_usage, catch_usage);
969a291999-11-17Henrik Grubbström (Grubba) 
36dd451999-11-17Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG if (l_flag > 0) { if ((n2 != n) || (l_flag > 4)) {
fa74242004-07-06Martin Nilsson  fputs("\nBefore localopt: ", stderr);
36dd451999-11-17Henrik Grubbström (Grubba)  print_tree(n);
969a291999-11-17Henrik Grubbström (Grubba) 
fa74242004-07-06Martin Nilsson  fputs("After localopt: ", stderr);
36dd451999-11-17Henrik Grubbström (Grubba)  print_tree(n2); } } #endif /* PIKE_DEBUG */
969a291999-11-17Henrik Grubbström (Grubba) 
36dd451999-11-17Henrik Grubbström (Grubba)  free_node(n);
969a291999-11-17Henrik Grubbström (Grubba)  return n2; }
bf2a352003-04-02Martin Nilsson #endif /* SHARED_NODES */
969a291999-11-17Henrik Grubbström (Grubba) 
5267b71995-08-09Fredrik Hübinette (Hubbe) static void optimize(node *n) { node *tmp1, *tmp2, *tmp3;
178e2d1999-12-27Henrik Grubbström (Grubba)  struct pike_string *save_file = lex.current_file;
f639a52003-02-04Martin Stjernholm  INT32 save_line = lex.current_line;
178e2d1999-12-27Henrik Grubbström (Grubba) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  do {
bf4f7d1999-11-12Henrik Grubbström (Grubba)  if(car_is_node(n) && ((CAR(n)->node_info & (OPT_OPTIMIZED|OPT_DEFROSTED)) != OPT_OPTIMIZED))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
bf4f7d1999-11-12Henrik Grubbström (Grubba)  CAR(n)->parent = n; n = CAR(n);
5267b71995-08-09Fredrik Hübinette (Hubbe)  continue; }
bf4f7d1999-11-12Henrik Grubbström (Grubba)  if(cdr_is_node(n) && ((CDR(n)->node_info & (OPT_OPTIMIZED|OPT_DEFROSTED)) != OPT_OPTIMIZED))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
bf4f7d1999-11-12Henrik Grubbström (Grubba)  CDR(n)->parent = n; n = CDR(n);
5267b71995-08-09Fredrik Hübinette (Hubbe)  continue; }
bf4f7d1999-11-12Henrik Grubbström (Grubba)  #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. */
149e372000-09-28Henrik Grubbström (Grubba)  /* Make sure the original isn't defrosted too. */ tmp1->node_info &= ~OPT_DEFROSTED;
bf4f7d1999-11-12Henrik Grubbström (Grubba)  goto use_tmp1; } /* Remove the extra ref from n */ free_node(n);
149e372000-09-28Henrik Grubbström (Grubba)  n->node_info &= ~OPT_DEFROSTED;
bf4f7d1999-11-12Henrik Grubbström (Grubba)  if (n->node_info & OPT_OPTIMIZED) { /* No need to check this node any more. */ n = n->parent; continue; } }
bf2a352003-04-02Martin Nilsson #endif /* SHARED_NODES */
bf4f7d1999-11-12Henrik Grubbström (Grubba) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  lex.current_line = n->line_number;
178e2d1999-12-27Henrik Grubbström (Grubba)  lex.current_file = n->current_file;
66d51c1997-03-04Fredrik Hübinette (Hubbe) 
c3b17f2000-11-27Henrik Grubbström (Grubba) #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 */
5267b71995-08-09Fredrik Hübinette (Hubbe) 
66d51c1997-03-04Fredrik Hübinette (Hubbe)  if(!n->parent) break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(n->tree_info & (OPT_NOT_CONST| OPT_SIDE_EFFECT| OPT_EXTERNAL_DEPEND|
65757d2000-08-31Henrik Grubbström (Grubba)  OPT_ASSIGNMENT|
408a1e2004-10-30Martin Stjernholm  OPT_RETURN| OPT_FLAG_NODE))
5267b71995-08-09Fredrik Hübinette (Hubbe)  { if(car_is_node(n) && !(CAR(n)->tree_info & (OPT_NOT_CONST| OPT_SIDE_EFFECT| OPT_EXTERNAL_DEPEND|
65757d2000-08-31Henrik Grubbström (Grubba)  OPT_ASSIGNMENT|
408a1e2004-10-30Martin Stjernholm  OPT_RETURN| OPT_FLAG_NODE)) &&
5267b71995-08-09Fredrik Hübinette (Hubbe)  (CAR(n)->tree_info & OPT_TRY_OPTIMIZE) &&
6901ff2001-09-29Fredrik Hübinette (Hubbe)  CAR(n)->token != F_VAL_LVAL)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
046afe1999-11-11Henrik Grubbström (Grubba) #ifdef SHARED_NODES sub_node(n); #endif /* SHARED_NODES */ _CAR(n) = eval(CAR(n)); #ifdef SHARED_NODES
bf4f7d1999-11-12Henrik Grubbström (Grubba)  n->node_info |= OPT_DEFROSTED;
a7988a2000-11-26Henrik Grubbström (Grubba)  if (!(n->tree_info & OPT_NOT_SHARED)) { n->hash = hash_node(n); add_node(n); }
046afe1999-11-11Henrik Grubbström (Grubba) #endif /* SHARED_NODES */
5267b71995-08-09Fredrik Hübinette (Hubbe)  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|
65757d2000-08-31Henrik Grubbström (Grubba)  OPT_ASSIGNMENT|
408a1e2004-10-30Martin Stjernholm  OPT_RETURN| OPT_FLAG_NODE)) && (CDR(n)->tree_info & OPT_TRY_OPTIMIZE))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
046afe1999-11-11Henrik Grubbström (Grubba) #ifdef SHARED_NODES sub_node(n); #endif /* SHARED_NODES */ _CDR(n) = eval(CDR(n)); #ifdef SHARED_NODES
bf4f7d1999-11-12Henrik Grubbström (Grubba)  n->node_info |= OPT_DEFROSTED;
a7988a2000-11-26Henrik Grubbström (Grubba)  if (!(n->tree_info & OPT_NOT_SHARED)) { n->hash = hash_node(n); add_node(n); }
046afe1999-11-11Henrik Grubbström (Grubba) #endif /* SHARED_NODES */
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(CDR(n)) CDR(n)->parent = n; zapp_try_optimize(CDR(n)); /* avoid infinite loops */ continue; } }
f68afd1999-11-20Henrik Grubbström (Grubba)  if (!n->type || (n->node_info & OPT_TYPE_NOT_FIXED)) { fix_type_field(n); }
3c0c281998-01-26Fredrik Hübinette (Hubbe)  debug_malloc_touch(n->type);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
66d51c1997-03-04Fredrik Hübinette (Hubbe)  if(l_flag > 3 && n)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
b464611999-11-14Henrik Grubbström (Grubba)  fprintf(stderr,"Optimizing (tree info=%04x):",n->tree_info);
5267b71995-08-09Fredrik Hübinette (Hubbe)  print_tree(n); } #endif switch(n->token) {
7018811999-11-08Henrik Grubbström (Grubba) #include "treeopt.h"
5267b71995-08-09Fredrik Hübinette (Hubbe)  use_car:
71e11e1999-11-12Henrik Grubbström (Grubba)  ADD_NODE_REF2(CAR(n), tmp1 = CAR(n));
5267b71995-08-09Fredrik Hübinette (Hubbe)  goto use_tmp1; use_cdr:
71e11e1999-11-12Henrik Grubbström (Grubba)  ADD_NODE_REF2(CDR(n), tmp1 = CDR(n));
5267b71995-08-09Fredrik Hübinette (Hubbe)  goto use_tmp1;
5392401999-11-06Henrik Grubbström (Grubba)  zap_node: tmp1 = 0; goto use_tmp1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  use_tmp1:
bf4f7d1999-11-12Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG if (l_flag > 4) {
fa74242004-07-06Martin Nilsson  fputs("Optimized: ", stderr);
bf4f7d1999-11-12Henrik Grubbström (Grubba)  print_tree(n);
fa74242004-07-06Martin Nilsson  fputs("Result: ", stderr);
bf4f7d1999-11-12Henrik Grubbström (Grubba)  print_tree(tmp1); } #endif /* PIKE_DEBUG */
046afe1999-11-11Henrik Grubbström (Grubba) #ifdef SHARED_NODES sub_node(n->parent); #endif /* SHARED_NODES */
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(CAR(n->parent) == n)
a836c01999-11-12Henrik Grubbström (Grubba)  _CAR(n->parent) = tmp1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  else
a836c01999-11-12Henrik Grubbström (Grubba)  _CDR(n->parent) = tmp1;
046afe1999-11-11Henrik Grubbström (Grubba) 
f68afd1999-11-20Henrik Grubbström (Grubba)  if (!tmp1 || (tmp1->type != n->type)) { n->parent->node_info |= OPT_TYPE_NOT_FIXED; }
046afe1999-11-11Henrik Grubbström (Grubba) #ifdef SHARED_NODES
bf4f7d1999-11-12Henrik Grubbström (Grubba)  n->parent->node_info |= OPT_DEFROSTED;
a7988a2000-11-26Henrik Grubbström (Grubba)  if (!(n->tree_info & OPT_NOT_SHARED)) { n->parent->hash = hash_node(n->parent); add_node(n->parent); }
046afe1999-11-11Henrik Grubbström (Grubba) #endif /* SHARED_NODES */
5392401999-11-06Henrik Grubbström (Grubba)  if(tmp1) tmp1->parent = n->parent; else tmp1 = n->parent;
046afe1999-11-11Henrik Grubbström (Grubba) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  free_node(n);
046afe1999-11-11Henrik Grubbström (Grubba)  n = tmp1;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(l_flag > 3) {
fa74242004-07-06Martin Nilsson  fputs("Result: ", stderr);
5267b71995-08-09Fredrik Hübinette (Hubbe)  print_tree(n); } #endif continue; } n->node_info |= OPT_OPTIMIZED; n=n->parent; }while(n);
178e2d1999-12-27Henrik Grubbström (Grubba) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  lex.current_line = save_line;
178e2d1999-12-27Henrik Grubbström (Grubba)  lex.current_file = save_file;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
71bde82001-03-16Fredrik Hübinette (Hubbe) void optimize_node(node *n) { if(n && !Pike_compiler->num_parse_error && Pike_compiler->compiler_pass==2 && (n->node_info & OPT_TRY_OPTIMIZE)) { optimize(n); check_tree(n,0); } }
a29e021996-10-15Fredrik Hübinette (Hubbe) struct timer_oflo { INT32 counter; int yes; };
d085c71996-11-18Fredrik Hübinette (Hubbe) static void check_evaluation_time(struct callback *cb,void *tmp,void *ignored)
a29e021996-10-15Fredrik Hübinette (Hubbe) { struct timer_oflo *foo=(struct timer_oflo *)tmp; if(foo->counter-- < 0) { foo->yes=1;
dc7cc91998-01-14Fredrik Hübinette (Hubbe)  pike_throw();
a29e021996-10-15Fredrik Hübinette (Hubbe)  } }
9f85c32002-10-25Marcus Comstedt ptrdiff_t eval_low(node *n,int print_error)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
5c8e891995-10-29Fredrik Hübinette (Hubbe)  unsigned INT16 num_strings, num_constants;
ee6a782003-11-19Henrik Grubbström (Grubba)  unsigned INT32 num_program;
21df0b2002-11-24Henrik Grubbström (Grubba)  size_t jump;
cd86322000-07-06Fredrik Hübinette (Hubbe)  struct svalue *save_sp = Pike_sp;
93b7202000-08-14Henrik Grubbström (Grubba)  ptrdiff_t ret;
5d3afc2003-08-03Martin Stjernholm  struct program *prog = Pike_compiler->new_program;
302ede2001-07-19Henrik Grubbström (Grubba) #ifdef PIKE_USE_MACHINE_CODE size_t num_relocations; #endif /* PIKE_USE_MACHINE_CODE */
5267b71995-08-09Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
66d51c1997-03-04Fredrik Hübinette (Hubbe)  if(l_flag > 3 && n) { fprintf(stderr,"Evaluating (tree info=%x):",n->tree_info); print_tree(n); } #endif
cd2be32004-03-13Henrik Grubbström (Grubba)  if(Pike_compiler->num_parse_error) { return -1; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
ee6a782003-11-19Henrik Grubbström (Grubba)  num_strings = prog->num_strings; num_constants = prog->num_constants; num_program = prog->num_program;
302ede2001-07-19Henrik Grubbström (Grubba) #ifdef PIKE_USE_MACHINE_CODE
5d3afc2003-08-03Martin Stjernholm  num_relocations = prog->num_relocations;
302ede2001-07-19Henrik Grubbström (Grubba) #endif /* PIKE_USE_MACHINE_CODE */
5267b71995-08-09Fredrik Hübinette (Hubbe) 
ee6a782003-11-19Henrik Grubbström (Grubba)  jump = docode(dmalloc_touch(node *, n));
5267b71995-08-09Fredrik Hübinette (Hubbe)  ret=-1;
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(!Pike_compiler->num_parse_error)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
a29e021996-10-15Fredrik Hübinette (Hubbe)  struct callback *tmp_callback; struct timer_oflo foo; /* This is how long we try to optimize before giving up... */ foo.counter=10000; foo.yes=0;
5d3afc2003-08-03Martin Stjernholm  make_program_executable(prog);
f822262001-07-16Fredrik Hübinette (Hubbe) 
a29e021996-10-15Fredrik Hübinette (Hubbe)  tmp_callback=add_to_callback(&evaluator_callbacks, check_evaluation_time, (void *)&foo,0);
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(apply_low_safe_and_stupid(Pike_compiler->fake_object, jump))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
9f85c32002-10-25Marcus Comstedt  if(print_error) /* Generate error message */ if(!Pike_compiler->catch_level)
37dd922003-11-14Martin Stjernholm  handle_compile_exception ("Error evaluating constant.\n");
9f85c32002-10-25Marcus Comstedt  else { free_svalue(&throw_value); throw_value.type = T_INT; }
9036e82001-08-16Martin Stjernholm  else { free_svalue(&throw_value); throw_value.type = T_INT;
9f85c32002-10-25Marcus Comstedt  /* Assume the node will throw errors at runtime too. */ n->tree_info |= OPT_SIDE_EFFECT; n->node_info |= OPT_SIDE_EFFECT;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }else{
a29e021996-10-15Fredrik Hübinette (Hubbe)  if(foo.yes)
cd86322000-07-06Fredrik Hübinette (Hubbe)  pop_n_elems(Pike_sp-save_sp);
a29e021996-10-15Fredrik Hübinette (Hubbe)  else
cd86322000-07-06Fredrik Hübinette (Hubbe)  ret=Pike_sp-save_sp;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
a29e021996-10-15Fredrik Hübinette (Hubbe)  remove_callback(tmp_callback);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
5d3afc2003-08-03Martin Stjernholm  while(prog->num_strings > num_strings)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
5d3afc2003-08-03Martin Stjernholm  prog->num_strings--; free_string(prog->strings[prog->num_strings]);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
5d3afc2003-08-03Martin Stjernholm  while(prog->num_constants > num_constants)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
8132f31999-09-19Henrik Grubbström (Grubba)  struct program_constant *p_const;
5d3afc2003-08-03Martin Stjernholm  prog->num_constants--;
8132f31999-09-19Henrik Grubbström (Grubba) 
5d3afc2003-08-03Martin Stjernholm  p_const = prog->constants + prog->num_constants;
8132f31999-09-19Henrik Grubbström (Grubba)  free_svalue(&p_const->sval);
4ea54f2004-05-29Henrik Grubbström (Grubba) #if 0
8132f31999-09-19Henrik Grubbström (Grubba)  if (p_const->name) { free_string(p_const->name); p_const->name = NULL; }
4ea54f2004-05-29Henrik Grubbström (Grubba) #endif /* 0 */
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
302ede2001-07-19Henrik Grubbström (Grubba) #ifdef PIKE_USE_MACHINE_CODE
5d3afc2003-08-03Martin Stjernholm  prog->num_relocations = num_relocations;
b19aff2002-11-24Henrik Grubbström (Grubba)  #ifdef VALGRIND_DISCARD_TRANSLATIONS /* We won't use this machine code any more... */
ee6a782003-11-19Henrik Grubbström (Grubba)  VALGRIND_DISCARD_TRANSLATIONS(prog->program + num_program, (prog->num_program - num_program)*sizeof(PIKE_OPCODE_T));
b19aff2002-11-24Henrik Grubbström (Grubba) #endif /* VALGRIND_DISCARD_TRANSLATIONS */
302ede2001-07-19Henrik Grubbström (Grubba) #endif /* PIKE_USE_MACHINE_CODE */
5267b71995-08-09Fredrik Hübinette (Hubbe) 
ee6a782003-11-19Henrik Grubbström (Grubba)  prog->num_program=num_program;
b19aff2002-11-24Henrik Grubbström (Grubba) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  return ret; } static node *eval(node *n) {
3facd41999-12-30Martin Stjernholm  node *new;
93b7202000-08-14Henrik Grubbström (Grubba)  ptrdiff_t args;
408a1e2004-10-30Martin Stjernholm  if(!is_const(n) || n->node_info & OPT_FLAG_NODE)
5267b71995-08-09Fredrik Hübinette (Hubbe)  return n;
84191b1999-11-23Henrik Grubbström (Grubba) 
9f85c32002-10-25Marcus Comstedt  args=eval_low(n,0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  switch(args) { case -1: return n; break; case 0:
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->catch_level) return n;
5267b71995-08-09Fredrik Hübinette (Hubbe)  free_node(n); n=0; break; case 1:
9f516a2001-12-16Martin Stjernholm  if(Pike_compiler->catch_level && SAFE_IS_ZERO(Pike_sp-1))
9649491998-02-27Fredrik Hübinette (Hubbe)  { pop_stack(); return n; }
46ab571999-12-30Henrik Grubbström (Grubba)  if (n->token == F_SOFT_CAST) {
cd86322000-07-06Fredrik Hübinette (Hubbe)  new = mksoftcastnode(n->type, mksvaluenode(Pike_sp-1));
46ab571999-12-30Henrik Grubbström (Grubba)  } else {
cd86322000-07-06Fredrik Hübinette (Hubbe)  new = mksvaluenode(Pike_sp-1);
46ab571999-12-30Henrik Grubbström (Grubba)  if (n->type && (!new->type || ((n->type != new->type) && pike_types_le(n->type,new->type)))) { if (new->type)
07f5432001-02-21Henrik Grubbström (Grubba)  free_type(new->type);
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(new->type, n->type);
46ab571999-12-30Henrik Grubbström (Grubba)  }
84191b1999-11-23Henrik Grubbström (Grubba)  }
3facd41999-12-30Martin Stjernholm  free_node(n); n = new;
5267b71995-08-09Fredrik Hübinette (Hubbe)  pop_stack(); break; default:
84191b1999-11-23Henrik Grubbström (Grubba)  if (n->token != F_SOFT_CAST) { free_node(n); n=NULL; while(args--) {
cd86322000-07-06Fredrik Hübinette (Hubbe)  n=mknode(F_ARG_LIST,mksvaluenode(Pike_sp-1),n);
84191b1999-11-23Henrik Grubbström (Grubba)  pop_stack(); } } else { node *nn = n; n = NULL; while(args--) {
cd86322000-07-06Fredrik Hübinette (Hubbe)  n=mknode(F_ARG_LIST,mksvaluenode(Pike_sp-1),n);
84191b1999-11-23Henrik Grubbström (Grubba)  pop_stack(); } n = mksoftcastnode(nn->type, n); free_node(nn);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
a836c01999-11-12Henrik Grubbström (Grubba)  return dmalloc_touch(node *, n);
5267b71995-08-09Fredrik Hübinette (Hubbe) } INT32 last_function_opt_info;
889d232000-09-12Henrik Grubbström (Grubba) /* FIXME: Ought to use parent pointer to avoid recursion. */
329cc01997-02-17Fredrik Hübinette (Hubbe) static int stupid_args(node *n, int expected,int vargs)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
329cc01997-02-17Fredrik Hübinette (Hubbe)  if(!n) return expected;
aee2d32000-09-12Henrik Grubbström (Grubba)  fatal_check_c_stack(16384);
329cc01997-02-17Fredrik Hübinette (Hubbe)  switch(n->token) { case F_PUSH_ARRAY: if(!vargs) return -1; if(stupid_args(CAR(n), expected,vargs) == expected+1) return 65535; return -1; case F_ARG_LIST: expected=stupid_args(CAR(n), expected,vargs); if(expected==-1) return -1; return stupid_args(CDR(n), expected,vargs); case F_LOCAL:
4218011999-01-31Fredrik Hübinette (Hubbe)  return (!n->u.integer.b && n->u.integer.a==expected) ? expected + 1 : -1;
329cc01997-02-17Fredrik Hübinette (Hubbe)  default: return -1; } }
889d232000-09-12Henrik Grubbström (Grubba) /* FIXME: Ought to use parent pointer to avoid recursion. */
9c6f7d1997-04-15Fredrik Hübinette (Hubbe) static int is_null_branch(node *n)
329cc01997-02-17Fredrik Hübinette (Hubbe) { if(!n) return 1;
aee2d32000-09-12Henrik Grubbström (Grubba)  fatal_check_c_stack(16384);
7daa182001-02-23Henrik Grubbström (Grubba)  if((n->token==F_CAST && n->type == void_type_string) ||
2a8cd81999-11-18Henrik Grubbström (Grubba)  n->token == F_POP_VALUE)
329cc01997-02-17Fredrik Hübinette (Hubbe)  return is_null_branch(CAR(n)); if(n->token==F_ARG_LIST) return is_null_branch(CAR(n)) && is_null_branch(CDR(n)); return 0; } static struct svalue *is_stupid_func(node *n, int args,
3aa7831999-06-02Fredrik Hübinette (Hubbe)  int vargs,
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *type)
329cc01997-02-17Fredrik Hübinette (Hubbe) { int tmp; while(1) { if(!n) return 0; if(n->token == F_ARG_LIST) { if(is_null_branch(CAR(n))) n=CDR(n); else n=CAR(n); continue; }
7daa182001-02-23Henrik Grubbström (Grubba)  if((n->token == F_CAST && n->type == void_type_string) ||
2a8cd81999-11-18Henrik Grubbström (Grubba)  n->token == F_POP_VALUE)
329cc01997-02-17Fredrik Hübinette (Hubbe)  { n=CAR(n); continue; } break; }
9669e81997-02-27Fredrik Hübinette (Hubbe)  if(!n || n->token != F_RETURN) return 0;
329cc01997-02-17Fredrik Hübinette (Hubbe)  n=CAR(n);
9669e81997-02-27Fredrik Hübinette (Hubbe)  if(!n || n->token != F_APPLY) return 0;
329cc01997-02-17Fredrik Hübinette (Hubbe)  tmp=stupid_args(CDR(n),0,vargs); if(!(vargs?tmp==65535:tmp==args)) return 0; n=CAR(n);
9669e81997-02-27Fredrik Hübinette (Hubbe)  if(!n || n->token != F_CONSTANT) return 0;
a609b51998-01-28Fredrik Hübinette (Hubbe) 
3aa7831999-06-02Fredrik Hübinette (Hubbe)  if((count_arguments(n->type) < 0) == !vargs) return 0; if(minimum_arguments(type) < minimum_arguments(n->type)) return 0;
a609b51998-01-28Fredrik Hübinette (Hubbe) 
3aa7831999-06-02Fredrik Hübinette (Hubbe)  return &n->u.sval;
329cc01997-02-17Fredrik Hübinette (Hubbe) } int dooptcode(struct pike_string *name, node *n,
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *type,
329cc01997-02-17Fredrik Hübinette (Hubbe)  int modifiers) { union idptr tmp; int args, vargs, ret; struct svalue *foo;
71bde82001-03-16Fredrik Hübinette (Hubbe)  optimize_node(n);
046afe1999-11-11Henrik Grubbström (Grubba)  check_tree(check_node_hash(n),0);
3c0c281998-01-26Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(a_flag > 1)
393a592000-08-16Henrik Grubbström (Grubba)  fprintf(stderr, "Doing function '%s' at %lx\n", name->str,
1302b12001-08-14Martin Stjernholm  DO_NOT_WARN((unsigned long)PIKE_PC));
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif
329cc01997-02-17Fredrik Hübinette (Hubbe)  args=count_arguments(type); if(args < 0) { args=~args; vargs=IDENTIFIER_VARARGS; }else{ vargs=0; }
8322b62000-05-08Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->compiler_frame->lexical_scope & SCOPE_SCOPED)
97f6282000-03-07Fredrik Hübinette (Hubbe)  vargs|=IDENTIFIER_SCOPED;
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->compiler_frame->lexical_scope & SCOPE_SCOPE_USED)
8322b62000-05-08Fredrik Hübinette (Hubbe)  vargs|=IDENTIFIER_SCOPE_USED;
b19aff2002-11-24Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG if(a_flag > 5) fprintf(stderr, "Extra identifier flags:0x%02x\n", vargs); #endif
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->compiler_pass==1)
329cc01997-02-17Fredrik Hübinette (Hubbe)  {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  tmp.offset=-1;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
1b5eb41998-11-17Fredrik Hübinette (Hubbe)  if(a_flag > 4) {
fa74242004-07-06Martin Nilsson  fputs("Making prototype (pass 1) for: ", stderr);
1b5eb41998-11-17Fredrik Hübinette (Hubbe)  print_tree(n); } #endif
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }else{
bf2a352003-04-02Martin Nilsson #if defined(SHARED_NODES) && 0
969a291999-11-17Henrik Grubbström (Grubba)  /* Try the local variable usage analyser. */ n = localopt(check_node_hash(n)); /* Try optimizing some more. */ optimize(n);
bf2a352003-04-02Martin Nilsson #endif /* SHARED_NODES && 0 */
969a291999-11-17Henrik Grubbström (Grubba)  n = mknode(F_ARG_LIST,check_node_hash(n),0);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
046afe1999-11-11Henrik Grubbström (Grubba)  if((foo=is_stupid_func(check_node_hash(n), args, vargs, type)))
329cc01997-02-17Fredrik Hübinette (Hubbe)  {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(foo->type == T_FUNCTION && foo->subtype==FUNCTION_BUILTIN) { tmp.c_fun=foo->u.efun->function;
4879c12000-04-06Fredrik Hübinette (Hubbe)  if(tmp.c_fun != f_destruct && tmp.c_fun != f_this_object && tmp.c_fun != f_backtrace) {
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
4879c12000-04-06Fredrik Hübinette (Hubbe)  if(a_flag > 1) fprintf(stderr,"%s:%d: IDENTIFIER OPTIMIZATION %s == %s\n", lex.current_file->str, lex.current_line, name->str, foo->u.efun->name->str);
1be5391998-01-29Fredrik Hübinette (Hubbe) #endif
03d1cd2000-08-27Henrik Grubbström (Grubba)  ret=define_function(name, type,
2b1b5f2002-02-06Henrik Grubbström (Grubba)  (unsigned INT16)modifiers,
98cf2a2003-02-24Martin Stjernholm  (unsigned INT8)(IDENTIFIER_C_FUNCTION | IDENTIFIER_HAS_BODY | vargs),
1ef5572000-08-30Henrik Grubbström (Grubba)  &tmp, foo->u.efun->flags);
03d1cd2000-08-27Henrik Grubbström (Grubba)  free_node(n);
4879c12000-04-06Fredrik Hübinette (Hubbe)  return ret; }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }
329cc01997-02-17Fredrik Hübinette (Hubbe)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
1302b12001-08-14Martin Stjernholm  tmp.offset=PIKE_PC;
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->compiler_frame->num_args=args;
329cc01997-02-17Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(a_flag > 2) {
fa74242004-07-06Martin Nilsson  fputs("Coding: ", stderr);
c21ee82004-12-18Henrik Grubbström (Grubba)  /*print_tree(check_node_hash(n));*/
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(!Pike_compiler->num_parse_error)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  {
a7538d1998-05-12Fredrik Hübinette (Hubbe)  extern int remove_clear_locals; remove_clear_locals=args; if(vargs) remove_clear_locals++;
852c152001-07-23Fredrik Hübinette (Hubbe)  tmp.offset=do_code_block(check_node_hash(n));
a7538d1998-05-12Fredrik Hübinette (Hubbe)  remove_clear_locals=0x7fffffff;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
329cc01997-02-17Fredrik Hübinette (Hubbe)  ret=define_function(name, type,
2b1b5f2002-02-06Henrik Grubbström (Grubba)  (unsigned INT16)modifiers,
98cf2a2003-02-24Martin Stjernholm  (unsigned INT8)(IDENTIFIER_PIKE_FUNCTION | IDENTIFIER_HAS_BODY | vargs),
9679732001-05-22Henrik Grubbström (Grubba)  Pike_compiler->num_parse_error?NULL:&tmp,
3a1bb12000-09-22Henrik Grubbström (Grubba)  (unsigned INT16) (Pike_compiler->compiler_frame->opt_flags));
329cc01997-02-17Fredrik Hübinette (Hubbe) 
1be5391998-01-29Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
1be5391998-01-29Fredrik Hübinette (Hubbe)  if(a_flag > 1) fprintf(stderr,"Identifer = %d\n",ret); #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  free_node(n);
329cc01997-02-17Fredrik Hübinette (Hubbe)  return ret;
5267b71995-08-09Fredrik Hübinette (Hubbe) }