Mon 16 Mar 11:09:06 CET 2026
This commit is contained in:
parent
e6ab306721
commit
389ba56aa3
270
src/debug.c
Normal file
270
src/debug.c
Normal file
|
|
@ -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 (pc<M->bottom) {
|
||||||
|
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 (pc<M->bottom) {
|
||||||
|
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;i<E->top;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;i<v->length;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
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user