/*
* LANGUAGE - Language support
*
* Author:
* Emile van Bergen, emile@evbergen.xs4all.nl
*
* Permission to redistribute an original or modified version of this program
* in source, intermediate or object code form is hereby granted exclusively
* under the terms of the GNU General Public License, version 2. Please see the
* file COPYING for details, or refer to http://www.gnu.org/copyleft/gpl.html.
*
* History:
* 2001/05/06 - EvB - Created
*/
/*
* INCLUDES & DEFINES
*/
#include <sys/types.h> /* For ssize_t */
#include <metaops.h> /* For META, META_AV */
/* Stack machine result codes */
#define VM_CONTINUE 0
#define VM_HALTED 1
#define VM_ABORTED 2
#define VM_OVERFLOW 3
#define VM_UNDERFLOW 4
#define VM_NOMEM 5
#define VM_INVALIDOP 6
#define VM_INVALIDARG 7
#define VM_IFACETRAP 8
/* Stack machine opcodes */
/* Low nibble opcode type specifiers. Note that if any of these are different,
* the opcode is also *called* differently, so don't misuse the type flags as
* some form of immediate operand!
*
* (bits 0-1: stack requirements)
* 0 = nothing needed
* 1 = fixup one
* 2 = fixup two, discard one
* 3 = discard one
*
* (bit 2: if fixup two, default list for left (2nd) arg, reserved otherwise)
* 0 = default for left term is request list
* 1 = default for left term is reply list
*
* (bit 3: reserved)
*/
#define OP_FIXCNT(opcode) (((opcode) & 3) <= 2 ? ((opcode) & 3) : 0)
#define OP_DSCCNT(opcode) (((opcode) >> 1) & 1)
#define OP_USEREP(opcode, arg) (((opcode) >> 2) & ((arg) == ((opcode) & 3)))
/* arg: l=2, r=1, so the above applies for opcode's highest arg. */
#define OP_HALT 0x00000
#define OP_ABORT 0xffff0
#define OP_ACCEPT 0xf0000
#define OP_REJECT 0xf0010
#define OP_ACCTRESP 0xf0020
#define OP_NOP 0x00010
#define OP_PUSHINT 0x00020
#define OP_PUSHSTR 0x00030
#define OP_PUSHAV 0x00040 /* ref to first/last atr from req/rep */
#define OP_POP 0x00053 /* discard */
#define OP_NEG 0x00061
#define OP_NOT 0x00071
#define OP_MUL 0x00082
#define OP_DIV 0x00092
#define OP_CIDRMASK 0x000a2 /* mask address using CIDR netmask */
#define OP_MOD 0x000b2
#define OP_ADD 0x000c2
#define OP_SUB 0x000d2
#define OP_SHL 0x000e2
#define OP_SHR 0x000f2
#define OP_XOR 0x00102
#define OP_AND 0x00112
#define OP_OR 0x00122
#define OP_GE 0x00132
#define OP_LE 0x00142
#define OP_GT 0x00152
#define OP_LT 0x00162
#define OP_EQ 0x00172
#define OP_NE 0x00182
#define OP_BF 0x00192 /* before first */
#define OP_AF 0x001a2 /* after first */
#define OP_BL 0x001b2 /* before last */
#define OP_AL 0x001c2 /* after last */
#define OP_FO 0x001d2 /* first of */
#define OP_LO 0x001e2 /* last of */
#define OP_MD5 0x001f1
#define OP_HEX 0x00201
#define OP_UPPER 0x00211
#define OP_LOWER 0x00221
#define OP_RANDOM 0x00231
#define OP_DICTENC 0x00240 /* encode rep using given dict. space */
#define OP_XORSTR 0x00262
#define OP_CONCAT 0x00272
#define OP_GESTR 0x00282
#define OP_LESTR 0x00292
#define OP_GTSTR 0x002a2
#define OP_LTSTR 0x002b2
#define OP_EQSTR 0x002c2
#define OP_NESTR 0x002d2
#define OP_OCTSTR2ORD 0x00301
#define OP_DECSTR2ORD 0x00311
#define OP_HEXSTR2ORD 0x00321
#define OP_RAWSTR2ORD 0x00331 /* binary value in network order */
#define OP_IPASTR2ORD 0x00341 /* n.n.n.n */
#define OP_DATSTR2ORD 0x00351 /* YYYYMMDDhhmmss */
#define OP_INTSTR2ORD 0x00361 /* leading 0 = oct, leading 0x = hex */
#define OP_ORD2OCTSTR 0x00381
#define OP_ORD2DECSTR 0x00391
#define OP_ORD2HEXSTR 0x003a1
#define OP_ORD2RAWSTR 0x003b1 /* binary value in network order */
#define OP_ORD2IPASTR 0x003c1 /* n.n.n.n */
#define OP_ORD2DATSTR 0x003d1 /* YYYYMMDDhhmmss */
#define OP_ORD2DFMSTR 0x003e2 /* formatted date using strftime() */
#define OP_STR2MAC 0x003f2 /* canonicalized MAC address */
#define OP_PAPDECR 0x00402 /* decrypt/encrypt with PAP method */
#define OP_PAPENCR 0x00412 /* using Secret . Authenticator */
#define OP_UNIXCRYPT 0x00422 /* unix crypt(3) using given salt */
#define OP_HMACMD5 0x00432 /* HMAC using MD5 with given key */
#define OP_DICTDEC 0x00442 /* decode using given dict. space */
#define OP_EXISTS 0x00481 /* returns 1 if resolved */
#define OP_BOOLNOT 0x00491 /* boolean not, returns 1 when false */
#define OP_JMPZ 0x004a1 /* jmp if zero (false) */
#define OP_JMPNZ 0x004b1 /* jmp if nonzero (true) */
#define OP_ADDAV 0x00506 /* add referenced AV based on term */
#define OP_REPLACEAV 0x00516 /* replace referenced AV with term */
#define OP_POKEAV 0x00526 /* poke at referenced AV's memory */
#define OP_DELAV 0x00535 /* delete referenced AV (see code) */
#define OP_DELALLAV 0x00540 /* delete all inst. of referenced AV */
#define OP_MOVEALLAV 0x00550 /* copy all inst. of referenced AV */
#define OP_JOINSTR 0x00560 /* join all inst. of referenced AV into
stack item */
#define OP_CALLIFACE 0x00600 /* call external interface */
/* Request and Reply list indexes for head and tail arrays */
#define VM_REQ 0
#define VM_REP 1
/*
* TYPES
*/
typedef struct insn {
int op; /* Opcode */
union {
META_ORD ord;
struct {
short disp; /* Displacement for jmpXX and pushstr */
short str_len; /* String length in bytes for pushstr */
} d;
struct {
META_ITEM *item;
int flags; /* Flags for META_AV object on stack */
} i;
struct iface *iface;
} imm; /* Immediate operand */
} INSN;
typedef struct vm {
INSN *ip, *codeend;
META_AV *stk, *head[2], *tail[2]; /* 0 = req, 1 = rep */
int sp, stackend; /* sp is index in stack array; stack grows up */
} VM;
/*
* PROTOTYPES
*/
/* langcompile.c */
#ifdef COMP_MEM
ssize_t lang_compile(META *m, struct iface *ifaces, char *source,
INSN *buf, ssize_t bufsize);
#else
struct text;
ssize_t lang_compile(META *m, struct iface *ifaces, struct text *source,
INSN *buf, ssize_t bufsize);
#endif
/* langdisasm.c */
void lang_disassemble(META *m, INSN *i, ssize_t bufsize);
/* langvm.c */
VM *vm_new(INSN *code, ssize_t len, int stackend,
META_AV *reqhead, META_AV *reqtail,
META_AV *rephead, META_AV *reptail);
void vm_chgcode(VM *vm, INSN *code, ssize_t len);
void vm_popall(VM *vm);
void vm_del(VM *vm);
int vm_run(META *m, VM *vm);
struct iface *vm_getiface(VM *vm);
void vm_dumptrace(VM *vm, META *m, INSN *codestart);
void vm_dumpstack(VM *vm, META *m);
syntax highlighted by Code2HTML, v. 0.9.1