⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bytecode.h

📁 一个学习SNMP项目:tmoerlan.
💻 H
字号:
/* $Id: bytecode.h,v 1.2 2003/09/17 11:26:10 tmoerlan Exp $ */#include <stdio.h>#include <limits.h>#include "config.h"#include "dyncheck.h"#include "wassert.h"#ifndef _SNAP_BYTECODE_H_#define _SNAP_BYTECODE_H_#ifdef CONFIG_IP_SNAP_SMALL_INSTRS#define SMALL_INSTRS#endif#ifdef CONFIG_IP_SNAP_SMALL_VALUES#define SMALL_VALUES#endif#ifdef TAG_CHECK#define DYNCHECK_TAG(v,tag) DYNCHECK(GET_TAG((v)) == (tag))#else#define DYNCHECK_TAG(v,tag) ((void)0)#endif/* having small representation for instructions requires small values   as well */#ifdef SMALL_INSTRS#ifndef SMALL_VALUES#define SMALL_VALUES#endif#endif/* enumeration of all value types -- these are the tags for the values */#ifdef SMALL_VALUES#define INTV	0		/* integers (32-bit) */#define ADDRV 	1		/* IPv4 addresses (32-bit) */#define STRV	2		/* strings/blobs */#define EXCV	3		/* exceptions */#define TUPLEV	4		/* tuples */#define FLOATV  5		/* 32-bit floats */#define BOGUSV  6		/* for ops that ignore the tag */#define TAG_T int/* not enough space to put addrs as literals when values are small */#ifndef ADDR_IN_HEAP#define ADDR_IN_HEAP#endif#elsetypedef enum {  INTV,				/* integers (32-bit) */  ADDRV,			/* IPv4 addresses (32-bit) */  STRV,				/* strings/blobs */  EXCV,				/* exceptions */  TUPLEV,			/* tuples */  FLOATV			/* 32-bit floats */} value_tag_t;#define TAG_T value_tag_t#endif/* heap objects are strings */#define LENTYPE unsigned short#define MAX_HEAPOBJ_SZ (1 << ((sizeof(unsigned short) * 8)))typedef struct {  LENTYPE len;			/* length of string/exc/tuple in bytes */  unsigned short flag;		/* legal values				   0          : non-ptr-containing object				   1          : ptr-containing object				   4,8,12,... : forwarding offset */  char s[0];			/* string (maybe not null terminated) */} heap_obj;/* stack value-- has a type tag plus the value itself */#ifdef SMALL_VALUEStypedef unsigned int value_t;#define ZERO_VALUE_T 0#ifdef SMALL_INSTRS#define TAGSZ 7#else#define TAGSZ 3#endif#define MAX_VINT (1 << ((sizeof(unsigned int) * 8-(TAGSZ+1))))#define MIN_VINT (- MAX_VINT - 1)#define GET_TAG(v) ((v) >> (sizeof(unsigned int)*8-TAGSZ))#define SET_TAG(v,t) ((v) = (((v) << TAGSZ) >> TAGSZ) | ((t) << (sizeof(unsigned int)*8-TAGSZ)))#define GET_INT(v) (((int)((v) << TAGSZ)) >> TAGSZ)#define SET_INT(v,i) ((v) = (((v) >> (sizeof(unsigned int)*8-TAGSZ)) << (sizeof(unsigned int)*8-TAGSZ)) | ((((unsigned int)(i)) << TAGSZ) >> TAGSZ))#define GET_OFFS GET_INT#define SET_OFFS SET_INT#define COPY_VAL(val1,val2) ((val1) = (val2))#define GET_BOXED(res,heap,v,t)					\{								\  heap_obj *ho1 = (heap_obj *)((heap) + GET_OFFS(v));		\  DYNCHECK_ADDR_IN_HEAP(ho1);					\  wassert(ho1->len == sizeof(t));				\  (res) = *((t *)ho1->s);					\}#define GET_ADDR(res,h,v) GET_BOXED(res,h,v,uint32_t)#define GET_FLOAT(res,h,v) GET_BOXED(res,h,v,float32)#define GET_ADDR_VAL(h,v) (*((uint32_t *)(((heap_obj *)((h) + GET_OFFS(v)))->s)))#define GET_FLT_VAL(h,v) (*((float32 *)(((heap_obj *)((h) + GET_OFFS(v)))->s)))#define FLTINTPAIR(f) (int)(f),(int)(((f) - (int)(f)) * 1000000)#define SET_ADDR(val,a,p)				\{ int hoffset;						\  heap_obj *ho;						\  if (!heap_alloc((p),sizeof(uint32_t),0,&ho,&hoffset)) {	\    *((uint32_t *)ho->s) = (a);				\    SET_OFFS(val,hoffset);				\  }							\  else return -1;					\}#define SET_FLOAT(val,a,p)				\{ int hoffset;						\  heap_obj *ho;						\  if (!heap_alloc((p),sizeof(float32),0,&ho,&hoffset)) {\    *((float32 *)ho->s) = (a);				\    SET_OFFS(val,hoffset);				\  }							\  else return -1;					\}#define IS_HEAP_VAL(v) \  ((GET_TAG(v) == ADDRV) || (GET_TAG(v) == STRV) || \   (GET_TAG(v) == TUPLEV) || (GET_TAG(v) == FLOATV))#elsetypedef struct {  TAG_T tag;			/* type tag */  union {    int intval;			/* 32-bit integer */#ifndef ADDR_IN_HEAP    uint32_t addrval;	/* 32-bit IPv4 address */    float32 floatval;		/* 32-bit float */#endif    int hoffset;		/* offset for a heap object */  } v;} value_t;#define ZERO_VALUE_T { 0, { 0 } }#define MAX_VINT INT_MAX#define MIN_VINT INT_MIN#define GET_TAG(val) ((val).tag)#define SET_TAG(val,t) ((val).tag = (t))#define GET_INT(val) ((val).v.intval)#define SET_INT(val,i) ((val).v.intval = (i))#define GET_OFFS(val) ((val).v.hoffset)#define SET_OFFS(val,o) ((val).v.hoffset = (o))#ifndef ADDR_IN_HEAP#define GET_ADDR(res,unused,val) ((res) = (val).v.addrval)#define SET_ADDR(val,a,unused) ((val).v.addrval = (a))#define GET_FLOAT(res,unused,val) ((res) = (val).v.floatval)#define SET_FLOAT(val,a,unused) ((val).v.floatval = (a))#define IS_HEAP_VAL(v) \  ((GET_TAG(v) == STRV) || (GET_TAG(v) == TUPLEV))#else#define GET_BOXED(res,heap,v,t)					\{								\  heap_obj *ho1 = (heap_obj *)((heap) + GET_OFFS(v));		\  DYNCHECK_ADDR_IN_HEAP(ho1);					\  wassert(ho1->len == sizeof(t));				\  (res) = *((t *)ho1->s);					\}#define GET_ADDR(res,h,v) GET_BOXED(res,h,v,uint32_t)#define GET_FLOAT(res,h,v) GET_BOXED(res,h,v,float32)#define GET_ADDR_VAL(h,v) (*((uint32_t *)(((heap_obj *)((h) + GET_OFFS(v)))->s)))#define GET_FLT_VAL(h,v) (*((float32 *)(((heap_obj *)((h) + GET_OFFS(v)))->s)))#define IS_HEAP_VAL(v) \  ((GET_TAG(v) == STRV) || (GET_TAG(v) == TUPLEV) || \   (GET_TAG(v) == ADDRV))#define FLTINTPAIR(f) (int)(f),(int)(((f) - (int)(f)) * 1000000)#define SET_ADDR(val,a,p)				\{ int hoffset;						\  heap_obj *ho;						\  if (!heap_alloc((p),sizeof(uint32_t),0,&ho,&hoffset)) {	\    *((uint32_t *)ho->s) = (a);				\    SET_OFFS(val,hoffset);				\  }							\  else return -1;					\}#define SET_FLOAT(val,a,p)				\{ int hoffset;						\  heap_obj *ho;						\  if (!heap_alloc((p),sizeof(float32),0,&ho,&hoffset)) {\    *((float32 *)ho->s) = (a);				\    SET_OFFS(val,hoffset);				\  }							\  else return -1;					\}#endif#define COPY_VAL(val1,val2) ((val1) = (val2))#endif/* opcodes */#ifdef SMALL_INSTRS#define  EXIT	0#define  PUSH	1 /* not used */#define  POP	2#define  POPI	3#define  PULL	4#define  STORE	5#define  PAJ	6#define  TPAJ	7#define  JI	8#define  BEZ	9#define  BNE	10#define  MKTUP	11#define  NTH	12#define  LEN	13#define  ISTUP	14#define  EQ	15#define  EQI	16 /* not used */#define  NEQ	17#define  NEQI	18 /* not used */#define  GT	19#define  GTI	20#define  GEQ	21#define  GEQI	22#define  LEQ	23#define  LEQI	24#define  LT	25#define  LTI	26#define  ADD	27#define  ADDI	28#define  SUB	29#define  SUBI	30#define  MULT	31#define  MULTI	32#define  DIV	33#define  DIVI	34#define  MOD	35#define  MODI	36#define  NEG	37#define  NOT	38#define  LNOT	39#define  AND	40#define  ANDI	41#define  OR	42#define  ORI	43#define  LSHL	44#define  LSHLI	45#define  RSHL	46#define  RSHLI	47#define  RSHA	48#define  RSHAI	49#define  XOR	50#define  XORI	51#define  SNET	52#define  SNETI	53#define  BCAST	54#define  BCASTI	55#define  ISX	56#define  GETRB	57#define  GETSRC	58#define  GETDST	60#define  GETSPT	61#define  HERE	62#define  ISHERE	63#define  ROUTE	64#define  RTDEV  65#define  SEND	66#define  HOP	67/*  #define  SENDCK	67 *//*  #define  HOPCK	68 */#define  FORW	69#define  FORWTO	70#define  DEMUX	71#define  DEMUXI	72#define  PRINT  73#define  PINT	74#define  PADDR	75#define  PTUP	76#define  PEXC	77#define  PSTR	78#define  PFLT   79#define  EQINT	80#define  EQADR	81#define  EQTUP	82#define  EQEXC	83#define  EQSTR	84#define  EQFLT  85#define  NQINT	86#define  NQADR	87#define  NQTUP	88#define  NQEXC	89#define  NQSTR	90#define  NQFLT  91#define  SVCV   92#define  CALLS  93#define  FGTI	94#define  FGEQI	95#define  FLEQI	96#define  FLTI	97#define  FADDI	98#define  FSUBI	99#define  FMULI	100#define  FDIVI	101#define  GETLD  102#define  SETXH  103#define  RAISEX 104/* willem's additions */#define  DSEND		105		/* direct send (no interpretation on intermediate hops) */#define  DFORW		106		/* idem for forw */#define  DFORWTO	107		/* idem for forwto */#define STACKEMPTY 108		/* pushes a 1 if the stack is empty, 0 otherwise */#define STACKCOUNT 109		/* pushes the number of elements on the stack */#define PULLSTACK 110		/* PULL using top stack element as index (this value is removed */#define OPCODE_T int/* operations on literals *//* assumes that TAGSZ is set appropriately above */#define GET_OP(v) ((v) >> (sizeof(unsigned int)*8-TAGSZ))#define SET_OP(v,i) ((v) = (((v) << TAGSZ) >> TAGSZ) | ((i) << (sizeof(unsigned int)*8-TAGSZ)))#define GET_LIT(l,t,i) ((l) = (((int)((i) << TAGSZ)) >> TAGSZ))#define SET_LIT(i,t,l) ((i) = (((i) >> (sizeof(unsigned int)*8-TAGSZ)) << (sizeof(unsigned int)*8-TAGSZ)) | ((((unsigned int)(l)) << TAGSZ) >> TAGSZ))#define GET_LIT_VAL(i) (((int)((i) << TAGSZ)) >> TAGSZ)#define GET_STR_VAL(h,v) (((heap_obj *)((h) + GET_OFFS(v)))->s)#define NUM_OPS 	87	/* total number of (legal) opcodes */typedef unsigned int instr_t;#elsetypedef enum {  /* stack and flow control */  EXIT,  PUSH,				/* push a value on the stack */  POP,				/* pop the top value off the stack */  POPI,				/* pop the top n values off the stack */  PULL,				/* push a copy of the nth stack value */  STORE,			/* store the top of the stack into the				   nth stack value (thus store 0 is				   a no-op) */  PAJ,				/* jump by the value on the top of the				   stack (pop and jump) plus the given				   immediate value */  TPAJ,				/* jump by the 2nd value on the top of				   the stack, plus the immediate				   value,if the top value is zero 				   (test, pop, and jump) */  JI,				/* jump by the immediate value */  BEZ,				/* branch x instrs if the top stack				   value is equal to zero */  BNE,				/* branch x instrs if the top stack				   value is not zero */  /* heap operations */  MKTUP,			/* allocates a tuple that holds n				   values, where n>0 is an immediate.				   Must be followed by n-1 (JI 1)				   instructions */  NTH,				/* get's the nTH entry of the tuple				   on the top of the stack, where				   n is an immediate > 0 */  LEN,				/* returns the length of the tuple,				   that is, how many values it				   contains. */  ISTUP,			/* is the top value a tuple? */				     /* relational operators */  EQ,				/* are the top two stack values equal? */  EQI,				/* is the top stack value equal to the				   immediate argument? */  NEQ,				/* are the top two stack values not equal? */  NEQI,				/* is the top stack value not equal to the				   immediate argument? */  GT,				/* comparing top 2 values: v2 > v1 */  GTI,				/* top > immediate */  GEQ,				/* comparing top 2 values: v2 >= v1 */  GEQI,				/* top >= immediate */  LEQ,				/* comparing top 2 values: v2 <= v1 */  LEQI,				/* top <= immediate */  LT,				/* comparing top 2 values: v2 < v1 */  LTI,				/* top < immediate */  /* arithmetic */  ADD,				/* integer addition */  ADDI,				/* integer addition with immediate */  SUB,				/* integer subtraction */  SUBI,				/* integer subtraction with immediate */  MULT,				/* integer multiplication */  MULTI,			/* integer multiplication with immediate*/  DIV,				/* integer division */  DIVI,				/* integer division with immediate */  MOD,				/* integer modulus */  MODI,				/* integer modulus with immediate */  NEG,				/* integer arithmetic negation */  NOT,				/* integer boolean negation */  LNOT,				/* integer logical negation */  AND,				/* integer logical and */  ANDI,				/* integer logical and with immediate */  OR,				/* integer logical or */  ORI,				/* integer logical or with immediate */  LSHL,				/* integer left shift logical */  LSHLI,			/* integer left shift logical with immediate */  RSHL,				/* integer right shift logical */  RSHLI,			/* integer right shift logical with				   immediate */  RSHA,				/* integer right shift arithmetic */  RSHAI,			/* integer right shift arithmetic with				   immediate */  XOR,				/* integer logical xor */  XORI,				/* integer logical xor with immediate */  /* operations on addresses */  SNET,				/* given an address and a subnet mask,				   give the subnet address */  SNETI,			/* subnet with immediate mask */  BCAST,			/* given an address and a subnet mask,				   give the broadcast address */  BCASTI,			/* broadcast address with immed. mask */  /* operations on exceptions */  ISX,				/* is the top value an exception? */  /* core services */  GETRB,			/* get the resource bound field */  GETSRC,			/* get the source field */  GETDST,			/* get the destination field */  GETSPT,			/* get the flow id */  HERE,				/* push an address of the current host */  ISHERE,			/* does the address on top of the				   stack belong to the current host? */  ROUTE,			/* determine the next hop to send to */  RTDEV,			/* next hop and outgoing interface */  SEND,				/* OnRemote w/ literal: args are:				   entry point, how many values of				   stack to take, how much resource				   bound, destination. side effects				   the header dest and source fields of				   outgoing packet */  HOP,				/* OnNeighbor w/ literal: args are:				     entry point,				     stack amount,				     resource bound,				     neighbor */  /* SENDCK, */			/* OnRemote: same as SEND, except				   (entrypoint,how much stack) args				   replaced with a chunk. */  /* HOPCK, */			/* OnNeighbor: same as HOP, except				   (entrypoint,how much stack) args				   replaced with a chunk. */  FORW,				/* if at destination, do nothing. else				   forward packet towards destination				   and exit */  FORWTO,			/* arg is final destination. if there,				   do nothing. else set header's src				   and dst appropriately and forward */  DEMUX,			/* application delivery: args are:				     UDP port, string */  DEMUXI,			/* same, but port num is immediate */  PRINT,			/* print value to console */  /* general services */  SVCV,				/* returns (non-function) value with				   given name from the service symtab */  CALLS,			/* invokes service routine with given				   string */  /* willem's additions */  ,  DSEND,			/* direct send (no interpretation on intermediate hops) */  DFORW,			/* idem for forw */  DFORWTO,			/* idem for forwto */    STACKEMPTY,		/* pushes a 1 if the stack is empty, 0 otherwise */  STACKCOUNT,		/* pushes the number of elements on the stack */    PULLSTACK			/* PULL using top stack element as index (this value is removed */} opcode_t;#define OPCODE_T opcode_t/* operations on literals */#define GET_LIT(l,t,i)							\  DYNCHECK_TAG((i).arg,t);						\  (l) = GET_INT((i).arg); /* assumes this is the same as GET_OFFS */#define SET_LIT(i,t,l) 				\  SET_INT((i).arg,(l)); /* all ints anyway */	\  SET_TAG((i).arg,(t));#define GET_OP(i) ((i).op)#define SET_OP(i,t) ((i).op = (t))#define NUM_OPS 	73	/* total number of opcodes *//* instructions are an opcode with an (optional) argument */typedef struct {  OPCODE_T op;  value_t arg;} instr_t;#endif#define COPY_LIT(d,t,s)			\{ int _lit;				\  GET_LIT(_lit,t,(s));			\  SET_INT((d),_lit);			\  SET_TAG((d),t);			\}#endif /* _SNAP_BYTECODE_H_ */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -