e576bb2002-10-11Martin Nilsson /* || 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.
0edf502003-12-05Henrik Grubbström (Grubba) || $Id: interpret.h,v 1.145 2003/12/05 13:35:10 grubba Exp $
e576bb2002-10-11Martin Nilsson */
24ddc71998-03-28Henrik Grubbström (Grubba) 
5267b71995-08-09Fredrik Hübinette (Hubbe) #ifndef INTERPRET_H #define INTERPRET_H
442aea1997-01-28Fredrik Hübinette (Hubbe) #include "global.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "program.h"
b2d3e42000-12-01Fredrik Hübinette (Hubbe) #include "pike_error.h"
92c73b2001-11-08Fredrik Hübinette (Hubbe) #include "bignum.h"
ec2bab2000-06-24Fredrik Hübinette (Hubbe)  struct Pike_interpreter { /* Swapped variables */
5923b12000-07-06Fredrik Hübinette (Hubbe)  struct svalue *stack_pointer; struct svalue *evaluator_stack;
17f08c2000-07-06Fredrik Hübinette (Hubbe)  struct svalue **mark_stack_pointer;
5923b12000-07-06Fredrik Hübinette (Hubbe)  struct svalue **mark_stack; struct pike_frame *frame_pointer;
ec2bab2000-06-24Fredrik Hübinette (Hubbe)  int evaluator_stack_malloced; int mark_stack_malloced; JMP_BUF *recoveries;
f077582000-07-06Fredrik Hübinette (Hubbe) #ifdef PIKE_THREADS
0431312003-02-15Henrik Grubbström (Grubba)  struct thread_state *thread_state;
f077582000-07-06Fredrik Hübinette (Hubbe) #endif
5923b12000-07-06Fredrik Hübinette (Hubbe)  char *stack_top;
ec2bab2000-06-24Fredrik Hübinette (Hubbe)  DO_IF_SECURITY(struct object *current_creds;)
6697042000-11-20Martin Stjernholm  int svalue_stack_margin; int c_stack_margin;
ec2bab2000-06-24Fredrik Hübinette (Hubbe) #ifdef PROFILING #ifdef HAVE_GETHRTIME long long accounted_time; long long time_base; #endif
0612442001-05-16Fredrik Hübinette (Hubbe)  char *stack_bottom;
ec2bab2000-06-24Fredrik Hübinette (Hubbe) #endif
6198092003-01-08Martin Stjernholm  int trace_level;
ec2bab2000-06-24Fredrik Hübinette (Hubbe) };
5267b71995-08-09Fredrik Hübinette (Hubbe) 
dfa5b31996-12-05Fredrik Hübinette (Hubbe) #ifndef STRUCT_FRAME_DECLARED #define STRUCT_FRAME_DECLARED #endif
4218011999-01-31Fredrik Hübinette (Hubbe) struct pike_frame
5267b71995-08-09Fredrik Hübinette (Hubbe) {
6e21a52000-08-09Henrik Grubbström (Grubba)  INT32 refs; /* must be first */
9900ef2002-11-23Henrik Grubbström (Grubba)  INT32 args; /* Actual number of arguments. */ unsigned INT16 fun; /* Function number. */ INT16 num_locals; /* Number of local variables. */ INT16 num_args; /* Number of argument variables. */ unsigned INT16 flags; /* PIKE_FRAME_* */
207f562001-05-13Fredrik Hübinette (Hubbe)  INT16 ident;
4218011999-01-31Fredrik Hübinette (Hubbe)  struct pike_frame *next; struct pike_frame *scope;
9900ef2002-11-23Henrik Grubbström (Grubba)  PIKE_OPCODE_T *pc; /* Program counter of last/next opcode. */ struct svalue *locals; /* Start of local variables. */
9ddbf22001-05-10Fredrik Hübinette (Hubbe)  /* This is <= locals, and this is where the * return value should go. */ struct svalue *save_sp; /* This tells us the current level of * svalues on the stack that can be discarded once the * current function is done with them */
5017631998-06-05Fredrik Hübinette (Hubbe)  struct svalue *expendible;
9ddbf22001-05-10Fredrik Hübinette (Hubbe)  struct svalue **save_mark_sp; struct svalue **mark_sp_base;
5267b71995-08-09Fredrik Hübinette (Hubbe)  struct object *current_object;
9ddbf22001-05-10Fredrik Hübinette (Hubbe) 
92fb222001-05-13Fredrik Hübinette (Hubbe)  DO_IF_SECURITY(struct object *current_creds;)
9ddbf22001-05-10Fredrik Hübinette (Hubbe) #if defined(PROFILING) && defined(HAVE_GETHRTIME) long long children_base; long long start_time; INT32 self_time_base; #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  struct inherit context; char *current_storage; };
9ddbf22001-05-10Fredrik Hübinette (Hubbe) #define PIKE_FRAME_RETURN_INTERNAL 1 #define PIKE_FRAME_RETURN_POP 2 #define PIKE_FRAME_MALLOCED_LOCALS 0x8000
342fef2000-08-23Fredrik Hübinette (Hubbe) struct external_variable_context { struct object *o; struct inherit *inherit; int parent_identifier; };
7df3482001-07-21Henrik Grubbström (Grubba) #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 */
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
c299402001-11-10Martin Stjernholm PMOD_EXPORT extern const char msg_stack_error[];
5aad932002-08-15Marcus Comstedt #define debug_check_stack() do{if(Pike_sp<Pike_interpreter.evaluator_stack)Pike_fatal(msg_stack_error);}while(0) #define check__positive(X,Y) if((X)<0) Pike_fatal Y
b2d3e42000-12-01Fredrik Hübinette (Hubbe) #include "pike_error.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #else
9649491998-02-27Fredrik Hübinette (Hubbe) #define check__positive(X,Y)
fa382f1996-06-21Fredrik Hübinette (Hubbe) #define debug_check_stack()
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif
fa382f1996-06-21Fredrik Hübinette (Hubbe) 
c915472000-12-04Martin Stjernholm #define low_stack_check(X) \ (Pike_sp - Pike_interpreter.evaluator_stack + \ Pike_interpreter.svalue_stack_margin + (X) >= Pike_stack_size)
c299402001-11-10Martin Stjernholm PMOD_EXPORT extern const char Pike_check_stack_errmsg[];
c915472000-12-04Martin Stjernholm 
6f95902000-08-17Henrik Grubbström (Grubba) #define check_stack(X) do { \
c915472000-12-04Martin Stjernholm  if(low_stack_check(X)) \
b1197a2000-12-28Henrik Grubbström (Grubba)  ((void (*)(const char *, ...))Pike_error)( \ Pike_check_stack_errmsg, \
c915472000-12-04Martin Stjernholm  PTRDIFF_T_TO_LONG(Pike_sp - Pike_interpreter.evaluator_stack), \ PTRDIFF_T_TO_LONG(Pike_stack_size), \ PTRDIFF_T_TO_LONG(X)); \
7e97c31999-01-21Fredrik Hübinette (Hubbe)  }while(0)
c299402001-11-10Martin Stjernholm PMOD_EXPORT extern const char Pike_check_mark_stack_errmsg[];
c915472000-12-04Martin Stjernholm 
7e97c31999-01-21Fredrik Hübinette (Hubbe) #define check_mark_stack(X) do { \
b1197a2000-12-28Henrik Grubbström (Grubba)  if(Pike_mark_sp - Pike_interpreter.mark_stack + (X) >= Pike_stack_size) \ ((void (*)(const char*, ...))Pike_error)(Pike_check_mark_stack_errmsg); \
7e97c31999-01-21Fredrik Hübinette (Hubbe)  }while(0)
c299402001-11-10Martin Stjernholm PMOD_EXPORT extern const char Pike_check_c_stack_errmsg[];
c915472000-12-04Martin Stjernholm 
6697042000-11-20Martin Stjernholm #define check_c_stack(X) do { \ ptrdiff_t x_= ((char *)&x_) + \ STACK_DIRECTION * (Pike_interpreter.c_stack_margin + (X)) - \ Pike_interpreter.stack_top ; \
7e97c31999-01-21Fredrik Hübinette (Hubbe)  x_*=STACK_DIRECTION; \ if(x_>0) \
b1197a2000-12-28Henrik Grubbström (Grubba)  ((void (*)(const char*, ...))low_error)(Pike_check_c_stack_errmsg); \
7e97c31999-01-21Fredrik Hübinette (Hubbe)  }while(0)
fffb2a2000-09-12Henrik Grubbström (Grubba) #define fatal_check_c_stack(X) do { \ ptrdiff_t x_= \ ((char *)&x_) + STACK_DIRECTION * (X) - Pike_interpreter.stack_top ; \ x_*=STACK_DIRECTION; \ if(x_>0) { \
5aad932002-08-15Marcus Comstedt  ((void (*)(const char*, ...))Pike_fatal)(Pike_check_c_stack_errmsg); \
fffb2a2000-09-12Henrik Grubbström (Grubba)  } \ }while(0)
7e97c31999-01-21Fredrik Hübinette (Hubbe) 
938a5d2002-10-12Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG #define STACK_LEVEL_START(depth) \ do { \
e7a7142002-11-23Martin Stjernholm  struct svalue *save_stack_level = (Pike_sp - (depth))
938a5d2002-10-12Henrik Grubbström (Grubba)  #define STACK_LEVEL_DONE(depth) \ STACK_LEVEL_CHECK(depth); \ } while(0) #define STACK_LEVEL_CHECK(depth) \ do { \ if (Pike_sp != save_stack_level + (depth)) { \ Pike_fatal("Unexpected stack level! " \ "Actual: %d, expected: %d\n", \ DO_NOT_WARN((int)(Pike_sp - save_stack_level)), \ (depth)); \ } \ } while(0) #else /* !PIKE_DEBUG */ #define STACK_LEVEL_START(depth) do { #define STACK_LEVEL_DONE(depth) } while(0) #define STACK_LEVEL_CHECK(depth) #endif /* PIKE_DEBUG */
15a05f2002-11-23Martin Stjernholm #define pop_stack() do{ free_svalue(--Pike_sp); debug_check_stack(); }while(0)
2ac9502001-08-14Fredrik Hübinette (Hubbe) #define pop_2_elems() do { pop_stack(); pop_stack(); }while(0)
2d12341997-03-10Fredrik Hübinette (Hubbe) 
2eaa402000-08-03Henrik Grubbström (Grubba) #ifdef __ECL #define MAYBE_CAST_TO_LONG(X) (X) #else /* !__ECL */ #define MAYBE_CAST_TO_LONG(X) ((long)(X)) #endif /* __ECL */
c299402001-11-10Martin Stjernholm PMOD_EXPORT extern const char msg_pop_neg[];
3469ac2000-08-03Henrik Grubbström (Grubba) #define pop_n_elems(X) \
87a4162003-04-27Martin Stjernholm  do { \ ptrdiff_t x_=(X); \ if(x_) { \ struct svalue *_sp_; \ check__positive(x_, (msg_pop_neg, x_)); \ _sp_ = Pike_sp = Pike_sp - x_; \ debug_check_stack(); \ free_mixed_svalues(_sp_, x_); \ } \ } while (0)
9649491998-02-27Fredrik Hübinette (Hubbe) 
a6d61a2003-04-25Martin Stjernholm /* This pops a number of arguments from the stack but keeps the top * element on top. Used for popping the arguments while keeping the * return value. */ #define stack_unlink(X) do { \
db17192003-04-27Martin Stjernholm  ptrdiff_t x2_ = (X); \ if (x2_) { \
87a4162003-04-27Martin Stjernholm  struct svalue *_sp_ = --Pike_sp; \
db17192003-04-27Martin Stjernholm  free_svalue (_sp_ - x2_); \ move_svalue (_sp_ - x2_, _sp_); \ pop_n_elems (x2_ - 1); \
a6d61a2003-04-25Martin Stjernholm  } \ }while(0) #define stack_pop_n_elems_keep_top(X) stack_unlink(X)
87a4162003-04-27Martin Stjernholm #define stack_pop_keep_top() do { \ struct svalue *_sp_ = --Pike_sp; \ free_svalue (_sp_ - 1); \
db17192003-04-27Martin Stjernholm  move_svalue (_sp_ - 1, _sp_); \
87a4162003-04-27Martin Stjernholm  debug_check_stack(); \ } while (0)
b0d33f2003-04-27Martin Stjernholm #define stack_pop_2_elems_keep_top() do { \ struct svalue *_sp_ = Pike_sp = Pike_sp - 2; \ free_svalue (_sp_ - 1); \ free_svalue (_sp_); \ move_svalue (_sp_ - 1, _sp_ + 1); \ debug_check_stack(); \ } while (0)
a6d61a2003-04-25Martin Stjernholm #define stack_pop_to_no_free(X) move_svalue(X, --Pike_sp) #define stack_pop_to(X) do { \ struct svalue *_=(X); \ free_svalue(_); \ stack_pop_to_no_free(_); \ }while(0) #define push_program(P) do{ \ struct program *_=(P); \
379c892003-04-25Martin Stjernholm  struct svalue *_sp_ = Pike_sp++; \
a6d61a2003-04-25Martin Stjernholm  debug_malloc_touch(_); \ _sp_->u.program=_; \ _sp_++->type=PIKE_T_PROGRAM; \ }while(0) #define push_int(I) do{ \ INT_TYPE _=(I); \
379c892003-04-25Martin Stjernholm  struct svalue *_sp_ = Pike_sp++; \
a6d61a2003-04-25Martin Stjernholm  _sp_->u.integer=_; \ _sp_->type=PIKE_T_INT; \ _sp_->subtype=NUMBER_NUMBER; \ }while(0) #define push_undefined() do{ \ struct svalue *_sp_ = Pike_sp++; \ _sp_->u.integer=0; \ _sp_->type=PIKE_T_INT; \ _sp_->subtype=NUMBER_UNDEFINED; \ }while(0) #define push_mapping(M) do{ \ struct mapping *_=(M); \
379c892003-04-25Martin Stjernholm  struct svalue *_sp_ = Pike_sp++; \
a6d61a2003-04-25Martin Stjernholm  debug_malloc_touch(_); \ _sp_->u.mapping=_; \ _sp_->type=PIKE_T_MAPPING; \ }while(0) #define push_array(A) do{ \ struct array *_=(A); \
379c892003-04-25Martin Stjernholm  struct svalue *_sp_ = Pike_sp++; \
a6d61a2003-04-25Martin Stjernholm  debug_malloc_touch(_); \ _sp_->u.array=_ ; \ _sp_->type=PIKE_T_ARRAY; \ }while(0) #define push_multiset(L) do{ \ struct multiset *_=(L); \
379c892003-04-25Martin Stjernholm  struct svalue *_sp_ = Pike_sp++; \
a6d61a2003-04-25Martin Stjernholm  debug_malloc_touch(_); \ _sp_->u.multiset=_; \ _sp_->type=PIKE_T_MULTISET; \ }while(0) #define push_string(S) do { \ struct pike_string *_=(S); \
379c892003-04-25Martin Stjernholm  struct svalue *_sp_ = Pike_sp++; \
a6d61a2003-04-25Martin Stjernholm  debug_malloc_touch(_); \ _sp_->subtype=0; \ _sp_->u.string=_; \ _sp_->type=PIKE_T_STRING; \ }while(0) #define push_type_value(S) do{ \ struct pike_type *_=(S); \
379c892003-04-25Martin Stjernholm  struct svalue *_sp_ = Pike_sp++; \
a6d61a2003-04-25Martin Stjernholm  debug_malloc_touch(_); \ _sp_->u.type=_; \ _sp_->type=PIKE_T_TYPE; \ }while(0) #define push_object(O) do { \ struct object *_=(O); \
379c892003-04-25Martin Stjernholm  struct svalue *_sp_ = Pike_sp++; \
a6d61a2003-04-25Martin Stjernholm  debug_malloc_touch(_); \ _sp_->u.object=_; \ _sp_->type=PIKE_T_OBJECT; \ }while(0) #define push_float(F) do{ \ FLOAT_TYPE _=(F); \
379c892003-04-25Martin Stjernholm  struct svalue *_sp_ = Pike_sp++; \
a6d61a2003-04-25Martin Stjernholm  _sp_->u.float_number=_; \ _sp_->type=PIKE_T_FLOAT; \ }while(0)
04925b1996-09-29Fredrik Hübinette (Hubbe) #define push_text(T) push_string(make_shared_string((T)))
0542ef1999-11-17Fredrik Hübinette (Hubbe) 
a6d61a2003-04-25Martin Stjernholm #define push_constant_text(T) do{ \ struct svalue *_sp_ = Pike_sp++; \ _sp_->subtype=0; \ REF_MAKE_CONST_STRING(_sp_->u.string,T); \ _sp_->type=PIKE_T_STRING; \ }while(0) #define push_function(OBJ, FUN) do { \ struct object *_=(OBJ); \
379c892003-04-25Martin Stjernholm  struct svalue *_sp_ = Pike_sp++; \
a6d61a2003-04-25Martin Stjernholm  debug_malloc_touch(_); \ _sp_->u.object=_; \ _sp_->subtype=(FUN); \ _sp_->type=PIKE_T_FUNCTION; \ } while (0) #define ref_push_program(P) do{ \ struct program *_=(P); \
379c892003-04-25Martin Stjernholm  struct svalue *_sp_ = Pike_sp++; \
a6d61a2003-04-25Martin Stjernholm  add_ref(_); \ _sp_->u.program=_; \ _sp_->type=PIKE_T_PROGRAM; \ }while(0) #define ref_push_mapping(M) do{ \ struct mapping *_=(M); \
379c892003-04-25Martin Stjernholm  struct svalue *_sp_ = Pike_sp++; \
a6d61a2003-04-25Martin Stjernholm  add_ref(_); \ _sp_->u.mapping=_; \ _sp_->type=PIKE_T_MAPPING; \ }while(0) #define ref_push_array(A) do{ \ struct array *_=(A); \
379c892003-04-25Martin Stjernholm  struct svalue *_sp_ = Pike_sp++; \
a6d61a2003-04-25Martin Stjernholm  add_ref(_); \ _sp_->u.array=_ ; \ _sp_->type=PIKE_T_ARRAY; \ }while(0) #define ref_push_multiset(L) do{ \ struct multiset *_=(L); \
379c892003-04-25Martin Stjernholm  struct svalue *_sp_ = Pike_sp++; \
a6d61a2003-04-25Martin Stjernholm  add_ref(_); \ _sp_->u.multiset=_; \ _sp_->type=PIKE_T_MULTISET; \ }while(0) #define ref_push_string(S) do{ \ struct pike_string *_=(S); \
379c892003-04-25Martin Stjernholm  struct svalue *_sp_ = Pike_sp++; \
a6d61a2003-04-25Martin Stjernholm  add_ref(_); \ _sp_->subtype=0; \ _sp_->u.string=_; \ _sp_->type=PIKE_T_STRING; \ }while(0) #define ref_push_type_value(S) do{ \ struct pike_type *_=(S); \
379c892003-04-25Martin Stjernholm  struct svalue *_sp_ = Pike_sp++; \
a6d61a2003-04-25Martin Stjernholm  add_ref(_); \ _sp_->u.type=_; \ _sp_->type=PIKE_T_TYPE; \ }while(0)
2d12341997-03-10Fredrik Hübinette (Hubbe) 
a6d61a2003-04-25Martin Stjernholm #define ref_push_object(O) do{ \ struct object *_=(O); \
379c892003-04-25Martin Stjernholm  struct svalue *_sp_ = Pike_sp++; \
a6d61a2003-04-25Martin Stjernholm  add_ref(_); \ _sp_->u.object=_; \ _sp_->type=PIKE_T_OBJECT; \ }while(0) #define ref_push_function(OBJ, FUN) do { \ struct object *_=(OBJ); \
379c892003-04-25Martin Stjernholm  struct svalue *_sp_ = Pike_sp++; \
a6d61a2003-04-25Martin Stjernholm  add_ref(_); \ _sp_->u.object=_; \ _sp_->subtype=(FUN); \ _sp_->type=PIKE_T_FUNCTION; \ } while (0) #define push_svalue(S) do { \ const struct svalue *_=(S); \
379c892003-04-25Martin Stjernholm  struct svalue *_sp_ = Pike_sp++; \
a6d61a2003-04-25Martin Stjernholm  assign_svalue_no_free(_sp_,_); \ }while(0)
5267b71995-08-09Fredrik Hübinette (Hubbe) 
a2ad152000-02-16Fredrik Hübinette (Hubbe) #define stack_dup() push_svalue(Pike_sp-1)
a6d61a2003-04-25Martin Stjernholm  #define stack_swap() do { \ struct svalue *_sp_ = Pike_sp; \ struct svalue _=_sp_[-1]; \ _sp_[-1]=_sp_[-2]; \ _sp_[-2]=_; \ } while(0)
3635bb1998-02-19Fredrik Hübinette (Hubbe) 
b23b112001-08-15Fredrik Hübinette (Hubbe) #define push_zeroes(N) do{ \ struct svalue *s_=Pike_sp; \ ptrdiff_t num_= (N); \ for(;num_-- > 0;s_++) \ { \ s_->type=PIKE_T_INT; \ s_->subtype=NUMBER_NUMBER; \ s_->u.integer=0; \ } \ Pike_sp=s_; \ }while(0) #define push_undefines(N) do{ \ struct svalue *s_=Pike_sp; \ ptrdiff_t num_= (N); \ for(;num_-- > 0;s_++) \ { \ s_->type=PIKE_T_INT; \ s_->subtype=NUMBER_UNDEFINED; \ s_->u.integer=0; \ } \ Pike_sp=s_; \ }while(0)
711b072001-03-08Fredrik Hübinette (Hubbe) 
50ea682003-03-14Henrik Grubbström (Grubba) #define free_pike_frame(F) do{ struct pike_frame *f_=(F); if(!sub_ref(f_)) really_free_pike_frame(f_); }while(0)
4218011999-01-31Fredrik Hübinette (Hubbe) 
fa21262001-08-31Fredrik Hübinette (Hubbe) /* A scope is any frame which may have malloced locals */
50ea682003-03-14Henrik Grubbström (Grubba) #define free_pike_scope(F) do{ struct pike_frame *f_=(F); if(!sub_ref(f_)) really_free_pike_scope(f_); }while(0)
fa21262001-08-31Fredrik Hübinette (Hubbe) 
4218011999-01-31Fredrik Hübinette (Hubbe) #define POP_PIKE_FRAME() do { \
a6d61a2003-04-25Martin Stjernholm  struct pike_frame *_fp_ = Pike_fp; \ struct pike_frame *tmp_=_fp_->next; \ if(!sub_ref(_fp_)) \
4218011999-01-31Fredrik Hübinette (Hubbe)  { \
a6d61a2003-04-25Martin Stjernholm  really_free_pike_frame(_fp_); \
4218011999-01-31Fredrik Hübinette (Hubbe)  }else{ \
0edf502003-12-05Henrik Grubbström (Grubba)  ptrdiff_t num_expendible = _fp_->expendible - _fp_->locals; \
50ea682003-03-14Henrik Grubbström (Grubba)  DO_IF_DEBUG( \
a6d61a2003-04-25Martin Stjernholm  if( (_fp_->locals + _fp_->num_locals > Pike_sp) || \
0edf502003-12-05Henrik Grubbström (Grubba)  (Pike_sp < _fp_->expendible) || \ (num_expendible < 0) || (num_expendible > _fp_->num_locals)) \
50ea682003-03-14Henrik Grubbström (Grubba)  Pike_fatal("Stack failure in POP_PIKE_FRAME %p+%d=%p %p %p!\n", \
a6d61a2003-04-25Martin Stjernholm  _fp_->locals, _fp_->num_locals, \ _fp_->locals+_fp_->num_locals, \ Pike_sp,_fp_->expendible)); \ debug_malloc_touch(_fp_); \
0edf502003-12-05Henrik Grubbström (Grubba)  if(num_expendible) \
4218011999-01-31Fredrik Hübinette (Hubbe)  { \ struct svalue *s=(struct svalue *)xalloc(sizeof(struct svalue)* \
0edf502003-12-05Henrik Grubbström (Grubba)  num_expendible); \ _fp_->num_locals = num_expendible; \ assign_svalues_no_free(s, _fp_->locals, num_expendible, \
50ea682003-03-14Henrik Grubbström (Grubba)  BIT_MIXED); \
a6d61a2003-04-25Martin Stjernholm  _fp_->locals=s; \ _fp_->flags|=PIKE_FRAME_MALLOCED_LOCALS; \
4218011999-01-31Fredrik Hübinette (Hubbe)  }else{ \
a6d61a2003-04-25Martin Stjernholm  _fp_->locals=0; \
4218011999-01-31Fredrik Hübinette (Hubbe)  } \
a6d61a2003-04-25Martin Stjernholm  _fp_->next=0; \
4218011999-01-31Fredrik Hübinette (Hubbe)  } \
a2ad152000-02-16Fredrik Hübinette (Hubbe)  Pike_fp=tmp_; \
4218011999-01-31Fredrik Hübinette (Hubbe)  }while(0)
3635bb1998-02-19Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) enum apply_type { APPLY_STACK, /* The function is the first argument */ APPLY_SVALUE, /* arg1 points to an svalue containing the function */
24c37f2001-05-24Fredrik Hübinette (Hubbe)  APPLY_SVALUE_STRICT, /* Like APPLY_SVALUE, but does not return values for void functions */
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  APPLY_LOW /* arg1 is the object pointer,(int)arg2 the function */ };
5267b71995-08-09Fredrik Hübinette (Hubbe) #define APPLY_MASTER(FUN,ARGS) \ do{ \
57d4d32000-08-23Henrik Grubbström (Grubba)  static int fun_, master_cnt=0; \
5267b71995-08-09Fredrik Hübinette (Hubbe)  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; \ } \ apply_low(master_ob, fun_, ARGS); \ }while(0) #define SAFE_APPLY_MASTER(FUN,ARGS) \ do{ \
57d4d32000-08-23Henrik Grubbström (Grubba)  static int fun_, master_cnt=0; \
5267b71995-08-09Fredrik Hübinette (Hubbe)  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; \ } \
c1b8f02001-07-02Martin Stjernholm  safe_apply_low2(master_ob, fun_, ARGS, 1); \
5267b71995-08-09Fredrik Hübinette (Hubbe) }while(0)
8fa6b52001-06-08Henrik Grubbström (Grubba) #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); \
b5e5382001-06-11Henrik Grubbström (Grubba)  if (h_ && h_->prog) { \
8fa6b52001-06-08Henrik Grubbström (Grubba)  if (h_->prog->id != h_id_) { \ h_fun_ = find_identifier(fun, h_->prog); \ h_id_ = h_->prog->id; \ } \ if (h_fun_ != -1) { \ safe_apply_low(h_, h_fun_, ARGS); \ break; \ } \ } \
b5e5382001-06-11Henrik Grubbström (Grubba)  if (c_ && c_->prog) { \
8fa6b52001-06-08Henrik Grubbström (Grubba)  if (c_->prog->id != c_id_) { \ c_fun_ = find_identifier(fun, c_->prog); \ c_id_ = c_->prog->id; \ } \ if (c_fun_ != -1) { \ safe_apply_low(c_, c_fun_, ARGS); \ break; \ } \ } \ SAFE_APPLY_MASTER(FUN, ARGS); \ } while(0)
032a812001-08-18Fredrik Hübinette (Hubbe) 
0f65e12002-09-14Martin Stjernholm #ifdef INTERNAL_PROFILING PMOD_EXPORT extern unsigned long evaluator_callback_calls; #endif
032a812001-08-18Fredrik Hübinette (Hubbe) #define check_threads_etc() do { \
0f65e12002-09-14Martin Stjernholm  DO_IF_INTERNAL_PROFILING (evaluator_callback_calls++); \
d2361e2003-06-30Martin Stjernholm  call_callback(& evaluator_callbacks, NULL); \
032a812001-08-18Fredrik Hübinette (Hubbe) }while(0)
0a861b1997-09-17Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
c846981997-10-13Fredrik Hübinette (Hubbe) #define fast_check_threads_etc(X) do { \ static int div_; if(d_flag || !(div_++& ((1<<(X))-1))) check_threads_etc(); } while(0) #else
0a861b1997-09-17Fredrik Hübinette (Hubbe) #define fast_check_threads_etc(X) do { \ static int div_; if(!(div_++& ((1<<(X))-1))) check_threads_etc(); } while(0)
c846981997-10-13Fredrik Hübinette (Hubbe) #endif
0a861b1997-09-17Fredrik Hübinette (Hubbe) 
4218011999-01-31Fredrik Hübinette (Hubbe) #include "block_alloc_h.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) /* Prototypes begin here */
be478c1997-08-30Henrik Grubbström (Grubba) void push_sp_mark(void);
45705c2000-08-09Henrik Grubbström (Grubba) ptrdiff_t pop_sp_mark(void);
cc2e9f2003-09-24Martin Stjernholm void gc_mark_stack_external (struct pike_frame *frame, struct svalue *stack_p, struct svalue *stack);
4ee9222000-12-13Fredrik Hübinette (Hubbe) PMOD_EXPORT void init_interpreter(void);
5267b71995-08-09Fredrik Hübinette (Hubbe) void lvalue_to_svalue_no_free(struct svalue *to,struct svalue *lval);
4ee9222000-12-13Fredrik Hübinette (Hubbe) PMOD_EXPORT void assign_lvalue(struct svalue *lval,struct svalue *from);
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT union anything *get_pointer_if_this_type(struct svalue *lval, TYPE_T t);
be478c1997-08-30Henrik Grubbström (Grubba) void print_return_value(void); void reset_evaluator(void);
5267b71995-08-09Fredrik Hübinette (Hubbe) struct backlog;
5683de1995-11-06Fredrik Hübinette (Hubbe) void dump_backlog(void);
4218011999-01-31Fredrik Hübinette (Hubbe) BLOCK_ALLOC(pike_frame,128)
142b002003-11-25Martin Stjernholm #ifdef PIKE_USE_MACHINE_CODE #ifdef OPCODE_INLINE_BRANCH void branch_check_threads_etc(); #endif #ifdef PIKE_DEBUG
b1f6a62003-03-21Martin Stjernholm 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);
31984c2003-03-20Martin Stjernholm #endif
142b002003-11-25Martin Stjernholm #endif /* PIKE_USE_MACHINE_CODE */
31984c2003-03-20Martin Stjernholm 
342fef2000-08-23Fredrik Hübinette (Hubbe) PMOD_EXPORT void find_external_context(struct external_variable_context *loc, int arg2);
e29cb72001-09-01Henrik Grubbström (Grubba) void really_free_pike_scope(struct pike_frame *scope);
f663c92003-04-03Henrik Grubbström (Grubba) int low_mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2);
9ddbf22001-05-10Fredrik Hübinette (Hubbe) void low_return(void);
2ac9502001-08-14Fredrik Hübinette (Hubbe) void low_return_pop(void);
9ddbf22001-05-10Fredrik Hübinette (Hubbe) void unlink_previous_frame(void); void mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2);
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void f_call_function(INT32 args);
6697042000-11-20Martin Stjernholm PMOD_EXPORT void call_handle_error(void);
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT int apply_low_safe_and_stupid(struct object *o, INT32 offset); PMOD_EXPORT void safe_apply_low(struct object *o,int fun,int args);
c1b8f02001-07-02Martin Stjernholm PMOD_EXPORT void safe_apply_low2(struct object *o,int fun,int args, int handle_errors);
b770752002-11-14Marcus Comstedt PMOD_EXPORT void safe_apply(struct object *o, const char *fun ,INT32 args);
61863e2001-12-20Martin Stjernholm PMOD_EXPORT int low_unsafe_apply_handler(const char *fun, struct object *handler, struct object *compat, INT32 args);
9036e82001-08-16Martin Stjernholm PMOD_EXPORT void low_safe_apply_handler(const char *fun, struct object *handler, struct object *compat, INT32 args); PMOD_EXPORT int safe_apply_handler(const char *fun, struct object *handler, struct object *compat, INT32 args, TYPE_FIELD rettypes);
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void apply_lfun(struct object *o, int fun, int args); PMOD_EXPORT void apply_shared(struct object *o,
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *fun,
5267b71995-08-09Fredrik Hübinette (Hubbe)  int args);
b770752002-11-14Marcus Comstedt PMOD_EXPORT void apply(struct object *o, const char *fun, int args);
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void apply_svalue(struct svalue *s, INT32 args);
9335ea2003-01-17Henrik Grubbström (Grubba) PMOD_EXPORT void apply_external(int depth, int fun, INT32 args);
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void slow_check_stack(void);
66a1572001-01-12Martin Stjernholm PMOD_EXPORT void custom_check_stack(ptrdiff_t amount, const char *fmt, ...)
c915472000-12-04Martin Stjernholm  ATTRIBUTE((format (printf, 2, 3)));
4ee9222000-12-13Fredrik Hübinette (Hubbe) PMOD_EXPORT void cleanup_interpret(void);
b660c81999-03-01Fredrik Hübinette (Hubbe) void really_clean_up_interpret(void);
5267b71995-08-09Fredrik Hübinette (Hubbe) /* Prototypes end here */
d080fb2000-08-07Henrik Grubbström (Grubba) /* These need to be after the prototypes, * to avoid implicit declaration of mega_apply(). */ #ifdef __ECL static inline void apply_low(struct object *o, ptrdiff_t fun, INT32 args) { mega_apply(APPLY_LOW, args, (void*)o, (void*)fun); } static inline void strict_apply_svalue(struct svalue *sval, INT32 args) {
24c37f2001-05-24Fredrik Hübinette (Hubbe)  mega_apply(APPLY_SVALUE_STRICT, args, (void*)sval, 0);
d080fb2000-08-07Henrik Grubbström (Grubba) } #else /* !__ECL */ #define apply_low(O,FUN,ARGS) \
57d4d32000-08-23Henrik Grubbström (Grubba)  mega_apply(APPLY_LOW, (ARGS), (void*)(O),(void*)(ptrdiff_t)(FUN))
d080fb2000-08-07Henrik Grubbström (Grubba)  #define strict_apply_svalue(SVAL,ARGS) \ mega_apply(APPLY_SVALUE, (ARGS), (void*)(SVAL),0) #endif /* __ECL */
114b162003-01-18Henrik Grubbström (Grubba) #define apply_current(FUN, ARGS) \ apply_low(Pike_fp->current_object, \ (FUN) + Pike_fp->context.identifier_level, \ (ARGS))
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT extern int d_flag; /* really in main.c */ PMOD_EXPORT extern int Pike_stack_size; PMOD_EXPORT struct callback; PMOD_EXPORT extern struct callback_list evaluator_callbacks;
e132001998-11-19Fredrik Hübinette (Hubbe) 
b28dd12000-07-06Fredrik Hübinette (Hubbe) /* Things to try: * we could reduce thread swapping to a pointer operation if * we do something like: * #define Pike_interpreter (*Pike_interpreter_pointer) * * Since global variables are usually accessed through indirection * anyways, it might not make any speed differance. * * The above define could also be used to facilitate dynamic loading * on Win32.. */
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT extern struct Pike_interpreter Pike_interpreter;
5923b12000-07-06Fredrik Hübinette (Hubbe)  #define Pike_sp Pike_interpreter.stack_pointer #define Pike_fp Pike_interpreter.frame_pointer
17f08c2000-07-06Fredrik Hübinette (Hubbe) #define Pike_mark_sp Pike_interpreter.mark_stack_pointer
e132001998-11-19Fredrik Hübinette (Hubbe) 
a2ad152000-02-16Fredrik Hübinette (Hubbe) 
60d9872000-03-23Fredrik Hübinette (Hubbe) #define CURRENT_STORAGE (dmalloc_touch(struct pike_frame *,Pike_fp)->current_storage)
24c37f2001-05-24Fredrik Hübinette (Hubbe)  #define PIKE_STACK_MMAPPED struct Pike_stack { struct svalue *top; int flags; struct Pike_stack *previous; struct svalue *save_ptr; struct svalue stack[1]; }; #define PIKE_STACK_REQUIRE_BEGIN(num, base) do { \
4061442001-05-25Henrik Grubbström (Grubba)  struct Pike_stack *old_stack_; \
24c37f2001-05-24Fredrik Hübinette (Hubbe)  if(Pike_interpreter.current_stack->top - Pike_sp < num) \ { \
4061442001-05-25Henrik Grubbström (Grubba)  old_stack_=Pike_interpreter.current_stack; \ old_stack_->save_ptr=Pike_sp; \
24c37f2001-05-24Fredrik Hübinette (Hubbe)  Pike_interpreter.current_stack=allocate_array(MAXIMUM(num, 8192)); \
4061442001-05-25Henrik Grubbström (Grubba)  while(old_sp > base) *(Pike_sp++) = *--old_stack_->save_ptr; \
24c37f2001-05-24Fredrik Hübinette (Hubbe)  } #define PIKE_STACK_REQUIRE_END() \ while(Pike_sp > Pike_interpreter.current_stack->stack) \
4061442001-05-25Henrik Grubbström (Grubba)  *(old_stack_->save_ptr++) = *--Pike_sp; \
24c37f2001-05-24Fredrik Hübinette (Hubbe)  Pike_interpreter.current_stack=Pike_interpreter.current_stack->previous; \ }while(0)
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif