summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--conf.c19
-rw-r--r--debug.c6
-rw-r--r--syslogd.c4
-rw-r--r--var.c2
-rw-r--r--vm.c79
-rw-r--r--vm.h1
-rw-r--r--vmstk.c6
7 files changed, 104 insertions, 13 deletions
diff --git a/conf.c b/conf.c
index 56ba3837..a537d18a 100644
--- a/conf.c
+++ b/conf.c
@@ -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;
diff --git a/debug.c b/debug.c
index 00b7916b..c99dfa93 100644
--- a/debug.c
+++ b/debug.c
@@ -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) {
diff --git a/syslogd.c b/syslogd.c
index 294187d9..4a4506b3 100644
--- a/syslogd.c
+++ b/syslogd.c
@@ -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());
diff --git a/var.c b/var.c
index 8b5a8dd0..3c6a101d 100644
--- a/var.c
+++ b/var.c
@@ -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);
diff --git a/vm.c b/vm.c
index 7b933c39..76f06328 100644
--- a/vm.c
+++ b/vm.c
@@ -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)
diff --git a/vm.h b/vm.h
index c9173255..1234349e 100644
--- a/vm.h
+++ b/vm.h
@@ -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! */
diff --git a/vmstk.c b/vmstk.c
index 6f8d36f6..a739f395 100644
--- a/vmstk.c
+++ b/vmstk.c
@@ -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;