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