pike.git / src / interpret.h

version» Context lines:

pike.git/src/interpret.h:5:   */      #ifndef INTERPRET_H   #define INTERPRET_H      #include "global.h"   #include "program.h"   #include "pike_error.h"   #include "object.h"   #include "pike_rusage.h" + #include "pikecode.h"      struct catch_context   {    struct catch_context *prev;    JMP_BUF recovery; -  struct svalue *save_expendible; +     PIKE_OPCODE_T *next_addr;    ptrdiff_t continue_reladdr;   #ifdef PIKE_DEBUG    struct pike_frame *frame;   #endif   };      struct Pike_interpreter_struct {    /* Swapped variables */    struct svalue *stack_pointer;
pike.git/src/interpret.h:54:   #endif       int trace_level;   };      #ifndef STRUCT_FRAME_DECLARED   #define STRUCT_FRAME_DECLARED   #endif   struct pike_frame   { -  INT32 refs;/* must be first */ -  -  /* The folloing fields are only used during setup and teardown */ +  GC_MARKER_MEMBERS;    unsigned INT16 fun; /** Function number. */    INT16 ident; /** Function identifier offset */    -  +  /* The folloing fields are only used during setup and teardown */ +     struct pike_frame *next; /** parent frame */    struct pike_frame *scope; /** scope */    struct svalue **save_mark_sp; /** saved mark sp level */       PIKE_OPCODE_T *pc; /** Address of current opcode. */    struct svalue *locals; /** Start of local variables. */    char *current_storage; /** == current_object->storage + context->storage_offset */    struct object *current_object;    struct inherit *context; /** inherit context */    struct program *current_program; /* program containing the context. */
pike.git/src/interpret.h:83:    * If PIKE_FRAME_SAVE_LOCALS is set, this is a pointer to a bitmask    * represented by an array of 16-bit ints. A set bit indicates that    * the corresponding local variable is used from a subscope and    * needs to be preserved in LOW_POP_PIKE_FRAME. The least    * significant bit of the first entry represents the first local    * variable and so on. The array is (num_locals >> 4) + 1 entries    * (i.e. it will always have enough space to represent all    * locals). */    unsigned INT16 *save_locals_bitmask;    -  unsigned INT16 flags; /** PIKE_FRAME_* */ +     /**    * This tells us the current level of svalues on the stack that can    * be discarded once the current function is done with them. It is an offset    * from locals and is always positive.    */ -  INT16 expendible_offset; +     INT16 num_locals; /** Number of local variables. */    INT16 num_args; /** Number of argument variables. */       INT32 args; /** Actual number of arguments passed to the function. */ -  +  +  unsigned INT16 flags; /** PIKE_FRAME_* */ +     /**    * This is an offset from locals and denotes the place where the return value    * should go.    *    * It can be -1 if the function to be called is on the stack.    * It can be even more negative in case of recursion when the return value location    * get replaced by that of the previous frame.    */    INT16 save_sp_offset;   
pike.git/src/interpret.h:123:      static inline void frame_set_save_sp(struct pike_frame *frame, struct svalue *sv) {    ptrdiff_t n = sv - frame->locals;   #ifdef PIKE_DEBUG    if (n < MIN_INT16 || n > MAX_INT16)    Pike_error("Save SP offset too large.\n");   #endif    frame->save_sp_offset = n;   }    - static inline struct svalue *frame_get_expendible(const struct pike_frame *frame) { -  return frame->locals + frame->expendible_offset; - } -  - static inline void frame_set_expendible(struct pike_frame *frame, struct svalue *sv) { -  ptrdiff_t n = sv - frame->locals; - #ifdef PIKE_DEBUG -  if (n < MIN_INT16 || n > MAX_INT16) -  Pike_error("Expendible offset too large.\n"); - #endif -  frame->expendible_offset = n; - } -  +    #define PIKE_FRAME_RETURN_INTERNAL 1   #define PIKE_FRAME_RETURN_POP 2   #define PIKE_FRAME_SAVE_LOCALS 0x4000 /* save_locals_bitmask is set */   #define PIKE_FRAME_MALLOCED_LOCALS 0x8000    -  + #define PIKE_FRAME_RETURN_MASK (PIKE_FRAME_RETURN_INTERNAL|PIKE_FRAME_RETURN_POP) + #define PIKE_FRAME_LOCALS_MASK (PIKE_FRAME_SAVE_LOCALS|PIKE_FRAME_MALLOCED_LOCALS) +    struct external_variable_context   {    struct object *o;    struct inherit *inherit;    int parent_identifier;   };    - #ifdef HAVE_COMPUTED_GOTO - extern PIKE_OPCODE_T *fcode_to_opcode; - extern struct op_2_f { -  PIKE_OPCODE_T opcode; -  INT32 fcode; - } *opcode_to_fcode; - #endif /* HAVE_COMPUTED_GOTO */ +             #ifdef PIKE_DEBUG   PMOD_EXPORT extern const char msg_stack_error[];   #define debug_check_stack() do{if(Pike_sp<Pike_interpreter.evaluator_stack)Pike_fatal("%s", msg_stack_error);}while(0)   #define check__positive(X,Y) if((X)<0) Pike_fatal Y   #else   #define check__positive(X,Y)   #define debug_check_stack()
pike.git/src/interpret.h:214:    Pike_interpreter.c_stack_margin + (MIN_BYTES)); */ \    }); \    }while(0)      #define fatal_check_c_stack(MIN_BYTES) do { \    low_check_c_stack ((MIN_BYTES), { \    ((void (*)(const char*, ...))Pike_fatal)(Pike_check_c_stack_errmsg); \    }); \    }while(0)    + PMOD_EXPORT extern void check_c_stack_margin(void);      #ifdef PIKE_DEBUG   #define STACK_LEVEL_START(depth) \    do { \    struct svalue *save_stack_level = (Pike_sp - (depth))      #define STACK_LEVEL_DONE(depth) \    STACK_LEVEL_CHECK(depth); \    } while(0)   
pike.git/src/interpret.h:399:    FLOAT_TYPE _=(F); \    struct svalue *_sp_ = Pike_sp++; \    SET_SVAL_TYPE_CHECKER(*_sp_, PIKE_T_FLOAT); \    _sp_->u.float_number=_; \    }while(0)      PMOD_EXPORT extern void push_text( const char *x );   PMOD_EXPORT extern void push_static_text( const char *x );      #define push_constant_text(T) do{ \ -  struct svalue *_sp_ = Pike_sp++; \ +  struct svalue *_sp_ = Pike_sp; \    SET_SVAL_TYPE_SUBTYPE(*_sp_, PIKE_T_STRING,0); \    REF_MAKE_CONST_STRING(_sp_->u.string,T); \ -  +  Pike_sp = _sp_ + 1; \    }while(0)      #define push_constant_string_code(STR, CODE) do{ \    struct pike_string *STR; \    REF_MAKE_CONST_STRING_CODE (STR, CODE); \    push_string (STR); \    }while(0)      #define push_function(OBJ, FUN) do { \ -  +  INT16 _fun_ = (FUN); \    struct object *_=(OBJ); \    struct svalue *_sp_ = Pike_sp++; \    debug_malloc_touch(_); \ -  SET_SVAL_TYPE_SUBTYPE(*_sp_, PIKE_T_FUNCTION,(FUN)); \ +  SET_SVAL_TYPE_SUBTYPE(*_sp_, PIKE_T_FUNCTION, _fun_); \    _sp_->u.object=_; \    } while (0)      #define ref_push_program(P) do{ \    struct program *_=(P); \    struct svalue *_sp_ = Pike_sp++; \    add_ref(_); \    SET_SVAL_TYPE_CHECKER(*_sp_, PIKE_T_PROGRAM); \    _sp_->u.program=_; \    }while(0)
pike.git/src/interpret.h:473:    struct pike_type *_=(S); \    struct svalue *_sp_ = Pike_sp++; \    add_ref(_); \    SET_SVAL_TYPE_SUBTYPE(*_sp_, PIKE_T_TYPE,0); \    _sp_->u.type=_; \    }while(0)      #define ref_push_object(O) ref_push_object_inherit(O,0)      #define ref_push_object_inherit(O, INH_NUM) do{ \ +  INT16 _inherit_ = (INH_NUM); \    struct object *_ = (O); \    struct svalue *_sp_ = Pike_sp++; \    add_ref(_); \ -  SET_SVAL_TYPE_SUBTYPE(*_sp_, PIKE_T_OBJECT, (INH_NUM)); \ +  SET_SVAL_TYPE_SUBTYPE(*_sp_, PIKE_T_OBJECT, _inherit_); \    _sp_->u.object = _; \    }while(0)      #define ref_push_function(OBJ, FUN) do { \ -  +  INT16 _fun_ = (FUN); \    struct object *_=(OBJ); \    struct svalue *_sp_ = Pike_sp++; \    add_ref(_); \ -  SET_SVAL_TYPE_SUBTYPE(*_sp_, PIKE_T_FUNCTION,(FUN)); \ +  SET_SVAL_TYPE_SUBTYPE(*_sp_, PIKE_T_FUNCTION, _fun_); \    _sp_->u.object=_; \    } while (0)      #define push_svalue(S) do { \    const struct svalue *_=(S); \ -  struct svalue *_sp_ = Pike_sp++; \ +  struct svalue *_sp_ = Pike_sp; \    assign_svalue_no_free(_sp_,_); \ -  +  Pike_sp = _sp_ + 1; \    }while(0)      #define stack_dup() push_svalue(Pike_sp-1)      #define stack_swap() do { \    struct svalue *_sp_ = Pike_sp; \    struct svalue _=_sp_[-1]; \    _sp_[-1]=_sp_[-2]; \    _sp_[-2]=_; \    } while(0)
pike.git/src/interpret.h:546:    } \    Pike_sp=s_; \   }while(0)         #define free_pike_frame(F) do{ struct pike_frame *f_=(F); if(!sub_ref(f_)) really_free_pike_frame(f_); }while(0)      /* A scope is any frame which may have malloced locals */   #define free_pike_scope(F) do{ struct pike_frame *f_=(F); if(!sub_ref(f_)) really_free_pike_scope(f_); }while(0)    - /* Without fancy accounting stuff. This one can't assume there is an -  * identifier corresponding to the frame (i.e. _fp_->ident might be -  * bogus). */ - #define LOW_POP_PIKE_FRAME(_fp_) do { \ -  struct pike_frame *tmp_=_fp_->next; \ -  if(!sub_ref(_fp_)) \ -  { \ -  really_free_pike_frame(_fp_); \ -  }else{ \ -  ptrdiff_t exp_offset = _fp_->expendible_offset; \ -  DO_IF_DEBUG( \ -  if( (_fp_->locals + _fp_->num_locals > Pike_sp) || \ -  (Pike_sp < _fp_->locals + _fp_->expendible_offset) || \ -  (exp_offset < 0) || (exp_offset > _fp_->num_locals)) \ -  Pike_fatal("Stack failure in POP_PIKE_FRAME %p+%d=%p %p %hd!\n", \ -  _fp_->locals, _fp_->num_locals, \ -  _fp_->locals+_fp_->num_locals, \ -  Pike_sp,_fp_->expendible_offset)); \ -  debug_malloc_touch(_fp_); \ -  if (exp_offset || (_fp_->flags & PIKE_FRAME_SAVE_LOCALS)) { \ -  struct svalue *locals = _fp_->locals; \ -  struct svalue *s; \ -  INT16 num_new_locals = 0; \ -  unsigned int num_bitmask_entries = 0; \ -  if(_fp_->flags & PIKE_FRAME_SAVE_LOCALS) { \ -  ptrdiff_t offset; \ -  for (offset = 0; \ -  offset < (ptrdiff_t)((_fp_->num_locals >> 4) + 1); \ -  offset++) { \ -  if (*(_fp_->save_locals_bitmask + offset)) \ -  num_bitmask_entries = offset + 1; \ -  } \ -  } \ -  \ -  num_new_locals = MAXIMUM(exp_offset, num_bitmask_entries << 4); \ -  \ -  s=(struct svalue *)xalloc(sizeof(struct svalue)* \ -  num_new_locals); \ -  memset(s, 0, sizeof(struct svalue) * num_new_locals); \ -  \ -  { \ -  int idx; \ -  unsigned INT16 bitmask=0; \ -  \ -  for (idx = 0; idx < num_new_locals; idx++) { \ -  if (!(idx % 16)) { \ -  ptrdiff_t offset = (ptrdiff_t)(idx >> 4); \ -  if (offset < num_bitmask_entries) { \ -  bitmask = *(_fp_->save_locals_bitmask + offset); \ -  } else { \ -  bitmask = 0; \ -  } \ -  } \ -  if (bitmask & (1 << (idx % 16)) || idx < exp_offset) { \ -  assign_svalue_no_free(s + (ptrdiff_t)idx, \ -  locals + (ptrdiff_t)idx); \ -  } \ -  } \ -  } \ -  _fp_->flags &= ~PIKE_FRAME_SAVE_LOCALS; \ -  free(_fp_->save_locals_bitmask); \ -  _fp_->num_locals = num_new_locals; \ -  _fp_->locals=s; \ -  _fp_->flags|=PIKE_FRAME_MALLOCED_LOCALS; \ -  } else { \ -  _fp_->locals=0; \ -  } \ -  _fp_->next=0; \ -  } \ -  Pike_fp=tmp_; \ -  } while (0) -  - #define POP_PIKE_FRAME() do { \ -  struct pike_frame *_fp_ = Pike_fp; \ -  DO_IF_PROFILING({ \ -  /* Time spent in this frame + children. */ \ -  cpu_time_t time_passed = \ -  get_cpu_time() - Pike_interpreter.unlocked_time; \ -  /* Time spent in children to this frame. */ \ -  cpu_time_t time_in_children; \ -  /* Time spent in just this frame. */ \ -  cpu_time_t self_time; \ -  struct identifier *function; \ -  W_PROFILING_DEBUG("%p}: Pop got %" PRINT_CPU_TIME \ -  " (%" PRINT_CPU_TIME ")" \ -  " %" PRINT_CPU_TIME " (%" PRINT_CPU_TIME ")\n", \ -  Pike_interpreter.thread_state, time_passed, \ -  _fp_->start_time, \ -  Pike_interpreter.accounted_time, \ -  _fp_->children_base); \ -  time_passed -= _fp_->start_time; \ -  DO_IF_DEBUG(if (time_passed < 0) { \ -  Pike_fatal("Negative time_passed: %" PRINT_CPU_TIME \ -  " now: %" PRINT_CPU_TIME \ -  " unlocked_time: %" PRINT_CPU_TIME \ -  " start_time: %" PRINT_CPU_TIME \ -  "\n", time_passed, get_cpu_time(), \ -  Pike_interpreter.unlocked_time, \ -  _fp_->start_time); \ -  }); \ -  time_in_children = \ -  Pike_interpreter.accounted_time - _fp_->children_base; \ -  DO_IF_DEBUG(if (time_in_children < 0) { \ -  Pike_fatal("Negative time_in_children: %" \ -  PRINT_CPU_TIME \ -  " accounted_time: %" PRINT_CPU_TIME \ -  " children_base: %" PRINT_CPU_TIME \ -  "\n", time_in_children, \ -  Pike_interpreter.accounted_time, \ -  _fp_->children_base); \ -  }); \ -  self_time = time_passed - time_in_children; \ -  DO_IF_DEBUG(if (self_time < 0) { \ -  Pike_fatal("Negative self_time: %" PRINT_CPU_TIME \ -  " time_passed: %" PRINT_CPU_TIME \ -  " time_in_children: %" PRINT_CPU_TIME \ -  "\n", self_time, time_passed, \ -  time_in_children); \ -  }); \ -  Pike_interpreter.accounted_time += self_time; \ -  /* FIXME: Can context->prog be NULL? */ \ -  function = _fp_->context->prog->identifiers + _fp_->ident; \ -  if (!--function->recur_depth) \ -  function->total_time += time_passed; \ -  function->self_time += self_time; \ -  }); \ -  LOW_POP_PIKE_FRAME (_fp_); \ -  }while(0) -  +    #define ASSIGN_CURRENT_STORAGE(VAR, TYPE, INH, EXPECTED_PROGRAM) \    do { \    int inh__ = (INH); \    DO_IF_DEBUG( \    struct program *prog__ = (EXPECTED_PROGRAM); \    if ((inh__ < 0) || \    (inh__ >= Pike_fp->context->prog->num_inherits)) \    Pike_fatal("Inherit #%d out of range [0..%d]\n", \    inh__, Pike_fp->context->prog->num_inherits-1); \    if (prog__ && (Pike_fp->context[inh__].prog != prog__)) \
pike.git/src/interpret.h:701:         enum apply_type   {    APPLY_STACK, /* The function is the first argument */    APPLY_SVALUE, /* arg1 points to an svalue containing the function */    APPLY_SVALUE_STRICT, /* Like APPLY_SVALUE, but does not return values for void functions */    APPLY_LOW /* arg1 is the object pointer,(int)arg2 the function */   };    - #define APPLY_MASTER(FUN,ARGS) \ - do{ \ -  static int fun_, master_cnt=0; \ -  struct object *master_ob=master(); \ -  if(master_cnt != master_ob->prog->id) \ -  { \ -  fun_=find_identifier(FUN,master_ob->prog); \ -  master_cnt = master_ob->prog->id; \ -  } \ -  if (fun_ >= 0) { \ -  apply_low(master_ob, fun_, ARGS); \ -  } else { \ -  Pike_error("Cannot call undefined function \"%s\" in master.\n", FUN); \ -  } \ - }while(0) + PMOD_EXPORT void apply_master(const char* fun, INT32 args, int mode); + #define APPLY_MASTER(FUN,ARGS) apply_master(FUN,ARGS,1) + #define SAFE_APPLY_MASTER(FUN,ARGS) apply_master(FUN,ARGS,2) + #define SAFE_MAYBE_APPLY_MASTER(FUN,ARGS) apply_master(FUN,ARGS,3);    - #define SAFE_APPLY_MASTER(FUN,ARGS) \ - do{ \ -  static int fun_, master_cnt=0; \ -  struct object *master_ob=master(); \ -  if(master_cnt != master_ob->prog->id) \ -  { \ -  fun_=find_identifier(FUN,master_ob->prog); \ -  master_cnt = master_ob->prog->id; \ -  } \ -  safe_apply_low2(master_ob, fun_, ARGS, FUN); \ - }while(0) -  +    #define SAFE_APPLY_HANDLER(FUN, HANDLER, COMPAT, ARGS) do { \    static int h_fun_=-1, h_id_=0; \    static int c_fun_=-1, c_fun_id_=0; \    struct object *h_=(HANDLER), *c_=(COMPAT); \    if (h_ && h_->prog) { \    if (h_->prog->id != h_id_) { \    h_fun_ = find_identifier(fun, h_->prog); \    h_id_ = h_->prog->id; \    } \    if (h_fun_ != -1) { \
pike.git/src/interpret.h:841: Inside #if defined(PIKE_USE_MACHINE_CODE)
     #ifdef PIKE_USE_MACHINE_CODE   void call_check_threads_etc(void);   #if defined(OPCODE_INLINE_BRANCH) || defined(INS_F_JUMP) || \    defined(INS_F_JUMP_WITH_ARG) || defined(INS_F_JUMP_WITH_TWO_ARGS)   void branch_check_threads_etc(void);   #endif   #ifdef OPCODE_INLINE_RETURN   PIKE_OPCODE_T *inter_return_opcode_F_CATCH(PIKE_OPCODE_T *addr);   #endif + #ifdef OPCODE_INLINE_CATCH + PIKE_OPCODE_T *setup_catch_context(PIKE_OPCODE_T *addr); + PIKE_OPCODE_T *handle_caught_exception(void); + #endif   #ifdef PIKE_DEBUG   void simple_debug_instr_prologue_0 (PIKE_INSTR_T instr);   void simple_debug_instr_prologue_1 (PIKE_INSTR_T instr, INT32 arg);   void simple_debug_instr_prologue_2 (PIKE_INSTR_T instr, INT32 arg1, INT32 arg2);   #endif   #endif /* PIKE_USE_MACHINE_CODE */      PMOD_EXPORT void find_external_context(struct external_variable_context *loc,    int arg2);   struct pike_frame *alloc_pike_frame(void); -  + void LOW_POP_PIKE_FRAME_slow_path(struct pike_frame *frame);   void really_free_pike_scope(struct pike_frame *scope);   void *lower_mega_apply( INT32 args, struct object *o, ptrdiff_t fun );   void *low_mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2);   void low_return(void);   void low_return_pop(void);   void unlink_previous_frame(void);   int apply_low_safe_and_stupid(struct object *o, INT32 offset);      PMOD_EXPORT struct Pike_interpreter_struct * pike_get_interpreter_pointer();   PMOD_EXPORT void mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2);
pike.git/src/interpret.h:965:    Pike_interpreter.current_stack=allocate_array(MAXIMUM(num, 8192)); \    while(old_sp > base) *(Pike_sp++) = *--old_stack_->save_ptr; \    }      #define PIKE_STACK_REQUIRE_END() \    while(Pike_sp > Pike_interpreter.current_stack->stack) \    *(old_stack_->save_ptr++) = *--Pike_sp; \    Pike_interpreter.current_stack=Pike_interpreter.current_stack->previous; \   }while(0)    +  +  + /* Without fancy accounting stuff. This one can't assume there is an +  * identifier corresponding to the frame (i.e. _fp_->ident might be +  * bogus). */ + PIKE_UNUSED_ATTRIBUTE + static inline void LOW_POP_PIKE_FRAME(struct pike_frame *frame) + { +  struct pike_frame *tmp = frame->next; +  +  if (LIKELY(!sub_ref(frame))) +  really_free_pike_frame(frame); +  else +  LOW_POP_PIKE_FRAME_slow_path(frame); +  +  Pike_fp = tmp; + } +  + PIKE_UNUSED_ATTRIBUTE + static inline void POP_PIKE_FRAME(void) { +  struct pike_frame *frame = Pike_fp; + #ifdef PROFILING +  /* Time spent in this frame + children. */ +  cpu_time_t time_passed = get_cpu_time() - Pike_interpreter.unlocked_time; +  /* Time spent in children to this frame. */ +  cpu_time_t time_in_children; +  /* Time spent in just this frame. */ +  cpu_time_t self_time; +  struct identifier *function; +  W_PROFILING_DEBUG("%p}: Pop got %" PRINT_CPU_TIME +  " (%" PRINT_CPU_TIME ")" +  " %" PRINT_CPU_TIME " (%" PRINT_CPU_TIME ")n", +  Pike_interpreter.thread_state, time_passed, +  frame->start_time, +  Pike_interpreter.accounted_time, +  frame->children_base); +  time_passed -= frame->start_time; + # ifdef PIKE_DEBUG +  if (time_passed < 0) { +  Pike_fatal("Negative time_passed: %" PRINT_CPU_TIME +  " now: %" PRINT_CPU_TIME +  " unlocked_time: %" PRINT_CPU_TIME +  " start_time: %" PRINT_CPU_TIME +  "n", time_passed, get_cpu_time(), +  Pike_interpreter.unlocked_time, +  frame->start_time); +  } + # endif /* PIKE_DEBUG */ +  time_in_children = Pike_interpreter.accounted_time - frame->children_base; + # ifdef PIKE_DEBUG +  if (time_in_children < 0) { +  Pike_fatal("Negative time_in_children: %" +  PRINT_CPU_TIME +  " accounted_time: %" PRINT_CPU_TIME +  " children_base: %" PRINT_CPU_TIME +  "n", time_in_children, +  Pike_interpreter.accounted_time, +  frame->children_base); +  } + # endif /* PIKE_DEBUG */ +  self_time = time_passed - time_in_children; + # ifdef PIKE_DEBUG +  if (self_time < 0) { +  Pike_fatal("Negative self_time: %" PRINT_CPU_TIME +  " time_passed: %" PRINT_CPU_TIME +  " time_in_children: %" PRINT_CPU_TIME +  "n", self_time, time_passed, +  time_in_children); +  } + # endif /* PIKE_DEBUG */ +  Pike_interpreter.accounted_time += self_time; +  /* FIXME: Can context->prog be NULL? */ +  function = frame->context->prog->identifiers + frame->ident; +  if (!--function->recur_depth) +  function->total_time += time_passed; +  function->self_time += self_time; + #endif /* PROFILING */ +  +  LOW_POP_PIKE_FRAME (frame); + } +    #endif