#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