📄 snap_interp.c
字号:
} else { d_printf(10,"%s:%d: pc=%d: TPAJ %d: top=%d, falling thru\n", __FILE__,__LINE__,(p->pc - p->code_min), GET_LIT_VAL(*p->pc), GET_INT(*top1)); } p->sp = p->sp - 2; /* pop */ p->pc = p->pc + jump; break; } case BEZ: { value_t *top = p->sp - 1; int jump = 1; DYNCHECK(top >= p->stack_min); DYNCHECK_TAG(*top,INTV); if (GET_INT(*top) == 0) { GET_LIT(jump,INTV,*p->pc); DYNCHECK(jump > 0); d_printf(10,"%s:%d: pc=%d: BEZ %d: branching ahead\n", __FILE__,__LINE__,(p->pc - p->code_min),jump); } else { d_printf(100,"%s:%d: pc=%d: BEZ %d: falling thru\n", __FILE__,__LINE__,(p->pc - p->code_min),jump); } p->sp--; /* pop */ p->pc = p->pc + jump; break; } case BNE: { value_t *top = p->sp - 1; int jump = 1; DYNCHECK(top >= p->stack_min); DYNCHECK_TAG(*top,INTV); if (GET_INT(*top) != 0) { GET_LIT(jump,INTV,*p->pc); DYNCHECK(jump > 0); d_printf(10,"%s:%d: pc=%d: BNE %d: branching ahead\n", __FILE__,__LINE__,(p->pc - p->code_min),jump); } else { d_printf(10,"%s:%d: pc=%d: BNE %d: falling thru\n", __FILE__,__LINE__,(p->pc - p->code_min),jump); } p->sp--; /* pop */ p->pc = p->pc + jump; break; } case MKTUP: { int n, i, hoffset; value_t *newtop, *heapv, *cp; heap_obj *ho; ENSURE_HEAP_ROOM(p,iph); GET_LIT(n,INTV,*p->pc); DYNCHECK(n > 0); /* check for (n-2) trailing non-mktups */ DYNCHECK((p->pc + ((n-2) > 0 ? (n-2) : 0) < p->code_max));#ifndef NDYNCHECK for(i=1; i<n-1; i++) { /* check for non-mktup */ DYNCHECK(GET_OP(p->pc[i]) != MKTUP); }#endif /* check that the initial arguments are on the stack */ newtop = (p->sp - n); /* where to store the tuple result */ DYNCHECK(newtop >= p->stack_min); /* perform the allocation */ if (!heap_alloc(p,n*sizeof(value_t),1,&ho,&hoffset)) { /* initialize the tuple entries */ for (heapv = (value_t *)(&ho->s[0]), cp = p->sp - n, i=0; i<n; i++, heapv++, cp++) {#ifdef CONFIG_IP_SNAP_DEBUG d_printf(50,"%s:%d: MKTUP copying ",__FILE__,__LINE__); if (sysctl_snap_debug_level == -1 || 50 <= sysctl_snap_debug_level) { printk_value(p,cp); printk(" ( *0x%08x = 0x%08x)\n",(__u32)cp,(unsigned int)(*cp)); }#endif *heapv = *cp; } /* store pointer on the stack */ SET_TAG(*newtop,TUPLEV); SET_OFFS(*newtop,hoffset); d_printf(10,"%s:%d: pc=%d: MKTUP %d: new offs[%d] = \n", __FILE__,__LINE__,(p->pc - p->code_min),n, GET_OFFS(*newtop)); p->sp = newtop + 1;#ifdef CONFIG_IP_SNAP_DEBUG if (sysctl_snap_debug_level == -1 || 10 <= sysctl_snap_debug_level) { printk_value(p,p->sp - 1); printk("\n"); }#endif } else /* allocation failed, quit */ return -1; p->pc++; break; } case NTH: { value_t *top1 = p->sp - 1; int n,offs; heap_obj *ho; DYNCHECK(top1 >= p->stack_min); DYNCHECK_TAG(*top1,TUPLEV); GET_LIT(n,INTV,*p->pc); DYNCHECK(n > 0); offs = GET_OFFS(*top1); ho = (heap_obj *)(p->heap_min + offs); DYNCHECK_IN_HEAP(ho); DYNCHECK((ho->len / 4) >= n); wassert((ho->len / 4) * 4 == ho->len); *top1 = ((value_t *)&(ho->s[0]))[n-1];#ifdef CONFIG_IP_SNAP_DEBUG d_printf(10,"%s:%d: pc=%d: NTH %d: offs[%d].%d = ", __FILE__,__LINE__,(p->pc - p->code_min),n,offs,n); if (sysctl_snap_debug_level == -1 || 10 <= sysctl_snap_debug_level) { printk_value(p,top1); printk("\n"); }#endif /* CONFIG_IP_SNAP_DEBUG */ p->pc++; break; } case ISTUP: { /* unlike other ops, does not blow away top stack value */ value_t *top = p->sp - 1; int result; DYNCHECK(top >= p->stack_min); result = (GET_TAG(*top) == TUPLEV); DYNCHECK(p->sp < p->stack_max); SET_TAG(*p->sp,INTV); SET_INT(*p->sp,result); d_printf(10,"%s:%d: pc=%d: ISTUP: %s\n",__FILE__,__LINE__, (p->pc - p->code_min),(GET_INT(*p->sp)?"yes":"no")); p->sp++; p->pc++; break; } case LEN: { value_t *top = p->sp - 1; heap_obj *tup; int offs; DYNCHECK(top >= p->stack_min); DYNCHECK_TAG(*top,TUPLEV); offs = GET_OFFS(*top); tup = (heap_obj *)(p->heap_min + offs); DYNCHECK_IN_HEAP(tup); SET_TAG(*top,INTV); SET_INT(*top,tup->len / sizeof(value_t)); d_printf(10,"%s:%d: pc=%d: LEN: |offs[%d]|=%d\n",__FILE__,__LINE__, (p->pc - p->code_min),offs,GET_INT(*top)); p->pc++; break; } /* equality/inequality are polymorphic */ case EQ: EQOP(1,"EQ"); case NEQ: EQOP(0,"NEQ");#ifndef SMALL_INSTRS case EQI: EQOPI(1,"EQI"); case NEQI: EQOPI(0,"NEQI"); /* these could be on floats or on ints */ case GTI: INTFLOATIMMOPI(>,"GTI"); case GEQI: INTFLOATIMMOPI(>=,"GEQI"); case LEQI: INTFLOATIMMOPI(<=,"LEQI"); case LTI: INTFLOATIMMOPI(<,"LTI"); case ADDI: INTFLOATIMMOP(+,"ADDI"); case SUBI: INTFLOATIMMOP(-,"SUBI"); case MULTI: INTFLOATIMMOP(*,"MULTI"); case DIVI: INTFLOATIMMOP(/,"DIVI");#else#ifdef CONFIG_IP_SNAP_DEBUG#define EQOPI_D_PRINTF(opname,fmt1,fmt2,arg...) \ { d_printf(10,"%s:%d: pc=%d: %s " fmt1 ": eq? " fmt2 " (%s)\n", \ __FILE__,__LINE__,(p->pc - p->code_min),opname, \ ##arg,(result?"yes":"no")); \ break; \ }#define EQOPI(res,t,opname) \{ \ value_t v = ZERO_VALUE_T; \ int result; \ value_t *top = p->sp - 1; \ \ ENSURE_STACK_ROOM(p,iph); \ top = p->sp - 1; \ DYNCHECK(p->sp < p->stack_max); \ COPY_LIT(v,t,*p->pc); \ result = (res == eq_value(top,&v,p)); \ if (result == -1) \ return -1; \ switch(t) { \ case INTV: \ switch(GET_TAG(*top)) { \ case INTV: EQOPI_D_PRINTF(opname,"%d","%d",GET_INT(v),GET_INT(*top)); \ case ADDRV: EQOPI_D_PRINTF(opname,"%d","%d.%d.%d.%d",GET_INT(v), \ NIPQUAD(GET_ADDR_VAL(p->heap_min,*top))); \ case STRV: EQOPI_D_PRINTF(opname,"%d","\"%s\"",GET_INT(v), \ GET_STR_VAL(p->heap_min,*top)); \ case EXCV: EQOPI_D_PRINTF(opname,"%d","exc(%d)", \ GET_INT(v),GET_LIT_VAL(*top)); \ case TUPLEV: EQOPI_D_PRINTF(opname,"%d","offs[%d]", \ GET_INT(v),GET_OFFS(*top)); \ case FLOATV: EQOPI_D_PRINTF(opname,"%d","%d.%06d",GET_INT(v), \ FLTINTPAIR(GET_FLT_VAL(p->heap_min,*top))); \ } \ break; \ case ADDRV: \ switch(GET_TAG(*top)) { \ case INTV: EQOPI_D_PRINTF(opname,"%d.%d.%d.%d","%d",\ NIPQUAD(GET_ADDR_VAL(p->heap_min,v)),GET_INT(*top)); \ case ADDRV: EQOPI_D_PRINTF(opname,"%d.%d.%d.%d","%d.%d.%d.%d", \ NIPQUAD(GET_ADDR_VAL(p->heap_min,v)), \ NIPQUAD(GET_ADDR_VAL(p->heap_min,*top))); \ case STRV: EQOPI_D_PRINTF(opname,"%d.%d.%d.%d","\"%s\"", \ NIPQUAD(GET_ADDR_VAL(p->heap_min,v)), \ GET_STR_VAL(p->heap_min,*top)); \ case EXCV: EQOPI_D_PRINTF(opname,"%d.%d.%d.%d","exc(%d)", \ NIPQUAD(GET_ADDR_VAL(p->heap_min,v)), \ GET_LIT_VAL(*top)); \ case TUPLEV: EQOPI_D_PRINTF(opname,"%d.%d.%d.%d","offs[%d]", \ NIPQUAD(GET_ADDR_VAL(p->heap_min,v)), \ GET_OFFS(*top)); \ case FLOATV: EQOPI_D_PRINTF(opname,"%d.%d.%d.%d","%d.%06d", \ NIPQUAD(GET_ADDR_VAL(p->heap_min,v)), \ FLTINTPAIR(GET_FLT_VAL(p->heap_min,*top))); \ } \ break; \ case STRV: \ switch(GET_TAG(*top)) { \ case INTV: EQOPI_D_PRINTF(opname,"\"%s\"","%d", \ GET_STR_VAL(p->heap_min,v),GET_INT(*top)); \ case ADDRV: EQOPI_D_PRINTF(opname,"\"%s\"","%d.%d.%d.%d", \ GET_STR_VAL(p->heap_min,v), \ NIPQUAD(GET_ADDR_VAL(p->heap_min,*top))); \ case STRV: EQOPI_D_PRINTF(opname,"\"%s\"","\"%s\"", \ GET_STR_VAL(p->heap_min,v), \ GET_STR_VAL(p->heap_min,*top)); \ case EXCV: EQOPI_D_PRINTF(opname,"\"%s\"","exc(%d)", \ GET_STR_VAL(p->heap_min,v), \ GET_LIT_VAL(*top)); \ case TUPLEV: EQOPI_D_PRINTF(opname,"\"%s\"","offs[%d]", \ GET_STR_VAL(p->heap_min,v), \ GET_OFFS(*top)); \ case FLOATV: EQOPI_D_PRINTF(opname,"\"%s\"","%d.%06d", \ GET_STR_VAL(p->heap_min,v), \ FLTINTPAIR(GET_FLT_VAL(p->heap_min,*top))); \ } \ break; \ case EXCV: \ switch(GET_TAG(*top)) { \ case INTV: EQOPI_D_PRINTF(opname,"exc(%d)","%d", \ GET_INT(v),GET_INT(*top)); \ case ADDRV: EQOPI_D_PRINTF(opname,"exc(%d)","%d.%d.%d.%d",GET_INT(v), \ NIPQUAD(GET_ADDR_VAL(p->heap_min,*top))); \ case STRV: EQOPI_D_PRINTF(opname,"exc(%d)","\"%s\"",GET_INT(v), \ GET_STR_VAL(p->heap_min,*top)); \ case EXCV: EQOPI_D_PRINTF(opname,"exc(%d)","exc(%d)", \ GET_INT(v),GET_LIT_VAL(*top)); \ case TUPLEV: EQOPI_D_PRINTF(opname,"exc(%d)","offs[%d]", \ GET_INT(v),GET_OFFS(*top)); \ case FLOATV: EQOPI_D_PRINTF(opname,"exc(%d)","%d.%06d",GET_INT(v), \ FLTINTPAIR(GET_FLT_VAL(p->heap_min,*top))); \ } \ break; \ case TUPLEV: \ switch(GET_TAG(*top)) { \ case INTV: EQOPI_D_PRINTF(opname,"offs[%d])","%d", \ GET_OFFS(v),GET_INT(*top)); \ case ADDRV: EQOPI_D_PRINTF(opname,"offs[%d]","%d.%d.%d.%d",GET_OFFS(v), \ NIPQUAD(GET_ADDR_VAL(p->heap_min,*top))); \ case STRV: EQOPI_D_PRINTF(opname,"offs[%d]","\"%s\"",GET_OFFS(v), \ GET_STR_VAL(p->heap_min,*top)); \ case EXCV: EQOPI_D_PRINTF(opname,"offs[%d]","exc(%d)", \ GET_OFFS(v),GET_LIT_VAL(*top)); \ case TUPLEV: EQOPI_D_PRINTF(opname,"offs[%d]","offs[%d]", \ GET_OFFS(v),GET_OFFS(*top)); \ case FLOATV: EQOPI_D_PRINTF(opname,"offs[%d]","%d.%06d",GET_OFFS(v), \ FLTINTPAIR(GET_FLT_VAL(p->heap_min,*top))); \ } \ break; \ case FLOATV: \ switch(GET_TAG(*top)) { \ case INTV: EQOPI_D_PRINTF(opname,"%d.%06d","%d", \ FLTINTPAIR(GET_FLT_VAL(p->heap_min,v)), \ GET_INT(*top)); \ case ADDRV: EQOPI_D_PRINTF(opname,"%d.%06d","%d.%d.%d.%d", \ FLTINTPAIR(GET_FLT_VAL(p->heap_min,v)), \ NIPQUAD(GET_ADDR_VAL(p->heap_min,*top))); \ case STRV: EQOPI_D_PRINTF(opname,"%d.%06d","\"%s\"", \ FLTINTPAIR(GET_FLT_VAL(p->heap_min,v)), \ GET_STR_VAL(p->heap_min,*top)); \ case EXCV: EQOPI_D_PRINTF(opname,"%d.%06d","exc(%d)", \ FLTINTPAIR(GET_FLT_VAL(p->heap_min,v)), \ GET_LIT_VAL(*top)); \ case TUPLEV: EQOPI_D_PRINTF(opname,"%d.%06d","offs[%d]", \ FLTINTPAIR(GET_FLT_VAL(p->heap_min,v)), \ GET_OFFS(*top)); \ case FLOATV: EQOPI_D_PRINTF(opname,"%d.%06d","%d.%06d", \ FLTINTPAIR(GET_FLT_VAL(p->heap_min,v)), \ FLTINTPAIR(GET_FLT_VAL(p->heap_min,*top))); \ } \ break; \ } \ SET_TAG(*top,INTV); \ SET_INT(*top,result); \ p->pc++; \ break; \}#else#define EQOPI(res,t,opname) \{ \ value_t v = ZERO_VALUE_T; \ int result; \ value_t *top = p->sp - 1; \ \ d_printf(100,"%s:%d: interp: %s\n",__FILE__,__LINE__, \ opname); \ ENSURE_STACK_ROOM(p,iph); \ top = p->sp - 1; \ DYNCHECK(p->sp < p->stack_max); \ COPY_LIT(v,t,*p->pc); \ result = (res == eq_value(top,&v,p)); \ if (result == -1) \ return -1; \ SET_TAG(*top,INTV); \ SET_INT(*top,result); \ p->pc++; \ break; \}#define EQOPI_D_PRINTF(fmt,arg...) /**/#endif case EQINT: EQOPI(1,INTV,"EQINT"); case EQADR: EQOPI(1,ADDRV,"EQADR"); case EQTUP: EQOPI(1,TUPLEV,"EQTUP"); case EQEXC: EQOPI(1,EXCV,"EQEXC"); case EQSTR: EQOPI(1,STRV,"EQSTR"); case EQFLT: EQOPI(1,FLOATV,"EQFLT"); case NQINT: EQOPI(0,INTV,"NQINT"); case NQADR: EQOPI(0,ADDRV,"NQADR"); case NQTUP: EQOPI(0,TUPLEV,"NQTUP"); case NQEXC: EQOPI(0,EXCV,"NQEXC"); case NQSTR: EQOPI(0,STRV,"NQSTR"); case NQFLT: EQOPI(0,FLOATV,"EQFLT"); /* floating point ops */ case FGTI: FLOATIMMOPI(>,"GTI"); case FGEQI: FLOATIMMOPI(>=,"GEQI"); case FLEQI: FLOATIMMOPI(<=,"LEQI"); case FLTI: FLOATIMMOPI(<,"LTI"); case FADDI: FLOATIMMOP(+,"ADDI"); case FSUBI: FLOATIMMOP(-,"SUBI"); case FMULI: FLOATIMMOP(*,"MULTI"); case FDIVI: FLOATIMMOP(/,"DIVI"); /* integer ops */ case GTI: INTIMMOP(int,>,"GTI"); case GEQI: INTIMMOP(int,>=,"GEQI"); case LEQI: INTIMMOP(int,<=,"LEQI"); case LTI: INTIMMOP(int,<,"LTI"); case ADDI: INTIMMOP(int,+,"ADDI"); case SUBI: INTIMMOP(int,-,"SUBI"); case MULTI: INTIMMOP(int,*,"MULTI"); case DIVI: INTIMMOP(int,/,"DIVI");#undef EQOPI_D_PRINTF#endif /* integer and/or floating point relational and arithmetic operators */ case GT: INTFLOATOPI(>,"GT"); case GEQ: INTFLOATOPI(>=,"GEQ"); case LEQ: INTFLOATOPI(<=,"LEQ"); case LT: INTFLOATOPI(<,"LT"); case ADD: INTFLOATOP(+,"ADD"); case SUB: INTFLOATOP(-,"SUB"); case MULT: INTFLOATOP(*,"MULT"); case DIV: INTFLOATOP(/,"DIV"); case NEG: { value_t *top = p->sp - 1; DYNCHECK(top >= p->stack_min); if (GET_TAG(*top) == INTV) { int result; result = -(GET_INT(*top)); d_printf(10,"%s:%d: pc=%d: NEG: %d -> %d\n",__FILE__,__LINE__, (p->pc - p->code_min),GET_INT(*top),result); SET_TAG(*top,INTV); SET_INT(*top,result); } else { float32 v, result; ENSURE_HEAP_ROOM(p,iph); top = p->sp - 1; DYNCHECK_TAG(*top,FLOATV); GET_FLOAT(v,p->heap_min,*top); result = -v; d_printf(10,"%s:%d: pc=%d: NEG: %d.%06d -> %d.%06d\n", __FILE__,__LINE__,(p->pc - p->code_min), FLTINTPAIR(GET_FLT_VAL(p->heap_min,*top)), FLTINTPAIR(result)); SET_TAG(*top,FLOATV); SET_FLOAT(*top,result,p); } p->pc++; break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -