pike.git / src / interpret.c

version» Context lines:

pike.git/src/interpret.c:65:   #define SVALUE_STACK_MARGIN (100 + LOW_SVALUE_STACK_MARGIN)   /* Observed in 7.4: 11000 was enough, 10000 wasn't. */   #define C_STACK_MARGIN (20000 + LOW_C_STACK_MARGIN)      /* Another extra margin to use while dumping the raw error in    * exit_on_error, so that backtrace_frame._sprintf can be called    * then. */   #define LOW_SVALUE_STACK_MARGIN 20   #define LOW_C_STACK_MARGIN 500    - #ifdef HAVE_COMPUTED_GOTO - PIKE_OPCODE_T *fcode_to_opcode = NULL; - struct op_2_f *opcode_to_fcode = NULL; - #endif /* HAVE_COMPUTED_GOTO */ +       PMOD_EXPORT const char Pike_check_stack_errmsg[] =    "Svalue stack overflow. "    "(%ld of %ld entries on stack, needed %ld more entries)\n";   PMOD_EXPORT const char Pike_check_mark_stack_errmsg[] =    "Mark stack overflow.\n";   PMOD_EXPORT const char Pike_check_c_stack_errmsg[] =    "C stack overflow.\n";   #ifdef PIKE_DEBUG   PMOD_EXPORT const char msg_stack_error[] =    "Stack error.\n";   PMOD_EXPORT const char msg_pop_neg[] =    "Popping negative number of args.... (%"PRINTPTRDIFFT"d) \n";   #endif    -  + PMOD_EXPORT extern void check_c_stack_margin(void) + { +  check_c_stack(Pike_interpreter.c_stack_margin); + }      #ifdef PIKE_DEBUG   static char trace_buffer[2000];   #endif      #ifdef INTERNAL_PROFILING   PMOD_EXPORT unsigned long evaluator_callback_calls = 0;   #endif         int fast_check_threads_counter = 0;      PMOD_EXPORT int Pike_stack_size = EVALUATOR_STACK_SIZE;      static void do_trace_call(struct byte_buffer *buf, INT32 args);   static void do_trace_func_return (int got_retval, struct object *o, int fun);   static void do_trace_return (struct byte_buffer *buf, int got_retval); -  + static void do_trace_efun_call(const struct svalue *s, INT32 args); + #ifdef PIKE_DEBUG + static void do_trace_efun_return(const struct svalue *s, int got_retval); + #endif      void push_sp_mark(void)   {    if(Pike_mark_sp == Pike_interpreter.mark_stack + Pike_stack_size)    Pike_error("No more mark stack!\n");    *Pike_mark_sp++=Pike_sp;   }   ptrdiff_t pop_sp_mark(void)   {   #ifdef PIKE_DEBUG
pike.git/src/interpret.c:296: Inside #if defined(PIKE_DEBUG)
  #ifdef PIKE_DEBUG    {    static struct callback *spcb;    if(!spcb)    {    spcb=add_gc_callback(gc_check_stack_callback,0,0);    dmalloc_accept_leak(spcb);    }    }   #endif - #if defined(HAVE_COMPUTED_GOTO) || defined(PIKE_USE_MACHINE_CODE) + #ifdef PIKE_USE_MACHINE_CODE    {    static int tables_need_init=1;    if(tables_need_init) {    /* Initialize the fcode_to_opcode table / jump labels. */   #if !defined(OPCODE_INLINE_RETURN)    eval_instruction(NULL);   #endif - #if defined(PIKE_USE_MACHINE_CODE) && !defined(PIKE_DEBUG) -  /* Simple operator opcodes... */ - #define SET_INSTR_ADDRESS(X, Y) (instrs[(X)-F_OFFSET].address = (void *)Y) -  SET_INSTR_ADDRESS(F_COMPL, o_compl); -  SET_INSTR_ADDRESS(F_LSH, o_lsh); -  SET_INSTR_ADDRESS(F_RSH, o_rsh); -  SET_INSTR_ADDRESS(F_SUBTRACT, o_subtract); -  SET_INSTR_ADDRESS(F_AND, o_and); -  SET_INSTR_ADDRESS(F_OR, o_or); -  SET_INSTR_ADDRESS(F_XOR, o_xor); -  SET_INSTR_ADDRESS(F_MULTIPLY, o_multiply); -  SET_INSTR_ADDRESS(F_DIVIDE, o_divide); -  SET_INSTR_ADDRESS(F_MOD, o_mod); -  SET_INSTR_ADDRESS(F_CAST, f_cast); -  SET_INSTR_ADDRESS(F_CAST_TO_INT, o_cast_to_int); -  SET_INSTR_ADDRESS(F_CAST_TO_STRING, o_cast_to_string); -  SET_INSTR_ADDRESS(F_RANGE, o_range2); -  SET_INSTR_ADDRESS(F_SSCANF, o_sscanf); - #endif /* PIKE_USE_MACHINE_CODE && !PIKE_DEBUG */ +     tables_need_init=0;   #ifdef INIT_INTERPRETER_STATE    INIT_INTERPRETER_STATE();   #endif    }    } - #endif /* HAVE_COMPUTED_GOTO || PIKE_USE_MACHINE_CODE */ + #endif /* PIKE_USE_MACHINE_CODE */   }      /*    * lvalues are stored in two svalues in one of these formats:    * array[index] : { array, index }    * mapping[index] : { mapping, index }    * multiset[index] : { multiset, index }    * object[index] : { object, index } (external object indexing)    * local variable : { svalue pointer (T_SVALUE_PTR), nothing (T_VOID) }    * global variable : { object, identifier index (T_OBJ_INDEX) } (internal object indexing)
pike.git/src/interpret.c:400:    if(multiset_member(lval->u.multiset,lval+1))    {    SET_SVAL(*to, T_INT, NUMBER_NUMBER, integer, 1);    }else{    SET_SVAL(*to, T_INT, NUMBER_UNDEFINED, integer, 0);    }    break;       default:    if(SAFE_IS_ZERO(lval)) -  index_error(0,0,0,lval,lval+1,"Indexing the NULL value.\n"); +  index_error(0,0,lval,lval+1,"Indexing the NULL value.\n");    else -  index_error(0,0,0,lval,lval+1,"Indexing a basic type.\n"); +  index_error(0,0,lval,lval+1,"Indexing a basic type.\n");    }    return run_time_type;   }      PMOD_EXPORT void assign_lvalue(struct svalue *lval,struct svalue *from)   {    switch(TYPEOF(*lval))    {    case T_ARRAY_LVALUE:    {
pike.git/src/interpret.c:459:       case T_MULTISET:    if(UNSAFE_IS_ZERO(from))    multiset_delete(lval->u.multiset, lval+1);    else    multiset_insert(lval->u.multiset, lval+1);    break;       default:    if(SAFE_IS_ZERO(lval)) -  index_error(0,0,0,lval,lval+1,"Indexing the NULL value.\n"); +  index_error(0,0,lval,lval+1,"Indexing the NULL value.\n");    else -  index_error(0,0,0,lval,lval+1,"Indexing a basic type.\n"); +  index_error(0,0,lval,lval+1,"Indexing a basic type.\n");    }   }      /* On error callback. lvalue is followed by value to assign. */   static void o_assign_lvalue(struct svalue *lvalue)   {    assign_lvalue(lvalue, lvalue+2);   }      union anything *get_pointer_if_this_type(struct svalue *lval, TYPE_T t)
pike.git/src/interpret.c:497:    case T_ARRAY:    return array_get_item_ptr(lval->u.array,lval+1,t);       case T_MAPPING:    return mapping_get_item_ptr(lval->u.mapping,lval+1,t);       case T_MULTISET: return 0;       default:    if(SAFE_IS_ZERO(lval)) -  index_error(0,0,0,lval,lval+1,"Indexing the NULL value.\n"); +  index_error(0,0,lval,lval+1,"Indexing the NULL value.\n");    else -  index_error(0,0,0,lval,lval+1,"Indexing a basic type.\n"); +  index_error(0,0,lval,lval+1,"Indexing a basic type.\n");    return 0;    }   }      #ifdef PIKE_DEBUG      static inline void pike_trace(int level,char *fmt, ...) ATTRIBUTE((format (printf, 2, 3)));   static inline void pike_trace(int level,char *fmt, ...)   {    if(Pike_interpreter.trace_level > level)
pike.git/src/interpret.c:794: Inside #if defined(PIKE_DEBUG)
  #ifdef PIKE_DEBUG   void print_return_value(void)   {    if(Pike_interpreter.trace_level>3)    {    struct byte_buffer buf = BUFFER_INIT();       safe_describe_svalue(&buf, Pike_sp-1,0,0);    if(buffer_content_length(&buf) > TRACE_LEN)    { -  buffer_remove(&buf, buffer_content_length(&buf) - TRACE_LEN - 3); +  buffer_remove(&buf, buffer_content_length(&buf) - TRACE_LEN);    buffer_add_str(&buf, "...");    }    fprintf(stderr,"- value: %s\n",buffer_get_string(&buf));    buffer_free(&buf);    }   }   #else   #define print_return_value()   #endif   
pike.git/src/interpret.c:867:    fprintf(stderr,"- %s:%4ld:%p(%"PRINTPTRDIFFT"d): "    "%-25s %4"PRINTPTRDIFFT"d %4"PRINTPTRDIFFT"d\n",    file ? file : "-",(long)linep,    Pike_fp->pc, Pike_fp->pc - Pike_fp->context->prog->program,    get_opcode_name(instr),    Pike_sp-Pike_interpreter.evaluator_stack,    Pike_mark_sp-Pike_interpreter.mark_stack);    free_string(filep);    }    - #ifdef HAVE_COMPUTED_GOTO -  if (instr) -  ADD_RUNNED(instr); -  else -  Pike_fatal("NULL Instruction!\n"); - #else /* !HAVE_COMPUTED_GOTO */ +     if(instr + F_OFFSET < F_MAX_OPCODE)    ADD_RUNNED(instr); - #endif /* HAVE_COMPUTED_GOTO */ +        if(d_flag )    {    backlogp++;    if(backlogp >= BACKLOG) backlogp=0;       backlog[backlogp].program_id = Pike_fp->context->prog->id;    backlog[backlogp].instruction=instr;    backlog[backlogp].pc = Pike_fp->pc;    backlog[backlogp].stack = Pike_sp - Pike_interpreter.evaluator_stack;
pike.git/src/interpret.c:1012: Inside #if defined(_REENTRANT)
     #ifdef _REENTRANT    if(thread != backlog[e].thread_state)    {    fprintf(stderr,"[Thread swap, Pike_interpreter.thread_state=%p]\n",backlog[e].thread_state);    thread = backlog[e].thread_state;    }   #endif       file = get_line(backlog[e].pc,p, &line); - #ifdef HAVE_COMPUTED_GOTO -  fprintf(stderr,"%s:%ld:(%"PRINTPTRDIFFT"d): %s", -  file->str, -  (long)line, -  backlog[e].pc - p->program, -  get_opcode_name(backlog[e].instruction)); - #else /* !HAVE_COMPUTED_GOTO */ +     if(backlog[e].instruction+F_OFFSET > F_MAX_OPCODE)    {    fprintf(stderr,"%s:%ld:(%"PRINTPTRDIFFT"d): ILLEGAL INSTRUCTION %d\n",    file->str,    (long)line,    backlog[e].pc - p->program,    backlog[e].instruction + F_OFFSET);    free_string(file);    continue;    }
pike.git/src/interpret.c:1051:    else if(instrs[backlog[e].instruction].flags & I_POINTER)    {    fprintf(stderr,"(%+ld)", (long)backlog[e].arg);    }    else if(instrs[backlog[e].instruction].flags & I_HASARG)    {    fprintf(stderr,"(%ld)", (long)backlog[e].arg);    }    fprintf(stderr," %ld, %ld\n", (long)backlog[e].stack,    (long)backlog[e].mark_stack); - #endif /* HAVE_COMPUTED_GOTO */ +     free_string(file);    }    }while(e!=backlogp);   }      #else /* PIKE_DEBUG */      #define DEBUG_LOG_ARG(arg) 0   #define DEBUG_LOG_ARG2(arg2) 0      #endif /* !PIKE_DEBUG */    -  + #ifdef OPCODE_INLINE_CATCH   #define POP_CATCH_CONTEXT do { \    struct catch_context *cc = Pike_interpreter.catch_ctx; \    DO_IF_DEBUG ( \    TRACE((3,"- Popping catch context %p ==> %p\n", \    cc, cc ? cc->prev : NULL)); \ -  +  if (!cc) \ +  Pike_fatal ("Catch context dropoff.\n"); \ +  if (cc->frame != Pike_fp) \ +  Pike_fatal ("Catch context doesn't belong to this frame.\n"); \ +  if (Pike_mark_sp != cc->recovery.mark_sp + Pike_interpreter.mark_stack) \ +  Pike_fatal ("Mark sp diff in catch context pop.\n"); \ +  ); \ +  debug_malloc_touch (cc); \ +  UNSETJMP (cc->recovery); \ +  Pike_interpreter.catch_ctx = cc->prev; \ +  really_free_catch_context (cc); \ +  } while (0) + #else + #define POP_CATCH_CONTEXT do { \ +  struct catch_context *cc = Pike_interpreter.catch_ctx; \ +  DO_IF_DEBUG ( \ +  TRACE((3,"- Popping catch context %p ==> %p\n", \ +  cc, cc ? cc->prev : NULL)); \    if (!Pike_interpreter.catching_eval_jmpbuf) \    Pike_fatal ("Not in catching eval.\n"); \    if (!cc) \    Pike_fatal ("Catch context dropoff.\n"); \    if (cc->frame != Pike_fp) \    Pike_fatal ("Catch context doesn't belong to this frame.\n"); \    if (Pike_mark_sp != cc->recovery.mark_sp + Pike_interpreter.mark_stack) \    Pike_fatal ("Mark sp diff in catch context pop.\n"); \    ); \    debug_malloc_touch (cc); \    UNSETJMP (cc->recovery); \ -  frame_set_expendible(Pike_fp, cc->save_expendible); \ +     Pike_interpreter.catch_ctx = cc->prev; \    really_free_catch_context (cc); \    } while (0) -  + #endif      static struct catch_context *free_catch_context;   static int num_catch_ctx, num_free_catch_ctx;      PMOD_EXPORT void really_free_catch_context( struct catch_context *data )   {    if( num_free_catch_ctx > 100 && free_catch_context )    {    num_catch_ctx--;    free( data );
pike.git/src/interpret.c:1121:    {    num_free_catch_ctx--;    res = free_catch_context;    PIKE_MEM_RW(res->prev);    free_catch_context = res->prev;    PIKE_MEM_WO(*res);    }    else    {    num_catch_ctx++; -  res = xalloc( sizeof( struct catch_context ) ); +  res = ALLOC_STRUCT( catch_context );    }    return res;   }      void count_memory_in_catch_contexts(size_t *num, size_t *size )   {    *num = (num_catch_ctx-num_free_catch_ctx);    *size = num_catch_ctx * (sizeof(struct catch_context)+8); /* assumes 8 bytes overhead. */   }   
pike.git/src/interpret.c:1208: Inside #if defined(PIKE_USE_MACHINE_CODE) and #if defined(OPCODE_INLINE_RETURN)
   }   #endif    {    struct catch_context *new_catch_ctx = alloc_catch_context();   #ifdef PIKE_DEBUG    new_catch_ctx->frame = Pike_fp;    init_recovery (&new_catch_ctx->recovery, 0, 0, PERR_LOCATION());   #else    init_recovery (&new_catch_ctx->recovery, 0);   #endif -  new_catch_ctx->save_expendible = frame_get_expendible(Pike_fp); +     new_catch_ctx->continue_reladdr = (INT32)get_unaligned32(addr)    /* We need to run the entry prologue... */    - ENTRY_PROLOGUE_SIZE;       new_catch_ctx->next_addr = addr;    new_catch_ctx->prev = Pike_interpreter.catch_ctx;    Pike_interpreter.catch_ctx = new_catch_ctx;    DO_IF_DEBUG({    TRACE((3,"- Pushed catch context %p\n", new_catch_ctx));    });    }    -  Pike_fp->expendible_offset = Pike_fp->num_locals; -  +     /* Need to adjust next_addr by sizeof(INT32) to skip past the jump    * address to the continue position after the catch block. */    addr = (PIKE_OPCODE_T *) ((INT32 *) addr + 1);       if (Pike_interpreter.catching_eval_jmpbuf) {    /* There's already a catching_eval_instruction around our    * eval_instruction, so we can just continue. */    debug_malloc_touch_named (Pike_interpreter.catch_ctx, "(1)");    /* Skip past the entry prologue... */    addr += ENTRY_PROLOGUE_SIZE;
pike.git/src/interpret.c:1285: Inside #if defined(PIKE_USE_MACHINE_CODE)
      DO_IF_DEBUG ({    TRACE((3,"- Caught exception. catch context: %p\n", cc));    if (!cc) Pike_fatal ("Catch context dropoff.\n");    if (cc->frame != Pike_fp)    Pike_fatal ("Catch context doesn't belong to this frame.\n");    });       debug_malloc_touch_named (cc, "(3)");    UNSETJMP (cc->recovery); -  frame_set_expendible(Pike_fp, cc->save_expendible); +     move_svalue (Pike_sp++, &throw_value);    mark_free_svalue (&throw_value);    low_destruct_objects_to_destruct();       if (cc->continue_reladdr < 0)    FAST_CHECK_THREADS_ON_BRANCH();    addr = cc->next_addr + cc->continue_reladdr;       DO_IF_DEBUG({    TRACE((3,"- Popping catch context %p ==> %p\n",
pike.git/src/interpret.c:1310: Inside #if defined(PIKE_USE_MACHINE_CODE)
   Pike_interpreter.catch_ctx = cc->prev;    really_free_catch_context (cc);    }    }       return (PIKE_OPCODE_T *)(ptrdiff_t)-1; /* INTER_RETURN; */    }   }      void *do_inter_return_label = (void*)(ptrdiff_t)-1; - #else + #else /* OPCODE_INLINE_RETURN */   /* Labels to jump to to cause eval_instruction to return */   /* FIXME: Replace these with assembler lables */   void *do_inter_return_label = NULL;   void *dummy_label = NULL; -  + #endif /* OPCODE_INLINE_RETURN */ +  + #ifdef OPCODE_INLINE_CATCH + /* Helper function for F_CATCH machine code. +  For a description of the addr argument, see inter_return_opcode_F_CATCH. +  Returns the jump destination (for the catch body). */ + PIKE_OPCODE_T *setup_catch_context(PIKE_OPCODE_T *addr) + { + #ifdef PIKE_DEBUG +  if (d_flag || Pike_interpreter.trace_level > 2) { +  low_debug_instr_prologue (F_CATCH - F_OFFSET); +  if (Pike_interpreter.trace_level>3) { +  sprintf(trace_buffer, "- Addr = %p\n", addr); +  write_to_stderr(trace_buffer,strlen(trace_buffer)); +  } +  }   #endif -  +  { +  struct catch_context *new_catch_ctx = alloc_catch_context(); + #ifdef PIKE_DEBUG +  new_catch_ctx->frame = Pike_fp; +  init_recovery (&new_catch_ctx->recovery, 0, 0, PERR_LOCATION()); + #else +  init_recovery (&new_catch_ctx->recovery, 0); + #endif    -  +  /* Note: no prologue. */ +  new_catch_ctx->continue_reladdr = (INT32)get_unaligned32(addr); +  +  new_catch_ctx->next_addr = addr; +  new_catch_ctx->prev = Pike_interpreter.catch_ctx; +  Pike_interpreter.catch_ctx = new_catch_ctx; +  DO_IF_DEBUG({ +  TRACE((3,"- Pushed catch context %p\n", new_catch_ctx)); +  }); +  } +  +  /* Need to adjust next_addr by sizeof(INT32) to skip past the jump +  * address to the continue position after the catch block. */ +  return (PIKE_OPCODE_T *) ((INT32 *) addr + 1) + ENTRY_PROLOGUE_SIZE; + } +  + /* Helper function for F_CATCH machine code. Called when an exception +  is caught. Pops the catch context and returns the continue jump +  destination. */ + PIKE_OPCODE_T *handle_caught_exception(void) + { +  /* Caught an exception. */ +  struct catch_context *cc = Pike_interpreter.catch_ctx; +  PIKE_OPCODE_T *addr; +  +  DO_IF_DEBUG ({ +  TRACE((3,"- Caught exception. catch context: %p\n", cc)); +  if (!cc) Pike_fatal ("Catch context dropoff.\n"); +  if (cc->frame != Pike_fp) +  Pike_fatal ("Catch context doesn't belong to this frame.\n"); +  }); +  +  debug_malloc_touch_named (cc, "(3)"); +  UNSETJMP (cc->recovery); +  move_svalue (Pike_sp++, &throw_value); +  mark_free_svalue (&throw_value); +  low_destruct_objects_to_destruct(); +  +  if (cc->continue_reladdr < 0) +  FAST_CHECK_THREADS_ON_BRANCH(); +  addr = cc->next_addr + cc->continue_reladdr; +  +  DO_IF_DEBUG({ +  TRACE((3,"- Popping catch context %p ==> %p\n", +  cc, cc->prev)); +  if (!addr) Pike_fatal ("Unexpected null continue addr.\n"); +  }); +  +  Pike_interpreter.catch_ctx = cc->prev; +  really_free_catch_context (cc); +  +  return addr; + } +  + #endif /* OPCODE_INLINE_CATCH */ +    #ifndef CALL_MACHINE_CODE   #define CALL_MACHINE_CODE(pc) \    do { \    /* The test is needed to get the labels to work... */ \    if (pc) { \    /* No extra setup needed! \    */ \    return ((int (*)(void))(pc))(); \    } \    } while(0)
pike.git/src/interpret.c:1552:   #define OPCODE1_BRANCH(O,N,F,C) TEST_OPCODE1(O,N,F,C)   #define OPCODE2_BRANCH(O,N,F,C) TEST_OPCODE2(O,N,F,C)   #define OPCODE0_TAILBRANCH(O,N,F,C) TEST_OPCODE0(O,N,F,C)   #define OPCODE1_TAILBRANCH(O,N,F,C) TEST_OPCODE1(O,N,F,C)   #define OPCODE2_TAILBRANCH(O,N,F,C) TEST_OPCODE2(O,N,F,C)      #define OPCODE0_ALIAS(O,N,F,C)   #define OPCODE1_ALIAS(O,N,F,C)   #define OPCODE2_ALIAS(O,N,F,C)    - #undef HAVE_COMPUTED_GOTO -  +    #ifdef GLOBAL_DEF_PROG_COUNTER   GLOBAL_DEF_PROG_COUNTER;   #endif      #ifndef SET_PROG_COUNTER   #define SET_PROG_COUNTER(X) (PROG_COUNTER=(X))   #endif /* SET_PROG_COUNTER */      #undef DONE   #undef FETCH
pike.git/src/interpret.c:1575:      #define DONE return   #define FETCH   #define INTER_RETURN {SET_PROG_COUNTER(do_inter_return_label);JUMP_DONE;}      #if defined(PIKE_USE_MACHINE_CODE) && defined(_M_IX86)   /* Disable frame pointer optimization */   #pragma optimize("y", off)   #endif    - static void do_trace_efun_call(const struct svalue *s, INT32 args); - #ifdef PIKE_DEBUG - static void do_trace_efun_return(const struct svalue *s, int got_retval); - #endif -  + #define ADVERTISE_FALLTHROUGH   #include "interpret_functions_fixed.h" -  + #undef ADVERTISE_FALLTHROUGH      #if defined(PIKE_USE_MACHINE_CODE) && defined(_M_IX86)   /* Restore optimization */   #pragma optimize("", on)   #endif      #ifdef PIKE_SMALL_EVAL_INSTRUCTION   #undef SET_PROG_COUNTER   #undef PROG_COUNTER   #define PROG_COUNTER pc
pike.git/src/interpret.c:1705:    return -1;   }      #else /* PIKE_USE_MACHINE_CODE */         #ifndef SET_PROG_COUNTER   #define SET_PROG_COUNTER(X) (PROG_COUNTER=(X))   #endif /* SET_PROG_COUNTER */    - #ifdef HAVE_COMPUTED_GOTO - int lookup_sort_fun(const void *a, const void *b) - { -  return (int)(((ptrdiff_t)((struct op_2_f *)a)->opcode) - -  ((ptrdiff_t)((struct op_2_f *)b)->opcode)); - } - #endif /* HAVE_COMPUTED_GOTO */ +     - /* NOTE: Due to the implementation of computed goto, -  * interpreter.h may only be included once. -  */ - #if defined(PIKE_DEBUG) && !defined(HAVE_COMPUTED_GOTO) + #if defined(PIKE_DEBUG)   #define eval_instruction eval_instruction_with_debug - #include "interpreter_debug.h" -  + #include "interpreter.h"   #undef eval_instruction   #define eval_instruction eval_instruction_without_debug      #undef PIKE_DEBUG   #undef NDEBUG   #undef DO_IF_DEBUG   #define DO_IF_DEBUG(X)   #define print_return_value()   #include "interpreter.h"   
pike.git/src/interpret.c:1747:      static inline int eval_instruction(unsigned char *pc)   {    if(d_flag || Pike_interpreter.trace_level>2)    return eval_instruction_with_debug(pc);    else    return eval_instruction_without_debug(pc);   }       - #else /* !PIKE_DEBUG || HAVE_COMPUTED_GOTO */ + #else /* !PIKE_DEBUG */   #include "interpreter.h"   #endif         #endif /* PIKE_USE_MACHINE_CODE */      #undef REAL_PIKE_DEBUG   #undef DO_IF_REAL_DEBUG   #undef DO_IF_NOT_REAL_DEBUG   
pike.git/src/interpret.c:1779:    buffer_add_str(b, "(");    for(e=0;e<args;e++)    {    if(e) buffer_add_str(b, ",");    safe_describe_svalue(b, Pike_sp-args+e,0,0);    }    buffer_add_str(b, ")");       if(buffer_content_length(b) > TRACE_LEN)    { -  buffer_remove(b, buffer_content_length(b) - TRACE_LEN - 3); +  buffer_remove(b, buffer_content_length(b) - TRACE_LEN);    buffer_add_str(b, "...");    }       if(Pike_fp && Pike_fp->pc)    {    char *f;    filep = get_line(Pike_fp->pc,Pike_fp->context->prog,&linep);    if (filep->size_shift)    file = "...";    else {
pike.git/src/interpret.c:1910:       if (got_retval) {    buffer_add_str (b, "returns: ");    safe_describe_svalue(b, Pike_sp-1,0,0);    }    else    buffer_add_str (b, "returns with no value");       if(buffer_content_length(b) > TRACE_LEN)    { -  buffer_remove(b, buffer_content_length(b) - TRACE_LEN - 3); +  buffer_remove(b, buffer_content_length(b) - TRACE_LEN);    buffer_add_str(b, "...");    }       s = buffer_get_string(b);       if(Pike_fp && Pike_fp->pc)    {    char *f;    filep = get_line(Pike_fp->pc,Pike_fp->context->prog,&linep);    if (filep->size_shift)
pike.git/src/interpret.c:1963:   PMOD_EXPORT void really_free_pike_frame( struct pike_frame *X )   {    free_object(X->current_object);    if(X->current_program)    free_program(X->current_program);    if(X->scope)    free_pike_scope(X->scope);    DO_IF_DEBUG(    if(X->flags & PIKE_FRAME_MALLOCED_LOCALS)    Pike_fatal("Pike frame is not supposed to have malloced locals here!\n")); +  if (X->flags & PIKE_FRAME_SAVE_LOCALS) { +  free(X->save_locals_bitmask); +  X->flags &= ~PIKE_FRAME_SAVE_LOCALS; +  }    DO_IF_DMALLOC(    X->current_program=0;    X->context=0;    X->scope=0;    X->current_object=0;    X->flags=0; -  X->expendible_offset=0; +     X->locals=0;    );    X->next = free_pike_frame;    PIKE_MEMPOOL_FREE(&free_pike_frame, X, sizeof(struct pike_frame));    free_pike_frame = X;   }      struct pike_frame *alloc_pike_frame(void)   {    struct pike_frame *res;    if( free_pike_frame )    {    res = free_pike_frame;    PIKE_MEMPOOL_ALLOC(&free_pike_frame, res, sizeof(struct pike_frame));    PIKE_MEM_RW_RANGE(&res->next, sizeof(void*));    free_pike_frame = res->next;    PIKE_MEM_WO_RANGE(&res->next, sizeof(void*)); -  +  gc_init_marker(res);    res->refs=0;    add_ref(res); /* For DMALLOC... */    res->flags=0;    res->next=0;    res->scope=0; -  +  res->pc = NULL; +     return res;    }       /* Need to allocate more. */    {    unsigned int i;   #define FRAMES_PER_CHUNK ((4096*4-8-sizeof(struct pike_frame_chunk))/sizeof(struct pike_frame))   #define FRAME_CHUNK_SIZE (FRAMES_PER_CHUNK*sizeof(struct pike_frame))+sizeof(struct pike_frame_chunk)       void *p = xalloc( FRAME_CHUNK_SIZE );
pike.git/src/interpret.c:2017:    {    res->next = &free_pike_frame[i];    res = res->next;    }    res->next = NULL;    num_pike_frames+=FRAMES_PER_CHUNK;    }    return alloc_pike_frame();   }    + void LOW_POP_PIKE_FRAME_slow_path(struct pike_frame *frame) + { +  debug_malloc_touch(frame); +  +  if (frame->flags & PIKE_FRAME_SAVE_LOCALS) { +  int num_new_locals = 0; +  int num_locals = frame->num_locals; +  int i; +  +  /* find the highest set bit */ +  for (i = num_locals - 1; i >= 0; i--) { +  unsigned INT16 bitmask = frame->save_locals_bitmask[i / 16]; +  +  if (bitmask & (1 << (i % 16))) { +  num_new_locals = i + 1; +  break; +  } +  } +  +  if (num_new_locals) +  { +  struct svalue *s = xcalloc(sizeof(struct svalue), num_new_locals); +  struct svalue *locals = frame->locals; +  unsigned INT16 bitmask = 0; +  +  for (i = 0; i < num_new_locals; i++) { +  unsigned INT16 bitmask = frame->save_locals_bitmask[i / 16]; +  +  if (bitmask & (1 << (i % 16))) { +  assign_svalue_no_free(s + i, locals + i); +  } + #ifdef PIKE_DEBUG +  else +  mark_free_svalue(s + i); + #endif +  } +  +  frame->locals = s; +  frame->flags |= PIKE_FRAME_MALLOCED_LOCALS; +  } else { +  frame->locals = NULL; +  } +  +  frame->flags &= ~PIKE_FRAME_SAVE_LOCALS; +  +  free(frame->save_locals_bitmask); +  +  frame->num_locals = num_new_locals; +  } else { +  frame->locals = NULL; +  } +  +  frame->next=0; + } +    void count_memory_in_pike_frames(size_t *num, size_t *size )   {    *num = num_pike_frames;    *size = num_pike_frame_chunks * (FRAME_CHUNK_SIZE*8);   }   #undef FRAMES_PER_CHUNK   #undef FRAME_CHUNK_SIZE      #ifdef DO_PIKE_CLEANUP   static void free_all_pike_frame_blocks(void)
pike.git/src/interpret.c:2079:       int type = (function->identifier_flags & (IDENTIFIER_TYPE_MASK|IDENTIFIER_ALIAS));    if( o->prog != pike_trampoline_program && function->func.offset != -1 )    {    switch( type )    {    case IDENTIFIER_CONSTANT:    constant = &context->prog->constants[function->func.const_info.offset].sval;    if( TYPEOF(*constant) != PIKE_T_PROGRAM )    break; +  /* FALLTHRU */    case IDENTIFIER_C_FUNCTION:    case IDENTIFIER_PIKE_FUNCTION:    if( !new_frame )    {    new_frame=alloc_pike_frame();    debug_malloc_touch(new_frame);    }   #ifdef PROFILING    new_frame->children_base = Pike_interpreter.accounted_time;    new_frame->start_time = get_cpu_time() - Pike_interpreter.unlocked_time;
pike.git/src/interpret.c:2112:    new_frame->children_base);   #endif    new_frame->next = Pike_fp;    add_ref(new_frame->current_object = o);    add_ref(new_frame->current_program = p);    new_frame->context = context;    new_frame->fun = (unsigned INT16)fun;    new_frame->locals = save_sp;    new_frame->args = args;    new_frame->save_sp_offset = 0; -  new_frame->expendible_offset = 0; +       #ifdef PIKE_DEBUG    if (Pike_in_gc > GC_PASS_PREPARE && Pike_in_gc < GC_PASS_FREE)    Pike_fatal("Pike code called within gc.\n");   #endif       Pike_fp = new_frame;    debug_malloc_touch(Pike_fp);   #ifdef PROFILING    function->num_calls++;
pike.git/src/interpret.c:2256:   #endif       switch(type)    {    case APPLY_STACK:    if(!args)    PIKE_ERROR("`()", "Too few arguments (apply stack).\n", Pike_sp, 0);    args--;    arg1=(void *)(Pike_sp-args-1);    -  /* FALL_THROUGH */ +  /* FALLTHRU */       case APPLY_SVALUE:    case APPLY_SVALUE_STRICT:    apply_svalue:    {    struct svalue *s=(struct svalue *)arg1;    switch(TYPEOF(*s))    {    case T_INT:    if (!s->u.integer) {
pike.git/src/interpret.c:2608: Inside #if defined(PIKE_DEBUG)
   /* FIXME: Wouldn't a simple return be ok? */    if(rec->frame_pointer == current->next)    Pike_fatal("You can't touch this!\n");    }    }   #endif    /* Save various fields from the previous frame.    */    frame_set_save_sp(current, frame_get_save_sp(prev));    current->save_mark_sp=prev->save_mark_sp; -  current->flags = prev->flags; +  current->flags = prev->flags & PIKE_FRAME_RETURN_MASK;       /* Unlink the top frame temporarily. */    Pike_interpreter.frame_pointer=prev;      #ifdef PROFILING    {    /* We must update the profiling info of the previous frame    * to account for that the current frame has gone away.    */    cpu_time_t total_time =
pike.git/src/interpret.c:2804:    struct byte_buffer buf = BUFFER_INIT();    fprintf (stderr, "There's no master to handle the error. Dumping it raw:\n");    safe_describe_svalue (&buf, Pike_sp - 1, 0, 0);    fprintf(stderr,"%s\n",buffer_get_string(&buf));    buffer_free(&buf);    if (TYPEOF(Pike_sp[-1]) == PIKE_T_OBJECT && Pike_sp[-1].u.object->prog) {    int fun = find_identifier("backtrace", Pike_sp[-1].u.object->prog);    if (fun != -1) {    fprintf(stderr, "Attempting to extract the backtrace.\n");    safe_apply_low2(Pike_sp[-1].u.object, fun, 0, 0); -  buf = BUFFER_INIT(); +     safe_describe_svalue(&buf, Pike_sp - 1, 0, 0);    pop_stack();    fprintf(stderr,"%s\n",buffer_get_string(&buf));    buffer_free(&buf);    }    }    }       pop_stack();    Pike_interpreter.svalue_stack_margin = SVALUE_STACK_MARGIN;
pike.git/src/interpret.c:2876:    fun = prog->num_identifier_references;    add_to_identifier_references(dummy_ref);    }       /* FIXME: Is this up-to-date with mega_apply? */    new_frame->next = Pike_fp;    add_ref(new_frame->current_object = o);    add_ref(new_frame->current_program = prog);    new_frame->context = prog->inherits;    new_frame->locals = Pike_sp; -  new_frame->expendible_offset=0; +     new_frame->args = 0;    new_frame->num_args=0;    new_frame->num_locals=0;    new_frame->fun = fun;    new_frame->pc = 0;    new_frame->current_storage=o->storage;      #ifdef PIKE_DEBUG    if (Pike_fp && (new_frame->locals < Pike_fp->locals)) {    Pike_fatal("New locals below old locals: %p < %p\n",
pike.git/src/interpret.c:3033:    safe_apply_low2(master_obj, i, args, fun);    else {    pop_n_elems(args);    push_undefined();    }    }   }      PMOD_EXPORT void push_text( const char *x )   { +  struct pike_string *s = make_shared_string(x);    struct svalue *_sp_ = Pike_sp++;    SET_SVAL_SUBTYPE(*_sp_, 0); -  _sp_->u.string=make_shared_string(x); +  _sp_->u.string=s;    debug_malloc_touch(_sp_->u.string);    SET_SVAL_TYPE(*_sp_, PIKE_T_STRING);   }      PMOD_EXPORT void push_static_text( const char *x )   { -  +  struct pike_string *s = make_shared_static_string(x, strlen(x), eightbit);    struct svalue *_sp_ = Pike_sp++;    SET_SVAL_SUBTYPE(*_sp_, 0); -  _sp_->u.string=make_shared_static_string(x, strlen(x), eightbit); +  _sp_->u.string=s;    debug_malloc_touch(_sp_->u.string);    SET_SVAL_TYPE(*_sp_, PIKE_T_STRING);   }      /* NOTE: Returns 1 if result on stack, 0 otherwise. */   PMOD_EXPORT int safe_apply_handler(const char *fun,    struct object *handler,    struct object *compat,    INT32 args,    TYPE_FIELD rettypes)
pike.git/src/interpret.c:3188:       find_external_context(&loc, depth);       apply_low(loc.o, fun + loc.inherit->identifier_level, args);    } else {    PIKE_ERROR("destructed object", "Apply on parent of destructed object.\n",    Pike_sp, args);    }   }    + /* mode=1 : Exception on lookup and on execution +  * mode=2 : Exception on lookup but not execution +  * mode=3 : No exceptions +  */ + PMOD_EXPORT void apply_master(const char* fun, INT32 args, int mode) + { +  static int id_=-1; +  struct object *master_ob=master(); +  if(master_ob->prog->id != 0) +  id_=find_identifier(fun, master_ob->prog); +  +  if (id_ >= 0) { +  if( mode==1 ) +  apply_low(master_ob, id_, args); +  else +  safe_apply_low2(master_ob, id_, args, fun); +  } else { +  if( mode==3 ) +  { +  pop_n_elems(args); +  push_undefined(); +  } +  else +  Pike_error("Cannot call undefined function \"%s\" in master.\n", fun); +  } + } +    #ifdef PIKE_DEBUG   void slow_check_stack(void)   {    struct svalue *s,**m;    struct pike_frame *f;       debug_check_stack();       if(Pike_sp > &(Pike_interpreter.evaluator_stack[Pike_stack_size]))    Pike_fatal("Svalue stack overflow. "
pike.git/src/interpret.c:3335:       if(!f->locals)    {    args=0;    }else{    ptrdiff_t tmp;       if(of) {    tmp = of->locals - f->locals;    } else { + #ifdef PIKE_THREADS    tmp = ts->state.stack_pointer - f->locals; -  + #else +  tmp = f->num_args; /* FIXME */ + #endif    }    args = (INT32)tmp;    args = MAXIMUM(MINIMUM(args, f->num_args),0);    }       for (i = 0; i < args; i++) {    struct svalue *arg = f->locals + i;       switch (TYPEOF(*arg)) {    case T_INT: