pike.git / src / interpret.c

version» Context lines:

pike.git/src/interpret.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$ +    */      #include "global.h"   #include "interpret.h"   #include "object.h"   #include "program.h"   #include "svalue.h"   #include "array.h"   #include "mapping.h"   #include "pike_error.h"
pike.git/src/interpret.c:21:   #include "operators.h"   #include "opcodes.h"   #include "pike_embed.h"   #include "lex.h"   #include "builtin_functions.h"   #include "signal_handler.h"   #include "gc.h"   #include "threads.h"   #include "callback.h"   #include "fd_control.h" - #include "pike_security.h" +    #include "bignum.h"   #include "pike_types.h"   #include "pikecode.h"    - #include "block_alloc.h" -  +    #include <fcntl.h>   #include <errno.h>   #include <ctype.h>      #ifdef HAVE_MMAP - #ifdef HAVE_SYS_TYPES_H - #include <sys/types.h> - #endif +       #ifdef HAVE_SYS_MMAN_H   #include <sys/mman.h>   #endif      #ifdef MAP_NORESERVE   #define USE_MMAP_FOR_STACK   #endif   #endif   
pike.git/src/interpret.c:103:   static char trace_buffer[2000];   #endif      #ifdef INTERNAL_PROFILING   PMOD_EXPORT unsigned long evaluator_callback_calls = 0;   #endif         int fast_check_threads_counter = 0;    - /* This is used for strapping the interpreter before the threads -  * are loaded, and when there's no support for threads. -  */ - static struct Pike_interpreter_struct static_pike_interpreter; -  - /* Pike_sp points to first unused value on stack -  * (much simpler than letting it point at the last used value.) -  */ - PMOD_EXPORT struct Pike_interpreter_struct *Pike_interpreter_pointer = -  &static_pike_interpreter; +    PMOD_EXPORT int Pike_stack_size = EVALUATOR_STACK_SIZE;      static void do_trace_call(INT32 args, dynamic_buffer *old_buf);   static void do_trace_func_return (int got_retval, struct object *o, int fun);   static void do_trace_return (int got_retval, dynamic_buffer *old_buf);    -  +    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    if(Pike_mark_sp < Pike_interpreter.mark_stack)
pike.git/src/interpret.c:164: Inside #if defined(PIKE_DEBUG)
   gc_mark_external_svalues (f->locals, stack_p - f->locals, " on svalue stack");    stack_p = f->locals;    }    }    }    } GC_LEAVE;    if (stack != stack_p)    gc_mark_external_svalues (stack, stack_p - stack, " on svalue stack");   }    - static void gc_check_stack_callback(struct callback *foo, void *bar, void *gazonk) + static void gc_check_stack_callback(struct callback *UNUSED(foo), void *UNUSED(bar), void *UNUSED(gazonk))   {    if (Pike_interpreter.evaluator_stack   #ifdef PIKE_DEBUG    /* Avoid this if the thread is swapped out. Useful when calling    * locate_references from gdb. */    && Pike_sp != (void *) -1   #endif    )    gc_mark_stack_external (Pike_fp, Pike_sp, Pike_interpreter.evaluator_stack);   }
pike.git/src/interpret.c:285:    interpreter->catching_eval_jmpbuf = NULL;       interpreter->svalue_stack_margin = SVALUE_STACK_MARGIN;    interpreter->c_stack_margin = C_STACK_MARGIN;      #ifdef PROFILING    interpreter->unlocked_time = 0;    interpreter->accounted_time = 0;   #endif    +  interpreter->trace_level = default_t_flag; +     return 0; /* OK. */   }    -  + static struct pike_frame *free_pike_frame; +    PMOD_EXPORT void init_interpreter(void)   { -  + #ifdef USE_VALGRIND +  { +  static int create_mempool = 1; +  +  if (create_mempool) { +  PIKE_MEMPOOL_CREATE(&free_pike_frame); +  create_mempool = 0; +  } +  } + #endif    if (low_init_interpreter(Pike_interpreter_pointer)) {    Pike_fatal("Out of memory initializing the interpreter stack.\n");    }      #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)    {    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);
pike.git/src/interpret.c:349:    * 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)    * lvalue array: { T_ARRAY_LVALUE, array with lvalue pairs }    */    - void lvalue_to_svalue_no_free(struct svalue *to,struct svalue *lval) + int lvalue_to_svalue_no_free(struct svalue *to, struct svalue *lval)   { - #ifdef PIKE_SECURITY -  if(TYPEOF(*lval) <= MAX_COMPLEX) -  if(!CHECK_DATA_SECURITY(lval->u.array, SECURITY_BIT_INDEX)) -  Pike_error("Index permission denied.\n"); - #endif -  switch(TYPEOF(*lval)) +  int run_time_type; +  switch(run_time_type = TYPEOF(*lval))    {    case T_ARRAY_LVALUE:    {    INT32 e;    struct array *a;    TYPE_FIELD types = 0;    ONERROR err;    a=allocate_array(lval[1].u.array->size>>1);    SET_ONERROR(err, do_free_array, a);    for(e=0;e<a->size;e++) {
pike.git/src/interpret.c:382:    UNSET_ONERROR(err);    break;    }       case T_SVALUE_PTR:    dmalloc_touch_svalue(lval->u.lval);    assign_svalue_no_free(to, lval->u.lval);    break;       case T_OBJECT: -  /* FIXME: Object subtypes! */ +  /* FIXME: Index subtypes! */    if (TYPEOF(lval[1]) == T_OBJ_INDEX) -  low_object_index_no_free (to, lval->u.object, lval[1].u.identifier); +  run_time_type = low_object_index_no_free(to, lval->u.object, +  lval[1].u.identifier);    else -  object_index_no_free(to, lval->u.object, SUBTYPEOF(*lval), lval+1); +  run_time_type = object_index_no_free(to, lval->u.object, +  SUBTYPEOF(*lval), lval+1);    break;       case T_ARRAY:    simple_array_index_no_free(to, lval->u.array, lval+1);    break;       case T_MAPPING:    mapping_index_no_free(to, lval->u.mapping, lval+1);    break;   
pike.git/src/interpret.c:412:    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");    else    index_error(0,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)   { - #ifdef PIKE_SECURITY -  if(TYPEOF(*lval) <= MAX_COMPLEX) -  if(!CHECK_DATA_SECURITY(lval->u.array, SECURITY_BIT_SET_INDEX)) -  Pike_error("Assign index permission denied.\n"); - #endif -  +     switch(TYPEOF(*lval))    {    case T_ARRAY_LVALUE:    {    INT32 e;    if(TYPEOF(*from) != T_ARRAY)    Pike_error("Trying to assign combined lvalue from non-array.\n");       if(from->u.array->size < (lval[1].u.array->size>>1))    Pike_error("Not enough values for multiple assign.\n");
pike.git/src/interpret.c:486:   }      /* 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)   { - #ifdef PIKE_SECURITY -  if(TYPEOF(*lval) <= MAX_COMPLEX) -  if(!CHECK_DATA_SECURITY(lval->u.array, SECURITY_BIT_SET_INDEX)) -  Pike_error("Assign index permission denied.\n"); - #endif -  +     switch(TYPEOF(*lval))    {    case T_ARRAY_LVALUE:    return 0;       case T_SVALUE_PTR:    dmalloc_touch_svalue(lval->u.lval);    if(TYPEOF(*(lval->u.lval)) == t) return & ( lval->u.lval->u );    return 0;   
pike.git/src/interpret.c:558: Inside #if defined(PIKE_DEBUG)
   p->parent ? p->parent->id : -1);    for(e=0;e<p->num_identifier_references;e++)    {    in=INHERIT_FROM_INT(p,e);    while(last < in)    {    last++;    fprintf(stderr,    "[%ld]%*s parent{ offset=%d ident=%d id=%d } "    "id{ level=%d } prog=%d\n", -  DO_NOT_WARN((long)(last - p->inherits)), +  (long)(last - p->inherits),    last->inherit_level*2,"",    last->parent_offset,    last->parent_identifier,    last->prog->parent ? last->prog->parent->id : -1,    last->identifier_level,    last->prog->id);    i=0;    }       fprintf(stderr," %*s %d,%d: %s\n",
pike.git/src/interpret.c:607:    * struct object *o // object containing the scope.    * struct inherit *inherit // inherit in o->prog being the scope.    * int parent_identifier // identifier in o from the inherit.    */   PMOD_EXPORT void find_external_context(struct external_variable_context *loc,    int depth)   {    struct program *p;       TRACE((4, "-find_external_context(%d, inherit=%ld)\n", depth, -  DO_NOT_WARN((long)(loc->o->prog ? loc->inherit - loc->o->prog->inherits : 0)))); +  (long)(loc->o->prog ? loc->inherit - loc->o->prog->inherits : 0)));      #ifdef PIKE_DEBUG    if(!loc->o)    Pike_fatal("No object\n");   #endif       if (!(p = loc->o->prog)) {    /* magic fallback */    p = get_program_for_object_being_destructed(loc->o);    if(!p)
pike.git/src/interpret.c:782:    }    else    /* Return a valid pointer to a dummy inherit for the convenience    * of the caller. Identifier offsets will be bogus but it'll    * never get to that since the object is destructed. */    loc->inherit = &dummy_inherit;       TRACE((5,"- Parent identifier = %d (%s), inherit # = %ld\n",    loc->parent_identifier,    p ? ID_FROM_INT(p, loc->parent_identifier)->name->str : "N/A", -  p ? DO_NOT_WARN((long)(loc->inherit - p->inherits)) : -1)); +  p ? (long)(loc->inherit - p->inherits) : -1));      #ifdef DEBUG_MALLOC    if (p && loc->inherit->storage_offset == 0x55555555) {    fprintf(stderr, "The inherit %p has been zapped!\n", loc->inherit);    debug_malloc_dump_references(loc->inherit,0,2,0);    fprintf(stderr, "It was extracted from the program %p %d\n", p, loc->parent_identifier);    describe(p);    fprintf(stderr, "Which was in turn taken from the object %p\n", loc->o);    describe(loc->o);    Pike_fatal("Looks like the program %p has been zapped!\n", p);
pike.git/src/interpret.c:873:      struct backlog backlog[BACKLOG];   int backlogp=BACKLOG-1;      static INLINE void low_debug_instr_prologue (PIKE_INSTR_T instr)   {    if(Pike_interpreter.trace_level > 2)    {    char *file = NULL, *f;    struct pike_string *filep; -  INT32 linep; +  INT_TYPE linep;       filep = get_line(Pike_fp->pc,Pike_fp->context->prog,&linep);    if (filep && !filep->size_shift) {    file = filep->str; -  while((f=STRCHR(file,'/'))) +  while((f=strchr(file,'/')))    file=f+1;    }    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);
pike.git/src/interpret.c:901: Inside #if defined(HAVE_COMPUTED_GOTO)
  #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) +  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;    backlog[backlogp].mark_stack = Pike_mark_sp - Pike_interpreter.mark_stack;   #ifdef _REENTRANT    backlog[backlogp].thread_state=Pike_interpreter.thread_state;   #endif      #ifdef _REENTRANT    CHECK_INTERPRETER_LOCK();    if(d_flag>1) DEBUG_CHECK_THREAD();   #endif    -  SET_SVAL_TYPE(Pike_sp[0], 99); /* an invalid type */ -  SET_SVAL_TYPE(Pike_sp[1], 99); -  SET_SVAL_TYPE(Pike_sp[2], 99); -  SET_SVAL_TYPE(Pike_sp[3], 99); +  INVALIDATE_SVAL(Pike_sp[0]); +  INVALIDATE_SVAL(Pike_sp[1]); +  INVALIDATE_SVAL(Pike_sp[2]); +  INVALIDATE_SVAL(Pike_sp[3]);       if(Pike_sp<Pike_interpreter.evaluator_stack ||    Pike_mark_sp < Pike_interpreter.mark_stack || Pike_fp->locals>Pike_sp)    Pike_fatal("Stack error (generic) sp=%p/%p mark_sp=%p/%p locals=%p.\n",    Pike_sp,    Pike_interpreter.evaluator_stack,    Pike_mark_sp,    Pike_interpreter.mark_stack,    Pike_fp->locals);       if(Pike_mark_sp > Pike_interpreter.mark_stack+Pike_stack_size)    Pike_fatal("Mark Stack error (overflow).\n");          if(Pike_mark_sp < Pike_interpreter.mark_stack)    Pike_fatal("Mark Stack error (underflow).\n");       if(Pike_sp > Pike_interpreter.evaluator_stack+Pike_stack_size)    Pike_fatal("stack error (overflow).\n");    -  if(/* Pike_fp->fun>=0 && */ Pike_fp->current_object->prog && -  Pike_fp->locals+Pike_fp->num_locals > Pike_sp) -  Pike_fatal("Stack error (stupid!).\n"); +     -  +  /* The locals will not be correct when running FILL_STACK +  (actually, they will always be incorrect before running FILL_STACK, +  but at least currently that is the first opcode run). +  */ +  +  /* as it turns out, this is no longer true.. */ +  /* if( instr+F_OFFSET != F_FILL_STACK ) */ +  /* { */ +  /* if(/\* Pike_fp->fun>=0 && *\/ Pike_fp->current_object->prog && */ +  /* Pike_fp->locals+Pike_fp->num_locals > Pike_sp) */ +  /* Pike_fatal("Stack error (stupid! %p %p+%x).\n",Pike_sp, */ +  /* Pike_fp->locals, Pike_fp->num_locals*sizeof(struct svalue)); */ +  /* } */ +     if(Pike_interpreter.recoveries &&    (Pike_sp-Pike_interpreter.evaluator_stack <    Pike_interpreter.recoveries->stack_pointer))    Pike_fatal("Stack error (underflow).\n");       if(Pike_mark_sp > Pike_interpreter.mark_stack &&    Pike_mark_sp[-1] > Pike_sp)    Pike_fatal("Stack error (underflow?)\n");       if(d_flag > 9) do_debug();
pike.git/src/interpret.c:993:    (long) backlog[backlogp].arg), \    write_to_stderr(trace_buffer,strlen(trace_buffer)) : 0))      #define DEBUG_LOG_ARG2(ARG2) \    (backlog[backlogp].arg2 = (ARG2), \    (Pike_interpreter.trace_level>3 ? \    sprintf(trace_buffer, "- Arg2 = %ld\n", \    (long) backlog[backlogp].arg2), \    write_to_stderr(trace_buffer,strlen(trace_buffer)) : 0))    - void dump_backlog(void) + PMOD_EXPORT void dump_backlog(void)   {   #ifdef _REENTRANT    struct thread_state *thread=0;   #endif       int e;    if(!d_flag || backlogp<0 || backlogp>=BACKLOG)    return;       e=backlogp;    do    {    struct program *p;    e++;    if(e>=BACKLOG) e=0;       p = id_to_program (backlog[e].program_id);    if (p)    {    struct pike_string *file; -  INT32 line; +  INT_TYPE line;      #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);
pike.git/src/interpret.c:1062:    (long)backlog[e].arg2);    }    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", -  DO_NOT_WARN((long)backlog[e].stack), -  DO_NOT_WARN((long)backlog[e].mark_stack)); +  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 */    - #undef BLOCK_ALLOC_NEXT - #define BLOCK_ALLOC_NEXT prev +     - BLOCK_ALLOC_FILL_PAGES (catch_context, 1) -  - #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"); \ + #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); \ -  Pike_fp->expendible = cc->save_expendible; \ -  Pike_interpreter.catch_ctx = cc->prev; \ -  really_free_catch_context (cc); \ +  Pike_fatal ("Mark sp diff in catch context pop.\n"); \ +  ); \ +  debug_malloc_touch (cc); \ +  UNSETJMP (cc->recovery); \ +  Pike_fp->expendible = cc->save_expendible; \ +  Pike_interpreter.catch_ctx = cc->prev; \ +  really_free_catch_context (cc); \    } while (0)    -  + 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 ); +  } +  else +  { +  data->prev = free_catch_context; +  +  num_free_catch_ctx++; +  PIKE_MEM_NA(*data); +  PIKE_MEM_RW(data->prev); +  free_catch_context = data; +  } + } +  + struct catch_context *alloc_catch_context(void) + { +  struct catch_context *res; +  if( free_catch_context ) +  { +  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 ) ); +  } +  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. */ + } +  + #ifdef DO_PIKE_CLEANUP + static void free_all_catch_context_blocks(void) + { +  struct catch_context *x = free_catch_context, *n; +  while( x ) +  { +  PIKE_MEM_RW(x->prev); +  n = x->prev; +  free( x ); +  x = n; +  } +  free_catch_context = NULL; + } + #endif +    static int catching_eval_instruction (PIKE_OPCODE_T *pc);         #ifdef PIKE_USE_MACHINE_CODE   #ifdef OPCODE_INLINE_RETURN   /* Catch notes:    *    * Typical F_CATCH use:    *    * F_CATCH
pike.git/src/interpret.c:1166: 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 = Pike_fp->expendible; -  new_catch_ctx->continue_reladdr = ((INT32 *)addr)[0] +  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.git/src/interpret.c:1293:    } while(0)   #endif /* !CALL_MACHINE_CODE */      #ifndef EXIT_MACHINE_CODE   #define EXIT_MACHINE_CODE()   #endif      /* Intended to be called from machine code before inlined function    * calls (primarily the CALL_BUILTIN opcodes), to ensure thread    * switching. */ - void call_check_threads_etc() + void call_check_threads_etc(void)   {    FAST_CHECK_THREADS_ON_CALL();   }      #if defined(OPCODE_INLINE_BRANCH) || defined(INS_F_JUMP) || \    defined(INS_F_JUMP_WITH_ARG) || defined(INS_F_JUMP_WITH_TWO_ARGS)   /* Intended to be called from machine code on backward branch jumps,    * to ensure thread switching. */ - void branch_check_threads_etc() + void branch_check_threads_etc(void)   {    FAST_CHECK_THREADS_ON_BRANCH();   }   #endif      #ifdef PIKE_DEBUG      static void debug_instr_prologue (PIKE_INSTR_T instr)   {    low_debug_instr_prologue (instr);
pike.git/src/interpret.c:1587: Inside #if defined(PIKE_USE_MACHINE_CODE)
  #endif /* DISASSEMBLE_CODE */    }    x = eval_instruction_low(pc);    pike_trace(3, "- eval_instruction(%p) ==> %d\n", pc, x);    return x;   }      static int eval_instruction_low(PIKE_OPCODE_T *pc)   #endif /* PIKE_DEBUG */   { -  if(pc == NULL) { -  +    #ifndef OPCODE_INLINE_RETURN -  +  if(pc == NULL) {    if(do_inter_return_label != NULL)    Pike_fatal("eval_instruction called with NULL (twice).\n");      #ifdef __GNUC__    do_inter_return_label = && inter_return_label;   #elif defined (_M_IX86)    /* MSVC. */    _asm    {    lea eax,inter_return_label
pike.git/src/interpret.c:1621: Inside #if 0
   */    if (do_inter_return_label == do_escape_catch_label) {    Pike_fatal("Inter return and escape catch labels are equal: %p\n",    do_inter_return_label);    }   #endif       /* Trick optimizer */    if(!dummy_label)    return 0; - #endif /* !OPCODE_INLINE_RETURN */ +     }       /* This else is important to avoid an overoptimization bug in (at    * least) gcc 4.0.2 20050808 which caused the address stored in    * do_inter_return_label to be at the CALL_MACHINE_CODE below. */    else { -  + #endif /* !OPCODE_INLINE_RETURN */    CALL_MACHINE_CODE(pc);    -  + #ifndef OPCODE_INLINE_RETURN    /* This code is never reached, but will    * prevent gcc from optimizing the labels below too much    */      #ifdef PIKE_DEBUG    fprintf(stderr,"We have reached the end of the world!\n");   #endif    }    - #ifndef OPCODE_INLINE_RETURN +    #ifdef __GNUC__    goto *dummy_label;   #endif    - #if 0 -  if (dummy_label) { -  inter_escape_catch_label: -  EXIT_MACHINE_CODE(); -  return -2; -  } - #endif -  - #endif /* !OPCODE_INLINE_RETURN */ +     inter_return_label: -  EXIT_MACHINE_CODE(); + #endif /*!OPCODE_INLINE_RETURUN */   #ifdef PIKE_DEBUG    pike_trace(3, "- Inter return\n");   #endif -  +  EXIT_MACHINE_CODE();    return -1;   }      #else /* PIKE_USE_MACHINE_CODE */         #ifndef SET_PROG_COUNTER   #define SET_PROG_COUNTER(X) (PROG_COUNTER=(X))   #endif /* SET_PROG_COUNTER */   
pike.git/src/interpret.c:1726:      #undef REAL_PIKE_DEBUG   #undef DO_IF_REAL_DEBUG   #undef DO_IF_NOT_REAL_DEBUG         static void do_trace_call(INT32 args, dynamic_buffer *old_buf)   {    struct pike_string *filep = NULL;    char *file, *s; -  INT32 linep,e; +  INT_TYPE linep; +  INT32 e;    ptrdiff_t len = 0;       my_strcat("(");    for(e=0;e<args;e++)    {    if(e) my_strcat(",");    safe_describe_svalue(Pike_sp-args+e,0,0);    }    my_strcat(")");   
pike.git/src/interpret.c:1754:    }       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 {    file = filep->str; -  while((f = STRCHR(file, '/')) +  while((f = strchr(file, '/'))   #ifdef __NT__ -  || (f = STRCHR(file, '\\')) +  || (f = strchr(file, '\\'))   #endif /* __NT__ */    )    file=f+1;    len = filep->len - (file - filep->str);    }    }else{    linep=0;    file="-";    }       if (len < 30)    {    char buf[40];    if (linep) -  SNPRINTF(buf, sizeof (buf), "%s:%ld:", file, (long)linep); +  snprintf(buf, sizeof (buf), "%s:%ld:", file, (long)linep);    else -  SNPRINTF(buf, sizeof (buf), "%s:", file); +  snprintf(buf, sizeof (buf), "%s:", file);    fprintf(stderr, "- %-20s %s\n",buf,s);    } else if (linep) {    fprintf(stderr, "- %s:%ld: %s\n", file, (long)linep, s);    } else {    fprintf(stderr, "- %s: %s\n", file, s);    }       if (filep) {    free_string(filep);    }
pike.git/src/interpret.c:1795:   }      static void do_trace_func_return (int got_retval, struct object *o, int fun)   {    dynamic_buffer save_buf;    init_buf (&save_buf);    if (o) {    if (o->prog) {    struct identifier *id = ID_FROM_INT (o->prog, fun);    char buf[50]; -  sprintf(buf, "%lx->", DO_NOT_WARN((long) PTR_TO_INT (o))); +  sprintf(buf, "%lx->", (long) PTR_TO_INT (o));    my_strcat(buf);    if (id->name->size_shift)    my_strcat ("[widestring function name]");    else    my_strcat(id->name->str);    my_strcat ("() ");    }    else    my_strcat ("function in destructed object ");    }    do_trace_return (got_retval, &save_buf);   }      static void do_trace_return (int got_retval, dynamic_buffer *old_buf)   {    struct pike_string *filep = NULL;    char *file, *s; -  INT32 linep; +  INT_TYPE linep;       if (got_retval) {    my_strcat ("returns: ");    safe_describe_svalue(Pike_sp-1,0,0);    }    else    my_strcat ("returns with no value");       s=simple_free_buf(old_buf);    if((size_t)strlen(s) > (size_t)TRACE_LEN)
pike.git/src/interpret.c:1839:    }       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 {    file = filep->str; -  while((f=STRCHR(file,'/'))) +  while((f=strchr(file,'/')))    file=f+1;    }    }else{    linep=0;    file="-";    }       {    char buf[40];    if (linep) -  SNPRINTF(buf, sizeof (buf), "%s:%ld:", file, (long)linep); +  snprintf(buf, sizeof (buf), "%s:%ld:", file, (long)linep);    else -  SNPRINTF(buf, sizeof (buf), "%s:", file); +  snprintf(buf, sizeof (buf), "%s:", file);    fprintf(stderr,"- %-20s %s\n",buf,s);    }       if (filep) {    free_string(filep);    }    free(s);   }    -  + static struct pike_frame_chunk { +  struct pike_frame_chunk *next; + } *pike_frame_chunks; + static int num_pike_frame_chunks; + static int num_pike_frames;    - #undef BLOCK_ALLOC_NEXT - #define BLOCK_ALLOC_NEXT next + 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")); +  DO_IF_DMALLOC( +  X->current_program=0; +  X->context=0; +  X->scope=0; +  X->current_object=0; +  X->flags=0; +  X->expendible=0; +  X->locals=0; +  ); +  X->next = free_pike_frame; +  PIKE_MEMPOOL_FREE(&free_pike_frame, X, sizeof(struct pike_frame)); +  free_pike_frame = X; + }    - #undef INIT_BLOCK - #define INIT_BLOCK(X) do { \ -  X->refs=0; \ -  add_ref(X); /* For DMALLOC... */ \ -  X->flags=0; \ -  X->scope=0; \ -  DO_IF_SECURITY( if(CURRENT_CREDS) { \ -  add_ref(X->current_creds=CURRENT_CREDS); \ -  } else { \ -  X->current_creds = 0; \ -  }) \ - }while(0) + 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*)); +  res->refs=0; +  add_ref(res); /* For DMALLOC... */ +  res->flags=0; +  res->next=0; +  res->scope=0; +  return res; +  }    - #undef EXIT_BLOCK - #define EXIT_BLOCK(X) do { \ -  free_object(X->current_object); \ -  if(X->current_program) free_program(X->current_program); \ -  if(X->scope) free_pike_scope(X->scope); \ -  DO_IF_SECURITY( if(X->current_creds) { \ -  free_object(X->current_creds); \ -  }) \ -  DO_IF_DEBUG( \ -  if(X->flags & PIKE_FRAME_MALLOCED_LOCALS) \ -  Pike_fatal("Pike frame is not supposed to have malloced locals here!\n")); \ -  \ -  DO_IF_DMALLOC( \ -  X->current_program=0; \ -  X->context=0; \ -  X->scope=0; \ -  X->current_object=0; \ -  X->flags=0; \ -  X->expendible=0; \ -  X->locals=0; \ -  DO_IF_SECURITY( X->current_creds=0; ) \ -  ) \ - }while(0) +  /* 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)    - BLOCK_ALLOC_FILL_PAGES(pike_frame, 4) +  void *p = xalloc( FRAME_CHUNK_SIZE ); +  num_pike_frame_chunks++; +  ((struct pike_frame_chunk*)p)->next = pike_frame_chunks; +  pike_frame_chunks = p; +  free_pike_frame = res = (struct pike_frame*)((char*)p+sizeof(struct pike_frame_chunk)); +  for( i=1; i<FRAMES_PER_CHUNK; i++ ) +  { +  res->next = &free_pike_frame[i]; +  res = res->next; +  } +  res->next = NULL; +  num_pike_frames+=FRAMES_PER_CHUNK; +  } +  return alloc_pike_frame(); + }    -  + 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) + { +  struct pike_frame_chunk *x = pike_frame_chunks, *n; +  while( x ) +  { +  n = x->next; +  free(x); +  x = n; +  } +  free_pike_frame = NULL; +  pike_frame_chunks = NULL; +  num_pike_frames=0; +  num_pike_frame_chunks=0; + } + #endif +    void really_free_pike_scope(struct pike_frame *scope)   {    if(scope->flags & PIKE_FRAME_MALLOCED_LOCALS)    {    free_mixed_svalues(scope->locals,scope->num_locals); -  free((char *)(scope->locals)); +  free(scope->locals);   #ifdef PIKE_DEBUG    scope->flags&=~PIKE_FRAME_MALLOCED_LOCALS;   #endif    }    really_free_pike_frame(scope);   }    -  + void *lower_mega_apply( INT32 args, struct object *o, ptrdiff_t fun ) + { +  struct program *p; +  check_stack(256); +  check_mark_stack(256); +  +  if( (p = o->prog) ) +  { +  struct svalue *save_sp = Pike_sp - args; +  struct reference *ref = p->identifier_references + fun; +  struct inherit *context = p->inherits + ref->inherit_offset; +  struct identifier *function = context->prog->identifiers + ref->identifier_offset; +  struct svalue *constant = NULL; +  struct pike_frame *new_frame = NULL; +  +  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; +  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; +  +  /* This is mostly for profiling, but +  * could also be used to find out the name of a function +  * in a destructed object. -hubbe +  * +  * Since it not used for anything but profiling yet, I will +  * put it here until someone needs it. -Hubbe +  */ +  new_frame->ident = ref->identifier_offset; +  DO_IF_PROFILING_DEBUG({ +  fprintf(stderr, "%p{: Push at %" PRINT_CPU_TIME +  " %" PRINT_CPU_TIME "\n", +  Pike_interpreter.thread_state, new_frame->start_time, +  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->expendible = new_frame->locals = save_sp; +  new_frame->args = args; +  new_frame->save_sp = save_sp; +  + #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++; +  function->recur_depth++; + #endif + #ifdef PIKE_USE_MACHINE_CODE +  call_check_threads_etc(); + #endif +  +  if( !constant ) +  { +  if (PIKE_FN_START_ENABLED()) +  { +  /* DTrace enter probe +  arg0: function name +  arg1: object +  */ +  dynamic_buffer save_buf; +  dynbuf_string obj_name; +  struct svalue obj_sval; +  SET_SVAL(obj_sval, T_OBJECT, 0, object, o); +  init_buf(&save_buf); +  safe_describe_svalue(&obj_sval, 0, NULL); +  obj_name = complex_free_buf(&save_buf); +  PIKE_FN_START(function->name->size_shift == 0 ? +  function->name->str : "[widestring fn name]", +  obj_name.str); +  } +  if(UNLIKELY(Pike_interpreter.trace_level)) +  { +  dynamic_buffer save_buf; +  char buf[50]; +  +  init_buf(&save_buf); +  sprintf(buf, "%lx->", (long) PTR_TO_INT (o)); +  my_strcat(buf); +  if (function->name->size_shift) +  my_strcat ("[widestring function name]"); +  else +  my_strcat(function->name->str); +  do_trace_call(args, &save_buf); +  } +  if( type == IDENTIFIER_C_FUNCTION ) +  { +  new_frame->num_args = args; +  new_frame->num_locals = args; +  new_frame->current_storage = o->storage+context->storage_offset; +  new_frame->pc = 0; + #ifndef PIKE_USE_MACHINE_CODE +  FAST_CHECK_THREADS_ON_CALL(); + #endif +  (*function->func.c_fun)(args); +  +  /* .. and below follows what is basically a copy of the +  * low_return function... +  */ +  if(save_sp+1 > Pike_sp) +  { +  push_int(0); +  } else if(save_sp+1 < Pike_sp) { +  stack_pop_n_elems_keep_top( Pike_sp-save_sp-1 ); +  } +  if(UNLIKELY(Pike_interpreter.trace_level>1)) +  do_trace_func_return (1, o, fun); +  goto pop; +  } +  new_frame->save_mark_sp=new_frame->mark_sp_base=Pike_mark_sp; +  new_frame->pc = new_frame->context->prog->program + function->func.offset + #ifdef ENTRY_PROLOGUE_SIZE +  + ENTRY_PROLOGUE_SIZE + #endif /* ENTRY_PROLOGUE_SIZE */ +  ; +  return new_frame->pc; +  } +  else +  { +  struct object *tmp; +  new_frame->pc = 0; +  new_frame->num_args = 0; +  tmp=parent_clone_object(constant->u.program, +  o, +  fun, +  args); +  push_object(tmp); +  pop: +  POP_PIKE_FRAME(); +  return 0; +  } +  } +  } +  } +  return low_mega_apply( APPLY_LOW, args, o, (void*)fun ); + } +    /* Apply a function.    *    * Application types:    *    * APPLY_STACK: Apply Pike_sp[-args] with args-1 arguments.    *    * APPLY_SVALUE: Apply the svalue at arg1, and adjust the stack    * to leave a return value.    *    * APPLY_SVALUE_STRICT: Apply the svalue at arg1, and don't adjust the
pike.git/src/interpret.c:1942:    *    * Return values:    *    * Returns zero if the function was invalid or has been executed.    *    * Returns one if a frame has been set up to start the function    * with eval_instruction(Pike_fp->pc - ENTRY_PROLOGUE_SIZE). After    * eval_instruction() is done the frame needs to be removed by a call    * to low_return() or low_return_pop().    */ - int low_mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2) + void* low_mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2)   {    struct object *o = NULL;    struct pike_frame *scope=0;    ptrdiff_t fun=0;    struct svalue *save_sp=Pike_sp-args;      #if defined(PIKE_DEBUG) && defined(_REENTRANT)    if(d_flag)    {    THREAD_T self = th_self();
pike.git/src/interpret.c:1973:   #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 */ +     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_ERROR("0", "Attempt to call the NULL-value\n", Pike_sp, args);    } else {    Pike_error("Attempt to call the value %"PRINTPIKEINT"d\n",    s->u.integer);    } -  +  break;       case T_STRING:    if (s->u.string->len > 20) {    Pike_error("Attempt to call the string \"%20S\"...\n", s->u.string);    } else {    Pike_error("Attempt to call the string \"%S\"\n", s->u.string);    } -  +  break; +     case T_MAPPING:    Pike_error("Attempt to call a mapping\n"); -  +  break; +     default:    Pike_error("Call to non-function value type:%s.\n",    get_name_of_type(TYPEOF(*s))); -  +  break;       case T_FUNCTION:    if(SUBTYPEOF(*s) == FUNCTION_BUILTIN)    {   #ifdef PIKE_DEBUG    struct svalue *expected_stack = Pike_sp-args;   #endif    if(Pike_interpreter.trace_level>1)    {    dynamic_buffer save_buf;
pike.git/src/interpret.c:2058: Inside #if defined(PIKE_DEBUG)
   if(Pike_sp==expected_stack+1 && s->u.efun->may_return_void)    Pike_fatal("Void function returned with a value on the stack: %S %d\n",    s->u.efun->name, s->u.efun->may_return_void);    }   #endif       break;    }else{    type=APPLY_SVALUE;    o=s->u.object; +  fun = SUBTYPEOF(*s);    if(o->prog == pike_trampoline_program && -  SUBTYPEOF(*s) == QUICK_FIND_LFUN(pike_trampoline_program, LFUN_CALL)) +  fun == QUICK_FIND_LFUN(pike_trampoline_program, LFUN_CALL))    {    fun=((struct pike_trampoline *)(o->storage))->func;    scope=((struct pike_trampoline *)(o->storage))->frame;    o=scope->current_object; -  goto apply_low_with_scope; +     } -  fun = SUBTYPEOF(*s); +     goto apply_low;    }    break;       case T_ARRAY:    if(Pike_interpreter.trace_level)    {    dynamic_buffer save_buf;    init_buf(&save_buf);    safe_describe_svalue(s,0,0);
pike.git/src/interpret.c:2128:    break;       case T_OBJECT:    /* FIXME: Object subtypes! */    o=s->u.object;    if(o->prog == pike_trampoline_program)    {    fun=((struct pike_trampoline *)(o->storage))->func;    scope=((struct pike_trampoline *)(o->storage))->frame;    o=scope->current_object; -  goto apply_low_with_scope; +  goto apply_low;    }    fun=LFUN_CALL;    type=APPLY_SVALUE;    goto call_lfun;    }    break;    }       call_lfun: {    int lfun;
pike.git/src/interpret.c:2161:       case APPLY_LOW:    o = (struct object *)arg1;    fun = PTR_TO_INT(arg2);    if(o->prog == pike_trampoline_program &&    fun == QUICK_FIND_LFUN(pike_trampoline_program, LFUN_CALL))    {    fun=((struct pike_trampoline *)(o->storage))->func;    scope=((struct pike_trampoline *)(o->storage))->frame;    o=scope->current_object; -  goto apply_low_with_scope; +     }       apply_low: - #undef SCOPE +    #include "apply_low.h"    break; -  -  apply_low_with_scope: - #define SCOPE scope - #include "apply_low.h" -  break; +     }       if(save_sp+1 > Pike_sp)    {    if(type != APPLY_SVALUE_STRICT) {    push_int(0);    if(Pike_interpreter.trace_level>1)    do_trace_func_return (1, o, fun);    }    else    if(Pike_interpreter.trace_level>1)    do_trace_func_return (0, o, fun);    }else{    if(save_sp+1 < Pike_sp)    {    assign_svalue(save_sp,Pike_sp-1);    pop_n_elems(Pike_sp-save_sp-1);    low_destruct_objects_to_destruct(); /* consider using a flag for immediate destruct instead... */ -  +     }    if(Pike_interpreter.trace_level>1)    do_trace_func_return (1, o, fun);    }       if (PIKE_FN_DONE_ENABLED()) {    /* DTrace leave probe    arg0: function name    */    char *fn = "(unknown)";
pike.git/src/interpret.c:2229:    Pike_fatal("Stack error (also simple).\n"); \    ) \    \    Pike_mark_sp=Pike_fp->save_mark_sp; \    \    POP_PIKE_FRAME()         void low_return(void)   { -  struct svalue *save_sp = Pike_fp->save_sp; -  int trace_level = Pike_interpreter.trace_level; -  struct object *o; /* Got bogus gcc warning here. */ -  int fun; /* Got bogus gcc warning here. */ +  struct svalue *save_sp = Pike_fp->save_sp+1; +  struct object *o = Pike_fp->current_object; +  int fun = Pike_fp->fun;    -  if (trace_level > 1) { -  o = Pike_fp->current_object; -  fun = Pike_fp->fun; -  } -  +     if (PIKE_FN_DONE_ENABLED()) {    /* DTrace leave probe    arg0: function name    */    char *fn = "(unknown)"; -  o = Pike_fp->current_object; -  fun = Pike_fp->fun; +     if (o && o->prog) {    struct identifier *id = ID_FROM_INT(o->prog, fun);    fn = id->name->size_shift == 0 ? id->name->str : "[widestring fn name]";    }    PIKE_FN_DONE(fn);    }      #if defined (PIKE_USE_MACHINE_CODE) && defined (OPCODE_RETURN_JUMPADDR)    /* If the function that returns is the only ref to the current    * object and its program then the program would be freed in    * destruct_objects_to_destruct below. However, we're still    * executing in an opcode in its code so we need prog->program to    * stick around for a little while more to handle the returned    * address. We therefore add a ref to the current object so that    * it'll live through this function. */ -  o = Pike_fp->current_object; +     add_ref (o);   #endif       basic_low_return (save_sp); -  if(save_sp+1 > Pike_sp) -  { -  push_int(0); -  }else{ -  if(save_sp+1 < Pike_sp) -  { -  stack_pop_n_elems_keep_top (Pike_sp - save_sp - 1); +     -  +  stack_pop_n_elems_keep_top (Pike_sp - save_sp); +  {    /* consider using a flag for immediate destruct instead... */ -  +  extern struct object *objects_to_destruct; +  if( objects_to_destruct )    destruct_objects_to_destruct();    } -  } +     -  if(trace_level>1) + #ifdef PIKE_DEBUG +  if(save_sp > Pike_sp) +  Pike_fatal("Pike function did not leave an return value\n"); + #endif +  +  if(UNLIKELY(Pike_interpreter.trace_level>1))    do_trace_func_return (1, o, fun);      #if defined (PIKE_USE_MACHINE_CODE) && defined (OPCODE_RETURN_JUMPADDR)    free_object (o);   #endif   }      void low_return_pop(void)   {    struct svalue *save_sp = Pike_fp->save_sp;
pike.git/src/interpret.c:2312:    int fun = Pike_fp->fun;    if (o && o->prog) {    struct identifier *id = ID_FROM_INT(o->prog, fun);    fn = id->name->size_shift == 0 ? id->name->str : "[widestring fn name]";    }    PIKE_FN_DONE(fn);    }       basic_low_return (save_sp);    -  if(save_sp < Pike_sp) -  { +     pop_n_elems(Pike_sp-save_sp);    /* consider using a flag for immediate destruct instead... */    destruct_objects_to_destruct(); -  } +       #if defined (PIKE_USE_MACHINE_CODE) && defined (OPCODE_RETURN_JUMPADDR)    free_object (o);   #endif   }         void unlink_previous_frame(void)   {    struct pike_frame *current, *prev;
pike.git/src/interpret.c:2351: 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.    */    current->save_sp=prev->save_sp;    current->save_mark_sp=prev->save_mark_sp; -  current->flags=prev->flags; +  current->flags = prev->flags;       /* 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 =    get_cpu_time() - (Pike_interpreter.unlocked_time + current->start_time);    cpu_time_t child_time =    Pike_interpreter.accounted_time - current->children_base;    struct identifier *function =    current->context->prog->identifiers + current->ident; -  +  if (!function->recur_depth)    function->total_time += total_time;    total_time -= child_time;    function->self_time += total_time;    Pike_interpreter.accounted_time += total_time;   #ifdef PROFILING_DEBUG    fprintf(stderr, "%p: Unlinking previous frame.\n"    "Previous: %" PRINT_CPU_TIME " %" PRINT_CPU_TIME "\n"    "Current: %" PRINT_CPU_TIME " %" PRINT_CPU_TIME "\n",    Pike_interpreter.thread_state,    prev->start_time, prev->children_base,
pike.git/src/interpret.c:2393:    POP_PIKE_FRAME();       /* Hook our frame again. */    current->next=Pike_interpreter.frame_pointer;    Pike_interpreter.frame_pointer=current;      #ifdef PROFILING    current->children_base = Pike_interpreter.accounted_time;    current->start_time = get_cpu_time() - Pike_interpreter.unlocked_time;   #endif /* PROFILING */ -  - #if 0 -  /* FIXME: This code is questionable, and the Pike_sp -  * adjustment ought to modify the mark stack. -  */ -  { -  int freespace; -  /* Move svalues down */ -  freespace=current->locals - current->save_sp; -  if(freespace > ((Pike_sp - current->locals)<<2) + 32) -  { -  assign_svalues(current->save_sp, -  current->locals, -  Pike_sp - current->locals, -  BIT_MIXED); -  -  current->locals-=freespace; -  current->expendible-=freespace; -  pop_n_elems(freespace); +    }    -  /* Move pointers down */ -  freespace=current->mark_sp_base - current->save_mark_sp; -  if(freespace > ((Pike_mark_sp - current->mark_sp_base)<<2)+32) -  { -  MEMMOVE(current->save_mark_sp, -  current->mark_sp_base, -  sizeof(struct svalue **)*(Pike_mark_sp - current->mark_sp_base)); -  current->mark_sp_base-=freespace; -  Pike_mark_sp-=freespace; -  } -  } - #endif /* 0 */ - } -  +    static void restore_catching_eval_jmpbuf (LOW_JMP_BUF *p)   {    Pike_interpreter.catching_eval_jmpbuf = p;   }      PMOD_EXPORT void mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2)   {    /* Save and clear Pike_interpreter.catching_eval_jmpbuf so that the    * following eval_instruction will install a LOW_JMP_BUF of its    * own to handle catches. */    LOW_JMP_BUF *saved_jmpbuf = Pike_interpreter.catching_eval_jmpbuf;    ONERROR uwp;    Pike_interpreter.catching_eval_jmpbuf = NULL;    SET_ONERROR (uwp, restore_catching_eval_jmpbuf, saved_jmpbuf);       /* The C stack margin is normally 8 kb, but if we get here during a    * lowered margin then don't fail just because of that, unless it's    * practically zero. */    check_c_stack(Pike_interpreter.c_stack_margin ?    Pike_interpreter.c_stack_margin : 100); -  +  if( low_mega_apply(type, args, arg1, arg2) ) +  { +  eval_instruction(Pike_fp->pc + #ifdef ENTRY_PROLOGUE_SIZE +  - ENTRY_PROLOGUE_SIZE + #endif /* ENTRY_PROLOGUE_SIZE */ +  ); +  low_return(); +  } +  CALL_AND_UNSET_ONERROR(uwp); + }    -  if(low_mega_apply(type, args, arg1, arg2)) + PMOD_EXPORT void mega_apply_low(INT32 args, void *arg1, ptrdiff_t arg2)   { -  +  /* Save and clear Pike_interpreter.catching_eval_jmpbuf so that the +  * following eval_instruction will install a LOW_JMP_BUF of its +  * own to handle catches. */ +  LOW_JMP_BUF *saved_jmpbuf = Pike_interpreter.catching_eval_jmpbuf; +  ONERROR uwp; +  Pike_interpreter.catching_eval_jmpbuf = NULL; +  SET_ONERROR (uwp, restore_catching_eval_jmpbuf, saved_jmpbuf); +  +  /* The C stack margin is normally 8 kb, but if we get here during a +  * lowered margin then don't fail just because of that, unless it's +  * practically zero. */ +  check_c_stack(Pike_interpreter.c_stack_margin ? +  Pike_interpreter.c_stack_margin : 100); +  if( lower_mega_apply( args, arg1, arg2 ) ) +  {    eval_instruction(Pike_fp->pc   #ifdef ENTRY_PROLOGUE_SIZE    - ENTRY_PROLOGUE_SIZE   #endif /* ENTRY_PROLOGUE_SIZE */    );    low_return();    }    CALL_AND_UNSET_ONERROR(uwp);   }   
pike.git/src/interpret.c:2584:    mark_free_svalue (&throw_value);    }   }      /* NOTE: This function may only be called from the compiler! */   int apply_low_safe_and_stupid(struct object *o, INT32 offset)   {    JMP_BUF tmp;    struct pike_frame *new_frame=alloc_pike_frame();    int ret; -  int use_dummy_reference = 1; +  volatile int use_dummy_reference = 1;    struct program *prog = o->prog;    int p_flags = prog->flags;    LOW_JMP_BUF *saved_jmpbuf;    int fun = -1;       /* Search for a function that belongs to the current program,    * since this is needed for opcodes that use INHERIT_FROM_*    * (eg F_EXTERN) to work.    */    for (fun = prog->num_identifier_references; fun--;) {
pike.git/src/interpret.c:2784:    struct object *master_obj = master();    if ((i = find_identifier(fun, master_obj->prog)) != -1)    safe_apply_low2(master_obj, i, args, fun);    else {    pop_n_elems(args);    push_undefined();    }    }   }    + PMOD_EXPORT void push_text( const char *x ) + { +  struct svalue *_sp_ = Pike_sp++; +  SET_SVAL_SUBTYPE(*_sp_, 0); +  _sp_->u.string=make_shared_string(x); +  debug_malloc_touch(_sp_->u.string); +  SET_SVAL_TYPE(*_sp_, PIKE_T_STRING); + } +  + PMOD_EXPORT void push_static_text( const char *x ) + { +  struct svalue *_sp_ = Pike_sp++; +  SET_SVAL_SUBTYPE(*_sp_, 0); +  _sp_->u.string=make_shared_static_string(x, strlen(x), eightbit); +  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)   {    JMP_BUF recovery;    int ret;   
pike.git/src/interpret.c:2829:    ret = 1;    }       UNSETJMP(recovery);       STACK_LEVEL_DONE(ret);       return ret;   }    - PMOD_EXPORT void apply_lfun(struct object *o, int fun, int args) + PMOD_EXPORT void apply_lfun(struct object *o, int lfun, int args)   { -  +  int fun;   #ifdef PIKE_DEBUG -  if(fun < 0 || fun >= NUM_LFUNS) +  if(lfun < 0 || lfun >= NUM_LFUNS)    Pike_fatal("Apply lfun on illegal value!\n");   #endif    if(!o->prog) -  PIKE_ERROR("destructed object", "Apply on destructed object.\n", Pike_sp, args); +  PIKE_ERROR("destructed object", "Apply on destructed object.\n", +  Pike_sp, args);    -  apply_low(o, (int)FIND_LFUN(o->prog,fun), args); +  if ((fun = (int)FIND_LFUN(o->prog, lfun)) < 0) +  Pike_error("Calling undefined lfun::%s.\n", lfun_names[lfun]); +  +  apply_low(o, fun, args);   }      PMOD_EXPORT void apply_shared(struct object *o,    struct pike_string *fun,    int args)   {    int id = find_shared_string_identifier(fun, o->prog);    if (id >= 0)    apply_low(o, id, args);    else
pike.git/src/interpret.c:3040: Inside #if defined(PIKE_DEBUG) and #if defined(PIKE_THREADS)
   }    f = ts->state.frame_pointer;   #else    f = Pike_fp;   #endif       for (of = 0; f; f = (of = f)->next)    if (f->refs) {    int args, i;    char *file = NULL; -  INT32 line; +  INT_TYPE line;       if (f->context) {    if (f->pc)    file = low_get_line_plain (f->pc, f->context->prog, &line, 0);    else    file = low_get_program_line_plain (f->context->prog, &line, 0);    }    if (file) -  fprintf (stderr, "%s:%d: ", file, line); +  fprintf (stderr, "%s:%ld: ", file, (long)line);    else    fputs ("unknown program: ", stderr);       if (f->current_program) {    /* FIXME: Wide string identifiers. */    fputs (safe_idname_from_int(f->current_program, f->fun), stderr);    fputc ('(', stderr);    }    else    fputs ("unknown function(", stderr);       if(!f->locals)    {    args=0;    }else{ -  args=f->num_args; -  args = DO_NOT_WARN((INT32) MINIMUM(f->num_args, Pike_sp - f->locals)); -  if(of) -  args = DO_NOT_WARN((INT32)MINIMUM(f->num_args,of->locals - f->locals)); -  args=MAXIMUM(args,0); +  ptrdiff_t tmp; +  +  if(of) { +  tmp = of->locals - f->locals; +  } else { +  tmp = ts->state.stack_pointer - f->locals;    } -  +  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:    fprintf (stderr, "%ld", (long) arg->u.integer);    break;       case T_TYPE:
pike.git/src/interpret.c:3161:    fputs (safe_idname_from_int(arg->u.object->prog,    SUBTYPEOF(*arg)), stderr);    else    fputc ('0', stderr);    break;       case T_OBJECT: {    struct program *p = arg->u.object->prog;    if (p && p->num_linenumbers) {    file = low_get_program_line_plain (p, &line, 0); -  fprintf (stderr, "object(%s:%d)", file, line); +  fprintf (stderr, "object(%s:%ld)", file, (long)line);    }    else    fputs ("object", stderr);    break;    }       case T_PROGRAM: {    struct program *p = arg->u.program;    if (p->num_linenumbers) {    file = low_get_program_line_plain (p, &line, 0); -  fprintf (stderr, "program(%s:%d)", file, line); +  fprintf (stderr, "program(%s:%ld)", file, (long)line);    }    else    fputs ("program", stderr);    break;    }       case T_FLOAT:    fprintf (stderr, "%f",(double) arg->u.float_number);    break;   
pike.git/src/interpret.c:3221:    *: debugger session; it can't be used from inside the program.    */   void gdb_backtraces()   {   #ifdef PIKE_THREADS    extern INT32 gdb_next_thread_state(INT32, struct thread_state **);    INT32 i = 0;    struct thread_state *ts = 0;    while ((i = gdb_next_thread_state (i, &ts)), ts) {    fprintf (stderr, "\nTHREAD_ID %p (swapped %s):\n", -  (void *)ts->id, ts->swapped ? "out" : "in"); +  (void *)(ptrdiff_t)ts->id, ts->swapped ? "out" : "in");    gdb_backtrace (ts->id);    }   #else    gdb_backtrace();   #endif   }   #endif      PMOD_EXPORT void custom_check_stack(ptrdiff_t amount, const char *fmt, ...)   {
pike.git/src/interpret.c:3257: Inside #if defined(USE_MMAP_FOR_STACK)
   }    if(!interpreter->mark_stack_malloced)    {    munmap((char *)interpreter->mark_stack,    Pike_stack_size*sizeof(struct svalue *));    interpreter->mark_stack = 0;    }   #endif       if(interpreter->evaluator_stack) -  free((char *)interpreter->evaluator_stack); +  free(interpreter->evaluator_stack);    if(interpreter->mark_stack) -  free((char *)interpreter->mark_stack); +  free(interpreter->mark_stack);       interpreter->mark_stack = 0;    interpreter->evaluator_stack = 0;    interpreter->mark_stack_malloced = 0;    interpreter->evaluator_stack_malloced = 0;       interpreter->stack_pointer = 0;    interpreter->mark_stack_pointer = 0;    interpreter->frame_pointer = 0;   }