summaryrefslogtreecommitdiffstats
path: root/runtime/vm.c
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2009-03-10 17:37:13 +0100
committerRainer Gerhards <rgerhards@adiscon.com>2009-03-10 17:37:13 +0100
commite8499c6d33d09f6d8b42df72da1661be0ef0f088 (patch)
tree577caaba6912f8f88f8bc29b4105eafe44fd4024 /runtime/vm.c
parentf67cf99ee5cd88bda499aa52d6008bb7d4afe483 (diff)
downloadrsyslog-e8499c6d33d09f6d8b42df72da1661be0ef0f088.tar.gz
rsyslog-e8499c6d33d09f6d8b42df72da1661be0ef0f088.tar.xz
rsyslog-e8499c6d33d09f6d8b42df72da1661be0ef0f088.zip
initial implementation of RainerScript functions & strlen()
- implemented function support in RainerScript. That means the engine parses and compile functions, as well as executes a few build-in ones. Dynamic loading and registration of functions is not yet supported - but we now have a good foundation to do that later on. NOTE: nested function calls are not yet supported due to a design issue with the function call VM instruction set design. - implemented the strlen() RainerScript function
Diffstat (limited to 'runtime/vm.c')
-rw-r--r--runtime/vm.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/runtime/vm.c b/runtime/vm.c
index bc6c3dd2..113a9d59 100644
--- a/runtime/vm.c
+++ b/runtime/vm.c
@@ -331,6 +331,33 @@ finalize_it:
ENDop(PUSHSYSVAR)
+/* The function call operation is only very roughly implemented. While the plumbing
+ * to reach this instruction is fine, the instruction itself currently supports only
+ * functions with a single argument AND with a name that we know.
+ * TODO: later, we can add here the real logic, that involves looking up function
+ * names, loading them dynamically ... and all that...
+ * implementation begun 2009-03-10 by rgerhards
+ */
+BEGINop(FUNC_CALL) /* remember to set the instruction also in the ENDop macro! */
+ var_t *numOperands;
+ var_t *operand1;
+ int iStrlen;
+CODESTARTop(FUNC_CALL)
+ vmstk.PopNumber(pThis->pStk, &numOperands);
+ if(numOperands->val.num != 1)
+ ABORT_FINALIZE(RS_RET_INVLD_NBR_ARGUMENTS);
+ vmstk.PopString(pThis->pStk, &operand1); /* guess there's just one ;) */
+ if(!rsCStrSzStrCmp(pOp->operand.pVar->val.pStr, (uchar*) "strlen", 6)) { /* only one supported so far ;) */
+RUNLOG_VAR("%s", rsCStrGetSzStr(operand1->val.pStr));
+ iStrlen = strlen((char*) rsCStrGetSzStr(operand1->val.pStr));
+RUNLOG_VAR("%d", iStrlen);
+ } else
+ ABORT_FINALIZE(RS_RET_INVLD_FUNC);
+ PUSHRESULTop(operand1, iStrlen); // TODO: dummy, FIXME
+finalize_it:
+ENDop(FUNC_CALL)
+
+
/* ------------------------------ end instruction set implementation ------------------------------ */
@@ -412,6 +439,7 @@ execProg(vm_t *pThis, vmprg_t *pProg)
doOP(DIV);
doOP(MOD);
doOP(UNARY_MINUS);
+ doOP(FUNC_CALL);
default:
ABORT_FINALIZE(RS_RET_INVALID_VMOP);
dbgoprint((obj_t*) pThis, "invalid instruction %d in vmprg\n", pCurrOp->opcode);