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: interpret.c,v 1.344 2004/03/24 20:34:44 grubba Exp $ + || $Id: interpret.c,v 1.345 2004/04/03 21:53:49 mast Exp $   */      #include "global.h" - RCSID("$Id: interpret.c,v 1.344 2004/03/24 20:34:44 grubba Exp $"); + RCSID("$Id: interpret.c,v 1.345 2004/04/03 21:53:49 mast Exp $");   #include "interpret.h"   #include "object.h"   #include "program.h"   #include "svalue.h"   #include "array.h"   #include "mapping.h"   #include "pike_error.h"   #include "stralloc.h"   #include "constants.h"   #include "pike_macros.h"
pike.git/src/interpret.c:94:   PMOD_EXPORT unsigned long evaluator_callback_calls = 0;   #endif         /* 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 Pike_interpreter;   PMOD_EXPORT int Pike_stack_size = EVALUATOR_STACK_SIZE;    - static void trace_return_value(void); +    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 gdb_stop_here(void)   {    ;   }         void push_sp_mark(void)   {    if(Pike_mark_sp == Pike_interpreter.mark_stack + Pike_stack_size)
pike.git/src/interpret.c:1367:   }         #else   #include "interpreter.h"   #endif         #endif /* PIKE_USE_MACHINE_CODE */    - static void trace_return_value(void) + static void do_trace_call(INT32 args, dynamic_buffer *old_buf)   { -  char *s; -  dynamic_buffer save_buf; +  struct pike_string *filep = NULL; +  char *file, *s; +  INT32 linep,e;    -  init_buf(&save_buf); -  my_strcat("Return: "); -  describe_svalue(Pike_sp-1,0,0); -  s=simple_free_buf(&save_buf); +  my_strcat("("); +  for(e=0;e<args;e++) +  { +  if(e) my_strcat(","); +  describe_svalue(Pike_sp-args+e,0,0); +  } +  my_strcat(")"); +  +  s=simple_free_buf(old_buf);    if((size_t)strlen(s) > (size_t)TRACE_LEN)    {    s[TRACE_LEN]=0;    s[TRACE_LEN-1]='.';    s[TRACE_LEN-2]='.'; -  s[TRACE_LEN-2]='.'; +  s[TRACE_LEN-3]='.';    } -  fprintf(stderr,"%-*s%s\n",4,"-",s); +  +  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,'/'))) +  file=f+1; +  } +  }else{ +  linep=0; +  file="-"; +  } +  +  { +  char buf[40]; +  if (linep) +  snprintf (buf, sizeof (buf), "%s:%ld:", file, (long)linep); +  else +  snprintf (buf, sizeof (buf), "%s:", file); +  fprintf(stderr,"- %-20s %s\n",buf,s); +  } +  +  if (filep) { +  free_string(filep); +  }    free(s);   }    - 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)   { -  +  dynamic_buffer save_buf; +  init_buf (&save_buf); +  if (fun >= 0) { +  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))); +  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,e; -  my_strcat("("); -  for(e=0;e<args;e++) -  { -  if(e) my_strcat(","); -  describe_svalue(Pike_sp-args+e,0,0); +  INT32 linep; +  +  if (got_retval) { +  my_strcat ("returns: "); +  describe_svalue(Pike_sp-1,0,0);    } -  my_strcat(")"); +  else +  my_strcat ("returns with no value"); +     s=simple_free_buf(old_buf);    if((size_t)strlen(s) > (size_t)TRACE_LEN)    {    s[TRACE_LEN]=0;    s[TRACE_LEN-1]='.';    s[TRACE_LEN-2]='.'; -  s[TRACE_LEN-2]='.'; +  s[TRACE_LEN-3]='.';    } -  +     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,'/')))    file=f+1; -  +  }    }else{    linep=0;    file="-";    } -  fprintf(stderr,"- %s:%4ld: %s\n",file,(long)linep,s); +  +  { +  char buf[40]; +  if (linep) +  snprintf (buf, sizeof (buf), "%s:%ld:", file, (long)linep); +  else +  snprintf (buf, sizeof (buf), "%s:", file); +  fprintf(stderr,"- %-20s %s\n",buf,s); +  } +     if (filep) {    free_string(filep);    }    free(s);   }         #undef INIT_BLOCK   #define INIT_BLOCK(X) do { \    X->refs=0; \
pike.git/src/interpret.c:1508:    *    * 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)   {    struct object *o;    struct pike_frame *scope=0; -  ptrdiff_t fun; +  ptrdiff_t fun = -1;    struct svalue *save_sp=Pike_sp-args;      #if defined(PIKE_DEBUG) && defined(_REENTRANT)    if(d_flag)    {    THREAD_T self = th_self();       CHECK_INTERPRETER_LOCK();       if( Pike_interpreter.thread_state &&
pike.git/src/interpret.c:1566:    Pike_error("Attempt to call a mapping\n");    default:    Pike_error("Call to non-function value type:%s.\n",    get_name_of_type(s->type));       case T_FUNCTION:    if(s->subtype == FUNCTION_BUILTIN)    {   #ifdef PIKE_DEBUG    struct svalue *expected_stack = Pike_sp-args; + #endif    if(Pike_interpreter.trace_level>1)    {    dynamic_buffer save_buf;    init_buf(&save_buf); -  describe_svalue(s,0,0); +  if (s->u.efun->name->size_shift) +  my_strcat ("[widestring function name]"); +  else +  my_strcat (s->u.efun->name->str);    do_trace_call(args, &save_buf);    } - #endif +     check_threads_etc();    (*(s->u.efun->function))(args);      #ifdef PIKE_DEBUG    s->u.efun->runs++;    if(Pike_sp != expected_stack + !s->u.efun->may_return_void)    {    if(Pike_sp < expected_stack)    Pike_fatal("Function popped too many arguments: %s\n",    s->u.efun->name->str);
pike.git/src/interpret.c:1614:    scope=((struct pike_trampoline *)(o->storage))->frame;    o=scope->current_object;    goto apply_low_with_scope;    }    fun=s->subtype;    goto apply_low;    }    break;       case T_ARRAY: - #ifdef PIKE_DEBUG -  if(Pike_interpreter.trace_level>1) +  if(Pike_interpreter.trace_level)    {    dynamic_buffer save_buf;    init_buf(&save_buf);    describe_svalue(s,0,0);    do_trace_call(args, &save_buf);    } - #endif +     apply_array(s->u.array,args);    break;       case T_PROGRAM: - #ifdef PIKE_DEBUG -  if(Pike_interpreter.trace_level>1) +  if(Pike_interpreter.trace_level)    {    dynamic_buffer save_buf;    init_buf(&save_buf);    describe_svalue(s,0,0);    do_trace_call(args, &save_buf);    } - #endif +     push_object(clone_object(s->u.program,args));    break;       case T_OBJECT:    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;
pike.git/src/interpret.c:1695:    break;       apply_low_with_scope:   #define SCOPE scope   #include "apply_low.h"    break;    }       if(save_sp+1 > Pike_sp)    { -  if(type != APPLY_SVALUE_STRICT) +  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) trace_return_value(); +  if(Pike_interpreter.trace_level>1) +  do_trace_func_return (1, o, fun);    }    return 0;   }            #define low_return_profiling()      #ifdef PROFILING   #ifdef HAVE_GETHRTIME
pike.git/src/interpret.c:1748:    ) \    \    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; +  int fun; +  +  if (trace_level > 1) { +  o = Pike_fp->current_object; +  fun = Pike_fp->fun; +  } +    #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. */ -  struct object *o = Pike_fp->current_object; +  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)    {    assign_svalue(save_sp,Pike_sp-1);    pop_n_elems(Pike_sp-save_sp-1);       /* consider using a flag for immediate destruct instead... */    destruct_objects_to_destruct();    } -  if(Pike_interpreter.trace_level>1) trace_return_value(); +     }    -  +  if(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;   #if defined (PIKE_USE_MACHINE_CODE) && defined (OPCODE_RETURN_JUMPADDR)    /* See note above. */