diff --git a/src/debug.c b/src/debug.c new file mode 100644 index 0000000..7419b03 --- /dev/null +++ b/src/debug.c @@ -0,0 +1,270 @@ + +#include "config.h" +#include "types.h" +#include "error.h" +#include "ops.h" +#include "mem.h" +#include "stack.h" +#include "reg.h" +#include "context.h" +#include "var.h" +#include "utils.h" +#include "vm.h" +#include "types.h" +#include "tokens.h" +#include "lexer.h" +#include "event.h" +#include "debug.h" +#include "printf.h" + +int CountCode(mem_t *M) { + int pc=0,opn=0; + while (pcbottom) { + int _pc=pc; + op_t *op = OPT(M,pc); + opn++; + INCR(pc,ops_s[op->command]+1); + switch (op->command) { + case DATA: INCR(pc,op->ix); break; + case STRING: INCR(pc,op->ix+1); break; + } + } + return opn; +} + +#if DEBUG > 0 +int PrintCode(mem_t *M) { + int pc=0,opn=0; + vLog("======= Code [%d] ========\n",M->bottom); + while (pcbottom) { + int _pc=pc; + op_t *op = OPT(M,pc); + vLog("[%d] ",pc); + opn++; + INCR(pc,ops_s[op->command]+1); + switch (op->command) { + case DATA: INCR(pc,op->ix); break; + case STRING: INCR(pc,op->ix+1); break; + } + PrintOp(op,_pc); + } + return opn; +} + +void PrintEvents(events_t *E) { + int i; + vLog("======= Events [%d] %x ========\n",E->top,E->mask); + for(i=0;itop;i++) { + event_t *ev=&E->table[i]; + char name[10]; + strncpy(name,ev->name,4); + name[4]=0; + vLog("(%d) Event %s[%d] pending=%d listeners=%d\n",i,name,ev->index,ev->pending,ev->listeners); + } +} + +void PrintHeap(mem_t *M) { + index_t top=M->top; + address_t addr; + var_t *v=NULL; + // print in reverse order bottom-up + vLog("======= Heap [%d] ========\n",M->top); + // search, find of heap TODO hash/cache + while (top<(M->size-1)) { + v=(var_t*)(&M->data[top]); + if (v->type==MEVENT) + addr=(address_t)(&v->name[0]-(char*)M->data); + else + addr=(address_t)((char *)&v->data-(char*)M->data); + vLog("%d: %s [%d] %c $=%d ",top,v->name,v->length,v->type,v->type==MFUNC||v->type==MPROC?v->data:addr); + if (v->type==MVAR || v->type==MCONST || v->type==MSTRING) { + for(index_t i=0;ilength;i++) { + if (v->type==MSTRING) { + if (i==0) vLog("("); + if (CHAR(M,addr)) vLog("%c",CHAR(M,addr)); + addr++; + } else { + vLog("%c%d",i==0?'(':',',NUMBER(M,addr)); + addr+=number_s; + } + } + vLog(")"); + } +#if HAS_FUNC > 0 + if (v->type==MVARLOC || v->type==MEVENT) { + vLog("<%d> ",(index_t)v->data); + } +#endif + vLog("\n"); + switch (v->type) { + case MEVENT: + case MVAR: + case MCONST: +#if HAS_FUNC > 0 + case MVARLOC: +#endif + top+=(var_s+(v->length-1)*number_s); + break; + case MSTRING: + // TODO + top+=(var_s+(v->length-1)); + break; + case MFUNC: + top += number_s; + case MPROC: + top += var_s; + break; + } + top=top+(top%MEMALIGN); + } +} + +void PrintOp(op_t *op,address_t addr) { + switch (op->command) { + case ADD: vLog("ADD\n"); break; + case AND: vLog("AND\n"); break; + case CMPS: vLog("CMPS\n"); break; + case DIV: vLog("DIV\n"); break; + case EQ: vLog("EQ\n"); break; + case GE: vLog("GE\n"); break; + case GT: vLog("GT\n"); break; + case LE: vLog("LE\n"); break; + case LT: vLog("LT\n"); break; + case MOD: vLog("MOD\n"); break; + case NEG: vLog("NEG\n"); break; + case NEQ: vLog("NEQ\n"); break; + case NOT: vLog("NOT\n"); break; + case MUL: vLog("MUL\n"); break; + case OR: vLog("OR\n"); break; + case SUB: vLog("SUB\n"); break; + + case INARRAY: vLog("INARRAY\n"); break; + case INCHAR: vLog("INCHAR\n"); break; + case INNUMBER: vLog("INNUMBER\n"); break; + case INSTRING: vLog("INSTRING\n"); break; + case OUTCHAR: vLog("OUTCHAR\n"); break; + case OUTNUMBER: vLog("OUTNUMBER\n"); break; + case OUTSTRING: vLog("OUTSTRING\n"); break; + + + case DROPD: vLog("DROPD(%d)\n",(int)op->ix); break; + case DROPF: vLog("DROPF(%d)\n",(int)op->ix); break; + case NTHD: vLog("NTHD(%d)\n",(int)op->ix); break; + case NTHF: vLog("NTHF(%d)\n",(int)op->ix); break; + case PUSHD: vLog("PUSHD(%d)\n",(int)op->nx); break; + case PUSHF: vLog("PUSHF(%d)\n",(int)op->nx); break; + case TOF: vLog("TOF(%d)\n",op->ix); break; + case SETF: vLog("SETF(%d)\n",(int)op->ix); break; +#if HAS_FUNC > 0 + case INCSP: vLog("INCSP(%d)\n",(int)op->ix); break; + case SETSP: vLog("SETSP(%d)\n",(int)op->ix); break; +#endif + + case CALL: vLog("CALL(%d)\n",(int)op->ax); break; + case CCALL: vLog("CCALL(%d)\n",(int)op->ix); break; + case ERR: vLog("ERROR(%d)\n",(int)op->ax); break; + case EMIT: vLog("EMIT(%d)\n",(int)op->ix); break; + case EVENT: vLog("EVENT(%d)\n",(int)op->ax); break; + case FORK: vLog("FORK\n"); break; + case INTERRUPT: vLog("INTERRUPT(%d)\n",(int)op->ix); break; + case JMP: vLog("JMP(%d)\n",(int)op->ax); break; + case JZ: vLog("JZ(%d)\n",(int)op->ax); break; + case JNZ: vLog("JNZ(%d)\n",(int)op->ax); break; + case LOOP: vLog("LOOP\n"); break; + case PROC: vLog("PROC(%d)\n",(int)op->ix); break; + case RESUME: vLog("RESUME(%d)\n",(int)op->ix); break; + case RETURN: vLog("RETURN(%d)\n",op->ix); break; + case YIELD: vLog("YIELD\n"); break; + case LOCK: vLog("LOCK($%d)\n",op->ax); break; + case UNLOCK: vLog("UNLOCK($%d)\n",op->ax); break; + + case DATA: vLog("DATA(%d)\n",(int)op->nx); break; + case READ: vLog("READ($%d)\n",(int)op->ix); break; + case WRITE: vLog("WRITE($%d)\n",(int)op->ix); break; + case READS: vLog("READS($%d)\n",(int)op->ix); break; + case WRITES: vLog("WRITES($%d)\n",(int)op->ix); break; + + case STRING: vLog("STRING($%d[%d])\n",addr+1+index_s,(int)op->ix); break; + case ENV: vLog("ENV(%d)\n",(int)op->ix); break; + case END: vLog("END\n"); break; + default: vLog("OP(%d)\n",op->command); break; + } +} + + +void PrintLexerToken(lexer_t * L) { + switch (L->token) { + case EOL: vLog("EOL\n"); break; + + case TADD: vLog("TADD\n"); break; + case TAND: vLog("TAND\n"); break; + case TAWAIT: vLog("TAWAIT\n"); break; + case TBREAK: vLog("TBREAK\n"); break; + case TCONST: vLog("TCONST\n"); break; + case TCONTINUE: vLog("TCONTINUE\n"); break; + case TCHAR: vLog("TCHAR(%d)\n",(int)(*L->arg)); break; + case TCALL: vLog("TCALL\n"); break; + case TDELAY: vLog("TDELAY\n"); break; + case TDO: vLog("TDO\n"); break; + case TDATA: vLog("TDATA\n"); break; + case TELSE: vLog("TELSE\n"); break; + case TERROR: vLog("TERROR\n"); break; + case TEVENT: vLog("TEVENT\n"); break; + case TEQUAL: vLog("TEQUAL\n"); break; + case TFOR: vLog("TFOR\n"); break; + case TFORK: vLog("TFORK\n"); break; + case TGEQ: vLog("TGEQ\n"); break; + case TGT: vLog("TGT\n"); break; + case TIF: vLog("TIF\n"); break; + case TINPUT: vLog("TINPUT\n"); break; + case TLEQ: vLog("TLEQ\n"); break; + case TLT: vLog("TLT\n"); break; +#if HAS_LOCK > 0 + case TLOCK: vLog("TLOCK\n"); break; +#endif + case TNEQ: vLog("TNEQ\n"); break; + case TNEXTARG: vLog("TNEXTARG\n"); break; + case TON: vLog("TON\n"); break; + case TOUTPUT: vLog("TOUTPUT\n"); break; + case TPROC: vLog("TPROC\n"); break; + case TRETURN: vLog("TRETURN\n"); break; + case TSUB: vLog("TSUB\n"); break; + case TSTRING: vLog("TSTRING(%d)\n",(int)(L->arglen)); break; + case TTHEN: vLog("TTHEN\n"); break; +#if HAS_LOCK > 0 + case TUNLOCK: vLog("TUNLOCK\n"); break; +#endif + case TVARDEF: vLog("TVARDEF\n"); break; + case TWHILE: vLog("TWHILE\n"); break; + case TYIELD: vLog("TYIELD\n"); break; + + case TCCALL: vLog("TCCALL(%d)\n",L->ix); break; + case TNUMBER: vLog("TNUMBER(%d)\n",(int)L->x); break; + case TIDENTIFIER: vLog("TIDENTIFIER(%s)\n",L->name); break; + default: if (L->token>20) vLog("TOKEN('%c')\n",L->token); else vLog("TOKEN(%d)\n",L->token); break; + } +} + +void PrintStack(char *label,stack_t * S) { + vLog("======= %s Stack [%d] ========\n",label,S->sp); + for(int i=S->sp-1;i>=0;i--) { + vLog("[%d] %d\n",S->sp-i,(int)S->data[i]); + } +} + +void PrintState(reg_t *R) { + vLog("VM state [pc=%d:state=%x:error=%d]: ",R->pc,R->state,R->error); + if (R->state&PIDLE) vLog("PIDLE "); + if (R->state&PRUNNING) vLog("PRUNNING "); + if (R->state&PTIMEOUT) vLog("PTIMEOUT "); + if (R->state&PSUSPENDED) vLog("PSUSPENDED "); + if (R->state&PAWAIT) vLog("PAWAIT "); + if (R->state&PINTERRUPT) vLog("PINTERRUPT "); + if (R->state&PHANDLER) vLog("PHANDLER "); + if (R->state&PERROR) vLog("PERROR "); + if (R->state&PEVENTPEND) vLog("PEVENTPEND "); + vLog("\n"); + +} +#endif +