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 
f90e541995-08-17Fredrik Hübinette (Hubbe) #include "global.h"
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"
1a26b22004-12-30Henrik Grubbström (Grubba) #include "pike_embed.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 "lex.h"
5e44422001-02-25Fredrik Hübinette (Hubbe) #include "mapping.h" #include "multiset.h"
e021fe2008-04-14Henrik Grubbström (Grubba) #include "pike_compiler.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) 
7e877a2003-04-02Martin Stjernholm static int do_docode2(node *n, int 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;
ef24a82012-01-12Henrik Grubbström (Grubba)  INT_TYPE line_number;
25702d2015-10-18Henrik Grubbström (Grubba)  int used;
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) \
5aad932002-08-15Marcus Comstedt  Pike_fatal("current_label points to an unused statement_label.\n"); \
6c8ada2001-01-14Martin Stjernholm  ) \ if (current_label->break_label == -2) { \ DO_IF_DEBUG( \ if (current_label->prev->break_label == -2) \
5aad932002-08-15Marcus Comstedt  Pike_fatal("Found two open statement_label entries in a row.\n"); \
6c8ada2001-01-14Martin Stjernholm  ) \ 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__) \
5aad932002-08-15Marcus Comstedt  Pike_fatal("Cleanup frame lost from statement_label cleanup list.\n");\
6c8ada2001-01-14Martin Stjernholm  ) \ 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); \
5aad932002-08-15Marcus Comstedt  Pike_fatal("Stack not in synch after block: is %d, should be %d.\n", \
1544fd2001-01-31Martin Stjernholm  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) \
5aad932002-08-15Marcus Comstedt  Pike_fatal("Cleanup frames still left in statement_label.\n")); \
5a0fd52001-01-10Martin Stjernholm } while (0)
5267b71995-08-09Fredrik Hübinette (Hubbe) 
9abda42002-03-02Martin Stjernholm struct switch_data { INT32 index; INT32 less_label, greater_label, default_label; INT32 values_on_stack; INT32 *jumptable; struct pike_type *type; }; static struct switch_data current_switch = {0, 0, 0, 0, 0, NULL, 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) {
c9d3972014-09-03Martin Nilsson  memcpy(Pike_compiler->new_program->program+offset, &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) {
cd93cc2017-07-20Martin Nilsson  return (INT32)get_unaligned32(Pike_compiler->new_program->program+offset);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
7a82f91996-04-13Fredrik Hübinette (Hubbe) 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) {
e021fe2008-04-14Henrik Grubbström (Grubba)  struct compilation *c = THIS_COMPILATION;
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
7563742016-11-08Arne Goedeke #define CURRENT_INSTR (buffer_content_length(&instrbuf) / sizeof(p_instr))
928f952000-11-30Fredrik Hübinette (Hubbe) #define MAX_UNWIND 100 static int lbl_cache[LBLCACHESIZE];
8b62562006-02-25Martin Stjernholm static int do_branch(INT32 lbl)
928f952000-11-30Fredrik Hübinette (Hubbe) {
e021fe2008-04-14Henrik Grubbström (Grubba)  struct compilation *c = THIS_COMPILATION;
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) {
7563742016-11-08Arne Goedeke #define BUF ((p_instr *)buffer_ptr(&instrbuf))
928f952000-11-30Fredrik Hübinette (Hubbe)  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; }
8b62562006-02-25Martin Stjernholm static void low_insert_label(int lbl)
928f952000-11-30Fredrik Hübinette (Hubbe) {
e021fe2008-04-14Henrik Grubbström (Grubba)  struct compilation *c = THIS_COMPILATION;
928f952000-11-30Fredrik Hübinette (Hubbe)  lbl_cache[ lbl % LBLCACHESIZE ] = CURRENT_INSTR; emit1(F_LABEL, lbl); }
8b62562006-02-25Martin Stjernholm static int ins_label(int lbl)
928f952000-11-30Fredrik Hübinette (Hubbe) { if(lbl==-1) lbl=alloc_label(); low_insert_label(lbl); return lbl; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
1493c52008-08-28Henrik Grubbström (Grubba) void modify_stack_depth(int delta) { current_stack_depth += delta; #ifdef PIKE_DEBUG if (current_stack_depth < 0) { Pike_fatal("Popped out of virtual stack.\n"); } #endif }
a7622c1996-08-06Fredrik Hübinette (Hubbe) void do_pop(int x)
7a82f91996-04-13Fredrik Hübinette (Hubbe) {
e021fe2008-04-14Henrik Grubbström (Grubba)  struct compilation *c = THIS_COMPILATION;
6c8ada2001-01-14Martin Stjernholm #ifdef PIKE_DEBUG
5aad932002-08-15Marcus Comstedt  if (x < 0) Pike_fatal("Cannot do pop of %d args.\n", x);
6c8ada2001-01-14Martin Stjernholm #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)  }
2a50e72017-06-07Henrik Grubbström (Grubba)  modify_stack_depth(-x);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
66d51c1997-03-04Fredrik Hübinette (Hubbe) 
74dfe82012-12-30Jonas Walldén static void do_pop_mark(void *UNUSED(ignored))
7acaf12001-01-15Martin Stjernholm {
e021fe2008-04-14Henrik Grubbström (Grubba)  struct compilation *c = THIS_COMPILATION;
7acaf12001-01-15Martin Stjernholm  emit0(F_POP_MARK); }
74dfe82012-12-30Jonas Walldén static void do_pop_to_mark(void *UNUSED(ignored))
7acaf12001-01-15Martin Stjernholm {
e021fe2008-04-14Henrik Grubbström (Grubba)  struct compilation *c = THIS_COMPILATION;
7acaf12001-01-15Martin Stjernholm  emit0(F_POP_TO_MARK); }
1d6ca22008-06-30Martin Stjernholm #ifdef PIKE_DEBUG
8b62562006-02-25Martin Stjernholm static void do_cleanup_synch_mark(void)
1544fd2001-01-31Martin Stjernholm {
e021fe2008-04-14Henrik Grubbström (Grubba)  struct compilation *c = THIS_COMPILATION;
1544fd2001-01-31Martin Stjernholm  if (d_flag > 2) emit0(F_CLEANUP_SYNCH_MARK); }
1d6ca22008-06-30Martin Stjernholm #endif
1544fd2001-01-31Martin Stjernholm 
8b62562006-02-25Martin Stjernholm static void do_escape_catch(void)
f181de2001-01-11Martin Stjernholm {
e021fe2008-04-14Henrik Grubbström (Grubba)  struct compilation *c = THIS_COMPILATION;
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) 
7e877a2003-04-02Martin Stjernholm int do_docode(node *n, int flags)
5267b71995-08-09Fredrik Hübinette (Hubbe) { int i;
7acaf12001-01-15Martin Stjernholm  int stack_depth_save = current_stack_depth;
e021fe2008-04-14Henrik Grubbström (Grubba)  struct compilation *c = THIS_COMPILATION;
ef24a82012-01-12Henrik Grubbström (Grubba)  INT_TYPE save_current_line = c->lex.current_line;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!n) return 0;
e021fe2008-04-14Henrik Grubbström (Grubba)  c->lex.current_line=n->line_number;
7acaf12001-01-15Martin Stjernholm #ifdef PIKE_DEBUG
5aad932002-08-15Marcus Comstedt  if (current_stack_depth == -4711) Pike_fatal("do_docode() used outside docode().\n");
7acaf12001-01-15Martin Stjernholm #endif
0b84582007-10-06Henrik Grubbström (Grubba)  i=do_docode2(n, flags);
7acaf12001-01-15Martin Stjernholm  current_stack_depth = stack_depth_save + i;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
e021fe2008-04-14Henrik Grubbström (Grubba)  c->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 &&
017b572011-10-28Henrik Grubbström (Grubba)  SUBTYPEOF(n->u.sval) == FUNCTION_BUILTIN &&
419fab1997-03-09Fredrik Hübinette (Hubbe)  n->u.sval.u.efun->function == fun; }
7e877a2003-04-02Martin Stjernholm static void code_expression(node *n, int flags, char *err)
c64e8a1997-04-17Fredrik Hübinette (Hubbe) {
0b84582007-10-06Henrik Grubbström (Grubba)  switch(do_docode(n, flags & ~DO_POP))
c64e8a1997-04-17Fredrik Hübinette (Hubbe)  { case 0: my_yyerror("Void expression for %s",err); case 1: return; case 2:
5aad932002-08-15Marcus Comstedt  Pike_fatal("Internal compiler error (%s), line %ld, file %s\n",
e021fe2008-04-14Henrik Grubbström (Grubba)  err, (long)THIS_COMPILATION->lex.current_line, THIS_COMPILATION->lex.current_file->str);
c64e8a1997-04-17Fredrik Hübinette (Hubbe)  } }
b662d92014-05-08Per Hedbor static 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;
13670c2015-05-25Martin Nilsson 
419fab1997-03-09Fredrik Hübinette (Hubbe)  case F_APPLY:
2d12341997-03-10Fredrik Hübinette (Hubbe)  if(!is_efun(CAR(n), f_not)) break;
3595ea2018-02-12Marcus Comstedt  /* FALLTHRU */
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;
d819fe2016-10-22Henrik Grubbström (Grubba)  default: /* Inform gcc that we handle all the values in the enum. */ break;
a7622c1996-08-06Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
7e877a2003-04-02Martin Stjernholm  code_expression(n, flags | DO_NOT_COPY, "condition");
13670c2015-05-25Martin Nilsson 
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);
2a50e72017-06-07Henrik Grubbström (Grubba)  modify_stack_depth(-1);
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:
9abda42002-03-02Martin Stjernholm  return 1; case F_CASE_RANGE:
5267b71995-08-09Fredrik Hübinette (Hubbe)  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; } }
c280762014-08-14Per Hedbor static int has_automap(node *n) { if(!n) return 0; switch(n->token) { case F_AUTO_MAP_MARKER: case F_AUTO_MAP: return 1; default: if(car_is_node(n) && has_automap(CAR(n)) ) return 1; if( cdr_is_node(n) && has_automap(CDR(n)) ) return 1; } return 0; }
4f20e92001-01-25Fredrik Hübinette (Hubbe)  int generate_call_function(node *n) {
e021fe2008-04-14Henrik Grubbström (Grubba)  struct compilation *c = THIS_COMPILATION;
4f20e92001-01-25Fredrik Hübinette (Hubbe)  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; }
b662d92014-05-08Per Hedbor static struct compiler_frame *find_local_frame(INT32 depth)
4218011999-01-31Fredrik Hübinette (Hubbe) {
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; }
5e5a592002-11-14Henrik Grubbström (Grubba) /* Emit code for a function call to the identifier reference #id, * with the arguments specified by args. */
8b62562006-02-25Martin Stjernholm static int do_lfun_call(int id, node *args)
6fd5172000-04-25Fredrik Hübinette (Hubbe) {
e021fe2008-04-14Henrik Grubbström (Grubba)  struct compilation *c = THIS_COMPILATION;
5e5a592002-11-14Henrik Grubbström (Grubba)  struct reference *ref = Pike_compiler->new_program->identifier_references + id;
4e1fb32014-08-07Per Hedbor  if((Pike_compiler->compiler_frame->current_function_number >= 0) && ((id == Pike_compiler->compiler_frame->current_function_number) || ((!ref->inherit_offset) && (ref->identifier_offset == Pike_compiler->new_program-> identifier_references[Pike_compiler->compiler_frame-> current_function_number].identifier_offset))) && !(Pike_compiler->new_program-> identifiers[ref->identifier_offset].identifier_flags & (IDENTIFIER_VARARGS|IDENTIFIER_SCOPE_USED)) && !(Pike_compiler->compiler_frame->lexical_scope & SCOPE_SCOPE_USED)) { PUSH_CLEANUP_FRAME(do_pop_mark, 0); emit0(F_MARK); do_docode(args,0);
45dda92012-06-10Henrik Grubbström (Grubba) 
1918542002-11-22Henrik Grubbström (Grubba)  /* Test description: * * * Test if we have a valid current function. * * * Quick check if id is the current function. * * * Check if id is an alternate reference to the current function.
f5cfc32002-11-23Martin Stjernholm  *
2bc1702008-07-14Henrik Grubbström (Grubba)  * * Check that the function isn't varargs or contains scoped functions. * * * Check that the current function doesn't contain scoped functions.
1918542002-11-22Henrik Grubbström (Grubba)  */
4e1fb32014-08-07Per Hedbor  if(Pike_compiler->compiler_frame->is_inline || (ref->id_flags & (ID_INLINE|ID_PRIVATE)))
6fd5172000-04-25Fredrik Hübinette (Hubbe)  {
45dda92012-06-10Henrik Grubbström (Grubba)  /* Identifier is declared inline/local * or in inlining pass. */
4e1fb32014-08-07Per Hedbor  if ((ref->id_flags & (ID_INLINE|ID_PRIVATE)) &&
45dda92012-06-10Henrik Grubbström (Grubba)  (!Pike_compiler->compiler_frame->is_inline)) { /* Explicit local:: reference in first pass. * * RECUR directly to label 0. * * Note that we in this case don't know if we are overloaded or * not, and thus can't RECUR to the recur_label.
5e5a592002-11-14Henrik Grubbström (Grubba)  */
45dda92012-06-10Henrik Grubbström (Grubba)  do_jump(F_RECUR, 0);
5e5a592002-11-14Henrik Grubbström (Grubba)  } else {
45dda92012-06-10Henrik Grubbström (Grubba)  Pike_compiler->compiler_frame->recur_label = do_jump(F_RECUR, Pike_compiler->compiler_frame->recur_label);
6fd5172000-04-25Fredrik Hübinette (Hubbe)  }
45dda92012-06-10Henrik Grubbström (Grubba)  } else { /* Recur if not overloaded. */ emit1(F_COND_RECUR,id); Pike_compiler->compiler_frame->recur_label = do_jump(F_POINTER, Pike_compiler->compiler_frame->recur_label);
6fd5172000-04-25Fredrik Hübinette (Hubbe)  }
4e1fb32014-08-07Per Hedbor  POP_AND_DONT_CLEANUP; return 1; } else { #ifdef USE_APPLY_N int nargs = count_args(args); if( nargs == -1 ) { #endif PUSH_CLEANUP_FRAME(do_pop_mark, 0); emit0(F_MARK); do_docode(args,0); emit1(F_CALL_LFUN, id); POP_AND_DONT_CLEANUP; return 1; #ifdef USE_APPLY_N } else { do_docode(args,0); emit2(F_CALL_LFUN_N, id, nargs); } #endif
6fd5172000-04-25Fredrik Hübinette (Hubbe)  } return 1; }
8bef1b2001-09-27Fredrik Hübinette (Hubbe) /* * FIXME: this can be optimized, but is not really used * enough to be worth it yet. */ static void emit_apply_builtin(char *func) { INT32 tmp1;
e021fe2008-04-14Henrik Grubbström (Grubba)  struct compilation *c = THIS_COMPILATION;
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  struct pike_string *n1=make_shared_string(func); node *n=find_module_identifier(n1,0); free_string(n1); switch(n?n->token:0) { case F_CONSTANT: tmp1=store_constant(&n->u.sval,
515bcf2002-07-02Henrik Grubbström (Grubba)  !(n->tree_info & OPT_EXTERNAL_DEPEND),
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  n->name);
017b572011-10-28Henrik Grubbström (Grubba)  if(TYPEOF(n->u.sval) == T_FUNCTION && SUBTYPEOF(n->u.sval) == FUNCTION_BUILTIN)
bd67392015-10-14Martin Nilsson  emit1(F_CALL_BUILTIN, (INT32)tmp1);
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  else
bd67392015-10-14Martin Nilsson  emit1(F_APPLY, (INT32)tmp1);
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  break; default: my_yyerror("docode: Failed to make call to %s",func); } free_node(n); } static int do_encode_automap_arg_list(node *n,
7e877a2003-04-02Martin Stjernholm  int flags)
8bef1b2001-09-27Fredrik Hübinette (Hubbe) {
e021fe2008-04-14Henrik Grubbström (Grubba)  struct compilation *c = THIS_COMPILATION;
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  int stack_depth_save = current_stack_depth; if(!n) return 0; switch(n->token) { default: return do_docode(n, flags); case F_ARG_LIST: { int ret; ret=do_encode_automap_arg_list(CAR(n), flags); current_stack_depth=stack_depth_save + ret; ret+=do_encode_automap_arg_list(CDR(n), flags); current_stack_depth=stack_depth_save + ret; return ret; } case F_AUTO_MAP_MARKER: { int depth=0; while(n->token == F_AUTO_MAP_MARKER) { n=CAR(n); depth++; } emit0(F_MARK); code_expression(n, 0, "[*]"); emit1(F_NUMBER, depth); emit_apply_builtin("__builtin.automap_marker"); return 1; } } }
005bf42001-09-29Fredrik Hübinette (Hubbe) static void emit_builtin_svalue(char *func) { INT32 tmp1;
e021fe2008-04-14Henrik Grubbström (Grubba)  struct compilation *c = THIS_COMPILATION;
005bf42001-09-29Fredrik Hübinette (Hubbe)  struct pike_string *n1=make_shared_string(func); node *n=find_module_identifier(n1,0); free_string(n1); switch(n?n->token:0) { case F_CONSTANT: tmp1=store_constant(&n->u.sval,
515bcf2002-07-02Henrik Grubbström (Grubba)  (!(n->tree_info & OPT_EXTERNAL_DEPEND)) &&
017b572011-10-28Henrik Grubbström (Grubba)  (TYPEOF(n->u.sval) != T_TYPE),
005bf42001-09-29Fredrik Hübinette (Hubbe)  n->name);
bd67392015-10-14Martin Nilsson  emit1(F_CONSTANT, (INT32)tmp1);
005bf42001-09-29Fredrik Hübinette (Hubbe)  break; default: my_yyerror("docode: Failed to make svalue for builtin %s",func); } free_node(n); }
8bef1b2001-09-27Fredrik Hübinette (Hubbe) 
408a1e2004-10-30Martin Stjernholm static void emit_range (node *n DO_IF_DEBUG (COMMA int num_args)) {
e021fe2008-04-14Henrik Grubbström (Grubba)  struct compilation *c = THIS_COMPILATION;
408a1e2004-10-30Martin Stjernholm  node *low = CADR (n), *high = CDDR (n);
61989f2013-02-06Henrik Grubbström (Grubba)  int bound_types = 0; /* Got bogus gcc warning here. */
408a1e2004-10-30Martin Stjernholm  switch (low->token) { case F_RANGE_FROM_BEG: bound_types = RANGE_LOW_FROM_BEG; break; case F_RANGE_FROM_END: bound_types = RANGE_LOW_FROM_END; break; case F_RANGE_OPEN: bound_types = RANGE_LOW_OPEN; break; #ifdef PIKE_DEBUG default: Pike_fatal ("Unexpected node %d as range lower bound.\n", low->token); #endif } switch (high->token) { case F_RANGE_FROM_BEG: bound_types |= RANGE_HIGH_FROM_BEG; break; case F_RANGE_FROM_END: bound_types |= RANGE_HIGH_FROM_END; break; case F_RANGE_OPEN: bound_types |= RANGE_HIGH_OPEN; break; #ifdef PIKE_DEBUG default: Pike_fatal ("Unexpected node %d as range upper bound.\n", high->token); #endif } #ifdef PIKE_DEBUG {
0b84582007-10-06Henrik Grubbström (Grubba)  int expected_args = 0;
408a1e2004-10-30Martin Stjernholm  switch (bound_types & (RANGE_LOW_OPEN|RANGE_HIGH_OPEN)) { case 0: expected_args = 2; break; case RANGE_LOW_OPEN: case RANGE_HIGH_OPEN: expected_args = 1; break; case RANGE_LOW_OPEN|RANGE_HIGH_OPEN: expected_args = 0; break; } if (num_args != expected_args) Pike_fatal ("Wrong number of args to o_range opcode. Expected %d, got %d.\n", expected_args, num_args); } #endif emit1 (F_RANGE, bound_types); }
4ec32c2014-08-07Per Hedbor static void emit_global( int n ) { struct compilation *c = THIS_COMPILATION; struct reference *ref = PTR_FROM_INT(Pike_compiler->new_program, n); struct identifier *id = ID_FROM_PTR(Pike_compiler->new_program, ref);
12cfbe2014-08-11Per Hedbor 
83b92e2014-08-16Per Hedbor  if(!(id->identifier_flags & IDENTIFIER_NO_THIS_REF)
ca56552014-08-18Per Hedbor  && !ref->inherit_offset
83b92e2014-08-16Per Hedbor  && !IDENTIFIER_IS_ALIAS(id->identifier_flags) && IDENTIFIER_IS_VARIABLE(id->identifier_flags))
4ec32c2014-08-07Per Hedbor  { /* fprintf( stderr, "private global %d\n", (INT32)id->func.offset ); */
83b92e2014-08-16Per Hedbor  if( ref->id_flags & (ID_PRIVATE|ID_FINAL) ) { if( id->run_time_type == PIKE_T_MIXED ) emit1(F_PRIVATE_GLOBAL, id->func.offset); else emit2(F_PRIVATE_TYPED_GLOBAL, id->func.offset, id->run_time_type); return; }
ca56552014-08-18Per Hedbor  if( id->run_time_type == PIKE_T_MIXED )
83b92e2014-08-16Per Hedbor  {
ca56552014-08-18Per Hedbor  emit2(F_PRIVATE_IF_DIRECT_GLOBAL, id->func.offset, n); return; } /* else if( (id->func.offset < 65536) && (n<65536) ) */ /* { */
83b92e2014-08-16Per Hedbor /* INT32 mix = id->func.offset | (n<<16); */ /* emit2(F_PRIVATE_IF_DIRECT_TYPED_GLOBAL, mix, id->run_time_type); */
ca56552014-08-18Per Hedbor /* } */
4ec32c2014-08-07Per Hedbor  }
83b92e2014-08-16Per Hedbor  emit1(F_GLOBAL, n);
4ec32c2014-08-07Per Hedbor } static void emit_assign_global( int n, int and_pop ) { struct compilation *c = THIS_COMPILATION; struct reference *ref = PTR_FROM_INT(Pike_compiler->new_program, n); struct identifier *id = ID_FROM_PTR(Pike_compiler->new_program, ref);
83b92e2014-08-16Per Hedbor  if( !(id->identifier_flags & IDENTIFIER_NO_THIS_REF)
ca56552014-08-18Per Hedbor  && !ref->inherit_offset
12cfbe2014-08-11Per Hedbor  && !IDENTIFIER_IS_ALIAS(id->identifier_flags)
83b92e2014-08-16Per Hedbor  && IDENTIFIER_IS_VARIABLE(id->identifier_flags))
4ec32c2014-08-07Per Hedbor  {
83b92e2014-08-16Per Hedbor  if( (ref->id_flags & (ID_PRIVATE|ID_FINAL)) ) { if( id->run_time_type == PIKE_T_MIXED )
da045c2014-08-14Per Hedbor  emit1((and_pop?F_ASSIGN_PRIVATE_GLOBAL_AND_POP:F_ASSIGN_PRIVATE_GLOBAL), id->func.offset);
83b92e2014-08-16Per Hedbor  else
da045c2014-08-14Per Hedbor  emit2((and_pop?F_ASSIGN_PRIVATE_TYPED_GLOBAL_AND_POP:F_ASSIGN_PRIVATE_TYPED_GLOBAL), id->func.offset, id->run_time_type);
83b92e2014-08-16Per Hedbor  return; } if( id->run_time_type == PIKE_T_MIXED ) { emit2(F_ASSIGN_PRIVATE_IF_DIRECT_GLOBAL, id->func.offset, n ); if( and_pop ) emit0(F_POP_VALUE); return; }
4ec32c2014-08-07Per Hedbor  }
83b92e2014-08-16Per Hedbor  emit1((and_pop?F_ASSIGN_GLOBAL_AND_POP:F_ASSIGN_GLOBAL), n);
4ec32c2014-08-07Per Hedbor }
f85f662014-08-14Per Hedbor static int emit_ltosval_call_and_assign( node *lval, node *func, node *args ) { struct compilation *c = THIS_COMPILATION; node **arg; int no = 0; int tmp1=store_constant(&func->u.sval, !(func->tree_info & OPT_EXTERNAL_DEPEND), func->name); #ifdef PIKE_DEBUG arg = my_get_arg(&args,0); if( !node_is_eq(*arg,lval) ) Pike_fatal("lval should be the same as arg1, or this will not work.\n"); #endif do_docode(lval, DO_LVALUE); emit0(F_MARK); emit0(F_CONST0); PUSH_CLEANUP_FRAME(do_pop_mark, 0); while ((arg = my_get_arg(&args, ++no)) && *arg) { do_docode(*arg, 0); }
bd67392015-10-14Martin Nilsson  emit1(F_LTOSVAL_CALL_BUILTIN_AND_ASSIGN, (INT32)tmp1);
f85f662014-08-14Per Hedbor  POP_AND_DONT_CLEANUP; return 1; }
4b8e592015-02-20Per Hedbor static int is_apply_constant_function_arg0( node *n, node *target ) {
13670c2015-05-25Martin Nilsson  if (/*n->token == F_APPLY &&*/
4b8e592015-02-20Per Hedbor  (CAR(n)->token == F_CONSTANT) && (TYPEOF(CAR(n)->u.sval) == T_FUNCTION) && (SUBTYPEOF(CAR(n)->u.sval) == FUNCTION_BUILTIN) && (CAR(n)->u.sval.u.efun->function != f_map) && (CAR(n)->u.sval.u.efun->function != f_filter)) { /* efuns typically don't access object variables. */ node *args = CDR(n), **arg; if (args) { arg = my_get_arg(&args, 0); if (arg && node_is_eq(target, *arg) && !(args->tree_info & OPT_ASSIGNMENT)) { if(match_types(target->type, array_type_string) || match_types(target->type, string_type_string) || match_types(target->type, object_type_string) || match_types(target->type, multiset_type_string) || match_types(target->type, mapping_type_string)) { return emit_ltosval_call_and_assign(target,CAR(n),args); } } } } return 0; }
13cdf22008-01-28Henrik Grubbström (Grubba) static void emit_multi_assign(node *vals, node *vars, int no) {
e021fe2008-04-14Henrik Grubbström (Grubba)  struct compilation *c = THIS_COMPILATION;
13cdf22008-01-28Henrik Grubbström (Grubba)  node *var; node *val; node **valp = my_get_arg(&vals, no); if (!vars && (!valp || !*valp)) return; if (!(vars && valp && (val = *valp))) { yyerror("Argument count mismatch for multi-assignment.\n"); return; }
f85f662014-08-14Per Hedbor 
13cdf22008-01-28Henrik Grubbström (Grubba)  if (vars->token == F_LVALUE_LIST) { var = CAR(vars); vars = CDR(vars); } else { var = vars; vars = NULL; } switch(var->token) { case F_LOCAL:
13670c2015-05-25Martin Nilsson  if(var->u.integer.a >=
27404b2008-01-29Henrik Grubbström (Grubba)  find_local_frame(var->u.integer.b)->max_number_of_locals)
13cdf22008-01-28Henrik Grubbström (Grubba)  yyerror("Illegal to use local variable here."); if(var->u.integer.b) goto normal_assign; if (var->node_info & OPT_ASSIGNMENT) { /* Initialize. */ emit0(F_CONST0); emit1(F_ASSIGN_LOCAL_AND_POP, var->u.integer.a); } code_expression(val, 0, "RHS"); emit_multi_assign(vals, vars, no+1); emit1(F_ASSIGN_LOCAL_AND_POP, var->u.integer.a ); break; case F_GET_SET: { /* Check for the setter function. */ struct program_state *state = Pike_compiler; int program_id = var->u.integer.a; int level = 0; while (state && (state->new_program->id != program_id)) { state = state->previous; level++; } if (!state) { yyerror("Lost parent."); } else { struct reference *ref = PTR_FROM_INT(state->new_program, var->u.integer.b); struct identifier *id = ID_FROM_PTR(state->new_program, ref); struct inherit *inh = INHERIT_FROM_PTR(state->new_program, ref); int f; #ifdef PIKE_DEBUG if (!IDENTIFIER_IS_VARIABLE(id->identifier_flags) || (id->run_time_type != PIKE_T_GET_SET)) { Pike_fatal("Not a getter/setter in a F_GET_SET node!\n" " identifier_flags: 0x%08x\n" " run_time_type; %s (%d)\n", id->identifier_flags, get_name_of_type(id->run_time_type), id->run_time_type); } #endif /* PIKE_DEBUG */
85e4552008-05-13Henrik Grubbström (Grubba)  f = id->func.gs_info.setter;
13cdf22008-01-28Henrik Grubbström (Grubba)  if (f == -1) { yywarning("Variable %S lacks a setter.", id->name); } else if (!level) { f += inh->identifier_level; emit0(F_MARK); code_expression(val, 0, "RHS"); emit_multi_assign(vals, vars, no+1); emit1(F_CALL_LFUN, f); emit0(F_POP_VALUE); } } }
5f50842018-02-12Marcus Comstedt  /* FALLTHRU */
13cdf22008-01-28Henrik Grubbström (Grubba)  case F_EXTERNAL: /* Check that it is in this context */ if(Pike_compiler ->new_program->id == var->u.integer.a) { /* Check that it is a variable */ if(var->u.integer.b != IDREF_MAGIC_THIS && IDENTIFIER_IS_VARIABLE( ID_FROM_INT(Pike_compiler->new_program, var->u.integer.b)->identifier_flags)) { code_expression(val, 0, "RHS"); emit_multi_assign(vals, vars, no+1);
4ec32c2014-08-07Per Hedbor  emit_assign_global( var->u.integer.b, 1 );
13cdf22008-01-28Henrik Grubbström (Grubba)  break; } } /* fall through */ default: normal_assign: do_docode(var, DO_LVALUE); if(do_docode(val, 0) != 1) yyerror("RHS is void!"); emit_multi_assign(vals, vars, no+1); emit0(F_ASSIGN_AND_POP); break; } }
7e877a2003-04-02Martin Stjernholm static int do_docode2(node *n, int flags)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
e021fe2008-04-14Henrik Grubbström (Grubba)  struct compilation *c = THIS_COMPILATION;
e0755c2000-08-15Henrik Grubbström (Grubba)  ptrdiff_t tmp1,tmp2,tmp3;
57c2872003-09-19Henrik Grubbström (Grubba)  int ret;
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;
13670c2015-05-25Martin Nilsson 
2a32691998-01-31Fredrik Hübinette (Hubbe)  case F_ARRAY_LVALUE: case F_LVALUE_LIST: case F_LOCAL: case F_GLOBAL: 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:
0e757b2006-10-28Henrik Grubbström (Grubba)  case F_GET_SET:
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  case F_AUTO_MAP_MARKER:
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 ;
13670c2015-05-25Martin Nilsson  x_*=STACK_DIRECTION;
f9abcf1999-09-16Fredrik Hübinette (Hubbe)  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:
cbe1132001-12-16Martin Stjernholm  case F_MAGIC_INDICES: case F_MAGIC_VALUES:
7195af2011-01-15Henrik Grubbström (Grubba)  case F_MAGIC_TYPES:
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;
13670c2015-05-25Martin Nilsson 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case F_EXTERNAL:
0e757b2006-10-28Henrik Grubbström (Grubba)  case F_GET_SET:
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  {
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)) {
afb16a2010-11-11Henrik Grubbström (Grubba)  if ((flags & WANT_LVALUE) || (n->node_info & (OPT_EXTERNAL_DEPEND|OPT_NOT_CONST))) { /* Not a reference to a locally bound external constant. * We will thus need true parent pointers. */ state->new_program->flags |= PROGRAM_USES_PARENT | PROGRAM_NEEDS_PARENT; }
ff88db2000-07-12Henrik Grubbström (Grubba)  state = state->previous; level++; } if (!state) { my_yyerror("Program parent %d lost during compiling.", n->u.integer.a); emit1(F_NUMBER,0);
0e757b2006-10-28Henrik Grubbström (Grubba)  } else if (flags & WANT_LVALUE) { if (n->u.integer.b == IDREF_MAGIC_THIS) { my_yyerror("this is not an lvalue."); } if (level) {
342fef2000-08-23Fredrik Hübinette (Hubbe)  emit2(F_EXTERNAL_LVALUE, n->u.integer.b, level);
0e757b2006-10-28Henrik Grubbström (Grubba)  } else { emit1(F_GLOBAL_LVALUE, n->u.integer.b);
342fef2000-08-23Fredrik Hübinette (Hubbe)  }
0e757b2006-10-28Henrik Grubbström (Grubba)  return 2; } else { struct reference *ref = PTR_FROM_INT(state->new_program, n->u.integer.b); struct identifier *id = ID_FROM_PTR(state->new_program, ref); if (n->token == F_GET_SET) { struct inherit *inh = INHERIT_FROM_PTR(state->new_program, ref); int f; #ifdef PIKE_DEBUG if (!IDENTIFIER_IS_VARIABLE(id->identifier_flags) || (id->run_time_type != PIKE_T_GET_SET)) { Pike_fatal("Not a getter/setter in a F_GET_SET node!\n" " identifier_flags: 0x%08x\n" " run_time_type; %s (%d)\n", id->identifier_flags, get_name_of_type(id->run_time_type), id->run_time_type);
57306e2004-12-18Henrik Grubbström (Grubba)  }
0e757b2006-10-28Henrik Grubbström (Grubba) #endif /* PIKE_DEBUG */
85e4552008-05-13Henrik Grubbström (Grubba)  f = id->func.gs_info.getter;
0e757b2006-10-28Henrik Grubbström (Grubba)  if (f == -1) { yywarning("Variable %S lacks a getter.", id->name); } else if (!level) { return do_lfun_call(f + inh->identifier_level, NULL); } else { /* FIXME: Support inlining for the parent case. * * do_call_external(n->u.integer.a, f + inh->identifier_level, * NULL); */ emit2(F_EXTERNAL, n->u.integer.b, level);
342fef2000-08-23Fredrik Hübinette (Hubbe)  }
0e757b2006-10-28Henrik Grubbström (Grubba)  } else if (level) {
83128f2010-07-01Henrik Grubbström (Grubba)  if (IDENTIFIER_IS_CONSTANT(id->identifier_flags) &&
5d4cba2013-11-10Henrik Grubbström (Grubba)  (ref->id_flags & ID_INLINE) &&
89378b2010-11-23Henrik Grubbström (Grubba)  (id->func.const_info.offset >= 0)) {
83128f2010-07-01Henrik Grubbström (Grubba)  /* An inline, local or final constant identifier in * a lexically surrounding (aka parent) class. * Avoid vtable traversal during runtime by moving * the constant to this class. */
05c3732010-07-04Henrik Grubbström (Grubba)  struct svalue *s = &state->new_program->
5d4cba2013-11-10Henrik Grubbström (Grubba)  inherits[ref->inherit_offset].prog->
89378b2010-11-23Henrik Grubbström (Grubba)  constants[id->func.const_info.offset].sval;
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(*s) == T_PROGRAM &&
05c3732010-07-04Henrik Grubbström (Grubba)  s->u.program->flags & PROGRAM_USES_PARENT) { /* An external reference is required. */ emit2(F_EXTERNAL, n->u.integer.b, level); } else { int tmp1 = store_constant(s, 1, NULL); emit1(F_CONSTANT, tmp1); }
83128f2010-07-01Henrik Grubbström (Grubba)  } else {
5d4cba2013-11-10Henrik Grubbström (Grubba)  struct program_state *state = Pike_compiler; int e; for (e = level; e; e--) { state->new_program->flags |= PROGRAM_USES_PARENT|PROGRAM_NEEDS_PARENT; state = state->previous; }
83128f2010-07-01Henrik Grubbström (Grubba)  emit2(F_EXTERNAL, n->u.integer.b, level); }
0e757b2006-10-28Henrik Grubbström (Grubba)  } else if (n->u.integer.b == IDREF_MAGIC_THIS) { emit1(F_THIS_OBJECT, 0); } else if(IDENTIFIER_IS_FUNCTION(id->identifier_flags) && id->identifier_flags & IDENTIFIER_HAS_BODY) { /* Only use this opcode when it's certain that the result * can't zero, i.e. when we know the function isn't just a * prototype. */ emit1(F_LFUN, n->u.integer.b);
83128f2010-07-01Henrik Grubbström (Grubba)  } else if (IDENTIFIER_IS_CONSTANT(id->identifier_flags) &&
4e1fb32014-08-07Per Hedbor  (ref->id_flags & (ID_INLINE|ID_PRIVATE)) && !ref->inherit_offset &&
89378b2010-11-23Henrik Grubbström (Grubba)  (id->func.const_info.offset >= 0)) {
83128f2010-07-01Henrik Grubbström (Grubba)  /* An inline, local or final constant identifier. * No need for vtable traversal during runtime. */
05c3732010-07-04Henrik Grubbström (Grubba)  struct svalue *s = &state->new_program->
89378b2010-11-23Henrik Grubbström (Grubba)  constants[id->func.const_info.offset].sval;
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(*s) == T_PROGRAM &&
05c3732010-07-04Henrik Grubbström (Grubba)  s->u.program->flags & PROGRAM_USES_PARENT) { /* Program using parent. Convert to an LFUN. */ emit1(F_LFUN, n->u.integer.b); } else {
89378b2010-11-23Henrik Grubbström (Grubba)  emit1(F_CONSTANT, id->func.const_info.offset);
05c3732010-07-04Henrik Grubbström (Grubba)  }
0e757b2006-10-28Henrik Grubbström (Grubba)  }else{
4ec32c2014-08-07Per Hedbor  emit_global( n->u.integer.b );
342fef2000-08-23Fredrik Hübinette (Hubbe)  }
ff88db2000-07-12Henrik Grubbström (Grubba)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }
0e757b2006-10-28Henrik Grubbström (Grubba)  return 1;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
57306e2004-12-18Henrik Grubbström (Grubba)  case F_THIS: { int level = 0; struct program_state *state = Pike_compiler; int inh = n->u.integer.b; 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);
388e5d2008-05-30Henrik Grubbström (Grubba)  } else if (!level && (inh < 0)) {
57306e2004-12-18Henrik Grubbström (Grubba)  emit1(F_THIS_OBJECT, 0); } else { emit2(F_THIS, level, inh); } return 1; } break;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  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))
5aad932002-08-15Marcus Comstedt  Pike_fatal("F_PUSH_ARRAY unexpected in this context.\n");
7acaf12001-01-15Martin Stjernholm #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) 
02f17a2007-12-17Henrik Grubbström (Grubba)  case F_APPEND_ARRAY: { emit0(F_MARK); PUSH_CLEANUP_FRAME(do_pop_mark, 0); do_docode(CAR(n),DO_LVALUE); emit0(F_CONST0); /* Reserved for svalue. */ do_docode(CDR(n),0); emit0(F_APPEND_ARRAY); POP_AND_DONT_CLEANUP; return 1; }
e3832f2014-10-02Per Hedbor  case F_APPEND_MAPPING: { emit0(F_MARK); PUSH_CLEANUP_FRAME(do_pop_mark, 0); do_docode(CAR(n),DO_LVALUE); emit0(F_CONST0); /* Reserved for svalue. */ do_docode(CDR(n),0); emit0(F_APPEND_MAPPING); POP_AND_DONT_CLEANUP; return 1; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  case '?': {
9abda42002-03-02Martin Stjernholm  INT32 *prev_switch_jumptable = current_switch.jumptable;
9d61521996-08-03Fredrik Hübinette (Hubbe)  int adroppings , bdroppings;
9abda42002-03-02Martin Stjernholm  current_switch.jumptable=0;
2e4e451997-02-13Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!CDDR(n)) {
a7622c1996-08-06Fredrik Hübinette (Hubbe)  tmp1=alloc_label();
bd67392015-10-14Martin Nilsson  do_jump_when_zero(CAR(n), (INT32)tmp1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  DO_CODE_BLOCK(CADR(n));
bd67392015-10-14Martin Nilsson  low_insert_label( (INT32)tmp1 );
9abda42002-03-02Martin Stjernholm  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();
bd67392015-10-14Martin Nilsson  do_jump_when_non_zero(CAR(n), (INT32)tmp1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  DO_CODE_BLOCK(CDDR(n));
bd67392015-10-14Martin Nilsson  low_insert_label( (INT32)tmp1 );
9abda42002-03-02Martin Stjernholm  current_switch.jumptable = prev_switch_jumptable;
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; }
a7622c1996-08-06Fredrik Hübinette (Hubbe)  tmp1=alloc_label();
bd67392015-10-14Martin Nilsson  do_jump_when_zero(CAR(n), (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);
bd67392015-10-14Martin Nilsson  low_insert_label( (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) {
bd67392015-10-14Martin Nilsson  update_arg((INT32)tmp3, adroppings - bdroppings);
9d61521996-08-03Fredrik Hübinette (Hubbe)  adroppings=bdroppings; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
bd67392015-10-14Martin Nilsson  low_insert_label( (INT32)tmp2 );
2e4e451997-02-13Fredrik Hübinette (Hubbe) 
9abda42002-03-02Martin Stjernholm  current_switch.jumptable = prev_switch_jumptable;
9d61521996-08-03Fredrik Hübinette (Hubbe)  return adroppings;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
13cdf22008-01-28Henrik Grubbström (Grubba)  case F_MULTI_ASSIGN: if (flags & DO_POP) {
a1af302017-03-18Henrik Grubbström (Grubba)  emit_multi_assign(CDR(n), CAR(n), 0);
13cdf22008-01-28Henrik Grubbström (Grubba)  return 0; } else { /* Fall back to the normal assign case. */
a1af302017-03-18Henrik Grubbström (Grubba)  tmp1=do_docode(CAR(n),DO_LVALUE);
13cdf22008-01-28Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG if(tmp1 & 1) Pike_fatal("Very internal compiler error.\n"); #endif
bd67392015-10-14Martin Nilsson  emit1(F_ARRAY_LVALUE, (INT32)(tmp1>>1) );
13cdf22008-01-28Henrik Grubbström (Grubba)  emit0(F_MARK); PUSH_CLEANUP_FRAME(do_pop_mark, 0);
a1af302017-03-18Henrik Grubbström (Grubba)  do_docode(CDR(n), 0);
13cdf22008-01-28Henrik Grubbström (Grubba)  emit_apply_builtin("aggregate"); POP_AND_DONT_CLEANUP; emit0(F_ASSIGN); return 1; }
f85f662014-08-14Per Hedbor  case F_ASSIGN_SELF:
68e0472014-08-14Per Hedbor  /* in assign self we know this: * * car(n) = lvalue * cdr(n)= softcast(apply(efun, arglist(car(n),one more arg))) * * The first argument of the arglist is equal to the lvalue. * * We only want to evaluate car(n) once. */
a1af302017-03-18Henrik Grubbström (Grubba)  if( CAR(n)->token == F_AUTO_MAP_MARKER )
f85f662014-08-14Per Hedbor  yyerror("[*] is not yet supported here\n");
a1af302017-03-18Henrik Grubbström (Grubba)  return emit_ltosval_call_and_assign( CAR(n), CAADR(n), CDADR(n) );
f85f662014-08-14Per Hedbor 
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_ASSIGN:
f85f662014-08-14Per Hedbor 
a1af302017-03-18Henrik Grubbström (Grubba)  if( CAR(n)->token == F_AUTO_MAP_MARKER )
0aeaca2014-08-13Per Hedbor  { int depth = 0;
2efefe2017-03-19Arne Goedeke  node *lval = CAR(n);
0aeaca2014-08-13Per Hedbor  while( lval->token == F_AUTO_MAP_MARKER ) {
2efefe2017-03-19Arne Goedeke  lval = CAR(lval);
0aeaca2014-08-13Per Hedbor  depth++; } do_docode(lval,0); /* note: not lvalue */
a1af302017-03-18Henrik Grubbström (Grubba)  if(do_docode(CDR(n),0)!=1)
0aeaca2014-08-13Per Hedbor  yyerror("RHS is void!");
c280762014-08-14Per Hedbor 
a1af302017-03-18Henrik Grubbström (Grubba)  if( CDR(n)->token == F_AUTO_MAP_MARKER || CDR(n)->token == F_AUTO_MAP ||
c280762014-08-14Per Hedbor  /* Well, hello there... ;) */ /* This is what is generated by a[*] += 10 and such. */
a1af302017-03-18Henrik Grubbström (Grubba)  (CDR(n)->token == F_SOFT_CAST && has_automap(CDR(n))))
c280762014-08-14Per Hedbor  { emit1(F_ASSIGN_INDICES,depth); } else
f85f662014-08-14Per Hedbor  {
c280762014-08-14Per Hedbor  emit1(F_ASSIGN_ALL_INDICES,depth);
f85f662014-08-14Per Hedbor  }
0aeaca2014-08-13Per Hedbor  if( flags & DO_POP ) emit0( F_POP_VALUE ); return !(flags&DO_POP); }
a1af302017-03-18Henrik Grubbström (Grubba)  switch(CDR(n)->token)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
b99ff82001-06-07Fredrik Hübinette (Hubbe)  case F_RANGE:
a1af302017-03-18Henrik Grubbström (Grubba)  if(node_is_eq(CAR(n),CADR(n)))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
4ec32c2014-08-07Per Hedbor  int num_args; /* tmp1=do_docode(CDR(n),DO_LVALUE); */
a1af302017-03-18Henrik 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, object_type_string) || match_types(CAR(n)->type, multiset_type_string) || match_types(CAR(n)->type, mapping_type_string))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
a1af302017-03-18Henrik Grubbström (Grubba)  do_docode(CAR(n),DO_LVALUE); num_args = do_docode(CDDR(n), 0);
408a1e2004-10-30Martin Stjernholm  switch (num_args)
b99ff82001-06-07Fredrik Hübinette (Hubbe)  {
403a532010-10-01Martin Stjernholm  case 0: emit0(F_LTOSVAL_AND_FREE); break; case 1: emit0(F_LTOSVAL2_AND_FREE); break; case 2: emit0(F_LTOSVAL3_AND_FREE); break;
b99ff82001-06-07Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG default:
5aad932002-08-15Marcus Comstedt  Pike_fatal("Arglebargle glop-glyf?\n");
b99ff82001-06-07Fredrik Hübinette (Hubbe) #endif }
5267b71995-08-09Fredrik Hübinette (Hubbe)  }else{
4ec32c2014-08-07Per Hedbor  goto do_not_suboptimize_assign;
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_LTOSVAL);
a1af302017-03-18Henrik Grubbström (Grubba)  num_args = do_docode(CDDR(n), 0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
a1af302017-03-18Henrik Grubbström (Grubba)  if (CDR (n)->token == F_RANGE) emit_range (CDR (n) DO_IF_DEBUG (COMMA num_args));
408a1e2004-10-30Martin Stjernholm  else
a1af302017-03-18Henrik Grubbström (Grubba)  emit0(CDR(n)->token);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(n->token);
403a532010-10-01Martin Stjernholm  return n->token==F_ASSIGN; /* So when is this false? /mast */
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
269d332016-09-14Henrik Grubbström (Grubba)  goto do_not_suboptimize_assign;
4b8e592015-02-20Per Hedbor  case F_SOFT_CAST: /* a = [type]`oper(a,*) */
a1af302017-03-18Henrik Grubbström (Grubba)  if( CADR(n)->token == F_APPLY && is_apply_constant_function_arg0( CADR(n), CAR(n) ))
4b8e592015-02-20Per Hedbor  return 1; goto do_not_suboptimize_assign;
27404b2008-01-29Henrik Grubbström (Grubba)  case F_APPLY:
4b8e592015-02-20Per Hedbor  /* a = `oper(a,*) */
a1af302017-03-18Henrik Grubbström (Grubba)  if (is_apply_constant_function_arg0( CDR(n), CAR(n) ))
4b8e592015-02-20Per Hedbor  return 1;
5f50842018-02-12Marcus Comstedt  /* FALLTHRU */
5267b71995-08-09Fredrik Hübinette (Hubbe)  default:
4ec32c2014-08-07Per Hedbor  do_not_suboptimize_assign:
a1af302017-03-18Henrik Grubbström (Grubba)  switch(CAR(n)->token)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
4ec32c2014-08-07Per Hedbor  case F_GLOBAL:
a1af302017-03-18Henrik Grubbström (Grubba)  if(CAR(n)->u.integer.b) goto normal_assign; code_expression(CDR(n), 0, "RHS"); emit_assign_global( CAR(n)->u.integer.a, flags & DO_POP );
4ec32c2014-08-07Per Hedbor  break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_LOCAL:
a1af302017-03-18Henrik Grubbström (Grubba)  if(CAR(n)->u.integer.a >= find_local_frame(CAR(n)->u.integer.b)->max_number_of_locals)
a8ef6e1996-12-03Fredrik Hübinette (Hubbe)  yyerror("Illegal to use local variable here.");
a1af302017-03-18Henrik Grubbström (Grubba)  if(CAR(n)->u.integer.b) goto normal_assign;
4218011999-01-31Fredrik Hübinette (Hubbe) 
a1af302017-03-18Henrik Grubbström (Grubba)  if (CAR(n)->node_info & OPT_ASSIGNMENT) {
c981662006-03-02Henrik Grubbström (Grubba)  /* Initialize. */ emit0(F_CONST0);
a1af302017-03-18Henrik Grubbström (Grubba)  emit1(F_ASSIGN_LOCAL_AND_POP, CAR(n)->u.integer.a);
c981662006-03-02Henrik Grubbström (Grubba)  }
a1af302017-03-18Henrik Grubbström (Grubba)  code_expression(CDR(n), 0, "RHS");
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit1(flags & DO_POP ? F_ASSIGN_LOCAL_AND_POP:F_ASSIGN_LOCAL,
a1af302017-03-18Henrik Grubbström (Grubba)  CAR(n)->u.integer.a );
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
8f12702014-08-14Per Hedbor  case F_GET_SET: { /* Check for the setter function. */ struct program_state *state = Pike_compiler;
a1af302017-03-18Henrik Grubbström (Grubba)  int program_id = CAR(n)->u.integer.a;
8f12702014-08-14Per Hedbor  int level = 0; while (state && (state->new_program->id != program_id)) { state = state->previous; level++; } if (!state) { yyerror("Lost parent."); } else { struct reference *ref =
a1af302017-03-18Henrik Grubbström (Grubba)  PTR_FROM_INT(state->new_program, CAR(n)->u.integer.b);
8f12702014-08-14Per Hedbor  struct identifier *id = ID_FROM_PTR(state->new_program, ref); struct inherit *inh = INHERIT_FROM_PTR(state->new_program, ref); int f;
0e757b2006-10-28Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG
8f12702014-08-14Per Hedbor  if (!IDENTIFIER_IS_VARIABLE(id->identifier_flags) || (id->run_time_type != PIKE_T_GET_SET)) { Pike_fatal("Not a getter/setter in a F_GET_SET node!\n" " identifier_flags: 0x%08x\n" " run_time_type; %s (%d)\n", id->identifier_flags, get_name_of_type(id->run_time_type), id->run_time_type); }
0e757b2006-10-28Henrik Grubbström (Grubba) #endif /* PIKE_DEBUG */
8f12702014-08-14Per Hedbor  f = id->func.gs_info.setter; if (f == -1) { yywarning("Variable %S lacks a setter.", id->name); } else if (!level) { f += inh->identifier_level; if (flags & DO_POP) {
4e1fb32014-08-07Per Hedbor #ifndef USE_APPLY_N
8f12702014-08-14Per Hedbor  emit0(F_MARK);
4e1fb32014-08-07Per Hedbor #endif
a1af302017-03-18Henrik Grubbström (Grubba)  code_expression(CDR(n), 0, "RHS");
8f12702014-08-14Per Hedbor  } else { code_expression(CAR(n), 0, "RHS");
4e1fb32014-08-07Per Hedbor #ifndef USE_APPLY_N
8f12702014-08-14Per Hedbor  emit0(F_MARK);
4e1fb32014-08-07Per Hedbor #endif
8f12702014-08-14Per Hedbor  emit0(F_DUP); }
4e1fb32014-08-07Per Hedbor #ifdef USE_APPLY_N
8f12702014-08-14Per Hedbor  emit2(F_CALL_LFUN_N, f, 1);
4e1fb32014-08-07Per Hedbor #else
8f12702014-08-14Per Hedbor  emit1(F_CALL_LFUN, f);
4e1fb32014-08-07Per Hedbor #endif
8f12702014-08-14Per Hedbor  emit0(F_POP_VALUE); return !(flags & DO_POP); } } }
5f50842018-02-12Marcus Comstedt  /* FALLTHRU */
8f12702014-08-14Per Hedbor  case F_EXTERNAL: /* Check that it is in this context */
a1af302017-03-18Henrik Grubbström (Grubba)  if(Pike_compiler ->new_program->id == CAR(n)->u.integer.a)
8f12702014-08-14Per Hedbor  { /* Check that it is a variable */
a1af302017-03-18Henrik Grubbström (Grubba)  if(CAR(n)->u.integer.b != IDREF_MAGIC_THIS && IDENTIFIER_IS_VARIABLE( ID_FROM_INT(Pike_compiler->new_program, CAR(n)->u.integer.b)->identifier_flags))
8f12702014-08-14Per Hedbor  {
a1af302017-03-18Henrik Grubbström (Grubba)  code_expression(CDR(n), 0, "RHS"); emit_assign_global(CAR(n)->u.integer.b, flags & DO_POP );
8f12702014-08-14Per Hedbor  break; } } /* fall through */
57f3162001-06-29Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  default:
4218011999-01-31Fredrik Hübinette (Hubbe)  normal_assign:
a1af302017-03-18Henrik Grubbström (Grubba)  tmp1=do_docode(CAR(n),DO_LVALUE); if(do_docode(CDR(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();
0811472001-07-02Fredrik Hübinette (Hubbe)  if(flags & DO_POP) {
bd67392015-10-14Martin Nilsson  do_cond_jump(CAR(n), (INT32)tmp1, n->token == F_LOR, DO_POP);
0811472001-07-02Fredrik Hübinette (Hubbe)  DO_CODE_BLOCK(CDR(n));
bd67392015-10-14Martin Nilsson  low_insert_label( (INT32)tmp1 );
0811472001-07-02Fredrik Hübinette (Hubbe)  return 0; }else{
bd67392015-10-14Martin Nilsson  do_cond_jump(CAR(n), (INT32)tmp1, n->token == F_LOR, 0);
0811472001-07-02Fredrik Hübinette (Hubbe)  code_expression(CDR(n), flags, n->token == F_LOR ? "||" : "&&");
bd67392015-10-14Martin Nilsson  low_insert_label( (INT32)tmp1 );
0811472001-07-02Fredrik Hübinette (Hubbe)  return 1; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_RANGE:
5e44422001-02-25Fredrik Hübinette (Hubbe)  tmp1=do_docode(CAR(n),DO_NOT_COPY_TOPLEVEL);
408a1e2004-10-30Martin Stjernholm  { #ifdef PIKE_DEBUG int num_args = #endif do_docode (CDR (n), DO_NOT_COPY); emit_range (n DO_IF_DEBUG (COMMA num_args));
bd67392015-10-14Martin Nilsson  return (INT32)tmp1;
408a1e2004-10-30Martin Stjernholm  } /* The special bound type nodes are simply ignored when the * arglist to the range operator is coded. emit_range looks at * them later on instead. */ case F_RANGE_FROM_BEG: case F_RANGE_FROM_END: return do_docode (CAR (n), flags); case F_RANGE_OPEN: return 0;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_INC: case F_POST_INC:
005bf42001-09-29Fredrik Hübinette (Hubbe)  if(CAR(n)->token == F_AUTO_MAP_MARKER) { int depth=0; int ret=0; node *tmp=CAR(n); while(tmp->token == F_AUTO_MAP_MARKER) { depth++; tmp=CAR(tmp); } tmp1=do_docode(tmp,DO_LVALUE); if(n->token == F_POST_INC) { emit0(F_LTOSVAL); emit2(F_REARRANGE,1,2); ret++; flags|=DO_POP; }
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
005bf42001-09-29Fredrik Hübinette (Hubbe)  if(tmp1 != 2)
5aad932002-08-15Marcus Comstedt  Pike_fatal("HELP! FATAL INTERNAL COMPILER ERROR (1)\n");
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif
005bf42001-09-29Fredrik Hübinette (Hubbe)  emit0(F_MARK); emit0(F_MARK); emit0(F_LTOSVAL); emit1(F_NUMBER, depth); emit_apply_builtin("__builtin.automap_marker"); emit_builtin_svalue("`+"); emit2(F_REARRANGE,1,1); emit1(F_NUMBER, 1); emit_apply_builtin("__automap__"); if(flags & DO_POP) { emit0(F_ASSIGN_AND_POP); }else{ emit0(F_ASSIGN); ret++; } return ret;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }else{
005bf42001-09-29Fredrik Hübinette (Hubbe)  tmp1=do_docode(CAR(n),DO_LVALUE); #ifdef PIKE_DEBUG if(tmp1 != 2)
5aad932002-08-15Marcus Comstedt  Pike_fatal("HELP! FATAL INTERNAL COMPILER ERROR (1)\n");
005bf42001-09-29Fredrik Hübinette (Hubbe) #endif if(flags & DO_POP) { emit0(F_INC_AND_POP); return 0; }else{ emit0(n->token); return 1; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  } case F_DEC: case F_POST_DEC:
005bf42001-09-29Fredrik Hübinette (Hubbe)  if(CAR(n)->token == F_AUTO_MAP_MARKER) { int depth=0; int ret=0; node *tmp=CAR(n); while(tmp->token == F_AUTO_MAP_MARKER) { depth++; tmp=CAR(tmp); } tmp1=do_docode(tmp,DO_LVALUE); if(n->token == F_POST_DEC) { emit0(F_LTOSVAL); emit2(F_REARRANGE,1,2); ret++; flags|=DO_POP; }
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
005bf42001-09-29Fredrik Hübinette (Hubbe)  if(tmp1 != 2)
5aad932002-08-15Marcus Comstedt  Pike_fatal("HELP! FATAL INTERNAL COMPILER ERROR (1)\n");
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif
005bf42001-09-29Fredrik Hübinette (Hubbe)  emit0(F_MARK); emit0(F_MARK); emit0(F_LTOSVAL); emit1(F_NUMBER, depth); emit_apply_builtin("__builtin.automap_marker"); emit_builtin_svalue("`-"); emit2(F_REARRANGE,1,1); emit1(F_NUMBER, 1); emit_apply_builtin("__automap__"); if(flags & DO_POP) { emit0(F_ASSIGN_AND_POP); }else{ emit0(F_ASSIGN); ret++; } return ret;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }else{
005bf42001-09-29Fredrik Hübinette (Hubbe)  tmp1=do_docode(CAR(n),DO_LVALUE); #ifdef PIKE_DEBUG if(tmp1 != 2)
5aad932002-08-15Marcus Comstedt  Pike_fatal("HELP! FATAL INTERNAL COMPILER ERROR (2)\n");
005bf42001-09-29Fredrik Hübinette (Hubbe) #endif if(flags & DO_POP) { emit0(F_DEC_AND_POP); return 0; }else{ emit0(n->token); return 1; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  } case F_FOR: {
9abda42002-03-02Martin Stjernholm  INT32 *prev_switch_jumptable = current_switch.jumptable;
1544fd2001-01-31Martin Stjernholm  BLOCK_BEGIN;
6c8ada2001-01-14Martin Stjernholm  PUSH_STATEMENT_LABEL;
5a0fd52001-01-10Martin Stjernholm 
9abda42002-03-02Martin Stjernholm  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)  }
bd67392015-10-14Martin Nilsson  do_jump_when_non_zero(CAR(n), (INT32)tmp2);
5a0fd52001-01-10Martin Stjernholm  ins_label(current_label->break_label);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
9abda42002-03-02Martin Stjernholm  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 ' ':
0adc722017-05-26Henrik Grubbström (Grubba)  /* FIXME: Is this code reached? */
57c2872003-09-19Henrik Grubbström (Grubba)  ret = do_docode(CAR(n),0); return ret + do_docode(CDR(n),DO_LVALUE);
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_FOREACH: {
a982301999-04-30Fredrik Hübinette (Hubbe)  node *arr;
9abda42002-03-02Martin Stjernholm  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);
2a50e72017-06-07Henrik Grubbström (Grubba)  modify_stack_depth(2);
4cdb802001-02-23Fredrik Hübinette (Hubbe)  } if(CDDR(arr)) { do_docode(CDDR(arr), DO_LVALUE); }else{ emit0(F_CONST0); emit0(F_CONST0);
2a50e72017-06-07Henrik Grubbström (Grubba)  modify_stack_depth(2);
4cdb802001-02-23Fredrik Hübinette (Hubbe)  } PUSH_CLEANUP_FRAME(do_pop, 5); PUSH_STATEMENT_LABEL;
9abda42002-03-02Martin Stjernholm  current_switch.jumptable=0;
4cdb802001-02-23Fredrik Hübinette (Hubbe)  current_label->break_label=alloc_label(); current_label->continue_label=alloc_label();
f139182003-09-05Martin Stjernholm  /* Doubt it's necessary to use a label separate from * current_label->break_label, but I'm playing safe. /mast */ tmp3 = alloc_label();
bd67392015-10-14Martin Nilsson  do_jump(F_FOREACH_START, (INT32) tmp3);
4cdb802001-02-23Fredrik Hübinette (Hubbe)  tmp1=ins_label(-1); DO_CODE_BLOCK(CDR(n)); ins_label(current_label->continue_label);
bd67392015-10-14Martin Nilsson  do_jump(F_FOREACH_LOOP, (INT32)tmp1);
4cdb802001-02-23Fredrik Hübinette (Hubbe)  ins_label(current_label->break_label);
bd67392015-10-14Martin Nilsson  low_insert_label( (INT32)tmp3 );
f139182003-09-05Martin Stjernholm 
9abda42002-03-02Martin Stjernholm  current_switch.jumptable = prev_switch_jumptable;
4cdb802001-02-23Fredrik Hübinette (Hubbe)  POP_STATEMENT_LABEL; POP_AND_DO_CLEANUP; BLOCK_END; return 0; }
13670c2015-05-25Martin Nilsson 
4cdb802001-02-23Fredrik Hübinette (Hubbe)  BLOCK_BEGIN; if(CAR(arr) && CAR(arr)->token==F_RANGE)
a982301999-04-30Fredrik Hübinette (Hubbe)  {
2d74b42004-10-28Martin Stjernholm  node *range = CAR(arr);
408a1e2004-10-30Martin Stjernholm  node *low = CADR(range); node *high = CDDR(range); if(high->token == F_RANGE_OPEN && low->token == F_RANGE_FROM_BEG && match_types (low->type, int_type_string))
a982301999-04-30Fredrik Hübinette (Hubbe)  {
85f3722003-09-05Henrik Grubbström (Grubba)  /* Optimize foreach(x[start..],y). */
2d74b42004-10-28Martin Stjernholm  do_docode (CAR(range), DO_NOT_COPY_TOPLEVEL); do_docode (CDR(arr), DO_NOT_COPY|DO_LVALUE);
b280282014-07-15Henrik Grubbström (Grubba)  if ((low->token == F_CONSTANT) && (TYPEOF(low->u.sval) == PIKE_T_INT)) { if (low->u.sval.u.integer < 0) { emit0(F_CONST0); goto foreach_arg_pushed; } do_docode (CAR(low), DO_NOT_COPY); goto foreach_arg_pushed; }
408a1e2004-10-30Martin Stjernholm  do_docode (CAR(low), DO_NOT_COPY);
b280282014-07-15Henrik Grubbström (Grubba)  tmp1 = alloc_label(); emit0(F_DUP); emit0(F_CONST0); do_jump(F_BRANCH_WHEN_GE, tmp1); /* The value is negative. replace it with zero. */ emit0(F_POP_VALUE); emit0(F_CONST0);
bd67392015-10-14Martin Nilsson  low_insert_label((INT32)tmp1);
a982301999-04-30Fredrik Hübinette (Hubbe)  goto foreach_arg_pushed; } }
2d74b42004-10-28Martin Stjernholm  do_docode(arr,DO_NOT_COPY);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_CONST0);
2a50e72017-06-07Henrik Grubbström (Grubba)  modify_stack_depth(1);
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;
9abda42002-03-02Martin Stjernholm  current_switch.jumptable=0;
7acaf12001-01-15Martin Stjernholm  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);
bd67392015-10-14Martin Nilsson  low_insert_label( (INT32)tmp3 ); do_jump(n->token, (INT32)tmp1);
5a0fd52001-01-10Martin Stjernholm  ins_label(current_label->break_label);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
9abda42002-03-02Martin Stjernholm  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: {
9abda42002-03-02Martin Stjernholm  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;
9abda42002-03-02Martin Stjernholm  current_switch.jumptable=0;
7acaf12001-01-15Martin Stjernholm  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);
bd67392015-10-14Martin Nilsson  low_insert_label( (INT32)tmp3 ); do_jump(n->token, (INT32)tmp1);
5a0fd52001-01-10Martin Stjernholm  ins_label(current_label->break_label);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
9abda42002-03-02Martin Stjernholm  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: {
9abda42002-03-02Martin Stjernholm  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) 
9abda42002-03-02Martin Stjernholm  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);
bd67392015-10-14Martin Nilsson  do_jump_when_non_zero(CDR(n), (INT32)tmp2);
5a0fd52001-01-10Martin Stjernholm  ins_label(current_label->break_label);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
9abda42002-03-02Martin Stjernholm  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:
1932482007-03-03Henrik Grubbström (Grubba)  switch(n->type->type) { case T_VOID:
5267b71995-08-09Fredrik Hübinette (Hubbe)  DO_CODE_BLOCK(CAR(n)); return 0;
1932482007-03-03Henrik Grubbström (Grubba)  case T_INT: /* FIXME: Integer range? */
0232d22001-06-17Henrik Grubbström (Grubba)  tmp1 = do_docode(CAR(n), 0);
7f94c22001-06-17Henrik Grubbström (Grubba)  if(!tmp1) emit0(F_CONST0);
0232d22001-06-17Henrik Grubbström (Grubba)  else {
7f94c22001-06-17Henrik Grubbström (Grubba)  if(tmp1>1)
bd67392015-10-14Martin Nilsson  do_pop((INT32)(tmp1-1));
0232d22001-06-17Henrik Grubbström (Grubba)  emit0(F_CAST_TO_INT); } return 1;
1932482007-03-03Henrik Grubbström (Grubba)  case T_STRING: /* FIXME: String width? */
7f94c22001-06-17Henrik Grubbström (Grubba)  tmp1 = do_docode(CAR(n), 0); if(!tmp1) emit0(F_CONST0); else if(tmp1>1)
bd67392015-10-14Martin Nilsson  do_pop((INT32)(tmp1-1));
7f94c22001-06-17Henrik Grubbström (Grubba)  emit0(F_CAST_TO_STRING); return 1;
1932482007-03-03Henrik Grubbström (Grubba)  default: if (compile_type_to_runtime_type(n->type) == PIKE_T_MIXED) { tmp1 = do_docode(CAR(n), 0);
13670c2015-05-25Martin Nilsson  if(!tmp1)
1932482007-03-03Henrik Grubbström (Grubba)  emit0(F_CONST0); else if(tmp1>1)
bd67392015-10-14Martin Nilsson  do_pop((INT32)(tmp1-1));
1932482007-03-03Henrik Grubbström (Grubba)  return 1; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
d68a072001-02-20Henrik Grubbström (Grubba)  { struct svalue sv;
017b572011-10-28Henrik Grubbström (Grubba)  SET_SVAL(sv, T_TYPE, 0, type, n->type);
515bcf2002-07-02Henrik Grubbström (Grubba)  tmp1 = store_constant(&sv, 0, n->name);
bd67392015-10-14Martin Nilsson  emit1(F_CONSTANT, (INT32)tmp1);
d68a072001-02-20Henrik Grubbström (Grubba)  }
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; }
bd67392015-10-14Martin Nilsson  if(tmp1>1) do_pop((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;
017b572011-10-28Henrik Grubbström (Grubba)  SET_SVAL(sv, T_TYPE, 0, type, n->type);
515bcf2002-07-02Henrik Grubbström (Grubba)  tmp1 = store_constant(&sv, 0, n->name);
bd67392015-10-14Martin Nilsson  emit1(F_CONSTANT, (INT32)tmp1);
d68a072001-02-20Henrik Grubbström (Grubba)  }
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; }
bd67392015-10-14Martin Nilsson  if (tmp1 > 1) do_pop((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);
bd67392015-10-14Martin Nilsson  if (tmp1 > 1) do_pop((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) {
1807c02014-07-15Per Hedbor  int args = count_args(CDR(n));
017b572011-10-28Henrik Grubbström (Grubba)  if(TYPEOF(CAR(n)->u.sval) == T_FUNCTION)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
017b572011-10-28Henrik Grubbström (Grubba)  if(SUBTYPEOF(CAR(n)->u.sval) == FUNCTION_BUILTIN) /* driver fun? */
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  {
13670c2015-05-25Martin Nilsson  if(!CAR(n)->u.sval.u.efun->docode ||
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  !CAR(n)->u.sval.u.efun->docode(n)) {
1807c02014-07-15Per Hedbor  if(args==1)
d9a93b2001-07-01Fredrik Hübinette (Hubbe)  { do_docode(CDR(n),0); tmp1=store_constant(& CAR(n)->u.sval, !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND), CAR(n)->name);
bd67392015-10-14Martin Nilsson  emit1(F_CALL_BUILTIN1, (INT32)tmp1);
1807c02014-07-15Per Hedbor #ifdef USE_APPLY_N }else if(args>0){ do_docode(CDR(n),0); tmp1=store_constant(& CAR(n)->u.sval, !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND), CAR(n)->name);
bd67392015-10-14Martin Nilsson  emit2(F_CALL_BUILTIN_N, (INT32)tmp1, args);
1807c02014-07-15Per Hedbor #endif
d9a93b2001-07-01Fredrik Hübinette (Hubbe)  }else{ emit0(F_MARK); PUSH_CLEANUP_FRAME(do_pop_mark, 0); do_docode(CDR(n),0); tmp1=store_constant(& CAR(n)->u.sval, !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND), CAR(n)->name);
bd67392015-10-14Martin Nilsson  emit1(F_CALL_BUILTIN, (INT32)tmp1);
d9a93b2001-07-01Fredrik Hübinette (Hubbe)  POP_AND_DONT_CLEANUP; }
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  }
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);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  }else{
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(CAR(n)->u.sval.u.object == Pike_compiler->fake_object)
017b572011-10-28Henrik Grubbström (Grubba)  return do_lfun_call(SUBTYPEOF(CAR(n)->u.sval), CDR(n));
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
1807c02014-07-15Per Hedbor #ifdef USE_APPLY_N if( args <= 1 ) #endif { emit0(F_MARK); PUSH_CLEANUP_FRAME(do_pop_mark, 0); do_docode(CDR(n),0); tmp1=store_constant(& CAR(n)->u.sval, !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND), CAR(n)->name);
bd67392015-10-14Martin Nilsson  emit1(F_APPLY, (INT32)tmp1);
1807c02014-07-15Per Hedbor  POP_AND_DONT_CLEANUP; } #ifdef USE_APPLY_N else { do_docode(CDR(n),0); tmp1=store_constant(& CAR(n)->u.sval, !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND), CAR(n)->name);
bd67392015-10-14Martin Nilsson  emit2(F_APPLY_N, (INT32)tmp1, args);
1807c02014-07-15Per Hedbor  } #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; }
342fef2000-08-23Fredrik Hübinette (Hubbe)  else if(CAR(n)->token == F_EXTERNAL &&
5d642e2003-08-03Martin Stjernholm  CAR(n)->u.integer.a == Pike_compiler->new_program->id && CAR(n)->u.integer.b != IDREF_MAGIC_THIS)
342fef2000-08-23Fredrik Hübinette (Hubbe)  {
5e5a592002-11-14Henrik Grubbström (Grubba)  return do_lfun_call(CAR(n)->u.integer.b, CDR(n));
342fef2000-08-23Fredrik Hübinette (Hubbe)  }
0e757b2006-10-28Henrik Grubbström (Grubba)  else if(CAR(n)->token == F_GET_SET && CAR(n)->u.integer.a == Pike_compiler->new_program->id && CAR(n)->u.integer.b != IDREF_MAGIC_THIS) { return do_lfun_call(CAR(n)->u.integer.b, CDR(n)); }
a8aed22001-08-15Fredrik Hübinette (Hubbe)  else if(CAR(n)->token == F_ARROW) { emit0(F_MARK); PUSH_CLEANUP_FRAME(do_pop_mark, 0); do_docode(CAAR(n),0); /* object */ do_docode(CDR(n),0); /* args */ emit1(F_CALL_OTHER, store_prog_string(CDAR(n)->u.sval.u.string)); POP_AND_DONT_CLEANUP; return 1; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  else {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *tmp;
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) 
531bc92016-08-23Martin Nilsson  foo=find_module_identifier(lfun_strings[LFUN_CALL],0);
e950292009-11-10Peter Bortas  if(!foo || foo->token!=F_CONSTANT)
f53bab1997-01-26Fredrik Hübinette (Hubbe)  {
531bc92016-08-23Martin Nilsson  yyerror("No `() efun.");
f53bab1997-01-26Fredrik Hübinette (Hubbe)  }else{
017b572011-10-28Henrik Grubbström (Grubba)  if(TYPEOF(foo->u.sval) == T_FUNCTION && SUBTYPEOF(foo->u.sval) == FUNCTION_BUILTIN &&
d103cb1998-01-30Fredrik Hübinette (Hubbe)  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);
bd67392015-10-14Martin Nilsson  emit1(F_APPLY, (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:
408a1e2004-10-30Martin Stjernholm  case ':':
83c60c2001-06-13Henrik Grubbström (Grubba)  { node *root = n; node *parent = n->parent; /* Avoid a bit of recursion by traversing the graph... */ n->parent = NULL; tmp1 = 0; next_car:
13670c2015-05-25Martin Nilsson  while (CAR(n) &&
83c60c2001-06-13Henrik Grubbström (Grubba)  ((CAR(n)->token == F_ARG_LIST) || (CAR(n)->token == F_COMMA_EXPR))) { CAR(n)->parent = n; n = CAR(n); } /* CAR(n) is not F_ARG_LIST or F_COMMA_EXPR */
7e877a2003-04-02Martin Stjernholm  tmp1 += do_docode(CAR(n), flags & ~WANT_LVALUE);
13670c2015-05-25Martin Nilsson 
83c60c2001-06-13Henrik Grubbström (Grubba)  do { if (CDR(n)) { if ((CDR(n)->token == F_ARG_LIST) || (CDR(n)->token == F_COMMA_EXPR)) { /* Note: Parent points to the closest preceding CAR node * on the way to the root. */ CDR(n)->parent = n->parent; n = CDR(n); goto next_car; } /* CDR(n) is not F_ARG_LIST or F_COMMA_EXPR */ if (n->parent) {
7e877a2003-04-02Martin Stjernholm  tmp1 += do_docode(CDR(n), flags & ~WANT_LVALUE);
83c60c2001-06-13Henrik Grubbström (Grubba)  } else { tmp1 += do_docode(CDR(n), flags); } } /* Retrace */ /* Note: n->parent is always a visited CAR node on the * way to the root. */ n = n->parent; } while (n); /* Restore root->parent. */ root->parent = parent; }
bd67392015-10-14Martin Nilsson  return (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;
9abda42002-03-02Martin Stjernholm  struct switch_data prev_switch = current_switch;
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)
5aad932002-08-15Marcus Comstedt  Pike_fatal("Internal compiler error, time to panic\n");
5267b71995-08-09Fredrik Hübinette (Hubbe) 
9abda42002-03-02Martin Stjernholm  if (!(CAR(n) && (current_switch.type = CAR(n)->type))) { current_switch.type = mixed_type_string;
7670902000-01-04Henrik Grubbström (Grubba)  }
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);
2a50e72017-06-07Henrik Grubbström (Grubba)  modify_stack_depth(-1);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit1(F_ALIGN,sizeof(INT32));
7a82f91996-04-13Fredrik Hübinette (Hubbe) 
9abda42002-03-02Martin Stjernholm  current_switch.values_on_stack=0; current_switch.index=2; current_switch.less_label=-1; current_switch.greater_label=-1; current_switch.default_label=-1;
dc8d022014-04-27Martin Nilsson  current_switch.jumptable=xalloc(sizeof(INT32)*(cases*2+2)); jumptable=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)  {
bd67392015-10-14Martin Nilsson  jumptable[e] = (INT32)emit1(F_POINTER, 0);
9abda42002-03-02Martin Stjernholm  current_switch.jumptable[e]=-1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
928f952000-11-30Fredrik Hübinette (Hubbe)  emit0(F_NOTREACHED);
5267b71995-08-09Fredrik Hübinette (Hubbe)  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)
5aad932002-08-15Marcus Comstedt  Pike_fatal("Count cases is wrong!\n");
7af7d21997-08-03Fredrik Hübinette (Hubbe) #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 */
9abda42002-03-02Martin Stjernholm  if (cases && ((current_switch.less_label >= 0 && current_switch.jumptable[order[0]*2+2] != current_switch.less_label) || (current_switch.greater_label >= 0 && current_switch.jumptable[order[cases-1]*2+2] != current_switch.greater_label))) yyerror("Case inside range.");
7c95f12000-01-04Henrik Grubbström (Grubba)  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;
9abda42002-03-02Martin Stjernholm  if(current_switch.jumptable[o1]==current_switch.jumptable[o1+1] && current_switch.jumptable[o1]==current_switch.jumptable[o1+2])
7c95f12000-01-04Henrik Grubbström (Grubba)  { if(order[e]+1 != order[e+1]) yyerror("Case inside range."); e++; }
ba62cf1997-09-18Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
fc26f62000-07-06Fredrik Hübinette (Hubbe)  order_array(Pike_sp[-1].u.array,order);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
9abda42002-03-02Martin Stjernholm  reorder((void *)(current_switch.jumptable+2),cases,sizeof(INT32)*2,order);
0ec7522014-04-27Martin Nilsson  free(order);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
9abda42002-03-02Martin Stjernholm  current_switch.jumptable[1] = current_switch.less_label; current_switch.jumptable[current_switch.index - 1] = current_switch.greater_label; if(current_switch.default_label < 0) current_switch.default_label = ins_label(-1); for(e=1;e<cases*2+2;e++) if(current_switch.jumptable[e]==-1) current_switch.jumptable[e]=current_switch.default_label;
52fcc81998-01-28Fredrik Hübinette (Hubbe)  for(e=1; e<cases*2+2; e++)
9abda42002-03-02Martin Stjernholm  update_arg(jumptable[e], current_switch.jumptable[e]);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
bd67392015-10-14Martin Nilsson  update_arg((INT32)tmp1, store_constant(Pike_sp-1,1,0));
5267b71995-08-09Fredrik Hübinette (Hubbe)  pop_stack();
0ec7522014-04-27Martin Nilsson  free(jumptable); free(current_switch.jumptable);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
9abda42002-03-02Martin Stjernholm  current_switch = prev_switch;
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)
5aad932002-08-15Marcus Comstedt  Pike_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:
9abda42002-03-02Martin Stjernholm  case F_CASE_RANGE:
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
9abda42002-03-02Martin Stjernholm  if(!current_switch.jumptable)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { yyerror("Case outside switch."); }else{
9abda42002-03-02Martin Stjernholm  INT32 label = ins_label(-1); int i;
7670902000-01-04Henrik Grubbström (Grubba) 
9abda42002-03-02Martin Stjernholm  for (i = 0; i < 2; i++) { node *case_val = i == 0 ? CAR(n) : CDR(n);
7a82f91996-04-13Fredrik Hübinette (Hubbe) 
9abda42002-03-02Martin Stjernholm  if (case_val) {
1adcc92018-02-14Henrik Grubbström (Grubba)  if(!is_const(case_val))
271a6b2000-01-04Henrik Grubbström (Grubba)  yyerror("Case label isn't constant.");
9abda42002-03-02Martin Stjernholm 
c2c9322014-08-10Martin Nilsson  if (case_val->type) {
9abda42002-03-02Martin Stjernholm  if (!pike_types_le(case_val->type, current_switch.type)) { if (!match_types(case_val->type, current_switch.type)) { yytype_error("Type mismatch in case.", current_switch.type, case_val->type, 0);
e021fe2008-04-14Henrik Grubbström (Grubba)  } else if (c->lex.pragmas & ID_STRICT_TYPES) {
9abda42002-03-02Martin Stjernholm  yytype_error("Type mismatch in case.", current_switch.type, case_val->type, YYTE_IS_WARNING); } } }
ba62cf1997-09-18Fredrik Hübinette (Hubbe) 
bad5162000-06-23Fredrik Hübinette (Hubbe)  if (!Pike_compiler->num_parse_error) {
9f85c32002-10-25Marcus Comstedt  tmp1=eval_low(case_val,1);
271a6b2000-01-04Henrik Grubbström (Grubba)  if(tmp1<1) {
9abda42002-03-02Martin Stjernholm  yyerror("Error in case label.");
271a6b2000-01-04Henrik Grubbström (Grubba)  push_int(0); tmp1=1;
b1bfe22000-01-04Henrik Grubbström (Grubba)  }
271a6b2000-01-04Henrik Grubbström (Grubba)  pop_n_elems(tmp1-1);
9abda42002-03-02Martin Stjernholm  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))
9abda42002-03-02Martin Stjernholm  yyerror("Duplicate case label.");
271a6b2000-01-04Henrik Grubbström (Grubba)  } else { push_int(0);
9abda42002-03-02Martin Stjernholm  current_switch.values_on_stack++;
ba62cf1997-09-18Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
9abda42002-03-02Martin Stjernholm  } if (n->token == F_CASE) { current_switch.jumptable[current_switch.index++] = label; current_switch.jumptable[current_switch.index++] = -1; } else { if (!CAR(n)) current_switch.less_label = label; if (!CDR(n)) current_switch.greater_label = label; if (CAR(n) && CDR(n)) { current_switch.jumptable[current_switch.index++] = label; current_switch.jumptable[current_switch.index++] = label; current_switch.jumptable[current_switch.index++] = label; current_switch.jumptable[current_switch.index++] = -1; } else { current_switch.jumptable[current_switch.index++] = label; current_switch.jumptable[current_switch.index++] = -1; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  } } return 0; } case F_DEFAULT:
9abda42002-03-02Martin Stjernholm  if(!current_switch.jumptable)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { yyerror("Default outside switch.");
9abda42002-03-02Martin Stjernholm  }else if(current_switch.default_label!=-1){
5267b71995-08-09Fredrik Hübinette (Hubbe)  yyerror("Duplicate switch default."); }else{
9abda42002-03-02Martin Stjernholm  current_switch.default_label = 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)
25702d2015-10-18Henrik Grubbström (Grubba)  if (lbl_name->str == name) { lbl_name->used = 1;
7acaf12001-01-15Martin Stjernholm  goto label_found_1;
25702d2015-10-18Henrik Grubbström (Grubba)  }
ce060e2004-06-30Martin Nilsson  my_yyerror("No surrounding statement labeled %S.", name);
5a0fd52001-01-10Martin Stjernholm  return 0;
7acaf12001-01-15Martin Stjernholm  label_found_1:
f181de2001-01-11Martin Stjernholm  if (n->token == F_CONTINUE && label->continue_label < 0) {
ef24a82012-01-12Henrik Grubbström (Grubba)  my_yyerror("Cannot continue the non-loop statement on line %ld.", (long)lbl_name->line_number);
f181de2001-01-11Martin Stjernholm  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;
25702d2015-10-18Henrik Grubbström (Grubba)  name.used = 0;
6c8ada2001-01-14Martin Stjernholm  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) {
ef24a82012-01-12Henrik Grubbström (Grubba)  INT_TYPE save_line = c->lex.current_line;
e021fe2008-04-14Henrik Grubbström (Grubba)  c->lex.current_line = name.line_number;
6c8ada2001-01-14Martin Stjernholm  my_yyerror("Duplicate nested labels, previous one on line %d.", lbl_name->line_number);
e021fe2008-04-14Henrik Grubbström (Grubba)  c->lex.current_line = save_line;
6c8ada2001-01-14Martin Stjernholm  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);
25702d2015-10-18Henrik Grubbström (Grubba)  if (!name.used) { low_yyreport(REPORT_WARNING, n->current_file, n->line_number, parser_system_string, 0,
61f03d2015-11-15Martin Nilsson  "Label %S not used.", name.str);
25702d2015-10-18Henrik Grubbström (Grubba)  }
6c8ada2001-01-14Martin Stjernholm  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) 
ca176b2006-02-27Martin Stjernholm  case F_RETURN: { struct statement_label *p; int in_catch = 0;
7a82f91996-04-13Fredrik Hübinette (Hubbe)  do_docode(CAR(n),0);
ca176b2006-02-27Martin Stjernholm  /* Insert the appropriate number of F_ESCAPE_CATCH. The rest of * the cleanup is handled wholesale in low_return et al. * Alternatively we could handle this too in low_return and * then allow tail recursion of these kind of returns too. */ for (p = current_label; p; p = p->prev) { struct cleanup_frame *q;
1d6ca22008-06-30Martin Stjernholm  for (q = p->cleanups; q; q = q->prev) {
ca176b2006-02-27Martin Stjernholm  if (q->cleanup == (cleanup_func) do_escape_catch) { in_catch = 1; do_escape_catch(); }
1d6ca22008-06-30Martin Stjernholm #ifdef PIKE_DEBUG /* Have to pop marks from F_SYNCH_MARK too if the debug level * is high enough to get them inserted, otherwise we'll get * false alarms from debug checks in e.g. POP_CATCH_CONTEXT. */ else if (d_flag > 2 && q->cleanup == (cleanup_func) do_cleanup_synch_mark) { /* Use the ordinary pop mark instruction here since we know * the stack isn't in synch and we don't want debug checks * for that. */ do_pop_mark (NULL); } #endif }
ca176b2006-02-27Martin Stjernholm  }
3958992001-06-23Fredrik Hübinette (Hubbe)  emit0(in_catch ? F_VOLATILE_RETURN : F_RETURN);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0;
ca176b2006-02-27Martin Stjernholm  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_SSCANF:
fffdad2014-10-13Martin Nilsson  tmp1=do_docode(CAR(n),DO_NOT_COPY);
5267b71995-08-09Fredrik Hübinette (Hubbe)  tmp2=do_docode(CDR(n),DO_NOT_COPY | DO_LVALUE);
bd67392015-10-14Martin Nilsson  emit1(F_SSCANF, (INT32)(tmp1+tmp2));
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1;
6c8ada2001-01-14Martin Stjernholm  case F_CATCH: {
9abda42002-03-02Martin Stjernholm  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) 
ca176b2006-02-27Martin Stjernholm  /* Entry point called via catching_eval_instruction(). */
461e0a2002-11-06Henrik Grubbström (Grubba)  emit0(F_ENTRY);
7acaf12001-01-15Martin Stjernholm  PUSH_STATEMENT_LABEL;
9abda42002-03-02Martin Stjernholm  current_switch.jumptable=0;
5a0fd52001-01-10Martin Stjernholm  current_label->break_label=alloc_label();
5267b71995-08-09Fredrik Hübinette (Hubbe)  DO_CODE_BLOCK(CAR(n));
5a0fd52001-01-10Martin Stjernholm  ins_label(current_label->break_label);
9307b42002-09-23Martin Stjernholm  emit0(F_EXIT_CATCH);
7acaf12001-01-15Martin Stjernholm  POP_STATEMENT_LABEL;
9abda42002-03-02Martin Stjernholm  current_switch.jumptable = prev_switch_jumptable;
a38a222006-03-15Henrik Grubbström (Grubba)  do_branch (tmp1);
7acaf12001-01-15Martin Stjernholm 
2a50e72017-06-07Henrik Grubbström (Grubba)  modify_stack_depth(1);
ca176b2006-02-27Martin Stjernholm  /* Entry point called via catching_eval_instruction() after
a38a222006-03-15Henrik Grubbström (Grubba)  * catching an error. * * NB: This is reached by subtracting ENTRY_PROLOGUE_SIZE * from the label below. * NB: The label must be after the entry, since it may expand to code * that requires the entry code to have run. */
ca176b2006-02-27Martin Stjernholm  emit0(F_ENTRY);
bd67392015-10-14Martin Nilsson  ins_label((INT32)tmp1);
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:
57c2872003-09-19Henrik Grubbström (Grubba)  ret = do_docode(CAR(n),DO_LVALUE); return ret + do_docode(CDR(n),DO_LVALUE);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
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)
5aad932002-08-15Marcus Comstedt  Pike_fatal("Very internal compiler error.\n");
2a32691998-01-31Fredrik Hübinette (Hubbe) #endif
bd67392015-10-14Martin Nilsson  emit1(F_ARRAY_LVALUE, (INT32)(tmp1>>1));
2a32691998-01-31Fredrik Hübinette (Hubbe)  return 2;
dffa011997-01-15Fredrik Hübinette (Hubbe)  case F_ARROW:
017b572011-10-28Henrik Grubbström (Grubba)  if(CDR(n)->token != F_CONSTANT || TYPEOF(CDR(n)->u.sval) != T_STRING)
6de0852004-01-23Martin Nilsson  Pike_fatal("Bugg in F_ARROW, index not string.\n");
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);
900bf92014-02-25Per Hedbor  if ((tmp2 = lfun_lookup_id(CDR(n)->u.sval.u.string)) != -1 ) {
286afb2001-02-05Henrik Grubbström (Grubba)  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);
978cc62015-04-19Henrik Grubbström (Grubba)  if(n && 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)  } }
bd67392015-10-14Martin Nilsson  return (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),
7e877a2003-04-02Martin Stjernholm  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)
5aad932002-08-15Marcus Comstedt  Pike_fatal("Unwanted lvalue!\n");
19aaeb1998-05-25Fredrik Hübinette (Hubbe) #endif
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_INDIRECT);
19aaeb1998-05-25Fredrik Hübinette (Hubbe)  }
13670c2015-05-25Martin Nilsson 
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(do_docode(CDR(n),0) != 1)
6de0852004-01-23Martin Nilsson  Pike_fatal("Internal compiler error, please report this (1).\n");
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);
726dd92014-04-19Henrik Grubbström (Grubba)  if(n && (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)  } }
bd67392015-10-14Martin Nilsson  return (INT32)tmp1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_CONSTANT:
017b572011-10-28Henrik Grubbström (Grubba)  switch(TYPEOF(n->u.sval))
5267b71995-08-09Fredrik Hübinette (Hubbe)  { case T_INT:
017b572011-10-28Henrik Grubbström (Grubba)  if(!n->u.sval.u.integer && SUBTYPEOF(n->u.sval) == NUMBER_UNDEFINED)
ece3201999-08-02Fredrik Hübinette (Hubbe)  {
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_UNDEFINED);
ece3201999-08-02Fredrik Hübinette (Hubbe)  }else{
648a8c2003-01-26Mirar (Pontus Hagland) #if SIZEOF_INT_TYPE > 4 INT_TYPE i=n->u.sval.u.integer; if (i != (INT32)i) {
cf84382003-01-26Mirar (Pontus Hagland)  unsigned INT_TYPE ip=(unsigned INT_TYPE)i;
648a8c2003-01-26Mirar (Pontus Hagland)  INT32 a,b; a=(INT32)(ip>>32); b=(INT32)(ip&0xffffffff); emit2(F_NUMBER64,a,b); } else emit1(F_NUMBER,i); #else
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit1(F_NUMBER,n->u.sval.u.integer);
648a8c2003-01-26Mirar (Pontus Hagland) #endif
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);
bd67392015-10-14Martin Nilsson  emit1(F_STRING, (INT32)tmp1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; case T_FUNCTION:
017b572011-10-28Henrik Grubbström (Grubba)  if(SUBTYPEOF(n->u.sval) != 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)  {
98cf2a2003-02-24Martin Stjernholm  /* When does this occur? /mast */
017b572011-10-28Henrik Grubbström (Grubba)  emit1(F_GLOBAL, SUBTYPEOF(n->u.sval));
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) 
7c3fe02009-11-20Henrik Grubbström (Grubba)  for(o=Pike_compiler->fake_object;o!=n->u.sval.u.object;o=o->parent) { state->new_program->flags |= PROGRAM_USES_PARENT | PROGRAM_NEEDS_PARENT;
6d22541998-01-28Fredrik Hübinette (Hubbe)  x++;
7c3fe02009-11-20Henrik Grubbström (Grubba)  }
f3c7152001-04-14Fredrik Hübinette (Hubbe) #else struct program_state *state=Pike_compiler;
7c3fe02009-11-20Henrik Grubbström (Grubba)  for(;state->fake_object!=n->u.sval.u.object;state=state->previous) { state->new_program->flags |= PROGRAM_USES_PARENT | PROGRAM_NEEDS_PARENT;
f3c7152001-04-14Fredrik Hübinette (Hubbe)  x++;
7c3fe02009-11-20Henrik Grubbström (Grubba)  }
f3c7152001-04-14Fredrik Hübinette (Hubbe) #endif
017b572011-10-28Henrik Grubbström (Grubba)  emit2(F_EXTERNAL, SUBTYPEOF(n->u.sval), x);
22d7992001-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->new_program->flags |= PROGRAM_USES_PARENT | PROGRAM_NEEDS_PARENT;
6d22541998-01-28Fredrik Hübinette (Hubbe)  return 1; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
5f50842018-02-12Marcus Comstedt  /* FALLTHRU */
fb5b3f2002-11-18Henrik Grubbström (Grubba)  default:
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
017b572011-10-28Henrik Grubbström (Grubba)  if((TYPEOF(n->u.sval) == T_OBJECT) &&
fb5b3f2002-11-18Henrik Grubbström (Grubba)  (n->u.sval.u.object->next == n->u.sval.u.object))
5aad932002-08-15Marcus Comstedt  Pike_fatal("Internal error: Pointer to parent cannot be a compile time constant!\n");
6d22541998-01-28Fredrik Hübinette (Hubbe) #endif
454d541999-09-18Fredrik Hübinette (Hubbe)  tmp1=store_constant(&(n->u.sval), !(n->tree_info & OPT_EXTERNAL_DEPEND), n->name);
bd67392015-10-14Martin Nilsson  emit1(F_CONSTANT, (INT32)tmp1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1;
515bcf2002-07-02Henrik Grubbström (Grubba)  case T_TYPE: tmp1 = store_constant(&(n->u.sval), 0, n->name);
bd67392015-10-14Martin Nilsson  emit1(F_CONSTANT, (INT32)tmp1);
515bcf2002-07-02Henrik Grubbström (Grubba)  return 1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  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);
bd67392015-10-14Martin Nilsson  emit1(F_CONSTANT, (INT32)tmp1);
13670c2015-05-25Martin Nilsson 
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) {
017b572011-10-28Henrik Grubbström (Grubba)  switch(TYPEOF(n->u.sval))
5e44422001-02-25Fredrik Hübinette (Hubbe)  { case T_ARRAY:
2575242004-05-14Martin Nilsson  if(array_fix_type_field(n->u.sval.u.array) & BIT_COMPLEX)
5e44422001-02-25Fredrik Hübinette (Hubbe)  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:
5b15bb2001-12-10Martin Stjernholm  multiset_fix_type_field(n->u.sval.u.multiset); if(multiset_ind_types(n->u.sval.u.multiset) & BIT_COMPLEX)
5e44422001-02-25Fredrik Hübinette (Hubbe)  emit0(F_COPY_VALUE); break; } }else{ emit0(F_COPY_VALUE); } }
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; } case F_LOCAL:
13670c2015-05-25Martin Nilsson  if(n->u.integer.a >=
4218011999-01-31Fredrik Hübinette (Hubbe)  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) {
c981662006-03-02Henrik Grubbström (Grubba)  emit2(F_LEXICAL_LOCAL_LVALUE, n->u.integer.a, n->u.integer.b);
4218011999-01-31Fredrik Hübinette (Hubbe)  return 2; }else{
c981662006-03-02Henrik Grubbström (Grubba)  emit2(F_LEXICAL_LOCAL, n->u.integer.a, 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) {
c981662006-03-02Henrik Grubbström (Grubba)  if (n->node_info & OPT_ASSIGNMENT) { /* Initialize the variable. */ emit0(F_CONST0); emit1(F_ASSIGN_LOCAL_AND_POP, n->u.integer.a); } emit1(F_LOCAL_LVALUE, n->u.integer.a);
4218011999-01-31Fredrik Hübinette (Hubbe)  return 2; }else{
c981662006-03-02Henrik Grubbström (Grubba)  if (n->node_info & OPT_ASSIGNMENT) { /* Initialize the variable. */ emit0(F_CONST0); emit1(F_ASSIGN_LOCAL, n->u.integer.a); } else { emit1(F_LOCAL, n->u.integer.a); }
4218011999-01-31Fredrik Hübinette (Hubbe)  return 1; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
4218011999-01-31Fredrik Hübinette (Hubbe)  case F_TRAMPOLINE:
8c70ba2001-09-28Fredrik Hübinette (Hubbe)  { struct compiler_frame *f; int depth=0; for(f=Pike_compiler->compiler_frame; f!=n->u.trampoline.frame;f=f->previous) depth++; emit2(F_TRAMPOLINE,n->u.trampoline.ident,depth);
4218011999-01-31Fredrik Hübinette (Hubbe)  return 1;
8c70ba2001-09-28Fredrik Hübinette (Hubbe)  }
4218011999-01-31Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_VAL_LVAL:
5073752018-05-26Henrik Grubbström (Grubba)  case F_FOREACH_VAL_LVAL:
c3823f2003-09-19Henrik Grubbström (Grubba)  ret = do_docode(CAR(n),flags); return ret + do_docode(CDR(n), flags | DO_LVALUE);
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  case F_AUTO_MAP: emit0(F_MARK); code_expression(CAR(n), 0, "automap function"); do_encode_automap_arg_list(CDR(n),0); emit_apply_builtin("__automap__"); return 1; case F_AUTO_MAP_MARKER:
0aeaca2014-08-13Per Hedbor  if( flags & DO_LVALUE ) { do_docode(CAR(n),DO_LVALUE); } else { yyerror("[*] not supported here.\n"); emit0(F_CONST0); }
8bef1b2001-09-27Fredrik Hübinette (Hubbe)  return 1;
e9fbb72018-05-21Henrik Grubbström (Grubba)  case F_TYPEOF: { struct svalue s; /* NB: This should only be reachable via eval_low(). * Typically treeopt will get rid of this node. */ SET_SVAL(s, PIKE_T_TYPE, 0, type, CAR(n)->type?CAR(n)->type:mixed_type_string); tmp1 = store_constant(&s, 0, NULL); emit1(F_CONSTANT, (INT32)tmp1); } return 1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  default:
5aad932002-08-15Marcus Comstedt  Pike_fatal("Infernal compiler error (unknown parse-tree-token %d).\n", n->token);
9282fd2015-09-27Martin Nilsson  UNREACHABLE(return 0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
9d52082016-10-30Martin Karlgren static void emit_save_locals(struct compiler_frame *f) { struct compilation *c = THIS_COMPILATION;
eb29d92016-11-04Martin Karlgren  unsigned INT16 offset; unsigned INT16 idx; int num_locals = f->max_number_of_locals;
9d52082016-10-30Martin Karlgren  for (offset = 0; offset < (num_locals >> 4) + 1; offset++) {
eb29d92016-11-04Martin Karlgren  unsigned int bitmask = 0;
9d52082016-10-30Martin Karlgren  for (idx = 0; idx < 16; idx++) {
eb29d92016-11-04Martin Karlgren  int local_var_idx = offset * 16 + idx;
9d52082016-10-30Martin Karlgren  if (local_var_idx >= num_locals) { break; } if (f->variable[local_var_idx].flags & LOCAL_VAR_USED_IN_SCOPE) { bitmask |= 1 << idx; } } if (bitmask) {
eb29d92016-11-04Martin Karlgren  emit1(F_SAVE_LOCALS, (offset << 16) | bitmask);
9d52082016-10-30Martin Karlgren  } } }
ee6a782003-11-19Henrik Grubbström (Grubba) /* Used to generate code for functions. */
dc6e4d2017-01-09Henrik Grubbström (Grubba) INT32 do_code_block(node *n, int identifier_flags)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
e021fe2008-04-14Henrik Grubbström (Grubba)  struct compilation *c = THIS_COMPILATION;
45dda92012-06-10Henrik Grubbström (Grubba)  struct reference *id = NULL;
ee6a782003-11-19Henrik Grubbström (Grubba)  INT32 entry_point;
45dda92012-06-10Henrik Grubbström (Grubba)  int aggregate_cnum = -1;
b2ac6f2017-03-29Henrik Grubbström (Grubba)  int save_stack_depth = current_stack_depth;
3995112017-12-15Henrik Grubbström (Grubba)  int save_label_no = label_no;
7acaf12001-01-15Martin Stjernholm  current_stack_depth = 0;
45dda92012-06-10Henrik Grubbström (Grubba)  if (Pike_compiler->compiler_frame->current_function_number >= 0) { id = Pike_compiler->new_program->identifier_references + Pike_compiler->compiler_frame->current_function_number; }
7a82f91996-04-13Fredrik Hübinette (Hubbe)  init_bytecode();
6fd5172000-04-25Fredrik Hübinette (Hubbe)  label_no=1;
873ceb2000-04-30Fredrik Hübinette (Hubbe) 
5e5a592002-11-14Henrik Grubbström (Grubba)  /* NOTE: This is no ordinary label... */ low_insert_label(0);
a468a02001-07-24Henrik Grubbström (Grubba)  emit0(F_ENTRY);
873ceb2000-04-30Fredrik Hübinette (Hubbe)  emit0(F_START_FUNCTION);
b1aa472001-10-05Fredrik Hübinette (Hubbe) 
45dda92012-06-10Henrik Grubbström (Grubba)  if (Pike_compiler->compiler_frame->num_args) { emit2(F_FILL_STACK, Pike_compiler->compiler_frame->num_args, 1); } emit1(F_MARK_AT, Pike_compiler->compiler_frame->num_args);
dc6e4d2017-01-09Henrik Grubbström (Grubba)  if (identifier_flags & IDENTIFIER_VARARGS) {
45dda92012-06-10Henrik Grubbström (Grubba)  struct svalue *sval = simple_mapping_string_lookup(get_builtin_constants(), "aggregate"); if (!sval) { yyerror("predef::aggregate() is missing.\n"); Pike_fatal("No aggregate!\n");
8383c82015-10-17Martin Nilsson  UNREACHABLE(return 0);
45dda92012-06-10Henrik Grubbström (Grubba)  } aggregate_cnum = store_constant(sval, 0, NULL); emit1(F_CALL_BUILTIN, aggregate_cnum); if (Pike_compiler->compiler_frame->max_number_of_locals != Pike_compiler->compiler_frame->num_args+1) { emit2(F_FILL_STACK, Pike_compiler->compiler_frame->max_number_of_locals, 0); } } else { emit0(F_POP_TO_MARK); if (Pike_compiler->compiler_frame->max_number_of_locals != Pike_compiler->compiler_frame->num_args) { emit2(F_FILL_STACK, Pike_compiler->compiler_frame->max_number_of_locals, 0); } }
7dcd1a2012-06-25Per Hedbor  emit2(F_INIT_FRAME, Pike_compiler->compiler_frame->num_args, Pike_compiler->compiler_frame->max_number_of_locals);
4a26652012-06-19Henrik Grubbström (Grubba)  if (Pike_compiler->compiler_frame->lexical_scope & SCOPE_SCOPE_USED) {
9d52082016-10-30Martin Karlgren  emit_save_locals(Pike_compiler->compiler_frame);
45dda92012-06-10Henrik Grubbström (Grubba)  } if(id && (id->id_flags & ID_INLINE))
873ceb2000-04-30Fredrik Hübinette (Hubbe)  {
ec1d4d2002-11-14Henrik Grubbström (Grubba)  Pike_compiler->compiler_frame->recur_label=0;
bad5162000-06-23Fredrik Hübinette (Hubbe)  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) 
4686dd2002-11-12Henrik Grubbström (Grubba)  /* NOTE: This is no ordinary label... */ low_insert_label(Pike_compiler->compiler_frame->recur_label); emit0(F_ENTRY);
873ceb2000-04-30Fredrik Hübinette (Hubbe)  emit0(F_START_FUNCTION);
45dda92012-06-10Henrik Grubbström (Grubba)  if (Pike_compiler->compiler_frame->num_args) { emit2(F_FILL_STACK, Pike_compiler->compiler_frame->num_args, 1); } emit1(F_MARK_AT, Pike_compiler->compiler_frame->num_args);
dc6e4d2017-01-09Henrik Grubbström (Grubba)  if (identifier_flags & IDENTIFIER_VARARGS) {
45dda92012-06-10Henrik Grubbström (Grubba)  emit1(F_CALL_BUILTIN, aggregate_cnum); if (Pike_compiler->compiler_frame->max_number_of_locals != Pike_compiler->compiler_frame->num_args+1) { emit2(F_FILL_STACK, Pike_compiler->compiler_frame->max_number_of_locals, 0); } emit2(F_INIT_FRAME, Pike_compiler->compiler_frame->num_args+1, Pike_compiler->compiler_frame->max_number_of_locals); } else { emit0(F_POP_TO_MARK); if (Pike_compiler->compiler_frame->max_number_of_locals != Pike_compiler->compiler_frame->num_args) { emit2(F_FILL_STACK, Pike_compiler->compiler_frame->max_number_of_locals, 0); } emit2(F_INIT_FRAME, Pike_compiler->compiler_frame->num_args, Pike_compiler->compiler_frame->max_number_of_locals); }
4a26652012-06-19Henrik Grubbström (Grubba)  if (Pike_compiler->compiler_frame->lexical_scope & SCOPE_SCOPE_USED) {
9d52082016-10-30Martin Karlgren  emit_save_locals(Pike_compiler->compiler_frame);
45dda92012-06-10Henrik Grubbström (Grubba)  }
873ceb2000-04-30Fredrik Hübinette (Hubbe)  DO_CODE_BLOCK(n); }
ee6a782003-11-19Henrik Grubbström (Grubba)  entry_point = assemble(1);
7acaf12001-01-15Martin Stjernholm 
b2ac6f2017-03-29Henrik Grubbström (Grubba)  current_stack_depth = save_stack_depth;
3995112017-12-15Henrik Grubbström (Grubba)  label_no = save_label_no;
ee6a782003-11-19Henrik Grubbström (Grubba)  return entry_point;
7a82f91996-04-13Fredrik Hübinette (Hubbe) }
ee6a782003-11-19Henrik Grubbström (Grubba) /* Used by eval_low() to build code for constant expressions. */ INT32 docode(node *n)
7a82f91996-04-13Fredrik Hübinette (Hubbe) {
ee6a782003-11-19Henrik Grubbström (Grubba)  INT32 entry_point;
7a82f91996-04-13Fredrik Hübinette (Hubbe)  int label_no_save = label_no;
2d10fb2016-12-29Arne Goedeke  struct byte_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) 
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();
ee6a782003-11-19Henrik Grubbström (Grubba)  insert_opcode0(F_ENTRY, n->line_number, n->current_file); /* FIXME: Should we check that do_docode() returns 1? */ do_docode(n,0); insert_opcode0(F_DUMB_RETURN, n->line_number, n->current_file); entry_point = assemble(0); /* Don't store linenumbers. */
7a82f91996-04-13Fredrik Hübinette (Hubbe)  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;
ee6a782003-11-19Henrik Grubbström (Grubba)  return entry_point;
5267b71995-08-09Fredrik Hübinette (Hubbe) }