pike.git / src / docode.c

version» Context lines:

pike.git/src/docode.c:1:   /*   || 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. - || $Id: docode.c,v 1.184 2006/02/25 04:05:32 mast Exp $ + || $Id: docode.c,v 1.185 2006/02/27 12:07:09 mast Exp $   */      #include "global.h"   #include "las.h"   #include "program.h"   #include "pike_types.h"   #include "stralloc.h"   #include "interpret.h"   #include "constants.h"   #include "array.h"
pike.git/src/docode.c:163:   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}; - static int in_catch=0; +       void upd_int(int offset, INT32 tmp)   {    MEMCPY(Pike_compiler->new_program->program+offset, (char *)&tmp,sizeof(tmp));   }      INT32 read_int(int offset)   {    return EXTRACT_INT(Pike_compiler->new_program->program+offset);   }
pike.git/src/docode.c:2014:    current_label->break_label = -1;    }    DO_CODE_BLOCK(CDR(n));    if (!name.next && current_label->emit_break_label)    low_insert_label(current_label->break_label);    POP_STATEMENT_LABEL;    BLOCK_END;    return 0;    }    -  case F_RETURN: +  case F_RETURN: { +  struct statement_label *p; +  int in_catch = 0;    do_docode(CAR(n),0); -  +  +  /* 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; +  for (q = p->cleanups; q; q = q->prev) +  if (q->cleanup == (cleanup_func) do_escape_catch) { +  in_catch = 1; +  do_escape_catch(); +  } +  } +     emit0(in_catch ? F_VOLATILE_RETURN : F_RETURN);    return 0; -  +  }       case F_SSCANF:    tmp1=do_docode(CAR(n),DO_NOT_COPY);    tmp2=do_docode(CDR(n),DO_NOT_COPY | DO_LVALUE);    emit1(F_SSCANF, DO_NOT_WARN((INT32)(tmp1+tmp2)));    return 1;       case F_CATCH: {    INT32 *prev_switch_jumptable = current_switch.jumptable;       tmp1=do_jump(F_CATCH,-1);    PUSH_CLEANUP_FRAME(do_escape_catch, 0);    -  /* Entry point called by eval_instruction() via o_catch(). */ +  /* Entry point called via catching_eval_instruction(). */    emit0(F_ENTRY);       PUSH_STATEMENT_LABEL;    current_switch.jumptable=0;    current_label->break_label=alloc_label();    if (TEST_COMPAT(7,0))    current_label->continue_label = current_label->break_label;    -  in_catch++; +     DO_CODE_BLOCK(CAR(n)); -  in_catch--; +        ins_label(current_label->break_label);    emit0(F_EXIT_CATCH);    POP_STATEMENT_LABEL;    current_switch.jumptable = prev_switch_jumptable; -  +  tmp2 = do_branch (-1);       ins_label(DO_NOT_WARN((INT32)tmp1));    current_stack_depth++; -  +  /* Entry point called via catching_eval_instruction() after +  * catching an error. */ +  emit0(F_ENTRY);    -  +  ins_label(DO_NOT_WARN((INT32)tmp2));    POP_AND_DONT_CLEANUP;    return 1;    }       case F_LVALUE_LIST:    ret = do_docode(CAR(n),DO_LVALUE);    return ret + do_docode(CDR(n),DO_LVALUE);       case F_ARRAY_LVALUE:    tmp1=do_docode(CAR(n),DO_LVALUE);