# define I_INSTR_MASK 0x1f /* instruction mask */ # define I_PUSH_ZERO 0 # define I_PUSH_ONE 1 # define I_PUSH_INT1 2 /* 1 signed */ # define I_PUSH_INT4 3 /* 4 signed */ # define I_PUSH_FLOAT 4 /* 6 unsigned */ # define I_PUSH_STRING 5 /* 1 unsigned */ # define I_PUSH_NEAR_STRING 6 /* 1 unsigned, 1 unsigned */ # define I_PUSH_FAR_STRING 7 /* 1 unsigned, 2 unsigned */ # define I_PUSH_LOCAL 8 /* 1 signed */ # define I_PUSH_GLOBAL 9 /* 1 unsigned */ # define I_PUSH_FAR_GLOBAL 10 /* 1 unsigned, 1 unsigned */ # define I_PUSH_LOCAL_LVAL 11 /* 1 signed */ # define I_PUSH_GLOBAL_LVAL 12 /* 1 unsigned */ # define I_PUSH_FAR_GLOBAL_LVAL 13 /* 1 unsigned, 1 unsigned */ # define I_INDEX 14 # define I_INDEX_LVAL 15 # define I_AGGREGATE 16 /* 1 unsigned, 2 unsigned */ # define I_SPREAD 17 /* 1 signed */ # define I_CAST 18 /* 1 unsigned */ # define I_FETCH 19 # define I_STORE 20 # define I_JUMP 21 /* 2 unsigned */ # define I_JUMP_ZERO 22 /* 2 unsigned */ # define I_JUMP_NONZERO 23 /* 2 unsigned */ # define I_SWITCH 24 /* n */ # define I_CALL_KFUNC 25 /* 1 unsigned (+ 1 unsigned) */ # define I_CALL_AFUNC 26 /* 1 unsigned, 1 unsigned */ # define I_CALL_DFUNC 27 /* 1 unsigned, 1 unsigned, 1 unsigned */ # define I_CALL_FUNC 28 /* 2 unsigned, 1 unsigned */ # define I_CATCH 29 /* 2 unsigned */ # define I_RLIMITS 30 # define I_RETURN 31 # define I_LINE_MASK 0xc0 /* line add bits */ # define I_POP_BIT 0x20 /* pop 1 after instruction */ # define I_TYPE_BIT I_POP_BIT /* lvalue typechecks assignment */ # define I_LINE_SHIFT 6 # define FETCH1S(pc) SCHAR(*(pc)++) # define FETCH1U(pc) UCHAR(*(pc)++) # define FETCH2S(pc, v) ((short) (v = *(pc)++ << 8, v |= UCHAR(*(pc)++))) # define FETCH2U(pc, v) ((unsigned short) (v = *(pc)++ << 8, \ v |= UCHAR(*(pc)++))) # define FETCH3S(pc, v) ((Int) (v = *(pc)++ << 8, \ v |= UCHAR(*(pc)++), v <<= 8, \ v |= UCHAR(*(pc)++))) # define FETCH3U(pc, v) ((Uint) (v = UCHAR(*(pc)++) << 8, \ v |= UCHAR(*(pc)++), v <<= 8, \ v |= UCHAR(*(pc)++))) # define FETCH4S(pc, v) ((Int) (v = *(pc)++ << 8, \ v |= UCHAR(*(pc)++), v <<= 8, \ v |= UCHAR(*(pc)++), v <<= 8, \ v |= UCHAR(*(pc)++))) # define FETCH4U(pc, v) ((Uint) (v = *(pc)++ << 8, \ v |= UCHAR(*(pc)++), v <<= 8, \ v |= UCHAR(*(pc)++), v <<= 8, \ v |= UCHAR(*(pc)++))) # define T_TYPE 0x0f /* type mask */ # define T_INVALID 0x00 # define T_INT 0x01 # define T_FLOAT 0x02 # define T_STRING 0x03 # define T_OBJECT 0x04 # define T_ARRAY 0x05 /* value type only */ # define T_MAPPING 0x06 # define T_RESERVED 0x07 /* reserved for add-on packages */ # define T_MIXED 0x08 /* declaration type only */ # define T_VOID 0x09 /* function return type only */ # define T_LVALUE 0x0a /* address of a value */ # define T_SLVALUE 0x0b /* indexed string lvalue */ # define T_ALVALUE 0x0c /* indexed array lvalue */ # define T_MLVALUE 0x0d /* indexed mapping lvalue */ # define T_SALVALUE 0x0e /* indexed string indexed array lvalue */ # define T_SMLVALUE 0x0f /* indexed string indexed mapping lvalue */ # define T_ELLIPSIS 0x10 /* or'ed with declaration type */ # define T_REF 0xe0 /* reference count mask */ # define REFSHIFT 5 # define T_ARITHMETIC(t) ((t) <= T_FLOAT) # define T_ARITHSTR(t) ((t) <= T_STRING) # define T_INDEXED(t) ((t) >= T_ARRAY) /* only T_ARRAY and T_MAPPING */ # define TYPENAMES { "invalid", "int", "float", "string", "object", \ "array", "mapping", "reserved", "mixed", "void" } struct _value_ { char type; /* value type */ bool modified; /* dirty bit */ uindex oindex; /* index in object table */ union { Int number; /* number */ Uint objcnt; /* object creation count */ string *string; /* string */ array *array; /* array or mapping */ value *lval; /* lvalue: variable */ } u; }; # define VFLT_GET(v, f) ((f).high = (v)->oindex, (f).low = (v)->u.objcnt) # define VFLT_PUT(v, f) ((v)->oindex = (f).high, (v)->u.objcnt = (f).low) # define VFLT_ISZERO(v) FLT_ISZERO((v)->oindex, (v)->u.objcnt) # define VFLT_ISONE(v) FLT_ISONE((v)->oindex, (v)->u.objcnt) # define VFLT_ONE(v) FLT_ONE((v)->oindex, (v)->u.objcnt) # define VFLT_ABS(v) FLT_ABS((v)->oindex, (v)->u.objcnt) # define VFLT_NEG(v) FLT_NEG((v)->oindex, (v)->u.objcnt) # define VFLT_HASH(v) ((v)->oindex ^ (v)->u.objcnt) # define DESTRUCTED(v) (otable[(v)->oindex].count != (v)->u.objcnt) # define C_PRIVATE 0x01 # define C_STATIC 0x02 # define C_NOMASK 0x04 # define C_VARARGS 0x08 # define C_ATOMIC 0x10 # define C_TYPECHECKED 0x20 # define C_COMPILED 0x40 # define C_UNDEFINED 0x80 struct _frame_ { frame *prev; /* previous stack frame */ object *obj; /* current object */ control *ctrl; /* object control block */ dataspace *data; /* dataspace of current object */ control *p_ctrl; /* program control block */ unsigned short p_index; /* program index */ unsigned short nargs; /* # arguments */ bool external; /* TRUE if it's an external call */ bool sos; /* stack on stack */ uindex foffset; /* program function offset */ struct _dfuncdef_ *func; /* current function */ char *prog; /* start of program */ char *pc; /* program counter */ value *stack; /* local value stack */ value *sp; /* stack pointer */ value *ilvp; /* indexed lvalue pointer */ value *argp; /* argument pointer (previous sp) */ value *fp; /* frame pointer (at end of local stack) */ value *prev_ilvp; /* previous indexed lvalue pointer */ string *lvstr; /* last indexed lvalue string */ Int depth; /* stack depth */ Int maxdepth; /* max stack depth */ Int ticks; /* ticks left */ bool nodepth; /* no stack depth checking */ bool noticks; /* no ticks checking */ short rli; /* rlimits stack index */ }; extern void i_init P((char*)); extern void i_ref_value P((value*)); extern void i_del_value P((value*)); extern void i_copy P((value*, value*, unsigned int)); extern void i_grow_stack P((frame*, int)); extern void i_push_value P((frame*, value*)); extern void i_pop P((frame*, int)); extern void i_odest P((frame*, object*)); extern void i_string P((frame*, int, unsigned int)); extern void i_aggregate P((frame*, unsigned int)); extern void i_map_aggregate P((frame*, unsigned int)); extern int i_spread P((frame*, int, int)); extern void i_global P((frame*, int, int)); extern void i_global_lvalue P((frame*, int, int, int)); extern void i_index P((frame*)); extern void i_index_lvalue P((frame*, int)); extern char *i_typename P((unsigned int)); extern void i_cast P((value*, unsigned int)); extern void i_fetch P((frame*)); extern void i_store P((frame*, value*, value*)); extern Int i_get_depth P((frame*)); extern Int i_get_ticks P((frame*)); extern int i_set_rlimits P((frame*, Int, Int)); extern int i_get_rllevel P((frame*)); extern void i_set_rllevel P((frame*, int)); extern frame *i_set_sp P((frame*, value*)); extern object *i_prev_object P((frame*, int)); extern char *i_prev_program P((frame*, int)); extern void i_typecheck P((frame*, char*, char*, char*, int, int)); extern void i_catcherr P((frame*, Int)); extern void i_funcall P((frame*, object*, int, int, int)); extern bool i_call P((frame*, object*, char*, unsigned int, int, int)); extern bool i_call_tracei P((frame*, Int, value*)); extern array *i_call_trace P((frame*)); extern bool i_call_critical P((frame*, char*, int, int)); extern void i_runtime_error P((frame*, Int)); extern void i_clear P((void)); extern frame *cframe; extern value zero_value, zero_float; # define i_add_ticks(f, t) ((f)->ticks -= (t))