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. */
aedfb12002-10-09Martin Nilsson 
8504212019-08-15Henrik Grubbström (Grubba) /* NB: Last sync with las.c commit 433f48f9e78dca065f359f71a5c8a42a51b74e1e */
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "global.h" #include "interpret.h" #include "las.h" #include "array.h" #include "object.h" #include "stralloc.h"
2d10fb2016-12-29Arne Goedeke #include "buffer.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #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"
f76b4c2000-05-11Henrik Grubbström (Grubba) #include "opcodes.h"
acae272001-07-20Henrik Grubbström (Grubba) #include "pikecode.h"
cb10a32007-04-27Henrik Grubbström (Grubba) #include "gc.h"
e021fe2008-04-14Henrik Grubbström (Grubba) #include "pike_compiler.h"
44e3402013-10-09Arne Goedeke #include "block_allocator.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);
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:
9e2df02006-10-28Henrik Grubbström (Grubba)  case F_GET_SET:
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:
204df92006-01-21Henrik Grubbström (Grubba)  case F_VERSION:
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; default:
c919c92008-10-12Martin Stjernholm  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:
9e2df02006-10-28Henrik Grubbström (Grubba)  case F_GET_SET:
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:
204df92006-01-21Henrik Grubbström (Grubba)  case F_VERSION:
c0ce662019-10-26Marcus Comstedt  case F_GENERATOR:
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; default:
c919c92008-10-12Martin Stjernholm  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:
9e2df02006-10-28Henrik Grubbström (Grubba)  case F_GET_SET:
cbe8f32000-07-10Henrik Grubbström (Grubba)  case F_TRAMPOLINE: case F_CONSTANT: case F_LOCAL:
204df92006-01-21Henrik Grubbström (Grubba)  case F_VERSION:
cbe8f32000-07-10Henrik Grubbström (Grubba)  return 1;
d819fe2016-10-22Henrik Grubbström (Grubba)  default: /* Inform gcc that we don't care about most values of the enum. */ break;
cbe8f32000-07-10Henrik Grubbström (Grubba)  } 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)  switch(n->token) {
01d4902000-07-11Fredrik Hübinette (Hubbe)  case F_EXTERNAL:
9e2df02006-10-28Henrik Grubbström (Grubba)  case F_GET_SET:
01d4902000-07-11Fredrik Hübinette (Hubbe)  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 } } }
d819fe2016-10-22Henrik Grubbström (Grubba)  default: /* Inform gcc that we don't care about most values of the enum. */ break;
ae7cc02000-09-12Henrik Grubbström (Grubba)  } if(d_flag<2) break;
01d4902000-07-11Fredrik Hübinette (Hubbe) 
47eaff2007-12-15Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG
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)  }
47eaff2007-12-15Henrik Grubbström (Grubba) #endif
889d232000-09-12Henrik Grubbström (Grubba) 
ae7cc02000-09-12Henrik Grubbström (Grubba)  if(car_is_node(n))
889d232000-09-12Henrik Grubbström (Grubba)  {
0b84582007-10-06Henrik Grubbström (Grubba)  /* Update parent for CAR */
ae7cc02000-09-12Henrik Grubbström (Grubba)  CAR(n)->parent = n; 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)) {
0b84582007-10-06Henrik Grubbström (Grubba)  /* Update parent for CDR */
ae7cc02000-09-12Henrik Grubbström (Grubba)  CDR(n)->parent = n; 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 */ CDR(n->parent)->parent = n->parent; 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
c59e382013-08-23Henrik Grubbström (Grubba) static int low_count_args(node *n)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  int a,b;
aee2d32000-09-12Henrik Grubbström (Grubba) 
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:
5073752018-05-26Henrik Grubbström (Grubba)  case F_FOREACH_VAL_LVAL:
5267b71995-08-09Fredrik Hübinette (Hubbe)  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;
c59e382013-08-23Henrik Grubbström (Grubba)  return count_args(CAR(n));
5267b71995-08-09Fredrik Hübinette (Hubbe) 
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));
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 &&
017b572011-10-28Henrik Grubbström (Grubba)  TYPEOF(CAR(n)->u.sval) == T_FUNCTION &&
ee4fe82016-04-26Henrik Grubbström (Grubba)  SUBTYPEOF(CAR(n)->u.sval) == FUNCTION_BUILTIN) {
95d1152016-04-26Henrik Grubbström (Grubba)  if (!n->type) fix_type_field(n);
ee4fe82016-04-26Henrik Grubbström (Grubba)  return !pike_types_le(n->type, void_type_string); }
cd06162000-03-01Fredrik Hübinette (Hubbe)  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; }
5ee9e32018-12-26Henrik Grubbström (Grubba)  UNREACHABLE(return 0);
c59e382013-08-23Henrik Grubbström (Grubba) } INT32 count_args(node *n) { int total = 0; int a,b; node *orig = n; node *orig_parent; node *prev = NULL; check_tree(n,0); fatal_check_c_stack(16384); if(!n) return 0; orig_parent = n->parent; n->parent = NULL; while(1) { int val; while ((n->token == F_COMMA_EXPR) || (n->token == F_VAL_LVAL) ||
5073752018-05-26Henrik Grubbström (Grubba)  (n->token == F_FOREACH_VAL_LVAL) ||
c59e382013-08-23Henrik Grubbström (Grubba)  (n->token == F_ARG_LIST)) { if (CAR(n)) { CAR(n)->parent = n; n = CAR(n); } else if (CDR(n)) { CDR(n)->parent = n; n = CDR(n); } else { /* Unlikely, but... */ goto backtrack; } } /* Leaf. */ val = low_count_args(n); if (val == -1) { total = -1; break; } if (n->parent && (CAR(n->parent) == CDR(n->parent))) { /* Same node in both CDR and CAR ==> count twice. */ val *= 2; } total += val; backtrack: while (n->parent && (!CDR(n->parent) || (n == CDR(n->parent)))) { n = n->parent; } if (!(n = n->parent)) break; /* Found a parent where we haven't visited CDR. */ CDR(n)->parent = n; n = CDR(n); } orig->parent = orig_parent; return total;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
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;
7b92132008-07-15Henrik Grubbström (Grubba)  if (Pike_compiler->compiler_frame->lexical_scope & SCOPE_SCOPE_USED) {
1cfd5b2008-07-14Henrik Grubbström (Grubba)  /* There might be a lambda around that has references to the old context * in which case we can't reuse it with a tail-recursive call. */ return 0; }
d4a1362001-02-09Fredrik Hübinette (Hubbe)  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; }
dbbc862006-08-21Henrik Grubbström (Grubba) static int check_node_type(node *n, struct pike_type *t, const char *msg) {
a5ad9f2021-02-07Henrik Grubbström (Grubba) #if 1 struct pike_type *diff = type_binop(PT_BINOP_MINUS, n->type, t,
33e1a62021-02-15Henrik Grubbström (Grubba)  PT_FLAG_CMP_NULLABLE, PT_FLAG_CMP_NULLABLE, 0);
a5ad9f2021-02-07Henrik Grubbström (Grubba)  if (!diff) return 1; /* Strict match. */ if (diff == n->type) { /* Strict mismatch. */ yytype_report(REPORT_ERROR, NULL, 0, t, NULL, 0, diff, 0, msg); free_type(diff); /* print_tree(n); */ return 0; } if (THIS_COMPILATION->lex.pragmas & ID_STRICT_TYPES) { yytype_report(REPORT_WARNING, NULL, 0, t, NULL, 0, diff, 0, msg); } free_type(diff); #else
dbbc862006-08-21Henrik Grubbström (Grubba)  if (pike_types_le(n->type, t)) return 1; if (!match_types(n->type, t)) {
94d66b2008-05-24Henrik Grubbström (Grubba)  yytype_report(REPORT_ERROR, NULL, 0, t, NULL, 0, n->type, 0, msg);
dbbc862006-08-21Henrik Grubbström (Grubba)  return 0; }
e021fe2008-04-14Henrik Grubbström (Grubba)  if (THIS_COMPILATION->lex.pragmas & ID_STRICT_TYPES) {
94d66b2008-05-24Henrik Grubbström (Grubba)  yytype_report(REPORT_WARNING, NULL, 0, t, NULL, 0, n->type, 0, msg);
dbbc862006-08-21Henrik Grubbström (Grubba)  }
a5ad9f2021-02-07Henrik Grubbström (Grubba) #endif
dbbc862006-08-21Henrik Grubbström (Grubba)  if (runtime_options & RUNTIME_CHECK_TYPES) { node *p = n->parent;
39049b2018-05-30Henrik Grubbström (Grubba)  if (p && (CAR(p) == n)) {
faa3232013-02-19Henrik Grubbström (Grubba)  (_CAR(p) = mksoftcastnode(t, mkcastnode(mixed_type_string, n))) ->parent = p;
39049b2018-05-30Henrik Grubbström (Grubba)  } else if (p && (CDR(p) == n)) {
faa3232013-02-19Henrik Grubbström (Grubba)  (_CDR(p) = mksoftcastnode(t, mkcastnode(mixed_type_string, n))) ->parent = p;
dbbc862006-08-21Henrik Grubbström (Grubba)  } else { yywarning("Failed to find place to insert soft cast."); } } return 1; }
a8ef6e1996-12-03Fredrik Hübinette (Hubbe) 
44e3402013-10-09Arne Goedeke void init_node_s_blocks() { }
011ad31999-10-22Fredrik Hübinette (Hubbe) 
44e3402013-10-09Arne Goedeke void really_free_node_s(node * n) {
1239e72019-11-14Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG if (!Pike_compiler->compiler) { Pike_fatal("Attempt to free a node with no active compiler.\n"); } #endif ba_free(&Pike_compiler->compiler->node_allocator, n);
44e3402013-10-09Arne Goedeke }
1982302002-06-06Martin Stjernholm 
44e3402013-10-09Arne Goedeke MALLOC_FUNCTION node * alloc_node_s() {
1239e72019-11-14Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG if (!Pike_compiler->compiler) { Pike_fatal("Attempt to allocate a node with no active compiler.\n"); } #endif return ba_alloc(&Pike_compiler->compiler->node_allocator);
44e3402013-10-09Arne Goedeke }
3aab372002-11-24Martin Stjernholm 
44e3402013-10-09Arne Goedeke void count_memory_in_node_ss(size_t * num, size_t * size) { struct program_state * state = Pike_compiler;
a8ef6e1996-12-03Fredrik Hübinette (Hubbe) 
44e3402013-10-09Arne Goedeke  *num = 0; *size = 0; while (state) {
1239e72019-11-14Henrik Grubbström (Grubba)  /* NB: Pike_compiler_base has no active compiler. */ if (state->compiler) {
44e3402013-10-09Arne Goedeke  size_t _num, _size;
ff075c2019-11-14Henrik Grubbström (Grubba)  ba_count_all(&state->compiler->node_allocator, &_num, &_size);
44e3402013-10-09Arne Goedeke  *num += _num; *size += _size;
1239e72019-11-14Henrik Grubbström (Grubba)  } state = state->previous;
44e3402013-10-09Arne Goedeke  } }
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) 
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) #endif /* PIKE_DEBUG */ return;
046afe1999-11-11Henrik Grubbström (Grubba)  }
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);
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 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) 
d819fe2016-10-22Henrik Grubbström (Grubba)  /* NB: Cast below is to get gcc to stop complaining about * USHRT_MAX not being in the enum. */ switch((int)n->token)
03ef8b2000-09-13Henrik Grubbström (Grubba)  { 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;
d819fe2016-10-22Henrik Grubbström (Grubba)  default: /* Inform gcc that we don't care about most values of the enum. */ break;
03ef8b2000-09-13Henrik Grubbström (Grubba)  } if (car_is_node(n)) { /* Free CAR */
50ea682003-03-14Henrik Grubbström (Grubba)  if (sub_ref(_CAR(n))) {
03ef8b2000-09-13Henrik Grubbström (Grubba)  _CAR(n) = NULL; } else { _CAR(n)->parent = n; n = _CAR(n); _CAR(n->parent) = NULL; continue; } } if (cdr_is_node(n)) { /* Free CDR */
1b5eb41998-11-17Fredrik Hübinette (Hubbe) 
50ea682003-03-14Henrik Grubbström (Grubba)  if (sub_ref(_CDR(n))) {
03ef8b2000-09-13Henrik Grubbström (Grubba)  _CDR(n) = NULL; } else { _CDR(n)->parent = n; n = _CDR(n); _CDR(n->parent) = NULL; continue; } } backtrack: while (n->parent && !cdr_is_node(n->parent)) { /* Kill the node and backtrack */ node *dead = n;
0b84582007-10-06Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG
03ef8b2000-09-13Henrik Grubbström (Grubba)  if (dead->refs) {
0b84582007-10-06Henrik Grubbström (Grubba)  print_tree(dead); Pike_fatal("Killed node %p (%d) still has refs: %d\n", dead, dead->token, dead->refs);
03ef8b2000-09-13Henrik Grubbström (Grubba)  }
0b84582007-10-06Henrik Grubbström (Grubba) #endif /* 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) 
0b84582007-10-06Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG
03ef8b2000-09-13Henrik Grubbström (Grubba)  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)  }
0b84582007-10-06Henrik Grubbström (Grubba) #endif /* PIKE_DEBUG */
03ef8b2000-09-13Henrik Grubbström (Grubba)  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);
50ea682003-03-14Henrik Grubbström (Grubba)  if (sub_ref(_CDR(n))) {
03ef8b2000-09-13Henrik Grubbström (Grubba)  _CDR(n) = NULL; goto backtrack; } else { _CDR(n)->parent = n; n = _CDR(n); _CDR(n->parent) = NULL; continue; } } /* Kill root node. */
0b84582007-10-06Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG
03ef8b2000-09-13Henrik Grubbström (Grubba)  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)  }
0b84582007-10-06Henrik Grubbström (Grubba) #endif /* PIKE_DEBUG */
03ef8b2000-09-13Henrik Grubbström (Grubba) 
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) } /* 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) 
e021fe2008-04-14Henrik Grubbström (Grubba)  CHECK_COMPILER();
0b84582007-10-06Henrik Grubbström (Grubba) #ifdef __CHECKER__
21b12a2014-09-03Martin Nilsson  memset(res, 0, sizeof(node));
0b84582007-10-06Henrik Grubbström (Grubba) #endif /* __CHECKER__ */
50ea682003-03-14Henrik Grubbström (Grubba)  res->refs = 0; add_ref(res); /* For DMALLOC... */
a8ef6e1996-12-03Fredrik Hübinette (Hubbe)  res->token=0;
e021fe2008-04-14Henrik Grubbström (Grubba)  res->line_number=THIS_COMPILATION->lex.current_line; copy_shared_string(res->current_file, THIS_COMPILATION->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; } }
bdb12f2018-11-28Henrik Grubbström (Grubba) static int apply_opt_flags_for_ref(struct program *prog, int fun); static int apply_opt_flags_for_sval(struct svalue *s) { switch(TYPEOF(*s)) { case T_FUNCTION: if (SUBTYPEOF(*s) == FUNCTION_BUILTIN) { return s->u.efun->flags; } if (s->u.object->prog) { return apply_opt_flags_for_ref(s->u.object->prog, SUBTYPEOF(*s)); } yyerror("Calling function in destructed module."); break; case T_PROGRAM: if (s->u.program->flags & PROGRAM_CONSTANT) { return 0; } break; case T_OBJECT: if (!s->u.object->prog) { break; } return apply_opt_flags_for_ref(s->u.object->prog, FIND_LFUN(s->u.object->prog, LFUN_CALL)); } return OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND; } static int apply_opt_flags_for_ref(struct program *prog, int fun) { if (!prog) { yyerror("Calling function in destructed object."); } else if (fun < 0) { yyerror("Attempt to call a missing function."); } else { struct identifier *id = ID_FROM_INT(prog, fun); struct program *p = PROG_FROM_INT(prog, fun); if (IDENTIFIER_IS_FUNCTION(id->identifier_flags)) { return id->opt_flags; } if (IDENTIFIER_IS_CONSTANT(id->identifier_flags)) { DECLARE_CYCLIC(); struct svalue *s = &p->constants[id->func.const_info.offset].sval; int ret; if ((ret = (size_t)BEGIN_CYCLIC(p, s))) { return ret; } SET_CYCLIC_RET(OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND); ret = apply_opt_flags_for_sval(s); END_CYCLIC(); return ret; } } return OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND; }
8bef1b2001-09-27Fredrik Hübinette (Hubbe) 
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;
ccdb522017-10-01Henrik Grubbström (Grubba)  case F_ASSIGN: case F_MULTI_ASSIGN: case F_ASSIGN_SELF:
ed61452021-02-27Henrik Grubbström (Grubba)  case F_INITIALIZE:
bdfe4e2017-12-11Henrik Grubbström (Grubba)  if ((!a || a->token == F_CONSTANT) && (Pike_compiler->compiler_pass == COMPILER_PASS_LAST)) {
ccdb522017-10-01Henrik Grubbström (Grubba)  yyerror("Illegal lvalue."); } break;
88bc272002-08-12Henrik Grubbström (Grubba) #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_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");
9e2df02006-10-28Henrik Grubbström (Grubba)  case F_GET_SET: Pike_fatal("Attempt to create an F_GET_SET-node with mknode()!\n");
88bc272002-08-12Henrik Grubbström (Grubba) #endif /* PIKE_DEBUG */
c18e2f2014-10-30Per Hedbor  #define OPERNODE(X,Y) case X: return mkopernode(("`" #Y), a, b ) OPERNODE(F_LT,<); OPERNODE(F_GT,>); OPERNODE(F_LE,<=); OPERNODE(F_GE,>=); OPERNODE(F_EQ,==); OPERNODE(F_NE,!=); OPERNODE(F_ADD,+); OPERNODE(F_SUBTRACT,-); OPERNODE(F_DIVIDE,/); OPERNODE(F_MULTIPLY,*); OPERNODE(F_MOD,%); OPERNODE(F_LSH,<<); OPERNODE(F_RSH,>>); OPERNODE(F_OR,|); OPERNODE(F_AND,&); OPERNODE(F_XOR,^); OPERNODE(F_NOT,!); OPERNODE(F_COMPL,~); #if 0 OPERNODE(F_NEGATE,-); #endif #undef OPERNODE
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  }
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);
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; if (a) { switch(a->token) { case F_CONSTANT:
017b572011-10-28Henrik Grubbström (Grubba)  switch(TYPEOF(a->u.sval))
f3c7152001-04-14Fredrik Hübinette (Hubbe)  { case T_FUNCTION:
bdb12f2018-11-28Henrik Grubbström (Grubba)  opt_flags = apply_opt_flags_for_sval(&a->u.sval);
f3c7152001-04-14Fredrik Hübinette (Hubbe)  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:
9e2df02006-10-28Henrik Grubbström (Grubba)  case F_GET_SET:
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) {
bdb12f2018-11-28Henrik Grubbström (Grubba)  opt_flags = apply_opt_flags_for_ref(state->new_program, a->u.integer.b);
1ef5572000-08-30Henrik Grubbström (Grubba)  } else { yyerror("Parent has left."); } } break; case F_LOCAL: /* FIXME: Should lookup functions in the local scope. */ default: res->tree_info |= a->tree_info; } }
bdb12f2018-11-28Henrik Grubbström (Grubba)  res->node_info |= opt_flags | OPT_APPLY;
1ef5572000-08-30Henrik Grubbström (Grubba)  if(b) res->tree_info |= b->tree_info;
34f5362018-02-13Henrik Grubbström (Grubba)  if (res->node_info & OPT_EXTERNAL_DEPEND) { /* Applying something that has external dependencies * renders a result that isn't constant. */ res->tree_info |= OPT_NOT_CONST; }
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);
13670c2015-05-25Martin Nilsson 
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;
5f50842018-02-12Marcus Comstedt  /* FALLTHRU */
b464611999-11-14Henrik Grubbström (Grubba)  case F_MAGIC_INDEX:
cbe1132001-12-16Martin Stjernholm  case F_MAGIC_INDICES: case F_MAGIC_VALUES:
7195af2011-01-15Henrik Grubbström (Grubba)  case F_MAGIC_TYPES:
6c22d22018-12-19Henrik Grubbström (Grubba)  case F_MAGIC_ANNOTATIONS:
1c1c5e2001-04-08Fredrik Hübinette (Hubbe)  { int e; struct program_state *state = Pike_compiler; res->node_info |= OPT_EXTERNAL_DEPEND;
032b052008-01-16Henrik Grubbström (Grubba)  if (!b) break; /* Paranoia; probably compiler error. */
1c1c5e2001-04-08Fredrik Hübinette (Hubbe)  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; }
13670c2015-05-25Martin Nilsson 
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) 
02f17a2007-12-17Henrik Grubbström (Grubba)  case F_APPEND_ARRAY:
e3832f2014-10-02Per Hedbor  case F_APPEND_MAPPING:
fe935d2008-01-28Henrik Grubbström (Grubba)  case F_MULTI_ASSIGN:
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_ASSIGN:
4e1b092014-09-30Henrik Grubbström (Grubba)  case F_ASSIGN_SELF:
ed61452021-02-27Henrik Grubbström (Grubba)  case F_INITIALIZE:
b464611999-11-14Henrik Grubbström (Grubba)  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;
710fa92019-02-14Henrik Grubbström (Grubba)  case F_SET_LOCAL_NAME: case F_SET_LOCAL_TYPE: case F_SET_LOCAL_END: /* Protect against the node being removed by the optimizer. */ res->node_info |= OPT_NOT_CONST|OPT_SIDE_EFFECT; break;
906b9e2021-03-01Henrik Grubbström (Grubba)  case '?': if (b && (b->token == ':') && CDR(b)) { /* There's an else statement. */ goto set_default_tree_info; } /* FALLTHRU */ case F_FOR: case F_LAND: if (Pike_compiler->compiler_pass == COMPILER_PASS_LAST) { if (a && (a->token == F_INITIALIZE)) { /* Special case to handle code like: * * if (string foo = expr) { xxx; } * while (string foo = expr) { xxx; } * for (;string foo = expr;yyy) { xxx; } * (string foo = expr) && xxx; * * where foo never will be zero even though expr may * very well be zero. */ fix_type_field(CDR(a)); if (CDR(a)->type && (CDR(a)->type != mixed_type_string)) { struct pike_type *not_zero = type_binop(PT_BINOP_MINUS, CDR(a)->type, zero_type_string, 0, 0, 0); if (not_zero && (not_zero != CDR(a)->type)) { free_type(CDR(a)->type); _CDR(a)->type = not_zero; } else { free_type(not_zero); } } } } goto set_default_tree_info;
046afe1999-11-11Henrik Grubbström (Grubba)  default:
906b9e2021-03-01Henrik Grubbström (Grubba)  set_default_tree_info:
046afe1999-11-11Henrik Grubbström (Grubba)  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;
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) 
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; }
911d012019-02-15Henrik Grubbström (Grubba) static node *vmknestednodes(int token, va_list args) { node *n = va_arg(args, node *); if (!n) return n; return mknode(token, n, vmknestednodes(token, args)); } node *mknestednodes(int token, ...) { va_list args; node *res; va_start(args, token); res = vmknestednodes(token, args); va_end(args); 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;
017b572011-10-28Henrik Grubbström (Grubba)  SET_SVAL(res->u.sval, T_STRING, 0, string, str); add_ref(str);
fe2a2c2007-03-05Henrik Grubbström (Grubba)  res->type = get_type_of_svalue(&res->u.sval);
7869512008-07-18Martin Stjernholm  res->tree_info = OPT_SAFE;
0b84582007-10-06Henrik Grubbström (Grubba)  return 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;
017b572011-10-28Henrik Grubbström (Grubba)  SET_SVAL(res->u.sval, T_INT, NUMBER_NUMBER, integer, nr);
b660c81999-03-01Fredrik Hübinette (Hubbe)  res->type=get_type_of_svalue( & res->u.sval);
7869512008-07-18Martin Stjernholm  res->tree_info = OPT_SAFE;
046afe1999-11-11Henrik Grubbström (Grubba) 
0b84582007-10-06Henrik Grubbström (Grubba)  return res;
046afe1999-11-11Henrik Grubbström (Grubba) }
69aa4b2003-01-26Mirar (Pontus Hagland) node *debug_mknewintnode(INT_TYPE nr)
046afe1999-11-11Henrik Grubbström (Grubba) { node *res = mkemptynode(); res->token = F_CONSTANT;
017b572011-10-28Henrik Grubbström (Grubba)  SET_SVAL(res->u.sval, T_INT, NUMBER_NUMBER, integer, nr);
046afe1999-11-11Henrik Grubbström (Grubba)  res->type=get_type_of_svalue( & res->u.sval);
7869512008-07-18Martin Stjernholm  res->tree_info = OPT_SAFE;
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);
017b572011-10-28Henrik Grubbström (Grubba)  SET_SVAL(res->u.sval, T_FLOAT, 0, float_number, foo);
7869512008-07-18Martin Stjernholm  res->tree_info = OPT_SAFE;
046afe1999-11-11Henrik Grubbström (Grubba) 
0b84582007-10-06Henrik Grubbström (Grubba)  return 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;
017b572011-10-28Henrik Grubbström (Grubba)  SET_SVAL(s, T_PROGRAM, 0, program, p);
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); }
204df92006-01-21Henrik Grubbström (Grubba) node *debug_mkversionnode(int major, int minor) { node *res = mkemptynode(); res->token = F_VERSION; #ifdef __CHECKER__ _CDR(res) = 0; #endif res->u.integer.a = major; res->u.integer.b = minor;
0b84582007-10-06Henrik Grubbström (Grubba)  return res;
204df92006-01-21Henrik Grubbström (Grubba) }
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) 
0b84582007-10-06Henrik Grubbström (Grubba)  res->node_info = OPT_NOT_CONST;
a836c01999-11-12Henrik Grubbström (Grubba)  res->tree_info = res->node_info;
81bd142018-05-23Henrik Grubbström (Grubba)  if (res->type && (res->type->type == PIKE_T_AUTO)) { res->node_info |= OPT_TYPE_NOT_FIXED; }
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;
c981662006-03-02Henrik Grubbström (Grubba)  if (depth < 0) { /* First appearance of this variable. * Add initialization code. */ res->node_info |= OPT_ASSIGNMENT; res->u.integer.b = 0; } else { res->u.integer.b = depth; }
046afe1999-11-11Henrik Grubbström (Grubba) 
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) {
da77e22000-09-08Fredrik Hübinette (Hubbe)  node *res = mkexternalnode(Pike_compiler->new_program, i); check_tree(res,0); return res;
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;
13670c2015-05-25Martin Nilsson 
8c70ba2001-09-28Fredrik Hübinette (Hubbe)  for(f=Pike_compiler->compiler_frame;f != frame;f=f->previous) f->lexical_scope|=SCOPE_SCOPED; f->lexical_scope|=SCOPE_SCOPE_USED; res->u.trampoline.prog = Pike_compiler->new_program;
bf4f7d1999-11-12Henrik Grubbström (Grubba)  check_tree(res,0); return res; }
d2d30d2019-08-24Henrik Grubbström (Grubba) node *debug_mkgeneratornode(int i) { node *res = mkemptynode(); res->token = F_GENERATOR; _CAR(res) = mktrampolinenode(i, Pike_compiler->compiler_frame); copy_pike_type(res->type, CAR(res)->type); res->node_info = OPT_NOT_CONST;
d69a212019-08-26Henrik Grubbström (Grubba)  return res;
d2d30d2019-08-24Henrik Grubbström (Grubba) }
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 */
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;
0b84582007-10-06Henrik Grubbström (Grubba)  Pike_compiler->compiler_frame->opt_flags |= OPT_EXTERNAL_DEPEND;
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_string(id->name); }
01d4902000-07-11Fredrik Hübinette (Hubbe) #endif
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
04802d2007-10-11Henrik Grubbström (Grubba)  /* Mark the identifier reference as used. */ PTR_FROM_INT(parent_prog, i)->id_flags |= ID_USED;
5d642e2003-08-03Martin Stjernholm  copy_pike_type(res->type, id->type);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
9f5cf12012-03-06Henrik Grubbström (Grubba)  /* FIXME: The IDENTIFIER_IS_ALIAS case isn't handled! */
5d642e2003-08-03Martin Stjernholm  if(IDENTIFIER_IS_CONSTANT(id->identifier_flags)) {
afb16a2010-11-11Henrik Grubbström (Grubba)  if (!(PTR_FROM_INT(parent_prog, i)->id_flags & ID_LOCAL)) { /* It's possible to overload the identifier. */ res->node_info = OPT_EXTERNAL_DEPEND;
89378b2010-11-23Henrik Grubbström (Grubba)  } else if (id->func.const_info.offset != -1) {
9f5cf12012-03-06Henrik Grubbström (Grubba)  struct program *p = PROG_FROM_INT(parent_prog, i); struct svalue *s = &p->constants[id->func.const_info.offset].sval;
017b572011-10-28Henrik Grubbström (Grubba)  if ((TYPEOF(*s) == T_PROGRAM) &&
afb16a2010-11-11Henrik Grubbström (Grubba)  (s->u.program->flags & PROGRAM_USES_PARENT)) { /* The constant program refers to its parent, so we need as well. */ res->node_info = OPT_EXTERNAL_DEPEND; } }
5d642e2003-08-03Martin Stjernholm  }else{ res->node_info = OPT_NOT_CONST;
9e2df02006-10-28Henrik Grubbström (Grubba)  if (IDENTIFIER_IS_VARIABLE(id->identifier_flags) && (id->run_time_type == PIKE_T_GET_SET)) { /* Special case of F_EXTERNAL for ease of detection. */ res->token = F_GET_SET; }
5d642e2003-08-03Martin Stjernholm  }
0b84582007-10-06Henrik Grubbström (Grubba)  if (i) { Pike_compiler->compiler_frame->opt_flags |= OPT_EXTERNAL_DEPEND; }
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) 
7c3fe02009-11-20Henrik Grubbström (Grubba) #if 0
883c732009-11-19Henrik Grubbström (Grubba)  /* Don't do this if res about to get inherited, since the inherit won't * be affected by later overloading of the inherited class in our parents. */
e54fb52009-11-19Henrik Grubbström (Grubba) /* if (!(Pike_compiler->flags & COMPILATION_FORCE_RESOLVE)) { */
883c732009-11-19Henrik 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; }
e54fb52009-11-19Henrik Grubbström (Grubba) /* } */
7c3fe02009-11-20Henrik Grubbström (Grubba) #endif /* 0 */
1994251999-09-06Fredrik Hübinette (Hubbe) 
da77e22000-09-08Fredrik Hübinette (Hubbe)  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
388e5d2008-05-30Henrik Grubbström (Grubba)  if ((inherit_num < -1) || (inherit_num > 65535)) {
c21ee82004-12-18Henrik Grubbström (Grubba)  Pike_fatal("This is bad: %p, %d\n", parent_prog, inherit_num); } #endif /* PIKE_DEBUG */ res = mkemptynode(); res->token = F_THIS; type_stack_mark();
388e5d2008-05-30Henrik Grubbström (Grubba)  if (inherit_num >= 0) { push_object_type(1, parent_prog->inherits[inherit_num].prog->id); } else { push_object_type(0, parent_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; }
0b84582007-10-06Henrik Grubbström (Grubba)  return res;
c21ee82004-12-18Henrik Grubbström (Grubba) }
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;
6d48f12007-11-20Henrik Grubbström (Grubba)  /* FIXME: Consider strengthening the node type [bug 4435]. * E.g. the cast in the code * * mapping(string:string) m = (["a":"A", "b":"B"]); * return (array)m; * * should have a result type of array(array(string)), * rather than array(mixed).
13670c2015-05-25Martin Nilsson  */
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(res->type, type);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
9403422010-11-18Henrik Grubbström (Grubba)  if((type != zero_type_string) && (match_types(object_type_string, type) || 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) 
0b84582007-10-06Henrik Grubbström (Grubba)  return 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;
a8f0be2007-04-13Henrik Grubbström (Grubba)  struct pike_type *result_type = NULL;
1d480f1999-11-23Henrik Grubbström (Grubba)  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 */
bdfe4e2017-12-11Henrik Grubbström (Grubba)  if (Pike_compiler->compiler_pass == COMPILER_PASS_LAST && type->type != PIKE_T_AUTO ) {
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) {
c15dc12021-02-07Henrik Grubbström (Grubba)  if (!(result_type = soft_cast(type, n->type, SOFT_WEAKER))) {
94d66b2008-05-24Henrik Grubbström (Grubba)  ref_push_type_value(n->type); ref_push_type_value(type); yytype_report(REPORT_ERROR,
0b36af2013-02-19Henrik Grubbström (Grubba)  NULL, 0, type, NULL, 0, n->type,
94d66b2008-05-24Henrik Grubbström (Grubba)  2, "Soft cast of %O to %O isn't a valid cast.");
d4b9ec2007-04-16Henrik Grubbström (Grubba)  } else if (result_type == n->type) {
94d66b2008-05-24Henrik Grubbström (Grubba)  ref_push_type_value(n->type); ref_push_type_value(type); yytype_report(REPORT_WARNING, NULL, 0, NULL, NULL, 0, NULL, 2, "Soft cast of %O to %O is a noop.");
a8f0be2007-04-13Henrik Grubbström (Grubba)  }
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;
a8f0be2007-04-13Henrik Grubbström (Grubba)  if (result_type) { res->type = result_type; } else { 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;
0b84582007-10-06Henrik Grubbström (Grubba)  return res;
1d480f1999-11-23Henrik Grubbström (Grubba) }
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:
9e2df02006-10-28Henrik Grubbström (Grubba)  case F_GET_SET:
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) {
9233282008-08-16Henrik Grubbström (Grubba)  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;
591c0c1997-01-19Fredrik Hübinette (Hubbe)  case F_LOCAL:
9250a61998-07-20Henrik Grubbström (Grubba)  /* FIXME: Ought to have the name of the identifier in the message. */
9233282008-08-16Henrik Grubbström (Grubba)  yyerror("Expected constant, got local variable.");
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  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. */
9233282008-08-16Henrik Grubbström (Grubba)  yyerror("Expected constant, got global variable.");
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  push_int(0); return;
b69ede1998-04-09Fredrik Hübinette (Hubbe)  case F_UNDEFINED:
bdfe4e2017-12-11Henrik Grubbström (Grubba)  if(Pike_compiler->compiler_pass == COMPILER_PASS_LAST) {
9250a61998-07-20Henrik Grubbström (Grubba)  /* FIXME: Ought to have the name of the identifier in the message. */
9233282008-08-16Henrik Grubbström (Grubba)  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)  {
1adcc92018-02-14Henrik Grubbström (Grubba)  if(is_const(n))
c5c2ff1999-07-06Fredrik Hübinette (Hubbe)  {
1adcc92018-02-14Henrik Grubbström (Grubba)  ptrdiff_t args=eval_low(n,1);
c5c2ff1999-07-06Fredrik Hübinette (Hubbe)  if(args==1) return; if(args!=-1) { if(!args) {
9233282008-08-16Henrik Grubbström (Grubba)  yyerror("Expected constant, got void expression.");
c5c2ff1999-07-06Fredrik Hübinette (Hubbe)  }else{
a4a1722000-12-05Per Hedbor  yyerror("Possible internal error!!!");
bd67392015-10-14Martin Nilsson  pop_n_elems(args-1);
c5c2ff1999-07-06Fredrik Hübinette (Hubbe)  return; }
9233282008-08-16Henrik Grubbström (Grubba)  } else { yyerror("Failed to evaluate constant expression.");
c5c2ff1999-07-06Fredrik Hübinette (Hubbe)  }
9233282008-08-16Henrik Grubbström (Grubba)  } else { yyerror("Expected constant expression.");
c5c2ff1999-07-06Fredrik Hübinette (Hubbe)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  push_int(0); return; }
c5c2ff1999-07-06Fredrik Hübinette (Hubbe)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
b0abf62009-11-09Henrik Grubbström (Grubba)  i = ID_FROM_INT(p, numid);
13670c2015-05-25Martin Nilsson 
086acc1999-09-11Fredrik Hübinette (Hubbe)  /* Warning: * This code doesn't produce function pointers for class constants, * which can be harmful... * /Hubbe */
13670c2015-05-25Martin Nilsson 
b0abf62009-11-09Henrik Grubbström (Grubba)  if (IDENTIFIER_IS_ALIAS(i->identifier_flags)) { struct external_variable_context loc; loc.o = Pike_compiler->fake_object; do { loc.inherit = INHERIT_FROM_INT(p, numid); loc.parent_identifier = 0; find_external_context(&loc, i->func.ext_ref.depth); numid = i->func.ext_ref.id; p = loc.o->prog; i = ID_FROM_INT(p, numid); } while (IDENTIFIER_IS_ALIAS(i->identifier_flags)); }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(IDENTIFIER_IS_CONSTANT(i->identifier_flags)) {
89378b2010-11-23Henrik Grubbström (Grubba)  if(i->func.const_info.offset != -1)
e945ee2000-02-09Fredrik Hübinette (Hubbe)  {
89378b2010-11-23Henrik Grubbström (Grubba)  push_svalue(&PROG_FROM_INT(p, numid)-> constants[i->func.const_info.offset].sval);
e945ee2000-02-09Fredrik Hübinette (Hubbe)  }else{
bdfe4e2017-12-11Henrik Grubbström (Grubba)  if(Pike_compiler->compiler_pass != COMPILER_PASS_FIRST)
e945ee2000-02-09Fredrik Hübinette (Hubbe)  yyerror("Constant is not defined yet."); push_int(0); }
b0abf62009-11-09Henrik Grubbström (Grubba)  } 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);
017b572011-10-28Henrik Grubbström (Grubba)  switch(TYPEOF(Pike_sp[-1]))
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{
4f33c62012-10-27Henrik Grubbström (Grubba)  o_cast(program_type_string, T_PROGRAM);
61e9a01998-01-25Fredrik Hübinette (Hubbe)  } break;
01a9572000-02-03Henrik Grubbström (Grubba) 
086acc1999-09-11Fredrik Hübinette (Hubbe)  default:
bdfe4e2017-12-11Henrik Grubbström (Grubba)  if (Pike_compiler->compiler_pass != COMPILER_PASS_FIRST)
a786431999-11-18Martin Stjernholm  yyerror("Illegal program identifier");
086acc1999-09-11Fredrik Hübinette (Hubbe)  pop_stack(); push_int(0);
13670c2015-05-25Martin Nilsson 
086acc1999-09-11Fredrik Hübinette (Hubbe)  case T_FUNCTION: case T_PROGRAM: break; } }
94d5aa2017-11-25Henrik Grubbström (Grubba) void resolv_type(node *n)
086acc1999-09-11Fredrik Hübinette (Hubbe) {
94d5aa2017-11-25Henrik Grubbström (Grubba)  resolv_constant(n);
086acc1999-09-11Fredrik Hübinette (Hubbe) 
8e38712017-11-27Henrik Grubbström (Grubba)  if (TYPEOF(Pike_sp[-1]) == T_STRING) { /* Program name, etc */ if (call_handle_inherit(n->u.sval.u.string)) { stack_swap(); pop_stack(); } }
94d5aa2017-11-25Henrik Grubbström (Grubba)  if (TYPEOF(Pike_sp[-1]) == T_TYPE) { /* "typedef" */ push_finished_type(Pike_sp[-1].u.type); } else { /* object type */ struct program *p = NULL;
38f9312014-05-03Henrik Grubbström (Grubba) 
94d5aa2017-11-25Henrik Grubbström (Grubba)  if (TYPEOF(Pike_sp[-1]) == T_OBJECT) { if(!(p = Pike_sp[-1].u.object->prog)) { pop_stack(); push_int(0); yyerror("Destructed object used as program identifier."); }else{ int f = FIND_LFUN(p->inherits[SUBTYPEOF(Pike_sp[-1])].prog, LFUN_CALL); if(f!=-1) { SET_SVAL_SUBTYPE(Pike_sp[-1], f + p->inherits[SUBTYPEOF(Pike_sp[-1])]. identifier_level); SET_SVAL_TYPE(Pike_sp[-1], T_FUNCTION); }else{ extern void f_object_program(INT32);
bdfe4e2017-12-11Henrik Grubbström (Grubba)  if (Pike_compiler->compiler_pass == COMPILER_PASS_LAST)
94d5aa2017-11-25Henrik Grubbström (Grubba)  yywarning("Using object as program identifier."); f_object_program(1); } } }
38f9312014-05-03Henrik Grubbström (Grubba) 
94d5aa2017-11-25Henrik Grubbström (Grubba)  switch(TYPEOF(Pike_sp[-1])) {
61e9a01998-01-25Fredrik Hübinette (Hubbe)  case T_FUNCTION:
94d5aa2017-11-25Henrik Grubbström (Grubba)  if((p = program_from_function(Pike_sp-1))) {
d6d43e2017-11-26Martin Nilsson  push_object_type(0, p->id);
61e9a01998-01-25Fredrik Hübinette (Hubbe)  break;
94d5aa2017-11-25Henrik Grubbström (Grubba)  } else { /* Attempt to get the return type for the function. */ struct pike_type *a, *b; a = get_type_of_svalue(Pike_sp-1); /* Note: check_splice_call() below eats a reference from a. * Note: CALL_INHIBIT_WARNINGS is needed since we don't * provide a function name (and we don't want * warnings here anyway). */ a = check_splice_call(NULL, a, 0, mixed_type_string, NULL, CALL_INHIBIT_WARNINGS); if (a) { b = new_get_return_type(a, 0); free_type(a); if (b) { push_finished_type(b); free_type(b); break; } } }
5f50842018-02-12Marcus Comstedt  /* FALLTHRU */
13670c2015-05-25Martin Nilsson 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  default:
4dab7a2017-12-19Henrik Grubbström (Grubba)  if (Pike_compiler->compiler_pass == COMPILER_PASS_FIRST) { /* The type isn't fully known yet, so do an extra pass. */ struct compilation *c = THIS_COMPILATION; c->flags |= COMPILER_NEED_EXTRA_PASS; } else {
94d5aa2017-11-25Henrik Grubbström (Grubba)  my_yyerror("Illegal program identifier: %O.", Pike_sp-1);
4dab7a2017-12-19Henrik Grubbström (Grubba)  }
94d5aa2017-11-25Henrik Grubbström (Grubba)  push_object_type(0, 0); break;
13670c2015-05-25Martin Nilsson 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  case T_PROGRAM:
94d5aa2017-11-25Henrik Grubbström (Grubba)  p = Pike_sp[-1].u.program;
cb1f782017-11-26Henrik Grubbström (Grubba)  push_object_type(0, p->id);
61e9a01998-01-25Fredrik Hübinette (Hubbe)  break;
94d5aa2017-11-25Henrik Grubbström (Grubba)  }
61e9a01998-01-25Fredrik Hübinette (Hubbe)  }
cb1f782017-11-26Henrik Grubbström (Grubba)  pop_stack();
61e9a01998-01-25Fredrik Hübinette (Hubbe) }
43133e2016-07-29Arne Goedeke node *index_node(node * const 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);
3a30d72014-10-05Martin Nilsson  if (!is_const(n)) {
9e015e2005-07-13Henrik Grubbström (Grubba)  /* Index dynamically. */
bdfe4e2017-12-11Henrik Grubbström (Grubba)  if (Pike_compiler->compiler_pass == COMPILER_PASS_LAST && !(THIS_COMPILATION->lex.pragmas & ID_DYNAMIC_DOT))
0ffc192016-11-05Tobias S. Josefowitz  { yywarning("Using . to index dynamically."); }
9e015e2005-07-13Henrik Grubbström (Grubba)  return mknode(F_INDEX, copy_node(n), mkstrnode(id));
e06faf2005-07-12Henrik Grubbström (Grubba)  }
591c0c1997-01-19Fredrik Hübinette (Hubbe)  if(SETJMP(tmp)) {
fae37d1998-08-30Henrik Grubbström (Grubba)  if (node_name) {
3152712008-08-17Martin 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);
017b572011-10-28Henrik Grubbström (Grubba)  switch(TYPEOF(Pike_sp[-1]))
d6aef21997-02-27Fredrik Hübinette (Hubbe)  {
1470d81997-02-27Fredrik Hübinette (Hubbe)  case T_INT:
3152712008-08-17Martin Stjernholm  if (!Pike_sp[-1].u.integer) { if(!Pike_compiler->num_parse_error) { if (node_name) { my_yyerror("Failed to index module %s with '%S'. " "(Module doesn't exist?)", node_name, id); } else { my_yyerror("Failed to index module with '%S'. " "(Module doesn't exist?)", id); }
fae37d1998-08-30Henrik Grubbström (Grubba)  }
3152712008-08-17Martin Stjernholm  break;
fae37d1998-08-30Henrik Grubbström (Grubba)  }
3152712008-08-17Martin Stjernholm  /* Fall through. */
1470d81997-02-27Fredrik Hübinette (Hubbe)  case T_FLOAT: case T_STRING: case T_ARRAY:
fae37d1998-08-30Henrik Grubbström (Grubba)  if (node_name) {
3152712008-08-17Martin Stjernholm  my_yyerror("Failed to index module %s, got %s. (Not a module?)",
017b572011-10-28Henrik Grubbström (Grubba)  node_name, get_name_of_type (TYPEOF(Pike_sp[-1])));
fae37d1998-08-30Henrik Grubbström (Grubba)  } else {
3152712008-08-17Martin Stjernholm  my_yyerror("Failed to index a module, got %s. (Not a module?)",
017b572011-10-28Henrik Grubbström (Grubba)  get_name_of_type (TYPEOF(Pike_sp[-1])));
fae37d1998-08-30Henrik Grubbström (Grubba)  }
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;
017b572011-10-28Henrik Grubbström (Grubba)  if(TYPEOF(Pike_sp[-1]) == T_OBJECT)
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  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)  } } }
3595ea2018-02-12Marcus Comstedt  /* FALLTHRU */
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)  {
3152712008-08-17Martin Stjernholm  my_yyerror("Recursive module dependency when indexing with '%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) {
3152712008-08-17Martin Stjernholm  handle_compile_exception ("Error looking up '%S' in module %s.", id, node_name);
37dd922003-11-14Martin Stjernholm  } else {
3152712008-08-17Martin Stjernholm  handle_compile_exception ("Error looking up '%S' in module.", id);
37dd922003-11-14Martin Stjernholm  }
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)  }
13670c2015-05-25Martin Nilsson 
017b572011-10-28Henrik Grubbström (Grubba)  if(TYPEOF(Pike_sp[-1]) == T_INT &&
cd86322000-07-06Fredrik Hübinette (Hubbe)  !Pike_sp[-1].u.integer &&
017b572011-10-28Henrik Grubbström (Grubba)  SUBTYPEOF(Pike_sp[-1]) == 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) {
94d66b2008-05-24Henrik Grubbström (Grubba)  struct compilation *c = THIS_COMPILATION;
37dd922003-11-14Martin Stjernholm  if (node_name) {
3152712008-08-17Martin Stjernholm  my_yyerror("Index '%S' not present in module %s.",
ce060e2004-06-30Martin Nilsson  id, node_name);
37dd922003-11-14Martin Stjernholm  } else {
3152712008-08-17Martin Stjernholm  my_yyerror("Index '%S' not present in module.", id);
37dd922003-11-14Martin Stjernholm  }
94d66b2008-05-24Henrik Grubbström (Grubba)  resolv_constant(n);
4718112008-05-31Henrik Grubbström (Grubba)  low_yyreport(REPORT_ERROR, NULL, 0, parser_system_string, 1, "Indexed module was: %O.");
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 
3152712008-08-17Martin Stjernholm  else if (Pike_compiler->new_program->flags & PROGRAM_PASS_1_DONE) {
017b572011-10-28Henrik Grubbström (Grubba)  if (((TYPEOF(Pike_sp[-1]) == T_OBJECT &&
3152712008-08-17Martin Stjernholm  Pike_sp[-1].u.object == placeholder_object) ||
017b572011-10-28Henrik Grubbström (Grubba)  (TYPEOF(Pike_sp[-1]) == T_PROGRAM &&
3152712008-08-17Martin Stjernholm  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 when indexing " "module %s with '%S'. (Resolver problem.)",
017b572011-10-28Henrik Grubbström (Grubba)  get_name_of_type (TYPEOF(Pike_sp[-1])),
3152712008-08-17Martin Stjernholm  node_name, id); else my_yyerror("Got placeholder %s when indexing " "module with '%S'. (Resolver problem.)",
017b572011-10-28Henrik Grubbström (Grubba)  get_name_of_type (TYPEOF(Pike_sp[-1])),
3152712008-08-17Martin Stjernholm  id); } } else { /* If we get a program that hasn't gone through pass 1 yet * then we have to register a dependency now in our pass 1 * so that our pass 2 gets delayed. Otherwise the other * program might still be just as unfinished when we come * back here in pass 2. */ struct program *p = NULL;
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(Pike_sp[-1]) == T_PROGRAM)
3152712008-08-17Martin Stjernholm  p = Pike_sp[-1].u.program;
017b572011-10-28Henrik Grubbström (Grubba)  else if (TYPEOF(Pike_sp[-1]) == T_OBJECT || (TYPEOF(Pike_sp[-1]) == T_FUNCTION && SUBTYPEOF(Pike_sp[-1]) != FUNCTION_BUILTIN))
3152712008-08-17Martin Stjernholm  p = Pike_sp[-1].u.object->prog; if (p && !(p->flags & PROGRAM_PASS_1_DONE)) report_compiler_dependency (p);
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! */ if(a->u.trampoline.prog != b->u.trampoline.prog) return 0; return a->u.trampoline.ident == b->u.trampoline.ident && a->u.trampoline.frame == b->u.trampoline.frame;
8f12702014-08-14Per Hedbor 
4e77462001-06-07Fredrik Hübinette (Hubbe)  case F_EXTERNAL:
9e2df02006-10-28Henrik Grubbström (Grubba)  case F_GET_SET:
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;
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;
017b572011-10-28Henrik Grubbström (Grubba)  SET_SVAL(res->u.sval, T_TYPE, 0, type, t); add_ref(t);
be6fec2001-04-01Henrik Grubbström (Grubba)  /* FIXME: Should be type(val) */
a8f0be2007-04-13Henrik Grubbström (Grubba)  type_stack_mark(); push_finished_type(t); push_type(T_TYPE); res->type = pop_unfinished_type();
0b84582007-10-06Henrik Grubbström (Grubba)  return res;
0592971999-12-15Henrik Grubbström (Grubba) }
01d0152008-07-09Martin Stjernholm node *low_mkconstantsvaluenode(const struct svalue *s)
5267b71995-08-09Fredrik Hübinette (Hubbe) { node *res = mkemptynode(); res->token = F_CONSTANT;
09e95a2006-06-09Martin Stjernholm  assign_svalue_no_free(& res->u.sval, s);
017b572011-10-28Henrik Grubbström (Grubba)  if(TYPEOF(*s) == T_OBJECT || (TYPEOF(*s) == T_FUNCTION && SUBTYPEOF(*s) != 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);
7869512008-07-18Martin Stjernholm  res->tree_info |= OPT_SAFE;
71bde82001-03-16Fredrik Hübinette (Hubbe)  return res; }
01d0152008-07-09Martin Stjernholm node *debug_mkconstantsvaluenode(const struct svalue *s)
71bde82001-03-16Fredrik Hübinette (Hubbe) {
0b84582007-10-06Henrik Grubbström (Grubba)  return low_mkconstantsvaluenode(s);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
01d0152008-07-09Martin Stjernholm node *debug_mkliteralsvaluenode(const 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) 
017b572011-10-28Henrik Grubbström (Grubba)  if(TYPEOF(*s) != T_STRING && TYPEOF(*s) != T_INT && TYPEOF(*s) != T_FLOAT)
5683de1995-11-06Fredrik Hübinette (Hubbe)  res->node_info|=OPT_EXTERNAL_DEPEND;
0b84582007-10-06Henrik Grubbström (Grubba)  return 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) {
017b572011-10-28Henrik Grubbström (Grubba)  switch(TYPEOF(*s))
5267b71995-08-09Fredrik Hübinette (Hubbe)  { case T_ARRAY: return make_node_from_array(s->u.array);
13670c2015-05-25Martin Nilsson 
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 &&
bdfe4e2017-12-11Henrik Grubbström (Grubba)  Pike_compiler->compiler_pass == COMPILER_PASS_LAST)
f6b1172002-12-09Martin Stjernholm  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: {
017b572011-10-28Henrik Grubbström (Grubba)  if(SUBTYPEOF(*s) != FUNCTION_BUILTIN)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(s->u.object == Pike_compiler->fake_object)
017b572011-10-28Henrik Grubbström (Grubba)  return mkidentifiernode(SUBTYPEOF(*s));
5267b71995-08-09Fredrik Hübinette (Hubbe) 
6d22541998-01-28Fredrik Hübinette (Hubbe)  if(s->u.object->next == s->u.object) {
017b572011-10-28Henrik Grubbström (Grubba)  return mkexternalnode(s->u.object->prog, SUBTYPEOF(*s));
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) 
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);
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:
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:
50ea682003-03-14Henrik Grubbström (Grubba)  add_ref(n);
046afe1999-11-11Henrik Grubbström (Grubba)  return n;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } } int is_const(node *n) {
05533f1997-02-06Fredrik Hübinette (Hubbe)  if(!n) return 1;
de6c8b2020-07-06Henrik Grubbström (Grubba)  if(n->token == F_AUTO_MAP_MARKER) return 0;
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) {
7869512008-07-18Martin Stjernholm  if (!(n->tree_info & (OPT_SIDE_EFFECT | OPT_ASSIGNMENT | OPT_CASE | OPT_CONTINUE | OPT_BREAK | OPT_RETURN ))) { ptrdiff_t args; if (n->tree_info & (OPT_NOT_CONST|OPT_SAFE)) return 1; args = eval_low (n, 0); if (args == -1) { n->tree_info |= OPT_SIDE_EFFECT; /* A constant that throws. */ return 0; } else { pop_n_elems (args); n->tree_info |= OPT_SAFE; return 1; } } return 0;
5267b71995-08-09Fredrik Hübinette (Hubbe) } /* 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 &&
017b572011-10-28Henrik Grubbström (Grubba)  TYPEOF(CAR(n)->u.sval) == T_FUNCTION && SUBTYPEOF(CAR(n)->u.sval) == FUNCTION_BUILTIN &&
cc5e511998-06-05Fredrik Hübinette (Hubbe)  CAR(n)->u.sval.u.efun->function == f)
046afe1999-11-11Henrik Grubbström (Grubba)  return &_CDR(n);
d819fe2016-10-22Henrik Grubbström (Grubba)  default: /* Inform gcc that we don't care about most values of the enum. */ break;
cc5e511998-06-05Fredrik Hübinette (Hubbe)  } return 0; }
993f2b2014-10-08Per Hedbor #ifdef PIKE_DEBUG
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;
d1ae4f2000-08-27Henrik Grubbström (Grubba)  case F_EXTERNAL:
9e2df02006-10-28Henrik Grubbström (Grubba)  case F_GET_SET:
d1ae4f2000-08-27Henrik Grubbström (Grubba)  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:
ed61452021-02-27Henrik Grubbström (Grubba)  case F_INITIALIZE:
a1af302017-03-18Henrik Grubbström (Grubba)  low_print_tree(_CAR(foo),1);
fa74242004-07-06Martin Nilsson  fputc('=', stderr);
a1af302017-03-18Henrik Grubbström (Grubba)  low_print_tree(_CDR(foo),0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
4e1b092014-09-30Henrik Grubbström (Grubba)  case F_ASSIGN_SELF:
a1af302017-03-18Henrik Grubbström (Grubba)  low_print_tree(_CAR(foo),1);
4e1b092014-09-30Henrik Grubbström (Grubba)  fputc(':', stderr); fputc('=', stderr);
a1af302017-03-18Henrik Grubbström (Grubba)  low_print_tree(_CDR(foo),0);
4e1b092014-09-30Henrik Grubbström (Grubba)  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: {
1283982015-10-11Henrik Grubbström (Grubba)  fputc('(', stderr); simple_describe_type(foo->type); fprintf(stderr, "){");
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: {
1283982015-10-11Henrik Grubbström (Grubba)  fputc('[', stderr); simple_describe_type(foo->type); fputc('(', stderr);
a8f0be2007-04-13Henrik Grubbström (Grubba)  low_print_tree(_CDR(foo), 0); fprintf(stderr, ")]{");
84191b1999-11-23Henrik Grubbström (Grubba)  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: {
e0cd662016-12-28Arne Goedeke  struct byte_buffer buf = BUFFER_INIT(); describe_svalue(&buf, & foo->u.sval, 0, 0); fprintf(stderr, "const(%s)",buffer_get_string(&buf)); buffer_free(&buf);
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; } case F_VAL_LVAL:
5073752018-05-26Henrik Grubbström (Grubba)  case F_FOREACH_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;
1626092019-11-23Henrik Grubbström (Grubba)  case F_RETURN: switch(CDR(foo)?CDR(foo)->u.sval.u.integer:0) { case 2: fputs("yield", stderr); break; case 1: fputs("continue_return", stderr); break; default: fputs("return", stderr); break; } fputc('(', stderr); if(car_is_node(foo)) low_print_tree(_CAR(foo),0); fputc(')', stderr); 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) }
993f2b2014-10-08Per Hedbor #endif
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) };
78488c2018-01-19Martin Nilsson #define VAR_UNUSED 0 /* Rely on unused being 0 for calloc call. */ #define VAR_BLOCKED 1
5267b71995-08-09Fredrik Hübinette (Hubbe) #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;
2d21052018-01-19Martin Nilsson  ret=ALLOC_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. */ }
59fc9e2014-09-03Martin Nilsson  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. */ }
59fc9e2014-09-03Martin Nilsson  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; }
13670c2015-05-25Martin Nilsson 
e674e72000-08-27Henrik Grubbström (Grubba)  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 */
78488c2018-01-19Martin Nilsson  new = (struct scope_info *)xcalloc(1, sizeof(struct scope_info));
e674e72000-08-27Henrik Grubbström (Grubba)  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:
9e2df02006-10-28Henrik Grubbström (Grubba)  case F_GET_SET:
e674e72000-08-27Henrik Grubbström (Grubba)  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)  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:
4e1b092014-09-30Henrik Grubbström (Grubba)  case F_ASSIGN_SELF:
ed61452021-02-27Henrik Grubbström (Grubba)  case F_INITIALIZE:
a1af302017-03-18Henrik Grubbström (Grubba)  find_used_variables(CDR(n),p,noblock,0); find_used_variables(CAR(n),p,noblock,1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  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);
0c28ae2021-02-26Henrik Grubbström (Grubba)  find_used_variables(CDR(n),a,noblock,0);
e674e72000-08-27Henrik Grubbström (Grubba)  do_and_vars(p, a);
0c28ae2021-02-26Henrik Grubbström (Grubba)  find_used_variables(CAR(n),p,noblock,0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  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:
9e2df02006-10-28Henrik Grubbström (Grubba)  case F_GET_SET:
e674e72000-08-27Henrik Grubbström (Grubba)  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;
e82b301997-01-29Fredrik Hübinette (Hubbe)  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:
4e1b092014-09-30Henrik Grubbström (Grubba)  case F_ASSIGN_SELF:
3162d42008-10-15Henrik Grubbström (Grubba)  case F_MULTI_ASSIGN:
ed61452021-02-27Henrik Grubbström (Grubba)  case F_INITIALIZE:
a1af302017-03-18Henrik Grubbström (Grubba)  find_written_vars(CDR(n), p, 0); find_written_vars(CAR(n), p, 1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
e3832f2014-10-02Per Hedbor  case F_APPEND_MAPPING: case F_APPEND_ARRAY:
5219721998-11-06Fredrik Hübinette (Hubbe)  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;
13670c2015-05-25Martin Nilsson 
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:
5073752018-05-26Henrik Grubbström (Grubba)  case F_FOREACH_VAL_LVAL:
5267b71995-08-09Fredrik Hübinette (Hubbe)  find_written_vars(CAR(n), p, 0); find_written_vars(CDR(n), p, 1); break;
13670c2015-05-25Martin Nilsson 
5267b71995-08-09Fredrik Hübinette (Hubbe)  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;
13670c2015-05-25Martin Nilsson  }
e674e72000-08-27Henrik Grubbström (Grubba)  } } 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;
13670c2015-05-25Martin Nilsson  }
e674e72000-08-27Henrik Grubbström (Grubba)  } 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;
13670c2015-05-25Martin Nilsson  }
e674e72000-08-27Henrik Grubbström (Grubba)  } } 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) {
0045cf2014-12-08Henrik Grubbström (Grubba)  if(!b || !a) return 0;
e82b301997-01-29Fredrik Hübinette (Hubbe) #if 0
13670c2015-05-25Martin Nilsson  if(!(b->tree_info & OPT_SIDE_EFFECT) &&
5267b71995-08-09Fredrik Hübinette (Hubbe)  (b->tree_info & OPT_EXTERNAL_DEPEND)) return 1;
e82b301997-01-29Fredrik Hübinette (Hubbe) #endif if((a->tree_info & OPT_EXTERNAL_DEPEND)) return 1;
13670c2015-05-25Martin Nilsson 
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) { 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,
a1af302017-03-18Henrik Grubbström (Grubba)  tmp = mknode(F_ASSIGN, lval, mkintnode(0)));
226e1a2001-03-20Henrik Grubbström (Grubba)  ret = depend_p(n, tmp); free_node(tmp); return ret; }
086acc1999-09-11Fredrik Hübinette (Hubbe) static int function_type_max=0;
eda0e72018-05-27Henrik Grubbström (Grubba) static void fix_auto_node(node *n, struct pike_type *type) { free_type(n->type); copy_pike_type(n->type, type);
7e127f2018-06-14Henrik Grubbström (Grubba)  switch(n->token) { case F_LOCAL: if (!n->u.integer.b) { struct local_variable *var = &Pike_compiler->compiler_frame->variable[n->u.integer.a]; if (var->type) free_type(var->type); copy_pike_type(var->type, type); } break; case F_EXTERNAL: if (n->u.integer.a == Pike_compiler->new_program->id) { struct identifier *id = ID_FROM_INT(Pike_compiler->new_program, n->u.integer.b); if( id ) { if (id->type) free_type(id->type); copy_pike_type(id->type, type); } } break;
78176d2018-10-21Henrik Grubbström (Grubba)  default: break;
eda0e72018-05-27Henrik Grubbström (Grubba)  } } void fix_foreach_type(node *val_lval)
3c7fe72015-12-28Per Hedbor { struct compilation *c = THIS_COMPILATION;
eda0e72018-05-27Henrik Grubbström (Grubba)  node *expression, *lvalues; if (!val_lval || (val_lval->token != F_FOREACH_VAL_LVAL)) return; fix_type_field(val_lval); expression = CAR(val_lval); lvalues = CDR(val_lval);
3c7fe72015-12-28Per Hedbor  if (!expression || pike_types_le(expression->type, void_type_string)) { yyerror("foreach(): Looping over a void expression."); } else { if(lvalues && lvalues->token == ':') { /* Check the iterator type */ struct pike_type *iterator_type; struct pike_type *foreach_call_type; MAKE_CONSTANT_TYPE(iterator_type, tOr5(tArray, tStr, tObj, tMapping, tMultiset)); if (!check_node_type(expression, iterator_type, "Bad argument 1 to foreach()")) { /* No use checking the index and value types if * the iterator type is bad. */ free_type(iterator_type); return; } free_type(iterator_type); push_type(T_MIXED); push_type(T_VOID); push_type(T_MANY); push_finished_type(expression->type); push_type(T_FUNCTION); foreach_call_type = pop_type(); if (CAR(lvalues)) { /* Check the index type */ struct pike_type *index_fun_type; struct pike_type *index_type; 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))); index_type = check_call(foreach_call_type, index_fun_type, 0); if (!index_type) { /* Should not happen. */ yytype_report(REPORT_ERROR, NULL, 0, NULL, NULL, 0, NULL, 0, "Bad iterator type for index in foreach()."); } else { if( CAR(lvalues)->type->type == PIKE_T_AUTO ) {
eda0e72018-05-27Henrik Grubbström (Grubba)  fix_auto_node(CAR(lvalues), index_type);
3c7fe72015-12-28Per Hedbor  } else if (!pike_types_le(index_type, CAR(lvalues)->type)) { int level = REPORT_NOTICE; if (!match_types(CAR(lvalues)->type, index_type)) { level = REPORT_ERROR; } else if (c->lex.pragmas & ID_STRICT_TYPES) { level = REPORT_WARNING; } yytype_report(level, NULL, 0, index_type, NULL, 0, CAR(lvalues)->type, 0, "Type mismatch for index in foreach()."); } free_type(index_type); } free_type(index_fun_type); } if (CDR(lvalues)) { /* Check the value type */ struct pike_type *value_fun_type; struct pike_type *value_type; 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))); value_type = check_call(foreach_call_type, value_fun_type, 0); if (!value_type) { /* Should not happen. */ yytype_report(REPORT_ERROR, NULL, 0, NULL, NULL, 0, NULL, 0, "Bad iterator type for value in foreach()."); } else { if( CDR(lvalues)->type->type == PIKE_T_AUTO ) {
eda0e72018-05-27Henrik Grubbström (Grubba)  fix_auto_node(CDR(lvalues), value_type);
3c7fe72015-12-28Per Hedbor  }
628e892015-12-29Per Hedbor  else if (!pike_types_le(value_type, CDR(lvalues)->type)) {
3c7fe72015-12-28Per Hedbor  int level = REPORT_NOTICE; if (!match_types(CDR(lvalues)->type, value_type)) { level = REPORT_ERROR; } else if (c->lex.pragmas & ID_STRICT_TYPES) { level = REPORT_WARNING; } yytype_report(level, NULL, 0, value_type, NULL, 0, CDR(lvalues)->type, 0, "Type mismatch for value in foreach()."); } free_type(value_type); } free_type(value_fun_type); } free_type(foreach_call_type); } else { /* Old-style foreach */ struct pike_type *array_zero;
43080d2021-02-06Henrik Grubbström (Grubba)  MAKE_CONSTANT_TYPE(array_zero, tLArr(tUnknown, tUnknown));
3c7fe72015-12-28Per Hedbor  if (!pike_types_le(array_zero, expression->type)) { yytype_report(REPORT_ERROR, NULL, 0, array_zero, NULL, 0, expression->type, 0, "Bad argument 1 to foreach()."); } else { if ((c->lex.pragmas & ID_STRICT_TYPES) && !pike_types_le(expression->type, array_type_string)) { yytype_report(REPORT_WARNING, NULL, 0, array_type_string,
7d6c772021-02-18Henrik Grubbström (Grubba)  NULL, 0, expression->type,
3c7fe72015-12-28Per Hedbor  0, "Argument 1 to foreach() is not always an array."); }
e0114d2016-02-23Henrik Grubbström (Grubba)  if (!lvalues) { /* No loop variable. Will be converted to a counted loop * by treeopt. */ } else if( lvalues->type->type == PIKE_T_AUTO ) {
eda0e72018-05-27Henrik Grubbström (Grubba)  fix_auto_node(lvalues, expression->type->car);
e0114d2016-02-23Henrik Grubbström (Grubba)  } else if (pike_types_le(lvalues->type, void_type_string)) {
eda0e72018-05-27Henrik Grubbström (Grubba)  yytype_report(REPORT_ERROR, NULL, 0, expression->type->car,
7d6c772021-02-18Henrik Grubbström (Grubba)  NULL, 0, lvalues->type,
eda0e72018-05-27Henrik Grubbström (Grubba)  0, "Bad argument 2 to foreach().");
e0114d2016-02-23Henrik Grubbström (Grubba)  } else { struct pike_type *array_value_type; type_stack_mark(); push_finished_type(lvalues->type);
04017d2020-01-02Henrik Grubbström (Grubba)  push_unlimited_array_type(T_ARRAY);
e0114d2016-02-23Henrik Grubbström (Grubba)  array_value_type = pop_unfinished_type(); check_node_type(expression, array_value_type, "Argument 1 to foreach() does not match loop variable type."); free_type(array_value_type); }
3c7fe72015-12-28Per Hedbor  } free_type(array_zero); } } }
e680d92007-03-31Henrik Grubbström (Grubba) static struct pike_string *get_name_of_function(node *n) { struct pike_string *name = NULL; if (!n) { MAKE_CONST_STRING(name, "NULL"); return name; } switch(n->token) { #if 0 /* FIXME */ case F_TRAMPOLINE: #endif case F_ARROW: case F_INDEX:
cee4f22014-03-03Martin Nilsson  if(!CDR(n)) { MAKE_CONST_STRING(name, "NULL"); } else if(CDR(n)->token == F_CONSTANT &&
017b572011-10-28Henrik Grubbström (Grubba)  TYPEOF(CDR(n)->u.sval) == T_STRING)
e680d92007-03-31Henrik Grubbström (Grubba)  { name = CDR(n)->u.sval.u.string; }else{ MAKE_CONST_STRING(name, "dynamically resolved function"); } break; case F_CONSTANT:
017b572011-10-28Henrik Grubbström (Grubba)  switch(TYPEOF(n->u.sval))
e680d92007-03-31Henrik Grubbström (Grubba)  { case T_FUNCTION:
017b572011-10-28Henrik Grubbström (Grubba)  if(SUBTYPEOF(n->u.sval) == FUNCTION_BUILTIN)
e680d92007-03-31Henrik Grubbström (Grubba)  { name = n->u.sval.u.efun->name;
306bc92019-10-18Henrik Grubbström (Grubba)  } else { struct program *p = n->u.sval.u.object->prog;
55be622019-10-18Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG
306bc92019-10-18Henrik Grubbström (Grubba)  if (!p) { p = id_to_program(n->u.sval.u.object->program_id); }
55be622019-10-18Henrik Grubbström (Grubba) #endif
306bc92019-10-18Henrik Grubbström (Grubba)  if (p) { name = ID_FROM_INT(p, SUBTYPEOF(n->u.sval))->name; } else { MAKE_CONST_STRING(name, "function in destructed object"); }
e680d92007-03-31Henrik Grubbström (Grubba)  } break; case T_ARRAY: MAKE_CONST_STRING(name, "array call"); break; case T_PROGRAM: MAKE_CONST_STRING(name, "clone call"); break; default: MAKE_CONST_STRING(name, "`() (function call)"); break; } break; case F_EXTERNAL: case F_GET_SET: { int id_no = n->u.integer.b; if (id_no == IDREF_MAGIC_THIS) { MAKE_CONST_STRING(name, "this"); /* Should perhaps qualify it. */ } else { int program_id = n->u.integer.a; struct program_state *state = Pike_compiler; 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) { name = id->name; #if 0 #ifdef PIKE_DEBUG /* FIXME: This test crashes on valid code because the type of the * identifier can change in pass 2 -Hubbe */ if(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");
13670c2015-05-25Martin Nilsson 
e680d92007-03-31Henrik Grubbström (Grubba)  Pike_fatal("Type of external node is not matching it's identifier.\n"); } #endif #endif } } if (!name) { MAKE_CONST_STRING(name, "external symbol"); } } } break;
a8f0be2007-04-13Henrik Grubbström (Grubba)  case F_CAST: case F_SOFT_CAST: name = get_name_of_function(CAR(n)); break;
cb10a32007-04-27Henrik Grubbström (Grubba)  case F_TRAMPOLINE: MAKE_CONST_STRING(name, "trampoline function"); break; case F_LOCAL: MAKE_CONST_STRING(name, "local variable"); break; case F_APPLY: if ((CAR(n)->token == F_CONSTANT) &&
017b572011-10-28Henrik Grubbström (Grubba)  (TYPEOF(CAR(n)->u.sval) == T_FUNCTION) && (SUBTYPEOF(CAR(n)->u.sval) == FUNCTION_BUILTIN) &&
cb10a32007-04-27Henrik Grubbström (Grubba)  (CAR(n)->u.sval.u.efun->function == debug_f_aggregate)) { if (CDR(n)) { n = CDR(n); while (n && (n->token == F_ARG_LIST)) n = CAR(n); if (n) { /* FIXME: Should really join the names of all the args. */ name = get_name_of_function(n); } else { MAKE_CONST_STRING(name, "dynamic array"); } } else { MAKE_CONST_STRING(name, "empty array"); } } else { MAKE_CONST_STRING(name, "returned value"); } break;
13670c2015-05-25Martin Nilsson 
e680d92007-03-31Henrik Grubbström (Grubba)  default:
cb10a32007-04-27Henrik Grubbström (Grubba)  /* fprintf(stderr, "Node token: %s(%d)\n", get_f_name(n->token), n->token); */
e680d92007-03-31Henrik Grubbström (Grubba)  MAKE_CONST_STRING(name, "unknown function"); } #ifdef PIKE_DEBUG if (!name) { Pike_fatal("Failed to get name of function.\n"); } #endif return name; }
5267b71995-08-09Fredrik Hübinette (Hubbe) void fix_type_field(node *n) {
e021fe2008-04-14Henrik Grubbström (Grubba)  struct compilation *c = THIS_COMPILATION;
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) 
aa50312014-12-09Henrik Grubbström (Grubba)  if (!n || (n->type && !(n->node_info & OPT_TYPE_NOT_FIXED)))
f68afd1999-11-20Henrik Grubbström (Grubba)  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) 
a04fb12012-10-02Per Hedbor  /* These two are needed if we want to extract types from nodes while building the tree. */
4019aa2018-05-25Henrik Grubbström (Grubba)  if( car_is_node(n) ) fix_type_field(CAR(n)); if( cdr_is_node(n) ) fix_type_field(CDR(n));
a04fb12012-10-02Per Hedbor 
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) {
a8f0be2007-04-13Henrik Grubbström (Grubba)  struct pike_type *soft_type = NULL; if (CDR(n) && (CDR(n)->token == F_CONSTANT) &&
017b572011-10-28Henrik Grubbström (Grubba)  (TYPEOF(CDR(n)->u.sval) == T_TYPE)) {
a8f0be2007-04-13Henrik Grubbström (Grubba)  soft_type = CDR(n)->u.sval.u.type; if ((n->type = soft_cast(soft_type, CAR(n)->type, 0))) { /* Success. */ break; }
94d66b2008-05-24Henrik Grubbström (Grubba)  ref_push_type_value(CAR(n)->type); ref_push_type_value(soft_type);
b0984b2008-05-24Henrik Grubbström (Grubba)  yytype_report(REPORT_ERROR, NULL, 0, NULL, NULL, 0, NULL, 2, "Soft cast of %O to %O isn't a valid cast.");
a8f0be2007-04-13Henrik Grubbström (Grubba)  } else {
94d66b2008-05-24Henrik Grubbström (Grubba)  yytype_report(REPORT_ERROR, NULL, 0, type_type_string, NULL, 0, CDR(n)->type, 0, "Soft cast with non-type.");
a8f0be2007-04-13Henrik Grubbström (Grubba)  }
1d480f1999-11-23Henrik Grubbström (Grubba)  }
5f50842018-02-12Marcus Comstedt  /* FALLTHRU */
f68afd1999-11-20Henrik Grubbström (Grubba)  case F_CAST: /* Type-field is correct by definition. */
61c7d42016-02-24Henrik Grubbström (Grubba)  if (old_type) { copy_pike_type(n->type, old_type); } else { yyerror("Cast to invalid type."); copy_pike_type(n->type, mixed_type_string); }
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)  }
a04fb12012-10-02Per Hedbor 
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{
656b992021-02-19Henrik Grubbström (Grubba)  if (n->token == F_LOR) { struct pike_type *tmp = type_binop(PT_BINOP_MINUS, CAR(n)->type, zero_type_string, 0, PT_FLAG_CMP_VOIDABLE, 0); n->type = or_pike_types(tmp, CDR(n)->type, 0); free_type(tmp); } else { 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) 
e3832f2014-10-02Per Hedbor  case F_APPEND_MAPPING: if (!CAR(n) || (CAR(n)->type == void_type_string)) { yyerror("Assigning a void expression."); copy_pike_type(n->type, void_type_string); } else /* FIXME: Not really correct, should calculate type of RHS. */ copy_pike_type(n->type, CAR(n)->type); break;
02f17a2007-12-17Henrik Grubbström (Grubba)  case F_APPEND_ARRAY: if (!CAR(n) || (CAR(n)->type == void_type_string)) { yyerror("Assigning a void expression."); copy_pike_type(n->type, void_type_string); } else if (!CDR(n)) { copy_pike_type(n->type, CAR(n)->type); } else { struct pike_type *tmp; type_stack_mark(); push_finished_type(CDR(n)->type);
04017d2020-01-02Henrik Grubbström (Grubba)  push_unlimited_array_type(T_ARRAY);
02f17a2007-12-17Henrik Grubbström (Grubba)  n->type = and_pike_types(CAR(n)->type, tmp = pop_unfinished_type()); free_type(tmp); } break;
da55f91996-05-03Fredrik Hübinette (Hubbe)  case F_ASSIGN:
4e1b092014-09-30Henrik Grubbström (Grubba)  case F_ASSIGN_SELF:
ed61452021-02-27Henrik Grubbström (Grubba)  case F_INITIALIZE:
a1af302017-03-18Henrik Grubbström (Grubba)  if (!CDR(n) || (CDR(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);
a1af302017-03-18Henrik Grubbström (Grubba)  } else if (!CAR(n)) { copy_pike_type(n->type, CDR(n)->type);
67a8ce2006-01-09Henrik Grubbström (Grubba)  } else {
6e0fce2013-05-28Per Hedbor  struct pike_type *t;
a1af302017-03-18Henrik Grubbström (Grubba)  if( CDR(n)->type->type == PIKE_T_AUTO )
9af5052016-05-16Per Hedbor  { /* Update to actual type (assign from soft-cast to auto). */
a1af302017-03-18Henrik Grubbström (Grubba)  free_type( CDR(n)->type ); copy_pike_type( CDR(n)->type, CAR(n)->type );
9af5052016-05-16Per Hedbor  /* potential extension: fix general case: auto z; z = 1; z= 10; -> typeof(z) == int(1)|int(10) */ }
76855f2007-04-27Henrik Grubbström (Grubba) #if 0 /* This test isn't sufficient, see below. */
a1af302017-03-18Henrik Grubbström (Grubba)  check_node_type(CDR(n), CAR(n)->type, "Bad type in assignment.");
76855f2007-04-27Henrik Grubbström (Grubba) #else /* !0 */
a1af302017-03-18Henrik Grubbström (Grubba)  if (!pike_types_le(CDR(n)->type, CAR(n)->type)) {
57fa292005-02-15Henrik Grubbström (Grubba)  /* a["b"]=c and a->b=c can be valid when a is an array.
13670c2015-05-25Martin Nilsson  *
57fa292005-02-15Henrik Grubbström (Grubba)  * FIXME: Exactly what case is the problem? * /grubba 2005-02-15
76855f2007-04-27Henrik Grubbström (Grubba)  * * Example: * array tmp = ({([]),([])}); * tmp->foo = 7; // Multi-assign. * /grubba 2007-04-27
57fa292005-02-15Henrik Grubbström (Grubba)  */
a1af302017-03-18Henrik Grubbström (Grubba)  if (((CAR(n)->token != F_INDEX && CAR(n)->token != F_ARROW) || !(match_types(array_type_string, CAAR(n)->type))) && !match_types(CAR(n)->type, CDR(n)->type)) { yytype_report(REPORT_ERROR, NULL, 0, CAR(n)->type, NULL, 0, CDR(n)->type,
94d66b2008-05-24Henrik Grubbström (Grubba)  0, "Bad type in assignment.");
76855f2007-04-27Henrik Grubbström (Grubba)  } else {
2c5ad52021-02-08Henrik Grubbström (Grubba)  if ((c->lex.pragmas & ID_STRICT_TYPES) && (CDR(n)->type != zero_type_string)) {
a1af302017-03-18Henrik Grubbström (Grubba)  struct pike_string *t1 = describe_type(CDR(n)->type); struct pike_string *t2 = describe_type(CAR(n)->type);
49a0961999-11-24Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG
76855f2007-04-27Henrik Grubbström (Grubba)  if (l_flag > 0) { fputs("Warning: Invalid assignment: ", stderr); print_tree(n); }
49a0961999-11-24Henrik Grubbström (Grubba) #endif /* PIKE_DEBUG */
76855f2007-04-27Henrik Grubbström (Grubba)  yywarning("An expression of type %S cannot be assigned to " "a variable of type %S.", t1, t2); free_string(t2); free_string(t1); } if (runtime_options & RUNTIME_CHECK_TYPES) {
a1af302017-03-18Henrik Grubbström (Grubba)  _CDR(n) = mksoftcastnode(CAR(n)->type, mkcastnode(mixed_type_string, CDR(n)));
76855f2007-04-27Henrik Grubbström (Grubba)  }
84191b1999-11-23Henrik Grubbström (Grubba)  }
f68afd1999-11-20Henrik Grubbström (Grubba)  }
76855f2007-04-27Henrik Grubbström (Grubba) #endif /* 0 */
a1af302017-03-18Henrik Grubbström (Grubba)  n->type = and_pike_types(CDR(n)->type, CAR(n)->type);
e9b1771999-11-18Henrik Grubbström (Grubba)  }
da55f91996-05-03Fredrik Hübinette (Hubbe)  break;
57abdb2020-07-07Henrik 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_POW_EQ: case F_MOD_EQ: case F_DIV_EQ: /* <lval> <op>= <rval> */ { const char *efun_name = NULL; struct pike_string *efun_string = NULL; int orig_flags; node *efun_node = NULL; struct pike_type *f; enum Pike_opcodes opcode = n->token; INT32 args = 0; switch(opcode) { case F_AND_EQ: efun_name = "`&"; break; case F_OR_EQ: efun_name = "`|"; break; case F_XOR_EQ: efun_name = "`^"; break; case F_LSH_EQ: efun_name = "`<<"; break; case F_RSH_EQ: efun_name = "`>>"; break; case F_ADD_EQ: efun_name = "`+"; break; case F_SUB_EQ: efun_name = "`-"; break; case F_MULT_EQ: efun_name = "`*"; break; case F_POW_EQ: efun_name = "`**"; break; case F_MOD_EQ: efun_name = "`%"; break; case F_DIV_EQ: efun_name = "`/"; break; default: /* Keep compiler warnings away. */ break; } if (efun_name) { efun_string = findstring(efun_name); } SET_FORCE_RESOLVE(orig_flags); if (!efun_string || !(efun_node = find_module_identifier(efun_string, 0))) { UNSET_FORCE_RESOLVE(orig_flags);
ab94072020-07-07Henrik Grubbström (Grubba)  if (instrs[n->token-F_OFFSET].name) { my_yyerror("Efun implementing opcode %s undefined.", instrs[n->token-F_OFFSET].name); } else { my_yyerror("Efun implementing opcode <OTHER %d> undefined.", n->token); }
57abdb2020-07-07Henrik Grubbström (Grubba)  copy_pike_type(n->type, mixed_type_string); break; } UNSET_FORCE_RESOLVE(orig_flags); fix_type_field(efun_node); /* Just in case. */ /* NOTE: new_check_call() steals a reference from f! */ copy_pike_type(f, efun_node->type); free_node(efun_node); /* NOTE: Temporarily convert the node into an argument list node * for new_check_call(), */ n->token = F_ARG_LIST; f = debug_malloc_pass(new_check_call(efun_string, f, n, &args, 0)); n->token = opcode; if (f) { struct pike_type *ret = new_get_return_type(f, 0); free_type(f); f = ret; } if (f) { /* Check that the returned type is compatible with the * variable type. */ if (!pike_types_le(f, CAR(n)->type)) { /* 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 * * Example: * array tmp = ({([]),([])}); * tmp->foo += 7; // Multi-assign. * /grubba 2007-04-27 */ if (((CAR(n)->token != F_INDEX && CAR(n)->token != F_ARROW) || !(match_types(array_type_string, CAAR(n)->type))) && !match_types(CAR(n)->type, f)) { yytype_report(REPORT_ERROR, NULL, 0, CAR(n)->type, NULL, 0, f, 0, "Bad type in assignment."); } else {
2c5ad52021-02-08Henrik Grubbström (Grubba)  if ((c->lex.pragmas & ID_STRICT_TYPES) && (f != zero_type_string)) {
57abdb2020-07-07Henrik Grubbström (Grubba)  struct pike_string *t1 = describe_type(f); struct pike_string *t2 = describe_type(CAR(n)->type); #ifdef PIKE_DEBUG if (l_flag > 0) { fputs("Warning: Invalid assignment: ", stderr); print_tree(n); } #endif /* PIKE_DEBUG */ yywarning("An expression of type %S cannot be assigned to " "a variable of type %S.", t1, t2); free_string(t2); free_string(t1); } #if 0 if (runtime_options & RUNTIME_CHECK_TYPES) { /* The following is NOT correct code! */ _CDR(n) = mksoftcastnode(CAR(n)->type, mkcastnode(mixed_type_string, CDR(n))); } #endif /* 0 */ } } n->type = and_pike_types(f, CAR(n)->type); free_type(f); } else { copy_pike_type(n->type, mixed_type_string); } } 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);
04017d2020-01-02Henrik Grubbström (Grubba)  push_unlimited_array_type(T_ARRAY);
1276fa2002-06-03Henrik Grubbström (Grubba)  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);
e245362007-05-04Henrik Grubbström (Grubba)  } else if (CDR(n)) {
9638fb2008-06-27Henrik Grubbström (Grubba)  int valid;
e9b1771999-11-18Henrik Grubbström (Grubba)  type_a=CAR(n)->type; type_b=CDR(n)->type;
9638fb2008-06-27Henrik Grubbström (Grubba)  if((valid = check_indexing(type_a, type_b, n)) <= 0)
c5f0692010-04-15Henrik Grubbström (Grubba)  if(!Pike_compiler->catch_level) {
9638fb2008-06-27Henrik Grubbström (Grubba)  yytype_report((!valid)?REPORT_ERROR:REPORT_WARNING,
c5f0692010-04-15Henrik Grubbström (Grubba)  NULL, 0, NULL, NULL, 0, type_a,
94d66b2008-05-24Henrik Grubbström (Grubba)  0, "Indexing on illegal type.");
c5f0692010-04-15Henrik Grubbström (Grubba)  ref_push_type_value(type_b); low_yyreport((!valid)?REPORT_ERROR:REPORT_WARNING, NULL, 0, type_check_system_string, 1, "Index : %O."); }
94d66b2008-05-24Henrik Grubbström (Grubba)  n->type = index_type(type_a, type_b, n);
e245362007-05-04Henrik Grubbström (Grubba)  } else { copy_pike_type(n->type, mixed_type_string);
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,
9458312009-10-11Henrik Grubbström (Grubba)  ((low->token == F_RANGE_OPEN) || !CAR(low)) ? NULL : CAR (low)->type, ((high->token == F_RANGE_OPEN) || !CAR(high)) ? 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)) {
94d66b2008-05-24Henrik Grubbström (Grubba)  yytype_report(REPORT_ERROR, NULL, 0, array_type, NULL, 0, CAR(n)->type, 0, "Bad argument to splice operator.");
6f1e962005-03-20Henrik Grubbström (Grubba)  }
3bb2452005-04-06Henrik Grubbström (Grubba)  free_type(array_type);
8f64722008-02-26Henrik 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). */ n->type = index_type(CAR(n)->type, int_type_string, n); } else { copy_pike_type(n->type, mixed_type_string);
6f1e962005-03-20Henrik Grubbström (Grubba)  } 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)
94d66b2008-05-24Henrik Grubbström (Grubba)  yytype_report(REPORT_ERROR, NULL, 0, array_type_string, NULL, 0, type_a, 0, "[*] 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;
2d18e12008-06-28Martin Stjernholm  INT32 args;
f68afd1999-11-20Henrik Grubbström (Grubba) 
335eb52001-03-28Henrik Grubbström (Grubba)  args = 0;
e680d92007-03-31Henrik Grubbström (Grubba)  name = get_name_of_function(CAR(n));
cf8ba32008-08-17Martin Stjernholm #ifdef PIKE_DEBUG if (l_flag>2)
ef24a82012-01-12Henrik Grubbström (Grubba)  safe_pike_fprintf (stderr, "Checking call to %S at %S:%ld.\n", name, n->current_file, (long)n->line_number);
cf8ba32008-08-17Martin Stjernholm #endif /* PIKE_DEBUG */
e680d92007-03-31Henrik Grubbström (Grubba)  /* NOTE: new_check_call() steals a reference from f! */
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(f, CAR(n)->type);
6f16cb2008-05-18Henrik Grubbström (Grubba)  f = debug_malloc_pass(new_check_call(name, f, CDR(n), &args, 0));
335eb52001-03-28Henrik Grubbström (Grubba) 
e680d92007-03-31Henrik Grubbström (Grubba)  if (!f) { /* Errors have been generated. */ copy_pike_type(n->type, mixed_type_string); break; }
335eb52001-03-28Henrik Grubbström (Grubba) 
e680d92007-03-31Henrik Grubbström (Grubba)  if ((n->type = new_get_return_type(dmalloc_touch(struct pike_type *, f), 0))) {
335eb52001-03-28Henrik Grubbström (Grubba)  /* Type/argument-check OK. */
b275372008-05-01Martin Stjernholm  debug_malloc_touch(n->type);
e680d92007-03-31Henrik Grubbström (Grubba) 
335eb52001-03-28Henrik Grubbström (Grubba)  free_type(f);
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  if(n->token == F_AUTO_MAP) {
d9d2582019-03-14Henrik Grubbström (Grubba)  type_stack_mark();
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  push_finished_type(n->type);
04017d2020-01-02Henrik Grubbström (Grubba)  push_unlimited_array_type(T_ARRAY);
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  free_type(n->type);
d9d2582019-03-14Henrik Grubbström (Grubba)  n->type = pop_unfinished_type();
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  }
335eb52001-03-28Henrik Grubbström (Grubba)  break; }
e680d92007-03-31Henrik Grubbström (Grubba)  /* Too few arguments or similar. */ copy_pike_type(n->type, mixed_type_string);
e1483f2011-12-11Henrik Grubbström (Grubba)  if ((s = get_first_arg_type(dmalloc_touch(struct pike_type *, f),
301daf2011-12-09Henrik Grubbström (Grubba)  CALL_NOT_LAST_ARG))) {
94d66b2008-05-24Henrik Grubbström (Grubba)  yytype_report(REPORT_ERROR, NULL, 0, s, NULL, 0, NULL, 0, "Too few arguments to %S (got %d).", name, args);
e680d92007-03-31Henrik Grubbström (Grubba)  free_type(s);
94d66b2008-05-24Henrik Grubbström (Grubba)  yytype_report(REPORT_ERROR, NULL, 0, NULL, NULL, 0, CAR(n)->type, 0, "Function type:");
e680d92007-03-31Henrik Grubbström (Grubba)  } else {
94d66b2008-05-24Henrik Grubbström (Grubba)  yytype_report(REPORT_ERROR, NULL, 0, function_type_string, NULL, 0, f, 0, "Attempt to call a non function value %S.", name);
e680d92007-03-31Henrik Grubbström (Grubba)  } free_type(f); break;
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)  }
13670c2015-05-25Martin Nilsson 
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;
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)  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); }
faa94f2017-09-09Marcus Comstedt  if (!Pike_compiler->compiler_frame || Pike_compiler->compiler_frame->current_return_type != void_type_string) { yywarning("Returning a void expression. Converted to zero."); break; }
6e0fce2013-05-28Per Hedbor  } else if(Pike_compiler->compiler_frame && Pike_compiler->compiler_frame->current_return_type) {
97c65a2016-01-11Henrik Grubbström (Grubba)  struct pike_type *t = Pike_compiler->compiler_frame->current_return_type;
6e0fce2013-05-28Per Hedbor 
97c65a2016-01-11Henrik Grubbström (Grubba)  if( t->type == PIKE_T_AUTO ) {
f89bf52019-03-19Henrik Grubbström (Grubba)  type_stack_mark();
ec9bc12016-05-01Henrik Grubbström (Grubba)  if( t->car != zero_type_string )
97c65a2016-01-11Henrik Grubbström (Grubba)  { /* Not the first one.. */
b6b06e2017-08-12Henrik Grubbström (Grubba)  struct pike_type *t2; push_finished_type( t2 = or_pike_types( t->car, CAR(n)->type, 1 ) ); free_type(t2);
97c65a2016-01-11Henrik Grubbström (Grubba)  } else { /* first one.. */
ec9bc12016-05-01Henrik Grubbström (Grubba)  push_finished_type(CAR(n)->type);
97c65a2016-01-11Henrik Grubbström (Grubba)  }
ec9bc12016-05-01Henrik Grubbström (Grubba)  push_type(PIKE_T_AUTO);
97c65a2016-01-11Henrik Grubbström (Grubba)  free_type( t );
f89bf52019-03-19Henrik Grubbström (Grubba)  t = pop_unfinished_type();
97c65a2016-01-11Henrik Grubbström (Grubba)  Pike_compiler->compiler_frame->current_return_type = t;
faa94f2017-09-09Marcus Comstedt  } else { node *retval = CAR(n); if (retval->token == F_COMMA_EXPR) { retval = CDR(retval); } if ((Pike_compiler->compiler_frame->current_return_type !=
97c65a2016-01-11Henrik Grubbström (Grubba)  void_type_string) ||
faa94f2017-09-09Marcus Comstedt  (retval->token != F_CONSTANT) || !SAFE_IS_ZERO(&retval->u.sval)) { check_node_type(CAR(n), t, "Wrong return type."); }
84191b1999-11-23Henrik Grubbström (Grubba)  }
cb22561995-10-11Fredrik Hübinette (Hubbe)  }
7bdf282019-09-12Henrik Grubbström (Grubba)  if (CDR(n) && (CDR(n)->u.sval.u.integer == 2)) { /* __yield__ */ copy_pike_type(n->type, mixed_type_string); } else { 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:
c2c9322014-08-10Martin Nilsson  if (CDR(n) && CAR(n)) {
d6f6d62013-11-08Henrik Grubbström (Grubba)  fix_type_field(CAR(n)); fix_type_field(CDR(n));
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)) {
94d66b2008-05-24Henrik Grubbström (Grubba)  yytype_report(REPORT_ERROR, NULL, 0, CAR(n)->type, NULL, 0, CDR(n)->type, 0, "Type mismatch in case range.");
5ba7062000-01-04Henrik Grubbström (Grubba)  }
e021fe2008-04-14Henrik Grubbström (Grubba)  } else if ((c->lex.pragmas & ID_STRICT_TYPES) &&
c9cfae2000-01-04Henrik Grubbström (Grubba)  (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))) {
94d66b2008-05-24Henrik Grubbström (Grubba)  yytype_report(REPORT_ERROR, NULL, 0, CAR(n)->type, NULL, 0, CDR(n)->type, 0, "Type mismatch in case range.");
cbe8f32000-07-10Henrik Grubbström (Grubba)  }
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))) {
94d66b2008-05-24Henrik Grubbström (Grubba)  yytype_report(REPORT_WARNING, NULL, 0, CAR(n)->type, NULL, 0, CDR(n)->type, 0, "Type mismatch in case range.");
cbe8f32000-07-10Henrik Grubbström (Grubba)  }
c9cfae2000-01-04Henrik Grubbström (Grubba)  } } }
bdfe4e2017-12-11Henrik Grubbström (Grubba)  if (CDR(n) && (Pike_compiler->compiler_pass == COMPILER_PASS_LAST)) {
d6f6d62013-11-08Henrik Grubbström (Grubba)  fix_type_field(CDR(n)); if (!match_types(CDR(n)->type, enumerable_type_string)) { yytype_report(REPORT_WARNING, NULL, 0, enumerable_type_string, NULL, 0, CDR(n)->type, 0, "Case value is not an enumerable type."); } }
5f50842018-02-12Marcus Comstedt  /* FALLTHRU */
9abda42002-03-02Martin Stjernholm  case F_CASE:
bdfe4e2017-12-11Henrik Grubbström (Grubba)  if (CAR(n) && (Pike_compiler->compiler_pass == COMPILER_PASS_LAST)) {
d6f6d62013-11-08Henrik Grubbström (Grubba)  fix_type_field(CAR(n)); if (!match_types(CAR(n)->type, enumerable_type_string)) { yytype_report(REPORT_WARNING, NULL, 0, enumerable_type_string, NULL, 0, CAR(n)->type, 0, "Case value is not an enumerable type."); } }
5f50842018-02-12Marcus Comstedt  /* FALLTHRU */
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:
0c28ae2021-02-26Henrik Grubbström (Grubba)  if (!CAR(n) || (CAR(n)->type == void_type_string)) {
9a78b21999-11-18Henrik Grubbström (Grubba)  yyerror("do - while(): Conditional expression is void.");
0c28ae2021-02-26Henrik Grubbström (Grubba)  } else if(!match_types(CAR(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;
13670c2015-05-25Martin Nilsson 
cb22561995-10-11Fredrik Hübinette (Hubbe)  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:
1cfd5b2008-07-14Henrik Grubbström (Grubba)  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:
5073752018-05-26Henrik Grubbström (Grubba)  if (!CAR(n) || (CAR(n)->token != F_FOREACH_VAL_LVAL)) {
22a6d91999-12-19Henrik Grubbström (Grubba)  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 {
eda0e72018-05-27Henrik Grubbström (Grubba)  fix_foreach_type(CAR(n));
22a6d91999-12-19Henrik Grubbström (Grubba)  } }
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:
fffdad2014-10-13Martin Nilsson  if (!CAR(n) || (CAR(n)->token != F_ARG_LIST) || !CAAR(n)) {
16addb1999-12-10Henrik Grubbström (Grubba)  yyerror("Too few arguments to sscanf().");
6f16cb2008-05-18Henrik Grubbström (Grubba)  MAKE_CONSTANT_TYPE(n->type, tIntPos);
16addb1999-12-10Henrik Grubbström (Grubba)  } else {
6f16cb2008-05-18Henrik Grubbström (Grubba)  struct pike_string *sscanf_name; struct pike_type *sscanf_type; node *args; INT32 argno = 0;
c9562b2014-10-05Martin Nilsson  MAKE_CONST_STRING(sscanf_name, "sscanf"); add_ref(sscanf_type = sscanf_type_string);
fffdad2014-10-13Martin Nilsson  args = mknode(F_ARG_LIST, CAR(n), CDR(n)); add_ref(CAR(n));
b315242008-05-18Henrik Grubbström (Grubba)  if (CDR(n)) add_ref(CDR(n));
6f16cb2008-05-18Henrik Grubbström (Grubba)  sscanf_type = new_check_call(sscanf_name, sscanf_type, args, &argno, 0); free_node(args); if (sscanf_type) {
c075d92008-05-18Henrik Grubbström (Grubba)  if (!(n->type = new_get_return_type(sscanf_type, 0))) { struct pike_type *expected;
e1483f2011-12-11Henrik Grubbström (Grubba)  if ((expected = get_first_arg_type(sscanf_type, CALL_NOT_LAST_ARG))) {
94d66b2008-05-24Henrik Grubbström (Grubba)  yytype_report(REPORT_ERROR, NULL, 0, expected, NULL, 0, NULL,
fffdad2014-10-13Martin Nilsson  0, "Too few arguments to sscanf (got %d).", argno);
c075d92008-05-18Henrik Grubbström (Grubba)  free_type(expected); } else {
94d66b2008-05-24Henrik Grubbström (Grubba)  /* Most likely not reached. */ yytype_report(REPORT_ERROR, NULL, 0, function_type_string, NULL, 0, sscanf_type,
fffdad2014-10-13Martin Nilsson  0, "Attempt to call a non function value sscanf.");
c075d92008-05-18Henrik Grubbström (Grubba)  } }
6f16cb2008-05-18Henrik Grubbström (Grubba)  free_type(sscanf_type);
c075d92008-05-18Henrik Grubbström (Grubba)  } if (!n->type) {
6f16cb2008-05-18Henrik Grubbström (Grubba)  MAKE_CONSTANT_TYPE(n->type, tIntPos); }
16addb1999-12-10Henrik Grubbström (Grubba)  }
30c3b71999-11-22Henrik Grubbström (Grubba)  break;
1c53d32018-05-21Henrik Grubbström (Grubba)  case F_TYPEOF:
8cf6872019-03-12Henrik Grubbström (Grubba)  type_stack_mark();
1c53d32018-05-21Henrik Grubbström (Grubba)  if (CAR(n)) { push_finished_type(CAR(n)->type); } else { push_finished_type(mixed_type_string); } push_type(T_TYPE); if (n->type) free_type(n->type);
8cf6872019-03-12Henrik Grubbström (Grubba)  n->type = pop_unfinished_type();
1c53d32018-05-21Henrik Grubbström (Grubba)  break;
30c3b71999-11-22Henrik Grubbström (Grubba)  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; }
5f50842018-02-12Marcus Comstedt  /* FALLTHRU */
f68afd1999-11-20Henrik Grubbström (Grubba)  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) 
81bd142018-05-23Henrik Grubbström (Grubba)  case F_LOCAL: { struct compiler_frame *f = Pike_compiler->compiler_frame; int e; for (e = 0; f && (e < n->u.integer.b); e++) { f = f->previous; } if (f) { copy_pike_type(n->type, f->variable[n->u.integer.a].type); } else { copy_pike_type(n->type, mixed_type_string); } break; }
d00b001999-11-21Henrik Grubbström (Grubba)  case F_MAGIC_INDEX:
e948371999-12-29Henrik Grubbström (Grubba)  /* FIXME: Could have a stricter type for ::`->(). */
3aebd92016-12-05Martin Nilsson  MAKE_CONSTANT_TYPE(n->type, tF_MAGIC_INDEX);
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 ::`->=(). */
3aebd92016-12-05Martin Nilsson  MAKE_CONSTANT_TYPE(n->type, tF_MAGIC_SET_INDEX);
e948371999-12-29Henrik Grubbström (Grubba)  break;
cbe1132001-12-16Martin Stjernholm  case F_MAGIC_INDICES:
3aebd92016-12-05Martin Nilsson  MAKE_CONSTANT_TYPE(n->type, tF_MAGIC_INDICES);
cbe1132001-12-16Martin Stjernholm  break; case F_MAGIC_VALUES: /* FIXME: Could have a stricter type for ::_values. */
3aebd92016-12-05Martin Nilsson  MAKE_CONSTANT_TYPE(n->type, tF_MAGIC_VALUES);
cbe1132001-12-16Martin Stjernholm  break;
7195af2011-01-15Henrik Grubbström (Grubba)  case F_MAGIC_TYPES: /* FIXME: Could have a stricter type for ::_types. */
3aebd92016-12-05Martin Nilsson  MAKE_CONSTANT_TYPE(n->type, tF_MAGIC_TYPES);
7195af2011-01-15Henrik Grubbström (Grubba)  break;
6c22d22018-12-19Henrik Grubbström (Grubba)  case F_MAGIC_ANNOTATIONS: /* FIXME: Could have a stricter type for ::_annotations. */ MAKE_CONSTANT_TYPE(n->type, tF_MAGIC_ANNOTATIONS); break;
e948371999-12-29Henrik Grubbström (Grubba) 
710fa92019-02-14Henrik Grubbström (Grubba)  case F_SET_LOCAL_NAME: case F_SET_LOCAL_TYPE: case F_SET_LOCAL_END: copy_pike_type(n->type, void_type_string); break;
d00b001999-11-21Henrik Grubbström (Grubba)  case F_CATCH:
5f50842018-02-12Marcus Comstedt  /* FALLTHRU */
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)  }
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; }
13670c2015-05-25Martin Nilsson  while (n->parent &&
d618e52000-09-13Henrik Grubbström (Grubba)  (!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) }
969a291999-11-17Henrik Grubbström (Grubba) 
5267b71995-08-09Fredrik Hübinette (Hubbe) static void optimize(node *n) { node *tmp1, *tmp2, *tmp3;
e021fe2008-04-14Henrik Grubbström (Grubba)  struct compilation *c = THIS_COMPILATION;
9e2df02006-10-28Henrik Grubbström (Grubba)  struct pike_string *save_file =
e021fe2008-04-14Henrik Grubbström (Grubba)  dmalloc_touch(struct pike_string *, c->lex.current_file);
ef24a82012-01-12Henrik Grubbström (Grubba)  INT_TYPE save_line = c->lex.current_line;
aae2312016-08-21Martin Nilsson  struct pike_string *plus_name = lfun_strings[LFUN_ADD]; struct pike_string *minus_name = lfun_strings[LFUN_SUBTRACT];
178e2d1999-12-27Henrik Grubbström (Grubba) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  do {
0b84582007-10-06Henrik Grubbström (Grubba)  if(car_is_node(n) && !(CAR(n)->node_info & 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; }
0b84582007-10-06Henrik Grubbström (Grubba)  if(cdr_is_node(n) && !(CDR(n)->node_info & 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) 
e021fe2008-04-14Henrik Grubbström (Grubba)  c->lex.current_line = n->line_number; c->lex.current_file = dmalloc_touch(struct pike_string *, n->current_file);
66d51c1997-03-04Fredrik Hübinette (Hubbe) 
0b84582007-10-06Henrik Grubbström (Grubba)  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;
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) &&
5073752018-05-26Henrik Grubbström (Grubba)  CAR(n)->token != F_VAL_LVAL && CAR(n)->token != F_FOREACH_VAL_LVAL)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
046afe1999-11-11Henrik Grubbström (Grubba)  _CAR(n) = eval(CAR(n));
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)  _CDR(n) = eval(CDR(n));
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) 
d3b2502017-09-10Marcus Comstedt  if(!n->parent) break;
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); }
13670c2015-05-25Martin Nilsson #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  switch(n->token) {
f1136b2014-08-22Martin Nilsson /* Unfortunately GCC doesn't ignore #pragma clang yet. */ #ifdef __clang__
0777472014-07-02Arne Goedeke #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wparentheses-equality"
7018811999-11-08Henrik Grubbström (Grubba) #include "treeopt.h"
0777472014-07-02Arne Goedeke #pragma clang diagnostic pop
f1136b2014-08-22Martin Nilsson #else #include "treeopt.h" #endif
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 */
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; }
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); }
13670c2015-05-25Martin Nilsson #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  continue;
d819fe2016-10-22Henrik Grubbström (Grubba)  default: /* Inform gcc that we don't care about some values of the enum. */ break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } n->node_info |= OPT_OPTIMIZED; n=n->parent; }while(n);
178e2d1999-12-27Henrik Grubbström (Grubba) 
e021fe2008-04-14Henrik Grubbström (Grubba)  c->lex.current_line = save_line; c->lex.current_file = dmalloc_touch(struct pike_string *, save_file);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
71bde82001-03-16Fredrik Hübinette (Hubbe) void optimize_node(node *n) { if(n &&
bdfe4e2017-12-11Henrik Grubbström (Grubba)  Pike_compiler->compiler_pass == COMPILER_PASS_LAST &&
71bde82001-03-16Fredrik Hübinette (Hubbe)  (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; };
74dfe82012-12-30Jonas Walldén static void check_evaluation_time(struct callback *UNUSED(cb), void *tmp, void *UNUSED(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
353bf92013-07-02Henrik Grubbström (Grubba)  fix_type_field(n);
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;
4c51562008-06-28Henrik Grubbström (Grubba) #ifdef PIKE_USE_MACHINE_CODE
559c362016-09-11Arne Goedeke  make_area_executable ((char *) prog->program, (prog->num_program) *
b089fe2008-06-28Martin Stjernholm  sizeof (prog->program[0]));
ffd2fb2008-06-28Henrik Grubbström (Grubba) #endif
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);
13670c2015-05-25Martin Nilsson 
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(apply_low_safe_and_stupid(Pike_compiler->fake_object, jump))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
7869512008-07-18Martin Stjernholm  /* Assume the node will throw errors at runtime too. */ n->tree_info |= OPT_SIDE_EFFECT; n->node_info |= OPT_SIDE_EFFECT;
9f85c32002-10-25Marcus Comstedt  if(print_error) /* Generate error message */ if(!Pike_compiler->catch_level)
0b84582007-10-06Henrik Grubbström (Grubba)  handle_compile_exception("Error evaluating constant.");
9f85c32002-10-25Marcus Comstedt  else { free_svalue(&throw_value);
1ab4ac2008-01-26Martin Stjernholm  mark_free_svalue (&throw_value);
9f85c32002-10-25Marcus Comstedt  }
9036e82001-08-16Martin Stjernholm  else { free_svalue(&throw_value);
1ab4ac2008-01-26Martin Stjernholm  mark_free_svalue (&throw_value);
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;
7869512008-07-18Martin Stjernholm  n->tree_info |= OPT_SAFE;
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) 
b089fe2008-06-28Martin Stjernholm  prog->num_program = num_program;
b19aff2002-11-24Henrik Grubbström (Grubba) 
c5f0692010-04-15Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG if(l_flag > 3 && n) {
b9dbed2011-03-29Martin Stjernholm  fprintf(stderr,"Evaluation ==> %"PRINTPTRDIFFT"d\n", ret);
c5f0692010-04-15Henrik Grubbström (Grubba)  } #endif
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;
13670c2015-05-25Martin Nilsson 
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; }
3f2e5f2020-01-23Henrik Grubbström (Grubba)  new = mksvaluenode(Pike_sp-1);
c713f92020-02-04Henrik Grubbström (Grubba)  if (new->type && ((new->type->type == PIKE_T_INT) || (new->type->type == PIKE_T_TYPE))) { /* Ok. */
83b9f52020-03-12Henrik Grubbström (Grubba)  } else if (n->type) { if (!new->type) { new->type = n->type; add_ref(n->type); } else if (!pike_types_le(new->type, n->type)) { /* Try consolidating the type information. */ struct pike_type *t = soft_cast(n->type, new->type, 0); if (t) { free_type(new->type); new->type = t; } else { new = mksoftcastnode(n->type, new); } }
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;
13670c2015-05-25Martin Nilsson 
3aa7831999-06-02Fredrik Hübinette (Hubbe)  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;
b865852015-02-10Henrik Grubbström (Grubba)  struct compilation *c = THIS_COMPILATION;
329cc01997-02-17Fredrik Hübinette (Hubbe) 
e021fe2008-04-14Henrik Grubbström (Grubba)  CHECK_COMPILER();
71bde82001-03-16Fredrik Hübinette (Hubbe)  optimize_node(n);
0b84582007-10-06Henrik Grubbström (Grubba)  check_tree(n, 0);
3c0c281998-01-26Fredrik Hübinette (Hubbe) 
fdde6b2017-01-16Henrik Grubbström (Grubba)  if(
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
fdde6b2017-01-16Henrik Grubbström (Grubba)  (a_flag > 1) || #endif
bdfe4e2017-12-11Henrik Grubbström (Grubba)  ((c->lex.pragmas & ID_DISASSEMBLE) && (Pike_compiler->compiler_pass == COMPILER_PASS_LAST)))
393a592000-08-16Henrik Grubbström (Grubba)  fprintf(stderr, "Doing function '%s' at %lx\n", name->str,
bd67392015-10-14Martin Nilsson  (unsigned long)PIKE_PC);
329cc01997-02-17Fredrik Hübinette (Hubbe)  args=count_arguments(type);
10bb002017-12-01Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG if((a_flag > 1) || (c->lex.pragmas & ID_DISASSEMBLE)) fprintf(stderr, "args: %d\n", args); #endif
13670c2015-05-25Martin Nilsson  if(args < 0)
329cc01997-02-17Fredrik Hübinette (Hubbe)  { 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
10bb002017-12-01Henrik Grubbström (Grubba)  if((a_flag > 1) || (c->lex.pragmas & ID_DISASSEMBLE))
b19aff2002-11-24Henrik Grubbström (Grubba)  fprintf(stderr, "Extra identifier flags:0x%02x\n", vargs); #endif
bdfe4e2017-12-11Henrik Grubbström (Grubba)  if(Pike_compiler->compiler_pass != COMPILER_PASS_LAST)
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{
0b84582007-10-06Henrik Grubbström (Grubba)  n = mknode(F_ARG_LIST, n, 0);
13670c2015-05-25Martin Nilsson 
0b84582007-10-06Henrik Grubbström (Grubba)  if((foo=is_stupid_func(n, args, vargs, type)))
329cc01997-02-17Fredrik Hübinette (Hubbe)  {
017b572011-10-28Henrik Grubbström (Grubba)  if(TYPEOF(*foo) == T_FUNCTION && SUBTYPEOF(*foo) == FUNCTION_BUILTIN)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  { 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)
ef24a82012-01-12Henrik Grubbström (Grubba)  fprintf(stderr,"%s:%ld: IDENTIFIER OPTIMIZATION %s == %s\n",
e021fe2008-04-14Henrik Grubbström (Grubba)  c->lex.current_file->str,
ef24a82012-01-12Henrik Grubbström (Grubba)  (long)c->lex.current_line,
4879c12000-04-06Fredrik Hübinette (Hubbe)  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;
13670c2015-05-25Martin Nilsson 
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);
5ecead2007-10-15Martin Stjernholm  print_tree(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;
034ef62017-01-05Henrik Grubbström (Grubba)  int saved_fun_num = Pike_compiler->compiler_frame->current_function_number;
dc6e4d2017-01-09Henrik Grubbström (Grubba)  /* NB: The following prototype is needed to propagate the * ID_LOCAL flags for the identifier to do_code_block().
034ef62017-01-05Henrik Grubbström (Grubba)  */ Pike_compiler->compiler_frame->current_function_number = define_function(name, type, (unsigned INT16)modifiers, (unsigned INT8)(IDENTIFIER_PIKE_FUNCTION | IDENTIFIER_HAS_BODY | vargs), NULL, (unsigned INT16) (Pike_compiler->compiler_frame->opt_flags));
a7538d1998-05-12Fredrik Hübinette (Hubbe)  remove_clear_locals=args; if(vargs) remove_clear_locals++;
dc6e4d2017-01-09Henrik Grubbström (Grubba)  tmp.offset=do_code_block(n, vargs);
a7538d1998-05-12Fredrik Hübinette (Hubbe)  remove_clear_locals=0x7fffffff;
034ef62017-01-05Henrik Grubbström (Grubba)  Pike_compiler->compiler_frame->current_function_number = saved_fun_num;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }
10bb002017-12-01Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG if(a_flag > 2) { fputs("Coded\n", stderr); } #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
13670c2015-05-25Martin Nilsson 
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) }
8504212019-08-15Henrik Grubbström (Grubba)  void init_las(void) { INIT; } void exit_las(void) { EXIT; }