2009-03-03 03:27:01 +00:00
|
|
|
#ifndef SIMULATE_H__
|
|
|
|
#define SIMULATE_H__ 1
|
|
|
|
|
|
|
|
#include <setjmp.h>
|
|
|
|
|
|
|
|
#include "driver.h"
|
|
|
|
#include "typedefs.h"
|
|
|
|
|
|
|
|
#include "bytecode.h"
|
|
|
|
#include "sent.h" /* shadow_sentence_t */
|
|
|
|
#include "strfuns.h" /* strbuf_t */
|
|
|
|
#include "svalue.h"
|
|
|
|
|
|
|
|
/* --- Types --- */
|
|
|
|
|
|
|
|
/* --- struct rt_context_s: runtime context information
|
|
|
|
*
|
|
|
|
* The runtime context struct is made up from children of these structures.
|
|
|
|
* The stack is used to store nested changes in the runtime context, may
|
|
|
|
* they be error recovery contexts, changes in the runtime limits, or else.
|
|
|
|
*
|
|
|
|
* Storing all this information into one stack makes it much easier to restore
|
|
|
|
* a previous context in case of errors. For that, error recovery information
|
|
|
|
* plays the most important role in this stack.
|
|
|
|
*
|
|
|
|
* Most of the stack entries are allocated on the stack, only few are
|
|
|
|
* allocated on the heap.
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct rt_context_s
|
|
|
|
{
|
|
|
|
struct rt_context_s *last; /* Previous context, or NULL */
|
|
|
|
int type; /* Type of this context entry */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* rt_context_s.type:
|
|
|
|
*
|
|
|
|
* Positive values are all ERROR_RECOVERY types, negative values
|
|
|
|
* denote other context types.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define LIMITS_CONTEXT -2
|
|
|
|
/* The previous set of runtime limits.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define COMMAND_CONTEXT -1
|
|
|
|
/* The previous command context (struct command_context in simulate.c).
|
|
|
|
* For the very first command given, this is all 0.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* For the following context types, the stack entry is in fact
|
|
|
|
* a error_recovery_info structure.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define ERROR_RECOVERY_NONE 0
|
|
|
|
/* No error recovery available (used by the top entry in the stack).
|
|
|
|
*/
|
|
|
|
#define ERROR_RECOVERY_BACKEND 1
|
|
|
|
/* Errors fall back to the backend, e.g. process_objects(),
|
|
|
|
* call_heart_beat() and others.
|
|
|
|
*/
|
|
|
|
#define ERROR_RECOVERY_APPLY 2
|
|
|
|
/* Errors fall back into the secure_apply() function used for sensitive
|
|
|
|
* applies.
|
|
|
|
*/
|
|
|
|
#define ERROR_RECOVERY_CATCH 3
|
|
|
|
/* Errors are caught in interpret.c by the catch() construct.
|
|
|
|
* This is in fact an extended error_recovery_info structure which
|
|
|
|
* is allocated on the heap.
|
|
|
|
*
|
|
|
|
* The CATCH context has a number of attributes, expressed by bitflags:
|
|
|
|
*/
|
|
|
|
#define CATCH_FLAG_NOLOG (0x01) /* The traceback is not logged */
|
|
|
|
#define CATCH_FLAG_PUBLISH (0x02) /* master::runtime_error() is called
|
|
|
|
* despite the error being caught.
|
|
|
|
*/
|
|
|
|
/* The following flags are used only by the bytecode interpreter
|
|
|
|
* to set up the instruction.
|
|
|
|
*/
|
|
|
|
#define CATCH_FLAG_RESERVE (0x04) /* The amount of ticks to keep in reserve
|
|
|
|
* is given on the stack.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#define ERROR_RECOVERY_CONTEXT(t) ((t) >= ERROR_RECOVERY_NONE)
|
|
|
|
/* True, if rt_context_s.type 't' denotes a error recovery context.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define ERROR_RECOVERY_CAUGHT(t) ((t) == ERROR_RECOVERY_CATCH)
|
|
|
|
/* True, if rt_context_s.type 't' denotes a catch recovery context.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* --- struct longjump_s: longjump context information
|
|
|
|
*
|
|
|
|
* This structure contains the necessary data to execute a longjmp()
|
|
|
|
* when recovering from an error.
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct longjump_s { jmp_buf text; };
|
|
|
|
|
|
|
|
|
|
|
|
/* --- struct error_recovery_info: error recovery context
|
|
|
|
*
|
|
|
|
* The error recovery stack is made up from these structures, describing
|
|
|
|
* the nature of the error handling, and where to jump back to.
|
|
|
|
*
|
|
|
|
* For ERROR_RECOVERY_CATCH contexts, the stack element is in fact a larger
|
|
|
|
* structure containing the error_recovery_info as first member, with
|
|
|
|
* additional members holding the information needed to perform a catch().
|
|
|
|
* That structure and all handling routines are local to interpret.c .
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct error_recovery_info
|
|
|
|
{
|
|
|
|
rt_context_t rt;
|
|
|
|
int flags; /* Flags for ERROR_RECOVERY_CATCH. */
|
|
|
|
struct longjump_s con; /* longjmp() information */
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* --- struct callback: describes a function call plus arguments
|
|
|
|
*
|
|
|
|
* This structure is used by input_tos and call_outs to store the
|
|
|
|
* information about the function to call and the arguments to pass.
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct callback_s {
|
|
|
|
union { /* The function to call: by name or the closure */
|
|
|
|
struct {
|
|
|
|
string_t *name; /* the tabled function name */
|
|
|
|
object_t *ob; /* reference to the object to call */
|
|
|
|
} named;
|
|
|
|
svalue_t lambda; /* the closure to call */
|
|
|
|
} function;
|
|
|
|
Bool is_lambda; /* Closure or named function? */
|
|
|
|
int num_arg; /* Number of arguments */
|
|
|
|
svalue_t arg;
|
|
|
|
/* Arguments to pass:
|
|
|
|
* - T_INVALID if no arguments
|
|
|
|
* - a single argument
|
|
|
|
* - T_LVALUE with u.lvalue pointing to the svalue_t[] with
|
|
|
|
* the arguments. If arg.x.extern_args is TRUE, the block
|
|
|
|
* was allocated from outside and is outside of our control.
|
|
|
|
* No argument can be a LVALUE itself.
|
|
|
|
*/
|
|
|
|
};
|
|
|
|
|
|
|
|
#ifdef CHECK_OBJECT_REF
|
|
|
|
typedef struct object_shadow_s {
|
|
|
|
struct object_shadow_s * next;
|
|
|
|
object_t * obj;
|
|
|
|
unsigned short flags;
|
|
|
|
p_int ref;
|
|
|
|
sentence_t *sent;
|
|
|
|
} object_shadow_t;
|
|
|
|
extern object_shadow_t * destructed_obj_shadows;
|
|
|
|
extern object_shadow_t * newly_destructed_obj_shadows;
|
|
|
|
extern void check_object_shadow (object_t *ob, object_shadow_t *sh);
|
|
|
|
extern void check_all_object_shadows (void);
|
|
|
|
extern void update_object_sent(object_t *obj, sentence_t *new_sent);
|
|
|
|
#endif /* CHECK_OBJECT_REF */
|
|
|
|
|
|
|
|
/* --- Macros --- */
|
|
|
|
|
|
|
|
#define RESET_LIMITS ( max_array_size = def_array_size \
|
|
|
|
, max_mapping_size = def_mapping_size \
|
|
|
|
, max_mapping_keys = def_mapping_keys \
|
|
|
|
, max_eval_cost = def_eval_cost \
|
|
|
|
, max_file_xfer = def_file_xfer \
|
|
|
|
, max_byte_xfer = def_byte_xfer \
|
|
|
|
, max_callouts = def_callouts \
|
|
|
|
, use_eval_cost = DEF_USE_EVAL_COST \
|
|
|
|
)
|
|
|
|
|
|
|
|
/* (Re)Initialize the runtime limits from the given default values.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define ERROR_BUF_LEN 10240
|
|
|
|
/* Length of the fixed buffer for error messages.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define ERROR_FMT_LEN 2048
|
|
|
|
/* Length of the fixed buffer for error message formats.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* --- Variables --- */
|
|
|
|
|
|
|
|
extern struct error_recovery_info toplevel_context;
|
|
|
|
extern rt_context_t *rt_context;
|
|
|
|
|
|
|
|
extern size_t def_array_size;
|
|
|
|
extern size_t def_mapping_size;
|
|
|
|
extern size_t def_mapping_keys;
|
|
|
|
extern int32 def_eval_cost;
|
|
|
|
extern int32 def_file_xfer;
|
|
|
|
extern int32 def_byte_xfer;
|
|
|
|
extern int32 def_callouts;
|
|
|
|
#define DEF_USE_EVAL_COST (-100)
|
|
|
|
|
|
|
|
extern size_t max_array_size;
|
|
|
|
extern size_t max_mapping_size;
|
|
|
|
extern size_t max_mapping_keys;
|
|
|
|
extern int32 max_eval_cost;
|
|
|
|
extern int32 max_file_xfer;
|
|
|
|
extern int32 max_byte_xfer;
|
|
|
|
extern int32 max_callouts;
|
|
|
|
extern int32 use_eval_cost;
|
|
|
|
|
|
|
|
extern object_t *obj_list;
|
|
|
|
extern object_t *obj_list_end;
|
|
|
|
extern object_t *master_ob;
|
|
|
|
extern object_t *destructed_objs;
|
|
|
|
extern object_t *newly_destructed_objs;
|
|
|
|
extern long num_destructed;
|
|
|
|
extern long num_newly_destructed;
|
|
|
|
|
|
|
|
extern object_t *current_object;
|
|
|
|
extern object_t *current_interactive;
|
|
|
|
extern object_t *previous_ob;
|
|
|
|
|
|
|
|
extern svalue_t driver_hook[];
|
|
|
|
|
|
|
|
extern int num_error;
|
|
|
|
extern int num_warning;
|
|
|
|
extern string_t *current_error;
|
|
|
|
extern string_t *current_error_file;
|
|
|
|
extern string_t *current_error_object_name;
|
|
|
|
extern mp_int current_error_line_number;
|
|
|
|
extern vector_t *uncaught_error_trace;
|
|
|
|
extern vector_t *current_error_trace;
|
|
|
|
|
2009-05-21 22:41:07 +00:00
|
|
|
extern Bool game_is_being_shut_down;
|
|
|
|
extern Bool master_will_be_updated;
|
2009-03-03 03:27:01 +00:00
|
|
|
|
|
|
|
/* --- Prototypes --- */
|
|
|
|
|
|
|
|
#ifndef USE_NEW_INLINES
|
|
|
|
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);
|
|
|
|
#else
|
|
|
|
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);
|
|
|
|
#endif /* USE_NEW_INLINES */
|
|
|
|
#ifdef USE_SHADOWING
|
|
|
|
extern void check_shadow_sent (object_t *ob);
|
|
|
|
extern void assert_shadow_sent (object_t *ob);
|
|
|
|
#endif
|
|
|
|
extern void init_empty_callback (callback_t *cb);
|
|
|
|
extern int setup_function_callback(callback_t *cb, object_t* ob, string_t *fun, int nargs, svalue_t * args, Bool delayed_callback);
|
|
|
|
extern int setup_closure_callback(callback_t *cb, svalue_t *cl, int nargs, svalue_t * args, Bool delayed_callback);
|
|
|
|
extern int setup_efun_callback_base ( callback_t *cb, svalue_t *args, int nargs, Bool bNoObj);
|
|
|
|
#define setup_efun_callback(cb,args,nargs) setup_efun_callback_base(cb,args,nargs,MY_FALSE)
|
|
|
|
#define setup_efun_callback_noobj(cb,args,nargs) setup_efun_callback_base(cb,args,nargs,MY_TRUE)
|
|
|
|
extern void free_callback (callback_t *cb);
|
|
|
|
extern svalue_t *execute_callback (callback_t *cb, int nargs, Bool keep, Bool toplevel);
|
|
|
|
#define apply_callback(cb,nargs) execute_callback(cb,nargs,MY_TRUE,MY_FALSE)
|
|
|
|
#define backend_callback(cb,nargs) execute_callback(cb,nargs,MY_FALSE,MY_TRUE)
|
|
|
|
extern object_t *callback_object(callback_t *cb);
|
|
|
|
extern void callback_change_object (callback_t *cb, object_t *obj);
|
|
|
|
#ifdef DEBUG
|
|
|
|
extern void count_callback_extra_refs (callback_t *cb);
|
|
|
|
#endif
|
|
|
|
#ifdef GC_SUPPORT
|
|
|
|
extern void clear_ref_in_callback (callback_t *cb);
|
|
|
|
extern void count_ref_in_callback (callback_t *cb);
|
|
|
|
#endif
|
|
|
|
extern void init_driver_hooks(void);
|
|
|
|
extern void set_svalue_user(svalue_t *svp, object_t *owner);
|
|
|
|
extern void destruct_object(svalue_t *v);
|
|
|
|
extern void destruct(object_t *ob);
|
|
|
|
extern void deep_destruct (object_t *ob);
|
|
|
|
extern void handle_newly_destructed_objects(void);
|
|
|
|
extern void remove_destructed_objects (Bool force);
|
|
|
|
extern void print_svalue(svalue_t *arg);
|
|
|
|
extern const char *make_name_sane(const char *pName, Bool addSlash);
|
|
|
|
extern object_t *lookfor_object(string_t *str, Bool bLoad);
|
|
|
|
#define find_object(str) lookfor_object((str), MY_FALSE)
|
|
|
|
#define get_object(str) lookfor_object((str), MY_TRUE)
|
|
|
|
extern object_t *find_object_str(const char *str);
|
|
|
|
extern Bool status_parse(strbuf_t * sbuf, char *buff);
|
|
|
|
extern void dinfo_data_status(svalue_t * svp, int value);
|
|
|
|
extern void warnf VARPROT((char *, ...), printf, 1, 2);
|
|
|
|
extern void errorf VARPROT((const char *, ...), printf, 1, 2) NORETURN;
|
|
|
|
extern void fatal VARPROT((const char *, ...), printf, 1, 2) NORETURN;
|
2009-05-21 22:41:07 +00:00
|
|
|
extern void throw_error(svalue_t *v) NORETURN;
|
2009-03-03 03:27:01 +00:00
|
|
|
extern char *limit_error_format(char *fixed_fmt, size_t fixed_fmt_len, const char *fmt);
|
|
|
|
extern Bool legal_path(const char *path);
|
|
|
|
extern Bool check_no_parentdirs(const char *path);
|
|
|
|
extern void parse_error(Bool warning, const char *error_file, int line, const char *what, const char *context);
|
|
|
|
extern string_t *check_valid_path(string_t *path, object_t *caller, string_t *call_fun, Bool writeflg);
|
|
|
|
extern Bool match_string(const char *match, const char *str, mp_int len);
|
|
|
|
|
|
|
|
extern svalue_t *f_write(svalue_t *sp);
|
|
|
|
extern svalue_t *f_clone_object(svalue_t *sp);
|
|
|
|
extern svalue_t *f_destruct(svalue_t *sp);
|
|
|
|
extern svalue_t *f_find_object(svalue_t *sp);
|
|
|
|
extern svalue_t *f_load_object(svalue_t *sp);
|
|
|
|
extern svalue_t *f_set_driver_hook(svalue_t *sp);
|
|
|
|
#ifdef USE_SHADOWING
|
|
|
|
extern svalue_t *f_shadow(svalue_t *sp);
|
|
|
|
extern svalue_t *f_query_shadowing(svalue_t *sp);
|
|
|
|
extern svalue_t *f_unshadow(svalue_t *sp);
|
|
|
|
#endif
|
|
|
|
extern svalue_t *v_limited(svalue_t * sp, int num_arg);
|
|
|
|
extern svalue_t *v_set_limits(svalue_t * sp, int num_arg);
|
|
|
|
extern svalue_t *f_query_limits(svalue_t * sp);
|
|
|
|
|
|
|
|
#endif /* SIMULATE_H__ */
|