diff options
-rw-r--r-- | conf.c | 19 | ||||
-rw-r--r-- | debug.c | 6 | ||||
-rw-r--r-- | syslogd.c | 4 | ||||
-rw-r--r-- | var.c | 2 | ||||
-rw-r--r-- | vm.c | 79 | ||||
-rw-r--r-- | vm.h | 1 | ||||
-rw-r--r-- | vmstk.c | 6 |
7 files changed, 104 insertions, 13 deletions
@@ -57,6 +57,9 @@ /* static data */ DEFobjCurrIf(expr) DEFobjCurrIf(ctok) +#include "vm.h" +DEFobjCurrIf(vm) // TODO: remove, testing aid! rgerhards, 2008-02-25 + uchar *pModDir = NULL; /* read-only after startup */ /* The following global variables are used for building @@ -791,7 +794,22 @@ dbgprintf("calling expression parser, pp %p ('%s')\n", *pline, *pline); dbgprintf("expression parser successfully ended, pp %p ('%s')\n", *pline, *pline); +/* debug aid, try to exec - just now for testing the vm... -- rgerhards, 2008-02-25 */ +vm_t *pVM; +var_t *pResult; +CHKiRet(vm.Construct(&pVM)); +CHKiRet(vm.ConstructFinalize(pVM)); + +CHKiRet(vm.ExecProg(pVM, f->f_filterData.f_expr->pVmprg)); +CHKiRet(vm.PopBoolFromStack(pVM, &pResult)); +dbgprintf("result of expression run: %lld\n", pResult->val.num); + +CHKiRet(vm.Destruct(&pVM)); +/* ...end testing aid... */ + + finalize_it: +RUNLOG_VAR("%d", iRet); if(iRet == RS_RET_SYNTAX_ERROR) { logerror("syntax error in expression"); } @@ -1172,6 +1190,7 @@ rsRetVal confClassInit(void) /* request objects we use */ CHKiRet(objUse(expr)); CHKiRet(objUse(ctok)); + CHKiRet(objUse(vm)); // TODO: remove, testing aid! rgerhards, 2008-02-25 finalize_it: RETiRet; @@ -930,7 +930,8 @@ int dbgEntrFunc(dbgFuncDB_t *pFuncDB, int line) /* when we reach this point, we have a fully-initialized FuncDB! */ //if(bLogFuncFlow) /* quick debug hack... select the best for you! */ - if(bLogFuncFlow && !strcmp((char*)pFuncDB->file, "expr.c")) /* quick debug hack... select the best for you! */ + if(bLogFuncFlow && !strcmp((char*)pFuncDB->file, "vm.c")) /* quick debug hack... select the best for you! */ + //if(bLogFuncFlow && !strcmp((char*)pFuncDB->file, "expr.c")) /* quick debug hack... select the best for you! */ dbgprintf("%s:%d: %s: enter\n", pFuncDB->file, pFuncDB->line, pFuncDB->func); if(pThrd->stackPtr >= (int) (sizeof(pThrd->callStack) / sizeof(dbgFuncDB_t*))) { dbgprintf("%s:%d: %s: debug module: call stack for this thread full, suspending call tracking\n", @@ -960,7 +961,8 @@ void dbgExitFunc(dbgFuncDB_t *pFuncDB, int iStackPtrRestore) dbgFuncDBPrintActiveMutexes(pFuncDB, "WARNING: mutex still owned by us as we exit function, mutex: ", pthread_self()); //if(bLogFuncFlow) /* quick debug hack... select the best for you! */ - if(bLogFuncFlow && !strcmp((char*)pFuncDB->file, "expr.c")) /* quick debug hack... select the best for you! */ + if(bLogFuncFlow && !strcmp((char*)pFuncDB->file, "vm.c")) /* quick debug hack... select the best for you! */ + //if(bLogFuncFlow && !strcmp((char*)pFuncDB->file, "expr.c")) /* quick debug hack... select the best for you! */ dbgprintf("%s:%d: %s: exit\n", pFuncDB->file, pFuncDB->line, pFuncDB->func); pThrd->stackPtr = iStackPtrRestore; if(pThrd->stackPtr < 0) { @@ -172,6 +172,8 @@ #include "ctok.h" #include "conf.h" #include "vmop.h" +#include "vmstk.h" +#include "vm.h" #include "vmprg.h" /* definitions for objects we access */ @@ -3558,6 +3560,8 @@ static rsRetVal InitGlobalClasses(void) CHKiRet(wtiClassInit()); CHKiRet(wtpClassInit()); CHKiRet(queueClassInit()); + CHKiRet(vmstkClassInit()); + CHKiRet(vmClassInit()); CHKiRet(vmopClassInit()); CHKiRet(vmprgClassInit()); CHKiRet(varClassInit()); @@ -80,7 +80,7 @@ CODESTARTobjDebugPrint(var) dbgoprint((obj_t*) pThis, "type: cstr, val '%s'\n", rsCStrGetSzStr(pThis->val.pStr)); break; case VARTYPE_NUMBER: - dbgoprint((obj_t*) pThis, "type: int64, val %lld\n", pThis->val.num); + dbgoprint((obj_t*) pThis, "type: number, val %lld\n", pThis->val.num); break; default: dbgoprint((obj_t*) pThis, "type %d currently not suppored in debug output\n", pThis->varType); @@ -48,6 +48,11 @@ DEFobjCurrIf(var) #define CODESTARTop(instruction) \ ISOBJ_TYPE_assert(pThis, vm); +#define PUSHRESULTop(operand, res) \ + /* we have a result, so let's push it */ \ + var.SetNumber(operand, res); \ + vmstk.Push(pThis->pStk, operand); /* result */ + #define ENDop(instruction) \ RETiRet; \ } @@ -74,12 +79,33 @@ BOOLOP(AND, &&) #undef BOOLOP +/* code generator for numerical operations */ +#define BOOLOP(name, OPERATION) \ +BEGINop(name) /* remember to set the instruction also in the ENDop macro! */ \ + var_t *operand1; \ + var_t *operand2; \ +CODESTARTop(name) \ + vmstk.PopNumber(pThis->pStk, &operand1); \ + vmstk.PopNumber(pThis->pStk, &operand2); \ + operand1->val.num = operand1->val.num OPERATION operand2->val.num; \ +RUNLOG_VAR("%lld", operand1->val.num); \ + vmstk.Push(pThis->pStk, operand1); /* result */ \ + var.Destruct(&operand2); /* no longer needed */ \ +ENDop(name) +BOOLOP(PLUS, +) +BOOLOP(MINUS, -) +BOOLOP(TIMES, *) +BOOLOP(DIV, /) +BOOLOP(MOD, %) +#undef BOOLOP + + /* code generator for compare operations */ #define BEGINCMPOP(name) \ BEGINop(name) \ var_t *operand1; \ var_t *operand2; \ - int bRes; \ + number_t bRes; \ CODESTARTop(name) \ CHKiRet(vmstk.Pop2CommOp(pThis->pStk, &operand1, &operand2)); \ /* data types are equal (so we look only at operand1), but we must \ @@ -93,6 +119,7 @@ CODESTARTop(name) \ } \ \ /* we have a result, so let's push it */ \ +RUNLOG_VAR("%lld", bRes); \ var.SetNumber(operand1, bRes); \ vmstk.Push(pThis->pStk, operand1); /* result */ \ var.Destruct(&operand2); /* no longer needed */ \ @@ -170,18 +197,26 @@ CODESTARTop(CMP_CONTAINS) bRes = (rsCStrLocateInSzStr(operand2->val.pStr, rsCStrGetSzStr(operand1->val.pStr)) == -1) ? 0 : 1; /* we have a result, so let's push it */ - var.SetNumber(operand1, bRes); - vmstk.Push(pThis->pStk, operand1); /* result */ + PUSHRESULTop(operand1, bRes); var.Destruct(&operand2); /* no longer needed */ ENDop(CMP_CONTAINS) /* end comare operations that work on strings, only */ +BEGINop(NOT) /* remember to set the instruction also in the ENDop macro! */ + var_t *operand; +CODESTARTop(NOT) + vmstk.PopBool(pThis->pStk, &operand); + PUSHRESULTop(operand, !operand->val.num); +ENDop(NOT) + +BEGINop(UNARY_MINUS) /* remember to set the instruction also in the ENDop macro! */ + var_t *operand; +CODESTARTop(UNARY_MINUS) + vmstk.PopNumber(pThis->pStk, &operand); + PUSHRESULTop(operand, -operand->val.num); +ENDop(UNARY_MINUS) -BEGINop(POP) /* remember to set the instruction also in the ENDop macro! */ -CODESTARTop(POP) -/* TODO: implement */ -ENDop(POP) BEGINop(PUSHCONSTANT) /* remember to set the instruction also in the ENDop macro! */ CODESTARTop(PUSHCONSTANT) @@ -206,6 +241,11 @@ vmConstructFinalize(vm_t __attribute__((unused)) *pThis) { DEFiRet; ISOBJ_TYPE_assert(pThis, vm); + + CHKiRet(vmstk.Construct(&pThis->pStk)); + CHKiRet(vmstk.ConstructFinalize(pThis->pStk)); + +finalize_it: RETiRet; } @@ -213,6 +253,8 @@ vmConstructFinalize(vm_t __attribute__((unused)) *pThis) /* destructor for the vm object */ BEGINobjDestruct(vm) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDestruct(vm) + if(pThis->pStk != NULL) + vmstk.Destruct(&pThis->pStk); ENDobjDestruct(vm) @@ -248,8 +290,14 @@ execProg(vm_t *pThis, vmprg_t *pProg) doOP(CMP_GTEQ); doOP(CMP_CONTAINS); // TODO: implement: doOP(CMP_STARTSWITH); - doOP(POP); + doOP(NOT); doOP(PUSHCONSTANT); + doOP(PLUS); + doOP(MINUS); + doOP(TIMES); + doOP(DIV); + doOP(MOD); + doOP(UNARY_MINUS); default: ABORT_FINALIZE(RS_RET_INVALID_VMOP); dbgoprint((obj_t*) pThis, "invalid instruction %d in vmprg\n", pCurrOp->opcode); @@ -269,6 +317,20 @@ finalize_it: } +/* Pop a boolean from the stack and return it to caller. This functionality is + * partly needed. We may (or may not ;)) be able to remove it once we have + * full RainerScript support. -- rgerhards, 2008-02-25 + */ +static rsRetVal +PopBoolFromStack(vm_t *pThis, var_t **ppVar) +{ + DEFiRet; + + CHKiRet(vmstk.PopBool(pThis->pStk, ppVar)); + +finalize_it: + RETiRet; +} /* queryInterface function * rgerhards, 2008-02-21 @@ -291,6 +353,7 @@ CODESTARTobjQueryInterface(vm) pIf->Destruct = vmDestruct; pIf->DebugPrint = vmDebugPrint; pIf->ExecProg = execProg; + pIf->PopBoolFromStack = PopBoolFromStack; finalize_it: ENDobjQueryInterface(vm) @@ -49,6 +49,7 @@ BEGINinterface(vm) /* name must also be changed in ENDinterface macro! */ rsRetVal (*ConstructFinalize)(vm_t __attribute__((unused)) *pThis); rsRetVal (*Destruct)(vm_t **ppThis); rsRetVal (*ExecProg)(vm_t *pThis, vmprg_t *pProg); + rsRetVal (*PopBoolFromStack)(vm_t *pThis, var_t **ppVar); /* there are a few cases where we need this... */ ENDinterface(vm) #define vmCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */ @@ -89,6 +89,8 @@ finalize_it: /* pop a value from the stack + * IMPORTANT: the stack pointer always points to the NEXT FREE entry. So in + * order to pop, we must access the element one below the stack pointer. * The user is responsible for destructing the ppVar returned. */ static rsRetVal @@ -97,12 +99,12 @@ pop(vmstk_t *pThis, var_t **ppVar) DEFiRet; ISOBJ_TYPE_assert(pThis, vmstk); - assert(ppVar != NULL); + ASSERT(ppVar != NULL); if(pThis->iStkPtr == 0) ABORT_FINALIZE(RS_RET_STACK_EMPTY); - *ppVar = pThis->vStk[pThis->iStkPtr--]; + *ppVar = pThis->vStk[--pThis->iStkPtr]; finalize_it: RETiRet; |