cb22561995-10-11Fredrik Hübinette (Hubbe) /*\
06983f1996-09-22Fredrik Hübinette (Hubbe) ||| This file a part of Pike, and is copyright by Fredrik Hubinette ||| Pike is distributed as GPL (General Public License)
cb22561995-10-11Fredrik Hübinette (Hubbe) ||| See the files COPYING and DISCLAIMER for more information. \*/
24ddc71998-03-28Henrik Grubbström (Grubba)  /*
fffb2a2000-09-12Henrik Grubbström (Grubba)  * $Id: interpret.h,v 1.67 2000/09/12 17:06:08 grubba Exp $
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"
5923b12000-07-06Fredrik Hübinette (Hubbe) #include "error.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
ec2bab2000-06-24Fredrik Hübinette (Hubbe)  struct object * thread_id;
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;) #ifdef PROFILING #ifdef HAVE_GETHRTIME long long accounted_time; long long time_base; #endif #endif #ifdef THREAD_TRACE int t_flag; #endif /* THREAD_TRACE */ };
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 */
4218011999-01-31Fredrik Hübinette (Hubbe)  INT32 args;
1e4e5f2000-04-07Fredrik Hübinette (Hubbe)  unsigned INT16 fun;
4218011999-01-31Fredrik Hübinette (Hubbe)  INT16 num_locals; INT16 num_args; INT16 malloced_locals; struct pike_frame *next; struct pike_frame *scope;
5267b71995-08-09Fredrik Hübinette (Hubbe)  unsigned char *pc; struct svalue *locals;
5017631998-06-05Fredrik Hübinette (Hubbe)  struct svalue *expendible;
5267b71995-08-09Fredrik Hübinette (Hubbe)  struct object *current_object; struct inherit context; char *current_storage; };
342fef2000-08-23Fredrik Hübinette (Hubbe) struct external_variable_context { struct object *o; struct inherit *inherit; int parent_identifier; };
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
5923b12000-07-06Fredrik Hübinette (Hubbe) #define debug_check_stack() do{if(Pike_sp<Pike_interpreter.evaluator_stack)fatal("Stack error.\n");}while(0)
5f776b2000-02-28Fredrik Hübinette (Hubbe) #define check__positive(X,Y) if((X)<0) fatal Y
9649491998-02-27Fredrik Hübinette (Hubbe) #include "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) 
6f95902000-08-17Henrik Grubbström (Grubba) #define check_stack(X) do { \ if(Pike_sp - Pike_interpreter.evaluator_stack + (X) >= Pike_stack_size) \
b6e1cd1999-07-29Mirar (Pontus Hagland)  error("Svalue stack overflow. " \
6f95902000-08-17Henrik Grubbström (Grubba)  "(%ld of %ld entries on stack, needed %ld more entries)\n", \ 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) #define check_mark_stack(X) do { \
fc26f62000-07-06Fredrik Hübinette (Hubbe)  if(Pike_mark_sp - Pike_interpreter.mark_stack + (X) >= Pike_stack_size) \
7e97c31999-01-21Fredrik Hübinette (Hubbe)  error("Mark stack overflow.\n"); \ }while(0) #define check_c_stack(X) do { \
deea492000-08-08Henrik Grubbström (Grubba)  ptrdiff_t x_= ((char *)&x_) + STACK_DIRECTION * (X) - Pike_interpreter.stack_top ; \
7e97c31999-01-21Fredrik Hübinette (Hubbe)  x_*=STACK_DIRECTION; \ if(x_>0) \
db40ab1999-04-15Fredrik Hübinette (Hubbe)  low_error("C stack overflow.\n"); \
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) { \ fatal("C stack overflow.\n"); \ } \ }while(0)
7e97c31999-01-21Fredrik Hübinette (Hubbe) 
a2ad152000-02-16Fredrik Hübinette (Hubbe) #define pop_stack() do{ free_svalue(--Pike_sp); debug_check_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 */
3469ac2000-08-03Henrik Grubbström (Grubba) #define pop_n_elems(X) \
945dfc2000-07-07Henrik Grubbström (Grubba)  do { ptrdiff_t x_=(X); if(x_) { \
b9c5502000-08-03Henrik Grubbström (Grubba)  check__positive(x_, ("Popping negative number of args.... (%ld) \n", \
2eaa402000-08-03Henrik Grubbström (Grubba)  MAYBE_CAST_TO_LONG(x_))); \
3469ac2000-08-03Henrik Grubbström (Grubba)  Pike_sp -= x_; debug_check_stack(); \ free_svalues(Pike_sp, x_, BIT_MIXED); \
9649491998-02-27Fredrik Hübinette (Hubbe)  } } while (0)
3983a81999-06-01Mirar (Pontus Hagland) #define stack_pop_n_elems_keep_top(X) \
a2ad152000-02-16Fredrik Hübinette (Hubbe)  do { struct svalue s=Pike_sp[-1]; Pike_sp[-1]=Pike_sp[-1-(X)]; Pike_sp[-1-(X)]=s; \
3983a81999-06-01Mirar (Pontus Hagland)  pop_n_elems(X); } while (0)
a2ad152000-02-16Fredrik Hübinette (Hubbe) #define push_program(P) do{ struct program *_=(P); debug_malloc_touch(_); Pike_sp->u.program=_; Pike_sp++->type=PIKE_T_PROGRAM; }while(0) #define push_int(I) do{ INT32 _=(I); Pike_sp->u.integer=_;Pike_sp->type=PIKE_T_INT;Pike_sp++->subtype=NUMBER_NUMBER; }while(0) #define push_mapping(M) do{ struct mapping *_=(M); debug_malloc_touch(_); Pike_sp->u.mapping=_; Pike_sp++->type=PIKE_T_MAPPING; }while(0) #define push_array(A) do{ struct array *_=(A); debug_malloc_touch(_); Pike_sp->u.array=_ ;Pike_sp++->type=PIKE_T_ARRAY; }while(0) #define push_multiset(L) do{ struct multiset *_=(L); debug_malloc_touch(_); Pike_sp->u.multiset=_; Pike_sp++->type=PIKE_T_MULTISET; }while(0) #define push_string(S) do{ struct pike_string *_=(S); debug_malloc_touch(_); Pike_sp->subtype=0; Pike_sp->u.string=_; Pike_sp++->type=PIKE_T_STRING; }while(0) #define push_object(O) do{ struct object *_=(O); debug_malloc_touch(_); Pike_sp->u.object=_; Pike_sp++->type=PIKE_T_OBJECT; }while(0)
ff8e462000-08-03Henrik Grubbström (Grubba) #define push_float(F) do{ FLOAT_TYPE _=(F); Pike_sp->u.float_number=_; Pike_sp++->type=PIKE_T_FLOAT; }while(0)
04925b1996-09-29Fredrik Hübinette (Hubbe) #define push_text(T) push_string(make_shared_string((T)))
a2ad152000-02-16Fredrik Hübinette (Hubbe) #define push_constant_text(T) do{ Pike_sp->subtype=0; MAKE_CONSTANT_SHARED_STRING(Pike_sp->u.string,T); Pike_sp++->type=PIKE_T_STRING; }while(0)
0542ef1999-11-17Fredrik Hübinette (Hubbe) 
a2ad152000-02-16Fredrik Hübinette (Hubbe) #define ref_push_program(P) do{ struct program *_=(P); debug_malloc_touch(_); _->refs++; Pike_sp->u.program=_; Pike_sp++->type=PIKE_T_PROGRAM; }while(0) #define ref_push_mapping(M) do{ struct mapping *_=(M); debug_malloc_touch(_); _->refs++; Pike_sp->u.mapping=_; Pike_sp++->type=PIKE_T_MAPPING; }while(0) #define ref_push_array(A) do{ struct array *_=(A); debug_malloc_touch(_); _->refs++; Pike_sp->u.array=_ ;Pike_sp++->type=PIKE_T_ARRAY; }while(0) #define ref_push_multiset(L) do{ struct multiset *_=(L); debug_malloc_touch(_); _->refs++; Pike_sp->u.multiset=_; Pike_sp++->type=PIKE_T_MULTISET; }while(0) #define ref_push_string(S) do{ struct pike_string *_=(S); debug_malloc_touch(_); _->refs++; Pike_sp->subtype=0; Pike_sp->u.string=_; Pike_sp++->type=PIKE_T_STRING; }while(0) #define ref_push_object(O) do{ struct object *_=(O); debug_malloc_touch(_); _->refs++; Pike_sp->u.object=_; Pike_sp++->type=PIKE_T_OBJECT; }while(0)
2d12341997-03-10Fredrik Hübinette (Hubbe) 
a2ad152000-02-16Fredrik Hübinette (Hubbe) #define push_svalue(S) do { struct svalue *_=(S); assign_svalue_no_free(Pike_sp,_); Pike_sp++; }while(0)
5267b71995-08-09Fredrik Hübinette (Hubbe) 
a2ad152000-02-16Fredrik Hübinette (Hubbe) #define stack_dup() push_svalue(Pike_sp-1) #define stack_swap() do { struct svalue _=Pike_sp[-1]; Pike_sp[-1]=Pike_sp[-2]; Pike_sp[-2]=_; } while(0)
3635bb1998-02-19Fredrik Hübinette (Hubbe) 
aa73fc1999-10-21Fredrik Hübinette (Hubbe) /* 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. */
a2ad152000-02-16Fredrik Hübinette (Hubbe) #define stack_unlink(X) do { if(X) { free_svalue(Pike_sp-(X)-1); Pike_sp[-(X)-1]=Pike_sp[-1]; Pike_sp--; pop_n_elems(X-1); } }while(0)
aa73fc1999-10-21Fredrik Hübinette (Hubbe) 
4218011999-01-31Fredrik Hübinette (Hubbe) #define free_pike_frame(F) do{ struct pike_frame *f_=(F); debug_malloc_touch(f_); if(!--f_->refs) really_free_pike_frame(f_); }while(0) #define POP_PIKE_FRAME() do { \
a2ad152000-02-16Fredrik Hübinette (Hubbe)  struct pike_frame *tmp_=Pike_fp->next; \ if(!--Pike_fp->refs) \
4218011999-01-31Fredrik Hübinette (Hubbe)  { \
a2ad152000-02-16Fredrik Hübinette (Hubbe)  really_free_pike_frame(Pike_fp); \
4218011999-01-31Fredrik Hübinette (Hubbe)  }else{ \
1b1cad2000-06-20Fredrik Hübinette (Hubbe)  DO_IF_DEBUG(if( Pike_fp->locals + Pike_fp->num_locals > Pike_sp || Pike_sp < Pike_fp->expendible) fatal("Stack failure in POP_PIKE_FRAME %p+%d=%p %p %p!\n",Pike_fp->locals,Pike_fp->num_locals,Pike_fp->locals+Pike_fp->num_locals,Pike_sp,Pike_fp->expendible)); \
a2ad152000-02-16Fredrik Hübinette (Hubbe)  debug_malloc_touch(Pike_fp); \ if(Pike_fp->num_locals) \
4218011999-01-31Fredrik Hübinette (Hubbe)  { \ struct svalue *s=(struct svalue *)xalloc(sizeof(struct svalue)* \
a2ad152000-02-16Fredrik Hübinette (Hubbe)  Pike_fp->num_locals); \ assign_svalues_no_free(s,Pike_fp->locals,Pike_fp->num_locals,BIT_MIXED); \ Pike_fp->locals=s; \ Pike_fp->malloced_locals=1; \
4218011999-01-31Fredrik Hübinette (Hubbe)  }else{ \
a2ad152000-02-16Fredrik Hübinette (Hubbe)  Pike_fp->locals=0; \
4218011999-01-31Fredrik Hübinette (Hubbe)  } \
a2ad152000-02-16Fredrik Hübinette (Hubbe)  Pike_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 */ 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; \ } \ safe_apply_low(master_ob, fun_, ARGS); \ }while(0)
0a861b1997-09-17Fredrik Hübinette (Hubbe) #define check_threads_etc() \ call_callback(& evaluator_callbacks, (void *)0)
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);
be478c1997-08-30Henrik Grubbström (Grubba) void init_interpreter(void);
5267b71995-08-09Fredrik Hübinette (Hubbe) void lvalue_to_svalue_no_free(struct svalue *to,struct svalue *lval); 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)
342fef2000-08-23Fredrik Hübinette (Hubbe) PMOD_EXPORT void find_external_context(struct external_variable_context *loc, int arg2);
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2); PMOD_EXPORT void f_call_function(INT32 args); 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); PMOD_EXPORT void safe_apply(struct object *o, char *fun ,INT32 args); 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);
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void apply(struct object *o, char *fun, int args); PMOD_EXPORT void apply_svalue(struct svalue *s, INT32 args); PMOD_EXPORT void slow_check_stack(void);
be478c1997-08-30Henrik Grubbström (Grubba) 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) { mega_apply(APPLY_SVALUE, args, (void*)sval, 0); } #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 */
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; PMOD_EXPORT extern void call_callback(struct callback_list *, void *);
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
f077582000-07-06Fredrik Hübinette (Hubbe) #ifdef PIKE_THREADS #define Pike_thread_id Pike_interpreter.thread_id #endif
e132001998-11-19Fredrik Hübinette (Hubbe) 
a2ad152000-02-16Fredrik Hübinette (Hubbe) #ifndef NO_PIKE_SHORTHAND
5923b12000-07-06Fredrik Hübinette (Hubbe) /* Shouldn't this be in Pike_interpreter? - Hubbe */ #define stack_size Pike_stack_size
a2ad152000-02-16Fredrik Hübinette (Hubbe) #define sp Pike_sp #define fp Pike_fp
17f08c2000-07-06Fredrik Hübinette (Hubbe) #define mark_sp Pike_mark_sp
a2ad152000-02-16Fredrik Hübinette (Hubbe)  #endif /* !NO_PIKE_SHORTHAND */
60d9872000-03-23Fredrik Hübinette (Hubbe) #define CURRENT_STORAGE (dmalloc_touch(struct pike_frame *,Pike_fp)->current_storage)
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif
5f776b2000-02-28Fredrik Hübinette (Hubbe)