pike.git / src / docode.c

version» Context lines:

pike.git/src/docode.c:1:   /*\   ||| This file a part of Pike, and is copyright by Fredrik Hubinette   ||| Pike is distributed as GPL (General Public License)   ||| See the files COPYING and DISCLAIMER for more information.   \*/   /**/   #include "global.h" - RCSID("$Id: docode.c,v 1.84 2000/11/08 20:03:45 hubbe Exp $"); + RCSID("$Id: docode.c,v 1.85 2000/12/01 01:13:43 hubbe Exp $");   #include "las.h"   #include "program.h"   #include "pike_types.h"   #include "stralloc.h"   #include "interpret.h"   #include "constants.h"   #include "array.h"   #include "pike_macros.h"   #include "error.h"   #include "pike_memory.h"
pike.git/src/docode.c:53:      int alloc_label(void) { return ++label_no; }      int do_jump(int token,INT32 lbl)   {    if(lbl==-1) lbl=alloc_label();    emit1(token, lbl);    return lbl;   }    - #define ins_label(L) do_jump(F_LABEL, L) +     -  + #define LBLCACHESIZE 4711 + #define CURRENT_INSTR ((long)instrbuf.s.len / (long)sizeof(p_instr)) + #define MAX_UNWIND 100 +  + static int lbl_cache[LBLCACHESIZE]; +  + int do_branch(INT32 lbl) + { +  if(lbl==-1) +  { +  lbl=alloc_label(); +  }else{ +  INT32 last,pos=lbl_cache[lbl % LBLCACHESIZE]; +  if(pos < (last=CURRENT_INSTR) && (CURRENT_INSTR - pos) < MAX_UNWIND) +  { + #define BUF ((p_instr *)instrbuf.s.str) +  if(BUF[pos].opcode == F_LABEL && BUF[pos].arg == lbl) +  { +  for(;pos < last;pos++) +  { +  if(BUF[pos].opcode != F_LABEL) +  { +  insert_opcode2(BUF[pos].opcode, +  BUF[pos].arg, +  BUF[pos].arg2, +  BUF[pos].line, +  BUF[pos].file); +  } +  } +  } +  } +  +  } +  emit1(F_BRANCH, lbl); +  return lbl; + } +  + void low_insert_label(int lbl) + { +  lbl_cache[ lbl % LBLCACHESIZE ] = CURRENT_INSTR; +  emit1(F_LABEL, lbl); + } +  + int ins_label(int lbl) + { +  if(lbl==-1) lbl=alloc_label(); +  low_insert_label(lbl); +  return lbl; + } +    void do_pop(int x)   {    switch(x)    {    case 0: return;    case 1: emit0(F_POP_VALUE); break;    default: emit1(F_POP_N_ELEMS,x); break;    }   }   
pike.git/src/docode.c:110:   void do_cond_jump(node *n, int label, int iftrue, int flags)   {    iftrue=!!iftrue;    if((flags & DO_POP) && node_is_tossable(n))    {    int t,f;    t=!!node_is_true(n);    f=!!node_is_false(n);    if(t || f)    { -  if(t == iftrue) do_jump(F_BRANCH, label); +  if(t == iftrue) do_branch( label);    return;    }    }       switch(n->token)    {    case F_LAND:    case F_LOR:    if(iftrue == (n->token==F_LAND))    {    int tmp=alloc_label();    do_cond_jump(CAR(n), tmp, !iftrue, flags | DO_POP);    do_cond_jump(CDR(n), label, iftrue, flags); -  emit1(F_LABEL,tmp); +  low_insert_label(tmp);    }else{    do_cond_jump(CAR(n), label, iftrue, flags);    do_cond_jump(CDR(n), label, iftrue, flags);    }    return;       case F_APPLY:    if(!is_efun(CAR(n), f_not)) break;       case F_NOT:
pike.git/src/docode.c:355:    INT32 *prev_switch_jumptable = current_switch_jumptable;    int adroppings , bdroppings;    current_switch_jumptable=0;          if(!CDDR(n))    {    tmp1=alloc_label();    do_jump_when_zero(CAR(n), DO_NOT_WARN((INT32)tmp1));    DO_CODE_BLOCK(CADR(n)); -  emit1(F_LABEL, DO_NOT_WARN((INT32)tmp1)); +  low_insert_label( DO_NOT_WARN((INT32)tmp1));    current_switch_jumptable = prev_switch_jumptable;    return 0;    }       if(!CADR(n))    {    tmp1=alloc_label();    do_jump_when_non_zero(CAR(n), DO_NOT_WARN((INT32)tmp1));    DO_CODE_BLOCK(CDDR(n)); -  emit1(F_LABEL, DO_NOT_WARN((INT32)tmp1)); +  low_insert_label( DO_NOT_WARN((INT32)tmp1));    current_switch_jumptable = prev_switch_jumptable;    return 0;    }       tmp1=alloc_label();    do_jump_when_zero(CAR(n), DO_NOT_WARN((INT32)tmp1));       adroppings=do_docode(CADR(n), flags);    tmp3=emit1(F_POP_N_ELEMS,0);       /* Else */ -  tmp2=do_jump(F_BRANCH,-1); -  emit1(F_LABEL, DO_NOT_WARN((INT32)tmp1)); +  tmp2=do_branch(-1); +  low_insert_label( DO_NOT_WARN((INT32)tmp1));       bdroppings=do_docode(CDDR(n), flags);    if(adroppings < bdroppings)    {    do_pop(bdroppings - adroppings);    }       if(adroppings > bdroppings)    {    update_arg(DO_NOT_WARN((INT32)tmp3),    adroppings - bdroppings);    adroppings=bdroppings;    }    -  emit1(F_LABEL, DO_NOT_WARN((INT32)tmp2)); +  low_insert_label( DO_NOT_WARN((INT32)tmp2));       current_switch_jumptable = prev_switch_jumptable;    return adroppings;    }       case F_AND_EQ:    case F_OR_EQ:    case F_XOR_EQ:    case F_LSH_EQ:    case F_RSH_EQ:
pike.git/src/docode.c:545:    break;    }    return flags & DO_POP ? 0 : 1;    }       case F_LAND:    case F_LOR:    tmp1=alloc_label();    do_cond_jump(CAR(n), DO_NOT_WARN((INT32)tmp1), n->token == F_LOR, 0);    code_expression(CDR(n), flags, n->token == F_LOR ? "||" : "&&"); -  emit1(F_LABEL, DO_NOT_WARN((INT32)tmp1)); +  low_insert_label( DO_NOT_WARN((INT32)tmp1));    return 1;       case F_EQ:    case F_NE:    case F_ADD:    case F_LT:    case F_LE:    case F_GT:    case F_GE:    case F_SUBTRACT:
pike.git/src/docode.c:680:       foreach_arg_pushed:   #ifdef PIKE_DEBUG    /* This is really ugly because there is always a chance that the bug    * will disappear when new instructions are added to the code, but    * think it is worth it.    */    if(d_flag)    emit0(F_MARK);   #endif -  tmp3=do_jump(F_BRANCH,-1); +  tmp3=do_branch(-1);    tmp1=ins_label(-1);    DO_CODE_BLOCK(CDR(n));    ins_label(current_continue); -  emit1(F_LABEL, DO_NOT_WARN((INT32)tmp3)); +  low_insert_label( DO_NOT_WARN((INT32)tmp3));    do_jump(n->token, DO_NOT_WARN((INT32)tmp1));    ins_label(current_break);      #ifdef PIKE_DEBUG    if(d_flag)    emit0(F_POP_MARK);   #endif       current_switch_jumptable = prev_switch_jumptable;    current_break=break_save;
pike.git/src/docode.c:722:       tmp2=do_docode(CAR(n),0);   #ifdef PIKE_DEBUG    /* This is really ugly because there is always a chance that the bug    * will disappear when new instructions are added to the code, but    * think it is worth it.    */    if(d_flag)    emit0(F_MARK);   #endif -  tmp3=do_jump(F_BRANCH,-1); +  tmp3=do_branch(-1);    tmp1=ins_label(-1);       DO_CODE_BLOCK(CDR(n));    ins_label(current_continue); -  emit1(F_LABEL, DO_NOT_WARN((INT32)tmp3)); +  low_insert_label( DO_NOT_WARN((INT32)tmp3));    do_jump(n->token, DO_NOT_WARN((INT32)tmp1));    ins_label(current_break);   #ifdef PIKE_DEBUG    if(d_flag)    emit0(F_POP_MARK);   #endif       current_switch_jumptable = prev_switch_jumptable;    current_break=break_save;    current_continue=continue_save;
pike.git/src/docode.c:940:    current_switch_case=1;    current_switch_default=-1;    current_switch_jumptable=(INT32 *)xalloc(sizeof(INT32)*(cases*2+2));    jumptable=(INT32 *)xalloc(sizeof(INT32)*(cases*2+2));       for(e=1; e<cases*2+2; e++)    {    jumptable[e] = DO_NOT_WARN((INT32)emit1(F_POINTER, 0));    current_switch_jumptable[e]=-1;    } +  emit0(F_NOTREACHED);       current_switch_jumptable[current_switch_case++]=-1;       DO_CODE_BLOCK(CDR(n));      #ifdef PIKE_DEBUG    if(Pike_sp-save_sp != cases)    fatal("Count cases is wrong!\n");   #endif   
pike.git/src/docode.c:1003:    pop_stack();    free((char *)jumptable);    free((char *)current_switch_jumptable);       current_switch_jumptable = prev_switch_jumptable;    current_switch_default = prev_switch_default;    current_switch_case = prev_switch_case;    current_switch_values_on_stack = prev_switch_values_on_stack;    current_switch_type = prev_switch_type;    -  emit1(F_LABEL, current_break); +  low_insert_label( current_break);       current_break=break_save;   #ifdef PIKE_DEBUG    if(Pike_interpreter.recoveries && Pike_sp-Pike_interpreter.evaluator_stack < Pike_interpreter.recoveries->stack_pointer)    fatal("Stack error after F_SWITCH (underflow)\n");   #endif    return 0;    }       case F_CASE:
pike.git/src/docode.c:1113:    }else{    current_switch_default = ins_label(-1);    }    return 0;       case F_BREAK:    if(current_break == -1)    {    yyerror("Break outside loop or switch.");    }else{ -  do_jump(F_BRANCH, current_break); +  do_branch( current_break);    }    return 0;       case F_CONTINUE:    if(current_continue == -1)    {    yyerror("continue outside loop or switch.");    }else{ -  do_jump(F_BRANCH, current_continue); +  do_branch( current_continue);    }    return 0;       case F_RETURN:    do_docode(CAR(n),0);    emit0(F_RETURN);    return 0;       case F_SSCANF:    tmp1=do_docode(CAR(n),DO_NOT_COPY);
pike.git/src/docode.c:1368:   }      void do_code_block(node *n)   {    init_bytecode();    label_no=1;       emit1(F_BYTE,Pike_compiler->compiler_frame->max_number_of_locals);    emit1(F_BYTE,Pike_compiler->compiler_frame->num_args);    emit0(F_START_FUNCTION); -  emit1(F_LABEL,0); +  low_insert_label(0);    if(Pike_compiler->new_program->identifier_references[Pike_compiler->compiler_frame->    current_function_number].id_flags &    ID_INLINE)    {    Pike_compiler->compiler_frame->recur_label=0;    Pike_compiler->compiler_frame->is_inline=1;    }       DO_CODE_BLOCK(n);   
pike.git/src/docode.c:1391: Inside #if defined(PIKE_DEBUG)
  #ifdef PIKE_DEBUG    if(l_flag)    {    fprintf(stderr,"Generating inline recursive function.\n");    }   #endif    /* generate code again, but this time it is inline */    Pike_compiler->compiler_frame->is_inline=1;       /* This is a no-op, but prevents optimizer to delete the bytes below */ -  emit1(F_LABEL,-1); +  low_insert_label(-1);    emit1(F_BYTE,Pike_compiler->compiler_frame->max_number_of_locals);    emit1(F_BYTE,Pike_compiler->compiler_frame->num_args);    emit0(F_START_FUNCTION); -  emit1(F_LABEL,Pike_compiler->compiler_frame->recur_label); +  low_insert_label(Pike_compiler->compiler_frame->recur_label);    DO_CODE_BLOCK(n);    }    assemble();   }      int docode(node *n)   {    int tmp;    int label_no_save = label_no;    dynamic_buffer instrbuf_save = instrbuf;