cb22561995-10-11Fredrik Hübinette (Hubbe) /*\
06983f1996-09-22Fredrik Hübinette (Hubbe) ||| This file a part of Pike, and is copyright by Fredrik Hubinette ||| Pike is distributed as GPL (General Public License)
cb22561995-10-11Fredrik Hübinette (Hubbe) ||| See the files COPYING and DISCLAIMER for more information. \*/
d0844b1999-09-19Henrik Grubbström (Grubba) /**/
f90e541995-08-17Fredrik Hübinette (Hubbe) #include "global.h"
f3c7152001-04-14Fredrik Hübinette (Hubbe) RCSID("$Id: docode.c,v 1.111 2001/04/14 09:44:19 hubbe Exp $");
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "las.h" #include "program.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "pike_types.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "stralloc.h" #include "interpret.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "constants.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "array.h"
bb55f81997-03-16Fredrik Hübinette (Hubbe) #include "pike_macros.h"
b2d3e42000-12-01Fredrik Hübinette (Hubbe) #include "pike_error.h"
d3fa6e1998-05-17Henrik Grubbström (Grubba) #include "pike_memory.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "svalue.h" #include "main.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "builtin_functions.h"
7a82f91996-04-13Fredrik Hübinette (Hubbe) #include "peep.h" #include "docode.h"
419fab1997-03-09Fredrik Hübinette (Hubbe) #include "operators.h"
6d22541998-01-28Fredrik Hübinette (Hubbe) #include "object.h"
f76b4c2000-05-11Henrik Grubbström (Grubba) #include "opcodes.h" #include "language.h" #include "lex.h"
5e44422001-02-25Fredrik Hübinette (Hubbe) #include "mapping.h" #include "multiset.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) 
f258372000-09-08Henrik Grubbström (Grubba) static int do_docode2(node *n, INT16 flags);
b079181998-04-27Fredrik Hübinette (Hubbe) 
6c8ada2001-01-14Martin Stjernholm typedef void (*cleanup_func)(void *); struct cleanup_frame { struct cleanup_frame *prev; cleanup_func cleanup; void *cleanup_arg;
7acaf12001-01-15Martin Stjernholm  int stack_depth;
6c8ada2001-01-14Martin Stjernholm };
5a0fd52001-01-10Martin Stjernholm struct statement_label_name { struct statement_label_name *next; struct pike_string *str;
6c8ada2001-01-14Martin Stjernholm  unsigned int line_number;
5a0fd52001-01-10Martin Stjernholm }; struct statement_label { struct statement_label *prev; struct statement_label_name *name;
6c8ada2001-01-14Martin Stjernholm  /* -2 in break_label is used to flag "open" statement_label entries. * If an open entry is on top of the stack, it's used instead of a * new one. That's used to associate statement labels to the * following statement. */
5a0fd52001-01-10Martin Stjernholm  INT32 break_label, continue_label;
6c8ada2001-01-14Martin Stjernholm  int emit_break_label;
7acaf12001-01-15Martin Stjernholm  int stack_depth;
6c8ada2001-01-14Martin Stjernholm  struct cleanup_frame *cleanups;
5a0fd52001-01-10Martin Stjernholm };
6c8ada2001-01-14Martin Stjernholm  static struct statement_label top_statement_label_dummy =
7acaf12001-01-15Martin Stjernholm  {0, 0, -1, -1, 0, -1, 0};
6c8ada2001-01-14Martin Stjernholm static struct statement_label *current_label = &top_statement_label_dummy;
7acaf12001-01-15Martin Stjernholm #ifdef PIKE_DEBUG static int current_stack_depth = -4711; #else static int current_stack_depth = 0; #endif
6c8ada2001-01-14Martin Stjernholm  #define PUSH_CLEANUP_FRAME(func, arg) do { \ struct cleanup_frame cleanup_frame__; \ cleanup_frame__.cleanup = (cleanup_func) (func); \ cleanup_frame__.cleanup_arg = (void *)(ptrdiff_t) (arg); \
7acaf12001-01-15Martin Stjernholm  cleanup_frame__.stack_depth = current_stack_depth; \
6c8ada2001-01-14Martin Stjernholm  DO_IF_DEBUG( \ if (current_label->cleanups == (void *)(ptrdiff_t) -1) \ fatal("current_label points to an unused statement_label.\n"); \ ) \ if (current_label->break_label == -2) { \ DO_IF_DEBUG( \ if (current_label->prev->break_label == -2) \ fatal("Found two open statement_label entries in a row.\n"); \ ) \ cleanup_frame__.prev = current_label->prev->cleanups; \ current_label->prev->cleanups = &cleanup_frame__; \ } \ else { \ cleanup_frame__.prev = current_label->cleanups; \ current_label->cleanups = &cleanup_frame__; \ } #define POP_AND_DONT_CLEANUP \ if (current_label->cleanups == &cleanup_frame__) \ current_label->cleanups = cleanup_frame__.prev; \ else { \ DO_IF_DEBUG( \ if (current_label->prev->cleanups != &cleanup_frame__) \ fatal("Cleanup frame lost from statement_label cleanup list.\n");\ ) \ current_label->prev->cleanups = cleanup_frame__.prev; \ } \ } while (0) #define POP_AND_DO_CLEANUP \
7acaf12001-01-15Martin Stjernholm  do_pop(current_stack_depth - cleanup_frame__.stack_depth); \
6c8ada2001-01-14Martin Stjernholm  cleanup_frame__.cleanup(cleanup_frame__.cleanup_arg); \ POP_AND_DONT_CLEANUP
5a0fd52001-01-10Martin Stjernholm 
1544fd2001-01-31Martin Stjernholm /* A block in the following sense is a region of code where: * o Execution always enters at the beginning. * o All stack nesting is left intact on exit (both normally and * through jumps, but not through exceptions). This includes the * svalue and mark stacks, and the catch block nesting. */ #ifdef PIKE_DEBUG #define BLOCK_BEGIN \ PUSH_CLEANUP_FRAME(do_cleanup_synch_mark, 0); \ if (d_flag > 2) emit0(F_SYNCH_MARK); #define BLOCK_END \ if (current_stack_depth != cleanup_frame__.stack_depth) { \ print_tree(n); \ fatal("Stack not in synch after block: is %d, should be %d.\n", \ current_stack_depth, cleanup_frame__.stack_depth); \ } \ if (d_flag > 2) emit0(F_POP_SYNCH_MARK); \ POP_AND_DONT_CLEANUP #else #define BLOCK_BEGIN #define BLOCK_END #endif
5a0fd52001-01-10Martin Stjernholm #define PUSH_STATEMENT_LABEL do { \ struct statement_label new_label__; \ new_label__.prev = current_label; \
6c8ada2001-01-14Martin Stjernholm  if (current_label->break_label != -2) { \ /* Only cover the current label if it's closed. */ \
5a0fd52001-01-10Martin Stjernholm  new_label__.name = 0; \ new_label__.break_label = new_label__.continue_label = -1; \
e9ebb72001-01-15Martin Stjernholm  new_label__.emit_break_label = 0; \
6c8ada2001-01-14Martin Stjernholm  new_label__.cleanups = 0; \
7acaf12001-01-15Martin Stjernholm  new_label__.stack_depth = current_stack_depth; \
5a0fd52001-01-10Martin Stjernholm  current_label = &new_label__; \ } \
7acaf12001-01-15Martin Stjernholm  else { \ DO_IF_DEBUG( \ new_label__.cleanups = (void *)(ptrdiff_t) -1; \ new_label__.stack_depth = current_stack_depth; \ ) \ current_label->stack_depth = current_stack_depth; \ }
5a0fd52001-01-10Martin Stjernholm  #define POP_STATEMENT_LABEL \ current_label = new_label__.prev; \
6c8ada2001-01-14Martin Stjernholm  DO_IF_DEBUG( \ if (new_label__.cleanups && \ new_label__.cleanups != (void *)(ptrdiff_t) -1) \ fatal("Cleanup frames still left in statement_label.\n")); \
5a0fd52001-01-10Martin Stjernholm } while (0)
5267b71995-08-09Fredrik Hübinette (Hubbe)  static INT32 current_switch_case; static INT32 current_switch_default; static INT32 current_switch_values_on_stack; static INT32 *current_switch_jumptable =0;
d68a072001-02-20Henrik Grubbström (Grubba) static struct pike_type *current_switch_type = NULL;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
7a82f91996-04-13Fredrik Hübinette (Hubbe) void upd_int(int offset, INT32 tmp)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
bad5162000-06-23Fredrik Hübinette (Hubbe)  MEMCPY(Pike_compiler->new_program->program+offset, (char *)&tmp,sizeof(tmp));
5267b71995-08-09Fredrik Hübinette (Hubbe) }
7a82f91996-04-13Fredrik Hübinette (Hubbe) INT32 read_int(int offset)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
bad5162000-06-23Fredrik Hübinette (Hubbe)  return EXTRACT_INT(Pike_compiler->new_program->program+offset);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
7a82f91996-04-13Fredrik Hübinette (Hubbe) int store_linenumbers=1; static int label_no=0;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
be478c1997-08-30Henrik Grubbström (Grubba) int alloc_label(void) { return ++label_no; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
a7622c1996-08-06Fredrik Hübinette (Hubbe) int do_jump(int token,INT32 lbl)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
7a82f91996-04-13Fredrik Hübinette (Hubbe)  if(lbl==-1) lbl=alloc_label();
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit1(token, lbl);
7a82f91996-04-13Fredrik Hübinette (Hubbe)  return lbl;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
928f952000-11-30Fredrik Hübinette (Hubbe)  #define LBLCACHESIZE 4711 #define CURRENT_INSTR ((long)instrbuf.s.len / (long)sizeof(p_instr)) #define MAX_UNWIND 100 static int lbl_cache[LBLCACHESIZE];
f181de2001-01-11Martin Stjernholm int do_branch(INT32 lbl)
928f952000-11-30Fredrik Hübinette (Hubbe) { if(lbl==-1) { lbl=alloc_label(); }else{ INT32 last,pos=lbl_cache[lbl % LBLCACHESIZE]; if(pos < (last=CURRENT_INSTR) && (CURRENT_INSTR - pos) < MAX_UNWIND) { #define BUF ((p_instr *)instrbuf.s.str) if(BUF[pos].opcode == F_LABEL && BUF[pos].arg == lbl) { for(;pos < last;pos++) { if(BUF[pos].opcode != F_LABEL) { insert_opcode2(BUF[pos].opcode, BUF[pos].arg, BUF[pos].arg2, BUF[pos].line, BUF[pos].file); } } } } } emit1(F_BRANCH, lbl); return lbl; } void low_insert_label(int lbl) { lbl_cache[ lbl % LBLCACHESIZE ] = CURRENT_INSTR; emit1(F_LABEL, lbl); } int ins_label(int lbl) { if(lbl==-1) lbl=alloc_label(); low_insert_label(lbl); return lbl; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
a7622c1996-08-06Fredrik Hübinette (Hubbe) void do_pop(int x)
7a82f91996-04-13Fredrik Hübinette (Hubbe) {
6c8ada2001-01-14Martin Stjernholm #ifdef PIKE_DEBUG if (x < 0) fatal("Cannot do pop of %d args.\n", x); #endif
7a82f91996-04-13Fredrik Hübinette (Hubbe)  switch(x)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
7a82f91996-04-13Fredrik Hübinette (Hubbe)  case 0: return;
a96ce92000-04-19Fredrik Hübinette (Hubbe)  case 1: emit0(F_POP_VALUE); break; default: emit1(F_POP_N_ELEMS,x); break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
7acaf12001-01-15Martin Stjernholm  current_stack_depth -= x;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
66d51c1997-03-04Fredrik Hübinette (Hubbe) 
9d6f3e2001-03-09Henrik Grubbström (Grubba) void do_pop_mark(void)
7acaf12001-01-15Martin Stjernholm { emit0(F_POP_MARK); }
986b522001-03-17Henrik Grubbström (Grubba) void do_pop_to_mark(void *ignored)
7acaf12001-01-15Martin Stjernholm { emit0(F_POP_TO_MARK); }
9d6f3e2001-03-09Henrik Grubbström (Grubba) void do_cleanup_synch_mark(void)
1544fd2001-01-31Martin Stjernholm { if (d_flag > 2) emit0(F_CLEANUP_SYNCH_MARK); }
9d6f3e2001-03-09Henrik Grubbström (Grubba) void do_escape_catch(void)
f181de2001-01-11Martin Stjernholm { emit0(F_ESCAPE_CATCH); }
1544fd2001-01-31Martin Stjernholm #define DO_CODE_BLOCK(X) do_pop(do_docode((X),DO_NOT_COPY | DO_POP ))
5267b71995-08-09Fredrik Hübinette (Hubbe) 
f258372000-09-08Henrik Grubbström (Grubba) int do_docode(node *n, INT16 flags)
5267b71995-08-09Fredrik Hübinette (Hubbe) { int i;
7acaf12001-01-15Martin Stjernholm  int stack_depth_save = current_stack_depth;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  int save_current_line=lex.current_line;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!n) return 0;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  lex.current_line=n->line_number;
7acaf12001-01-15Martin Stjernholm #ifdef PIKE_DEBUG if (current_stack_depth == -4711) fatal("do_docode() used outside docode().\n"); #endif
a2d5581999-11-11Henrik Grubbström (Grubba)  i=do_docode2(check_node_hash(n), flags);
7acaf12001-01-15Martin Stjernholm  current_stack_depth = stack_depth_save + i;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  lex.current_line=save_current_line;
5267b71995-08-09Fredrik Hübinette (Hubbe)  return i; }
419fab1997-03-09Fredrik Hübinette (Hubbe) static int is_efun(node *n, c_fun fun) { return n && n->token == F_CONSTANT && n->u.sval.subtype == FUNCTION_BUILTIN && n->u.sval.u.efun->function == fun; }
f258372000-09-08Henrik Grubbström (Grubba) static void code_expression(node *n, INT16 flags, char *err)
c64e8a1997-04-17Fredrik Hübinette (Hubbe) {
a309212000-09-11Henrik Grubbström (Grubba)  switch(do_docode(check_node_hash(n), (INT16)(flags & ~DO_POP)))
c64e8a1997-04-17Fredrik Hübinette (Hubbe)  { case 0: my_yyerror("Void expression for %s",err); case 1: return; case 2:
a4a1722000-12-05Per Hedbor  fatal("Internal compiler error (%s), line %ld, file %s\n",
c64e8a1997-04-17Fredrik Hübinette (Hubbe)  err,
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  (long)lex.current_line, lex.current_file?lex.current_file->str:"Unknown");
c64e8a1997-04-17Fredrik Hübinette (Hubbe)  } }
2d12341997-03-10Fredrik Hübinette (Hubbe) void do_cond_jump(node *n, int label, int iftrue, int flags)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
2d12341997-03-10Fredrik Hübinette (Hubbe)  iftrue=!!iftrue; if((flags & DO_POP) && node_is_tossable(n))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
2d12341997-03-10Fredrik Hübinette (Hubbe)  int t,f; t=!!node_is_true(n); f=!!node_is_false(n); if(t || f)
a7622c1996-08-06Fredrik Hübinette (Hubbe)  {
f181de2001-01-11Martin Stjernholm  if(t == iftrue) do_branch( label);
a7622c1996-08-06Fredrik Hübinette (Hubbe)  return; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
a7622c1996-08-06Fredrik Hübinette (Hubbe)  switch(n->token) {
419fab1997-03-09Fredrik Hübinette (Hubbe)  case F_LAND: case F_LOR:
2d12341997-03-10Fredrik Hübinette (Hubbe)  if(iftrue == (n->token==F_LAND))
a7622c1996-08-06Fredrik Hübinette (Hubbe)  {
2d12341997-03-10Fredrik Hübinette (Hubbe)  int tmp=alloc_label(); do_cond_jump(CAR(n), tmp, !iftrue, flags | DO_POP); do_cond_jump(CDR(n), label, iftrue, flags);
928f952000-11-30Fredrik Hübinette (Hubbe)  low_insert_label(tmp);
2d12341997-03-10Fredrik Hübinette (Hubbe)  }else{ do_cond_jump(CAR(n), label, iftrue, flags); do_cond_jump(CDR(n), label, iftrue, flags);
a7622c1996-08-06Fredrik Hübinette (Hubbe)  }
2d12341997-03-10Fredrik Hübinette (Hubbe)  return;
419fab1997-03-09Fredrik Hübinette (Hubbe)  case F_APPLY:
2d12341997-03-10Fredrik Hübinette (Hubbe)  if(!is_efun(CAR(n), f_not)) break;
419fab1997-03-09Fredrik Hübinette (Hubbe) 
a7622c1996-08-06Fredrik Hübinette (Hubbe)  case F_NOT:
2d12341997-03-10Fredrik Hübinette (Hubbe)  if(!(flags & DO_POP)) break; do_cond_jump(CDR(n), label , !iftrue, flags | DO_NOT_COPY);
a7622c1996-08-06Fredrik Hübinette (Hubbe)  return; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
a309212000-09-11Henrik Grubbström (Grubba)  code_expression(n, (INT16)(flags | DO_NOT_COPY), "condition");
2d12341997-03-10Fredrik Hübinette (Hubbe)  if(flags & DO_POP) { if(iftrue) do_jump(F_BRANCH_WHEN_NON_ZERO, label); else do_jump(F_BRANCH_WHEN_ZERO, label);
7acaf12001-01-15Martin Stjernholm  current_stack_depth--;
2d12341997-03-10Fredrik Hübinette (Hubbe)  }else{ if(iftrue) do_jump(F_LOR, label); else do_jump(F_LAND, label); }
5267b71995-08-09Fredrik Hübinette (Hubbe) }
2d12341997-03-10Fredrik Hübinette (Hubbe) #define do_jump_when_zero(N,L) do_cond_jump(N,L,0,DO_POP|DO_NOT_COPY) #define do_jump_when_non_zero(N,L) do_cond_jump(N,L,1,DO_POP|DO_NOT_COPY)
5267b71995-08-09Fredrik Hübinette (Hubbe) static INT32 count_cases(node *n) { INT32 ret; if(!n) return 0; switch(n->token) { case F_DO: case F_FOR: case F_FOREACH:
cb76e82001-01-14Henrik Grubbström (Grubba)  case F_LOOP:
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_INC_LOOP: case F_DEC_LOOP: case F_INC_NEQ_LOOP: case F_DEC_NEQ_LOOP: case F_SWITCH: case '?': return 0; case F_CASE: return !!CAR(n)+!!CDR(n); default: ret=0; if(car_is_node(n)) ret += count_cases(CAR(n)); if(cdr_is_node(n)) ret += count_cases(CDR(n)); return ret; } }
4f20e92001-01-25Fredrik Hübinette (Hubbe)  int generate_call_function(node *n) { node **arg; emit0(F_MARK); PUSH_CLEANUP_FRAME(do_pop_mark, 0); do_docode(CDR(n),DO_NOT_COPY); emit0(F_CALL_FUNCTION); POP_AND_DONT_CLEANUP; return 1; }
4218011999-01-31Fredrik Hübinette (Hubbe) static inline struct compiler_frame *find_local_frame(INT32 depth) {
bad5162000-06-23Fredrik Hübinette (Hubbe)  struct compiler_frame *f=Pike_compiler->compiler_frame;
4218011999-01-31Fredrik Hübinette (Hubbe)  while(--depth>=0) f=f->previous; return f; }
6fd5172000-04-25Fredrik Hübinette (Hubbe) int do_lfun_call(int id,node *args) {
7acaf12001-01-15Martin Stjernholm  emit0(F_MARK); PUSH_CLEANUP_FRAME(do_pop_mark, 0); do_docode(args,0);
6fd5172000-04-25Fredrik Hübinette (Hubbe) #if 1
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(id == Pike_compiler->compiler_frame->current_function_number)
6fd5172000-04-25Fredrik Hübinette (Hubbe)  {
873ceb2000-04-30Fredrik Hübinette (Hubbe)  int n=count_args(args);
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(n == Pike_compiler->compiler_frame->num_args)
6fd5172000-04-25Fredrik Hübinette (Hubbe)  {
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->compiler_frame->is_inline)
6fd5172000-04-25Fredrik Hübinette (Hubbe)  {
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->compiler_frame->recur_label=do_jump(F_RECUR, Pike_compiler->compiler_frame->recur_label);
873ceb2000-04-30Fredrik Hübinette (Hubbe)  }else{ emit1(F_COND_RECUR,id);
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->compiler_frame->recur_label=do_jump(F_POINTER, Pike_compiler->compiler_frame->recur_label);
6fd5172000-04-25Fredrik Hübinette (Hubbe)  } }
15f5ba2001-01-17Henrik Grubbström (Grubba)  else emit1(F_CALL_LFUN, id);
6fd5172000-04-25Fredrik Hübinette (Hubbe)  }
15f5ba2001-01-17Henrik Grubbström (Grubba)  else
69202f2001-01-17Henrik Grubbström (Grubba) #endif
7acaf12001-01-15Martin Stjernholm  emit1(F_CALL_LFUN, id); POP_AND_DONT_CLEANUP;
6fd5172000-04-25Fredrik Hübinette (Hubbe)  return 1; }
f258372000-09-08Henrik Grubbström (Grubba) static int do_docode2(node *n, INT16 flags)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
e0755c2000-08-15Henrik Grubbström (Grubba)  ptrdiff_t tmp1,tmp2,tmp3;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!n) return 0; if(flags & DO_LVALUE) { switch(n->token) {
2a32691998-01-31Fredrik Hübinette (Hubbe)  default: yyerror("Illegal lvalue.");
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit1(F_NUMBER,0); emit1(F_NUMBER,0);
fb05b61998-02-27Fredrik Hübinette (Hubbe)  return 2;
19aaeb1998-05-25Fredrik Hübinette (Hubbe) 
2a32691998-01-31Fredrik Hübinette (Hubbe)  case F_ARRAY_LVALUE: case F_LVALUE_LIST: case F_LOCAL: case F_GLOBAL: case F_IDENTIFIER: case F_INDEX: case F_ARROW: case F_ARG_LIST:
3d78821999-11-06Henrik Grubbström (Grubba)  case F_COMMA_EXPR:
2a32691998-01-31Fredrik Hübinette (Hubbe)  case F_EXTERNAL:
19aaeb1998-05-25Fredrik Hübinette (Hubbe)  break; } } if(flags & DO_LVALUE_IF_POSSIBLE) { flags|=DO_INDIRECT; flags &=~DO_LVALUE_IF_POSSIBLE; }else{ flags &=~DO_INDIRECT;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
f9abcf1999-09-16Fredrik Hübinette (Hubbe)  /* Stack check */ {
c7241b2000-08-10Henrik Grubbström (Grubba)  ptrdiff_t x_= ((char *)&x_) + STACK_DIRECTION * (32768) - Pike_interpreter.stack_top ;
f9abcf1999-09-16Fredrik Hübinette (Hubbe)  x_*=STACK_DIRECTION; if(x_>0) {
d0844b1999-09-19Henrik Grubbström (Grubba)  yyerror("Too deep recursion in compiler. (please report this)");
f9abcf1999-09-16Fredrik Hübinette (Hubbe) 
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit1(F_NUMBER,0);
f9abcf1999-09-16Fredrik Hübinette (Hubbe)  if(flags & DO_LVALUE) {
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit1(F_NUMBER,0);
f9abcf1999-09-16Fredrik Hübinette (Hubbe)  return 2; } return 1; } }
5267b71995-08-09Fredrik Hübinette (Hubbe)  switch(n->token) {
624f571999-03-11Fredrik Hübinette (Hubbe)  case F_MAGIC_INDEX: case F_MAGIC_SET_INDEX:
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit2(n->token, n->u.node.b->u.sval.u.integer, n->u.node.a->u.sval.u.integer);
624f571999-03-11Fredrik Hübinette (Hubbe)  return 1;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case F_EXTERNAL: {
ff88db2000-07-12Henrik Grubbström (Grubba)  int level = 0;
342fef2000-08-23Fredrik Hübinette (Hubbe)  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; level++; } if (!state) { my_yyerror("Program parent %d lost during compiling.", n->u.integer.a); emit1(F_NUMBER,0); return 1; }
342fef2000-08-23Fredrik Hübinette (Hubbe)  if(level)
ff88db2000-07-12Henrik Grubbström (Grubba)  {
342fef2000-08-23Fredrik Hübinette (Hubbe)  if(flags & WANT_LVALUE) { emit2(F_EXTERNAL_LVALUE, n->u.integer.b, level); return 2; }else{ emit2(F_EXTERNAL, n->u.integer.b, level); return 1; }
ff88db2000-07-12Henrik Grubbström (Grubba)  }else{
342fef2000-08-23Fredrik Hübinette (Hubbe)  if(flags & WANT_LVALUE) { emit1(F_GLOBAL_LVALUE, n->u.integer.b); return 2; }else{ if(IDENTIFIER_IS_FUNCTION(ID_FROM_INT(state->new_program,n->u.integer.b)->identifier_flags)) { emit1(F_LFUN, n->u.integer.b); }else{ emit1(F_GLOBAL, n->u.integer.b); } return 1; }
ff88db2000-07-12Henrik Grubbström (Grubba)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  } break; case F_UNDEFINED: yyerror("Undefined identifier");
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit1(F_NUMBER,0);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  return 1;
7acaf12001-01-15Martin Stjernholm  case F_PUSH_ARRAY: { if (current_label != &top_statement_label_dummy || current_label->cleanups) { /* Might not have a surrounding apply node if evaluated as a * constant by the optimizer. */ #ifdef PIKE_DEBUG if (!current_label->cleanups || (current_label->cleanups->cleanup != do_pop_mark && current_label->cleanups->cleanup != do_pop_to_mark)) fatal("F_PUSH_ARRAY unexpected in this context.\n"); #endif current_label->cleanups->cleanup = do_pop_to_mark; }
c64e8a1997-04-17Fredrik Hübinette (Hubbe)  code_expression(CAR(n), 0, "`@");
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_PUSH_ARRAY);
7acaf12001-01-15Martin Stjernholm  return 0; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  case '?': {
2e4e451997-02-13Fredrik Hübinette (Hubbe)  INT32 *prev_switch_jumptable = current_switch_jumptable;
9d61521996-08-03Fredrik Hübinette (Hubbe)  int adroppings , bdroppings;
2e4e451997-02-13Fredrik Hübinette (Hubbe)  current_switch_jumptable=0;
9d61521996-08-03Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!CDDR(n)) {
a7622c1996-08-06Fredrik Hübinette (Hubbe)  tmp1=alloc_label();
393a592000-08-16Henrik Grubbström (Grubba)  do_jump_when_zero(CAR(n), DO_NOT_WARN((INT32)tmp1));
5267b71995-08-09Fredrik Hübinette (Hubbe)  DO_CODE_BLOCK(CADR(n));
928f952000-11-30Fredrik Hübinette (Hubbe)  low_insert_label( DO_NOT_WARN((INT32)tmp1));
2e4e451997-02-13Fredrik Hübinette (Hubbe)  current_switch_jumptable = prev_switch_jumptable;
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; } if(!CADR(n)) {
a7622c1996-08-06Fredrik Hübinette (Hubbe)  tmp1=alloc_label();
393a592000-08-16Henrik Grubbström (Grubba)  do_jump_when_non_zero(CAR(n), DO_NOT_WARN((INT32)tmp1));
5267b71995-08-09Fredrik Hübinette (Hubbe)  DO_CODE_BLOCK(CDDR(n));
928f952000-11-30Fredrik Hübinette (Hubbe)  low_insert_label( DO_NOT_WARN((INT32)tmp1));
2e4e451997-02-13Fredrik Hübinette (Hubbe)  current_switch_jumptable = prev_switch_jumptable;
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; }
a7622c1996-08-06Fredrik Hübinette (Hubbe)  tmp1=alloc_label();
393a592000-08-16Henrik Grubbström (Grubba)  do_jump_when_zero(CAR(n), DO_NOT_WARN((INT32)tmp1));
5267b71995-08-09Fredrik Hübinette (Hubbe) 
9d61521996-08-03Fredrik Hübinette (Hubbe)  adroppings=do_docode(CADR(n), flags);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  tmp3=emit1(F_POP_N_ELEMS,0);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
9d61521996-08-03Fredrik Hübinette (Hubbe)  /* Else */
f181de2001-01-11Martin Stjernholm  tmp2=do_branch(-1);
928f952000-11-30Fredrik Hübinette (Hubbe)  low_insert_label( DO_NOT_WARN((INT32)tmp1));
5267b71995-08-09Fredrik Hübinette (Hubbe) 
9d61521996-08-03Fredrik Hübinette (Hubbe)  bdroppings=do_docode(CDDR(n), flags); if(adroppings < bdroppings) { do_pop(bdroppings - adroppings); }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
9d61521996-08-03Fredrik Hübinette (Hubbe)  if(adroppings > bdroppings) {
393a592000-08-16Henrik Grubbström (Grubba)  update_arg(DO_NOT_WARN((INT32)tmp3), adroppings - bdroppings);
9d61521996-08-03Fredrik Hübinette (Hubbe)  adroppings=bdroppings; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
928f952000-11-30Fredrik Hübinette (Hubbe)  low_insert_label( DO_NOT_WARN((INT32)tmp2));
2e4e451997-02-13Fredrik Hübinette (Hubbe)  current_switch_jumptable = prev_switch_jumptable;
9d61521996-08-03Fredrik Hübinette (Hubbe)  return adroppings;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } case F_AND_EQ: case F_OR_EQ: case F_XOR_EQ: case F_LSH_EQ: case F_RSH_EQ: case F_ADD_EQ: case F_SUB_EQ: case F_MULT_EQ: case F_MOD_EQ: case F_DIV_EQ: tmp1=do_docode(CAR(n),DO_LVALUE);
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(tmp1 != 2)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  fatal("HELP! FATAL INTERNAL COMPILER ERROR (7)\n");
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif
a2b70a2000-04-30Fredrik Hübinette (Hubbe)  if(n->token == F_ADD_EQ && (flags & DO_POP)) { code_expression(CDR(n), 0, "assignment"); emit0(F_ADD_TO_AND_POP); return 0; }
babd872001-02-23Henrik Grubbström (Grubba)  if(match_types(CAR(n)->type, array_type_string) || match_types(CAR(n)->type, string_type_string) || match_types(CAR(n)->type, mapping_type_string) || match_types(CAR(n)->type, object_type_string))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
c64e8a1997-04-17Fredrik Hübinette (Hubbe)  code_expression(CDR(n), 0, "assignment");
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_LTOSVAL2);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }else{
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_LTOSVAL);
c64e8a1997-04-17Fredrik Hübinette (Hubbe)  code_expression(CDR(n), 0, "assignment");
5267b71995-08-09Fredrik Hübinette (Hubbe)  } switch(n->token) {
a2b70a2000-04-30Fredrik Hübinette (Hubbe)  case F_ADD_EQ: if(CAR(n)->type == int_type_string && CDR(n)->type == int_type_string) { emit0(F_ADD_INTS); } else if(CAR(n)->type == float_type_string && CDR(n)->type == float_type_string) { emit0(F_ADD_FLOATS); }else{ emit0(F_ADD); } break; case F_AND_EQ: emit0(F_AND); break; case F_OR_EQ: emit0(F_OR); break; case F_XOR_EQ: emit0(F_XOR); break; case F_LSH_EQ: emit0(F_LSH); break; case F_RSH_EQ: emit0(F_RSH); break; case F_SUB_EQ: emit0(F_SUBTRACT); break; case F_MULT_EQ:emit0(F_MULTIPLY);break; case F_MOD_EQ: emit0(F_MOD); break; case F_DIV_EQ: emit0(F_DIVIDE); break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } if(flags & DO_POP) {
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_ASSIGN_AND_POP);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; }else{
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_ASSIGN);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; } case F_ASSIGN: switch(CAR(n)->token) { case F_AND: case F_OR: case F_XOR: case F_LSH: case F_RSH: case F_ADD: case F_MOD: case F_SUBTRACT: case F_DIVIDE: case F_MULTIPLY: if(node_is_eq(CDR(n),CAAR(n))) { tmp1=do_docode(CDR(n),DO_LVALUE);
babd872001-02-23Henrik Grubbström (Grubba)  if(match_types(CDR(n)->type, array_type_string) || match_types(CDR(n)->type, string_type_string))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
c64e8a1997-04-17Fredrik Hübinette (Hubbe)  code_expression(CDAR(n), 0, "binary operand");
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_LTOSVAL2);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }else{
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_LTOSVAL);
c64e8a1997-04-17Fredrik Hübinette (Hubbe)  code_expression(CDAR(n), 0, "binary operand");
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(CAR(n)->token);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(n->token);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return n->token==F_ASSIGN; } default: switch(CDR(n)->token) { case F_LOCAL:
4218011999-01-31Fredrik Hübinette (Hubbe)  if(CDR(n)->u.integer.a >= find_local_frame(CDR(n)->u.integer.b)->max_number_of_locals)
a8ef6e1996-12-03Fredrik Hübinette (Hubbe)  yyerror("Illegal to use local variable here.");
4218011999-01-31Fredrik Hübinette (Hubbe)  if(CDR(n)->u.integer.b) goto normal_assign;
c64e8a1997-04-17Fredrik Hübinette (Hubbe)  code_expression(CAR(n), 0, "RHS");
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit1(flags & DO_POP ? F_ASSIGN_LOCAL_AND_POP:F_ASSIGN_LOCAL,
4218011999-01-31Fredrik Hübinette (Hubbe)  CDR(n)->u.integer.a );
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
342fef2000-08-23Fredrik Hübinette (Hubbe)  /* FIXME: Make special case for F_EXTERNAL */
06983f1996-09-22Fredrik Hübinette (Hubbe)  case F_IDENTIFIER:
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(!IDENTIFIER_IS_VARIABLE( ID_FROM_INT(Pike_compiler->new_program, CDR(n)->u.id.number)->identifier_flags))
06983f1996-09-22Fredrik Hübinette (Hubbe)  {
d2c6081996-11-07Fredrik Hübinette (Hubbe)  yyerror("Cannot assign functions or constants.\n");
06983f1996-09-22Fredrik Hübinette (Hubbe)  }else{
c64e8a1997-04-17Fredrik Hübinette (Hubbe)  code_expression(CAR(n), 0, "RHS");
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit1(flags & DO_POP ? F_ASSIGN_GLOBAL_AND_POP:F_ASSIGN_GLOBAL,
a2d5581999-11-11Henrik Grubbström (Grubba)  CDR(n)->u.id.number);
06983f1996-09-22Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; default:
4218011999-01-31Fredrik Hübinette (Hubbe)  normal_assign:
06983f1996-09-22Fredrik Hübinette (Hubbe)  tmp1=do_docode(CDR(n),DO_LVALUE); if(do_docode(CAR(n),0)!=1) yyerror("RHS is void!");
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(flags & DO_POP ? F_ASSIGN_AND_POP:F_ASSIGN);
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; } return flags & DO_POP ? 0 : 1; } case F_LAND: case F_LOR:
2d12341997-03-10Fredrik Hübinette (Hubbe)  tmp1=alloc_label();
393a592000-08-16Henrik Grubbström (Grubba)  do_cond_jump(CAR(n), DO_NOT_WARN((INT32)tmp1), n->token == F_LOR, 0);
e205e01998-07-30Fredrik Hübinette (Hubbe)  code_expression(CDR(n), flags, n->token == F_LOR ? "||" : "&&");
928f952000-11-30Fredrik Hübinette (Hubbe)  low_insert_label( DO_NOT_WARN((INT32)tmp1));
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; case F_EQ: case F_NE: case F_ADD: case F_LT: case F_LE: case F_GT: case F_GE: case F_SUBTRACT: case F_MULTIPLY: case F_DIVIDE: case F_MOD: case F_LSH: case F_RSH: case F_XOR: case F_OR: case F_AND:
6930181996-02-25Fredrik Hübinette (Hubbe)  case F_NOT: case F_COMPL: case F_NEGATE:
a4a1722000-12-05Per Hedbor  fatal("Optimizer error.\n");
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_RANGE:
5e44422001-02-25Fredrik Hübinette (Hubbe)  tmp1=do_docode(CAR(n),DO_NOT_COPY_TOPLEVEL);
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(do_docode(CDR(n),DO_NOT_COPY)!=2)
a4a1722000-12-05Per Hedbor  fatal("Compiler internal error (at %ld).\n",(long)lex.current_line);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(n->token);
393a592000-08-16Henrik Grubbström (Grubba)  return DO_NOT_WARN((INT32)tmp1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_INC: case F_POST_INC: tmp1=do_docode(CAR(n),DO_LVALUE);
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(tmp1 != 2)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  fatal("HELP! FATAL INTERNAL COMPILER ERROR (1)\n");
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif if(flags & DO_POP) {
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_INC_AND_POP);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; }else{
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(n->token);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; } case F_DEC: case F_POST_DEC: tmp1=do_docode(CAR(n),DO_LVALUE);
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(tmp1 != 2)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  fatal("HELP! FATAL INTERNAL COMPILER ERROR (2)\n");
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif if(flags & DO_POP) {
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_DEC_AND_POP);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; }else{
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(n->token);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; } case F_FOR: { INT32 *prev_switch_jumptable = current_switch_jumptable;
1544fd2001-01-31Martin Stjernholm  BLOCK_BEGIN;
6c8ada2001-01-14Martin Stjernholm  PUSH_STATEMENT_LABEL;
5a0fd52001-01-10Martin Stjernholm 
5267b71995-08-09Fredrik Hübinette (Hubbe)  current_switch_jumptable=0;
5a0fd52001-01-10Martin Stjernholm  current_label->break_label=alloc_label(); current_label->continue_label=alloc_label();
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(CDR(n)) {
5a0fd52001-01-10Martin Stjernholm  do_jump_when_zero(CAR(n),current_label->break_label);
7a82f91996-04-13Fredrik Hübinette (Hubbe)  tmp2=ins_label(-1);
9d61521996-08-03Fredrik Hübinette (Hubbe)  DO_CODE_BLOCK(CADR(n));
5a0fd52001-01-10Martin Stjernholm  ins_label(current_label->continue_label);
9d61521996-08-03Fredrik Hübinette (Hubbe)  DO_CODE_BLOCK(CDDR(n));
5267b71995-08-09Fredrik Hübinette (Hubbe)  }else{
9d61521996-08-03Fredrik Hübinette (Hubbe)  tmp2=ins_label(-1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
393a592000-08-16Henrik Grubbström (Grubba)  do_jump_when_non_zero(CAR(n), DO_NOT_WARN((INT32)tmp2));
5a0fd52001-01-10Martin Stjernholm  ins_label(current_label->break_label);
5267b71995-08-09Fredrik Hübinette (Hubbe)  current_switch_jumptable = prev_switch_jumptable;
6c8ada2001-01-14Martin Stjernholm  POP_STATEMENT_LABEL;
1544fd2001-01-31Martin Stjernholm  BLOCK_END;
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; } case ' ': return do_docode(CAR(n),0)+do_docode(CDR(n),DO_LVALUE); case F_FOREACH: {
a982301999-04-30Fredrik Hübinette (Hubbe)  node *arr;
5267b71995-08-09Fredrik Hübinette (Hubbe)  INT32 *prev_switch_jumptable = current_switch_jumptable;
a982301999-04-30Fredrik Hübinette (Hubbe)  arr=CAR(n);
4cdb802001-02-23Fredrik Hübinette (Hubbe)  if(CDR(arr) && CDR(arr)->token == ':') { BLOCK_BEGIN; /* New-style */
5e44422001-02-25Fredrik Hübinette (Hubbe)  tmp1=do_docode(CAR(arr), DO_NOT_COPY_TOPLEVEL);
4cdb802001-02-23Fredrik Hübinette (Hubbe)  emit0(F_MAKE_ITERATOR); if(CADR(arr)) { do_docode(CADR(arr), DO_LVALUE); }else{ emit0(F_CONST0); emit0(F_CONST0); current_stack_depth+=2; } if(CDDR(arr)) { do_docode(CDDR(arr), DO_LVALUE); }else{ emit0(F_CONST0); emit0(F_CONST0); current_stack_depth+=2; } PUSH_CLEANUP_FRAME(do_pop, 5); PUSH_STATEMENT_LABEL; current_switch_jumptable=0; current_label->break_label=alloc_label(); current_label->continue_label=alloc_label(); tmp3=do_branch(-1); tmp1=ins_label(-1); DO_CODE_BLOCK(CDR(n)); ins_label(current_label->continue_label); low_insert_label( DO_NOT_WARN((INT32)tmp3)); do_jump(F_NEW_FOREACH, DO_NOT_WARN((INT32)tmp1)); ins_label(current_label->break_label); current_switch_jumptable = prev_switch_jumptable; POP_STATEMENT_LABEL; POP_AND_DO_CLEANUP; BLOCK_END; return 0; }
a982301999-04-30Fredrik Hübinette (Hubbe) 
4cdb802001-02-23Fredrik Hübinette (Hubbe)  BLOCK_BEGIN; if(CAR(arr) && CAR(arr)->token==F_RANGE)
a982301999-04-30Fredrik Hübinette (Hubbe)  {
4cdb802001-02-23Fredrik Hübinette (Hubbe)  node **a1=my_get_arg(&_CAR(arr),0); node **a2=my_get_arg(&_CAR(arr),1);
a982301999-04-30Fredrik Hübinette (Hubbe)  if(a1 && a2 && a2[0]->token==F_CONSTANT && a2[0]->u.sval.type==T_INT && a2[0]->u.sval.type==0x7fffffff && a1[0]->type == int_type_string) {
5e44422001-02-25Fredrik Hübinette (Hubbe)  do_docode(CAR(arr),DO_NOT_COPY_TOPLEVEL);
dc731d1999-06-19Fredrik Hübinette (Hubbe)  do_docode(*a1,DO_NOT_COPY);
a982301999-04-30Fredrik Hübinette (Hubbe)  goto foreach_arg_pushed; } }
1544fd2001-01-31Martin Stjernholm  do_docode(CAR(n),DO_NOT_COPY);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_CONST0);
7acaf12001-01-15Martin Stjernholm  current_stack_depth++;
a982301999-04-30Fredrik Hübinette (Hubbe)  foreach_arg_pushed:
1544fd2001-01-31Martin Stjernholm  PUSH_CLEANUP_FRAME(do_pop, 4);
7acaf12001-01-15Martin Stjernholm  PUSH_STATEMENT_LABEL; current_switch_jumptable=0; current_label->break_label=alloc_label(); current_label->continue_label=alloc_label();
f181de2001-01-11Martin Stjernholm  tmp3=do_branch(-1);
7a82f91996-04-13Fredrik Hübinette (Hubbe)  tmp1=ins_label(-1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  DO_CODE_BLOCK(CDR(n));
5a0fd52001-01-10Martin Stjernholm  ins_label(current_label->continue_label);
928f952000-11-30Fredrik Hübinette (Hubbe)  low_insert_label( DO_NOT_WARN((INT32)tmp3));
393a592000-08-16Henrik Grubbström (Grubba)  do_jump(n->token, DO_NOT_WARN((INT32)tmp1));
5a0fd52001-01-10Martin Stjernholm  ins_label(current_label->break_label);
5267b71995-08-09Fredrik Hübinette (Hubbe)  current_switch_jumptable = prev_switch_jumptable;
6c8ada2001-01-14Martin Stjernholm  POP_STATEMENT_LABEL; POP_AND_DO_CLEANUP;
1544fd2001-01-31Martin Stjernholm  BLOCK_END;
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; } case F_INC_NEQ_LOOP: case F_DEC_NEQ_LOOP: case F_INC_LOOP: case F_DEC_LOOP: { INT32 *prev_switch_jumptable = current_switch_jumptable;
1544fd2001-01-31Martin Stjernholm  BLOCK_BEGIN;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
1544fd2001-01-31Martin Stjernholm  do_docode(CAR(n),0); PUSH_CLEANUP_FRAME(do_pop, 3);
7acaf12001-01-15Martin Stjernholm  PUSH_STATEMENT_LABEL; current_switch_jumptable=0; current_label->break_label=alloc_label(); current_label->continue_label=alloc_label();
f181de2001-01-11Martin Stjernholm  tmp3=do_branch(-1);
7a82f91996-04-13Fredrik Hübinette (Hubbe)  tmp1=ins_label(-1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  DO_CODE_BLOCK(CDR(n));
5a0fd52001-01-10Martin Stjernholm  ins_label(current_label->continue_label);
928f952000-11-30Fredrik Hübinette (Hubbe)  low_insert_label( DO_NOT_WARN((INT32)tmp3));
393a592000-08-16Henrik Grubbström (Grubba)  do_jump(n->token, DO_NOT_WARN((INT32)tmp1));
5a0fd52001-01-10Martin Stjernholm  ins_label(current_label->break_label);
5267b71995-08-09Fredrik Hübinette (Hubbe)  current_switch_jumptable = prev_switch_jumptable;
6c8ada2001-01-14Martin Stjernholm  POP_STATEMENT_LABEL; POP_AND_DO_CLEANUP;
1544fd2001-01-31Martin Stjernholm  BLOCK_END;
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; }
cb76e82001-01-14Henrik Grubbström (Grubba)  case F_LOOP: { /* FIXME: No support for break or continue. */ PUSH_STATEMENT_LABEL;
f70c402001-01-14Henrik Grubbström (Grubba)  tmp1 = do_docode(CAR(n), 0);
cb76e82001-01-14Henrik Grubbström (Grubba)  if (tmp1 > 0) { do_pop(tmp1-1); tmp2 = do_branch(-1); tmp3 = ins_label(-1);
f70c402001-01-14Henrik Grubbström (Grubba)  DO_CODE_BLOCK(CDR(n));
cb76e82001-01-14Henrik Grubbström (Grubba)  ins_label(tmp2); emit1(F_LOOP, tmp3); } POP_STATEMENT_LABEL; return 0; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_DO: { INT32 *prev_switch_jumptable = current_switch_jumptable;
1544fd2001-01-31Martin Stjernholm  BLOCK_BEGIN;
6c8ada2001-01-14Martin Stjernholm  PUSH_STATEMENT_LABEL;
7a82f91996-04-13Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  current_switch_jumptable=0;
5a0fd52001-01-10Martin Stjernholm  current_label->break_label=alloc_label(); current_label->continue_label=alloc_label();
5267b71995-08-09Fredrik Hübinette (Hubbe) 
7a82f91996-04-13Fredrik Hübinette (Hubbe)  tmp2=ins_label(-1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  DO_CODE_BLOCK(CAR(n));
5a0fd52001-01-10Martin Stjernholm  ins_label(current_label->continue_label);
393a592000-08-16Henrik Grubbström (Grubba)  do_jump_when_non_zero(CDR(n), DO_NOT_WARN((INT32)tmp2));
5a0fd52001-01-10Martin Stjernholm  ins_label(current_label->break_label);
5267b71995-08-09Fredrik Hübinette (Hubbe)  current_switch_jumptable = prev_switch_jumptable;
6c8ada2001-01-14Martin Stjernholm  POP_STATEMENT_LABEL;
1544fd2001-01-31Martin Stjernholm  BLOCK_END;
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; }
176d621999-11-18Henrik Grubbström (Grubba)  case F_POP_VALUE: {
1544fd2001-01-31Martin Stjernholm  BLOCK_BEGIN;
176d621999-11-18Henrik Grubbström (Grubba)  DO_CODE_BLOCK(CAR(n));
1544fd2001-01-31Martin Stjernholm  BLOCK_END;
176d621999-11-18Henrik Grubbström (Grubba)  return 0; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_CAST: if(n->type==void_type_string) { DO_CODE_BLOCK(CAR(n)); return 0; }
d68a072001-02-20Henrik Grubbström (Grubba)  { struct svalue sv; sv.type = T_TYPE; sv.subtype = 0; sv.u.type = n->type; tmp1 = store_constant(&sv, 1, n->name); emit1(F_CONSTANT, DO_NOT_WARN((INT32)tmp1)); }
5267b71995-08-09Fredrik Hübinette (Hubbe)  tmp1=do_docode(CAR(n),0);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  if(!tmp1) { emit0(F_CONST0); tmp1=1; }
393a592000-08-16Henrik Grubbström (Grubba)  if(tmp1>1) do_pop(DO_NOT_WARN((INT32)(tmp1-1)));
5267b71995-08-09Fredrik Hübinette (Hubbe) 
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_CAST);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1;
1d480f1999-11-23Henrik Grubbström (Grubba)  case F_SOFT_CAST:
7d955e1999-12-13Henrik Grubbström (Grubba)  if (runtime_options & RUNTIME_CHECK_TYPES) {
d68a072001-02-20Henrik Grubbström (Grubba)  { struct svalue sv; sv.type = T_TYPE; sv.subtype = 0; sv.u.type = n->type; tmp1 = store_constant(&sv, 1, n->name); emit1(F_CONSTANT, DO_NOT_WARN((INT32)tmp1)); }
dad12d1999-11-25Henrik Grubbström (Grubba)  tmp1 = do_docode(CAR(n), 0);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  if (!tmp1) { emit0(F_CONST0); tmp1 = 1; }
393a592000-08-16Henrik Grubbström (Grubba)  if (tmp1 > 1) do_pop(DO_NOT_WARN((INT32)(tmp1 - 1)));
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_SOFT_CAST);
dad12d1999-11-25Henrik Grubbström (Grubba)  return 1; } tmp1 = do_docode(CAR(n), flags);
393a592000-08-16Henrik Grubbström (Grubba)  if (tmp1 > 1) do_pop(DO_NOT_WARN((INT32)(tmp1 - 1)));
dad12d1999-11-25Henrik Grubbström (Grubba)  return !!tmp1;
1d480f1999-11-23Henrik Grubbström (Grubba) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_APPLY: if(CAR(n)->token == F_CONSTANT) {
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  if(CAR(n)->u.sval.type == T_FUNCTION)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
bdb5091996-09-25Fredrik Hübinette (Hubbe)  if(CAR(n)->u.sval.subtype == FUNCTION_BUILTIN) /* driver fun? */
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  { if(!CAR(n)->u.sval.u.efun->docode || !CAR(n)->u.sval.u.efun->docode(n)) {
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_MARK);
7acaf12001-01-15Martin Stjernholm  PUSH_CLEANUP_FRAME(do_pop_mark, 0);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  do_docode(CDR(n),0); tmp1=store_constant(& CAR(n)->u.sval,
454d541999-09-18Fredrik Hübinette (Hubbe)  !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND), CAR(n)->name);
393a592000-08-16Henrik Grubbström (Grubba)  emit1(F_APPLY, DO_NOT_WARN((INT32)tmp1));
7acaf12001-01-15Martin Stjernholm  POP_AND_DONT_CLEANUP;
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  }
044c621999-04-14Fredrik Hübinette (Hubbe)  if(n->type == void_type_string) return 0;
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  return 1; }else{
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(CAR(n)->u.sval.u.object == Pike_compiler->fake_object)
6fd5172000-04-25Fredrik Hübinette (Hubbe)  return do_lfun_call(CAR(n)->u.sval.subtype,CDR(n));
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) 
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_MARK);
7acaf12001-01-15Martin Stjernholm  PUSH_CLEANUP_FRAME(do_pop_mark, 0);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  do_docode(CDR(n),0); tmp1=store_constant(& CAR(n)->u.sval,
454d541999-09-18Fredrik Hübinette (Hubbe)  !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND), CAR(n)->name);
393a592000-08-16Henrik Grubbström (Grubba)  emit1(F_APPLY, DO_NOT_WARN((INT32)tmp1));
7acaf12001-01-15Martin Stjernholm  POP_AND_DONT_CLEANUP;
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; } else if(CAR(n)->token == F_IDENTIFIER &&
bad5162000-06-23Fredrik Hübinette (Hubbe)  IDENTIFIER_IS_FUNCTION(ID_FROM_INT(Pike_compiler->new_program,
6fd5172000-04-25Fredrik Hübinette (Hubbe)  CAR(n)->u.id.number)->identifier_flags))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
6fd5172000-04-25Fredrik Hübinette (Hubbe)  return do_lfun_call(CAR(n)->u.id.number,CDR(n));
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
342fef2000-08-23Fredrik Hübinette (Hubbe)  else if(CAR(n)->token == F_EXTERNAL && CAR(n)->u.integer.a == Pike_compiler->new_program->id && IDENTIFIER_IS_FUNCTION(ID_FROM_INT(Pike_compiler->new_program, CAR(n)->u.integer.b)->identifier_flags)) { return do_lfun_call(CAR(n)->u.integer.b,CDR(n)); }
5267b71995-08-09Fredrik Hübinette (Hubbe)  else {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *tmp;
5267b71995-08-09Fredrik Hübinette (Hubbe)  struct efun *fun;
f53bab1997-01-26Fredrik Hübinette (Hubbe)  node *foo;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_MARK);
7acaf12001-01-15Martin Stjernholm  PUSH_CLEANUP_FRAME(do_pop_mark, 0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  do_docode(CAR(n),0); do_docode(CDR(n),0);
f53bab1997-01-26Fredrik Hübinette (Hubbe)  tmp=findstring("call_function"); if(!tmp) yyerror("No call_function efun.");
2816052000-03-30Fredrik Hübinette (Hubbe)  foo=find_module_identifier(tmp,0);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(!foo || !foo->token==F_CONSTANT)
f53bab1997-01-26Fredrik Hübinette (Hubbe)  { yyerror("No call_function efun."); }else{
d103cb1998-01-30Fredrik Hübinette (Hubbe)  if(foo->u.sval.type == T_FUNCTION && foo->u.sval.subtype == FUNCTION_BUILTIN && foo->u.sval.u.efun->function == f_call_function) {
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_CALL_FUNCTION);
d103cb1998-01-30Fredrik Hübinette (Hubbe)  }else{
454d541999-09-18Fredrik Hübinette (Hubbe)  /* We might want to put "predef::"+foo->name here /Hubbe */ tmp1=store_constant(& foo->u.sval, 1, foo->name);
393a592000-08-16Henrik Grubbström (Grubba)  emit1(F_APPLY, DO_NOT_WARN((INT32)tmp1));
d103cb1998-01-30Fredrik Hübinette (Hubbe)  }
f53bab1997-01-26Fredrik Hübinette (Hubbe)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  free_node(foo);
7acaf12001-01-15Martin Stjernholm  POP_AND_DONT_CLEANUP;
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; } case F_ARG_LIST:
bdf5eb2000-03-07Fredrik Hübinette (Hubbe)  case F_COMMA_EXPR:
a309212000-09-11Henrik Grubbström (Grubba)  tmp1 = do_docode(CAR(n), (INT16)(flags & ~WANT_LVALUE));
5267b71995-08-09Fredrik Hübinette (Hubbe)  tmp1+=do_docode(CDR(n),flags);
393a592000-08-16Henrik Grubbström (Grubba)  return DO_NOT_WARN((INT32)tmp1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  /* Switch: * So far all switches are implemented with a binsearch lookup. * It stores the case values in the programs area for constants. * It also has a jump-table in the program itself, for every index in * the array of cases, there is 2 indexes in the jumptable, and one extra. * The first entry in the jumptable is used if you call switch with * a value that is ranked lower than all the indexes in the array of * cases. (Ranked by the binsearch that is) The second is used if it * is equal to the first index. The third if it is greater than the * first, but lesser than the second. The fourth if it is equal to * the second.... etc. etc. */ case F_SWITCH: { INT32 e,cases,*order; INT32 *jumptable; INT32 prev_switch_values_on_stack = current_switch_values_on_stack; INT32 prev_switch_case = current_switch_case; INT32 prev_switch_default = current_switch_default; INT32 *prev_switch_jumptable = current_switch_jumptable;
07f5432001-02-21Henrik Grubbström (Grubba)  struct pike_type *prev_switch_type = current_switch_type;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
fc26f62000-07-06Fredrik Hübinette (Hubbe)  struct svalue *save_sp=Pike_sp;
7af7d21997-08-03Fredrik Hübinette (Hubbe) #endif
1544fd2001-01-31Martin Stjernholm  BLOCK_BEGIN;
6c8ada2001-01-14Martin Stjernholm  PUSH_STATEMENT_LABEL;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(do_docode(CAR(n),0)!=1)
a4a1722000-12-05Per Hedbor  fatal("Internal compiler error, time to panic\n");
5267b71995-08-09Fredrik Hübinette (Hubbe) 
7670902000-01-04Henrik Grubbström (Grubba)  if (!(CAR(n) && (current_switch_type = CAR(n)->type))) { current_switch_type = mixed_type_string; }
5a0fd52001-01-10Martin Stjernholm  current_label->break_label=alloc_label();
5267b71995-08-09Fredrik Hübinette (Hubbe)  cases=count_cases(CDR(n));
a96ce92000-04-19Fredrik Hübinette (Hubbe)  tmp1=emit1(F_SWITCH,0);
7acaf12001-01-15Martin Stjernholm  current_stack_depth--;
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit1(F_ALIGN,sizeof(INT32));
7a82f91996-04-13Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  current_switch_values_on_stack=0;
4399511998-01-28Fredrik Hübinette (Hubbe)  current_switch_case=1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  current_switch_default=-1;
52fcc81998-01-28Fredrik Hübinette (Hubbe)  current_switch_jumptable=(INT32 *)xalloc(sizeof(INT32)*(cases*2+2)); jumptable=(INT32 *)xalloc(sizeof(INT32)*(cases*2+2));
5267b71995-08-09Fredrik Hübinette (Hubbe) 
52fcc81998-01-28Fredrik Hübinette (Hubbe)  for(e=1; e<cases*2+2; e++)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
e0755c2000-08-15Henrik Grubbström (Grubba)  jumptable[e] = DO_NOT_WARN((INT32)emit1(F_POINTER, 0));
5267b71995-08-09Fredrik Hübinette (Hubbe)  current_switch_jumptable[e]=-1; }
928f952000-11-30Fredrik Hübinette (Hubbe)  emit0(F_NOTREACHED);
5267b71995-08-09Fredrik Hübinette (Hubbe)  current_switch_jumptable[current_switch_case++]=-1; DO_CODE_BLOCK(CDR(n));
1544fd2001-01-31Martin Stjernholm 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
fc26f62000-07-06Fredrik Hübinette (Hubbe)  if(Pike_sp-save_sp != cases)
7af7d21997-08-03Fredrik Hübinette (Hubbe)  fatal("Count cases is wrong!\n"); #endif
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  f_aggregate(cases);
49398c2000-11-08Fredrik Hübinette (Hubbe)  /* FIXME: get_switch_order might possibly be able to * throw errors, add a catch around this! -Hubbe */
fc26f62000-07-06Fredrik Hübinette (Hubbe)  order=get_switch_order(Pike_sp[-1].u.array);
7a82f91996-04-13Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  if (!Pike_compiler->num_parse_error) {
7c95f12000-01-04Henrik Grubbström (Grubba)  /* Check for cases inside a range */ for(e=0; e<cases-1; e++)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
7c95f12000-01-04Henrik Grubbström (Grubba)  if(order[e] < cases-1)
ba62cf1997-09-18Fredrik Hübinette (Hubbe)  {
7c95f12000-01-04Henrik Grubbström (Grubba)  int o1=order[e]*2+2; if(current_switch_jumptable[o1]==current_switch_jumptable[o1+1] && current_switch_jumptable[o1]==current_switch_jumptable[o1+2]) { if(order[e]+1 != order[e+1]) yyerror("Case inside range."); e++; }
ba62cf1997-09-18Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
7a82f91996-04-13Fredrik Hübinette (Hubbe)  if(current_switch_default < 0) current_switch_default = ins_label(-1);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
52fcc81998-01-28Fredrik Hübinette (Hubbe)  for(e=1;e<cases*2+2;e++)
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(current_switch_jumptable[e]==-1) current_switch_jumptable[e]=current_switch_default;
fc26f62000-07-06Fredrik Hübinette (Hubbe)  order_array(Pike_sp[-1].u.array,order);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
52fcc81998-01-28Fredrik Hübinette (Hubbe)  reorder((void *)(current_switch_jumptable+2),cases,sizeof(INT32)*2,order);
5267b71995-08-09Fredrik Hübinette (Hubbe)  free((char *)order);
52fcc81998-01-28Fredrik Hübinette (Hubbe)  for(e=1; e<cases*2+2; e++)
7a82f91996-04-13Fredrik Hübinette (Hubbe)  update_arg(jumptable[e], current_switch_jumptable[e]);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
393a592000-08-16Henrik Grubbström (Grubba)  update_arg(DO_NOT_WARN((INT32)tmp1), store_constant(Pike_sp-1,1,0));
5267b71995-08-09Fredrik Hübinette (Hubbe)  pop_stack(); free((char *)jumptable); free((char *)current_switch_jumptable); current_switch_jumptable = prev_switch_jumptable; current_switch_default = prev_switch_default; current_switch_case = prev_switch_case;
7670902000-01-04Henrik Grubbström (Grubba)  current_switch_values_on_stack = prev_switch_values_on_stack; current_switch_type = prev_switch_type;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
5a0fd52001-01-10Martin Stjernholm  low_insert_label( current_label->break_label);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
6c8ada2001-01-14Martin Stjernholm  POP_STATEMENT_LABEL;
1544fd2001-01-31Martin Stjernholm  BLOCK_END;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
fc26f62000-07-06Fredrik Hübinette (Hubbe)  if(Pike_interpreter.recoveries && Pike_sp-Pike_interpreter.evaluator_stack < Pike_interpreter.recoveries->stack_pointer)
a4a1722000-12-05Per Hedbor  fatal("Stack error after F_SWITCH (underflow)\n");
7af7d21997-08-03Fredrik Hübinette (Hubbe) #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; } case F_CASE: { if(!current_switch_jumptable) { yyerror("Case outside switch."); }else{
ba62cf1997-09-18Fredrik Hübinette (Hubbe)  node *lower=CAR(n); if(!lower) lower=CDR(n); if(!is_const(lower))
5267b71995-08-09Fredrik Hübinette (Hubbe)  yyerror("Case label isn't constant.");
b8cd052000-09-26Fredrik Hübinette (Hubbe)  if (lower && lower->type && !TEST_COMPAT(0,6)) {
7670902000-01-04Henrik Grubbström (Grubba)  if (!pike_types_le(lower->type, current_switch_type)) { if (!match_types(lower->type, current_switch_type)) { yytype_error("Type mismatch in case.", current_switch_type, lower->type, 0); } else if (lex.pragmas & ID_STRICT_TYPES) { yytype_error("Type mismatch in case.", current_switch_type, lower->type, YYTE_IS_WARNING); } } }
bad5162000-06-23Fredrik Hübinette (Hubbe)  if (!Pike_compiler->num_parse_error) {
b1bfe22000-01-04Henrik Grubbström (Grubba)  tmp1=eval_low(lower); if(tmp1<1) { yyerror("Error in case label."); push_int(0); tmp1=1; } pop_n_elems(tmp1-1); current_switch_values_on_stack++; for(tmp1=current_switch_values_on_stack; tmp1 > 1; tmp1--)
fc26f62000-07-06Fredrik Hübinette (Hubbe)  if(is_equal(Pike_sp-tmp1, Pike_sp-1))
b1bfe22000-01-04Henrik Grubbström (Grubba)  yyerror("Duplicate case.");
271a6b2000-01-04Henrik Grubbström (Grubba)  } else { push_int(0); current_switch_values_on_stack++; } current_switch_jumptable[current_switch_case++]=ins_label(-1);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
271a6b2000-01-04Henrik Grubbström (Grubba)  if(CDR(n)) { current_switch_jumptable[current_switch_case]= current_switch_jumptable[current_switch_case-1]; current_switch_case++;
7a82f91996-04-13Fredrik Hübinette (Hubbe) 
271a6b2000-01-04Henrik Grubbström (Grubba)  if(CAR(n))
ba62cf1997-09-18Fredrik Hübinette (Hubbe)  {
271a6b2000-01-04Henrik Grubbström (Grubba)  if(!is_const(CDR(n))) yyerror("Case label isn't constant.");
7a82f91996-04-13Fredrik Hübinette (Hubbe)  current_switch_jumptable[current_switch_case]= current_switch_jumptable[current_switch_case-1];
ba62cf1997-09-18Fredrik Hübinette (Hubbe)  current_switch_case++;
bad5162000-06-23Fredrik Hübinette (Hubbe)  if (!Pike_compiler->num_parse_error) {
271a6b2000-01-04Henrik Grubbström (Grubba)  tmp1=eval_low(CDR(n)); if(tmp1<1) { yyerror("Error in second half of case label."); push_int(0); tmp1=1;
b1bfe22000-01-04Henrik Grubbström (Grubba)  }
271a6b2000-01-04Henrik Grubbström (Grubba)  pop_n_elems(tmp1-1); current_switch_values_on_stack++; for(tmp1=current_switch_values_on_stack; tmp1 > 1; tmp1--)
fc26f62000-07-06Fredrik Hübinette (Hubbe)  if(is_equal(Pike_sp-tmp1, Pike_sp-1))
271a6b2000-01-04Henrik Grubbström (Grubba)  yyerror("Duplicate case."); } else { push_int(0); current_switch_values_on_stack++;
ba62cf1997-09-18Fredrik Hübinette (Hubbe)  } current_switch_jumptable[current_switch_case++]=-1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
271a6b2000-01-04Henrik Grubbström (Grubba)  }else{ current_switch_jumptable[current_switch_case++]=-1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } } return 0; } case F_DEFAULT: if(!current_switch_jumptable) { yyerror("Default outside switch."); }else if(current_switch_default!=-1){ yyerror("Duplicate switch default."); }else{
7a82f91996-04-13Fredrik Hübinette (Hubbe)  current_switch_default = ins_label(-1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } return 0; case F_BREAK:
f181de2001-01-11Martin Stjernholm  case F_CONTINUE: { struct statement_label *label, *p;
5a0fd52001-01-10Martin Stjernholm  if (CAR(n)) { struct pike_string *name = CAR(n)->u.sval.u.string; struct statement_label_name *lbl_name; for (label = current_label; label; label = label->prev) for (lbl_name = label->name; lbl_name; lbl_name = lbl_name->next) if (lbl_name->str == name)
7acaf12001-01-15Martin Stjernholm  goto label_found_1;
5a0fd52001-01-10Martin Stjernholm  my_yyerror("No surrounding statement labeled '%s'.", name->str); return 0;
7acaf12001-01-15Martin Stjernholm  label_found_1:
f181de2001-01-11Martin Stjernholm  if (n->token == F_CONTINUE && label->continue_label < 0) { my_yyerror("Cannot continue the non-loop statement on line %d.", lbl_name->line_number); return 0;
5a0fd52001-01-10Martin Stjernholm  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
5a0fd52001-01-10Martin Stjernholm 
7acaf12001-01-15Martin Stjernholm  else {
5a0fd52001-01-10Martin Stjernholm  if (n->token == F_BREAK) {
7acaf12001-01-15Martin Stjernholm  for (label = current_label; label; label = label->prev)
e9ebb72001-01-15Martin Stjernholm  if (label->break_label >= 0 && !label->emit_break_label)
7acaf12001-01-15Martin Stjernholm  goto label_found_2; yyerror("Break outside loop or switch."); return 0;
5a0fd52001-01-10Martin Stjernholm  } else { for (label = current_label; label; label = label->prev)
f181de2001-01-11Martin Stjernholm  if (label->continue_label >= 0)
7acaf12001-01-15Martin Stjernholm  goto label_found_2;
5a0fd52001-01-10Martin Stjernholm  yyerror("Continue outside loop.");
f181de2001-01-11Martin Stjernholm  return 0;
5a0fd52001-01-10Martin Stjernholm  }
7acaf12001-01-15Martin Stjernholm  label_found_2: ; }
f181de2001-01-11Martin Stjernholm 
6c8ada2001-01-14Martin Stjernholm  for (p = current_label; 1; p = p->prev) { struct cleanup_frame *q;
7acaf12001-01-15Martin Stjernholm  for (q = p->cleanups; q; q = q->prev) { do_pop(current_stack_depth - q->stack_depth);
6c8ada2001-01-14Martin Stjernholm  q->cleanup(q->cleanup_arg);
7acaf12001-01-15Martin Stjernholm  } do_pop(current_stack_depth - p->stack_depth);
6c8ada2001-01-14Martin Stjernholm  if (p == label) break; }
f181de2001-01-11Martin Stjernholm  if (n->token == F_BREAK) { if (label->break_label < 0) label->emit_break_label = 1; label->break_label = do_branch(label->break_label); } else do_branch(label->continue_label);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0;
f181de2001-01-11Martin Stjernholm  }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
5a0fd52001-01-10Martin Stjernholm  case F_NORMAL_STMT_LABEL:
6c8ada2001-01-14Martin Stjernholm  case F_CUSTOM_STMT_LABEL: { struct statement_label *label; struct statement_label_name name;
1544fd2001-01-31Martin Stjernholm  BLOCK_BEGIN;
6c8ada2001-01-14Martin Stjernholm  PUSH_STATEMENT_LABEL; name.str = CAR(n)->u.sval.u.string; name.line_number = n->line_number; for (label = current_label; label; label = label->prev) { struct statement_label_name *lbl_name; for (lbl_name = label->name; lbl_name; lbl_name = lbl_name->next) if (lbl_name->str == name.str) { INT32 save_line = lex.current_line; lex.current_line = name.line_number; my_yyerror("Duplicate nested labels, previous one on line %d.", lbl_name->line_number); lex.current_line = save_line; goto label_check_done; } } label_check_done: name.next = current_label->name; current_label->name = &name; if (!name.next) { if (n->token == F_CUSTOM_STMT_LABEL) /* The statement we precede has custom label handling; leave * the statement_label "open" so the statement will use it * instead of covering it. */ current_label->break_label = -2; else current_label->break_label = -1; } DO_CODE_BLOCK(CDR(n)); if (!name.next && current_label->emit_break_label) low_insert_label(current_label->break_label); POP_STATEMENT_LABEL;
1544fd2001-01-31Martin Stjernholm  BLOCK_END;
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0;
6c8ada2001-01-14Martin Stjernholm  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_RETURN:
7a82f91996-04-13Fredrik Hübinette (Hubbe)  do_docode(CAR(n),0);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_RETURN);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; case F_SSCANF: tmp1=do_docode(CAR(n),DO_NOT_COPY); tmp2=do_docode(CDR(n),DO_NOT_COPY | DO_LVALUE);
393a592000-08-16Henrik Grubbström (Grubba)  emit1(F_SSCANF, DO_NOT_WARN((INT32)(tmp1+tmp2)));
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1;
6c8ada2001-01-14Martin Stjernholm  case F_CATCH: {
5267b71995-08-09Fredrik Hübinette (Hubbe)  INT32 *prev_switch_jumptable = current_switch_jumptable;
1544fd2001-01-31Martin Stjernholm 
7acaf12001-01-15Martin Stjernholm  tmp1=do_jump(F_CATCH,-1); PUSH_CLEANUP_FRAME(do_escape_catch, 0);
7a82f91996-04-13Fredrik Hübinette (Hubbe) 
7acaf12001-01-15Martin Stjernholm  PUSH_STATEMENT_LABEL;
5267b71995-08-09Fredrik Hübinette (Hubbe)  current_switch_jumptable=0;
5a0fd52001-01-10Martin Stjernholm  current_label->break_label=alloc_label(); if (TEST_COMPAT(7,0))
1544fd2001-01-31Martin Stjernholm  current_label->continue_label = current_label->break_label;
5267b71995-08-09Fredrik Hübinette (Hubbe)  DO_CODE_BLOCK(CAR(n));
5a0fd52001-01-10Martin Stjernholm  ins_label(current_label->break_label);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_THROW_ZERO);
7acaf12001-01-15Martin Stjernholm  POP_STATEMENT_LABEL;
1544fd2001-01-31Martin Stjernholm  current_switch_jumptable = prev_switch_jumptable;
7acaf12001-01-15Martin Stjernholm 
393a592000-08-16Henrik Grubbström (Grubba)  ins_label(DO_NOT_WARN((INT32)tmp1));
7acaf12001-01-15Martin Stjernholm  current_stack_depth++;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
6c8ada2001-01-14Martin Stjernholm  POP_AND_DONT_CLEANUP;
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1;
6c8ada2001-01-14Martin Stjernholm  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_LVALUE_LIST: return do_docode(CAR(n),DO_LVALUE)+do_docode(CDR(n),DO_LVALUE);
2a32691998-01-31Fredrik Hübinette (Hubbe)  case F_ARRAY_LVALUE: tmp1=do_docode(CAR(n),DO_LVALUE);
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
2a32691998-01-31Fredrik Hübinette (Hubbe)  if(tmp1 & 1)
a4a1722000-12-05Per Hedbor  fatal("Very internal compiler error.\n");
2a32691998-01-31Fredrik Hübinette (Hubbe) #endif
393a592000-08-16Henrik Grubbström (Grubba)  emit1(F_ARRAY_LVALUE, DO_NOT_WARN((INT32)(tmp1>>1)));
2a32691998-01-31Fredrik Hübinette (Hubbe)  return 2;
dffa011997-01-15Fredrik Hübinette (Hubbe)  case F_ARROW: if(CDR(n)->token != F_CONSTANT || CDR(n)->u.sval.type!=T_STRING) fatal("Bugg in F_ARROW, index not string.");
19aaeb1998-05-25Fredrik Hübinette (Hubbe)  if(flags & WANT_LVALUE)
dffa011997-01-15Fredrik Hübinette (Hubbe)  {
9b08a21998-03-31Fredrik Hübinette (Hubbe)  /* FIXME!!!! ??? I wonder what needs fixing... /Hubbe */
dffa011997-01-15Fredrik Hübinette (Hubbe)  tmp1=do_docode(CAR(n), 0);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit1(F_ARROW_STRING, store_prog_string(CDR(n)->u.sval.u.string));
dffa011997-01-15Fredrik Hübinette (Hubbe)  return 2; }else{
286afb2001-02-05Henrik Grubbström (Grubba)  tmp1 = do_docode(CAR(n), DO_NOT_COPY); if ((tmp2 = lfun_lookup_id(CDR(n)->u.sval.u.string)) != -1) { emit1(F_LOOKUP_LFUN, tmp2); } else { emit1(F_ARROW, store_prog_string(CDR(n)->u.sval.u.string)); }
dffa011997-01-15Fredrik Hübinette (Hubbe)  if(!(flags & DO_NOT_COPY)) { while(n && (n->token==F_INDEX || n->token==F_ARROW)) n=CAR(n); if(n->token==F_CONSTANT && !(n->node_info & OPT_EXTERNAL_DEPEND))
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_COPY_VALUE);
dffa011997-01-15Fredrik Hübinette (Hubbe)  } }
393a592000-08-16Henrik Grubbström (Grubba)  return DO_NOT_WARN((INT32)tmp1);
dffa011997-01-15Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_INDEX:
19aaeb1998-05-25Fredrik Hübinette (Hubbe)  if(flags & WANT_LVALUE)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
19aaeb1998-05-25Fredrik Hübinette (Hubbe)  int mklval=CAR(n) && match_types(CAR(n)->type, string_type_string);
a309212000-09-11Henrik Grubbström (Grubba)  tmp1 = do_docode(CAR(n), (INT16)(mklval ? DO_LVALUE_IF_POSSIBLE : 0));
19aaeb1998-05-25Fredrik Hübinette (Hubbe)  if(tmp1==2) {
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
19aaeb1998-05-25Fredrik Hübinette (Hubbe)  if(!mklval) fatal("Unwanted lvalue!\n"); #endif
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_INDIRECT);
19aaeb1998-05-25Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(do_docode(CDR(n),0) != 1)
a4a1722000-12-05Per Hedbor  fatal("Internal compiler error, please report this (1).");
e82b301997-01-29Fredrik Hübinette (Hubbe)  if(CDR(n)->token != F_CONSTANT && match_types(CDR(n)->type, string_type_string))
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_CLEAR_STRING_SUBTYPE);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 2; }else{ tmp1=do_docode(CAR(n), DO_NOT_COPY);
99761f1998-10-09Fredrik Hübinette (Hubbe) 
c64e8a1997-04-17Fredrik Hübinette (Hubbe)  code_expression(CDR(n), DO_NOT_COPY, "index");
99761f1998-10-09Fredrik Hübinette (Hubbe)  if(CDR(n)->token != F_CONSTANT && match_types(CDR(n)->type, string_type_string))
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_CLEAR_STRING_SUBTYPE);
19aaeb1998-05-25Fredrik Hübinette (Hubbe) 
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_INDEX);
19aaeb1998-05-25Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!(flags & DO_NOT_COPY)) {
dffa011997-01-15Fredrik Hübinette (Hubbe)  while(n && (n->token==F_INDEX || n->token==F_ARROW)) n=CAR(n);
5683de1995-11-06Fredrik Hübinette (Hubbe)  if(n->token==F_CONSTANT && !(n->node_info & OPT_EXTERNAL_DEPEND))
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_COPY_VALUE);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
393a592000-08-16Henrik Grubbström (Grubba)  return DO_NOT_WARN((INT32)tmp1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_CONSTANT: switch(n->u.sval.type) { case T_INT:
ece3201999-08-02Fredrik Hübinette (Hubbe)  if(!n->u.sval.u.integer && n->u.sval.subtype==NUMBER_UNDEFINED) {
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_UNDEFINED);
ece3201999-08-02Fredrik Hübinette (Hubbe)  }else{
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit1(F_NUMBER,n->u.sval.u.integer);
ece3201999-08-02Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; case T_STRING: tmp1=store_prog_string(n->u.sval.u.string);
393a592000-08-16Henrik Grubbström (Grubba)  emit1(F_STRING, DO_NOT_WARN((INT32)tmp1));
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; case T_FUNCTION:
bdb5091996-09-25Fredrik Hübinette (Hubbe)  if(n->u.sval.subtype!=FUNCTION_BUILTIN)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(n->u.sval.u.object == Pike_compiler->fake_object)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit1(F_LFUN,n->u.sval.subtype);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; }
6d22541998-01-28Fredrik Hübinette (Hubbe)  if(n->u.sval.u.object->next == n->u.sval.u.object) { int x=0;
f3c7152001-04-14Fredrik Hübinette (Hubbe) #if 0
6d22541998-01-28Fredrik Hübinette (Hubbe)  struct object *o;
ff88db2000-07-12Henrik Grubbström (Grubba) 
342fef2000-08-23Fredrik Hübinette (Hubbe)  for(o=Pike_compiler->fake_object;o!=n->u.sval.u.object;o=o->parent)
6d22541998-01-28Fredrik Hübinette (Hubbe)  x++;
f3c7152001-04-14Fredrik Hübinette (Hubbe) #else struct program_state *state=Pike_compiler; for(;state->fake_object!=n->u.sval.u.object;state=state->previous) x++; #endif
ff88db2000-07-12Henrik Grubbström (Grubba)  emit2(F_EXTERNAL, n->u.sval.subtype, x);
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->new_program->flags |= PROGRAM_USES_PARENT;
6d22541998-01-28Fredrik Hübinette (Hubbe)  return 1; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
6d22541998-01-28Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
6d22541998-01-28Fredrik Hübinette (Hubbe)  case T_OBJECT: if(n->u.sval.u.object->next == n->u.sval.u.object)
a4a1722000-12-05Per Hedbor  fatal("Internal error: Pointer to parent cannot be a compile time constant!\n");
6d22541998-01-28Fredrik Hübinette (Hubbe) #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  default:
454d541999-09-18Fredrik Hübinette (Hubbe)  tmp1=store_constant(&(n->u.sval), !(n->tree_info & OPT_EXTERNAL_DEPEND), n->name);
393a592000-08-16Henrik Grubbström (Grubba)  emit1(F_CONSTANT, DO_NOT_WARN((INT32)tmp1));
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; case T_ARRAY: case T_MAPPING:
06983f1996-09-22Fredrik Hübinette (Hubbe)  case T_MULTISET:
454d541999-09-18Fredrik Hübinette (Hubbe)  tmp1=store_constant(&(n->u.sval), !(n->tree_info & OPT_EXTERNAL_DEPEND), n->name);
393a592000-08-16Henrik Grubbström (Grubba)  emit1(F_CONSTANT, DO_NOT_WARN((INT32)tmp1));
5683de1995-11-06Fredrik Hübinette (Hubbe)  /* copy now or later ? */ if(!(flags & DO_NOT_COPY) && !(n->tree_info & OPT_EXTERNAL_DEPEND))
5e44422001-02-25Fredrik Hübinette (Hubbe)  { if(flags & DO_NOT_COPY_TOPLEVEL) { switch(n->u.sval.type) { case T_ARRAY: array_fix_type_field(n->u.sval.u.array); if(n->u.sval.u.array -> type_field & BIT_COMPLEX) emit0(F_COPY_VALUE); break; case T_MAPPING: mapping_fix_type_field(n->u.sval.u.mapping); if((n->u.sval.u.mapping->data->ind_types | n->u.sval.u.mapping->data->val_types) & BIT_COMPLEX) emit0(F_COPY_VALUE); break; case T_MULTISET: array_fix_type_field(n->u.sval.u.multiset->ind); if(n->u.sval.u.multiset->ind-> type_field & BIT_COMPLEX) emit0(F_COPY_VALUE); break; } }else{ emit0(F_COPY_VALUE); } }
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; } case F_LOCAL:
4218011999-01-31Fredrik Hübinette (Hubbe)  if(n->u.integer.a >= find_local_frame(n->u.integer.b)->max_number_of_locals)
a8ef6e1996-12-03Fredrik Hübinette (Hubbe)  yyerror("Illegal to use local variable here.");
4218011999-01-31Fredrik Hübinette (Hubbe)  if(n->u.integer.b)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
4218011999-01-31Fredrik Hübinette (Hubbe)  if(flags & WANT_LVALUE) {
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit2(F_LEXICAL_LOCAL_LVALUE,n->u.id.number,n->u.integer.b);
4218011999-01-31Fredrik Hübinette (Hubbe)  return 2; }else{
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit2(F_LEXICAL_LOCAL,n->u.id.number,n->u.integer.b);
4218011999-01-31Fredrik Hübinette (Hubbe)  return 1; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  }else{
4218011999-01-31Fredrik Hübinette (Hubbe)  if(flags & WANT_LVALUE) {
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit1(F_LOCAL_LVALUE,n->u.id.number);
4218011999-01-31Fredrik Hübinette (Hubbe)  return 2; }else{
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit1(F_LOCAL,n->u.id.number);
4218011999-01-31Fredrik Hübinette (Hubbe)  return 1; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
4218011999-01-31Fredrik Hübinette (Hubbe)  case F_TRAMPOLINE:
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit1(F_TRAMPOLINE,n->u.id.number);
4218011999-01-31Fredrik Hübinette (Hubbe)  return 1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_IDENTIFIER:
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(IDENTIFIER_IS_FUNCTION(ID_FROM_INT(Pike_compiler->new_program, n->u.id.number)->identifier_flags))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
19aaeb1998-05-25Fredrik Hübinette (Hubbe)  if(flags & WANT_LVALUE)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { yyerror("Cannot assign functions.\n"); }else{
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit1(F_LFUN,n->u.id.number);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }else{
19aaeb1998-05-25Fredrik Hübinette (Hubbe)  if(flags & WANT_LVALUE)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit1(F_GLOBAL_LVALUE,n->u.id.number);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 2; }else{
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit1(F_GLOBAL,n->u.id.number);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } } return 1; case F_VAL_LVAL:
a309212000-09-11Henrik Grubbström (Grubba)  return do_docode(CAR(n),flags) + do_docode(CDR(n), (INT16)(flags | DO_LVALUE));
5267b71995-08-09Fredrik Hübinette (Hubbe)  default:
f181de2001-01-11Martin Stjernholm  fatal("Infernal compiler error (unknown parse-tree-token %d).\n", n->token);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; /* make gcc happy */ } } void do_code_block(node *n) {
7acaf12001-01-15Martin Stjernholm #ifdef PIKE_DEBUG if (current_stack_depth != -4711) fatal("Reentrance in do_code_block().\n"); current_stack_depth = 0; #endif
7a82f91996-04-13Fredrik Hübinette (Hubbe)  init_bytecode();
6fd5172000-04-25Fredrik Hübinette (Hubbe)  label_no=1;
873ceb2000-04-30Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  emit1(F_BYTE,Pike_compiler->compiler_frame->max_number_of_locals); emit1(F_BYTE,Pike_compiler->compiler_frame->num_args);
873ceb2000-04-30Fredrik Hübinette (Hubbe)  emit0(F_START_FUNCTION);
928f952000-11-30Fredrik Hübinette (Hubbe)  low_insert_label(0);
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->new_program->identifier_references[Pike_compiler->compiler_frame->
873ceb2000-04-30Fredrik Hübinette (Hubbe)  current_function_number].id_flags & ID_INLINE) {
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->compiler_frame->recur_label=0; Pike_compiler->compiler_frame->is_inline=1;
873ceb2000-04-30Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  DO_CODE_BLOCK(n);
873ceb2000-04-30Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->compiler_frame->recur_label > 0)
873ceb2000-04-30Fredrik Hübinette (Hubbe)  { #ifdef PIKE_DEBUG if(l_flag) { fprintf(stderr,"Generating inline recursive function.\n"); } #endif /* generate code again, but this time it is inline */
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->compiler_frame->is_inline=1;
873ceb2000-04-30Fredrik Hübinette (Hubbe)  /* This is a no-op, but prevents optimizer to delete the bytes below */
928f952000-11-30Fredrik Hübinette (Hubbe)  low_insert_label(-1);
bad5162000-06-23Fredrik Hübinette (Hubbe)  emit1(F_BYTE,Pike_compiler->compiler_frame->max_number_of_locals); emit1(F_BYTE,Pike_compiler->compiler_frame->num_args);
873ceb2000-04-30Fredrik Hübinette (Hubbe)  emit0(F_START_FUNCTION);
928f952000-11-30Fredrik Hübinette (Hubbe)  low_insert_label(Pike_compiler->compiler_frame->recur_label);
873ceb2000-04-30Fredrik Hübinette (Hubbe)  DO_CODE_BLOCK(n); }
7a82f91996-04-13Fredrik Hübinette (Hubbe)  assemble();
7acaf12001-01-15Martin Stjernholm  #ifdef PIKE_DEBUG current_stack_depth = -4711; #endif
7a82f91996-04-13Fredrik Hübinette (Hubbe) } int docode(node *n) { int tmp; int label_no_save = label_no; dynamic_buffer instrbuf_save = instrbuf;
7acaf12001-01-15Martin Stjernholm  int stack_depth_save = current_stack_depth; struct statement_label *label_save = current_label; struct cleanup_frame *top_cleanups_save = top_statement_label_dummy.cleanups;
7a82f91996-04-13Fredrik Hübinette (Hubbe)  instrbuf.s.str=0;
6fd5172000-04-25Fredrik Hübinette (Hubbe)  label_no=1;
7acaf12001-01-15Martin Stjernholm  current_stack_depth = 0; current_label = &top_statement_label_dummy; /* Fix these two to */ top_statement_label_dummy.cleanups = 0; /* please F_PUSH_ARRAY. */
7a82f91996-04-13Fredrik Hübinette (Hubbe)  init_bytecode(); tmp=do_docode(n,0); assemble(); instrbuf=instrbuf_save; label_no = label_no_save;
7acaf12001-01-15Martin Stjernholm  current_stack_depth = stack_depth_save; current_label = label_save; top_statement_label_dummy.cleanups = top_cleanups_save;
7a82f91996-04-13Fredrik Hübinette (Hubbe)  return tmp;
5267b71995-08-09Fredrik Hübinette (Hubbe) }