1 #ifndef INTERPRET_H__ 2 #define INTERPRET_H__ 1 3 4 #include <setjmp.h> 5 #ifdef HAVE_SYS_TIME_H 6 #include <sys/time.h> 7 #endif 8 #include <time.h> 9 #include <sys/types.h> 10 11 #include "driver.h" 12 #include "typedefs.h" 13 14 #include "backend.h" 15 #include "bytecode.h" 16 #include "svalue.h" 17 18 /* --- Types --- */ 19 20 /* --- struct control_stack: one control stack element 21 * 22 * Every structure describes the previous function call levels, the 23 * current function call data is kept in interpret's global variables.. 24 * 'prog' is usually the same as ob->prog, except when 25 * executing inherited functions. 26 * 27 * TODO: The frames should have special flags to mark stuff like 28 * TODO:: sefun closures, closures, etc. 29 */ 30 31 struct control_stack { 32 object_t *ob; /* Current object */ 33 object_t *prev_ob; /* Save previous object */ 34 program_t *prog; /* Current program, NULL in the bottom entry */ 35 svalue_t lambda; /* Current lambda, counted, or svalue-0 if none */ 36 bytecode_p pc; /* Program counter, points to next bytecode */ 37 svalue_t *fp; /* Frame pointer: first arg on stack */ 38 #ifdef USE_NEW_INLINES 39 svalue_t *context; /* Context pointer */ 40 #endif /* USE_NEW_INLINES */ 41 bytecode_p funstart; 42 /* Start of the function code. 43 * Two magic values (SIMUL_EFUN_FUNSTART and EFUN_FUNSTART) mark 44 * entries for simul-efun and efun closures. 45 */ 46 int num_local_variables; /* Number of local vars + arguments */ 47 int function_index_offset; 48 /* Index of current program's function block within the functions of the 49 * current objects program (needed for inheritance). 50 */ 51 svalue_t *current_variables; /* Same */ 52 int extern_call; 53 /* TRUE if the call came from outside the object (call_others to 54 * oneself are a special case of this). Only entries with this flag 55 * set save the .ob and .prev_ob for the flagged and all previous 56 * unflagged entries. 57 * If the current this_object was changed, the 'imposter' object is 58 * stored in .pretend_to_be and this flag is or'ed with CS_PRETEND. 59 */ 60 # define CS_PRETEND 0x80 61 Bool catch_call; 62 /* This is the 'faked' call context for the code inside a catch(). 63 * Since the interpreter fakes a subroutine call for this, F_RETURN 64 * must be able to tell the contexts apart. 65 * (Right now the LPC compiler prohibits the use of 'return' inside 66 * of a catch, but providing it on this level already doesn't hurt). 67 */ 68 int instruction; 69 /* For EFUN_FUNSTART entries, this is the efun executed. 70 */ 71 72 bytecode_p *break_sp; 73 /* Points to address to branch to at next F_BREAK, which is also 74 * the actual bottom of the break stack. 75 */ 76 object_t *pretend_to_be; 77 /* After set_this_object(), the this_object imposter. 78 * TODO: This should be mirrored in the current_object global variable, 79 * TODO:: to avoid accesses to wrong functions/variables. 80 */ 81 #ifdef EVAL_COST_TRACE 82 int32 eval_cost; 83 /* The eval cost at that moment. */ 84 #endif 85 }; 86 87 /* a general error handler structure. head is assigned as payload to an 88 * T_LVALUE svalue of type T_ERROR_HANDLER and pushed onto the value stack. 89 * If the stack is unrolled during runtime errors the error_handler function 90 * is called and frees buff. */ 91 typedef struct errorhandler_s { 92 svalue_t head; /* The T_ERROR_HANDLER structure */ 93 char * buff; /* The allocated buffer to free. */ 94 } errorhandler_t; 95 96 97 /* --- Constants --- */ 98 99 static const short MAX_SHIFT = (sizeof(p_int) << 3) - 1; 100 /* The maximally useful shift (left or right) of a number in LPC. 101 */ 102 103 /* --- Variables --- */ 104 105 extern program_t *current_prog; 106 extern int tracedepth; 107 extern int trace_level; 108 extern bytecode_p inter_pc; 109 extern struct control_stack *csp; 110 extern svalue_t * inter_sp; 111 extern int function_index_offset; 112 extern svalue_t *current_variables; 113 extern int32 eval_cost; 114 extern int32 assigned_eval_cost; 115 extern svalue_t apply_return_value; 116 extern svalue_t last_indexing_protector; 117 118 #ifdef APPLY_CACHE_STAT 119 extern p_uint apply_cache_hit; 120 extern p_uint apply_cache_miss; 121 #endif 122 123 extern p_uint eval_number; 124 extern unsigned long total_evalcost; 125 extern unsigned long last_total_evalcost; 126 extern struct timeval last_eval_duration; 127 extern statistic_t stat_total_evalcost; 128 extern statistic_t stat_eval_duration; 129 130 /* --- Prototypes --- */ 131 132 extern void assign_eval_cost(void); 133 extern void mark_start_evaluation (void); 134 extern void mark_end_evaluation(void); 135 136 extern Bool eval_instruction(bytecode_p first_instruction, svalue_t *initial_sp); 137 extern void free_string_svalue(svalue_t *v); 138 #ifdef USE_NEW_INLINES 139 extern void push_control_stack(svalue_t *sp, bytecode_p pc, svalue_t *fp, svalue_t *context); 140 #else 141 extern void push_control_stack(svalue_t *sp, bytecode_p pc, svalue_t *fp); 142 #endif /* USE_NEW_INLINES */ 143 extern void pop_control_stack(void); 144 extern struct longjump_s *push_error_context(svalue_t *sp, int catch_flags); 145 extern void pop_error_context (void); 146 extern svalue_t *pull_error_context (svalue_t *sp, svalue_t *msg); 147 extern void transfer_error_message (svalue_t *v, rt_context_t *rt); 148 extern Bool destructed_object_ref (svalue_t *svp); 149 extern void free_object_svalue(svalue_t *v); 150 extern void zero_object_svalue(svalue_t *v); 151 extern void free_svalue(svalue_t *v); 152 extern void assign_svalue_no_free(svalue_t *to, svalue_t *from); 153 extern void assign_svalue(svalue_t *dest, svalue_t *v); 154 extern void copy_svalue_no_free (svalue_t *to, svalue_t *from); 155 extern void transfer_svalue_no_free(svalue_t *dest, svalue_t *v); 156 extern void transfer_svalue(svalue_t *dest, svalue_t *v); 157 158 extern void put_c_string (svalue_t *sp, const char *p); 159 extern void put_c_n_string (svalue_t *sp, const char *p, size_t len); 160 161 extern void push_svalue(svalue_t *v); 162 extern void push_svalue_block(int num, svalue_t *v); 163 extern svalue_t *pop_n_elems (int n, svalue_t *sp); 164 extern void pop_stack(void); 165 extern void push_apply_value(void); 166 extern void pop_apply_value (void); 167 extern void push_referenced_mapping(mapping_t *m); 168 extern svalue_t *push_error_handler(void (*errorhandler)(svalue_t *), svalue_t *arg); 169 extern void *xalloc_with_error_handler(size_t size); 170 171 extern void init_interpret(void); 172 extern const char *typename(int type); 173 extern const char *efun_arg_typename (long type); 174 extern void vefun_bad_arg (int arg, svalue_t *sp) NORETURN; 175 extern void efun_gen_arg_error (int arg, int got, svalue_t *sp) NORETURN; 176 extern void vefun_gen_arg_error (int arg, int got, svalue_t *sp) NORETURN; 177 extern void efun_arg_error (int arg, int expected, int got, svalue_t *sp) NORETURN; 178 extern void efun_exp_arg_error (int arg, long expected, int got, svalue_t *sp) NORETURN; 179 extern void vefun_arg_error (int arg, int expected, int got, svalue_t *sp) NORETURN; 180 extern void vefun_exp_arg_error (int arg, long expected, int got, svalue_t *sp) NORETURN; 181 extern Bool privilege_violation(string_t *what, svalue_t *arg, svalue_t *sp); 182 extern Bool privilege_violation2(string_t *what, svalue_t *arg, svalue_t *arg2, svalue_t *sp); 183 extern Bool privilege_violation4(string_t *what, object_t *whom, string_t *how_str, int how_num, svalue_t *sp); 184 extern Bool privilege_violation_n(string_t *what, object_t *whom, svalue_t *sp, int num_arg); 185 186 extern svalue_t *sapply_int(string_t *fun, object_t *ob, int num_arg, Bool b_ign_prot, Bool b_use_default); 187 #define sapply(f,o,n) sapply_int(f,o,n, MY_FALSE, MY_TRUE) 188 #define sapply_ign_prot(f,o,n) sapply_int(f,o,n, MY_TRUE, MY_TRUE) 189 extern svalue_t *apply(string_t *fun, object_t *ob, int num_arg); 190 extern void call_function(program_t *progp, int fx); 191 extern int get_line_number(bytecode_p p, program_t *progp, string_t **namep); 192 extern string_t *collect_trace(strbuf_t * sbuf, vector_t ** rvec); 193 extern string_t *dump_trace(Bool how, vector_t **rvec); 194 extern int get_line_number_if_any(string_t **name); 195 extern void reset_machine(Bool first); 196 extern void secure_apply_error(svalue_t *save_sp, struct control_stack *save_csp, Bool clear_costs); 197 extern svalue_t *secure_apply_ob(string_t *fun, object_t *ob, int num_arg, Bool external); 198 #define secure_apply(fun, ob, num_arg) secure_apply_ob(fun, ob, num_arg, MY_FALSE) 199 #define secure_callback(fun, ob, num_arg) secure_apply_ob(fun, ob, num_arg, MY_TRUE) 200 201 extern svalue_t *apply_master_ob(string_t *fun, int num_arg, Bool external); 202 #define apply_master(fun, num_arg) apply_master_ob(fun, num_arg, MY_FALSE) 203 #define callback_master(fun, num_arg) apply_master_ob(fun, num_arg, MY_TRUE) 204 205 extern void assert_master_ob_loaded(void); 206 extern svalue_t *secure_call_lambda(svalue_t *closure, int num_arg, Bool external); 207 #define secure_apply_lambda(fun, num_arg) secure_call_lambda(fun, num_arg, MY_FALSE) 208 #define secure_callback_lambda(fun, num_arg) secure_call_lambda(fun, num_arg, MY_TRUE) 209 210 extern void remove_object_from_stack(object_t *ob); 211 extern void int_call_lambda(svalue_t *lsvp, int num_arg, Bool allowRefs, Bool external); 212 #define call_lambda(lsvp, num_arg) int_call_lambda(lsvp, num_arg, MY_FALSE, MY_TRUE) 213 extern inherit_t *adjust_variable_offsets(const inherit_t *inheritp, const program_t *prog, const object_t *obj); 214 extern void free_interpreter_temporaries(void); 215 extern void invalidate_apply_low_cache(void); 216 extern void m_indices_filter (svalue_t *key, svalue_t *data, void *extra); 217 extern void m_values_filter (svalue_t *key, svalue_t *data, void *extra); 218 extern void m_unmake_filter ( svalue_t *key, svalue_t *data, void *extra); 219 extern svalue_t *v_apply (svalue_t *sp, int num_arg); 220 extern svalue_t *v_funcall (svalue_t *sp, int num_arg); 221 extern svalue_t *v_call_direct_resolved (svalue_t *sp, int num_arg); 222 extern svalue_t *v_call_resolved (svalue_t *sp, int num_arg); 223 extern svalue_t *f_caller_stack_depth (svalue_t *sp); 224 extern svalue_t *f_caller_stack (svalue_t *sp); 225 extern svalue_t *f_get_eval_cost (svalue_t *sp); 226 extern svalue_t *f_previous_object (svalue_t *sp); 227 extern svalue_t *f_set_this_object (svalue_t *sp); 228 extern svalue_t *f_trace(svalue_t *sp); 229 extern svalue_t *f_traceprefix(svalue_t *sp); 230 231 #ifdef OPCPROF 232 extern Bool opcdump(string_t *fname); 233 #endif 234 235 #ifdef TRACE_CODE 236 extern svalue_t *f_last_instructions(svalue_t *sp); 237 extern int last_instructions(int length, Bool verbose, svalue_t **svpp); 238 #endif 239 240 #ifdef DEBUG 241 extern int check_state(void); 242 extern void count_inherits(program_t *progp); 243 extern void count_extra_ref_in_object(object_t *ob); 244 extern void count_extra_ref_in_vector(svalue_t *svp, size_t num); 245 extern void check_a_lot_ref_counts(program_t *search_prog); 246 #endif 247 248 extern size_t interpreter_overhead(void); 249 250 #ifdef GC_SUPPORT 251 extern void clear_interpreter_refs(void); 252 extern void count_interpreter_refs(void); 253 #endif 254 255 extern int control_stack_depth(void); 256 257 #endif /* INTERPRET_H__ */ 258