1 #ifndef SIMULATE_H__ 2 #define SIMULATE_H__ 1 3 4 #include <setjmp.h> 5 6 #include "driver.h" 7 #include "typedefs.h" 8 9 #include "bytecode.h" 10 #include "sent.h" /* shadow_sentence_t */ 11 #include "strfuns.h" /* strbuf_t */ 12 #include "svalue.h" 13 14 /* --- Types --- */ 15 16 /* --- struct rt_context_s: runtime context information 17 * 18 * The runtime context struct is made up from children of these structures. 19 * The stack is used to store nested changes in the runtime context, may 20 * they be error recovery contexts, changes in the runtime limits, or else. 21 * 22 * Storing all this information into one stack makes it much easier to restore 23 * a previous context in case of errors. For that, error recovery information 24 * plays the most important role in this stack. 25 * 26 * Most of the stack entries are allocated on the stack, only few are 27 * allocated on the heap. 28 */ 29 30 struct rt_context_s 31 { 32 struct rt_context_s *last; /* Previous context, or NULL */ 33 int type; /* Type of this context entry */ 34 }; 35 36 /* rt_context_s.type: 37 * 38 * Positive values are all ERROR_RECOVERY types, negative values 39 * denote other context types. 40 */ 41 42 #define LIMITS_CONTEXT -2 43 /* The previous set of runtime limits. 44 */ 45 46 #define COMMAND_CONTEXT -1 47 /* The previous command context (struct command_context in simulate.c). 48 * For the very first command given, this is all 0. 49 */ 50 51 /* For the following context types, the stack entry is in fact 52 * a error_recovery_info structure. 53 */ 54 55 #define ERROR_RECOVERY_NONE 0 56 /* No error recovery available (used by the top entry in the stack). 57 */ 58 #define ERROR_RECOVERY_BACKEND 1 59 /* Errors fall back to the backend, e.g. process_objects(), 60 * call_heart_beat() and others. 61 */ 62 #define ERROR_RECOVERY_APPLY 2 63 /* Errors fall back into the secure_apply() function used for sensitive 64 * applies. 65 */ 66 #define ERROR_RECOVERY_CATCH 3 67 /* Errors are caught in interpret.c by the catch() construct. 68 * This is in fact an extended error_recovery_info structure which 69 * is allocated on the heap. 70 * 71 * The CATCH context has a number of attributes, expressed by bitflags: 72 */ 73 #define CATCH_FLAG_NOLOG (0x01) /* The traceback is not logged */ 74 #define CATCH_FLAG_PUBLISH (0x02) /* master::runtime_error() is called 75 * despite the error being caught. 76 */ 77 /* The following flags are used only by the bytecode interpreter 78 * to set up the instruction. 79 */ 80 #define CATCH_FLAG_RESERVE (0x04) /* The amount of ticks to keep in reserve 81 * is given on the stack. 82 */ 83 84 85 #define ERROR_RECOVERY_CONTEXT(t) ((t) >= ERROR_RECOVERY_NONE) 86 /* True, if rt_context_s.type 't' denotes a error recovery context. 87 */ 88 89 #define ERROR_RECOVERY_CAUGHT(t) ((t) == ERROR_RECOVERY_CATCH) 90 /* True, if rt_context_s.type 't' denotes a catch recovery context. 91 */ 92 93 /* --- struct longjump_s: longjump context information 94 * 95 * This structure contains the necessary data to execute a longjmp() 96 * when recovering from an error. 97 */ 98 99 struct longjump_s { jmp_buf text; }; 100 101 102 /* --- struct error_recovery_info: error recovery context 103 * 104 * The error recovery stack is made up from these structures, describing 105 * the nature of the error handling, and where to jump back to. 106 * 107 * For ERROR_RECOVERY_CATCH contexts, the stack element is in fact a larger 108 * structure containing the error_recovery_info as first member, with 109 * additional members holding the information needed to perform a catch(). 110 * That structure and all handling routines are local to interpret.c . 111 */ 112 113 struct error_recovery_info 114 { 115 rt_context_t rt; 116 int flags; /* Flags for ERROR_RECOVERY_CATCH. */ 117 struct longjump_s con; /* longjmp() information */ 118 }; 119 120 121 /* --- struct callback: describes a function call plus arguments 122 * 123 * This structure is used by input_tos and call_outs to store the 124 * information about the function to call and the arguments to pass. 125 */ 126 127 struct callback_s { 128 union { /* The function to call: by name or the closure */ 129 struct { 130 string_t *name; /* the tabled function name */ 131 object_t *ob; /* reference to the object to call */ 132 } named; 133 svalue_t lambda; /* the closure to call */ 134 } function; 135 Bool is_lambda; /* Closure or named function? */ 136 int num_arg; /* Number of arguments */ 137 svalue_t arg; 138 /* Arguments to pass: 139 * - T_INVALID if no arguments 140 * - a single argument 141 * - T_LVALUE with u.lvalue pointing to the svalue_t[] with 142 * the arguments. If arg.x.extern_args is TRUE, the block 143 * was allocated from outside and is outside of our control. 144 * No argument can be a LVALUE itself. 145 */ 146 }; 147 148 #ifdef CHECK_OBJECT_REF 149 typedef struct object_shadow_s { 150 struct object_shadow_s * next; 151 object_t * obj; 152 unsigned short flags; 153 p_int ref; 154 sentence_t *sent; 155 } object_shadow_t; 156 extern object_shadow_t * destructed_obj_shadows; 157 extern object_shadow_t * newly_destructed_obj_shadows; 158 extern void check_object_shadow (object_t *ob, object_shadow_t *sh); 159 extern void check_all_object_shadows (void); 160 extern void update_object_sent(object_t *obj, sentence_t *new_sent); 161 #endif /* CHECK_OBJECT_REF */ 162 163 /* --- Macros --- */ 164 165 #define RESET_LIMITS ( max_array_size = def_array_size \ 166 , max_mapping_size = def_mapping_size \ 167 , max_mapping_keys = def_mapping_keys \ 168 , max_eval_cost = def_eval_cost \ 169 , max_file_xfer = def_file_xfer \ 170 , max_byte_xfer = def_byte_xfer \ 171 , max_callouts = def_callouts \ 172 , use_eval_cost = DEF_USE_EVAL_COST \ 173 ) 174 175 /* (Re)Initialize the runtime limits from the given default values. 176 */ 177 178 #define ERROR_BUF_LEN 10240 179 /* Length of the fixed buffer for error messages. 180 */ 181 182 #define ERROR_FMT_LEN 2048 183 /* Length of the fixed buffer for error message formats. 184 */ 185 186 /* --- Variables --- */ 187 188 extern struct error_recovery_info toplevel_context; 189 extern rt_context_t *rt_context; 190 191 extern size_t def_array_size; 192 extern size_t def_mapping_size; 193 extern size_t def_mapping_keys; 194 extern int32 def_eval_cost; 195 extern int32 def_file_xfer; 196 extern int32 def_byte_xfer; 197 extern int32 def_callouts; 198 #define DEF_USE_EVAL_COST (-100) 199 200 extern size_t max_array_size; 201 extern size_t max_mapping_size; 202 extern size_t max_mapping_keys; 203 extern int32 max_eval_cost; 204 extern int32 max_file_xfer; 205 extern int32 max_byte_xfer; 206 extern int32 max_callouts; 207 extern int32 use_eval_cost; 208 209 extern object_t *obj_list; 210 extern object_t *obj_list_end; 211 extern object_t *master_ob; 212 extern object_t *destructed_objs; 213 extern object_t *newly_destructed_objs; 214 extern long num_destructed; 215 extern long num_newly_destructed; 216 217 extern object_t *current_object; 218 extern object_t *current_interactive; 219 extern object_t *previous_ob; 220 221 extern svalue_t driver_hook[]; 222 223 extern int num_error; 224 extern int num_warning; 225 extern string_t *current_error; 226 extern string_t *current_error_file; 227 extern string_t *current_error_object_name; 228 extern mp_int current_error_line_number; 229 extern vector_t *uncaught_error_trace; 230 extern vector_t *current_error_trace; 231 232 extern Bool game_is_being_shut_down; 233 extern Bool master_will_be_updated; 234 235 /* --- Prototypes --- */ 236 237 #ifndef USE_NEW_INLINES 238 extern Bool catch_instruction (int flags, uint offset, volatile svalue_t ** volatile i_sp, bytecode_p i_pc, svalue_t * i_fp, int32 reserve_cost); 239 #else 240 extern Bool catch_instruction (int flags, uint offset, volatile svalue_t ** volatile i_sp, bytecode_p i_pc, svalue_t * i_fp, int32 reserve_cost, svalue_t *i_context); 241 #endif /* USE_NEW_INLINES */ 242 extern void check_shadow_sent (object_t *ob); 243 extern void assert_shadow_sent (object_t *ob); 244 extern void init_empty_callback (callback_t *cb); 245 extern int setup_function_callback(callback_t *cb, object_t* ob, string_t *fun, int nargs, svalue_t * args, Bool delayed_callback); 246 extern int setup_closure_callback(callback_t *cb, svalue_t *cl, int nargs, svalue_t * args, Bool delayed_callback); 247 extern int setup_efun_callback_base ( callback_t *cb, svalue_t *args, int nargs, Bool bNoObj); 248 #define setup_efun_callback(cb,args,nargs) setup_efun_callback_base(cb,args,nargs,MY_FALSE) 249 #define setup_efun_callback_noobj(cb,args,nargs) setup_efun_callback_base(cb,args,nargs,MY_TRUE) 250 extern void free_callback (callback_t *cb); 251 extern svalue_t *execute_callback (callback_t *cb, int nargs, Bool keep, Bool toplevel); 252 #define apply_callback(cb,nargs) execute_callback(cb,nargs,MY_TRUE,MY_FALSE) 253 #define backend_callback(cb,nargs) execute_callback(cb,nargs,MY_FALSE,MY_TRUE) 254 extern object_t *callback_object(callback_t *cb); 255 extern void callback_change_object (callback_t *cb, object_t *obj); 256 #ifdef DEBUG 257 extern void count_callback_extra_refs (callback_t *cb); 258 #endif 259 #ifdef GC_SUPPORT 260 extern void clear_ref_in_callback (callback_t *cb); 261 extern void count_ref_in_callback (callback_t *cb); 262 #endif 263 extern void init_driver_hooks(void); 264 extern void set_svalue_user(svalue_t *svp, object_t *owner); 265 extern void destruct_object(svalue_t *v); 266 extern void destruct(object_t *ob); 267 extern void deep_destruct (object_t *ob); 268 extern void handle_newly_destructed_objects(void); 269 extern void remove_destructed_objects (Bool force); 270 extern void print_svalue(svalue_t *arg); 271 extern const char *make_name_sane(const char *pName, Bool addSlash); 272 extern object_t *lookfor_object(string_t *str, Bool bLoad); 273 #define find_object(str) lookfor_object((str), MY_FALSE) 274 #define get_object(str) lookfor_object((str), MY_TRUE) 275 extern object_t *find_object_str(const char *str); 276 extern Bool status_parse(strbuf_t * sbuf, char *buff); 277 extern void dinfo_data_status(svalue_t * svp, int value); 278 extern void warnf VARPROT((char *, ...), printf, 1, 2); 279 extern void errorf VARPROT((const char *, ...), printf, 1, 2) NORETURN; 280 extern void fatal VARPROT((const char *, ...), printf, 1, 2) NORETURN; 281 extern void throw_error(svalue_t *v) NORETURN; 282 extern char *limit_error_format(char *fixed_fmt, size_t fixed_fmt_len, const char *fmt); 283 extern Bool legal_path(const char *path); 284 extern Bool check_no_parentdirs(const char *path); 285 extern void parse_error(Bool warning, const char *error_file, int line, const char *what, const char *context); 286 extern string_t *check_valid_path(string_t *path, object_t *caller, string_t *call_fun, Bool writeflg); 287 extern Bool match_string(const char *match, const char *str, mp_int len); 288 289 extern svalue_t *f_write(svalue_t *sp); 290 extern svalue_t *f_clone_object(svalue_t *sp); 291 extern svalue_t *f_destruct(svalue_t *sp); 292 extern svalue_t *f_find_object(svalue_t *sp); 293 extern svalue_t *f_load_object(svalue_t *sp); 294 extern svalue_t *f_set_driver_hook(svalue_t *sp); 295 extern svalue_t *f_shadow(svalue_t *sp); 296 extern svalue_t *f_query_shadowing(svalue_t *sp); 297 extern svalue_t *f_unshadow(svalue_t *sp); 298 extern svalue_t *v_limited(svalue_t * sp, int num_arg); 299 extern svalue_t *v_set_limits(svalue_t * sp, int num_arg); 300 extern svalue_t *f_query_limits(svalue_t * sp); 301 302 #endif /* SIMULATE_H__ */ 303