pike.git / src / interpret.c

version» Context lines:

pike.git/src/interpret.c:1:   /*\   ||| This file a part of Pike, and is copyright by Fredrik Hubinette   ||| Pike is distributed as GPL (General Public License)   ||| See the files COPYING and DISCLAIMER for more information.   \*/   #include "global.h" - RCSID("$Id: interpret.c,v 1.112 1999/01/21 09:15:01 hubbe Exp $"); + RCSID("$Id: interpret.c,v 1.113 1999/01/31 09:01:47 hubbe Exp $");   #include "interpret.h"   #include "object.h"   #include "program.h"   #include "svalue.h"   #include "array.h"   #include "mapping.h"   #include "error.h"   #include "language.h"   #include "stralloc.h"   #include "constants.h"
pike.git/src/interpret.c:22:   #include "opcodes.h"   #include "main.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 "security.h" + #include "block_alloc.h"      #include <fcntl.h>   #include <errno.h>      #ifdef HAVE_MMAP   #ifdef HAVE_SYS_TYPES_H   #include <sys/types.h>   #endif      #ifdef HAVE_SYS_MMAN_H
pike.git/src/interpret.c:84:   }   int pop_sp_mark(void)   {   #ifdef PIKE_DEBUG    if(mark_sp < mark_stack)    fatal("Mark stack underflow!\n");   #endif    return sp - *--mark_sp;   }    - struct frame *fp; /* frame pointer */ + struct pike_frame *fp; /* pike_frame pointer */      #ifdef PIKE_DEBUG   static void gc_check_stack_callback(struct callback *foo, void *bar, void *gazonk)   { -  struct frame *f; +  struct pike_frame *f;    debug_gc_xmark_svalues(evaluator_stack,sp-evaluator_stack-1,"interpreter stack");    -  for(f=fp;f;f=f->parent_frame) +  for(f=fp;f;f=f->next)    {    if(f->context.parent)    gc_external_mark(f->context.parent);    gc_external_mark(f->current_object);    gc_external_mark(f->context.prog);    }      }   #endif   
pike.git/src/interpret.c:189: Inside #if defined(PROFILING)
  #endif   #ifdef PROFILING   #ifdef HAVE_GETHRTIME    time_base = gethrtime();    accounted_time =0;   #endif   #endif   }       -  +    static int eval_instruction(unsigned char *pc);         /*    * 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 }    * local variable : { svalue_pointer, nothing }
pike.git/src/interpret.c:655:       CASE(F_LFUN);    sp->u.object=fp->current_object;    add_ref(fp->current_object);    sp->subtype=GET_ARG()+fp->context.identifier_level;    sp->type=T_FUNCTION;    sp++;    print_return_value();    break;    +  CASE(F_TRAMPOLINE); +  { +  struct object *o=low_clone(pike_trampoline_program); +  add_ref( ((struct pike_trampoline *)(o->storage))->frame=fp ); +  ((struct pike_trampoline *)(o->storage))->func=GET_ARG()+fp->context.identifier_level; +  push_object(o); +  print_return_value(); +  break; +  } +  +     /* The not so basic 'push value' instructions */    CASE(F_GLOBAL);    low_object_index_no_free(sp,    fp->current_object,    GET_ARG() + fp->context.identifier_level);    sp++;    print_return_value();    break;       CASE(F_EXTERNAL);
pike.git/src/interpret.c:830:    break;    }       CASE(F_LOCAL_LVALUE);    sp[0].type=T_LVALUE;    sp[0].u.lval=fp->locals+GET_ARG();    sp[1].type=T_VOID;    sp+=2;    break;    +  CASE(F_LEXICAL_LOCAL); +  { +  struct pike_frame *f=fp; +  while(accumulator--) +  { +  f=f->scope; +  if(!f) error("Lexical scope error.\n"); +  } +  push_svalue(f->locals + GET_ARG()); +  print_return_value(); +  break; +  } +  +  CASE(F_LEXICAL_LOCAL_LVALUE); +  { +  struct pike_frame *f=fp; +  while(accumulator--) +  { +  f=f->scope; +  if(!f) error("Lexical scope error.\n"); +  } +  sp[0].type=T_LVALUE; +  sp[0].u.lval=f->locals+GET_ARG(); +  sp[1].type=T_VOID; +  sp+=2; +  break; +  } +     CASE(F_ARRAY_LVALUE);    f_aggregate(GET_ARG()*2);    sp[-1].u.array->flags |= ARRAY_LVALUE;    sp[-1].u.array->type_field |= BIT_UNFINISHED | BIT_MIXED;    sp[0]=sp[-1];    sp[-1].type=T_ARRAY_LVALUE;    sp++;    break;       CASE(F_CLEAR_2_LOCAL);
pike.git/src/interpret.c:1529:    CASE(F_OR); o_or(); break;    CASE(F_XOR); o_xor(); break;    CASE(F_MULTIPLY); o_multiply(); break;    CASE(F_DIVIDE); o_divide(); break;    CASE(F_MOD); o_mod(); break;       CASE(F_ADD_INT); push_int(GET_ARG()); f_add(2); break;    CASE(F_ADD_NEG_INT); push_int(-GET_ARG()); f_add(2); break;       CASE(F_PUSH_ARRAY); -  if(sp[-1].type!=T_ARRAY) +  switch(sp[-1].type) +  { +  default:    PIKE_ERROR("@", "Bad argument.\n", sp, 1); -  +  +  case T_OBJECT: +  if(!sp[-1].u.object->prog || FIND_LFUN(sp[-1].u.object->prog,LFUN__VALUES) == -1) +  PIKE_ERROR("@", "Bad argument.\n", sp, 1); +  +  apply_lfun(sp[-1].u.object, LFUN__VALUES, 0); +  if(sp[-1].type != T_ARRAY) +  error("Bad return type from o->_values() in @\n"); +  free_svalue(sp-2); +  sp[-2]=sp[-1];    sp--; -  +  break; +  +  case T_ARRAY: break; +  } +  sp--;    push_array_items(sp->u.array);    break;       CASE(F_LOCAL_LOCAL_INDEX);    {    struct svalue *s=fp->locals+GET_ARG();    if(s->type == T_STRING) s->subtype=0;    sp++->type=T_INT;    index_no_free(sp-1,fp->locals+GET_ARG2(),s);    break;
pike.git/src/interpret.c:1789:    file=get_line(fp->pc,fp->context.prog,&linep);    while((f=STRCHR(file,'/'))) file=f+1;    }else{    linep=0;    file="-";    }    fprintf(stderr,"- %s:%4ld: %s\n",file,(long)linep,s);    free(s);   }    +  + #undef INIT_BLOCK + #define INIT_BLOCK(X) do { X->refs=1; X->malloced_locals=0; X->scope=0; }while(0) +  + #undef EXIT_BLOCK + #define EXIT_BLOCK(X) do { \ +  free_object(X->current_object); \ +  if(X->context.prog) free_program(X->context.prog); \ +  if(X->context.parent) free_object(X->context.parent); \ +  if(X->scope) free_pike_frame(X->scope); \ +  if(X->malloced_locals) \ +  { \ +  free_svalues(X->locals,X->num_locals,BIT_MIXED); \ +  free((char *)(X->locals)); \ +  } \ + }while(0) +  + BLOCK_ALLOC(pike_frame,128) +  +  +    #ifdef PIKE_SECURITY   static void restore_creds(struct object *creds)   {    if(current_creds) free_object(current_creds);    current_creds=creds;   }      /* Magic trick */   static      #else   #define mega_apply2 mega_apply   #endif    -  +    void mega_apply2(enum apply_type type, INT32 args, void *arg1, void *arg2)   {    struct object *o; -  +  struct pike_frame *scope=0;    int fun, tailrecurse=-1;    struct svalue *save_sp=sp-args;      #ifdef PROFILING   #ifdef HAVE_GETHRTIME    long long children_base = accounted_time;    long long start_time = gethrtime() - time_base;    unsigned INT32 self_time_base;    if(start_time < 0)    {
pike.git/src/interpret.c:1912: Inside #if defined(PIKE_DEBUG)
   init_buf();    describe_svalue(s,0,0);    do_trace_call(args);    }   #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; +  goto apply_low_with_scope; +  }    fun=LFUN_CALL;    goto call_lfun;    }    break;    }       call_lfun:   #ifdef PIKE_DEBUG    if(fun < 0 || fun >= NUM_LFUNS)    fatal("Apply lfun on illegal value!\n");
pike.git/src/interpret.c:1934:    PIKE_ERROR("destructed object", "Apply on destructed object.\n", sp, args);    fun=FIND_LFUN(o->prog,fun);    goto apply_low;          case APPLY_LOW:    o=(struct object *)arg1;    fun=(long)arg2;       apply_low: +  scope=0; +  apply_low_with_scope:    {    struct program *p;    struct reference *ref; -  struct frame new_frame; +  struct pike_frame *new_frame=alloc_pike_frame();    struct identifier *function;       if(fun<0)    {    pop_n_elems(sp-save_sp);    push_int(0);    return;    }       check_stack(256);
pike.git/src/interpret.c:1977: Inside #if defined(PIKE_DEBUG)
   fatal("Function index out of range.\n");    }   #endif       ref = p->identifier_references + fun;   #ifdef PIKE_DEBUG    if(ref->inherit_offset>=p->num_inherits)    fatal("Inherit offset out of range in program.\n");   #endif    -  /* init a new evaluation frame */ -  new_frame.parent_frame = fp; -  new_frame.current_object = o; -  new_frame.context = p->inherits[ ref->inherit_offset ]; +  /* init a new evaluation pike_frame */ +  new_frame->next = fp; +  new_frame->current_object = o; +  new_frame->context = p->inherits[ ref->inherit_offset ];    -  function = new_frame.context.prog->identifiers + ref->identifier_offset; +  function = new_frame->context.prog->identifiers + ref->identifier_offset;      #ifdef PIKE_SECURITY    CHECK_DATA_SECURITY_OR_ERROR(o, SECURITY_BIT_CALL, ("Function call permission denied.\n"));       if(!CHECK_DATA_SECURITY(o, SECURITY_BIT_NOT_SETUID))    SET_CURRENT_CREDS(o->prot);   #endif         #ifdef PROFILING    function->num_calls++;   #endif    -  new_frame.locals = sp - args; -  new_frame.expendible = new_frame.locals; -  new_frame.args = args; -  new_frame.fun = fun; -  new_frame.current_storage = o->storage+new_frame.context.storage_offset; -  new_frame.pc = 0; +  new_frame->locals = sp - args; +  new_frame->expendible = new_frame->locals; +  new_frame->args = args; +  new_frame->fun = fun; +  new_frame->current_storage = o->storage+new_frame->context.storage_offset; +  new_frame->pc = 0; +  new_frame->scope=scope;    -  add_ref(new_frame.current_object); -  add_ref(new_frame.context.prog); -  if(new_frame.context.parent) add_ref(new_frame.context.parent); +  add_ref(new_frame->current_object); +  add_ref(new_frame->context.prog); +  if(new_frame->context.parent) add_ref(new_frame->context.parent); +  if(new_frame->scope) add_ref(new_frame->scope);       if(t_flag)    {    char buf[50];    init_buf();    sprintf(buf,"%lx->",(long)o);    my_strcat(buf);    my_strcat(function->name->str);    do_trace_call(args);    }    -  fp = &new_frame; +  fp = new_frame;       if(function->func.offset == -1)    PIKE_ERROR(function->name->str, "Calling undefined function.\n", sp, args);       tailrecurse=-1;      #ifdef PROFILING   #ifdef HAVE_GETHRTIME    self_time_base=function->total_time;   #endif   #endif       switch(function->identifier_flags & (IDENTIFIER_FUNCTION | IDENTIFIER_CONSTANT))    {    case IDENTIFIER_C_FUNCTION:    fp->num_args=args; -  new_frame.num_locals=args; +  new_frame->num_locals=args;    check_threads_etc();    (*function->func.c_fun)(args);    break;       case IDENTIFIER_CONSTANT:    {    struct svalue *s=fp->context.prog->constants+function->func.offset;    if(s->type == T_PROGRAM)    {    struct object *tmp;
pike.git/src/interpret.c:2075:    low_object_index_no_free(sp-args-1,o,fun);    tailrecurse=args+1;    break;    }       case IDENTIFIER_PIKE_FUNCTION:    {    int num_args;    int num_locals;    unsigned char *pc; -  pc=new_frame.context.prog->program + function->func.offset; +  pc=new_frame->context.prog->program + function->func.offset;       num_locals=EXTRACT_UCHAR(pc++);    num_args=EXTRACT_UCHAR(pc++);    -  +  /* FIXME: this is only needed if this function contains +  * trampolines +  */ +  new_frame->expendible+=num_locals; +     /* adjust arguments on stack */    if(args < num_args) /* push zeros */    {    clear_svalues(sp, num_args-args);    sp += num_args-args;    args += num_args-args;    }       if(function->identifier_flags & IDENTIFIER_VARARGS)    {
pike.git/src/interpret.c:2107:    args=num_args;    }    }       clear_svalues(sp, num_locals - args);    sp += num_locals - args;   #ifdef PIKE_DEBUG    if(num_locals < num_args)    fatal("Wrong number of arguments or locals in function def.\n");   #endif -  new_frame.num_locals=num_locals; -  new_frame.num_args=num_args; +  new_frame->num_locals=num_locals; +  new_frame->num_args=num_args;       check_threads_etc();       {    struct svalue **save_mark_sp=mark_sp;    tailrecurse=eval_instruction(pc);   #ifdef PIKE_DEBUG    if(mark_sp < save_mark_sp)    fatal("Popped below save_mark_sp!\n");   #endif
pike.git/src/interpret.c:2156: Inside #if defined(PROFILING), #if defined(HAVE_GETHRTIME) and #if defined(PIKE_DEBUG)
   (long)(start_time/100000)    );   #endif    function->total_time=self_time_base + (INT32)(time_passed /1000);    function->self_time+=(INT32)( self_time /1000);    }   #endif   #endif      #if 0 -  if(sp - new_frame.locals > 1) +  if(sp - new_frame->locals > 1)    { -  pop_n_elems(sp - new_frame.locals -1); -  }else if(sp - new_frame.locals < 1){ +  pop_n_elems(sp - new_frame->locals -1); +  }else if(sp - new_frame->locals < 1){   #ifdef PIKE_DEBUG -  if(sp - new_frame.locals<0) fatal("Frame underflow.\n"); +  if(sp - new_frame->locals<0) fatal("Frame underflow.\n");   #endif    sp->u.integer = 0;    sp->subtype=NUMBER_NUMBER;    sp->type = T_INT;    sp++;    }   #endif    -  if(new_frame.context.parent) free_object(new_frame.context.parent); -  free_object(new_frame.current_object); -  free_program(new_frame.context.prog); + #ifdef PIKE_DEBUG +  if(fp!=new_frame) +  fatal("Frame stack out of whack!\n"); + #endif    -  fp = new_frame.parent_frame; +  POP_PIKE_FRAME();       if(tailrecurse>=0)    {    args=tailrecurse;    goto apply_stack;    }       }    }   
pike.git/src/interpret.c:2249:   }      void f_call_function(INT32 args)   {    mega_apply(APPLY_STACK,args,0,0);   }      int apply_low_safe_and_stupid(struct object *o, INT32 offset)   {    JMP_BUF tmp; -  struct frame new_frame; +  struct pike_frame *new_frame=alloc_pike_frame();    int ret;    -  new_frame.parent_frame = fp; -  new_frame.current_object = o; -  new_frame.context=o->prog->inherits[0]; -  new_frame.locals = evaluator_stack; -  new_frame.expendible=new_frame.locals; -  new_frame.args = 0; -  new_frame.num_args=0; -  new_frame.num_locals=0; -  new_frame.fun = -1; -  new_frame.pc = 0; -  new_frame.current_storage=o->storage; -  new_frame.context.parent=0; -  fp = & new_frame; +  new_frame->next = fp; +  new_frame->current_object = o; +  new_frame->context=o->prog->inherits[0]; +  new_frame->locals = evaluator_stack; +  new_frame->expendible=new_frame->locals; +  new_frame->args = 0; +  new_frame->num_args=0; +  new_frame->num_locals=0; +  new_frame->fun = -1; +  new_frame->pc = 0; +  new_frame->current_storage=o->storage; +  new_frame->context.parent=0; +  fp = new_frame;    -  add_ref(new_frame.current_object); -  add_ref(new_frame.context.prog); +  add_ref(new_frame->current_object); +  add_ref(new_frame->context.prog);       if(SETJMP(tmp))    {    ret=1;    }else{    int tmp=eval_instruction(o->prog->program + offset);    if(tmp!=-1) mega_apply(APPLY_STACK, tmp, 0,0);      #ifdef PIKE_DEBUG    if(sp<evaluator_stack)    fatal("Stack error (simple).\n");   #endif    ret=0;    }    UNSETJMP(tmp);    -  free_object(new_frame.current_object); -  free_program(new_frame.context.prog); +  POP_PIKE_FRAME();    -  fp=new_frame.parent_frame; +     return ret;   }      void safe_apply_low(struct object *o,int fun,int args)   {    JMP_BUF recovery;       sp-=args;    free_svalue(& throw_value);    throw_value.type=T_INT;
pike.git/src/interpret.c:2394: Inside #if defined(PIKE_DEBUG)
   if(sp < (expected_stack + evaluator_stack))    fatal("Stack underflow!\n");   #endif    }   }      #ifdef PIKE_DEBUG   void slow_check_stack(void)   {    struct svalue *s,**m; -  struct frame *f; +  struct pike_frame *f;       debug_check_stack();       if(sp > &(evaluator_stack[stack_size]))    fatal("Stack overflow.\n");       if(mark_sp > &(mark_stack[stack_size]))    fatal("Mark stack overflow.\n");       if(mark_sp < mark_stack)
pike.git/src/interpret.c:2421: Inside #if defined(PIKE_DEBUG)
   {    if(*m < s)    fatal("Mark stack failiure.\n");       s=*m;    }       if(s > &(evaluator_stack[stack_size]))    fatal("Mark stack exceeds svalue stack\n");    -  for(f=fp;f;f=f->parent_frame) +  for(f=fp;f;f=f->next)    {    if(f->locals)    {    if(f->locals < evaluator_stack ||    f->locals > &(evaluator_stack[stack_size]))    fatal("Local variable pointer points to FinspĂ„ng.\n");       if(f->args < 0 || f->args > stack_size) -  fatal("FEL FEL FEL! HELP!! (corrupted frame)\n"); +  fatal("FEL FEL FEL! HELP!! (corrupted pike_frame)\n");    }    }   }   #endif      void cleanup_interpret(void)   {   #ifdef PIKE_DEBUG    int e;   #endif       while(fp)    { -  free_object(fp->current_object); -  free_program(fp->context.prog); -  -  fp = fp->parent_frame; +  struct pike_frame *tmp=fp; +  fp=tmp->next; +  tmp->next=0; +  free_pike_frame(tmp);    }      #ifdef PIKE_DEBUG    for(e=0;e<BACKLOG;e++)    {    if(backlog[e].program)    {    free_program(backlog[e].program);    backlog[e].program=0;    }