/* scan the current array for a specific index and return value_t XXX should use some hashing tables here for speed and scalability */ array_t* eppic_getarrval(array_t**app, value_t *idx) { array_t*ap, *apr; /* eppic_setarray(app); AAA comment out */ apr=*app; for(ap=apr->next; ap != apr; ap=ap->next) { if(ap->idx->type.type == idx->type.type) { int b=0; switch(idx->type.type) { case V_STRING: b=(!strcmp(ap->idx->v.data, idx->v.data)); break; case V_BASE: b=(unival(ap->idx)==unival(idx)); break; case V_REF: if(eppic_defbsize()==4) b=(ap->idx->v.ul==idx->v.ul); else b=(ap->idx->v.ull==idx->v.ull); break; default: eppic_error("Invalid index type %d", idx->type.type); } if(b) { return ap; } } } /* we have not found this index, create one */ ap=(array_t*)eppic_calloc(sizeof(array_t)); ap->idx=eppic_makebtype(0); eppic_dupval(ap->idx, idx); /* just give it a int value_t of 0 for now */ ap->val=eppic_makebtype(0); /* we must set the same refenrence number as the upper level array_t*/ ap->val->arr->ref=apr->ref; /* link it in */ ap->prev=apr->prev; ap->next=apr; apr->prev->next=ap; apr->prev=ap; ap->ref=0; return ap; }
value_t * eppic_intindex(value_t *a, int idx) { value_t *v=eppic_makebtype(idx); array_t*ap=eppic_getarrval(&a->arr, v); eppic_dupval(v, ap->val); return v; }
/* eppic_prarr builtin */ value_t* eppic_prarr(value_t*vname, value_t*root) { char *name=eppic_getptr(vname, char); printf("%s=", name); prtval(root); printf("\n"); prlevel(name, root, 1); return eppic_makebtype(0); }
/* Extensions to built-in functions */ VALUE_S * eppic_memset(VALUE_S *vaddr, VALUE_S *vch, VALUE_S *vlen) { ull addr = eppic_getval(vaddr); int len = eppic_getval(vlen); int ch = eppic_getval(vch); /* * Set the value at address from iaddr till iaddr + nbytes * to the value specified in variable ch */ UPDATE_FILTER_INFO_RAW(addr, ch, len); return eppic_makebtype(1); }
var_t* eppic_newvar(char *name) { var_t*v=eppic_calloc(sizeof(var_t)); char *myname=eppic_alloc(strlen(name)+1); TAG(myname); strcpy(myname,name); v->name=myname; v->v=eppic_makebtype(0); v->v->setval=v->v; v->next=v->prev=v; return v; }
value_t* eppic_showaddr(value_t *vadr) { void *addr=eppic_getptr(vadr, void); blist *bl; int n=0; for(bl=temp.next; bl != &temp; bl=bl->next) { if(bl->caller==addr) { if(!(n%8)) eppic_msg("\n"); eppic_msg("0x%08x ", ((char *)bl) + SIZEBL); n++; } } return eppic_makebtype(0); }
static value_t * eppic_exeop(oper *o) { value_t *v=0, *v1=0, *v2=0, *v3=0, *v4=0; int top; srcpos_t p; eppic_curpos(&o->pos, &p); /* if ME (op on myself) operator, translate to normal operator we will re-assign onto self when done */ top=getop(o->op); if(top == ASSIGN) { goto doop; } else if(top == IN) { /* the val in array[] test is valid for anything but struct/union */ v=eppic_makebtype((ull)eppic_lookuparray(P1,P2)); } else if(is_cond(top)) { /* the operands are eithr BASE (integer) or REF (pointer) */ /* all conditional operators accept a mixture of pointers and integer */ /* set the return as a basetype even if bool */ switch(top) { case CEXPR: { /* conditional expression expr ? : stmt : stmt */ if(eppic_bool(V1)) { v=eppic_cloneval(V2); } else { v=eppic_cloneval(V3); } } break; case BOR: { /* a || b */ v=eppic_makebtype((ull)(eppic_bool(V1) || eppic_bool(V2))); } break; case BAND: { /* a && b */ v=eppic_makebtype((ull)(eppic_bool(V1) && eppic_bool(V2))); } break; case NOT: { /* ! expr */ v=eppic_makebtype((ull)(! eppic_bool(V1))); } break; default: { v=eppic_docomp(top, V1, V2); } } } else if(anyop(V_STRING)) { if(top == ADD) { char *buf; if(V1->type.type != V_STRING || V2->type.type != V_STRING) { eppic_rerror(&P1->pos, "String concatenation needs two strings!"); } buf=eppic_alloc(strlen(S1)+strlen(S2)+1); strcpy(buf, S1); strcat(buf, S2); v=eppic_makestr(buf); eppic_free(buf); } else { eppic_rerror(&P1->pos, "Invalid string operator"); } } /* arithmetic operator */ else if(anyop(V_REF)) { int size; value_t *vt; /* make sure we have the base type second */ if(V1->type.type != V_REF) { vt=V1; v1=V2; v2=vt; } if(V1->type.type == V_BASE) { inval: eppic_error("Invalid operand on pointer operation"); } /* get the size of whas we reference */ size=V1->type.size; switch(top) { case ADD: { /* expr + expr */ /* adding two pointers ? */ if(V2->type.type == V_REF) goto inval; V1; eppic_transfer(v=eppic_newval(), v1, unival(v1) + L2 * size); } break; case SUB: { /* expr - expr */ /* different results if mixed types. if both are pointers then result is a V_BASE */ if(V2->type.type == V_REF) v=eppic_makebtype(L1 - L2); else { V1; eppic_transfer(v=eppic_newval(), v1, unival(v1) - L2 * size); } } break; case PREDECR: { /* pre is easy */ V1; eppic_transfer(v=eppic_newval(), v1, unival(v1) - size); eppic_setval(v1, v); } break; case PREINCR: { V1; eppic_transfer(v=eppic_newval(), v1, unival(v1) + size); eppic_setval(v1, v); } break; case POSTINCR: { V1; eppic_transfer(v=eppic_newval(), v1, unival(v1) + size); eppic_setval(v1, v); eppic_transfer(v, v1, unival(v1)); } break; case POSTDECR: { V1; eppic_transfer(v=eppic_newval(), v1, unival(v1) - size); eppic_setval(v1, v); eppic_transfer(v, v1, unival(v1)); } break; default: eppic_error("Invalid operation on pointer [%d]",top); } } else { /* both operands are V_BASE */ switch(top) { /* for mod and div, we check for divide by zero */ case MOD: case DIV: if(!L2) { eppic_rerror(&P1->pos, "Mod by zero"); } case ADD: case SUB: case MUL: case XOR: case OR: case AND: case SHL: case SHR: { eppic_baseop(top, V1, V2, v=eppic_newval()); } break; case UMINUS: { value_t *v0=eppic_newval(); eppic_defbtype(v0, (ull)0); /* keep original type of v1 */ v=eppic_newval(); eppic_duptype(&v0->type, &V1->type); eppic_duptype(&v->type, &V1->type); eppic_baseop(SUB, v0, V1, v); eppic_freeval(v0); /* must make result signed */ eppic_mkvsigned(v); } break; case FLIP: { value_t *v0=eppic_newval(); eppic_defbtype(v0, (ull)0xffffffffffffffffll); /* keep original type of v1 */ eppic_duptype(&v0->type, &V1->type); eppic_baseop(XOR, v0, V1, v=eppic_newval()); eppic_freeval(v0); } break; case PREDECR: { /* pre is easy */ V1; eppic_transfer(v=eppic_newval(), v1, unival(v1) - 1); eppic_setval(v1, v); } break; case PREINCR: { V1; eppic_transfer(v=eppic_newval(), v1, unival(v1) + 1); eppic_setval(v1, v); } break; case POSTINCR: { V1; eppic_transfer(v=eppic_newval(), v1, unival(v1) + 1); eppic_setval(v1, v); eppic_transfer(v, v1, unival(v1)); } break; case POSTDECR: { V1; eppic_transfer(v=eppic_newval(), v1, unival(v1) - 1); eppic_setval(v1, v); eppic_transfer(v, v1, unival(v1)); } break; default: eppic_rerror(&P1->pos, "Oops ops ! [%d]", top); } } doop: /* need to assign the value_t back to P1 */ if(top != o->op || top==ASSIGN) { /* in the case the Lvalue_t is a variable , bypass execution and set ini */ if(P1->exe == eppic_exevar) { char *name=NODE_NAME(P1); var_t*va=eppic_getvarbyname(name, 0, 0); value_t *vp; eppic_free(name); if(top != o->op) vp=v; else vp=V2; eppic_chkandconvert(va->v, vp); eppic_freeval(v); v=eppic_cloneval(va->v); va->ini=1; } else { if(!(V1->set)) { eppic_rerror(&P1->pos, "Not Lvalue_t on assignment"); } else { /* if it's a Me-op then v is already set */ V1; if(top != o->op) { eppic_setval(v1, v); } else { eppic_setval(v1, V2); v=eppic_cloneval(V2); } } } /* the result of a assignment if not an Lvalue_t */ v->set=0; } eppic_freeval(v1); eppic_freeval(v2); eppic_freeval(v3); eppic_freeval(v4); eppic_setpos(&p); return v; }
static value_t* eppic_docomp(int op, value_t *v1, value_t *v2) { /* if one parameter is string then both must be */ if(v1->type.type == V_STRING || v2->type.type == V_STRING) { if(v1->type.type != V_STRING || v2->type.type != V_STRING) { eppic_error("Invalid condition arguments"); } else { switch(op) { case EQ: { /* expr == expr */ return eppic_makebtype(!strcmp(v1->v.data, v2->v.data)); } case GT: case GE: { /* expr > expr */ return eppic_makebtype(strcmp(v1->v.data, v2->v.data) > 0); } case LE: case LT: { /* expr <= expr */ return eppic_makebtype(strcmp(v1->v.data, v2->v.data) < 0); } case NE: { /* expr != expr */ return eppic_makebtype(strcmp(v1->v.data, v2->v.data)); } default: { eppic_error("Oops conditional unknown 1"); } } } } else { int idx1, idx2; value_t *v=eppic_newval(); /* make sure pointers are forced to proper basetype before calling eppic_baseop()*/ idx1=eppic_reftobase(v1); idx2=eppic_reftobase(v2); switch(op) { case EQ: case GT: case GE: case LE: case LT: case NE: eppic_baseop(op, v1, v2, v); break; default: { eppic_error("Oops conditional unknown 2"); } } v1->type.idx=idx1; v2->type.idx=idx2; return v; } return 0; }
value_t* eppic_memdebugoff() { memdebug=0; return eppic_makebtype(0); }
/* these two functions must *not* receive any values */ value_t* eppic_memdebugon() { memdebug=1; return eppic_makebtype(0); }